/**
 * 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 {
		padding-top: 1rem;
	}

	.pb-pdp .woocommerce-breadcrumb {
		margin-bottom: 0.5rem;
	}
}

/* ---- 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;
	}

	.pb-pdp__summary .product_title {
		order: 1;
	}

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

	.pb-pdp__summary p.price,
	.pb-pdp__summary span.price,
	.pb-pdp__summary p.stock {
		order: 3;
	}

	.pb-pdp__summary .pb-pdp-trustpilot-row {
		order: 4;
	}

	.pb-pdp__gallery {
		order: 5;
	}

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

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

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

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

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

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

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

/* ---- 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(720px, 70vh);
	}
}

/* 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) and a square
 * aspect ratio tied to the viewport width instead of the old fixed
 * 20rem min-height, which read as small/cramped next to a full-width
 * photo. Placed after the base/desktop rules above so it actually wins
 * at this breakpoint (same lesson as the padding-top fix above:
 * same-selector, same-specificity rules resolve by source order, not
 * by media query alone). */
@media (max-width: 1023.98px) {
	.pb-pdp__gallery {
		width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: calc(50% - 50vw);
	}

	.pb-pdp-gallery__main {
		min-height: 0;
	}
}

/* Mobile: the image was still small inside its full-width frame because
 * .pb-pdp-gallery__image (base rule above) uses width:auto/height:auto
 * capped by max-width/max-height:100% — against an intrinsic-height
 * parent that only ever wraps tightly to the image's own natural
 * rendered size, "100%" never has a real box to cap against, so the
 * image just rendered at whatever size its own aspect ratio produced at
 * the available width, however small that left it vertically.
 *
 * A *fixed* box height (an earlier version of this rule used 80vh) only
 * exactly fits photos that happen to share that one ratio — every other
 * photo (still never cropped, object-fit:contain) then renders smaller
 * than the box, and the leftover box area is blank, reading as unwanted
 * white space. assets/js/woocommerce.js now sets this element's own
 * aspect-ratio (inline style) to match whichever photo/video is actually
 * active, so the box always matches its content exactly — height:auto
 * here lets that aspect-ratio drive the real height, max-height is only
 * a safety cap for an unusually tall/narrow source photo. */
@media (max-width: 767px) {
	.pb-pdp-gallery__main {
		height: auto;
		/* Neutral starting guess only — JS overrides this via inline
		 * style the moment the active photo/video's real dimensions are
		 * known, which always wins over this stylesheet rule. Just avoids
		 * a layout jump on first paint before that runs. */
		aspect-ratio: 4 / 5;
		max-height: 80vh;
	}

	.pb-pdp-gallery__image {
		width: 100%;
		height: 100%;
		padding: 0.25rem;
	}
}

/* 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.
 * Colours/radius/font reuse the same --wc-* tokens the Design System's
 * own button rule uses (assets/css/woocommerce.css, "Buttons" section
 * above) for visual consistency, without touching that rule itself. */
.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;
	}

	/* Uses the same global Primary CTA tokens as .pb-button--primary
	 * (assets/css/design-system.css) — mobile-only scope, radius/
	 * padding/typography kept as-is per this bar's own design. */
	.pb-pdp-sticky-cta__button {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		padding: 0.9rem 1.75rem;
		border: none;
		border-radius: var(--wc-radius-button, 999px);
		background: var(--wp--custom--button--primary--background, #6848f4);
		color: var(--wp--custom--button--primary--text, #ffffff);
		font-family: inherit;
		font-size: var(--wc-font-button, 0.8rem);
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.06em;
		cursor: pointer;
		transition: background-color var(--wp--custom--button--primary--transition, 0.25s cubic-bezier(0.4, 0, 0.2, 1));
	}

	.pb-pdp-sticky-cta__button:hover,
	.pb-pdp-sticky-cta__button:focus-visible {
		background: var(--wp--custom--button--primary--hover-background, #7e6fef);
		color: var(--wp--custom--button--primary--hover-text, #ffffff);
		outline: none;
	}
}

/* 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;
		/* Was 3rem (48px, from the base rule above) — halved to bring
		 * the main image 24px closer to the thumbnail column. Top/
		 * right/bottom padding and the margin:0 auto centering
		 * mechanism are untouched. */
		padding-left: 1.5rem;
	}
}

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

/* Minimal mobile padding so the photo genuinely fills the now-100vw
 * frame (true Nike-style edge-to-edge feel) instead of desktop's
 * generous 3rem — object-fit:contain (above) means the photo is never
 * cropped regardless of how small this padding is. Placed after the
 * base rule above (and after the desktop-only padding-top:0 override),
 * since a previous attempt at this exact override was placed earlier
 * in the file and got silently cancelled by the base rule's later
 * source-order position — same lesson noted throughout this file. */
@media (max-width: 1023.98px) {
	.pb-pdp-gallery__image {
		padding: 0.5rem;
	}
}

/* Vertical thumbnail rail, far left, on desktop; a horizontal strip
 * under the main image on phones/tablets (easier to use/scroll there).
 * Same >=1024px breakpoint as the two-column hero itself, so there's
 * no in-between tablet state with a desktop-style rail inside an
 * otherwise still-stacked mobile layout. */
.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 {
		padding-left: 2px;
	}
}

/* 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;
	}

	.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;
}

.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: 30px !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;
}

/* Trustpilot review row (hero) + "Bekijk alle reviews" on the same
 * line — see pb_wc_render_pdp_trustpilot_row() (inc/woocommerce-product-page.php).
 * Renders a real Trustpilot TrustBox widget once a Business Unit ID
 * is configured (Appearance -> Customize -> Trustpilot); until then, a
 * plain, honest placeholder — never an invented score. flex-wrap lets
 * the widget and the review link wrap onto their own line on very
 * narrow screens while staying directly under the title either way. */
.pb-pdp-trustpilot-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	margin: 0 0 1.5rem;
}

/* Both the real-widget slot and the placeholder share the exact same
 * fixed height/min-width, so the layout is identical either way —
 * switching from placeholder to the real TrustBox (once Trustpilot is
 * connected) never shifts anything around it. 24px matches the
 * official TrustBox "Mini" template's own height. */
.pb-pdp-trustpilot-row__widget,
.pb-pdp-trustpilot-row__placeholder {
	display: flex;
	align-items: center;
	height: 24px;
	min-width: 13rem;
}

.pb-pdp-trustpilot-row__placeholder {
	font-size: var(--wc-font-body-sm);
	color: var(--wc-muted-text);
	font-style: italic;
}

/* 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: 0 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;
}

/* Featured option only (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). The other option(s) keep the
 * default border above untouched. */
.pb-pdp-bundle__option:has( .pb-pdp-bundle__badge ) {
	border-color: #d9d9d9;
}

.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__option.is-selected,
.pb-pdp-bundle__option:has( input:checked ) {
	border-color: var(--wc-primary);
	box-shadow: var(--wc-shadow-card);
}

.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. */
.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: 999px;
	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;
}

/* 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 0;
	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));
}

/* 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-trustpilot-row {
		margin-bottom: 0.25rem;
	}

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

	.pb-wc-trust-rows {
		margin-top: 0.25rem;
		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). */
		font-size: 25px !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 {
		font-size: 20px;
	}
}

/* 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);
}

.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;
}

/* ==========================================================================
 * "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;
}

.pb-mini-cart-drawer__title {
	font-size: var(--wc-font-heading-md);
	font-weight: 800;
	margin: 0;
}

.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 itself no longer scrolls (2026-07-08 fix) — it used
 * to, which meant the checkout button's position depended entirely on
 * how much content (mainly the upsell card) came before it: with no
 * upsell it sat right under a short item list, with one it sat
 * noticeably lower. Only ul.cart_list now scrolls internally
 * (flex:1 1 auto below); everything after it (upsell, subtotal,
 * shipping, buttons) keeps its natural size and stays pinned at a
 * fixed position at the bottom of the drawer regardless of item count
 * or whether the upsell renders at all. Any leftover vertical space
 * when there isn't enough content to fill the drawer now shows up
 * inside the (flex-grown) item list area, above the totals — never
 * below the buttons. */
.pb-mini-cart-drawer__body {
	flex: 1;
	overflow: hidden;
	padding: 1.5rem;
	display: flex;
	flex-direction: column;
}

.pb-mini-cart-drawer__body ul.cart_list,
.pb-mini-cart-drawer__body ul.product_list_widget {
	order: 1;
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

/* 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;
	grid-template-columns: 4.5rem 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;
	/* Explicit end line (not 1 / -1): the add-on card below is its own,
	 * full-width 4th row (see .pb-mini-cart-item__addons) and must not
	 * have the product thumbnail stretch down to cover it too. */
	grid-row: 1 / 4;
	align-self: start;
	width: 4.5rem;
	height: 4.5rem;
	object-fit: cover;
	border-radius: var(--wc-radius-input);
}

.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: 700;
	font-size: var(--wc-font-body-sm);
	color: var(--wc-heading);
	padding-right: 1.75rem;
}

.pb-mini-cart-drawer__body ul.cart_list li dl.variation {
	grid-column: 2;
	font-size: 0.75rem;
	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);
}

.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;
}

/* Product add-on(s) (e.g. gift wrap) — full-width 4th grid row below
 * the quantity stepper. Generic layer: pb_wc_get_product_addons()
 * decides per product whether anything renders here at all; most
 * products have none, in which case .pb-mini-cart-item__addons is
 * simply never output. */
.pb-mini-cart-item__addons {
	grid-column: 1 / 3;
	grid-row: 4;
	margin-top: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.pb-mini-cart-addon {
	display: grid;
	grid-template-columns: auto 3.5rem 1fr;
	align-items: center;
	gap: 0.85rem;
	background: var(--wc-surface);
	border-radius: 1.125rem;
	padding: 1rem;
	cursor: pointer;
}

.pb-mini-cart-addon__checkbox {
	width: 1.15rem;
	height: 1.15rem;
	margin: 0;
	accent-color: var(--wc-primary);
	cursor: pointer;
}

.pb-mini-cart-addon__image {
	display: block;
	width: 3.5rem;
	height: 3.5rem;
	object-fit: cover;
	border-radius: 0.65rem;
}

.pb-mini-cart-addon__text {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	min-width: 0;
}

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

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

.pb-mini-cart-addon__price {
	font-size: 0.8rem;
	font-weight: 600;
	color: var(--wc-heading);
	margin-top: 0.1rem;
}

/* Upsell rail ("Past goed bij") — products come from each cart item's
 * own native Upsells field, see pb_wc_get_cart_upsells(). 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. */
.pb-mini-cart-upsell {
	order: 2;
	flex-shrink: 0;
	margin-top: 1.25rem;
	padding-top: 1rem;
	border-top: 1px solid var(--wc-border);
}

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

.pb-mini-cart-upsell__track {
	display: flex;
	gap: 0.75rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	padding-bottom: 0.15rem;
}

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

.pb-mini-cart-upsell__track--fit .pb-mini-cart-upsell__item,
.pb-mini-cart-upsell__track--scroll .pb-mini-cart-upsell__item {
	flex: 0 0 14.5rem;
	scroll-snap-align: start;
}

.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;
}

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

.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__name {
	grid-column: 2;
	grid-row: 1;
	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;
}

.pb-mini-cart-upsell__price {
	grid-column: 2;
	grid-row: 2;
	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: this element 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. */
.pb-mini-cart-drawer .pb-mini-cart-upsell__add {
	grid-column: 3;
	grid-row: 1 / 3;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.85rem;
	height: 1.85rem;
	border-radius: 999px;
	background: var(--wc-primary);
	color: #fff;
	flex-shrink: 0;
	transition: opacity 0.2s ease;
}

.pb-mini-cart-upsell__add:hover,
.pb-mini-cart-upsell__add:focus-visible {
	opacity: 0.85;
	outline: none;
}

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

/* 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;
	margin-top: 1.75rem;
	padding-top: 1.5rem;
	border-top: 1px solid var(--wc-border);
	font-size: 1.05rem;
	font-weight: 700;
	display: flex;
	justify-content: space-between;
}

.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);
	margin: 0.5rem 0 0;
}

/* 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.75rem;
	margin-top: 2.5rem;
}

.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;
	}
}

/* ==========================================================================
 * 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);
}

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

.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;
}

/* ==========================================================================
 * 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;
	}
}

/* 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;
	}
}

/* ---- Form "steps" (contact, shipping, billing, payment, notes, terms) as premium cards ---- */
.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: 1.75rem;
	margin-bottom: 1.25rem !important;
}

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

.wc-block-components-checkout-step__title {
	font-size: var(--wp--preset--font-size--h-4, 1.3rem);
	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);
}

/* ---- 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;
}

.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);
}

/* 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);
}

.wc-block-components-product-name {
	font-weight: 700;
	color: var(--wp--preset--color--heading, #111111);
}

.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;
}

.wc-block-components-totals-coupon__button {
	border-radius: var(--wp--custom--radius--pill, 999px) !important;
}

/* Subtotal / shipping / tax / discount rows + grand total, with clean dividers. */
.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: var(--wp--preset--font-size--body, 1rem);
	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: var(--wp--preset--font-size--h-4, 1.3rem);
	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--radius--pill, 999px) !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: 1.25rem;
	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: 1.25rem;
	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;
}
