/*
Theme Name:         TrustUS Labs
Theme URI:          https://trustuslabs.com
Author:             Elliot Jemal
Description:        WooCommerce storefront block theme for TrustUS Labs. Built from
                    the client Figma handoff. PHP-only block registration, no JS
                    build step. All design values are tokens in theme.json.
Requires at least:  6.9
Tested up to:       7.1
Requires PHP:       8.3
Version:            0.1.1
License:            GPL-2.0-or-later
License URI:        https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:        trustus
Domain Path:        /languages
Tags:               block-theme, full-site-editing, e-commerce, woocommerce
*/

/*
 * Block themes take almost all styling from theme.json. Only rules that
 * theme.json genuinely cannot express belong here — and each one needs a reason.
 */

/* Wrapped headings never strand a single word in the design (sec-comparison-14:
   "Independently verified, / every batch."; sec-layout-237: "Scan the code on /
   your vial") where a greedy wrap leaves a one-word last line. text-wrap:pretty
   is exactly that rule — greedy wrapping plus orphan avoidance — where balance
   would even the lines further than the design does. theme.json has no
   text-wrap property. */
h1, h2, h3 {
	text-wrap: pretty;
}

/* Gradient-filled heading text. theme.json can set a gradient background on a
   block, but not clip it to the glyphs, which is what the hero H1 does. */
.trustus-gradient-text {
	background-image: var(--wp--preset--gradient--heading);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
	.trustus-gradient-text {
		color: var(--wp--preset--color--navy);
	}
}

/* ---------------------------------------------------------------------------
 * Component styles
 *
 * Everything below is here because theme.json cannot express it: list-marker
 * replacement, pseudo-element icons, and shape rules that apply to a specific
 * component rather than a block type. All values come from theme.json tokens —
 * there are no literals in this file beyond layout mechanics.
 * ------------------------------------------------------------------------- */

/* Hero trust badges — navy pills. A list, because it is a list of claims.
   core/list has no blockGap support, so the gaps for this and the other
   .trustus-* lists below are owned here, not by block attributes. */
.trustus-badges {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Design pill is 148x24 filled #054D7C (navy-mid) — sec-home-hero.png. The
   1.15 line-height is pill-height mechanics: 14px text x 1.15 + 2x4px padding
   = the design's 24px, where the root 1.5 would make a 29px pill. */
.trustus-badges > li {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--50);
	border-radius: var(--wp--custom--radius--pill);
	background-color: var(--wp--preset--color--navy-mid);
	color: var(--wp--preset--color--white);
	font-weight: 600;
	line-height: 1.15;
}

.trustus-badges > li::before,
.trustus-chips > li::before,
.trustus-checklist > li::before {
	content: "";
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	-webkit-mask: url("assets/images/icons/check.svg") no-repeat center / contain;
	mask: url("assets/images/icons/check.svg") no-repeat center / contain;
}

/* Credential chips — hairline-bordered pills that wrap into rows.
   Inline margins only: a shorthand margin reset here out-cascades the
   section group's blockGap rule and glues the chips to the heading, so the
   vertical margins stay with the layout system (the group's blockGap sets
   the start margin, the constrained-layout reset zeroes the end). */
.trustus-chips {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--70);
	margin-inline: 0;
	padding: 0;
	list-style: none;
}

.trustus-chips > li {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--80);
	border-radius: var(--wp--custom--radius--md);
	background-image: var(--wp--preset--gradient--chip);
	color: var(--wp--preset--color--navy);
	font-weight: 700;
}

/* The chip check mark is a thick gradient stroke in the design (sec-stats-50.png:
   ~5px stroke over a ~25px check, sky-deep at the lower-left tip rising to
   violet at the top-right — the heading-gradient stops at 45deg, not 135deg,
   so the direction is restated here from the same colour tokens). Badges stay
   currentColor. 1.35em is the design's icon-to-text ratio (~24px beside 18px
   text). */
.trustus-chips > li::before {
	width: 1.35em;
	height: 1.35em;
	background-color: transparent;
	background-image: linear-gradient(45deg, var(--wp--preset--color--sky-deep) 0%, var(--wp--preset--color--violet) 100%);
	-webkit-mask-image: url("assets/images/icons/check-bold.svg");
	mask-image: url("assets/images/icons/check-bold.svg");
}

/* Comparison checklist — check marks instead of bullets. Navy checks per the
   comparison cards; the product header's list uses deep purple (design). */
.trustus-checklist {
	margin: 0;
	padding: 0;
	list-style: none;
}

.trustus-checklist > li::before {
	background-color: var(--wp--preset--color--navy);
}

.trustus-getting .trustus-checklist > li::before {
	background-color: var(--wp--preset--color--purple-deep);
}

.trustus-checklist > li {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--40);
	padding-block: var(--wp--preset--spacing--30);
}

/* Stat figures carry a left rule in the design. */
.trustus-stat {
	border-left: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
}

/* Footer link columns are lists, not stacks of paragraphs. core/list has no
   blockGap support, so the design's 20px row rhythm is set here. */
.trustus-footer-nav {
	margin: 0;
	padding: 0;
	list-style: none;
}

.trustus-footer-nav > li + li {
	margin-top: var(--wp--preset--spacing--50);
}

/* Logo and icon figures should not inherit the block image margin. */
.trustus-logo,
.trustus-icon {
	margin: 0;
}

/* Buy Now — the product header's secondary CTA. Sits under Woo's gradient
   Add To Cart submit; outline treatment per the design. */
/* Follows the variation form's disabled state. Visual-only on purpose:
   pointer-events:none would not stop keyboard submits and would block the
   server-side out-of-stock rejection path the e2e suite exercises — Woo
   rejects the add server-side either way. */
.woocommerce-variation-add-to-cart-disabled .trustus-buy-now {
	opacity: 0.5;
	cursor: not-allowed;
}

.trustus-buy-now {
	display: block;
	width: 100%;
	margin-top: var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--80);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	font-weight: 600;
	cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Carousels — the design shows sliders (dot indicators, arrow buttons) for
 * the facility media and the catalog row. Native CSS scroll-snap does the
 * sliding; carousel.js only adds the dots/arrows chrome, so everything works
 * without JavaScript.
 * ------------------------------------------------------------------------- */
.trustus-carousel.trustus-carousel {
	display: flex;
	flex-wrap: nowrap; /* doubled class so Woo's .wc-block-product-template.is-flex-container grid loses */
	gap: var(--wp--preset--spacing--70);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	margin: 0;
	padding: 0;
	list-style: none;
}

.trustus-carousel::-webkit-scrollbar {
	display: none;
}

.trustus-carousel.trustus-carousel > * {
	flex: 0 0 100%;
	scroll-snap-align: start;
	margin: 0;
	/* Each slide is the containing block for its own contents. Without this,
	   WooCommerce's absolutely positioned product-image wrappers resolve
	   against an ancestor outside the scroller, escape the overflow, and add
	   their full row width to the document: the whole page scrolled sideways
	   into empty space. Invisible with three products, a 1046px drag once the
	   catalogue grew to eleven. */
	position: relative;
}

/* Catalog carousel tile sizing lives with the bleed rules near the end of
   this file — desktop tiles on the container token, mobile at 85%, in that
   cascade order so the mobile override wins inside its media query. */

/* Chrome added by carousel.js. */
.trustus-carousel-nav {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: var(--wp--preset--spacing--70);
}

.trustus-carousel-dots {
	display: flex;
	gap: var(--wp--preset--spacing--30);
}

.trustus-carousel-dot {
	position: relative;
	width: var(--wp--preset--spacing--30);
	height: var(--wp--preset--spacing--30);
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--radius--pill);
	background-color: var(--wp--preset--color--hairline);
	cursor: pointer;
}

/* WCAG 2.5.8: the dot stays 8px visually, but an invisible pseudo-element
   grows each button's hit area to 24x24 (8px + 8px on every side). */
.trustus-carousel-dot::after {
	content: "";
	position: absolute;
	inset: calc(-1 * var(--wp--preset--spacing--30));
}

.trustus-carousel-dot[aria-current="true"] {
	background-color: var(--wp--preset--color--navy);
}

.trustus-carousel-arrows {
	display: flex;
	gap: var(--wp--preset--spacing--50);
}

.trustus-carousel-arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--100);
	height: var(--wp--preset--spacing--100);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	font-size: 1.25rem; /* arrow glyph sizing inside the 48px button — typography mechanics, not a design token */
	line-height: 1;
	cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Catalog tiles — name/price row, soft image plate, gradient add-to-cart.
 * ------------------------------------------------------------------------- */
/* Woo's product-template renders tiles as <li class="wc-block-product">, not
   .wp-block-post — target the list items directly. Flex columns so the
   add-to-cart button's margin-top:auto bottom-aligns across the row. */
.trustus-catalog-carousel > li {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--40);
}

/* White, not paper: the plate shows beside contain-fit photos (tile box is
   wider than the 3:4 photography), and paper's blue cast seamed against the
   shots' own studio background, so the contain-letterbox bars are invisible.
   The client specified #e3e4e6 for the product image area (Alfons, 2026-08-27)
   and the photography was regenerated on exactly that grey, so plate and photo
   are the same colour. */
.trustus-catalog-carousel .wc-block-components-product-image img,
.trustus-catalog-carousel .wp-block-woocommerce-product-image img {
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--grey-200);
}

/* Tile names are ink in the design, not the link navy. */
.trustus-catalog-carousel .wp-block-post-title a {
	color: var(--wp--preset--color--ink);
}

.trustus-catalog-carousel .wp-block-woocommerce-product-button {
	margin-top: auto;
}

/* Design tiles use the primary-button gradient on Add to cart, same as the
   Shop GLP-R CTA (sec-product-12.png samples #D2BEFC -> #B6D7FA).
   background-color + background-image, never the shorthand: the shorthand
   resets background-color to transparent, so a failed gradient would expose
   core's dark fallback instead of the tokenised light one. */
.trustus-catalog-carousel .wp-block-woocommerce-product-button .wp-element-button {
	display: block;
	width: 100%;
	text-align: center;
	background-color: var(--wp--preset--color--lilac-tint);
	background-image: var(--wp--preset--gradient--primary-button);
	color: var(--wp--preset--color--navy);
	border: 0;
	border-radius: var(--wp--custom--radius--sm);
	font-weight: 600;
}

/* FAQ accordion — chevron instead of the default disclosure triangle. */
.trustus-faq details > summary {
	list-style: none;
	position: relative;
	cursor: pointer;
	padding-right: var(--wp--preset--spacing--100);
}

.trustus-faq details > summary::-webkit-details-marker {
	display: none;
}

.trustus-faq details > summary::after {
	content: "";
	position: absolute;
	right: var(--wp--preset--spacing--30);
	top: 50%;
	width: 0.6em;
	height: 0.6em;
	border-right: var(--wp--custom--stroke--thick) solid var(--wp--preset--color--navy);
	border-bottom: var(--wp--custom--stroke--thick) solid var(--wp--preset--color--navy);
	transform: translateY(-70%) rotate(45deg);
	transition: transform 0.15s ease;
}

.trustus-faq details[open] > summary::after {
	transform: translateY(-30%) rotate(225deg);
}

/* The design closes the accordion with a hairline above the first item too. */
.trustus-faq-list > .wp-block-details:first-child {
	border-top: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
}

/* Footer contact and legal links are underlined in the design. */
.trustus-underline-links a {
	text-decoration: underline;
}

/* Links inside running text need a non-colour distinguisher (axe
   link-in-text-block) — Woo's privacy-policy sentence is the offender. */
.woocommerce-privacy-policy-text a,
a.woocommerce-privacy-policy-link {
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
 * WooCommerce chrome the blocks/theme.json cannot reach.
 * ------------------------------------------------------------------------- */

/* Variable-product forms inject price + "N in stock" after a size is picked;
   reserve the space so the buttons below don't jump mid-interaction. */
.woocommerce-variation.single_variation {
	min-height: var(--wp--preset--spacing--100);
}

/* Purchase row: quantity beside a stretched Add To Cart, Buy Now full-width
   below — the design's stacked arrangement. */
.woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--wp--preset--spacing--40);
}

.woocommerce-variation-add-to-cart .single_add_to_cart_button {
	flex: 1 1 auto;
}

.woocommerce-variation-add-to-cart .trustus-buy-now {
	flex: 0 0 100%;
	margin-top: 0;
}

/* Static header cart link used on cart/checkout (see functions.php). */
.trustus-cart-link {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--100);
	height: var(--wp--preset--spacing--100);
	color: var(--wp--preset--color--ink);
}

.trustus-cart-link__badge {
	position: absolute;
	top: 0;
	right: 0;
	min-width: 1.4em;
	height: 1.4em;
	padding: 0 0.25em;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	line-height: 1.4em;
	text-align: center;
}

/* Woo's own button classes (checkout Place Order, account Log in, classic
   form submits) sit above theme.json's :where() specificity — restate the
   design's primary treatment for them. */
.wc-block-components-button:not(.is-link),
.woocommerce button.button:not(.trustus-buy-now),
.woocommerce a.button,
.woocommerce-page button.button:not(.trustus-buy-now) {
	/* longhands, not the background shorthand — see the catalog Add to cart
	   note: the tokenised background-color must survive a failed gradient. */
	background-color: var(--wp--preset--color--lilac-tint);
	background-image: var(--wp--preset--gradient--primary-button);
	color: var(--wp--preset--color--navy);
	border: 0;
	border-radius: var(--wp--custom--radius--sm);
	font-weight: 700;
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--70);
}

/* ---------------------------------------------------------------------------
 * Hover states. The design ships no hover frames, so these are deliberately
 * quiet: gradient surfaces dim a few percent (filter reaches through the
 * gradient where background-color cannot), bordered surfaces tint their
 * hairline. Colour/filter fades only — nothing moves, so there is no
 * transform to guard behind prefers-reduced-motion.
 * ------------------------------------------------------------------------- */
.wp-element-button,
.wc-block-components-button:not(.is-link),
.woocommerce button.button,
.woocommerce a.button,
.trustus-buy-now,
.trustus-carousel-arrow,
.trustus-carousel-dot,
.trustus-qty-btn {
	transition: filter 150ms ease, background-color 150ms ease, border-color 150ms ease;
}

/* Gradient-filled buttons: primary CTAs, Woo submits, catalog Add to cart.
   brightness alone at 0.96 moved the pastel gradient ~4 RGB levels — an
   invisible hover. Deepening saturation alongside a slightly stronger dim
   keeps the same hue but reads clearly. */
.wp-element-button:hover,
.wc-block-components-button:not(.is-link):hover,
.woocommerce button.button:not(.trustus-buy-now):hover,
.woocommerce a.button:hover {
	filter: brightness(0.94) saturate(1.4);
}

/* FAQ rows: the whole summary is the control; ink -> deep purple on hover,
   chevron included (its borders draw the glyph). */
.trustus-faq details > summary {
	transition: color 150ms ease;
}

.trustus-faq details > summary:hover {
	color: var(--wp--preset--color--purple-deep);
}

.trustus-faq details > summary:hover::after {
	border-color: var(--wp--preset--color--purple-deep);
}

/* White-surface controls: outline buttons, Buy Now, arrows, qty steppers.
   brightness() would grey the white fill, so tint the surface instead. */
.is-style-outline .wp-block-button__link:hover {
	filter: none;
	background-color: var(--wp--preset--color--paper-cool);
	border-color: var(--wp--preset--color--purple);
}

.trustus-buy-now:hover,
.trustus-carousel-arrow:hover,
.trustus-qty-btn:hover {
	background: var(--wp--preset--color--paper);
}

.trustus-carousel-dot:not([aria-current="true"]):hover {
	background-color: var(--wp--preset--color--dusty-blue);
}

/* ---------------------------------------------------------------------------
 * Verify page — batch lookup form and its server-rendered notice. Raw HTML
 * (core has no form block), so the component owns its look here, tokens only.
 * ------------------------------------------------------------------------- */
.trustus-verify-form {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
}

.trustus-verify-form__label {
	font-weight: 600;
	color: var(--wp--preset--color--navy);
}

.trustus-verify-form__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
}

.trustus-verify-form__input {
	flex: 1 1 60%;
	min-width: 0;
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--body);
}

.trustus-verify-notice {
	padding: var(--wp--preset--spacing--70);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--white);
}

.trustus-verify-notice__title {
	margin: 0 0 var(--wp--preset--spacing--30);
	font-weight: 600;
	color: var(--wp--preset--color--navy);
}

.trustus-verify-notice > p {
	margin: 0;
}

/* ---------------------------------------------------------------------------
 * Product-form quantity stepper — − / + touch targets around Woo's number
 * input (functions.php renders the buttons on product pages; mobile browsers
 * hide the native spinners). form.cart scope keeps the block cart/checkout
 * quantity UIs, which ship their own steppers, untouched.
 * ------------------------------------------------------------------------- */
form.cart .quantity {
	display: inline-flex;
	align-items: stretch;
	/* Match the Add to cart button so the purchase row lines up. The 781px
	   block below sets this for mobile; desktop had no height at all, leaving
	   a 24px stepper beside a 48px button. */
	min-height: var(--wp--preset--spacing--100);
}

form.cart .quantity .qty {
	width: var(--wp--preset--spacing--130);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: 0;
	text-align: center;
	appearance: textfield;
	-moz-appearance: textfield;
}

form.cart .quantity .qty::-webkit-outer-spin-button,
form.cart .quantity .qty::-webkit-inner-spin-button {
	appearance: none;
	margin: 0;
}

/* Woo core ships `.woocommerce div.product form.cart div.quantity .qty
   { margin-right: .5em }`, which opened an 8px gap before the + button and
   split the stepper pill. Its selector outranks ours, so match it. */
.woocommerce div.product form.cart div.quantity .qty {
	margin: 0;
}

.trustus-qty-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--100);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--body-large);
	line-height: 1;
	cursor: pointer;
}

.trustus-qty-btn--minus {
	border-right: 0;
	border-radius: var(--wp--custom--radius--sm) 0 0 var(--wp--custom--radius--sm);
}

.trustus-qty-btn--plus {
	border-left: 0;
	border-radius: 0 var(--wp--custom--radius--sm) var(--wp--custom--radius--sm) 0;
}

/* ---------------------------------------------------------------------------
 * Tablet band (600–781px). Core stacks every wp-block-columns below 781px;
 * the design has no tablet frame (1440/375, interpolate), and a stacked
 * product header at 768–781px leaves a band of dead space. Both rules need
 * !important to out-rank core's own !important stacking rules; 375 behaviour
 * is protected by the min-width bounds.
 * ------------------------------------------------------------------------- */

/* Product header: gallery and product columns side-by-side from 768px,
   core's own tablet breakpoint. */
@media (min-width: 768px) and (max-width: 781px) {
	.wp-block-columns.trustus-product-columns {
		flex-wrap: nowrap !important;
	}

	.wp-block-columns.trustus-product-columns > .wp-block-column {
		flex-basis: 50% !important;
	}
}

/* The four trust badges read as a 2×2 grid instead of one per row. */
@media (min-width: 600px) and (max-width: 781px) {
	.wp-block-columns.trustus-product-badges {
		flex-wrap: wrap !important;
		row-gap: var(--wp--preset--spacing--50);
	}

	.wp-block-columns.trustus-product-badges > .wp-block-column {
		flex-basis: calc(50% - var(--wp--preset--spacing--50) / 2) !important;
	}
}

/* User-typed batch numbers can be arbitrarily long; never let the echo
   stretch the page (the input caps at 64, this is belt and braces). */
.trustus-verify-notice {
	overflow-wrap: anywhere;
}

/* The active dot is navy-filled; the default ring drowns in it. Give dots a
   distinct focus ring so keyboard users can see focus on the current slide. */
.trustus-carousel-dot:focus-visible {
	outline: var(--wp--custom--stroke--thick) solid var(--wp--preset--color--purple-deep);
	outline-offset: var(--wp--custom--stroke--thick);
}

/* Hero at stacked widths: the design's mobile frame left-aligns the proof
   copy and keeps the bottle clear of text — headline and CTAs at the top,
   bottle in the middle, proof copy at the very bottom of the band on open
   snow. Pin the photo low, stretch the cover's inner flex chain, and let the
   wrapped column lines split to the band's ends (align-content works on the
   wrapped flex lines core creates when columns stack). */
@media (max-width: 781px) {
	.trustus-hero-proof p.has-text-align-right {
		text-align: left;
	}

	/* The landscape photo cannot cover the tall stacked band without the
	   bottle's bottom edge landing at ~82% of the band height — straight
	   through the bottom-pinned copy at narrow widths. The design's mobile
	   frame instead renders the photo at a smaller scale with white snow
	   below it, so: cap the image to the band's upper portion, show the
	   photo's snowfield foreground, and fade its cut edge into the white
	   page background (the snow is effectively white, so the seam vanishes). */
	.trustus-hero img.wp-block-cover__image-background {
		height: 72%;
		object-position: 50% 100%;
		-webkit-mask-image: linear-gradient(to bottom, black 82%, transparent 100%);
		mask-image: linear-gradient(to bottom, black 82%, transparent 100%);
	}

	.trustus-hero.wp-block-cover.has-custom-content-position {
		align-items: stretch;
	}

	.trustus-hero .wp-block-cover__inner-container {
		display: flex;
		flex-direction: column;
	}

	.trustus-hero .wp-block-cover__inner-container > .wp-block-columns {
		flex-grow: 1;
		align-content: space-between;
	}
}

/* The design butts every page's first section straight against the navbar
   strip (Home hero composite: navbar 0–72, hero photo starts at 72 —
   design-cache/screenshots/sec-home-hero.png). The root blockGap (16px)
   is right for content but paints a white seam between the header template
   part and <main>; sections carry their own 112px top padding, so the seam
   is pure surplus. theme.json cannot scope the root gap per-child. (All
   three selectors are needed: the root gap margins <main> itself; the
   constrained layout's generic child-gap rule out-cascades core's
   :first-child reset, so the first section carries its own 16px that
   collapses through; and on Woo pages the first child is the always-rendered
   empty wc-block-store-notices wrapper, which soaks up :first-child while
   the visible first section sits second.) */
.wp-site-blocks > main,
.wp-site-blocks > main > :first-child,
.wp-site-blocks > main > .wc-block-store-notices:first-child + * {
	margin-block-start: 0;
}

/* The same surplus sits between every pair of sections: each carries its own
   112px vertical padding, so the design's 224px boundary was rendering as 240
   with the root blockGap on top. Sections are the group/cover pattern wrappers
   that are direct children of main (front page, GLP-R) — post-title and
   post-content on page.html pages (/faq/, cart, checkout) are neither, so
   their 16px gap survives. Descendant selector, not child: Woo wraps the
   product template's main in a .woocommerce.product group, so main is not a
   direct child of .wp-site-blocks there. */
.wp-site-blocks main > :is(.wp-block-group, .wp-block-cover) {
	margin-block-start: 0;
}

/* Catalog tiles: normalise every tile image to the design's tile box —
   measured 395x484 off Product/12 (sec-product-12.png) — so card heights
   don't drift with the source photo's ratio. contain, not cover: the vial
   photography is 3:4 with the vial at ~84% of frame height, which already
   matches the design's vial-to-tile proportion; cover-cropping 3:4 into
   this wider box magnified the vial ~8% past the design and the client
   flagged desktop products as too enlarged (email 2026-08-27). The
   letterbox bars land on the white plate above, which matches the photo
   background. !important because the Product Image block serialises
   object-fit:cover as an inline style even at aspect-ratio auto — nothing
   short of it wins against a style attribute. */
.trustus-catalog-carousel .wp-block-woocommerce-product-image img {
	width: 100%;
	aspect-ratio: 395 / 484;
	object-fit: contain !important;
}

/* Shop archive grid: the archive template's Product Image block serialises
   aspect-ratio 1/1 as an inline style, cover-cropping the portrait vial
   shots into squares — vial magnified well past the catalog tiles, base
   clipped ("too enlarged on desktop"). Inline styles are only beatable with
   !important; keying the override on the --aspect-ratio-1-1 class retires
   it automatically once the template's attribute itself is corrected, which
   is where this fix really belongs. */
.wc-block-product-template .wc-block-components-product-image--aspect-ratio-1-1 img {
	aspect-ratio: 395 / 484 !important; /* design catalog tile box, as above */
	object-fit: contain !important;
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--grey-200);
}

/* Catalog: the design's 395px tiles on 48px gutters, with the 4th tile
   entering at the viewport edge as the scroll affordance (frame shows it cut
   at x1409/1440). The margin/padding pair bleeds the scroll clip to the
   viewport while child percentages stay on the 1280 container. max-width:none
   is what makes the bleed real: Woo's product template caps the list at 100%,
   which clamped the auto width back to the container and left the scrollport
   clipping at the container edge (tiles 4-5 fully hidden). */
.trustus-catalog-carousel.trustus-catalog-carousel {
	gap: var(--wp--preset--spacing--100);
	max-width: none;
	margin-right: calc(50% - 50vw);
	padding-right: calc(50vw - 50%);
}

.trustus-catalog-carousel.trustus-catalog-carousel > * {
	/* Base on the container token, not %: the bleed padding shrinks this
	   element's content box, which would undersize percentage children. */
	flex: 0 0 calc((var(--wp--custom--max-width--container) - 2 * var(--wp--preset--spacing--100)) / 3);
	width: calc((var(--wp--custom--max-width--container) - 2 * var(--wp--preset--spacing--100)) / 3);
}

/* One tile per view below core's 781px stacking breakpoint. This override
   sits after the token-basis rule above at equal specificity, so inside the
   media query it wins — the token basis (395px) used to out-cascade it and
   overflow a 390px viewport, cutting off prices. 85% of the content box (the
   bleed padding cancels the negative margin, so % still means the container)
   keeps the design's next-tile peek at the viewport edge. */
@media (max-width: 781px) {
	.trustus-catalog-carousel.trustus-catalog-carousel > * {
		flex: 0 0 85%;
		width: 85%;
	}
}

/* Outline buttons: the design draws their hairline with the primary-button
   gradient (sampled identically on white and navy sections). border-image
   ignores radius, so paint the ring via a masked overlay. */
.wp-block-button.is-style-outline .wp-block-button__link {
	position: relative;
	border-color: transparent;
}

.wp-block-button.is-style-outline .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
	padding: var(--wp--custom--stroke--hairline);
	background: var(--wp--preset--gradient--primary-button);
	mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
	mask-composite: exclude;
	-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
	-webkit-mask-composite: xor;
}

/* On the hero cover the design's outline button is glass — the snow photo
   reads through it (sec-home-hero.png samples ~rgb(227,231,238) inside the
   button). Everywhere else outline buttons keep their white fill: the
   sec-comparison-14 Explore Products sits white on the tinted wash. Hover
   restates the shared outline treatment so feedback survives the override. */
.trustus-hero .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: transparent;
}

.trustus-hero .wp-block-button.is-style-outline .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--paper-cool);
}

/* Branded focus ring for every interactive element, matching the treatment
   the carousel dots already had — UA defaults vanish against the washes. */
:is(a, button, input, select, textarea, summary):focus-visible {
	outline: var(--wp--custom--stroke--thick) solid var(--wp--preset--color--purple-deep);
	outline-offset: var(--wp--custom--stroke--thick);
}

/* ---------------------------------------------------------------------------
 * Product page purchase area (sec-product-header-1) — cross-agent handoff.
 * ------------------------------------------------------------------------- */

/* Gallery: 4-thumb rail left of a portrait main image. */
.trustus-gallery .woocommerce-product-gallery {
	display: grid;
	grid-template-columns: var(--wp--preset--spacing--120) 1fr;
	column-gap: var(--wp--preset--spacing--50);
	align-items: start;
}

.trustus-gallery .woocommerce-product-gallery > .flex-viewport,
.trustus-gallery .woocommerce-product-gallery > .woocommerce-product-gallery__wrapper {
	grid-column: 2;
	grid-row: 1;
}

.trustus-gallery .flex-control-thumbs {
	grid-column: 1;
	grid-row: 1;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--50);
	margin: 0;
	padding: 0;
	list-style: none;
}

.trustus-gallery .flex-control-thumbs img {
	border-radius: var(--wp--custom--radius--sm);
}

.trustus-gallery .woocommerce-product-gallery__image img {
	aspect-ratio: 503 / 660; /* design main-image box */
	object-fit: contain; /* 3:4 photo in a 0.762 box — contain drops the residual crop so the vial isn't magnified past the design (client: too enlarged) */
	width: 100%;
	/* The client specified a light grey plate behind the product image (Alfons,
	   2026-08-27) and the photography is shot on exactly this grey, so the
	   contain letterbox is invisible and the plate reads as one surface. */
	background-color: var(--wp--preset--color--grey-200);
	border-radius: var(--wp--custom--radius--md);
}

/* Gallery thumbnails sit on the same plate so the rail matches the main image. */
.trustus-gallery .flex-control-thumbs img {
	background-color: var(--wp--preset--color--grey-200);
}

@media (max-width: 781px) {
	/* Design mobile shows a single image; thumbs become a row below. */
	.trustus-gallery .woocommerce-product-gallery {
		display: block;
	}

	.trustus-gallery .flex-control-thumbs {
		flex-direction: row;
		margin-top: var(--wp--preset--spacing--40);
	}
}

/* Purchase block: stacked full-width CTAs, matched heights, theme type. */
.woocommerce-variation-add-to-cart {
	flex-direction: column;
	align-items: stretch;
}

form.cart .quantity {
	align-self: flex-start;
}

form.cart .single_add_to_cart_button,
.trustus-buy-now {
	width: 100%;
	min-height: var(--wp--preset--spacing--100);
}

form.cart select,
form.cart .quantity .qty,
.trustus-qty-btn,
.trustus-buy-now,
.trustus-variation-pill {
	font-family: inherit;
	font-size: var(--wp--preset--font-size--body);
}

form.cart .variations select {
	color: var(--wp--preset--color--navy);
}

.woocommerce-variation-availability,
.reset_variations {
	font-size: var(--wp--preset--font-size--small);
}

.trustus-qty-label {
	display: block;
	font-weight: 600;
}

/* Variations table → stacked label-over-control per the design. */
form.cart table.variations,
form.cart table.variations tbody,
form.cart table.variations tr,
form.cart table.variations th,
form.cart table.variations td {
	display: block;
	padding: 0;
	border: 0;
}

form.cart table.variations label {
	font-weight: 600;
}

/* Vial-size pills (selected fill sampled = the light-blue token). */
.trustus-variation-pills {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
}

.trustus-variation-pill {
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--60);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	cursor: pointer;
}

.trustus-variation-pill[aria-pressed="true"] {
	background: var(--wp--preset--color--light-blue);
	border-color: var(--wp--preset--color--light-blue);
}

.trustus-variation-pill:focus-visible {
	outline: var(--wp--custom--stroke--thick) solid var(--wp--preset--color--purple-deep);
	outline-offset: 2px;
}

/* One-facility: dots overlay the media's bottom edge (design bakes them in). */
.trustus-carousel-host {
	position: relative;
}

.trustus-carousel-host .trustus-carousel--overlay-dots + .trustus-carousel-nav {
	position: absolute;
	inset-inline: 0;
	bottom: var(--wp--preset--spacing--50);
	justify-content: center;
	margin-top: 0;
}

/* Gallery zoom trigger: Woo injects a raw emoji via JS (no PHP filter
   exists); hide it and draw the theme magnifier. */
.woocommerce-product-gallery__trigger {
	display: flex;
	align-items: center;
	justify-content: center;
}

.woocommerce-product-gallery__trigger > span {
	display: none;
}

.woocommerce-product-gallery__trigger::before {
	content: "";
	width: 1.25em;
	height: 1.25em;
	background-color: var(--wp--preset--color--ink);
	-webkit-mask: url("assets/images/icons/zoom.svg") no-repeat center / contain;
	mask: url("assets/images/icons/zoom.svg") no-repeat center / contain;
}

/* ---------------------------------------------------------------------------
 * Shop sorting — Woo's catalog-sorting block ships a bare <select>, which read
 * as unstyled browser chrome beside the themed catalog. Matched to the
 * vial-size pills: hairline border, small radius, white surface. The native
 * arrow is kept (no appearance:none) so the control stays platform-accessible.
 * ------------------------------------------------------------------------- */
.wc-block-catalog-sorting select.orderby {
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--60);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--body);
	cursor: pointer;
}

.wc-block-catalog-sorting select.orderby:hover {
	border-color: var(--wp--preset--color--purple);
}

/* Product header: core applies the group's blockGap (spacing 90 = 40px) as a
   top margin to the breadcrumb — the section's first child — where it stacked
   on the section's own top padding and pushed the page content down. The
   design puts the breadcrumb 86px below the navbar (measured off
   sec-product-header-1.png); the stray margin made it 104px. */
.woocommerce.wc-block-breadcrumbs {
	margin-block-start: 0;
}

/* Product page: core's root block gap adds a 16px top margin to the Woo
   product wrapper, on top of the section's own padding. Elliot's call (live
   client review) is that the product should sit close under the navbar; the
   Figma leaves ~86px there, so this is a deliberate deviation from
   Product Header / 1. */
.wp-site-blocks > .wp-block-group.product {
	margin-block-start: 0;
}

/* ---------------------------------------------------------------------------
 * My account — Woo puts the submit button and the remember-me checkbox in one
 * <p class="form-row"> and floats the button, which left a raw browser
 * checkbox stranded and baseline-misaligned beside a themed button (the same
 * unstyled-control problem the quantity stepper had). Lay the row out and give
 * the box the theme's accent colour.
 * ------------------------------------------------------------------------- */
/* Woo floats the submit button; with the checkbox and the button now on their
   own rows (see the template override) the float would still drag the button
   up beside "Remember me". */
.woocommerce-form-login__submit {
	float: none;
	margin: 0;
}

/* Woo pads .form-row by 3px, which the "Lost your password?" paragraph does
   not carry — so the fields sat 3px in from the links beneath them. Zero it
   across the account forms so every element shares one left edge. */
.trustus-account-forms .woocommerce-form .form-row {
	padding-inline: 0;
}

.trustus-login-remember {
	margin-block-end: var(--wp--preset--spacing--40);
}

/* Woo ships `.woocommerce form .form-row label { display: block }`, which
   outranks a single-class selector — the label never became a flex container,
   so the checkbox and its text stayed optically misaligned. Match that
   specificity. */
.woocommerce form .form-row label.woocommerce-form__label-for-checkbox {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: 0;
	cursor: pointer;
}

.woocommerce-form__input-checkbox {
	width: var(--wp--preset--spacing--60);
	height: var(--wp--preset--spacing--60);
	margin: 0;
	accent-color: var(--wp--preset--color--purple);
	cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * My account — one form at a time (woocommerce/myaccount/form-login.php).
 * Core's side-by-side login/register reads as dated; the register view now
 * replaces the login view via ?register=1. Constrained because a single column
 * would otherwise run the full content width, leaving short fields adrift.
 * ------------------------------------------------------------------------- */
.trustus-account-forms {
	max-width: 34rem;
}

.trustus-account-switch {
	margin-block-start: var(--wp--preset--spacing--70);
}

.trustus-account-switch a {
	color: var(--wp--preset--color--purple-deep);
	font-weight: 600;
}

/* The checkbox is 20px; its label text sits in a 31px line box, so centring
   the flex items still left the two optically 4px apart. Collapse the text's
   line box to its own height so both boxes share a centre. */
.woocommerce-form__label-for-checkbox > span {
	line-height: 1;
}

/* Gallery with no thumbnail rail. The flagship's extra angles were dropped
   when the new labelled vial arrived (they still showed the old branding), so
   Woo renders no .flex-control-thumbs and the reserved rail column left the
   main image pushed off its own left edge. Collapse to one column until more
   photography of the relabelled vial exists. */
.trustus-gallery .woocommerce-product-gallery:not(:has(.flex-control-thumbs)) {
	grid-template-columns: 1fr;
}

.trustus-gallery .woocommerce-product-gallery:not(:has(.flex-control-thumbs)) > .flex-viewport,
.trustus-gallery .woocommerce-product-gallery:not(:has(.flex-control-thumbs)) > .woocommerce-product-gallery__wrapper {
	grid-column: 1;
}

/* ---------------------------------------------------------------------------
 * Volume pricing table (plugins/trustus-pricing). The client asked for a
 * discount box under the purchase controls showing the quantity tiers. Styled
 * as a quiet card rather than a promo banner — it is reference information a
 * buyer scans, not an offer to shout about.
 * ------------------------------------------------------------------------- */
.trustus-volume-pricing {
	margin-block-start: var(--wp--preset--spacing--60);
	padding: var(--wp--preset--spacing--60);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--paper);
}

.trustus-volume-pricing__title {
	margin: 0 0 var(--wp--preset--spacing--40);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--body);
	font-weight: 600;
}

.trustus-volume-pricing__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.trustus-volume-pricing__list li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--50);
	padding-block: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
}

/* Hairline separators between tiers, not around the outside. */
.trustus-volume-pricing__list li + li {
	border-top: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
}

.trustus-volume-pricing__qty {
	color: var(--wp--preset--color--ink);
}

.trustus-volume-pricing__off {
	color: var(--wp--preset--color--purple-deep);
	font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * Shop grid tiles — bottom-align the buy button.
 *
 * The carousel tiles already do this (see .trustus-catalog-carousel > li), but
 * the /shop/ grid never got the same treatment, so each tile's button sat
 * directly under whatever content preceded it. Product names wrap to different
 * numbers of lines and a variable product adds a price RANGE where a simple one
 * has a single figure, so buttons landed at different heights across a row --
 * "Also select options not lined up" (Alfons, 2026-09-09).
 *
 * Making the tile a flex column lets the button's margin-top:auto push it to
 * the bottom, so every button in a row shares a baseline regardless of how tall
 * the text above it runs.
 * ------------------------------------------------------------------------- */
.wc-block-product-template > li.wc-block-product {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.wc-block-product-template > li.wc-block-product .wp-block-woocommerce-product-button {
	margin-top: auto;
}

/* ---------------------------------------------------------------------------
 * Mobile product page — put the buy controls within reach.
 *
 * Alfons, 2026-09-09: "when you click on a single product to add to cart and
 * buy now button is so far down on the page ... that's not an issue when you're
 * looking at web but when you jump to mobile, it takes a scroll."
 *
 * Measured on a 390x844 viewport before this rule: Add to cart sat at y1655,
 * almost two full screens down, and the four trust badges alone occupied 420px
 * of that because they stack one per row at mobile width.
 *
 * Two changes, mobile only. The badges become a 2x2 grid instead of a 1x4
 * stack, roughly halving their height; and the buy form (with its shipping and
 * research-use lines, which belong beside it) is ordered ABOVE them, so the
 * reader meets price, description and purchase before the trust marks. The
 * badges keep their place on desktop, where the two-column layout means they
 * were never in the way.
 *
 * The column is normally a block container, so it is switched to a flex column
 * here to make `order` meaningful. WordPress emits blockGap as margin-block-start
 * between DOM siblings, which reordering would scatter, so the gap is restated
 * as a flex `gap` and those margins are zeroed.
 * ------------------------------------------------------------------------- */
@media (max-width: 781px) {
	.trustus-product-buy {
		display: flex;
		flex-direction: column;
		gap: var(--wp--preset--spacing--70);
	}

	.trustus-product-buy > * {
		margin-block-start: 0;
	}

	/* Trust marks and the "What You're Getting" block move below the purchase
	   controls; everything else keeps its document order at the default 0. */
	.trustus-product-buy > .trustus-product-badges {
		order: 1;
	}

	.trustus-product-buy > h2,
	.trustus-product-buy > .trustus-getting {
		order: 2;
	}

	/* 2x2 instead of 1x4: core drops columns to full width below this
	   breakpoint, which is what made the block 420px tall. */
	.trustus-product-badges.trustus-product-badges {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--wp--preset--spacing--50);
	}

	.trustus-product-badges.trustus-product-badges > .wp-block-column {
		flex-basis: auto;
	}
}

/* ---------------------------------------------------------------------------
 * Checkout — make the card payment method read as the primary action.
 *
 * Alfons, 2026-09-09: "we can add logos to the pay with credit card/debit to
 * make it look more prominent? The box should look more prominent."
 *
 * It rendered as a plain hairline box identical to the shipping options above
 * it, so the one thing a buyer must engage with looked like another radio row.
 * It gets a heavier border and a tinted selected state.
 *
 * Brand marks are no longer ours to draw. Stripe renders the schemes the
 * account actually accepts inside its own card field — the exact thing the
 * previous processor could never tell us, and the reason the hand-built
 * Mastercard asset and the card-brand row that was waiting on an official Visa
 * file have both been removed rather than ported across.
 *
 * Scoped to the payment block: shipping options share the radio-control
 * classes, and they should stay quiet.
 * ------------------------------------------------------------------------- */
.wp-block-woocommerce-checkout-payment-block .wc-block-components-radio-control__option {

	/*
	 * Pad from the token, but NOT with the `padding` shorthand. Woo absolutely
	 * positions the radio input at inline-start 16px and reserves 48px of
	 * inline-start padding to clear it. The shorthand overwrote that reservation
	 * with the 16px token, so the control sat on top of the first ~20px of the
	 * method name and "Credit / Debit Card" rendered as "edit / Debit Card".
	 *
	 * The reservation is restated here rather than left to Woo's own rule, so a
	 * change to their value cannot silently re-collide. It is a literal because
	 * it is their control's geometry, not a value from our design system:
	 * 16px offset + 20px control + 12px gap.
	 */
	padding-block: var(--wp--preset--spacing--50);
	padding-inline-end: var(--wp--preset--spacing--50);
	padding-inline-start: 48px;

	transition: border-color 120ms ease, background-color 120ms ease;
}

/*
 * The ring goes on the ACCORDION option, not the label row inside it.
 *
 * WooCommerce 11.1 draws its own highlight on the accordion wrapper
 * (--checked-option-highlighted: a 1.5px inset currentColor ring at 4px
 * radius). We were separately ringing the inner label row at 16px radius, so a
 * selected card showed two mismatched borders — a rounded box around just the
 * method name sitting inside a squarer box around the whole panel.
 *
 * One ring now, on the wrapper, so the emphasis encloses the method name and
 * the card fields together. Woo's inset shadow is overridden rather than
 * fought, and the radius is matched to ours.
 */
.wp-block-woocommerce-checkout-payment-block .wc-block-components-radio-control-accordion-option {
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--paper-cool, #f7f8fa);
	box-shadow: inset 0 0 0 var(--wp--custom--stroke--thick) var(--wp--preset--color--hairline);
	transition: box-shadow 120ms ease, background-color 120ms ease;
}

.wp-block-woocommerce-checkout-payment-block
	.wc-block-components-radio-control-accordion-option--checked-option-highlighted {
	background-color: var(--wp--preset--color--paper-cool, #f7f8fa);
	/* Lifts the card method clear of the shipping radios above it, which share
	   these classes and carry only a hairline. */
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--navy);
}


/* ---------------------------------------------------------------------------
 * Order confirmation — collapse address cards that have nothing in them.
 *
 * WooCommerce shows the full order detail only to the person who placed the
 * order. Open a confirmation link later, or from another browser, and it drops
 * to a reduced view ("Log in here to view your order") where the shipping and
 * billing address blocks render nothing at all.
 *
 * The client styled this page himself (custom-css-js post #182), which gives
 * those address columns a plate, a border and an 18px radius — so in the
 * reduced view a customer revisiting their link sees two blank rounded boxes
 * sitting under the thank-you message. Reproduced on order #183.
 *
 * `:empty` does not match them: WooCommerce leaves whitespace inside. `:has()`
 * does, and is supported everywhere this theme targets.
 *
 * Only the EMPTY state is touched. A populated confirmation — the one the buyer
 * sees immediately after paying, and the one the client signed off — renders
 * exactly as before.
 * ------------------------------------------------------------------------- */
.woocommerce-order-received
	.wc-block-order-confirmation-address-wrapper
	.wp-block-column:not(:has(*)) {
	display: none;
}

/* If that leaves the row with no cards at all, drop the row too, so it does not
   leave the gap and margins of an invisible section behind. */
.woocommerce-order-received
	.wc-block-order-confirmation-address-wrapper:not(:has(.wp-block-column > *)) {
	display: none;
}

/* ---------------------------------------------------------------------------
 * My Account → Address.
 *
 * The client: "the format looks weird side by side" (2026-09-10).
 *
 * WooCommerce lays the billing and shipping blocks out with its own float
 * grid (.col2-set / .u-column1 / .u-column2) sized in percentages. Floats in a
 * block theme give uneven columns that do not clear, an Edit link that lands
 * wherever the float leaves it, and no visual separation between the two
 * addresses — so they read as one run-on block.
 *
 * Replaced with a real grid: two equal cards on desktop, stacked below the
 * breakpoint, each on the same paper plate and radius the rest of the account
 * area uses. The title row becomes flex so the heading sits left and Edit sits
 * right on one line.
 * ------------------------------------------------------------------------- */
.woocommerce-Addresses.col2-set {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--60);
}

/* Neutralise Woo's float sizing, which would otherwise fight the grid. */
.woocommerce-Addresses .woocommerce-Address {
	float: none;
	width: auto;
	padding: var(--wp--preset--spacing--60);
	border: var(--wp--custom--stroke--hairline) solid var(--wp--preset--color--hairline);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--white);
}

.woocommerce-Addresses .woocommerce-Address-title {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--40);
	margin-block-end: var(--wp--preset--spacing--40);
}

.woocommerce-Addresses .woocommerce-Address-title h2 {
	margin: 0;
	font-size: var(--wp--preset--font-size--lead);
}

/* The link text is "Edit Billing address" for screen readers; the visible
   label stays short so it cannot wrap the title row onto two lines. */
.woocommerce-Addresses .woocommerce-Address-title .edit {
	flex: none;
	font-size: var(--wp--preset--font-size--small);
	white-space: nowrap;
}

.woocommerce-Addresses address {
	font-style: normal;
	line-height: 1.7;
}

@media (max-width: 781px) {
	.woocommerce-Addresses.col2-set {
		grid-template-columns: 1fr;
	}
}
