/*
 * WooProductPages Pro - the product page.
 *
 * THREE RULES, AND THEY ARE THE WHOLE DESIGN.
 *
 * 1. Every colour, corner and typeface in here is a variable. Not one literal colour is typed
 *    below. A product that looks different has different values for the same names; no css is
 *    ever written for a particular product. The page this replaces printed its colours inline at
 *    render time, which landed them after the theme and made them unbeatable, so styling one page
 *    repainted another. A variable cannot do that.
 *
 * 2. Everything is scoped to `.wpp .wpp-product.product`, and that compound is deliberate rather
 *    than decorative. WooCommerce's own stylesheet uses selectors like
 *    `.woocommerce div.product p.price`, which outweighs a plainly scoped rule - so the price came
 *    out WooCommerce green and the button WooCommerce purple while the settings said otherwise.
 *    Three classes of base weight beats it honestly. NOT ONE !important IS USED: the page this
 *    replaces was full of them, and they are why a change in one place broke the look in another.
 *
 * 3. Layout choices arrive as classes from a fixed list. One static rule per choice, written once.
 */

/* ----------------------------------------------------------------- the page ---- */

.wpp {
	background: var(--wpp-surface-deep);
	color: var(--wpp-text);
	/* Follows the look, so the browser's own widgets - scrollbars, form controls, the colour
	   picker - match the page instead of fighting it. */
	color-scheme: var(--wpp-scheme, dark);
	font-family: var(--wpp-font-body);
	/* clip, not hidden: hidden would make this a scroll container and stop the buy box from
	   sticking. This is here so a full-width band cannot put a sideways scrollbar on the page. */
	overflow-x: clip;
	/* Makes cqw mean one percent of THIS, so spacing answers to the product area rather than to
	   the browser window. See the note on the gutter setting. */
	container-type: inline-size;
}

.wpp .wpp-product.product {
	width: min(100% - 2 * var(--wpp-gutter, 5vw), var(--wpp-container, 1280px));
	margin-inline: auto;
	padding-block: var(--wpp-gutter, 5vw);
	font-family: var(--wpp-font-body);
}

.wpp .wpp-product.product h1,
.wpp .wpp-product.product h2,
.wpp .wpp-product.product h3 {
	font-family: var(--wpp-font-heading);
}

.wpp .wpp-product.product a {
	color: var(--wpp-accent);
}
.wpp .wpp-product.product a:hover {
	color: var(--wpp-accent-hover);
}

/* ------------------------------------------------------------------- the trail ---- */

.wpp .wpp-top {
	/* Above the band, so a trail is never painted over by a picture. */
	position: relative;
	z-index: 2;
	width: min(100% - 2 * var(--wpp-gutter, 5vw), var(--wpp-container, 1280px));
	margin-inline: auto;
	padding-block: clamp(0.85rem, 1.6vw, 1.3rem);
	font-size: var(--wpp-crumb-size, 0.75rem);
	letter-spacing: var(--wpp-crumb-spacing, 0.08em);
	text-transform: var(--wpp-crumb-transform, uppercase);
	color: var(--wpp-text-muted);
}
.wpp .wpp-top:empty { display: none; }
.wpp .wpp-top .woocommerce-breadcrumb { margin: 0; color: var(--wpp-text-muted); }
.wpp .wpp-top a { color: var(--wpp-text-muted); text-decoration: none; }
.wpp .wpp-top a:hover { color: var(--wpp-text); }

/*
 * After a trail, the product's top padding is exactly the band's reach.
 *
 * These two have to be the same value or they cannot line up, and when they do not line up the
 * top edge of the picture cuts across the middle of the trail - which is what it did. Tying both
 * to one variable means a change to either keeps them flush.
 */
.wpp .wpp-top + .wpp-product.product { padding-top: var(--wpp-band-bleed, 2rem); }

/* -------------------------------------------------------- photos and buy box ---- */

/*
 * Two columns that become one without a media query.
 *
 * A breakpoint cannot be a variable - @media cannot read var() - so the stacking point is
 * expressed as the narrowest a column may get before the row wraps, which is half the chosen
 * width. That keeps the setting a setting instead of a number baked in here.
 *
 * The split is flex-grow, NOT flex-basis. Basis percentages were the first attempt and they were
 * wrong: 52% and 44% is 96%, and with a gap on top of it that exceeds the row, so the columns
 * wrapped and the buy box fell underneath the photographs on every screen size. Growth ratios
 * divide what is left after the gap, so the gap can never cause a wrap.
 */
/*
 * The band behind the photos and the buy box.
 *
 * Drawn as a pseudo-element rather than a background on .wpp-shop itself, because .wpp-shop is
 * centred inside a container with a maximum width - a background on it would stop at the edge of
 * that container instead of running the full width of the window.
 *
 * The tint is a second background layer over the picture, not a separate element, so it scrolls
 * and scales with it and there is nothing to keep in step.
 */
/*
 * TWO LAYERS, NOT ONE.
 *
 * The picture and the colour over it were a single element with two background layers, which
 * meant anything done to the picture was done to the colour as well - blur it and the tint
 * smears with it. They are separate elements now, stacked in the same box: ::before carries the
 * picture, ::after carries the colour over it.
 *
 * The blur is backdrop-filter on the layer ABOVE rather than filter on the picture itself, and
 * that is deliberate: a blurred background-image samples past its own edges and fades out at the
 * sides, while a backdrop-filter samples what is actually behind it and has no edge to fade.
 */
.wpp .wpp-product.wpp-has-bg .wpp-shop::before,
.wpp .wpp-product.wpp-has-bg .wpp-shop::after {
	content: "";
	position: absolute;
	left: 50%;
	width: 100vw;
	margin-left: -50vw;
	/*
	 * Reaches a little above the row and a long way below it.
	 *
	 * It used to reach a full gutter above, which is 70px at this width, and that put it on top
	 * of the breadcrumb - the trail rendered correctly and was simply painted over. Anything
	 * placed above the row has to stay clear of the band, so how far it reaches is a setting.
	 */
	top: calc(-1 * var(--wpp-band-bleed, 2rem));
	bottom: calc(-1 * var(--wpp-band-bleed-bottom, 4rem));
	pointer-events: none;
	z-index: 0;
}

.wpp .wpp-product.wpp-has-bg .wpp-shop::before {
	background-image: var(--wpp-shop-bg);
	background-size: var(--wpp-shop-bg-size, cover);
	background-position: var(--wpp-shop-bg-position, center);
	background-repeat: no-repeat;
}

.wpp .wpp-product.wpp-has-bg .wpp-shop::after {
	background-image: linear-gradient(
		180deg,
		var(--wpp-shop-tint-top) 0%,
		var(--wpp-shop-tint-mid) 45%,
		var(--wpp-shop-tint-bottom) 100%
	);
	backdrop-filter: blur(var(--wpp-shop-bg-blur, 0px));
}

/* Everything in the row sits on top of the band. */
.wpp .wpp-product.wpp-has-bg .wpp-shop > * { position: relative; z-index: 1; }

.wpp .wpp-product.product .wpp-shop {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wpp-gap, 3.5vw);
	align-items: flex-start;
}

.wpp .wpp-product.product .wpp-shop > * {
	flex: 1 1 0;
	min-width: min( calc( (var(--wpp-stack-at, 900px) - var(--wpp-gap, 3.5vw)) / 2 ), 100% );
}

/*
 * These have to out-weigh `.wpp .wpp-product.product .wpp-shop > *` above, which sets
 * `flex: 1 1 0` - a SHORTHAND, so it writes flex-grow:1 - and carries four classes plus an
 * element. At three classes these rules lost every time and the split setting did nothing at
 * all: the columns came out 611/600 where the design is 621/562. Nothing looked broken, which
 * is why it survived until the two pages were measured against each other.
 */
.wpp .wpp-product.product.wpp-split-even .wpp-shop > .wpp-media { flex-grow: 1; }
.wpp .wpp-product.product.wpp-split-even .wpp-shop > .wpp-summary { flex-grow: 1; }
.wpp .wpp-product.product.wpp-split-media .wpp-shop > .wpp-media { flex-grow: 1.1; }
.wpp .wpp-product.product.wpp-split-media .wpp-shop > .wpp-summary { flex-grow: 0.9; }
.wpp .wpp-product.product.wpp-split-summary .wpp-shop > .wpp-media { flex-grow: 0.9; }
.wpp .wpp-product.product.wpp-split-summary .wpp-shop > .wpp-summary { flex-grow: 1.1; }

.wpp .wpp-product.wpp-cols-summary_first .wpp-media { order: 2; }

.wpp .wpp-product.wpp-cols-one .wpp-shop { flex-direction: column; }
.wpp .wpp-product.wpp-cols-one .wpp-shop > * { min-width: 0; width: 100%; }

.wpp .wpp-product.wpp-is-sticky .wpp-summary {
	position: sticky;
	top: var(--wpp-sticky-top, 90px);
}

/* -------------------------------------------------------------- the buy box ---- */

.wpp .wpp-product.product .wpp-summary {
	border-radius: var(--wpp-radius-panel);
	box-sizing: border-box;
}

.wpp .wpp-product.wpp-has-card .wpp-summary {
	background: var(--wpp-buybox-fill);
	border: 1px solid var(--wpp-hairline);
	padding: var(--wpp-buybox-padding, 1.4rem);
	backdrop-filter: blur(var(--wpp-buybox-blur, 12px));
}

/*
 * A BLURRED CARD STOPS REPAINTING WHAT IS INSIDE IT.
 *
 * backdrop-filter makes this card its own composited layer, and on a phone the browser then
 * caches what is painted inside it. Change a descendant's border-colour - which is exactly how
 * the chosen option is marked - and the change does not show until something forces a new
 * frame. Owner, 21 September 2026: "the gold border on select for density only shows when i
 * scroll, as soon as i stop scrolling it disappears." Scrolling was the forced frame.
 *
 * Giving each option row a layer of its own makes it repaint independently of the card. It is
 * the standard fix, and it is scoped to a card that actually has a blur, so a shop that sets
 * the blur to 0 pays nothing for it.
 */
.wpp .wpp-product.wpp-has-card .wpp-summary label:has(> input[type="radio"]),
.wpp .wpp-product.wpp-has-card .wpp-summary label:has(> input[type="checkbox"]) {
	transform: translateZ(0);
}

.wpp .wpp-product.product .wpp-summary > * { margin-block: 0 0.95rem; }
.wpp .wpp-product.product .wpp-summary > *:last-child { margin-bottom: 0; }

/* Title */
.wpp .wpp-product.product .product_title {
	font-size: var(--wpp-title-size);
	font-weight: var(--wpp-title-weight);
	text-transform: var(--wpp-title-transform);
	line-height: var(--wpp-title-leading, 1.2);
	letter-spacing: -0.01em;
	margin: 0 0 0.5rem;
	color: var(--wpp-text);
	padding: 0;
}

/* Price. Four classes of weight, because WooCommerce paints this green at three. */
.wpp .wpp-product.product .price,
.wpp .wpp-product.product .price span,
.wpp .wpp-product.product .price .amount,
.wpp .wpp-product.product .price bdi {
	color: var(--wpp-text);
}
.wpp .wpp-product.product .wpp-summary > .price,
.wpp .wpp-product.product .wpp-summary .price {
	font-size: var(--wpp-price-size);
	font-weight: 700;
	line-height: 1.2;
	margin: 0 0 0.85rem;
	display: block;
}
.wpp .wpp-product.product .price del,
.wpp .wpp-product.product .price del span,
.wpp .wpp-product.product .price del bdi {
	color: var(--wpp-text-muted);
	opacity: 0.6;
	font-weight: 400;
	font-size: 0.7em;
	margin-right: 0.45rem;
}
.wpp .wpp-product.product .price ins,
.wpp .wpp-product.product .price ins span,
.wpp .wpp-product.product .price ins bdi {
	text-decoration: none;
	color: var(--wpp-text);
}

/* Short description */
.wpp .wpp-product.product .woocommerce-product-details__short-description {
	color: var(--wpp-text-muted);
	line-height: 1.55;
	font-size: 1rem;
}
.wpp .wpp-product.product .woocommerce-product-details__short-description p { margin: 0 0 0.7rem; }
.wpp .wpp-product.product .woocommerce-product-details__short-description p:last-child { margin-bottom: 0; }
.wpp .wpp-product.product .woocommerce-product-details__short-description ul { margin: 0 0 0.7rem; padding-left: 1.2rem; }
.wpp .wpp-product.product .woocommerce-product-details__short-description li { margin: 0 0 0.3rem; }

/* Stars */
.wpp .wpp-product.product .woocommerce-product-rating {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	margin: 0 0 0.7rem;
	font-size: 0.92rem;
	color: var(--wpp-text);
	line-height: 1;
}
.wpp .wpp-product.product .star-rating { color: var(--wpp-highlight); float: none; margin: 0; }
.wpp .wpp-product.product .woocommerce-review-link { color: var(--wpp-text); }

/* Code and categories */
/*
 * A RULE NEEDS AIR ON BOTH SIDES OF IT.
 *
 * This had padding under the line and nothing over it, so the separator sat flush against the
 * bottom of Add to basket - reading as an edge belonging to the button rather than as a line
 * dividing two things. Owner, 21 September 2026: "it touches the button and i think it's
 * supposed to be a separator with no padding above it".
 *
 * Both gaps come from one setting, because a separator with different space above and below is
 * not a separator, it is a mistake.
 */
.wpp .wpp-product.product .product_meta {
	font-size: 0.82rem;
	color: var(--wpp-text-muted);
	border-top: 1px solid var(--wpp-hairline);
	margin-top: var(--wpp-meta-gap);
	padding-top: var(--wpp-meta-gap);
	line-height: 1.8;
}

/* -------------------------------------------------- choices and add to basket ---- */

.wpp .wpp-product.product .wpp-summary form.cart { margin: 0; }

/*
 * Each choice is a panel with its own heading: the label the shop already gave the attribute,
 * and then the options. WooCommerce's table markup is flattened to blocks so it can be a panel
 * rather than a table row.
 */
.wpp .wpp-product.product table.variations {
	width: 100%;
	border: 0;
	border-collapse: collapse;
	margin: 0 0 0.9rem;
	display: block;
}
.wpp .wpp-product.product table.variations tbody,
.wpp .wpp-product.product table.variations tr { display: block; width: 100%; }
.wpp .wpp-product.product table.variations th,
.wpp .wpp-product.product table.variations td {
	border: 0;
	padding: 0;
	display: block;
	width: 100%;
	text-align: left;
}

.wpp .wpp-product.product table.variations tr {
	background: var(--wpp-control-fill);
	border: 1px solid var(--wpp-hairline);
	border-radius: var(--wpp-radius-card);
	padding: var(--wpp-panel-padding, 1rem);
	margin: 0 0 0.75rem;
	box-sizing: border-box;
}

.wpp .wpp-product.product table.variations td.value { position: relative; }

.wpp .wpp-product.product table.variations th.label label {
	font-size: 0.73rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-weight: 700;
	color: var(--wpp-text);
	margin: 0 0 0.6rem;
	display: block;
	line-height: 1.3;
}

/*
 * How the choices are grouped.
 *
 * The same markup either way - only whether each group is drawn as a card, separated by a line,
 * or left to stand on its own. A page with one choice does not need three cards on it.
 */
.wpp .wpp-product.wpp-buybox-bordered table.variations tr,
.wpp .wpp-product.wpp-buybox-plain table.variations tr,
.wpp .wpp-product.wpp-buybox-bordered .wpp-summary form.cart > div:has(label > input[type="radio"]),
.wpp .wpp-product.wpp-buybox-plain .wpp-summary form.cart > div:has(label > input[type="radio"]) {
	background: none;
	border: 0;
	border-radius: 0;
	padding: 0;
}
.wpp .wpp-product.wpp-buybox-bordered table.variations tr,
.wpp .wpp-product.wpp-buybox-bordered .wpp-summary form.cart > div:has(label > input[type="radio"]) {
	border-top: 1px solid var(--wpp-hairline);
	padding-top: 0.9rem;
	margin-bottom: 1rem;
}
.wpp .wpp-product.wpp-buybox-bordered table.variations tr:first-child { border-top: 0; padding-top: 0; }

/* ------------------------------------------------------------------- pills ---- */

.wpp .wpp-product.product .wpp-pills {
	display: flex;
	flex-wrap: wrap;
	gap: 0.45rem;
}

.wpp .wpp-product.product .wpp-pill {
	appearance: none;
	-webkit-appearance: none;
	font: inherit;
	font-size: 0.88rem;
	line-height: 1.2;
	color: var(--wpp-text);
	background: var(--wpp-control-fill);
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
	padding: 0.52rem 0.85rem;
	cursor: pointer;
	transition: border-color 0.12s ease, background 0.12s ease;
}
.wpp .wpp-product.product .wpp-pill:hover { border-color: var(--wpp-control-hover); }
.wpp .wpp-product.product .wpp-pill[aria-checked="true"] {
	border-color: var(--wpp-highlight);
	background: var(--wpp-control-fill);
	box-shadow: inset 0 0 0 1px var(--wpp-highlight);
}
.wpp .wpp-product.product .wpp-pill[disabled] {
	opacity: 0.32;
	cursor: not-allowed;
	text-decoration: line-through;
}
.wpp .wpp-product.product .wpp-pill:focus-visible {
	outline: 2px solid var(--wpp-accent);
	outline-offset: 2px;
}

/* ---------------------------------------------------------- selects, fields ---- */

.wpp .wpp-product.product .wpp-summary select,
.wpp .wpp-product.product .wpp-summary input[type="number"],
.wpp .wpp-product.product .wpp-summary input[type="text"],
.wpp .wpp-product.product .wpp-summary input[type="email"] {
	width: 100%;
	box-sizing: border-box;
	height: var(--wpp-control-height);
	padding: 0 2.4rem 0 0.9rem;
	background-color: var(--wpp-control-fill);
	color: var(--wpp-text);
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
	font: inherit;
	line-height: normal;
	appearance: none;
	-webkit-appearance: none;
}

/* The arrow, drawn rather than an image file, so it takes the text colour. */
.wpp .wpp-product.product .wpp-summary select {
	background-image:
		linear-gradient(45deg, transparent 50%, currentColor 50%),
		linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position:
		calc(100% - 1.15rem) calc(50% + 0.1rem),
		calc(100% - 0.85rem) calc(50% + 0.1rem);
	background-size: 0.36rem 0.36rem, 0.36rem 0.36rem;
	background-repeat: no-repeat;
	cursor: pointer;
}
.wpp .wpp-product.product .wpp-summary select option {
	background-color: var(--wpp-surface);
	color: var(--wpp-text);
}

.wpp .wpp-product.product .wpp-summary select:focus-visible,
.wpp .wpp-product.product .wpp-summary input:focus-visible {
	outline: 2px solid var(--wpp-accent);
	outline-offset: 2px;
	border-color: var(--wpp-accent);
}

/*
 * The real select stays in the form - named, submitted, and the thing WooCommerce reads - just
 * not drawn. It has to out-weigh the select rule above (which is why the tag is in the selector),
 * or it keeps its height and leaves a control-sized hole under the buttons. It did.
 */
.wpp .wpp-product.product .wpp-summary select.wpp-pills-used {
	position: absolute;
	width: 1px;
	height: 1px;
	min-height: 0;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	border: 0;
	background: none;
	appearance: none;
}

/*
 * "Clear" sits on the label line, out of flow.
 *
 * WooCommerce renders it with visibility:hidden inline until a choice is made, and
 * visibility:hidden STILL OCCUPIES ITS LINE - which left a control-sized hole under the options
 * in every choice panel. Taking it out of flow means the panel is the size of its contents
 * whether the link is showing or not, and the link still appears exactly when WooCommerce says.
 */
.wpp .wpp-product.product .reset_variations {
	position: absolute;
	right: 0;
	bottom: 100%;
	margin: 0 0 0.45rem;
	font-size: 0.78rem;
	color: var(--wpp-text-muted);
	text-decoration: underline;
}

.wpp .wpp-product.product .woocommerce-variation { margin: 0 0 0.85rem; color: var(--wpp-text-muted); }
.wpp .wpp-product.product .woocommerce-variation-price .price { font-size: var(--wpp-price-size); }

/* ------------------------------------------------------------ option rows ---- */

/*
 * A size, a finish, gift wrapping - anything a shop offers as a row of choices.
 *
 * Matched STRUCTURALLY, not by class name: a label that wraps a radio or a checkbox is an option
 * row, whoever rendered it. So a plugin that emits ordinary markup is styled by the page's own
 * design without knowing this plugin exists, and without this plugin knowing what the shop sells.
 * The alternative - naming somebody's classes in here - is how a stylesheet ends up knowing what
 * one particular shop happens to sell.
 */

/* The panel a group of rows sits in: a direct child of the form that holds labels with inputs. */
.wpp .wpp-product.product .wpp-summary form.cart > div:has(label > input[type="radio"]),
.wpp .wpp-product.product .wpp-summary form.cart > div:has(label > input[type="checkbox"]) {
	background: var(--wpp-control-fill);
	border: 1px solid var(--wpp-hairline);
	border-radius: var(--wpp-radius-card);
	padding: var(--wpp-panel-padding, 1rem);
	margin: 0 0 0.9rem;
	box-sizing: border-box;
}

/* Its heading and its note, whatever they are called. */
.wpp .wpp-product.product .wpp-summary form.cart > div:has(label > input[type="radio"]) > span:first-of-type {
	display: block;
	font-size: 0.95rem;
	font-weight: 700;
	color: var(--wpp-text);
	margin: 0 0 0.15rem;
}
.wpp .wpp-product.product .wpp-summary form.cart > div:has(label > input[type="radio"]) > span:nth-of-type(2) {
	display: block;
	font-size: 0.82rem;
	line-height: 1.45;
	color: var(--wpp-text-muted);
	margin: 0 0 0.7rem;
}

/* The rows themselves, stacked. */
.wpp .wpp-product.product .wpp-summary div:has(> label > input[type="radio"]),
.wpp .wpp-product.product .wpp-summary div:has(> label > input[type="checkbox"]) {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
}

.wpp .wpp-product.product .wpp-summary label:has(> input[type="radio"]),
.wpp .wpp-product.product .wpp-summary label:has(> input[type="checkbox"]) {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	width: 100%;
	box-sizing: border-box;
	min-height: var(--wpp-control-height);
	margin: 0;
	padding: 0.5rem 0.9rem;
	background: var(--wpp-card-fill);
	border: 1px solid var(--wpp-hairline);
	border-radius: var(--wpp-radius-control);
	color: var(--wpp-text);
	font-size: 0.95rem;
	cursor: pointer;
	transition: border-color 0.12s ease;
}
.wpp .wpp-product.product .wpp-summary label:has(> input[type="radio"]):hover,
.wpp .wpp-product.product .wpp-summary label:has(> input[type="checkbox"]):hover {
	border-color: var(--wpp-control-hover);
}

/* Chosen. The outline as well as the border: they are painted in different phases, so if one
   is held in a stale layer the other still shows. */
.wpp .wpp-product.product .wpp-summary label:has(> input:checked) {
	border-color: var(--wpp-highlight);
	outline: 1px solid var(--wpp-highlight);
	outline-offset: -1px;
}
.wpp .wpp-product.product .wpp-summary label > input[type="radio"],
.wpp .wpp-product.product .wpp-summary label > input[type="checkbox"] {
	accent-color: var(--wpp-highlight);
	width: auto;
	height: auto;
	margin: 0;
	flex: 0 0 auto;
}

/* Whatever comes last on the row - usually the price - goes to the right. */
.wpp .wpp-product.product .wpp-summary label:has(> input[type="radio"]) > span:last-child,
.wpp .wpp-product.product .wpp-summary label:has(> input[type="checkbox"]) > span:last-child {
	margin-left: auto;
	color: var(--wpp-text-muted);
	white-space: nowrap;
}
.wpp .wpp-product.product .wpp-summary label:has(> input:checked) > span:last-child {
	color: var(--wpp-text);
}

/* --------------------------------------------------------- the button row ---- */

.wpp .wpp-product.product .woocommerce-variation-add-to-cart,
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) {
	display: flex;
	gap: 0.6rem;
	align-items: stretch;
	flex-wrap: wrap;
}

/*
 * ANYTHING A PLUGIN PUTS IN THE FORM GETS ITS OWN ROW.
 *
 * The form is a flex row so the quantity and the button sit side by side. Everything else that
 * lands in there is a block wanting the full width - and plugins put plenty in there. So the
 * full width is the DEFAULT and the two things that belong on the button row opt out of it.
 *
 * The other way round is what shipped, and it fails the moment a shop installs anything: an
 * unrecognised block becomes a flex item beside the button, squeezed into a column, with the
 * button stretched to match its height. On one shop that was three dropdowns a promo plugin adds
 * squeezed into a 232px column next to a 246x304 blue square, on a live page.
 *
 * Nothing but the quantity and the submit button is named here, which is the point: this plugin
 * cannot know what a shop has installed, and it does not have to.
 */
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > *,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > * {
	flex: 0 0 100%;
	min-width: 0;   /* a flex item will not shrink below its content without this */

	/*
	 * THE ORDER OF THE BUY BOX IS THE SHOP'S, NOT A PLUGIN'S.
	 *
	 * An options plugin here set `order:-1` on its own block, which lifted a paid extra above
	 * the choices the product is actually sold by - so the page asked "how dense?" before it
	 * asked "which three?". Every plugin that does this wins over every plugin that does not,
	 * and the result is whatever order they happened to load in.
	 *
	 * Reset to source order, so what a shop sees is the order the page was built in.
	 */
	order: 0;
}

/*
 * ...and the button row is always last.
 *
 * Owner, 21 September 2026: anything a plugin attaches "should ALWAYS appear above the add to
 * cart buttons, so that any other things are above it". One rule does that for every plugin at
 * once, including ones that do not exist yet, which is better than knowing about each of them.
 */
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > .quantity,
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > button,
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > a,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > .quantity,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > button,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > a {
	order: 1;
}

.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > .quantity,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > .quantity {
	flex: 0 0 auto;
}

.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > .single_add_to_cart_button,
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > button[type="submit"],
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > .single_add_to_cart_button,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > button[type="submit"] {
	flex: 1 1 11rem;
}

/*
 * A link or a button among the form's children belongs BESIDE Add to basket, not under it.
 *
 * "Everything gets its own row" is right for a block a plugin adds - a set of dropdowns, a
 * density picker. It is wrong for a link, because a link sitting in the buy form is a second
 * action offered next to the first: view the basket, check the size guide, ask a question. Full
 * width pushed it onto a row of its own and it read as an afterthought at the bottom of the card.
 *
 * Shipped that way for about an hour on 21 September 2026 and the owner spotted it at once:
 * "the basket button shows like that, it's supposed to be on the right of the add to cart
 * button". It was - the OLD stylesheet put it there, and that stylesheet needs a wrapper class
 * this plugin does not print.
 */
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > a,
.wpp .wpp-product.product .wpp-summary form.cart:not(.variations_form) > button:not([type="submit"]),
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > a,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > button:not([type="submit"]) {
	flex: 0 0 auto;
}

/*
 * ...and it should LOOK like the second action it is.
 *
 * The same shape and height as Add to basket, in the quieter control colours, so the two read as
 * a pair. Built only from the settings that already exist, so a shop that changes its control
 * height or its corners gets this for free and never has to know it is here.
 */
.wpp .wpp-product.product .wpp-summary form.cart > a,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	/*
	 * HEIGHT FROM min-height, NOT FROM PADDING.
	 *
	 * An <a> is content-box unless something says otherwise, so min-height:44px plus 0.85rem of
	 * padding top and bottom came out at 73px - and align-items:stretch then dragged Add to
	 * basket up to 73px beside it. Two buttons half as tall again as every other product page,
	 * on a live page, because a link is not a button and I styled it as though it were.
	 *
	 * border-box and no vertical padding: the control height is the control height.
	 */
	box-sizing: border-box;
	min-height: var(--wpp-control-height);
	padding: 0 1.2rem;
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
	background: var(--wpp-control-fill);
	color: var(--wpp-text);
	text-decoration: none;
	font: inherit;
	font-weight: 700;
	font-size: 0.86rem;
	letter-spacing: var(--wpp-button-spacing, 0.06em);
	text-transform: uppercase;
	white-space: nowrap;
	transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease;
}
.wpp .wpp-product.product .wpp-summary form.cart > a:hover,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > a:hover {
	transform: translateY(-2px);
	border-color: var(--wpp-accent);
	color: var(--wpp-text);
}
.wpp .wpp-product.product .wpp-summary form.cart > a svg {
	width: 1.1em;
	height: 1.1em;
	flex: 0 0 auto;
}

/*
 * A <style> or <script> in the form is not a thing on the page.
 *
 * Plugins print both inside form.cart, and as flex children they took a row each - invisible,
 * but each one costing a full gap. Four of them and the card grows by nothing you can point at.
 */
.wpp .wpp-product.product .wpp-summary form.cart > style,
.wpp .wpp-product.product .wpp-summary form.cart > script,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > style,
.wpp .wpp-product.product .woocommerce-variation-add-to-cart > script {
	display: none;
}

/*
 * A quantity box with nothing in it is not a control.
 *
 * WooCommerce hides the input on a product sold one at a time but still prints the wrapper, so
 * the border, the background and the control height were drawn around nothing - a 2px vertical
 * line beside the button that looked like a rendering fault.
 */
.wpp .wpp-product.product .wpp-summary .quantity:not(:has(input:not([type="hidden"]))) {
	display: none;
}

/*
 * A label inside the buy box is this plugin's to colour.
 *
 * A theme chooses its label colour for ITS OWN background. Put a dark design behind it and the
 * labels a plugin prints come out near-black on near-black - "Choice 1" was rgb(21,23,28) on a
 * page that dark. The text was there the whole time and could not be read, which is worse than
 * it being missing, because nothing looks wrong enough to go and check.
 */
.wpp .wpp-product.product .wpp-summary form.cart label,
.wpp .wpp-product.product .wpp-summary form.cart legend,
.wpp .wpp-product.product .wpp-summary form.cart .form-row > label {
	color: var(--wpp-text);
}

/*
 * A DROPDOWN IN THE BUY BOX IS THIS PLUGIN'S TO COLOUR.
 *
 * Same trap as the labels: a plugin styles its own select for a white form - rgb(21,23,28) text
 * and an rgba(0,0,0,.1) edge - and on a dark design you get grey-on-grey with no visible border,
 * so it does not read as something you can open. The three strain dropdowns on a promo looked
 * like disabled boxes.
 */
.wpp .wpp-product.product .wpp-summary form.cart select,
.wpp .wpp-product.product .wpp-summary .form-row select {
	color: var(--wpp-text);
	background-color: var(--wpp-control-fill);
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
}
.wpp .wpp-product.product .wpp-summary form.cart select:hover {
	border-color: var(--wpp-accent);
}
/* The list the browser draws is the operating system's, so it needs telling separately. */
.wpp .wpp-product.product .wpp-summary form.cart select option {
	color: var(--wpp-text);
	background-color: var(--wpp-surface);
}

/* The little red star beside a required field, at a red that can be seen on this page. */
.wpp .wpp-product.product .wpp-summary form.cart .required,
.wpp .wpp-product.product .wpp-summary form.cart abbr[title="required"] {
	color: var(--wpp-required);
	border: 0;
	text-decoration: none;
}

/* Quantity, as a stepper: minus, the number, plus - all one control height. */
.wpp .wpp-product.product .wpp-summary .quantity {
	flex: 0 0 auto;
	display: flex;
	align-items: stretch;
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
	background: var(--wpp-control-fill);
	overflow: hidden;
	height: var(--wpp-control-height);
}
.wpp .wpp-product.product .wpp-summary .quantity input[type="number"] {
	width: 3rem;
	border: 0;
	border-radius: 0;
	background: transparent;
	padding: 0;
	text-align: center;
	height: auto;
	-moz-appearance: textfield;
}
.wpp .wpp-product.product .wpp-summary .quantity input[type="number"]::-webkit-outer-spin-button,
.wpp .wpp-product.product .wpp-summary .quantity input[type="number"]::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
.wpp .wpp-product.product .wpp-step {
	appearance: none;
	border: 0;
	background: transparent;
	color: var(--wpp-text);
	font: inherit;
	font-size: 1.1rem;
	line-height: 1;
	width: 2.2rem;
	cursor: pointer;
	padding: 0;
}
.wpp .wpp-product.product .wpp-step:hover { background: var(--wpp-hairline); }

/* Add to basket. Four classes of weight, because WooCommerce paints this purple at three. */
.wpp .wpp-product.product .single_add_to_cart_button.button,
.wpp .wpp-product.product .wpp-summary .single_add_to_cart_button {
	flex: 1 1 11rem;
	min-height: var(--wpp-control-height);
	background-color: var(--wpp-action);
	color: var(--wpp-text);
	border: 0;
	border-radius: var(--wpp-radius-control);
	font: inherit;
	font-weight: 700;
	letter-spacing: var(--wpp-button-spacing, 0.06em);
	text-transform: uppercase;
	font-size: 0.86rem;
	padding: 0.85rem 1.4rem;
	cursor: pointer;
	transition: transform 0.15s ease, background-color 0.2s ease;
}
.wpp .wpp-product.product .single_add_to_cart_button.button:hover {
	transform: translateY(-2px);
	background-color: var(--wpp-action-hover);
}
.wpp .wpp-product.product .single_add_to_cart_button.button.disabled,
.wpp .wpp-product.product .single_add_to_cart_button.button[disabled] {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
	background-color: var(--wpp-action);
}

.wpp .wpp-product.product .stock.out-of-stock { color: var(--wpp-highlight); font-weight: 600; }

/* ------------------------------------------------------------------ photos ---- */

.wpp .wpp-product.product .wpp-media { position: relative; }

.wpp .wpp-product.product div.woocommerce-product-gallery { margin: 0; width: 100%; }
.wpp .wpp-product.product .woocommerce-product-gallery__wrapper { margin: 0; }

.wpp .wpp-product.product .woocommerce-product-gallery img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--wpp-radius-card);
}

.wpp .wpp-product.product .flex-control-thumbs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wpp-thumb-gap);
	list-style: none;
	padding: 0;
}

/*
 * The gap above the strip needs FIVE classes to survive.
 *
 * WooCommerce ships `.woocommerce div.product div.images .flex-control-thumbs{margin:0}` - four
 * classes and two elements - so the plain three-class scope this file uses everywhere else lost,
 * silently, and the thumbnails sat flush against the bottom of the main photograph. Measured at
 * 0px against a setting that said 0.9rem, which is the only way to catch this sort of thing.
 *
 * Its own setting, because on a product with nine photographs the strip read as part of the main
 * image rather than as a row under it.
 */
.wpp .wpp-product.product .wpp-media .woocommerce-product-gallery .flex-control-thumbs {
	margin: var(--wpp-thumb-gap) 0 0;
}
.wpp .wpp-product.product .flex-control-thumbs li {
	flex: 0 0 var(--wpp-thumb-size);
	margin: 0;
	width: auto;
}

/*
 * DIM THE PICTURE, DO NOT MAKE IT SEE-THROUGH.
 *
 * These were opacity:.55, which is fine on a flat ground and mush on a photographic one - the
 * page's own background image came up through every thumbnail and the row turned to fog. A
 * brightness filter takes the picture down without letting anything through it, and the card
 * fill behind covers any transparent pixels in the photograph itself.
 */
.wpp .wpp-product.product .flex-control-thumbs img {
	border-radius: var(--wpp-radius-control);
	cursor: pointer;
	background: var(--wpp-card-fill);
	opacity: 1;
	/* The setting is a plain number so the panel can offer a slider; brightness() needs a unit,
	   and calc(N * 1%) is how a unitless setting becomes one without a second setting to hold it. */
	filter: brightness(calc(var(--wpp-thumb-dim) * 1%));
	transition: filter 0.15s ease, outline-color 0.15s ease;
	outline: 2px solid transparent;
	outline-offset: -2px;
	aspect-ratio: 1;
	object-fit: cover;
}
.wpp .wpp-product.product .flex-control-thumbs img.flex-active,
.wpp .wpp-product.product .flex-control-thumbs img:hover {
	filter: none;
}
/* Which one you are looking at, said plainly rather than by being slightly less dim. */
.wpp .wpp-product.product .flex-control-thumbs img.flex-active {
	outline-color: var(--wpp-highlight);
}

.wpp .wpp-product.product .onsale {
	position: absolute;
	top: 0.8rem;
	left: 0.8rem;
	z-index: 2;
	background: var(--wpp-highlight);
	color: var(--wpp-surface-deep);
	border-radius: var(--wpp-radius-control);
	padding: 0.32rem 0.75rem;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	margin: 0;
	min-height: 0;
	line-height: 1.4;
}

/* The gallery moved into the buy box is no longer a column. */
.wpp .wpp-product.product .wpp-summary .woocommerce-product-gallery { margin: 0 0 0.95rem; }

/* --------------------------------------------------------------- the promises ---- */

/*
 * A row of short promises. As many as are written, spread evenly, wrapping when they will not
 * fit rather than shrinking until nothing reads.
 */
.wpp .wpp-promises {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
	background: var(--wpp-promises-fill);
	border: 1px solid var(--wpp-hairline);
	border-radius: var(--wpp-radius-card);
	overflow: hidden;
	margin: clamp(1.2rem, 2.5vw, 2rem) 0;
}

.wpp .wpp-promise {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.55rem;
	padding: 0.85rem 1rem;
	font-size: var(--wpp-promises-size, 0.85rem);
	font-weight: 600;
	color: var(--wpp-text);
	text-align: center;
	/* A divider that is not there on the first of a row: a border on one side only, then the
	   row's own edge covers the leftmost one because the strip clips its contents. */
	box-shadow: -1px 0 0 0 var(--wpp-hairline);
}

.wpp .wpp-promise__icon {
	flex: 0 0 auto;
	width: 1.15em;
	height: 1.15em;
	opacity: 0.85;
}

/* Inside the buy box it is a stack, not a strip: there is no room for four across. */
.wpp .wpp-summary .wpp-promises {
	grid-template-columns: 1fr;
	margin: 0.9rem 0 0;
}
.wpp .wpp-summary .wpp-promise {
	justify-content: flex-start;
	box-shadow: 0 -1px 0 0 var(--wpp-hairline);
	padding: 0.6rem 0.85rem;
}

/* ------------------------------------------------------------ the look button ---- */

/*
 * Deliberately outside the .wpp scope: this button is meant to be put in a menu or a widget,
 * which is not inside the product area. It still takes its colours from the page's tokens, with
 * plain fallbacks for wherever it lands.
 */
.wpp-mode-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.4rem 0.75rem;
	border: 1px solid var(--wpp-hairline-strong, currentColor);
	border-radius: var(--wpp-radius-control, 8px);
	background: var(--wpp-control-fill, transparent);
	color: inherit;
	font: inherit;
	font-size: 0.82rem;
	line-height: 1.2;
	cursor: pointer;
}
.wpp-mode-toggle:hover { border-color: var(--wpp-control-hover, currentColor); }
.wpp-mode-toggle__dot {
	width: 0.7rem;
	height: 0.7rem;
	border-radius: 50%;
	border: 1px solid currentColor;
	background: linear-gradient(90deg, currentColor 50%, transparent 50%);
}
.wpp-mode-toggle[aria-pressed="true"] .wpp-mode-toggle__dot { transform: rotate(180deg); }

/* ----------------------------------------------------------------- notices ---- */

.wpp .wpp-product.product .woocommerce-notices-wrapper:empty { display: none; }
.wpp .wpp-product.product .woocommerce-message,
.wpp .wpp-product.product .woocommerce-info,
.wpp .wpp-product.product .woocommerce-error {
	background: var(--wpp-control-fill);
	border: 1px solid var(--wpp-hairline);
	border-left: 3px solid var(--wpp-accent);
	border-radius: var(--wpp-radius-control);
	color: var(--wpp-text);
	padding: 0.9rem 1.1rem;
	margin: 0 0 1.1rem;
	list-style: none;
}
.wpp .wpp-product.product .woocommerce-error { border-left-color: var(--wpp-highlight); }

/* ---------------------------------------------------------------- sections ---- */
/* Step 3 gives these tabs, stacking and backgrounds. Until then they inherit. */

/*
 * Below the band, and above it.
 *
 * ABOVE IT because the band is an absolutely positioned pseudo-element, and a positioned element
 * paints over the in-flow content of later siblings however far down the page they are. Without
 * this the band lay across the tab strip and cut the labels in half - readable text, half
 * covered by a tinted photograph.
 *
 * BELOW IT because the clearance and the band's reach have to be the same measurement or they
 * drift apart and overlap, which is exactly what happened. One variable decides both.
 */
/*
 * Behind the description area: the same two layers, on demand.
 *
 * Painted only when there is something to paint - an empty picture and a transparent colour
 * leave nothing behind, so a plain page stays a plain page with no extra elements in it.
 */
.wpp .wpp-product.product .wpp-sections::before,
.wpp .wpp-product.product .wpp-sections::after {
	content: "";
	position: absolute;
	left: 50%;
	width: 100vw;
	margin-left: -50vw;
	top: 0;
	bottom: calc(-1 * var(--wpp-gutter, 5cqw));
	pointer-events: none;
	z-index: -1;
}
.wpp .wpp-product.product .wpp-sections::before {
	background-color: var(--wpp-sections-fill, transparent);
	background-image: var(--wpp-sections-bg, none);
	background-size: var(--wpp-sections-bg-size, cover);
	background-position: var(--wpp-sections-bg-position, center);
	background-repeat: no-repeat;
}
.wpp .wpp-product.product .wpp-sections::after {
	background-color: var(--wpp-sections-overlay, transparent);
	backdrop-filter: blur(var(--wpp-sections-bg-blur, 0px));
}
/* With no picture there is nothing to darken, so the colour over it would only dim the page. */
.wpp .wpp-product.product:not(.wpp-has-sections-bg) .wpp-sections::after { display: none; }

.wpp .wpp-product.product .wpp-sections {
	position: relative;
	z-index: 1;
	isolation: isolate;
	margin-top: calc(var(--wpp-band-bleed-bottom, 4rem) + clamp(1.5rem, 3vw, 2.5rem));
}

/* --------------------------------------------------- colours from the content ---- */

/*
 * A colour typed into the editor, carried rather than applied.
 *
 * Ink.php moves style="color:X" to style="--wpp-ink:X", so the element arrives holding a colour
 * without using it, and these rules decide. NOT ONE !important: an inline colour cannot be beaten
 * by a stylesheet, so it is moved out of the way rather than shouted over.
 *
 * "Keep" never reaches here - nothing is rewritten in that case and the editor's colour applies
 * exactly as it always did.
 */
.wpp .wpp-ink-dark_only [style*="--wpp-ink"] { color: var(--wpp-ink); }

/* In the light look, a colour chosen against a dark page is set aside and the page's own text
   colour is used. The colour is still on the element - switch back and it returns. */
:root[data-wpp-mode="light"] .wpp .wpp-ink-dark_only [style*="--wpp-ink"] { color: inherit; }

/* "Always use the page's own colour" needs no rule at all: nothing claims --wpp-ink, so the text
   simply inherits. */

/* ------------------------------------------------- description and the rest ---- */

/*
 * The same sections either way. Tabs shows one at a time; stacked renders them all down the page
 * under their own headings. Nothing fades and nothing sticks - the page is simply longer.
 */

.wpp .wpp-product.product .wpp-tabstrip {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(1rem, 2.5vw, 2rem);
	border-bottom: 1px solid var(--wpp-hairline);
	margin: 0 0 clamp(1.4rem, 3vw, 2.4rem);
}

.wpp .wpp-product.product .wpp-tab {
	appearance: none;
	background: none;
	border: 0;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
	padding: 0.7rem 0.15rem;
	font: inherit;
	font-size: 0.95rem;
	font-weight: 600;
	color: var(--wpp-text-muted);
	opacity: 0.68;
	cursor: pointer;
	white-space: nowrap;
	transition: opacity 0.12s ease, border-color 0.12s ease;
}
.wpp .wpp-product.product .wpp-tab:hover { opacity: 1; }
.wpp .wpp-product.product .wpp-tab[aria-selected="true"] {
	color: var(--wpp-text);
	opacity: 1;
	border-bottom-color: var(--wpp-text);
}
.wpp .wpp-product.product .wpp-tab:focus-visible {
	outline: 2px solid var(--wpp-accent);
	outline-offset: 3px;
}

/* Stacked: each section under its own heading, separated by a hairline. */
.wpp .wpp-product.product .wpp-section {
	padding-top: clamp(1.6rem, 3.5vw, 2.8rem);
	margin-top: clamp(1.6rem, 3.5vw, 2.8rem);
	border-top: 1px solid var(--wpp-hairline);
}
.wpp .wpp-product.product .wpp-stacked > .wpp-section:first-child {
	padding-top: 0;
	margin-top: 0;
	border-top: 0;
}
.wpp .wpp-product.product .wpp-section-title {
	font-size: clamp(1.25rem, 2.2vw, 1.6rem);
	font-weight: var(--wpp-title-weight);
	color: var(--wpp-text);
	margin: 0 0 1rem;
}

/* The content of a section, either way. */
.wpp .wpp-product.product .wpp-panel,
.wpp .wpp-product.product .wpp-section-body {
	color: var(--wpp-text-muted);
	line-height: 1.65;
	max-width: 72ch;
}
.wpp .wpp-product.product .wpp-panel > h2:first-child { margin-top: 0; }
.wpp .wpp-product.product .wpp-panel h2,
.wpp .wpp-product.product .wpp-section-body h2 {
	font-size: clamp(1.15rem, 2vw, 1.45rem);
	color: var(--wpp-text);
	margin: 1.8rem 0 0.8rem;
}
.wpp .wpp-product.product .wpp-panel h3,
.wpp .wpp-product.product .wpp-section-body h3 {
	font-size: 1.05rem;
	color: var(--wpp-text);
	margin: 1.5rem 0 0.6rem;
}
.wpp .wpp-product.product .wpp-panel p,
.wpp .wpp-product.product .wpp-section-body p { margin: 0 0 1rem; }
.wpp .wpp-product.product .wpp-panel ul,
.wpp .wpp-product.product .wpp-panel ol,
.wpp .wpp-product.product .wpp-section-body ul,
.wpp .wpp-product.product .wpp-section-body ol { margin: 0 0 1rem; padding-left: 1.3rem; }
.wpp .wpp-product.product .wpp-panel li,
.wpp .wpp-product.product .wpp-section-body li { margin: 0 0 0.45rem; }
.wpp .wpp-product.product .wpp-panel img,
.wpp .wpp-product.product .wpp-section-body img {
	max-width: 100%;
	height: auto;
	border-radius: var(--wpp-radius-card);
}
.wpp .wpp-product.product .wpp-panel table,
.wpp .wpp-product.product .wpp-section-body table { width: 100%; border-collapse: collapse; }
.wpp .wpp-product.product .wpp-panel th,
.wpp .wpp-product.product .wpp-panel td,
.wpp .wpp-product.product .wpp-section-body th,
.wpp .wpp-product.product .wpp-section-body td {
	border-bottom: 1px solid var(--wpp-hairline);
	padding: 0.6rem 0.4rem;
	text-align: left;
}

/* Related products and upsells. WooCommerce's own markup, laid out as a grid that fits the
   space it is given rather than a fixed number of columns. */
.wpp .wpp-product.product .related > h2,
.wpp .wpp-product.product .upsells > h2 {
	font-size: 1.35rem;
	font-weight: var(--wpp-title-weight);
	color: var(--wpp-text);
	margin: 0 0 1.2rem;
}
/*
 * WooCommerce clearfixes this list with ::before and ::after.
 *
 * In a float layout those are invisible. In a GRID they are grid items, so they take the first
 * cell and push every product one column to the right - which is why the heading sat alone on
 * the left with a gap beside it. Nothing about it looks like a bug; the cards simply start in
 * the wrong place, and more so the wider the screen.
 */
.wpp .wpp-product.product .related ul.products::before,
.wpp .wpp-product.product .related ul.products::after,
.wpp .wpp-product.product .upsells ul.products::before,
.wpp .wpp-product.product .upsells ul.products::after { content: none; display: none; }

.wpp .wpp-product.product .related ul.products,
.wpp .wpp-product.product .upsells ul.products {
	display: grid;
	grid-template-columns: repeat(var(--wpp-related-columns, 4), minmax(0, 1fr));
	gap: 1.2rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.wpp .wpp-product.product ul.products li.product {
	background: var(--wpp-related-fill, var(--wpp-card-fill));
	border: 1px solid var(--wpp-hairline);
	border-radius: var(--wpp-radius-card);
	padding: 0.8rem;
	margin: 0;
	width: auto;
	float: none;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}
.wpp .wpp-product.product ul.products li.product img {
	width: 100%;
	height: auto;
	aspect-ratio: 1;
	object-fit: cover;
	border-radius: var(--wpp-radius-control);
	margin: 0 0 0.3rem;
}
.wpp .wpp-product.product ul.products li.product .woocommerce-loop-product__title {
	font-size: 0.92rem;
	font-weight: 600;
	color: var(--wpp-text);
	margin: 0;
	padding: 0;
	line-height: 1.3;
}
.wpp .wpp-product.product ul.products li.product a { color: var(--wpp-text); text-decoration: none; }
.wpp .wpp-product.product ul.products li.product .price { font-size: 0.95rem; font-weight: 700; margin: 0; }
.wpp .wpp-product.product ul.products li.product .star-rating { font-size: 0.7rem; margin: 0; }
.wpp .wpp-product.product ul.products li.product .button {
	margin-top: auto;
	align-self: flex-start;
	background-color: transparent;
	color: var(--wpp-text);
	border: 1px solid var(--wpp-hairline-strong);
	border-radius: var(--wpp-radius-control);
	padding: 0.45rem 0.85rem;
	font-size: 0.8rem;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
}
.wpp .wpp-product.product ul.products li.product .button:hover { border-color: var(--wpp-control-hover); }

/* ------------------------------------------------------------ ways to show them ---- */

/* Plain: no card, just the picture and the words under it. */
.wpp .wpp-product.wpp-related-plain ul.products li.product {
	background: none;
	border: 0;
	padding: 0;
}

/* Side by side: the picture beside the words instead of above them, so more fit in less height. */
.wpp .wpp-product.wpp-related-beside ul.products li.product {
	flex-direction: row;
	align-items: flex-start;
	gap: 0.8rem;
}
.wpp .wpp-product.wpp-related-beside ul.products li.product img {
	flex: 0 0 5.5rem;
	width: 5.5rem;
	margin: 0;
}
.wpp .wpp-product.wpp-related-beside ul.products li.product .button { margin-top: 0.4rem; }

/* What each card shows. Hidden here as well as unhooked, because a theme may render a price
   somewhere this plugin did not put it. */
.wpp .wpp-product.wpp-related-noprice ul.products li.product .price { display: none; }
.wpp .wpp-product.wpp-related-norating ul.products li.product .star-rating { display: none; }
.wpp .wpp-product.wpp-related-nobutton ul.products li.product .button { display: none; }
