/* ==========================================================================
   PolarLabs — woocommerce.css
   De-generic-ifies WooCommerce: single product, cart, checkout, account,
   mini-cart drawer, sticky mobile add-to-cart. Layout/branding only.
   ========================================================================== */

/* ==========================================================================
   0. CORE LAYOUT NEUTRALISATION  —  read before touching any grid below
   --------------------------------------------------------------------------
   WooCommerce core ships woocommerce-layout.css, which lays out product loops
   and account columns with FLOATS AND PERCENTAGE WIDTHS:

       .woocommerce ul.products li.product { float:left; width:30.75%; margin-right:3.8%; }
       .woocommerce ul.products.columns-4 li.product { width:22.05%; }
       .woocommerce .col2-set .col-1 { float:left; width:48%; }

   PolarLabs lays those same elements out with CSS Grid. A percentage width on
   a GRID ITEM resolves against its GRID AREA, not the container — so core's
   `width:30.75%` applied to a `repeat(3,1fr)` track produced a card ~10% of
   the container wide (30.75% OF one-third), and `.columns-4` produced ~5.5%.
   That single interaction is the shared cause of the narrow product strips,
   letter-by-letter wrapping, split prices, overflowing badges, cards shoved
   right, dead whitespace, the broken 1–5 product states, AND the collapsed
   desktop account form (48% of a half-track ≈ 24%).

   These are not separate bugs and must not be patched separately. Core's
   layout rules are neutralised ONCE, here, wherever PolarLabs owns layout.
   Core's *visual* styles (woocommerce-general.css) are intentionally kept.

   If a PolarLabs grid ever mysteriously narrows again, look here first.
   ========================================================================== */

/* Product loops: PolarLabs grid owns sizing; core float/width must not apply.
 *
 * SPECIFICITY IS LOAD-BEARING HERE — do not "simplify" this selector list.
 * woocommerce-smallscreen.css (<=768px) ships:
 *     .woocommerce ul.products[class*="columns-"] li.product { width:48%; float:left; clear:both; }
 * That is FOUR class-level tokens (.woocommerce, .products, [class*=], .product)
 * plus two elements = (0,4,2). A reset written as
 *     .woocommerce ul.products li.product
 * is only (0,3,2) and LOSES, no matter that the theme stylesheet loads later —
 * source order only breaks ties, and this is not a tie. The [class*="columns-"]
 * variants below exist purely to match core's specificity and win on order.
 *
 * Measured on the live 390px Shop before/after: card width 83.03px -> 173px
 * (83.03 == 48% of the 173px grid track — core's % resolved against the TRACK,
 * not the container). No !important needed once the specificity matches.
 */
.woocommerce ul.products[class*="columns-"] li.product,
.woocommerce-page ul.products[class*="columns-"] li.product,
.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product,
ul.products.pl-productgrid li.product,
.pl-productgrid > li {
	float: none;
	width: auto;
	margin-right: 0;
	margin-left: 0;
	clear: none;
	min-width: 0; /* grid/flex items default to min-width:auto (=min-content) and refuse to shrink */
}

/* Core's ::before/::after clearfix on the loop fights grid auto-placement. */
.woocommerce ul.products::before,
.woocommerce ul.products::after,
.pl-productgrid::before,
.pl-productgrid::after {
	content: none;
}

/* Account two-column sets (login/register, addresses, customer details). */
.woocommerce .col2-set .col-1,
.woocommerce .col2-set .col-2,
.woocommerce-page .col2-set .col-1,
.woocommerce-page .col2-set .col-2 {
	float: none;
	width: auto;
	min-width: 0;
}

/* Long unbroken strings (SKUs, URLs, compound names) must not blow out a track.
   Only the core loop title is targeted here — the PolarLabs card's own title and
   price are handled in main.css alongside the rest of the card. (The former
   .pl-productcard__title / .pl-productcard__price selectors here were dead: the
   renderer emits .pl-card__title / .pl-card__price and never matched them.) */
.pl-productgrid .woocommerce-loop-product__title {
	overflow-wrap: break-word;
	min-width: 0;
}

.pl-woo { padding-block: clamp(28px, 5vw, 56px); }

/* Hide default Woo demo/store notice styling override */
.woocommerce-store-notice { background: var(--pl-navy-900); color: var(--pl-icy); }

/* ---- Compact catalog heading + Shop toolbar / count / ordering ---- */
/* Compact white catalog heading (replaces the retired hero shophead panel): one
   H1, a short supporting line, moderate spacing, no eyebrow/badges/gradient. */
.pl-catalog-head { padding-bottom: clamp(12px, 2vw, 18px); }
.pl-catalog-head__title { font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.1rem); line-height: 1.15; margin: 0 0 6px; color: var(--pl-navy); }
.pl-catalog-head__desc { color: var(--pl-muted); max-width: 60ch; margin: 0; }

/* .pl-shop is the archive positioning context. The decorative atmosphere no longer
   sits here — S1.1's large .pl-shop::before field is retired (it read as a big top
   wash). It moved onto the compact command band (.pl-catalog-command::before, in the
   Catalog Command Surface block below), so the icy field is one controlled control-
   surface instead. A small top pad gives the band a controlled gap under the header
   (this custom archive template renders .pl-shop directly, without the .pl-woo pad). */
/* RC.6.8 — qualify to the content wrapper (which always carries BOTH .pl-container
   and .pl-shop). Previously the bare `.pl-shop` also matched <body class="pl-shop">
   (added by polarlabs_body_classes on shop/category/taxonomy), leaking a phantom
   top gap above the sticky header + bottom gap under the footer on Shop pages only.
   <body> never has .pl-container, so this scopes the padding/stacking to the wrapper. */
.pl-container.pl-shop { position: relative; z-index: 0; padding-block: clamp(12px, 2vw, 20px) clamp(28px, 4vw, 48px); }
/* Category filters: single horizontally-scrollable swipe row (never wraps).
   Categories are rendered dynamically from WooCommerce; JS adds the scroll
   affordance + centres the active pill. */
.pl-shop__filters { position: relative; margin-bottom: 24px; }
.pl-chiprow {
	list-style: none; display: flex; flex-wrap: nowrap; gap: 8px; margin: 0;
	overflow-x: auto; overflow-y: hidden; white-space: nowrap;
	-webkit-overflow-scrolling: touch; scroll-behavior: smooth;
	scrollbar-width: none; -ms-overflow-style: none;
	/* Safe leading + trailing inline padding so the first chip is fully visible at
	   the start position and the last chip can scroll clear of the right-edge fade;
	   vertical padding keeps the focus ring from being clipped by overflow-y. */
	padding: 4px 24px 4px 4px;
	scroll-padding-inline: 4px 24px;
}
.pl-chiprow::-webkit-scrollbar { display: none; }
.pl-chiprow > li { flex: 0 0 auto; }
.pl-chip { display: inline-flex; align-items: center; flex: 0 0 auto; white-space: nowrap; min-height: 44px; padding: 9px 18px; border-radius: var(--pl-radius-pill); background: var(--pl-surface); border: 1px solid var(--pl-line); color: var(--pl-navy); font-weight: 600; font-size: .9rem; transition: border-color var(--pl-dur) var(--pl-ease), color var(--pl-dur) var(--pl-ease), background var(--pl-dur) var(--pl-ease), transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease); }
.pl-chip:hover { border-color: var(--pl-blue); color: var(--pl-blue); background: var(--pl-blue-050); transform: translateY(-1px); box-shadow: 0 3px 10px rgba(40,120,245,.12); }
/* Active chip — controlled Polar-blue emphasis (S1). --pl-blue-600 keeps white text
   at 5.5:1 (AA); --pl-blue would be 4.1:1 and fail. Solid fill stays clearly distinct
   from the pale-blue inactive hover. */
.pl-chip.is-active { background: var(--pl-blue-600); border-color: var(--pl-blue-600); color: #fff; }
.pl-chip.is-active:hover { background: var(--pl-blue-600); border-color: var(--pl-blue-600); color: #fff; }
/* Right-edge fade affordance — shown only while more categories exist to the right. */
.pl-shop__filters::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 44px; background: linear-gradient(90deg, rgba(255,255,255,0), var(--pl-surface) 80%); pointer-events: none; opacity: 0; transition: opacity var(--pl-dur) var(--pl-ease); }
.pl-shop__filters.pl-chiprow--overflow::after { opacity: 1; }
.pl-shop__filters.pl-chiprow--end::after { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .pl-chiprow { scroll-behavior: auto; } }

.pl-shop__toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid var(--pl-line); }
.pl-shop__count { color: var(--pl-muted); font-size: .9rem; margin: 0; }
.woocommerce-result-count { margin: 0 !important; color: var(--pl-muted); }
.pl-shop__sort select, .woocommerce-ordering select { min-height: 44px; padding: 10px 40px 10px 14px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); background-color: var(--pl-surface); color: var(--pl-navy); font-size: 1rem; font-weight: 600; cursor: pointer; appearance: none; transition: border-color var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%235B6B80' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; }
.pl-shop__sort select:hover, .woocommerce-ordering select:hover { border-color: var(--pl-blue); }
.pl-shop__sort select:focus, .woocommerce-ordering select:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
.pl-shop__pagination { margin-top: 40px; }
.pl-shop__pagination .woocommerce-pagination ul { display: flex; gap: 6px; justify-content: center; list-style: none; border: 0 !important; }
.pl-shop__pagination .page-numbers { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; height: 44px; border: 1px solid var(--pl-line) !important; border-radius: var(--pl-radius-sm); color: var(--pl-navy); font-weight: 600; transition: border-color var(--pl-dur) var(--pl-ease), color var(--pl-dur) var(--pl-ease), background var(--pl-dur) var(--pl-ease); }
a.pl-shop__pagination .page-numbers:hover, .pl-shop__pagination a.page-numbers:hover { border-color: var(--pl-blue) !important; color: var(--pl-blue); background: var(--pl-blue-050); }
.pl-shop__pagination .page-numbers.current { background: var(--pl-blue-600); color: #fff; border-color: var(--pl-blue-600) !important; }

/* Loop add-to-cart button uses .pl-btn via filter */
.pl-productgrid .button.loading::after { content: ""; }

/* ==========================================================================
   Shop archive — product search, controls, and product card (.pl-scard)
   Every rule here is namespaced to .pl-scard / .pl-shopgrid / .pl-shop__* and is
   emitted only in the Shop-archive context, so none of it can reach .pl-card
   (related products / up-sells), .pl-fcard (frozen homepage rail) or the shared
   .pl-productgrid base grid. The shared grid supplies the 2/3/4 columns.
   ========================================================================== */

/* Product search — permanently visible; full-width and first control on mobile. */
.pl-shop__search { position: relative; display: flex; align-items: stretch; gap: 8px; width: 100%; margin-bottom: 20px; }
.pl-shop__search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); display: inline-flex; color: var(--pl-muted); pointer-events: none; z-index: var(--pl-z-base); }
.pl-shop__search-input { flex: 1 1 auto; min-width: 0; min-height: 50px; padding: 12px 16px 12px 42px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); background: var(--pl-surface); color: var(--pl-navy); font-size: 1rem; }
.pl-shop__search-input::placeholder { color: var(--pl-muted-soft); }
.pl-shop__search-input:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
.pl-shop__search-btn { flex: 0 0 auto; min-height: 50px; }
@media (min-width: 720px) { .pl-shop__search { max-width: 560px; } }

/* Toolbar end — clear-filters + sort, right-aligned opposite the count. */
.pl-shop__toolbar-end { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.pl-shop__clear { display: inline-flex; align-items: center; min-height: 44px; color: var(--pl-link); font-weight: 600; font-size: .9rem; white-space: nowrap; }
.pl-shop__clear:hover { text-decoration: underline; }

/* Shop grid modifier — the shared .pl-productgrid supplies the 2/3/4 columns;
   this scope only exists so any Shop-only grid tuning cannot touch related/up-sells. */
.pl-shopgrid { align-items: stretch; }

/* Shop product card — image, name, price, View product only. The authoritative
   PolarLabs product card (Shop archive, homepage Featured, PDP Related rail).
   Image-first (Lumex/EON): a seamless edge-to-edge 1:1 media area (object-fit:cover;
   the outer .pl-scard alone owns the border, radius and overflow clip) joined
   directly to the white information panel — no inner tile, padding or hairline
   (RC.6.2). Current product images are square, so cover crops nothing. Distinct
   .pl-scard namespace; the .pl-card variant is dormant (fallback), and .pl-fcard was removed in RC.6.3. */
.pl-scard { display: flex; flex-direction: column; height: 100%; min-width: 0; overflow: hidden;
	background: var(--pl-surface); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg);
	transition: transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease), border-color var(--pl-dur) var(--pl-ease); }
.pl-scard:hover { transform: translateY(-2px); box-shadow: var(--pl-shadow-sm); border-color: var(--pl-line-strong); }
/* RC.6.10.1 hotfix — RESTORE the approved edge-to-edge media (reverts the commerce-pass
   contain-on-tile, which framed each studio-background photo inside a second icy tile: a
   double-background regression with a small floating vial). The product photographs are
   already art-directed on their own clean studio backgrounds, so the image fills the media
   edge-to-edge via object-fit:cover (current masters are ~square, so cover crops no vial —
   confirmed against the owner's approved reference). The --pl-card-tile stays as the media
   background but is now covered by the photo; it shows ONLY behind the missing-image
   placeholder. DO NOT reintroduce media padding or object-fit:contain here — on
   studio-background photos that re-creates the framed / shrunken-vial regression. */
.pl-scard__media { position: relative; display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1; padding: 0; margin: 0; overflow: hidden;
	background: var(--pl-card-tile); }
.pl-scard__img { display: block; width: 100%; height: 100%; margin: 0; border: 0; border-radius: 0; object-fit: cover; object-position: center; transition: transform var(--pl-dur) var(--pl-ease); }
.pl-scard:hover .pl-scard__img { transform: scale(1.02); }
/* RC.6.2 — restrict the lift + image zoom to real pointer devices so a touch tap
   never leaves the card in a stuck hover state. */
@media (hover: none) {
	.pl-scard:hover { transform: none; box-shadow: none; }
	.pl-scard:hover .pl-scard__img { transform: none; }
}
.pl-scard__placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; width: 100%; height: 100%; padding: 16px; text-align: center; color: var(--pl-icy-200); }
.pl-scard__placeholder-label { font-size: .82rem; font-weight: 600; color: var(--pl-muted); }
/* M3.1 tile chips — real spec/availability only (assigned strength · Woo stock),
   never trust theater. Neutral pills on the tile, deliberately distinct from the
   prohibited purity/COA/"verified" badges.
   The chips share ONE absolutely-positioned flow band (.pl-scard__chips) pinned
   across the top of the tile. flex-wrap drops the stock chip cleanly BELOW the
   strength chip when the card is too narrow to hold both on one row (resilient down
   to ~130px cards — the 320px 2-up grid): no overlap, no clipping, and no guessed
   width threshold, because wrapping is driven by the real chip text at the real card
   width. Shared: applies anywhere polarlabs_render_product_card(..., 'shop') renders. */
.pl-scard__chips { position: absolute; top: 10px; left: 10px; right: 10px; z-index: 1;
	display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 4px 6px; }
.pl-scard__chip { display: inline-flex; align-items: center; max-width: 100%;
	padding: 3px 9px; border-radius: var(--pl-radius-pill);
	font-size: .72rem; font-weight: 700; line-height: 1.5; letter-spacing: .01em;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
	background: rgba(255, 255, 255, .92); border: 1px solid var(--pl-line); box-shadow: var(--pl-shadow-xs); }
/* RC.6.2 — stock is now the only card chip; it sits top-left inside the media safe
   area (the strength-count chip and its space-between/wrap logic were removed). */
.pl-scard__chip--stock { color: var(--pl-muted); font-weight: 600; }
/* RC.6.2 — the category descriptor line was removed from the card (it belongs on the PDP). */
/* M3.1 sale price — keep each amount atomic so a real sale wraps cleanly (old price
   above, current price below) at 320 instead of splitting mid-number; the existing
   size + weight already keep the struck old price subordinate to the current price. */
.pl-scard__price del, .pl-scard__price ins { white-space: nowrap; }
/* M3.1 compact body — tighter gaps + padding (Amino density) without crowding. */
.pl-scard__body { display: flex; flex-direction: column; gap: 5px; padding: 10px 12px 12px; flex: 1 1 auto; }
/* M3.1 compact title — ONE line with ellipsis (truncation on the LINK, below); no
   reserved 2-line height, so name length can't add blank rows or misalign cards. */
.pl-scard__title { margin: 0; font-size: 1.15rem; line-height: 1.3; font-weight: 700; color: var(--pl-navy); }
.pl-scard__title a { color: inherit; }
.pl-scard__title a:hover { color: var(--pl-link); }
/* Commerce-consolidation — product identity leads: the NAME is the largest, boldest
   element (via the catalog weight-800 rule below); the price is confident supporting
   detail, not the headline (was 1.15rem/800, which read commodity-store). */
.pl-scard__price { font-size: 1rem; font-weight: 700; color: var(--pl-navy); line-height: 1.2; }
.pl-scard__price del { color: var(--pl-muted-soft); font-weight: 600; font-size: .8em; margin-right: 6px; }
.pl-scard__price ins { text-decoration: none; color: var(--pl-navy); }
.pl-scard__price-pending { color: var(--pl-muted); font-weight: 600; font-size: .92rem; }
/* CTA: full-width, >=44px, deep PolarLabs navy with royal-blue hover/focus,
   pinned to the card bottom for consistent alignment. Drives the .pl-btn base
   via --btn-bg (markup carries .pl-btn, not .pl-btn--primary, so no blue glow). */
.pl-scard__cta { margin-top: auto; width: 100%; min-height: 44px; --btn-bg: var(--pl-navy); box-shadow: none; white-space: nowrap; }
.pl-scard__cta:hover { --btn-bg: var(--pl-blue); }
.pl-scard__cta:focus-visible { --btn-bg: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }

/* Mobile (<=640): two cards per row. Slightly reduced Shop-only outer padding so
   cards use more of the width and images stay substantial (the global DR-006
   gutter is unchanged everywhere else — this override is scoped to the Shop
   container via the .pl-container.pl-shop double-class). */
@media (max-width: 640px) {
	.pl-container.pl-shop { padding-inline: 16px; }
	.pl-shopgrid.pl-productgrid { gap: 10px; }
	/* Media stays edge-to-edge at <=640px too (base padding:0) — no icy frame on phone cards. */
	.pl-scard__body { padding: 9px 10px 10px; gap: 4px; }
	.pl-scard__title { font-size: 1.05rem; }
	.pl-scard__price { font-size: .92rem; }
	/* Trim the CTA's horizontal padding on the narrow (~138px @320) track so
	   "View product" stays on one line instead of wrapping. */
	.pl-scard__cta { padding-inline: 8px; font-size: .92rem; }
	.pl-scard__chips { top: 8px; left: 8px; right: 8px; }
	.pl-scard__chip { padding: 2px 7px; font-size: .66rem; }
}

/* Tablet (641–1024): three cards per row for the SHOP grid specifically, so the
   Shop matches the approved 2 / 3 / 4 column intent (owner Shop Phase 2 § H). The
   shared .pl-productgrid keeps its own breakpoints for related/up-sell loops; the
   double-class selector (.pl-shopgrid.pl-productgrid) out-specifies the base rule
   without editing it or touching main.css, so nothing else changes. */
@media (min-width: 641px) and (max-width: 1024px) {
	.pl-shopgrid.pl-productgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ==========================================================================
   Shop vNext — Quality Elevation (frame-only; DR-027). Namespaced to
   .pl-catalog-head / .pl-shop* / .pl-chip / .pl-scard / .pl-empty--shop; preserves
   the frozen section order + the four-element .pl-scard contract (image · name ·
   price · "View product"). No base .pl-productgrid / .pl-card / .pl-fcard / PDP /
   main.css change; the shared polarlabs-shop-card image size is untouched.
   ========================================================================== */

/* Catalog head onto the unified weight-800 head system + accessible-blue
   electric-rule eyebrow (--pl-link ~5:1 on white — NOT the sub-AA .pl-eyebrow). */
.pl-catalog-head__eyebrow { display: inline-flex; align-items: center; gap: 11px; margin: 0 0 12px;
	color: var(--pl-link); font-size: .72rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; }
.pl-catalog-head__eyebrow::before { content: ""; width: 24px; height: 1.5px; background: var(--pl-blue); }
.pl-catalog-head__title { font-family: var(--pl-font-heading); font-weight: 800; letter-spacing: -.025em; line-height: 1.05;
	font-size: clamp(1.85rem, 1.3rem + 1.6vw, 2.55rem); overflow-wrap: break-word; }
.pl-catalog-head__desc { font-size: 1.02rem; line-height: 1.55; max-width: 56ch; }

/* Fluid clamp control rhythm (was fixed 12/20/24/16px). */
.pl-catalog-head { padding-bottom: clamp(16px, 2.2vw, 26px); }
.pl-shop__search { margin-bottom: clamp(16px, 2vw, 24px); }
.pl-shop__filters { margin-bottom: clamp(18px, 2.4vw, 28px); }
.pl-shop__toolbar { margin-bottom: clamp(18px, 2.4vw, 28px); }

/* Chips: colour + hairline feedback only (drop the lift + blue glow); focus ring
   clears the 5px --pl-ring (block padding was 4px). Active navy + 44px unchanged. */
.pl-chip:hover { transform: none; box-shadow: none; border-color: var(--pl-blue); color: var(--pl-blue); background: var(--pl-blue-050); }
.pl-chiprow { padding-block: 6px; }

/* Card polish: title weight 800; the 2-line clamp moves onto the title LINK so the
   keyboard focus ring is never clipped by an ancestor overflow; sale strike-through
   to an AA-safe muted token. Media = the shared colored product-card tile
   (--pl-card-tile) + a 1px inner hairline (M3.1 — supersedes the earlier Frost
   surface + strict four-element scope; the renderer now carries the full anatomy). */
.pl-scard__title { font-weight: 800; display: block; overflow: visible; -webkit-line-clamp: none; }
/* M3.1 compact: single-line title, ellipsis on overflow (keyboard focus ring is not
   clipped — the link is inline-block-level with its own overflow, not an ancestor). */
.pl-scard__title a { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-scard__media { background: var(--pl-card-tile); }
.pl-scard__price del { color: var(--pl-muted); }

/* Empty (no-results) state keeps the frame voice — weight-800 head, left-aligned to
   the catalog-head axis. The truthful search/query behaviour is unchanged. */
.pl-empty--shop { text-align: left; margin-inline: 0; max-width: 60ch; }
.pl-empty--shop .pl-empty__title { font-family: var(--pl-font-heading); font-weight: 800; letter-spacing: -.02em; overflow-wrap: anywhere; }
.pl-empty--shop .pl-empty__icon { margin-inline: 0; }

/* Shop-only closing-band texture: the approved masked hairline grid, scoped by the
   adjacent-sibling combinator so it renders ONLY where .pl-shop precedes the shared
   newsletter (never on home / affiliate / COA). Newsletter markup + behaviour are
   untouched. (Static gradient mirrors home.css .plh-news::after — a value, not
   fragile logic; can be promoted to one shared token in a later pass.) */
.pl-shop + .pl-newsletter { isolation: isolate; }
.pl-shop + .pl-newsletter::after { content: ""; position: absolute; inset: 0; z-index: var(--pl-z-below); pointer-events: none; opacity: .5;
	background-image: linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
	background-size: 64px 64px;
	-webkit-mask-image: radial-gradient(120% 120% at 85% 0%, #000 0%, transparent 60%);
	mask-image: radial-gradient(120% 120% at 85% 0%, #000 0%, transparent 60%); }

/* ==========================================================================
   S1.2 — Catalog Command Surface. A compact, cohesive control band (structural
   wrappers .pl-catalog-command / __top added in archive-product.php around the
   UNCHANGED head, search form, chip nav and toolbar): an asymmetric intro | search
   zone, then the category chip rail and the count/sort utility rail, all sharing one
   icy control field that resolves to white at the product grid. No hero, no vh heights
   (content-driven), no new query / control / markup — presentation only. Namespaced to
   .pl-catalog-command*; the shared card renderer + .pl-shop__* controls are untouched.
   ========================================================================== */
.pl-catalog-command { position: relative; z-index: 0; padding-block: clamp(22px, 2.8vw, 34px) clamp(14px, 1.8vw, 20px); margin-bottom: clamp(20px, 2.6vw, 32px); }

/* Full-bleed icy control field behind the band (body overflow-x:hidden clips the 100vw
   bleed; z-index:-1 keeps it behind the real controls, which never fade). Icy upper
   field -> near-white at the grid edge, one restrained royal-blue radial toward the
   search (upper-right) side, faint coordinate/index geometry kept off the text. Pure
   decoration — no data, claims, molecules, certificates or dashboards. */
.pl-catalog-command::before { content: ""; position: absolute; z-index: -1; inset: 0; left: 50%; transform: translateX(-50%); width: 100vw; pointer-events: none; background-repeat: no-repeat;
	opacity: calc(1 - var(--pl-shop-recede, 0) * .4);
	background:
		radial-gradient(46% 92% at 87% 22%, rgba(40, 120, 245, .16), transparent 62%),
		repeating-linear-gradient(0deg, rgba(40, 120, 245, .03) 0 1px, transparent 1px 44px),
		repeating-linear-gradient(90deg, rgba(40, 120, 245, .03) 0 1px, transparent 1px 44px),
		linear-gradient(180deg, #dfeaff 0, #eef5ff 68%, var(--pl-surface) 100%); }
/* Gentle scroll settling (opacity 1 -> .6 over the first ~240px, eased in shop-
   atmosphere.js). Progressive + reduced-motion-safe: no-JS and reduced motion keep the
   complete static field; the CONTROLS are real DOM and never fade. */
@media (prefers-reduced-motion: reduce) { .pl-catalog-command::before { opacity: 1; } }
/* Crisp full-bleed hairline at the band's lower edge — a deliberate seam into the
   product grid rather than a fade to nothing. */
.pl-catalog-command::after { content: ""; position: absolute; z-index: -1; left: 50%; transform: translateX(-50%); bottom: 0; width: 100vw; height: 1px; background: var(--pl-line); }

/* Intro | search — stacked on mobile; asymmetric two columns from 880px (intro ~.84 /
   search 1fr), bottom-aligned so the search group sits on the intro's baseline while
   the upper-right radial fills the space above it. */
.pl-catalog-command__top { display: grid; grid-template-columns: 1fr; gap: clamp(16px, 3.5vw, 22px); align-items: end; }
@media (min-width: 880px) { .pl-catalog-command__top { grid-template-columns: minmax(0, .8fr) minmax(0, 1fr); column-gap: clamp(30px, 4.5vw, 60px); } }

/* Intro zone — the band owns the head rhythm; a touch more H1 presence via scale, on a
   tighter measure kept inside the intro column. */
.pl-catalog-command .pl-catalog-head { padding-bottom: 0; }
.pl-catalog-command .pl-catalog-head__title { font-size: clamp(1.9rem, 1.3rem + 2vw, 2.85rem); margin: 6px 0 0; }
.pl-catalog-command .pl-catalog-head__desc { margin-top: 10px; max-width: 46ch; }

/* Search — shed the standalone bottom margin (the band owns spacing) + fill the control
   column on desktop; input + button stay one control group (base .pl-shop__search rules). */
.pl-catalog-command .pl-shop__search { margin: 0; }
@media (min-width: 880px) { .pl-catalog-command .pl-shop__search { max-width: none; } }

/* Chip rail — full band width, under the intro/search zone. */
.pl-catalog-command .pl-shop__filters { margin: clamp(18px, 2.4vw, 26px) 0 0; }

/* Utility rail — count (left) · clear (secondary) · sort (right) on a shared thin top
   hairline; the base toolbar's bottom border drops (the band ::after is the grid seam). */
.pl-catalog-command .pl-shop__toolbar { margin: clamp(14px, 1.9vw, 20px) 0 0; padding-block: clamp(12px, 1.6vw, 16px) 0; border-top: 1px solid var(--pl-line); border-bottom: 0; }

/* Mobile (<880px): compact-not-cramped stack; desc measure relaxes to full width. */
@media (max-width: 879px) {
	.pl-catalog-command { padding-block: clamp(18px, 5vw, 26px) clamp(12px, 3vw, 18px); }
	.pl-catalog-command .pl-catalog-head__desc { max-width: 62ch; }
}

/* ---- Single product ---- */
/* RC.6.1 — the lower sections own the bottom gap (their own padding-bottom); zero
   .pl-woo's bottom padding here so it does not stack an extra ~56px before the footer. */
.single-product .pl-woo { padding-top: 8px; padding-bottom: 0; }
/* Figma 21:446 — gallery 560px, 56px column gap. The gallery is PINNED to its
   Figma width and the buy column takes the remainder (1248 - 560 - 56 = 632).
   Figma's own numbers (560 + 56 + 536) total 1152 and leave 96px unaccounted
   inside the 1248 column — that gap is the reported "excessive dead space
   between gallery and summary", so the buy column absorbs it rather than
   reproducing the hole. The previous 1.05fr/1fr ratio matched neither.
   minmax(0,…) on both tracks: a bare fr floors at min-content, and a wide image
   or long title would push the columns out of balance again. */
.single-product div.product { display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
/* rc.6: media in normal document flow (sticky removed per owner). */
.single-product div.product .woocommerce-product-gallery { margin: 0; }
/* RC.6.6 — this is the WINNING wrapper rule (0,3,2, more specific than the .pl-pdp-gallery
   rule below), so the continuous media radius must be set HERE. overflow:hidden clips the
   filled image + baked background to the same rounded rect (one continuous surface). */
.single-product div.product .woocommerce-product-gallery__wrapper { border-radius: var(--pl-radius-media); overflow: hidden; border: 1px solid var(--pl-line); }
.single-product .product_title { font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem); margin-bottom: 12px; }
.single-product .woocommerce-product-details__short-description { color: var(--pl-muted); }
.single-product .price { color: var(--pl-navy); font-weight: 700; font-size: 1.6rem; margin-bottom: 8px; }
.single-product .price del { color: var(--pl-muted); font-weight: 500; font-size: .8em; }
.single-product .price ins { text-decoration: none; }
.single-product form.cart { margin: 22px 0; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.single-product form.cart .quantity { display: inline-flex; }
.single-product .quantity input.qty { width: 76px; height: 52px; text-align: center; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); font-size: 1rem; }
/* Commerce CTA contract — PDP Add-to-Cart. Native Woo button styled to the shared funnel
   spec: --pl-radius, weight 700, the single --pl-cta-shadow elevation, blue-600 hover lift,
   and (new) a restrained :active press so the primary conversion control is as tactile as
   every other .pl-btn. Reduced-motion neutralization is added with the other funnel buttons. */
.single-product form.cart .single_add_to_cart_button, .single-product form.cart button.button {
	min-height: 52px; padding: 14px 28px; border-radius: var(--pl-radius); background: var(--pl-blue); color: #fff; border: none; font-weight: 700; font-size: 1.05rem;
	transition: background var(--pl-dur) var(--pl-ease), transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease); box-shadow: var(--pl-cta-shadow);
}
.single-product form.cart .single_add_to_cart_button:hover { background: var(--pl-blue-600); transform: translateY(-1px); box-shadow: var(--pl-cta-shadow-hover); }
.single-product form.cart .single_add_to_cart_button:active { transform: translateY(0) scale(.98); }
.single-product table.variations { margin-bottom: 16px; }
.single-product table.variations td, .single-product table.variations th { padding: 8px 0; }
.single-product .variations select { padding: 12px 40px 12px 14px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); min-width: 200px; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%235B6B80' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; }

/* Documentation status block */
.pl-docstatus { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 18px; margin: 20px 0; background: var(--pl-surface-2); }
.pl-docstatus__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.pl-docstatus__label { font-weight: 700; color: var(--pl-navy); }
.pl-docstatus__note { color: var(--pl-muted); font-size: .9rem; margin: 0 0 12px; }
.pl-docstatus__cta { }

/* Single-product: eyebrow, badges, stock, price fallback, media */
.pl-single-cat { font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--pl-blue); }
.pl-single-badges { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 14px; }
.single-product .price.price--pending { color: var(--pl-muted); font-weight: 600; font-size: 1.15rem; }
.pl-single-stock { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: .9rem; margin: 0 0 6px; }
.pl-single-stock__dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; flex: none; }
.pl-single-stock--ok { color: var(--pl-success); }
.pl-single-stock--pending { color: var(--pl-pending); }
.pl-single-stock--out { color: var(--pl-danger); }

/* Figma 21:473 BadgeRow — category chip + documentation chip on one line. */
.pl-single-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 6px; }
/* Figma 21:479 catalog meta line. */
.pl-single-meta { margin: 0 0 4px; font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: var(--pl-muted); font-weight: 600; }

.pl-single-media { position: static; }
.pl-single-media__placeholder { aspect-ratio: 1 / 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-media); overflow: hidden;
	background: radial-gradient(120% 90% at 50% 0%, #ffffff 0%, var(--pl-surface-2) 55%, var(--pl-surface-3) 100%); }
.pl-single-media__icon { color: var(--pl-blue); opacity: .5; }
.pl-single-media__label { font-size: .9rem; font-weight: 600; color: var(--pl-muted); }

/* ---- Cart page — PolarLabs card composition (Figma 33:936 / 33:1019) --------
   The previous rules here were a CSS reconstruction of core's table.shop_table,
   including ::before pseudo-labels faking the hidden <thead>. The theme now owns
   woocommerce/cart/cart.php and cart-totals.php outright, so all of that is gone:
   there is no table to re-style. --------------------------------------------- */
.pl-cart__layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 388px); gap: 32px; align-items: start; }
.pl-cart__items { display: grid; gap: 16px; min-width: 0; }

/* Cart info banner ("Shipping and discounts are calculated during checkout"):
   .pl-cart-notice reuses the .woocommerce-info base — constrain its inline SVG
   (which had no flex-shrink and could distort) and suppress any leaked core
   ::before icon-font glyph so the icon aligns cleanly beside the text. */
.pl-cart-notice { align-items: center; }
.pl-cart-notice::before { content: none; }
.pl-cart-notice svg { flex: none; width: 18px; height: 18px; }

.pl-cartrow {
	display: grid;
	grid-template-columns: 88px minmax(0, 1fr) auto auto;
	gap: 14px; align-items: center;
	padding: 14px 16px;
	background: var(--pl-surface); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg);
}
/* C1.1 — a more substantial, on-system product tile: the shared --pl-card-tile icy
   surface + 1px inner hairline (matching the shop/PDP media), object-fit:contain
   preserved below. Sized to the 88px column without lengthening the row materially. */
.pl-cartrow__media { width: 84px; height: 84px; border-radius: var(--pl-radius-sm); overflow: hidden; background: var(--pl-card-tile); box-shadow: inset 0 0 0 1px var(--pl-line); }
.pl-cartrow__media img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pl-cartrow__info { min-width: 0; display: grid; gap: 4px; }
.pl-cartrow__title { margin: 0; font-size: 1rem; line-height: 1.3; overflow-wrap: break-word; }
.pl-cartrow__title a { color: var(--pl-navy); }
.pl-cartrow__title a:hover { color: var(--pl-blue); }
.pl-cartrow__meta, .pl-cartrow__sku { margin: 0; font-size: .78rem; color: var(--pl-muted); }
.pl-cartrow__meta dl, .pl-cartrow__meta dt, .pl-cartrow__meta dd { margin: 0; display: inline; font-size: inherit; }
.pl-cartrow__meta dd + dt::before { content: " · "; }
.pl-cartrow__doc { display: inline-flex; margin-top: 2px; }
.pl-cartrow__qty .quantity { display: inline-flex; }
/* 44px minimum touch target on the quantity control. */
.pl-cartrow__qty input.qty { min-height: 44px; width: 84px; text-align: center; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); }
.pl-cartrow__price { display: grid; justify-items: end; gap: 2px; text-align: right; }
.pl-cartrow__linetotal { font-weight: 700; color: var(--pl-navy); }
.pl-cartrow__unit { font-size: .76rem; color: var(--pl-muted); }
/* Remove is a text action beside the price (Figma 33:977), not core's detached
   circular icon floated into its own column. */
.pl-cartrow__remove { font-size: .8rem; font-weight: 600; color: var(--pl-muted); text-decoration: underline; min-height: 44px; display: inline-flex; align-items: center; }
.pl-cartrow__remove:hover { color: var(--pl-danger); }
/* Neutralize WooCommerce core's a.remove (color:red!important; font-size:1.5em;
   round 1.41em box) inside the card. The old neutralizer only targeted the removed
   td.product-remove cell, so core leaked and pushed a huge red glyph off the right
   edge. Contain it to a small text link; only `color` needs !important (core's only
   !important on this element). */
.pl-cartrow__price a.remove.pl-cartrow__remove { width: auto; height: auto; line-height: 1.4; border-radius: 0; text-align: right; float: none; font-size: .8rem; color: var(--pl-muted) !important; }
.pl-cartrow__price a.remove.pl-cartrow__remove:hover { color: var(--pl-danger) !important; background: transparent; }

.pl-cart__actions { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-top: 4px; }
.pl-cart__coupon { display: grid; gap: 6px; flex: 1 1 280px; min-width: 0; }
.pl-cart__couponlabel { font-size: .82rem; font-weight: 600; color: var(--pl-navy); }
.pl-cart__couponrow { display: flex; gap: 8px; min-width: 0; }
.pl-cart__couponrow input.input-text { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 12px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); font-size: 1rem; }
.pl-cart__couponrow .pl-btn { flex: none; }
.pl-cart__update { flex: none; }
/* C1.1 — actions hierarchy: Apply coupon (inside the coupon row, keeping the
   --pl-line-strong border) reads as the coupon's own action; the standalone Update
   cart / Continue shopping recede with the lighter --pl-line border. Existing
   tokens only, no new decorative system; hover still resolves to the blue border. */
.pl-cart__update, .pl-cart-actions__continue { --btn-bd: var(--pl-line); }
/* C1.1 — the actions-row Continue shopping is a mobile-only fallback for the
   stacked layout; the header link (.pl-cart-head__continue) is its desktop home.
   Hide it on desktop here; the <=640 block re-shows it (removes the duplicate). */
.pl-cart-actions__continue { display: none; }
/* C1.1 — align cart input focus with the checkout field language (blue border +
   ring), layered over the global --pl-ring. Keyboard visibility preserved. */
.pl-cartrow__qty input.qty:focus,
.pl-cart__couponrow input.input-text:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }

/* Order Summary card — Figma 33:1019 */
/* Commerce-consolidation — cart & checkout summaries are ONE component family. The cart
   .pl-summary card and the checkout #order_review card now share surface, radius, padding,
   shadow, heading, and Total hierarchy, so the summary reads as two states of the same
   component from cart through place-order. */
.pl-summary { position: sticky; top: calc(var(--pl-header-h) + 20px); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); background: var(--pl-surface); padding: clamp(20px, 2.4vw, 26px); box-shadow: var(--pl-shadow-sm); }
.pl-summary__title { margin: 0 0 16px; font-size: 1.1rem; font-weight: 700; letter-spacing: -.01em; color: var(--pl-navy); }
.pl-summary__rows { display: grid; gap: 10px; }
.pl-summary__row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pl-summary__label { color: var(--pl-muted); font-size: .92rem; }
.pl-summary__value { font-weight: 700; color: var(--pl-navy); text-align: right; }
.pl-summary__value--muted { font-weight: 500; color: var(--pl-muted); font-size: .88rem; }
.pl-summary__row--total { margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--pl-line); }
.pl-summary__row--total .pl-summary__label { color: var(--pl-navy); font-weight: 700; font-size: 1rem; }
.pl-summary__row--total .pl-summary__value { font-size: 1.25rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.pl-summary__cta { margin-top: 16px; }
.pl-summary__cta .pl-btn, .pl-summary__cta .button { width: 100%; min-height: 48px; }
.pl-summary__notice { margin: 14px 0 0; font-size: .78rem; line-height: 1.5; color: var(--pl-muted); }
.pl-summary__help { margin: 8px 0 0; font-size: .78rem; color: var(--pl-muted); }

/* WooCommerce notices — branded, accessible, with a compact status icon. Covers the
   PDP add-to-cart SUCCESS message AND the cart "Coupon code applied successfully."
   message (both are `.woocommerce-message`). Woo's message DOM is button-FIRST
   (`<a class="button wc-forward">View cart</a> <text>`), so `order:2` sends the action
   to the end and the message text reads first. Wraps cleanly on narrow viewports. */
.woocommerce-message, .woocommerce-error, .woocommerce-info, .wc-block-components-notice-banner {
	list-style: none; border-radius: var(--pl-radius-lg); box-shadow: var(--pl-shadow-sm); padding: 13px 16px; margin: 0 0 18px; font-weight: 600; font-size: .92rem; line-height: 1.5; border: 1px solid transparent; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
}
/* Compact status icon — currentColor via mask, so it inherits each notice's accent. */
.woocommerce-message::before, .woocommerce-error::before, .woocommerce-info::before {
	content: ""; flex: none; width: 20px; height: 20px; background: currentColor;
	-webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px 20px; mask-size: 20px 20px;
}
.woocommerce-message::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5Zm5 8.2-6 6a1 1 0 0 1-1.4 0l-3-3 1.4-1.42 2.3 2.3 5.3-5.3Z'/%3E%3C/svg%3E");
	        mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5Zm5 8.2-6 6a1 1 0 0 1-1.4 0l-3-3 1.4-1.42 2.3 2.3 5.3-5.3Z'/%3E%3C/svg%3E");
}
.woocommerce-info::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5ZM13 17h-2v-6h2Zm0-8h-2V7h2Z'/%3E%3C/svg%3E");
	        mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5ZM13 17h-2v-6h2Zm0-8h-2V7h2Z'/%3E%3C/svg%3E");
}
.woocommerce-error::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5ZM13 13h-2V7h2Zm0 4h-2v-2h2Z'/%3E%3C/svg%3E");
	        mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5A10.5 10.5 0 1 0 22.5 12 10.51 10.51 0 0 0 12 1.5ZM13 13h-2V7h2Zm0 4h-2v-2h2Z'/%3E%3C/svg%3E");
}
.woocommerce-message { background: var(--pl-success-bg); color: var(--pl-success); border-color: var(--pl-success-border); }
.woocommerce-error { background: var(--pl-danger-bg); color: var(--pl-danger); border-color: var(--pl-danger-border); }
.woocommerce-info { background: var(--pl-blue-050); color: var(--pl-blue-600); border-color: var(--pl-info-border); }
/* Action button sits at the END (order:2 defeats Woo's button-first DOM); success
   "View cart" is a filled action, the rest are quiet outlines. */
.woocommerce-message .button, .woocommerce-error .button, .woocommerce-info .button {
	order: 2; margin-left: auto; flex: none; min-height: 38px; display: inline-flex; align-items: center; border-radius: var(--pl-radius); background: transparent; border: 1.5px solid currentColor; color: inherit; padding: 7px 15px; font-weight: 700; font-size: .86rem; white-space: nowrap;
}
.woocommerce-message .button { background: var(--pl-success); border-color: var(--pl-success); color: #fff; }

/* Mini-cart total label/value */
.pl-minicart__totallabel { color: var(--pl-muted); font-weight: 600; }
.pl-minicart__totalvalue { color: var(--pl-navy); }

/* ---- Checkout ---- */
/* form.checkout is NO LONGER the grid — woocommerce/checkout/form-checkout.php now
   owns .pl-checkout__grid. Gridding the form itself and pinning #order_review to
   grid-column:2 (the old approach) fought the real wrappers and depended on core's
   child order. */
.woocommerce-checkout .pl-woo form.checkout { display: block; }
.pl-checkout__head { margin-bottom: clamp(16px, 3vw, 28px); }
.pl-checkout__title { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.1rem); margin: 0 0 6px; }
.pl-checkout__note { margin: 0; font-size: .82rem; color: var(--pl-muted); }
/* Figma 25:767 — customer details beside the order summary. */
.pl-checkout__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: clamp(24px, 4vw, 48px); align-items: start; }
.pl-checkout__main { min-width: 0; }
.pl-checkout__aside { min-width: 0; }
.pl-checkout__help { margin: 10px 0 0; font-size: .78rem; color: var(--pl-muted); }
/* Left column spans both rows; the order review + heading stay pinned top-right. */
.woocommerce-checkout #order_review_heading { margin: 0 0 12px; font-size: 1.1rem; }

.woocommerce-checkout .col2-set .col-1, .woocommerce-checkout .col2-set .col-2 { width: 100%; float: none; }
.woocommerce-checkout h3 { font-size: 1.2rem; }
.woocommerce form .form-row label { font-weight: 600; color: var(--pl-navy); }
.woocommerce form .form-row input.input-text, .woocommerce form .form-row textarea, .woocommerce form .form-row .select2-container, .woocommerce form .form-row select {
	width: 100%; min-height: 48px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); padding: 12px 14px; font-size: 1rem; background: var(--pl-surface);
}
.woocommerce form .form-row input.input-text:focus, .woocommerce form .form-row textarea:focus, .woocommerce form .form-row select:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
/* iOS Safari zooms the page when a focused control renders below 16px. The
   `.form-row` fields above already sit at 1rem; this floor catches any Woo
   checkout/account control that lives OUTSIDE `.form-row` so focusing it can
   never trigger zoom. No `.form-row` selector is repeated here — those are
   handled above — so this adds no duplicate/conflicting declaration. */
.woocommerce-checkout input.input-text,
.woocommerce-checkout textarea,
.woocommerce-checkout select,
.woocommerce-account input.input-text,
.woocommerce-account textarea,
.woocommerce-account select {
	font-size: 16px;
}
.woocommerce form .form-row { margin: 0 0 16px; }
.woocommerce form .form-row label .required { color: var(--pl-danger); border: 0; }
/* Accessible validation: highlight the affected field + label. */
.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select,
.woocommerce form .form-row.woocommerce-invalid .select2-container { border-color: var(--pl-danger); }
.woocommerce form .form-row.woocommerce-invalid label { color: var(--pl-danger); }
.woocommerce form .form-row.woocommerce-validated input.input-text { border-color: var(--pl-success-border); }
.woocommerce-checkout #order_review { position: sticky; top: calc(var(--pl-header-h) + 20px); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: clamp(20px, 2.4vw, 26px); background: var(--pl-surface); box-shadow: var(--pl-shadow-sm); }
.woocommerce-checkout table.shop_table { width: 100%; }
.woocommerce-checkout #payment { background: transparent; border-radius: var(--pl-radius); }
.woocommerce-checkout #payment ul.payment_methods { border: 0; padding: 0; margin: 0; list-style: none; }
/* Native WooCommerce Place Order button — theme primary styling. The custom checkout
   confirmation feature (and its .pl-place-order alias + JS disable-gate) were removed in
   RC.6.7; WooCommerce owns the button's enabled/disabled state natively again. */
.woocommerce #payment #place_order {
	width: 100%; min-height: 54px; border-radius: var(--pl-radius); background: var(--pl-blue); color: #fff; border: none; font-weight: 700; font-size: 1.05rem; margin-top: 14px;
	box-shadow: var(--pl-cta-shadow);
	transition: background var(--pl-dur) var(--pl-ease), transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease);
}
.woocommerce #payment #place_order:active { transform: translateY(0) scale(.98); }

/* (RC.6.7) The custom checkout-confirmation module (.pl-checkout-confirm*) was removed
   entirely — the owner retired the confirmation requirement and WooCommerce native
   checkout owns validation again. No orphan selectors remain. */

/* ── Phase C.1 interaction polish — restrained motion (140–220ms, standard easing,
   no bounce, no scroll-jacking). All gated by prefers-reduced-motion; every control
   and total stays fully usable/visible without animation, and no visibility depends
   on JS. */
/* Woo notices: single fade-and-rise entrance (never loops) + View-cart press feedback. */
.woocommerce-message, .woocommerce-error, .woocommerce-info { animation: pl-notice-in 200ms var(--pl-ease) both; }
@keyframes pl-notice-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.woocommerce-message .button, .woocommerce-error .button, .woocommerce-info .button { transition: transform 140ms var(--pl-ease), background var(--pl-dur) var(--pl-ease); }
.woocommerce-message .button:active, .woocommerce-error .button:active, .woocommerce-info .button:active { transform: scale(.97); }
/* Cart drawer: short row fade when the Woo fragment re-renders the item list. */
.pl-cartdrawer__scroll .pl-minicart__item { animation: pl-row-in 180ms var(--pl-ease) both; }
@keyframes pl-row-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
/* (RC.6.7) The order-total flash was driven by the removed checkout.js (confirmation
   asset); removed here too so no orphan rule remains. The total still updates natively
   via WooCommerce fragments — just without the one-shot highlight. */
@media (prefers-reduced-motion: reduce) {
	.woocommerce-message, .woocommerce-error, .woocommerce-info,
	.pl-cartdrawer__scroll .pl-minicart__item { animation: none; }
	.woocommerce-message .button, .woocommerce-error .button, .woocommerce-info .button { transition: none; }
}

/* Returning-customer login + coupon toggles rendered as cards. */
.woocommerce-form-login, .woocommerce-form-coupon { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 20px; margin-bottom: 20px; background: var(--pl-surface); }
.woocommerce-form-login .button, .woocommerce-form-coupon .button { min-height: 48px; border-radius: var(--pl-radius); background: var(--pl-blue); color: #fff; border: none; font-weight: 600; padding: 12px 22px; }
.woocommerce-form-login-toggle, .woocommerce-form-coupon-toggle { margin-bottom: 16px; }

/* Order review — premium PolarLabs order-summary card. Styles Woo's NATIVE
   review-order table + payment; every class/row the checkout fragments update is
   preserved (cart items, product-quantity, cart-subtotal, coupon + remove-coupon,
   shipping options, tax, order-total, payment_methods, payment_box). Presentation
   only — no row is added, removed, or reordered. */
.woocommerce-checkout #order_review_heading { font-size: 1.1rem; font-weight: 700; letter-spacing: -.01em; color: var(--pl-navy); margin: 0 0 16px; }
.woocommerce-checkout .woocommerce-checkout-review-order-table { border-collapse: collapse; }
/* RC.6.10.2 — the summary reads as ONE calm card: strip WooCommerce core's .shop_table box
   + per-row borders (they were winning over Block A on stylesheet load order, giving a
   table-in-a-card look). The #order_review ID makes this authoritative regardless of load
   order; only TWO intentional hairlines are re-added — items→totals (above Subtotal) and
   above the Total. */
#order_review .woocommerce-checkout-review-order-table,
#order_review .woocommerce-checkout-review-order-table tbody th,
#order_review .woocommerce-checkout-review-order-table tbody td,
#order_review .woocommerce-checkout-review-order-table tfoot th,
#order_review .woocommerce-checkout-review-order-table tfoot td { border: 0; background: transparent; }
#order_review .woocommerce-checkout-review-order-table tfoot tr.cart-subtotal th,
#order_review .woocommerce-checkout-review-order-table tfoot tr.cart-subtotal td { border-top: 1px solid var(--pl-line); padding-top: 14px; }
#order_review .woocommerce-checkout-review-order-table tfoot tr.order-total th,
#order_review .woocommerce-checkout-review-order-table tfoot tr.order-total td { border-top: 1px solid var(--pl-line); padding-top: 15px; }
/* Header row kept in the DOM for assistive tech but hidden visually (the summary card has
   no header row). SINGLE AUTHORITY — consolidated here from the former .pl-review thead clip. */
.woocommerce-checkout .woocommerce-checkout-review-order-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
/* Product line items. */
.woocommerce-checkout .woocommerce-checkout-review-order-table tbody td { padding: 8px 0; border-top: 0; text-align: left; vertical-align: top; font-size: .92rem; color: var(--pl-navy); }
.woocommerce-checkout .woocommerce-checkout-review-order-table tbody tr:first-child td { border-top: 0; }
.woocommerce-checkout .woocommerce-checkout-review-order-table td.product-name { font-weight: 600; overflow-wrap: anywhere; }
.woocommerce-checkout .woocommerce-checkout-review-order-table td.product-name .product-quantity { color: var(--pl-muted); font-weight: 600; white-space: nowrap; }
.woocommerce-checkout .woocommerce-checkout-review-order-table td.product-name dl.variation { margin: 4px 0 0; font-size: .8rem; color: var(--pl-muted); }
.woocommerce-checkout .woocommerce-checkout-review-order-table td.product-total { text-align: right; white-space: nowrap; font-weight: 700; }
/* Totals foot: subtotal / coupon / shipping / tax / total. */
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot th,
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot td { padding: 6px 0; border-top: 0; text-align: left; font-size: .9rem; font-weight: 600; color: var(--pl-muted); }
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot td { text-align: right; color: var(--pl-navy); font-variant-numeric: tabular-nums; }
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot tr:first-child th,
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot tr:first-child td { border-top: 1px solid var(--pl-line); padding-top: 14px; }
/* Applied-coupon row + its quiet remove link. */
.woocommerce-checkout .woocommerce-checkout-review-order-table .cart-discount th,
.woocommerce-checkout .woocommerce-checkout-review-order-table .cart-discount td { color: var(--pl-success); }
.woocommerce-checkout .woocommerce-remove-coupon { margin-left: 8px; font-size: .78rem; font-weight: 600; color: var(--pl-muted); text-decoration: underline; white-space: nowrap; }
.woocommerce-checkout .woocommerce-remove-coupon:hover { color: var(--pl-danger); }
/* Shipping-method options list inside the shipping row. */
.woocommerce-checkout .woocommerce-checkout-review-order-table .shipping ul#shipping_method,
.woocommerce-checkout .woocommerce-checkout-review-order-table .shipping ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.woocommerce-checkout .woocommerce-checkout-review-order-table .shipping ul li { display: flex; align-items: center; gap: 10px; padding: 3px 0; }
/* Branded shipping radios (consolidated from the former .pl-review rule) + the neutral
   'Calculated at checkout' placeholder styled as a quiet secondary value — Block A's tfoot
   td would otherwise render it as a bold navy amount. */
.woocommerce-checkout .woocommerce-checkout-review-order-table .shipping input[type="radio"] { width: 18px; height: 18px; flex: none; accent-color: var(--pl-blue); }
.woocommerce-checkout .woocommerce-checkout-review-order-table .pl-review__shipping-neutral td { color: var(--pl-muted); font-weight: 500; }
/* RC.6.10.2 — shipping as a labelled section (was a cramped 'Shipment' cell wedged beside the
   radios): the label sits ABOVE its methods; each real method is a clean full-width selectable
   row (parity with payment). Real tr.shipping only — the neutral 'Calculated at checkout' row
   stays a normal inline label/value. */
#order_review .woocommerce-checkout-review-order-table tr.shipping th { display: block; width: 100%; text-align: left; padding: 4px 0 8px; font-size: .9rem; font-weight: 600; color: var(--pl-muted); }
#order_review .woocommerce-checkout-review-order-table tr.shipping td { display: block; width: 100%; text-align: left; }
#order_review .woocommerce-checkout-review-order-table .shipping ul li { padding: 10px 12px; min-height: 44px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius); }
#order_review .woocommerce-checkout-review-order-table .shipping ul li:has(input[type="radio"]:checked) { border-color: var(--pl-blue); background: var(--pl-blue-050); }
#order_review .woocommerce-checkout-review-order-table .shipping ul li label { font-weight: 600; color: var(--pl-navy); cursor: pointer; line-height: 1.35; }
/* Order total emphasis. */
.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total th { font-size: 1rem; font-weight: 700; color: var(--pl-navy); padding-top: 15px; border-top: 1px solid var(--pl-line); }
.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total td { font-size: 1.25rem; font-weight: 800; color: var(--pl-navy); letter-spacing: -.01em; padding-top: 15px; border-top: 1px solid var(--pl-line); }
.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total .amount { font-weight: 800; }
/* Payment integration. */
.woocommerce-checkout #payment { margin-top: 16px; }
/* Workstream E — payment methods as clean selectable rows that belong to the summary
   system, WITHOUT touching WooCommerce's native controls, gateway markup, or scripts.
   Native radios/labels/payment_box (incl. gateway fields/iframes) are all preserved; only
   presentation is added. Parity with the shipping rows: 18px branded radios, a clear
   selected state, and a visible focus ring at the most trust-critical step. */
.woocommerce-checkout #payment ul.payment_methods li { display: block; border: 1px solid var(--pl-line); border-radius: var(--pl-radius); padding: 12px 14px; margin: 0 0 8px; transition: border-color var(--pl-dur) var(--pl-ease), background var(--pl-dur) var(--pl-ease); }
.woocommerce-checkout #payment ul.payment_methods li:last-child { margin-bottom: 0; }
.woocommerce-checkout #payment ul.payment_methods li > input[type="radio"] { width: 18px; height: 18px; margin-right: 8px; accent-color: var(--pl-blue); vertical-align: middle; }
.woocommerce-checkout #payment ul.payment_methods li > label { font-weight: 600; color: var(--pl-navy); cursor: pointer; display: inline; }
/* Reliable selected emphasis (no :has() dependency — matches the codebase's class-first
   preference, theme.js:688): the checked radio's own label. */
.woocommerce-checkout #payment ul.payment_methods li > input[type="radio"]:checked + label { font-weight: 700; }
/* Progressive row highlight where :has() is supported; the native radio always shows the
   selected state regardless, so this is pure enhancement, never load-bearing. */
.woocommerce-checkout #payment ul.payment_methods li:has(> input[type="radio"]:checked) { border-color: var(--pl-blue); background: var(--pl-blue-050); }
.woocommerce-checkout #payment ul.payment_methods li > input[type="radio"]:focus-visible { outline: 2px solid var(--pl-blue); outline-offset: 2px; }
/* Expanded gateway content stays visually connected to its selected method — a quiet inset
   sub-panel, not a card-in-a-card. */
/* RC.6.10.2 — payment description is a quiet inset ATTACHED to its method, never a floating
   grey speech-bubble. The higher-specificity selector out-specifies core's grey
   `.woocommerce #payment div.payment_box` (1,2,1) that was winning; core's ::before caret is
   removed so the description reads as part of the selected method, not a callout bubble. */
.woocommerce-checkout #payment ul.payment_methods .payment_box { background: var(--pl-surface-2); border: 0; border-radius: var(--pl-radius-sm); padding: 10px 12px; margin: 10px 0 2px; font-size: .86rem; line-height: 1.5; color: var(--pl-muted); }
.woocommerce-checkout #payment ul.payment_methods .payment_box::before { display: none; }
.woocommerce-checkout #payment .woocommerce-privacy-policy-text { margin-top: 12px; font-size: .8rem; color: var(--pl-muted); }
.woocommerce #payment #place_order:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--pl-blue-600); transform: translateY(-1px); box-shadow: var(--pl-cta-shadow-hover); }

/* Reduced-motion-safe processing state (WooCommerce blockUI overlay). */
.woocommerce .blockUI.blockOverlay { position: relative; }
.woocommerce .blockUI.blockOverlay::before {
	content: ""; position: absolute; top: 50%; left: 50%; width: 34px; height: 34px; margin: -17px 0 0 -17px;
	border: 3px solid rgba(40,120,245,.25); border-top-color: var(--pl-blue); border-radius: 50%;
	animation: pl-spin .8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
	.woocommerce .blockUI.blockOverlay::before { animation: none; border-top-color: var(--pl-blue); opacity: .8; }
}
@keyframes pl-spin { to { transform: rotate(360deg); } }

/* ---- My Account ---- */
.woocommerce-account .woocommerce { display: grid; grid-template-columns: 260px 1fr; gap: 40px; align-items: start; }
.woocommerce-account .woocommerce-MyAccount-navigation ul { list-style: none; display: grid; gap: 4px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 10px; }
.woocommerce-account .woocommerce-MyAccount-navigation li a { display: flex; align-items: center; min-height: 44px; padding: 10px 14px; border-radius: var(--pl-radius-sm); color: var(--pl-navy); font-weight: 600; transition: background var(--pl-dur) var(--pl-ease), color var(--pl-dur) var(--pl-ease); }
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover { background: var(--pl-surface-3); color: var(--pl-blue); }
.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a { background: var(--pl-blue); color: #fff; }
/* Log out is a secondary action: separated + muted. */
.woocommerce-MyAccount-navigation-link--customer-logout { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--pl-line); }
.woocommerce-MyAccount-navigation-link--customer-logout a { color: var(--pl-muted); font-weight: 600; }
.woocommerce-MyAccount-navigation-link--customer-logout a:hover { color: var(--pl-danger); background: var(--pl-danger-bg); }
/* Mobile "Account menu" disclosure toggle — hidden on desktop. */
.pl-account-nav-toggle { display: none; }
.pl-account-nav-toggle__text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2; }
.pl-account-nav-toggle__label { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--pl-muted); }
.pl-account-nav-toggle__current { font-size: 1rem; color: var(--pl-navy); font-weight: 700; }
.pl-account-nav-toggle__chevron { transition: transform var(--pl-dur) var(--pl-ease); color: var(--pl-muted); flex: none; }
.pl-account-nav-toggle[aria-expanded="true"] .pl-account-nav-toggle__chevron { transform: rotate(180deg); }
.woocommerce-account .woocommerce-MyAccount-content, .woocommerce-account .woocommerce-MyAccount-navigation { min-width: 0; }
/* ==========================================================================
   Logged-out account width — the desktop "narrow strip" defect
   --------------------------------------------------------------------------
   NOT the product-card bug, despite looking like it. That was one percentage
   resolving against a grid track. This is FOUR nested constraints, measured on
   live v1.0.2 at 1440 by peeling them off one at a time:

     .pl-prose        621px   (72ch READING measure — page.php wrapped the
                               account app in it; My Account is a WP page)
       .woocommerce   480px   (the old cap that used to live on this line)
         .col2-set    224px   tracks
           .col-1     107.5px = core's .col-1{width:48%} of a 224px track

   Peeling them off, one layer at a time, gave: 107.5 -> 224 (section 0's
   col-1/col-2 reset alone) -> 294.5 (drop the 480 cap) -> 544 (unwrap prose)
   -> 424 per column with the composition below.

   IMPORTANT: section 0's reset is necessary but NOT sufficient. On its own it
   only lifts the form from 107.5px to 224px — still a strip. Do not re-close
   this defect by pointing at that reset; all four layers must go.
   page.php now renders .pl-page__app instead of .pl-prose on account/cart/
   checkout, which removes the outermost layer.
   ========================================================================== */
.pl-page__app { max-width: none; }
/* A real login/register composition: two columns, capped for readability rather
   than crushed. 880 - 32 gap / 2 = 424 per column at desktop. */
.woocommerce-account:not(.logged-in) .woocommerce { max-width: 880px; margin-inline: auto; }
.woocommerce-account .col2-set { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
.woocommerce form.login, .woocommerce form.register, .woocommerce form.lost_reset_password { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 24px; }
.woocommerce form.login .button, .woocommerce form.register .button, .woocommerce form.lost_reset_password .button { min-height: 48px; border-radius: var(--pl-radius); background: var(--pl-blue); color: #fff; border: none; font-weight: 700; padding: 12px 22px; width: 100%; }
.woocommerce form.login .button:hover, .woocommerce form.register .button:hover { background: var(--pl-blue-600); }
.woocommerce form .woocommerce-form-login__rememberme, .woocommerce form label.woocommerce-form__label-for-checkbox { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }

/* Dashboard */
.pl-account { display: grid; gap: 18px; }
.pl-account__welcome { padding-bottom: 4px; }
.pl-account__hello { font-size: clamp(1.3rem, 1rem + 1.2vw, 1.7rem); margin: 0; }
.pl-account__welcomemeta { color: var(--pl-muted); margin: 6px 0 0; font-size: .92rem; }
.pl-account__card { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 20px; }
.pl-account__cardhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.pl-account__cardtitle { font-size: 1.05rem; margin: 0 0 12px; }
.pl-account__cardhead .pl-account__cardtitle { margin: 0; }
.pl-account__orders { list-style: none; display: grid; gap: 8px; }
.pl-account__order a { display: grid; grid-template-columns: auto 1fr auto auto auto; gap: 14px; align-items: center; padding: 12px 14px; border-radius: var(--pl-radius-sm); background: var(--pl-surface-2); color: var(--pl-navy); min-height: 44px; transition: background var(--pl-dur) var(--pl-ease); }
.pl-account__order a:hover { background: var(--pl-surface-3); }
.pl-account__ordernum { font-weight: 700; }
.pl-account__orderdate { color: var(--pl-muted); font-size: .88rem; }
.pl-account__orderstatus { color: var(--pl-muted); font-size: .88rem; }
.pl-account__ordertotal { font-weight: 600; }
.pl-account__orderview { color: var(--pl-blue); font-weight: 600; font-size: .9rem; }
.pl-account__empty { text-align: center; padding: 18px; color: var(--pl-muted); }
.pl-account__empty p { margin: 0 0 12px; }
/* Future service slots (Coming Soon) */
.pl-account__services { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.pl-account__service { border: 1px solid var(--pl-line); border-radius: var(--pl-radius); padding: 14px; background: var(--pl-surface-2); }
.pl-account__service.is-available { background: var(--pl-surface); border-color: var(--pl-line-strong); }
.pl-account__servicetop { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.pl-account__servicetitle { font-weight: 700; color: var(--pl-navy); }
.pl-account__soon { font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--pl-muted); background: var(--pl-surface-3); border-radius: var(--pl-radius-pill); padding: 3px 8px; }
.pl-account__servicedesc { color: var(--pl-muted); font-size: .85rem; }
/* Support CTA */
.pl-account__support { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 20px; background: var(--pl-surface-2); }
.pl-account__supporttext { color: var(--pl-muted); margin: 4px 0 0; }

/* Orders list table (WooCommerce myaccount/orders) */
.woocommerce-account .woocommerce-orders-table, .woocommerce-account .woocommerce-MyAccount-content table.shop_table { width: 100%; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); border-collapse: separate; border-spacing: 0; overflow: hidden; }
.woocommerce-account table.shop_table th { background: var(--pl-surface-2); color: var(--pl-navy); text-align: left; padding: 12px 14px; font-weight: 700; }
.woocommerce-account table.shop_table td { padding: 14px; border-top: 1px solid var(--pl-line); }
.woocommerce-account .woocommerce-orders-table__cell-order-actions a.button { min-height: 40px; display: inline-flex; align-items: center; padding: 8px 14px; border-radius: var(--pl-radius); background: transparent; border: 1.5px solid var(--pl-field-border); color: var(--pl-navy); font-weight: 600; }
.woocommerce-account .woocommerce-orders-table__cell-order-actions a.button:hover { border-color: var(--pl-blue); color: var(--pl-blue); }

/* Order details + addresses */
.woocommerce mark, .woocommerce .order-number, .woocommerce .order-status { background: var(--pl-blue-050); color: var(--pl-navy); padding: 1px 7px; border-radius: 5px; font-weight: 700; }
.woocommerce-order-details, .woocommerce-customer-details { margin-top: 24px; }
.woocommerce-order-details__title, .woocommerce-column__title, .woocommerce-order-downloads__title { font-size: 1.2rem; margin: 0 0 12px; }
.woocommerce-order-overview.woocommerce-thankyou-order-details { list-style: none; display: flex; flex-wrap: wrap; gap: 20px; padding: 18px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); background: var(--pl-surface-2); margin: 0 0 24px; }
.woocommerce-order-overview li { font-size: .85rem; color: var(--pl-muted); }
.woocommerce-order-overview li strong { display: block; color: var(--pl-navy); font-size: 1rem; margin-top: 2px; word-break: break-word; }
.woocommerce-table--order-details { width: 100%; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); border-collapse: separate; border-spacing: 0; overflow: hidden; }
.woocommerce-table--order-details th, .woocommerce-table--order-details td { padding: 12px 14px; border-top: 1px solid var(--pl-line); text-align: left; }
.woocommerce-table--order-details tfoot th { text-align: right; }
.woocommerce-table--order-details .product-total, .woocommerce-table--order-details td:last-child, .woocommerce-table--order-details th:last-child { text-align: right; }
.woocommerce-table--order-details .order-total .amount { font-weight: 700; color: var(--pl-navy); }
.woocommerce-customer-details .col2-set, .woocommerce-Addresses.addresses { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.woocommerce-Address { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: 20px; }
.woocommerce-Address-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.woocommerce-Address-title .edit { color: var(--pl-blue); font-weight: 600; }
.woocommerce-Address address { font-style: normal; color: var(--pl-ink); line-height: 1.6; }

/* ---- Mini-cart drawer (C1.2 — compact commerce panel) ---------------------
   The panel is a flex column: header (shell) + body. The body is itself a flex
   column — pinned free-shipping progress (flex:none), the ONLY scroll container
   (.pl-cartdrawer__scroll, flex:1), and the anchored footer (flex:none). Header
   and footer never scroll; the footer can't obscure the last row. Everything below
   the header ships inside the .widget_shopping_cart_content fragment, so it all
   refreshes together after add / remove / quantity change. */
.pl-cartdrawer { position: fixed; inset: 0; z-index: var(--pl-z-cart-drawer); }
.pl-cartdrawer[hidden] { display: none; }
.pl-cartdrawer__backdrop { position: absolute; inset: 0; background: rgba(4,16,31,.5); opacity: 0; transition: opacity 240ms var(--pl-ease); }
.pl-cartdrawer.is-open .pl-cartdrawer__backdrop { opacity: 1; }
/* Full-width mobile (no wasteful 80% strip); ~448px right-drawer on tablet/desktop.
   Emil's iOS drawer curve; the global reduced-motion rule zeroes the duration so it
   appears instantly (translateX is functional positioning, not decorative motion). */
.pl-cartdrawer__panel {
	position: absolute; inset: 0 0 0 auto; height: 100%; width: min(100%, 448px);
	background: var(--pl-surface); box-shadow: var(--pl-shadow-lg);
	transform: translateX(100%); transition: transform 240ms cubic-bezier(0.32, 0.72, 0, 1);
	display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
.pl-cartdrawer.is-open .pl-cartdrawer__panel { transform: translateX(0); }

/* Header — compact, one hairline; count baseline-aligned to the title. */
.pl-cartdrawer__head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: calc(14px + env(safe-area-inset-top, 0px)) 18px 14px; border-bottom: 1px solid var(--pl-line); }
.pl-cartdrawer__heading { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.pl-cartdrawer__title { margin: 0; font-size: 1.12rem; }
.pl-cartdrawer__count { color: var(--pl-muted); font-size: .84rem; font-weight: 600; white-space: nowrap; }

/* Body geometry */
.pl-cartdrawer__body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pl-cartdrawer__scroll { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 14px 18px; display: grid; gap: 12px; align-content: start; }

/* Free-shipping progress — pinned; fail-closed (rendered only when a real WC Free
   Shipping threshold exists). One factual line + a restrained Polar-blue bar. */
.pl-cartdrawer__ship { flex: none; padding: 12px 18px; border-bottom: 1px solid var(--pl-line); display: grid; gap: 8px; }
.pl-cartdrawer__ship-status { margin: 0; font-size: .84rem; font-weight: 600; color: var(--pl-navy); }
.pl-cartdrawer__ship.is-qualified .pl-cartdrawer__ship-status { color: var(--pl-blue-600); }
.pl-cartdrawer__ship-track { height: 6px; border-radius: 999px; background: var(--pl-blue-050); overflow: hidden; }
.pl-cartdrawer__ship-bar { display: block; height: 100%; border-radius: 999px; background: var(--pl-blue); }

/* Product rows — [icy tile] [name + strength + qty/price], restrained text Remove. */
.pl-minicart__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.pl-minicart__item { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: start; }
.pl-minicart__thumb { flex: none; width: 76px; height: 76px; border-radius: var(--pl-radius-sm); overflow: hidden; background: var(--pl-card-tile); box-shadow: inset 0 0 0 1px var(--pl-line); display: block; }
.pl-minicart__thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pl-minicart__body { min-width: 0; display: grid; gap: 6px; }
.pl-minicart__row1 { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
/* Title: dominant, wraps, clamped to 2 lines (full name stays in the DOM/SR + the
   product link). break-word avoids mid-character cuts on names with spaces; min-width:0
   lets it shrink in the flex row so a long title can never force horizontal overflow. */
.pl-minicart__name { flex: 1 1 auto; min-width: 0; font-weight: 700; color: var(--pl-navy); font-size: .95rem; line-height: 1.3; overflow-wrap: break-word; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pl-minicart__name:hover { color: var(--pl-blue); }
.pl-minicart__attr { margin: 0; font-size: .78rem; color: var(--pl-muted); line-height: 1.4; overflow-wrap: anywhere; }
.pl-minicart__attr .variation, .pl-minicart__attr dl, .pl-minicart__attr dt, .pl-minicart__attr dd { margin: 0; display: inline; font-size: inherit; color: inherit; }
.pl-minicart__attr dd + dt::before { content: " · "; }
.pl-minicart__remove { flex: none; align-self: flex-start; font-size: .76rem; font-weight: 600; color: var(--pl-muted); text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; min-height: 44px; display: inline-flex; align-items: center; }
.pl-minicart__remove:hover, .pl-minicart__remove:focus-visible { color: var(--pl-danger); }
.pl-minicart__row2 { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }
.pl-minicart__price { font-weight: 700; color: var(--pl-navy); font-size: .95rem; white-space: nowrap; }

/* Quantity — READ-ONLY compact metadata (owner decision; edited on the full Cart
   page). Not an interactive control; re-renders with the fragment. */
.pl-minicart__qty { color: var(--pl-muted); font-size: .82rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Coupon — compact native form (POST to cart); only when wc_coupons_enabled(). */
.pl-minicart__coupon { display: grid; gap: 6px; margin-top: 2px; }
.pl-minicart__couponlabel { font-size: .78rem; font-weight: 600; color: var(--pl-navy); }
.pl-minicart__couponrow { display: flex; gap: 8px; min-width: 0; }
.pl-minicart__couponrow input.input-text { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 12px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); font-size: 1rem; }
.pl-minicart__couponrow input.input-text:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
.pl-minicart__couponbtn { flex: none; min-height: 44px; }

/* Anchored footer — subtotal · Proceed to checkout (dominant) · View cart (quiet) · RUO. */
.pl-cartdrawer__foot { flex: none; padding: 14px 18px calc(14px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--pl-line); box-shadow: 0 -6px 16px rgba(7,24,45,.06); background: var(--pl-surface); display: grid; gap: 10px; }
.pl-minicart__total { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pl-cartdrawer__foot .pl-minicart__totallabel { color: var(--pl-navy); font-weight: 700; font-size: 1rem; }
.pl-cartdrawer__foot .pl-minicart__totalvalue { color: var(--pl-navy); font-weight: 800; font-size: 1.18rem; }
.pl-minicart__buttons { display: grid; gap: 8px; margin: 0; }
/* Commerce CTA contract — mini-cart Proceed (the canonical .pl-btn--primary already
   carries --pl-radius + the shared elevation + :active press); weight 700 to match the
   rest of the funnel. */
.pl-minicart__checkout { min-height: 50px; font-size: 1.02rem; font-weight: 700; }
.pl-minicart__viewcart { justify-self: center; font-size: .85rem; font-weight: 600; min-height: 44px; display: inline-flex; align-items: center; }
.pl-minicart__ruo { margin: 2px 0 0; font-size: .74rem; line-height: 1.5; color: var(--pl-muted); text-align: center; }

/* Empty */
.pl-minicart__empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; padding: 40px 20px; }
.pl-minicart__empty .pl-empty__icon { color: var(--pl-blue); }

/* ── WooCommerce core neutralizers — SCOPED to the PolarLabs cart drawer ONLY.
   ROOT CAUSE: the drawer's <ul> carries Woo's `cart_list product_list_widget`
   classes and the Remove link carries `remove`, so on a WooCommerce page (where a
   `.woocommerce` ancestor is present) Woo core CSS reaches the drawer and OUT-
   specifies the `.pl-minicart__*` rules above — floating the thumbnail to a 32px
   corner image and turning Remove into a large red `color:red !important` circle.
   FIX: neutralize ONLY inside `.pl-cartdrawer`, with specificity ≥ Woo's; `!important`
   is used ONLY on the single property Woo forces with `!important` (a.remove colour).
   WooCommerce core is NOT dequeued; native markup, AJAX remove, fragments, subtotal,
   coupon and cart maths are all untouched. */
/* (a) Thumbnail — defeat Woo `.woocommerce ul.cart_list li img {float:right;width:32px}`
       (0,2,3) with (0,3,1). No !important. */
.pl-cartdrawer .pl-minicart__list .pl-minicart__thumb img { float: none; margin: 0; width: 100%; height: 100%; max-width: 100%; box-shadow: none; }
/* (b) Row spacing — defeat Woo `.woocommerce ul.cart_list li {padding:4px 0;border-bottom}`
       (0,2,2) with (0,3,0). No !important. */
.pl-cartdrawer .pl-minicart__list .pl-minicart__item { padding: 0; margin: 0; border: 0; }
/* (c) Remove — defeat Woo `.woocommerce a.remove {display:block;font-size:1.5em;
       width/height:1.41em;border-radius:100%;color:red !important}` (0,2,1). The
       geometry is beaten by specificity (0,3,1); the forced red colour is the ONE
       property needing `!important` to defeat Woo's own `!important`. */
.pl-cartdrawer a.remove.pl-minicart__remove { display: inline-flex; align-items: center; width: auto; height: auto; min-height: 44px; padding: 0; font-size: .76rem; font-weight: 600; line-height: 1.4; text-align: right; border: 0; border-radius: 0; background: transparent; color: var(--pl-muted) !important; } /* !important: defeats Woo a.remove{color:red!important} */
.pl-cartdrawer a.remove.pl-minicart__remove:hover,
.pl-cartdrawer a.remove.pl-minicart__remove:focus-visible { color: var(--pl-danger) !important; background: transparent; } /* !important: same Woo !important */
/* (d) Grid-item integrity — RC.6.4. ROOT CAUSE of the broken row: Woo core's legacy
       clearfix `.woocommerce ul.cart_list li::before, …li::after { content:" ";
       display:table }` (0,2,3) generates TWO pseudo-elements that become GRID ITEMS
       inside `.pl-minicart__item { display:grid }`. With 2 real children (thumb, body)
       + 2 pseudo-items auto-flowing into a 2-column grid, they wrapped onto a second
       row — thumbnail centred above the body instead of beside it. Neutralize the
       pseudo-elements (specificity 0,3,1 > Woo's 0,2,3 — no !important) and pin the two
       real children to row 1 so placement is deterministic even if a future pseudo
       reappears. Presentation only: markup, fragments, AJAX remove, subtotal, coupon,
       quantity all untouched. */
.pl-cartdrawer .pl-minicart__list .pl-minicart__item::before,
.pl-cartdrawer .pl-minicart__list .pl-minicart__item::after { content: none; display: none; }
.pl-cartdrawer .pl-minicart__list .pl-minicart__thumb { grid-column: 1; grid-row: 1; }
.pl-cartdrawer .pl-minicart__list .pl-minicart__body { grid-column: 2; grid-row: 1; min-width: 0; }

/* ── Cart-drawer recommendation "You may also need" (RC.6.5) ─────────────────
   One compact product row (thumb | name+price | action), the last item in the scroll
   region. Fail-closed (rendered only when a valid, in-stock, not-in-cart product is
   configured). A quiet top divider separates it from the coupon above; it never looks
   like a full product card and never pushes the pinned subtotal/checkout footer. */
.pl-cartrec { margin-top: 2px; padding-top: 14px; border-top: 1px solid var(--pl-line); }
.pl-cartrec__eyebrow { margin: 0 0 10px; font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--pl-muted); }
.pl-cartrec__row { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 12px; align-items: center; }
.pl-cartrec__thumb { grid-column: 1; grid-row: 1; width: 48px; height: 48px; border-radius: var(--pl-radius-sm); overflow: hidden; background: var(--pl-card-tile); box-shadow: inset 0 0 0 1px var(--pl-line); display: block; }
.pl-cartrec__img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pl-cartrec__placeholder { display: block; width: 100%; height: 100%; }
.pl-cartrec__info { grid-column: 2; grid-row: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-cartrec__name { font-size: .85rem; font-weight: 700; color: var(--pl-navy); line-height: 1.3; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pl-cartrec__name:hover { color: var(--pl-blue); }
.pl-cartrec__price { font-size: .82rem; font-weight: 700; color: var(--pl-navy); }
.pl-cartrec__action { grid-column: 3; grid-row: 1; flex: none; min-height: 40px; padding: 8px 14px; white-space: nowrap; }
/* Suppress Woo's auto-appended "View cart" link after an AJAX add (redundant with the
   footer View cart + the open drawer); the module itself vanishes on the fragment refresh. */
.pl-cartrec .added_to_cart { display: none; }

/* ── PDP mobile sticky purchase bar (RC.6.4) ─────────────────────────────────
   A compact bottom-fixed CTA that MIRRORS the single real WooCommerce add-to-cart
   form and triggers it (built + controlled by theme.js — no second form, no cloned
   select, no separate cart state). Shown ONLY ≤900px, only once the real
   `.pl-pdp-actions` has scrolled above the viewport, and only for a valid purchasable
   selection (theme.js toggles `.is-visible`). Pure progressive enhancement: with no
   JS the in-page form is the only control and this never renders. Sits below the cart
   drawer (1100) and researcher gate (2000); iOS safe-area padded; restrained translate
   that reduced-motion removes. */
.pl-pdp-stickybar {
	position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--pl-z-pdp-sticky);
	display: flex; align-items: center; gap: 12px;
	padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
	background: var(--pl-surface); border-top: 1px solid var(--pl-line);
	box-shadow: 0 -8px 24px rgba(7, 24, 45, .12);
	transform: translateY(110%); transition: transform 200ms var(--pl-ease);
}
.pl-pdp-stickybar.is-visible { transform: translateY(0); }
.pl-pdp-stickybar__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; }
.pl-pdp-stickybar__name { font-size: .8rem; font-weight: 700; color: var(--pl-navy); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-pdp-stickybar__price { font-size: .98rem; font-weight: 800; color: var(--pl-navy); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-pdp-stickybar__price:empty { display: none; }
.pl-pdp-stickybar__btn { flex: 0 0 auto; min-height: 48px; padding-inline: 22px; white-space: nowrap; }
.pl-pdp-stickybar__btn[disabled] { opacity: .55; cursor: not-allowed; box-shadow: none; }
/* Never on wide desktop. */
@media (min-width: 901px) { .pl-pdp-stickybar { display: none !important; } }
/* Kept off-screen behind any open drawer (nav or cart) and behind the researcher gate
   — same signals the theme already uses for scroll-lock. */
html.pl-drawer-open .pl-pdp-stickybar { transform: translateY(110%); }
html:has(body.pl-gate-armed):not(.pl-gate-cleared) .pl-pdp-stickybar { transform: translateY(110%); }
@media (prefers-reduced-motion: reduce) {
	.pl-pdp-stickybar { transition: none; }
}

/* Responsive Woo */
@media (max-width: 900px) {
	.single-product div.product { grid-template-columns: 1fr; }
	.single-product div.product .woocommerce-product-gallery { position: static; }
	.woocommerce-checkout .pl-woo form.checkout { grid-template-columns: 1fr; grid-template-rows: none; }
	.woocommerce-checkout #customer_details,
	.woocommerce-checkout #order_review { position: static; }
	.woocommerce-account .woocommerce { grid-template-columns: 1fr; }
	.woocommerce-account .col2-set { grid-template-columns: 1fr; }
	/* Workstream F — the cart drops to a single column at the SAME 900px as checkout, so both
	   funnel pages behave identically across tablet. This removes the ~768px "crushed items
	   column" (items previously shared the row with the 388px summary rail down to 640px). The
	   .pl-summary also unsticks here since it is no longer beside the items. */
	.pl-cart__layout { grid-template-columns: minmax(0, 1fr); gap: clamp(20px, 3vw, 28px); }
	.pl-summary { position: static; }
}

@media (max-width: 640px) {
	/* Cart rows stack on mobile. The old block here rebuilt core's table.shop_table
	   with grid-areas and ::before pseudo-labels faking the hidden <thead>; the theme
	   now owns cart.php outright, so there is no table to reconstruct. */
	.pl-cartrow { grid-template-columns: 64px minmax(0, 1fr); grid-template-areas: "media info" "qty price"; row-gap: 12px; }
	.pl-cartrow__media { grid-area: media; width: 64px; height: 64px; }
	.pl-cartrow__info { grid-area: info; }
	.pl-cartrow__qty { grid-area: qty; }
	/* The 84px qty input would overflow its 64px mobile track into the price cell;
	   let it size to the track (still >=44px tall, capped at the desktop 84px). */
	.pl-cartrow__qty input.qty { width: 100%; max-width: 84px; }
	.pl-cartrow__price { grid-area: price; }
	.pl-cart__actions { flex-direction: column; align-items: stretch; }
	/* C1.1 — the coupon block must size to its CONTENT height here. Its desktop
	   `flex: 1 1 280px` is a horizontal basis in the row layout, but once
	   .pl-cart__actions becomes a column it was reinterpreted as a ~280px VERTICAL
	   basis — inflating the coupon into a tall tile with a big void above the input.
	   Reset to content height so the input + Apply read as a compact utility control. */
	.pl-cart__coupon { flex: 0 0 auto; }
	/* Keep the coupon input + Apply on one compact row on mobile (don't stack them
	   into two full-width blocks); only the standalone Update cart button is full width. */
	.pl-cart__couponrow .pl-btn { flex: none; }
	.pl-cart__update { width: 100%; }

	/* --- Continue shopping: hide top-right link, show lower full-width button --- */
	.pl-cart-head__continue { display: none; }
	.pl-cart-actions__continue { display: flex; width: 100%; text-align: center; margin: 0; }

	/* Cart-page remove control meets the 44px touch target on mobile. (The drawer's
	   .pl-minicart__remove is now a restrained text link — C1.2 — not this icon box.) */
	.woocommerce-cart td.product-remove a.remove { width: 44px; height: 44px; font-size: 22px; }
	.pl-cart-head { align-items: flex-start; }
}

/* ---- Account responsive ---- */
@media (max-width: 900px) {
	/* Account nav becomes an accessible disclosure: compact toggle + full list. */
	.woocommerce-account .woocommerce { padding-top: 8px; }
	.pl-account-nav-toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 48px; padding: 8px 16px; border: 1px solid var(--pl-line-strong); border-radius: var(--pl-radius); background: var(--pl-surface); cursor: pointer; }
	.woocommerce-account .woocommerce-MyAccount-navigation { margin-bottom: 8px; }
	.woocommerce-account .woocommerce-MyAccount-navigation ul { display: none; margin-top: 8px; }
	.woocommerce-account .woocommerce-MyAccount-navigation ul.is-open { display: grid; }
	/* Welcome heading stays the primary heading; nav reads as secondary chrome. */
	.pl-account__welcome { margin-top: 4px; }
	.woocommerce-customer-details .col2-set, .woocommerce-Addresses.addresses { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
	/* Dashboard recent-order rows stack cleanly */
	.pl-account__order a { grid-template-columns: 1fr auto; grid-auto-rows: auto; row-gap: 4px; }
	.pl-account__orderdate, .pl-account__orderstatus { grid-column: 1; }
	.pl-account__ordertotal { grid-column: 2; grid-row: 1; text-align: right; }
	.pl-account__orderview { grid-column: 2; text-align: right; }
	.pl-account__support { flex-direction: column; align-items: stretch; }
	.pl-account__support .pl-btn { width: 100%; }
	/* Orders + order-details tables become labelled stacked rows */
	.woocommerce-account table.shop_table thead, .woocommerce-table--order-details thead { display: none; }
	.woocommerce-account table.shop_table tr, .woocommerce-table--order-details tr { display: grid; grid-template-columns: 1fr auto; border-bottom: 1px solid var(--pl-line); }
	.woocommerce-account table.shop_table td, .woocommerce-table--order-details td, .woocommerce-table--order-details th { border: 0; padding: 8px 12px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
	.woocommerce-account table.shop_table td::before, .woocommerce-table--order-details td::before { content: attr(data-title); font-weight: 600; color: var(--pl-muted); }
	.woocommerce-orders-table__cell-order-actions { grid-column: 1 / -1; justify-content: flex-start !important; }
}

/* ==========================================================================
   Sale flash + notices (Commit 6)
   ========================================================================== */

/* Sale badge — replaces WooCommerce's default circular "Sale!" bubble.
   Core positions span.onsale absolutely with a negative offset, which is what
   pushed it off the left of the viewport. This sits INSIDE the media container
   (.pl-card__media and .pl-single-media are position:relative) with positive
   offsets, so it cannot escape or clip at any width. Renders only when
   WooCommerce's own is_on_sale() is true — never decorative. */
.pl-sale {
	position: absolute; right: 12px; top: 12px; z-index: var(--pl-z-raised);
	display: inline-flex; align-items: center;
	min-height: 24px; padding: 4px 10px;
	border-radius: var(--pl-radius-pill);
	background: var(--pl-blue); color: #fff;
	font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
	box-shadow: 0 2px 8px rgba(40,120,245,.28);
}
/* Belt and braces: if core's own span.onsale is ever emitted by a plugin path
   that bypasses the template override, neutralise its escaping geometry. */
.woocommerce span.onsale { position: absolute; right: 12px; top: 12px; left: auto; margin: 0; min-height: 24px; min-width: 0; padding: 4px 10px; border-radius: var(--pl-radius-pill); background: var(--pl-blue); line-height: 1.4; font-size: .68rem; }

/* Notices — compact PolarLabs composition, not the default green block. */
.pl-notice {
	display: flex; align-items: flex-start; gap: 10px;
	margin: 0 0 14px; padding: 12px 14px;
	border: 1px solid var(--pl-line); border-left: 3px solid var(--pl-blue);
	border-radius: var(--pl-radius); box-shadow: var(--pl-shadow-sm);
	background: var(--pl-surface); color: var(--pl-navy);
	font-size: .9rem; line-height: 1.5;
	list-style: none;
}
.pl-notice__icon { flex: none; display: inline-flex; margin-top: 1px; }
.pl-notice__msg { min-width: 0; flex: 1; overflow-wrap: break-word; }
/* The View Cart action arrives inside Woo's message string; align it rather than
   letting it stack as a full-width block. */
.pl-notice__msg .button,
.pl-notice__msg .wc-forward {
	display: inline-flex; align-items: center; justify-content: center;
	min-height: 36px; margin-left: 10px; padding: 6px 14px;
	border-radius: var(--pl-radius-pill);
	background: var(--pl-blue); color: #fff; font-weight: 700; font-size: .84rem;
	text-decoration: none; white-space: nowrap;
}
.pl-notice__msg .button:hover, .pl-notice__msg .wc-forward:hover { background: var(--pl-blue-600); color: #fff; }
.pl-notice--success { border-left-color: var(--pl-success); background: var(--pl-success-bg); }
.pl-notice--success .pl-notice__icon { color: var(--pl-success); }
/* Success (add-to-cart): text + View Cart on one row, button pushed to the right. */
.pl-notice--success .pl-notice__msg { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; }
.pl-notice--success .pl-notice__msg .button,
.pl-notice--success .pl-notice__msg .wc-forward { margin-left: auto; }
.pl-notice--error { border-left-color: var(--pl-danger); background: var(--pl-danger-bg); }
.pl-notice--error .pl-notice__icon { color: var(--pl-danger); }
.pl-notice--error li { display: flex; align-items: flex-start; gap: 10px; }
.pl-notice--error li + li { margin-top: 8px; }
.pl-notice--info { border-left-color: var(--pl-blue); background: var(--pl-info-bg); }
.pl-notice--info .pl-notice__icon { color: var(--pl-blue); }

@media (max-width: 480px) {
	/* Let the action wrap under the message rather than squeezing both onto one
	   line at 390px. */
	.pl-notice { flex-wrap: wrap; }
	.pl-notice__msg .button, .pl-notice__msg .wc-forward { margin-left: 0; margin-top: 8px; width: 100%; }
}

/* ==========================================================================
   Checkout CTA — defeat core's purple 'alt' button (Commit 7)
   --------------------------------------------------------------------------
   The purple is NOT a theme colour: grep for a46497 / 7f54b3 across the theme
   returns zero. It is core's woocommerce-general.css painting
       .woocommerce a.button.alt { background-color: #a46497; }   (0,3,1)
   and the theme's own rules were only (0,2,0) / (0,3,0), so they lost outright —
   source order only breaks ties, and this is not a tie. (Same lesson as the
   product-grid reset in section 0.) Core's visual stylesheet is deliberately
   kept, so the fix is to match its specificity rather than dequeue it.
   ========================================================================== */
.woocommerce a.button.alt.checkout-button,
.woocommerce-page a.button.alt.checkout-button,
.woocommerce .wc-proceed-to-checkout a.button.alt,
.woocommerce-page .wc-proceed-to-checkout a.button.alt {
	background-color: var(--pl-blue);
	color: #fff;
	/* Commerce CTA contract — cart Proceed. Was a core Woo button merely recolored blue;
	   now carries the shared funnel spec (radius, weight 700, --pl-cta-shadow, press) so it
	   matches the mini-cart, PDP and checkout primaries. */
	min-height: 52px; border-radius: var(--pl-radius); font-weight: 700;
	box-shadow: var(--pl-cta-shadow);
	transition: background-color var(--pl-dur) var(--pl-ease), transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease);
}
.woocommerce a.button.alt.checkout-button:hover,
.woocommerce-page a.button.alt.checkout-button:hover,
.woocommerce .wc-proceed-to-checkout a.button.alt:hover,
.woocommerce-page .wc-proceed-to-checkout a.button.alt:hover {
	background-color: var(--pl-blue-600);
	color: #fff;
	transform: translateY(-1px);
	box-shadow: var(--pl-cta-shadow-hover);
}
.woocommerce a.button.alt.checkout-button:active,
.woocommerce-page a.button.alt.checkout-button:active,
.woocommerce .wc-proceed-to-checkout a.button.alt:active,
.woocommerce-page .wc-proceed-to-checkout a.button.alt:active {
	transform: translateY(0) scale(.98);
}

/* Same purple, second doorway: the PDP Add-to-Cart button.
   NOTE: core's value has MOVED since the block above was written — the copy
   currently served is #7f54b3, not #a46497. Verified by reading the deployed
   wp-content/plugins/woocommerce/assets/css/woocommerce.css.
   Core paints the DISABLED 'alt' state as
       .woocommerce:where(body:not(.woocommerce-block-theme-has-button-styles))
         button.button.alt.disabled { background-color: #7f54b3 }
   :where() contributes ZERO specificity, so that is effectively (0,4,1) and it
   outranks the theme's (0,3,1) purchase-panel rule — which is why a variable
   product whose variation is not yet resolved renders lavender. The
   single-strength auto-select in theme.js removes that state in practice; this
   keeps the pre-JS paint, and any genuinely unresolved multi-strength product,
   on-brand. Matched at (0,5,1) rather than dequeuing core. */
.woocommerce button.button.alt.single_add_to_cart_button.disabled,
.woocommerce button.button.alt.single_add_to_cart_button.disabled:hover,
.woocommerce button.button.alt.single_add_to_cart_button:disabled,
.woocommerce button.button.alt.single_add_to_cart_button:disabled:hover {
	background-color: var(--pl-line-strong);
	color: var(--pl-navy);
	box-shadow: none;
	transform: none;
	cursor: not-allowed;
}

/* ==========================================================================
   Checkout — review-order table: single-authority note
   --------------------------------------------------------------------------
   review-order.php stays a real <table> on purpose (its hooks are <tr>-context and the
   table IS the update_order_review fragment target). Its card presentation is now owned
   ENTIRELY by the winning "Order review — premium PolarLabs order-summary card" block
   above (.woocommerce-checkout .woocommerce-checkout-review-order-table …).

   The former parallel `.pl-review` block was REMOVED in the commerce-consolidation pass:
   it was permanently overridden on specificity (its 1.15rem order-total never rendered —
   Block A's did), so it was dead / misleading CSS exactly as the Taste review flagged. The
   three behaviours it still owned were consolidated into Block A: the a11y thead-hide, the
   branded 18px shipping radios, and the neutral-shipping tint. The `.pl-review` class stays
   on the table as a harmless styling hook; nothing in CSS or JS references it any more.
   ========================================================================== */

@media (max-width: 900px) {
	/* One column. DOM order IS the reading order: customer details, then summary,
	   payment and confirmations. No visual reordering. */
	.pl-checkout__grid { grid-template-columns: minmax(0, 1fr); }
	.woocommerce-checkout #order_review { position: static; }
}

/* ==========================================================================
   Product page (PDP) rich sections — DESIGNED MODULES (Phase-3 slice-4 rebuild).
   Reference-led: each section is a designed header (icon tile + title + subtitle)
   over content cards — never thin-line label lists. All rules are .pl-pdp-*
   namespaced; never touch .pl-card/.pl-fcard/.pl-scard/.pl-productgrid,
   cart/checkout/account, the homepage, or main.css.
   ========================================================================== */
.pl-pdp { display: block; }
.pl-pdp.pl-container { padding-top: clamp(8px, 2vw, 20px); padding-bottom: clamp(48px, 7vw, 88px); }

/* Section rhythm: generous vertical gaps + surface/depth separation, no 1px rules. */
.pl-pdp-section { margin-top: clamp(48px, 7vw, 92px); }
.pl-pdp-section:first-child { margin-top: clamp(36px, 5vw, 64px); }

/* Designed section header — small rounded icon tile + strong title + subtitle. */
.pl-pdp-shead { display: flex; align-items: flex-start; gap: 14px; margin: 0 0 clamp(16px, 2.2vw, 26px); }
.pl-pdp-shead__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 14px; background: var(--pl-blue-050); color: var(--pl-blue); box-shadow: inset 0 0 0 1px #D6E6FE; }
.pl-pdp-shead__text { min-width: 0; padding-top: 2px; }
.pl-pdp-shead__title { margin: 0; font-size: clamp(1.4rem, 1.08rem + 1.1vw, 2rem); line-height: 1.15; color: var(--pl-navy); }
.pl-pdp-shead__sub { margin: 5px 0 0; color: var(--pl-muted); font-size: clamp(.95rem, .9rem + .2vw, 1.05rem); }

/* Content card module — the base surface for every rich section. */
.pl-pdp-card { background: var(--pl-surface); border: 1px solid var(--pl-line); border-radius: clamp(16px, 1.6vw, 22px); padding: clamp(18px, 2.6vw, 32px); box-shadow: var(--pl-shadow-sm); }
.pl-pdp-card__source { margin: 12px 2px 0; color: var(--pl-muted); font-size: .88rem; }
.pl-pdp-card__source a { color: var(--pl-link); }

/* Definition lists — soft divided rows inside cards, not hard table lines. */
.pl-pdp-deflist { margin: 0; display: grid; gap: 0; }
.pl-pdp-deflist__row { display: grid; grid-template-columns: minmax(0, 200px) minmax(0, 1fr); gap: 6px 20px; padding: 13px 0; border-top: 1px solid var(--pl-surface-3); }
.pl-pdp-deflist__row:first-child { border-top: 0; padding-top: 2px; }
.pl-pdp-deflist dt { color: var(--pl-muted); font-weight: 600; margin: 0; }
.pl-pdp-deflist dd { margin: 0; color: var(--pl-navy); font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.pl-pdp-molecular__value { font-variant-numeric: tabular-nums; }

/* CARD variant — roomier label/value rows (molecular, COA). */
.pl-pdp-deflist--card .pl-pdp-deflist__row { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); gap: 6px 24px; padding: 15px 0; }
/* Molecular Profile — dense two-column spec grid on desktop (short values
   right-aligned within each column; long identifiers span the full width). This
   fills the card without a wide label→value gap. */
@media (min-width: 760px) {
	.pl-pdp-molecular .pl-pdp-deflist--card:not(.pl-pdp-deflist--compact) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(36px, 4.5vw, 64px); }
	.pl-pdp-molecular .pl-pdp-deflist--card:not(.pl-pdp-deflist--compact) .pl-pdp-deflist__row { grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; }
	.pl-pdp-molecular .pl-pdp-deflist--card:not(.pl-pdp-deflist--compact) dd { text-align: right; }
	.pl-pdp-molecular .pl-pdp-deflist--card:not(.pl-pdp-deflist--compact) .pl-pdp-deflist__row:first-child,
	.pl-pdp-molecular .pl-pdp-deflist--card:not(.pl-pdp-deflist--compact) .pl-pdp-deflist__row:nth-child(2) { border-top: 0; padding-top: 2px; }
	.pl-pdp-molecular .pl-pdp-deflist__row--wide { grid-column: 1 / -1; grid-template-columns: minmax(0, 210px) minmax(0, 1fr); }
	.pl-pdp-molecular .pl-pdp-deflist__row--wide dd { text-align: left; }
}

/* COLS variant — two-up identity grid on wider cards (compound information). */
.pl-pdp-deflist--cols { display: grid; grid-template-columns: 1fr; gap: 0 clamp(24px, 3vw, 44px); }
@media (min-width: 680px) {
	.pl-pdp-deflist--cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.pl-pdp-deflist--cols .pl-pdp-deflist__row:nth-child(2) { border-top: 0; padding-top: 2px; }
}
@media (max-width: 560px) { .pl-pdp-deflist__row, .pl-pdp-deflist--card .pl-pdp-deflist__row { grid-template-columns: 1fr; gap: 3px; } }

/* Compound information card content. */
.pl-pdp-profile__summary { color: var(--pl-navy); font-size: 1.02rem; line-height: 1.65; margin: 0 0 clamp(16px, 2vw, 22px); max-width: 72ch; }
.pl-pdp-profile__aliases { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin: clamp(16px, 2vw, 20px) 0 0; padding-top: clamp(16px, 2vw, 20px); border-top: 1px solid var(--pl-surface-3); }
.pl-pdp-profile__aliases-label { color: var(--pl-muted); font-weight: 600; font-size: .9rem; }
.pl-pdp-aliases { display: flex; flex-wrap: wrap; gap: 8px; }
.pl-pdp-alias { display: inline-flex; align-items: center; padding: 4px 12px; border-radius: var(--pl-radius-pill); background: var(--pl-blue-050); color: var(--pl-navy-700); font-size: .85rem; font-weight: 600; }

/* Research context — readable article card. */
.pl-pdp-research__card { display: block; }
.pl-pdp-research__evidence { display: inline-block; margin: 0 0 12px; padding: 3px 12px; border-radius: var(--pl-radius-pill); background: var(--pl-blue-050); color: var(--pl-blue-600); font-weight: 600; font-size: .82rem; }
.pl-pdp-research__body { color: var(--pl-navy); line-height: 1.7; max-width: 72ch; }
.pl-pdp-research__body h3 { font-size: 1.08rem; margin: 18px 0 6px; }
.pl-pdp-research__body p { margin: 0 0 12px; }
.pl-pdp-research__disclaimer { color: var(--pl-muted-soft); font-size: .85rem; margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--pl-surface-3); }

/* Certificate of Analysis — premium documentation card. */
.pl-pdp-coa__card { border-color: var(--pl-info-border); box-shadow: 0 10px 30px rgba(40,120,245,.08); }
.pl-pdp-coa__block { margin-top: clamp(16px, 2.2vw, 22px); padding-top: clamp(16px, 2.2vw, 22px); border-top: 1px solid var(--pl-surface-3); }
.pl-pdp-coa__block-title { display: block; font-weight: 700; color: var(--pl-navy); margin: 0 0 10px; }
.pl-pdp-coa__methods { margin: 0; padding-left: 18px; color: var(--pl-navy); display: grid; gap: 6px; }
.pl-pdp-coa__cta { margin-top: clamp(18px, 2.4vw, 24px); }
@media (min-width: 420px) { .pl-pdp-coa__cta { min-width: 220px; } }

/* Sources and references — source cards. */
.pl-pdp-references__grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 680px) { .pl-pdp-references__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pl-pdp-refcard { display: flex; flex-direction: column; gap: 8px; }
.pl-pdp-refcard__journal { color: var(--pl-blue); font-weight: 700; font-size: .82rem; letter-spacing: .06em; text-transform: uppercase; }
.pl-pdp-refcard__title { margin: 0; font-size: 1.02rem; font-weight: 700; line-height: 1.35; color: var(--pl-navy); overflow-wrap: anywhere; }
.pl-pdp-refcard__meta { margin: 0; color: var(--pl-muted); font-size: .9rem; }
.pl-pdp-refcard__id { margin: 0; color: var(--pl-muted-soft); font-size: .82rem; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pl-pdp-refcard__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: auto; padding-top: 12px; }
.pl-pdp-reference__evidence { display: inline-flex; align-items: center; padding: 3px 11px; border-radius: var(--pl-radius-pill); background: var(--pl-surface-3); color: var(--pl-navy-700); font-size: .82rem; font-weight: 600; }
.pl-pdp-reference__link { color: var(--pl-link); font-weight: 600; font-size: .9rem; }

/* Research use notice — large rounded panel. */
/* CONDENSED to a compact band. Measured at 390 the notice panel was 423px — the
   single largest block on the lower page, larger than the Product Information
   card it sat beneath. The approved wording is UNCHANGED (it comes from
   polarlabs_research_notice()) and the purchase-panel RUO line is untouched;
   only the presentation is tightened so a disclaimer stops out-ranking the
   product. Radius pulled onto the shared --pl-radius-lg rather than its own
   clamp, which was one of four competing radii on the page. */
.pl-pdp-notice__panel { display: flex; align-items: flex-start; gap: 14px; padding: clamp(16px, 2vw, 20px); border-radius: var(--pl-radius-lg); background: var(--pl-surface-2); border: 1px solid var(--pl-line); }
.pl-pdp-notice__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 14px; background: var(--pl-blue-050); color: var(--pl-blue); box-shadow: inset 0 0 0 1px #D6E6FE; }
.pl-pdp-notice__body { min-width: 0; }
.pl-pdp-notice__title { margin: 0 0 4px; font-size: 1rem; font-weight: 700; color: var(--pl-navy); }
.pl-pdp-notice__text { margin: 0 0 6px; color: var(--pl-muted); font-size: .9rem; line-height: 1.55; max-width: 76ch; }
.pl-pdp-notice__link { margin: 0; }
.pl-pdp-notice__link a { color: var(--pl-link); font-weight: 600; }

/* ── PDP "Researchers also added" (RC.6.5) ───────────────────────────────────
   A FIXED, compact grid — no swipe rail, no scroll-snap, no overflow-x (the old
   .pl-pdp-related scroll-snap rail was removed). A restrained eyebrow + H2 header
   keeps the section clearly secondary to the purchase area. Cards are the scoped
   compact .pl-reccard (NOT the Shop .pl-scard, which is untouched). */
.pl-pdp-recs__head { margin: 0 0 clamp(14px, 2.2vw, 22px); }
.pl-pdp-recs__eyebrow { margin: 0 0 6px; font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--pl-link); }
.pl-pdp-recs__title { margin: 0; font-size: clamp(1.3rem, 1.05rem + 1vw, 1.7rem); line-height: 1.15; letter-spacing: -.01em; color: var(--pl-navy); }

/* Fixed grid: 2 cols on phones/narrow tablet, 3 mid, up to 4 on desktop. */
.pl-recgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
/* DR-091 PDP layout wrapper: 1 column at 320/360px, 2 columns at 390/430px, 3 columns
   tablet/desktop (the rail caps at 3 products). The shared .pl-scard card is unchanged. */
@media (max-width: 380px) { .pl-recgrid { grid-template-columns: 1fr; } }
@media (min-width: 720px) { .pl-recgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; } }
@media (min-width: 1024px) { .pl-recgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; } }

/* Compact add-on card — one quiet border, compact square media, tight body. */
/* Commerce-consolidation — the compact rec card now shares the .pl-scard shell contract:
   same --pl-radius-lg, same hover lift + shadow + image zoom, same contained-on-tile media,
   and the same name>=price hierarchy. It differs only in scale/density (a smaller add-on
   card) and in its lighter outline CTA — a functional distinction ("Add" vs the archive's
   "View product"), not a stylistic drift. */
.pl-reccard { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); background: var(--pl-surface); overflow: hidden;
	transition: transform var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease), border-color var(--pl-dur) var(--pl-ease); }
.pl-reccard:hover { transform: translateY(-2px); box-shadow: var(--pl-shadow-sm); border-color: var(--pl-line-strong); }
/* RC.6.10.1 hotfix — same edge-to-edge restoration as .pl-scard (compact dimensions kept):
   the studio-background photo fills the media via cover; tile shows only behind placeholders. */
.pl-reccard__media { aspect-ratio: 1 / 1; background: var(--pl-card-tile); display: flex; align-items: center; justify-content: center; overflow: hidden; padding: 0; }
.pl-reccard__img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; transition: transform var(--pl-dur) var(--pl-ease); }
.pl-reccard:hover .pl-reccard__img { transform: scale(1.02); }
@media (hover: none) {
	.pl-reccard:hover { transform: none; box-shadow: none; }
	.pl-reccard:hover .pl-reccard__img { transform: none; }
}
.pl-reccard__placeholder { display: inline-flex; color: var(--pl-icy-200); }
.pl-reccard__body { display: flex; flex-direction: column; gap: 6px; padding: 10px 10px 12px; min-width: 0; }
.pl-reccard__name { margin: 0; font-size: .92rem; font-weight: 700; line-height: 1.25; }
.pl-reccard__name a { color: var(--pl-navy); overflow-wrap: anywhere; }
.pl-reccard__name a:hover { color: var(--pl-blue); }
.pl-reccard__price { font-size: .84rem; font-weight: 700; color: var(--pl-navy); }
.pl-reccard__price del { color: var(--pl-muted-soft); font-weight: 600; font-size: .85em; }
.pl-reccard__price ins { text-decoration: none; }
.pl-reccard__action { margin-top: 2px; width: 100%; justify-content: center; min-height: 44px; padding: 8px 10px; font-size: .82rem; }
/* Woo auto-appends a redundant "View cart" link after a successful AJAX add — the drawer
   (RC.6.4) + footer already provide that, and a compact card carries a single action. */
.pl-reccard .added_to_cart { display: none; }

/* COA public index + viewer — STRUCTURAL only (Phase-3 slice 2). */
/* (Old .pl-coa-index / .pl-coa-card grid superseded by the COA library system at
   the end of this file — Phase A. The viewer rules below are retained.) */
/* Certificate viewer — same COA system: breadcrumb strip + compact navy hero +
   premium metadata card (reuses .pl-pdp-card / .pl-pdp-coa__block). */
.pl-coa-viewer { display: block; }
.pl-coa-viewer__crumbs { padding-top: clamp(12px, 2vw, 18px); }
.pl-coa-viewer__breadcrumb { color: var(--pl-muted); font-size: .85rem; }
.pl-coa-viewer__breadcrumb a { color: var(--pl-link); }
.pl-coa-hero--compact .pl-coa-hero__inner { min-height: clamp(150px, 22vw, 240px); padding-block: clamp(28px, 4.5vw, 52px); }
.pl-coa-viewer__body { max-width: 860px; margin-inline: auto; padding-block: clamp(24px, 3.5vw, 40px); }
.pl-coa-viewer__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: clamp(18px, 2.4vw, 24px); }
.pl-coa-viewer__actions .pl-btn { min-height: 48px; }
.pl-coa-viewer__back { margin: clamp(16px, 2.4vw, 22px) 0 0; }
.pl-coa-viewer__back a { color: var(--pl-link); font-weight: 600; }
.screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ==========================================================================
   PDP interaction controls — Strength radiogroup + quantity stepper. Larger,
   confident touch targets (Strength ~54px, quantity ~54px).
   ========================================================================== */
/* Visually-hidden native <select> once theme.js has built the strength radiogroup.
   This was the ENTIRE desktop horizontal overflow. Measured live on staging: the
   "hidden" select computed to 1425x50, absolutely positioned at full viewport
   width, pushing documentElement.scrollWidth to 2231 against a 1440 viewport
   (791px of overflow). Only clip-path survived, so it was invisible but still
   occupied a box. Mobile never showed it because the same width still fits 390/430.

   Every declaration except the !important position was being outranked, by two
   different rules, and raising selector specificity cannot win:
     .pl-pdp .variations select                      width:100%     (0,2,1)
     .single-product .variations select              padding/border (0,2,1)
     .woocommerce div.product form.cart
       .variations select                            MIN-WIDTH:75%  (0,4,3)  <- core
   min-width beats width, so even at width:1px the box floors at 75% of its
   containing block — which, being absolutely positioned with no positioned
   ancestor, is the viewport. That is where 1068.75px (= 75% of 1425) came from.

   !important is correct here rather than lazy: this is a visually-hidden utility
   whose whole contract is to leave the visual flow unconditionally, the rule
   already establishes that with `position: absolute !important`, and the theme's
   own .screen-reader-text uses the same pattern. min-width/max-width are the two
   properties the original rule never defended and are the actual fix.

   The element stays in the DOM, keeps its value, stays WooCommerce's source of
   truth, and remains reachable by theme.js — only its box collapses. */
.pl-pdp-native-select--enhanced {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	min-width: 0 !important;
	max-width: none !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden !important;
	border: 0 !important;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}
/* Strength — full-width option ROWS (EON-direction), not pills. Label left,
   real variation price right for purchasable options, "Coming soon" right for
   approved-but-unavailable ones. Prices come from WooCommerce's own
   data-product_variations payload; nothing is computed, per-mg'd or discounted. */
.pl-pdp-strength { margin: 0 0 18px; } /* DR-PDP-CONTACT-003: tighter link to the price/qty/ATC cluster. */
.pl-pdp-strength__label { display: block; font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--pl-muted); margin-bottom: 12px; }
.pl-pdp-strength__options { display: flex; flex-direction: column; gap: 10px; }

/* Option card. Deliberately NOT a form row: 2px border so the selected state has
   somewhere to go without the card resizing, generous 18/20 padding, and the
   value set in the price's tabular figures so the right column stays aligned
   across rows. */
.pl-pdp-strength__option {
	display: flex; align-items: center; justify-content: space-between; gap: 14px;
	width: 100%; min-height: 62px; padding: 14px 18px;
	border-radius: 14px; border: 2px solid var(--pl-line); background: var(--pl-surface);
	color: var(--pl-navy); text-align: left; cursor: pointer;
	transition: border-color var(--pl-dur) var(--pl-ease), background var(--pl-dur) var(--pl-ease), box-shadow var(--pl-dur) var(--pl-ease);
}
.pl-pdp-strength__val { font-weight: 700; font-size: 1.02rem; letter-spacing: -.01em; }
.pl-pdp-strength__meta { font-weight: 700; font-size: 1rem; color: var(--pl-navy); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Sale prices render WooCommerce's own <del>/<ins> — core's markup, restyled to
   sit in a 62px card rather than reinterpreted. The struck original is muted and
   a size down; the active price keeps full weight. WooCommerce also emits
   .screen-reader-text ("Original price was…") inside this markup, which must stay
   readable to AT but must not be laid out in the card. */
.pl-pdp-strength__meta del { margin-right: 6px; color: var(--pl-muted-soft); font-weight: 600; font-size: .86em; text-decoration: line-through; }
.pl-pdp-strength__meta ins { text-decoration: none; color: var(--pl-navy); font-weight: 700; }
.pl-pdp-strength__meta .screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.pl-pdp-strength__option:hover:not(:disabled) { border-color: var(--pl-blue); background: var(--pl-blue-050); }
/* Selected — icy surface, royal-blue edge, navy text, soft outward glow. */
.pl-pdp-strength__option.is-selected {
	border-color: var(--pl-blue); background: var(--pl-blue-050); color: var(--pl-navy);
	box-shadow: 0 0 0 4px rgba(40,120,245,.12), 0 6px 18px rgba(40,120,245,.14);
}
.pl-pdp-strength__option.is-selected .pl-pdp-strength__meta { color: var(--pl-navy); }
.pl-pdp-strength__option:focus-visible { outline: none; box-shadow: var(--pl-ring); }
/* Approved strength with no purchasable variation yet — visible, inert, honest.
   Explicit muted token instead of opacity: 50% navy on white lands ~4.6:1, too
   close to the AA floor to rely on; --pl-muted on --pl-surface-2 measures 7.5:1.
   Three non-colour cues carry the state as well: dashed vs solid border, frost
   vs white fill, and aria-disabled + an "N mg — Coming soon" aria-label. */
/* Unavailable — polished, not damaged. Solid icy surface and a soft border (the
   dashed edge read as broken rather than pending), muted navy label, and the
   status set as a real pill on the right instead of loose grey text. Contrast:
   --pl-muted on --pl-surface-2 measures 7.5:1. */
.pl-pdp-strength__option[aria-disabled="true"], .pl-pdp-strength__option:disabled {
	opacity: 1; cursor: not-allowed;
	color: var(--pl-muted); background: var(--pl-surface-2); border-color: var(--pl-line); box-shadow: none;
}
.pl-pdp-strength__option:disabled .pl-pdp-strength__val { color: var(--pl-muted); font-weight: 600; }
.pl-pdp-strength__option:disabled .pl-pdp-strength__meta {
	flex: 0 0 auto; padding: 5px 11px; border-radius: 999px;
	background: var(--pl-surface); border: 1px solid var(--pl-line);
	color: var(--pl-muted); font-size: .76rem; font-weight: 700;
	letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}
.pl-pdp-strength__more { margin: 12px 0 0; font-size: .84rem; line-height: 1.5; color: var(--pl-muted); }

.pl-qty { display: inline-flex; align-items: stretch; height: 54px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); overflow: hidden; background: var(--pl-surface); }
.pl-qty input.qty { width: 60px; text-align: center; border: 0; border-left: 1px solid var(--pl-line); border-right: 1px solid var(--pl-line); font-size: 1rem; font-weight: 700; color: var(--pl-navy); background: var(--pl-surface); -moz-appearance: textfield; }
.pl-qty input.qty::-webkit-outer-spin-button, .pl-qty input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pl-qty__btn { display: inline-flex; align-items: center; justify-content: center; width: 52px; border: 0; background: var(--pl-surface); color: var(--pl-navy); font-size: 1.35rem; line-height: 1; cursor: pointer; }
.pl-qty__btn:hover:not(:disabled) { background: var(--pl-icy); }
.pl-qty__btn:focus-visible { outline: none; box-shadow: var(--pl-ring); }
.pl-qty__btn:disabled { opacity: .4; cursor: not-allowed; }

/* ==========================================================================
   PDP hero (above the fold) — gallery + purchase summary. Namespaced .pl-pdp* /
   .single-product only — never touches product grids, cart/checkout, or main.css.
   ========================================================================== */
/* RC.6.1 — one centered, compact commerce module. Both tracks are explicitly
   bounded (no unrestricted 1fr: the summary can no longer sprawl toward the viewport
   edge) and justify-content:center keeps media + purchase balanced and centered
   inside the .pl-woo container. Module max = 480 + ~40 (clamped column-gap) + 540 ≈ 1060px
   (DR-PDP-CONTACT-003 retuned the tracks 500->480 / 520->540); below that the
   minmax tracks share the available width evenly. Collapses to one column at <=900
   (see the media query below). */
/* RC.6.5 — split gap: column-gap tightened moderately (desktop media↔summary), and a
   lower row-gap floor so the title sits closer beneath the image on mobile (where the
   grid stacks to one column). Not cramped: the lower sections still carry their own
   section margin-top. */
/* DR-PDP-CONTACT-003 — desktop column balance: give the purchase column a little more
   readable width (520 -> 540) and trim the media track a touch (500 -> 480) so the two
   columns feel better balanced; the image stays prominent. PDP-scoped only — the global
   --pl-container and page gutter are unchanged. */
.single-product div.product.pl-pdp { grid-template-columns: minmax(0, 480px) minmax(0, 540px); column-gap: clamp(30px, 2.6vw, 40px); row-gap: clamp(30px, 4.5vw, 44px); align-items: start; justify-content: center; }
@media (max-width: 900px) {
	.single-product div.product.pl-pdp { row-gap: clamp(16px, 4vw, 24px); }
}

/* GRID DEFECT FIX. woocommerce_after_single_product_summary renders INSIDE
   div.product, so the entire below-product wrapper became a THIRD grid item and
   landed in column 1 — measured at 1440: media 742 / summary 297 / lower wrapper
   742 at left 0, i.e. the whole research profile, documentation, notice and
   related rail squeezed under the media column at 662px wide. Span both tracks
   so the lower sections flow beneath the hero at the hero's own centered module
   width — the bounded, justify-content:center grid above spans this 1/-1 track group
   (not the full container), so the whole PDP reads as one aligned column. padding-inline:0
   (RC.6.1) because the lower sections now sit inside the outer .pl-woo container,
   which already supplies the page gutter — keeping .pl-container's own gutter here
   would double it (and shift the related rail's -gutter full-bleed margin off the
   viewport edge on mobile). */
.single-product div.product.pl-pdp > .pl-container { grid-column: 1 / -1; width: 100%; max-width: none; padding-inline: 0; }

/* Summary must FILL its track. Core sets div.summary { float: right; width: 48% }
   at (0,3,2), which inside a 618px grid column resolved to exactly 297px — the
   48% measured live. Matched at (0,4,1); float is meaningless on a grid item. */
.single-product div.product.pl-pdp > .summary { width: 100%; max-width: none; float: none; }

/* Breadcrumb — capped to the hero module width (media 480 + gap + summary 540, the
   DR-PDP-CONTACT-003 tracks) so its left edge aligns with the centered commerce module
   below (RC.6.1), rather than sitting ~90px wider on the full 1248 page container.
   Keep this calc() in lockstep with the .pl-pdp grid-template-columns above. */
.pl-product-breadcrumb { padding-top: clamp(12px, 2vw, 20px); max-width: calc(480px + 540px + 48px + var(--pl-gutter) * 2); }
.pl-breadcrumb { color: var(--pl-muted); font-size: .85rem; }
.pl-breadcrumb a { color: var(--pl-link); }
/* Per-crumb spans come from WooCommerce's own before/after args (DR-PDP-CONTACT-005 — no
   HTML is parsed). The separator is drawn by CSS so it belongs to its crumb and hides
   with it; the current page is the last, link-less .pl-crumb. */
.pl-breadcrumb .pl-crumb { display: inline; }
.pl-breadcrumb .pl-crumb:not(:first-child)::before { content: "/"; margin: 0 .5ch; color: var(--pl-muted); }

/* Gallery — large product visible, object-fit:contain, icy surface. rc.6: media
   scrolls in normal document flow (sticky/follow-scroll removed per owner). */
.pl-single-media.pl-pdp-gallery { position: static; }
/* RC.6.1 — neutralize WooCommerce core's div.images sizing. The gallery element
   carries the `images` class, so core's `.woocommerce div.product div.images
   { float:left; width:48% }` (woocommerce-layout.css, specificity 0,3,2) shrank it
   to 48% of the 500px media track (~240px, rendering the image at only ~206px).
   This (0,4,1) rule, loaded after core, restores the gallery to the full media
   frame so the product fills its track. */
.single-product div.product.pl-pdp .woocommerce-product-gallery { float: none; width: 100%; max-width: none; }
/* RC.6.5/6.6 — ONE continuous rounded media surface. The wrapper owns the ONLY visible
   border + radius, and overflow:hidden clips the image (and its baked background) to the
   SAME rounded rect, so no square corners appear inside. Quiet frost fill (--pl-surface-2,
   near-white) shows only where a transparent/letterboxed image does not cover it. Softer
   continuous radius (--pl-radius-media). One hairline border, no shadow, no nested panel. */
.pl-pdp-gallery .woocommerce-product-gallery__wrapper { border-radius: var(--pl-radius-media); overflow: hidden; border: 1px solid var(--pl-line); background: var(--pl-surface-2); }
/* MEDIA SURFACE (RC.6.6). One SQUARE (1:1) panel at every breakpoint with NO inner
   padding, so the square product photo fills the rounded surface edge-to-edge and its
   corners clip to the wrapper radius — no padding gap, no square inset, no frame-inside-
   frame. The previous 4:3 mobile panel letterboxed the square image (side frost bars)
   and read as a square-inside-a-frame; RC.6.6 supersedes that below-fold relief because
   the RC.6.4 mobile sticky Add-to-Cart bar now provides the purchase control on scroll.
   object-fit:contain still guarantees the vial is never cropped (non-square images
   letterbox onto the quiet frost surface). */
.pl-pdp-gallery .woocommerce-product-gallery__image { aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; padding: 0; margin: 0; }
/* rc.6 mobile hero type-floors were declared here but were DEAD — overridden by the
   later, equal-specificity base .product_title/.price/.pl-pdp-summary__desc rules below
   (so the mobile H1 rendered at the full 32px). Removed in DR-PDP-CONTACT-003; the
   effective mobile density rules now live in one block AFTER those base declarations
   (search "DR-PDP-CONTACT-003 — mobile PDP density"). */
.pl-pdp-gallery .woocommerce-product-gallery__image a { display: block; width: 100%; height: 100%; }
/* Fill the panel (so a square photo's baked background becomes the continuous rounded
   surface) while object-fit:contain preserves aspect + never crops the vial. */
.pl-pdp-gallery .woocommerce-product-gallery__image img { display: block; width: 100%; height: 100%; object-fit: contain; margin: 0; }
.pl-pdp-gallery .flex-control-thumbs { list-style: none; display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 0; padding: 0; }
.pl-pdp-gallery .flex-control-thumbs li { flex: 0 0 auto; }
.pl-pdp-gallery .flex-control-thumbs img { width: 72px; height: 72px; object-fit: contain; padding: 8px; background: var(--pl-icy); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-sm); cursor: pointer; }
.pl-pdp-gallery .flex-control-thumbs img.flex-active, .pl-pdp-gallery .flex-control-thumbs img:focus-visible { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
.pl-single-media__placeholder { border-radius: var(--pl-radius-media); }

/* Purchase summary — category · title · code · aliases · summary · price · stock ·
   [native controls + add-to-cart + View COA] · RUO. */
.pl-pdp-summary__category { font-size: .78rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--pl-blue); margin: 0 0 10px; }
.single-product.pl-pdp .product_title, .pl-pdp .product_title { font-size: clamp(2rem, 1.4rem + 2.4vw, 3.35rem); line-height: 1.08; letter-spacing: -.02em; margin: 0 0 8px; }
.pl-pdp-summary__code { margin: 0 0 12px; color: var(--pl-muted); font-weight: 600; font-size: 1rem; font-variant-numeric: tabular-nums; }
.pl-pdp-summary__aliases { margin: 0 0 16px; }
.pl-pdp-summary__desc { color: var(--pl-muted); font-size: 1.02rem; line-height: 1.65; margin: 0 0 20px; max-width: 56ch; }
/* RC.6.8 — real WooCommerce short description in the PDP summary (after price, before
   the purchase form). Calm neutral body copy on a restrained measure; part of the
   summary flow, never a nested card or pill. .pl-prose keeps inline links/emphasis. */
.pl-pdp-shortdesc { margin: 6px 0 20px; max-width: 52ch; }
.pl-pdp-shortdesc.pl-prose p, .pl-pdp-shortdesc.pl-prose li { color: var(--pl-muted); line-height: 1.62; }
.pl-pdp-shortdesc.pl-prose p { margin: 0 0 .6em; }
.pl-pdp-shortdesc.pl-prose p:last-child { margin-bottom: 0; }
/* RC.6.8 — "Product overview" (real Woo long description) uses the lower-PDP card
   language (.pl-pdp-section / .pl-pdp-card), full-width like the sibling Storage/COA
   cards. .pl-prose caps at 72ch by default, which would leave this card narrow next to
   the full-width Storage card — reset the card to full width and cap the reading
   measure on the inner prose blocks instead. */
.pl-pdp-overview__card { max-width: none; }
.pl-pdp-overview__card > * { max-width: 74ch; }
.pl-pdp-overview__card > :first-child { margin-top: 0; }
.pl-pdp-overview__card > :last-child { margin-bottom: 0; }
@media (max-width: 640px) {
	.pl-pdp-shortdesc.pl-prose p, .pl-pdp-shortdesc.pl-prose li { font-size: .96rem; }
}
.pl-pdp .price, .single-product.pl-pdp .price { font-size: clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem); font-weight: 800; color: var(--pl-navy); line-height: 1.1; margin: 0 0 12px; }
.pl-pdp .price del { color: var(--pl-muted-soft); font-weight: 600; font-size: .62em; }
.pl-pdp .price ins { text-decoration: none; }
.pl-pdp .price--pending { color: var(--pl-muted); font-weight: 700; }
/* Variable products: before a variation is chosen the WooCommerce range ("From")
   price shows normally; once theme.js confirms a COMPLETE variation, the product
   root gets .pl-pdp--variation-selected and the range price is hidden so only the
   exact variation price remains. Restored on reset. A JS state class (not :has())
   drives this for reliable, widely-supported behaviour; the native WooCommerce
   variation price markup and screen-reader semantics are untouched. */
.pl-pdp--variation-selected .entry-summary > p.price,
.pl-pdp--variation-selected .summary > p.price { display: none; }

/* One price in the purchase flow, not two. When the variation carries its own
   price the strength card is already showing it, so WooCommerce's copy below the
   cards is a duplicate — suppressed visually only. When the variation has NO
   price of its own the class is absent, the range price above stays visible, and
   this rule does nothing: the "no visible price" state cannot recur from here.
   Kept in the DOM and out of `hidden`/`display:none` on the wrapper so the
   aria-live region WooCommerce updates still announces variation changes. */
.pl-pdp--variation-selected .single_variation .woocommerce-variation-price { display: none; }
/* Stock is stated once near the title by the .pl-single-stock pill, which
   DR-PDP-STOCK-STATE-002 keeps in step with the selected variation (see
   initPdpStockPillSync in theme.js). The native per-variation availability is
   therefore a VISUAL duplicate on the PolarLabs PDP — and its former in-stock-only
   hide let an out-of-stock variation's native "Out of stock" sit beneath a stale
   parent "In stock" pill.
   Gated on .pl-pdp--stock-synced (added by the script ONLY once the variation-aware
   pill is genuinely active): so if the script never runs or bails — no jQuery, a
   stale full-page cache without the label attrs, JS disabled — this rule never
   applies and WooCommerce's own availability line stays visible as the accurate
   fallback (true progressive enhancement, never a variation with no stock cue).
   When active it is hidden visually but kept in the accessibility tree (deliberately
   NOT display:none): assistive tech still reads the accurate per-variation
   availability at the control (native-WooCommerce parity), the pill carries the same
   state near the title, and the Specifications aria-live sync — which now mirrors the
   pill's own resolved wording — remains the single announcer, so there is no visual
   contradiction and no duplicate announcement. */
.pl-pdp--stock-synced .single_variation .woocommerce-variation-availability {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}
/* Reclaim the dead band the emptied wrapper leaves between cards and quantity. */
.pl-pdp .single_variation_wrap { margin-top: 0; }
.pl-pdp .single_variation:empty { display: none; }
.pl-pdp--variation-selected .single_variation { margin: 0; }

/* Single purchasable strength — drop WooCommerce's "Clear". PDP-scoped and
   count-derived; multi-strength products keep it.
   !important is required, not preference: add-to-cart-variation.js writes the
   link's visibility through jQuery, leaving an INLINE
   `visibility: visible; display: inline; opacity: 0` on the element, and an
   inline style outranks any stylesheet rule that is not !important. Measured on
   the element before this rule existed. */
.pl-pdp--single-strength .variations .reset_variations,
.pl-pdp--single-strength a.reset_variations { display: none !important; }

/* Price colour — third instance of the same core-specificity trap as the purple
   'alt' button and the min-width select. The olive is not a theme colour: it is
   core's --wc-highlight #958e09, painted by
     .woocommerce:where(body:not(.woocommerce-uses-block-theme)) div.product p.price
   at an effective (0,3,2). The theme's own `.single-product.pl-pdp .price` is
   (0,3,0) and lost outright. Matched at (0,4,2) on the PDP root only, so shop /
   archive / cart pricing is untouched. */
.woocommerce div.product.pl-pdp p.price,
.woocommerce div.product.pl-pdp p.price .amount,
.woocommerce div.product.pl-pdp .woocommerce-variation-price .price,
.woocommerce div.product.pl-pdp .woocommerce-variation-price .amount { color: var(--pl-navy); }
.woocommerce div.product.pl-pdp p.price del,
.woocommerce div.product.pl-pdp p.price del .amount { color: var(--pl-muted-soft); }
/* DR-PDP-CONTACT-003: the DR-PDP-CONTACT-002 operational line (.pl-pdp-summary__opnote)
   was removed as redundant with Storage & Handling; the RUO is the sole closing line and
   keeps its original 20px top rhythm. */
.pl-pdp-summary__ruo { margin: 20px 0 0; padding: 14px 16px; border-radius: var(--pl-radius); background: var(--pl-surface-2); border: 1px solid var(--pl-line); color: var(--pl-navy); font-size: .9rem; line-height: 1.55; }

/* Brand focus ring on the NO-JS fallback purchase controls (DR-062 --pl-ring), so the
   native <select> and quantity input match the focus system used site-wide and by the
   JS-enhanced strength/qty controls. When theme.js enhances the product, the native
   <select> is visually hidden (.pl-pdp-native-select--enhanced) and these are moot;
   with no JS they are the visible controls, and this keeps keyboard focus on-brand. */
.pl-pdp .variations select:focus-visible,
.single-product .quantity input.qty:focus-visible { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }

/* Purchase form — stack quantity above the action row; native structure intact.
   DR-PDP-CONTACT-003: gaps tightened so identity -> variations -> quantity -> Add to
   Cart read as one connected purchase cluster (native structure/behaviour untouched). */
.single-product.pl-pdp form.cart, .pl-pdp form.cart { margin: clamp(16px, 2vw, 22px) 0 0; }
.pl-pdp form.cart .quantity { display: block; margin: 0 0 12px; }
.pl-pdp .single_variation_wrap { margin-top: 4px; }
.pl-pdp .single_variation .price { margin: 0 0 10px; }
/* Native variations table → clean block rows; the radiogroup is self-labelled so
   the duplicate native attribute label is hidden. */
.pl-pdp .variations { width: 100%; border-collapse: collapse; margin: 0; }
.pl-pdp .variations tbody, .pl-pdp .variations tr, .pl-pdp .variations td, .pl-pdp .variations th { display: block; width: auto; }
.pl-pdp .variations th.label { text-align: left; padding: 0 0 8px; font-weight: 700; color: var(--pl-navy); }
/* The enhanced radiogroup is self-labelled — hide the duplicate native attribute
   label ONLY when JS has injected it; the no-JS <select> keeps its visible label. */
.pl-pdp .variations tr:has(.pl-pdp-strength) th.label { display: none; }
.pl-pdp .variations td.value { padding: 0; }
.pl-pdp .variations select { width: 100%; max-width: 320px; min-height: 50px; padding: 0 14px; border: 1.5px solid var(--pl-field-border); border-radius: var(--pl-radius); background: var(--pl-surface); font-size: 1rem; color: var(--pl-navy); }
.pl-pdp .reset_variations { display: inline-block; margin: 6px 0 0; font-size: .85rem; color: var(--pl-link); }

/* Actions — the Add to Cart button is the SOLE control in the purchase form.
   DR-091 / DR-PDP-CONTACT-002: the PDP purchase area is documentation-free — there
   is no "View COA" (or any documentation action) beside the cart; certificates live
   only in the Verification Center. The former .pl-pdp-actions__coa / --standalone
   rules and the <=339px COA-stacking rule are removed with the callbacks they styled
   (single-product.php, DR-091). The lone button fills the row via flex:1 1 auto at
   every width, so no small-screen stacking rule is needed. */
.pl-pdp-actions { display: flex; flex-wrap: nowrap; gap: 12px; align-items: stretch; width: 100%; }
.pl-pdp-actions .single_add_to_cart_button { flex: 1 1 auto; min-width: 0; min-height: 54px; font-size: 1.05rem; }

/* MOBILE PURCHASE RHYTHM. form.cart is a flex ROW, so quantity and the action
   group shared one line and the primary CTA measured just 142px wide at 390
   (quantity 186 + 12 gap + 142 = the 342 container). A 142px button is not a
   primary mobile action. Stack them: quantity on its own line, Add to Cart
   full-width beneath. Layout only — the form, its fields and its submit
   behaviour are untouched. */
@media (max-width: 600px) {
	.single-product div.product.pl-pdp form.cart { display: block; }
	.single-product div.product.pl-pdp form.cart .quantity { display: inline-flex; margin: 0 0 12px; }
	.single-product div.product.pl-pdp .pl-pdp-actions { display: flex; flex-wrap: wrap; width: 100%; }
	.single-product div.product.pl-pdp .pl-pdp-actions .single_add_to_cart_button { flex: 1 1 100%; width: 100%; }
}

/* RC.6.5 — the mobile scroll-snap "Related research compounds" rail was removed. The
   "Researchers also added" section is now a fixed two-column mobile grid (.pl-recgrid),
   never horizontally swipeable. No overflow-x / scroll-snap rule remains for it. */

/* Storage & Handling (DR-PDP-CONTACT-001): owner-approved DEFAULT-ON two-state card
   (Lyophilized material / After reconstitution) with mono micro-labels, strong
   temperature values, handling chips, per-state notes, optional fail-closed rows, a
   laboratory-reference line and the RUO notice. Restrained icy-blue; compact two-state
   on desktop, stacked on mobile. No emoji, no PASS styling, no medical/syringe symbols. */
.pl-pdp-storage__states { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2.6vw, 28px); }
.pl-pdp-storage__state { min-width: 0; padding: clamp(14px, 2vw, 18px); border: 1px solid var(--pl-line); border-radius: var(--pl-radius); background: var(--pl-surface-2); }
.pl-pdp-storage__statelabel { margin: 0; font-family: var(--pl-mono); font-size: .68rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--pl-muted); }
.pl-pdp-storage__temp { margin: 6px 0 0; font-family: var(--pl-font-heading); font-weight: 800; font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem); color: var(--pl-navy); letter-spacing: -.01em; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pl-pdp-storage__chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; padding: 0; list-style: none; }
.pl-pdp-storage__chip { display: inline-flex; align-items: center; padding: 6px 13px; border-radius: var(--pl-radius-pill); background: var(--pl-blue-050); border: 1px solid var(--pl-line); color: var(--pl-navy-700); font-size: .82rem; font-weight: 600; }
.pl-pdp-storage__statenote { margin: 12px 0 0; color: var(--pl-muted); font-size: .86rem; line-height: 1.55; overflow-wrap: anywhere; }
.pl-pdp-storage__extra { margin: clamp(14px, 2vw, 18px) 0 0; padding-top: clamp(12px, 1.6vw, 16px); border-top: 1px solid var(--pl-line); display: grid; gap: 8px; }
.pl-pdp-storage__extrarow { display: grid; grid-template-columns: minmax(120px, 32%) 1fr; gap: 4px 18px; align-items: baseline; margin: 0; }
.pl-pdp-storage__extrarow dt { margin: 0; color: var(--pl-muted); font-size: .86rem; font-weight: 600; }
.pl-pdp-storage__extrarow dd { margin: 0; color: var(--pl-navy); font-weight: 700; font-size: .92rem; overflow-wrap: anywhere; }
.pl-pdp-storage__mono { font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.pl-pdp-storage__ref { margin: clamp(14px, 2vw, 18px) 0 0; padding-top: clamp(12px, 1.6vw, 16px); border-top: 1px solid var(--pl-line); color: var(--pl-muted); font-size: .86rem; line-height: 1.6; max-width: 74ch; }
.pl-pdp-storage__source { margin: 8px 0 0; color: var(--pl-muted); font-size: .82rem; line-height: 1.55; overflow-wrap: anywhere; }
/* RUO is required compliance text — keep it AA on white (--pl-muted #42526A ~7.9:1),
   not the de-emphasised --pl-muted-soft (#718096 ~4.0:1, fails 1.4.3). */
.pl-pdp-storage__ruo { margin: 10px 0 0; font-family: var(--pl-mono); font-size: .74rem; letter-spacing: .04em; color: var(--pl-muted); }
@media (max-width: 560px) {
	.pl-pdp-storage__states { grid-template-columns: 1fr; gap: 14px; }
	.pl-pdp-storage__extrarow { grid-template-columns: 1fr; gap: 2px; }
}

/* Specifications (DR-091) — structured product fields only. Reuses the PDP section /
   card / header language (.pl-pdp-section / .pl-pdp-card / .pl-pdp-shead). Definition-
   list rows modeled on Storage; empty rows are server-hidden, and the Selected-strength
   / SKU values carry data-pl-spec hooks the variation-sync JS updates in place. */
.pl-pdp-specs__list { margin: 0; }
.pl-pdp-specs__row { display: grid; grid-template-columns: minmax(130px, 42%) 1fr; gap: 6px 20px; padding: 10px 0; border-top: 1px solid var(--pl-line); align-items: baseline; }
.pl-pdp-specs__row:first-child { border-top: 0; padding-top: 0; }
.pl-pdp-specs__row:last-child { padding-bottom: 0; }
.pl-pdp-specs__key { margin: 0; color: var(--pl-muted); font-size: .88rem; font-weight: 600; }
.pl-pdp-specs__val { margin: 0; color: var(--pl-navy); font-weight: 700; font-size: .95rem; font-variant-numeric: tabular-nums; letter-spacing: .01em; overflow-wrap: anywhere; }
@media (max-width: 480px) {
	.pl-pdp-specs__row { grid-template-columns: 1fr; gap: 2px; padding: 9px 0; }
}

/* Collapse to a single column at <=900 (gallery first, purchase summary second). */
@media (max-width: 900px) {
	.single-product div.product.pl-pdp { grid-template-columns: 1fr; }
	.pl-single-media.pl-pdp-gallery { position: static; }
}

/* ==========================================================================
   PDP vNext elevation (DR-029). Frame-only refinement of the approved slice-4
   PDP: unify the title ramp onto the weight-800 head system, lift the sub-AA
   category eyebrow + muted-soft secondary text to AA, un-clip the quantity
   focus ring, underline standalone links, and carry the approved References
   not-a-claim qualifier. All .pl-pdp-* / .single-product namespaced; overrides
   PROPERTIES only — renames/removes no class the theme.js .pl-pdp-* + [data-pl-coa*]
   hydration contract depends on. No product/COA data, no plugin, no JS change.
   ========================================================================== */

/* Title ramp — section heads + product title to weight-800 so the name is never
   out-weighted by the 800 price. The .pl-pdp-shead__title rule intentionally
   covers both server-rendered and the JS-rebuilt variation-COA section title. */
.pl-pdp-shead__title { font-weight: 800; letter-spacing: -.025em; }
.single-product.pl-pdp .product_title, .pl-pdp .product_title { font-weight: 800; letter-spacing: -.025em; }

/* Category eyebrow — sub-AA --pl-blue (.07em, no rule) → the accessible Home/Shop
   eyebrow: --pl-link (~5:1) + .22em + one 24×1.5px electric rule. This single hero
   eyebrow only — NOT added above every section (the DR-017 icon-tile head is kept). */
.pl-pdp-summary__category { display: inline-flex; align-items: center; gap: 11px; color: var(--pl-link); letter-spacing: .22em; }
.pl-pdp-summary__category::before { content: ""; width: 24px; height: 1.5px; background: var(--pl-blue); flex: none; }

/* Secondary text off the sub-AA --pl-muted-soft (~4.0:1) onto --pl-muted (~7.9:1):
   the sale strike, the DOI/PMID id line, and the not-a-claim disclaimer. */
.pl-pdp .price del { color: var(--pl-muted); }
.pl-pdp-refcard__id { color: var(--pl-muted); }
.pl-pdp-research__disclaimer { color: var(--pl-muted); }

/* ==========================================================================
   DR-PDP-CONTACT-003 — mobile PDP density. Placed AFTER every base metadata/title
   rule above (and carrying `.pl-pdp` descendant specificity, 0,2,0 > the 0,1,0 base
   rules) so these narrow-width overrides actually take effect — the earlier rc.6
   "mobile hero type floors" block
   was dead (defeated by later, equal-specificity base rules) and left the mobile H1 at
   the full 32px. Goal: bring the first purchase control into view sooner WITHOUT hiding
   any real product data or shrinking the image below premium presentation. No
   line-clamp, no ellipsis, no fixed-height clipping — long names still wrap freely.
   ========================================================================== */
/* Media stage: cap + center across the whole STACKED layout (<=900), so neither the
   phone nor the tablet shows an oversized square (at 768 the ungapped stage was a
   ~700px square). Mobile keeps a prominent ~78vw vial; the tablet caps at 400px. The
   1:1 stage, object-fit:contain, centered product, no-crop and no-CLS are all preserved
   — only the excess width (and thus height) is trimmed. */
@media (max-width: 900px) {
	.single-product div.product.pl-pdp .pl-single-media { max-width: clamp(232px, 78vw, 400px); margin-inline: auto; }
}
@media (max-width: 600px) {
	/* H1: lower the narrow-width ceiling (was an effective 32px) and tighten leading a
	   touch. Strong weight/hierarchy preserved; long product names still wrap. */
	.single-product.pl-pdp .product_title, .pl-pdp .product_title { font-size: clamp(1.5rem, 1.3rem + 1.05vw, 1.72rem); line-height: 1.06; }
	/* Category eyebrow: quieter + tighter tracking and a shorter rule so a long approved
	   label costs less height and wraps less. Taxonomy text is never rewritten/truncated.
	   Selectors use `.pl-pdp .x` (not the `.single-product.pl-pdp` compound): .single-product
	   is a <body> class and .pl-pdp is on the product wrapper, so the compound matches
	   nothing — `.pl-pdp .x` (0,2,0) is the form that actually beats the 0,1,0 base rules. */
	.pl-pdp .pl-pdp-summary__category { font-size: .72rem; letter-spacing: .1em; gap: 8px; margin: 0 0 7px; }
	.pl-pdp .pl-pdp-summary__category::before { width: 16px; }
	/* Identity metadata reads as one compact region; summary + short description stay
	   calm and secondary to the price. Nothing is hidden — only the vertical rhythm
	   tightens (each element still renders only when real owner/WooCommerce data exists). */
	.pl-pdp .pl-pdp-summary__code { margin: 0 0 6px; font-size: .95rem; }
	.pl-pdp .pl-pdp-summary__aliases { margin: 0 0 12px; }
	.pl-pdp .pl-pdp-summary__desc { margin: 0 0 14px; font-size: .96rem; }
	.pl-pdp .pl-pdp-shortdesc { margin: 4px 0 14px; }
	.pl-pdp .pl-single-stock { margin: 0 0 4px; }
	/* DR-PDP-POLISH-001: enlarge the PHONE product-media stage so the vial reads with more
	   authority. The <=900 rule above centred it at ~78vw (leaving a double inset: gutter +
	   auto margins); on phones (<=600) let the 1:1 stage FILL the container content column
	   instead — the container's 24px mobile gutter is the only inset, so the media never
	   touches the viewport edges. The 1:1 aspect, object-fit:contain, centred product, neutral
	   surface, rounded corners, intrinsic sizing and no-CLS are all inherited unchanged (only
	   the max-width increases). Same selector/specificity as the <=900 rule but later in
	   source, so it wins <=600; the tablet 400px cap (601-900) and the desktop grid are
	   untouched. */
	.single-product div.product.pl-pdp .pl-single-media { width: 100%; max-width: 100%; margin-inline: 0; }
}

/* ==========================================================================
   DR-PDP-CONTACT-004 — EXTREME-mobile PDP (<=380px: 320/360/375). A tighter tier ON TOP
   OF the <=600px DR-003 rules (placed after them so it wins where they overlap), for the
   long-title case where the breadcrumb + identity block pushed the first purchase control
   too far down. The approved standard mobile (>=390px) and desktop are untouched. No
   line-clamp / ellipsis / fixed height — the full product name still wraps freely.
   ========================================================================== */
@media (max-width: 380px) {
	/* Breadcrumb: collapse the trail to "Home / Shop" by VISUALLY hiding the current-page
	   crumb — the last, link-less .pl-crumb — together with its CSS-drawn separator. It
	   stays in the accessibility tree (clip, not display:none) and the <nav> landmark +
	   Home/Shop links are preserved, so the long title is not repeated above the media but
	   is still announced to AT. */
	.pl-product-breadcrumb { padding-top: 8px; }
	.pl-product-breadcrumb .pl-crumb:last-child {
		position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
		overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
	}
	/* H1: reduce the ceiling slightly from the DR-003 value, tighten leading, and balance
	   the wrap to reduce orphaned single-word last lines. Full name preserved (no clamp). */
	.pl-pdp .product_title { font-size: clamp(1.35rem, 1.2rem + 0.8vw, 1.55rem); line-height: 1.04; text-wrap: balance; }
	/* Category eyebrow: quieter still, shorter rule, tighter leading + margin. Wraps, never
	   clipped; taxonomy text is never rewritten or shortened. Stays subordinate to the H1. */
	.pl-pdp .pl-pdp-summary__category { font-size: .68rem; letter-spacing: .06em; line-height: 1.35; gap: 7px; margin: 0 0 5px; }
	.pl-pdp .pl-pdp-summary__category::before { width: 12px; }
	/* Compact metadata region: smaller-but-readable research code, tighter alias pills, and
	   reduced gaps/margins. Aliases still render only when real approved data exists. */
	.pl-pdp .pl-pdp-summary__code { font-size: .9rem; margin: 0 0 4px; }
	.pl-pdp .pl-pdp-aliases { gap: 6px; }
	.pl-pdp .pl-pdp-alias { padding: 3px 10px; font-size: .8rem; }
	.pl-pdp .pl-pdp-summary__aliases { margin: 0 0 10px; }
	/* Identity -> purchase rhythm: tighten summary / short description / stock and the
	   variation heading so the first control arrives sooner. Real content is preserved;
	   paragraph line-height and price prominence are unchanged. */
	.pl-pdp .pl-pdp-summary__desc { margin: 0 0 10px; }
	.pl-pdp .pl-pdp-shortdesc { margin: 4px 0 10px; }
	.pl-pdp .pl-single-stock { margin: 0 0 3px; }
	.pl-pdp .pl-pdp-strength__label { margin-bottom: 8px; }
}

/* Sources & References — the approved not-a-claim qualifier (identical wording +
   treatment to the research-context disclaimer), on the AA --pl-muted token. */
.pl-pdp-references__disclaimer { margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--pl-surface-3); color: var(--pl-muted); font-size: .85rem; }

/* Quantity stepper — keep the resting rounded corners (overflow:hidden) but let
   the keyboard focus ring escape the clip while a child is focused. */
.pl-qty:focus-within { overflow: visible; }

/* Standalone links — color-only affordance → underline: reference "View study",
   the molecular-profile "View on the authoritative database" source link, and the
   research-notice link. Add-to-Cart / View COA buttons are unaffected. */
.pl-pdp-reference__link, .pl-pdp-notice__link a, .pl-pdp-card__source a { text-decoration: underline; text-underline-offset: 2px; }

/* ==========================================================================
   COA public certificate DIRECTORY (P3). Reference-led: a compact navy hero, an
   overlapping "Search Certificates" panel, and a newest-first certificate table
   that collapses to labelled documentation rows on mobile. NO status/verification,
   purity, or laboratory column (owner decision §7). Namespaced .pl-coa-* only —
   never touches product grids, PDP, cart/checkout/account, homepage, or main.css.
   The .pl-coa-hero* base below is shared with the certificate viewer (which adds
   .pl-coa-hero--compact), so it must remain present for that route.
   ========================================================================== */
.pl-coa { display: block; }

/* Compact navy hero (shared base; the viewer adds .pl-coa-hero--compact). */
.pl-coa-hero { background: linear-gradient(150deg, var(--pl-navy) 0%, var(--pl-navy-800) 60%, var(--pl-navy-700) 100%); color: #fff; }
.pl-coa-hero__inner { padding-block: clamp(34px, 5vw, 60px); min-height: clamp(150px, 22vw, 240px); display: flex; flex-direction: column; justify-content: center; }
.pl-coa-hero__eyebrow { margin: 0 0 10px; font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--pl-icy-200); }
.pl-coa-hero__title { margin: 0; font-family: var(--pl-font-heading); font-weight: 800; font-size: clamp(2.1rem, 1.6rem + 2.4vw, 3rem); line-height: 1.04; letter-spacing: -.02em; color: #fff; }
.pl-coa-hero__intro { margin: 14px 0 0; max-width: 60ch; color: var(--pl-icy-200); font-size: clamp(1rem, .96rem + .3vw, 1.1rem); line-height: 1.6; }
.pl-coa-hero__note { margin: 6px 0 0; max-width: 60ch; color: var(--pl-icy-200); opacity: .78; font-size: .9rem; line-height: 1.55; }

/* Body: no top padding so the search panel can overlap the hero's lower edge. */
/* DR-COA-005: the approval card + transparency paragraph were removed, so the body now
   flows hero/stats → product directory. The hero→directory gap lives on this padding-top
   (24px mobile/tablet → 32px desktop) — put on padding, not the first child's margin, so it
   never margin-collapses and holds in every state (records / no-results / fail-closed). */
.pl-coa__body { padding-block: clamp(24px, 3vw, 32px) clamp(44px, 6vw, 80px); }
/* RC.6.9 — documentation-transparency notice. Takes the search panel's original
   hero-overlap slot (floats over the navy hero edge); the panel then flows normally
   below it. Light frost band, informational (not alarming). Navy/blue/frost tokens only. */
.pl-coa-notice { position: relative; z-index: var(--pl-z-base, 1); margin: calc(-1 * clamp(28px, 4.5vw, 52px)) 0 clamp(20px, 3vw, 28px); display: flex; align-items: flex-start; gap: 12px; background: var(--pl-surface-2); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); padding: clamp(14px, 2vw, 18px) clamp(16px, 2.4vw, 22px); }
.pl-coa-notice__icon { color: var(--pl-blue); flex: none; margin-top: 1px; }
.pl-coa-notice__text { margin: 0; color: var(--pl-muted); font-size: .9rem; line-height: 1.6; max-width: 72ch; }
.pl-coa-notice + .pl-coa-panel { margin-top: 0; }

/* Search panel — a white card overlapping the navy hero (reference composition). */
.pl-coa-panel { position: relative; z-index: var(--pl-z-base, 1); margin-top: calc(-1 * clamp(28px, 4.5vw, 52px)); background: #fff; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); box-shadow: 0 26px 60px rgba(2, 11, 22, .12); padding: clamp(20px, 3vw, 34px); }
.pl-coa-panel__title { margin: 0; font-family: var(--pl-font-heading); font-weight: 800; color: var(--pl-navy); font-size: clamp(1.2rem, 1.05rem + .6vw, 1.45rem); }
.pl-coa-panel__hint { margin: 6px 0 clamp(16px, 2vw, 20px); color: var(--pl-muted); font-size: .95rem; line-height: 1.5; }

/* Search — one horizontal row on desktop (flexible field + compact action). */
.pl-coa-search { display: block; }
.pl-coa-search__row { display: flex; gap: 12px; align-items: stretch; position: relative; }
.pl-coa-search__icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--pl-muted); pointer-events: none; display: inline-flex; }
.pl-coa-search__input { flex: 1 1 auto; min-width: 0; height: 54px; padding: 0 16px 0 46px; border-radius: var(--pl-radius); border: 1.5px solid var(--pl-field-border); background: var(--pl-surface); font-size: 1rem; color: var(--pl-navy); }
.pl-coa-search__input::placeholder { color: var(--pl-muted); }
.pl-coa-search__input:focus { border-color: var(--pl-blue); box-shadow: var(--pl-ring); outline: none; }
.pl-coa-search__submit { flex: 0 0 auto; min-height: 54px; white-space: nowrap; }

/* Results head — section title + accessible live count. */
.pl-coa-results { margin-top: 0; } /* DR-COA-005: first body child; the hero→directory gap is on .pl-coa__body padding-top. */
.pl-coa-results__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; margin: 0 0 clamp(12px, 1.8vw, 18px); }
.pl-coa-results__title { margin: 0; font-family: var(--pl-font-heading); font-size: clamp(1.3rem, 1.1rem + .8vw, 1.7rem); color: var(--pl-navy); }
.pl-coa-results__count { margin: 0; color: var(--pl-muted); font-size: .92rem; font-weight: 600; }

/* Certificate table (desktop). Light header, hairline rows, tabular numerals. */
.pl-coa-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.pl-coa-col--product { width: 34%; }
.pl-coa-col--lot { width: 18%; }
.pl-coa-col--cert { width: 20%; }
.pl-coa-col--date { width: 12%; }
.pl-coa-col--action { width: 16%; }
.pl-coa-table thead th { text-align: left; padding: 0 16px 12px; font-size: .74rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--pl-muted); border-bottom: 1.5px solid var(--pl-line-strong); }
.pl-coa-table thead th:last-child { text-align: right; }
.pl-coa-table tbody td { padding: 14px 16px; border-bottom: 1px solid var(--pl-line); vertical-align: middle; color: var(--pl-navy); font-size: .96rem; }
.pl-coa-table tbody tr:last-child td { border-bottom: 0; }
.pl-coa-cell--num { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pl-coa-cell--action { text-align: right; }

/* Product cell — icy contain-fit thumbnail + title + quiet strength. */
.pl-coa-prodcell { display: flex; align-items: center; gap: 14px; min-width: 0; }
.pl-coa-thumb { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; border-radius: 12px; background: var(--pl-icy); border: 1px solid var(--pl-line); color: var(--pl-blue); overflow: hidden; }
.pl-coa-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }
.pl-coa-prod { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-coa-prod__name { font-weight: 700; color: var(--pl-navy); line-height: 1.3; overflow-wrap: anywhere; }
.pl-coa-prod__name a { color: inherit; }
.pl-coa-prod__name a:hover { color: var(--pl-blue); text-decoration: underline; text-underline-offset: 2px; }
.pl-coa-prod__strength { color: var(--pl-muted); font-size: .85rem; font-weight: 600; }

/* View COA — one restrained outline action; >=44px, no download icon (§9/§18). */
.pl-coa-view { min-height: 44px; padding-inline: 20px; white-space: nowrap; }

/* Empty + no-results states. */
.pl-coa-empty { margin-top: 0; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; padding: clamp(30px, 6vw, 60px) 20px; background: var(--pl-surface-2); border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg); } /* DR-COA-005: first body child; hero gap on .pl-coa__body padding-top. */
.pl-coa-empty__icon { color: var(--pl-blue); opacity: .8; }
.pl-coa-empty__text { margin: 0; font-family: var(--pl-font-heading); font-size: 1.12rem; font-weight: 800; color: var(--pl-navy); }
.pl-coa-empty__sub { margin: 0; color: var(--pl-muted); max-width: 52ch; line-height: 1.55; }

/* Pagination */
.pl-coa-pager { margin-top: clamp(20px, 3vw, 28px); }
.pl-coa-pager ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.pl-coa-pager__link { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: var(--pl-radius); border: 1.5px solid var(--pl-field-border); background: var(--pl-surface); color: var(--pl-navy); font-weight: 600; }
.pl-coa-pager__link:hover { border-color: var(--pl-blue); color: var(--pl-blue); }
.pl-coa-pager__link.is-current { background: var(--pl-navy); border-color: var(--pl-navy); color: #fff; }

/* Mobile: the table becomes labelled documentation cards (no horizontal scroll, §14). */
@media (max-width: 767px) {
	.pl-coa-table, .pl-coa-table tbody, .pl-coa-table tr, .pl-coa-table td { display: block; width: 100%; }
	.pl-coa-table thead { display: none; }
	.pl-coa-table tbody tr { border: 1px solid var(--pl-line); border-radius: var(--pl-radius); background: var(--pl-surface); padding: 14px 16px; margin-bottom: 14px; }
	.pl-coa-table tbody tr:last-child { margin-bottom: 0; }
	.pl-coa-table tbody td { border: 0; padding: 7px 0; font-size: .95rem; }
	.pl-coa-table tbody td.pl-coa-cell--num { overflow-wrap: anywhere; }
	.pl-coa-table tbody td.pl-coa-cell--num::before { content: attr(data-label); display: block; font-weight: 700; font-size: .7rem; letter-spacing: .05em; text-transform: uppercase; color: var(--pl-muted); margin-bottom: 1px; }
	.pl-coa-table tbody td.pl-coa-cell--product { padding: 0 0 10px; border-bottom: 1px solid var(--pl-line); margin-bottom: 4px; }
	.pl-coa-table tbody td.pl-coa-cell--action { padding: 12px 0 0; text-align: left; }
	.pl-coa-view { width: 100%; }
	.pl-coa-search__row { flex-wrap: wrap; }
	.pl-coa-search__submit { flex: 1 1 100%; }
}
@media (max-width: 359px) {
	.pl-coa-panel { padding: 18px 16px; }
}
@media (prefers-reduced-motion: reduce) {
	/* main.css already zeroes every transition-duration globally, but that leaves
	   the END state — so a hover lift or image scale would still SNAP into place,
	   which is worse for a motion-sensitive reader than a smooth one. Neutralise
	   the transforms themselves for the PDP motion added in this pass. */
	.pl-pdp-strength__option, .pl-btn { transition: none; }
	.pl-btn:hover { transform: none; }
	/* RC.6.2 — neutralize the shared product card's hover lift + image zoom for
	   reduced-motion pointer users (restores the parity the removed .pl-pdp-rcard
	   reduced-motion rules had; now covers Shop, Featured and the migrated Related rail). */
	.pl-scard:hover, .pl-scard:hover .pl-scard__img { transform: none; }
	/* S2.1 — the PDP Add-to-Cart button's hover lift is set at a higher specificity
	   (.single-product form.cart .single_add_to_cart_button:hover, 0,3,1) than the
	   .pl-btn:hover rule above (0,2,0), so its 1px end-state transform survived here.
	   Zero it explicitly. Transform only: the background-colour hover state is
	   untouched, so the button still reads as active, and the static geometry is
	   identical. Scoped to .single-product, so no archive/shop/home/cart/checkout/
	   account leakage. */
	.single-product form.cart .single_add_to_cart_button:hover { transform: none; }
	/* Commerce-consolidation — neutralize the transforms added in this pass so nothing snaps
	   for motion-sensitive readers. Colour/background hover states are untouched, so every
	   control still reads as active; only the geometry is held still. */
	.pl-reccard:hover, .pl-reccard:hover .pl-reccard__img { transform: none; }
	.single-product form.cart .single_add_to_cart_button:active,
	.woocommerce #payment #place_order:hover:not([disabled]):not([aria-disabled="true"]),
	.woocommerce #payment #place_order:active,
	.woocommerce a.button.alt.checkout-button:hover,
	.woocommerce-page a.button.alt.checkout-button:hover,
	.woocommerce .wc-proceed-to-checkout a.button.alt:hover,
	.woocommerce-page .wc-proceed-to-checkout a.button.alt:hover,
	.woocommerce a.button.alt.checkout-button:active,
	.woocommerce-page a.button.alt.checkout-button:active,
	.woocommerce .wc-proceed-to-checkout a.button.alt:active,
	.woocommerce-page .wc-proceed-to-checkout a.button.alt:active { transform: none; }
}

/* --------------------------------------------------------------------------
   PDP mobile rhythm (CSS-only, .single-product, <=600px). Trims the mobile top
   margin on the variable-product purchase form and the RUO notice so the summary
   column is not over-tall on phones. The selectors are deliberately specific
   (.entry-summary-scoped element+class) so they win over the base theme form/RUO
   rules. Verified at 390 + 430: no horizontal overflow; purchase form + RUO intact.
   (An earlier revision of this note referenced a now-removed documentation-pending
   block and named specific products; both were removed — see DR-091 documentation-free
   PDP and DR-PDP-CONTACT-005 proof-data neutrality. Kept unchanged here to preserve
   the approved mobile output; a lower-specificity consolidation into the primary
   <=600 PDP block is a flagged, owner-gated follow-up.)
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
	.single-product .entry-summary form.variations_form.cart { margin-top: 10px; margin-bottom: 12px; }
	.single-product .entry-summary p.pl-pdp-summary__ruo { margin-top: 10px; padding-top: 10px; padding-bottom: 10px; }
}

/* ===========================================================================
   COA Verification pass (owner decisions) — the "Documentation before publication"
   process section (the directory approval notice was removed under DR-COA-005).
   Namespaced .pl-coa-*; consumes the shipped design tokens. Presentation only.
   =========================================================================== */
/* DR-COA-005: the .pl-coa-approval notice card + .pl-coa-transparency paragraph (and their
   hero-overlap adjacency reset) were removed — the Verification Center now flows hero/stats
   → product directory with no explanatory section between them. */

.pl-coa-process { border-top: 1px solid var(--pl-line); margin-top: clamp(32px, 5vw, 56px); padding-top: clamp(28px, 4vw, 44px); padding-bottom: clamp(8px, 2vw, 20px); }
.pl-coa-process__eyebrow { font-family: var(--pl-mono, ui-monospace, 'Cascadia Code', Consolas, monospace); font-size: .72rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--pl-blue-600, #1e63d8); margin: 0; }
.pl-coa-process__title { font-family: var(--pl-font-heading); font-weight: 800; font-size: clamp(1.25rem, 1rem + 1vw, 1.5rem); color: var(--pl-navy); margin: 6px 0 0; letter-spacing: -.01em; }
.pl-coa-steps { list-style: none; margin: 24px 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.pl-coa-step { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg, 18px); background: var(--pl-surface, #fff); padding: 20px; }
.pl-coa-step__n { display: block; font-family: var(--pl-mono, ui-monospace, 'Cascadia Code', Consolas, monospace); font-size: .72rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--pl-blue-600, #1e63d8); }
.pl-coa-step__t { font-family: var(--pl-font-heading); font-weight: 700; font-size: 1.0625rem; color: var(--pl-navy); margin: 8px 0 0; letter-spacing: -.01em; }
.pl-coa-step__d { color: var(--pl-muted); font-size: .9375rem; margin: 8px 0 0; line-height: 1.55; }
@media (max-width: 860px) { .pl-coa-steps { grid-template-columns: 1fr; } }

/* ===========================================================================
   Product-first Verification Center (DR-COA-004) — hero search + dynamic stats,
   product ARIA-disclosure cards, and certificate rows. Namespaced .pl-coa-*;
   shipped tokens; additive. Public certificate access never depends on JS
   (the .no-js fallback force-shows every panel).
   =========================================================================== */
.pl-coa-herosearch { display: flex; gap: 8px; align-items: center; background: #fff; border-radius: var(--pl-radius, 12px); padding: 6px; box-shadow: 0 3px 10px rgba(7,24,45,.16); max-width: 640px; margin-top: 24px; }
.pl-coa-herosearch__icon { display: grid; place-items: center; padding-left: 10px; color: var(--pl-muted); flex: none; }
.pl-coa-herosearch__input { flex: 1; min-width: 0; border: 0; outline: 0; font: inherit; font-size: 1rem; color: var(--pl-navy); background: transparent; padding: 10px 6px; }
.pl-coa-herosearch__submit { flex: none; }
.pl-coa-stats { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 24px 0 0; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.14); }
.pl-coa-stat { display: flex; flex-direction: column-reverse; gap: 2px; }
.pl-coa-stat__n { margin: 0; font-family: var(--pl-font-heading); font-weight: 800; font-size: 1.5rem; color: #fff; letter-spacing: -.02em; line-height: 1.05; }
.pl-coa-stat__n--text { font-size: 1.25rem; }
.pl-coa-stat__l { margin: 0; font-family: var(--pl-mono, ui-monospace, monospace); font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--pl-icy-200, #b9cdea); }

/* --- Testing pipeline (DR-COA-PIPELINE-004): "Testing in progress" / "Scheduled for testing"
   cards. Transparency only — NEVER a certificate; no View COA, no Notify button (flag OFF).
   Status is text + a dot (never colour alone). Shipped tokens with safe fallbacks. --- */
.pl-coa-testing { border-top: 1px solid var(--pl-line); margin-top: clamp(28px, 4vw, 48px); padding-top: clamp(24px, 3.5vw, 40px); }
.pl-coa-testing__head { max-width: 640px; }
.pl-coa-testing__title { font-family: var(--pl-font-heading); font-weight: 800; font-size: clamp(1.25rem, 1rem + 1vw, 1.5rem); color: var(--pl-navy); margin: 0; letter-spacing: -.01em; }
.pl-coa-testing__sub { color: var(--pl-muted); font-size: .9375rem; margin: 6px 0 0; line-height: 1.55; }
.pl-coa-testing__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; margin-top: 20px; }
.pl-coa-tcard { display: flex; gap: 14px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg, 18px); background: var(--pl-surface, #fff); box-shadow: var(--pl-shadow-sm); padding: 16px; }
.pl-coa-tcard__media { width: 60px; height: 60px; flex: none; border-radius: var(--pl-radius, 12px); border: 1px solid var(--pl-line); background: var(--pl-surface-2, #f7fafd); display: grid; place-items: center; overflow: hidden; }
.pl-coa-tcard__img { width: 100%; height: 100%; object-fit: contain; object-position: center; display: block; }
.pl-coa-tcard__ph { color: var(--pl-muted); display: grid; place-items: center; }
.pl-coa-tcard__body { flex: 1; min-width: 0; }
.pl-coa-tcard__title { display: inline-block; font-family: var(--pl-font-heading); font-weight: 800; font-size: 1.0625rem; color: var(--pl-navy); letter-spacing: -.015em; text-decoration: none; overflow-wrap: anywhere; }
.pl-coa-tcard__title:hover { color: var(--pl-blue); }
.pl-coa-tcard__variation { margin: 2px 0 0; font-size: .8125rem; color: var(--pl-muted); }
.pl-coa-tcard__statusline { margin: 8px 0 0; }
.pl-coa-tstatus { display: inline-flex; align-items: center; gap: 7px; padding: 3px 10px; border-radius: 999px; font-family: var(--pl-mono, ui-monospace, monospace); font-size: .68rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.pl-coa-tstatus__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.pl-coa-tstatus--in_testing { color: var(--pl-pending, #a66a08); background: var(--pl-pending-bg, #fff3d2); }
.pl-coa-tstatus--scheduled { color: var(--pl-blue-600, #1e63d8); background: var(--pl-info-bg, #e8f1ff); }
.pl-coa-tcard__meta { margin: 12px 0 0; display: grid; gap: 6px; }
.pl-coa-tcard__m { display: flex; flex-direction: column; gap: 1px; }
.pl-coa-tcard__m dt { font-family: var(--pl-mono, ui-monospace, monospace); font-size: .64rem; letter-spacing: .08em; text-transform: uppercase; color: var(--pl-muted); }
.pl-coa-tcard__m dd { margin: 0; font-size: .875rem; color: var(--pl-navy); }
@media (max-width: 520px) { .pl-coa-testing__grid { grid-template-columns: 1fr; } }
.pl-pdp-verify__testing { margin: 0 0 12px; }
/* Future-ready COA notify form (DR-COA-NOTIFY-001) — renders only when the global flag is enabled. */
.pl-coa-notify { margin: 12px 0 0; }
.pl-coa-notify__cta { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border: 1px solid var(--pl-line); border-radius: 999px; font-weight: 600; font-size: .875rem; color: var(--pl-navy); background: var(--pl-surface, #fff); }
.pl-coa-notify__form { margin: 12px 0 0; display: grid; gap: 8px; max-width: 340px; }
.pl-coa-notify__copy { margin: 0; font-size: .8125rem; color: var(--pl-muted); }
.pl-coa-notify__email { min-height: 44px; padding: 8px 12px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius, 12px); font-size: 1rem; width: 100%; }
.pl-coa-notify__submit { min-height: 44px; }
.pl-coa-notify__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.pl-coa-products { display: grid; gap: 14px; margin-top: 20px; }
.pl-coa-product { border: 1px solid var(--pl-line); border-radius: var(--pl-radius-lg, 18px); background: var(--pl-surface, #fff); box-shadow: var(--pl-shadow-sm); overflow: hidden; transition: border-color .2s var(--pl-ease, ease); }
.pl-coa-product__header { display: flex; align-items: center; gap: 16px; padding: 16px; }
.pl-coa-product__media { width: 64px; height: 64px; flex: none; border-radius: var(--pl-radius, 12px); border: 1px solid var(--pl-line); background: var(--pl-surface-2, #f7fafd); display: grid; place-items: center; overflow: hidden; }
.pl-coa-product__media img { width: 100%; height: 100%; object-fit: contain; object-position: center; display: block; }
.pl-coa-product__ph { color: var(--pl-muted); display: grid; place-items: center; }
.pl-coa-product__identity { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pl-coa-product__title { font-family: var(--pl-font-heading); font-weight: 800; font-size: 1.125rem; color: var(--pl-navy); letter-spacing: -.015em; text-decoration: none; overflow-wrap: anywhere; }
.pl-coa-product__title:hover { color: var(--pl-blue); }
/* DR-COA-009: a touch more space between the title and its metadata for editorial hierarchy. */
.pl-coa-product__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; margin: 4px 0 0; font-size: .875rem; color: var(--pl-muted); }
.pl-coa-product__count { font-weight: 600; color: var(--pl-navy); }
.pl-coa-product__lab { color: var(--pl-muted); }
.pl-coa-product__lab::before { content: "·"; margin-right: 8px; color: var(--pl-muted); }
.pl-coa-product__date { flex-basis: 100%; margin-top: 1px; color: var(--pl-muted); font-size: .8125rem; }
/* DR-COA-008: quieter, secondary disclosure — subdued text + hairline border so it recedes
   behind the product identity; it warms to PolarLabs blue only on hover/focus. Still >=44px. */
.pl-coa-product__toggle { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 8px 12px; border: 1px solid var(--pl-line); border-radius: var(--pl-radius, 12px); background: transparent; color: var(--pl-muted); font: inherit; font-weight: 600; font-size: .8125rem; cursor: pointer; transition: border-color .16s var(--pl-ease, ease), background .16s var(--pl-ease, ease), color .16s var(--pl-ease, ease); }
.pl-coa-product__toggle:hover { border-color: var(--pl-blue); color: var(--pl-blue); background: var(--pl-blue-050, #eaf3ff); }
.pl-coa-product__chev { flex: none; transition: transform .22s var(--pl-ease, ease); }
.pl-coa-product__toggle[aria-expanded="true"] .pl-coa-product__chev { transform: rotate(180deg); }
/* DR-COA-009: the expanded panel is set off by a subtle blue-tinted top divider (a calm
   "active" cue) over its recessed icy surface — no shadow, gradient, or heavy border. */
.pl-coa-product__panel { border-top: 1px solid var(--pl-blue-100, #d7e6fb); background: var(--pl-surface-2, #f7fafd); padding: 8px; }
.pl-coa-product__panel[hidden] { display: none; }
.no-js .pl-coa-product__panel[hidden] { display: block; }
.no-js .pl-coa-product__toggle { display: none; } /* no-JS: panel is force-shown above, so the disclosure toggle is redundant AND inert (no JS handler) — hide the whole control, not just its chevron. */
/* DR-COA-006 deep-link focus cue (the DR-COA-006 "View product" link was removed in DR-COA-008;
   the product image + title remain the PDP links). */
.pl-coa-product.is-focus { border-color: var(--pl-blue); box-shadow: 0 0 0 3px var(--pl-blue-050, #eaf3ff); scroll-margin-top: 96px; }

/* DR-COA-008: certificates read as ONE unit with the product card — inset rows with a hairline
   separator (no floating per-record cards), on desktop and mobile. Labels recede, values dominate. */
.pl-coa-record { display: flex; align-items: center; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; padding: 12px 8px; margin: 0; border: 0; border-top: 1px solid var(--pl-line); border-radius: 0; background: transparent; }
.pl-coa-record:first-child { border-top: 0; }
.pl-coa-record__facts { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 0; min-width: 0; }
.pl-coa-record__f { display: flex; flex-direction: column; min-width: 0; }
/* DR-COA-009: labels recede (smaller, lighter tracking), values read as premium lab data. */
.pl-coa-record__f dt { margin: 0; font-family: var(--pl-mono, ui-monospace, monospace); font-size: .625rem; letter-spacing: .04em; text-transform: uppercase; color: var(--pl-muted); }
.pl-coa-record__f dd { margin: 3px 0 0; font-size: .9375rem; color: var(--pl-navy); font-weight: 700; letter-spacing: -.005em; overflow-wrap: anywhere; }
.pl-coa-record__v--mono { font-family: var(--pl-mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; }
.pl-coa-record__action { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 8px 14px; border: 1px solid var(--pl-line-strong); border-radius: var(--pl-radius, 12px); color: var(--pl-blue); font-weight: 600; font-size: .875rem; white-space: nowrap; transition: border-color .16s var(--pl-ease, ease), background .16s var(--pl-ease, ease); }
.pl-coa-record__action:hover { border-color: var(--pl-blue); background: var(--pl-blue-050, #eaf3ff); }
/* DR-COA-LINKS: external-laboratory record — the action opens the lab's own webpage in a
   new tab; this note (its own flex line via flex-basis:100%) states the destination. */
.pl-coa-record__extnote { flex-basis: 100%; margin: 2px 0 0; font-size: .75rem; line-height: 1.45; color: var(--pl-muted); }

@media (max-width: 640px) {
	/* DR-COA-007/008 — compact mobile Verification Center. HEADER is a grid so the metadata
	   spans the FULL width beneath the title + chevron (image left, spanning both rows), giving
	   the owner's two-line rhythm: "N certificates · Lab" on one line, "Latest <date>" below.
	   Image + title stay real PDP links; the chevron stays a separate button (ARIA unchanged). */
	.pl-coa-products { gap: 12px; }
	.pl-coa-product__header { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "media title toggle" "media meta meta"; column-gap: 12px; row-gap: 3px; padding: 12px; align-items: start; }
	.pl-coa-product__identity { display: contents; }
	.pl-coa-product__media { grid-area: media; width: 56px; height: 56px; align-self: start; }
	.pl-coa-product__title { grid-area: title; align-self: center; font-size: 1.0625rem; }
	.pl-coa-product__meta { grid-area: meta; margin: 0; font-size: .8125rem; gap: 1px 6px; }
	.pl-coa-product__lab::before { margin-right: 6px; }
	.pl-coa-product__date { font-size: .75rem; margin-top: 0; }
	/* Chevron-only disclosure on phones so the toggle stops stealing identity width (which
	   forced the meta to wrap and inflated the header). "View COAs" stays the button's
	   accessible name via sr-only text (NOT display:none), so AT still announces it. */
	.pl-coa-product__toggle { grid-area: toggle; align-self: start; min-width: 44px; min-height: 44px; padding: 12px; gap: 0; }
	.pl-coa-product__toggletext { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

	/* RECORDS: shallow INSET rows with hairline separators (not floating cards); facts as
	   compact label-left / value-right lines; the action a small right-aligned link, not a
	   full-width button. Values dominant, labels small; long lot/cert IDs wrap cleanly. */
	.pl-coa-product__panel { padding: 0 12px; }
	/* Base already makes records inset hairline rows; mobile only restacks them to a column with
	   label-left / value-right facts and tightens the vertical rhythm (DR-COA-008: ~7% tighter). */
	.pl-coa-record { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0; padding: 8px 2px; }
	.pl-coa-record__facts { display: flex; flex-direction: column; gap: 2px; }
	.pl-coa-record__f { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 14px; line-height: 1.3; }
	.pl-coa-record__f dt { flex: none; margin: 0; }
	.pl-coa-record__f dd { margin: 0; text-align: right; min-width: 0; overflow-wrap: anywhere; }
	.pl-coa-record__action { align-self: flex-end; width: auto; justify-content: flex-end; margin-top: 2px; padding: 10px 2px; min-height: 44px; border: 0; border-radius: 0; background: transparent; }
	.pl-coa-record__action:hover { border-color: transparent; background: transparent; text-decoration: underline; }
}
@media (max-width: 360px) { .pl-coa-product__media { width: 48px; height: 48px; } }
@media (prefers-reduced-motion: reduce) { .pl-coa-product__chev, .pl-coa-product__panel { transition: none !important; } }

/* ===========================================================================
   PDP Verification section (DR-COA-006) — the product-page half of the product <->
   Verification Center bridge. Reuses the shared .pl-pdp-section / .pl-pdp-card / .pl-btn
   PDP system; adds only the stat grid + action. Namespaced .pl-pdp-verify*.
   =========================================================================== */
.pl-pdp-verify__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 28px; margin: 0 0 18px; }
.pl-pdp-verify__stat { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pl-pdp-verify__l { font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--pl-muted); }
.pl-pdp-verify__v { font-family: var(--pl-font-heading); font-weight: 700; font-size: 1.0625rem; color: var(--pl-navy); overflow-wrap: anywhere; }
.pl-pdp-verify__v--mono { font-family: var(--pl-mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.pl-pdp-verify__empty { margin: 0 0 16px; color: var(--pl-muted); font-size: .9375rem; line-height: 1.55; }
.pl-pdp-verify__action { display: inline-flex; align-items: center; gap: 8px; }
.pl-pdp-verify__arrow { flex: none; }
@media (max-width: 560px) { .pl-pdp-verify__stats { grid-template-columns: 1fr; gap: 12px; } .pl-pdp-verify__action { width: 100%; justify-content: center; } }
