/*
 * Custom Irish — brand layer (palette + typography + buttons)
 * ===========================================================
 * Implements Sinéad's brief of 2026-08-08: Coach House-inspired palette,
 * Cormorant Garamond headings / EB Garamond body, gold button system.
 *
 * TWO DELIBERATE DEVIATIONS, both to satisfy the accessibility requirement
 * that was also in the brief:
 *
 * 1. Gold button LABEL uses --c-gold-ink (#836A2A), not #C7A550.
 *    #C7A550 text on white measures 2.35:1 and on off-white 2.08:1. WCAG AA
 *    needs 4.5:1; it fails even the 3:1 large-text bar, so the specified
 *    default button would have been unreadable for low-vision users.
 *    #836A2A is the SAME hue (43deg) and saturation, just darker — it reads as
 *    the same gold and measures 5.17:1 on white, 4.57:1 on off-white.
 *    The button OUTLINE stays exactly #C7A550, so the brand gold is what you
 *    see. Hover/active states use #C7A550 as specified (teal on gold = 5.50:1).
 *
 * 2. Sage #818B7D is restricted to large text, borders and decorative fills.
 *    As body copy it measures 3.14:1 on off-white — fine at >=24px, not at
 *    paragraph sizes.
 *
 * Both are flagged for Sinéad's approval; revert by pointing --c-gold-ink at
 * --c-gold if she prefers the exact spec over the contrast requirement.
 */

/*
 * 21 Aug: the palette is READ FROM ELEMENTOR, not fixed here.
 *
 * Each token takes its value from the Elementor kit's global colour variable
 * (Site Settings > Global Colors), with the original client hex as the
 * fallback for anything that renders before/without the kit stylesheet. That
 * makes the swatches in Site Settings the single control for the whole site —
 * WooCommerce templates included, because this file is what colours them.
 *
 * Kit slot -> token:  Primary -> teal · Secondary -> sage · Text -> black ·
 * Button (c2ba474) -> gold · Background (7616fc7) -> off-white ·
 * Border Color (eda96eb) -> stone. Accent (white) is deliberately NOT bound.
 *
 * Declared on body as well as :root because Elementor puts the kit variables
 * on <body class="elementor-kit-N">, and a var() reference resolves on the
 * element that declares it — on :root alone every token would silently use
 * its fallback and Site Settings would do nothing.
 */
:root,
body {
	/* --- palette (client-specified defaults; live values from the kit) --- */
	--c-gold:        var(--e-global-color-c2ba474, #C7A550);  /* brand gold — fills, outlines, hover */
	--c-teal:        var(--e-global-color-primary, #0D3739);  /* deep heritage teal */
	--c-sage:        var(--e-global-color-secondary, #818B7D);  /* muted sage green */
	--c-stone:       var(--e-global-color-eda96eb, #EAE6E1);  /* warm stone */
	--c-offwhite:    var(--e-global-color-7616fc7, #F1F1EF);  /* soft off-white */
	--c-black:       var(--e-global-color-text, #030303);  /* near black */
	--c-white:       #FFFFFF;

	/* --- derived (fixed fallbacks; recomputed from the base colour below) --- */
	--c-gold-ink:    #836A2A;  /* accessible gold for text on light bg (see note 1) */
	--c-gold-press:  #A8873F;  /* darkened gold for the pressed state */
	--c-teal-soft:   #17494C;  /* teal hover for links */

	/* --- type --- */
	--font-heading: 'Cormorant Garamond', Cormorant, Garamond, 'Times New Roman', Times, serif;
	--font-body:    'EB Garamond', Garamond, 'Times New Roman', Times, serif;
}

/* Derived shades computed from the chosen base colours, so changing the gold
   or teal in Site Settings carries the text-safe gold and the hover teal with
   it. 62% gold / 38% black keeps the small-text gold above 4.5:1 on off-white.
   Older browsers without color-mix() keep the fixed fallbacks above. */
@supports (color: color-mix(in srgb, red, blue)) {
	:root,
	body {
		--c-gold-ink:   color-mix(in srgb, var(--c-gold) 62%, black);
		--c-gold-press: color-mix(in srgb, var(--c-gold) 84%, black);
		--c-teal-soft:  color-mix(in srgb, var(--c-teal) 92%, white);
	}
}

/* ==========================================================================
   TYPOGRAPHY
   Cormorant Garamond -> headings + buttons
   EB Garamond        -> body, navigation, supporting text
   Both stacks end in a real serif so a cold load degrades gracefully. The
   previous theme declared `font-family: Inter` with no fallback, which is why
   uncached loads flashed Times.
   ========================================================================== */

body,
button, input, select, optgroup, textarea,
.elementor-widget-text-editor,
.woocommerce-page {
	font-family: var(--font-body);
	color: var(--c-black);
}

h1, h2, h3, h4, h5, h6,
.entry-title, .product_title,
.elementor-heading-title,
.woocommerce-loop-product__title,
.widget-title, .footer-widget-title {
	font-family: var(--font-heading);
	color: var(--c-teal);
}

/* H1 and H2 colour come from Elementor Site Settings > Typography > H1 / H2
   (customirish_kit_heading_colors() in functions.php prints --c-h1/--c-h2
   from the kit). A level left unset there falls back to the teal token.
   H1–H3; paragraph text is deliberately excluded — it varies by context. */
h1, .product_title { color: var(--c-h1, var(--c-teal)); }
h2 { color: var(--c-h2, var(--c-teal)); }
h3 { color: var(--c-h3, var(--c-teal)); }
/* .entry-title is an H1 on a single post but an H2 on the blog archive, so the
   tag decides its level — and the link inside an archive title takes the
   heading's colour instead of the site link colour. */
body h1.entry-title a, body h2.entry-title a, body h3.entry-title a,
body h1 a:not(.button), body h2 a:not(.button), body h3 a:not(.button) {
	color: inherit !important;   /* Shoptimizer sets .entry-title a to #111 with more weight */
}

/* Navigation reads as supporting text -> EB Garamond */
.main-navigation, .main-navigation a,
#primary_menu, #primary_menu a,
#primary_menu--mob, #primary_menu--mob a,
.elementor-nav-menu, .elementor-nav-menu a,
.secondary-navigation, .secondary-navigation a,
.top-bar, .top-bar a {
	font-family: var(--font-body);
}

/*
 * EB Garamond Medium (500) for smaller text, per the brief. Garamond
 * letterforms are light at small sizes; 500 holds up where 400 goes muddy,
 * especially on mobile.
 */
small, .small, figcaption, .caption,
.woocommerce-breadcrumb,
.product_meta, .posted_on, .byline,
.wc-block-components-notice-banner,
label, .form-row label,
.woocommerce-form__label,
input, select, textarea,
.elementor-widget-text-editor small,
.site-footer .widget li,
.copyright, .copyright a {
	font-weight: 500;
}

@media (max-width: 782px) {
	/* Hold the floor at 16px on mobile so Garamond stays readable and iOS
	   does not zoom the viewport on input focus. */
	body, p, li, td, input, select, textarea {
		font-size: 16px;
		font-weight: 500;
	}
}

/* ==========================================================================
   COLOUR — global
   ========================================================================== */

body, .site {
	color: var(--c-black);
}

a { color: var(--c-teal); }
a:hover, a:focus { color: var(--c-gold-ink); }

/* Feature / alternating sections */
.shoptimizer-category-banner,
header.woocommerce-products-header,
.below-content,
.elementor-section.feature-section {
	background-color: var(--c-stone);
}

/* ==========================================================================
   HEADER + NAVIGATION
   ========================================================================== */

.top-bar {
	background-color: var(--c-teal);
	color: var(--c-white);
}
.top-bar a { color: var(--c-white); }
.top-bar a:hover { color: var(--c-gold); }

/*
 * Header background.
 *
 * Do NOT paint #primary_menu — it is an inner Elementor container sitting on a
 * wider header row. Giving it its own colour draws a visible rectangle behind
 * the menu items wherever it differs from the row around it. It stays
 * transparent and inherits; only the outer header surfaces get a colour.
 */
/* Header keeps its existing background; only the nav colours change. */

/*
 * Never blanket-paint Elementor containers in the header.
 *
 * `.elementor-location-header > .e-con > .e-con` looked like a tidy way to
 * catch the header row, but the teal top bar is also a direct .e-con child, so
 * the rule painted ITS inner containers off-white — producing pale blocks
 * floating on the teal strip. The header row is targeted by its id (#header_top)
 * instead, and every other container inside the header stays transparent so it
 * inherits whatever strip it sits on.
 */
.elementor-location-header .e-con .e-con,
.elementor-location-header .e-con-inner,
#header_top .e-con,
#header_top .e-con-inner,
.elementor-element-63094828 .e-con,
.elementor-element-63094828 .e-con-inner,
.elementor-element-63094828 .elementor-widget-container {
	background-color: transparent !important;
}

#primary_menu,
#primary_menu > .e-con-inner,
#primary_menu .elementor-widget-nav-menu,
#primary_menu .elementor-widget-container {
	background-color: transparent !important;
}

#primary_menu nav > ul > li > a,
.main-navigation ul.menu > li > a {
	color: var(--c-teal);
}
#primary_menu nav > ul > li > a:hover,
#primary_menu nav > ul > li.current_page_item > a,
.main-navigation ul.menu > li > a:hover {
	color: var(--c-gold-ink);
}

/* Dropdown panels */
#primary_menu nav > ul li.menu-item-has-children > ul.sub-menu {
	background-color: var(--c-white);
	border-top: 2px solid var(--c-gold);
}
#primary_menu nav > ul li.menu-item-has-children > ul.sub-menu a {
	color: var(--c-teal);
}
#primary_menu nav > ul li.menu-item-has-children > ul.sub-menu a:hover {
	color: var(--c-gold-ink);
	background-color: var(--c-offwhite);
}

/* ==========================================================================
   FOOTER
   ========================================================================== */

footer.site-footer,
footer.copyright {
	background-color: var(--c-teal);
	color: var(--c-offwhite);
}
.site footer.site-footer .widget .widget-title,
.site-footer .widget.widget_block h2 {
	color: var(--c-white);
	font-family: var(--font-heading);
}
footer.site-footer a:not(.button),
footer.copyright a {
	color: var(--c-offwhite);
}
footer.site-footer a:not(.button):hover,
footer.copyright a:hover {
	color: var(--c-gold);
}

/* ==========================================================================
   BUTTONS — the gold system
   default : off-white fill, gold outline, gold label
   hover   : solid gold fill, teal label
   active  : solid gold fill darkened, teal label
   focus   : visible teal ring for keyboard users
   ========================================================================== */

.button,
button,
input[type="submit"],
.wp-element-button,
.elementor-button,
ul.products li.product .button,
.product .cart .single_add_to_cart_button,
.woocommerce #respond input#submit,
.widget_shopping_cart a.button,
.woocommerce-cart p.return-to-shop a,
.cart-collaterals .checkout-button,
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button,
#payment .place-order .button,
.added_to_cart {
	font-family: var(--font-heading);
	font-weight: 600;
	letter-spacing: 0.02em;
	background-color: var(--c-offwhite);
	color: var(--c-gold-ink);
	border: 2px solid var(--c-gold);
	border-radius: 2px;
	transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.button:hover,
button:hover,
input[type="submit"]:hover,
.wp-element-button:hover,
.elementor-button:hover,
ul.products li.product .button:hover,
.product .cart .single_add_to_cart_button:hover,
.woocommerce #respond input#submit:hover,
.widget_shopping_cart a.button:hover,
.woocommerce-cart p.return-to-shop a:hover,
.cart-collaterals .checkout-button:hover,
.wc-block-cart__submit-button:hover,
.wc-block-components-checkout-place-order-button:hover,
#payment .place-order .button:hover,
.added_to_cart:hover {
	background-color: var(--c-gold);
	color: var(--c-teal);
	border-color: var(--c-gold);
}

.button:active,
button:active,
input[type="submit"]:active,
.wp-element-button:active,
.elementor-button:active,
.product .cart .single_add_to_cart_button:active,
.cart-collaterals .checkout-button:active,
.wc-block-components-checkout-place-order-button:active,
#payment .place-order .button:active {
	background-color: var(--c-gold-press);
	color: var(--c-teal);
	border-color: var(--c-gold-press);
	transform: translateY(1px);
}

/*
 * Focus ring. :focus-visible so it appears for keyboard users without ringing
 * every mouse click. The :focus fallback covers browsers without support.
 */
.button:focus-visible,
button:focus-visible,
input[type="submit"]:focus-visible,
.wp-element-button:focus-visible,
.elementor-button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
	outline: 3px solid var(--c-teal);
	outline-offset: 2px;
	border-radius: 2px;
}

/* ==========================================================================
   WOOCOMMERCE — product, cart, checkout, forms, notices
   ========================================================================== */

.single-product .site-content .col-full,
.woocommerce-cart .site-content,
.woocommerce-checkout .site-content {
	background-color: var(--c-offwhite);
}

.price, .amount, .woocommerce-Price-amount {
	font-family: var(--font-heading);
	color: var(--c-teal);
	font-weight: 600;
}

.onsale, .product-label, .wc-block-grid__product-onsale {
	background-color: var(--c-teal);
	color: var(--c-white);
	font-family: var(--font-body);
	font-weight: 500;
}

.star-rating > span:before,
p.stars.selected a.active::before,
p.stars:hover a::before {
	color: var(--c-gold);
}

/* Form controls */
input[type="text"], input[type="email"], input[type="tel"],
input[type="password"], input[type="number"], input[type="search"],
select, textarea,
.wc-block-components-text-input input {
	background-color: var(--c-white);
	border: 1px solid var(--c-sage);
	color: var(--c-black);
	font-family: var(--font-body);
}
input:focus, select:focus, textarea:focus {
	border-color: var(--c-teal);
}

/* Notices — teal for info, gold rule for the standard Woo message */
.woocommerce-message,
.wc-block-components-notice-banner.is-info {
	background-color: var(--c-stone);
	border-top-color: var(--c-gold);
	color: var(--c-black);
}
.woocommerce-info,
.wc-block-components-notice-banner {
	background-color: var(--c-stone);
	border-top-color: var(--c-teal);
	color: var(--c-black);
}
.woocommerce-error,
.wc-block-components-notice-banner.is-error {
	border-top-color: #9B2C2C;
	background-color: var(--c-stone);
	color: var(--c-black);
}

/* Checkout progress */
ul.checkout-bar:before,
.woocommerce-checkout .checkout-bar li.active:after,
ul.checkout-bar li.visited:after {
	background-color: var(--c-gold);
}

/* Free-shipping / progress bars */
.commercekit-fsn-bar, .fsn-bar {
	background-color: var(--c-gold);
}

/* ==========================================================================
   OVERRIDE LAYER — beating per-widget Elementor typography
   --------------------------------------------------------------------------
   Updating the Elementor kit fixes the GLOBAL defaults, and the generated CSS
   now emits both Garamonds. But many individual widgets on this site carry
   their own typography override (font_family set per-widget in the editor),
   and widget CSS outranks kit CSS. Those widgets still ask for Manrope.

   Rather than rewrite _elementor_data across every page — invasive, hard to
   reverse, and easy to get wrong on a live store — this layer forces the two
   brand families at the point of use. !important is deliberate and confined to
   font-family and the core brand colours; nothing else uses it.

   If Sinéad approves the direction, the clean follow-up is to strip the stale
   per-widget font_family values in the editor and delete this block.
   ========================================================================== */

body,
body p, body li, body td, body span, body div,
body input, body select, body textarea, body label,
body .elementor-widget-text-editor,
body .elementor-widget-text-editor *,
body .woocommerce, body .woocommerce * {
	font-family: var(--font-body) !important;
}

body h1, body h2, body h3, body h4, body h5, body h6,
body .elementor-heading-title,
body .entry-title, body .product_title,
body .woocommerce-loop-product__title,
body .widget-title,
body .price, body .woocommerce-Price-amount {
	font-family: var(--font-heading) !important;
}

body .button, body button,
body input[type="submit"],
body .elementor-button,
body .wp-element-button,
body .single_add_to_cart_button,
body .checkout-button,
body .wc-block-components-checkout-place-order-button {
	font-family: var(--font-heading) !important;
}

/*
 * Icon fonts must be named explicitly, not reverted.
 *
 * The broad !important rules above otherwise cascade into icon elements and
 * their ::before pseudo-elements, and an icon glyph rendered in Garamond comes
 * out as a stray letter (WooCommerce stars literally render "sssss").
 * `font-family: revert` does NOT work here — it reverts to the user-agent
 * value, not to the icon font — so each family is restored by name.
 */
body .ri, body .ri:before,
body [class^="ri-"], body [class*=" ri-"],
body [class^="ri-"]:before, body [class*=" ri-"]:before {
	font-family: Rivolicons, sans-serif !important;
}

body [class^="eicon-"], body [class*=" eicon-"],
body [class^="eicon-"]:before, body [class*=" eicon-"]:before {
	font-family: eicons !important;
}

body .dashicons, body .dashicons:before,
body .dashicons-before:before {
	font-family: dashicons !important;
}

body .fa, body .fab, body .fas, body .far,
body [class^="fa-"], body [class*=" fa-"],
body .fa:before, body .fab:before, body .fas:before, body .far:before,
body [class^="fa-"]:before, body [class*=" fa-"]:before {
	font-family: "Font Awesome 5 Free", "Font Awesome 5 Brands" !important;
}

/* WooCommerce star ratings use the 'WooCommerce' and 'star' icon fonts. */
body .star-rating, body .star-rating:before,
body .star-rating span:before,
body .comment-form-rating .stars a:before {
	font-family: WooCommerce !important;
}
body p.stars, body p.stars a, body p.stars a:before {
	font-family: star !important;
}

/* Core brand colours that widget-level settings would otherwise win. */
/* Page background is intentionally NOT set here. The homepage and inner
   templates define their own Elementor section backgrounds (cream hero, white
   feature rows); forcing a colour on body flattened all of them into one
   slab. Only the text colour is set. */
body { color: var(--c-black) !important; }
body h1, body h2, body h3, body h4, body h5, body h6,
body .elementor-heading-title { color: var(--c-teal); }
body h1, body h1.elementor-heading-title { color: var(--c-h1, var(--c-teal)); }
body h2, body h2.elementor-heading-title { color: var(--c-h2, var(--c-teal)); }
body h3, body h3.elementor-heading-title { color: var(--c-h3, var(--c-teal)); }

/* ==========================================================================
   BUTTON OVERRIDE TIER
   --------------------------------------------------------------------------
   The site ships legacy rules that force the OLD gold with !important, e.g.
     button[type="submit"], .checkout-button, #payment .place-order .button
       { background-color: #c2a76a !important }
   (from the Elementor Custom Code snippet and the theme's own CSS). Those beat
   the button system above on background and text colour — the outline came
   through, the fill did not.

   This tier restates the four states at !important so the gold system wins
   everywhere. Once the legacy #c2a76a declarations are removed, this whole
   block can go and the earlier, cleaner rules take over unaided.
   ========================================================================== */

/*
 * The :not() list keeps this tier off <button> elements that are controls, not
 * buttons — the attribute swatches, the drawer close X, the quantity steppers
 * and the gallery lightbox controls. Without it the teal fill covered the frame
 * colour swatches entirely (Gold, Silver and White all rendered as teal
 * squares) and turned the drawer's X into a solid block.
 *
 * Written as a single :not( a, b, c ) rather than :not(a):not(b):not(c) on
 * purpose: the chained form adds each class to the specificity total and would
 * push this rule above later ones that are supposed to win. A comma list
 * scores as its most specific argument, so the tier stays at (0,1,2).
 */
body .button,
body button:not(.cgkit-swatch, .close-drawer, .plus, .minus, .qty-btn, .pswp__button, .commercekit-wishlist-btn, .ci-select__button),
body input[type="submit"],
body button[type="submit"],
body .wp-element-button, body .elementor-button,
body ul.products li.product .button,
body .product .cart .single_add_to_cart_button,
body .woocommerce #respond input#submit,
body .widget_shopping_cart a.button,
body.woocommerce-cart p.return-to-shop a,
body .cart-collaterals .checkout-button,
body .checkout-button,
body .wc-block-cart__submit-button,
body .wc-block-components-checkout-place-order-button,
body #payment .place-order .button,
body .added_to_cart {
	/*
	 * Solid teal, was offwhite with a gold outline.
	 *
	 * Flipped here at the base tier rather than by adding selectors one at a
	 * time further down: this list is already the complete set of buttons on
	 * the site, so changing it once converts Post Comment, newsletter signup,
	 * Apply Coupon, Select Options and everything else in a single place.
	 * Anything appended below only adds type treatment on top.
	 */
	background-color: var(--c-teal) !important;
	color: var(--c-white) !important;
	border: 2px solid var(--c-teal) !important;
}

body .button:hover,
body button:not(.cgkit-swatch, .close-drawer, .plus, .minus, .qty-btn, .pswp__button, .commercekit-wishlist-btn, .ci-select__button):hover,
body input[type="submit"]:hover,
body button[type="submit"]:hover,
body .wp-element-button:hover, body .elementor-button:hover,
body ul.products li.product .button:hover,
body .product .cart .single_add_to_cart_button:hover,
body .woocommerce #respond input#submit:hover,
body .widget_shopping_cart a.button:hover,
body.woocommerce-cart p.return-to-shop a:hover,
body .cart-collaterals .checkout-button:hover,
body .checkout-button:hover,
body .wc-block-cart__submit-button:hover,
body .wc-block-components-checkout-place-order-button:hover,
body #payment .place-order .button:hover,
body .added_to_cart:hover {
	/*
	 * One step lighter than --c-teal, the same hover the product page's Add to
	 * Cart already uses. The previous gold hover was a full colour flip from a
	 * teal resting state, which read as the button changing identity rather
	 * than responding. Gold now signals hover on links, not on buttons.
	 */
	background-color: #16494C !important;
	color: var(--c-white) !important;
	border-color: #16494C !important;
}

body .button:active,
body button:not(.cgkit-swatch, .close-drawer, .plus, .minus, .qty-btn, .pswp__button, .commercekit-wishlist-btn, .ci-select__button):active,
body input[type="submit"]:active,
body button[type="submit"]:active,
body .elementor-button:active,
body .product .cart .single_add_to_cart_button:active,
body .checkout-button:active,
body .cart-collaterals .checkout-button:active,
body .wc-block-components-checkout-place-order-button:active,
body #payment .place-order .button:active {
	background-color: #0A2C2E !important;   /* one step darker than --c-teal */
	color: var(--c-white) !important;
	border-color: #0A2C2E !important;
}

/* Top bar / footer: legacy inline customizer CSS also uses !important. */
body .top-bar { background-color: var(--c-teal) !important; color: var(--c-white) !important; }
body .top-bar a { color: var(--c-white) !important; }
body .top-bar a:hover { color: var(--c-gold) !important; }
body footer.site-footer, body footer.copyright { background-color: var(--c-teal) !important; }

/* --- Header search box: white field, gold outline, teal text --- */
body .elementor-search-form__container {
	background-color: var(--c-white) !important;
	border: 2px solid var(--c-gold) !important;
	border-radius: 2px !important;
}
body .elementor-search-form__input,
body .elementor-search-form__input::placeholder {
	color: var(--c-teal) !important;
	font-family: var(--font-body) !important;
}
body .elementor-search-form__submit,
body .elementor-search-form .elementor-search-form__icon {
	color: var(--c-gold-ink) !important;
}

/* --------------------------------------------------------------------------
   Product card hover
   --------------------------------------------------------------------------
   Shoptimizer fills the hovered card with #fff. Against the old #FAFAF8 page
   that was almost invisible; against the new #F1F1EF it reads as a hard white
   rectangle popping out of the grid. Match the page instead and let the card's
   existing shadow carry the hover affordance.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   Product card padding
   --------------------------------------------------------------------------
   Cards ship with `padding: 0 15px` — horizontal only. Once the hover state
   paints a background, that zero top/bottom padding makes the image sit flush
   against the edge of the fill, which reads as "no padding" on the first card
   in each row where there is no neighbouring card to visually separate it.

   Set the padding evenly and apply it at rest as well as on hover, so the
   background gains breathing room without the card shifting on mouseover.
   box-sizing is already border-box, so the grid columns do not move.
   -------------------------------------------------------------------------- */
body ul.products li.product,
body ul.products li.product:hover {
	padding: 15px !important;
}

/* --------------------------------------------------------------------------
   Catalogue sorting select
   -------------------------------------------------------------------------- */
body .woocommerce-ordering select,
body select.orderby,
body .woocommerce-ordering .select2-selection--single {
	padding: 10px 40px 10px 16px !important;
	line-height: 1.4 !important;
	height: auto !important;
	background-color: var(--c-white);
	border: 1px solid var(--c-sage);
	border-radius: 2px;
	color: var(--c-teal);
	font-family: var(--font-body);
	font-weight: 500;
}

/* --------------------------------------------------------------------------
   Icon-only controls are NOT buttons
   --------------------------------------------------------------------------
   The cart toggle carries .elementor-button-like classes, so the gold button
   system gave it a 2px gold outline and an off-white fill around a 24px icon.
   Icon controls opt out of the button chrome entirely and just take the brand
   colour. Same for the wishlist heart.
   -------------------------------------------------------------------------- */
body .elementor-menu-cart__toggle_button,
body .elementor-menu-cart__toggle .elementor-button,
body .commercekit-wishlist-icon,
body .commercekit-wishlist-icon a,
body a.cart-contents,
body .shoptimizer-cart a,
body .site-header-cart a {
	background-color: transparent !important;
	border: 0 !important;
	padding: 0 !important;
	color: var(--c-teal) !important;
}
body .elementor-menu-cart__toggle_button:hover,
body .commercekit-wishlist-icon a:hover,
body a.cart-contents:hover {
	background-color: transparent !important;
	color: var(--c-gold-ink) !important;
}

/* --------------------------------------------------------------------------
   Wishlist count bubble = cart count bubble
   --------------------------------------------------------------------------
   The two were built to match — the site's own header snippet gives both a
   20px circle, #c9dcd1 on #5e7775 — but they are different widgets underneath
   (the cart's number is a data-counter attribute on a button icon; the
   wishlist's is a span inside an Elementor icon-box description), so nothing
   kept them in step. Two drifts, measured against the cart:

     POSITION  The cart bubble overlaps its icon by 10px on both axes. The
               wishlist's was set to top:-15px, and a `min-width:1400px` rule
               in the snippet pushes it to left:-20px — a rule the cart never
               receives, because it is keyed to a #cart--qty wrapper that is
               not in the markup. So above 1400px the heart's bubble sat a
               full 10px further out and 5px higher, floating clear of the
               heart while the cart's touched.

               The two icon boxes are NOT the same height — the heart's is
               20px and starts 7px lower than the cart's 25px box. So matching
               each bubble's offset to its own icon (-10/-10) still left the
               two bubbles 7px out of line with each other, which is what you
               see in the header: the 0 sitting below the 2. Levelling the
               bubbles was the call, so the top is -17px rather than -10px —
               the heart keeps a 3px overlap instead of 10px, and the pair
               reads as one row of badges.

     COLOUR    Elementor paints .elementor-icon-box-description with the
               primary teal (#0D3739), which beat the snippet's #5e7775 set on
               the circle. Same size, same weight, but a much darker digit —
               which is why it read as bold next to the cart's.

   Both restated here so the two bubbles stay identical at every width.
   -------------------------------------------------------------------------- */
body header #wishlist_counter .elementor-icon-box-wrapper .elementor-icon-box-content {
	/* Was -17px; the 2 Sep bag resize (25.2px -> 20px) moved the cart badge's
	   anchor, leaving the 0 riding 2.3px above the 7. Re-measured live:
	   both bubble tops at the same pixel with -14.7px. */
	top: -14.7px !important;   /* levels with the cart badge, not with the heart */
	left: -10px !important;
}

body #wishlist_counter .elementor-icon-box-description,
body #wishlist_counter p.elementor-icon-box-description,
body .wishlist--count {
	color: #5e7775 !important;
}

/* --------------------------------------------------------------------------
   Search field focus
   --------------------------------------------------------------------------
   The generic 3px teal focus ring reads as a hard black rectangle on the search
   box — and because text inputs ALWAYS match :focus-visible, it fired on every
   click, not just keyboard use. Swap it for a gold ring that belongs to the
   palette. Still clearly visible, so the keyboard-accessibility requirement in
   the brief is still met.
   -------------------------------------------------------------------------- */
body .elementor-search-form__container:focus-within,
body .elementor-search-form__container:focus,
body .elementor-search-form input:focus,
body .elementor-search-form input:focus-visible {
	outline: none !important;
	box-shadow: 0 0 0 3px rgba(199, 165, 80, 0.35) !important;
	border-color: var(--c-gold) !important;
}

/* --------------------------------------------------------------------------
   Single product page — white surfaces
   --------------------------------------------------------------------------
   Client preference (2026-08-08): the product page stays white like the live
   site, rather than the soft off-white used elsewhere. Both #FFFFFF and
   #F1F1EF are in Sinéad's approved palette and her brief does not assign
   either to a specific surface, so this is a placement choice for her to
   confirm at review — not a deviation from the spec.

   Scoped to .single-product so shop, category and home keep the off-white.
   -------------------------------------------------------------------------- */
body.single-product,
body.single-product .site,
body.single-product .site-content,
body.single-product .site-content .col-full,
body.single-product .product-details-wrapper,
body.single-product .commercekit-atc-sticky-tabs,
body.single-product .woocommerce-tabs,
body.single-product .wc-tabs-wrapper,
body.single-product #commercekit-atc-tabs-wrap,
body.single-product .related-wrapper,
body.single-product .related.products,
body.single-product .woocommerce-Tabs-panel {
	background-color: var(--c-white) !important;
}


/* --------------------------------------------------------------------------
   Product grid: let the first card's hover shadow paint
   --------------------------------------------------------------------------
   main.site-main carries overflow:hidden, while ul.products uses
   margin-left:-15px so card images line up with the page content edge. That
   pulls the first card in every row 15px outside the clipping box, so its
   hover shadow is sliced off flat on the left. Middle and right cards sit
   inside the box and render fully — hence the inconsistency.

   Allowing overflow on the archive main is the only fix that does not move the
   grid: removing the negative margin would shift every card image 15px right
   and break alignment with the breadcrumb and header above it.

   Scoped to product listings so any float-containment elsewhere is untouched.
   -------------------------------------------------------------------------- */
.archive main.site-main,
.post-type-archive-product main.site-main,
.tax-product_cat main.site-main,
.woocommerce-shop main.site-main {
	overflow: visible !important;
}

/* --------------------------------------------------------------------------
   Selected attribute swatch
   --------------------------------------------------------------------------
   CommerceKit marks the chosen swatch by adding .cgkit-swatch-selected to the
   inner <button>. The gold button system above styles every swatch identically,
   so the selected size was indistinguishable from the rest — the customer had
   no confirmation of what they had picked on a configurable product.

   Give the selected swatch the same treatment as hover (solid gold, teal text)
   so the choice is unmistakable, and keep it that way on hover so it does not
   flicker when the pointer passes over it.
   -------------------------------------------------------------------------- */
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch button.cgkit-swatch-selected,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch a.cgkit-swatch-selected,
body .cgkit-attribute-swatch button.cgkit-swatch-selected,
body .cgkit-attribute-swatch a.cgkit-swatch-selected,
body .cgkit-attribute-swatch button.cgkit-swatch-selected:hover,
body .cgkit-attribute-swatch a.cgkit-swatch-selected:hover {
	background-color: var(--c-gold) !important;
	color: var(--c-teal) !important;
	border-color: var(--c-gold) !important;
	font-weight: 600 !important;
}

/* Colour/image swatches use a tick marker instead of a fill — keep it gold. */
body .cgkit-attribute-swatch.cgkit-color > button.cgkit-swatch-selected:before,
body .cgkit-attribute-swatch.cgkit-image > button.cgkit-swatch-selected:before,
body .cgkit-attribute-swatch.cgkit-image > a.cgkit-swatch-selected:before {
	border-color: var(--c-gold) !important;
}

/* --------------------------------------------------------------------------
   Cart + checkout: white surfaces
   --------------------------------------------------------------------------
   These pages must stay white as they were. Shoptimizer tints the checkout
   content area, which now reads as a grey slab against the rest of the site.
   -------------------------------------------------------------------------- */
body.woocommerce-cart,
body.woocommerce-checkout,
body.woocommerce-cart .site-content,
body.woocommerce-checkout .site-content,
body.woocommerce-cart .site-content .col-full,
body.woocommerce-checkout .site-content .col-full,
body.woocommerce-cart .content-area,
body.woocommerce-checkout .content-area,
body.woocommerce-checkout .checkout,
body.woocommerce-cart main.site-main,
body.woocommerce-checkout main.site-main {
	background-color: var(--c-white) !important;
}

/* --------------------------------------------------------------------------
   Dropdown: current page marked with gold text, not a gold block
   --------------------------------------------------------------------------
   The theme highlighted the active sub-menu item with a filled gold bar that
   stopped short on the right (padding only on one side) and sat awkwardly
   against the panel. Drop the fill entirely and mark the current page with
   gold type instead — quieter, and it reads correctly at any item width.
   Uses --c-gold-ink so the label still clears 4.5:1 on the white panel.
   -------------------------------------------------------------------------- */
body #primary_menu .sub-menu li.current-menu-item > a,
body #primary_menu .sub-menu li.current_page_item > a,
body #primary_menu .sub-menu li.current-menu-ancestor > a,
body #primary_menu .sub-menu a.elementor-item-active,
body #primary_menu--mob .sub-menu li.current-menu-item > a {
	color: var(--c-gold-ink) !important;
	background-color: transparent !important;
	background-image: none !important;
	font-weight: 600 !important;
}

/* --------------------------------------------------------------------------
   Links inherit the body face
   --------------------------------------------------------------------------
   The override layer listed p/li/td/span/div/input/label but omitted <a>, so
   every link outside the main nav (which has its own rule) kept the old
   sans-serif — most visibly the footer link columns, where the headings were
   Garamond but the links under them were not.
   -------------------------------------------------------------------------- */
body a,
body .site-footer a,
body .site-footer li,
body .site-footer .widget a,
body .elementor-widget-container a,
body footer.copyright a {
	font-family: var(--font-body) !important;
}

/* Footer headings stay on the display face. */
body .site-footer .widget-title,
body .site-footer .widget.widget_block h2,
body .site-footer h1, body .site-footer h2,
body .site-footer h3, body .site-footer h4,
body .site-footer .elementor-heading-title {
	font-family: var(--font-heading) !important;
}

/*
 * Re-assert icon fonts AFTER the link rule above — social icons and similar are
 * <a> elements, and an icon glyph rendered in Garamond comes out as a stray
 * letter. These must be the last word on font-family for icon elements.
 */
body a.ri, body a.ri:before,
body a [class^="ri-"], body a [class*=" ri-"],
body a [class^="ri-"]:before, body a [class*=" ri-"]:before {
	font-family: Rivolicons, sans-serif !important;
}
body a [class^="eicon-"], body a [class*=" eicon-"],
body a [class^="eicon-"]:before, body a [class*=" eicon-"]:before,
body [class^="eicon-"], body [class*=" eicon-"],
body [class^="eicon-"]:before, body [class*=" eicon-"]:before {
	font-family: eicons !important;
}
body a .fa, body a .fab, body a .fas, body a .far,
body a [class^="fa-"], body a [class*=" fa-"],
body a .fab:before, body a .fas:before, body a .far:before,
body a [class^="fa-"]:before, body a [class*=" fa-"]:before,
body .fab:before, body .fas:before, body .far:before {
	font-family: "Font Awesome 5 Free", "Font Awesome 5 Brands" !important;
}
body a .dashicons, body a .dashicons:before,
body .dashicons, body .dashicons:before {
	font-family: dashicons !important;
}

/* --------------------------------------------------------------------------
   Checkout / cart: stop clipping the form
   --------------------------------------------------------------------------
   main.site-main carries overflow:hidden and the billing fields sit flush at
   its left edge, so input borders and the Order-notes box are sliced down the
   left. Same cause as the product-grid shadow clipping.
   -------------------------------------------------------------------------- */
.woocommerce-checkout main.site-main,
.woocommerce-cart main.site-main,
.woocommerce-checkout .content-area,
.woocommerce-cart .content-area {
	overflow: visible !important;
}

/* --------------------------------------------------------------------------
   Padlock icon on Place Order / Proceed to Checkout
   --------------------------------------------------------------------------
   The padlock is not a font glyph or an image — it is a CSS mask-image painted
   by background-color. That colour was white, which was invisible against the
   old solid-gold button and is still invisible against the new off-white fill.
   Colouring the text does nothing; the BACKGROUND-COLOR is the paint.

   Default: gold ink, matching the label. Hover/active: teal, because the button
   fills with gold and the label flips to teal.
   -------------------------------------------------------------------------- */
body #place_order:before,
body .checkout-button:before,
body .cart-collaterals .checkout-button:before,
body #payment .place-order .button:before,
body .wc-block-components-checkout-place-order-button:before,
body .wc-block-cart__submit-button:before {
	background-color: var(--c-gold-ink) !important;
}

body #place_order:hover:before,
body #place_order:active:before,
body .checkout-button:hover:before,
body .checkout-button:active:before,
body .cart-collaterals .checkout-button:hover:before,
body #payment .place-order .button:hover:before,
body .wc-block-components-checkout-place-order-button:hover:before,
body .wc-block-cart__submit-button:hover:before {
	background-color: var(--c-teal) !important;
}

/* --------------------------------------------------------------------------
   Homepage feature sections — muted sage
   --------------------------------------------------------------------------
   Client-specified #818B7E for:
     .elementor-element-4e70c77e  "How Personalization Works"  (was teal #0D3739)
     .elementor-element-23b167b5  "Loved By Our Customers"     (was #8DA299)

   Note: #818B7E is one digit off Sinéad's sage #818B7D — visually identical,
   using the value as given.

   CONTRAST WARNING: white body copy on this sage measures 3.55:1. That clears
   WCAG AA for LARGE text (>=24px / >=18.66px bold) but FAILS the 4.5:1 needed
   for normal-size text. The section headings are fine; the small step
   descriptions under them are not. Left as-is pending a decision — switching
   that small copy to --c-black would take it to 16.6:1.
   -------------------------------------------------------------------------- */
body .elementor-element-4e70c77e,   /* "How Personalization Works" heading band */
body .elementor-element-6c1eac9,    /* the four numbered steps below it        */
body .elementor-element-23b167b5 {  /* "Loved By Our Customers"                */
	background-color: var(--c-sage) !important;
}

/*
 * Deliberately NOT included: .elementor-element-63094828 (top bar),
 * .elementor-element-572d5d1d (footer) and .elementor-element-3ec3de3
 * (copyright). Those are the only other teal bands on the page and they stay
 * teal — the sage is for the two feature sections only.
 */

/* Step cards inside "How Personalization Works" inherit the sage rather than
   keeping their own teal fill. Targeting the container classes instead of the
   four elementor-element-NNN ids keeps this working if the section is edited. */
body .elementor-element-6c1eac9 .e-con,
body .elementor-element-6c1eac9 .e-con-inner,
body .elementor-element-6c1eac9 .elementor-widget-container {
	background-color: transparent !important;
}

/* ==========================================================================
   PRODUCT SUMMARY — USP bullets + social proof
   ========================================================================== */

/*
 * Product title line-height.
 *
 * 64px at the global 1.23 ratio leaves ~79px between lines, which opens a
 * visible gap on a two-line product title and makes the block read as two
 * separate headings. Display type at this size wants a tighter ratio than body
 * copy — 1.08 closes it up without the ascenders and descenders colliding.
 */
body .product_title.entry-title {
	line-height: 1.05 !important;
	margin-bottom: 0.35em !important;
}

/* Price sits close under the title as one unit. */
body.single-product .cgkit-as-variation-price,
body.single-product .summary > .price {
	margin-bottom: 0.9em !important;
}

/* --- USP bullets --- */
/*
 * The site's Elementor Custom Code snippet carries
 *   .single-product .summary > p, .single-product .summary > ul { display: none !important }
 * to suppress stray plugin markup in the product summary. That selector is
 * (0,2,1) and beats a bare .ci-product-usps class even with !important, so the
 * list rendered into the DOM in the right place and never painted.
 * Matching its structure and adding the class outranks it.
 */
.single-product .summary > ul.ci-product-usps,
.single-product .summary ul.ci-product-usps,
.ci-product-usps {
	display: block !important;
	list-style: none !important;
	margin: 0 0 1.1em !important;
	padding: 0 !important;
}

.ci-product-usps li {
	display: flex;
	align-items: baseline;
	gap: 0.6em;
	margin: 0 0 0.45em !important;
	padding: 0 !important;
	color: var(--c-black);
	font-family: var(--font-body);
}

.ci-product-usps li:last-child {
	margin-bottom: 0 !important;
}

/*
 * The bullet glyph is a text character (✦) rather than an icon font, so it is
 * immune to the font-family override that governs the rest of the site. Sized
 * in em so it tracks whatever the list inherits.
 */
.ci-usp-icon {
	color: var(--c-teal);
	font-size: 0.95em;
	line-height: 1;
	flex: 0 0 auto;
}

/* --- Social proof --- */
.ci-social-proof {
	display: flex;
	align-items: center;
	gap: 0.6em;
	margin: 1.1em 0 1.2em;
	flex-wrap: wrap;
}

.ci-stars {
	display: inline-flex;
	gap: 0.1em;
	color: var(--c-gold);   /* fill comes from currentColor on the SVG path */
	line-height: 1;
}

.ci-stars svg {
	display: block;
}

.ci-review-count {
	font-family: var(--font-body);
	font-weight: 500;
	color: var(--c-black);
}

/* --------------------------------------------------------------------------
   Product trust strip
   --------------------------------------------------------------------------
   Three columns separated by hairline rules, with a closing rule underneath,
   matching the approved layout. Grid rather than flex so the three columns stay
   equal width regardless of how long each label runs.

   The `.single-product .summary > div` hiding rule that caught the USP list
   does not apply here (it targets p and ul), but the selector is written
   defensively anyway.
   -------------------------------------------------------------------------- */
.single-product .summary > .ci-trust-strip,
.ci-trust-strip {
	display: grid !important;
	/*
	 * minmax(0, 1fr), not plain 1fr. A bare 1fr carries an implicit min-content
	 * floor, so the longest word in a column ("PRINTING") widens that column and
	 * the three stop being equal — which is what made column 3 visibly wider and
	 * squeezed column 2 into a five-line stack.
	 */
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0;
	margin: 1.4em 0 1.6em;
	padding: 1.2em 0;
	border-top: 1px solid var(--c-stone);
	border-bottom: 1px solid var(--c-stone);
}

.ci-trust-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 0.45em;
	padding: 0 0.75em;
	/* Hairline between columns, not after the last one. */
	border-right: 1px solid var(--c-stone);
}

.ci-trust-item:last-child {
	border-right: 0;
}

.ci-trust-icon {
	color: var(--c-teal);
	line-height: 0;
}

.ci-trust-title {
	font-family: var(--font-body);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	line-height: 1.25;
	color: var(--c-black);
	font-size: clamp(12px, 0.72rem + 0.15vw, 13.5px);
}

.ci-trust-text {
	font-family: var(--font-body);
	font-weight: 400;
	line-height: 1.4;
	color: var(--c-black);
	font-size: clamp(13px, 0.78rem + 0.2vw, 15px);
}

/* --------------------------------------------------------------------------
   Summary blocks as Elementor templates (26 Aug 2026)
   --------------------------------------------------------------------------
   .ci-usps-tpl wraps template 19872 (the three ✦ bullets, an Icon List
   widget); .ci-trust-tpl wraps template 19873 (the three-column strip).
   Rendered by customirish_product_usp_list()/customirish_product_trust_strip()
   in place of the PHP markup above, which remains as the fallback — so the
   .ci-product-usps/.ci-trust-* rules must stay too.

   The heading/text rules carry !important for the same reason .ci-cred-title
   does: theme-type.css styles `body h3` with !important. Sizes and faces
   mirror .ci-trust-title/.ci-trust-text exactly, colours included — the
   titles were black spans before, so they stay black rather than following
   the kit's H3 colour.
   -------------------------------------------------------------------------- */
body.single-product .ci-usps-tpl {
	margin: 0 0 1.1em;
}

body.single-product .ci-usps-tpl .elementor-icon-list-text {
	font-family: var(--font-body);
	color: var(--c-black);
}

/*
 * No disc markers on the USP list — the client wants the three teal ✦ stars
 * and nothing else. The stars are the widget's own icons; the bullets are the
 * browser's default `ul { list-style: disc }` showing through.
 *
 * Elementor normally suppresses them from widget-icon-list's stylesheet, but
 * that file is enqueued per widget and is subject to the page cache and the
 * CSS optimiser, so it is not guaranteed to be on the page — which is why the
 * bullets appeared in Safari and not in Chrome on the same URL. Pinning the
 * rule here makes it independent of whether Elementor's widget CSS loaded.
 *
 * `list-style` clears the marker box; the ::marker rule is the belt-and-braces
 * for engines that still paint one on a flex list item; the padding/margin
 * reset closes the indent the markers had reserved.
 */
body.single-product .ci-usps-tpl ul.elementor-icon-list-items {
	list-style: none !important;
	padding-left: 0 !important;
	margin-left: 0 !important;
}

body.single-product .ci-usps-tpl ul.elementor-icon-list-items > li::marker {
	content: "" !important;
	font-size: 0 !important;
}

body.single-product .ci-trust-tpl {
	margin-top: 40px !important;
	margin-bottom: 40px !important;
}

body.single-product .ci-trust-tpl .elementor-widget-icon {
	line-height: 0;
}

/* body.single-product, not bare body: theme-type's
   `body .elementor-widget-heading h3.elementor-heading-title` is also (0,2,2)
   with !important and loads later, so an equal selector loses on order. */
body.single-product .ci-trust-tpl h3.elementor-heading-title {
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	text-transform: uppercase !important;
	letter-spacing: 0.05em !important;
	line-height: 1.25 !important;
	color: var(--c-black);
	font-size: clamp(12px, 0.72rem + 0.15vw, 13.5px) !important;
	margin: 0 !important;
	overflow-wrap: normal;
	word-break: keep-all;
	hyphens: none;
}

body.single-product .ci-trust-tpl .elementor-widget-text-editor p {
	font-family: var(--font-body) !important;
	font-size: clamp(13px, 0.78rem + 0.2vw, 15px) !important;
	line-height: 1.4 !important;
	color: var(--c-black);
	margin: 0 !important;
	overflow-wrap: break-word;
	hyphens: none;
}

/*
 * Trust strip on small screens.
 *
 * Two columns per row, and each cell stays a VERTICAL stack (icon over title
 * over text). An earlier attempt set flex-direction:row on the cell, which put
 * icon, title and copy side by side and left them overlapping each other.
 *
 * The right-hand divider is dropped on every second cell so the rule only ever
 * appears between the pair, never against the outer edge.
 */
@media (max-width: 900px) {
	.ci-trust-strip {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
		gap: 1.2em 0;
	}

	.ci-trust-item {
		flex-direction: column !important;
		align-items: center !important;
		text-align: center !important;
		padding: 0 0.9em;
	}

	.ci-trust-item:nth-child(2n) {
		border-right: 0 !important;
	}

	.ci-trust-item:nth-child(2n+1) {
		border-right: 1px solid var(--c-stone) !important;
	}

	/*
	 * A lone third item spans the full width rather than sitting half-empty,
	 * and takes a rule across the top so it reads as its own row — matching the
	 * rules that close the strip above and below.
	 */
	.ci-trust-item:last-child:nth-child(2n+1) {
		grid-column: 1 / -1;
		border-right: 0 !important;
		border-top: 1px solid var(--c-stone);
		padding-top: 1.1em;
		margin-top: 0.2em;
	}
}

/*
 * Wrapping rules differ by element on purpose.
 *
 * Titles must NEVER break mid-word — break-word split "PERSONALIZED" into
 * "PERSONALIZ / ED FOR YOU". They wrap at spaces only, and the letter-spacing
 * is trimmed slightly so the longest single word still fits the column.
 *
 * The descriptions can wrap normally; the shipping line carries its own space
 * after "UK/" so it breaks there without needing to break a word.
 */
.ci-trust-title {
	overflow-wrap: normal;
	word-break: keep-all;
	hyphens: none;
	letter-spacing: 0.03em;
	max-width: 100%;
}

.ci-trust-text {
	overflow-wrap: break-word;
	hyphens: none;
	max-width: 100%;
}

/* --------------------------------------------------------------------------
   Attribute selection labels
   --------------------------------------------------------------------------
   CommerceKit appends the chosen value after the attribute name, and shows
   "No selection" until the customer picks one. That reads as an error state on
   arrival, when nothing is wrong — the customer simply has not chosen yet.
   Hide it while empty; once a value is chosen CommerceKit drops the
   .no-selection class and the value shows normally.
   -------------------------------------------------------------------------- */
.cgkit-chosen-attribute.no-selection {
	display: none !important;
}

/* --------------------------------------------------------------------------
   Attribute swatches — squared off
   --------------------------------------------------------------------------
   CommerceKit renders button swatches as rounded pills. The approved layout
   uses rectangles, which also matches the 2px radius used by the site's button
   system, so the size selector and the Add to Cart button read as one family.

   Colour/image swatches keep their circular shape — those are meant to read as
   colour dots, not buttons.
   -------------------------------------------------------------------------- */
body .cgkit-attribute-swatch.cgkit-button button,
body .cgkit-attribute-swatch.cgkit-button a,
body .cgkit-attribute-swatch.ckit-button button,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-button button {
	border-radius: 2px !important;
}

/*
 * Size swatch labels keep their authored casing.
 *
 * The term values are written as `12" x 12"`, but the swatch styling applies
 * text-transform: uppercase, which promotes that lowercase x to a full-height
 * capital X — visually heavier than the digits around it and not what the
 * approved layout shows. Letter-spacing is also trimmed, since the tracking
 * that suits uppercase labels looks loose on mixed-case measurements.
 */
body .cgkit-attribute-swatch.cgkit-button button,
body .cgkit-attribute-swatch.cgkit-button a,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-button button {
	text-transform: none !important;
	letter-spacing: 0.01em !important;
}

/* --------------------------------------------------------------------------
   Product summary — vertical rhythm
   --------------------------------------------------------------------------
   Tightening every gap in the summary block so title, price, USPs, description
   and social proof read as one unit rather than five loosely stacked pieces.
   Consolidated here as the last word on spacing, so the earlier per-element
   margins above do not have to be hunted down individually.

   Values are in em so they track the 19.2px body size rather than being pinned
   to pixels that would drift if the type scale changes again.
   -------------------------------------------------------------------------- */

/* title -> price */
body.single-product .product_title.entry-title {
	margin-bottom: 0.18em !important;
}

/* price -> USP list */
body.single-product .cgkit-as-variation-price,
body.single-product .summary > .price {
	margin-bottom: 0.45em !important;
}

/* between USP rows */
body .ci-product-usps li {
	margin-bottom: 0.18em !important;
}

/* USP list -> description */
body .ci-product-usps {
	margin-bottom: 0.6em !important;
}

/* description -> stars */
body.single-product .woocommerce-product-details__short-description,
body.single-product .woocommerce-product-details__short-description p:last-child {
	margin-bottom: 0.5em !important;
}

body .ci-social-proof {
	margin-top: 0.55em !important;
	margin-bottom: 0.9em !important;
}

/* --------------------------------------------------------------------------
   Size swatch box height + attribute label size
   -------------------------------------------------------------------------- */

/*
 * The swatch pills were tall because CommerceKit sizes them for a rounded
 * shape. Squared off they only need enough vertical padding to clear the text,
 * so the row reads as a compact set of options rather than a stack of blocks.
 * min-height is cleared too — it was holding the old pill height.
 */
body .cgkit-attribute-swatch.cgkit-button button,
body .cgkit-attribute-swatch.cgkit-button a,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-button button {
	padding-top: 0.42em !important;
	padding-bottom: 0.42em !important;
	min-height: 0 !important;
	height: auto !important;
	line-height: 1.3 !important;
}

/*
 * "1. Choose Your Size" / "2. Choose Frame Color" were set at small-print size,
 * which undersold them — they are the instructions for the main decision on the
 * page. Brought up to sit just under body size and given a little more weight.
 */
body .cgkit-as-wrap .cgkit-attribute-name,
body .cgkit-attribute-name,
body .variations label,
body .variations th.label label,
body .cgkit-as-wrap label,
body.single-product .summary .variations .label {
	/* Same size as the step-3 heading below (.pewc-group-description, 19.2px)
	   so all three numbered steps read as one sequence. */
	font-size: var(--fs-body) !important;
	font-weight: 600 !important;
	letter-spacing: 0.04em !important;
	line-height: 1.35 !important;
}

/* --------------------------------------------------------------------------
   Step 3 heading — Product Extras group
   --------------------------------------------------------------------------
   Product Extras renders its group description with no step number, so the
   personalisation block read as loose copy rather than the third step after
   "1. Choose Your Size" and "2. Choose Frame Color".

   The number is added with ::before rather than by editing the group text in
   the plugin, so it cannot be lost if that field is edited later. Scoped to the
   first group only — if a second Product Extras group is ever added it will not
   silently be numbered "3." as well.
   -------------------------------------------------------------------------- */
body .pewc-product-extra-groups-wrap .pewc-group-wrap:first-of-type .pewc-group-description {
	/* Uppercase with a trailing colon so step 3 matches the format of
	   "1. CHOOSE YOUR SIZE:" and "2. CHOOSE FRAME COLOR:" exactly. Done with
	   text-transform rather than by rewriting the copy, so the wording stays
	   editable in Product Extras. */
	text-transform: uppercase !important;
	font-weight: 600 !important;
	letter-spacing: 0.04em !important;
	margin-bottom: 0.5em !important;
}

body .pewc-product-extra-groups-wrap .pewc-group-wrap:first-of-type .pewc-group-description::after {
	content: ":";
}

body .pewc-product-extra-groups-wrap .pewc-group-wrap:first-of-type .pewc-group-description::before {
	content: "3. ";
}

/* ==========================================================================
   ADD TO CART — solid teal, full width
   --------------------------------------------------------------------------
   The gold outline treatment used elsewhere is the SECONDARY button style. The
   primary purchase action gets a solid teal fill with white text so it is
   unmistakably the main action on the page.

   Important: WooCommerce marks the button .disabled until every variation is
   chosen. The old styling made disabled and enabled look nearly identical, so
   customers could not tell the button was not yet clickable. Now the enabled
   state is solid teal and the disabled state is visibly muted.
   ========================================================================== */

body.single-product .single_add_to_cart_button,
body.single-product form.cart .single_add_to_cart_button {
	display: block !important;
	width: 100% !important;
	background-color: var(--c-teal) !important;
	color: var(--c-white) !important;
	border: 2px solid var(--c-teal) !important;
	border-radius: 3px !important;
	padding: 0.665em 1.2em !important;   /* was 0.95em — reduced 30% */
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	font-size: clamp(15px, 0.9rem + 0.25vw, 17px) !important;
	letter-spacing: 0.06em !important;
	text-transform: uppercase !important;
	line-height: 1.3 !important;
	transition: background-color 0.18s ease, border-color 0.18s ease !important;
}

body.single-product .single_add_to_cart_button:hover:not(.disabled),
body.single-product form.cart .single_add_to_cart_button:hover:not(.disabled) {
	background-color: #16494C !important;   /* one step lighter than --c-teal */
	border-color: #16494C !important;
	color: var(--c-white) !important;
}

body.single-product .single_add_to_cart_button:active:not(.disabled) {
	transform: translateY(1px);
}

/* Disabled: clearly not yet actionable, but still legible. */
body.single-product .single_add_to_cart_button.disabled,
body.single-product .single_add_to_cart_button:disabled {
	background-color: #A9B6B2 !important;
	border-color: #A9B6B2 !important;
	color: var(--c-white) !important;
	cursor: not-allowed !important;
	opacity: 1 !important;
}

/* --- Secure checkout note under the button --- */
/*
 * form.cart is a flex row, so the note sat in the leftover space beside the
 * button and wrapped into a narrow three-line column. flex-basis:100% forces it
 * onto its own row; width:100% covers the non-flex case.
 */
.ci-secure-note {
	display: flex !important;
	flex: 0 0 100% !important;
	width: 100% !important;
	order: 99;
	align-items: center;
	justify-content: center;
	gap: 0.45em;
	margin: 0.55em 0 0 !important;
	font-family: var(--font-body);
	font-size: clamp(13px, 0.8rem + 0.15vw, 14.5px) !important;
	color: var(--c-black);
	opacity: 0.85;
}

.ci-secure-note svg {
	flex: 0 0 auto;
	color: var(--c-teal);
}

/* --------------------------------------------------------------------------
   Remove the block below the button
   --------------------------------------------------------------------------
   The four shipping/returns bullets and the "Guaranteed Safe Checkout" payment
   strip all live in one text widget (#text-7) inside .product-widget. Hidden
   rather than deleted, so the widget content is still recoverable from
   Appearance > Widgets if it is wanted back.
   -------------------------------------------------------------------------- */
body.single-product .product-widget {
	display: none !important;
}

/* ==========================================================================
   SUMMARY SPACING — second pass, tighter
   ========================================================================== */
body.single-product .product_title.entry-title {
	margin-bottom: 0.08em !important;
}

body.single-product .cgkit-as-variation-price,
body.single-product .summary > .price {
	margin-bottom: 0.28em !important;
}

body .ci-product-usps {
	margin-bottom: 0.42em !important;
}

body .ci-product-usps li {
	margin-bottom: 0.12em !important;
}

/* Description sits tighter and reads a touch closer line to line. */
body.single-product .woocommerce-product-details__short-description,
body.single-product .woocommerce-product-details__short-description p {
	line-height: 1.45 !important;
	margin-bottom: 0.3em !important;
}

/* 21 Aug "consistent spacing" (revised the same day: 24px box-edge read
   too tight and uneven, so the gaps are now equalised on VISIBLE distance —
   ink to ink — at 30px). The excerpt's own bottom padding/margins used to
   supply 17.6px of this gap; they are zeroed so this margin owns it. 28px box
   measures 30px ink because of the reviews line's half-leading. */
body.single-product .summary .woocommerce-product-details__short-description {
	padding-bottom: 0 !important;
	margin-bottom: 0 !important;
}
body.single-product .summary .woocommerce-product-details__short-description p:last-child {
	margin-bottom: 0 !important;
}
body .ci-social-proof {
	margin-top: 28px !important;
	margin-bottom: 0.55em !important;
}

/* 21 Aug "consistent spacing": every gap in the summary column equals the
   description -> reviews-line gap, measured at 24px. The strip's margins ARE
   the gap above step 1 (the table's own top margin is zeroed further down and
   the first heading carries no padding), so change all three together. */
body .ci-trust-strip {
	margin-top: 40px !important;    /* ink = box here: the rule is the edge */
	margin-bottom: 40px !important;
	padding: 0.9em 0 !important;
}

/* ==========================================================================
   "How Personalization Works" — product page
   --------------------------------------------------------------------------
   Four across on desktop, one per row on mobile (client-specified).
   Mirrors the homepage section so the two read as the same component.
   ========================================================================== */
/*
 * Width matched to the product tabs below.
 *
 * .woocommerce-Tabs-panel resolves to 1170px of content centred in the 1657px
 * container (max-width 1253.72px minus 41.89px padding each side). These
 * sections were running the full container width, so the first and last steps
 * were cut off at the viewport edges while the tabs underneath sat inset.
 */
/* Elementor template 19789 in place of the PHP steps (21 Aug). Full-bleed like
   .ci-creds so the template's two bands run edge to edge as they do on the
   Personalize page; the Elementor containers inside are boxed, so the content
   stays centred at the kit width. The .ci-steps rules below now only serve
   the PHP fallback. */
.ci-steps-tpl {
	clear: both;
	width: 100vw;
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	margin-top: 1.6em;
}

/* The template's "Personalize Your Gift" button (Elementor CSS ID set by
   Gerald) links to Shop All — pointless on a product page, where the customer
   is already personalising. Hidden on product pages only; the Personalize page
   keeps it. */
.single-product #personalize-your-gift {
	display: none !important;
}

.ci-steps {
	clear: both;
	width: 100%;
	max-width: 1170px;
	/* Tight to the summary above. The gallery column is taller than the summary
	   column, so the 2.5em top margin plus 2em padding stacked on top of the
	   gap the float already leaves, opening a large empty band under the
	   button. */
	margin: 0.6em auto 1em;
	padding: 1.2em 0 0;
	border-top: 1px solid var(--c-stone);
	text-align: center;
}

.ci-steps-heading {
	font-family: var(--font-heading);
	color: var(--c-h2, var(--c-teal));
	margin: 0 0 0.25em !important;
}

.ci-steps-sub {
	font-family: var(--font-body);
	color: var(--c-black);
	margin: 0 auto 1.8em !important;
	max-width: 46em;
}

.ci-steps-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 1.6em;
	align-items: start;
}

.ci-step {
	text-align: center;
}

.ci-step-img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	margin: 0 0 0.9em;
	border-radius: 2px;
}

.ci-step-title {
	font-family: var(--font-heading);
	color: var(--c-h3, var(--c-teal));
	margin: 0 0 0.35em !important;
}

.ci-step-text {
	font-family: var(--font-body);
	color: var(--c-black);
	margin: 0 !important;
}

/* Two-up on tablet, one per row on phones — as specified. */
@media (max-width: 1024px) {
	.ci-steps-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 1.6em 1.2em;
	}
}

@media (max-width: 767px) {
	.ci-steps-grid {
		grid-template-columns: 1fr;
		/* Doubled again: with the caption now tight to its title, the break
		   between one step and the next image is what separates them. */
		gap: 5.6em;
	}

	/*
	 * 20px inset on the whole step, so the image stops bleeding edge to edge
	 * and the copy underneath stops touching the screen edges. Putting it on
	 * the step rather than separately on image and text keeps both aligned to
	 * the same margin.
	 */
	.ci-step {
		padding: 0 20px;
	}

	.ci-step-img {
		/* Full-width square images get very tall on a phone; cap the height so
		   the four steps stay scannable without endless scrolling. */
		max-height: 320px;
		object-position: center;
		margin-bottom: 1.1em;
	}

	.ci-step-title {
		/* Half the previous gap — the title and its description are one unit. */
		margin-bottom: 0.22em !important;
	}

	.ci-step-text {
		/* Tighter than body copy: these are short captions, and 1.6 left them
		   looking like loose paragraphs rather than a caption block. */
		line-height: 1.35 !important;
	}

	.ci-steps {
		margin-top: 1.8em;
		padding-top: 1.5em;
	}

	.ci-steps-heading,
	.ci-steps-sub {
		padding: 0 20px;
	}
}

/* ==========================================================================
   "Perfect For Life's Special Moments"
   --------------------------------------------------------------------------
   Four occasion prompts under the personalization steps. Same grid behaviour as
   the steps section so the two stack consistently: 4 across, 2 on tablet, 1 on
   phone.
   ========================================================================== */
/* Elementor template 19863 in place of the PHP occasions row (21 Aug). The
   template's container is boxed at 1170px with its own top hairline, so the
   wrapper only clears the floats. The .ci-moments rules below now serve the
   PHP fallback only. */
.ci-moments-tpl {
	clear: both;
	/* Elementor draws a boxed container's border on the full-width outer box;
	   constraining the wrapper keeps the hairline at the 1170px the tabs and
	   the old row used. */
	max-width: 1170px;
	margin: 0 auto;
}

.ci-moments {
	clear: both;
	width: 100%;
	max-width: 1170px;   /* matches .ci-steps and the tabs panel */
	margin: 1.2em auto 2em;
	padding: 1.4em 0 0;
	border-top: 1px solid var(--c-stone);
	text-align: center;
}

.ci-moments-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 1.8em 1.4em;
	align-items: start;
}

.ci-moment {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 0.55em;
}

/*
 * The ring is a CSS border, not part of the SVG, so its weight and colour come
 * from the brand tokens. aspect-ratio keeps it a true circle regardless of the
 * icon inside.
 */
.ci-moment-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	aspect-ratio: 1 / 1;
	border: 2px solid var(--c-gold);
	border-radius: 50%;
	color: var(--c-gold);
	margin-bottom: 0.2em;
}

.ci-moment-title {
	font-family: var(--font-heading);
	color: var(--c-h3, var(--c-teal));
	margin: 0 !important;
}

/* The single shared sentence under the icon row. 46em matches .ci-steps-sub
   so the two sections' body copy wraps at the same measure. */
.ci-moments-note {
	font-family: var(--font-body);
	color: var(--c-black);
	margin: 1.4em auto 0 !important;
	max-width: 46em;
}

@media (max-width: 1024px) {
	.ci-moments-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.ci-moments-grid {
		grid-template-columns: 1fr;
		gap: 2em;
	}
	/* Matching 20px inset so this section lines up with the steps above it. */
	.ci-moment,
	.ci-moments-note {
		padding: 0 20px;
	}
	.ci-moments {
		margin-top: 1.2em;
		padding-top: 1.5em;
	}
}

/* ==========================================================================
   "Loved By Our Customers" — reviews carousel
   --------------------------------------------------------------------------
   Built on CSS scroll-snap rather than a slider library: native momentum
   swiping on touch devices for free, no dependency to load or maintain, and it
   degrades to a plain scrollable row if scripting is unavailable. The desktop
   arrow only appears when the track actually overflows.
   ========================================================================== */
.ci-reviews {
	clear: both;
	width: 100%;
	max-width: 1170px;
	margin: 1.5em auto 2.5em;
	padding: 2em 0 0;
	border-top: 1px solid var(--c-stone);
	text-align: center;
}

.ci-reviews-heading {
	font-family: var(--font-heading);
	color: var(--c-h2, var(--c-teal));
	margin: 0 0 0.2em !important;
}

.ci-reviews-sub {
	font-family: var(--font-body);
	color: var(--c-black);
	opacity: 0.8;
	margin: 0 0 1.5em !important;
}

.ci-reviews-viewport {
	position: relative;
}

.ci-reviews-track {
	display: flex;
	gap: 20px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	padding: 4px 4px 12px;
	/* Hide the scrollbar without disabling scrolling — the swipe is the UI. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.ci-reviews-track::-webkit-scrollbar {
	display: none;
}

.ci-review {
	flex: 0 0 calc((100% - 60px) / 4);
	scroll-snap-align: start;
	background-color: var(--c-white);
	border: 1px solid var(--c-stone);
	border-radius: 3px;
	padding: 1.2em 1.3em;
	text-align: left;
	display: flex;
	flex-direction: column;
	gap: 0.6em;
}

.ci-review-stars {
	display: inline-flex;
	gap: 0.08em;
	color: var(--c-gold);
	line-height: 1;
}

.ci-review-quote {
	font-family: var(--font-body);
	color: var(--c-black);
	line-height: 1.45;
	margin: 0 !important;
	flex: 1 1 auto;
}

.ci-review-author {
	font-family: var(--font-body);
	font-weight: 600;
	color: var(--c-black);
	margin: 0 !important;
}

.ci-reviews-nav {
	position: absolute;
	top: 50%;
	right: -8px;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid var(--c-stone) !important;
	background-color: var(--c-white) !important;
	color: var(--c-teal) !important;
	font-size: 26px !important;
	line-height: 1 !important;
	padding: 0 !important;
	cursor: pointer;
	box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08);
}

.ci-reviews-nav:hover {
	background-color: var(--c-offwhite) !important;
	color: var(--c-teal) !important;
}

.ci-reviews-more {
	margin: 1em 0 0 !important;
}

.ci-reviews-more a {
	font-family: var(--font-body);
	color: var(--c-teal);
	text-decoration: underline;
	text-underline-offset: 3px;
}

@media (max-width: 1024px) {
	.ci-review {
		flex-basis: calc((100% - 20px) / 2);
	}
}

@media (max-width: 767px) {
	.ci-review {
		/* Slightly under full width so the next card peeks in — the strongest
		   signal that the row is swipeable. */
		flex-basis: 84%;
	}
	.ci-reviews {
		margin-top: 1.2em;
		padding-top: 1.5em;
	}
	.ci-reviews-heading,
	.ci-reviews-sub {
		padding: 0 20px;
	}
	.ci-reviews-track {
		padding-left: 20px;
		padding-right: 20px;
	}
	/* The arrow is redundant once the row is swipeable by touch. */
	.ci-reviews-nav {
		display: none !important;
	}
}

/* --------------------------------------------------------------------------
   Step separation in the options block
   --------------------------------------------------------------------------
   Steps 1, 2 and 3 ran together as one dense list. Extra space above each
   heading after the first gives the eye a break between "choose a size",
   "choose a frame colour" and the personalisation fields, so the three read as
   distinct decisions rather than one long form.
   -------------------------------------------------------------------------- */
/*
 * The variations form is a TABLE: each attribute is a <tr> with the label in
 * th.label and the swatches in td.value (.cgkit-as-wrap lives inside that cell).
 * Margins do not collapse the way they would on block elements inside table
 * cells, which is why an earlier margin-top on .cgkit-as-wrap moved the
 * personalisation block (not a table) but left "2. Choose Frame Color" alone.
 *
 * Padding on the cells of every row after the first is what actually separates
 * them.
 */
/*
 * Only the label cell takes the gap. The th and td render stacked here (label
 * above swatches), so padding on BOTH produced the space twice — once above the
 * heading, then again between the heading and its own swatches.
 */
/* 24px above each numbered heading — the client's 21 Aug "consistent spacing"
   note supersedes the 48px from the 15 Aug notes: every gap must equal the
   description -> reviews-line gap, which measures 24px on the live page. */
body.single-product table.variations th.label,
body.single-product .variations th.label {
	padding-top: 35px !important;   /* 40px ink: the label's half-leading adds ~5 */
}

/* Step 1's 24px comes from the trust strip's margin-bottom, so the first row
   carries no padding of its own — otherwise the two stack to 48px. */
body.single-product table.variations tr:first-child > th.label,
body.single-product .variations tr:first-child > th.label {
	padding-top: 0 !important;
}

body.single-product table.variations tr > td.value,
body.single-product .variations tr > td.value {
	padding-top: 0 !important;
}

body.single-product .pewc-product-extra-groups-wrap {
	margin-top: 38px !important;   /* 40px ink (+2 half-leading); was 48px */
}

/* The personalisation heading needs the same breathing room as the two above. */
body .pewc-product-extra-groups-wrap .pewc-group-wrap:first-of-type .pewc-group-description {
	margin-top: 0.2em !important;
}

/* First step keeps its existing position — no leading gap at the top. */
body.single-product .cgkit-as-wrap:first-of-type {
	margin-top: 0 !important;
}

/* --------------------------------------------------------------------------
   Step headings read as headings
   --------------------------------------------------------------------------
   A hairline under each numbered step gives the three the weight of section
   headings rather than inline form labels, and reinforces the separation the
   row padding provides.

   display:block is needed because these are <label> elements inside table
   cells — inline by default, so a border would only run the width of the text.
   -------------------------------------------------------------------------- */
body.single-product table.variations th.label label,
body.single-product .variations th.label label,
body.single-product .cgkit-attribute-name,
body .pewc-product-extra-groups-wrap .pewc-group-wrap:first-of-type .pewc-group-description {
	display: block !important;
	width: 100%;
	/* 15px heading -> divider, 24px divider -> first control. Client's 15 Aug
	   notes ask for 14-16px and 24px; was 0.4em (7.7px) and 0.7em (13.4px).
	   THIS rule covers all three steps — the two variation labels and step 3's
	   .pewc-group-description — so the numbers live here, once. */
	padding-bottom: 15px !important;
	border-bottom: 1px solid var(--c-stone) !important;
	margin-bottom: 24px !important;
}

/*
 * Space above step 1 — now zero here on purpose (21 Aug).
 *
 * This used to add 1.6em on top of the trust strip's margin and the heading's
 * padding, stacking three gaps into ~90px. The strip's 24px margin-bottom is
 * the single source of that gap now; anything added here doubles it.
 */
body.single-product form.cart .variations,
body.single-product form.cart table.variations {
	margin-top: 0 !important;
}

/*
 * Close the gap the cart form leaves under the button. Shoptimizer pads the
 * bottom of form.cart for the widget block that used to sit there — that block
 * is hidden now, so the padding is just empty space.
 */
body.single-product form.cart,
body.single-product .summary form.cart {
	margin-bottom: 0.4em !important;
	padding-bottom: 0 !important;
}

body.single-product .summary.entry-summary {
	padding-bottom: 0 !important;
	margin-bottom: 0 !important;
}

/* ==========================================================================
   Credentials strip — five reassurance points below the reviews
   --------------------------------------------------------------------------
   Dressed to match the reference band: a warm cream field running full width,
   gold icons sitting to the LEFT of the text rather than above it, bold teal
   titles and a lighter gold sub-line.

   The band bleeds past the 1170px content column so the colour runs edge to
   edge, while the content inside stays aligned with everything else on the
   page.
   ========================================================================== */
/* Elementor template 19805 in place of the PHP strip (21 Aug) — same
   full-bleed treatment as .ci-creds so the band runs edge to edge; the
   Elementor container inside is boxed at 1170px. The .ci-creds rules below
   now only serve the PHP fallback. */
.ci-creds-tpl {
	clear: both;
	width: 100vw;
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	margin-top: 1.6em;
}

/* The sub-lines' size is set in the template's text widgets, but the theme's
   body sizing carries !important and wins over Elementor's generated CSS on
   WooCommerce pages, so the size is restated here — the same clamp the PHP
   strip used. Editing the size in Elementor will NOT take effect; edit here. */
.ci-creds-tpl .elementor-widget-text-editor p {
	font-size: clamp(12.5px, 0.75rem + 0.2vw, 14px) !important;
	line-height: 1.35 !important;
}

/* No icon CSS here on purpose (Gerald, 21 Aug): the icons in the template are
   Elementor Icon widgets chosen from the media library, and their colour and
   size are set in the widget so whoever edits the template has full control.
   The uploaded ci-icon-*.svg files carry fill/stroke on every shape so the
   widget's colour control works on them without theme help. */

.ci-creds {
	clear: both;
	width: 100vw;
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	margin-top: 1.6em;
	margin-bottom: 0;
	padding: 1.8em 0;
	background-color: #F1F0EF;   /* client-specified, 19 Aug */
	border-top: 1px solid var(--c-stone);
	border-bottom: 1px solid var(--c-stone);
}

.ci-creds-grid {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: 1.2em;
	align-items: center;
	max-width: 1170px;
	margin: 0 auto;
	padding: 0 20px;
}

/*
 * Icon above the copy, centred.
 *
 * Side by side, the five cells each had to fit an icon plus two lines of text
 * across a fifth of the width, so "Quality You Can Trust" wrapped while its
 * neighbours did not and the row sat unevenly. Stacking gives each cell the
 * full cell width for its text.
 */
.ci-cred {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 0.45em;
	padding: 0 0.4em;
}

.ci-cred-icon {
	color: var(--c-gold);
	line-height: 0;
	flex: 0 0 auto;
}

.ci-cred-icon svg {
	width: 30px;
	height: 30px;
}

.ci-cred-copy {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.15em;
	min-width: 0;
}

/*
 * Real <h3> as of 19 Aug (client request). Size, face, ALL CAPS and tracking
 * all come from the global H3 spec in theme-type.css — only the colour, the
 * zeroed margin and the wrap behaviour are local. Anything added here that
 * the spec also sets needs to outrank body .woocommerce h3 at (0,1,1) plus
 * theme-type's later load order — see §9 of the runbook before trying.
 */
.ci-cred-title {
	margin: 0 !important;
	color: var(--c-h3, var(--c-teal));
	overflow-wrap: normal;
	word-break: keep-all;
}

.ci-cred-text {
	font-family: var(--font-body);
	line-height: 1.35;
	color: var(--c-gold-ink);
	font-size: clamp(12.5px, 0.75rem + 0.2vw, 14px);
}

@media (max-width: 1100px) {
	.ci-creds-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 1.4em 1em;
	}
}

@media (max-width: 767px) {
	.ci-creds-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 1.2em 0.8em;
	}
	.ci-cred:last-child:nth-child(2n+1) {
		grid-column: 1 / -1;
	}
}

@media (max-width: 480px) {
	.ci-creds-grid {
		grid-template-columns: 1fr;
		gap: 1em;
	}
}

/* ==========================================================================
   Wishlist link shares the breadcrumb row, right-aligned
   --------------------------------------------------------------------------
   The wishlist is moved inside the breadcrumb element by a small script (see
   functions.php) because the two live in different parents and cannot be put on
   one line by float or margin alone.

   The breadcrumb is display:flex, so margin-left:auto pushes the wishlist to
   the right edge and keeps it there at any width — no fixed offsets to drift.
   ========================================================================== */
body.single-product .woocommerce-breadcrumb .ci-wishlist-row {
	margin-left: auto !important;
	margin-right: 0 !important;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	padding: 0 !important;
	float: none !important;
	flex: 0 0 auto;
	white-space: nowrap;
}

body.single-product .woocommerce-breadcrumb .ci-wishlist-row .commercekit-wishlist,
body.single-product .woocommerce-breadcrumb .ci-wishlist-row .commercekit-wishlist-btn-wrap {
	margin: 0 !important;
	padding: 0 !important;
}

/* Breadcrumb text takes the remaining width and wraps rather than clipping. */
body.single-product .woocommerce-breadcrumb {
	flex-wrap: wrap;
	align-items: center;
	gap: 0 0.35em;
}



/* ==========================================================================
   Category pages — pull the title up level with the breadcrumb
   --------------------------------------------------------------------------
   The archive header carried a large top margin, so "Framed Prints" sat well
   below the breadcrumb while the sidebar ("CATEGORIES") started right under it.
   The two columns began at visibly different heights.

   Zeroing the header's top spacing lines the title up with the top of the
   breadcrumb/sidebar area, and the two columns start together.
   ========================================================================== */
body.archive .woocommerce-products-header,
body.tax-product_cat .woocommerce-products-header,
body.post-type-archive-product .woocommerce-products-header,
body.archive header.woocommerce-products-header,
body.tax-product_cat .page-title,
body.archive .page-title,
body.tax-product_cat h1.woocommerce-products-header__title,
body.archive h1.woocommerce-products-header__title {
	margin-top: 0 !important;
	padding-top: 0 !important;
}

/* The content column itself also carried leading space. */
body.archive .site-main,
body.tax-product_cat .site-main,
body.post-type-archive-product .site-main {
	padding-top: 0 !important;
	margin-top: 0 !important;
}

/* Keep a small gap under the title before the category description box. */
body.archive .woocommerce-products-header__title,
body.tax-product_cat .woocommerce-products-header__title {
	margin-bottom: 0.4em !important;
	/* 1.1 until 15 Aug, when a sweep caught it as the only H1 on the site not on
	   the spec sheet's 1.15. The margin-bottom above is what controls the gap to
	   the category description, so the line-height was doing nothing here that
	   the margin was not already doing. */
	line-height: var(--lh-h1) !important;
}

/* ==========================================================================
   Breadcrumb + wishlist on mobile
   --------------------------------------------------------------------------
   The breadcrumb was set to nowrap, so a long product name ran off the right
   edge and was simply cut. It wraps now. The wishlist sits centred on its own
   line directly beneath, with the surrounding space trimmed — it was taking a
   tall band for one short link.
   ========================================================================== */
@media (max-width: 991px) {
	body.single-product .woocommerce-breadcrumb,
	body.single-product nav.woocommerce-breadcrumb {
		white-space: normal !important;
		overflow: visible !important;
		text-overflow: clip !important;
		word-break: break-word;
		padding-right: 20px !important;
		padding-bottom: 0 !important;
		margin-bottom: 0.4em !important;
		line-height: 1.5 !important;
	}

	/*
	 * Separator padding off on mobile.
	 *
	 * The " / " between crumbs is spaced entirely by its own padding — 0.8em
	 * each side in the parent theme — so every separator costs ~1.6em of a
	 * line that is already wrapping on a phone. Zeroed per the client.
	 *
	 * Not scoped to .single-product like the rules above it: the shop and
	 * category breadcrumbs use the same separator and wrap for the same
	 * reason.
	 */
	.woocommerce-breadcrumb .breadcrumb-separator {
		padding: 0 !important;
	}

	body.single-product .ci-wishlist-row {
		float: none !important;
		display: flex !important;
		justify-content: center !important;
		margin: 0.2em 0 0.5em !important;
		padding: 0 !important;
	}

	body.single-product .ci-wishlist-row .commercekit-wishlist,
	body.single-product .ci-wishlist-row .commercekit-wishlist-btn-wrap,
	body.single-product .ci-wishlist-row .commercekit-wishlist-icon {
		margin: 0 !important;
		padding: 0 !important;
	}
}

/* --------------------------------------------------------------------------
   Product Extras radio options sit on one row
   --------------------------------------------------------------------------
   Product Extras renders each option as an <li> inside
   ul.pewc-checkbox-group-wrapper, which is display:block — so a simple Yes/No
   choice took two full rows and pushed the rest of the form down.

   flex-wrap puts longer option sets (the blessing choices, for example) onto
   further rows. Note what it does NOT do: wrapping items onto new rows is a
   separate thing from wrapping the text inside one item, which is governed by
   flex-shrink on the <li> below — see the comment there before changing it.
   -------------------------------------------------------------------------- */
body .pewc-checkbox-group-wrapper {
	display: flex !important;
	flex-wrap: wrap;
	gap: 0.4em 2em;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
}

/*
 * flex-shrink is 1, not 0.
 *
 * `flex: 0 0 auto` sized each <li> to its content on a single line and refused
 * to let it shrink, so a long option — the blessing texts, which run to a full
 * sentence or three — laid out at its max-content width and was clipped by
 * .product-details-wrapper (overflow:hidden). Measured on the Antrim PDP: one
 * <li> was 1523px wide inside a 421px <ul>, overflowing by 1102px, and 31px
 * tall, i.e. one line where four were needed.
 *
 * The wrapper's flex-wrap only ever wrapped *items onto new rows*; it could not
 * wrap text inside an item that was forbidden to shrink. Allowing the shrink is
 * what makes the label's own text wrap, and short options like Yes/No still
 * share a row because flex-basis stays auto.
 *
 * min-width:0 overrides the default min-width:auto on flex items, which would
 * otherwise hold the <li> at its min-content width.
 */
body .pewc-checkbox-group-wrapper > li {
	margin: 0 !important;
	padding: 0 !important;
	flex: 0 1 auto;
	min-width: 0;
	max-width: 100%;
	list-style: none !important;
}

body .pewc-checkbox-group-wrapper .pewc-radio-form-label {
	display: flex !important;
	align-items: center;
	gap: 0.5em;
	margin: 0 !important;
}

/*
 * Space between Product Extras fields.
 *
 * Now that Yes/No sits on one row, "Shipping Note" followed immediately with no
 * break, reading as part of the same question. Each field after the first gets
 * a gap so the personalisation block reads as separate questions.
 */
body .pewc-product-extra-groups > .pewc-item + .pewc-item,
body .pewc-group-content-wrapper > .pewc-item + .pewc-item,
body li.pewc-item + li.pewc-item {
	margin-top: 1.2em !important;
}

/*
 * Section item headings carry more weight.
 *
 * The global heading weight is 400 (matching Coach House), which suits large
 * display type but leaves these smaller item headings looking thin against the
 * imagery and icons above them.
 */
/*
 * 700 is the heaviest weight in the self-hosted Cormorant Garamond set (the
 * family does not ship anything above it), so this is as bold as these can go
 * without switching face. Garamond reads lighter than a sans at the same
 * numeric weight, which is why 600 still looked thin here.
 */
body .ci-step-title,
body .ci-moment-title,
body .ci-steps-heading,
body .ci-moments-heading,
body .ci-reviews-heading {
	font-weight: 700 !important;
}

/*
 * Step and occasion titles — overrides REMOVED 15 Aug, they now follow the H3
 * spec (20px desktop / 16px mobile) from theme-type.css.
 *
 * They used to be pinned to 18-21px with this note: "At the h3 size (--fs-h3,
 * up to 28px) '2. Personalize (Optional)' and '4. Preview Before Printing'
 * wrapped onto two lines while steps 1 and 3 sat on one, so the four captions
 * started at different heights and the row looked ragged."
 *
 * That reasoning inverted when the client's spec sheet took H3 down to 20px:
 * the override was making these titles BIGGER than the spec (21px vs 20px),
 * and the wrapping it was written to prevent is less likely at 20px than at
 * the 21px it imposed. Deleting it satisfies the sheet and the original intent
 * at the same time. If the ragged-row problem returns, fix it with the row's
 * min-height, not by re-pinning the font size.
 */

/* --------------------------------------------------------------------------
   Quantity + Add to Cart layout
   --------------------------------------------------------------------------
   On products that expose a quantity field, the box and the button sat on one
   line: the button lost its full width, shifted right, and no longer lined up
   with the totals above or the payment button below.

   The cart form becomes a wrapping flex column so quantity takes its own row,
   left-aligned under a visible label, and the button spans the full width
   beneath it — matching the Secure Checkout note and the express-payment
   button so the whole block shares one left and right edge.
   -------------------------------------------------------------------------- */
/* form.cart stays in normal flow for the same reason as the wrapper above. */
body.single-product form.cart {
	display: block !important;
}

/* Products with no quantity field must not gain a stray label row. */
body.single-product form.cart:not(:has(.quantity)) .ci-qty-label {
	display: none;
}

/* --------------------------------------------------------------------------
   Quantity layout on VARIABLE products
   --------------------------------------------------------------------------
   Do NOT make .woocommerce-variation-add-to-cart a flex container. It holds the
   personalisation fields and the running totals as well as the quantity box and
   button, so flex laid all of them out in a row and threw the quantity box up
   beside the Shipping Note field.

   Normal block flow already stacks these correctly. Only the individual pieces
   need adjusting: the label becomes a block so it sits on its own line, and the
   button spans the width beneath the quantity.
   -------------------------------------------------------------------------- */
body.single-product .woocommerce-variation-add-to-cart {
	display: block !important;
}

/* Label sits to the LEFT of the number box, both on one line. */
body.single-product .ci-qty-label {
	display: inline-block !important;
	width: auto;
	margin: 0 0.7em 0 0 !important;
	vertical-align: middle;
	line-height: 1;
	font-family: var(--font-body);
	font-weight: 600;
	color: var(--c-teal);
	font-size: clamp(14px, 0.85rem + 0.2vw, 16px);
}

body.single-product .woocommerce-variation-add-to-cart .quantity,
body.single-product form.cart .quantity {
	display: inline-block !important;
	float: none !important;
	margin: 0 0 1em 0 !important;
	vertical-align: middle;
}

/*
 * Shorten the number box.
 *
 * Shoptimizer sizes it to match the old tall pill button; against the new
 * button it looked oversized for a single digit. Height comes from the input's
 * own padding, and the stepper arrows are sized to match so they stay centred.
 */
body.single-product .quantity input.qty,
body.single-product .quantity input[type="number"] {
	height: auto !important;
	min-height: 0 !important;
	padding: 0.42em 0.5em !important;
	line-height: 1.3 !important;
	font-size: clamp(15px, 0.9rem + 0.2vw, 16px) !important;
}

body.single-product .quantity .qty-plus,
body.single-product .quantity .qty-minus,
body.single-product .quantity .commercekit-qty-plus,
body.single-product .quantity .commercekit-qty-minus,
body.single-product .quantity .quantity-button {
	height: auto !important;
	min-height: 0 !important;
	padding: 0.1em 0.35em !important;
	line-height: 1 !important;
}

body.single-product .woocommerce-variation-add-to-cart .single_add_to_cart_button,
body.single-product form.cart .single_add_to_cart_button {
	display: block !important;
	width: 100% !important;
	margin: 0 !important;
	clear: both;
}

body.single-product .ci-secure-note {
	clear: both;
}

/* --------------------------------------------------------------------------
   SKU / category meta line
   --------------------------------------------------------------------------
   Removing woocommerce_template_single_meta from the summary hook took it off
   the hook list but the markup is still emitted elsewhere (Shoptimizer renders
   its own copy), so it is hidden here as well.
   -------------------------------------------------------------------------- */
body.single-product .product_meta {
	display: none !important;
}

/* --------------------------------------------------------------------------
   Product Extras running totals — TEMPORARILY HIDDEN
   --------------------------------------------------------------------------
   Hides the "Product total / Options total / Grand total" rows that Product
   Extras prints above the Add to Cart button. They showed $0.00 until a
   variation was chosen, which read as an error state on arrival.

   TEMPORARY at the client's request — delete this block to bring them back.
   Nothing else depends on it, and the totals still calculate; they are only
   not displayed.
   -------------------------------------------------------------------------- */
body.single-product .pewc-total-field,
body.single-product .pewc-total-field-wrapper {
	display: none !important;
}

/* --------------------------------------------------------------------------
   Quantity: no steppers, label centred against the box
   --------------------------------------------------------------------------
   The up/down arrows sat in a tall stacked column beside a single-digit field,
   with a visible gap between them. The field is typeable, so the steppers add
   nothing here — hidden, leaving a plain number box.

   Native browser spinners are hidden too, otherwise Chrome and Firefox draw
   their own on hover and the arrows reappear.
   -------------------------------------------------------------------------- */
body.single-product .quantity .qty-plus,
body.single-product .quantity .qty-minus,
body.single-product .quantity .commercekit-qty-plus,
body.single-product .quantity .commercekit-qty-minus,
body.single-product .quantity .quantity-button,
body.single-product .quantity .plus,
body.single-product .quantity .minus,
body.single-product .quantity-buttons,
body.single-product .quantity .shoptimizer-qty-buttons {
	display: none !important;
}

/* Native spinners. */
body.single-product .quantity input[type="number"] {
	-moz-appearance: textfield;
	appearance: textfield;
}
body.single-product .quantity input[type="number"]::-webkit-outer-spin-button,
body.single-product .quantity input[type="number"]::-webkit-inner-spin-button {
	-webkit-appearance: none;
	appearance: none;
	margin: 0;
}

body.single-product .quantity input.qty,
body.single-product .quantity input[type="number"] {
	width: 4.5em !important;
	text-align: center !important;
	border: 1px solid var(--c-sage) !important;
	border-radius: 2px !important;
}

/*
 * Label and box share a baseline. Both become inline-flex so the label centres
 * against the middle of the field rather than sitting on the text baseline,
 * which left it looking low.
 */
body.single-product .ci-qty-label {
	display: inline-flex !important;
	align-items: center;
	height: auto;
	vertical-align: middle !important;
}

body.single-product .woocommerce-variation-add-to-cart .quantity,
body.single-product form.cart .quantity {
	display: inline-flex !important;
	align-items: center;
	vertical-align: middle !important;
}

/*
 * The stepper CONTAINER, not just the arrows.
 *
 * Hiding .qty-plus / .qty-minus left div.quantity-nav in place — 35px wide with
 * its own border and white fill, so an empty bordered box sat beside the input
 * exactly where the arrows had been.
 */
body.single-product .quantity .quantity-nav,
body.single-product .quantity-nav {
	display: none !important;
}

/*
 * Hide the label wherever the quantity field itself is hidden.
 *
 * Product Extras marks these products by adding .pewc-hide-quantity to <body>
 * and hides the input from there, so the input is still in the DOM — which is
 * why a :has(input.qty) test matched and left the label stranded above the Add
 * to Cart button. Mirroring the plugin's own body class is exact: the label
 * disappears on precisely the products where the box does.
 *
 * The PHP check in functions.php covers is_sold_individually() and the
 * pewc_hide_quantity post meta; this covers the body-class case.
 */
body.pewc-hide-quantity .ci-qty-label,
body.single-product form.cart:not(:has(.quantity input.qty)) .ci-qty-label,
body.single-product .woocommerce-variation-add-to-cart:not(:has(.quantity input.qty)) .ci-qty-label {
	display: none !important;
}

/* The now-empty quantity wrapper should not hold space either. */
body.pewc-hide-quantity .quantity {
	display: none !important;
}

/* --------------------------------------------------------------------------
   FAQ accordions — readable text
   --------------------------------------------------------------------------
   Both the question labels and the answers failed the contrast bar on white:
     titles   sage rgb(129,139,125)      3.55:1
     answers  rgba(84,89,95,0.7)         3.43:1 effective

   The answers were the sneakier of the two: the colour itself is dark enough,
   but the 70% alpha composites it to roughly rgb(135,139,143) over white. Any
   contrast check run on the declared value alone would have passed it.

   Titles go teal (12.94:1), answers near-black at full opacity (20.62:1).
   -------------------------------------------------------------------------- */
body .elementor-accordion-title,
body .elementor-toggle-title,
body .e-n-accordion-item-title,
body .e-n-accordion-item-title-text {
	color: var(--c-teal) !important;
}

body .elementor-tab-content,
body .elementor-tab-content p,
body .elementor-tab-content li,
body .elementor-accordion-content,
body .elementor-accordion-content p,
body .elementor-accordion-content li,
body .e-n-accordion-item > div p,
body .e-n-accordion-item > div li {
	color: var(--c-black) !important;
	opacity: 1 !important;
}

/* --------------------------------------------------------------------------
   Shop / category cards — match the site body size
   --------------------------------------------------------------------------
   Card titles and prices were rendering at 16px against the 19.2px used
   everywhere else, so the grid read a size smaller than the rest of the site.
   -------------------------------------------------------------------------- */
/*
 * The visible card title is the <a class="woocommerce-LoopProduct-link">, which
 * sits OUTSIDE the h2.woocommerce-loop-product__title and carries its own 16px.
 * Styling the h2 alone did nothing visible — it measured 28px while the link
 * the customer actually reads stayed at 16px.
 */
body ul.products li.product .woocommerce-loop-product__title,
body ul.products li.product a.woocommerce-LoopProduct-link,
body ul.products li.product a.woocommerce-loop-product__link,
body .wc-block-grid__product-title {
	font-size: var(--fs-body) !important;
	line-height: 1.35 !important;
}

/*
 * The "FRAMED PRINTS" category label above each card title was 12px — the
 * smallest text in the grid. 16px keeps it clearly subordinate to the 19.2px
 * product name while staying legible.
 *
 * Price is deliberately left alone: it already renders correctly.
 */
/*
 * The category label is a bare <a> with no class inside p.product__categories,
 * so it has to be targeted through the parent.
 */
body ul.products li.product p.product__categories,
body ul.products li.product p.product__categories a,
body .woocommerce-card__header p.product__categories,
body .woocommerce-card__header p.product__categories a {
	font-size: 16px !important;
	letter-spacing: 0.05em !important;
	line-height: 1.4 !important;
}

/* --------------------------------------------------------------------------
   Layered-nav filter "radios"
   --------------------------------------------------------------------------
   These are not form controls — the theme draws them as an 8x8px li::before
   circle with a 2px border, so nothing that targets input[type="radio"] has any
   effect. Sizing the pseudo-element is the only way to change them.

   18px reads properly beside the 19.2px labels. The chosen filter fills teal
   via an inset box-shadow rather than a background, so the ring stays visible
   around the dot.
   -------------------------------------------------------------------------- */
body .woocommerce-widget-layered-nav-list__item::before,
body .wc-layered-nav-term::before,
body .widget_layered_nav li::before {
	/* 18px was too heavy beside the labels; 11px is ~40% smaller and still a
	   clear step up from the original 8px. Border trimmed to 1.5px so the ring
	   stays proportional at the smaller size. */
	width: 11px !important;
	height: 11px !important;
	border-width: 1.5px !important;
	border-color: var(--c-sage) !important;
	border-radius: 50% !important;
	flex: 0 0 auto;
	margin-right: 0.55em !important;
	box-sizing: border-box !important;
	/*
	 * Optical nudge. align-items:center centres the dot against the full line
	 * box, but the labels run at line-height 1.6, so the visual centre of the
	 * text sits above the box centre and the dot reads low. Done with relative
	 * positioning rather than a negative margin so the row height is unaffected.
	 */
	position: relative;
	top: -3px;
	transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

/* Selected filter: teal centre, teal ring. */
body .woocommerce-widget-layered-nav-list__item.chosen::before,
body .wc-layered-nav-term.chosen::before,
body .widget_layered_nav li.chosen::before {
	border-color: var(--c-teal) !important;
	box-shadow: inset 0 0 0 2.5px var(--c-white), inset 0 0 0 11px var(--c-teal) !important;
}

body .woocommerce-widget-layered-nav-list__item:hover::before,
body .wc-layered-nav-term:hover::before {
	border-color: var(--c-teal) !important;
}

/* Row alignment so the larger dot sits centred against its label. */
body .woocommerce-widget-layered-nav-list__item,
body .wc-layered-nav-term,
body .widget_layered_nav li {
	display: flex !important;
	align-items: center;
	line-height: 1.6 !important;
}

body .woocommerce-widget-layered-nav-list__item .count,
body .wc-layered-nav-term .count,
body .widget_layered_nav li .count {
	margin-left: auto !important;
}

/* ==========================================================================
   PRIMARY BUTTON TIER — solid teal
   --------------------------------------------------------------------------
   Add to Cart was given a solid teal fill on the product page and reads far
   better than the gold outline everywhere else, so the same treatment now
   carries the primary action on every screen in the purchase path: Checkout in
   the drawer, Proceed to Checkout on the cart page, and Place Order at the end.

   This is a two-tier system, not a global swap:

     PRIMARY    solid teal, white caps   — one per screen, the action we want
     SECONDARY  gold outline on offwhite — everything else

   View Cart is included at your request. Worth knowing what it costs: with two
   solid teal buttons stacked in the drawer, neither one reads as "the next
   step" any more. If you want that hierarchy back, the cleanest version is a
   teal OUTLINE for View Cart — still converted off the gold, still obviously
   part of the same family, but visibly the lesser of the two. Say the word and
   it is a two-line change.

   Note this also takes gold off the purchase-path buttons entirely, which is a
   departure from Sinead's brief. Gold still carries links, ratings, the
   progress bar and hover states, so it has not left the page.

   Must stay at the END of this file: the BUTTON OVERRIDE TIER above restates
   background/colour/border at !important for every button on the site, so an
   equal-specificity rule only wins by coming later in source order.
   ========================================================================== */

body .checkout-button,
body .cart-collaterals .checkout-button,
body #place_order,
body #payment .place-order .button,
body .wc-block-cart__submit-button,
body .wc-block-components-checkout-place-order-button,
body .elementor-menu-cart__footer-buttons .elementor-button--checkout,
body .elementor-button.elementor-button--checkout {
	background-color: var(--c-teal) !important;
	color: var(--c-white) !important;
	border: 2px solid var(--c-teal) !important;
	border-radius: 3px !important;
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	letter-spacing: 0.06em !important;
	text-transform: uppercase !important;
	line-height: 1.3 !important;
	transition: background-color 0.18s ease, border-color 0.18s ease !important;
}

body .checkout-button:hover,
body .cart-collaterals .checkout-button:hover,
body #place_order:hover,
body #payment .place-order .button:hover,
body .wc-block-cart__submit-button:hover,
body .wc-block-components-checkout-place-order-button:hover,
body .elementor-menu-cart__footer-buttons .elementor-button--checkout:hover,
body .elementor-button.elementor-button--checkout:hover {
	background-color: #16494C !important;   /* one step lighter than --c-teal */
	border-color: #16494C !important;
	color: var(--c-white) !important;
}

body .checkout-button:active,
body .cart-collaterals .checkout-button:active,
body #place_order:active,
body .wc-block-components-checkout-place-order-button:active,
body .elementor-button.elementor-button--checkout:active {
	background-color: #0A2C2E !important;
	border-color: #0A2C2E !important;
	color: var(--c-white) !important;
}

/*
 * The Place Order padlock is a CSS mask painted with background-color, NOT a
 * font glyph — changing `color` does nothing to it. On the old offwhite button
 * it was gold; on teal it has to become white or it disappears.
 */
/*
 * `body #payment .place-order .button::before` must be in this list. The gold
 * rule earlier in the file carries that selector, which scores (1,2,2) against
 * this block's (1,0,2) — being later in source order is not enough to beat it,
 * so without the matching selector the padlock stayed gold on a teal button.
 */
body #place_order:before,
body #payment .place-order .button:before,
body .checkout-button:before,
body .cart-collaterals .checkout-button:before,
body #place_order:hover:before,
body #place_order:active:before,
body #payment .place-order .button:hover:before,
body #payment .place-order .button:active:before,
body .checkout-button:hover:before,
body .checkout-button:active:before,
body .cart-collaterals .checkout-button:hover:before {
	background-color: var(--c-white) !important;
}

/*
 * Drawer buttons: match the product page's full-width block so View Cart and
 * Checkout share one left and right edge.
 */
body .elementor-menu-cart__footer-buttons .elementor-button {
	display: block !important;
	width: 100% !important;
	text-align: center !important;
}

/*
 * View Cart converted to solid teal alongside Checkout, per request.
 * Declared here rather than added to the list above so the hierarchy note in
 * that comment stays honest about what changed and why.
 */
body .elementor-menu-cart__footer-buttons .elementor-button--view-cart,
body .elementor-button.elementor-button--view-cart,
body .widget_shopping_cart a.button:not(.checkout) {
	background-color: var(--c-teal) !important;
	color: var(--c-white) !important;
	border: 2px solid var(--c-teal) !important;
	border-radius: 3px !important;
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	letter-spacing: 0.06em !important;
	text-transform: uppercase !important;
	transition: background-color 0.18s ease, border-color 0.18s ease !important;
}

body .elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover,
body .elementor-button.elementor-button--view-cart:hover,
body .widget_shopping_cart a.button:not(.checkout):hover {
	background-color: #16494C !important;
	border-color: #16494C !important;
	color: var(--c-white) !important;
}

/* The button label is a nested span in Elementor's markup — colour set on the
   anchor alone leaves it inheriting the old gold ink. */
body .elementor-button--view-cart .elementor-button-text,
body .elementor-button--checkout .elementor-button-text {
	color: var(--c-white) !important;
}

/* --------------------------------------------------------------------------
   Size swatches — restore the approved outline treatment
   --------------------------------------------------------------------------
   The size swatches used to get their offwhite fill and gold outline from the
   global button tier, since they are <button> elements. Excluding them from
   that tier (so the frame COLOUR swatches could show their actual colours
   again) dropped them back to CommerceKit's own white-on-pale-green default.

   Restated here for the text/size swatches only. .cgkit-color and .cgkit-image
   are deliberately not in this list — those render the real frame colour and
   must keep whatever fill the plugin gives them.

   The selected state is unchanged and still lives further up the file: solid
   gold with teal text.
   -------------------------------------------------------------------------- */
body .cgkit-attribute-swatch.cgkit-button button:not(.cgkit-swatch-selected),
body .cgkit-attribute-swatch.cgkit-button a:not(.cgkit-swatch-selected),
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-button button:not(.cgkit-swatch-selected) {
	background-color: var(--c-offwhite) !important;
	color: var(--c-gold-ink) !important;
	border: 2px solid var(--c-gold) !important;
}

body .cgkit-attribute-swatch.cgkit-button button:not(.cgkit-swatch-selected):hover,
body .cgkit-attribute-swatch.cgkit-button a:not(.cgkit-swatch-selected):hover {
	background-color: var(--c-gold) !important;
	color: var(--c-teal) !important;
	border-color: var(--c-gold) !important;
}

/* --------------------------------------------------------------------------
   Button shape — square corners everywhere
   --------------------------------------------------------------------------
   Most buttons pick up border-radius: 3px from the primary tier, but Apply
   Coupon and the Contact form's SEND button were being rendered as full pills
   by the theme and by Elementor's form widget respectively. Stated once here
   for the whole button set so the shape matches Add to Cart and Place Order.
   -------------------------------------------------------------------------- */
body .button,
body button:not(.cgkit-swatch, .close-drawer, .plus, .minus, .qty-btn, .pswp__button, .commercekit-wishlist-btn, .ci-select__button),
body input[type="submit"],
body button[type="submit"],
body .wp-element-button,
body .elementor-button,
body .elementor-field-type-submit button,
body .elementor-form .elementor-button,
body ul.products li.product .button,
body .woocommerce #respond input#submit,
body .coupon .button,
body .checkout_coupon .button,
body #payment .place-order .button {
	border-radius: 3px !important;
}

/*
 * Apply Coupon on one line.
 *
 * The label was wrapping to "APPLY / COUPON" because the button had no width
 * of its own and the uppercase letterspacing pushed it past the space the row
 * gave it. nowrap plus a minimum width keeps it on a single line; the coupon
 * row is a flex line so the input takes the remaining space.
 */
body .coupon .button,
body .checkout_coupon .button,
body form.checkout_coupon button,
body .woocommerce-cart-form .coupon button {
	white-space: nowrap !important;
	min-width: 11em !important;
	padding-left: 1.6em !important;
	padding-right: 1.6em !important;
}

/* --------------------------------------------------------------------------
   Cart rows — thumbnail aligns to the top
   --------------------------------------------------------------------------
   The personalisation summary makes some rows very tall (a full blessing runs
   to eight lines), and a vertically centred thumbnail then floated halfway
   down beside the middle of the text with no visual link to the product name
   it belongs to. Top alignment puts the image level with the name.
   -------------------------------------------------------------------------- */
body .woocommerce-cart-form__cart-item .product-thumbnail,
body .woocommerce-cart-form td.product-thumbnail,
body .shop_table td.product-thumbnail,
body .woocommerce-cart-form__cart-item .product-remove,
body .shop_table td.product-remove {
	vertical-align: top !important;
	padding-top: 1.2em !important;
}

/* --------------------------------------------------------------------------
   Bare headings inside Elementor content widgets
   --------------------------------------------------------------------------
   A heading typed into a Text Editor widget is a plain <h1>-<h6> with no
   .elementor-heading-title class, so it falls through to Elementor's kit rule
   (`.elementor-kit-283 h3`, specificity 0,1,1) instead of the child theme's
   heading rules. The homepage hero subhead was rendering in EB Garamond, the
   body face, while every other H3 on the site used Cormorant.

   Scoped to Elementor widget containers and given enough specificity to clear
   the kit rule outright rather than relying on !important alone.
   -------------------------------------------------------------------------- */
body .elementor-widget-container h1,
body .elementor-widget-container h2,
body .elementor-widget-container h3,
body .elementor-widget-container h4,
body .elementor-widget-container h5,
body .elementor-widget-container h6,
body .elementor-widget-text-editor h1,
body .elementor-widget-text-editor h2,
body .elementor-widget-text-editor h3,
body .elementor-widget-text-editor h4 {
	font-family: var(--font-heading) !important;
}

/* --------------------------------------------------------------------------
   Elementor form submit buttons — old brand font leaking through
   --------------------------------------------------------------------------
   The newsletter "Sign Up Now" and the contact form's "Send" still rendered in
   Manrope, the pre-rebrand sans-serif, with its wider 2.4px tracking. They are
   Elementor Form widget submits, and that widget prints its own typography with
   enough specificity to clear the general button rules.

   The two of them were the last Manrope on the site.
   -------------------------------------------------------------------------- */
body .elementor-form .elementor-button,
body .elementor-widget-form .elementor-button,
body .elementor-field-type-submit .elementor-button,
body .elementor-form button[type="submit"],
body .elementor-widget-form button[type="submit"] {
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	font-size: var(--fs-button, 16px) !important;
	letter-spacing: 0.06em !important;
	text-transform: uppercase !important;
}

/*
 * WooCommerce account form buttons (Log in, Register, Save changes).
 *
 * `body button` above sets the button face, but Shoptimizer ships a more
 * specific rule for .woocommerce-form-login__submit that carried Manrope
 * through with it. This was the last of the old font anywhere on the site.
 *
 * Note the family here is --font-body, not --font-heading: buttons across the
 * site settle on EB Garamond 600 (the primary tier at the end of this file
 * sets it, and the Elementor kit's button typography matches). The older
 * --font-heading declaration further up is overridden by that and is left in
 * place only because removing it is a separate, wider change.
 */
body .woocommerce-form-login__submit,
body .woocommerce-form-register__submit,
body .woocommerce-Button,
body button.woocommerce-button,
body .woocommerce-EditAccountForm button {
	font-family: var(--font-body) !important;
	font-weight: 600 !important;
	letter-spacing: 0.06em !important;
	text-transform: uppercase !important;
}

/* --------------------------------------------------------------------------
   Coupon input matches the button beside it
   --------------------------------------------------------------------------
   The field measured 60px against a 46px Apply Coupon button — a 14px
   mismatch sitting side by side on both /cart/ and /checkout/. Shoptimizer
   gives the input a fixed height that never moved when the button standard
   settled on 46px.

   Sized from --btn-min-h rather than a literal 46px so it tracks the button
   automatically, including the 48px mobile step-up that theme-buttons.css
   declares in its own media query. The token is defined on :root there; custom
   properties resolve at use time, so it is available here even though this
   file loads first. The fallback covers theme-buttons.css being reverted.

   Padding goes to 0 with the height doing the work: the field is centred by
   line-height, and adding padding on top of a fixed height would push the
   placeholder off-centre.
   -------------------------------------------------------------------------- */
body .coupon input#coupon_code,
body .coupon input.input-text,
body .checkout_coupon input#coupon_code,
body .checkout_coupon input.input-text,
body form.checkout_coupon .form-row input.input-text {
	height: var(--btn-min-h, 46px) !important;
	min-height: var(--btn-min-h, 46px) !important;
	padding-top: 0 !important;
	padding-bottom: 0 !important;
	box-sizing: border-box !important;
}

/* Put the field and the button on one baseline rather than relying on the
   inline-block default, which aligns them on their text baselines and leaves a
   few pixels of drift once the two have different font sizes. */
body .coupon,
body .checkout_coupon .form-row {
	display: flex !important;
	align-items: center !important;
	gap: 12px !important;
	flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Product page, mobile — gap below Secure Checkout Guaranteed
   --------------------------------------------------------------------------
   Measured 93px between the bottom of the secure-checkout note and the rule
   that opens "How Personalization Works". It came from two places, neither
   obvious from looking at either element:

     .product-details-wrapper  padding-bottom  60px
     .ci-steps                 margin-top      27px
     (plus ~6px of the summary's own trailing space)

   Halved on request, split across both contributors so neither ends up
   carrying the whole reduction: 28 + 13 + 6 = 47px, against a 46.5px target.

   Mobile only. The desktop spacing was reviewed and approved earlier in this
   work, and the wrapper's padding is shared by both breakpoints.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	body.single-product .product-details-wrapper {
		padding-bottom: 28px !important;
	}

	body.single-product .ci-steps {
		margin-top: 13px !important;
	}
}

/* --------------------------------------------------------------------------
   Reassurance strip (above the footer)
   --------------------------------------------------------------------------
   Sinéad's three points: the descriptive line under each of the four headings
   is too small, its line spacing looks compressed, and the icons want more
   breathing room above them.

   Done here rather than in Elementor because the widget settings cannot win.
   theme-brand.css sets font-family at !important across a very broad list
   (body, p, li, span, div...) and theme-type.css does the same for font-size on
   `body p`, so an image-box's own Style tab values are overridden before they
   reach the page. Anything changed on this strip has to be changed here.

   Measured before: description 14px / lh 1.60 on both breakpoints.
   -------------------------------------------------------------------------- */
body .footer__up .elementor-image-box-description {
	/* 14px -> 15.5px, the "1-2px" she asked for. */
	font-size: 15.5px !important;
	/* 1.60 -> 1.75. At 14px the descenders of one line sat close to the caps of
	   the next, which is what reads as compressed even though 1.6 is a normal
	   body ratio — short two-line strings show it more than paragraphs do. */
	line-height: 1.75 !important;
}

/*
 * Breathing room above the icons.
 *
 * Desktop: the icon sits to the LEFT of the text and the strip's band has no
 * top padding of its own, so the space goes on the band.
 *
 * Mobile: the strip stacks and each icon sits ABOVE its own heading, so the
 * space goes on each item — including the first, which a container `gap`
 * would skip (a gap only applies BETWEEN children).
 */
@media (min-width: 768px) {
	body .footer__up {
		padding-top: 12px !important;
	}
}

@media (max-width: 767px) {
	body .footer__up {
		padding-top: 12px !important;
	}
}

/* --------------------------------------------------------------------------
   "Show Filters" button — mobile only
   --------------------------------------------------------------------------
   On the shop and category archives the button appeared at every width, even
   though the filter sidebar is sitting open beside it on desktop. Two controls
   for the same job, one of which opens a drawer over a panel already on screen.

   Hidden from 993px up. That number is the theme's own breakpoint, not a guess
   — measured on /product-category/framed-canvas/:

     <= 992px   .widget-area is position:fixed, left:-300px, visibility:hidden
                (off-canvas — the button is the ONLY way to reach the filters)
     >= 1024px  .widget-area is position:static, in flow, 197px wide

   So the button has to survive below the breakpoint and only disappear above
   it. Tying the two together means the filters are always reachable: if the
   theme's breakpoint ever moves, this rule wants moving with it.

   The button's own class is `.mobile-filter` — the theme intends it for small
   screens; it simply ships without a rule to enforce that.
   -------------------------------------------------------------------------- */
@media (min-width: 993px) {

	body.archive button.mobile-filter,
	body.post-type-archive-product button.mobile-filter,
	body.woocommerce-shop button.mobile-filter,
	body .shoptimizer-archive button.mobile-filter,
	body button.mobile-filter.shoptimizer-mobile-toggle {
		display: none !important;
	}
}

/* --------------------------------------------------------------------------
   Product gallery — prev/next arrows beside the thumbnails
   --------------------------------------------------------------------------
   FlexSlider absolutely positions ul.flex-direction-nav over the main image,
   so both arrows sat in the bottom-right corner on top of the photograph.
   Requested: one arrow at each end of the thumbnail strip instead.

   The two arrows are a single <ul> containing both <li>s, so they cannot be
   split into separate grid cells. Instead the gallery becomes a grid and the
   nav is placed in the SAME cell as the thumbnail strip (both grid-area 2/1),
   spanning its full width with space-between — which puts one arrow at each
   end — while the strip is padded inwards so the thumbnails clear them.

   Why grid rather than nudging the existing absolute position: the thumbnail
   strip's offset depends on the main image height and on how many rows the
   thumbnails wrap to, so any hardcoded top/bottom would drift per product and
   per breakpoint. Sharing a grid cell tracks the strip wherever it lands.

   pointer-events is none on the <ul> because it now covers the whole strip and
   would otherwise swallow clicks meant for the thumbnails underneath; the <li>s
   put it back so the arrows stay clickable.

   The li margin drops 4px -> 3px purely to buy back width: nine thumbs at the
   original margins measured 612px against the 610px left after the 46px
   gutters, so they wrapped to a second row. Galleries with appreciably more
   thumbnails will still wrap, which is the same behaviour they already have on
   narrow screens.

   :has() scopes all of this to galleries that actually have a nav — a
   single-image product has no slider markup and is left as plain block flow.
   Where :has() is unsupported the whole treatment is skipped and the arrows
   simply stay on the image, which is the current behaviour.
   -------------------------------------------------------------------------- */
body.single-product .woocommerce-product-gallery:has(> ul.flex-direction-nav) {
	display: grid;
	grid-template-columns: 1fr;
}

body.single-product .woocommerce-product-gallery:has(> ul.flex-direction-nav) > .flex-viewport {
	grid-area: 1 / 1;
}

body.single-product .woocommerce-product-gallery:has(> ul.flex-direction-nav) > .flex-control-thumbs {
	grid-area: 2 / 1;
	padding-left: 46px;
	padding-right: 46px;
}

body.single-product .woocommerce-product-gallery:has(> ul.flex-direction-nav) > .flex-control-thumbs li {
	margin-left: 3px;
	margin-right: 3px;
}

body.single-product .woocommerce-product-gallery > ul.flex-direction-nav {
	grid-area: 2 / 1;
	position: static;
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin: 0;
	padding: 0;
	pointer-events: none;
}

body.single-product .woocommerce-product-gallery > ul.flex-direction-nav li {
	pointer-events: auto;
}

/* --------------------------------------------------------------------------
   Archive page headers — centred title + ornament divider
   --------------------------------------------------------------------------
   Covers the blog archive (`<h1 class="blog-title">Blog</h1>` inside
   `<header class="entry-header title">`), the shop page and every product
   category archive (`h1.woocommerce-products-header__title`). All theme
   templates, not Elementor, so there is no widget to set this on and it has to
   be CSS.

   Shop and the category archives were left-aligned before 15 Aug; they are
   centred here on request so every archive header matches the blog.

   The divider is the same artwork and the same treatment as the two in the home
   hero (theme-hero.css): 16px tall, `contain`, centred, full opacity. The URL is
   relative to THIS stylesheet, and theme-brand.css sits in the theme root
   alongside theme-hero.css, so `assets/images/...` resolves identically. It
   deliberately points at the theme copy rather than the wp-content/uploads URL —
   see the 15 Aug hero block in CHANGE-NOTES for why.

   ::after rather than a real element, so nothing is added to the template and
   the ornament cannot be deleted by accident while editing content.
   -------------------------------------------------------------------------- */
body h1.blog-title,
body .entry-header.title h1.blog-title,
body.post-type-archive-product .woocommerce-products-header__title,
body.tax-product_cat .woocommerce-products-header__title,
body.archive .woocommerce-products-header__title {
	text-align: center !important;
}

/*
 * `.woocommerce-products-header` is a FLEX container, so the h1 was a flex item
 * hugging its own text — 125px wide for "Shop". `text-align: center` therefore
 * centred the word inside a box the width of the word (i.e. did nothing
 * visible), and the ::after below, being that same 125px wide, shrank the
 * ornament to fit it under `background-size: contain`.
 *
 * Giving the h1 the full row fixes both at once. Safe because the h1 is the
 * ONLY child of that container — checked, not assumed.
 */
body.post-type-archive-product .woocommerce-products-header__title,
body.tax-product_cat .woocommerce-products-header__title,
body.archive .woocommerce-products-header__title {
	flex: 1 1 100% !important;
	width: 100% !important;
}

body h1.blog-title::after,
body.post-type-archive-product .woocommerce-products-header__title::after,
body.tax-product_cat .woocommerce-products-header__title::after,
body.archive .woocommerce-products-header__title::after {
	content: "";
	display: block;
	/*
	 * 22px, not 16px — this is the artwork's NATURAL height, and at
	 * `background-size: contain` in a container wider than 300px it therefore
	 * draws at exactly 300 x 22, its native size.
	 *
	 * 16px was the original value and it rendered the ornament at 218 x 16, which
	 * read as noticeably thinner and smaller than the section dividers further
	 * down the homepage. Those are real <img> elements (Elementor image widgets,
	 * wp-image-197) sitting at their natural 300 x 22 — measured, which is how
	 * the mismatch was pinned down. This now matches them exactly.
	 *
	 * `contain` is kept rather than a fixed 300px so the ornament still shrinks
	 * on a container narrower than 300px instead of clipping.
	 *
	 * NOTE the home HERO dividers (theme-hero.css) are deliberately still 16px —
	 * that card is narrow and they were signed off at that size. Do not assume
	 * these two should match.
	 */
	height: 22px;
	/*
	 * -5px, settled 15 Aug after trying 0.45em (too loose), -20px (cut through
	 * the descender of the "g" in "Blog" by 24.7px) and -10px (4.7px into it).
	 * The h1 is 64px text in a 73.6px line box, and clearing the "g" tail needs
	 * -5.3px or looser — so this sits right on the edge: tight to the word,
	 * just clear of the descender.
	 */
	margin: -5px auto 0;
	background-image: url("assets/images/gold-ornament-divider-sm.webp");
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	opacity: 1;
}

/* --------------------------------------------------------------------------
   PDP configurator — spacing rhythm from the client's 15 Aug notes
   --------------------------------------------------------------------------
   Requested: 48px above each numbered heading, 14-16px heading to divider,
   24px divider to first control, 48px from a section's end to the next
   heading. The notes give these as mobile figures but state the 48px as a
   general rule, so the rhythm applies at all widths.

   SUPERSEDED IN PART, 21 Aug: the client's "consistent spacing" annotation
   makes every gap in the summary column equal the description -> reviews-line
   gap. First pass set all five to 24px box-edge; Gerald read that as small
   and uneven, so they are equalised on VISIBLE (ink-to-ink) distance. Second
   revision: Gerald still read the gaps under the reviews line as smaller than
   the one above it, so those four carry +10px — 40px ink (box 40/40/35/38)
   against the 30px reference above the reviews line (box 28). Heading ->
   divider 15px and divider -> control 24px are unchanged.

   MOST OF IT IS NOT HERE. The values were folded into the existing step-spacing
   rules further up this file rather than bolted on as a second set — that block
   already styles all three step headings together, so a competing rule here
   lost to it on specificity and silently did nothing for step 3. Search for
   "48px above EVERY numbered heading" and the "15px heading -> divider" comment.

   Only the two declarations below had no existing home.

   Deliberately not tightened further: the client's own note says "do not reduce
   the internal spacing too aggressively... this is essentially a three-step
   product configurator". These values reduce the gaps; they do not close them.
   -------------------------------------------------------------------------- */

/* The controls carried 8px underneath, making the gap to the next heading 56px
   rather than the 48px asked for. */
body.single-product table.variations td.value {
	padding-bottom: 0 !important;
}

/* The table's own 7px bottom margin ADDS to the personalisation block's 48px
   rather than collapsing into it, which made that gap 55px. */
body.single-product table.variations {
	margin-bottom: 0 !important;
}

/* --------------------------------------------------------------------------
   PDP personalisation field labels — made subordinate to the step heading
   --------------------------------------------------------------------------
   Client's 15 Aug note: "Add Your FREE Personalization [Optional]" is visually
   competing with the numbered heading above it, and everything under
   "3. PERSONALIZATION:" should read as subordinate to it.

   They were right, and the numbers are worse than they look. Measured before:

       step heading   19.2px desktop / 18px mobile
       field label    23px    at BOTH widths

   so on mobile the label was 28% LARGER than the heading it sits under. The
   size came from Product Extras' own CSS, not from this theme — nothing in the
   child theme touched it, which is why it never tracked the type scale.

   THE CLIENT'S PRESCRIPTION IS NOT WHAT IS APPLIED HERE, deliberately. They
   suggested label 22-24px against a step heading raised to 26-28px on mobile.
   Raising the heading contradicts their own typography spec sheet, where H3 on
   mobile is 16px, so the same result is reached from the other side: the label
   comes down instead of the heading going up. Their ~0.85 label:heading ratio
   is preserved — 17/19.2 = 0.89 desktop, 16/18 = 0.89 mobile.

   Weight stays 600. The client framed this as a size problem, and the heading
   is already distinguished by being uppercase with a rule under it.
   -------------------------------------------------------------------------- */
body.single-product .pewc-field-label,
body.single-product h4.pewc-field-label {
	font-size: 17px !important;
}

@media (max-width: 768px) {
	body.single-product .pewc-field-label,
	body.single-product h4.pewc-field-label {
		font-size: 16px !important;
	}
}

/* --------------------------------------------------------------------------
   Blessing chooser — accordion over the long radio lists
   --------------------------------------------------------------------------
   Paired with assets/js/ci-blessing-accordion.js (client mockup, 25 Aug 2026).
   The radios are still the real controls: each Product Extras <label> becomes
   one row — the radio, a short title, an arrow button, and the full wording
   underneath. Two independent states, both set by the script: `.is-selected`
   (the circle was clicked: gold disc + tick, gold left border, SELECTED tag)
   and `.is-open` (the wording is showing, arrow points up). Reading a
   blessing does not select it; a second click on the circle clears it.
   `.ci-blessing-enhanced` gates everything, so if the JS fails the radios
   render exactly as Product Extras built them.

   Replaced the 15 Aug dropdown (`.ci-blessing__select`, `__summary`,
   `__toggle`); those classes no longer exist.
   -------------------------------------------------------------------------- */

/* Rows stack. The generic wrapper rule above makes option lists flex-wrap so
   Yes/No share a line; a blessing list must not. */
body.single-product .ci-blessing-enhanced .pewc-checkbox-group-wrapper {
	display: block !important;
	margin-top: 6px !important;
	border-top: 1px solid var(--c-stone);
}

body.single-product .ci-blessing-enhanced .pewc-checkbox-group-wrapper > li {
	display: block;
	border-bottom: 1px solid var(--c-stone);
}

/*
 * The selector is long ON PURPOSE. Product Extras prints an inline <style> with
 *
 *   ul.pewc-product-extra-groups .pewc-item:not(.pewc-item-checkbox):not(.pewc-item-products-radio-list) label
 *       { display: block !important }
 *
 * which scores (0,4,2). This scores (0,5,3) so the grid wins. Do not shorten
 * it. Columns: radio | title | "Selected" + chevron; the wording spans the
 * last two on its own line.
 */
body.single-product ul.pewc-product-extra-groups .pewc-item .ci-blessing-enhanced label.ci-blessing__row {
	display: grid !important;
	grid-template-columns: 18px minmax(0, 1fr) auto;
	column-gap: 14px;
	align-items: center;
	margin: 0 !important;
	padding: 12px 12px 12px 13px !important;
	border-left: 3px solid transparent;
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

body.single-product ul.pewc-product-extra-groups .pewc-item .ci-blessing-enhanced label.ci-blessing__row:hover {
	background-color: rgba(199, 165, 80, 0.05);
}

body.single-product ul.pewc-product-extra-groups .pewc-item .ci-blessing-enhanced label.ci-blessing__row.is-selected {
	border-left-color: var(--c-gold);
	background-color: transparent;
}

/*
 * The radio itself. Product Extras' preset style (inline CSS, class
 * .pewc-preset-style on the form) hides every radio input and draws a 25px
 * disc on the span.pewc-theme-element that follows it — grey, gold when
 * `input:checked ~ span.pewc-theme-element` matches, with a white tick in
 * :after. That is what the Yes/No and occasion rows show, so the accordion
 * uses the same disc rather than a second radio style in one form. The span
 * is pulled out of its absolute position into the first grid column; the
 * sibling selectors keep working because the span stays after the input
 * inside the label. The hidden input is sized over the disc so it remains the
 * click and focus target.
 */
body.single-product .ci-blessing-enhanced label.ci-blessing__row input.ci-blessing__radio {
	position: absolute !important;
	left: 13px;
	top: 14px;
	width: 18px !important;
	height: 18px !important;
	margin: 0 !important;
	opacity: 0;
	cursor: pointer;
	/* Above the disc span (which is positioned too, and later in the DOM):
	   a click on the circle must land on the radio, not on the label. */
	z-index: 1;
}

body.single-product .ci-blessing-enhanced label.ci-blessing__row span.pewc-theme-element {
	display: block !important;
	position: relative;
	top: 0;
	left: 0;
	grid-area: 1 / 1;
	width: 18px;
	height: 18px;
	transform: none;
}

/* Selected blessing: the design's filled gold disc (the other radios show a
   ring and dot — see "Radio buttons" below). */
body.single-product .ci-blessing-enhanced label.ci-blessing__row.is-selected span.pewc-theme-element {
	background: var(--c-gold) !important;
	border-color: var(--c-gold) !important;
}

/* The white tick on the chosen disc. Product Extras draws it in :after and
   the site's styling leaves it at opacity 0 everywhere (the Yes/No discs are
   plain gold). The mockup's selected blessing carries a tick, so it is shown
   here — in the accordion only; the other radios keep the site's look. */
/* Outranks the ring-and-dot :after rule below ((0,5,2)); this is (0,7,3).
   Without that the "tick" became the gold dot, invisible on the gold disc. */
body.single-product.pewc-preset-style .ci-blessing-enhanced label.ci-blessing__row.is-selected input:checked ~ span.pewc-theme-element::after {
	content: '';
	display: block;
	position: absolute;
	left: 5px;
	top: 1px;
	width: 4.5px;
	height: 9px;
	margin: 0;
	border-radius: 0;
	background: none;
	border-style: solid;
	border-color: var(--c-white);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
	opacity: 1 !important;
}

body.single-product .ci-blessing-enhanced label.ci-blessing__row input.ci-blessing__radio:focus-visible ~ span.pewc-theme-element {
	outline: 2px solid var(--c-teal);
	outline-offset: 2px;
}

body.single-product .ci-blessing-enhanced .ci-blessing__title {
	grid-area: 1 / 2;
	font-size: 16px !important;
	line-height: 1.4 !important;
	color: var(--c-black);
}

body.single-product .ci-blessing-enhanced .ci-blessing__state {
	grid-area: 1 / 3;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding-left: 8px;
}

/* "SELECTED" tag — only on the open row. */
body.single-product .ci-blessing-enhanced .ci-blessing__selected {
	display: none;
	font-size: 10px !important;
	line-height: 1 !important;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--c-teal);
}

body.single-product .ci-blessing-enhanced .is-selected .ci-blessing__selected {
	display: inline;
}

/* The arrow is a real <button> (keyboard-reachable, aria-expanded), stripped
   of the theme's button styling. The chevron inside is a rotated border, so
   nothing to colour or upload. Points down on closed rows, up on the open one.
   36px hit area, larger than it looks, because on a phone it is the thing
   people tap to read. */
body.single-product .ci-blessing-enhanced button.ci-blessing__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	min-height: 0 !important;
	margin: -8px -10px -8px 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 50%;
	background: none !important;
	box-shadow: none !important;
	color: var(--c-teal) !important;
	cursor: pointer;
}

body.single-product .ci-blessing-enhanced button.ci-blessing__toggle:hover {
	background: rgba(199, 165, 80, 0.12) !important;
}

body.single-product .ci-blessing-enhanced button.ci-blessing__toggle:focus-visible {
	outline: 2px solid var(--c-teal) !important;
	outline-offset: 1px;
}

body.single-product .ci-blessing-enhanced .ci-blessing__chevron {
	display: block;
	width: 8px;
	height: 8px;
	margin: 0 0 4px 0;
	border-right: 1.5px solid var(--c-teal);
	border-bottom: 1.5px solid var(--c-teal);
	transform: rotate(45deg);
	transition: transform 0.15s ease;
}

body.single-product .ci-blessing-enhanced .is-open .ci-blessing__chevron {
	margin: 4px 0 0 0;
	transform: rotate(-135deg);
}

/* The full wording: the option text Product Extras rendered, moved under the
   title. Shows on the open row, whether or not it is the chosen one. */
body.single-product .ci-blessing-enhanced .pewc-radio-option-text.ci-blessing__full {
	display: none;
	grid-area: 2 / 2 / 3 / -1;
	margin: 8px 0 2px;
	font-size: 16px !important;
	line-height: 1.6 !important;
	color: var(--c-black);
}

body.single-product .ci-blessing-enhanced .is-open .pewc-radio-option-text.ci-blessing__full {
	display: block;
}

/* Helper line, moved by the script from under the list to under the label. */
body.single-product .ci-blessing-enhanced .pewc-description {
	margin: -2px 0 6px !important;
	font-size: 13px !important;
	line-height: 1.4 !important;
	color: var(--c-ink-soft, #6B6F73);
}

/* --------------------------------------------------------------------------
   Radio buttons in the personalisation form
   --------------------------------------------------------------------------
   Product Extras' preset style draws every radio as a 25px solid disc (grey,
   gold when chosen) on span.pewc-theme-element. Gerald, 25 Aug 2026, against
   the client's mockup: make them read as radio buttons — an 18px ring with a
   gold dot inside when chosen. Applies to every radio field in the form
   (Yes/No, occasion, and the accordion's unselected rows); the accordion's
   selected row is the exception above. Also gives the preset's hidden tick
   a proper ring/dot geometry for the accordion's unselected rows.

   Specificity: the preset rules run to (0,4,1) for the :hover and :checked
   variants, so these carry .pewc-preset-style to sit above them. That class
   is on <body> itself (not a wrapper), hence `body.single-product.pewc-…`
   — written as a descendant it never matches.
   -------------------------------------------------------------------------- */
body.single-product.pewc-preset-style .pewc-radio-form-label span.pewc-theme-element {
	box-sizing: border-box;
	width: 18px;
	height: 18px;
	top: 50%;
	left: 0;
	transform: translateY(-50%);
	border: 1.5px solid #C9C5BD;
	border-radius: 50%;
	background: var(--c-white);
	transition: border-color 0.15s ease;
}

body.single-product.pewc-preset-style .pewc-radio-form-label:hover span.pewc-theme-element {
	border-color: var(--c-gold);
	background: var(--c-white);
}

body.single-product.pewc-preset-style .pewc-radio-form-label input:checked ~ span.pewc-theme-element {
	border-color: var(--c-gold);
	background: var(--c-white);
}

/* The dot. Replaces the tick Product Extras keeps in :after. */
body.single-product.pewc-preset-style .pewc-radio-form-label input:checked ~ span.pewc-theme-element::after {
	content: '';
	display: block;
	position: absolute;
	left: 50%;
	top: 50%;
	width: 8px;
	height: 8px;
	margin: -4px 0 0 -4px;
	border: 0;
	border-radius: 50%;
	background: var(--c-gold);
	transform: none;
	opacity: 1;
}

body.single-product.pewc-preset-style .pewc-radio-form-label input:focus-visible ~ span.pewc-theme-element {
	outline: 2px solid var(--c-teal);
	outline-offset: 2px;
}

/* The preset pads the label 35px for its 25px disc; 28px suits the ring. The
   accordion rows set their own padding with !important and are unaffected. */
body.single-product.pewc-preset-style .pewc-option-list .pewc-item-field-wrapper label.pewc-radio-form-label {
	padding-left: 28px;
}

/* --------------------------------------------------------------------------
   Occasion chooser and section heading
   --------------------------------------------------------------------------
   `.ci-occasion` is the Product Extras field class set on the occasion field
   by aaa_remote/blessing-accordion-fields.php. Two even columns as in the
   mockup (Baby | New Home, Wedding | Sympathy, Traditional Irish | Use My Own
   Wording) instead of the flex-wrap that left "May the road rise…" stranded.
   -------------------------------------------------------------------------- */
body.single-product .pewc-item.ci-occasion .pewc-checkbox-group-wrapper {
	display: grid !important;
	/* First column hugs its longest option ("Traditional Irish") so the second
	   has room for "Use My Own Wording" on one line at the summary's width. */
	grid-template-columns: max-content minmax(0, 1fr);
	gap: 0.55em 1.5em;
	margin-top: 4px !important;
}

/* The two section headings — "Add Your FREE Personalization [Optional]" and
   "Choose Your Blessing [Optional]" — sit a step above the numbered field
   labels (17px), which is how the mockup separates sections from steps. The
   first is the Yes/No field's own label; `.pewc-field-count-0` is Product
   Extras' class for the first field of the group. */
body.single-product .ci-blessing-heading,
body.single-product h4.pewc-field-label.ci-blessing-heading,
body.single-product .pewc-item.pewc-field-count-0 h4.pewc-field-label {
	font-size: 20px !important;
	margin-bottom: 10px !important;
}

body.single-product h4.pewc-field-label.ci-blessing-heading {
	margin-top: 4px !important;
	margin-bottom: 12px !important;
}

/* "Use My Own Wording" box. Product Extras renders a two-row textarea (56px)
   for a 200-character field; Gerald wants it at least as tall as the 15 Aug
   version, ~150px. `.ci-own-wording` is the field class set on field 9741 by
   aaa_remote/blessing-accordion-fields.php. */
body.single-product .pewc-item.ci-own-wording textarea {
	min-height: 150px !important;
}

/* --------------------------------------------------------------------------
   Sticky product gallery (desktop)
   --------------------------------------------------------------------------
   The summary column runs to ~2300px once the personalisation form is open;
   the gallery is 780px. Gerald (25 Aug 2026): keep the image on screen while
   the shopper works down the form, as far as the bottom of the column, desktop
   only.

   Two things had to change for `position: sticky` to work here:

   1. `.product-details-wrapper` — the columns' parent — has `overflow: hidden`
      from Shoptimizer. Any overflow value other than visible/clip makes an
      ancestor a scroll container, and a sticky element sticks to THAT box
      instead of the viewport, so nothing visibly happened. The theme uses the
      hidden overflow only to contain the two floats; `display: flow-root`
      does exactly that without the scroll container. Wrapper height measured
      identical before and after (2357px on the Antrim PDP).

   2. The sticky box's limit is its containing block, the same wrapper, whose
      bottom is the summary's bottom plus the wrapper's padding — so the image
      stops where the column ends, which is the requested behaviour.

   The gallery is a float and stays one; sticky positioning works on floats.
   Offset: 24px from the top of the viewport, plus the admin bar when there is
   one (WordPress sets --wp-admin--admin-bar--height on :root for logged-in
   users; it is undefined for shoppers, so the fallback 0px applies).

   992px matches Shoptimizer's desktop breakpoint, where the two columns sit
   side by side. Below it the columns stack and sticky would pin the image over
   the form.
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {

	body.single-product .product-details-wrapper {
		overflow: visible !important;
		display: flow-root;
	}

	/* !important: Shoptimizer's product.min.css pins the gallery with
	   `position: relative` and the computed value stayed relative without it. */
	body.single-product .product .woocommerce-product-gallery {
		position: sticky !important;
		top: calc(var(--wp-admin--admin-bar--height, 0px) + 24px);
	}
}


/* --------------------------------------------------------------------------
   Header bag icon sized to the heart (client, 2 Sep 2026)
   --------------------------------------------------------------------------
   The wishlist heart is a Font Awesome outline glyph at 20px; the cart bag is
   a custom filled SVG the Elementor menu-cart widget inlines at 22px tall
   (25.2px rendered), so it read heavier and taller than the heart and its
   bottom floated 2px above the heart's. Per the client ("same weight as the
   heart") and Gerald ("make it smaller, baseline even with the heart"):
   drawn at the heart's 20px and translated down so the two bottoms sit on the
   same line. width:auto keeps the SVG's own 17.459:22 ratio.

   2.9px, not the 4.4px that makes the BOXES align: the Font Awesome glyph's
   ink stops ~1.5px above its own box bottom (descender space in the em), so
   box-aligned looked like the bag hung low — Gerald asked for it "up a pixel
   or 2". This aligns the ink, checked at 4x zoom.
   -------------------------------------------------------------------------- */
.elementor-location-header .elementor-menu-cart__toggle_button svg {
	height: 20px !important;
	width: auto !important;
	transform: translateY(2.9px);
}

/* Colour too (client, 2 Sep): the SVG's shapes carry fill="#5e7775" as
   attributes, so no colour rule ever reached them. currentColor hands the
   fill to CSS, and the colour is pinned to teal ON THE SVG itself — the
   heart is an Elementor Icon widget locked to teal with no hover change, and
   inheriting from the toggle button would have turned the bag gold on hover
   (the "icon controls" block above) while the heart stayed put. The clipPath
   rect also matches but only clips; its fill never paints.

   And bolder (Gerald, 2 Sep: "make the bag bolder"): the bag's line weight
   is baked into its outline-as-fill geometry (~1px rendered) and the Font
   Awesome heart draws nearer 1.7px. A same-colour stroke on top of the fill
   thickens the artwork; 0.9 SVG user units at the 20px render ≈ 0.8px extra.
   The heart itself cannot be lightened — FA free has one weight. */
.elementor-location-header .elementor-menu-cart__toggle_button svg {
	color: var(--c-teal);
}

.elementor-location-header .elementor-menu-cart__toggle_button svg path,
.elementor-location-header .elementor-menu-cart__toggle_button svg rect {
	fill: currentColor;
	stroke: currentColor;
	stroke-width: 0.9;
	stroke-linejoin: round;
}


/* --------------------------------------------------------------------------
   Frame colour swatch — selected state is an outline, not a fill
   (client, 2 Sep 2026)
   --------------------------------------------------------------------------
   "Rather than a square with a gold fill, can it just be a gold square outline
   with no fill colour?"

   The selected-swatch rule further up this file (solid gold, teal text — right
   for the size pills) also caught the frame COLOUR swatches. Those buttons are
   40px with the real colour drawn as a 32px disc on top, so the gold
   background showed all round the disc as a filled square.

   Colour swatches only. The size pills keep the solid gold fill, and the
   unselected colour swatches keep their gold circle — the shape change from
   circle to square is still what marks the choice, now unfilled.

   Two consequences of removing the fill, handled here:
   - CommerceKit's own selected marker is a ring on ::before (2px, at the
     button's edge, radius 50%). It was invisible against the fill; left alone
     it would now draw a gold circle touching the inside of the gold square.
     Turned off — the square is the marker.
   - White/Ivory then had nothing behind it: a #FAF9F6 disc on a white page
     with no ring reads as an empty box. A hairline on the disc keeps its edge.
     It is inset, so nothing moves, and it disappears against the dark colours.

   Specificity: this ties the earlier selected-swatch rule at (0,3,2) and wins
   on source order alone, so it must stay AFTER it — hence appended at the end
   of the file. The :hover forms are restated for the same reason.
   -------------------------------------------------------------------------- */
body .cgkit-attribute-swatch.cgkit-color button.cgkit-swatch-selected,
body .cgkit-attribute-swatch.cgkit-color button.cgkit-swatch-selected:hover,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-color button.cgkit-swatch-selected,
body .cgkit-as-wrap .cgkit-attribute-swatches .cgkit-attribute-swatch.cgkit-color button.cgkit-swatch-selected:hover {
	background-color: transparent !important;
	border: 2px solid var(--c-gold) !important;
	border-radius: 4px !important;
}

body .cgkit-attribute-swatch.cgkit-color > button.cgkit-swatch-selected:before,
body .cgkit-attribute-swatch.cgkit-color > button.cgkit-swatch-selected:hover:before {
	border-color: transparent !important;
}

body .cgkit-attribute-swatch.cgkit-color > button.cgkit-swatch-selected span.color-div {
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

/* ==========================================================================
   CART — "[Edit options]" on its own line
   ==========================================================================
   Product Extras appends its edit link inline after the product title, so on a
   long name it wrapped mid-phrase ("… Framed Print Gift [Edit / options]").
   customirish_cart_edit_options_own_line() in functions.php wraps it in
   .ci-cart-edit-options purely so there is something to address here — the
   plugin's own markup is an unclassed <small>.

   display:block drops it under the title; the small top margin keeps it from
   sitting tight against the descenders, and it reads as a link belonging to
   the item rather than part of the name.

   nowrap because the phrase is three inline pieces — "[", the link, "]" — and
   the mobile cart makes the middle one a block:

       @media (max-width: 768px)
       .m-cart table.cart tr td.product-name a { display: block; padding-right: 40px }

   which broke it across three lines, one bracket stranded on each. Putting the
   anchor back to inline is the actual fix; nowrap on the wrapper then keeps the
   three pieces together if the cell gets narrower still. The 40px right padding
   goes too — it exists to clear the remove-item X beside the product title, and
   on our own line there is nothing to clear.
   ========================================================================== */
.ci-cart-edit-options {
	display: block;
	margin-top: 0.35em;
	line-height: 1.3;
	white-space: nowrap;
}

/* (0,4,4) with !important, against the theme's (0,3,4) — it wins on both. */
.m-cart table.cart tr td.product-name .ci-cart-edit-options a,
.ci-cart-edit-options a {
	display: inline !important;
	padding-right: 0 !important;
}

/* ==========================================================================
   PDP variations — swatches on one row, "Clear" on the price line
   --------------------------------------------------------------------------
   Every width: the client asked for desktop and mobile to match, so what was
   a mobile-only arrangement now applies throughout and there is no breakpoint
   here to keep in step with the script.

   `td.value` is a flex row with `flex-wrap: nowrap`, holding the swatch list
   (.cgkit-as-wrap) and — until customirish_reset_link_onto_price_line() moves
   it — the "Clear" link. Narrow, the 37px link took enough width off the list
   that the seventh 40px swatch wrapped to a row of its own, so the frame
   colours read as 6 + 1 rather than one set. Letting the cell wrap and giving
   the list a 100% basis keeps all seven together at any width.

   Measured at a 390px viewport when this was mobile-only: list 298px -> 345px,
   seven swatches on one row ending at 343px against a 360px cell edge.
   ========================================================================== */
body.single-product table.variations td.value {
	flex-wrap: wrap;
}

body.single-product table.variations td.value .cgkit-as-wrap {
	flex: 1 1 100%;
}

/*
 * The link's own line in the cell — the no-JS fallback.
 *
 * This is what renders if scripting is off, so it keeps the spacing that was
 * measured for it: the inherited box was margin 0 0 12px 10px, which indented
 * "Clear" past the first swatch and left a gap under it that read as a break
 * before "3. Personalization". With the script running the link is not in this
 * cell at all and these rules simply do not match.
 */
body.single-product table.variations td.value a.reset_variations {
	flex: 1 0 100%;
	margin: 5px 0 0 !important;
	padding: 0 !important;
}

/*
 * Where the link actually lives once the script has moved it: sharing the
 * price's line.
 *
 * .single_variation and the link shrink to their content and sit on one
 * baseline; the add-to-cart block below keeps a full-width line of its own,
 * which is what stops the personalisation fields riding up beside the price.
 */
body.single-product .single_variation_wrap {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 0.9em;
}

body.single-product .single_variation_wrap > .single_variation,
body.single-product .single_variation_wrap > a.reset_variations {
	flex: 0 0 auto;
}

body.single-product .single_variation_wrap > a.reset_variations {
	margin: 0 !important;
	padding: 0 !important;
}

body.single-product .single_variation_wrap > .woocommerce-variation-add-to-cart {
	flex: 1 0 100%;
}

/*
 * The price's own 12px bottom margin has to go on this shared line.
 *
 * It is invisible while the price is stacked on its own, but beside "Clear" it
 * makes .single_variation (30.7px of price + 12px) the tallest item on the flex
 * line, so selecting a variation pushed the add-to-cart block — and
 * "3. Personalization" under it — 12px further down than the unselected state.
 * Measured at 616px: gap below the line 38px with nothing selected, 50px once a
 * variation was chosen; 38px in both with this rule.
 */
body.single-product .single_variation_wrap > .single_variation .woocommerce-variation-price {
	margin-bottom: 0 !important;
}

/* ==========================================================================
   CART — the mobile thumbnail is sized by width, never cropped
   --------------------------------------------------------------------------
   The parent theme's mobile cart pins the thumbnail cell to the row's top-left
   corner and clamps it:

       .m-cart table.cart td.product-thumbnail {
           position: absolute; overflow: hidden; max-height: 120px; width: 100px;
       }

   The image is 100px wide and square, so it is 100px tall — but the cell also
   carries 23px of top padding, and 23 + 100 overruns the 120px clamp by 3px,
   which `overflow: hidden` then cut off the bottom of the frame. Measured on a
   live cart line, not inferred.

   Height follows width and nothing crops it: the clamp goes, the cell is free
   to be as tall as its image, and the image keeps its own aspect ratio. Safe to
   let it size itself here — every product and variation image on the store is
   square (1496 at 800x800, 251 at 800x792, all 55 parent images 1:1), so a
   100px-wide thumbnail is ~100px tall against a row that is at least 130px.
   A taller image would simply make the cell taller rather than being cropped,
   which is the behaviour the client asked for.

   The top padding stays: it is what lines the image up with the product title
   beside it.
   ========================================================================== */
/* body.m-cart, not `body .m-cart`: the theme puts that class ON the body
   element, so a descendant selector matches nothing. */
body.m-cart table.cart td.product-thumbnail {
	max-height: none !important;
	overflow: visible !important;
}

body.m-cart table.cart td.product-thumbnail img {
	width: 100px !important;
	max-width: 100px !important;
	height: auto !important;
	object-fit: contain !important;
}

/* ==========================================================================
   Catalogue sorting — the custom listbox
   --------------------------------------------------------------------------
   Styling for the widget built by assets/js/ci-sorting-select.js, which stands
   in for the native <select> so the OPEN list can carry the brand face. iOS
   draws a native select's options in a system picker outside the web view,
   where no CSS reaches them.

   The closed control is deliberately identical to the rules for
   `select.orderby` further up this file — same padding, border, radius, colour
   and face — so nothing moves when the widget replaces the select. If those
   are edited, edit these with them.

   !important alone was not enough on the button: the gold button system's
   `body button:not(...)` rule is (0,1,2) against a plain `body .ci-select__button`
   at (0,1,1), so it won on specificity even with both marked important and the
   control rendered as a gold pill. Fixed at both ends — .ci-select__button is
   listed in that rule's :not() exclusions alongside .cgkit-swatch and the other
   controls that are not buttons in the brand sense, and the selectors here are
   `body button.ci-select__button` so they outrank it on their own.
   ========================================================================== */
.ci-select {
	position: relative;
	display: block;
}

body button.ci-select__button {
	display: flex !important;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	width: 100%;
	/*
	 * ~100px wider than the label needs (client's call). The control is sized
	 * by its content — "Default sorting" plus the caret came to ~165px — so the
	 * floor is set here rather than a width, and max-width keeps it inside a
	 * narrow row on a small phone. The label stays left and the caret right,
	 * because the button is a space-between flex row.
	 */
	min-width: 265px;
	max-width: 100%;
	padding: 10px 16px !important;
	background: var(--c-white) !important;
	border: 1px solid var(--c-sage) !important;
	border-radius: 2px !important;
	box-shadow: none !important;
	color: var(--c-teal) !important;
	font-family: var(--font-body) !important;
	/* Size is set with the rest of the catalogue chrome in theme-type.css. */
	font-weight: 500 !important;
	line-height: 1.4 !important;
	letter-spacing: normal !important;
	text-align: left;
	text-transform: none !important;
	cursor: pointer;
}

body button.ci-select__button:hover,
body button.ci-select__button:focus-visible {
	border-color: var(--c-teal) !important;
	background: var(--c-white) !important;
	color: var(--c-teal) !important;
}

/* Caret drawn here rather than shipped as an image: it is three declarations
   and it tracks the text colour. */
.ci-select__caret {
	flex: 0 0 auto;
	width: 0;
	height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 5px solid currentColor;
}

/*
 * Anchored to the control's RIGHT edge, not its left.
 *
 * The panel is as wide as its longest label ("Sort by price: low to high"),
 * which is wider than the button. Hung from the left it grew rightwards off
 * the screen on a phone, where the control already sits against the right edge
 * of the sorting row. Hung from the right it grows inwards instead, and the
 * viewport cap plus wrapping labels cover the case where even that is not
 * enough room.
 */
.ci-select__list {
	position: absolute;
	z-index: 30;
	top: calc(100% + 4px);
	right: 0;
	left: auto;
	/* The panel is exactly as wide as the control, not as wide as its longest
	   label — the two read as one object that way, and a label longer than the
	   box wraps rather than widening it. */
	width: 100%;
	max-width: calc(100vw - 24px);
	max-height: 60vh;
	margin: 0;
	padding: 4px 0;
	overflow-y: auto;
	list-style: none;
	background: var(--c-white);
	border: 1px solid var(--c-sage);
	border-radius: 2px;
	box-shadow: 0 6px 20px rgba(3, 3, 3, 0.12);
}

/* The list takes DOM focus while open, but the active row is what the eye
   follows — so the focus ring goes there rather than round the whole box. */
.ci-select__list:focus {
	outline: none;
}

.ci-select__option {
	margin: 0;
	padding: 9px 16px;
	font-family: var(--font-body);
	font-weight: 400;
	line-height: 1.4;
	color: var(--c-teal);
	cursor: pointer;
}

.ci-select__option:hover,
.ci-select__option.is-active {
	background: var(--c-offwhite);
}

.ci-select__option[aria-selected="true"] {
	font-weight: 600;
}

/* --------------------------------------------------------------------------
   Mobile: the sorting control matches the product image's width
   --------------------------------------------------------------------------
   As wide as the image below it, per the client — NOT as wide as the "Show
   Filters" bar, which spans the whole row. Desktop keeps the 265px control
   above.

   The tracks have to fill the row before anything in them can: the theme's
   <=992px row is `grid-template-columns: auto auto` with
   `justify-content: flex-end`, so the columns are content-sized and packed
   right — measured at 0px + 164.9px — and spanning the form across both still
   only spanned those 165px. One full-width column fixes it at the source. The
   row's other children (notices wrapper, result count, pagination) all render
   at zero width on this store, so nothing else moves.

   The panel follows the button, since it is width:100% of this wrapper.
   -------------------------------------------------------------------------- */
@media (max-width: 992px) {
	body .shoptimizer-sorting {
		grid-template-columns: minmax(0, 1fr) !important;
		justify-content: stretch !important;
	}

	body .shoptimizer-sorting form.woocommerce-ordering {
		grid-column: 1 / -1 !important;
		width: 100% !important;
		justify-self: stretch !important;
		/*
		 * Inset to the IMAGE's edges, not the row's. The product card spans the
		 * container and carries 15px of padding, so the image sits 15px inside
		 * the row on each side — matching the row itself (what "Show Filters"
		 * does) made the control wider than the image below it. Padding rather
		 * than a width so the number stays tied to the card's padding: if that
		 * 15px changes, this is the one place to follow it.
		 */
		padding-right: 15px !important;
		padding-left: 15px !important;
	}

	body .ci-select {
		width: 100%;
	}
}

/* --------------------------------------------------------------------------
   CART + CHECKOUT — payment badges are Visa/Mastercard only, at native size
   --------------------------------------------------------------------------
   Client review: "Remove additional icons below as we only use VISA and MC."

   The strip under Proceed to Checkout / Place Order is NOT theme markup. It is
   a text widget: #text-9 in the `cart-field` sidebar and #text-21 in
   `checkout-field`, both printed inside .cart-custom-field by the parent theme
   (`inc/woocommerce/template-functions/cart.php` and `checkout.php`). Both
   carried the Shoptimizer demo's six-badge strip — 100% guarantee, secure,
   BBB accredited, Visa, Mastercard, PayPal — HOTLINKED at 1024x108 from
   themedemo.commercegurus.com. Both now point at the media library's
   Visa+Mastercard pair, /wp-content/uploads/2025/04/MC-VISA-trust-symbols.jpg
   (attachment 15940, 162x40 native, already on production).

   That swap is a DB change to the `widget_text` option. It does NOT travel
   with a theme rsync — the wp-cli command is in the change note.

   Why this rule has to exist: the parent theme stretches
   `.cart-custom-field img` to `width:100%; max-width:400px` below 992px. That
   suited a 1024px-wide strip. It blows the 162px badge up to 386x95 in the
   386px totals column — 2.4x its native width, visibly soft. Cap it at native
   size; it stays centred on the 0 auto margin the theme already sets.
   -------------------------------------------------------------------------- */
@media (max-width: 992px) {
	body .cart-custom-field img {
		width: auto !important;
		max-width: 100% !important;
	}
}

/* --------------------------------------------------------------------------
   CHECKOUT — "Returning customer? / Click here to login" stacks on phones
   --------------------------------------------------------------------------
   Client review: the green login bar reads as two ragged columns on a phone —
   "Returning" / "customer?" on the left, "Click here to" / "login" on the
   right — instead of one sentence.

   Cause: the bar is `.woocommerce-form-login-toggle > .woocommerce-info`, and
   `.woocommerce-info` is set to `display:flex; align-items:center;
   justify-content:space-between` by the site's DB-stored Additional CSS (an
   inline <style> in the head, so it loads after every theme file). WooCommerce
   prints the label and the link as one text run — `Returning customer?
   <a class="showlogin">Click here to login</a>` — so flex turns the bare text
   into one anonymous flex item and the anchor into a second, pins them to
   opposite ends, and each then wraps inside its own column.

   Measured at a 386px viewport: the box is 341px wide with 31.07px of side
   padding, leaving 278.9px of content; the string needs 295.7px on one line.
   17px short, so it always wraps — and space-between makes that wrap read as
   two columns rather than as one wrapped sentence.

   Fix: keep the flex context but turn the axis on phones. `flex-direction:
   column` puts label and link on their own rows, and `align-items: center`
   centres them in the bar (client's call on review — the first pass was
   `flex-start`).

   `align-items` is doing a second job that is not cosmetic: it stops the
   anchor stretching to the full 278.9px content width, which a column flex
   container would otherwise do by default and which would make the entire
   width of the bar a click target. Either `center` or `flex-start` prevents
   that; `stretch` (the default) must not come back. Measured after: link
   135.3px wide, centred, bar height unchanged at 96px.

   `text-align: center` is belt-and-braces for narrow phones — the items are
   content-sized and both fit on one line down to 320px, but if the label ever
   did wrap its second line would otherwise sit left inside a centred box.

   `display: flex` is restated rather than inherited from the inline block, so
   this rule still stacks the two rows if that DB-stored CSS is ever edited away.

   Specificity, not order, is what wins here: this is (0,2,1) against the
   inline rule's (0,1,0), so no !important is needed even though the inline
   block loads later. 767px is the child theme's usual phone breakpoint.

   Desktop and tablet keep the label-left / link-right bar.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
	body .woocommerce-form-login-toggle .woocommerce-info {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: flex-start;
		text-align: center;
	}
}

/* ==========================================================================
   "Loved By Our Customers" — Etsy reviews carousel repainted to the brand
   --------------------------------------------------------------------------
   Client review: "Replace the colours on the Etsy reviews carousel", with a
   seven-swatch palette and a mockup. Every hex in that palette is already a
   brand colour, so this uses the variables rather than restating the values:

     outer background (section)   #818B7D  --c-sage      already correct
     heading + card background    #F1F1EF  --c-offwhite
     carousel panel               #EAE6E1  --c-stone
     arrow / controls             #0D3739  --c-teal
     stars + decorative line      #C7A550  --c-gold
     primary text (names, bodies) #030303  --c-black
     secondary text (dates)       #818B7D  --c-sage

   WHAT THIS IS. The carousel is an **Elfsight Etsy Reviews** widget, mounted
   by script into an Elementor HTML widget inside section 23b167b5 — it is not
   theme markup and not an iframe, so it renders into the light DOM and CSS can
   reach it. Elfsight paints it with styled-components: hashed class names
   (`.ijpSPf`) in a runtime-injected <style>, plus a parallel set of stable
   `es-*` hooks on the same elements. **Target the `es-*` classes only** — the
   hashed ones change on every Elfsight build.

   WHY EVERY RULE IS !important. Two different things outrank a plain rule
   here. The panel's colour is an **inline style** on `.es-background-base`
   (`background-color: rgb(141,162,153)`), and the rest arrives in a <style>
   injected at runtime, i.e. after every theme stylesheet. Specificity alone
   loses to the first and source order loses to the second.

   Scoped to the Elfsight app id rather than to the Elementor section, so the
   palette follows the widget if the section is rebuilt or the widget is placed
   on a second page. If the widget is ever re-created in the Elfsight dashboard
   its app id changes and these rules stop matching — that is the failure mode
   to look for if the carousel goes green again.

   The alternative to all of this is Elfsight's own colour settings in their
   dashboard. Deliberately not used: those live in a third-party account with
   no credentials in this repo and no revert path in git.

   THE ORNAMENT DIVIDER needs no rule. It is `gold-ornament-divider-sm.webp`,
   a 300x22 raster; sampling it gives #C8A361 / #CDA865 with #FFD994
   highlights — the brand gold already, and a colour value could not repaint
   it anyway.

   CONTRAST, measured:
     primary #030303 on the card       18.24:1  (was ~8.6:1 on the green card)
     heading #F1F1EF on the sage        3.14:1  (was 3.55:1 in white — still
                                                 clears the 3:1 large-text bar)
     secondary #818B7D on the card      3.14:1  — FAILS the 4.5:1 AA bar for
       normal-size text. It is a large improvement on what it replaces (the old
       50%-black dates measured 1.86:1 on the green card), and it is the value
       the client specified, so it ships as given. Flagged, not silently
       changed — same treatment as the sage-section warning further up.
   ========================================================================== */

/* The heading sits OUTSIDE the widget, so it is targeted on its own Elementor
   id. Elementor's page CSS paints it with --e-global-color-accent (white) at
   (0,3,1); that global is used elsewhere on the site, so it is overridden here
   per-element rather than globally. */
body .elementor-element-23126655 .elementor-heading-title {
	color: var(--c-offwhite) !important;
}

/* Panel behind the cards — the inline-styled element. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-background-base {
	background-color: var(--c-stone) !important;
}

/* The cards. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-background-container {
	background-color: var(--c-offwhite) !important;
}

/* The skeleton that stands in for an avatar while it loads. It inherited the
   old green, so without this the new off-white card flashes a green disc on
   every page view. Stone rather than off-white so it still reads as a
   placeholder against the card. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-skeleton-loader {
	background-color: var(--c-stone) !important;
}

/* Carousel arrows: a solid teal disc, was 50%-opacity black. The chevron takes
   its fill from the control's `color`, but the path is pinned as well so a
   future Elfsight build that hard-codes the fill cannot turn it dark. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-carousel-arrow-control {
	background-color: var(--c-teal) !important;
	color: #FFFFFF !important;
}

body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-carousel-arrow-control .es-icon-svg path {
	fill: #FFFFFF !important;
}

/* Stars. The gold is a `fill` on the <path> inside each filled star; the
   unfilled ones are left neutral on purpose. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-rating-item-filled svg path {
	fill: var(--c-gold) !important;
}

/* Primary text — reviewer names, review bodies, the AI summary's bullet list.
   `.es-review-author-block-author-name` rather than the bare
   `.es-review-author-name`: that class is shared with the AI summary's title,
   which is deliberately a different colour (below). */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-author-block-author-name,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-author-block-author-name .es-review-author-name,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-content,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-content,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-list-item,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-checkmark,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-list-item-text {
	color: var(--c-black) !important;
}

/* Secondary text — dates, the "Based on N Etsy reviews" caption, "Read more".
   All were 50%-opacity black; sage is the client's value for this role. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-info-container,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-info-info-block,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-info-date-container,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-info-date,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-review-info-caption,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-caption,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-text-shortener-control {
	color: var(--c-sage) !important;
}

/* "AI-Generated Summary" ships purple — a colour that appears nowhere in the
   supplied palette. The mockup renders it dark teal (sampled #10262B against
   #090A09 for the reviewer names beside it, so it is teal on purpose and not
   just black), which is why it is teal here rather than --c-black.
   Elfsight draws it with `background-clip: text` and a transparent
   text-fill, so `color` alone does nothing — the fill and the background have
   to be reset too. */
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-author-name,
body .elfsight-app-ddf1108a-5205-40ae-aa09-bf2fcab7dec1 .es-ai-summary-author-name .es-review-author-name {
	background-image: none !important;
	color: var(--c-teal) !important;
	-webkit-text-fill-color: var(--c-teal) !important;
}

/* --------------------------------------------------------------------------
   Add-to-cart confirmation — white text on the green bar
   --------------------------------------------------------------------------
   Client: "Make the text white where it says it's been added to your cart."

   The bar is green because the site's DB-stored Additional CSS carries
   `.single-product .woocommerce-message { background-color: #5e7775; border: 0 }`.
   That same inline block DOES set `color: #fff` — but only on
   `.single-product .woocommerce-message .message-inner`, and that element is
   not reliably present. Shoptimizer's `wc_add_to_cart_message_html` filter
   (inc/woocommerce/template-functions/pdp.php) wraps the notice in
   `.message-inner > .message-content`, and on production the filter was NOT
   applying — the text rendered as a bare child of `.woocommerce-message`:

       <div class="woocommerce-message" role="alert" tabindex="-1">
         "…" has been added to your cart.
         <a href="/cart/" class="button wc-forward">View Cart</a>
       </div>

   So the white had nothing to land on, and the generic
   `.woocommerce-message { color: var(--c-black) }` above (l.400) won instead.
   Staging renders WITH `.message-inner` and production WITHOUT it, from the
   same theme — which is why this looked inconsistent between the two.

   Both shapes are therefore named below, so the rule holds whichever the
   filter produces.

   Contrast, measured on the real bar (#5E7775):
     before  #030303  4.29:1  — under the 4.5:1 AA bar
     after   #FFFFFF  4.80:1  — passes
   So this is a small accessibility gain, not just a preference.

   `:not(.button)` keeps "View Cart" on the button standard from
   theme-buttons.css rather than bleaching its label. Specificity is (0,2,1)
   against the inline block's (0,2,0), which is what lets this win despite the
   DB CSS loading after every theme stylesheet — no !important needed.
   -------------------------------------------------------------------------- */
body.single-product .woocommerce-message,
body.single-product .woocommerce-message .message-inner,
body.single-product .woocommerce-message .message-content,
body.single-product .woocommerce-message a:not(.button) {
	color: #FFFFFF;
}

/* --------------------------------------------------------------------------
   Notice LINKS follow their own notice's background
   --------------------------------------------------------------------------
   Client: checkout validation text was unreadable — "Billing State is a
   required field." with the field name invisible.

   Cause: the parent theme paints every notice link white —

       .woocommerce-error a, .woocommerce-info a, .woocommerce-message a,
       .woocommerce-noreviews a, p.no-comments a { color: #fff }      (0,1,1)

   — which was right when Shoptimizer's notices were all dark. theme-brand.css
   (l.400-417) repainted `.woocommerce-error` and `.woocommerce-message` onto
   the light stone `--c-stone`, but that anchor rule was never revisited.

   It only shows on VALIDATION errors because WooCommerce wraps the offending
   field's name in an anchor for click-to-focus —
   `<strong><a href="#billing_state">Billing State</a></strong>` — so the field
   name goes white while the rest of the sentence stays black. That is why it
   reads as a half-invisible message rather than a missing one, and why it does
   not reproduce with hand-written `<strong>` markup.

   Measured on the live cart/checkout:

     | notice                          | background | text    | link      |
     |---------------------------------|------------|---------|-----------|
     | .woocommerce-error              | #EAE6E1    | #030303 | #FFFFFF ✗ |
     | .woocommerce-message (cart)     | #EAE6E1    | #030303 | #FFFFFF ✗ |
     | .woocommerce-info (login bar)   | #5E7775    | #FFFFFF | #FFFFFF ✓ |

   White on #EAE6E1 is **1.24:1**. Black is **16.60:1**.

   NOT a blanket darkening — two link sets must stay white, and both are on a
   green bar: `.woocommerce-info` ("Returning customer? / Click here to login")
   and `.woocommerce-message` on a single-product page (the add-to-cart bar,
   handled in the block above). Hence `.woocommerce-info` is untouched here and
   the message rule carries `body:not(.single-product)`.

   `:not(.button)` throughout so "View Cart" and friends keep the button
   standard from theme-buttons.css. Hover goes teal rather than matching the
   resting colour, so the link still reads as a link.
   -------------------------------------------------------------------------- */
body .woocommerce-error a:not(.button),
body:not(.single-product) .woocommerce-message a:not(.button) {
	color: var(--c-black);
}

body .woocommerce-error a:not(.button):hover,
body:not(.single-product) .woocommerce-message a:not(.button):hover {
	color: var(--c-teal);
}
