/*
 * PouchPick PLP / Shop — S5, built from design-lab/final/plp/round-2-5-plp.html
 * (PLP-VISUAL-SYSTEM-LOCK.md v1.0); S9D-B polish per that lock's S9C
 * amendment and GLOBAL-COMMERCE-POLISH-LOCK.md §11 / §15 / §24-§28 as
 * rendered in design-lab/final/global-polish/ (Hybrid V2, global-polish.css
 * §13). Class names are this theme's own (.pp-plp-*), per CLAUDE.md's
 * POUCHPICK VISUAL OWNERSHIP.
 *
 * Product cards are the shared grammar (assets/css/product-card.css — FULL
 * PLP variant with the segmented tier row); this file owns the collection
 * header, toolbar, facets, active chips, the all-filters sheet
 * (.pp-fpanel-*), grid density and pagination. The filter / sort / query
 * architecture (inc/plp.php) is untouched.
 *
 * SHOP.SEO V4.2 (Human selection 2026-10-23; PLP lock amendment): Sort in the
 * heading row; the strength row (.pp-plp-bands — in the toolbar on desktop,
 * its own row on phones); "All filters" opens the one sheet, which is a 320px
 * drawer from 901px (the More Filters panel is gone); the phone Filter / Sort
 * bar sticks at the header line; two-column phone cards; balanced final rows;
 * "Show more products" over the kept numbered pages. Tokens only; hover lives
 * inside @media (hover: hover) (UI.1) and presses use :active + .is-pressed.
 */

/* ---------------- Collection header (page-title role, lock §11) ---------------- */

.pp-plp-head { padding: var(--pp-space-5) 0 var(--pp-space-3); display: flex; align-items: baseline; gap: var(--pp-space-2); flex-wrap: wrap; }
.pp-plp-title { font: 600 var(--pp-text-page-title)/1.15 var(--pp-font-display); letter-spacing: -0.02em; margin: 0; }
.pp-plp-count { font: 600 13px/1 var(--pp-font-body); color: var(--pp-secondary-text); }
.pp-plp-desc { flex-basis: 100%; color: var(--pp-secondary-text); font-size: 0.8125rem; margin: 0; }

/* SF.4 — a contextual heading keeps the archive's stable anchor above it:
   "Home / Shop", on the PDP breadcrumb's own values (pdp.css .pp-pdp-crumb).
   The canonical Shop view renders no crumb, so it is unchanged. */
.pp-plp-crumb { flex-basis: 100%; font-size: var(--pp-text-meta-min); line-height: 1.3; color: var(--pp-secondary-text); }
.pp-plp-crumb a { color: var(--pp-secondary-text); }
.pp-plp-crumb a:hover { color: var(--pp-ink); }
.pp-plp-crumb span[aria-hidden] { margin: 0 4px; }
.pp-plp-title { overflow-wrap: anywhere; }   /* a long search query wraps */

/* SHOP.SEO V4.2 — the listing head: earlier products (tighter spacing), the
   one sentence beside the H1 on wide screens, Sort at the end of the row
   (still a field of the toolbar form), the guide link on the clean first page.
   The generic search page keeps its own head. */
.pp-plp:not(.pp-search-page) .pp-plp-head { align-items: center; row-gap: 2px; padding-top: 18px; }
.pp-plp:not(.pp-search-page) .pp-plp-desc { font-size: 13px; line-height: 1.5; }
.pp-plp-jump { margin-inline-start: 4px; white-space: nowrap; font-weight: 600; color: var(--pp-navy); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: transparent; }
@media (hover: hover) { .pp-plp-jump:hover { text-decoration-color: currentColor; } }
.pp-plp-jump:focus-visible { text-decoration-color: currentColor; }
.pp-plp-headsort { display: flex; align-items: center; gap: 8px; margin-inline-start: auto; align-self: center; }
.pp-plp-headsort-k { font: 600 12px/1 var(--pp-font-body); letter-spacing: .04em; text-transform: uppercase; color: var(--pp-secondary-text); }
.pp-plp-headsort .pp-plp-sort { width: auto; min-height: 38px; padding: 6px 36px 6px 12px; font: 600 13px/1.2 var(--pp-font-body); border-width: 1px; border-radius: var(--pp-radius-control); }
@media (min-width: 1280px) {
	.pp-plp:not(.pp-search-page) .pp-plp-head:not(.has-context) .pp-plp-desc { flex: 1 1 0; min-width: 0; margin-inline-start: var(--pp-space-3); padding-inline-start: var(--pp-space-3); border-inline-start: 1px solid var(--pp-border); }
}
@media (max-width: 1279.98px) { .pp-plp:not(.pp-search-page) .pp-plp-head .pp-plp-desc { order: 3; } }

/* ---------------- Desktop sticky facet toolbar ----------------
   Keeps its blur; nothing position:fixed lives inside it any more (lock §28).
   UI.1 (Human Lock §11): it sticks at the header's sticky line
   (header.css --pp-sticky-top) instead of top:0, where it slid behind the
   fixed desktop header (and under T2 on the tablet tier) and was never seen
   once stuck. */

.pp-plp-toolbar {
	position: sticky;
	top: calc(var(--pp-sticky-top, 0px) + var(--pp-admin-bar-h, 0px));
	z-index: 15;
	display: flex;
	align-items: center;
	gap: 4px;
	background: rgba(255, 255, 255, 0.94);
	backdrop-filter: blur(6px);
	border-top: 1px solid var(--pp-border);
	border-bottom: 1px solid var(--pp-border);
	padding: var(--pp-space-2) 0;
	flex-wrap: wrap;
	margin-bottom: var(--pp-space-4);
}
.pp-plp-facet { position: relative; }
.pp-plp-facet-trigger {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	min-height: 36px;
	padding: 0 10px;
	border-radius: var(--pp-radius-control);
	font: 600 13px/1 var(--pp-font-body);
	color: var(--pp-ink);
	position: relative;
	cursor: pointer;
	transition: background-color var(--pp-motion-micro) var(--pp-ease-out), color var(--pp-motion-micro) var(--pp-ease-out);
}
.pp-plp-facet-trigger .pp-plp-caret { width: 14px; height: 14px; color: var(--pp-secondary-text); transition: transform var(--pp-motion-micro) var(--pp-ease-out); }
@media (hover: hover) { .pp-plp-facet-trigger:hover { background: var(--pp-soft-surface); } } /* UI.1 P2 (Human Lock §8): hover-capable input only — a tap never leaves this shade behind. */
.pp-plp-facet-trigger:active, .pp-plp-facet-trigger.is-pressed { background: var(--pp-navy-tint); }
.pp-plp-facet.is-open .pp-plp-facet-trigger { background: var(--pp-soft-surface); }
.pp-plp-facet.is-open .pp-plp-caret { transform: rotate(180deg); }
.pp-plp-facet-trigger.has-selection { color: var(--pp-navy); }
.pp-plp-facet-trigger .n { background: var(--pp-navy); color: #fff; font: 700 10.5px/1 var(--pp-font-body); min-width: 18px; height: 18px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; padding: 0 5px; }
/* Edge (lock §5) — ONLY under a facet trigger that carries an active selection,
   in addition to the Navy text + count; sits on the toolbar's bottom rule. */
.pp-plp-facet-trigger.has-selection::after {
	content: "";
	position: absolute;
	inset-inline-start: 50%;
	transform: translateX(-50%);
	bottom: -9px;
	width: min(60px, calc(100% - 12px));
	height: 3px;
	border-radius: var(--pp-radius-edge);
	background: var(--pp-edge-gradient);
	animation: pp-edge-in var(--pp-motion-micro) var(--pp-ease-out);
}
[dir="rtl"] .pp-plp-facet-trigger.has-selection::after { transform: translateX(50%); background: linear-gradient(270deg, var(--pp-navy) 0 73.3%, var(--pp-lime) 73.3% 100%); }
/* SHOP.SEO V4.2: "All filters" opens the all-groups sheet / drawer. */
.pp-plp-allfilters { gap: 6px; }
.pp-plp-allfilters .pp-i { width: 16px; height: 16px; }

.pp-plp-facet-popover {
	position: absolute;
	top: calc(100% + 6px);
	inset-inline-start: 0;
	min-width: 220px;
	background: #fff;
	border: 1px solid var(--pp-border);
	border-radius: var(--pp-radius-md);
	box-shadow: var(--pp-shadow-popover);
	padding: var(--pp-space-4);
	z-index: 20;
	/* INT.6 — COMPACT arrival (INT.5 rollout). plp.js flips .is-open on BOTH
	   edges, so open and close are plain transitions: no keyframes, no timers,
	   no presentation classes, no motion JS. The closed state is
	   visibility-hidden rather than display:none purely so the 100ms exit fade
	   can render; hidden + pointer-events:none keeps it as unfocusable and
	   AT-invisible as display:none was. Surface only — option rows never
	   stagger, and checkbox changes inside an open popover animate nothing. */
	--pp-plpf-open-ms: var(--pp-motion-popover-fast);
	--pp-plpf-ease: var(--pp-ease-enter);
	--pp-plpf-from: translateY(-4px); /* arrives from the trigger above */
	--pp-plpf-close-ms: 100ms;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: var(--pp-plpf-from);
	transition:
		opacity var(--pp-plpf-close-ms) var(--pp-ease-in),
		transform var(--pp-plpf-close-ms) var(--pp-ease-in),
		visibility 0s linear var(--pp-plpf-close-ms);
}
.pp-plp-facet-popover.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: none;
	transition:
		opacity var(--pp-plpf-open-ms) var(--pp-plpf-ease),
		transform var(--pp-plpf-open-ms) var(--pp-plpf-ease),
		visibility 0s;
}
/* Touch / coarse pointer — one fast surface, ≤3px, no hover dependency
   (the same gate INT.4 uses). */
@media (hover: none), (pointer: coarse) {
	.pp-plp-facet-popover {
		--pp-plpf-open-ms: 140ms;
		--pp-plpf-from: translateY(-3px);
	}
}
/* Reduced motion (G0): 80ms opacity-only — the global token already drops to
   80ms; re-asserting it here lets the token win over the coarse-pointer
   literal above by source order. No travel in either state. */
@media (prefers-reduced-motion: reduce) {
	.pp-plp-facet-popover {
		--pp-plpf-open-ms: var(--pp-motion-popover-fast);
		--pp-plpf-ease: linear;
		--pp-plpf-from: none;
	}
}
.pp-plp-facet-popover-foot {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--pp-space-2);
	margin-top: var(--pp-space-3);
	padding-top: var(--pp-space-3);
	border-top: 1px solid var(--pp-border);
}

.pp-plp-toolbar-right { margin-inline-start: auto; display: flex; align-items: center; gap: var(--pp-space-3); }
/* Sort — the PouchPick select at toolbar density (36px, Inter 600 13). */
.pp-plp-toolbar .pp-plp-sort { width: auto; min-height: 36px; padding: 6px 36px 6px 12px; font: 600 13px/1.2 var(--pp-font-body); border-width: 1px; border-radius: var(--pp-radius-control); }
.pp-plp:not(.pp-search-page) .pp-plp-toolbar { margin-bottom: 14px; }

/* ---------------- SHOP.SEO V4.2 — the strength row ----------------
   All · Light · Medium · Strong · 16+ with the approved meter, range and
   count: real links to listing URLs (template-parts/plp/strength-bands.php).
   A group with no product in this view stays on the scale, not a link. */

.pp-plp-bands { position: relative; display: flex; align-items: center; gap: 10px; margin: 0 0 10px; }
.pp-plp-bands-head { display: contents; }
.pp-plp-bands-label { order: 0; flex: none; margin: 0; font: 700 12px/1.2 var(--pp-font-body); letter-spacing: .04em; text-transform: uppercase; color: var(--pp-ink); }
.pp-plp-bands-label span { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--pp-secondary-text); }
.pp-plp-bands-list { order: 1; position: relative; display: flex; gap: 6px; min-width: 0; margin: 0; padding: 2px; list-style: none; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
.pp-plp-bands-list::-webkit-scrollbar { display: none; }
.pp-plp-bands-list > li { flex: none; scroll-snap-align: start; }
.pp-plp-band { position: relative; display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 0 12px 0 10px; border: 1px solid var(--pp-border); border-radius: 999px; background: #fff; color: var(--pp-ink); font: 600 13px/1 var(--pp-font-body); white-space: nowrap; text-decoration: none; transition: border-color var(--pp-motion-micro) var(--pp-ease-out), background-color var(--pp-motion-micro) var(--pp-ease-out); }
.pp-plp-band--all { padding-inline: 14px; }
.pp-plp-band-range { font-weight: 500; color: var(--pp-secondary-text); }
.pp-plp-band-n { min-width: 14px; font: 600 12px/1 var(--pp-font-body); color: var(--pp-secondary-text); font-variant-numeric: tabular-nums; text-align: end; }
@media (hover: hover) { a.pp-plp-band:hover { border-color: var(--pp-border-hover); background: var(--pp-soft-surface); } }
a.pp-plp-band:active, a.pp-plp-band.is-pressed { background: var(--pp-navy-tint); }
.pp-plp-band.is-active { border-color: var(--pp-navy); background: var(--pp-navy-tint); color: var(--pp-navy); box-shadow: inset 0 0 0 1px var(--pp-navy); }
.pp-plp-band.is-active .pp-plp-band-n, .pp-plp-band.is-active .pp-plp-band-range { color: var(--pp-navy); }
.pp-plp-band.is-empty:not(.is-active) { color: var(--pp-secondary-text); }
span.pp-plp-band[aria-disabled] { cursor: default; opacity: .6; }
.pp-plp-band:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
.pp-plp-bands-info { order: 2; flex: none; display: inline-grid; place-items: center; width: 40px; min-height: 40px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--pp-navy); cursor: pointer; }
@media (hover: hover) { .pp-plp-bands-info:hover { background: var(--pp-soft-surface); } }
.pp-plp-bands-info:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
.pp-plp-bands-info-t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.pp-plp-i { display: inline-grid; place-items: center; width: 18px; height: 18px; border: 1.5px solid currentColor; border-radius: 50%; font: 700 11px/1 var(--pp-font-body); }
.pp-plp-bands-note { position: absolute; z-index: 25; top: calc(100% + 6px); inset-inline-end: 0; width: min(420px, 100%); padding: 14px 16px; background: #fff; border: 1px solid var(--pp-border); border-radius: var(--pp-radius-md); box-shadow: var(--pp-shadow-popover); font: 400 13px/1.5 var(--pp-font-body); color: var(--pp-ink); }
.pp-plp-bands-note p { margin: 0 0 8px; }
.pp-plp-bands-note a { font-weight: 600; color: var(--pp-navy); }
@media (min-width: 901px) and (max-width: 1279px) { .pp-plp-bands-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } }

/* In the toolbar (desktop): one control bar — groups | Brand · Flavour · All
   filters; narrower desktops show more compact stops. The bar's meter is the
   approved component at its PDP scale (design-system.css §10d), as in the
   approved render. From 1056px it shows wherever the bar holds it on one row
   (assets/js/plp-bar-meter.js, `data-pp-meter`); where it would wrap (the approved render
   does at 1056–1100px, and wider with filter badges or larger counts) the bar
   is the approved 901–1055 word-and-count variant. Without JavaScript the
   meter shows from 1200px. */
.pp-plp-bands--row { display: none; }
.pp-plp-toolbar--bar .pp-plp-bands { flex: 0 1 auto; min-width: 0; margin: 0 6px 0 0; padding-inline-end: 10px; border-inline-end: 1px solid var(--pp-border); gap: 2px; }
.pp-plp-toolbar--bar .pp-plp-bands-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.pp-plp-toolbar--bar .pp-plp-band { min-height: 36px; padding: 0 10px 0 8px; gap: 6px; }
.pp-plp-toolbar--bar .pp-plp-band--all { padding-inline: 12px; }
.pp-plp-toolbar--bar .pp-plp-bands-list { gap: 4px; }
.pp-plp-toolbar--bar .pp-plp-facet-trigger { padding-inline: 8px; }
.pp-plp-toolbar--bar .pp-plp-bands-info { width: 36px; min-height: 36px; }
.pp-plp-toolbar--bar .pp-plp-bands-note { inset-inline-start: 0; inset-inline-end: auto; }
@media (min-width: 1056px) and (max-width: 1309.98px) { .pp-plp-toolbar--bar .pp-plp-band-range { display: none; } }
@media (min-width: 901px) and (max-width: 1055.98px) { .pp-plp-toolbar--bar .pp-plp-band-range, .pp-plp-toolbar--bar .pp-plp-band .pp-strength-meter { display: none; } }
@media (min-width: 1056px) and (max-width: 1199.98px) { .pp-plp-toolbar--bar:not([data-pp-meter="on"]) .pp-plp-band .pp-strength-meter { display: none; } }
.pp-plp-toolbar--bar[data-pp-meter="off"] .pp-plp-band .pp-strength-meter { display: none; }

/* ---------------- Shared filter-group / option primitives (panel, sheet, popovers) ---------------- */

.pp-plp-filter-group { margin-bottom: var(--pp-space-5); }
.pp-plp-filter-group h3 {
	font: 700 12px/1.3 var(--pp-font-body);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--pp-ink);
	margin: 0 0 var(--pp-space-2);
}
.pp-plp-filter-option {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 40px;
	font: 400 14px/1.3 var(--pp-font-body);
	color: var(--pp-ink);
	cursor: pointer;
}
.pp-plp-filter-option input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--pp-navy); cursor: pointer; flex-shrink: 0; }
.pp-plp-opt-count { margin-inline-start: auto; color: var(--pp-secondary-text); font-size: 0.75rem; }
.pp-plp-facet-popover .pp-plp-filter-option { min-height: 36px; }

/* ---------------- Active filter chips (design-system .pp-chip) ---------------- */

.pp-plp-active-filters {
	display: flex;
	align-items: center;
	gap: var(--pp-space-2);
	flex-wrap: wrap;
	margin-bottom: var(--pp-space-4);
}
.pp-plp-active-filters .pp-chip { color: var(--pp-ink); }
.pp-plp-active-filters .pp-chip .pp-i { color: var(--pp-secondary-text); }
.pp-plp-active-filters .pp-chip:hover .pp-i { color: var(--pp-ink); }
.pp-plp-clear-all { font-size: 12.5px; }

/* ---------------- The all-filters sheet (phones) / drawer (desktop, SHOP.SEO V4.2) ----------------
   A viewport-level overlay on the theme's modal layer (300 — the Cart Drawer
   overlay's layer; header shell is 200), rendered OUTSIDE the toolbar's
   backdrop-filter stacking context (lock §28 / S9A F3 P0). Shared contract
   (pp-overlay.js): scrim, focus trap, Escape, focus return, scroll lock;
   transitions on the overlay tokens (fade only under reduced motion). */

.pp-fpanel-overlay {
	position: fixed;
	inset: 0;
	background: var(--pp-overlay);
	z-index: 300;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity var(--pp-motion-overlay-exit) var(--pp-ease-in), visibility 0s linear var(--pp-motion-overlay-exit);
}
.pp-fpanel-overlay.is-open { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity var(--pp-motion-overlay) var(--pp-ease-out), visibility 0s; }

.pp-fpanel { position: absolute; background: #fff; display: flex; flex-direction: column; }
.pp-fpanel--sheet {
	top: 24px; inset-inline: 0; bottom: 0;
	border-radius: var(--pp-radius-lg) var(--pp-radius-lg) 0 0;
	overflow: hidden;
	transform: translateY(100%);
	transition: transform var(--pp-motion-overlay-exit) var(--pp-ease-in);
}
.pp-fpanel-overlay.is-open .pp-fpanel--sheet { transform: none; transition: transform var(--pp-motion-overlay) var(--pp-ease-out); }
.pp-fpanel--sheet form { display: flex; flex-direction: column; flex: 1; min-height: 0; }

.pp-fpanel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--pp-space-3); padding: 14px 12px 12px 24px; border-bottom: 1px solid var(--pp-border); flex: none; }
.pp-fpanel-head h2 { font: 600 20px/1.2 var(--pp-font-display); letter-spacing: -0.01em; margin: 0; }
.pp-fpanel-head .pp-icon-btn { color: var(--pp-ink); }
.pp-fpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px; }
.pp-fpanel-foot { flex: none; display: flex; align-items: center; gap: var(--pp-space-3); padding: 14px 24px; border-top: 1px solid var(--pp-border); --pp-safe-pad-bottom: 14px; }
.pp-fpanel-foot .pp-btn-primary { flex: 1; }
@media (max-width: 767px) {
	.pp-fpanel-head { padding-inline: var(--pp-gutter-mobile); }
	.pp-fpanel-body { padding-inline: var(--pp-gutter-mobile); }
	.pp-fpanel-foot { padding-inline: var(--pp-gutter-mobile); }
}
/* From 901px the same sheet is a 320px drawer at the end of the viewport. */
@media (min-width: 901px) {
	.pp-plp-sheet-overlay .pp-fpanel--sheet { top: 0; bottom: 0; inset-inline: auto 0; width: 320px; max-width: 88vw; border-radius: 0; box-shadow: var(--pp-shadow-drawer); transform: translateX(100%); }
	[dir="rtl"] .pp-plp-sheet-overlay .pp-fpanel--sheet { transform: translateX(-100%); }
	.pp-plp-sheet-overlay.is-open .pp-fpanel--sheet { transform: none; }
	.pp-plp-sheet-overlay .pp-fpanel-head { padding-inline-start: 20px; }
	.pp-plp-sheet-overlay .pp-fpanel-body { padding: 4px 20px 20px; }
	.pp-plp-sheet-overlay .pp-fpanel-foot { padding-inline: 20px; }
}

/* Filter groups as disclosure rows: Strength open first (its groups, then the
   exact values), every group with a selection open; long groups show eight
   options and "Show all N". */
.pp-plp-group { margin: 0; border-bottom: 1px solid var(--pp-border); }
.pp-plp-group > summary { display: flex; align-items: center; gap: 8px; min-height: 52px; list-style: none; cursor: pointer; }
.pp-plp-group > summary::-webkit-details-marker { display: none; }
.pp-plp-group > summary h3 { margin: 0; }
.pp-plp-group > summary::after { content: ""; margin-inline-start: auto; width: 8px; height: 8px; border: solid var(--pp-secondary-text); border-width: 0 1.6px 1.6px 0; transform: rotate(45deg) translate(-2px, -2px); transition: transform var(--pp-motion-micro) var(--pp-ease-out); }
.pp-plp-group[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.pp-plp-group > summary:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
.pp-plp-group-n { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--pp-navy); color: #fff; font: 700 10.5px/1 var(--pp-font-body); }
.pp-plp-group-body { padding: 0 0 12px; }
.pp-plp-group-body .pp-plp-opt-more { display: none; }
.pp-plp-group-body.is-all .pp-plp-opt-more { display: flex; }
.pp-plp-showall { margin-top: 4px; min-height: 40px; }
.pp-plp-bandopt { white-space: nowrap; }
.pp-plp-bandopt-word { font-weight: 600; }
.pp-plp-bandopt-range { color: var(--pp-secondary-text); }
.pp-plp-exact { margin: 4px 0 0; }
.pp-plp-exact > summary { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; font: 600 13px/1.2 var(--pp-font-body); color: var(--pp-navy); cursor: pointer; list-style: none; text-decoration: underline; text-underline-offset: 3px; }
.pp-plp-exact > summary::-webkit-details-marker { display: none; }
.pp-plp-exact > summary:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
.pp-plp-exact-n { color: var(--pp-secondary-text); text-decoration: none; font-weight: 500; }
.pp-plp-exact-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 14px; }

/* ---------------- Mobile Filter + Sort bar ---------------- */

.pp-plp-mobile-bar {
	display: none;
	gap: var(--pp-space-2);
	padding: 0 0 var(--pp-space-3);
}
.pp-plp-mobile-filter-btn { flex: 1; gap: 8px; }
.pp-plp-mobile-filter-btn .pp-i { width: 18px; height: 18px; }
.pp-plp-count-dot {
	background: var(--pp-navy);
	color: #fff;
	font: 700 10.5px/1 var(--pp-font-body);
	min-width: 18px;
	height: 18px;
	border-radius: 9px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 5px;
}
.pp-plp-mobile-bar .pp-plp-sort { flex: 1; min-height: var(--pp-hit-min); font-weight: 600; }

/* ---------------- Empty state ----------------
   SF.4: moved to assets/css/states.css (.pp-state) — the same box, shared by
   the Shop listing, the search page and the 404, now with a state per kind
   (search / search-filtered / deals / filters — inc/plp.php). */

/* ---------------- Pagination (native woocommerce_pagination(), restyled) ---------------- */

.pp-plp-pagination { padding: var(--pp-space-5) 0 0; }
.pp-plp-pagination .woocommerce-pagination { display: flex; justify-content: center; }
.pp-plp-pagination .page-numbers {
	list-style: none;
	display: flex;
	gap: 6px;
	margin: 0;
	padding: 0;
}
.pp-plp-pagination .page-numbers li { display: inline-flex; }
.pp-plp-pagination .page-numbers a,
.pp-plp-pagination .page-numbers span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 36px;
	height: 36px;
	padding: 0 10px;
	border-radius: var(--pp-radius-control);
	border: 1px solid var(--pp-border);
	font: 600 13px/1 var(--pp-font-body);
	color: var(--pp-ink);
}
.pp-plp-pagination .page-numbers .current { background: var(--pp-navy); border-color: var(--pp-navy); color: #fff; }
.pp-plp-pagination .page-numbers a:hover { background: var(--pp-soft-surface); }
@media (max-width: 767px) {
	.pp-plp-pagination .page-numbers a, .pp-plp-pagination .page-numbers span { min-width: var(--pp-hit-min); height: var(--pp-hit-min); }
}
/* SHOP.SEO V4.2 (found in V3): WooCommerce's own woocommerce.css outranks the
   rules above (`.woocommerce nav.woocommerce-pagination ul …` — floats, a
   boxed list and a #ebe9eb current page at 3.6:1), so the Shop pages never
   showed them. Restated at that specificity. */
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; border: 0; margin: 0; }
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li { float: none; border: 0; overflow: visible; }
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li :is(a, span) { display: inline-flex; align-items: center; justify-content: center; min-width: 36px; height: 36px; padding: 0 10px; border: 1px solid var(--pp-border); border-radius: var(--pp-radius-control); background: #fff; font: 600 13px/1 var(--pp-font-body); color: var(--pp-ink); }
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li span.current { background: var(--pp-navy); border-color: var(--pp-navy); color: #fff; }
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li span.dots { border-color: transparent; }
.pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li a:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
@media (hover: hover) { .pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li a:hover { background: var(--pp-soft-surface); } }
@media (max-width: 767px) { .pp-plp .pp-plp-pagination .woocommerce-pagination ul.page-numbers li :is(a, span) { min-width: var(--pp-hit-min); height: var(--pp-hit-min); } }

/* ---------------- SHOP.SEO V4.2 — "Show more products" + the quiet numbered pages ----------------
   One clear next step after the last products (a real link to the next page,
   appended in place by assets/js/load-more.js); the numbered pages stay below
   as the quiet alternative. The icon slot keeps the button's width: a
   chevron at rest, Production's spinner while loading. */
.pp-plp-prev { margin: 0 0 16px; text-align: center; }
.pp-plp-prev a { display: inline-flex; align-items: center; min-height: 40px; font: 600 13.5px/1 var(--pp-font-body); color: var(--pp-navy); }
.pp-plp-more { display: grid; justify-items: center; gap: 12px; max-width: 460px; margin: 40px auto 0; text-align: center; }
.pp-plp-more-status { margin: 0; font: 500 13.5px/1.4 var(--pp-font-body); color: var(--pp-secondary-text); }
.pp-plp-more-status b { font-weight: 600; color: var(--pp-ink); font-variant-numeric: tabular-nums; }
.pp-plp-more-bar { width: 240px; height: 3px; border-radius: 2px; background: var(--pp-border); overflow: hidden; }
.pp-plp-more-bar > span { display: block; height: 100%; border-radius: 2px; background: var(--pp-navy); transition: width var(--pp-motion-micro) var(--pp-ease-out); }
.pp-plp-more-btn { gap: 10px; min-height: 52px; min-width: 300px; margin-top: 4px; padding-inline: 28px; border: 1.5px solid var(--pp-ink); border-radius: var(--pp-radius-md); background: #fff; color: var(--pp-ink); font: 600 16px/1 var(--pp-font-body); transition: background-color var(--pp-motion-micro) var(--pp-ease-out), color var(--pp-motion-micro) var(--pp-ease-out), transform var(--pp-motion-press-out) var(--pp-ease-out); }
/* Production's phone rule `.pp-btn:not(.pp-btn-l)` (design-system.css, ≤767px: the 44px hit minimum) out-ranks the
   class above; the approved button keeps its 52px on phones too. */
.pp-plp-more .pp-plp-more-btn { min-height: 52px; }
.pp-plp-more-btn.is-loading { pointer-events: none; }
.pp-plp-more-ico { display: inline-flex; flex: none; width: 16px; height: 16px; }
.pp-plp-more-ico .pp-i { width: 16px; height: 16px; transform: translateY(0); transition: transform var(--pp-motion-micro) var(--pp-ease-out); }
.pp-plp-more-btn.is-loading .pp-plp-more-ico { display: none; }
@media (hover: hover) {
	.pp-plp-more-btn:hover { background: var(--pp-ink); border-color: var(--pp-ink); color: #fff; }
	.pp-plp-more-btn:hover .pp-plp-more-ico .pp-i { transform: translateY(var(--pp-dir-travel)); }
}
.pp-plp-more-end { margin: 4px 0 0; font: 600 13.5px/1.4 var(--pp-font-body); color: var(--pp-ink); }
.pp-plp-pages { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 10px; padding-top: 14px; }
.pp-plp-pages-k { font: 500 13px/1 var(--pp-font-body); color: #5A6572; }
.pp-plp .pp-plp-pages .woocommerce-pagination ul.page-numbers { gap: 2px; }
.pp-plp .pp-plp-pages .woocommerce-pagination ul.page-numbers li :is(a, span) { min-width: 40px; height: 40px; border-color: transparent; background: transparent; font: 600 14px/1 var(--pp-font-body); color: var(--pp-navy); transition: background-color var(--pp-motion-micro) var(--pp-ease-out); }
.pp-plp .pp-plp-pages .woocommerce-pagination ul.page-numbers li span.current { background: transparent; border-color: transparent; border-radius: 0; color: var(--pp-ink); box-shadow: inset 0 -2px 0 var(--pp-ink); }
@media (hover: hover) { .pp-plp .pp-plp-pages .woocommerce-pagination ul.page-numbers li a:hover { background: var(--pp-soft-surface); } }
@media (max-width: 767px) { .pp-plp .pp-plp-pages .woocommerce-pagination ul.page-numbers li :is(a, span) { min-width: 44px; height: 44px; } }
/* Products added by "Show more" arrive with a short rise (opacity + transform only). */
[data-plp-grid] > .pp-plp-enter { opacity: 0; transform: translateY(8px); }
[data-plp-grid] > .pp-plp-enter.is-in { opacity: 1; transform: none; transition: opacity var(--pp-motion-entrance) var(--pp-ease-out), transform var(--pp-motion-entrance) var(--pp-ease-out); transition-delay: calc(var(--pp-plp-i, 0) * var(--pp-motion-stagger)); }

/* ---------------- Product grid ---------------- */

.pp-plp-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
	gap: var(--pp-space-5);
}
.pp-plp-grid > .pp-card { min-width: 0; }

/* ================================================================
 * Responsive — 900px remains the PLP's own extracted UI-mode breakpoint
 * (design-lab/final/plp/round-2-5.css: ".r25-toolbar{display:none}" below
 * 900px): the sticky facet toolbar/active-filter chip bar give way to the
 * dedicated mobile Filter+Sort bar there, unchanged from the original S5
 * implementation and untouched by this pass.
 *
 * Grid density below 900px is a SEPARATE concern from that UI-mode switch
 * (human visual correction pass): a one-column card at tablet width read as
 * "a mobile card stretched wide," not an intentional tablet composition —
 * ROUND-2-DECISIONS.md's "mobile cards remain one column... never two
 * columns" is honored for actual phone widths, refined here to mean phone
 * widths specifically rather than the whole sub-900px range.
 *
 * The 600px lower bound is measured, not an arbitrary device width: at
 * 600px a 2-column card is 256px wide and the longest real product title in
 * this catalogue ("LOOP Habanero Mint Hyper Strong") sits on one line; at
 * 560px and below the same title wraps to two lines and the tier row
 * narrows below a comfortable width (measured live via Playwright across
 * 430–1024px). 600px is also one of the required verification widths.
 * ================================================================ */

@media (max-width: 900px) {
	.pp-plp-toolbar { display: none; }
	.pp-plp-mobile-bar { display: flex; }
	.pp-plp-headsort { display: none; }
	/* SHOP.SEO V4.2: the strength row is its own scrolling row; the range lives
	   in the note and the guide, a compact meter keeps the scale readable. */
	.pp-plp-bands--row { display: flex; margin: 0 calc(var(--pp-gutter-mobile) * -1) 10px; padding-inline-start: var(--pp-gutter-mobile); gap: 6px; }
	.pp-plp-bands-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
	.pp-plp-bands--row .pp-plp-bands-list { padding-inline-end: var(--pp-gutter-mobile); -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
	.pp-plp-bands--row .pp-plp-band-range { display: none; }
	.pp-plp-bands--row .pp-plp-band { gap: 6px; padding-inline: 8px 11px; }
	.pp-plp-bands--row .pp-plp-band--all { padding-inline: 12px; }
	.pp-plp-bands--row .pp-strength-meter { gap: 2px; padding: 3px 5px; }
	.pp-plp-bands--row .pp-strength-meter i { width: 6px; height: 4px; border-radius: 1px; }
	.pp-plp-bands--row .pp-plp-bands-info { position: relative; margin-inline-end: 8px; }
	/* GLOBAL-COMMERCE-POLISH §15: a ≥ 44px effective hit area for filter controls on true mobile. The approved
	   40px pill and 40px info button stay the visual and the layout; their hit areas reach 2px further (the pill's
	   inset counts from the padding box, inside its 1px border). */
	.pp-plp-bands--row .pp-plp-band::after { content: ""; position: absolute; inset: -3px -1px; }
	.pp-plp-bands--row .pp-plp-bands-info::after { content: ""; position: absolute; inset: -2px; border-radius: 50%; }
	.pp-plp-bands--row .pp-plp-bands-note { inset-inline: var(--pp-gutter-mobile); width: auto; }
	/* The Filter / Sort bar sticks at the header line, so filtering is always one tap away. */
	.pp-plp:not(.pp-search-page) .pp-plp-mobile-bar { position: sticky; top: calc(var(--pp-sticky-top, 0px) + var(--pp-admin-bar-h, 0px)); z-index: 15; margin: 0 calc(var(--pp-gutter-mobile) * -1) 10px; padding: 6px var(--pp-gutter-mobile); background: rgba(255, 255, 255, .95); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); border-bottom: 1px solid var(--pp-border); }
	.pp-plp-mobile-bar .pp-btn, .pp-plp-mobile-bar .pp-plp-sort { min-height: 44px; }
	.pp-plp:not(.pp-search-page) .pp-plp-head { padding-top: 12px; padding-bottom: 4px; }
	.pp-plp:not(.pp-search-page) .pp-plp-title { font-size: 1.5rem; }
	.pp-plp:not(.pp-search-page) .pp-plp-desc { font-size: 12.5px; line-height: 1.45; }
}

/* Tablet: intentional 2-column density, not a stretched mobile card. */
@media (min-width: 600px) and (max-width: 900px) {
	.pp-plp-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Phone: two columns (SHOP.SEO V4.2, PLP lock §J amended — the Brand Page's
   phone grid, with the narrow card's quantity sheet: product-card.css). */
@media (max-width: 599px) {
	.pp-plp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
	.pp-plp-grid > .pp-card { padding: var(--pp-card-pad-compact); }
	.pp-plp-grid > .pp-card .pp-card-media { margin-bottom: var(--pp-space-2); }
	.pp-plp-grid > .pp-card .pp-card-price { margin: 8px 0 10px; }
}

/* SHOP.SEO V4.2 — balanced final rows. Explicit column counts at the grid's
   own auto-fill breakpoints (230px cards, 24px gaps, the 1320px container:
   5 columns from 1310px, 4 at 1056–1309, 3 at 901–1055) on a HALF-column
   track grid where every card spans two tracks — card widths are unchanged,
   but a row can be centred. When the last row is short and there is more
   than one row, the last two rows share their cards as evenly as possible
   (5 + 1 → 3 + 3, 4 + 1 → 3 + 2, 3 + 1 → 2 + 2), centred. Pure
   :nth-child / :nth-last-child, so a filtered count and a "Show more" append
   rebalance by themselves. Order never changes, no card is resized or
   duplicated; a one-row result and the two-column layouts stay as they are.
   (Generator: SHOPSEO lab tools/v4_grid_css.py.) */
@media (min-width: 1310px) {
	[data-plp-grid] { grid-template-columns: repeat(10, minmax(0, 1fr)); }
	[data-plp-grid] > * { grid-column: span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(6) { grid-column: 3 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(6) ~ :nth-last-child(3) { grid-column: 3 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(7) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(7) ~ :nth-last-child(3) { grid-column: 3 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(8) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(8) ~ :nth-last-child(4) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(5n+1):nth-last-child(9) ~ :nth-last-child(4) { grid-column: 2 / span 2; }
}
@media (min-width: 1056px) and (max-width: 1309.98px) {
	[data-plp-grid] { grid-template-columns: repeat(8, minmax(0, 1fr)); }
	[data-plp-grid] > * { grid-column: span 2; }
	[data-plp-grid] > :nth-child(4n+1):nth-last-child(5) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(4n+1):nth-last-child(5) ~ :nth-last-child(2) { grid-column: 3 / span 2; }
	[data-plp-grid] > :nth-child(4n+1):nth-last-child(6) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(4n+1):nth-last-child(6) ~ :nth-last-child(3) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(4n+1):nth-last-child(7) ~ :nth-last-child(3) { grid-column: 2 / span 2; }
}
@media (min-width: 901px) and (max-width: 1055.98px) {
	[data-plp-grid] { grid-template-columns: repeat(6, minmax(0, 1fr)); }
	[data-plp-grid] > * { grid-column: span 2; }
	[data-plp-grid] > :nth-child(3n+1):nth-last-child(4) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(3n+1):nth-last-child(4) ~ :nth-last-child(2) { grid-column: 2 / span 2; }
	[data-plp-grid] > :nth-child(3n+1):nth-last-child(5) ~ :nth-last-child(2) { grid-column: 2 / span 2; }
}

/* ================================================================
 * TABLET CARD DENSITY (human production-review correction, post-S6D):
 * live browser review at 1024/900/820/768px found the card reading as a
 * desktop card simply zoomed up — tighter internal spacing and a more
 * compact tier selector / CTA. Column-count architecture above is untouched
 * (still governed by the 900px/600px rules): this is internal card density
 * only (compact card padding, lock §22), spanning the combined range those
 * two column-count zones cover (600–1024). True desktop (>1024px) and true
 * mobile (<600px) keep the full density. The segmented cells keep their
 * ≥44px floor at every width (lock §27).
 * ================================================================ */
@media (min-width: 600px) and (max-width: 1024px) {
	.pp-plp-grid > .pp-card { padding: var(--pp-card-pad-compact); }
	.pp-plp-grid > .pp-card .pp-card-media { margin-bottom: var(--pp-space-2); }
	.pp-plp-grid > .pp-card .pp-card-price { margin: 8px 0 10px; }
}

/* ---------------- True-mobile gutter (lock §17) — this OWNED discovery
   surface migrates to the 16px primary commerce gutter across the whole
   true-mobile range (S9D-A kept 481–767 at 32px globally). ---------------- */
@media (max-width: 767px) {
	.pp-plp .pp-container { padding-inline: var(--pp-gutter-mobile); }
}

/* ---------------- Reduced motion (lock §7): overlays fade only ---------------- */
@media (prefers-reduced-motion: reduce) {
	.pp-fpanel--sheet, .pp-plp-sheet-overlay .pp-fpanel--sheet, [dir="rtl"] .pp-plp-sheet-overlay .pp-fpanel--sheet { transform: none; }
	.pp-plp-facet-trigger.has-selection::after { animation: none; }
	[data-plp-grid] > .pp-plp-enter { opacity: 1; transform: none; }
}

/* ---------------- SF.4 — the generic search page (search.php) ----------------
   Products reuse the PLP grid + card; other result types are compact title
   rows on the PLP's own border / radius / type tokens. */

.pp-search-group + .pp-search-group { margin-top: var(--pp-space-6); }
.pp-search-group-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--pp-space-3); flex-wrap: wrap; margin-bottom: var(--pp-space-4); padding-top: var(--pp-space-3); border-top: 1px solid var(--pp-border); }
.pp-search-group-title { margin: 0; font-family: var(--pp-font-display); font-size: var(--pp-text-sub-title); font-weight: 600; line-height: 1.2; }
.pp-search-group-all { display: inline-flex; align-items: center; gap: 6px; font-size: var(--pp-text-label); font-weight: 600; color: var(--pp-navy); overflow-wrap: anywhere; }
.pp-search-group-all .pp-i { color: currentColor; flex: none; }
.pp-search-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pp-space-2); }
.pp-search-row {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: var(--pp-space-3) var(--pp-space-4);
	background: #fff;
	border: 1px solid var(--pp-border);
	border-radius: var(--pp-radius-lg);
	color: var(--pp-ink);
	transition: border-color var(--pp-motion-micro) var(--pp-ease-out);
}
.pp-search-row:hover { border-color: var(--pp-navy); }
.pp-search-row-type { font-size: var(--pp-text-meta-min); font-weight: 700; line-height: 1.3; letter-spacing: 0.06em; text-transform: uppercase; color: var(--pp-secondary-text); }
.pp-search-row-title { font-family: var(--pp-font-display); font-size: 1rem; font-weight: 600; line-height: 1.3; }
.pp-search-row-text { font-size: var(--pp-text-label); line-height: 1.45; color: var(--pp-secondary-text); }
