/* AUTOBOSS Sticky Picker – ported from gooek-product-page 0.1.0 (Gooek, in-house): shared modal,
   specification picker and the Blocksy floating-bar layout (AUTOOL sticky add-to-cart export).
   Localized for AUTOBOSS: abspk prefix, tokens mapped to the Blocksy palette, and the picker is a
   bottom sheet at every width (centred dialogs removed on request). */

:root {
	--abspk-ink: var(--theme-palette-color-4, #212529);
	--abspk-text: var(--theme-text-color, #576471);
	--abspk-muted: var(--theme-palette-color-3, #576471);
	--abspk-brand: var(--theme-palette-color-2, #fdb016);
	--abspk-border: var(--theme-palette-color-5, #e6eaec);
	--abspk-surface: #fff;
	--abspk-surface-alt: var(--theme-palette-color-7, #f9fafb);
	--abspk-sheet-width: 640px;
	--abspk-radius: 12px;
}

/* ---------------------------------------------------------------------------
 * Shared modal -- one overlay reused by Key Features (and, later, B2B and
 * Reviews). The preset lands on the overlay as data-style.
 * ------------------------------------------------------------------------- */
.abspk-modal-open,
.abspk-modal-open body {
	overflow: hidden;
}
/* The overlay is created by our JS as a direct child of <body>; the
   abspk-modal-* prefix is ours alone, so these rules can only ever match it. */
.abspk-modal {
	position: fixed;
	inset: 0;
	z-index: 100000;
	display: flex;
	padding: 20px;
	background: rgba(15, 18, 22, 0.55);
	opacity: 0;
	transition: opacity 0.22s ease;
}
.abspk-modal[hidden] {
	display: none;
}
.abspk-modal.is-open {
	opacity: 1;
}
.abspk-modal__panel {
	display: flex;
	flex-direction: column;
	width: min(560px, 100%);
	max-height: min(80vh, 720px);
	margin: auto;
	overflow: hidden;
	border-radius: 10px;
	background: var(--abspk-surface, #fff);
	box-shadow: 0 24px 60px rgba(15, 18, 22, 0.28);
	transform: translateY(12px);
	transition: transform 0.24s ease;
}
.abspk-modal.is-open .abspk-modal__panel {
	transform: none;
}
.abspk-modal__panel:focus {
	outline: none;
}
.abspk-modal__header {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 18px 20px;
	border-bottom: 1px solid var(--abspk-border, #e2e8f0);
}
.abspk-modal__title {
	margin: 0;
	color: var(--abspk-ink, #1a1a1a);
	font-family: var(--abspk-display-font, inherit);
	font-size: 16px;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: 0.02em;
}
.abspk-modal__title[hidden] {
	display: none;
}
.abspk-modal__close {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	min-height: 36px;
	padding: 0;
	border: 1px solid var(--abspk-border, #e2e8f0);
	border-radius: 50%;
	background: transparent;
	box-shadow: none;
	color: var(--abspk-ink, #1a1a1a);
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}
.abspk-modal__close:hover,
.abspk-modal__close:focus-visible {
	border-color: var(--abspk-ink, #1a1a1a);
	background: var(--abspk-surface-alt, #f7f8fa);
}
.abspk-modal__body {
	flex: 1 1 auto;
	padding: 18px 20px 22px;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	color: var(--abspk-text, #33373d);
	font-size: 14px;
	line-height: 1.65;
}
.abspk-modal__body > div > *:first-child { margin-top: 0; }
.abspk-modal__body > div > *:last-child { margin-bottom: 0; }
.abspk-modal__body img {
	max-width: 100%;
	height: auto;
}

/* --- Modal preset: centered glass card (default) -------------------------- */
.abspk-modal[data-style="center-glass"] .abspk-modal__panel {
	border: 1px solid rgba(255, 255, 255, 0.5);
	border-radius: 14px;
	background: rgba(255, 255, 255, 0.94);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
}

/* --- Modal preset: slide in from the right -------------------------------- */
.abspk-modal[data-style="slide-right"] {
	padding: 0;
}
.abspk-modal[data-style="slide-right"] .abspk-modal__panel {
	width: min(460px, 100%);
	max-height: none;
	height: 100%;
	margin: 0 0 0 auto;
	border-radius: 0;
	transform: translateX(24px);
}
.abspk-modal[data-style="slide-right"].is-open .abspk-modal__panel {
	transform: none;
}

/* --- Modal preset: bottom sheet ------------------------------------------- */
.abspk-modal[data-style="bottom-sheet"] {
	padding: 0;
}
.abspk-modal[data-style="bottom-sheet"] .abspk-modal__panel {
	width: 100%;
	max-height: 82vh;
	margin: auto 0 0;
	border-radius: 16px 16px 0 0;
	transform: translateY(24px);
}
.abspk-modal[data-style="bottom-sheet"].is-open .abspk-modal__panel {
	transform: none;
}

/* --- Modal preset: minimal ------------------------------------------------ */
.abspk-modal[data-style="minimal"] {
	background: rgba(15, 18, 22, 0.35);
}
.abspk-modal[data-style="minimal"] .abspk-modal__panel {
	border: 1px solid var(--abspk-border, #e2e8f0);
	border-radius: 2px;
	box-shadow: none;
}
.abspk-modal[data-style="minimal"] .abspk-modal__header {
	padding-bottom: 12px;
}

/* Small screens: the centered presets become sheets so the panel never exceeds
   the viewport or hides its close control behind browser chrome. The drawer
   preset keeps its own full-height rule (higher specificity) -- a full-screen
   drawer is the expected phone mapping for it. */
@media (max-width: 689.98px) {
	.abspk-modal {
		padding: 0;
	}
	.abspk-modal .abspk-modal__panel {
		width: 100%;
		max-height: 86vh;
		height: auto;
		margin: auto 0 0;
		border-radius: 14px 14px 0 0;
	}
}


/* --- Specification picker -------------------------------------------------
   The real options form is moved into the shared modal, so these rules dress a
   node that normally lives in the product summary. Everything is scoped to the
   .abspk-spec-picker overlay class, which only this module sets, so the
   in-page form is never affected. */
.abspk-modal.abspk-spec-picker .abspk-modal__body {
	padding-bottom: 0;
}

/* The moved form drives the panel's layout: options scroll, the price and the
   real Add-to-Cart button stay reachable at the foot. */
.abspk-spec-picker .abspk-modal__body > .abspk-sheet-product > form.cart,
.abspk-spec-picker .abspk-modal__body > form.cart {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 0;
}

/* WooCommerce's own wrapper around price + quantity + submit. Sticky rather
   than fixed, so a long option list scrolls underneath it without the button
   ever leaving the viewport. */
.abspk-spec-picker .single_variation_wrap,
.abspk-spec-picker .woocommerce-variation-add-to-cart,
.abspk-spec-picker .ct-cart-actions {
	position: sticky;
	bottom: 0;
	z-index: 1;
	background: var(--abspk-surface, #fff);
}
.abspk-spec-picker .single_variation_wrap {
	/* Clears the body's own side padding so the sticky band spans the panel. */
	margin: 0 -20px;
	padding: 12px 20px calc(16px + env(safe-area-inset-bottom, 0px));
	box-shadow: 0 -8px 20px -12px rgba(15, 18, 22, 0.35);
}

/* Simple products (opt-in) have no variation wrapper; their form.cart carries
   the quantity and button directly. */
.abspk-spec-picker .abspk-sheet-product > form.cart:not(.variations_form) > .ct-cart-actions,
.abspk-spec-picker .abspk-modal__body > form.cart:not(.variations_form) > .ct-cart-actions {
	margin: 0 -20px;
	padding: 12px 20px calc(16px + env(safe-area-inset-bottom, 0px));
	box-shadow: 0 -8px 20px -12px rgba(15, 18, 22, 0.35);
}

/* Touch targets. The bar is most often used on a phone. Two deliberate
   omissions: the Add-to-Cart button, because Blocksy owns its paint and height
   (it already clears 44px, and the smoke guard only permits inline-axis
   geometry here), and the quantity field, which now inherits the purchase
   area's own stepper sizing -- see the shared quantity block above, whose
   selectors cover this dialog and the floating bar. */
.abspk-spec-picker .abspk-variation-card {
	min-height: 44px;
}
.abspk-spec-picker .single_add_to_cart_button {
	width: 100%;
}

/* The price-based-country pair wraps every price in span._abspk_none_ and fills
   it by AJAX; it is briefly empty. Reserve the line so the sticky band does not
   jump when the real price lands. */
.abspk-spec-picker .woocommerce-variation-price {
	min-height: 1.5em;
}

/* Options area: let a many-attribute product scroll rather than push the
   button off the panel. */
.abspk-spec-picker .variations {
	margin-bottom: 0;
}

/* On the sheet, give the grabbable top edge a little more room. */
.abspk-modal[data-style="bottom-sheet"].abspk-spec-picker .abspk-modal__panel {
	max-height: 88vh;
}

/* Placeholder price, shown only inside the picker while nothing is chosen.
   It is rendered into the product form with the page (so the country-based
   currency lookup fills it on its single pass), which means it also travels
   into the in-page purchase area -- where Blocksy already prints a price. Hence
   hidden by default and revealed only inside the dialog. */
.abspk-picker-price {
	display: none;
}
.abspk-spec-picker .abspk-picker-price:not(.is-hidden) {
	display: block;
	margin: 0 0 4px;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--abspk-ink);
}
.abspk-spec-picker .abspk-picker-price .from {
	margin-right: 4px;
	font-size: 13px;
	font-weight: 500;
	opacity: 0.75;
}
/* Never let the currency plugin's placeholder collapse the line or hide the
   text permanently inside the dialog. */
.abspk-spec-picker .abspk-picker-price ._abspk_none_ {
	visibility: visible !important;
}

/* --- Specification picker: price beside the button ------------------------
   The placeholder price belongs with the money control, not above the quantity
   stepper. Both rows live inside .single_variation_wrap, so the price is
   right-aligned over the Add-to-Cart row. */
.abspk-spec-picker .abspk-picker-price:not(.is-hidden) {
	text-align: right;
}
.abspk-spec-picker .single_variation_wrap {
	display: flex;
	flex-direction: column;
}
/* WooCommerce's own resolved price sits in the same slot, aligned the same. */
.abspk-spec-picker .woocommerce-variation-price {
	text-align: right;
}



/* --- Sticky purchase bar ---------------------------------------------------
   Implemented 1:1 from the AUTOOL export package
   (autoGenFile/docs/autool-sticky-add-to-cart-export-20260807-en.zip,
   assets/css/sticky-add-to-cart.css), which is the authoritative spec rather
   than anything measured off a screenshot.

   Deliberately NOT copied, per instruction: colours, corner radius and button
   appearance. Those keep the site's palette, the site's radius token and the
   purchase-area button styling. Everything structural -- the grid templates,
   action widths, gaps, heights, typography scale and the mobile two-row
   layout -- follows the export exactly.

   Blocksy structure: .ct-drawer-canvas > .ct-drawer-inner > .ct-floating-bar >
   .ct-container > .ct-floating-bar-content + .ct-floating-bar-actions.
   ------------------------------------------------------------------------- */

.abspk-has-atc {
	/* export: clamp(128px, 14vw, 184px) -- 184px at 1440, narrowing on smaller
	   desktops instead of wrapping. */
	--abspk-sticky-action-width: clamp(128px, 14vw, 184px);
	/* export drives this from the theme's own button token, so the bar's
	   actions inherit the site's button height rather than the reference's. */
	--abspk-sticky-action-height: var(--theme-button-min-height, 48px);
}

/* Thumbnail and stepper removal, per the configured tier. */
.abspk-stickyimg-always .ct-floating-bar .ct-media-container,
.abspk-stickyimg-always .ct-floating-bar .ct-image-container {
	display: none !important;
}
.abspk-stickyqty-always .ct-floating-bar .quantity {
	display: none !important;
}

/* export: sections are flex rows and their paragraphs carry no margin. */
/* export: the desktop container centres its two sections. */
.abspk-has-atc .ct-floating-bar .ct-container {
	align-items: center;
}
.abspk-has-atc .ct-floating-bar section {
	display: flex;
	align-items: center;
}
.abspk-has-atc .ct-floating-bar section p {
	margin: 0;
}

/* export: .ct-floating-bar-content { min-width: 0; gap: 15px } */
.abspk-has-atc .ct-floating-bar-content {
	min-width: 0;
	gap: 15px;
}

/* export: fixed 40x40 thumbnail that never shrinks. Radius left to our token. */
.abspk-has-atc .ct-floating-bar .ct-media-container {
	display: inline-flex !important;
	flex: 0 0 40px;
	width: 40px;
	height: 40px;
	overflow: hidden;
}
.abspk-has-atc .ct-floating-bar .ct-media-container img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* export: title block takes the free space; the title is one ellipsised line. */
.abspk-has-atc .ct-floating-bar .ct-floating-bar-item-title {
	flex: 1;
	min-width: 0;
}
.abspk-has-atc .ct-floating-bar .product-title {
	overflow: hidden;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.35;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* export: price is a wrapping flex row at 12px/500 with a 0.5em column gap.
   Our markup nests <p class="price"> inside .product-price where the export
   element carries the text itself, so the scale is applied to both. */
.abspk-has-atc .ct-floating-bar .product-price,
.abspk-has-atc .ct-floating-bar .product-price .price {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	column-gap: 0.5em;
	font-size: 12px;
	font-weight: 500;
}

/* export: actions sit right, 10px apart, and stretch to a common height --
   which is what keeps the stepper and the buttons the same size. */
.abspk-has-atc .ct-floating-bar-actions {
	justify-content: flex-end;
	align-items: stretch;
	min-width: 0;
	gap: 10px;
}

/* export: three tracks when the stepper shows -- stepper, then two actions --
   collapsing to two when it is hidden. */
.abspk-sticky-equal-actions .ct-floating-bar-actions {
	display: grid !important;
	align-items: stretch !important;
	grid-template-columns:
		minmax(calc((44px * 2) + 64px), auto)
		minmax(0, var(--abspk-sticky-action-width))
		minmax(0, var(--abspk-sticky-action-width));
}
.abspk-stickyqty-always.abspk-sticky-equal-actions .ct-floating-bar-actions,
.abspk-sticky-equal-actions .ct-floating-bar-actions:not(:has(> .quantity)) {
	grid-template-columns: repeat(2, minmax(0, var(--abspk-sticky-action-width)));
}
/* With a single action there is no pair to balance: keep it content-sized and
   right-aligned rather than stretched across the bar. */
.abspk-sticky-equal-actions .ct-floating-bar-actions:not(:has([data-abspk-modal-trigger], .abspk-sticky-action2)) {
	grid-template-columns: max-content !important;
	justify-content: flex-end !important;
}

/* export: stepper is 152x44 with 44px steppers around a 64px field. */
.abspk-has-atc .ct-floating-bar-actions > .quantity {
	box-sizing: border-box;
	width: 152px;
	min-height: 44px;
}

/* Action metrics from the export; appearance stays ours. */
.abspk-has-atc .ct-floating-bar-actions > .button,
.abspk-has-atc .ct-floating-bar-actions > .added_to_cart,
.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-width: 0;
	min-height: var(--abspk-sticky-action-height);
	margin: 0;
	overflow: hidden;
	line-height: 1.1;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The quote action is a link; give it the outlined counterpart of our own
   primary button so the pair reads as one control group. */
.abspk-has-atc .ct-floating-bar .autool-sticky-quote,
.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger] {
	min-width: 0;
	margin: 0;
}
.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger] {
	padding: 5px 18px;
	/* The trigger picks up an uppercase transform from its own module styles;
	   inside the bar it must read as the sibling of our Add-to-Cart button. */
	text-transform: none;
	border: 1px solid var(--abspk-ink);
	background: transparent;
	color: var(--abspk-ink);
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.15px;
	text-decoration: none;
}
.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger]:hover,
.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger]:focus-visible {
	border-color: var(--abspk-brand);
	color: var(--abspk-brand);
}

/* export: theme pseudo-element decorations are suppressed inside the bar. */
.abspk-has-atc .ct-floating-bar-actions > :is(.button, .added_to_cart)::before,
.abspk-has-atc .ct-floating-bar-actions > :is(.button, .added_to_cart)::after {
	display: none !important;
	content: none !important;
}

/* --- Sticky purchase bar: mobile ------------------------------------------
   export @media (max-width: 689.98px) */
@media (max-width: 689.98px) {
	.abspk-stickyimg-mobile .ct-floating-bar .ct-media-container,
	.abspk-stickyimg-mobile .ct-floating-bar .ct-image-container {
		display: none !important;
	}
	.abspk-stickyqty-mobile .ct-floating-bar .quantity {
		display: none !important;
	}

	/* Blocksy reserves page space from this variable and pins the bar to it, so
	   the taller two-row bar has to raise it or it would cover the content it
	   sits above. The export ships the same 89px. */
	/* 8 top + 22 meta row + 8 gap + action height + 8 bottom + 1 hairline.
	   Derived rather than hard-coded so it cannot drift from the action
	   height, which follows the site's own button token. */
	.abspk-has-atc .ct-drawer-canvas[data-floating-bar] {
		--floating-bar-height: calc(47px + var(--abspk-sticky-action-height, 48px));
		--floating-bar-parent-height: var(--floating-bar-height);
	}
	.abspk-has-atc .ct-drawer-canvas[data-location="end"] .ct-drawer-inner {
		top: auto;
		bottom: 0;
		height: auto;
		min-height: 0;
		inset-inline: 0;
	}

	/* export: auto height, 8px/12px padding plus the safe area, no shadow, and
	   a blurred translucent surface. The surface colour stays ours; only its
	   alpha treatment and the blur come from the export. */
	.abspk-has-atc .ct-floating-bar {
		position: relative;
		display: flex;
		align-items: center;
		height: auto;
		min-height: 0;
		padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
		border-top: 1px solid var(--abspk-border);
		background: color-mix(in srgb, var(--abspk-surface, #fff) 96%, transparent);
		box-shadow: none;
		backdrop-filter: blur(16px);
		-webkit-backdrop-filter: blur(16px);
	}
	/* export: paints the safe-area strip below the bar so it never shows through. */
	.abspk-has-atc .ct-floating-bar::after {
		position: absolute;
		inset-inline: 0;
		bottom: calc(-1 * max(2px, env(safe-area-inset-bottom, 0px)));
		height: max(2px, env(safe-area-inset-bottom, 0px));
		background: var(--abspk-surface, #fff);
		content: "";
		pointer-events: none;
	}

	/* export: container becomes a full-width column with an 8px gap. */
	/* export: column layout with an 8px gap. The export ships width:100% for a
	   standalone page, but the live bar it reproduces uses the theme container --
	   measured at exactly 90vw, centred: 360->324, 390->351, 430->387, 600->540.
	   That formula is used here so the inset matches at every width rather than
	   only at 390px. */
	.abspk-has-atc .ct-floating-bar .ct-container {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 8px;
		width: min(100%, 90vw);
		height: auto;
		margin-inline: auto;
		padding: 0;
	}

	/* export: content row is space-between at 16px (the reference's meta row);
	   ours carries the title and price directly. */
	.abspk-has-atc .ct-floating-bar .ct-floating-bar-content {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		width: 100%;
		min-width: 0;
	}
	.abspk-has-atc .ct-floating-bar .ct-floating-bar-item-title {
		display: flex;
		flex: 1 1 auto;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		min-width: 0;
	}
	/* export: 11px/700, 0.08em tracking, uppercase, single ellipsised line. */
	.abspk-has-atc .ct-floating-bar .product-title {
		flex: 1 1 auto;
		min-width: 0;
		margin: 0;
		overflow: hidden;
		font-size: 11px;
		font-weight: 700;
		line-height: 1.2;
		letter-spacing: 0.08em;
		text-overflow: ellipsis;
		text-transform: uppercase;
		white-space: nowrap;
	}
	/* export: 22px/800, line-height 1, never shrinking. */
	.abspk-has-atc .ct-floating-bar .product-price,
	.abspk-has-atc .ct-floating-bar .product-price .price {
		flex: 0 0 auto;
		margin: 0;
		column-gap: 0.5em;
		font-size: 22px;
		font-weight: 800;
		line-height: 1;
		text-align: right;
		white-space: nowrap;
	}
	.abspk-has-atc .ct-floating-bar .product-price del {
		font-size: 0.8em;
		opacity: 0.65;
	}
	.abspk-has-atc .ct-floating-bar .product-price ins {
		text-decoration: none;
	}
	.abspk-has-atc .ct-floating-bar .product-price .stock {
		display: none;
	}

	/* export: two equal tracks, 8px apart, full width. */
	.abspk-sticky-equal-actions .ct-floating-bar-actions {
		display: grid !important;
		align-items: stretch !important;
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
		gap: 8px;
		width: 100%;
	}
	/* A lone action still does not stretch across the bar. */
	.abspk-sticky-equal-actions .ct-floating-bar-actions:not(:has([data-abspk-modal-trigger], .abspk-sticky-action2)) {
		grid-template-columns: max-content !important;
		justify-content: flex-end !important;
	}
	.abspk-has-atc .ct-floating-bar-actions > .button,
	.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger] {
		padding-inline: 12px;
	}
}

/* export @media (max-width: 389.98px): tighter action gap. */
@media (max-width: 389.98px) {
	.abspk-has-atc .ct-floating-bar-actions {
		gap: 7px !important;
	}
	.abspk-has-atc .ct-floating-bar-actions > .button,
	.abspk-has-atc .ct-floating-bar-actions [data-abspk-modal-trigger] {
		padding-inline: 10px;
	}
}

/* export: motion opt-out. */
@media (prefers-reduced-motion: reduce) {
	.abspk-has-atc .ct-drawer-canvas[data-location="end"] .ct-drawer-inner,
	.abspk-has-atc .ct-floating-bar {
		transition: none;
	}
}

/* --- Sticky bar + picker: price treatment ---------------------------------
   The site styles every price globally: `.sale-price del {order:2; opacity:.7}`
   pushes the original to the right, `.price del` greys it and `.price ins`
   paints the current one in the sale colour. The export's bar does none of
   that -- it renders both halves in one colour at one weight, the original
   simply smaller and struck. These rules restore that inside the bar and the
   popup only, leaving every other price on the site alone.

   Colours follow the export's own tokens rather than literal values, so they
   resolve to this theme: --theme-text-color in the bar's desktop row and
   --theme-headings-color for the large mobile/popup price, exactly as
   `--autool-sticky-text` and `--autool-sticky-ink` do in the export.
   ------------------------------------------------------------------------- */
.abspk-has-atc .ct-floating-bar .product-price {
	color: var(--theme-text-color, var(--abspk-ink));
}
/* export: the bar shows a price, never a stock line. */
.abspk-has-atc .ct-floating-bar .product-price .stock,
.abspk-has-atc .ct-floating-bar .ct-floating-bar-content .stock {
	display: none !important;
}
.abspk-has-atc .ct-floating-bar .product-price :is(.price, .amount, bdi, ins, del, .sale-price, ._abspk_none_) {
	color: inherit;
	font-weight: inherit;
}

/* Order differs by context, on request:
     desktop bar - current price first, original after  (the export order)
     mobile bar  - original first, current after
     popup       - original first, current after
   The mobile and popup rules live in their own blocks further down. */
.abspk-has-atc .ct-floating-bar .product-price :is(del, .sale-price del) {
	order: 2;
	font-size: 0.8em;
	text-decoration: line-through;
}
.abspk-has-atc .ct-floating-bar .product-price :is(ins, .sale-price ins) {
	order: 1;
	text-decoration: none;
}
.abspk-spec-picker .abspk-picker-price :is(del, .sale-price del),
.abspk-spec-picker .woocommerce-variation-price :is(del, .sale-price del) {
	order: 1;
	opacity: 1;
	font-size: 0.8em;
	text-decoration: line-through;
}
.abspk-spec-picker .abspk-picker-price :is(ins, .sale-price ins),
.abspk-spec-picker .woocommerce-variation-price :is(ins, .sale-price ins) {
	order: 2;
	text-decoration: none;
}
/* The wrappers have to be flex for `order` to mean anything. */
.abspk-has-atc .ct-floating-bar .product-price .sale-price,
.abspk-spec-picker .abspk-picker-price .sale-price,
.abspk-spec-picker .woocommerce-variation-price .sale-price {
	display: inline-flex;
	align-items: baseline;
	column-gap: 0.5em;
}



/* --- Specification picker: price only ------------------------------------
   The popup is a purchase step, not a spec sheet: the description, stock line
   and SKU are noise there. Only the price remains, above the Add-to-Cart row.
   ------------------------------------------------------------------------- */
.abspk-spec-picker .woocommerce-variation-description,
.abspk-spec-picker .woocommerce-variation-availability,
.abspk-spec-picker .stock,
.abspk-spec-picker .sku_wrapper,
.abspk-spec-picker .product_meta {
	display: none !important;
}

/* The resolved variation price gets the same treatment as the placeholder:
   large, ink, right-aligned, sitting directly above the button. */
.abspk-spec-picker .woocommerce-variation-price,
.abspk-spec-picker .woocommerce-variation-price :is(.price, .amount, bdi, ins, del, .sale-price, ._abspk_none_),
.abspk-spec-picker .abspk-picker-price,
.abspk-spec-picker .abspk-picker-price :is(.price, .amount, bdi, ins, del, .sale-price, ._abspk_none_) {
	color: var(--theme-headings-color, var(--abspk-ink));
}
/* Milestone 3 hides the in-form variation price while the summary mirrors it
   (`.abspk-price-sync-active`). Inside the popup there is no summary to
   mirror it, so the price has to come back -- and it is the only thing left in
   that row now that the description, stock and SKU are gone. */
.abspk-modal.abspk-spec-picker .woocommerce-variation-price {
	display: block !important;
}
.abspk-spec-picker .woocommerce-variation-price .price {
	display: flex;
	align-items: baseline;
	justify-content: flex-end;
	column-gap: 0.5em;
	margin: 0;
	font-size: 18px;
	font-weight: 700;
	line-height: 1.3;
}

/* export: the large mobile price is the heading colour with .04em tracking,
   not the smaller desktop row's text colour. */
@media (max-width: 689.98px) {
	.abspk-has-atc .ct-floating-bar .product-price {
		color: var(--theme-headings-color, var(--abspk-ink));
		letter-spacing: 0.04em;
	}
	.abspk-has-atc .ct-floating-bar .product-price :is(.price, .amount, bdi, ins, del, .sale-price, ._abspk_none_) {
		color: inherit;
		font-weight: inherit;
		letter-spacing: inherit;
	}
	/* Keep the row a single line with the two halves side by side. */
	.abspk-has-atc .ct-floating-bar .product-price .price {
		display: flex;
		align-items: baseline;
		justify-content: flex-end;
		column-gap: 0.5em;
	}
}

/* --- Sticky bar: mobile price order and struck original -------------------
   Mobile puts the original first, ahead of the current price (desktop keeps
   the export's order, current first). The struck original also takes the
   product summary's own treatment rather than the bar's ink: the same muted
   token, weight and fade the price block uses, so the two read alike.
   ------------------------------------------------------------------------- */
@media (max-width: 689.98px) {
	.abspk-has-atc .ct-floating-bar .product-price :is(del, .sale-price del) {
		order: 1;
	}
	.abspk-has-atc .ct-floating-bar .product-price :is(ins, .sale-price ins) {
		order: 2;
	}
	/* Matches `.entry-summary .price del`: muted, regular weight, 0.7 opacity. */
	.abspk-has-atc .ct-floating-bar .product-price :is(del, del .amount, del bdi, del .woocommerce-Price-currencySymbol) {
		color: var(--abspk-muted, #6e7c88);
		font-weight: 400;
		opacity: 0.7;
	}
}

/* --- Specification picker: price sizing and load state --------------------
   Scale taken from the sticky bar's own primary price (22px/800 with the
   struck original at 0.8em), so the two purchase surfaces read alike -- the
   popup's 18px was noticeably smaller than the bar it opens from.

   The theme also puts a 20px bottom margin on every `p.price`, which is a body
   -copy rhythm, not a control-group one. Replaced with a measured 10px so the
   price sits with the Add-to-Cart row rather than floating above it.
   ------------------------------------------------------------------------- */
/* Scale on the text, spacing on the block. The theme gives every `p.price` a
   20px body-copy margin; zeroing it on the inner elements and owning the gap
   on the wrapper keeps the price visually tied to the button below it. */
.abspk-modal.abspk-spec-picker .woocommerce-variation-price .price,
.abspk-modal.abspk-spec-picker .woocommerce-variation-price p,
.abspk-modal.abspk-spec-picker .abspk-picker-price p {
	margin: 0 !important;
}
.abspk-spec-picker .woocommerce-variation-price .price,
.abspk-spec-picker .abspk-picker-price:not(.is-hidden) {
	font-size: 22px;
	font-weight: 800;
	line-height: 1.2;
}
/* One measured gap between the price and the Add-to-Cart row. */
.abspk-modal.abspk-spec-picker .woocommerce-variation-price,
.abspk-modal.abspk-spec-picker .abspk-picker-price:not(.is-hidden) {
	margin: 0 0 12px !important;
}
.abspk-spec-picker .woocommerce-variation-price :is(del, .sale-price del),
.abspk-spec-picker .abspk-picker-price :is(del, .sale-price del) {
	font-size: 0.8em;
}

/* The struck original takes the summary price block's muted treatment here
   too, matching the sticky bar. */
.abspk-spec-picker .woocommerce-variation-price :is(del, del .amount, del bdi, del .woocommerce-Price-currencySymbol),
.abspk-spec-picker .abspk-picker-price :is(del, del .amount, del bdi, del .woocommerce-Price-currencySymbol) {
	color: var(--abspk-muted, #6e7c88);
	font-weight: 400;
	opacity: 0.7;
}

/* Load state: the currency plugin ships prices as `visibility: hidden` behind
   an animated placeholder until its lookup returns. Inside the dialog that
   reads as a missing price, so the value is always shown and the placeholder
   never is. spec-picker.js also strips the class; this is the half that works
   with JavaScript disabled. */
.abspk-spec-picker ._abspk_none_,
.abspk-spec-picker ._abspk_none_.loading {
	visibility: visible !important;
	display: inline !important;
}
.abspk-spec-picker .wcpbc-placeholder {
	display: none !important;
}

/* Reserve the row so a late-arriving price cannot shift the button under the
   visitor's finger. */
.abspk-spec-picker .woocommerce-variation-price {
	min-height: 27px;
}

@media (min-width: 1000px) {
	.abspk-no-sticky-desktop .ct-floating-bar { display: none !important; }
}
@media (min-width: 690px) and (max-width: 999.98px) {
	.abspk-no-sticky-tablet .ct-floating-bar { display: none !important; }
}
@media (max-width: 689.98px) {
	.abspk-no-sticky-mobile .ct-floating-bar { display: none !important; }
}



/* ---------------------------------------------------------------------------
 * AUTOBOSS: bottom sheet at every width
 * The picker always rises from the bottom. On wide screens the sheet keeps a readable width and is
 * centred horizontally; the corner radius follows the Taobao button radius (12).
 * ------------------------------------------------------------------------- */
.abspk-modal[data-style="bottom-sheet"] {
	padding: 0;
}
.abspk-modal[data-style="bottom-sheet"] .abspk-modal__panel {
	width: min(var(--abspk-sheet-width), 100%);
	max-height: min(88vh, 88dvh);
	margin: auto auto 0;
	border-radius: 16px 16px 0 0;
	transform: translateY(100%);
	transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.abspk-modal[data-style="bottom-sheet"].is-open .abspk-modal__panel {
	transform: none;
}
.abspk-modal__handle {
	display: block;
	width: 36px;
	height: 4px;
	margin: 8px auto 0;
	border-radius: 2px;
	background: var(--abspk-border);
}
.abspk-modal__header {
	padding-top: 12px;
}
.abspk-spec-picker .single_add_to_cart_button {
	border-radius: var(--abspk-radius);
}
@media (prefers-reduced-motion: reduce) {
	.abspk-modal, .abspk-modal .abspk-modal__panel { transition: none !important; }
}

/* Wrapper that gives Blocksy's swatch script its `.product` ancestor inside the sheet. */
.abspk-sheet-product { display: block; margin: 0; padding: 0; }

/* ---------------------------------------------------------------------------
 * AUTOBOSS: Blocksy shrinks the bar button to a 40px icon (font-size 0) below 690px. The export layout is
 * a full-width text button on its own row, so the text comes back and a lone action spans the row.
 * Buttons use the 12px radius shared with the Taobao-style pages.
 * ------------------------------------------------------------------------- */
.abspk-has-atc .ct-floating-bar-actions > :is(.button, .added_to_cart) {
	border-radius: var(--abspk-radius);
}
@media (max-width: 689.98px) {
	.abspk-has-atc .ct-floating-bar-actions :is(.added_to_cart, .single_add_to_cart_button, .product_type_variable.button, .button) {
		min-width: 0;
		max-width: none;
		min-height: 44px;
		font-size: 15px !important;
		--theme-button-padding: 0 12px;
	}
	.abspk-has-atc .ct-floating-bar-actions :is(.added_to_cart, .single_add_to_cart_button, .product_type_variable.button):after {
		content: none !important;
	}
	.abspk-sticky-equal-actions .ct-floating-bar-actions:not(:has(.abspk-sticky-action2)) {
		grid-template-columns: minmax(0, 1fr) !important;
		justify-content: stretch !important;
	}
}

/* Simple products: price above the quantity + button row, right-aligned like the variable case. */
.abspk-spec-picker form.cart:not(.variations_form) .ct-cart-actions { flex-wrap: wrap; }
.abspk-spec-picker .abspk-picker-price--simple:not(.is-hidden) { flex: 0 0 100%; margin: 0 0 12px; text-align: right; font-size: 22px; font-weight: 800; line-height: 1.2; color: var(--theme-headings-color, var(--abspk-ink)); }
.abspk-spec-picker .abspk-picker-price--simple p { margin: 0; }

/* Keep the form visible through the closing animation, but stop further submissions. */
.abspk-modal.is-closing { pointer-events: none; }
.abspk-spec-picker .single_add_to_cart_button.loading { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.abspk-spec-picker .single_add_to_cart_button.loading::before { content: ""; display: inline-block; flex: none; width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: abspk-loading-spin .7s linear infinite; }
@keyframes abspk-loading-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .abspk-spec-picker .single_add_to_cart_button.loading::before { animation: none; } }
