/*
 * PouchPick shared product-card grammar — S9D-B (Global Commerce Polish,
 * discovery surfaces). GLOBAL-COMMERCE-POLISH-LOCK.md §9 (Lifted Can), §22
 * (card core), §23 (no numeric savings badge), §24 (packshot), §25 (hover),
 * §26 (pricing presentation), §27 (tier selector), §5 (Edge on the selected
 * tier only). Values measured from the promoted final lab
 * design-lab/final/global-polish/ (Hybrid V2, global-polish.css §11).
 *
 * ONE grammar, contextual layouts: `.pp-tiers--grid` (Homepage 2×2 + Best
 * Value) and `.pp-tiers--segmented` (PLP 5-cell row). Consumed by
 * front-page.php and woocommerce/content-product.php in S9D-B; the PDP,
 * related rail, Cart Drawer / Cart Page compact rows and Account historical
 * previews adopt it in their own gates (S9D-C / S9D-D). Presentation only —
 * every price, saving and tier value is server-formatted WooCommerce data
 * (MARKET-ARCHITECTURE.md §14); nothing here computes or formats money.
 */

/* ---------- Packshot (lock §24) ----------
   S9D-D: the base `.pp-packshot` component moved to design-system.css so the
   ONE shared packshot is available on every surface that renders a product
   image — including the ones that do not load this card stylesheet (Checkout's
   order review, Pay for Order, Order Received). Pure move: identical
   declarations, no visual change. Card-context sizing stays here. */

/* ---------- Card shell (lock §22): radius 12, hairline border, 16px padding ---------- */
.pp-card {
	display: flex;
	flex-direction: column;
	background: var(--pp-card-bg);
	border: 1px solid var(--pp-border);
	border-radius: var(--pp-radius-card);
	padding: var(--pp-card-pad);
	position: relative;
	min-width: 0;
	transition: border-color var(--pp-motion-micro) var(--pp-ease-out);
}
.pp-card-media { display: block; position: relative; margin-bottom: 12px; }
.pp-card-media-link { display: block; }
.pp-card-badges { position: absolute; top: 10px; inset-inline-start: 10px; display: flex; flex-direction: column; gap: 4px; z-index: 1; }
.pp-card-badge { display: inline-block; font: 800 10px/1 var(--pp-font-body); letter-spacing: .02em; padding: 5px 8px; border-radius: 5px; text-transform: uppercase; }
.pp-card-badge--new { background: var(--pp-lime); color: var(--pp-ink); }
.pp-card-badge--sale { background: var(--pp-red); color: #fff; }
.pp-card-badge--muted { background: var(--pp-secondary-surface); color: var(--pp-secondary-text); }

.pp-card-brand { display: block; font: 700 var(--pp-text-meta-min)/1.2 var(--pp-font-body); letter-spacing: .04em; text-transform: uppercase; color: var(--pp-navy); }
.pp-card-title { font: 600 var(--pp-text-card-title)/1.3 var(--pp-font-body); letter-spacing: 0; color: var(--pp-ink); margin: 3px 0 2px; transition: color var(--pp-motion-micro) var(--pp-ease-out); }
.pp-card-title a { color: inherit; }
.pp-card-meta { font: 400 var(--pp-text-meta)/1.35 var(--pp-font-body); color: var(--pp-secondary-text); margin: 0; }
.pp-card-rating { font: 400 var(--pp-text-meta-min)/1.3 var(--pp-font-body); color: var(--pp-secondary-text); margin: 4px 0 0; }

/* ---------- Price hierarchy (lock §26): PRIMARY per-can 20/700 + unit 13/500,
   SECONDARY struck reference (discounted tiers only), SAVINGS Navy 12/700,
   TERTIARY labelled total 11/500 uppercase. ---------- */
.pp-card-price { margin: 10px 0 12px; display: flex; flex-direction: column; gap: 2px; }
.pp-price-primary { font: 700 var(--pp-text-price-primary)/1.2 var(--pp-font-body); color: var(--pp-ink); }
.pp-price-primary .unit { font: 500 var(--pp-text-label)/1 var(--pp-font-body); color: var(--pp-secondary-text); }
.pp-price-ref { font: 400 var(--pp-text-meta)/1.3 var(--pp-font-body); color: var(--pp-secondary-text); text-decoration: line-through; }
.pp-price-save { font: 700 var(--pp-text-meta)/1.3 var(--pp-font-body); color: var(--pp-navy); }
.pp-price-total { font: 500 var(--pp-text-meta-min)/1.3 var(--pp-font-body); color: var(--pp-secondary-text); text-transform: uppercase; letter-spacing: .03em; }
.pp-price-total b { font-weight: 600; color: var(--pp-ink); text-transform: none; letter-spacing: 0; }
.pp-price-ref[hidden], .pp-price-save[hidden] { display: none; }
.pp-card-cta { margin-top: auto; }
.pp-card-cta .pp-btn { width: 100%; }
/* S9E-A1: a real WooCommerce rejection of a direct card add renders the ONE
   shared commerce-notice error variant (design-system.css) inside the card,
   below the CTA — the component owns its own geometry; only the gap is set. */
.pp-card .pp-card-notice { margin-top: var(--pp-space-2); }
.pp-card--oos .pp-packshot img { opacity: .35; }
.pp-card--oos .pp-price-primary { color: var(--pp-secondary-text); }

/* ---------- Tier selector (lock §27) — one grammar, two layouts ----------
   Every rule is scoped under .pp-tiers: the PDP's own .pp-tier cells
   (pdp.css, S9D-C) co-load this stylesheet and must not inherit it yet. */
.pp-tiers { display: grid; gap: 6px; margin: 4px 0 0; }
.pp-tiers--grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pp-tiers--grid .pp-tier-bv { grid-column: 1 / -1; }
.pp-tiers--segmented { display: flex; gap: 0; border: 1px solid var(--pp-border); border-radius: var(--pp-radius-control); overflow: visible; }

.pp-tiers .pp-tier {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1px;
	min-height: 44px;
	padding: 7px 6px;
	font-family: var(--pp-font-body);
	font-weight: 600;
	font-size: 12.5px;
	line-height: 1.15;
	color: var(--pp-ink);
	background: #fff;
	border: 1px solid var(--pp-border);
	border-radius: var(--pp-radius-control);
	text-align: center;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	transition:
		background-color var(--pp-motion-micro) var(--pp-ease-out),
		border-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);
}
.pp-tiers .pp-tier:hover { background: var(--pp-soft-surface); border-color: var(--pp-border-hover); }
.pp-tiers .pp-tier:active, .pp-tiers .pp-tier.is-pressed { background: var(--pp-navy-tint); border-color: var(--pp-navy); transform: scale(var(--pp-press-scale-compact)); transition-duration: var(--pp-motion-press-in); }
.pp-tiers .pp-tier.is-selected { background: var(--pp-navy-tint); border-color: var(--pp-navy); color: var(--pp-navy); }
.pp-tiers .pp-tier:disabled { opacity: .5; cursor: not-allowed; transform: none; background: #fff; }
.pp-tiers .pp-tier-qty { display: block; font-weight: 600; }
/* Ordinary tier-discount percentage is NAVY (lock §10, §27) — never Red. */
.pp-tiers .pp-tier-pct { display: block; font: 600 var(--pp-text-meta-min)/1.2 var(--pp-font-body); color: var(--pp-navy); }
.pp-tiers .pp-tier-pct.pp-tier-unit { color: var(--pp-secondary-text); }
/* Selected-cell rule (lock §27): the selected cell never repeats a saving the
   price block already states — the "−X%" (and the qty-1 unit label) hide. */
.pp-tiers .pp-tier.is-selected .pp-tier-pct { display: none; }
.pp-tiers .pp-tier-badge {
	position: absolute; top: -9px; inset-inline-start: 50%; transform: translateX(-50%);
	background: var(--pp-navy); color: #fff; font: 700 9px/1 var(--pp-font-body);
	padding: 4px 7px; border-radius: 5px; white-space: nowrap; letter-spacing: .02em;
}
.pp-tiers .pp-tier-bv { padding-top: 12px; }

/* Segmented row — cells share the row border; the selected cell carries the Edge. */
.pp-tiers--segmented .pp-tier { flex: 1; min-width: 0; border: 0; border-inline-end: 1px solid var(--pp-border); border-radius: 0; padding: 6px 2px 7px; }
/* The last TIER (SHOP.SEO V4.2: on Shop cards the quantity sheet's head and close button follow the tiers). */
.pp-tiers--segmented .pp-tier:is(:last-child, :has(+ .pp-qty-head)) { border-inline-end: 0; }
.pp-tiers--segmented .pp-tier:first-child { border-start-start-radius: var(--pp-radius-control); border-end-start-radius: var(--pp-radius-control); }
.pp-tiers--segmented .pp-tier:is(:last-child, :has(+ .pp-qty-head)) { border-start-end-radius: var(--pp-radius-control); border-end-end-radius: var(--pp-radius-control); }
.pp-tiers--segmented .pp-tier-qty { font-size: 14px; }
.pp-tiers--segmented .pp-tier-pct { font-size: 10.5px; }
.pp-tiers--segmented .pp-tier:active, .pp-tiers--segmented .pp-tier.is-pressed { transform: none; }

/* Edge (lock §5) — ONLY on the selected tier cell, always in addition to the
   Navy tint + border; 3px, ≈73/27 Navy/Lime, 60px where the cell allows. */
.pp-tiers .pp-tier.is-selected::after {
	content: "";
	position: absolute;
	inset-inline-start: 50%;
	transform: translateX(-50%);
	bottom: -1px;
	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);
}
.pp-tiers--segmented .pp-tier.is-selected::after { bottom: 0; }
[dir="rtl"] .pp-tiers .pp-tier.is-selected::after { transform: translateX(50%); background: linear-gradient(270deg, var(--pp-navy) 0 73.3%, var(--pp-lime) 73.3% 100%); }

/* ---------- Standard-card packshot presentation (PI.1) ----------
   The card context is the approved 80% optical target: the corrected meta
   scale puts every contract can at the 66% reference, and this ONE surface
   factor raises it to 80/66. Applies wherever the shared card grammar is
   used — Home rails, PLP, related. The tilt pivots near the can base, so
   the pick-up reads physical; at production display scales the sub-2px
   rest-state offset this origin introduces is invisible. */
.pp-card .pp-packshot { --pp-stage-fit: 1.2121; }
.pp-card .pp-packshot img { transform-origin: 50% 88%; }

/* ---------- Lifted Can (lock §9/§25, amended by PI.1 human selection) —
   fine-pointer hover only: the PRODUCT rises 4px and tilts 1.6° in ONE
   consistent direction (H4; the grounded floor shadow responds in
   design-system.css §10b-GS). The CARD itself never moves — feedback is
   B1: an extremely subtle Navy border tint plus the Navy title. No card
   scale, no card shadow, nothing on touch; reduced motion zeroes both
   motion tokens so the product stays still. ---------- */
@media (hover: hover) and (pointer: fine) {
	/* The 4px card lift is declared ON .pp-card, which would outrank the
	   :root reduced-motion zeroing of the token — so it carries the same
	   reduced-motion guard itself; under reduce the card inherits 0px/0deg
	   and the hover transform resolves to the rest state. */
	@media (prefers-reduced-motion: no-preference) {
		.pp-card { --pp-lift: 4px; }
	}
	.pp-card:hover { border-color: rgba(20, 47, 81, 0.5); } /* --pp-navy at 50% — B1 */
	.pp-card:hover .pp-packshot img { transform: translateY(calc(var(--pp-lift) * -1)) rotate(calc(var(--pp-tilt, 0deg) * -1)) scale(var(--pp-packshot-display, 1)); }
	.pp-card:hover .pp-card-title { color: var(--pp-navy); }
}

/* ---------- Reduced motion (lock §7): Edge instant, no lift, press shade only ---------- */
@media (prefers-reduced-motion: reduce) {
	.pp-tiers .pp-tier.is-selected::after { animation: none; }
	.pp-tiers .pp-tier:active, .pp-tiers .pp-tier.is-pressed { transform: none; }
	.pp-packshot img { transition: none; }
}

/* ---------- MK.8B-P1: fail-closed "not available" card state ----------
   A product with no valid storefront price renders a quiet Inter note in
   the price slot — never a money string, never the stock vocabulary. The
   card keeps media/title/meta so catalogue browsing stays coherent; only
   commerce is withheld. Secondary text token: calm, not an error state. */
.pp-card-unavailable-note { font: 400 var(--pp-text-meta)/1.4 var(--pp-font-body); color: var(--pp-secondary-text); }
.pp-card--unavailable .pp-card-media { opacity: 0.88; }

/* =====================================================================
 * PC.L1 — product-card stability (Human Design Lock 2026-10-16,
 * design-locks/PC-L1-PRODUCT-CARD-STABILITY-LOCK.md). Choosing a quantity
 * changes the information on a card, never its layout: the card, its tier
 * selector, its price summary and its CTA keep one geometry for every tier,
 * so neither the card nor its rail / grid neighbours move. Presentation only:
 * every amount and label is server-rendered, pp-tiers.js is unchanged.
 * ===================================================================== */

/* Price summary — Concept B (template-parts/product/price-summary.php): the
   per-can price + the struck original per can, then TOTAL + the saving. Each
   value is a slot holding the live element and aria-hidden twins of every
   tier's string in ONE grid cell, so every slot keeps its largest tier's
   width and height. */
.pp-card-price--summary { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 2px; }
.pp-price-line { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; min-width: 0; }
.pp-price-line--total { column-gap: 6px; }
.pp-price-slot { display: inline-grid; min-width: 0; }
.pp-price-slot > * { grid-area: 1 / 1; }
.pp-twin { display: grid; visibility: hidden; pointer-events: none; user-select: none; } /* grid: a twin adds no line box of its own */
.pp-card-price--summary .pp-price-save::before { content: "·"; content: "·" / ""; margin-inline-end: 6px; color: var(--pp-border-hover); font-weight: 400; }
.pp-card-price--summary :is(.pp-price-primary, .pp-price-ref, .pp-price-save, .pp-price-total b) { font-variant-numeric: tabular-nums; }
/* The visually hidden "Original price" is announced only while the struck price is shown. */
.pp-price-ref-k:has(+ [data-pp-ref][hidden]) { display: none; }

/* Tier cells: one two-line structure in every state. Lock §27 stands — the
   selected cell still shows no saving: its "−X%" (and the PLP qty-1 "can") is
   made invisible instead of removed, so the label never re-centres and the
   cell never changes height. A cell with no second line (the qty-1 cell of
   the 2×2 grid) reserves one — a non-breaking space, never a discount — so
   every label in a row shares one top line. Cards only: the PDP grid keeps
   its own rule. */
.pp-card .pp-tiers .pp-tier.is-selected .pp-tier-pct { display: block; visibility: hidden; }
.pp-card .pp-tiers .pp-tier:not(:has(.pp-tier-pct))::before { content: "\00a0"; display: block; order: 2; visibility: hidden; font: 600 var(--pp-text-meta-min)/1.2 var(--pp-font-body); }

/* The commerce block (tiers → price → CTA) is bottom-anchored as one: in a
   stretched rail or grid row the slack falls under the product facts, so
   tier rows, prices and CTAs line up across neighbours whatever the name
   length. With no slack this is Production's geometry (the title's own 2px
   bottom margin is kept as padding). */
.pp-card > :has(+ .pp-tiers) { margin-bottom: auto; }
.pp-card > .pp-card-title:has(+ .pp-tiers) { padding-bottom: 2px; }
.pp-card:has(> .pp-tiers) > .pp-card-cta { margin-top: 0; }

/* CTA label stack: the button keeps its longest tier label's size. The short
   label stack (one label per tier, in tier order) and the short confirmation
   only show on narrow cards; the selected tier's short label is matched by
   position against the tier row, so no script writes it. */
.pp-cta-label { display: inline-grid; justify-items: center; min-width: 0; }
.pp-cta-label > * { grid-area: 1 / 1; }
/* Loading keeps the design system's own state (spinner beside the live label):
   the stack drops its twins, so the spinner sits next to the live label. */
.pp-btn.is-loading .pp-cta-label .pp-twin { display: none; }
/* Standard cards: the spinner takes no inline space of its own (its start
   margin cancels its size and the gap), so the label keeps its normal
   position and line count. The spinner sits in the free space beside it; at
   Shop / search 1440 the spinner had wrapped "Add 30 / 60 cans to cart" by
   under 1px. The label's cap keeps that free space at least spinner + gap
   wide, so the spinner stays inside the button for any label; only a label
   within 8px of the content width (a longer translation) can still gain a
   line while loading, never more than before. 16px = .pp-btn-spinner, 20px
   = .pp-btn padding-inline (design-system.css). Narrow cards keep their
   centred spinner (below). */
@container pp-card (min-width: 190px) {
	.pp-card .pp-btn.is-loading .pp-btn-spinner { margin-inline-start: calc(-16px - var(--pp-control-gap)); }
	.pp-card .pp-btn.is-loading .pp-cta-label { max-width: calc(100% + 2 * 20px - 2 * (16px + var(--pp-control-gap))); }
}
.pp-cta-short, .pp-cta-done { display: none; }
.pp-cta-short > * { grid-area: 1 / 1; visibility: hidden; }
.pp-card:has(.pp-tiers > .pp-tier:nth-child(1).is-selected) .pp-cta-short > :nth-child(1),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(2).is-selected) .pp-cta-short > :nth-child(2),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(3).is-selected) .pp-cta-short > :nth-child(3),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(4).is-selected) .pp-cta-short > :nth-child(4),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(5).is-selected) .pp-cta-short > :nth-child(5),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(6).is-selected) .pp-cta-short > :nth-child(6),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(7).is-selected) .pp-cta-short > :nth-child(7),
.pp-card:has(.pp-tiers > .pp-tier:nth-child(8).is-selected) .pp-cta-short > :nth-child(8) { visibility: visible; }

/* Narrow cards — the Human-approved exception. A card whose content box is
   narrower than 190px (measured: only the Brand Page 2-column phone grid,
   125–184px; the Shop grid never goes below 196px, the Home rail below 216px)
   keeps Production's pricing: the one-column summary in Production's order,
   its optional rows added on discount tiers (the 1-can card stays short and
   grows for 5+ cans), Production's figures and tier cells. Its CTA is one
   line: 12px inline padding and the short label below. */
.pp-card[data-pp-tier-scope] { container: pp-card / inline-size; }
@container pp-card (max-width: 189.98px) {
	.pp-card-price--summary { display: flex; flex-direction: column; gap: 2px; }
	.pp-card-price--summary :is(.pp-price-line, .pp-price-slot) { display: contents; }
	.pp-card-price--summary .pp-twin { display: none; }
	.pp-card-price--summary [data-pp-percan] { order: 1; }
	.pp-card-price--summary [data-pp-ref] { order: 2; }
	.pp-card-price--summary [data-pp-save] { order: 3; }
	.pp-card-price--summary .pp-price-total { order: 4; }
	.pp-card-price--summary .pp-price-save::before { content: none; }
	.pp-card-price--summary :is(.pp-price-primary, .pp-price-ref, .pp-price-save, .pp-price-total b) { font-variant-numeric: normal; }
	.pp-card .pp-tiers .pp-tier.is-selected .pp-tier-pct { display: none; }
	.pp-card .pp-tiers .pp-tier:not(:has(.pp-tier-pct))::before { content: none; display: none; }
	.pp-card .pp-card-cta .pp-btn { padding-inline: 12px; }
	.pp-cta-label .pp-twin { display: none; }
}
/* The short label replaces the visible label only where :has() can pick the
   selected tier's — one of the eight positions matched above; elsewhere (no
   :has(), a ninth tier or later, no tier selected) the full label simply
   stays. The full label stays in the button, visually hidden, as its
   accessible name ("Add 5 cans to cart"; "Added to cart ✓" after an add);
   the short labels are aria-hidden. Loading: the spinner sits centred in the
   label's place (the label keeps its space), so the button never wraps.
   Success: "Added ✓". */
@supports selector(:has(*)) {
	@container pp-card (max-width: 189.98px) {
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-cta-label { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-cta-short { display: inline-grid; justify-items: center; min-width: 0; }
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-btn.is-loading .pp-cta-short { opacity: 0; }
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-btn.is-loading .pp-btn-spinner { position: absolute; inset: 0; margin: auto; }
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-btn.is-confirmed .pp-cta-short { display: none; }
		.pp-card:has(.pp-tiers > .pp-tier:nth-child(-n+8).is-selected) .pp-btn.is-confirmed .pp-cta-done { display: inline; }
	}
}

/* =====================================================================
 * SHOP.SEO V4.2 — the PLP card (Human selection 2026-10-23; PLP lock and
 * PC-L1 §26 amendments). Scoped to .pp-card--plp: the Homepage rails and the
 * Brand Pages render their own cards and are unchanged.
 *   · the classification line's mg value is set apart (semibold, unbroken);
 *   · each tier cell also carries a row (cans · per can · total — aria-hidden)
 *     that only the quantity sheet shows;
 *   · on a narrow card (content box under 190px — the two-column phone grid)
 *     a 48px quantity control states the selected tier and opens the card's
 *     own tier group as a bottom sheet (a native popover, so it needs no
 *     script to open or close — assets/js/qty-sheet.js adds the focus
 *     handling); the tier buttons stay in the card, so pp-tiers.js and the
 *     positional PC.L1 rules work unchanged. Without :popover-open support
 *     the narrow card keeps today's five-cell row;
 *   · D-V4-3: with the sheet, the narrow price block keeps per can + total on
 *     two stable lines (the sheet lists every tier's price).
 * ===================================================================== */
.pp-card--plp .pp-card-meta { margin-top: 2px; }
.pp-card--plp .pp-card-meta-mg { font-weight: 600; color: var(--pp-ink); white-space: nowrap; }
.pp-card--plp .pp-tier-row { display: none; }

/* Standard cards: the inline tier row, as before — the popover attribute's
   own UA presentation is neutralised; the control and the sheet head hide. */
.pp-card--plp .pp-qty-trigger { display: none; }
.pp-card--plp .pp-tiers[popover] { display: flex; position: static; inset: auto; width: auto; height: auto; margin: 4px 0 0; padding: 0; overflow: visible; color: inherit; background: transparent; }
.pp-card--plp .pp-tiers .pp-qty-head, .pp-card--plp .pp-tiers .pp-qty-close { display: none; }
/* PC.L1 bottom anchoring, re-pointed at the control that now precedes the tiers. */
.pp-card--plp > :has(+ .pp-qty-trigger) { margin-bottom: auto; }
.pp-card--plp > .pp-card-title:has(+ .pp-qty-trigger) { padding-bottom: 2px; }
.pp-card--plp > .pp-qty-trigger:has(+ .pp-tiers) { margin-bottom: 0; }

@container pp-card (max-width: 189.98px) {
	/* Card 2 (V3): one stable cell height; the summary keeps PC.L1's two-line slots. */
	.pp-card--plp .pp-tiers .pp-tier.is-selected .pp-tier-pct { display: block; visibility: hidden; }
	.pp-card--plp .pp-card-price--summary { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 1px; }
	.pp-card--plp .pp-card-price--summary .pp-price-line { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 6px; }
	.pp-card--plp .pp-card-price--summary .pp-price-slot { display: inline-grid; }
	.pp-card--plp .pp-card-price--summary .pp-twin { display: grid; }
	.pp-card--plp .pp-card-price--summary .pp-price-primary { font-size: 1.125rem; }
	.pp-card--plp .pp-card-price--summary .pp-price-save::before { content: none; }
}

@supports selector(:popover-open) {
	@container pp-card (max-width: 189.98px) {
		.pp-card--plp .pp-qty-trigger { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: 4px; align-items: center; width: 100%; min-height: 48px; margin: 6px 0 0; padding: 6px 8px 6px 10px; border: 1px solid var(--pp-border); border-radius: var(--pp-radius-control); background: #fff; color: var(--pp-ink); text-align: start; cursor: pointer; font: inherit; -webkit-tap-highlight-color: transparent; transition: border-color var(--pp-motion-micro) var(--pp-ease-out), background-color var(--pp-motion-micro) var(--pp-ease-out); }
		.pp-card--plp .pp-qty-trigger:active { background: var(--pp-navy-tint); }
		.pp-card--plp .pp-qty-trigger:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
		.pp-card--plp :is(.pp-qty-trigger-k, .pp-qty-trigger-sr) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
		/* one state per tier; only the selected tier's state takes part (row 1: quantity + caret, row 2: its hint or discount) */
		.pp-card--plp .pp-qty-trigger-v { display: contents; }
		.pp-card--plp .pp-qty-trigger-s { display: none; }
		.pp-card--plp .pp-qty-trigger-s b { grid-column: 1; grid-row: 1; font: 600 14px/1.25 var(--pp-font-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
		.pp-card--plp .pp-qty-trigger-s i { grid-column: 1 / -1; grid-row: 2; font: normal 600 11.5px/1.3 var(--pp-font-body); color: var(--pp-navy); }
		.pp-card--plp .pp-qty-trigger .pp-plp-caret { grid-column: 2; grid-row: 1; width: 16px; height: 16px; color: var(--pp-secondary-text); }
		.pp-card--plp .pp-tiers[popover]:not(:popover-open) { display: none; }
		/* D-V4-3: per can + total, two stable lines (the struck price and the saving are in the sheet's rows) */
		.pp-card--plp .pp-card-price--summary .pp-price-line > .pp-price-slot + .pp-price-slot { display: none; }

		/* the sheet — the top layer, still inside the card's DOM (pp-tiers.js scope) */
		.pp-card--plp .pp-tiers[popover]:popover-open { position: fixed; inset: auto 0 0 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; width: 100%; max-width: none; max-height: 86vh; margin: 0; padding: 26px 16px calc(18px + env(safe-area-inset-bottom)); overflow: auto; overscroll-behavior: contain; border: 0; border-radius: 18px 18px 0 0; background: #fff; color: var(--pp-ink); box-shadow: 0 -12px 40px rgba(17, 17, 17, 0.2); transition: transform var(--pp-motion-popover) var(--pp-ease-enter), opacity var(--pp-motion-popover) var(--pp-ease-enter); }
		.pp-card--plp .pp-tiers[popover]:popover-open::backdrop { background: rgba(17, 17, 17, 0.45); opacity: calc(1 - var(--pp-qty-drag, 0)); transition: opacity var(--pp-motion-popover) var(--pp-ease-out); }
		.pp-card--plp .pp-tiers[popover]:popover-open::before { content: ""; position: absolute; top: 8px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: #D3D7DA; }
		@starting-style {
			.pp-card--plp .pp-tiers[popover]:popover-open { transform: translateY(28px); opacity: 0; }
			.pp-card--plp .pp-tiers[popover]:popover-open::backdrop { opacity: 0; }
		}
		/* the heading and close button follow the tier buttons in the DOM (PC.L1's positional rules) and come first visually */
		.pp-card--plp .pp-tiers:popover-open .pp-qty-head { order: -2; display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; gap: 14px; margin: 0 52px 8px 0; }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-thumb { display: block; width: 56px; height: 56px; object-fit: contain; border-radius: 12px; background: var(--pp-soft-surface); }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-id { display: grid; gap: 1px; }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-id b { font: 600 18px/1.2 var(--pp-font-display); letter-spacing: -0.01em; color: var(--pp-ink); }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-id > span { font: 500 14px/1.35 var(--pp-font-body); color: var(--pp-ink); }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-id .pp-qty-meta { font: 400 13px/1.35 var(--pp-font-body); color: #5A6572; }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-close { position: absolute; top: 10px; inset-inline-end: 10px; display: inline-grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 50%; background: none; color: var(--pp-ink); cursor: pointer; }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-close .pp-i { width: 20px; height: 20px; }
		.pp-card--plp .pp-tiers:popover-open .pp-qty-close:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
		/* rows: a radio mark states the choice; per can (primary) above the tier's total */
		.pp-card--plp .pp-tiers:popover-open .pp-tier { position: relative; display: grid; grid-template-columns: 22px auto minmax(0, 1fr); grid-template-rows: auto auto; align-items: center; column-gap: 12px; row-gap: 2px; min-height: 60px; padding: 8px 16px; border: 1px solid var(--pp-border); border-radius: 10px; text-align: start; transition: background-color var(--pp-motion-micro) var(--pp-ease-out), border-color var(--pp-motion-micro) var(--pp-ease-out), transform var(--pp-motion-press-out) var(--pp-ease-out); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-qty { display: none; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-row { display: contents; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier::before { content: ""; grid-row: 1 / span 2; grid-column: 1; align-self: center; display: block; width: 20px; height: 20px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px #A9AFB4; background: #fff; visibility: visible; transition: box-shadow var(--pp-motion-micro) var(--pp-ease-out); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier.is-selected::before { box-shadow: inset 0 0 0 1.5px var(--pp-navy); }
		/* the radio's dot is its own layer and grows into place (transform only; the Edge's arrival does not run here) */
		.pp-card--plp .pp-tiers:popover-open .pp-tier::after { content: ""; position: absolute; inset: auto; top: calc(50% - 5px); left: 21px; width: 10px; height: 10px; margin: 0; border: 0; border-radius: 50%; background: var(--pp-navy); opacity: 1; transform: scale(0); animation: none; transition: transform var(--pp-motion-feedback) var(--pp-ease-out); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier.is-selected::after { inset: auto; top: calc(50% - 5px); left: 21px; width: 10px; transform: scale(1); animation: none; }
		[dir="rtl"] .pp-card--plp .pp-tiers:popover-open .pp-tier::after { left: auto; right: 21px; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-cans { grid-column: 2; grid-row: 1 / span 2; font: 600 16px/1.2 var(--pp-font-body); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-pct { grid-column: 3; grid-row: 1 / span 2; justify-self: start; display: inline-block; visibility: visible; padding: 3px 6px; border-radius: 5px; background: var(--pp-navy-tint); font-size: 11.5px; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-pct.pp-tier-unit { visibility: hidden; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-per { grid-column: 3; grid-row: 1; justify-self: end; align-self: end; font: 700 15px/1 var(--pp-font-body); font-variant-numeric: tabular-nums; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-per span { font-weight: 500; font-size: 12.5px; color: var(--pp-secondary-text); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier .pp-tier-tot { grid-column: 3; grid-row: 2; justify-self: end; align-self: start; display: block; font: 500 12.5px/1.2 var(--pp-font-body); color: #5A6572; font-variant-numeric: tabular-nums; }
		.pp-card--plp .pp-tiers:popover-open .pp-tier.is-selected { border-color: var(--pp-navy); background: var(--pp-navy-tint); box-shadow: inset 0 0 0 1px var(--pp-navy); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier:is(:active, .is-pressed) { background: var(--pp-navy-tint); transform: scale(var(--pp-press-scale)); transition-duration: var(--pp-motion-press-in); }
		.pp-card--plp .pp-tiers:popover-open .pp-tier:focus-visible { outline: 2px solid var(--pp-ink); outline-offset: 2px; }
		/* MOB-02: a drag moves the sheet with the finger (qty-sheet.js writes the offset and --pp-qty-drag, 0–1, which the
		   backdrop follows) — nothing eases behind it; the row under the finger drops its pressed state (a drag is not a press) */
		.pp-card--plp .pp-tiers[popover]:popover-open.is-dragging, .pp-card--plp .pp-tiers[popover]:popover-open.is-dragging::backdrop { transition: none; }
		.pp-card--plp .pp-tiers.is-dragging .pp-tier:is(:active, .is-pressed) { transform: none; }
		.pp-card--plp .pp-tiers.is-dragging .pp-tier:not(.is-selected):is(:active, .is-pressed) { background: #fff; border-color: var(--pp-border); }
	}
	@container pp-card (max-width: 189.98px) {
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(1).is-selected) .pp-qty-trigger-s:nth-child(1),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(2).is-selected) .pp-qty-trigger-s:nth-child(2),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(3).is-selected) .pp-qty-trigger-s:nth-child(3),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(4).is-selected) .pp-qty-trigger-s:nth-child(4),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(5).is-selected) .pp-qty-trigger-s:nth-child(5),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(6).is-selected) .pp-qty-trigger-s:nth-child(6),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(7).is-selected) .pp-qty-trigger-s:nth-child(7),
		.pp-card--plp:has(.pp-tiers > .pp-tier:nth-child(8).is-selected) .pp-qty-trigger-s:nth-child(8) { display: contents; }
	}
}
@media (hover: hover) {
	@supports selector(:popover-open) {
		@container pp-card (max-width: 189.98px) {
			.pp-card--plp .pp-qty-trigger:hover { border-color: var(--pp-border-hover); }
		}
	}
}
/* UI.1: a touch never leaves a hover shade on a sheet row (the shared tier rule's :hover is not input-gated) */
@media (hover: none) {
	@supports selector(:popover-open) {
		@container pp-card (max-width: 189.98px) {
			.pp-card--plp .pp-tiers:popover-open .pp-tier:not(.is-selected):hover { background: #fff; border-color: var(--pp-border); }
		}
	}
}
@media (prefers-reduced-motion: reduce) {
	@supports selector(:popover-open) {
		@container pp-card (max-width: 189.98px) {
			@starting-style { .pp-card--plp .pp-tiers[popover]:popover-open { transform: none; } }
			.pp-card--plp .pp-tiers:popover-open .pp-tier::after { transition: none; }
			.pp-card--plp .pp-tiers:popover-open .pp-tier:is(:active, .is-pressed) { transform: none; }
		}
	}
}
