/* DTH BYD — theme-owned WooCommerce block styling (BY-14).
   Aligns the cart / checkout / single-product block surfaces to the live storefront's
   Kadence + ShopKit look — type, weight and colour only (totals, shipping, GST and
   payment already match live). Enqueued globally like fluentform.css; every rule is
   scoped to a WooCommerce block/class so non-WC pages stay untouched.
   Live reference values combed at 1440 against byd.dthmedia.com.au. */

/* --- Shared WC block text colour: live uses rgb(45,55,72); the theme default is the
       lighter rgb(74,85,104). Colour inherits, so setting it on the block wrappers
       fixes labels, totals and summary text in one place. --- */
.wp-block-woocommerce-cart,
.wp-block-woocommerce-checkout {
	color: rgb(45, 55, 72);
}

/* Order summary / totals body text: live renders 14.4px, the theme default is 14px. */
.wc-block-components-totals-item__label,
.wc-block-components-totals-item__value,
.wc-block-components-order-summary-item__description,
.wc-block-components-order-summary-item__total-price {
	font-size: 14.4px;
	color: rgb(45, 55, 72);
}

/* --- Primary filled buttons (cart "Proceed to checkout", checkout "Place order"):
       live is Montserrat 400 / 18px; the theme renders them 700 / 14–17px. --- */
.wc-block-components-button.wp-element-button {
	font-family: "Montserrat", sans-serif;
	font-weight: 400;
	font-size: 18px;
	/* Live rounds these submit buttons 3px; the block default renders them square. */
	border-radius: 3px;
}

/* --- Cart item title: live is dark and un-underlined; the theme renders it as a
       blue underlined link. (Font-size stays WC's 14px — 0.4px under live's 14.4px,
       sub-pixel and not worth an escalating-specificity override.) --- */
.wc-block-components-product-name {
	color: rgb(45, 55, 72);
	text-decoration: none;
}

/* --- Checkout step + order-summary headings: live 20px, theme 17px. Scoped through the
       block wrapper so it beats WooCommerce's own single-class step-title rule. --- */
.wp-block-woocommerce-checkout .wc-block-components-title,
.wp-block-woocommerce-cart .wc-block-components-title {
	font-size: 20px;
}

/* --- Cart line-item + totals-heading text. SOURCE: live byd.dthmedia.com.au /cart/
       | dealer @1440 2026-10-01: live (Kadence) renders cart block text at 14.4px /
       20.16px; dev's dealer-portal small preset is 14px / 19.6px, so the line-item names,
       prices and the "Cart totals" heading read a touch small. Match live, scoped to
       the cart block (the totals-item rows already sit at 14.4px above). --- */
.wp-block-woocommerce-cart .wc-block-components-product-name,
.wp-block-woocommerce-cart .wc-block-cart-item__prices,
.wp-block-woocommerce-cart .wc-block-cart-item__total,
.wp-block-woocommerce-cart .wc-block-cart__totals-title {
	/* !important: WooCommerce's cart.css scopes the line-item name/price through the
	   row (.wc-block-cart-items__row ...), out-specifying a plain block-scoped rule. */
	font-size: 14.4px !important;
	line-height: 20.16px !important;
}

/* --- Single product ------------------------------------------------------- */
/* Product title (H1): live 32px / line-height 1.5; theme x-large preset is 34px / 1.2. */
.dth-single-product .wp-block-post-title {
	font-size: 32px;
	line-height: 1.5;
}

/* Price: live 16px / rgb(45,55,72); theme 17px / rgb(74,85,104). */
.dth-single-product .wc-block-components-product-price {
	font-size: 16px;
	color: rgb(45, 55, 72);
}

/* Short description: rendered via the [dealer_portal_short_description] shortcode so the
   stored HTML list (ul/li + bold-italic) survives — the core/post-excerpt block
   flattened it to a run-on plain paragraph. SOURCE: live byd.dthmedia.com.au
   /product/byd-attoverse-atto-2-poster/ | dealer @1440 2026-10-01: wrapper
   17px/27.2px/#2D3748 margin 17px 0 34px; p margin 0 0 17px; ul disc margin
   0 0 25.5px 25.5px. Match live. */
.dth-single-product .woocommerce-product-details__short-description {
	font-size: 17px;
	line-height: 27.2px;
	color: rgb(45, 55, 72);
	margin: 17px 0 34px;
}
.dth-single-product .woocommerce-product-details__short-description p {
	margin: 0 0 17px;
}
.dth-single-product .woocommerce-product-details__short-description ul {
	list-style: disc outside;
	margin: 0 0 25.5px 25.5px;
	padding-left: 0;
}

/* Add-to-cart button: live Montserrat 400 / 18px; theme 700 / 17px. */
.single_add_to_cart_button {
	font-weight: 400;
	font-size: 18px;
	border-radius: 3px;
}

/* Variation (pa_style) dropdown. SOURCE: live byd.dthmedia.com.au
   /product/byd-attoverse-atto-2-poster/ | dealer @1440 2026-10-01: select
   17px Montserrat #2D3748, 1px solid #CBD5E0, square, padding 3.4px 35px 3.4px 8.5px,
   appearance:none with a grey chevron SVG at 98% 50%, min-width 75% of a full-width
   variations table (renders ~362px). Dev rendered a raw 14px black browser select
   (193px) inside a shrink-wrapped table. Widen the table to 100% and restyle the
   select to live. */
/* WooCommerce core (woocommerce.css) + blocktheme (woocommerce-blocktheme.css) style
   the variation select at a higher specificity (font-size small/14px, min-width 70%,
   a black feather chevron), so live's values need !important to win. */
.single-product table.variations {
	width: 100% !important;
}
.single-product .variations select {
	width: 362px !important;
	max-width: 100%;
	height: 36px !important;
	font-size: 17px !important;
	line-height: 27.2px;
	font-family: "Montserrat", sans-serif;
	color: rgb(45, 55, 72);
	border: 1px solid rgb(203, 213, 224);
	border-radius: 0;
	padding: 3.4px 35px 3.4px 8.5px !important;
	background-color: #fff;
	background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNSIgaGVpZ2h0PSIyNSIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiNiYmIiPjxwYXRoIGQ9Ik02IDlsNiA2IDYtNiIvPjwvc3ZnPg==") !important;
	background-repeat: no-repeat;
	background-position: 98% 50% !important;
	-webkit-appearance: none;
	appearance: none;
}

/* Gallery fills the full summary column like live (589px). The block wrapper
   inherited a max-width:512px from the template column's width attribute, capping the
   image narrower than live; drop the cap so the image fills the column. */
.single-product .wp-block-woocommerce-product-image-gallery {
	max-width: 100%;
	width: 100%;
}

/* Single-product gallery: keep wide/tall collateral IN FRAME, matching the archive
   tiles. SOURCE/operator restyle 2026-10-02: commit 0a16a81b dropped the gallery box so
   a wide Windscreen (~2.8) went edge-to-edge and the box collapsed to the image's own
   height, while a tall Pull Up (~0.43) ballooned the column to ~1370px tall. Box the
   gallery to the same uniform 5:7 (300/420) the tiles use and contain the image inside
   it: a wide banner letterboxes top/bottom, a tall one left/right, a 5:7 poster fills it.
   The box goes on .woocommerce-product-gallery__wrapper (the flexslider main-image track),
   NOT the outer .woocommerce-product-gallery — the zoom trigger and the (future
   multi-image) .flex-control-thumbs strip are siblings of the wrapper, so leaving them
   outside the box keeps the lightbox trigger and thumbnails unclipped. The letterbox is
   white (#fff, matching the page — Dave asked for the grey behind products removed) with
   a 4px radius (all four corners here, the image is standalone). The lightbox/PhotoSwipe overlay uses
   the full-size image independently of this box, so zoom still shows the whole image. */
.single-product .woocommerce-product-gallery__wrapper {
	aspect-ratio: 300 / 420;
	overflow: hidden;
	background-color: #fff;
	border-radius: 4px;
}
.single-product .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image,
.single-product .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image > a {
	width: 100%;
	height: 100%;
}
.single-product .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image img,
.single-product .woocommerce-product-gallery__wrapper img.wp-post-image {
	width: 100% !important;
	height: 100% !important;
	object-fit: contain !important;
	object-position: top !important;
}

/* BY-131: vertical elasticity on desktop. A short product (a wide banner, a square
   cube) in a fixed 5:7 box left white space below the gallery while the summary column
   ran taller, so the two columns did not share a bottom edge. On desktop (two columns),
   let the gallery stretch to the summary's height: a flex chain from the column down to
   the __wrapper fills the row height, the fixed aspect-ratio is released, and the image
   (object-fit:contain, object-position:top above) sits flush at the top with the white
   letterbox falling to the shared bottom edge. Below the wp-columns breakpoint (781px)
   the columns stack and the base aspect-ratio: 300/420 holds, so mobile is unchanged. */
@media (min-width: 782px) {
	.dth-single-product {
		align-items: stretch;
	}
	.dth-single-product > .wp-block-column:first-child,
	.single-product .wp-block-woocommerce-product-image-gallery,
	.single-product .woocommerce-product-gallery {
		display: flex;
		flex-direction: column;
		flex: 1 1 auto;
		min-height: 0;
	}
	/* Push the gallery down so the image TOP lines up with the title's visible letter
	   tops (cap height), not the column edge or the title's line-box (Dave, BY-131).
	   The title is 32px / 48px line-height with a 16px top margin, so its caps start
	   ~31px below the column top: 16px margin + 8px half-leading + the ascent-to-cap
	   gap (measured 290 vs column top 259). Padding on the column shifts the whole
	   gallery down as a unit; margin on the inner wrapper does not work here —
	   WordPress's first-child margin reset and flexslider zero it. The box still runs
	   to the shared bottom edge. Desktop only — mobile stacks. */
	.dth-single-product > .wp-block-column:first-child {
		padding-top: 10px; /* cap-top math gives 31px; Dave nudged it 21px up for optical balance */
	}
	.single-product .woocommerce-product-gallery__wrapper {
		aspect-ratio: auto;
		flex: 1 1 auto;
		min-height: 0;
	}
}

/* BY-131 mobile: the columns stack below 781px, so there is no summary column to
   match and the fixed 5:7 box just left a tall empty tail under a short product (a
   round decal, a square cube). On mobile, size the box to the image's natural shape
   instead, capped at 75vh so a tall pull-up banner still can't run away. */
@media (max-width: 781px) {
	/* The add-to-cart form is a grid; on mobile its quantity cell let the stepper sit a
	   few px in from the card's left edge, so it no longer lined up with the price above
	   and the full-width Add-to-cart button below. Pin the stepper hard to the cell start
	   and clear any left margin so all three share one left edge. */
	.single-product form.cart .quantity {
		justify-self: start;
		margin-left: 0;
	}
	.single-product .woocommerce-product-gallery__wrapper {
		aspect-ratio: auto;
		max-height: 75vh;
	}
	.single-product .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image img,
	.single-product .woocommerce-product-gallery__wrapper img.wp-post-image {
		height: auto !important;
		max-height: 75vh;
	}
}
/* Round ALL FOUR gallery corners. The outer .woocommerce-product-gallery also carries the
   #EDF2F7 letterbox (theme.json) at the EXACT same rect as the rounded wrapper, so its
   square corners filled in behind the wrapper's 4px radius — identical grey, so the rounding
   read as square (notably the bottom). The wrapper now owns the grey letterbox, so clear the
   outer one; the wrapper's rounded grey box then shows its radius on all four corners against
   the page. (A transparent decal still gets grey from the wrapper, which covers the same rect.) */
body.single-product .woocommerce-product-gallery {
	background-color: transparent;
}

/* --- Loading spinner for lazy campaign images (archive tiles + single-product gallery + home grid) ---
   Campaign artwork is big lossless PNG served with loading="lazy", so a tile/gallery image can
   take a beat to paint. While it is still loading, show a subtle thin spinner centered on the
   #EDF2F7 letterbox; the image fades in over it once loaded. assets/js/image-loading.js adds
   .is-loading to a box whose img has NOT finished loading and removes it on load/error — so a
   cached/instant image (img.complete at init) is never marked and the spinner never flashes.
   Pure CSS can't do this: it couldn't hide the spinner in the letterbox after load, nor skip
   cached images. Scoped to the two boxes created above. */
.wp-block-woocommerce-product-collection .wc-block-components-product-image,
.single-product .woocommerce-product-gallery__wrapper,
.dth-cat-thumb {
	position: relative;
}
/* The home dealer grid wraps each tile image in .dth-cat-thumb (functions.php)
   so the spinner has an image-only box; the span is a block so the img keeps the
   full tile width it had as a direct <a> child. */
.dth-cat-thumb {
	display: block;
}
.wp-block-woocommerce-product-collection .wc-block-components-product-image img,
.single-product .woocommerce-product-gallery__wrapper img,
.dth-cat-thumb img {
	transition: opacity 0.3s ease;
}
.wp-block-woocommerce-product-collection .wc-block-components-product-image.is-loading img,
.single-product .woocommerce-product-gallery__wrapper.is-loading img,
.dth-cat-thumb.is-loading img {
	opacity: 0;
}
.wp-block-woocommerce-product-collection .wc-block-components-product-image.is-loading::after,
.single-product .woocommerce-product-gallery__wrapper.is-loading::after,
.dth-cat-thumb.is-loading::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 28px;
	height: 28px;
	margin: -14px 0 0 -14px;
	border: 3px solid rgba(113, 128, 150, 0.25); /* muted-2 #718096, faint track ring */
	border-top-color: #718096;                   /* muted-2, the spinning head */
	border-radius: 50%;
	animation: dth-img-spin 0.7s linear infinite;
	pointer-events: none;
	z-index: 1;
}
@keyframes dth-img-spin {
	to { transform: rotate(360deg); }
}

/* Add-to-cart quantity: a connected stepper — grey minus / plus buttons flush either
   side of the bordered number box (qty-stepper.js injects the buttons). Only the number
   keeps a border; the buttons are borderless grey squares butted against it, so there is
   no double line and no gap. The native number spinner is hidden. */
.quantity {
	display: inline-flex;
	align-items: stretch;
}
.quantity input.qty {
	font-size: 17px;
	color: rgb(74, 85, 104);
	background: #fff;
	border: 1px solid rgb(203, 213, 224);
	border-radius: 0;
	/* !important beats the theme's own `.single-product .quantity .qty { width:62px }`
	   and WooCommerce core's `margin-right:0.5em` on the qty, both higher-specificity;
	   without it the buttons sit apart from the number with a gap on the right. */
	width: 54px !important;
	height: 40px;
	padding: 0 !important;
	margin: 0 !important;
	text-align: center;
	-moz-appearance: textfield;
	appearance: textfield;
}
.quantity input.qty::-webkit-outer-spin-button,
.quantity input.qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
.dth-qty-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	/* No fixed height: the flex row's `align-items: stretch` makes each button match
	   the number box's FULL outer height, including its 1px top+bottom border, so the
	   three sit perfectly level regardless of the input's box model. */
	align-self: stretch;
	padding: 0;
	margin: 0;
	border: 0 !important;
	background: rgb(237, 242, 247);
	color: rgb(74, 85, 104);
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	user-select: none;
	-webkit-appearance: none;
	appearance: none;
}
.dth-qty-btn.dth-qty-minus {
	border-radius: 4px 0 0 4px;
}
.dth-qty-btn.dth-qty-plus {
	border-radius: 0 4px 4px 0;
}
.dth-qty-btn:hover {
	background: rgb(226, 232, 240);
}
.dth-qty-btn:active {
	background: rgb(203, 213, 224);
}

/* --- Classic WooCommerce form inputs (login, register, account details, lost password,
       coupon): live styles them 17px / rgb(74,85,104) / 1px rgb(203,213,224) / 3px radius;
       the theme leaves them at WC/browser defaults (14px, dark border, 4px). The block
       checkout/cart inputs use different classes and already match live, so they are
       untouched here. --- */
.woocommerce form .input-text,
.woocommerce-Input.input-text {
	font-size: 17px !important;
	color: rgb(74, 85, 104) !important;
	border: 1px solid rgb(203, 213, 224) !important;
	border-radius: 3px !important;
}

/* Cart block quantity selector: distinct from the single-product `.quantity input.qty`
   above (different block class). Live rounds it 3px; the block default renders it square. */
.wc-block-components-quantity-selector__input {
	border-radius: 3px;
}

/* My-account nav: the classic navigation renders as a bulleted <ul> locally; live has
   no list markers. */
.woocommerce-MyAccount-navigation ul {
	list-style: none;
}

/* --- Responsive parity pass (local -> live), combed 390 + 1440 against
       byd.dthmedia.com.au. --- */

/* Kadence "global fill" buttons (cart "Continue shopping" etc.) fall back to the
   indigo #3633E1 default locally; live uses the brand blue accent. */
.kb-button.kb-btn-global-fill,
.wc-block-cart .kb-button.kb-btn-global-fill {
	background-color: #2B6CB0;
}
.kb-button.kb-btn-global-fill:hover {
	background-color: #2c5282;
}

/* Empty-cart heading: live tightens the bottom margin (14.11px -> 8.5px). */
.wp-block-woocommerce-empty-cart-block h2,
.wc-block-cart__empty-cart__title {
	margin: 0 0 8.5px;
}

/* --- Archive/catalogue product thumbnails (Product Collection block) ---
   SOURCE: live byd.dthmedia.com.au /product-category/{02-byd-attoverse-atto-2,
   11-on-roads-on-us-sealion-7} | dealer @1440 2026-10-01: EVERY archive thumbnail
   renders a uniform 281x393 portrait box (300:420 = 5:7), object-fit cover, across
   posters, flyers, pull-up/windscreen banners and the decal. Live's collateral is all
   authored to that 5:7 portrait ratio, so cover crops nothing; the uniform box is what
   keeps rows balanced.
   The earlier build boxed these to 1:1 SQUARE, which cropped the tops off the tall
   5:7 posters. The fix is NOT to drop the box (that let mixed pixel-sizes render at
   natural size and blew up rows) but to box them to live's real 5:7 portrait ratio:
   the 5:7 artwork fills it with zero crop, and any odd-aspect image crops to fill the
   way live's server-side catalog-thumbnail crop does. Scoped to the collection block,
   so the single-product gallery is untouched.

   CONTAIN (operator restyle 2026-10-01): cover made a tall Pull Up Banner (~0.44)
   and a wide Windscreen Banner (~2.8) both fill the same 5:7 box identically — you
   couldn't read their true shape and the tall banner's "BYD ..." top header was
   clipped. Switch the image to object-fit:contain so it scales until it touches the
   box on ONE axis then stops: a tall poster shows tall-and-narrow, a wide one
   wide-and-short, conveying the real shape with nothing cropped. The box stays a
   uniform 5:7 across every tile so rows still align; the leftover letterbox fills
   with white (#fff) — matching the page and the single-product gallery (Dave asked
   for the grey behind products removed, both surfaces). Reuse the card's 4px top
   radius (.wc-block-product) on the box so the rounded top edge survives. The product-collection
   block prints the img with an INLINE style="object-fit:cover", which beats a plain
   selector, so object-fit needs !important to flip to contain (same reason the
   variation-select rules above carry !important). */
.wp-block-woocommerce-product-collection .wc-block-components-product-image {
	display: block;
	aspect-ratio: 300 / 420;
	overflow: hidden;
	background-color: #fff;
	border-radius: 4px 4px 0 0;
	transition: opacity 0.2s ease;
}

/* BY-130: hover feedback on the archive. With the letterbox now white, a small
   heavily-letterboxed product (passport, decal) can read as static. Dimming the
   whole image box — the product AND its white background — to 70% opacity on hover
   gives a clear interactive cue. */
.wp-block-woocommerce-product-collection .wc-block-components-product-image:hover {
	opacity: 0.7;
}
.wp-block-woocommerce-product-collection .wc-block-components-product-image a,
.wp-block-woocommerce-product-collection .wc-block-components-product-image img {
	width: 100%;
	height: 100%;
	object-fit: contain !important;
	object-position: center;
}

/* Kadence's roomier archive grid gap (Woo block default 1.25em -> Kadence 2.5rem). */
.wp-block-woocommerce-product-collection .wc-block-product-template.is-flex-container {
	gap: 2.5rem;
}

/* 06-sales-material is merch (folders/caps/ribbons/flyers), authored square like
   live's classic-loop 300x300 thumbs, NOT the 5:7 poster campaigns. Box it square
   so cover does not crop+upscale the square art. Scoped by WP archive body class. */
body.term-06-sales-material .wp-block-woocommerce-product-collection .wc-block-components-product-image {
	aspect-ratio: 1 / 1;
}

/* Order-received (thank-you) page: on a full order its billing/shipping address
   boxes (the last block of WooCommerce's block Order Confirmation) sat flush
   against the dark site footer with no gap. The footer template part is a
   sibling of <main>, so bottom padding on <main> opens a gap before it no matter
   which confirmation block renders last. Scoped by the WooCommerce body class so
   no other page shifts. */
body.woocommerce-order-received main {
	padding-bottom: var(--wp--preset--spacing--80, 4rem);
}

/* Black primary CTAs (BY-20). The dealer portal's WooCommerce buttons read black
   to match the BYD mark, superseding the old blue CTA. Covers Add to cart,
   Continue shopping, cart/checkout and Place order; the business-card Customize
   button reuses the Add to cart classes (.button.alt / .wp-element-button) so it
   is caught by the same rule. */
.woocommerce a.button, .woocommerce button.button, .woocommerce input.button,
.woocommerce #respond input#submit, .wc-block-components-button,
.wp-block-woocommerce-cart .wc-block-cart__submit-button,
.woocommerce a.button.alt, .woocommerce button.button.alt, .woocommerce input.button.alt,
.button.alt, .wp-element-button, .single_add_to_cart_button, .added_to_cart,
.wc-backward, .woocommerce .return-to-shop .button, .checkout-button,
.woocommerce #place_order, .woocommerce-cart .wc-proceed-to-checkout a.checkout-button {
	background-color: var(--dp-primary) !important;
	border-color: var(--dp-primary) !important;
	color: #fff !important;
}
.woocommerce a.button:hover, .woocommerce button.button:hover, .woocommerce input.button:hover,
.woocommerce a.button.alt:hover, .woocommerce button.button.alt:hover,
.button.alt:hover, .wp-element-button:hover, .single_add_to_cart_button:hover, .added_to_cart:hover,
.wc-backward:hover, .woocommerce .return-to-shop .button:hover, .checkout-button:hover,
.woocommerce #place_order:hover, .woocommerce-cart .wc-proceed-to-checkout a.checkout-button:hover {
	background-color: var(--dp-primary-hover) !important;
	border-color: var(--dp-primary-hover) !important;
	color: #fff !important;
}
