/* ==========================================================================
   Bonza, shared WooCommerce product-card component.
   ClickUp 86eypb6m9. Figma PRODUCT CARD 29089:54366 (STATE=Default,
   Device=Desktop 2.0). Full research/config-first/scope notes: see the PR
   description and CHANGELOG, not shipped here (this file is publicly
   fetchable). One Figma field (Subheadline/ingredient chips) still has no
   backing product-meta field on this site and stays off rather than
   fabricated; Star Rating renders only when Feefo has a verified count for
   that SKU (category-card.php), matching Figma's own per-instance true/
   false toggle on this component rather than a blanket state.
   Cost-per-day (86eypb6m9, 2026-09-16) is wired
   in category-page.php's bonza_category_cost_per_day() but renders
   nothing until a product has real chews-per-pack/daily-dose ACF values
   -- .bcp-cost-per-day below styles it for when that data exists.
   Enqueued unconditionally wherever WooCommerce is active
   (category-page.php), not gated to one archive -- this markup is shared
   with Shop, search and related/wishlist loops.
   ========================================================================== */

.woocommerce ul.products li.product {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--bhp-white, #FFFFFF);
	border-radius: 12px;
	box-shadow: 0px 4px 6px -2px rgba(0, 0, 0, 0.03), 0px 12px 16px -4px rgba(0, 0, 0, 0.08);
	overflow: hidden;
	padding: 0 0 8px;
	transition: box-shadow 0.2s ease;
}

/* Corrected 2026-09-21 (hover/type audit 86eyxb3yu): dropped
   `transform: translateY(-2px)`. hover-type-contract.md's proven negative
   holds project-wide, not just for Button: across every measured
   Default/Hover bbox pair in this Figma file, nothing ever moves or
   resizes on hover, and the contract explicitly bans a hover rule adding
   a transform. This card lift was never sourced from Figma (PRODUCT CARD
   29089:54366 draws no such delta) -- source: DERIVED, and removed
   outright rather than kept as an unsanctioned addition. The shadow
   deepening on hover stays; it is paint-only and was already present. */
.woocommerce ul.products li.product:hover {
	box-shadow: 0px 8px 10px -3px rgba(0, 0, 0, 0.06), 0px 20px 25px -5px rgba(0, 0, 0, 0.1);
}

/* Image panel: Figma's photo panel is a 1:1 square FILL crop (category-
   page.css already sets aspect-ratio/object-fit on the <img> itself; this
   file only owns the card-shell layer around it). */
.woocommerce ul.products li.product figure {
	order: 0;
	margin: 0;
	position: relative;
}

.woocommerce ul.products li.product .ct-media-container {
	display: block;
}

/* Wishlist heart: Blocksy already renders this control (ct-wishlist-
   button-archive) with working functionality, just with no card-specific
   position/skin, so it rendered inline in the document flow above the
   image instead of Figma's floating circle over the top-right corner of
   the photo. */
.woocommerce ul.products li.product .ct-woo-card-extra {
	order: 0;
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 2;
}

.woocommerce ul.products li.product .ct-wishlist-button-archive {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 999px;
	background: var(--wp--preset--color--bhp-white, #FFFFFF);
	box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.12);
	/* bhp-red is not a registered palette slug on this site (homepage.php's
	   wp_theme_json_data_theme filter registers amber/black/coral/cream/
	   green/ink/peach/purple/white/yellow only) -- coral (#BF4940) is the
	   closest registered token to Figma's wishlist-heart red and cascades
	   correctly from the editor Styles panel, unlike an invented slug whose
	   fallback would silently become the only value in effect. */
	color: var(--wp--preset--color--bhp-coral, #BF4940);
	padding: 0;
}

.woocommerce ul.products li.product .ct-wishlist-button-archive svg {
	width: 14px;
	height: 14px;
}

/* Category chip: the real product_cat term link Blocksy already outputs
   into entry-meta -- the only per-product "category" data this site's
   schema actually has, so it stands in for Figma's category badge chip. */
.woocommerce ul.products li.product .entry-meta {
	order: 1;
	margin: 8px 8px 0;
	padding: 0;
	list-style: none;
}

.woocommerce ul.products li.product .entry-meta .meta-categories {
	display: block;
}

.woocommerce ul.products li.product .entry-meta .meta-categories a {
	display: inline-flex;
	align-items: center;
	padding: 4px 6px;
	border-radius: 999px;
	background: var(--wp--preset--color--bhp-cream, #F8EDE3);
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 400;
	font-size: 12px;
	line-height: 1.4; /* was 14px, 86eypb6j8 */
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 12.30:1 on the cream #F8EDE3 pill bg (WCAG AA/AAA) */
	text-decoration: none;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	order: 2;
	margin: 8px 8px 0;
	padding: 0;
	font-family: var(--wp--preset--font-family--bhp-heading, "Nominee", sans-serif);
	font-weight: 900;
	font-size: 14px;
	line-height: 1.2; /* was 16px (1.14x), 86eypb6j8 */
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 14.18:1 on the white #FFFFFF card bg (WCAG AA/AAA) */
}

.woocommerce ul.products li.product .woocommerce-loop-product__link {
	text-decoration: none;
	color: inherit;
}

/* Price + subscription row: WooCommerce/WooCommerce Subscriptions already
   render both the price and the recurring "every 2 months" text into this
   one <span class="price">, this file only re-skins it to the Figma green/
   uppercase treatment instead of theme default ink/regular weight. */
.woocommerce ul.products li.product .price {
	order: 3;
	margin: 8px 8px 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-family: var(--wp--preset--font-family--bhp-heading, "Nominee", sans-serif);
	font-weight: 900;
	font-size: 12px;
	line-height: 16px;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--wp--preset--color--bhp-green, #247B4E);
}

.woocommerce ul.products li.product .price del {
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 400;
	text-transform: none;
	/* bhp-ink-muted is not a registered palette slug (see the wishlist-heart
	   note above) -- the registered "ink" token plus reduced opacity gives
	   the same muted strikethrough read without an invented fallback.
	   Recomputed for the corrected #2E2A2A ink (86eyv0k44 GL-05, was #494545):
	   opacity: 0.6 (#2E2A2A at 60% on white) measures 3.96:1, still failing
	   WCAG 1.4.3's 4.5:1 floor for this 12px text -- a contractual miss under
	   Bonza's WCAG 2.2 AA guarantee. 0.8 measures 7.42:1, comfortably passing. */
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 7.42:1 at the applied 0.8 opacity on white (WCAG AA/AAA) */
	opacity: 0.8;
}

.woocommerce ul.products li.product .price ins {
	text-decoration: none;
}

/* Cost-per-day (86eypb6m9): only ever printed by bonza_category_cost_per_day()
   when a product has real chews-per-pack + daily-dose data, never a
   placeholder. Muted like .price del -- ink at 0.8 opacity measures 7.42:1
   on the white card bg, comfortably passing WCAG AA/AAA at this size. */
.woocommerce ul.products li.product .bcp-cost-per-day {
	order: 3;
	margin: 2px 8px 0;
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 400;
	font-size: 11px;
	line-height: 14px;
	text-transform: none;
	letter-spacing: normal;
	color: var(--wp--preset--color--bhp-ink, #2E2A2A);
	opacity: 0.8;
}

/* z8udzket44: no "every 60 days" on the card. Figma's card price is the
   amount alone (node 29323:47306), the card carries no frequency choice,
   and View More opens the PDP where the delivery interval is picked. */
.woocommerce ul.products li.product .price .subscription-details {
	display: none;
}

/* Figma "saving-badge": 4/8 padding, radius 4, white Kobe1.1 Bold. Text is
   the 12px floor (Figma 10px). The fill is a fixed #BF4940 (5.0:1 with
   white, WCAG AA), not a token: bhp-red is not registered here and
   bhp-coral resolves to #FF6256, which measures 2.9:1 with white and
   fails AA at this size. Order 4 puts it after the price
   (order 3) and before View More (order 4, later in the DOM). */
.woocommerce ul.products li.product .bcp-card-save {
	order: 4;
	align-self: flex-start;
	margin: 4px 8px 0;
	padding: 4px 8px;
	border-radius: 4px;
	background: #BF4940; /* editor-friendly-ok: no registered palette slug is a red that passes AA with white */
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 700;
	font-size: 12px;
	line-height: 12px;
	color: var(--wp--preset--color--bhp-white, #FFFFFF);
}

/* 86eypb6j8: in compact cards (.bpc-price is a block of inline spans) the "every N months"
   text wrapped mid-phrase and its inline box spanned the same line as "From:" (bounding
   boxes overlapped). Own line = clean break, same two-line height as before. */
.bpc-card .bpc-price .subscription-details {
	display: block;
}

/* Real WooCommerce sale badge (Figma "Sale#29089:6" state) -- New/Best
   Seller/Pre-order have no equivalent meta field on this site yet (see
   file header), so only .onsale is styled. */
.woocommerce ul.products li.product .onsale {
	order: 0;
	position: absolute;
	top: 8px;
	left: 8px;
	right: auto;
	margin: 0;
	padding: 4px 6px;
	min-height: 0;
	min-width: 0;
	border-radius: 999px;
	background: var(--wp--preset--color--bhp-cream, #F8EDE3);
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 900;
	font-size: 12px; /* WCAG floor 12px (Figma 8px), 86eypb6j8 */
	line-height: 16px;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 12.30:1 on the cream #F8EDE3 badge bg (WCAG AA/AAA) */
}

/* CTA button: the base blaze-blocksy theme already renders this as
   a.button.bc-see-more-link with a working arrow-icon SVG (confirmed live,
   20x20, visible) -- only the pill/green skin and the "VIEW MORE" label
   (relabelled in category-page.php, not here) are this file's job.

   WCAG 2.2 AA fix, 86eypb6me: these rules never reached the "Build Your
   Dog's Routine" grid (product-page-marketing.php's bppm-routine section).
   That grid calls wc_get_template_part('content','product') directly, so
   the li.product/.ct-woo-card-actions/a.button markup this file already
   targets IS present -- but the grid's own wrapper is a bare
   <ul class="bppm-routine__grid">, with no .woocommerce ancestor and no
   ul.products class. Every selector below requires
   ".woocommerce ul.products li.product", so none of them could ever match
   there, and the button fell through to an unstyled default: measured live
   at rgb(255,255,255) on rgb(40,114,250) (#2872fa, Blocksy's global "Link
   Initial Color"), 15px/500 -- 4.31:1, below the 4.5:1 normal-text floor
   (15px/500 doesn't clear the 18.66px-bold/24px-regular large-text
   threshold). 6 nodes measured failing on the live "Build Your Dog's
   Routine" grid this way; a separate second grid on the same template
   already resolves through this exact rule (4 nodes measured passing at
   5.23:1) -- corrects the source audit's "7 nodes sitewide" to 6 actually
   failing, 4 already passing.

   Fix is structural, not a repaint: add ".bppm-routine__grid li.product"
   as a sibling selector everywhere below, so the grid's cards resolve
   through the SAME #247B4E-on-white pair already measured at 5.23:1,
   rather than inventing a new colour. Confirmed against Figma
   (checklist-pdp.json, "PRODUCT CARD > Frame 1261154771 > Button", all
   breakpoints) that #247B4E/rgb(36,123,78) is the design's own fill for
   this exact button, not a borrowed value. Deliberately NOT adding
   .woocommerce/ul.products classes to the grid markup itself -- that would
   pull in WooCommerce's grid layout CSS and fight bppm-routine__grid's own
   flex/grid layout, a regression risk this task doesn't need to take.

   Why :is() rather than a comma-separated pair. The two ancestor chains
   match provably disjoint elements -- the routine grid has no .woocommerce
   ancestor, which IS this bug -- but they carry different specificity, so
   listing them as siblings made stylelint's no-descending-specificity fire
   on every :hover and :focus-visible rule: the shorter chain plus a
   pseudo-class scores below the longer chain's base rule, whatever the
   source order. :is() takes the specificity of its most specific argument,
   so both branches resolve at one uniform weight and the ordering problem
   disappears without duplicating a declaration or muting the lint. The file
   already requires color-mix() (Safari 16.2+), so :is() (Safari 14+) adds
   no new browser floor.

   The :focus-visible outline rule below now reaches the routine grid too.
   It previously did not, so those six buttons would have gained a hover
   state and still had no visible keyboard focus ring.

   86eypb6me: `width: auto` added below fixes the Related Products button
   losing its right-side inset. The base child theme (NOT this custom/ tree
   -- blocksy-child/assets/css/components/woo-single.css, confirmed via
   document.styleSheets) carries
   ".related.products .ct-woo-card-actions, .bc-recently-viewed
   .ct-woo-card-actions, .ct-suggested-products .ct-woo-card-actions {
   width: 100% }" with no competing width declaration anywhere, so it was
   the only rule setting width and applied unopposed. `li.product` is
   `display:flex; flex-direction:column` (top of this file), so
   .ct-woo-card-actions is a flex item on the cross axis with default
   `align-items: stretch` -- an explicit width:100% plus this rule's own
   8px+8px side margins put the box at 100% of the card's content width
   PLUS 16px of margin, overflowing the right edge by 16px total (8px
   swallowed by the left margin pushing the box right, 8px left over on
   the right); li.product's `overflow: hidden` (top of this file) clipped
   that overflow instead of showing it, so the button read as flush right
   with no inset while the left inset looked correct by coincidence.
   Measured live at 1024px and 1512px (`.related.products` is
   `ct-hidden-sm ct-hidden-md`, so it never renders below ~1024):
   .ct-woo-card-actions left/right gap-from-card-edge was 8px / -8px
   before this fix, 8px / 8px after, matching the category chip/title/
   price rows' existing (pre-verified) 8px inset on the same card. Fixed
   by overriding width to `auto` on this selector, which already outranks
   the base theme's 3-class rule by specificity alone (0,4,2 via :is()'s
   .woocommerce ul.products li.product branch, vs 0,3,0) -- confirmed
   winning with no !important, and confirmed no regression on the
   `.bppm-routine__grid` card this same selector also reaches (8px/8px
   before and after, at 375/1024/1512px). Per MDN's flexbox alignment spec,
   a cross-axis `auto` width under the default `align-items: stretch`
   resolves to "as close to filling the container as possible" while still
   respecting the box's own margins, which is exactly the fill-minus-
   margins behaviour this fix restores. Figma draws no Related Products or
   Recently Viewed section at all (checked every node's leaf_name/text
   across both PDP templates, all 8 breakpoints, checklist-pdp.json,
   60,141 rows, zero matches) -- the shared PRODUCT CARD component's own
   8px insets are the only applicable Figma reference, and this fix makes
   the button match what the card's other rows already render. */
:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions {
	order: 4;
	margin: 12px 8px 0;
	width: auto;
}

:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions a.button {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: 100%;
	padding: 13px 16px;
	border-radius: 999px;
	background: var(--wp--preset--color--bhp-green, #247B4E);
	font-family: var(--wp--preset--font-family--bhp-heading, "Nominee", sans-serif);
	font-weight: 900;
	font-size: 12px; /* WCAG floor 12px (Figma 10px), 86eypb6j8 */
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--bhp-white, #FFFFFF);
	text-decoration: none;
	border: none;
	box-shadow: none;
}

:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions a.button svg {
	width: 16px;
	height: 16px;
	fill: currentColor;
	color: var(--wp--preset--color--bhp-white, #FFFFFF);
}

/* #FFFFFF on #247B4E measures ~5.3:1, the same pair already verified for
   this exact green in category-page.css's own WCAG note. No registered
   "darker green" palette slug exists to hover into (see the wishlist-heart
   note above), so color-mix() darkens the registered bhp-green directly --
   computed white-on-darkened-bg is ~6.65:1, better than the base pair,
   unlike filter: brightness() which dims the white label too and drops the
   ratio toward the AA floor instead of away from it. Literal #1F6942
   fallback first (the same 85%-toward-black mix, precomputed FROM the
   registered bhp-green token, not an invented colour) for Safari
   <16.2/Chrome+Edge <111/Firefox <113, which drop an unsupported
   color-mix() declaration entirely rather than falling back to it --
   without this line those browsers would show no hover background at
   all. editor-friendly-ok: a var()-wrapped color-mix() input still
   isn't itself a preset token once mixed, so the pre-color-mix()
   fallback line is necessarily a literal computed from that preset,
   same as every other var(--x, #hex) fallback in this file already is. */
:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions a.button:hover,
:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions a.button:focus-visible {
	background: #1F6942;
	background: color-mix(in srgb, var(--wp--preset--color--bhp-green, #247B4E) 85%, #000);
	color: var(--wp--preset--color--bhp-white, #FFFFFF);
}

:is(.bppm-routine__grid li.product, .woocommerce ul.products li.product) .ct-woo-card-actions a.button:focus-visible {
	outline: 2px solid var(--wp--preset--color--bhp-ink, #2E2A2A); /* 14.18:1 UI-boundary on white (WCAG 1.4.11 3:1 floor) */
	outline-offset: 2px;
}

/* Badge stack (86eypb6m9 CAT-08b): category-card.php unhooks WooCommerce's
   own loop sale-flash and renders Best Seller + Sale together here instead,
   so the two can never occupy the same absolute-positioned corner at once
   (see that file's own header for the collision this replaces). */
.woocommerce ul.products li.product .bcp-card-badges {
	order: 0;
	position: absolute;
	top: 8px;
	left: 8px;
	right: auto;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
}

.woocommerce ul.products li.product .bcp-card-badge {
	padding: 4px 6px;
	border-radius: 999px;
	background: var(--wp--preset--color--bhp-cream, #F8EDE3);
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-weight: 900;
	font-size: 12px; /* WCAG floor 12px (Figma 8px), 86eypb6j8 */
	line-height: 16px;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 12.30:1 on the cream #F8EDE3 badge bg (WCAG AA/AAA) */
}

.woocommerce ul.products li.product .bcp-card-badge--best {
	background: var(--wp--preset--color--bhp-yellow, #FFD874);
	/* 86eyy8hud: Figma draws the Best Seller badge (I36250:89836;34250:86687;29323:47327) in Nominee Heavy Extended, lh 14, ls 0. Size stays at the 12px floor above (Figma 10px). */
	font-family: var(--wp--preset--font-family--bhp-heading, "Nominee", sans-serif);
	line-height: 14px;
	letter-spacing: 0;
}

/* Star rating + verified count (category-card.php, empty until Feefo has a
   count for the SKU). */
.woocommerce ul.products li.product .bcp-card-rating {
	order: 3;
	margin: 4px 8px 0;
	display: flex;
	align-items: baseline;
	gap: 4px;
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-size: 12px;
	line-height: 1.4; /* >=1.2x, 86eypb6j8 */
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 14.18:1 on white (WCAG AA/AAA) */
}

.woocommerce ul.products li.product .bcp-card-rating__score {
	font-weight: 900;
}

.woocommerce ul.products li.product .bcp-card-rating__count {
	opacity: 0.8; /* 7.42:1 at this opacity on white, same pair verified elsewhere in this file */
}

/* 86eypb6j8: Blocksy/Woo out-of-stock label rendered 12px on a 13.2px line (1.1x). */
.out-of-stock-badge {
	line-height: 1.4;
}

/* One-time/subscribe picker (includes/product-card.php).
   Unscoped to an ancestor on purpose: the same .bpc-mode
   markup renders inside both .bpc-card (homepage) and the native
   li.product loop (category-card.php) -- one ruleset covers both. */
.bpc-mode {
	order: 3;
	margin: 8px 8px 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.bpc-mode__row {
	display: flex;
	align-items: center;
	gap: 6px;
	font-family: var(--wp--preset--font-family--bhp-body, "Kobe1.1", sans-serif);
	font-size: 12px;
	line-height: 16px;
	color: var(--wp--preset--color--bhp-ink, #2E2A2A); /* 14.18:1 on white (WCAG AA/AAA) */
}

.bpc-mode__row.is-unavailable {
	opacity: 0.5;
}

.bpc-mode__label {
	flex: 1 1 auto;
}

.bpc-mode__price {
	font-weight: 900;
}

.bpc-mode__save {
	margin: 0;
	line-height: 1.4;
	font-size: 12px; /* WCAG floor 12px (Figma 11px), 86eypb6j8 */
	color: var(--wp--preset--color--bhp-green, #247B4E); /* 4.5:1+ on white, verified elsewhere in this file at this weight/size */
}
