/* ==========================================================================
   ULTRA PEP LABS - CART, CHECKOUT, CART DRAWER + ADD-TO-CART TOAST
   (TopOpti, 2026-09-15, rewritten for classic checkout 2026-09-16)
   --------------------------------------------------------------------------
   Standalone stylesheet. Loaded from the child theme functions.php as
   'upl-cart-checkout', after 'upl-pdp-refresh' so the shared tokens defined
   there are already in scope (this file re-declares them defensively anyway,
   so it still renders correctly if loaded on its own). Loaded site-wide, not
   just on cart and checkout, because the cart drawer appears on every page.

   CSS ONLY. No markup, content or PHP behaviour is changed by this file.
   The furniture classes (.upl-*) are emitted by the hook functions in
   functions.php; if those are removed, every .upl-* rule here simply
   matches nothing.

   To disable: comment out the wp_enqueue_style call in functions.php, or
   rename this file. Nothing in style.css is modified.

   --------------------------------------------------------------------------
   2026-09-16. Cart and Checkout moved from WooCommerce Blocks to the classic
   shortcodes ([woocommerce_cart] / [woocommerce_checkout]). This file was
   rewritten against classic markup: .woocommerce-cart-form, .shop_table,
   #customer_details, #order_review, #place_order, .cart_totals.

   Section 10 (the legacy WooCommerce Blocks rules) was REMOVED 2026-09-17
   once classic checkout was signed off, along with the draft backup pages
   2003 and 2004 that held the original block markup.

   THE ONE TRAP ON THIS SITE, worth reading before editing anything below.
   This site serves CSS inside @layer. For !important declarations the cascade
   REVERSES layer order, so a *layered* !important beats an *unlayered* one.
   A plain `.shop_table td` selector therefore loses to the theme even with
   !important. Prefixing with `body.woocommerce-cart` / `body.woocommerce-checkout`
   raises specificity enough to win. Native form controls (input, select,
   .qty) need the body prefix AND !important. This cost real time twice; do
   not remove those prefixes because they look redundant.
   ========================================================================== */

:root {
	--ink:        #002a8f;
	--ink-2:      #001c5e;
	--ink-soft:   #1a47a8;
	--muted:      #5a6478;
	--line:       #d8dfea;
	--gr:         #f0f5fa;
	--ok:         #17935a;
	--r-lg:       24px;
	--r-md:       16px;
	--r-sm:       12px;
	--pdp-max:    1240px;
	--aside:      400px;
	--shadow-lg:  0 24px 48px -30px rgba(0, 28, 94, .50);
}

/* --------------------------------------------------------------------------
   1. ADD-TO-CART TOAST
   The toast is injected by the "toast notoi" Code Snippet, whose inline
   <style> loads before this file, so these overrides win on source order.

   Problem: the toast is width:fit-content with justify-content:normal and
   the text set to flex-grow:0. The three children therefore sit end to end,
   so the "View cart" button's position drifted with the product-name length
   instead of being pinned to the right edge.
   -------------------------------------------------------------------------- */
.cart-toast {
	min-width: 340px;
}
.cart-toast .cart-toast-text {
	flex: 1 1 auto;                 /* absorb the free space... */
}
.cart-toast a.cart-toast-view-cart {
	margin-left: auto;              /* ...and pin the action right */
	flex: 0 0 auto;
}

@media (max-width: 480px) {
	.cart-toast {
		min-width: 0;
		left: 16px;
		right: 16px;
		transform: none;
		width: auto;
	}
	.cart-toast.is-visible { transform: none; }
}

/* --------------------------------------------------------------------------
   2. SHARED SHELL for both pages
   -------------------------------------------------------------------------- */
body.woocommerce-cart .entry-content > .woocommerce,
body.woocommerce-checkout .entry-content > .woocommerce,
body.woocommerce-cart .ast-container > .woocommerce,
body.woocommerce-checkout .ast-container > .woocommerce {
	max-width: var(--pdp-max);
	margin-left: auto;
	margin-right: auto;
}

body.woocommerce-cart .entry-title,
body.woocommerce-checkout .entry-title {
	font-size: clamp(30px, 3.4vw, 44px);
	line-height: 1.08;
	font-weight: 600;
	letter-spacing: -.03em;
	color: var(--ink);
	margin-bottom: 8px;
}

/* Default WooCommerce link blue, brought onto the brand. */
body.woocommerce-cart a:not(.button):not(.ast-button),
body.woocommerce-checkout a:not(.button):not(.ast-button) {
	color: var(--ink);
}
body.woocommerce-cart a:not(.button):not(.ast-button):hover,
body.woocommerce-checkout a:not(.button):not(.ast-button):hover {
	color: var(--ink-2);
}

/* Section headings: "Cart totals", "Billing details", "Your order". */
body.woocommerce-cart .cart_totals > h2,
body.woocommerce-checkout #order_review_heading,
body.woocommerce-checkout .woocommerce-billing-fields > h3,
body.woocommerce-checkout .woocommerce-shipping-fields > h3,
body.woocommerce-checkout .woocommerce-additional-fields > h3,
body.woocommerce-checkout #ship-to-different-address {
	font-size: 19px;
	font-weight: 600;
	letter-spacing: -.01em;
	color: var(--ink);
	/* Astra gives these headings a near-white band with negative side margins,
	   which reads as a stray white strip inside our tinted card. */
	background: none !important;
	padding: 0 !important;
	margin: 0 0 16px !important;
	border: 0 !important;
	text-transform: none;
}

/* --------------------------------------------------------------------------
   3. NOTICES. Woo's defaults are a grey bar with a coloured left edge and a
      ::before glyph that collides with our own icons. Rebuilt as soft cards.
   -------------------------------------------------------------------------- */
body.woocommerce-cart .woocommerce-message,
body.woocommerce-cart .woocommerce-info,
body.woocommerce-cart .woocommerce-error,
body.woocommerce-checkout .woocommerce-message,
body.woocommerce-checkout .woocommerce-info,
body.woocommerce-checkout .woocommerce-error {
	border: 1px solid var(--line);
	border-top-width: 1px;
	border-radius: var(--r-md);
	background: var(--gr);
	color: var(--ink);
	font-size: 14.5px;
	line-height: 1.5;
	padding: 15px 20px;
	margin: 0 0 20px;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 16px;
	list-style: none;
}
body.woocommerce-cart .woocommerce-message::before,
body.woocommerce-cart .woocommerce-info::before,
body.woocommerce-cart .woocommerce-error::before,
body.woocommerce-checkout .woocommerce-message::before,
body.woocommerce-checkout .woocommerce-info::before,
body.woocommerce-checkout .woocommerce-error::before {
	display: none;
}
body.woocommerce-cart .woocommerce-message,
body.woocommerce-checkout .woocommerce-message {
	background: rgba(23, 147, 90, .08);
	border-color: rgba(23, 147, 90, .26);
	color: #0f6b41;
}
body.woocommerce-cart .woocommerce-error,
body.woocommerce-checkout .woocommerce-error {
	background: rgba(179, 38, 30, .07);
	border-color: rgba(179, 38, 30, .24);
	color: #8c1d18;
}
/* The inline button Woo puts inside a notice ("View cart", "Continue"). */
body.woocommerce-cart .woocommerce-message .button,
body.woocommerce-checkout .woocommerce-message .button {
	margin-left: auto;
}

/* --------------------------------------------------------------------------
   4. CART PAGE
   Classic markup. .woocommerce-cart-form and .cart-collaterals are siblings
   inside the shortcode's .woocommerce wrapper, stacked by default. Grid puts
   them side by side and lets the full-width furniture span both columns.

   :has() gates the grid so the EMPTY cart (no form present) stays a simple
   centred column rather than a 400px aside with nothing beside it.
   -------------------------------------------------------------------------- */
body.woocommerce-cart .woocommerce:has(> .woocommerce-cart-form) {
	display: grid;
	grid-template-columns: minmax(0, 1fr) var(--aside);
	gap: 26px 40px;
	align-items: start;
}
/* Rows are assigned explicitly, so on-screen order does not depend on markup
   order or on which hook emitted a block. */
body.woocommerce-cart .woocommerce > .upl-cart-head {
	grid-column: 1 / -1;
	grid-row: 1;
}
body.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper {
	grid-column: 1 / -1;
	grid-row: 2;
}
body.woocommerce-cart .woocommerce-cart-form {
	grid-column: 1;
	grid-row: 3;
	margin: 0;
}
body.woocommerce-cart .cart-collaterals {
	grid-column: 2;
	grid-row: 3;
	width: auto;
	float: none;
	margin: 0;
}
body.woocommerce-cart .woocommerce > .upl-trust-strip {
	grid-column: 1 / -1;
	grid-row: 4;
}
body.woocommerce-cart .cart-collaterals .cart_totals {
	width: auto;
	float: none;
}
/* Astra ships cross-sells in the collaterals column; full width below. */
body.woocommerce-cart .cart-collaterals .cross-sells {
	grid-column: 1 / -1;
	width: auto;
	float: none;
}

/* 4.1 The cart page header.
   The cart renders its OWN <h1> (see upl_cart_header() in functions.php) and
   Astra's is hidden, because Astra's title lives in header.entry-header, a
   sibling of .entry-content, and nothing inside the cart can reach it. That
   is the only way to get "Continue shopping" onto the title's own row.
   Cart page only - checkout still uses Astra's title. */
body.woocommerce-cart .entry-header { display: none; }

.upl-cart-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 16px 24px;
	flex-wrap: wrap;
	margin: 0;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--line);
}
.upl-cart-head__text { min-width: 0; }
.upl-cart-head__title {
	font-size: clamp(30px, 3.4vw, 44px);
	line-height: 1.05;
	font-weight: 600;
	letter-spacing: -.03em;
	color: var(--ink);
	margin: 0;
}
.upl-cart-head__eyebrow {
	margin: 8px 0 0;
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--muted);
}
.upl-cart-head__back {
	flex: 0 0 auto;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ink) !important;
	text-decoration: none;
	padding-bottom: 4px;
	white-space: nowrap;
}
.upl-cart-head__back:hover { text-decoration: underline; }

/* 4.2 The line-item table.
   Stripped back to rows: no cell borders, no zebra, no header rules. */
/* table-layout:fixed, deliberately.
   With the default `auto` algorithm this table came out 849px inside an 800px
   column, with a 326px remove column and a 125px product name that wrapped
   the title onto three lines: the widths declared on the cells were losing to
   Woo's own, and the auto algorithm then handed the slack to the wrong
   column. Fixed layout takes the widths from the header row and gives the
   remainder to the one `auto` column, which is the product name. The column
   widths below are therefore load-bearing, not decoration.
   Overridden back to block display under 767px, where rows become cards. */
body.woocommerce-cart table.shop_table.cart {
	border: 0;
	border-collapse: collapse;
	border-radius: 0;
	margin: 0;
	width: 100%;
	max-width: 100%;
	table-layout: fixed;
}
body.woocommerce-cart table.shop_table.cart th.product-remove,
body.woocommerce-cart table.shop_table.cart td.product-remove { width: 42px !important; }
body.woocommerce-cart table.shop_table.cart th.product-thumbnail,
body.woocommerce-cart table.shop_table.cart td.product-thumbnail { width: 116px !important; }
body.woocommerce-cart table.shop_table.cart th.product-name,
body.woocommerce-cart table.shop_table.cart td.product-name { width: auto !important; }
body.woocommerce-cart table.shop_table.cart th.product-price,
body.woocommerce-cart table.shop_table.cart td.product-price { width: 104px !important; }
body.woocommerce-cart table.shop_table.cart th.product-quantity,
body.woocommerce-cart table.shop_table.cart td.product-quantity { width: 136px !important; }
body.woocommerce-cart table.shop_table.cart th.product-subtotal,
body.woocommerce-cart table.shop_table.cart td.product-subtotal { width: 116px !important; }
body.woocommerce-cart table.shop_table.cart thead th {
	border: 0;
	border-bottom: 1px solid var(--line);
	background: none;
	padding: 0 12px 12px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--muted);
	text-align: left;
}
body.woocommerce-cart table.shop_table.cart thead th.product-price,
body.woocommerce-cart table.shop_table.cart thead th.product-subtotal {
	text-align: right;
}
body.woocommerce-cart table.shop_table.cart td {
	border: 0;
	border-bottom: 1px solid var(--line);
	padding: 20px 12px;
	vertical-align: middle;
	background: none;
}
body.woocommerce-cart table.shop_table.cart tr:last-child td { border-bottom: 0; }

body.woocommerce-cart td.product-remove { width: 34px; padding-left: 0; }
body.woocommerce-cart td.product-remove a.remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 999px;
	font-size: 20px;
	line-height: 1;
	color: var(--muted) !important;
	background: none !important;
	transition: background-color .18s, color .18s;
}
/* Hover stays on the brand. The Material red this used to carry was the only
   off-palette colour on the page. Error states elsewhere are still red,
   because there the colour is carrying meaning; here it was decoration. */
body.woocommerce-cart td.product-remove a.remove:hover {
	background: var(--gr) !important;
	color: var(--ink) !important;
}

/* Woo caps cart thumbnails at 70px via its own img rule, so these need
   !important or the image comes out 70x85 instead of a square. */
body.woocommerce-cart td.product-thumbnail img {
	width: 88px !important;
	height: 88px !important;
	max-width: none !important;
	/* Product shots are portrait vials. cover slices them in half. */
	object-fit: contain;
	background: var(--gr);
	border-radius: var(--r-md);
	padding: 6px;
	display: block;
}

/* 4.2b The line-item identity block: category eyebrow, name, descriptor.
   Markup from upl_cart_item_name_meta(). Applied at every width so the two
   breakpoints read the same; to go back to a bare product name on desktop,
   hide .upl-item__eyebrow and .upl-item__desc above 767px. */
.upl-item__eyebrow {
	display: block;
	margin: 0 0 4px;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--muted);
}
.upl-item__name { display: block; }
.upl-item__desc {
	display: block;
	margin: 5px 0 0;
	font-size: 12.5px;
	line-height: 1.4;
	color: var(--muted);
}

body.woocommerce-cart td.product-name a {
	font-weight: 600;
	font-size: 16px;
	line-height: 1.35;
	color: var(--ink) !important;
	text-decoration: none;
}
body.woocommerce-cart td.product-name a:hover { color: var(--ink-2) !important; }
/* The variation list ("Specification: 10mg"). Compact, secondary. */
body.woocommerce-cart td.product-name dl.variation {
	margin: 6px 0 0;
	font-size: 13px;
	color: var(--muted);
	display: flex;
	flex-wrap: wrap;
	gap: 0 6px;
}
body.woocommerce-cart td.product-name dl.variation dt,
body.woocommerce-cart td.product-name dl.variation dd {
	margin: 0;
	padding: 0;
	float: none;
	clear: none;
	font-weight: 400;
}
body.woocommerce-cart td.product-name dl.variation dd p { margin: 0; }
body.woocommerce-cart td.product-name dl.variation dd::after { content: ""; }

body.woocommerce-cart td.product-price,
body.woocommerce-cart td.product-subtotal { text-align: right; }
body.woocommerce-cart td.product-price { color: var(--muted); font-size: 15px; }
body.woocommerce-cart td.product-subtotal {
	color: var(--ink);
	font-weight: 700;
	font-size: 16px;
}

/* 4.3 Quantity stepper.
   Astra renders this as `<a class="minus">- <input> <a class="plus">+`, and
   its own rules leave the two anchors 38x28 next to a 44px input, so the pill
   read as a squashed "- 1  +" with the parts on different baselines. Rebuilt
   as three equal cells with dividers: minus | value | plus.

   `align-items: stretch` plus `height: auto !important` on all three children
   is what keeps them the same height - the anchors and the input each carry
   their own height from elsewhere. Native controls, so body prefix AND
   !important, per the note at the top of this file. */
body.woocommerce-cart td.product-quantity .quantity {
	display: inline-flex !important;
	align-items: stretch;
	height: 46px;
	border: 1px solid var(--line);
	border-radius: 999px;
	overflow: hidden;
	background: #fff;
	transition: border-color .18s, box-shadow .18s;
}
body.woocommerce-cart td.product-quantity .quantity a.minus,
body.woocommerce-cart td.product-quantity .quantity a.plus {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 42px !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: 0 !important;
	border: 0;
	border-radius: 0 !important;
	background: none !important;
	color: var(--ink) !important;
	font-size: 17px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none !important;
	user-select: none;
	transition: background-color .15s;
}
body.woocommerce-cart td.product-quantity .quantity a.minus { border-right: 1px solid var(--line); }
body.woocommerce-cart td.product-quantity .quantity a.plus  { border-left: 1px solid var(--line); }
body.woocommerce-cart td.product-quantity .quantity a.minus:hover,
body.woocommerce-cart td.product-quantity .quantity a.plus:hover {
	background: var(--gr) !important;
}
body.woocommerce-cart td.product-quantity .quantity input.qty {
	width: 52px !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: none !important;
	text-align: center;
	font-size: 15px;
	font-weight: 600;
	color: var(--ink);
	box-shadow: none !important;
	-moz-appearance: textfield;
}
/* The native spinners duplicate the plus and minus and break the pill shape. */
body.woocommerce-cart td.product-quantity .quantity input.qty::-webkit-outer-spin-button,
body.woocommerce-cart td.product-quantity .quantity input.qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
body.woocommerce-cart td.product-quantity .quantity input.qty:focus {
	outline: none;
	box-shadow: none !important;
}
body.woocommerce-cart td.product-quantity .quantity:focus-within {
	border-color: var(--ink);
	box-shadow: 0 0 0 3px rgba(0, 42, 143, .12);
}

/* While a background cart update is in flight. Kept subtle: the numbers are
   about to change and a heavy spinner on every stepper click is worse. */
body.upl-cart-busy .woocommerce-cart-form,
body.upl-cart-busy .cart_totals {
	opacity: .55;
	pointer-events: none;
	transition: opacity .15s;
}

/* 4.4 The actions row: coupon on the left, Update cart on the right.
   This cell MUST stay display:table-cell. It carries colspan="6", which is
   what makes it span the table; display:flex (or a display:block row) takes
   it out of the table layout algorithm and under table-layout:fixed it then
   collapses to the width of column one, 42px. Both were tried. The layout is
   therefore done with inline-flex on the coupon and a float on the button,
   not with flex on the cell. */
body.woocommerce-cart table.shop_table.cart td.actions {
	display: table-cell !important;
	width: auto !important;
	padding: 24px 0 0;
	border-bottom: 0;
	text-align: left;
}
body.woocommerce-cart table.shop_table.cart td.actions::after {
	content: "";
	display: block;
	clear: both;
}
body.woocommerce-cart td.actions .coupon {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	float: none;
	margin: 0;
}
body.woocommerce-cart td.actions button[name="update_cart"] {
	float: right;
}
body.woocommerce-cart td.actions .coupon label { display: none; }

/* Once cart-enhance.js has run, quantities apply themselves, so "Update cart"
   has nothing left to do and the coupon has been moved into the order
   summary. That empties the actions row, so hide it - but ONLY under
   .upl-cart-js, so that with JavaScript off the button is still there and the
   cart is still usable.

   The row also holds the cart nonce as hidden inputs. display:none does not
   stop them being submitted, so hiding the row is safe. */
body.upl-cart-js.woocommerce-cart table.shop_table.cart td.actions {
	display: none !important;
}

/* 4.4b The coupon box in its new home, at the top of the order summary.
   Moved here by cart-enhance.js; see the note on placeCoupon(). */
.upl-coupon-slot {
	margin: 0 0 18px;
	padding: 0 0 18px;
	border-bottom: 1px solid var(--line);
}
.upl-coupon-slot .coupon {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	float: none !important;
	margin: 0 !important;
	padding: 0 !important;
	width: 100%;
}
.upl-coupon-slot .coupon label { display: none; }
.upl-coupon-slot .coupon input#coupon_code {
	flex: 1 1 130px;
	width: auto !important;
	min-width: 0;
	height: 46px !important;
	padding: 0 16px !important;
	border: 1px solid var(--line) !important;
	border-radius: 999px !important;
	background: #fff !important;
	font-size: 14.5px;
	color: var(--ink);
	margin: 0 !important;
}
.upl-coupon-slot .coupon button {
	flex: 0 0 auto;
	min-height: 46px !important;
	padding: 0 20px !important;
	font-size: 14px !important;
}
.upl-coupon-slot #coupon-error-notice {
	flex: 1 0 100%;
	order: 3;
}
body.woocommerce-cart td.actions .coupon input#coupon_code {
	width: 200px !important;
	height: 48px !important;
	padding: 0 18px !important;
	border: 1px solid var(--line) !important;
	border-radius: 999px !important;
	background: #fff !important;
	font-size: 14.5px;
	color: var(--ink);
	margin: 0 !important;
	transition: border-color .18s, box-shadow .18s;
}
body.woocommerce-cart td.actions .coupon input#coupon_code:focus {
	outline: none;
	border-color: var(--ink) !important;
	box-shadow: 0 0 0 3px rgba(0, 42, 143, .12);
}

/* An invalid coupon. WooCommerce appends #coupon-error-notice INSIDE .coupon
   and flags the input with .has-error, rather than printing a normal
   .woocommerce-error at the top of the page, so it needs styling of its own
   or it renders as bare text wedged between the two buttons. */
body.woocommerce-cart td.actions .coupon { flex-wrap: wrap; }
body.woocommerce-cart td.actions .coupon input#coupon_code.has-error {
	border-color: #b3261e !important;
}
body.woocommerce-cart #coupon-error-notice {
	order: 3;
	flex: 1 0 100%;
	margin: 12px 0 0;
	padding: 11px 15px;
	border: 1px solid rgba(179, 38, 30, .24);
	border-radius: var(--r-sm);
	background: rgba(179, 38, 30, .07);
	color: #8c1d18;
	font-size: 13px;
	line-height: 1.45;
}

/* 4.5 Cart totals card */
body.woocommerce-cart .cart_totals {
	background: var(--gr);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	padding: 24px 22px !important;
	position: sticky;
	top: 24px;
}
body.woocommerce-cart .cart_totals table.shop_table {
	border: 0;
	border-collapse: collapse;
	margin: 0 0 6px;
	width: 100%;
	background: none;
}
body.woocommerce-cart .cart_totals table.shop_table th,
body.woocommerce-cart .cart_totals table.shop_table td {
	border: 0;
	border-bottom: 1px solid var(--line);
	background: none;
	padding: 13px 0;
	font-size: 14.5px;
	font-weight: 500;
	color: var(--muted);
	vertical-align: middle;
}
body.woocommerce-cart .cart_totals table.shop_table td {
	text-align: right;
	color: var(--ink);
	font-weight: 600;
}
body.woocommerce-cart .cart_totals tr.order-total th,
body.woocommerce-cart .cart_totals tr.order-total td {
	border-bottom: 0;
	padding-top: 16px;
	font-size: 20px;
	font-weight: 700;
	color: var(--ink);
}
body.woocommerce-cart .cart_totals tr.order-total small { font-weight: 400; }
/* Shipping rows, once zones exist. */
body.woocommerce-cart .cart_totals ul#shipping_method {
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: right;
}
body.woocommerce-cart .cart_totals ul#shipping_method li { margin: 0 0 6px; }
body.woocommerce-cart .cart_totals .woocommerce-shipping-destination {
	font-size: 13px;
	color: var(--muted);
	margin: 6px 0 0;
}
body.woocommerce-cart .wc-proceed-to-checkout { padding: 18px 0 0; }

/* --------------------------------------------------------------------------
   5. CHECKOUT PAGE
   -------------------------------------------------------------------------- */

/* 5.1 Two columns: the form on the left, the order summary on the right.
   The summary column is .upl-checkout-aside, a wrapper added by the hook pair
   in functions.php. Grid therefore places exactly two children, and anything
   a plugin injects into the summary (Route's #route-checkout-radio, for one)
   rides along inside the wrapper instead of auto-placing itself into a grid
   cell of its own. Do not go back to placing the heading and #order_review
   individually; that is what this replaced.

   The width:100% overrides are load-bearing. Astra sets percentage widths on
   both #customer_details (47%) and #order_review (40%), which are percentages
   OF THE GRID TRACK, so without these the columns come out 440px and 160px
   inside 800px and 400px tracks. */
body.woocommerce-checkout form.checkout.woocommerce-checkout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) var(--aside);
	column-gap: 40px;
	align-items: start;
}
body.woocommerce-checkout form.checkout #customer_details {
	grid-column: 1;
	width: 100% !important;
	float: none !important;
}
body.woocommerce-checkout form.checkout .upl-checkout-aside {
	grid-column: 2;
	min-width: 0;
}
body.woocommerce-checkout form.checkout #order_review,
body.woocommerce-checkout form.checkout #order_review_heading {
	width: 100% !important;
	float: none !important;
}
/* Smart Coupons and friends drop message holders straight into the form.
   Span them rather than letting them take a column. */
body.woocommerce-checkout form.checkout > .wc_coupon_message_wrap,
body.woocommerce-checkout form.checkout > #coupons_list,
body.woocommerce-checkout form.checkout > .woocommerce-notices-wrapper {
	grid-column: 1 / -1;
}
/* Route's shipping-protection toggle, which renders inside the summary
   column. Client decision on Route is still open; this only keeps it from
   looking unstyled next to the summary card. */
body.woocommerce-checkout #route-checkout-radio {
	margin: 14px 0 0;
	font-size: 13.5px;
	color: var(--muted);
}

/* The billing / shipping halves stack. The left column is ~700px, which is a
   comfortable single measure; two 340px columns of address fields is not. */
body.woocommerce-checkout #customer_details.col2-set,
body.woocommerce-checkout #customer_details .col2-set {
	display: block;
	width: auto;
}
body.woocommerce-checkout #customer_details .col-1,
body.woocommerce-checkout #customer_details .col-2 {
	width: auto;
	float: none;
	max-width: none;
}
body.woocommerce-checkout #customer_details .col-2:not(:empty) { margin-top: 30px; }

body.woocommerce-checkout .woocommerce-billing-fields,
body.woocommerce-checkout .woocommerce-shipping-fields,
body.woocommerce-checkout .woocommerce-additional-fields {
	border-top: 1px solid var(--line);
	padding-top: 26px;
	margin-top: 26px;
}
body.woocommerce-checkout .woocommerce-billing-fields:first-child {
	border-top: 0;
	padding-top: 0;
	margin-top: 0;
}

/* 5.2 Form fields. Native controls: body prefix AND !important, both needed. */
body.woocommerce-checkout .form-row {
	padding: 0;
	margin: 0 0 16px;
}
body.woocommerce-checkout .form-row label {
	display: block;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--muted);
	margin: 0 0 7px;
}
body.woocommerce-checkout .form-row .required {
	color: #b3261e;
	text-decoration: none;
	border: 0;
}
/* NOTE THE :not(.select2-hidden-accessible). Select2 keeps the original
   <select> in the DOM, absolutely positioned and 1px wide, for screen readers.
   Styling it like a visible field (width:100%, min-height:52px) pushed it
   371px wide at its absolute offset and gave the whole checkout ~19px of
   horizontal scroll on a phone. Do not drop the :not(). */
body.woocommerce-checkout .form-row input.input-text,
body.woocommerce-checkout .form-row textarea,
body.woocommerce-checkout .form-row select:not(.select2-hidden-accessible),
body.woocommerce-checkout .select2-container .select2-selection--single,
body.woocommerce-checkout .woocommerce-form-coupon input.input-text,
body.woocommerce-checkout .woocommerce-form-login input.input-text {
	width: 100% !important;
	min-height: 52px !important;
	padding: 14px 16px !important;
	border: 1px solid var(--line) !important;
	border-radius: 14px !important;
	background-color: #fff !important;
	font-size: 15px !important;
	line-height: 1.4;
	color: var(--ink) !important;
	box-shadow: none !important;
	transition: border-color .18s, box-shadow .18s;
}
body.woocommerce-checkout .form-row textarea {
	min-height: 104px !important;
	resize: vertical;
}
body.woocommerce-checkout .form-row input.input-text:focus,
body.woocommerce-checkout .form-row textarea:focus,
body.woocommerce-checkout .form-row select:focus,
body.woocommerce-checkout .woocommerce-form-coupon input.input-text:focus {
	outline: none;
	border-color: var(--ink) !important;
	box-shadow: 0 0 0 3px rgba(0, 42, 143, .12) !important;
}
/* Belt and braces on the same problem: whatever else targets it, the hidden
   native select stays out of the layout. */
body.woocommerce-checkout select.select2-hidden-accessible {
	width: 1px !important;
	height: 1px !important;
	min-height: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	overflow: hidden !important;
	clip: rect(0 0 0 0) !important;
	clip-path: inset(50%) !important;
}

/* Select2 (country / state) is a div pretending to be a select. */
body.woocommerce-checkout .select2-container .select2-selection--single {
	display: flex !important;
	align-items: center;
}
body.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__rendered {
	line-height: 1.4;
	padding: 0;
	color: var(--ink);
}
body.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__arrow {
	height: 100%;
	right: 12px;
}
body.woocommerce-checkout .woocommerce-invalid input.input-text,
body.woocommerce-checkout .woocommerce-invalid select {
	border-color: #b3261e !important;
}
body.woocommerce-checkout .woocommerce-validated input.input-text {
	border-color: rgba(23, 147, 90, .5) !important;
}

/* Pair the short fields so the form does not read as one long ladder. */
@media (min-width: 768px) {
	body.woocommerce-checkout #customer_details .form-row-first,
	body.woocommerce-checkout #customer_details .form-row-last {
		width: calc(50% - 8px);
		float: none;
		display: inline-block;
		vertical-align: top;
	}
	body.woocommerce-checkout #customer_details .form-row-first { margin-right: 12px; }
}

/* 5.3 Coupon.
   The "Have a coupon? Click here to enter your code" notice and the form it
   toggles are HIDDEN: the coupon now lives at the top of the order summary
   (.upl-checkout-coupon, rendered by upl_checkout_coupon_box()). Hidden rather
   than unhooked, so reverting is a one-line CSS change. */
body.woocommerce-checkout .woocommerce-form-coupon-toggle,
body.woocommerce-checkout form.checkout_coupon {
	display: none !important;
}

body.woocommerce-checkout .woocommerce-form-login-toggle .woocommerce-info {
	margin-bottom: 14px;
}
body.woocommerce-checkout form.woocommerce-form-login {
	border: 1px solid var(--line) !important;
	border-radius: var(--r-lg) !important;
	padding: 22px !important;
	margin: 0 0 24px !important;
	background: #fff;
}

/* 5.3b The coupon box inside the order summary.
   Not a <form> - see upl_checkout_coupon_box() for why - so it is laid out
   here and submitted by cart-enhance.js. */
.upl-checkout-coupon {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0 0 18px;
	padding: 0 0 18px;
	border-bottom: 1px solid var(--line);
}
body.woocommerce-checkout .upl-checkout-coupon__input {
	flex: 1 1 130px;
	width: auto !important;
	min-width: 0;
	min-height: 46px !important;
	height: 46px !important;
	padding: 0 16px !important;
	border: 1px solid var(--line) !important;
	border-radius: 999px !important;
	background: #fff !important;
	font-size: 14.5px !important;
	color: var(--ink) !important;
	margin: 0 !important;
	box-shadow: none !important;
}
body.woocommerce-checkout .upl-checkout-coupon__input:focus {
	outline: none;
	border-color: var(--ink) !important;
	box-shadow: 0 0 0 3px rgba(0, 42, 143, .12) !important;
}
body.woocommerce-checkout .upl-checkout-coupon__btn {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 46px;
	padding: 0 20px;
	border: 1px solid var(--ink) !important;
	border-radius: 999px !important;
	background: #fff !important;
	color: var(--ink) !important;
	font-size: 14px !important;
	font-weight: 600 !important;
	cursor: pointer;
	transition: background-color .2s, color .2s, transform .15s cubic-bezier(.2,.7,.3,1), box-shadow .2s;
}
/* Same hover as "Proceed to checkout" and "Complete order": navy fill, white
   text, 1px lift, matching shadow. Previously this one filled navy with no
   lift or shadow, which read as a different button. */
body.woocommerce-checkout .upl-checkout-coupon__btn:hover {
	background: var(--ink-2) !important;
	border-color: var(--ink-2) !important;
	color: #fff !important;
	transform: translateY(-1px);
	box-shadow: 0 12px 24px -14px rgba(0, 28, 94, .6);
}
body.woocommerce-checkout .upl-checkout-coupon__btn[disabled] { opacity: .6; cursor: default; }
.upl-checkout-coupon__msg {
	flex: 1 0 100%;
	margin: 0;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--muted);
}
.upl-checkout-coupon__msg:empty { display: none; }
.upl-checkout-coupon__msg.is-error { color: #8c1d18; }
.upl-checkout-coupon__msg.is-success { color: #0f6b41; }

/* 5.4 Order summary card */
/* padding needs !important, exactly as .cart_totals does. Astra sets its own
   padding on this box and wins otherwise, which left the coupon field flush
   against the top edge of the summary card on checkout while the identical
   arrangement on the cart page looked right. */
body.woocommerce-checkout #order_review {
	background: var(--gr);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	padding: 24px 22px !important;
	position: sticky;
	top: 24px;
}
body.woocommerce-checkout table.woocommerce-checkout-review-order-table {
	border: 0;
	border-collapse: collapse;
	width: 100%;
	margin: 0;
	background: none;
}
body.woocommerce-checkout table.woocommerce-checkout-review-order-table th,
body.woocommerce-checkout table.woocommerce-checkout-review-order-table td {
	border: 0;
	background: none;
	padding: 12px 0;
	vertical-align: top;
}
body.woocommerce-checkout table.woocommerce-checkout-review-order-table thead th {
	border-bottom: 1px solid var(--line);
	padding-bottom: 12px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--muted);
}
body.woocommerce-checkout table.woocommerce-checkout-review-order-table thead th.product-total { text-align: right; }
body.woocommerce-checkout tr.cart_item td {
	border-bottom: 1px solid var(--line) !important;
	font-size: 14.5px;
	line-height: 1.45;
	color: var(--ink);
}
body.woocommerce-checkout tr.cart_item td.product-name { font-weight: 600; }
body.woocommerce-checkout tr.cart_item td.product-total {
	text-align: right;
	white-space: nowrap;
	font-weight: 600;
}
body.woocommerce-checkout tr.cart_item strong.product-quantity {
	display: inline-block;
	margin-left: 6px;
	font-weight: 500;
	color: var(--muted);
}
body.woocommerce-checkout tr.cart_item dl.variation {
	margin: 5px 0 0;
	font-size: 12.5px;
	font-weight: 400;
	color: var(--muted);
	display: flex;
	flex-wrap: wrap;
	gap: 0 6px;
}
body.woocommerce-checkout tr.cart_item dl.variation dt,
body.woocommerce-checkout tr.cart_item dl.variation dd {
	margin: 0;
	float: none;
	font-weight: 400;
}
body.woocommerce-checkout tr.cart_item dl.variation dd p { margin: 0; }

body.woocommerce-checkout table.woocommerce-checkout-review-order-table tfoot th,
body.woocommerce-checkout table.woocommerce-checkout-review-order-table tfoot td {
	border-bottom: 1px solid var(--line);
	padding: 13px 0;
	font-size: 14.5px;
	font-weight: 500;
	color: var(--muted);
}
body.woocommerce-checkout table.woocommerce-checkout-review-order-table tfoot td {
	text-align: right;
	color: var(--ink);
	font-weight: 600;
}
body.woocommerce-checkout tfoot tr.order-total th,
body.woocommerce-checkout tfoot tr.order-total td {
	border-bottom: 0;
	padding-top: 16px;
	font-size: 20px;
	font-weight: 700;
	color: var(--ink);
}

/* 5.5 Payment methods as selectable cards. */
body.woocommerce-checkout #payment {
	background: none;
	border-radius: 0;
	margin-top: 4px;
}
body.woocommerce-checkout #payment ul.payment_methods {
	border: 0;
	padding: 18px 0 0;
	margin: 0;
	list-style: none;
}
body.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method {
	border: 1px solid var(--line);
	border-radius: 14px;
	background: #fff;
	margin: 0 0 10px;
	padding: 14px 16px;
	transition: border-color .18s, box-shadow .18s;
}
body.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method:has(input:checked) {
	border-color: var(--ink);
	box-shadow: 0 0 0 3px rgba(0, 42, 143, .10);
}
body.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method label {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	font-size: 15px;
	font-weight: 600;
	color: var(--ink);
	margin: 0;
	cursor: pointer;
}
body.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method input.input-radio {
	accent-color: var(--ink);
	width: 18px !important;
	height: 18px !important;
	margin: 0 2px 0 0 !important;
}
body.woocommerce-checkout #payment div.payment_box {
	background: var(--gr) !important;
	border-radius: var(--r-sm);
	margin: 12px 0 0;
	padding: 13px 15px;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--muted);
}
body.woocommerce-checkout #payment div.payment_box::before { display: none !important; }
body.woocommerce-checkout #payment div.payment_box p:last-child { margin-bottom: 0; }

/* 5.6 Terms checkbox + legal links. */
body.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper {
	margin: 18px 0 0;
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--muted);
}
body.woocommerce-checkout .woocommerce-privacy-policy-text p { margin: 0 0 12px; }
body.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper .form-row {
	margin: 0;
}
/* Block, not flex. As a flex row the required-asterisk is a third flex item
   and gets pushed to the far right of the label while the sentence wraps
   under itself. Positioning the checkbox out of flow lets the whole label
   read as one wrapped sentence with the asterisk inline after it. */
body.woocommerce-checkout label.woocommerce-form__label-for-checkbox {
	display: block !important;
	position: relative;
	padding-left: 28px;
	font-size: 13.5px !important;
	font-weight: 500 !important;
	line-height: 1.5;
	color: var(--muted) !important;
	cursor: pointer;
	margin: 0;
}
body.woocommerce-checkout input.woocommerce-form__input-checkbox {
	position: absolute;
	left: 0;
	top: 2px;
	width: 18px !important;
	height: 18px !important;
	min-height: 0 !important;
	margin: 0 !important;
	flex: 0 0 auto;
	accent-color: var(--ink);
}
body.woocommerce-checkout .woocommerce-terms-and-conditions-checkbox-text a {
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 2px;
}
body.woocommerce-checkout .woocommerce-terms-and-conditions {
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	padding: 14px 16px;
	margin: 12px 0;
	background: #fff;
	font-size: 13.5px;
}

/* 5.7 Place order.
   #place_order is floated by WooCommerce. Left floated, anything output on
   woocommerce_review_order_after_submit (our reassurance rows) wraps into
   the sliver of space beside it and renders about 60px wide underneath the
   button. Unset the float, and clear after it for anything that follows. */
body.woocommerce-checkout .form-row.place-order {
	margin: 20px 0 0;
	padding: 20px 0 0;
	border-top: 1px solid var(--line);
	float: none;
	width: auto;
}
body.woocommerce-checkout #place_order {
	float: none !important;
	clear: both;
}
body.woocommerce-checkout .form-row.place-order::after {
	content: "";
	display: block;
	clear: both;
}
body.woocommerce-checkout .form-row.place-order .upl-reassure { clear: both; }

/* --------------------------------------------------------------------------
   6. BUTTONS. One pill treatment across cart, checkout and the drawer,
      matching the PDP add-to-cart.
   -------------------------------------------------------------------------- */
body.woocommerce-cart .wc-proceed-to-checkout a.checkout-button,
body.woocommerce-checkout #place_order,
body.woocommerce-cart td.actions button[name="apply_coupon"],
body.woocommerce-cart td.actions button[name="update_cart"],
body.woocommerce-checkout form.checkout_coupon button[type="submit"],
body.woocommerce-checkout form.woocommerce-form-login button[type="submit"],
.astra-cart-drawer .woocommerce-mini-cart__buttons a.button,
body.woocommerce-cart .return-to-shop a.button,
.upl-empty-cart a.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 52px;
	padding: 0 28px;
	border-radius: 999px !important;
	border: 1px solid var(--ink) !important;
	background-color: var(--ink) !important;
	color: #fff !important;
	font-weight: 600 !important;
	font-size: 15.5px !important;
	line-height: 1.2;
	letter-spacing: .01em;
	text-align: center;
	text-decoration: none;
	transition: background-color .2s, transform .15s cubic-bezier(.2,.7,.3,1), box-shadow .2s;
}
body.woocommerce-cart .wc-proceed-to-checkout a.checkout-button,
body.woocommerce-checkout #place_order,
.astra-cart-drawer .woocommerce-mini-cart__buttons a.button,
.upl-empty-cart a.button {
	width: 100%;
	min-height: 56px;
	font-size: 16px !important;
}
body.woocommerce-cart .wc-proceed-to-checkout a.checkout-button:hover,
body.woocommerce-checkout #place_order:hover,
body.woocommerce-cart td.actions button[name="apply_coupon"]:hover,
body.woocommerce-cart td.actions button[name="update_cart"]:hover,
.astra-cart-drawer .woocommerce-mini-cart__buttons a.button:hover,
.upl-empty-cart a.button:hover {
	background-color: var(--ink-2) !important;
	border-color: var(--ink-2) !important;
	color: #fff !important;
	transform: translateY(-1px);
	box-shadow: 0 12px 24px -14px rgba(0, 28, 94, .6);
}

/* Secondary: outline at rest. On HOVER they take the primary treatment
   exactly - navy fill, white text, 1px lift, same shadow - so there is one
   hover behaviour across the whole cart and checkout rather than two.
   The shared hover rule above already supplies the lift and shadow; these
   only need to stop forcing the white background back on. */
body.woocommerce-cart td.actions button[name="apply_coupon"],
body.woocommerce-cart td.actions button[name="update_cart"],
.astra-cart-drawer .woocommerce-mini-cart__buttons a.button:not(.checkout) {
	background-color: #fff !important;
	color: var(--ink) !important;
	min-height: 48px;
	font-size: 14.5px !important;
}
body.woocommerce-cart td.actions button[name="apply_coupon"]:hover,
body.woocommerce-cart td.actions button[name="update_cart"]:not([disabled]):hover,
.astra-cart-drawer .woocommerce-mini-cart__buttons a.button:not(.checkout):hover {
	background-color: var(--ink-2) !important;
	border-color: var(--ink-2) !important;
	color: #fff !important;
}
body.woocommerce-cart td.actions button[name="update_cart"][disabled] {
	opacity: .4;
	cursor: not-allowed;
	transform: none;
	box-shadow: none;
}

/* --------------------------------------------------------------------------
   7. FURNITURE emitted by the hook functions in functions.php
      (.upl-trust-strip, .upl-reassure, .upl-checkout-intro, .upl-empty-cart)
   -------------------------------------------------------------------------- */

/* 7.1 Full-width trust strip under the cart. */
.upl-trust-strip {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 10px 30px;
	margin: 8px 0 0 !important;
	padding: 18px 22px !important;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--gr);
	list-style: none;
}
/* The theme styles every list item on the page. These are not content list
   items, so reset the inherited padding, borders and min-heights. */
.upl-trust-strip li {
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	min-height: 0 !important;
	width: auto !important;
	line-height: 1.3;
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--muted);
	display: flex;
	align-items: center;
	gap: 9px;
}
.upl-trust-strip li::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 999px;
	background: var(--ok);
	flex: 0 0 auto;
}

/* 7.2 Reassurance rows: under the cart's checkout button, and under the
   checkout's place-order button. */
.upl-reassure {
	margin: 16px 0 0 !important;
	padding: 0 !important;
	list-style: none;
	display: grid;
	gap: 12px;
}
.upl-reassure li {
	margin: 0 !important;
	padding: 0 0 0 26px !important;
	border: 0 !important;
	min-height: 0 !important;
	position: relative;
	font-size: 13px;
	line-height: 1.45;
	color: var(--muted);
}
.upl-reassure li strong {
	display: block;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ink);
}
/* Tick, drawn in CSS so there is no icon dependency. */
.upl-reassure li::before {
	content: "";
	position: absolute;
	left: 2px;
	top: 3px;
	width: 12px;
	height: 7px;
	border-left: 2px solid var(--ok);
	border-bottom: 2px solid var(--ok);
	transform: rotate(-45deg);
}

/* 7.3 Small print under a totals card ("Shipping and taxes..."). */
.upl-fineprint {
	margin: 14px 0 0;
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--muted);
	text-align: center;
}

/* 7.4 Checkout intro / research-use notice. */
.upl-checkout-intro {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	margin: 0 0 26px;
	padding: 16px 20px;
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--gr);
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--muted);
}
.upl-checkout-intro strong { color: var(--ink); font-weight: 600; }
.upl-checkout-intro::before {
	content: "";
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	margin-top: 7px;
	border-radius: 999px;
	background: var(--ink);
}

/* 7.5 Legal links line under the terms checkbox. */
.upl-legal-links {
	margin: 12px 0 0;
	font-size: 12.5px;
	line-height: 1.6;
	color: var(--muted);
}
.upl-legal-links a {
	color: var(--ink) !important;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* 7.6 Branded empty cart. Replaces the default sad-face line. */
body.woocommerce-cart .cart-empty.woocommerce-info {
	justify-content: center;
	text-align: center;
	font-size: 17px;
	font-weight: 600;
	color: var(--ink);
	background: none;
	border: 0;
	padding: 0;
	margin: 0 0 10px;
}
.upl-empty-cart {
	max-width: 480px;
	margin: 0 auto;
	text-align: center;
}
.upl-empty-cart p {
	font-size: 14.5px;
	line-height: 1.6;
	color: var(--muted);
	margin: 0 0 22px;
}
body.woocommerce-cart .return-to-shop { text-align: center; margin: 0; }

/* --------------------------------------------------------------------------
   8. CART DRAWER (Astra's flyout, enabled in the Customizer)
   Stock Astra renders it 672px wide with square default-blue buttons and a
   "Shopping Cart" title. Contents are the standard WooCommerce mini-cart,
   so every selector here is core Woo apart from the .astra-* shell.

   These rules are NOT prefixed with body.woocommerce-* because the drawer
   exists on every page. Where they compete with Astra's own layered rules
   they carry !important.
   -------------------------------------------------------------------------- */
/* Astra ships the drawer as `position:fixed; display:block; padding:32px 0 0`
   with an ABSOLUTELY POSITIONED header sitting at top:32px, and relies on the
   drawer's own scrolling. That gives a 32px white gap above the header, and
   any change to the content's top padding slides the first line item under
   the header.

   Rebuilt as a flex column instead: header in normal flow, list the only
   scrolling region, footer pinned. Every property Astra sets directly needs
   !important to be overridden - see the @layer note at the top of this file. */
#astra-mobile-cart-drawer.astra-cart-drawer {
	width: min(420px, 92vw) !important;
	max-width: 92vw !important;
	padding: 0 !important;
	display: flex !important;
	flex-direction: column;
	overflow: hidden !important;
	background: #fff;
	box-shadow: -18px 0 60px -30px rgba(0, 28, 94, .55);
}

/* That 32px of drawer padding was Astra clearing the WP ADMIN BAR, which only
   exists for logged-in staff. Removing it is right for customers but slides
   the drawer header under the admin bar for everyone who can see one, so put
   the offset back as a top/height pair, scoped to .admin-bar. 782px is
   WordPress's own admin-bar breakpoint, where the bar grows to 46px. */
body.admin-bar #astra-mobile-cart-drawer.astra-cart-drawer {
	top: 32px !important;
	height: calc(100% - 32px) !important;
}
@media screen and (max-width: 782px) {
	body.admin-bar #astra-mobile-cart-drawer.astra-cart-drawer {
		top: 46px !important;
		height: calc(100% - 46px) !important;
	}
}

.astra-cart-drawer .astra-cart-drawer-header {
	position: relative !important;
	top: auto !important;
	left: auto !important;
	width: auto !important;
	max-height: none !important;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 18px 20px !important;
	border-bottom: 1px solid var(--line);
	background: #fff;
	min-height: 64px;
}
.astra-cart-drawer .astra-cart-drawer-title {
	font-size: 16px !important;
	font-weight: 600 !important;
	letter-spacing: -.01em;
	color: var(--ink) !important;
	text-transform: none;
	order: 1;
	flex: 1 1 auto;
	text-align: left;
}
/* Close button to the right of the title, not the left of it. */
.astra-cart-drawer .astra-cart-drawer-close {
	order: 2;
	flex: 0 0 auto;
	width: 36px !important;
	height: 36px !important;
	padding: 0 !important;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 999px !important;
	color: var(--muted) !important;
	background: none !important;
	transition: background-color .18s, color .18s;
}
.astra-cart-drawer .astra-cart-drawer-close:hover {
	background: var(--gr) !important;
	color: var(--ink) !important;
}

.astra-cart-drawer .astra-cart-drawer-content {
	padding: 0 20px 20px !important;
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden;
}
/* display:flex needs !important here: Astra sets display:block on the widget
   directly, and a plain declaration loses to it. */
.astra-cart-drawer .widget_shopping_cart,
.astra-cart-drawer .widget_shopping_cart_content {
	display: flex !important;
	flex-direction: column;
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden;
}

/* 8.1 Line items */
.astra-cart-drawer ul.woocommerce-mini-cart {
	display: block !important;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none;
	flex: 1 1 auto;
	overflow-y: auto;
	min-height: 0;
}
/* The footer block: total, fine print, buttons, trust row. Never scrolls. */
.astra-cart-drawer p.woocommerce-mini-cart__total,
.astra-cart-drawer p.woocommerce-mini-cart__buttons,
.astra-cart-drawer .widget_shopping_cart_content > .upl-fineprint,
.astra-cart-drawer .upl-drawer-trust {
	flex: 0 0 auto;
}
.astra-cart-drawer li.woocommerce-mini-cart-item {
	position: relative;
	display: block;
	margin: 0 !important;
	/* Roomier than stock, so the stepper row has somewhere to breathe and the
	   items read as separated blocks rather than a dense list. */
	padding: 20px 32px 20px 80px !important;
	border-bottom: 1px solid var(--line);
	min-height: 0;
}
.astra-cart-drawer li.woocommerce-mini-cart-item:last-child { border-bottom: 0; }
/* The thumbnail is positioned against the PRODUCT LINK, not the row.
   Positioned against the row it would not land where the computed `top` said
   it should (computed 20px, rendered 12px above the row's own top), so it
   overlapped the row above. The link starts exactly where the text block
   starts, so `top: 0` here means "level with the category eyebrow" with no
   arithmetic. left is the negative of the row's padding-left: CHANGE THE TWO
   TOGETHER. */
.astra-cart-drawer li.woocommerce-mini-cart-item img {
	position: absolute !important;
	left: -80px !important;
	top: 0 !important;
	/* Astra centres this thumbnail with top:50% PLUS translateY(-50%).
	   Overriding `top` alone leaves the transform pulling it up by half its
	   own height, which is why it rendered 12px above the row and overlapped
	   the item above even though the computed top read 20px. Both have to go. */
	transform: none !important;
	width: 64px !important;
	height: 64px !important;
	margin: 0 !important;
	float: none !important;
	/* Portrait vials on white: contain, not cover. */
	object-fit: contain;
	background: var(--gr);
	border-radius: var(--r-sm);
	padding: 4px;
}
.astra-cart-drawer li.woocommerce-mini-cart-item > a:not(.remove) {
	/* Containing block for the thumbnail - see the img rule below. */
	position: relative;
	display: block;
	min-height: 64px;
	font-size: 14.5px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--ink) !important;
	text-decoration: none;
}

/* The category eyebrow and descriptor, same as the cart page. In the mini-cart
   these sit INSIDE the product anchor (WooCommerce wraps the name in the
   link), so the weight and colour have to be reset off the anchor. */
.astra-cart-drawer li.woocommerce-mini-cart-item .upl-item__eyebrow {
	font-size: 10px;
	margin-bottom: 3px;
	font-weight: 700;
	color: var(--muted);
}
.astra-cart-drawer li.woocommerce-mini-cart-item .upl-item__name {
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ink);
}
.astra-cart-drawer li.woocommerce-mini-cart-item .upl-item__desc {
	margin-top: 3px;
	font-size: 11.5px;
	font-weight: 400;
	color: var(--muted);
}
/* Fallback styling for WooCommerce's stock "1 x $19.00" text, which is what
   renders if the upl_mini_cart_item_quantity filter is ever removed. */
.astra-cart-drawer li.woocommerce-mini-cart-item .quantity {
	display: block;
	margin-top: 5px;
	font-size: 13.5px;
	font-weight: 500;
	color: var(--muted);
}
.astra-cart-drawer li.woocommerce-mini-cart-item .quantity .amount { color: var(--ink); }

/* 8.1b The drawer's stepper row: quantity on the left, line total on the
   right, as on the reference site. Markup comes from
   upl_mini_cart_item_quantity() in functions.php. */
.astra-cart-drawer .upl-mini-qty {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 12px;
	transition: opacity .15s;
}
.astra-cart-drawer .upl-mini-qty.is-busy {
	opacity: .5;
	pointer-events: none;
}
.astra-cart-drawer .upl-mini-qty__line {
	font-size: 15px;
	font-weight: 700;
	color: var(--ink);
	white-space: nowrap;
}
.astra-cart-drawer li.woocommerce-mini-cart-item dl.variation {
	margin: 4px 0 0;
	font-size: 12.5px;
	color: var(--muted);
	display: flex;
	flex-wrap: wrap;
	gap: 0 6px;
}
.astra-cart-drawer li.woocommerce-mini-cart-item dl.variation dt,
.astra-cart-drawer li.woocommerce-mini-cart-item dl.variation dd {
	margin: 0;
	float: none;
	font-weight: 400;
}
.astra-cart-drawer li.woocommerce-mini-cart-item dl.variation dd p { margin: 0; }

.astra-cart-drawer li.woocommerce-mini-cart-item a.remove {
	position: absolute !important;
	right: 0;
	top: 16px;
	width: 26px !important;
	height: 26px !important;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	border-radius: 999px;
	color: var(--muted) !important;
	background: none !important;
	font-size: 17px;
	line-height: 1;
	transition: background-color .18s, color .18s;
}
.astra-cart-drawer li.woocommerce-mini-cart-item a.remove:hover {
	background: rgba(179, 38, 30, .10) !important;
	color: #b3261e !important;
}

/* 8.2 Footer: subtotal, note, buttons, trust row. */
.astra-cart-drawer p.woocommerce-mini-cart__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin: 0 !important;
	padding: 18px 0 0 !important;
	border-top: 1px solid var(--line);
	border-bottom: 0 !important;
	font-size: 16px;
	color: var(--ink);
}
.astra-cart-drawer p.woocommerce-mini-cart__total strong {
	font-weight: 600;
	font-size: 15px;
	color: var(--muted);
}
.astra-cart-drawer p.woocommerce-mini-cart__total .amount {
	font-size: 20px;
	font-weight: 700;
	color: var(--ink);
}

.astra-cart-drawer p.woocommerce-mini-cart__buttons {
	display: flex;
	/* Source order is View cart then Checkout. Checkout is the primary
	   action, so reverse it and let the outline button sit underneath. */
	flex-direction: column-reverse;
	gap: 10px;
	margin: 14px 0 0 !important;
	padding: 0 !important;
}
.astra-cart-drawer .woocommerce-mini-cart__empty-message {
	margin: 40px 0;
	text-align: center;
	font-size: 15px;
	color: var(--muted);
}

/* The drawer's own fine print and trust row, from the mini-cart hooks. */
.astra-cart-drawer .upl-fineprint { margin: 12px 0 0; }
.upl-drawer-trust {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 6px 16px;
	margin: 16px 0 0 !important;
	padding: 14px 0 0 !important;
	border-top: 1px solid var(--line);
	list-style: none;
}
/* Astra styles every li inside the drawer as a cart line item (padding,
   border, min-height). These are not cart items, so reset them or they come
   out 199px wide and wrap onto two lines. */
.upl-drawer-trust li {
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	min-height: 0 !important;
	width: auto !important;
	line-height: 1.3;
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: .07em;
	text-transform: uppercase;
	color: var(--muted);
	display: flex;
	align-items: center;
	gap: 7px;
}
.upl-drawer-trust li::before {
	content: "";
	width: 5px;
	height: 5px;
	border-radius: 999px;
	background: var(--ok);
	flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   8.5 SHARED QUANTITY STEPPER (.upl-qty)
   Used by the cart drawer today. Standalone on purpose: it is plain markup
   with no dependency on WooCommerce's classes, so the COA modal and the size
   sheet can reuse it later.
   -------------------------------------------------------------------------- */
.upl-qty {
	display: inline-flex !important;
	align-items: stretch;
	height: 38px;
	border: 1px solid var(--line);
	border-radius: 999px;
	overflow: hidden;
	background: #fff;
	flex: 0 0 auto;
}
.upl-qty__btn {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 36px !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: none !important;
	color: var(--ink) !important;
	font-size: 16px;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	appearance: none;
	transition: background-color .15s;
}
.upl-qty__btn:hover { background: var(--gr) !important; }
.upl-qty__btn:first-of-type { border-right: 1px solid var(--line) !important; }
.upl-qty__btn:last-of-type  { border-left: 1px solid var(--line) !important; }
.upl-qty__value {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 38px;
	padding: 0 4px;
	font-size: 14px;
	font-weight: 600;
	color: var(--ink);
}

/* --------------------------------------------------------------------------
   8.6 RECONSTITUTION BUMP
   Rendered under the cart's line items by upl_reconstitution_bump(), only
   when the cart holds a peptide and no bacteriostatic water.

   The reference site uses a green rail here because their brand is green.
   Ours is navy: green is already spoken for on this site as the in-stock and
   tick colour, and a second meaning would muddy it.
   -------------------------------------------------------------------------- */
.upl-bump {
	position: relative;
	margin: 24px 0 0;
	padding: 22px 24px;
	border: 1px solid var(--line);
	border-left: 4px solid var(--ink);
	border-radius: var(--r-md);
	background: var(--gr);
}
.upl-bump__icon {
	display: block;
	width: 26px;
	height: 26px;
	margin: 0 0 12px;
	color: var(--ink);
}
.upl-bump__icon svg { width: 100%; height: 100%; display: block; }
.upl-bump__eyebrow {
	margin: 0 0 8px;
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--ink);
}
.upl-bump__body {
	margin: 0 0 18px;
	font-size: 14px;
	line-height: 1.55;
	color: var(--muted);
	max-width: 58ch;
}
.upl-bump__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}
.upl-bump__cta {
	flex: 1 1 240px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	min-height: 58px;
	padding: 10px 20px;
	border: 1px solid var(--ink);
	border-radius: var(--r-md);
	background: #fff;
	color: var(--ink);
	cursor: pointer;
	text-align: center;
	appearance: none;
	transition: background-color .2s, color .2s, transform .15s cubic-bezier(.2,.7,.3,1), box-shadow .2s;
}
.upl-bump__cta--primary {
	background: var(--ink);
	color: #fff;
}
.upl-bump__cta:hover {
	transform: translateY(-1px);
	box-shadow: 0 12px 24px -14px rgba(0, 28, 94, .6);
}
.upl-bump__cta--primary:hover { background: var(--ink-2); border-color: var(--ink-2); }
.upl-bump__cta:not(.upl-bump__cta--primary):hover { background: #fff; color: var(--ink-2); }
.upl-bump__cta[disabled], .upl-bump__cta.is-busy { opacity: .6; cursor: default; transform: none; }
.upl-bump__cta-name {
	font-size: 15px;
	font-weight: 600;
	line-height: 1.25;
}
.upl-bump__cta-meta {
	font-size: 12.5px;
	font-weight: 500;
	opacity: .85;
}
.upl-bump__note {
	margin: 14px 0 0;
	font-size: 12.5px;
	color: var(--muted);
}

/* --------------------------------------------------------------------------
   9. RESPONSIVE
   -------------------------------------------------------------------------- */
@media (max-width: 1024px) {
	:root { --aside: 340px; }
	body.woocommerce-cart .woocommerce:has(> .woocommerce-cart-form),
	body.woocommerce-checkout form.checkout.woocommerce-checkout {
		column-gap: 28px;
	}
}

@media (max-width: 921px) {
	/* One column. Astra's breakpoint is 921px, so the header collapses here
	   too and the two changes stay in step. */
	body.woocommerce-cart .woocommerce:has(> .woocommerce-cart-form) {
		display: block;
	}
	body.woocommerce-checkout form.checkout.woocommerce-checkout {
		display: block;
	}
	body.woocommerce-cart .cart-collaterals,
	body.woocommerce-checkout .upl-checkout-aside {
		margin-top: 30px;
	}
	/* Sticky in a single column just pins the summary over the form. */
	body.woocommerce-cart .cart_totals,
	body.woocommerce-checkout #order_review {
		position: static;
	}
}

@media (max-width: 767px) {
	body.woocommerce-cart .entry-title,
	body.woocommerce-checkout .entry-title {
		font-size: clamp(26px, 7vw, 32px);
	}

	/* WooCommerce's shop_table_responsive stacks each row into a card. Give
	   the stacked rows a real card treatment rather than bare stripes, and
	   lay them out as: thumbnail on the left, name and variant beside it,
	   then the stepper and the line total sharing a row underneath.

	   The image sizes below MUST carry !important. The desktop rule sets
	   88x88 with !important (it has to, to beat WooCommerce's own 70px cap),
	   and an unflagged mobile override loses to it - which is exactly what
	   put the thumbnail on top of the product title on a phone. The row's
	   padding-left is image width + 16px inset + 12px gutter; change one and
	   change the other. */
	/* The mobile card is a GRID on the <tr>, not floats.

	   Two things fight you here and both need !important:
	   1. woocommerce-smallscreen.css sets `display: block !important` on every
	      cell. That is why the unit-price cell would not hide, and it is why
	      every display rule below is flagged.
	   2. The desktop column widths in section 4.2 carry !important (they have
	      to, to beat WooCommerce). Those widths leak into the stacked layout
	      and were pinning the name column to 217px and the total to 116px, so
	      the card ran 275px tall with the price on its own line. Every cell is
	      reset to width:auto here.

	   Layout: image spans both rows on the left; name block and remove on row
	   one; stepper and line total share row two, which is what keeps the card
	   short and puts the total on the stepper's baseline. */
	body.woocommerce-cart table.shop_table.cart thead { display: none; }
	body.woocommerce-cart table.shop_table.cart tr.cart_item {
		display: grid !important;
		grid-template-columns: 80px minmax(0, 1fr) auto;
		grid-template-areas:
			"img name  remove"
			"img qty   total";
		column-gap: 14px;
		row-gap: 12px;
		align-items: start;
		position: relative;
		border: 1px solid var(--line);
		border-radius: var(--r-md);
		padding: 16px;
		margin: 0 0 12px;
	}
	body.woocommerce-cart table.shop_table.cart tr.cart_item td {
		display: block !important;
		width: auto !important;
		min-width: 0;
		border: 0 !important;
		padding: 0 !important;
		text-align: left !important;
	}
	body.woocommerce-cart tr.cart_item td.product-thumbnail {
		grid-area: img;
		width: 80px !important;
	}
	body.woocommerce-cart tr.cart_item td.product-thumbnail img {
		width: 80px !important;
		height: 80px !important;
	}
	body.woocommerce-cart tr.cart_item td.product-name { grid-area: name; }
	body.woocommerce-cart tr.cart_item td.product-remove {
		grid-area: remove;
		justify-self: end;
	}
	/* Unit price is redundant next to the line total on a narrow screen.
	   The FULL selector chain is required, not just `tr.cart_item
	   td.product-price`. The blanket cell rule above is
	   `body.woocommerce-cart table.shop_table.cart tr.cart_item td` and both
	   carry !important, so the shorter selector loses to it on specificity -
	   this rule was silently doing nothing and the price kept its own row. */
	body.woocommerce-cart table.shop_table.cart tr.cart_item td.product-price {
		display: none !important;
	}
	body.woocommerce-cart tr.cart_item td.product-quantity {
		grid-area: qty;
		align-self: center;
	}
	body.woocommerce-cart tr.cart_item td.product-subtotal {
		grid-area: total;
		align-self: center;
		justify-self: end;
		text-align: right !important;
		font-size: 17px;
		white-space: nowrap;
	}
	/* Woo's responsive table prints the column name via a data-title
	   ::before. Useful on price rows, noise on these. */
	body.woocommerce-cart tr.cart_item td::before { display: none !important; }

	/* Slightly tighter stepper so it and the total always share one row. */
	body.woocommerce-cart td.product-quantity .quantity { height: 42px; }
	body.woocommerce-cart td.product-quantity .quantity a.minus,
	body.woocommerce-cart td.product-quantity .quantity a.plus { width: 38px !important; }
	body.woocommerce-cart td.product-quantity .quantity input.qty { width: 40px !important; }

	/* Breathing room between the mobile header bar and the page title. The
	   header is flush to the content on a phone and "Cart" / "Checkout" sat
	   right under the hamburger. Applied to the cart's own header block and
	   to Astra's title on checkout, which is still Astra's. */
	body.woocommerce-cart .upl-cart-head,
	body.woocommerce-checkout .entry-header {
		padding-top: 22px;
	}

	.upl-cart-head {
		align-items: flex-start;
		gap: 10px;
	}
	.upl-cart-head__back { padding-bottom: 0; }

	body.woocommerce-cart table.shop_table.cart td.actions {
		display: block;
		padding-top: 18px;
	}
	body.woocommerce-cart td.actions .coupon {
		display: flex;
		width: 100%;
		margin-bottom: 12px;
	}
	body.woocommerce-cart td.actions .coupon input#coupon_code {
		flex: 1 1 auto;
		width: auto !important;
	}
	body.woocommerce-cart td.actions button[name="update_cart"] { width: 100%; }

	body.woocommerce-cart .cart_totals,
	body.woocommerce-checkout #order_review {
		padding: 20px 18px;
	}
	body.woocommerce-cart .cart_totals tr.order-total th,
	body.woocommerce-cart .cart_totals tr.order-total td,
	body.woocommerce-checkout tfoot tr.order-total th,
	body.woocommerce-checkout tfoot tr.order-total td {
		font-size: 18px;
	}

	/* Comfortable tap targets. */
	body.woocommerce-cart .wc-proceed-to-checkout a.checkout-button,
	body.woocommerce-checkout #place_order { min-height: 54px; }

	.upl-trust-strip { gap: 10px 20px; padding: 16px; }
	.upl-trust-strip li { font-size: 11.5px; }
}

@media (max-width: 480px) {
	#astra-mobile-cart-drawer.astra-cart-drawer {
		width: 100vw !important;
		max-width: 100vw !important;
	}
	/* Narrower image column on small phones. The grid column and the image
	   must be changed together, and both need !important to beat the desktop
	   thumbnail rule in section 4.2. */
	body.woocommerce-cart table.shop_table.cart tr.cart_item {
		grid-template-columns: 68px minmax(0, 1fr) auto;
		column-gap: 12px;
		padding: 14px;
	}
	body.woocommerce-cart tr.cart_item td.product-thumbnail,
	body.woocommerce-cart tr.cart_item td.product-thumbnail img {
		width: 68px !important;
	}
	body.woocommerce-cart tr.cart_item td.product-thumbnail img { height: 68px !important; }
	body.woocommerce-cart tr.cart_item td.product-name { font-size: 14.5px; }
	body.woocommerce-cart tr.cart_item td.product-subtotal { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   11. Affiliate signup and dashboard (TopOpti Affiliates), added 2026-09-17.

   The plugin styles itself entirely from CSS variables and picks up the brand
   navy through --ast-global-color-0, so the palette and the pill submit button
   are already correct with no help from us. What it does not win is the text
   fields: Astra's own form styling beats the plugin's .toaff-input rule, which
   left inputs at 4px radius in the system font stack while the rest of the
   site uses 14px and the body font.

   Same @layer trap as everything else in this file, so these carry the body
   prefix AND !important. Do not "tidy" the body prefix away.
   -------------------------------------------------------------------------- */
body .toaff-form .toaff-input,
body .toaff-form input[type="text"],
body .toaff-form input[type="email"],
body .toaff-form input[type="tel"],
body .toaff-form input[type="url"],
body .toaff-form input[type="number"],
body .toaff-form textarea,
body .toaff-form select {
	border-radius: 14px !important;
	font-family: inherit !important;
	font-size: 15px !important;
	border: 1px solid var(--line) !important;
	background-color: #fff;
	color: var(--ink);
}
body .toaff-form .toaff-input:focus,
body .toaff-form textarea:focus,
body .toaff-form select:focus {
	border-color: var(--ink) !important;
	outline: 2px solid var(--ink);
	outline-offset: 1px;
}


/* --------------------------------------------------------------------------
   FREE SHIPPING METER  (cart drawer, added 2026-09-17, restyled same day)

   Modelled on the reference drawer's "distance to the summit" panel: a dark
   band of lines fanning toward a vanishing point, lit from the left up to the
   progress point, with a glowing node on the boundary and a summit glyph at
   the far end. Theirs is green; this is the Ultra Pep navy family.

   Geometry comes from upl_free_shipping_meter() in functions.php. The lines
   are drawn twice with identical paths - dim underneath, bright on top - and
   the bright copy is CLIPPED rather than resized, so the two never drift out
   of register as the percentage changes.

   Everything animates off ONE custom property, --upl-pct. cart-enhance.js
   re-applies the previous value and then the new one after the drawer is
   re-rendered, which is what makes adds and removals animate rather than
   snap. See uplShipMeter() there.

   Read the warning on upl_free_shipping_meter() before making this louder:
   the store has no shipping methods configured, so the promise it makes
   cannot currently be honoured.
   -------------------------------------------------------------------------- */
.upl-ship-meter {
	/* Top margin clears the drawer header's border-bottom, which is the rule
	   the meter text was sitting flush against - the drawer content itself has
	   padding-top: 0. Ralph, 2026-09-17. */
	margin: 16px 0 18px;
}

.upl-ship-meter__text {
	margin: 0 0 10px;
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: .01em;
	color: var(--muted);
}

.upl-ship-meter__text strong {
	color: var(--ink);
	font-weight: 700;
}

/* ---- The panel ---- */
.upl-ship-meter__panel {
	position: relative;
	height: 76px;   /* Ralph, 2026-09-17: was 104px, too dominant in the drawer.
	                   The SVG stretches (preserveAspectRatio="none"), so the
	                   line fan just compresses - no geometry change needed. */
	border-radius: 14px;
	overflow: hidden;
	background:
		radial-gradient(120% 140% at 12% 50%, #0a2a7a 0%, #04143f 55%, #020c28 100%);
	background-color: #04143f;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
}

.upl-ship-meter__lines {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

.upl-ship-meter__lines path {
	fill: none;
	stroke-width: 1.1;
	vector-effect: non-scaling-stroke;
}

/* Unlit: the distance still to travel. */
.upl-ship-meter__base path {
	stroke: rgba(255, 255, 255, .16);
}

/* Lit: revealed from the left to the progress point.

   The clip lives on this plain DIV rather than on the SVG group. An earlier
   comment here claimed clipping a <g> was broken in Chrome - that was WRONG,
   and is corrected rather than deleted so nobody re-derives it. The real
   cause of the symptom was that the meter sits inside the cart drawer, which
   is `visibility: hidden` and 2x2 while closed: Chrome does not recalculate
   style in that subtree, so a custom property changed there reads back as
   updated while the computed clip-path stays stale. The same declaration on
   a visible element resolves and transitions correctly (verified directly).
   A div is still the better place for it, so the structure stayed.
   
   Clipping rather than resizing also keeps the lit copy in exact register
   with the base copy underneath - both SVGs share a viewBox and
   preserveAspectRatio="none", so they stretch identically. */
.upl-ship-meter__litwrap {
	position: absolute;
	inset: 0;
	clip-path: inset(0 calc(100% - var(--upl-pct, 0%)) 0 0);
	transition: clip-path 900ms cubic-bezier(.22, .61, .36, 1);
	will-change: clip-path;
}

.upl-ship-meter__lit path {
	stroke: #4d7cff;
	filter: drop-shadow(0 0 3px rgba(77, 124, 255, .85));
}

/* ---- The node on the boundary ---- */
.upl-ship-meter__node {
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--upl-pct, 0%);
	width: 1px;
	margin-left: -1px;
	background: linear-gradient(to bottom,
		rgba(120, 160, 255, 0) 0%,
		rgba(120, 160, 255, .55) 35%,
		rgba(120, 160, 255, .55) 65%,
		rgba(120, 160, 255, 0) 100%);
	transition: left 900ms cubic-bezier(.22, .61, .36, 1);
}

.upl-ship-meter__node::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	transform: translate(-50%, -50%);
	background: #dce6ff;
	box-shadow:
		0 0 6px 2px rgba(120, 160, 255, .9),
		0 0 18px 6px rgba(77, 124, 255, .55);
}

/* ---- Summit ---- */
.upl-ship-meter__summit {
	position: absolute;
	right: 12px;
	bottom: 10px;
	width: 15px;
	height: 15px;
	fill: rgba(255, 255, 255, .28);
	transition: fill 600ms ease;
}

/* ---- Unlocked ----
   Ralph, 2026-09-17: white / light branded blue at the summit rather than the
   reference's green. The lines brighten to near-white with a blue bloom, which
   reads as "fully lit" and keeps the panel inside the navy palette instead of
   introducing a second accent colour the brand does not use anywhere else. */
.upl-ship-meter.is-unlocked .upl-ship-meter__text { color: var(--ink); }
.upl-ship-meter.is-unlocked .upl-ship-meter__text strong { color: var(--ink); }
.upl-ship-meter.is-unlocked .upl-ship-meter__lit path {
	stroke: #eaf1ff;
	filter: drop-shadow(0 0 5px rgba(150, 185, 255, .95));
}
.upl-ship-meter.is-unlocked .upl-ship-meter__node { background: none; }
.upl-ship-meter.is-unlocked .upl-ship-meter__node::after {
	background: #ffffff;
	box-shadow:
		0 0 8px 3px rgba(190, 215, 255, .95),
		0 0 22px 8px rgba(120, 160, 255, .55);
}
.upl-ship-meter.is-unlocked .upl-ship-meter__summit { fill: rgba(234, 241, 255, .95); }

/* A reduced-motion user gets the end state without the sweep. */
@media (prefers-reduced-motion: reduce) {
	.upl-ship-meter__litwrap,
	.upl-ship-meter__node,
	.upl-ship-meter__summit { transition: none; }
}

/* --------------------------------------------------------------------------
   UNLOCKED METER: BIGGER TEXT + THE SWEEP  (2026-09-22)

   Once free shipping is achieved the line steps up to 15px/700 from 13px/400
   - "a bit bigger and bolder. Nothing crazy" - and a narrow white band sweeps
   along it.

   TWO MECHANISMS, ONE EFFECT, split by width:

     desktop  the band is a gradient painted INTO the glyphs with
              background-clip: text. Sub-pixel and exact.
     mobile   the band is an overlay blended over the paragraph with
              mix-blend-mode: lighten, because the desktop mechanism leaves
              the line blank on mobile Safari. See that block for the full
              account.

   Both run the same 10.5s on the same gradient geometry. Change one, change
   the other.

   A third treatment (letters lighting in sequence) and a ?shipanim= switch
   for comparing them lived here until the sweep was chosen; both are gone.
   -------------------------------------------------------------------------- */
.upl-ship-meter.is-unlocked .upl-ship-meter__text {
	font-size: 15px;
	line-height: 1.35;
	margin-bottom: 12px;
}

.upl-ship-meter__unlocked {
	display: inline;
	font-weight: 700;
}


/* ---- Desktop: the band, clipped to the text ----
   One moving highlight over the whole line, from a gradient clipped to the
   glyphs. The gradient is 220% wide so the band has somewhere to come from
   and somewhere to go. It cuts hard at the leading edge and fades only
   behind - see the note inside the rule for why that asymmetry matters.

   background-clip: text needs a transparent fill, which means the text has no
   colour of its own while this runs - so the fallback below sets a solid
   colour first, and only browsers that support the clip take it away. */
.upl-ship-meter.is-unlocked .upl-ship-meter__unlocked {
	color: var(--ink);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
	.upl-ship-meter.is-unlocked .upl-ship-meter__unlocked {
		/* THE WHITE EDGE, AND NOTHING ELSE.
		   
		   Corrected 2026-09-22 after I removed the wrong half. The crisp
		   part - the part worth keeping - is the WHITE band and its hard
		   boundary: the meter text is brand navy on a white drawer, so a
		   white band does not paint light onto the letters, it takes them
		   away, and the hard stop makes them snap back. That edge is what
		   reads as clean.
		   
		   The soft blue ramp that used to sit behind it was the "bubble" -
		   a rounded wash of colour with no defined edge of its own. Gone.
		   
		   So: a narrow band of white travelling over navy, with a HARD stop
		   at the leading edge (the repeated 50%) and a fade behind it,
		   43.5% to 47.5%, easing back into the navy. It cuts off hard
		   in front and recovers behind - which is the shape of something
		   moving, rather than a blob that happens to be lit.
		   
		   The fade is an opaque near-white tint (#e6ebfb), not a
		   transparent white. background-clip: text paints the gradient INTO
		   the glyphs, so a semi-transparent stop lets the white page show
		   through and reads as fully white - there would be no gradation at
		   all. The tint has to be a real colour between navy and white, and
		   it is kept close to white so the trail reads as light rather than
		   as blue. Ralph, 2026-09-22: the bluer version "looks weird".
		   
		   Do not "tidy" the repeated stop positions into single stops. Each
		   duplicated percentage IS an edge; merging them puts the blur back. */
		background-image: linear-gradient(
			100deg,
			var(--ink)                       0%,
			var(--ink)                    43.5%,
			#e6ebfb                       46.1%,
			#ffffff                       47.5%,
			#ffffff                         50%,
			var(--ink)                      50%,
			var(--ink)                     100%
		);
		background-size: 220% 100%;
		background-position: 120% 0;
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		color: transparent;
		animation: upl-ship-trail 10.5s cubic-bezier(.4, .02, .3, 1) infinite;
	}
}

@keyframes upl-ship-trail {
	0%   { background-position: 120% 0; }
	70%  { background-position: -20% 0; }
	100% { background-position: -20% 0; }   /* rest before the next pass */
}

/* A reduced-motion user gets the finished state: bigger, bold, navy, still.
   The text fill has to be handed back explicitly - stopping the animation
   would otherwise leave the desktop rule's transparent fill in place, and an
   invisible line is not a calmer one. The overlay is stopped too. */
@media (prefers-reduced-motion: reduce) {
	.upl-ship-meter__unlocked {
		animation: none !important;
		background-image: none;
		color: var(--ink);
		-webkit-text-fill-color: currentColor;
	}

	.upl-ship-meter.is-unlocked .upl-ship-meter__text::after {
		animation: none !important;
		display: none;
	}
}

/* --------------------------------------------------------------------------
   MOBILE: the same sweep, painted OVER the text  (2026-09-22)

   Two failed attempts precede this one, and both are worth knowing about.

   1. The desktop mechanism - background-clip: text with a transparent text
      fill - left the line completely blank on a phone. It is unreliable on
      mobile Safari, particularly once the sentence wraps and the inline box
      paints as two fragments, and it fails invisibly: transparent fill, no
      text, nothing to read.

   2. Animating the per-character spans instead fixed the blankness but
      quantised the sweep to whole letters. Ralph: "it looks like its
      stuttering". At 13-15px a character is 7-9px, so the band jumps in
      visible steps instead of sliding.

   So the band is now a real moving object: an overlay on the paragraph,
   carrying the same gradient, blended onto the text with mix-blend-mode:
   lighten. White pixels in the band lift the navy glyphs beneath them to
   white; everything outside the band is transparent and changes nothing.
   Continuous, sub-pixel, and the TEXT'S OWN COLOUR IS NEVER TOUCHED - so
   there is no failure mode that empties the line.

   If mix-blend-mode is not supported the overlay is never created and the
   line is simply static: larger, bold, legible. That is the right way for
   this to degrade.

   The overlay covers the whole paragraph, so on a wrapped line the band
   crosses both rows at once rather than snaking through the text. At this
   width that reads as a single edge passing over the message, which is the
   intent.

   KEEP IN STEP WITH THE DESKTOP RULE: same 10.5s, same gradient geometry.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
	/* Hand the text back its own colour. Nothing here makes it transparent. */
	.upl-ship-meter.is-unlocked .upl-ship-meter__unlocked {
		background-image: none;
		-webkit-text-fill-color: currentColor;
		color: var(--ink);
		animation: none;
	}

		@supports (mix-blend-mode: lighten) {
		.upl-ship-meter.is-unlocked .upl-ship-meter__text {
			position: relative;
			/* Contain the blend: without isolation it would reach past the
			   paragraph and lighten whatever the drawer paints behind it. */
			isolation: isolate;
		}

		.upl-ship-meter.is-unlocked .upl-ship-meter__text::after {
			content: "";
			position: absolute;
			inset: 0;
			pointer-events: none;
			mix-blend-mode: lighten;
			background-image: linear-gradient(
				100deg,
				rgba( 255, 255, 255, 0 )        0%,
				rgba( 255, 255, 255, 0 )     43.5%,
				rgba( 255, 255, 255, .55 )   46.1%,
				#ffffff                      47.5%,
				#ffffff                        50%,
				rgba( 255, 255, 255, 0 )       50%,
				rgba( 255, 255, 255, 0 )      100%
			);
			background-size: 220% 100%;
			background-position: 120% 0;
			animation: upl-ship-trail 10.5s cubic-bezier(.4, .02, .3, 1) infinite;
		}
	}
}
