/**
 * PaperBrain WooCommerce design layer.
 *
 * Styles and extends WooCommerce's own native markup/classes (core
 * templates + WooCommerce Blocks) — it never replaces WooCommerce
 * functionality, never overrides Cart/Checkout Block logic, and adds
 * no custom PHP templates. Loads after main.css and after
 * WooCommerce's own bundled stylesheets (see functions.php), so it can
 * override with plain classes at equal specificity, no !important.
 *
 * Colors are CSS custom properties fed by inc/woocommerce-design.php
 * (Customizer → "WooCommerce-ontwerp"); typography/spacing/radius are
 * custom properties too, defined once below, so nothing in this file
 * is a hardcoded magic number repeated in multiple places.
 */

:root {
	/* Colors — overridden per-site via wp_add_inline_style() from the Customizer (inc/woocommerce-design.php); values below are the fallback defaults. */
	--wc-primary: #6848f4;
	--wc-secondary: #111111;
	--wc-accent: #ea3325;
	--wc-background: #ffffff;
	--wc-surface: #f7f7f7;
	--wc-border: #e6e3df;
	--wc-success: #1e7a46;
	--wc-error: #c62828;
	--wc-muted-text: #6b6b6b;
	--wc-heading: #111111;

	/* Typography */
	--wc-font-heading-xl: clamp(1.9rem, 1.4vw + 1.6rem, 2.75rem);
	--wc-font-heading-lg: clamp(1.4rem, 1vw + 1.2rem, 1.85rem);
	--wc-font-heading-md: 1.15rem;
	--wc-font-body: 1rem;
	--wc-font-body-sm: 0.875rem;
	--wc-font-label: 0.78rem;
	--wc-font-button: 0.8rem;

	/* Spacing / radius / shadow */
	--wc-radius-card: 1.25rem;
	--wc-radius-input: 0.65rem;
	--wc-radius-button: 999px;
	--wc-shadow-card: 0 12px 32px rgba(17, 17, 17, 0.08);
	--wc-shadow-drawer: -24px 0 60px rgba(17, 17, 17, 0.18);
	--wc-section-spacing: clamp(2.5rem, 5vw, 5rem);
	--wc-container-width: 1600px;
	--wc-container-narrow: 1200px;
	/* Both devtools-measured off elvou.com/products/grasgevoerde-whey
	 * (1440px viewport): --wc-content-card-width is the grey description
	 * card's own max-width; --wc-content-narrow is the narrower, centered
	 * column the text section right below that card uses. */
	--wc-content-card-width: 1152px;
	--wc-content-narrow: 896px;
}

/* ==========================================================================
 * Full-bleed WooCommerce pages — same technique already used for
 * Store Locator / Blog (.site-main normally caps at 800px). Multiple
 * selectors cover every WC page context without needing to touch
 * page.php/index.php.
 * ========================================================================*/
body.woocommerce-page .site-main,
body.woocommerce .site-main,
body.single-product .site-main {
	max-width: none;
	padding: 0;
}

/* ==========================================================================
 * Header/logo regression guard.
 *
 * WooCommerce's own bundled woocommerce-layout.css ships a global
 * `.woocommerce-page img, .woocommerce img { height: auto; max-width:
 * 100%; }` reset. Because <body> gets the woocommerce-page/woocommerce
 * classes on every Shop/Product/Cart/Checkout/My Account page, that
 * selector's specificity (0,1,1) beats the theme's own single-class
 * `.custom-logo` sizing rule in main.css (0,1,0) — so on those pages
 * only, the logo's own sizing was silently overridden, rendering it at
 * its native uploaded pixel size (thousands of pixels wide) and
 * breaking the header layout.
 *
 * This restores the theme's own logo sizing, scoped strictly to
 * .site-header so it can never affect WooCommerce's own product/
 * gallery/cart images elsewhere on the same page — those keep relying
 * on WooCommerce's responsive `max-width:100%; height:auto` as
 * intended. Driven by the same --pb-header-logo-width-mobile/-desktop
 * custom properties as main.css's own `.custom-logo` rule (PaperBrain
 * Design -> Header -> "Logo breedte …"), rather than a hardcoded
 * height, so that setting actually takes effect on WooCommerce pages
 * too, not just everywhere else.
 * ========================================================================*/
.site-header .custom-logo,
.site-header .site-branding img {
	max-width: var(--pb-header-logo-width-mobile, 90px) !important;
	width: auto !important;
	height: auto !important;
}

@media (min-width: 768px) {
	.site-header .custom-logo,
	.site-header .site-branding img {
		/* Spec: logo rendered size 78 x 30.47 on desktop — same fallback
		 * as main.css's own .custom-logo rule (kept in sync). */
		max-width: var(--pb-header-logo-width-desktop, 78px) !important;
	}
}

/* ==========================================================================
 * Base typography
 * ========================================================================*/
.woocommerce,
.woocommerce-page {
	color: var(--wc-secondary);
	font-size: var(--wc-font-body);
}

.woocommerce a {
	color: var(--wc-primary);
}

/* Site header/nav links must stay black on WooCommerce pages —
 * `.woocommerce a` above has higher specificity (one class + one
 * element) than the header's own single-class selectors, so without
 * this scoped override every header link silently turns var(--wc-primary)
 * purple on product/shop pages, while the same header renders correctly
 * black everywhere else. Same "extra scope beats .woocommerce a" pattern
 * already used for .pb-mini-cart-upsell__add below. */
.woocommerce .site-header-wrap a,
.woocommerce-page .site-header-wrap a {
	color: inherit;
}

/* The header CTA (filled purple by default, 2026-07-23) needs its own
 * pin here too — three-class specificity beats the `a { color: inherit }`
 * rule just above (two classes + element) regardless of source order,
 * restoring its white label text in both its default and hover fill
 * (assets/css/main.css, .pb-newsletter__cta--header.pb-button--ghost). */
.woocommerce .site-header-wrap .pb-newsletter__cta--header,
.woocommerce-page .site-header-wrap .pb-newsletter__cta--header {
	color: #ffffff;
}

.woocommerce .site-header-wrap .pb-newsletter__cta--header:hover,
.woocommerce .site-header-wrap .pb-newsletter__cta--header:focus-visible,
.woocommerce-page .site-header-wrap .pb-newsletter__cta--header:hover,
.woocommerce-page .site-header-wrap .pb-newsletter__cta--header:focus-visible {
	color: #ffffff;
}

/* Same "extra scope beats .woocommerce a" pattern as the header fix
 * above, for the footer — .site-footer renders on every WooCommerce-
 * templated page too (shop/product/cart/checkout/account all add
 * body.woocommerce / .woocommerce-page), and without this every
 * footer link/heading/icon silently turns var(--wc-primary) purple or
 * var(--wc-secondary) body text there, while the same footer renders
 * with its own colors correctly everywhere else. Values copied as-is
 * from each rule's own main.css declaration, just re-scoped. */
.woocommerce .site-footer,
.woocommerce-page .site-footer {
	color: var(--pb-footer-text, #6b6b6b);
}

.woocommerce .site-footer a,
.woocommerce-page .site-footer a {
	color: inherit;
}

.woocommerce .site-footer__links a,
.woocommerce-page .site-footer__links a,
.woocommerce .site-footer__address-line,
.woocommerce-page .site-footer__address-line {
	color: var(--pb-footer-link, #6b6b6b);
}

.woocommerce .site-footer__links a:hover,
.woocommerce-page .site-footer__links a:hover,
.woocommerce .site-footer__links a:focus-visible,
.woocommerce-page .site-footer__links a:focus-visible {
	color: var(--pb-footer-link-hover, #111111);
}

.woocommerce .site-footer__col-title,
.woocommerce-page .site-footer__col-title,
.woocommerce .site-footer__col-icon,
.woocommerce-page .site-footer__col-icon,
.woocommerce .site-footer__group-heading,
.woocommerce-page .site-footer__group-heading,
.woocommerce .site-footer__group-icon,
.woocommerce-page .site-footer__group-icon {
	color: var(--pb-footer-heading, #111111);
}

.woocommerce .site-footer__social-icon,
.woocommerce-page .site-footer__social-icon {
	color: var(--pb-footer-icon, #111111);
}

.woocommerce .site-footer__copyright,
.woocommerce-page .site-footer__copyright {
	color: var(--pb-footer-text, #6b6b6b);
}

/* Heading weight/letter-spacing/color used to be set here from the
 * older --wc-heading Customizer token; removed in favour of the
 * central h1-h6 rules in design-system.css (theme.json
 * settings.custom.typography.h1-h6 + color palette "heading"), which
 * WooCommerce's product_title/etc. already pick up automatically as
 * real <h1>-<h3> elements — this closes the last bit of WooCommerce
 * heading style living outside the central Design System. Only
 * practical effect: H1/H2 letter-spacing tightens slightly from the
 * old flat -0.01em to the token's -0.02em (H3 is unchanged, already
 * -0.01em); color and weight are identical values either way.
 */

.woocommerce mark {
	background: none;
	color: inherit;
}

/* ==========================================================================
 * Buttons — one consistent look across every WooCommerce button
 * variant (loop add-to-cart, PDP add-to-cart, cart/checkout CTAs,
 * mini-cart, my-account forms). Colour/radius/font-size/font-weight/
 * text-transform/font-family now come straight from the central
 * Primary button token (theme.json settings.custom.button.primary) —
 * the same source .pb-button--primary uses — closing the WooCommerce
 * side of the Button Design System "as far as technically supported".
 * Padding and letter-spacing stay WooCommerce's own established
 * values (0.9rem/1.75rem and 0.06em vs. Primary's 0.95rem/2.25rem and
 * 0.08em): those two are visibly different from the Primary token, so
 * forcing them to match would change every WooCommerce button's size
 * — a redesign, not a cleanup — and this task explicitly rules that
 * out.
 * ========================================================================*/
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.wc-block-components-button,
.wp-block-woocommerce-checkout .wc-block-components-checkout-place-order-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.9rem 1.75rem;
	border: none;
	border-radius: var(--wp--custom--button--primary--radius, var(--wc-radius-button, 999px));
	background: var(--wp--custom--button--primary--background, var(--wc-primary, #6848f4));
	color: var(--wp--custom--button--primary--text, #ffffff);
	font-family: var(--wp--preset--font-family--theme-button, inherit);
	font-size: var(--wp--custom--button--primary--font-size, var(--wc-font-button, 0.8rem));
	font-weight: var(--wp--custom--button--primary--font-weight, 700);
	text-transform: var(--wp--custom--typography--button--transform, none);
	letter-spacing: 0.06em;
	line-height: 1.2;
	cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.woocommerce a.button:hover,
.woocommerce a.button:focus-visible,
.woocommerce button.button:hover,
.woocommerce button.button:focus-visible,
.woocommerce input.button:hover,
.woocommerce input.button:focus-visible,
.wc-block-components-button:hover,
.wp-block-woocommerce-checkout .wc-block-components-checkout-place-order-button:hover {
	transform: translateY(-1px);
	box-shadow: 0 10px 24px rgba(17, 17, 17, 0.18);
	opacity: 0.94;
	outline: none;
}

.woocommerce a.button.loading,
.woocommerce button.button.loading,
.wc-block-components-button.wc-block-components-button--loading {
	opacity: 0.6;
	cursor: wait;
}

.woocommerce a.button.alt,
.woocommerce button.button.alt {
	background: var(--wc-secondary);
}

/* Outline/secondary button variant (e.g. "View cart", "Continue shopping"). */
.woocommerce a.wc-forward,
.wc-block-components-button.is-style-outlined {
	background: transparent;
	border: 1.5px solid var(--wc-border);
	color: var(--wc-secondary);
}

/* ==========================================================================
 * Forms / inputs — shop filters, quantity inputs, my-account, checkout.
 * ========================================================================*/
.woocommerce input.qty,
.woocommerce table.shop_table input.qty,
.woocommerce input[type="text"],
.woocommerce input[type="email"],
.woocommerce input[type="tel"],
.woocommerce input[type="password"],
.woocommerce input[type="number"],
.woocommerce select,
.woocommerce textarea,
.wc-block-components-text-input input,
.wc-block-components-select select {
	border: 1.5px solid var(--wc-border);
	border-radius: var(--wc-radius-input);
	padding: 0.75rem 1rem;
	font-size: var(--wc-font-body-sm);
	background: var(--wc-background);
	color: var(--wc-secondary);
	transition: border-color 0.2s ease;
}

.woocommerce input:focus,
.woocommerce select:focus,
.woocommerce textarea:focus {
	border-color: var(--wc-primary);
	outline: none;
}

.woocommerce label,
.wc-block-components-text-input label {
	font-size: var(--wc-font-label);
	font-weight: 600;
	color: var(--wc-secondary);
}

/* ==========================================================================
 * Notices (success / error) — reuses core WC notice classes.
 * ========================================================================*/
.woocommerce-message,
.woocommerce-info {
	border-top-color: var(--wc-success);
	background: var(--wc-surface);
	border-radius: var(--wc-radius-input);
}

.woocommerce-message::before {
	color: var(--wc-success);
}

.woocommerce-error {
	border-top-color: var(--wc-error);
	background: var(--wc-surface);
	border-radius: var(--wc-radius-input);
}

.woocommerce-error::before {
	color: var(--wc-error);
}

/* ==========================================================================
 * Shop archive — responsive card grid, image hover-zoom (same technique
 * as .pb-blog-card), native WC classes only (ul.products / li.product).
 * ========================================================================*/
.woocommerce-products-header {
	max-width: var(--wc-container-width);
	margin: var(--wc-section-spacing) auto 2rem;
	padding: 0 1.25rem;
}

@media (min-width: 1024px) {
	.woocommerce-products-header {
		padding: 0 3rem;
	}
}

.woocommerce-products-header__title.page-title {
	font-size: var(--wc-font-heading-xl);
	color: var(--wc-heading);
	margin: 0 0 0.5rem;
}

.woocommerce ul.products {
	max-width: var(--wc-container-width);
	margin: 0 auto !important;
	padding: 0 1.25rem;
	display: grid !important;
	grid-template-columns: 1fr;
	gap: 1.75rem;
	list-style: none;
}

@media (min-width: 768px) {
	.woocommerce ul.products {
		grid-template-columns: repeat(2, 1fr);
		padding: 0 2rem;
		gap: 2rem;
	}
}

@media (min-width: 1024px) {
	.woocommerce ul.products {
		grid-template-columns: repeat(3, 1fr);
		padding: 0 3rem;
		gap: 2.5rem;
	}
}

.woocommerce ul.products li.product {
	position: relative;
	width: auto !important;
	margin: 0 !important;
	float: none !important;
}

.woocommerce ul.products li.product a {
	text-decoration: none;
}

.woocommerce ul.products li.product a img {
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	border-radius: var(--wc-radius-card);
	transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
	margin-bottom: 1rem !important;
}

.woocommerce ul.products li.product a.woocommerce-LoopProduct-link {
	display: block;
	overflow: hidden;
	border-radius: var(--wc-radius-card);
}

.woocommerce ul.products li.product:hover a img,
.woocommerce ul.products li.product a:focus-visible img {
	transform: scale(1.06);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	font-size: var(--wc-font-heading-md);
	font-weight: 700;
	color: var(--wc-heading);
	margin: 0 0 0.35rem;
}

.woocommerce ul.products li.product .price {
	font-size: var(--wc-font-body);
	font-weight: 700;
	color: var(--wc-primary);
}

.woocommerce ul.products li.product .price del {
	color: var(--wc-muted-text);
	font-weight: 400;
	opacity: 0.7;
}

.woocommerce ul.products li.product .price ins {
	text-decoration: none;
	color: var(--wc-accent);
}

/* "Quick add" — WooCommerce's own loop add-to-cart link/button, repositioned as a floating pill over the image on hover (optional progressive enhancement, still the same native <a class="add_to_cart_button">). */
.woocommerce ul.products li.product .button.add_to_cart_button {
	position: absolute;
	right: 0.75rem;
	bottom: calc(100% + 0.75rem);
	padding: 0.6rem 1.1rem;
	font-size: 0.7rem;
	opacity: 0;
	transform: translateY(6px);
	transition: opacity 0.2s ease, transform 0.2s ease;
	pointer-events: none;
}

.woocommerce ul.products li.product:hover .button.add_to_cart_button,
.woocommerce ul.products li.product:focus-within .button.add_to_cart_button {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

.woocommerce ul.products li.product .added_to_cart {
	display: block;
	margin-top: 0.5rem;
	font-size: var(--wc-font-label);
}

.woocommerce nav.woocommerce-pagination {
	max-width: var(--wc-container-width);
	margin: 3rem auto 0;
	padding: 0 1.25rem;
	text-align: center;
}

.woocommerce nav.woocommerce-pagination ul {
	border: none !important;
	display: inline-flex;
	gap: 0.5rem;
}

.woocommerce nav.woocommerce-pagination ul li {
	border: none !important;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5rem;
	height: 2.5rem;
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-button);
	color: var(--wc-secondary);
	font-weight: 600;
}

.woocommerce nav.woocommerce-pagination ul li span.current {
	background: var(--wc-secondary);
	border-color: var(--wc-secondary);
	color: #fff;
}

/* Native WC filter widgets (layered nav, ratings, price filter) — left untouched functionally, just aligned to the type scale. */
.woocommerce .widget_layered_nav ul,
.woocommerce .widget_layered_nav_filters ul,
.woocommerce .widget_price_filter {
	font-size: var(--wc-font-body-sm);
}

@media (prefers-reduced-motion: reduce) {
	.woocommerce ul.products li.product a img,
	.woocommerce ul.products li.product .button.add_to_cart_button {
		transition: none;
	}
}

/* ==========================================================================
 * Single Product (PDP) — real, controlled template structure. See
 * woocommerce/content-single-product.php for the actual markup
 * (.pb-pdp > .pb-pdp__hero > .pb-pdp__gallery + .pb-pdp__summary, then
 * .pb-pdp__details) and woocommerce/global/wrapper-start.php +
 * wrapper-end.php for the outer page wrapper. Every selector below is
 * either our own scaffolding (.pb-pdp*) or WooCommerce's own native
 * output (the gallery, .product_title, form.cart, .woocommerce-tabs,
 * etc.) — nothing here reimplements product data, pricing, stock,
 * variations, or add-to-cart logic; this only styles/positions what
 * WooCommerce already renders.
 * ========================================================================*/
.pb-wc-content-area,
.pb-wc-main {
	width: 100%;
}

/* Top padding is deliberately smaller than the bottom (a fixed 2rem,
 * not the full --wc-section-spacing scale) — the breadcrumb sits
 * right under the header, close to it, the same way breadcrumbs sit
 * on most sites; the large section-spacing rhythm still applies
 * between the hero and the details/tabs section below it. */
.pb-pdp {
	max-width: var(--wc-container-width);
	margin: 0 auto;
	padding: 2rem 1.25rem var(--wc-section-spacing);
	background: var(--wc-background);
	overflow-x: hidden;
}

@media (min-width: 1024px) {
	.pb-pdp {
		padding: 2rem 3rem var(--wc-section-spacing);
		overflow-x: visible;
	}
}

/* Breadcrumb — moved inside .pb-pdp (see pb_wc_pdp_move_breadcrumb(),
 * inc/woocommerce-product-page.php) so it shares the same container
 * width/padding as the hero below it instead of sitting as a
 * detached strip above the page. Deliberately quiet: small, muted,
 * a little letter-spacing, no border/background of its own. */
.pb-pdp .woocommerce-breadcrumb {
	margin: 0 0 1.5rem;
	font-size: var(--wc-font-label);
	letter-spacing: 0.02em;
	color: var(--wc-muted-text);
}

.pb-pdp .woocommerce-breadcrumb a {
	color: var(--wc-muted-text);
	text-decoration: none;
}

.pb-pdp .woocommerce-breadcrumb a:hover {
	color: var(--wc-primary);
	text-decoration: underline;
}

/* Mobile-only: the gallery/title/meta/price/Trustpilot spacing was
 * already tightened below (search "Mobile-only: tighten"), but that
 * pass never touched .pb-pdp's own 2rem top padding or the breadcrumb's
 * 1.5rem bottom margin — both sit *above* the breadcrumb/title/gallery
 * stack, so they were still pushing the whole hero (and therefore the
 * product photo itself, order:5 in that same stack) down the page
 * regardless of how tight everything below them got. Desktop/tablet
 * (>767px) keep the original 2rem/1.5rem — this is additive, mobile-only. */
@media (max-width: 767px) {
	.pb-pdp {
		/* 0, not 1rem (2026-08-16, explicit bug report) -- with the
		 * gallery order:1 right under the header on mobile (see the
		 * hero-order rules below), any top padding here is a literal
		 * blank gap between the header and the first product photo,
		 * not breathing room around other content. Desktop/tablet
		 * (>767px) keep the original 2rem -- mobile-only. */
		padding-top: 0;
	}

	/* Removed entirely on mobile (2026-08-13) — with the gallery now
	 * large/near screen-filling right under the header (order:1, see
	 * the mobile hero-order rules below), the breadcrumb's small "Home /
	 * Category / Product" trail added a line of low-value text directly
	 * above the photo for no real navigational benefit on a phone (no
	 * one taps a breadcrumb link mid-scroll on mobile the way they might
	 * on desktop). Desktop/tablet (>767px) keep it exactly as before —
	 * this is mobile-only. */
	.pb-pdp .woocommerce-breadcrumb {
		display: none;
	}
}

/* ---- Hero: gallery (left) + summary (right) ---- */
.pb-pdp__hero {
	display: flex;
	flex-direction: column;
	gap: 2.5rem;
}

@media (min-width: 1024px) {
	.pb-pdp__hero {
		flex-direction: row;
		align-items: flex-start;
		gap: 4rem;
	}

	/* Desktop only — sticky while the summary column scrolls past it,
	 * stopping naturally once .pb-pdp__hero (its containing block, which
	 * wraps only the gallery+summary, not .pb-pdp__details) finishes
	 * scrolling. --pb-pdp-sticky-top accounts for the sticky site header;
	 * the body.admin-bar rule below adds the WP admin bar's own height
	 * (32px desktop / 46px <783px) so the gallery never sits underneath
	 * either. Was 6rem — larger than the actual header height, which
	 * meant the sticky threshold was reached (and the gallery pinned
	 * down to it) even at initial page load/scroll position 0, while
	 * .pb-pdp__summary (not sticky) simply sat at its own, smaller
	 * natural position — that gap was the actual cause of the gallery
	 * starting lower than the title. Reduced to comfortably clear the
	 * header alone. */
	.pb-pdp__gallery {
		--pb-pdp-sticky-top: 4rem;
		flex: 1 1 55%;
		min-width: 0;
		position: sticky;
		top: var(--pb-pdp-sticky-top);
	}

	.pb-pdp__summary {
		flex: 1 1 45%;
		min-width: 0;
	}
}

/* The sticky gallery only exists >=1024px, and WordPress's admin bar
 * is always in its 32px desktop form at that width (it only grows to
 * 46px below 783px), so a single offset covers every case here. */
@media (min-width: 1024px) {
	body.admin-bar .pb-pdp__gallery {
		--pb-pdp-sticky-top: calc(4rem + 32px);
	}
}

/* Mobile: sticky explicitly disabled — the gallery scrolls with the
 * page like any other section. */
@media (max-width: 1023.98px) {
	.pb-pdp__gallery {
		position: static;
	}
}

/* Mobile ("like Nike"), full order: title, product meta (category, as
 * a subtitle-style line), price/stock, Trustpilot row (+ its "Bekijk
 * alle reviews" link, rendered inline inside it), gallery, trust
 * benefits, bundle selector, the purchase form (quantity/add-to-cart/
 * buy-now), short description, upsells, then the Productinformatie/
 * Beoordelingen accordions. Correction: pb_wc_render_pdp_attributes()
 * and pb_wc_render_pdp_reviews_accordion() are called from INSIDE
 * .pb-pdp__summary (right after product meta), not from .pb-pdp__details
 * as an earlier version of this comment claimed — verified directly
 * against woocommerce/content-single-product.php. That means they were
 * being promoted by display:contents like everything else here, but
 * with no explicit order they defaulted to order:0 and rendered before
 * even the title; giving them the last two order values below is the
 * actual fix, not just a doc correction. Any linked Gutenberg PDP
 * content (pb_wc_render_pdp_content()) genuinely does live in
 * .pb-pdp__details, a separate <section> after .pb-pdp__hero closes,
 * so it needs no order here and always renders last regardless.
 * .pb-pdp__summary is our own wrapper (the native "summary
 * entry-summary" classes stay on the same element only for plugin/JS
 * compatibility), so this `display:contents` + `order` is a deliberate
 * choice on markup we fully control — not a workaround. DOM order in
 * woocommerce/content-single-product.php is untouched; only these
 * order values move things around visually on mobile.
 *
 * gap is reduced from the desktop/base 2.5rem: with ~12 promoted flex
 * items now sharing this one gap value (rather than the 2 items —
 * gallery + summary — it was originally sized for), 2.5rem between
 * every single one of them, stacking on top of each element's own
 * margin, was the main source of the reported "too much whitespace". */
@media (max-width: 1023.98px) {
	.pb-pdp__hero {
		gap: 0.25rem;
	}

	.pb-pdp__summary {
		display: contents;
	}

	/* 2026-07-31: gallery moved to first (was order:5, interleaved
	 * after title/meta/price) -- reference layout wants the large
	 * product image immediately under the header, title/price below
	 * it. Trustpilot row removed from this mobile sequence entirely
	 * (see its own display:none rule further below) rather than given
	 * an order, since it no longer appears on mobile at all. */
	.pb-pdp__gallery {
		order: 1;
	}

	/* 2026-07-31: title+price now render as one .pb-pdp__title-price
	 * wrapper (woocommerce/content-single-product.php) instead of two
	 * separate flex items -- takes over title's old order:2 slot; price
	 * no longer needs its own order (it's nested inside this one now).
	 * p.stock keeps its own order below in case a product ever renders
	 * one (still not wrapped in the title/price row). */
	.pb-pdp__summary .pb-pdp__title-price {
		order: 2;
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 0px;
	}

	.pb-pdp__title-price .product_title,
	.pb-pdp__title-price p.price,
	.pb-pdp__title-price span.price {
		margin: 0;
	}

	/* If a product ever renders stock text inside this same output
	 * (WooCommerce's price template can append it), it drops to its own
	 * full-width line below title+price rather than squeezing onto the
	 * same row. */
	.pb-pdp__title-price p.stock {
		flex-basis: 100%;
		margin: 0;
	}

	.pb-pdp__summary .product_meta {
		order: 3;
	}

	.pb-pdp__summary p.stock {
		order: 4;
	}

	.pb-pdp__summary .pb-wc-trust-rows {
		order: 5;
	}

	.pb-pdp__summary .pb-pdp-bundle {
		order: 6;
	}

	/* Shirts: colour/size swatches below the gallery, right above the
	 * quantity + add-to-cart row (otherwise order:0 → above the image). */
	.pb-pdp__summary .pb-shirt-test-swatches {
		order: 6;
	}

	.pb-pdp__summary form.cart {
		order: 7;
	}

	.pb-pdp__summary .woocommerce-product-details__short-description {
		order: 8;
	}

	.pb-pdp__summary .up-sells {
		order: 9;
	}

	.pb-pdp__summary .pb-pdp__attributes {
		order: 10;
	}

	.pb-pdp__summary .pb-pdp__reviews-accordion {
		order: 11;
	}
}

/* ---- Gallery (Nike-style: theme-controlled, not WooCommerce/FlexSlider) ----
 * See pb_render_pdp_gallery() (inc/woocommerce-product-page.php) for
 * the markup and assets/js/woocommerce.js for the click/arrow
 * behaviour. This is a small, fully-owned gallery — no FlexSlider
 * markup or classes are involved, so there's nothing here that can
 * fight FlexSlider's own internal positioning/sizing. */
.pb-pdp-gallery {
	position: relative;
}

.pb-pdp-gallery--empty {
	background: var(--wc-surface);
	border-radius: var(--wc-radius-card);
}

/* No card treatment (no background/border-radius) — Nike-style, the
 * image sits directly on the page's own white background rather than
 * inside a distinct panel. overflow:hidden is only a containing
 * block for the arrows below, not a scroll container. */
/* align-items:flex-start (not center) so the product photo's own top
 * edge starts level with the thumbnail rail's top edge — centering it
 * vertically inside a tall card was what made the photo look "lower"
 * than the thumbnails even though the two columns' containers were
 * already aligned. */
.pb-pdp-gallery__main {
	position: relative;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	overflow: hidden;
	min-height: 20rem;
}

@media (min-width: 1024px) {
	.pb-pdp-gallery__main {
		min-height: min(560px, 60vh);
		/* 2026-08-17, second follow-up, explicit request: the image now
		 * needs to bottom-align with .pb-pdp__summary's own real height
		 * (title/price/description/USPs/quantity+CTA) — assets/js/
		 * woocommerce.js's pbMatchPdpGalleryHeightToSummary() now sets
		 * that as an explicit inline height on this element, which
		 * min-height/max-height still clamp regardless of source. A
		 * fixed max-height here would silently defeat that JS-driven
		 * match, so this is now a generous safety ceiling only (guards
		 * against a pathological edge case, e.g. JS failing to run) —
		 * min-height above remains the pre-JS/no-JS fallback floor
		 * (object-fit:cover still crops a tall photo to it, same as
		 * before). */
		max-height: 90vh;
	}
}

/* Larger, Nike-style mobile gallery: true 100vw full-bleed (the
 * calc(50% - 50vw) trick, rather than matching .pb-pdp's own 1.25rem
 * padding by hand — more robust since it doesn't depend on knowing any
 * particular ancestor's exact padding value. Safe because .pb-pdp
 * itself already sets overflow-x:hidden, so this can never cause
 * page-level horizontal scroll even if 100vw is fractionally wider
 * than the layout viewport, e.g. due to a scrollbar).
 *
 * 2026-08-13 rewrite: the previous version of this rule forced a fixed
 * `aspect-ratio: 320/480 !important` box. That !important silently
 * defeated assets/js/woocommerce.js's own applyMainAspectRatio(), which
 * already sets this exact element's aspect-ratio as an *inline* style
 * to match whichever photo/video is actually active (a plain CSS rule
 * of equal importance always loses to an inline style — !important was
 * specifically what let the fixed ratio win instead). Every product
 * photo was therefore squeezed into the same rigid 2:3 box regardless
 * of its real shape — for anything not naturally 2:3 (e.g. this site's
 * common square 1:1 product photos), object-fit:contain then had to
 * letterbox the difference, rendering well below what the viewport
 * actually had room for. Dropping the !important lets JS's own
 * per-photo ratio drive the box's shape again (height:auto) — this is
 * the primary sizing mechanism now, not a fallback.
 *
 * min-height is a floor, not a target: a first version of this rule
 * used calc(100vh - header) here (near-full-screen regardless of photo
 * shape), which forces a tall, mostly-portrait box on every product —
 * fine for a genuinely tall photo, but this site's actual product
 * photos are mostly square/4:5, so that box ended up much taller than
 * any of them, with the real photo floating small in the middle
 * surrounded by empty top/bottom space — the same "small photo, lots
 * of whitespace" complaint this rule exists to fix, just moved from
 * width to height. 24rem only protects against an unusually flat/wide
 * photo collapsing the box down small; any square-or-taller photo's
 * own width×ratio height already exceeds it, so the floor is inert for
 * normal product photos and the photo's real shape is what's visible.
 * max-height still caps the opposite extreme (an unusually tall/narrow
 * photo growing past the screen). */
@media (max-width: 1023.98px) {
	.pb-pdp__gallery {
		width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: calc(50% - 50vw);
		padding: 0;
	}

	.pb-pdp-gallery__main {
		display: flex;
		/* flex-start, not center (2026-08-13) — whenever this box ends up
		 * taller than the actual photo (the 24rem floor binding for a
		 * flatter-than-square image, or simply a photo shorter than the
		 * viewport allows), align-items:center split that leftover space
		 * evenly above AND below the photo, showing as an unwanted gap
		 * between the header and the top of the image. flex-start pins
		 * the photo to the top of the box instead (matching the desktop
		 * rule's own reasoning above — "product photo's own top edge
		 * starts level"), pushing any leftover space to the bottom only,
		 * right above the dots — nothing between the header and photo. */
		align-items: flex-start;
		justify-content: center;
		width: 100%;
		height: auto;
		min-height: 24rem;
		max-height: 90vh;
	}

	/* .pb-pdp-gallery__image's own mobile override lives further down,
	 * AFTER its unguarded base rule (~line 983) — same selector, same
	 * specificity, so it must come later in the file to actually win;
	 * see that base rule's own neighbouring comment. */
}

/* Sticky mobile "Toevoegen aan winkelwagen" bar — see
 * pb_wc_render_pdp_sticky_add_to_cart() (inc/woocommerce-product-page.php)
 * for why this never duplicates cart logic (it only scrolls the real
 * add-to-cart button into view). Hidden entirely on desktop; on mobile
 * it's always in the DOM but only visually shown via .is-visible,
 * toggled by an IntersectionObserver in assets/js/woocommerce.js.
 * 2026-07-31: the button itself now carries the real .pb-button
 * .pb-button--primary classes (pb_button_class('primary'),
 * inc/block-helpers.php) instead of a hand-duplicated copy of that
 * rule's colour/radius/font/hover declarations — one CTA
 * implementation, reused here, not a second one that can drift out of
 * sync with it (which is exactly how this bar's old hardcoded #6848f4
 * fallback had gone stale against .pb-button--primary's own current
 * default). Only the full-width override below is this bar's own. */
.pb-pdp-sticky-cta {
	display: none;
}

@media (max-width: 1023.98px) {
	.pb-pdp-sticky-cta {
		display: block;
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 60;
		padding: 0.75rem 1.25rem calc(0.75rem + env(safe-area-inset-bottom));
		background: var(--wc-background);
		border-top: 1px solid var(--wc-border);
		box-shadow: var(--wc-shadow-drawer, 0 -4px 16px rgba(0, 0, 0, 0.08));
		transform: translateY(100%);
		opacity: 0;
		pointer-events: none;
		transition: transform 0.25s ease, opacity 0.25s ease;
	}

	.pb-pdp-sticky-cta.is-visible {
		transform: translateY(0);
		opacity: 1;
		pointer-events: auto;
	}

	/* Compact title + price row, above the button, same white bar
	 * (2026-07-31) -- title/price text itself, not a duplicate of
	 * .product_title/.price elsewhere in .pb-pdp__summary (those stay
	 * exactly as they are; this is its own small readout so it works
	 * even once the real title/price have scrolled out of view). Price
	 * comes from $product->get_price_html() (PHP), so sale prices/
	 * ranges render with WooCommerce's own native markup, unchanged. */
	.pb-pdp-sticky-cta__info {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 0.75rem;
		margin-bottom: 0.5rem;
	}

	.pb-pdp-sticky-cta__title {
		font-size: 13px;
		font-weight: 600;
		color: var(--wc-heading);
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		min-width: 0;
	}

	.pb-pdp-sticky-cta__price {
		font-size: 14px;
		font-weight: 700;
		color: var(--wc-heading);
		white-space: nowrap;
		flex-shrink: 0;
	}

	/* Fixed 412.51 x 48 (2026-07-31, was width:100% / the shared
	 * .pb-button--primary's own 46px height) -- centered within the
	 * bar's own padding via margin:0 auto; .pb-button--primary's other
	 * styling (colour/radius/font/hover) is untouched. */
	.pb-pdp-sticky-cta__button {
		display: flex;
		width: 412.51px;
		max-width: 100%;
		height: 60px;
		margin: 0 auto;
	}

	/* Reserves room at the very bottom of the PDP for this now-taller
	 * (title+price row plus button) bar once it can be visible (mobile
	 * only, same 1023.98px scope) -- without this, the fixed-position
	 * bar could sit directly over the last on-screen content (trust
	 * rows/description/reviews/related products) instead of the page
	 * having scrolled clear of it. JS measures the bar's real height
	 * itself for the IntersectionObserver margin (assets/js/woocommerce.js,
	 * `bar.offsetHeight || 72`), so this only needs to be a generous,
	 * safe estimate, not an exact match. */
	.pb-pdp {
		padding-bottom: calc(8rem + env(safe-area-inset-bottom));
	}
}

/* Exactly one image visible at a time — plain class toggle, no
 * FlexSlider/CSS-timing tricks needed since this markup is entirely
 * ours. Generous padding (Nike/Apple-style breathing room) so the
 * product photo never touches the card's edges. */
.pb-pdp-gallery__image {
	display: none;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	padding: 3rem;
	box-sizing: border-box;
	margin: 0 auto;
}

/* Verified via live computed-style measurement (getBoundingClientRect +
 * getComputedStyle in the browser): .pb-pdp-gallery__main, the first
 * thumbnail, .pb-pdp__summary, and the title all measured at the exact
 * same top offset — the containers were never misaligned. Only this
 * image's own 3rem padding (above) was pushing the visible photo down
 * inside its own correctly-positioned box. A desktop-only override was
 * already added for this once (removing padding-top only, at
 * min-width:1024px) but never actually took effect — it was declared
 * *before* the base rule above, and since both target the exact same
 * selector at equal specificity, the later rule in the file wins
 * regardless of the media query, silently cancelling the override.
 * Placing it after the base rule (still min-width:1024px, still only
 * padding-top, left/right/bottom and mobile untouched) is what actually
 * lets it apply. */
@media (min-width: 1024px) {
	.pb-pdp-gallery__image {
		padding-top: 0;
		/* 2026-08-17 follow-up, explicit request: the cover/crop fix
		 * below left a visible empty gap on the right side of the box —
		 * the base rule's own remaining padding-right/padding-bottom
		 * (3rem each, box-sizing:border-box) carved space out of the
		 * 100% width/height box, and this element's own flex-item
		 * sizing (no explicit flex-basis, inside .pb-pdp-gallery__main's
		 * justify-content:center row) wasn't reliably stretching to
		 * fill the row either. Zeroing all padding + adding flex:1 1
		 * 100%/align-self:stretch removes both causes at once, so the
		 * image genuinely fills the whole capped box edge-to-edge, same
		 * "no padding, fill + crop" approach mobile's own override
		 * already uses further down. */
		padding: 0;
		flex: 1 1 100%;
		align-self: stretch;
		width: 100%;
		height: 100%;
		object-fit: cover;
	}
}

.pb-pdp-gallery__image.is-active {
	display: block;
}

/* Mobile override of the base rule above (width:auto/height:auto,
 * max-width/max-height:100%, padding:3rem) — placed after it on
 * purpose, same lesson as the desktop padding-top override two rules
 * up: an earlier media-query rule targeting the exact same selector at
 * equal specificity gets silently cancelled by this later, unguarded
 * base rule, regardless of the media query. width:100%/max-width:none
 * (rather than leaving max-width:100% from the base rule, which is
 * redundant with width:100% but not actively wrong) makes the "no
 * shrinking" intent explicit; height:100%/max-height:100% fills
 * whichever box .pb-pdp-gallery__main above computes (its own
 * min-height/max-height, or an active photo's own JS-set aspect-ratio
 * within that range) without ever cropping (object-fit:contain) or
 * distorting. padding:0 is the true edge-to-edge mobile frame — the
 * base rule's 3rem is a desktop-only breathing-room choice. */
@media (max-width: 1023.98px) {
	.pb-pdp-gallery__image {
		width: 100%;
		max-width: none;
		height: 100%;
		max-height: 100%;
		padding: 0;
		object-fit: contain;
	}
}

/* Vertical thumbnail rail, far left, on desktop/tablet only (>=1024px
 * two-column hero breakpoint). 2026-07-31: no longer shown on mobile
 * (<1024px) -- replaced there by .pb-pdp-gallery__dots below, same
 * data-pb-pdp-gallery-thumb-driven nav, just a dot instead of an
 * image per item. */
.pb-pdp-gallery__thumbs {
	display: flex;
	gap: 0.6rem;
	margin: 1rem 0 0;
	padding: 0;
	list-style: none;
}

@media (max-width: 1023.98px) {
	.pb-pdp-gallery__thumbs {
		display: none;
	}
}

/* Mobile/tablet pagination dots (2026-07-31) -- see the PHP markup's
 * own doc comment (pb_render_pdp_gallery(), inc/woocommerce-product-page.php)
 * for why these reuse the gallery JS unchanged. Hidden by default
 * (desktop keeps the thumbnail rail above); active/inactive colours
 * only -- no size/shape override needed beyond this rule itself. */
.pb-pdp-gallery__dots {
	display: none;
}

@media (max-width: 1023.98px) {
	.pb-pdp-gallery__dots {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 4px;
		margin: 1rem 0 0;
	}

	/* 2026-07-31: button itself IS the dot now (was a ::before pseudo
	 * inside a larger tap box) -- simpler and more robust than a
	 * pseudo-element nested in a flex item, and matches the requested
	 * tight spacing directly. */
	.pb-pdp-gallery__dot {
		width: 8px;
		height: 8px;
		padding: 0;
		border: none;
		border-radius: 50%;
		background: #d9d9d9;
		cursor: pointer;
	}

	.pb-pdp-gallery__dot.is-active {
		background: #000000;
	}
}

/* Explicit fixed width so .pb-pdp-gallery__thumb's own width:100%
 * (below) has a definite containing block to resolve against. Without
 * it, flex:0 0 auto has no intrinsic size to fall back to, and the
 * button's width:100% + aspect-ratio:1/1 combination made each
 * thumbnail balloon to several hundred pixels tall on narrow mobile
 * viewports (verified: .pb-pdp-gallery__thumbs measured 3000px tall
 * for 4 thumbnails before this fix). Desktop's own media query below
 * re-declares width:100% against its own fixed-width column, so this
 * mobile-only value never affects it. */
.pb-pdp-gallery__thumbs li {
	flex: 0 0 4.5rem;
	width: 4.5rem;
}

/* align-items defaults to "stretch" on a flex row — without setting it
 * explicitly here, .pb-pdp-gallery__thumbs (a flex item in this row)
 * stretched to match .pb-pdp-gallery__main's full height (720px),
 * which is what let the thumbnail *column* visually read as "larger"
 * even though each individual thumbnail button was correctly sized.
 * flex-start keeps both columns sized to their own natural content. */
@media (min-width: 1024px) {
	.pb-pdp-gallery {
		display: flex;
		flex-direction: row;
		align-items: flex-start;
		gap: 0.5rem; /* small white gap between thumbnail column and main image */
	}

	.pb-pdp-gallery__thumbs {
		order: -1;
		flex: 0 0 4.5rem;
		flex-direction: column;
		align-items: flex-start;
		align-self: flex-start;
		margin: 0;
		gap: 0.35rem;
	}

	.pb-pdp-gallery__thumbs li {
		flex: 0 0 auto;
		width: 100%;
	}

	.pb-pdp-gallery__main {
		flex: 1 1 auto;
		min-width: 0;
		align-self: stretch;
		margin-left: 0;
	}
}

.pb-pdp-gallery__thumb {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	padding: 0;
	border: none;
	background: var(--wc-surface);
	border-radius: var(--wc-radius-input);
	cursor: pointer;
	overflow: hidden;
	opacity: 0.6;
	transition: opacity 0.2s ease;
}

.pb-pdp-gallery__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	pointer-events: none;
}

.pb-pdp-gallery__thumb.is-active,
.pb-pdp-gallery__thumb:hover {
	opacity: 1;
}

/* Video thumbnail — see pb_wc_render_pdp_gallery_thumb_media()
 * (inc/woocommerce-product-page.php). The <video> itself is the
 * preview (shows its first frame via preload="metadata", no poster
 * image needed), sized identically to .pb-pdp-gallery__thumb img
 * above; the play icon is a plain centered overlay. Kept as a real
 * <video> element (not a static generated poster) specifically so a
 * future hover-preview feature only needs to add play()/pause() calls
 * on hover, no markup changes. */
.pb-pdp-gallery__thumb-video-wrap {
	position: relative;
	display: block;
	width: 100%;
	height: 100%;
}

.pb-pdp-gallery__thumb-video {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	pointer-events: none;
}

.pb-pdp-gallery__thumb-play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	color: #ffffff;
	font-size: 1.25rem;
	text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.pb-pdp-gallery__thumb {
		transition: none;
	}
}

/* Prev/next arrows — one small paired control inside the card's
 * bottom-right corner (needs .pb-pdp-gallery__main to be the
 * positioned ancestor, set above), rather than floating across the
 * full image edges. */
.pb-pdp-gallery__arrows {
	position: absolute;
	z-index: 2;
	right: 1rem;
	bottom: 1rem;
	display: flex;
	gap: 0.5rem;
}

/* 2026-07-31: hidden on mobile/tablet -- redundant next to the dots
 * below the image (same nav, two controls). Swipe (assets/js/woocommerce.js's
 * own touch handling, not these buttons) and the lightbox are
 * untouched -- this only hides the arrow buttons themselves. */
@media (max-width: 1023.98px) {
	.pb-pdp-gallery__arrows {
		display: none;
	}
}

.pb-pdp-gallery__arrow {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: var(--wc-background);
	box-shadow: var(--wc-shadow-card);
	color: var(--wc-secondary);
	cursor: pointer;
	opacity: 0.9;
}

.pb-pdp-gallery__arrow:hover {
	opacity: 1;
}

.pb-pdp-gallery__arrow::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 0.5rem;
	height: 0.5rem;
	margin-top: -0.3rem;
	border: solid currentColor;
	border-width: 0 2px 2px 0;
}

.pb-pdp-gallery__arrow--prev::before {
	margin-left: -0.15rem;
	transform: rotate(135deg);
}

.pb-pdp-gallery__arrow--next::before {
	margin-left: -0.35rem;
	transform: rotate(-45deg);
}

/* ---- Summary (PLNKTON-style purchase panel) ---- */
/* Fixed 30px/Poppins per explicit request (2026-07-08) — replaces the
 * older clamp(2rem,...,3rem)/Cardo sizing. Font-family now points at
 * the theme-heading token (PB Design -> Typography -> H1-H6, now
 * Poppins by default, 2026-07-10) instead of a hardcoded literal, so
 * this inherits the PB Design hierarchy like every other heading
 * instead of being stuck on Poppins if that's ever changed. Size/
 * weight/line-height/margin are unchanged. */
.pb-pdp__summary .product_title {
	/* !important is load-bearing here, not stylistic: design-system.css
	 * has a sitewide `h1 { font-size: …!important; }` rule (real <h1>,
	 * this element carries product_title AND entry-title), and a plain
	 * declaration can never win against !important regardless of
	 * selector specificity — every earlier size change on this rule
	 * (30/22/16/14px) was silently losing to that global rule and never
	 * actually rendered. font-family/weight/line-height are deliberately
	 * left as-is (still governed by that same h1 rule) — only font-size
	 * is being forced here, per "preserve existing family/weight/line-height". */
	font-size: 17px !important;
	font-family: var( --wp--preset--font-family--theme-heading, "Poppins", sans-serif );
	font-weight: 700;
	line-height: 1.25;
	margin: 0 0 1.25rem;
}


/* Material Symbols Rounded font (enqueued only on the product page —
 * see pb_wc_pdp_enqueue_material_icons()). Still used by the
 * Productinformatie/Beoordelingen accordion expand/collapse icons
 * (.pb-pdp__attributes-icon) — Google's own recommended baseline
 * rules for the icon font. */
.material-symbols-rounded {
	font-family: 'Material Symbols Rounded';
	font-weight: normal;
	font-style: normal;
	display: inline-block;
	line-height: 1;
	white-space: nowrap;
	direction: ltr;
	-webkit-font-smoothing: antialiased;
}

.pb-pdp__summary p.price,
.pb-pdp__summary span.price {
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--wc-heading);
	margin-bottom: 1.5rem;
	display: block;
}

.pb-pdp__summary p.price del {
	color: var(--wc-muted-text);
	font-size: 1rem;
	opacity: 0.7;
}

.pb-pdp__summary p.stock {
	font-size: var(--wc-font-body-sm);
	font-weight: 600;
	color: var(--wc-success);
	margin-bottom: 2rem;
}

.pb-pdp__summary p.stock.out-of-stock {
	color: var(--wc-error);
}

/* "Bullet benefits" — only ever appears if the product's own short
 * description content contains a list; WooCommerce's short-description
 * template (woocommerce_template_single_excerpt()) prints whatever the
 * editor entered as-is, so this purely restyles a <ul> if one exists —
 * nothing is added or assumed when there isn't one. */
.pb-pdp__summary .woocommerce-product-details__short-description {
	font-size: 14px;
	color: var(--wc-secondary);
	margin-bottom: 2rem;
}

.pb-pdp__summary .woocommerce-product-details__short-description ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.pb-pdp__summary .woocommerce-product-details__short-description ul li {
	position: relative;
	padding-left: 1.5rem;
	margin-bottom: 0.65rem;
}

.pb-pdp__summary .woocommerce-product-details__short-description ul li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.5em;
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 999px;
	background: var(--wc-primary);
}

/* "Bekijk alle reviews" link — see pb_wc_render_pdp_reviews_link()
 * (inc/woocommerce-product-page.php) and its click handler in
 * assets/js/woocommerce.js. */
.pb-pdp__reviews-link {
	display: inline-block;
	margin: 0;
	font-size: var(--wc-font-body-sm);
	font-weight: 600;
	color: var(--wc-secondary);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.pb-pdp__reviews-link:hover {
	color: var(--wc-primary);
}

/* Bundle/quantity-discount card selector — see
 * pb_wc_render_pdp_bundle_selector() (inc/woocommerce-product-page.php)
 * for why this is placeholder-data presentation only. Existing tokens
 * only: --wc-primary (purple), --wc-radius-card, --wc-border, --wc-shadow-card. */
.pb-pdp-bundle {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	margin: 20px 0 2rem;
}

.pb-pdp-bundle__option {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.85rem;
	padding: 1.1rem 1.25rem;
	border: 1.5px solid var(--wc-border);
	border-radius: var(--wc-radius-card);
	cursor: pointer;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* 2026-07-31: featured-option emphasis (the one with a "Meest
 * gekozen"-style badge — see pb_wc_render_pdp_bundle_selector(),
 * .pb-pdp-bundle__badge only renders when $option['badge'] is set) is
 * now purely presentational, independent of which option is actually
 * selected/checked below -- the purple border + shadow always follows
 * the badge, not the selection. The other option(s) keep the default
 * border from the base rule above, regardless of selected state. */
.pb-pdp-bundle__option:has( .pb-pdp-bundle__badge ) {
	border-color: var(--wc-primary);
	box-shadow: var(--wc-shadow-card);
}

.pb-pdp-bundle__option:has( .pb-pdp-bundle__badge ):hover {
	border-color: #7e6fef;
}

.pb-pdp-bundle__option input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.pb-pdp-bundle__radio {
	flex: 0 0 auto;
	width: 1.15rem;
	height: 1.15rem;
	border-radius: 999px;
	border: 1.5px solid var(--wc-border);
}

.pb-pdp-bundle__option.is-selected .pb-pdp-bundle__radio,
.pb-pdp-bundle__option:has( input:checked ) .pb-pdp-bundle__radio {
	border-color: var(--wc-primary);
	border-width: 0.35rem;
}

.pb-pdp-bundle__body {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.pb-pdp-bundle__title {
	font-weight: 700;
	color: var(--wc-secondary);
}

.pb-pdp-bundle__benefit {
	font-size: var(--wc-font-body-sm);
	color: var(--wc-success);
	font-weight: 600;
}

.pb-pdp-bundle__price {
	flex: 0 0 auto;
	font-weight: 700;
	color: var(--wc-secondary);
	text-align: right;
	white-space: nowrap;
}

.pb-pdp-bundle__price del {
	display: block;
	font-weight: 400;
	color: var(--wc-muted-text);
	font-size: var(--wc-font-body-sm);
	opacity: 0.8;
}

.pb-pdp-bundle__badge {
	position: absolute;
	top: -0.65rem;
	right: 1.25rem;
	padding: 0.2rem 0.75rem;
	border-radius: 999px;
	background: #6848f4;
	color: #fff;
	font-size: var(--wc-font-label);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.pb-pdp-bundle__option:hover .pb-pdp-bundle__badge {
	background: #7e6fef;
}

/* Single horizontal purchase row (2026-07-17): [ - ][ qty ][ + ] then
 * single_add_to_cart_button, one row, full width on every breakpoint.
 * "Buy now" removed (pb_wc_render_buy_now_button() unhooked, see
 * inc/woocommerce-mini-cart.php) — single_add_to_cart_button is the
 * only action now. Native quantity input untouched (no template
 * override); the -/+ steppers are injected around it by JS (see
 * assets/js/woocommerce.js) purely as UI, no custom cart logic. */
.pb-pdp__summary form.cart {
	display: flex;
	align-items: stretch;
	gap: 0.75rem;
	margin-bottom: 2.5rem;
}

.pb-pdp__summary form.cart .quantity {
	display: flex;
	align-items: stretch;
	flex: 0 0 auto;
	margin: 0;
	border: 1.5px solid var(--wc-border);
	border-radius: var(--wc-radius-input);
	overflow: hidden;
}

.pb-pdp__summary form.cart .quantity .qty {
	width: 3rem;
	border: 0;
	border-radius: 0;
	padding: 0.75rem 0.25rem;
	text-align: center;
	-moz-appearance: textfield;
}

.pb-pdp__summary form.cart .quantity .qty::-webkit-outer-spin-button,
.pb-pdp__summary form.cart .quantity .qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.pb-pdp-qty__btn {
	flex: 0 0 auto;
	width: 2.75rem;
	border: 0;
	background: transparent;
	color: var(--wc-secondary);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
}

.pb-pdp-qty__btn:hover,
.pb-pdp-qty__btn:focus-visible {
	background: var(--wc-border);
}

/* Same look as .pb-newsletter__cta--header ("Bestel nu") — background, radius,
 * typography and hover state copied as-is from assets/css/main.css so
 * both buttons match exactly. */
/* 2026-07-31: radius/padding match the quantity selector's own shape
 * -- var(--wc-radius-input), the exact same token .quantity already
 * uses (no new value invented) -- on every breakpoint (was mobile-
 * only at first, extended to desktop/tablet per follow-up request).
 * Height/vertical centering already come from align-items:stretch on
 * .pb-pdp__summary form.cart (shared) + this button's own
 * align-items:center. Background/text colour, hover state,
 * add-to-cart JS and loading/disabled states are all untouched. */
.pb-pdp__summary form.cart button.single_add_to_cart_button {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: var(--wc-radius-input);
	padding: 0 1.5rem;
	background: var(--pb-header-cta-background, #6848f4);
	color: #ffffff;
	font-size: 0.8rem;
	font-weight: 700;
	text-transform: var(--wp--custom--typography--button--transform, none);
	letter-spacing: 0.06em;
	white-space: nowrap;
	transition: background-color 0.2s ease, transform 0.2s ease;
}

.pb-pdp__summary form.cart button.single_add_to_cart_button:hover,
.pb-pdp__summary form.cart button.single_add_to_cart_button:focus-visible {
	background: #7e6fef;
	transform: translateY(-1px);
	outline: none;
}

/* Mobile only (2026-08-04): the button has no height of its own above —
 * it passively stretches to match its sibling .quantity's height via
 * .pb-pdp__summary form.cart's align-items:stretch, which currently
 * computes to ~38.69px. An explicit height here overrides *just this
 * flex item's* stretch sizing, without touching align-items on the
 * shared row or .quantity's own (unrelated, untouched) sizing — label
 * stays centered via the existing align-items/justify-content:center
 * above, no extra centering rule needed. Width/radius/typography/
 * colors/horizontal padding are all still the unmodified rules above;
 * only this one property is added. Desktop (>=1024px) keeps today's
 * stretch-derived height unchanged. */
@media (max-width: 1023.98px) {
	.pb-pdp__summary form.cart button.single_add_to_cart_button {
		height: 40px;
	}
}

/* Variable products (e.g. "Shirts"): WooCommerce nests quantity + button
 * one level deeper (.single_variation_wrap > .woocommerce-variation-
 * add-to-cart), so the shared form.cart flex row above doesn't reach
 * them. Same row, same gap, applied to that wrapper instead — the
 * quantity/button rules above already match by descendant selector. */
.pb-pdp__summary form.variations_form {
	display: block;
}

.pb-pdp__summary form.variations_form .woocommerce-variation-add-to-cart {
	display: flex;
	align-items: stretch;
	gap: 0.75rem;
}

/* Until a variation is chosen WooCommerce marks the button .disabled
 * and its own CSS (.woocommerce button.button.alt.disabled /
 * :disabled[disabled]) repaints it in WC purple at 50% opacity — keep
 * the same PaperBrain CTA colour as on simple products instead.
 * Clicking it still shows WooCommerce's own "kies eerst een optie". */
.woocommerce .pb-pdp__summary form.cart button.single_add_to_cart_button.disabled,
.woocommerce .pb-pdp__summary form.cart button.single_add_to_cart_button:disabled[disabled] {
	background: var(--pb-header-cta-background, #6848f4);
	color: #ffffff;
	opacity: 1;
}

/* Trust/USP rows — see pb_wc_render_pdp_trust_rows() (inc/woocommerce-product-page.php). Styled as quiet, evenly-spaced benefit rows (small check mark + label) rather than a generic bulleted list, with a soft top divider separating them from the buttons above. */
.pb-wc-trust-rows {
	display: flex;
	flex-direction: column;
	gap: 0.65rem;
	margin: 0.5rem 0 1.5rem;
	padding: 1.25rem 0 0;
	border-top: 1px solid var(--wc-border);
	list-style: none;
	font-size: var(--wc-font-body-sm);
	color: var(--wc-secondary);
}

.pb-wc-trust-rows li {
	position: relative;
	padding-left: 1.75rem;
}

.pb-wc-trust-rows li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.15em;
	width: 0.9rem;
	height: 0.55rem;
	border-left: 2px solid var(--pb-usp-icon-color, var(--wc-success));
	border-bottom: 2px solid var(--pb-usp-icon-color, var(--wc-success));
	transform: rotate(-45deg);
}

/* A product-specific USP row can set its own Material Symbols icon
 * (Product data -> PDP tab) instead of the default checkmark above. */
.pb-wc-trust-rows li.pb-wc-trust-rows__item--icon::before {
	content: none;
}

.pb-wc-trust-rows__icon {
	position: absolute;
	left: 0;
	top: -0.1em;
	width: 1.5rem;
	overflow: hidden;
	white-space: nowrap;
	font-size: 1.1rem;
	line-height: 1;
	color: var(--pb-usp-icon-color, var(--wc-success));
}

/* 2026-08-17, explicit request: USP checkmarks black instead of green
 * on this one product (paperbrain-gift, post 238) only — sets the same
 * --pb-usp-icon-color custom property both rules above already read,
 * scoped to this product's page so every other product's USP list
 * (default green) is unaffected. Text/spacing/other styling untouched. */
body.postid-238 {
	--pb-usp-icon-color: #000000;
}

/* Product meta (SKU/categories/tags): deliberately the quietest thing
 * in the panel — smallest token size, no top border/divider weight,
 * so it reads as fine print rather than another content block. */
.pb-pdp__summary .product_meta {
	font-size: var(--wc-font-label);
	color: var(--wc-muted-text);
	margin-top: 2rem;
	opacity: 0.85;
}

.pb-pdp__summary .product_meta a {
	color: var(--wc-muted-text);
}

/* Mobile-only: tighten the individual margins each of the rules above
 * (used identically on desktop) carries — sized generously for the
 * wider two-column desktop layout, they compound with .pb-pdp__hero's
 * own gap (already reduced) between every promoted flex item on the
 * single-column mobile stack, producing large gaps between title/
 * category/price/Trustpilot, between Trustpilot and the gallery,
 * between the gallery and thumbnails, and between thumbnails and trust
 * benefits. p.price/p.stock also get an explicit margin-top:0 here —
 * neither rule above resets it, so both were inheriting the browser's
 * default <p> top margin (1em of their own, different, font-sizes).
 * Placed after every rule it overrides, for the same source-order
 * reason noted throughout this file. Desktop is completely unaffected. */
@media (max-width: 1023.98px) {
	.pb-pdp__summary .product_title {
		margin-bottom: 0.25rem;
	}

	.pb-pdp__summary .product_meta {
		margin-top: 0;
	}

	.pb-pdp__summary p.price,
	.pb-pdp__summary span.price {
		margin-top: 0;
		margin-bottom: 0.25rem;
	}

	.pb-pdp__summary p.stock {
		margin-top: 0;
		margin-bottom: 0.5rem;
	}

	.pb-pdp-gallery__thumbs {
		margin-top: 0.5rem;
	}

	.pb-wc-trust-rows {
		margin-top: 0.25rem;
		margin-bottom: 1.5rem;
		padding-top: 0.75rem;
	}
}

/* Mobile-only title size — the base rule below (30px, still what
 * desktop/tablet get) is otherwise untouched; only font-size changes
 * here, so family/weight/line-height/margin all stay exactly as
 * already set. 767px (not the 1023.98px tablet+mobile breakpoint used
 * above) so tablet renders identically to desktop, per this request. */
@media (max-width: 767px) {
	.pb-pdp__summary .product_title.entry-title {
		/* !important needed for the same reason as the base rule above
		 * (design-system.css's sitewide `h1 {…!important}` rule).
		 * 2026-07-31: smaller still, to comfortably share one line with
		 * the price; family/weight/line-height untouched. */
		font-size: 17px !important;
	}

	/* .pb-pdp__summary is display:contents on mobile (see the
	 * flex-order block above), so .product_meta is a direct flex item
	 * of .pb-pdp__hero — display:none removes it from that flex layout
	 * entirely, no leftover gap from .pb-pdp__hero's own `gap`. */
	.pb-pdp__summary .product_meta {
		display: none;
	}

	/* .price bdi wraps the currency symbol + amount specifically (not
	 * the del/ins sale-price wrapper) — .price/span.price's own
	 * font-size (base rule above) sets the line's overall size, but
	 * <bdi> inherits from it rather than being independently sized, so
	 * it needs its own rule to differ. Sale del/ins both contain their
	 * own nested bdi, so this applies equally to either and keeps them
	 * aligned. font-family/weight/line-height/color are untouched —
	 * still inherited from .price as before. */
	.pb-pdp__summary .price bdi {
		/* 2026-07-31: smaller still, to comfortably share one line with
		 * the title; family/weight/color untouched (still inherited
		 * from .price). */
		font-size: 15px;
	}
}

/* Product attributes table — moved here from the "Aanvullende
 * informatie" tab (see pb_wc_render_pdp_attributes(),
 * inc/woocommerce-product-page.php). Overrides WooCommerce core's own
 * table.shop_attributes styling (dotted borders, 150px label column,
 * zebra striping) with a compact, quiet definition-list look matching
 * .product_meta above — not a heavy/full table. */
.pb-pdp__attributes {
	margin-top: 1.5rem;
}

/* "Productinformatie" accordion header — collapsed by default (see
 * pb_wc_render_pdp_attributes()); JS (assets/js/woocommerce.js) toggles
 * [hidden] + .is-open on the panel and aria-expanded here. */
.pb-pdp__attributes-heading {
	margin: 0;
}

.pb-pdp__attributes-toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	width: 100%;
	padding: 0.85rem 0;
	background: none;
	border: 0;
	border-top: 1px solid var(--wc-border);
	font-family: inherit;
	font-size: var(--wc-font-label);
	font-weight: 600;
	color: var(--wc-heading);
	text-align: left;
	cursor: pointer;
}

.pb-pdp__attributes-icon {
	font-size: 1.25rem;
	color: var(--wc-muted-text);
	transition: transform 0.2s ease;
}

.pb-pdp__attributes-toggle[aria-expanded="true"] .pb-pdp__attributes-icon {
	transform: rotate(180deg);
}

.pb-pdp__attributes-panel {
	max-height: 0;
	overflow: hidden;
	transition: max-height 0.3s ease;
}

.pb-pdp__attributes-panel.is-open {
	max-height: 2000px;
}

.pb-pdp__attributes-panel-inner {
	padding-top: 0.25rem;
	padding-bottom: 0.75rem;
}

.pb-pdp__attributes table.shop_attributes {
	border: 0;
	width: 100%;
	margin: 0;
	border-collapse: collapse;
	font-size: var(--wc-font-label);
}

.pb-pdp__attributes table.shop_attributes tr {
	border-bottom: 1px solid var(--wc-border);
}

.pb-pdp__attributes table.shop_attributes tr:last-child {
	border-bottom: none;
}

.pb-pdp__attributes table.shop_attributes tr:nth-child(even) td,
.pb-pdp__attributes table.shop_attributes tr:nth-child(even) th {
	background: none;
}

.pb-pdp__attributes table.shop_attributes th,
.pb-pdp__attributes table.shop_attributes td {
	padding: 0.55rem 0;
	border: 0;
	font-style: normal;
	font-weight: 400;
	line-height: 1.5;
	vertical-align: top;
}

.pb-pdp__attributes table.shop_attributes th {
	width: 40%;
	color: var(--wc-muted-text);
	font-weight: 500;
}

.pb-pdp__attributes table.shop_attributes td {
	color: var(--wc-secondary);
}

.pb-pdp__attributes table.shop_attributes td p {
	margin: 0;
	padding: 0;
}

/* ---- Details: tabs / reviews / related products, full-width below the hero (a real separate section — nothing can fall into the gallery column) ---- */
.pb-pdp__details {
	margin-top: calc(var(--wc-section-spacing) * 1.4);
	padding-top: calc(var(--wc-section-spacing) * 0.6);
	border-top: 1px solid var(--wc-border);
}

/* 2026-07-31, mobile only: this border-top is the "divider" directly
 * below the Productinformatie accordion (the last thing in
 * .pb-pdp__summary on mobile's single-column stack -- see the mobile
 * reorder block earlier in this file). The margin-top above is sized
 * for the much bigger "end of hero section" transition (was tuned
 * against the two-column desktop layout, and still applies there
 * unchanged); on mobile's narrow single column that same gap reads as
 * an oversized space between the accordion row and its own divider.
 * Only margin-top changes -- padding-top (space *below* the divider,
 * before tabs/description/related products) and the border itself are
 * untouched. */
@media (max-width: 1023.98px) {
	.pb-pdp__details {
		margin-top: 16px;
	}
}

.pb-pdp__details .woocommerce-tabs ul.tabs {
	display: flex;
	gap: 1.5rem;
	border-bottom: 1px solid var(--wc-border);
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
}

.pb-pdp__details .woocommerce-tabs ul.tabs li {
	margin: 0;
	padding: 0 0 0.85rem;
	border: none;
	background: none;
	font-weight: 700;
	font-size: var(--wc-font-body-sm);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--wc-muted-text);
}

.pb-pdp__details .woocommerce-tabs ul.tabs li::before,
.pb-pdp__details .woocommerce-tabs ul.tabs li::after {
	display: none;
}

.pb-pdp__details .woocommerce-tabs ul.tabs li a {
	color: inherit;
}

.pb-pdp__details .woocommerce-tabs ul.tabs li.active {
	border-bottom: 2px solid var(--wc-secondary);
	color: var(--wc-secondary);
}

.pb-pdp__details .woocommerce-tabs .panel {
	max-width: 42rem;
	font-size: var(--wc-font-body);
	line-height: 1.75;
	color: var(--wc-secondary);
}

/* ---- Product description ("Productbeschrijving") — the product's own
 * long description (post_content, see pb_wc_render_pdp_description()),
 * styled as a quiet, premium card: light surface background, large
 * rounded corners, generous padding, comfortable reading width. Sits
 * between the (no-op) tabs call and "PDP Extra Content" (a separate
 * linked Page, .pb-pdp__content below) inside .pb-pdp__details — only
 * .pb-pdp-description__content's own typography is scoped here, never
 * a bare .entry-content selector, so this can never leak into that
 * other, differently-sourced section which also carries that class. */
.pb-pdp-description {
	/* Smaller than --wc-section-spacing on purpose (that shared token
	 * is used sitewide) — this section's own, tighter top gap. */
	margin-top: 1.5rem;
}

.pb-pdp-description__card {
	/* All values devtools-measured directly off Elvou's own
	 * ".max-w-6xl.mx-auto.bg-accent-light.rounded-xl.py-12.lg:py-16.px-6.lg:px-16"
	 * description card (1440px viewport → card 1152px wide/centered,
	 * padding 64px all sides; 768px viewport → padding drops to 24px
	 * horizontal/48px vertical, card just fills its column). No inner
	 * max-width beyond the padding — Elvou's own text (.prose.max-w-none)
	 * fills the padded box exactly, it isn't narrower still. */
	max-width: var(--wc-content-card-width);
	margin-left: auto;
	margin-right: auto;
	background: var(--wc-surface);
	/* 12px — Elvou's card uses Tailwind's "rounded-xl" (0.75rem), not
	 * this theme's own larger card-radius token. */
	border-radius: 0.75rem;
	padding-block: 2rem;
	padding-inline: 1.5rem;
}

@media (min-width: 1024px) {
	.pb-pdp-description__card {
		padding-block: 2.5rem;
		padding-inline: 4rem;
	}
}

.pb-pdp-description__label {
	display: block;
	font-size: var(--wc-font-label);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wc-muted-text);
	margin-bottom: 1.5rem;
}

.pb-pdp-description__content {
	/* No max-width here on purpose — fills the card's own padded width
	 * exactly, matching Elvou's ".prose.max-w-none" (devtools-verified:
	 * its text column is exactly card-width minus the card's own
	 * padding, not a separate, narrower measure). */
	font-size: 14px;
	line-height: 1.75;
	text-align: left;
	color: var(--wc-secondary);
}

.pb-pdp-description__content > * + * {
	margin-top: 1.25rem;
}

.pb-pdp-description__content h2 {
	font-size: 14px;
	line-height: 1.3;
	color: var(--wc-heading);
	margin: 2rem 0 0.75rem;
}

.pb-pdp-description__content h3 {
	font-size: 14px;
	line-height: 1.4;
	color: var(--wc-heading);
	margin: 1.75rem 0 0.6rem;
}

.pb-pdp-description__content h2:first-child,
.pb-pdp-description__content h3:first-child {
	margin-top: 0;
}

.pb-pdp-description__content ul,
.pb-pdp-description__content ol {
	margin: 0;
	padding-left: 1.3rem;
}

.pb-pdp-description__content ul {
	list-style: disc;
}

.pb-pdp-description__content ol {
	list-style: decimal;
}

.pb-pdp-description__content li + li {
	margin-top: 0.5rem;
}

.pb-pdp-description__content a {
	color: var(--wc-primary);
	text-decoration: underline;
}

/* "vier fundamentele pijlers" only — targeted by its own href so no
 * other link in the description (or elsewhere) is affected; underline
 * is untouched (still inherited from the rule above). */
.pb-pdp-description__content a[href="https://paperbrain.store/fundament/"],
.pb-pdp-description__content a[href="https://paperbrain.store/fundament/"]:hover,
.pb-pdp-description__content a[href="https://paperbrain.store/fundament/"]:focus,
.pb-pdp-description__content a[href="https://paperbrain.store/fundament/"]:visited {
	color: #000000;
}

.pb-pdp-description__content img {
	display: block;
	max-width: 100%;
	height: auto;
	border-radius: var(--wc-radius-input);
}

/* "PDP content page" (pb_wc_render_pdp_content(), real Gutenberg blocks
 * from a separately linked Page) — same shared --wc-content-narrow
 * column as the description card above it, so the two line up. Real
 * Gutenberg blocks in there can carry core's own alignwide/alignfull
 * classes, which would otherwise stretch to the section's full width
 * (up to 1344px+) — both are capped back to the same centered column. */
.pb-pdp__content {
	max-width: var(--wc-content-narrow);
	margin-left: auto;
	margin-right: auto;
	/* 32px — devtools-measured gap on Elvou between the description
	 * card and this same section (its own ".max-w-4xl.mt-8"). */
	margin-top: 2rem;
	font-size: 14px;
}

.pb-pdp__content h1,
.pb-pdp__content h2,
.pb-pdp__content h3,
.pb-pdp__content h4,
.pb-pdp__content h5,
.pb-pdp__content h6,
.pb-pdp__content p,
.pb-pdp__content li {
	font-size: 14px;
}

.pb-pdp__content .alignwide,
.pb-pdp__content .alignfull {
	max-width: var(--wc-content-narrow);
	width: 100%;
	margin-left: auto;
	margin-right: auto;
	left: auto;
}

/* pb/faq must be a truly shared component — render identically on
 * every page, this PDP content column included. Exempted from both
 * overrides above: the width cap (its own .faq/.faq__inner/
 * .faq.alignfull rules in main.css already give it the correct full-
 * bleed width + centered content column everywhere else) and the
 * generic h1-h6/p/li font-size:14px reset (would otherwise shrink its
 * answer text below the .pb-type--body size every other page uses --
 * font-size:inherit here just lets it fall through to that ancestor's
 * own value, same as everywhere else). */
.pb-pdp__content .faq.alignfull {
	max-width: 100vw;
	width: 100vw;
	left: 50%;
	margin-left: -50vw;
}

.pb-pdp__content .faq p,
.pb-pdp__content .faq li {
	font-size: inherit;
}

/* ==========================================================================
 * "Past goed bij" — PDP upsell/cross-sell slider (Elvou card layout,
 * PaperBrain light cart/checkout palette — 2026-07-08 restyle, replaces
 * the earlier dark-section version). Markup:
 * pb_wc_render_pdp_upsell_slider() (inc/woocommerce-product-page.php),
 * called from woocommerce/content-single-product.php directly after
 * the summary column (real document position, not a CSS reorder) —
 * always after price/variations/add-to-cart/Productinformatie/
 * Beoordelingen, before the rest of .pb-pdp__details. var(--wc-surface)
 * (#f7f7f7, ~#F6F6F4) is the same light-grey token already used by
 * every cart/checkout card on the site (mini-cart items, bundle
 * selector, description card) — no new one-off grey introduced.
 * Card size (454.5 × 110) and the nav-arrow size (24px) are exact
 * devtools measurements taken directly off the live Elvou reference
 * (elvou.com/products/grasgevoerde-whey) — not eyeballed.
 * ========================================================================*/
.pb-pdp-upsell {
	max-width: var(--wc-container-width);
	margin: var(--wc-section-spacing) auto 0;
	padding: 0 1.25rem;
}

/* __spacer is a leftover empty/aria-hidden node from an earlier
 * "mirror the 55/45 hero split" layout — permanently hidden (CSS-only
 * fix, markup unchanged) because that made __inner only 592px wide,
 * not enough room for 2 fixed 454.5px cards + gap (needs ~1013px).
 * __inner instead gets its own content-hugging max-width (exactly 2
 * cards + gap + padding, not the full 1600px page container) and, on
 * desktop, right-aligns via margin-left:auto so it still sits under
 * the buy-box/Beoordelingen side rather than spanning edge-to-edge or
 * centering under the whole hero. */
.pb-pdp-upsell__row {
	display: block;
}

.pb-pdp-upsell__spacer {
	display: none;
}

.pb-pdp-upsell__inner {
	background: var(--wc-surface);
	border-radius: 28px;
	padding: 40px 48px;
}

@media (min-width: 1024px) {
	.pb-pdp-upsell__inner {
		/* 2 × 454.5px card + 24px gap + 2 × 48px padding = 1029px. */
		max-width: 1029px;
		margin-left: auto;
	}
}

.pb-pdp-upsell__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 1.5rem;
}

.pb-pdp-upsell__title {
	font-size: var(--wc-font-heading-md);
	font-weight: 600;
	margin: 0;
	color: var(--wc-heading);
}

.pb-pdp-upsell__nav {
	display: flex;
	gap: 0.5rem;
	flex: 0 0 auto;
}

.pb-pdp-upsell__nav-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 999px;
	border: 1px solid var(--wc-border);
	background: #ffffff;
	color: var(--wc-secondary);
	cursor: pointer;
	padding: 0;
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

.pb-pdp-upsell__nav-btn:hover,
.pb-pdp-upsell__nav-btn:focus-visible {
	background: var(--wc-background);
	border-color: var(--wc-secondary);
	outline: none;
}

.pb-pdp-upsell__nav-btn svg {
	width: 1.3rem;
	height: 1.3rem;
}

.pb-pdp-upsell__track {
	display: flex;
	gap: 24px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.pb-pdp-upsell__track::-webkit-scrollbar {
	display: none;
}

.pb-pdp-upsell__card {
	scroll-snap-align: start;
	/* ~50% of the track each, clamped between 430px (the "never
	 * smaller than" floor) and 454.5px (the Elvou reference width) —
	 * at the __inner max-width set above this resolves to exactly
	 * 454.5px; on any narrower viewport where 2 × 430px + gap doesn't
	 * fit, the card holds its 430px floor instead of shrinking further
	 * and the track (already scroll-snap + nav-arrow driven) scrolls
	 * to reach the second card, rather than squeezing both to fit. */
	flex: 0 1 calc(50% - 12px);
	min-width: 430px;
	max-width: 454.5px;
	display: flex;
	align-items: center;
	gap: 1.5rem;
	padding: 21px 24px;
	border: 1px solid #e5e2dd;
	border-radius: 16px;
	background: #ffffff;
	box-sizing: border-box;
}

.pb-pdp-upsell__media {
	flex: 0 0 auto;
	display: block;
	width: 68px;
	height: 68px;
	border-radius: var(--wc-radius-input);
	overflow: hidden;
	background: var(--wc-surface);
}

.pb-pdp-upsell__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.pb-pdp-upsell__body {
	flex: 1 1 auto;
	min-width: 0;
}

/* .pb-pdp prefix (not just .pb-pdp-upsell__name alone) is load-bearing,
 * not stylistic: `.woocommerce a { color: var(--wc-primary); }` has
 * higher specificity (one class + one element) than a single-class
 * selector — same "extra scope beats .woocommerce a" pattern used
 * throughout this file (see .pb-mini-cart-upsell__add's own comment). */
/* font-family/weight pulled from the same custom properties
 * .pb-type--h3 (design-system.css) resolves against — the card name
 * was previously rendering in the browser's system-ui fallback (not
 * the theme heading font), which at weight 600 reads visually heavier
 * than the theme's actual H3 (Poppins, 800). Matching the real H3
 * tokens fixes both the font and the "too-Black" look in one move. */
.pb-pdp .pb-pdp-upsell__name {
	display: block;
	font-family: var(--wp--custom--typography--h-3--font, var(--wp--preset--font-family--theme-heading));
	font-size: var(--wc-font-body);
	font-weight: var(--wp--custom--typography--h-3--weight, 800);
	color: var(--wc-heading);
	text-decoration: none;
	margin-bottom: 0.35rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.pb-pdp-upsell__name:hover {
	text-decoration: underline;
}

.pb-pdp-upsell__meta {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	flex-wrap: wrap;
}

.pb-pdp-upsell__price {
	font-size: var(--wc-font-body-sm);
	color: var(--wc-muted-text);
}

.pb-pdp-upsell__price del {
	color: var(--wc-muted-text);
	opacity: 0.6;
	margin-right: 0.35rem;
}

.pb-pdp-upsell__variation {
	font-size: var(--wc-font-body-sm);
	padding: 0.3rem 0.6rem;
	border-radius: var(--wc-radius-input);
	border: 1px solid var(--wc-border);
	background: var(--wc-surface);
	color: var(--wc-heading);
}

/* Deliberately its own small, self-contained button style, not a
 * .pb-button--* CTA token — same "not the shared CTA library" choice
 * .pb-mini-cart-upsell__add already makes. .pb-pdp prefix needed for
 * the same `.woocommerce a` specificity reason as .pb-pdp-upsell__name
 * above. */
.pb-pdp .pb-pdp-upsell__add {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border-radius: 999px;
	background: var(--wc-secondary);
	color: #ffffff;
	transition: transform 0.2s ease, filter 0.2s ease;
}

.pb-pdp-upsell__add:hover,
.pb-pdp-upsell__add:focus-visible {
	transform: scale(1.06);
	filter: brightness(1.2);
	outline: none;
}

.pb-pdp-upsell__add svg {
	width: 1.4rem;
	height: 1.4rem;
}

@media (max-width: 640px) {
	.pb-pdp-upsell__inner {
		border-radius: 24px;
		padding: 24px;
	}

	.pb-pdp-upsell__card {
		flex-basis: 100%;
		min-width: 0;
		max-width: 100%;
		padding: 18px 20px;
	}
}

/* Related products — reuses the shop-loop card styling automatically (same ul.products/li.product classes). */
.pb-pdp__details .related.products {
	margin-top: var(--wc-section-spacing);
}

.pb-pdp__details .related.products > h2 {
	/* visibility (not display:none) so its box/margin stays — keeps the
	 * products grid below at the exact same position/spacing, only the
	 * heading text itself disappears. */
	visibility: hidden;
	font-size: var(--wc-font-heading-lg);
	margin: 0 0 1.5rem;
}

.pb-pdp__details .related.products ul.products {
	padding: 0;
}

/* Upsells — now rendered inside .pb-pdp__summary (see
 * woocommerce/content-single-product.php), between the reviews link
 * and the price, per the requested PLNKTON-style order. Narrower cards
 * than the full-width related-products grid, since this column is
 * only ~45% of the page width. */
.pb-pdp__summary .up-sells {
	margin: 0.5rem 0 2rem;
}

.pb-pdp__summary .up-sells > h2 {
	font-size: var(--wc-font-heading-md);
	margin: 0 0 1rem;
}

.pb-pdp__summary .up-sells ul.products {
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1rem;
}

/* ==========================================================================
 * Mini Cart drawer — see inc/woocommerce-mini-cart.php for markup.
 * ========================================================================*/
.pb-mini-cart-trigger {
	position: relative;
}

.pb-mini-cart-trigger__count {
	position: absolute;
	top: -0.3rem;
	right: -0.3rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.1rem;
	height: 1.1rem;
	padding: 0 0.2rem;
	border-radius: 999px;
	background: var(--wc-accent);
	color: #fff;
	font-size: 0.62rem;
	font-weight: 700;
	line-height: 1;
}

.pb-mini-cart-trigger__count[hidden] {
	display: none;
}

.pb-mini-cart-overlay {
	position: fixed;
	inset: 0;
	background: rgba(17, 17, 17, 0.4);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.3s ease, visibility 0.3s ease;
	z-index: 1200;
}

.pb-mini-cart-drawer {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	width: min(26rem, 100vw);
	background: var(--wc-background);
	box-shadow: var(--wc-shadow-drawer);
	transform: translateX(100%);
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
	z-index: 1201;
	display: flex;
	flex-direction: column;
}

body.pb-mini-cart-open .pb-mini-cart-overlay {
	opacity: 1;
	visibility: visible;
}

body.pb-mini-cart-open .pb-mini-cart-drawer {
	transform: translateX(0);
}

body.pb-mini-cart-open {
	overflow: hidden;
}

.pb-mini-cart-drawer__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1.5rem;
	border-bottom: 1px solid var(--wc-border);
	flex-shrink: 0;
}

/* font-size !important (2026-08-05) is load-bearing: this is a real
 * <h2>, and design-system.css's sitewide `h2{font-size:...!important}`
 * reset (deliberately built so no block-level class can silently
 * out-specificity it) otherwise always wins over a plain declaration
 * here regardless of source order — this title has actually been
 * rendering at that sitewide 1.65rem/800 default the whole time, not
 * the smaller size below. font-weight needs the same !important
 * treatment (2026-08-05) for the same reason, now that Regular (400)
 * is the actual requirement. */
.pb-mini-cart-drawer__title {
	font-size: 16px !important;
	font-weight: 400 !important;
	margin: 0;
	display: flex;
	align-items: baseline;
	gap: 0.4rem;
}

/* Item-count badge next to the title (e.g. "3") — same fragment-backed
 * live-update pattern as .pb-mini-cart-trigger__count, see
 * pb_wc_render_mini_cart_drawer_count()/pb_wc_cart_fragments() in
 * inc/woocommerce-mini-cart.php. */
.pb-mini-cart-drawer__count {
	font-size: 12px;
	font-weight: 400;
	color: var(--wc-muted-text);
}

.pb-mini-cart-drawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	border: none;
	border-radius: 999px;
	background: transparent;
	color: var(--wc-secondary);
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.pb-mini-cart-drawer__close:hover,
.pb-mini-cart-drawer__close:focus-visible {
	background: var(--wc-surface);
	outline: none;
}

.pb-mini-cart-drawer__close svg {
	width: 1.1rem;
	height: 1.1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
}

/* Cart contents — WooCommerce's own `woocommerce_mini_cart()` template
 * output (ul.cart_list / p.total / p.buttons) renders as direct
 * children of this element, no extra wrapper div. Made a flex column
 * so the upsell card + summary rows (both hooked into
 * woocommerce_widget_shopping_cart_before_buttons, so both land in the
 * DOM right before the buttons regardless) can be given explicit
 * `order` values to appear in the requested visual sequence — items,
 * upsell, summary, buttons — without needing a full template override
 * to physically reorder WooCommerce's own native markup.
 *
 * This container scrolls as a whole again (2026-08-06 — see its own
 * rule below for the full history): an in-between version had only
 * ul.cart_list scroll internally with everything else pinned at a
 * fixed natural size, but that meant any product beyond what already-
 * fit-on-screen content left room for was simply unreachable (this
 * container had `overflow: hidden`) rather than just requiring a
 * scroll — confirmed broken on both mobile and desktop. Scrolling the
 * whole body guarantees every product is always reachable; .buttons
 * uses `position: sticky` so checkout/"Bekijk winkelwagen" still never
 * require scrolling regardless. */
.pb-mini-cart-drawer__body {
	flex: 1;
	/* Back to `hidden` (2026-08-06 — this exact rule has flip-flopped a
	 * few times, this is the final architecture): the drawer is split
	 * into a fixed region (header, free-shipping status, totals,
	 * buttons — all flex-shrink:0, never clipped as long as their own
	 * combined height fits, which the tightened spacing throughout this
	 * file now guarantees) and exactly one scrollable region
	 * (ul.cart_list below). The earlier whole-body-scroll +
	 * `position: sticky` buttons version caused its own bug: a sticky
	 * bottom bar pinned mid-scroll could visually sit on top of/overlap
	 * the shipping row above it before any scrolling happened, which is
	 * what "CTA sits too high, pushing Verzendkosten out of view" (this
	 * ticket's own bug report) actually was. Removing position:sticky
	 * entirely (see .buttons below) and keeping this fixed removes that
	 * failure mode by construction — nothing can ever overlap anything
	 * else, and nothing outside ul.cart_list can be clipped since it's
	 * the only flex-shrinkable child. */
	overflow: hidden;
	/* Top padding halved from 1.5rem (2026-08-05) — the free-shipping
	 * block is now the drawer's first item, and the full 1.5rem read as
	 * too much empty space between the header divider and it. Bottom
	 * padding widened from 1.5rem (2026-08-06) — the fixed footer
	 * (totals/buttons) sat right at the drawer's own bottom edge with
	 * no breathing room below "Bekijk winkelwagen"; this shifts the
	 * whole fixed footer up by a bit, at ul.cart_list's expense (the
	 * one region designed to flex/shrink for exactly this) rather than
	 * touching any of the spacing *between* individual elements, which
	 * was already right. */
	padding: 0.75rem 1.5rem 2.25rem;
	display: flex;
	flex-direction: column;
}

.pb-mini-cart-drawer__body ul.cart_list,
.pb-mini-cart-drawer__body ul.product_list_widget {
	order: 1;
	/* The one scrollable region in the drawer (2026-08-06, restored —
	 * see .pb-mini-cart-drawer__body's own comment above for the full
	 * architecture). Grows to fill whatever space the fixed regions
	 * around it don't need (flex: 1 1 auto), and scrolls internally
	 * once there are enough products/upsells that it would otherwise
	 * push the totals/buttons out of the drawer. min-height is a floor,
	 * not a fixed height — it only stops this from being squeezed
	 * *below* one item's own real content height; on wider ≥900px
	 * layouts it's raised further so roughly 1.5 items are visible by
	 * default (one full item + about half of the next), per this
	 * ticket's own desktop requirement — see the @media block below. */
	flex: 1 1 auto;
	min-height: 8rem;
	overflow-y: auto;
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

@media (min-width: 900px) {
	.pb-mini-cart-drawer__body ul.cart_list,
	.pb-mini-cart-drawer__body ul.product_list_widget {
		min-height: 13rem;
	}
}

/* Grid: [thumbnail | name/price/qty stack]. The name+thumbnail native
 * link (`a:not(.remove)`) is `display: contents` so its own children
 * (the <img>, and the <span class="pb-mini-cart-item__name"> added via
 * the woocommerce_cart_item_name filter above) become direct grid
 * items in their own right, instead of being squeezed together into a
 * single grid cell — that mismatch (image nested one level deeper than
 * the grid expected) was the root cause of the previous misalignment. */
.pb-mini-cart-drawer__body ul.cart_list li {
	position: relative;
	display: grid;
	/* Matches the image's own width below (was still 4.5rem here after
	 * the image itself was enlarged to 6rem — explicit bug report: the
	 * image overflowed its column instead of rendering as a clean
	 * square, since a grid item's explicit width isn't constrained by
	 * a narrower track). */
	grid-template-columns: 6rem 1fr;
	column-gap: 0.85rem;
	padding-bottom: 1.25rem;
	border-bottom: 1px solid var(--wc-border);
}

.pb-mini-cart-drawer__body ul.cart_list li:last-child {
	border-bottom: none;
	padding-bottom: 0;
}

.pb-mini-cart-drawer__body ul.cart_list li a:not(.remove) {
	display: contents;
}

.pb-mini-cart-drawer__body ul.cart_list li img {
	grid-column: 1;
	grid-row: 1 / 4;
	align-self: start;
	/* Enlarged from 4.5rem (2026-08-05) — large enough to identify the
	 * product, per the desktop cart drawer redesign reference. Shape
	 * (object-fit/border-radius) is shared with the added-to-cart
	 * popup — see .pb-added-to-cart-popup__item-media's own rule. */
	width: 6rem;
	height: 6rem;
}

.pb-mini-cart-drawer__body ul.cart_list li a.remove {
	position: absolute;
	top: 0;
	right: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 1.5rem;
	border-radius: 999px;
	color: var(--wc-muted-text) !important;
	font-size: 1rem;
	line-height: 1;
	background: var(--wc-surface);
}

.pb-mini-cart-drawer__body ul.cart_list li a.remove:hover {
	color: var(--wc-error) !important;
	background: var(--wc-border);
}

.pb-mini-cart-item__name {
	grid-column: 2;
	grid-row: 1;
	font-weight: 400 !important;
	font-size: 12px !important;
	color: var(--wc-heading);
	padding-right: 1.75rem;
}

/* This is the "subtitle/description beneath the title" — WooCommerce's
 * native item-data markup (variation attributes and/or the bundle-deal
 * label pb_wc_display_bundle_cart_item_data() adds, inc/woocommerce-mini-cart.php),
 * not a separate custom element. */
.pb-mini-cart-drawer__body ul.cart_list li dl.variation {
	grid-column: 2;
	font-size: 9px !important;
	font-weight: 400 !important;
	color: var(--wc-muted-text);
	margin: 0.25rem 0 0;
}

.pb-mini-cart-item__price {
	grid-column: 2;
	grid-row: 2;
	margin-top: 0.4rem;
	font-size: var(--wc-font-body-sm);
	color: var(--wc-muted-text);
}

/* Sale-price strikethrough — WooCommerce's own price_html already
 * outputs <del>/<ins> when a line's product is on sale; only the
 * visual treatment (muted+struck original, emphasized current) is
 * custom here. */
.pb-mini-cart-item__price del {
	margin-right: 0.35rem;
	font-weight: 400;
	text-decoration: line-through;
	opacity: 0.7;
}

.pb-mini-cart-item__price ins {
	font-weight: 600;
	color: var(--wc-heading);
	text-decoration: none;
}

.pb-mini-cart-item__qty {
	grid-column: 2;
	grid-row: 3;
	margin-top: 0.6rem;
	display: inline-flex;
	align-items: center;
	gap: 0.65rem;
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-input);
	padding: 0.15rem 0.5rem;
	width: fit-content;
}

.pb-mini-cart-item__qty-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.35rem;
	height: 1.35rem;
	border: none;
	background: none;
	color: var(--wc-heading);
	font-size: 1rem;
	line-height: 1;
	cursor: pointer;
}

.pb-mini-cart-item__qty-btn:hover,
.pb-mini-cart-item__qty-btn:focus-visible {
	color: var(--wc-primary);
	outline: none;
}

.pb-mini-cart-item__qty-btn:disabled {
	opacity: 0.5;
	cursor: default;
}

.pb-mini-cart-item__qty-value {
	min-width: 1rem;
	text-align: center;
	font-size: var(--wc-font-body-sm);
	font-weight: 600;
}

/* Upsell rail ("Maak je bestelling compleet") — the gift-wrap add-on
 * card(s) (pb_wc_render_mini_cart_addon_cards()) always come first,
 * then admin-configured products (pb_wc_get_cart_upsell_products(),
 * inc/cart-upsells-admin.php), see pb_wc_render_mini_cart_upsell() in
 * inc/woocommerce-mini-cart.php. Every card is a fixed, compact
 * horizontal size regardless of item count — it previously stretched
 * to fill the row (flex: 1 1 0) when there was only 1 upsell, which
 * combined with the thumbnail's `width: 100%; aspect-ratio: 1` made a
 * single upsell balloon into a large square tile. A constant card width
 * means 1 item is always compact, and 2-3 items intentionally don't
 * fill the row either, so part of the next card peeks in as a scroll
 * affordance (plus the prev/next arrows below once there's more than
 * one card). */
.pb-mini-cart-upsell {
	order: 2;
	flex-shrink: 0;
	/* Trimmed back to the original 1.25rem (2026-08-05) — with the
	 * free-shipping block now also fixed/always-visible at the top of
	 * the drawer, and only ul.cart_list scrollable, every extra bit of
	 * margin here directly shrinks the room left for products. */
	margin-top: 0.85rem;
	padding-top: 0.65rem;
	border-top: 1px solid var(--wc-border);
}

.pb-mini-cart-upsell__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin: 0 0 0.85rem;
}

.pb-mini-cart-upsell__title {
	font-size: var(--wc-font-body-sm);
	font-weight: 700;
	color: var(--wc-heading);
	margin: 0;
}

.pb-mini-cart-upsell__nav {
	display: flex;
	gap: 0.4rem;
	flex-shrink: 0;
}

.pb-mini-cart-upsell__nav-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	border: 1px solid var(--wc-border);
	border-radius: 999px;
	background: var(--wc-background);
	color: var(--wc-heading);
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.pb-mini-cart-upsell__nav-btn:hover,
.pb-mini-cart-upsell__nav-btn:focus-visible {
	background: var(--wc-surface);
	outline: none;
}

.pb-mini-cart-upsell__nav-btn:disabled {
	opacity: 0.4;
	cursor: default;
}

.pb-mini-cart-upsell__nav-btn svg {
	width: 1rem;
	height: 1rem;
}

/* Native horizontally-scrollable track — touch/trackpad already work
 * with zero JS. The grab/grabbing cursor + .is-dragging (toggled by
 * assets/js/woocommerce.js, same click-and-drag pattern already built
 * for the desktop reviews carousel) add mouse click-drag support on
 * top of that; the prev/next arrows are a third, independent way to
 * move the same native scroll position. */
.pb-mini-cart-upsell__track {
	display: flex;
	gap: 0.75rem;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scrollbar-width: none;
	padding-bottom: 0.15rem;
	cursor: grab;
}

.pb-mini-cart-upsell__track::-webkit-scrollbar {
	display: none;
}

.pb-mini-cart-upsell__track.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}

.pb-mini-cart-upsell__item {
	position: relative;
	display: grid;
	grid-template-columns: 3.25rem 1fr auto;
	align-items: center;
	gap: 0.65rem;
	background: var(--wc-surface);
	border-radius: var(--wc-radius-input);
	padding: 0.6rem 0.65rem;
	flex: 0 0 14.5rem;
	scroll-snap-align: start;
}

/* A single card (today: just the gift-wrap card, before any product is
 * configured in Cart Upsells) fills the full track width instead of
 * staying at the compact multi-card size (2026-08-05) — at 14.5rem the
 * name/subtitle text was cramped/truncated with nothing to scroll to
 * anyway. Multi-card rows are untouched: :only-child never matches once
 * a 2nd card is added, so they keep the original compact/scrollable
 * sizing. */
.pb-mini-cart-upsell__item:only-child {
	flex: 1 1 100%;
	grid-template-columns: 4.5rem 1fr auto;
	padding: 0.85rem 1rem;
}

.pb-mini-cart-upsell__item:only-child .pb-mini-cart-upsell__media img {
	width: 4.5rem;
	height: 4.5rem;
}

.pb-mini-cart-upsell__media {
	display: block;
	grid-column: 1;
}

.pb-mini-cart-upsell__media img {
	display: block;
	width: 3.25rem;
	height: 3.25rem;
	object-fit: cover;
	border-radius: 0.5rem;
}

.pb-mini-cart-upsell__text {
	grid-column: 2;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
}

.pb-mini-cart-upsell__name {
	min-width: 0;
	font-size: 0.75rem;
	font-weight: 600;
	color: var(--wc-heading);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Addon cards only (e.g. "PaperBrain® luxe verpakt in goudfolie") —
 * product cards have no subtitle, so this element simply isn't output
 * for them (pb_wc_render_mini_cart_upsell(), inc/woocommerce-mini-cart.php). */
.pb-mini-cart-upsell__subtitle {
	font-size: 0.65rem;
	color: var(--wc-muted-text);
	display: -webkit-box;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.pb-mini-cart-upsell__price {
	font-size: 0.75rem;
	color: var(--wc-muted-text);
}

/* .pb-mini-cart-drawer prefix (not just .pb-mini-cart-upsell__add
 * alone) is load-bearing here, not stylistic: a product card's add
 * button is an <a> (required for WooCommerce's native ajax_add_to_cart
 * mechanism), and `.woocommerce a { color: var(--wc-primary); }` has
 * higher specificity (one class + one element) than a single-class
 * selector would — without the extra scope, that rule wins and the
 * plus icon (fill: currentColor) renders the same purple as its own
 * circular background, i.e. invisible. This was a real, confirmed bug,
 * not a rendering artifact. The addon card's add "button" is a <label>
 * instead (wrapping the existing data-pb-addon-toggle checkbox), which
 * this same rule/scope applies to identically. */
/* 2026-08-17, explicit request: background matches "Afrekenen"
 * (.pb-mini-cart-drawer__body .buttons a.checkout, further below)
 * exactly — same hardcoded #6848f4, not var(--wc-primary). That CTA
 * deliberately hardcodes this value instead of using --wc-primary for
 * the same reason this button was wrong: a saved Customizer override
 * pushed --wc-primary to a more saturated violet (#8224e3) than the
 * real brand purple used everywhere else. Matching the CTA's own
 * approach (not the variable it avoids) keeps both immune to that same
 * drift, and stays "exact dezelfde kleur" regardless of future
 * Customizer changes to --wc-primary. */
.pb-mini-cart-drawer .pb-mini-cart-upsell__add {
	grid-column: 3;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.85rem;
	height: 1.85rem;
	border-radius: 999px;
	background: #6848f4;
	color: #fff;
	flex-shrink: 0;
	cursor: pointer;
	transition: opacity 0.2s ease, background-color 0.2s ease;
}

/* opacity:0.9 (was 0.85) — matches the checkout CTA's own hover/focus
 * state exactly (.buttons a.checkout:hover/:focus-visible below). */
.pb-mini-cart-upsell__add:hover,
.pb-mini-cart-upsell__add:focus-visible {
	opacity: 0.9;
	outline: none;
}

.pb-mini-cart-upsell__add svg {
	width: 1rem;
	height: 1rem;
	fill: currentColor;
}

.pb-mini-cart-upsell__add-icon {
	font-size: 1.05rem;
	line-height: 1;
}

/* The checkbox itself stays in the DOM (keyboard/AT operable via the
 * <label>'s native for/id association) but is visually replaced by
 * .pb-mini-cart-upsell__add-icon's +/checkmark glyph. */
.pb-mini-cart-upsell__add--toggle input[type="checkbox"] {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Already-enabled gift wrap — card stays visible (the checkbox must
 * stay reachable to remove it again) but the add button tints to show
 * it's already applied, never a second time. */
.pb-mini-cart-upsell__item--added .pb-mini-cart-upsell__add {
	background: var(--wc-heading);
}

/* Summary — subtotal (native "total") + shipping row, grouped
 * visually via matching `order`. No grand total per spec. */
.pb-mini-cart-drawer__body .total {
	order: 3;
	flex-shrink: 0;
	/* Trimmed further from 1.5rem (2026-08-06) — this block, and
	 * everything after it, must always be visible without scrolling
	 * (only ul.cart_list scrolls, see .pb-mini-cart-drawer__body's own
	 * comment), so height here comes directly out of the room left for
	 * products above it — desktop had noticeably more breathing room
	 * here than mobile ever got, trimmed to match. */
	margin-top: 0.6rem;
	padding-top: 0.6rem;
	/* Strengthened from 1px var(--wc-border) (2026-08-05) so the totals
	 * section reads as a clearly separate block below the cart
	 * items/upsell rail, per the desktop cart drawer redesign
	 * reference. */
	border-top: 2px solid var(--wc-heading);
	font-size: 14px !important;
	font-weight: 400 !important;
	display: flex;
	justify-content: space-between;
}

/* "Subtotaal:" itself (native <strong>, WooCommerce's own mini-cart
 * template) — a plain author declaration already beats the browser's
 * own default `strong{font-weight:bolder}` UA style regardless of
 * !important (any author rule outranks a user-agent default), but
 * kept !important anyway for the same reason every other size/weight
 * in this file now is: consistent, unambiguous intent, not reliant on
 * cascade-origin subtlety being obvious to the next reader. The price
 * itself inherits this rule's own font-size/weight (no competing rule
 * of its own); the "(incl. btw)" <small> gets its own smaller/regular
 * override just below instead (2026-08-14).
 */
.pb-mini-cart-drawer__body .total strong {
	font-weight: 400 !important;
}

/* Price + "(incl. btw)" as one tight group (2026-08-14) — previously
 * two independent elements, which .total's own
 * `display:flex;justify-content:space-between` above then treated as
 * two separate flex children and spread across the full row width
 * (the tax label ending up far right, away from the price) — same bug
 * whether or not a fee/gift-wrap was in the cart, since both paths
 * produced that same unwrapped sibling structure. The PHP side
 * (pb_wc_include_fees_in_cart_subtotal(), inc/woocommerce-mini-cart.php)
 * now always wraps both in this span, making the pair a single flex
 * child (paired with "Subtotaal:" as the row's only other child) —
 * consistent regardless of fees, and never lost on an AJAX fragment
 * refresh since it's rebuilt from PHP every time, not injected once
 * via JS. */
.pb-mini-cart-subtotal-group {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
}

.pb-mini-cart-subtotal-group .tax_label {
	font-size: 0.75em;
	font-weight: 400;
}

.pb-mini-cart-summary-row {
	order: 3;
	flex-shrink: 0;
	display: flex;
	justify-content: space-between;
	font-size: var(--wc-font-body-sm);
	color: var(--wc-muted-text);
	/* Tightened further from 0.35rem (2026-08-05) — subtotal and
	 * shipping costs now read as one tight group. */
	margin: 0.15rem 0 0;
}

/* Free-shipping progress — moved to the very top of the drawer body
 * (2026-08-05), directly under the header divider and above the cart
 * items list (see the woocommerce_before_mini_cart hook change,
 * inc/woocommerce-mini-cart.php). `order` is left at the default 0 —
 * lower than ul.cart_list's explicit `order: 1` — so it always sorts
 * first regardless of DOM position. Restyled into its own full-width
 * light surface block (left-aligned icon+text, bold amount, taller
 * progress bar) instead of the popup's smaller centered version; scoped
 * to this drawer context only, the "Toegevoegd aan winkelwagen" popup's
 * own instance (assets/css/woocommerce.css further down) is untouched. */
.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping {
	flex-shrink: 0;
	width: 100%;
	box-sizing: border-box;
	/* Space below before the first cart item, per "tussen het product
	 * wat geselecteerd is" — the cart items list itself keeps its own
	 * unrelated top spacing (padding inherited from the drawer body).
	 * Margin trimmed again from 1rem (2026-08-06, desktop pass — mobile
	 * already has its own tighter 0.65rem in the @media block below,
	 * which always wins there) — this block is always-visible,
	 * non-scrolling content, so its own size directly competes with
	 * ul.cart_list for room. */
	margin: 0 0 0.5rem;
	padding: 0.55rem 0.75rem;
}

.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping-text {
	/* Centered (2026-08-05, was flex-start/left) — icon + text as one
	 * centered group. */
	justify-content: center;
	text-align: center;
	white-space: normal;
	font-size: 0.72rem;
}

.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping-text .woocommerce-Price-amount {
	font-weight: 700;
}

.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping-icon {
	font-size: 0.9rem;
}

.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping-track {
	height: 0.25rem;
}

/* Mobile only (2026-08-06, widened) — trims the vertical space around
 * the product list so more of it fits without scrolling. ul.cart_list
 * itself (flex: 1 1 auto) grows to fill whatever room is left after
 * everything else in the drawer — trimming just the space *above* it
 * (header/body/shipping, the first pass) only helped the list start
 * sooner; it didn't grow the list itself, because the upsell rail /
 * totals / buttons below it were still claiming the same fixed share of
 * a mobile viewport's much shorter height than desktop has to spare.
 * Trimming their margins/padding here too directly gives ul.cart_list
 * more of that room back, which is what actually lets a 2nd item
 * become visible. Same shared classes/tokens, desktop untouched, all
 * values stay positive (no negative margins), and every section still
 * keeps its own distinct — just smaller — gap from the next. */
@media (max-width: 767px) {
	.pb-mini-cart-drawer__header {
		padding-bottom: 1rem;
	}

	.pb-mini-cart-drawer__body {
		padding-top: 0.4rem;
	}

	.pb-mini-cart-drawer__body .pb-added-to-cart-popup__shipping {
		margin-bottom: 0.65rem;
	}

	.pb-mini-cart-upsell {
		margin-top: 0.75rem;
		padding-top: 0.65rem;
	}

	/* Subtotaal — tightened further (2026-08-06) so it + the
	 * "Verzendkosten" row right below it take noticeably less height,
	 * on top of the earlier margin-top/padding-top trim. font-size
	 * needs !important here too, same reason as the shared base rule
	 * above (design-system.css's sitewide h-tag reset otherwise wins). */
	.pb-mini-cart-drawer__body .total {
		margin-top: 0.5rem;
		padding-top: 0.5rem;
		font-size: 12px !important;
	}

	/* Verzendkosten row — closer to Subtotaal above it and smaller. */
	.pb-mini-cart-summary-row {
		margin-top: 0.05rem;
		font-size: 11px;
	}

	/* Widened again from 0.5rem (2026-08-06) — the CTA/cart-link were
	 * "sitting too high" against the shipping row above them (this
	 * ticket's own mobile bug report); no longer relies on
	 * position:sticky (removed, see the base rule below), so this is a
	 * plain, harmless margin increase now — nothing to overlap. */
	.pb-mini-cart-drawer__body .buttons {
		margin-top: 0.85rem;
	}
}

/* Buttons — checkout is the full-width primary button; view-cart is a
 * plain text link underneath. Native markup order is "View cart" then
 * "Checkout"; `order` visually flips them without touching the DOM. */
.pb-mini-cart-drawer__body .buttons {
	order: 4;
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	/* No longer position:sticky (removed 2026-08-06) — the drawer body
	 * itself doesn't scroll anymore (see .pb-mini-cart-drawer__body's
	 * own comment: only ul.cart_list does), so this and the totals
	 * above it are already always visible by construction; sticky
	 * positioning was actually the root cause of this ticket's mobile
	 * bug (a pinned bottom bar visually overlapping the shipping row
	 * above it before any scroll happened). Margin trimmed from 1.5rem
	 * — desktop had noticeably more space here than mobile ever did. */
	margin-top: 0.65rem;
}

.pb-mini-cart-drawer__body .buttons a {
	width: 100%;
	text-align: center;
}

.pb-mini-cart-drawer__body .buttons a.checkout {
	order: 1;
	/* Hardcoded #6848f4 (2026-07-15), not var(--wc-primary) — a saved
	 * Customizer override (WooCommerce Design -> Primary, #8224e3) had
	 * pushed --wc-primary to a more saturated violet than the brand
	 * purple used everywhere else (hero, campaign, footer CTAs), making
	 * this one button visibly off. Locking this specific button to the
	 * real brand purple regardless of that setting. */
	background: #6848f4;
	border-color: #6848f4;
	color: #fff;
}

.pb-mini-cart-drawer__body .buttons a.checkout:hover,
.pb-mini-cart-drawer__body .buttons a.checkout:focus-visible {
	opacity: 0.9;
	outline: none;
}

.pb-mini-cart-drawer__body .buttons a:not(.checkout) {
	order: 2;
	background: none;
	border-color: transparent;
	color: var(--wc-heading);
	text-decoration: underline;
	font-weight: 600;
	text-transform: none;
	padding: 0;
}

.pb-mini-cart-drawer .woocommerce-mini-cart__empty-message {
	color: var(--wc-muted-text);
	text-align: center;
	padding: 3rem 0;
}

@media (prefers-reduced-motion: reduce) {
	.pb-mini-cart-overlay,
	.pb-mini-cart-drawer {
		transition: none;
	}
}

/* ==========================================================================
 * "Toegevoegd aan winkelwagen" popup — same wc-* tokens/shadow tone as
 * the Mini Cart drawer just above (own classes, own z-index tier, so
 * the two can never visually collide even in the unlikely case both
 * are ever open together), but its own layout: a small notification
 * card rather than a persistent edge-to-edge drawer. Mobile-first —
 * base rules below are the centered mobile panel; the >=768px query
 * repositions it into a compact panel under the header, right-aligned
 * over the PDP, without touching a single mobile rule.
 * ========================================================================*/
.pb-added-to-cart-overlay {
	position: fixed;
	inset: 0;
	background: rgba(17, 17, 17, 0.4);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.3s ease, visibility 0.3s ease;
	z-index: 1300;
}

body.pb-added-to-cart-open .pb-added-to-cart-overlay {
	opacity: 1;
	visibility: visible;
}

body.pb-added-to-cart-open {
	overflow: hidden;
}

.pb-added-to-cart-popup {
	position: fixed;
	top: 50%;
	left: 50%;
	width: min(92vw, 30rem);
	max-height: min(88vh, 640px);
	transform: translate(-50%, -50%) scale(0.96);
	background: var(--wc-background);
	border: 1px solid var(--wc-heading);
	/* Same 4px the CTAs below render at (design-system.css's sitewide
	 * button standardization) — not a separately-chosen value. */
	border-radius: 4px;
	box-shadow: 0 24px 60px rgba(17, 17, 17, 0.22);
	z-index: 1301;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

body.pb-added-to-cart-open .pb-added-to-cart-popup {
	opacity: 1;
	visibility: visible;
	transform: translate(-50%, -50%) scale(1);
}

/* Compact panel, right-aligned under the header (>=768px) — the
 * header/cart-icon markup itself is completely untouched; only this
 * popup's own position changes. --pb-header-height is the same
 * live-synced custom property assets/css/main.css already keeps
 * updated for the sticky header, not a separately-maintained number. */
@media (min-width: 768px) {
	.pb-added-to-cart-popup {
		top: calc(var(--pb-header-height, 71px) + 1rem);
		left: auto;
		right: 1.5rem;
		width: min(24rem, calc(100vw - 3rem));
		max-height: min(80vh, 600px);
		transform: translateY(-12px) scale(0.98);
	}

	body.pb-added-to-cart-open .pb-added-to-cart-popup {
		transform: translateY(0) scale(1);
	}
}

.pb-added-to-cart-popup__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.5rem 1.5rem 1rem;
	flex-shrink: 0;
}

/* !important on size/weight (2026-08-05) is load-bearing: this is a
 * real <h2>, and design-system.css's sitewide `h2{font-size/weight
 * ...!important}` reset (deliberately built so no block-level class
 * can silently out-specificity it) otherwise always wins over a plain
 * declaration here regardless of source order — same root cause
 * already fixed the same way for Hero Centered's h1/FAQ's h2. Every
 * earlier size/weight change to this title was silently overridden by
 * that rule and never actually rendered. */
.pb-added-to-cart-popup__title {
	font-size: 14px !important;
	font-weight: 400 !important;
	color: var(--wc-heading);
	margin: 0;
}

/* Byte-for-byte the same close-button treatment as
 * .pb-mini-cart-drawer__close, own class only because it lives on a
 * separate element. */
.pb-added-to-cart-popup__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	flex-shrink: 0;
	border: none;
	border-radius: 999px;
	background: transparent;
	color: var(--wc-secondary, var(--wc-heading));
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.pb-added-to-cart-popup__close:hover,
.pb-added-to-cart-popup__close:focus-visible {
	background: var(--wc-surface);
	outline: none;
}

.pb-added-to-cart-popup__close svg {
	width: 1.1rem;
	height: 1.1rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
}

.pb-added-to-cart-popup__body {
	padding: 0 1.5rem 1.5rem;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

.pb-added-to-cart-popup__item {
	display: flex;
	gap: 1rem;
}

/* Shared square product-image styling (2026-08-16, explicit request) —
 * same radius formula + object-fit for both the added-to-cart popup
 * and the mini-cart drawer, one declaration each instead of two
 * separately-maintained copies. Drawer stays 6rem (its own deliberate
 * enlarge-from-4.5rem, unrelated to this fix) vs the popup's 4.5rem —
 * only the SHAPE (square/radius/crop-behaviour), not the size, needs
 * to match. */
.pb-added-to-cart-popup__item-media,
.pb-mini-cart-drawer__body ul.cart_list li img {
	border-radius: calc(var(--wc-radius-input) - 0.2rem);
}

.pb-added-to-cart-popup__item-media {
	flex-shrink: 0;
	width: 4.5rem;
	height: 4.5rem;
	overflow: hidden;
	display: block;
}

.pb-added-to-cart-popup__item-media img,
.pb-mini-cart-drawer__body ul.cart_list li img {
	object-fit: cover;
	display: block;
}

.pb-added-to-cart-popup__item-media img {
	width: 100%;
	height: 100%;
}

.pb-added-to-cart-popup__item-body {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}

/* Extra .pb-added-to-cart-popup__item scope (2026-08-05) is load-bearing:
 * `.woocommerce a { color: var(--wc-primary) }` (this file, "Global"
 * section) is class+element specificity, one level above a single
 * class selector, so it silently won every product-name link in this
 * card purple regardless of source order — same root cause, same
 * fix pattern already used for .woocommerce .site-header-wrap a. */
.pb-added-to-cart-popup__item .pb-added-to-cart-popup__item-title {
	font-size: var(--wc-font-body-sm, 0.9rem);
	font-weight: 400;
	color: var(--wc-heading);
	text-decoration: none;
}

.pb-added-to-cart-popup__item .pb-added-to-cart-popup__item-title:hover,
.pb-added-to-cart-popup__item .pb-added-to-cart-popup__item-title:focus-visible {
	text-decoration: underline;
}

/* WC_Cart::get_item_data()'s own native markup (variation attributes,
 * plus the bundle-deal/add-on labels pb_wc_display_bundle_cart_item_data()/
 * pb_wc_display_addon_cart_item_data() already add to it elsewhere) —
 * a plain <dl>/<p>, reset to this card's own compact type scale rather
 * than overridden per element. */
.pb-added-to-cart-popup__item-meta {
	font-size: 0.78rem;
	color: var(--wc-muted-text);
}

.pb-added-to-cart-popup__item-meta dl,
.pb-added-to-cart-popup__item-meta p {
	margin: 0;
}

.pb-added-to-cart-popup__item-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	margin-top: 0.25rem;
}

.pb-added-to-cart-popup__item-qty {
	font-size: 0.8rem;
	color: var(--wc-muted-text);
}

.pb-added-to-cart-popup__item-price {
	font-size: 0.8rem;
	font-weight: 400;
	color: var(--wc-heading);
}

/* Free-shipping readout — its own light, rounded box below the CTAs
 * (reference layout), not a bare progress bar floating in the body. */
.pb-added-to-cart-popup__shipping {
	background: var(--wc-surface);
	border-radius: var(--wc-radius-input);
	padding: 0.5rem 0.75rem;
}

.pb-added-to-cart-popup__shipping-text {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.35rem;
	margin: 0 0 0.35rem;
	font-size: 0.75rem;
	color: var(--wc-heading);
	text-align: center;
	white-space: nowrap;
}

.pb-added-to-cart-popup__shipping-icon {
	font-size: 0.55rem;
	color: var(--wc-heading);
}

.pb-added-to-cart-popup__shipping.is-complete .pb-added-to-cart-popup__shipping-icon {
	color: var(--wp--preset--color--success, #1e7a46);
}

.pb-added-to-cart-popup__shipping-track {
	height: 0.2rem;
	border-radius: 999px;
	background: var(--wc-border);
	overflow: hidden;
}

.pb-added-to-cart-popup__shipping-fill {
	height: 100%;
	border-radius: inherit;
	background: var(--wc-heading);
	transition: width 0.4s ease;
}

.pb-added-to-cart-popup__shipping.is-complete .pb-added-to-cart-popup__shipping-fill {
	background: var(--wp--preset--color--success, #1e7a46);
}

.pb-added-to-cart-popup__shipping.is-complete .pb-added-to-cart-popup__shipping-text {
	color: var(--wp--preset--color--success, #1e7a46);
	font-weight: 600;
	margin-bottom: 0;
	/* This message ("Je bestelling heeft gratis verzending") is longer
	 * than the in-progress one — a touch smaller here specifically
	 * keeps it guaranteed on one line (white-space:nowrap above) even
	 * on the narrowest phone widths, without shrinking the shorter
	 * in-progress message unnecessarily. */
	font-size: 0.68rem;
}

/* Once qualified there's nothing left to progress toward — the track
 * (and its now-full fill) is hidden entirely rather than left showing
 * a permanently-full bar, matching the requested reference. */
.pb-added-to-cart-popup__shipping.is-complete .pb-added-to-cart-popup__shipping-track {
	display: none;
}

.pb-added-to-cart-popup__actions {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.pb-added-to-cart-popup__actions .pb-button {
	width: 100%;
}

/* "Bekijk winkelwagen" deliberately does NOT use the sitewide
 * "every secondary CTA looks like the filled header CTA" standard
 * (design-system.css, .pb-button--secondary:not(.pb-newsletter__cta))
 * — this popup pairs an outlined secondary action with a filled
 * primary one (reference layout: white/outlined "view cart" + solid
 * "checkout"), so it opts back out the same way .pb-newsletter__cta
 * already does. Box model (radius/height/padding/font) is a
 * deliberate byte-for-byte copy of that *same* standardized rule's
 * own box model — only the color tokens differ (secondary's white
 * background + brand-purple text/border, vs. that rule's filled
 * purple) — so this button always matches "Afrekenen" (which the
 * standardized rule *does* apply to) exactly in size/shape, never a
 * second, independently-sized box model to keep in sync by hand.
 * Three levels of scope (popup > actions > link) is deliberately
 * higher than that sitewide rule's own two (class + :not()), so this
 * wins regardless of stylesheet source order. */
.pb-added-to-cart-popup .pb-added-to-cart-popup__actions .pb-added-to-cart-popup__cart-link {
	background-color: var(--wp--custom--button--secondary--background, #ffffff);
	color: var(--wp--custom--button--secondary--text, #6848f4);
	border-width: 1px;
	border-color: var(--wp--custom--button--secondary--border-color, #6848f4);
	border-radius: 4px;
	height: auto;
	min-width: 0;
	padding: 0.6rem 1.25rem;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: normal;
	text-transform: none;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.pb-added-to-cart-popup .pb-added-to-cart-popup__actions .pb-added-to-cart-popup__cart-link:hover,
.pb-added-to-cart-popup .pb-added-to-cart-popup__actions .pb-added-to-cart-popup__cart-link:focus-visible {
	background-color: var(--wp--custom--button--secondary--hover-background, #ffffff);
	border-color: var(--wp--custom--button--secondary--hover-text, #7e6fef);
	color: var(--wp--custom--button--secondary--hover-text, #7e6fef);
	transform: none;
	box-shadow: none;
	outline: none;
}

@media (prefers-reduced-motion: reduce) {
	.pb-added-to-cart-overlay,
	.pb-added-to-cart-popup {
		transition: none;
	}
}

/* ==========================================================================
 * Cart page — WooCommerce Blocks (wp:woocommerce/cart), 2-column desktop.
 * Only spacing/typography/visual polish; no functionality touched.
 * ========================================================================*/
.wp-block-woocommerce-cart {
	max-width: var(--wc-container-width);
	margin: 0 auto !important;
	padding: var(--wc-section-spacing) 1.25rem;
}

@media (min-width: 1024px) {
	.wp-block-woocommerce-cart {
		padding: var(--wc-section-spacing) 3rem;
	}
}

.wp-block-woocommerce-cart .wc-block-cart-items {
	font-size: var(--wc-font-body-sm);
}

.wp-block-woocommerce-cart .wc-block-components-product-name {
	font-weight: 700;
	color: var(--wc-heading);
}

.wp-block-woocommerce-cart .wc-block-components-quantity-selector {
	border-radius: var(--wc-radius-input);
	border-color: var(--wc-border);
}

.wp-block-woocommerce-cart .wc-block-cart-item__remove-link {
	color: var(--wc-muted-text);
}

.wp-block-woocommerce-cart .wc-block-cart-item__remove-link:hover {
	color: var(--wc-error);
}

.wp-block-woocommerce-cart .wc-block-components-totals-item__value,
.wp-block-woocommerce-cart .wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	font-weight: 700;
}

.wp-block-woocommerce-cart .wc-block-components-panel,
.wp-block-woocommerce-cart .wc-block-components-totals-wrapper,
.wp-block-woocommerce-cart .wc-block-cart__totals-title {
	border-radius: var(--wc-radius-card);
}

/* 2026-08-17: the rounded-pill grey outlines around "Coupons
 * toevoegen" and "Totaal" (still visible after the first line-removal
 * pass) — checked WooCommerce's own SHARED component stylesheet
 * (packages-style.css, loaded on cart + checkout both) directly.
 * `.wc-block-components-panel.has-border` puts a top+bottom border on
 * the coupon panel, and the generic `.wc-block-components-totals-wrapper`
 * rule puts a border-top on every row — neither is scoped to the
 * order-summary-block container my previous fix targeted, so they
 * were untouched by it. Cart-scoped (not checkout, which keeps its
 * own intentional row dividers). */
.wp-block-woocommerce-cart .wc-block-components-panel.has-border,
.wp-block-woocommerce-cart .wc-block-components-totals-wrapper {
	border: none !important;
}

/* 2026-08-17, explicit request: thin black divider directly above +
 * below the "Verzending" row specifically — :has() targets just that
 * row's own wrapper (same shared .wc-block-components-totals-wrapper
 * class the border:none rule above applies to, higher specificity via
 * the extra pseudo-class here so this wins), leaving Coupons/Totaal
 * untouched. Padding (existing spacing between divider and text) left
 * as-is. Full content width by default (block-level div inside the
 * card's own padding). */
.wp-block-woocommerce-cart .wc-block-components-totals-wrapper:has(.wc-block-components-totals-shipping) {
	/* 2026-08-17: lightened from #000000 (explicit request) to match
	 * this page's other divider lines — --wc-border, the same light
	 * grey token used sitewide for "clean divider" borders. */
	border-top: 1px solid var( --wc-border, #e6e3df ) !important;
	border-bottom: 1px solid var( --wc-border, #e6e3df ) !important;
	/* This wrapper class also gets border-radius:var(--wc-radius-card)
	 * from the "Right rail" rule earlier in this file (applies broadly
	 * to .wc-block-components-panel/-totals-wrapper/__totals-title) —
	 * combined with the border above that read as a rounded pill/button
	 * shape instead of a plain straight divider line. Zeroing it here,
	 * scoped to just this row. */
	border-radius: 0 !important;
}

.wp-block-woocommerce-cart .wc-block-cart__submit-container,
.wp-block-woocommerce-cart .wc-proceed-to-checkout {
	margin-top: 1.25rem;
}

/* 2026-08-17, explicit request: "Doorgaan naar afrekenen" exactly
 * matching the sitewide Primary CTA — same --wp--custom--button--
 * primary--* tokens as .pb-button--primary and the checkout page's own
 * place-order button, no new/duplicate button style. Width/text/link
 * untouched (WC's own width:100% on this button, from cart.css, is
 * left as-is). !important needed to win over WooCommerce's own block
 * CSS, same reason already established for the other primary CTAs. */
.wp-block-woocommerce-cart .wc-block-cart__submit-button {
	border-radius: var( --wp--custom--button--primary--radius, 10px ) !important;
	background: var( --wp--custom--button--primary--background, #111111 ) !important;
	border-color: var( --wp--custom--button--primary--background, #111111 ) !important;
	color: var( --wp--custom--button--primary--text, #ffffff ) !important;
	font-family: var( --wp--preset--font-family--theme-button, inherit );
	font-size: var( --wp--preset--font-size--button, 0.8rem ) !important;
	font-weight: 700 !important;
	text-transform: var( --wp--custom--typography--button--transform, none );
	letter-spacing: 0.06em;
	padding: 0.95rem 2.25rem !important;
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.wp-block-woocommerce-cart .wc-block-cart__submit-button:hover:not(:disabled),
.wp-block-woocommerce-cart .wc-block-cart__submit-button:focus-visible:not(:disabled) {
	background: var( --wp--custom--button--primary--hover-background, #2b2b2b ) !important;
	border-color: var( --wp--custom--button--primary--hover-background, #2b2b2b ) !important;
	transform: translateY(-1px);
	box-shadow: var( --wp--custom--button--primary--shadow, 0 8px 20px rgba(17, 17, 17, 0.25) );
	outline: none;
}

.wc-block-cart-cross-sells {
	margin-top: 3rem;
	padding-top: 2rem;
	border-top: 1px solid var(--wc-border);
}

.wc-block-cart-cross-sells .wc-block-cart-cross-sells__product {
	border-radius: var(--wc-radius-card);
}

/* Right rail (Cart Totals block) — a real surface card. */
.wp-block-woocommerce-cart .is-large .wp-block-woocommerce-cart-order-summary-block,
.wp-block-woocommerce-cart .wc-block-cart__sidebar {
	background: var(--wc-surface);
	border-radius: var(--wc-radius-card);
	padding: 1.5rem;
}

/* 2026-08-17: the visible "besteloverzicht vak" card is actually this
 * element (.wp-block-woocommerce-cart-order-summary-block), a CHILD of
 * .wc-block-cart__sidebar with its own separate background painted on
 * top — the outer sidebar's background color below was never visible
 * behind it. Same #F5F5F5 request, applied to the element that's
 * actually rendering the visible pixels. Radius/padding (set by the
 * shared rule above) untouched. */
.wp-block-woocommerce-cart .is-large .wp-block-woocommerce-cart-order-summary-block {
	background-color: #f5f5f5;
}

/* 2026-08-17, explicit request: #F5F5F5 instead of the shared
 * --wc-surface (#F7F7F7) for this exact selector only — not changing
 * the variable itself, which is used elsewhere too. */
.wc-block-components-sidebar.wc-block-cart__sidebar {
	background-color: #f5f5f5;
}

/* 2026-08-17, explicit request: unwanted internal grey lines inside
 * the "Overzicht" card — checked WooCommerce's own bundled cart.css
 * directly. Two native rules are the source: a border-bottom under the
 * heading/coupon area (.wp-block-woocommerce-cart-order-summary-block)
 * and a border-top above the Subtotaal/Levering/Totaal rows
 * (.wp-block-woocommerce-cart-order-summary-totals-block) — the
 * second one is even inconsistently toggled between 1px and none by
 * WooCommerce itself depending on state/breakpoint, reading as
 * "gekke lijnen". !important since these are otherwise unconditional
 * native rules. Only the outer card's own border-radius (set above)
 * remains. Spacing/margin-bottom untouched, so layout doesn't shift. */
.wp-block-woocommerce-cart-order-summary-block,
.wp-block-woocommerce-cart-order-summary-totals-block {
	border: none !important;
}

/* "Overzicht" heading (was "Totalen winkelwagen", already renamed in
 * this page's own block content) — !important needed since this
 * renders as a heading tag, so design-system.css's sitewide h1-h6
 * !important rules otherwise win regardless of specificity, same root
 * cause already fixed for several other checkout/cart titles this
 * theme reuses. Family/weight left as-is per explicit request. */
.wp-block-woocommerce-cart-order-summary-heading-block,
.wp-block-woocommerce-cart-order-summary-heading-block h2,
.wp-block-woocommerce-cart-order-summary-heading-block h3 {
	font-size: 16px !important;
}

/* ==========================================================================
 * Checkout — WooCommerce Checkout Blocks (wp:woocommerce/checkout),
 * "Elvou-inspired" premium styling.
 *
 * Verified against the actual installed WooCommerce Blocks markup/CSS
 * (assets/client/blocks/checkout.css + packages-style.css) rather than
 * assumed class names — the checkout page is composed of confirmed
 * real blocks:
 *   .wp-block-woocommerce-checkout
 *     .wp-block-woocommerce-checkout-fields-block   (left: contact/shipping/billing/payment/notes/terms/place-order)
 *     .wp-block-woocommerce-checkout-totals-block   (right: order summary)
 *       .wp-block-woocommerce-checkout-order-summary-block
 *
 * WooCommerce's own bundled CSS already drives the responsive column
 * split via a CSS container query on `.wp-block-woocommerce-checkout`
 * (container-type: inline-size, switching around a 700px container
 * width) and already supports an optional sticky sidebar via
 * `.wc-block-checkout__sidebar.is-sticky`. Nothing below sets
 * display/width/float on the two columns — only spacing, color,
 * radius, and typography layered on top, plus an additive `position:
 * sticky` that works regardless of which wrapper is present.
 * ========================================================================*/

.wp-block-woocommerce-checkout {
	max-width: 1600px;
	margin: 0 auto;
	padding: var(--wp--preset--spacing--xl, 3rem) 1.25rem clamp(3rem, 6vw, 5rem);
}

@media (min-width: 768px) {
	.wp-block-woocommerce-checkout {
		padding-left: 2rem;
		padding-right: 2rem;
	}
}

@media (min-width: 1024px) {
	.wp-block-woocommerce-checkout {
		padding-left: 3rem;
		padding-right: 3rem;
		/* 2026-08-16: less top padding on desktop, explicit request —
		 * Besteloverzicht + the gift-wrap card below it were getting cut
		 * off below the fold on landing. Left/right unchanged, bottom
		 * unchanged. */
		padding-top: 1.25rem;
	}
}

/* Page title ("Checkout") — page.php's own h1.page-title has no
 * horizontal padding of its own (it sits in a full-width <article>,
 * not inside .wp-block-woocommerce-checkout), so without this it sits
 * flush against the viewport edge while the form/order-summary below
 * it start 1.25rem/2rem/3rem in. Mirrors .wp-block-woocommerce-checkout's
 * own padding scale exactly, at the same breakpoints, so the title's
 * left edge always lines up with the content below it. Scoped to
 * body.woocommerce-checkout (WooCommerce's own body class on this
 * page) so no other page's h1.page-title is affected. */
body.woocommerce-checkout h1.page-title {
	max-width: 1600px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 1.25rem;
	padding-right: 1.25rem;
	box-sizing: border-box;
}

@media (min-width: 768px) {
	body.woocommerce-checkout h1.page-title {
		padding-left: 2rem;
		padding-right: 2rem;
	}
}

@media (min-width: 1024px) {
	body.woocommerce-checkout h1.page-title {
		padding-left: 3rem;
		padding-right: 3rem;
	}
}

/* Sticky order summary on desktop — additive only; WooCommerce's own
 * .is-sticky toggle may or may not be present depending on block
 * version/editor setting, so this applies to both possible wrappers. */
@media (min-width: 700px) {
	.wp-block-woocommerce-checkout-totals-block,
	.wc-block-checkout__sidebar {
		position: sticky;
		top: 6.5rem;
		align-self: flex-start;
	}
}

/* 2026-08-16: "Besteloverzicht" was sitting visibly lower than
 * "Contactgegevens" even after equalizing the two cards' own top
 * padding — the parent row was vertically centering the two columns
 * against each other (align-items:center, likely from Gutenberg's own
 * generic .is-layout-flex utility style), so the shorter right column
 * got pushed down to center it against the much taller left column.
 * align-self:flex-start above only works if the parent IS flex/grid,
 * which it is — this just forces both columns explicitly, since only
 * the right one had its own override. */
@media (min-width: 1024px) {
	.wp-block-woocommerce-checkout {
		align-items: flex-start !important;
	}
}

/* 2026-08-16: previous alignment attempts (equalizing card padding,
 * align-items) didn't visibly move it — direct instruction: just pull
 * the gray Besteloverzicht block itself up via margin-top, desktop
 * only. Shifts the whole right column (card + gift-wrap card below
 * it) up as one unit. */
@media (min-width: 1024px) {
	.wp-block-woocommerce-checkout-totals-block {
		margin-top: -3.5rem;
	}
}

/* ---- Form "steps" (contact, shipping, billing, payment, notes, terms) as premium cards ---- */
/* 2026-08-16: padding widened from 1.75rem to 2.5rem (40px) — explicit
 * reference (DevTools screenshot of another checkout's card) measured
 * at padding:40px; fields felt too wide/edge-to-edge at the old value.
 * Mobile + tablet + desktop, no page-specific override. */
.wc-block-components-checkout-step {
	background: var(--wp--preset--color--background, #fff);
	border: 1px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
	border-radius: var(--wp--custom--radius--large, 1.25rem);
	padding: 2.5rem;
	margin-bottom: 1.25rem !important;
}

.wc-block-components-checkout-step:last-of-type {
	margin-bottom: 0 !important;
}

/* !important is load-bearing (2026-08-16): renders as <h2>
 * (headingLevel="2", checkout-frontend.js), so design-system.css's
 * sitewide `h2 {font-size:...!important}` otherwise always wins
 * regardless of specificity — same root cause/fix already established
 * for .pb-pdp__summary .product_title and .wc-block-components-product-name. */
.wc-block-components-checkout-step__title {
	font-size: 20px !important;
	font-weight: 800;
	color: var(--wp--preset--color--heading, #111111);
	letter-spacing: -0.01em;
}

.wc-block-components-checkout-step__description {
	color: var(--wp--preset--color--body-text, #222222);
	font-size: var(--wp--preset--font-size--small, 0.875rem);
}

.wc-block-components-checkout-step--with-step-number .wc-block-components-checkout-step__heading-content::before {
	color: #fff;
	background: var(--wp--preset--color--primary, #6848f4);
}

/* ---- Inputs (defensive: targets the real <input>/<select> descendants directly, independent of WooCommerce's own wrapper markup) ---- */
.wc-block-components-text-input input,
.wc-block-components-text-input textarea,
.wc-block-components-address-form input,
.wc-block-components-select-input select,
.wc-block-components-country-input input,
.wc-block-components-state-input input,
.wc-block-components-totals-coupon__input input {
	border: 1.5px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
	padding: 0.9rem 1rem;
	font-size: var(--wp--preset--font-size--body, 1rem);
	background: var(--wp--preset--color--background, #fff);
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.wc-block-components-text-input label,
.wc-block-components-select-input label {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 600;
	color: var(--wp--preset--color--body-text, #222222);
}

.wc-block-components-text-input input:focus,
.wc-block-components-text-input textarea:focus,
.wc-block-components-address-form input:focus,
.wc-block-components-select-input select:focus,
.wc-block-components-country-input input:focus,
.wc-block-components-state-input input:focus,
.wc-block-components-totals-coupon__input input:focus {
	border-color: var(--wp--preset--color--primary, #6848f4);
	box-shadow: 0 0 0 3px rgba(104, 72, 244, 0.15);
	outline: none;
}

/* ---- Shipping / payment method choices ---- */
.wc-block-components-radio-control-accordion-option {
	border: 1.5px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
	padding: 1rem 1.1rem;
	margin-bottom: 0.6rem;
	transition: border-color 0.2s ease;
}

.wc-block-components-radio-control--highlight-checked .wc-block-components-radio-control-accordion-option--checked-option-highlighted {
	border-color: var(--wp--preset--color--primary, #6848f4);
}

/* ---- Terms checkbox ---- */
.wc-block-components-checkbox__mark {
	color: var(--wp--preset--color--primary, #6848f4);
}

.wc-block-components-checkbox input:checked ~ .wc-block-components-checkbox__mark {
	color: var(--wp--preset--color--primary, #6848f4);
}

/* 2026-08-16: the amount shown next to "Besteloverzicht" in the
 * toggle (.wc-block-components-checkout-order-summary__title-price) —
 * explicit request to remove it, mobile + desktop; the chevron icon
 * stays untouched. Unconditional + !important rather than relying on
 * WooCommerce's own desktop-only container-query hide rule, so this
 * holds regardless of container width. */
.wc-block-components-checkout-order-summary__title-price {
	display: none !important;
}

/* ---- Order summary card (right column) ---- */
.wp-block-woocommerce-checkout-order-summary-block {
	background: var(--wp--preset--color--surface, #f7f7f7);
	border: 1px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12)) !important;
	border-radius: var(--wp--custom--radius--large, 1.25rem) !important;
	padding: 1.75rem;
	padding-top: 1.25rem;
}

/* 2026-08-16: WooCommerce's own bundled CSS adds an extra 16px
 * margin-top on this title (unconditional, all widths) on top of the
 * card's own padding above — "Besteloverzicht" was sitting visibly
 * lower than "Contactgegevens" in the left column, which has no such
 * extra offset. Clearing it here to align the two headings. */
.wp-block-woocommerce-checkout-order-summary-block .wc-block-components-checkout-order-summary__title {
	margin-top: 0 !important;
}

/* 2026-08-16: WooCommerce Blocks renders the order summary TWICE in
 * the DOM by design — checked its own bundled checkout.css directly.
 * One copy lives in .wc-block-checkout__sidebar (reordered to the top
 * via a container-query `order:0` on mobile — the collapsible
 * "Besteloverzicht" toggle already fixed above); a second, separate
 * copy carries an extra .checkout-order-summary-block-fill-wrapper
 * class and is a plain non-collapsible full recap, inserted at a
 * different DOM position (renders further down, before the submit
 * button). WooCommerce's own CSS only ever hides this second copy on
 * desktop (`@container (min-width:700px)`); on mobile it's visible by
 * default, alongside the sidebar copy — reading as the order summary
 * appearing twice (explicit bug report + screenshot: collapsible one
 * at top, full one again just above "Plaats bestelling"). Hiding it
 * unconditionally (not just mobile-scoped) is safe: WooCommerce
 * already hides it on desktop itself, so this is only ever the active
 * rule on the mobile/narrow-container layout it was showing on. */
.wp-block-woocommerce-checkout-order-summary-block.checkout-order-summary-block-fill-wrapper {
	display: none !important;
}

.wc-block-components-checkout-order-summary__title-text,
.wp-block-woocommerce-checkout-order-summary-block .wc-block-components-title {
	font-size: var(--wp--preset--font-size--h-4, 1.3rem) !important;
	font-weight: 800 !important;
	color: var(--wp--preset--color--heading, #111111);
}

/* 2026-08-16: reverted the mobile "hide title-text" rule that used to
 * live here. Checked WooCommerce Blocks' own source
 * (checkout-frontend.js): .wc-block-components-checkout-order-summary__title-text
 * is the ONLY "Besteloverzicht" label — it IS the collapsible toggle's
 * own visible text (same <div class="...__title"> is both the
 * role="button" toggle and the text's parent), not a second/duplicate
 * element. Hiding it removed the only visible label and, combined with
 * the JS toggle-selector bug below, made the whole panel look empty on
 * mobile ("het is allemaal niet te zien op mobiel"). No CSS override
 * needed here — WooCommerce's own single title/toggle is left as-is. */

/* Cart line items: thumbnail, title, quantity badge, price.
 * .wc-block-components-order-summary-item__image had no explicit
 * size/flex-shrink of its own, so WooCommerce Blocks' default flex row
 * let the name/price text compress it down to ~23px wide (measured
 * live) whenever the description text was long enough to want the
 * space — the 48x48 <img> inside then got clipped by this wrapper's
 * own overflow:hidden into a cropped vertical sliver. flex-shrink:0 +
 * a fixed box stops the compression; object-fit:contain on the image
 * (was the browser default, "fill"/stretch) keeps the product photo's
 * own proportions intact inside that fixed box instead of stretching
 * or cropping it. */
.wc-block-components-order-summary-item__image {
	flex: 0 0 auto;
	width: 56px;
	height: 56px;
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
	overflow: hidden;
}

.wc-block-components-order-summary-item__image img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
}

/* !important is load-bearing (2026-08-16): this element renders as an
 * <h3>, so design-system.css's sitewide `h3 { font-size:1.6rem
 * !important }` rule otherwise always wins regardless of specificity —
 * same root cause/fix already established for .pb-pdp__summary
 * .product_title. */
.wc-block-components-product-name {
	font-size: 14px !important;
	font-weight: 700;
	color: var(--wp--preset--color--heading, #111111);
}

/* Quantity label ("1x", "2x", ...) injected right after the product
 * title by assets/js/woocommerce.js (pbSyncCheckoutItemQuantities) —
 * same font-family as the title (inherit), lighter weight/color and a
 * touch smaller so it reads as a modifier, not part of the title. */
.pb-checkout-item-qty {
	font-family: inherit;
	font-size: 0.85em;
	font-weight: 400;
	color: var(--wp--preset--color--muted-text, #6b6b6b);
	margin-left: 0.4em;
}

/* Order summary item: title + one price only (2026-08-16, explicit
 * request). WooCommerce Blocks natively renders two extra things per
 * item — .wc-block-components-product-metadata (short description/
 * variation text under the title) and .wc-block-components-order-
 * summary-item__individual-prices (a secondary "per unit x qty" price
 * line alongside the item's own total price, reading as the price
 * shown twice) — both hidden here, desktop + mobile, no breakpoint
 * scoping. Doesn't touch price/qty DATA, only which of WooCommerce's
 * own already-rendered price elements are visible — the one remaining
 * price is still WooCommerce's own line-item total, kept in perfect
 * sync with subtotal/shipping/tax/discount/AJAX updates. */
.wc-block-components-product-metadata,
.wc-block-components-order-summary-item__individual-prices {
	display: none;
}

/* 2026-08-16: the quantity badge (.wc-block-components-order-summary-
 * item__quantity) is a small circular badge WooCommerce Blocks
 * absolutely-positions half outside the item image's top-right corner
 * (background:currentColor, i.e. near-black here); the image wrapper's
 * own border-radius + overflow:hidden then clips the overlapping half
 * into what reads as an ugly black triangular notch (explicit bug
 * report + screenshot). The mini-cart drawer/added-to-cart popup never
 * had this (classic, non-block markup with no such overlay), so hiding
 * it here matches that already-established "clean square image" look.
 * Quantity itself isn't lost — it's already folded into the visible
 * line-item total price. !important is load-bearing: WooCommerce's own
 * rule is `.wc-block-components-order-summary .wc-block-components-order-summary-item__quantity`
 * (two classes), a higher specificity than this single-class selector,
 * so a plain declaration silently lost to it (2026-08-16 report: notch
 * still visible after the first attempt at this fix). */
.wc-block-components-order-summary-item__quantity {
	display: none !important;
}

.wc-block-components-product-badge {
	background: var(--wp--preset--color--success, #1e7a46);
	color: #fff;
	font-weight: 700;
	border-radius: var(--wp--custom--radius--pill, 999px);
	padding: 2px 8px;
}

/* Coupon area. */
.wc-block-components-totals-coupon-link {
	color: var(--wp--preset--color--primary, #6848f4);
	font-weight: 700;
}

/* 2026-08-16: full sitewide Primary CTA match (explicit request — was
 * only getting border-radius before, otherwise WooCommerce's own muted/
 * lighter default button style, reading as "different from every other
 * CTA on the site"). Same --wp--custom--button--primary--* tokens as
 * .pb-button--primary / .wc-block-components-checkout-place-order-button
 * above, so this always tracks any sitewide Customizer change with
 * nothing to keep in sync by hand. !important needed to win over
 * WooCommerce's own block CSS, same reason as the place-order button. */
.wc-block-components-totals-coupon__button {
	border-radius: var(--wp--custom--button--primary--radius, 10px) !important;
	background: var(--wp--custom--button--primary--background, #111111) !important;
	border-color: var(--wp--custom--button--primary--background, #111111) !important;
	color: var(--wp--custom--button--primary--text, #ffffff) !important;
	font-size: var(--wp--preset--font-size--button, 0.8rem) !important;
	font-weight: 700 !important;
	text-transform: var(--wp--custom--typography--button--transform, none);
	letter-spacing: 0.06em;
	opacity: 1 !important;
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.wc-block-components-totals-coupon__button:hover:not(:disabled),
.wc-block-components-totals-coupon__button:focus-visible:not(:disabled) {
	background: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	border-color: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	transform: translateY(-1px);
	box-shadow: var(--wp--custom--button--primary--shadow, 0 8px 20px rgba(17, 17, 17, 0.25));
	outline: none;
}

.wc-block-components-totals-coupon__button:active:not(:disabled) {
	background: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	border-color: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	transform: translateY(0);
}

.wc-block-components-totals-coupon__button:disabled {
	opacity: 0.6 !important;
	cursor: not-allowed;
}

/* Neutralizes WooCommerce's own separate opacity:.5 on just the inner
 * text span when disabled (packages-style.css) — it was stacking with
 * the button-level opacity:0.6 above (0.6*0.5=0.3 on text vs 0.6 on
 * background), reading as washed-out text on a still-solid pill
 * instead of a uniformly dimmed button like every other disabled CTA
 * on the site (e.g. the place-order button, which has no such inner
 * override to fight). */
.wc-block-components-totals-coupon__button:disabled .wc-block-components-button__text {
	opacity: 1 !important;
}

/* Subtotal / shipping / tax / discount rows + grand total, with clean
 * dividers — checkout only (2026-08-17: this was unscoped, leaking
 * onto the CART page too, where WooCommerce's own bundled CSS
 * deliberately resets this same wrapper's border to 0
 * (.wp-block-woocommerce-cart-order-summary-totals-block
 * .wc-block-components-totals-wrapper{border:0}) — our unscoped rule
 * was reintroducing a border WooCommerce intentionally removed there,
 * reading as random/duplicate grey lines. Scoping to checkout leaves
 * WooCommerce's own clean cart default in place. */
.wp-block-woocommerce-checkout .wc-block-components-totals-wrapper {
	border-top: 1px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
}

.wc-block-components-totals-item {
	font-size: 14px;
	color: var(--wp--preset--color--body-text, #222222);
}

.wc-block-components-totals-footer-item .wc-block-components-totals-item__value,
.wc-block-components-totals-footer-item .wc-block-components-totals-item__label {
	font-size: 14px;
	font-weight: 800;
	color: var(--wp--preset--color--heading, #111111);
}

.wc-block-components-totals-discount .wc-block-components-totals-item__value {
	color: var(--wp--preset--color--success, #1e7a46);
}

/* ---- "Place order" CTA (2026-07-17: was a hardcoded green success
 * color, !important, that didn't match the sitewide Primary CTA
 * anywhere else on the site) — same --wp--custom--button--primary--*
 * tokens .pb-button--primary itself uses (design-system.css), not a
 * new checkout-specific color: background/hover/active all read that
 * one source, so this always matches every other Primary CTA,
 * including any Customizer override, with nothing to keep in sync by
 * hand. !important still required to win over WooCommerce's own block
 * CSS (unchanged reason from before); border-radius/padding/
 * typography/transitions/disabled-opacity are all untouched. */
.wc-block-components-checkout-place-order-button {
	width: 100%;
	display: flex;
	justify-content: center;
	padding: 1.1rem 1.5rem !important;
	border-radius: var(--wp--custom--button--primary--radius, 10px) !important;
	background: var(--wp--custom--button--primary--background, #111111) !important;
	border-color: var(--wp--custom--button--primary--background, #111111) !important;
	color: var(--wp--custom--button--primary--text, #ffffff) !important;
	font-size: var(--wp--preset--font-size--button, 0.8rem);
	font-weight: 700;
	text-transform: var(--wp--custom--typography--button--transform, none);
	letter-spacing: 0.06em;
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.wc-block-components-checkout-place-order-button:hover:not(:disabled),
.wc-block-components-checkout-place-order-button:focus-visible:not(:disabled) {
	background: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	border-color: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	transform: translateY(-1px);
	box-shadow: var(--wp--custom--button--primary--shadow, 0 8px 20px rgba(17, 17, 17, 0.25));
	outline: none;
}

.wc-block-components-checkout-place-order-button:active:not(:disabled) {
	background: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	border-color: var(--wp--custom--button--primary--hover-background, #2b2b2b) !important;
	transform: translateY(0);
}

.wc-block-components-checkout-place-order-button:disabled,
.wc-block-components-checkout-place-order-button--loading {
	opacity: 0.6;
	cursor: wait;
}

.wc-block-components-checkout-return-to-cart-button {
	color: var(--wp--preset--color--body-text, #222222);
}

/* ---- Express payment area: no fake providers, just reserve clean spacing for whenever WooCommerce/a gateway renders real buttons here. ---- */
.wp-block-woocommerce-checkout-express-payment-block:not(:empty) {
	margin-bottom: 1.5rem;
}

.wc-block-components-express-payment-continue-rule {
	color: var(--wp--preset--color--body-text, #222222);
	opacity: 0.6;
}

/* ---- Checkout gift-wrap upsell (pb_wc_checkout_render_gift_wrap_upsell(), inc/woocommerce-checkout.php) — same compact horizontal-card language as the PDP's own "Past goed bij" cards (.pb-pdp-upsell__card), scaled down for the narrower checkout sidebar column. ---- */
.pb-checkout-upsell {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin-top: 0.75rem;
	margin-bottom: 1.5rem;
	padding: 0.85rem 1rem;
	background: var(--wp--preset--color--background, #fff);
	border: 1px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
	border-radius: var(--wp--custom--radius--large, 1.25rem);
}

.pb-checkout-upsell__media {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
	overflow: hidden;
	background: var(--wp--preset--color--surface, #f7f7f7);
}

.pb-checkout-upsell__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

.pb-checkout-upsell__body {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
}

.pb-checkout-upsell__eyebrow {
	font-size: var(--wp--preset--font-size--label, 0.75rem);
	color: var(--wp--preset--color--muted-text, #6b6b6b);
}

.pb-checkout-upsell__name {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 700;
	color: var(--wp--preset--color--heading, #111111);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.pb-checkout-upsell__price {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	color: var(--wp--preset--color--body-text, #222222);
}

.pb-checkout-upsell__add {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	border: none;
	border-radius: 999px;
	background: var(--wp--preset--color--secondary, #111111);
	color: #fff;
	font-size: 1.1rem;
	font-family: inherit;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	padding: 0;
	transition: transform 0.2s ease, filter 0.2s ease;
}

.pb-checkout-upsell__add:disabled {
	opacity: 0.6;
	cursor: wait;
}

.pb-checkout-upsell__add:hover,
.pb-checkout-upsell__add:focus-visible {
	transform: scale(1.06);
	filter: brightness(1.2);
	outline: none;
}

/* ---- Enabled gift-wrap add-on card (pb_wc_checkout_render_gift_wrap_addon_card(), inc/woocommerce-checkout.php) — replaces the plain "Label: price" item-data text line in the order summary once the add-on is on. ---- */
.pb-checkout-addon-card {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	margin-top: 0.75rem;
	margin-bottom: 1.5rem;
	padding: 0.75rem 1rem;
	background: var(--wp--preset--color--surface, #f7f7f7);
	border: 1px solid var(--wp--preset--color--border, rgba(17, 17, 17, 0.12));
	border-radius: var(--wp--custom--radius--large, 1.25rem);
}

.pb-checkout-addon-card__media {
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	border-radius: var(--wp--custom--radius--medium, 0.75rem);
	overflow: hidden;
	background: #fff;
}

.pb-checkout-addon-card__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

/* Now a real <button> (was a plain <span>) so it's clickable to remove
 * the add-on again — this reset keeps it visually identical to the
 * span it replaced (no border/background/padding, cursor:pointer is
 * the only added affordance). */
.pb-checkout-addon-card__check {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.25rem;
	height: 1.25rem;
	color: var(--wp--preset--color--primary, #6848f4);
	background: none;
	border: none;
	padding: 0;
	margin: 0;
	font: inherit;
	cursor: pointer;
}

.pb-checkout-addon-card__check:disabled {
	cursor: wait;
	opacity: 0.6;
}

.pb-checkout-addon-card__check svg {
	width: 100%;
	height: 100%;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.pb-checkout-addon-card__body {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
}

.pb-checkout-addon-card__title {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 700;
	color: var(--wp--preset--color--heading, #111111);
}

.pb-checkout-addon-card__desc {
	font-size: var(--wp--preset--font-size--label, 0.75rem);
	color: var(--wp--preset--color--muted-text, #6b6b6b);
}

.pb-checkout-addon-card__price {
	flex: 0 0 auto;
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 700;
	color: var(--wp--preset--color--heading, #111111);
}

@media (prefers-reduced-motion: reduce) {
	.wc-block-components-checkout-place-order-button,
	.wc-block-components-text-input input,
	.wc-block-components-radio-control-accordion-option {
		transition: none;
	}
}

/* ==========================================================================
 * My Account — native templates (form-login, my-account nav, orders
 * table, addresses, edit-account). Presentation only.
 * ========================================================================*/
/*
 * My Account reads best as a centered dashboard rather than a
 * full-bleed grid — narrower than Shop/PDP, overriding the general
 * full-bleed rule above specifically for this body class.
 */
body.woocommerce-account .site-main {
	max-width: 60rem;
	margin: 0 auto;
	padding: var(--wc-section-spacing) 1.25rem;
}

.woocommerce-account .woocommerce {
	display: block;
}

.woocommerce-MyAccount-navigation {
	margin-bottom: 2rem;
}

.woocommerce-MyAccount-navigation ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.woocommerce-MyAccount-navigation ul li {
	margin: 0;
}

.woocommerce-MyAccount-navigation ul li a {
	display: inline-flex;
	align-items: center;
	padding: 0.6rem 1.1rem;
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-button);
	font-size: var(--wc-font-body-sm);
	font-weight: 600;
	color: var(--wc-secondary);
	transition: border-color 0.2s ease, background-color 0.2s ease;
}

.woocommerce-MyAccount-navigation ul li.is-active a {
	background: var(--wc-secondary);
	border-color: var(--wc-secondary);
	color: #fff;
}

.woocommerce-MyAccount-navigation ul li a:hover,
.woocommerce-MyAccount-navigation ul li a:focus-visible {
	border-color: var(--wc-secondary);
	outline: none;
}

.woocommerce-MyAccount-content {
	max-width: 46rem;
}

.woocommerce-MyAccount-content > p:first-child {
	background: var(--wc-surface);
	padding: 1.25rem 1.5rem;
	border-radius: var(--wc-radius-card);
}

.woocommerce table.shop_table,
.woocommerce-MyAccount-orders,
.account-orders-table {
	border-collapse: separate;
	border-spacing: 0;
	width: 100%;
	font-size: var(--wc-font-body-sm);
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-card);
	overflow: hidden;
}

.woocommerce table.shop_table th {
	background: var(--wc-surface);
	text-align: left;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 0.7rem;
	padding: 1rem;
}

.woocommerce table.shop_table td {
	padding: 1rem;
	border-top: 1px solid var(--wc-border);
}

.woocommerce-Addresses {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
}

@media (min-width: 640px) {
	.woocommerce-Addresses {
		grid-template-columns: repeat(2, 1fr);
	}
}

.woocommerce-Address {
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-card);
	padding: 1.5rem;
}

.woocommerce-Address-title {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 0.75rem;
}

.woocommerce-Address-title h3 {
	font-size: var(--wc-font-body);
	margin: 0;
}

.woocommerce form .form-row {
	margin-bottom: 1.25rem;
}

/* ==========================================================================
 * Mobile PDP gallery — vertical scroll vs. horizontal swipe.
 *
 * This PDP does NOT use WooCommerce's native FlexSlider/PhotoSwipe
 * gallery — woocommerce_show_product_images() is explicitly unhooked
 * (inc/woocommerce-product-page.php) and replaced by the theme's own
 * pb_render_pdp_gallery(), a plain "one .is-active image + thumbnail
 * rail" structure with its own swipe handling in assets/js/woocommerce.js.
 * touch-action: pan-y tells the browser to always own vertical panning
 * on the main image natively, so JS's own axis-lock touchmove handler
 * (which only ever preventDefault()s once a gesture has clearly resolved
 * horizontal) can never be raced by a vertical scroll. Mobile/tablet-only
 * media query is cosmetic here — touch-action never affects desktop's
 * mouse-driven interaction — kept for parity with "mobile gallery" scope. */
@media (max-width: 1023.98px) {
	.pb-pdp-gallery__main {
		touch-action: pan-y;
	}
}

/* Fullscreen mobile/tablet lightbox (assets/js/woocommerce.js) — built
 * at runtime by cloning the same <img>/<video> elements already in
 * .pb-pdp-gallery__main (same src/srcset/alt, so no re-fetch and no
 * duplicated gallery data), not a second gallery/slider library. Reuses
 * the exact same axis-lock swipe handler as the main gallery. */
.pb-pdp-gallery__lightbox {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 9999;
	background: #000;
	/* pan-y (not plain pan-y alone) + pinch-zoom: keeps vertical panning
	 * native and horizontal panning reserved for the JS swipe-nav (see
	 * attachSwipeNav(), assets/js/woocommerce.js), while still letting
	 * the browser's own native pinch gesture zoom the visual viewport —
	 * "pan-y" alone (the main gallery's own value) blocks pinch-zoom
	 * entirely, which is exactly why it didn't work here before. */
	touch-action: pan-y pinch-zoom;
}

.pb-pdp-gallery__lightbox.is-open {
	display: flex;
	align-items: center;
	justify-content: center;
}

.pb-pdp-gallery__lightbox-image {
	display: none;
	/* width/height:100% (not auto+max-*) — same fix as the main gallery
	 * image: a video clone in particular has no reliably-loaded intrinsic
	 * size the instant it's inserted (a fresh <video> only knows its real
	 * dimensions once its own metadata loads, defaulting to the HTML spec's
	 * 300x150 fallback until then), so width:auto/height:auto rendered it
	 * at that tiny default instead of the fullscreen box — max-width/
	 * max-height:100% only ever caps a *larger* size down, it never scales
	 * a smaller one up. Explicit 100%/100% + object-fit:contain fills the
	 * box either way, for both <img> and <video>, no crop. */
	width: 100%;
	height: 100%;
	object-fit: contain;
	margin: auto;
}

.pb-pdp-gallery__lightbox-image.is-active {
	display: block;
}

.pb-pdp-gallery__lightbox-close {
	position: absolute;
	top: max(1rem, env(safe-area-inset-top));
	right: 1rem;
	width: 2.75rem;
	height: 2.75rem;
	border: none;
	background: rgba(255, 255, 255, 0.12);
	border-radius: 999px;
	cursor: pointer;
	z-index: 1;
}

.pb-pdp-gallery__lightbox-close::before,
.pb-pdp-gallery__lightbox-close::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 1.1rem;
	height: 2px;
	background: #fff;
	transform: translate(-50%, -50%) rotate(45deg);
}

.pb-pdp-gallery__lightbox-close::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.pb-pdp-gallery__lightbox .pb-pdp-gallery__arrow {
	z-index: 1;
}

.woocommerce-EditAccountForm fieldset,
.woocommerce-Address fieldset {
	border: 1px solid var(--wc-border);
	border-radius: var(--wc-radius-card);
	padding: 1.5rem;
	margin-top: 1.5rem;
}

/* ==========================================================================
   shirt-test PDP swatches (2026-10-12) — pb/woocommerce-shirt-test-pdp.php.
   Scoped under body.postid-{shirt-test-id} as a second safety net (the
   markup itself only ever renders on this one product's page anyway).
   ========================================================================== */
.pb-shirt-test-swatches {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	margin: 1rem 0 1.5rem;
}

.pb-shirt-test-swatches__label {
	display: block;
	margin-bottom: 0.5rem;
	font-size: 0.85rem;
	font-weight: 600;
	color: #111111;
}

.pb-shirt-test-swatches__options {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

/* Color swatches — round, selected gets a dark offset ring. */
.pb-shirt-test-swatches__swatch {
	width: 28px;
	height: 28px;
	border-radius: 50%;
	border: 2px solid transparent;
	box-shadow: 0 0 0 1px rgba( 0, 0, 0, 0.12 );
	padding: 0;
	cursor: pointer;
	transition: box-shadow 0.15s ease;
}

.pb-shirt-test-swatches__swatch.is-selected {
	border-color: #ffffff;
	box-shadow: 0 0 0 2px #111111;
}

.pb-shirt-test-swatches__swatch:disabled {
	opacity: 0.3;
	cursor: not-allowed;
}

/* Size buttons — square, selected = dark fill. */
.pb-shirt-test-swatches__size {
	min-width: 44px;
	height: 40px;
	padding: 0 0.5rem;
	border: 1px solid #d8d6d2;
	border-radius: 2px;
	background-color: #ffffff;
	color: #111111;
	font-size: 0.85rem;
	font-weight: 500;
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.pb-shirt-test-swatches__size:hover:not(:disabled):not(.is-selected) {
	border-color: #111111;
}

.pb-shirt-test-swatches__size.is-selected {
	background-color: #111111;
	border-color: #111111;
	color: #ffffff;
}

.pb-shirt-test-swatches__size:disabled {
	background-color: #f5f4f2;
	border-color: #ebe9e6;
	color: #b8b6b2;
	cursor: not-allowed;
}

@media ( max-width: 767.98px ) {
	.pb-shirt-test-swatches {
		margin: 0.85rem 0 1.25rem;
	}
}

/* Option buttons for quantity-style choices ("Aantal: 1 voor €5,-",
 * 2026-10-19) — same look as size buttons, a bit wider for the text. */
.pb-shirt-test-swatches__group--option .pb-shirt-test-swatches__size {
	padding: 0 0.9rem;
	white-space: nowrap;
}

/* PDP gallery video sound toggle (2026-10-19) — round button bottom-left
 * over the main media (the prev/next arrows sit bottom-right), only
 * visible while a video is the active item (assets/js/woocommerce.js). */
.pb-pdp-gallery__main {
	position: relative;
}

.pb-pdp-gallery__sound {
	position: absolute;
	left: 14px;
	bottom: 14px;
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: rgba( 255, 255, 255, 0.92 );
	color: #111111;
	box-shadow: 0 2px 8px rgba( 0, 0, 0, 0.18 );
	cursor: pointer;
}

.pb-pdp-gallery__sound[hidden] {
	display: none;
}

.pb-pdp-gallery__sound .material-symbols-rounded {
	font-size: 22px;
	line-height: 1;
}

.pb-pdp-gallery__sound:focus-visible {
	outline: 2px solid #111111;
	outline-offset: 2px;
}

/* Pack pricing (Buttons, 2026-10-19): the pack combination under the
 * combined price, e.g. "1× 4 voor €16,- + 1× 2 voor €8,-". */
.pb-pack-breakdown {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.8rem;
	font-weight: 400;
	color: #6b6b6b;
}
