/**
 * Build-a-box / mix & match (Pro) — styling.
 *
 * A full-width grid of product cards with quantity steppers, a "N of M added"
 * meter and a progress bar that turns complete-green when the box is full.
 * Reads the configurator's --bb-* tokens so it brands with everything else.
 */

.bb-box {
	margin-top: 4px;
	/* Clearance so the last grid row can sit above the docked sticky summary
	   bar (~80px tall) instead of tucking behind it. The compact grid rows
	   otherwise have too little room below them, unlike the tall list items. */
	padding-bottom: 72px;
}

/* A question asked under the items (the slot's own personalisation) already
   gives the last row its clearance, so the 72px became an empty gap between
   the cards and the question (a live shop asked to close it, Oct 2026). */
.bb-box:has( + .bb-row-asks .bb-ask-secband ) {
	padding-bottom: 12px;
}

/* Keyboard / anchored scrolling parks a card above the pinned bar, matching
   .bundle-item's clearance. */
.bb-box-card {
	scroll-margin-bottom: 96px;
}

/* Head: the "Choose 6" instruction + the live "3 / 6" meter. */
.bb-box-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 8px;
}

.bb-box-instruction {
	font-weight: 600;
	color: var(--bb-ink);
}

.bb-box-meter {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	color: var(--bb-muted);
	white-space: nowrap;
}

.bb-box-ok .bb-box-meter {
	color: var(--bb-success);
}

.bb-box-over .bb-box-meter {
	color: #b91c1c;
}

/* Progress bar. */
.bb-box-bar {
	height: 6px;
	background: var(--bb-surface-alt);
	border-radius: 3px;
	overflow: hidden;
	margin-bottom: 14px;
}

.bb-box-bar-fill {
	display: block;
	height: 100%;
	width: 0;
	background: var(--bb-accent);
	border-radius: 3px;
	transition: width 0.25s ease;
}

.bb-box-ok .bb-box-bar-fill {
	background: var(--bb-success-bright);
}

.bb-box-over .bb-box-bar-fill {
	background: #dc2626;
}

/* -----------------------------------------------------------------
   Tiered quantity-break bar: the fill track doubles as a rewards
   ladder. A marker sits at each discount tier; it lights green once
   the box fills past it and the next one up is spotlighted in the
   brand accent. The %-off shows above each marker (hidden when the
   tiers get crowded), and a single caption under the bar gives the
   active saving plus the next-tier nudge. One row for any number of
   tiers, so it never crams or leaves a mostly-empty list.
   ----------------------------------------------------------------- */
.bb-box-progress {
	margin: 6px 0 12px;
}

.bb-box-bar-tiered {
	position: relative;
	overflow: visible;      /* let the markers + %-caps sit above the thin track */
	margin: 26px 0 8px;     /* head-room for the caps above the markers */
}

.bb-box-bar-tiered.is-dense {
	margin-top: 10px;       /* many tiers: caps are hidden, so no head-room needed */
}

.bb-box-bar-tiered .bb-box-bar-fill {
	position: relative;
	z-index: 1;             /* fill sits under the markers */
}

/* A tier marker, positioned along the track by JS (left %). */
.bb-box-node {
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.bb-box-node-dot {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--bb-surface);
	border: 2px solid var(--bb-border-strong);
	box-shadow: 0 0 0 2px var(--bb-surface); /* punch a gap so the dot reads over the fill */
	transition: background 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

/* The %-off label above each marker. */
.bb-box-node-cap {
	position: absolute;
	bottom: calc(100% + 5px);
	font-size: 0.72em;
	font-weight: 700;
	line-height: 1;
	color: var(--bb-muted);
	white-space: nowrap;
	transition: color 0.15s;
}

.bb-box-bar-tiered.is-dense .bb-box-node-cap {
	display: none;
}

/* Passed tier: green dot + green cap ("unlocked"), matching the box-full tone. */
.bb-box-node.is-reached .bb-box-node-dot {
	background: var(--bb-success-bright);
	border-color: var(--bb-success-bright);
}

.bb-box-node.is-reached .bb-box-node-cap {
	color: var(--bb-success);
}

/* Next tier: the accent target — a larger dot with a soft ring to aim for. */
.bb-box-node.is-next .bb-box-node-dot {
	background: var(--bb-accent);
	border-color: var(--bb-accent);
	transform: scale(1.3);
	box-shadow: 0 0 0 2px var(--bb-surface), 0 0 0 5px var(--bb-accent-bg);
}

.bb-box-node.is-next .bb-box-node-cap {
	color: var(--bb-accent-deep, var(--bb-accent));
}

/* One concise caption under the bar: the active saving + next-tier nudge.
   Accent while there's still a tier to aim for; green once one is unlocked. */
.bb-box-reward {
	margin: 0;
	font-size: 0.88em;
	font-weight: 600;
	line-height: 1.3;
	color: var(--bb-accent-deep, var(--bb-accent));
}

.bb-box-reward:empty {
	display: none;
}

.bb-box-progress.bb-box-has-active .bb-box-reward {
	color: var(--bb-success);
}

@media ( prefers-reduced-motion: reduce ) {
	.bb-box-node-dot,
	.bb-box-bar-fill {
		transition: none;
	}
}

/* Card grid: auto-fills as many columns as fit, no sideways scroll. The
   column floor, gap and photo square read custom properties with today's
   numbers as the fallbacks; the Card size classes only set the properties,
   so exactly ONE rule ever declares each of these and a box with no choice
   renders precisely as it always has. */
.bb-box-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(var(--bb-box-card-min, 140px), 1fr));
	gap: var(--bb-box-card-gap, 12px);
}

.bb-box-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 6px;
	padding: 12px 10px 10px;
	background: var(--bb-surface);
	border: 1px solid var(--bb-border);
	border-radius: 10px;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.bb-box-card-chosen {
	border-color: var(--bb-accent);
	box-shadow: inset 0 0 0 1px var(--bb-accent);
}

.bb-box-card-img {
	width: var(--bb-box-card-photo, 72px);
	height: var(--bb-box-card-photo, 72px);
	object-fit: cover;
	border-radius: 8px;
	background: var(--bb-surface-faint);
}

/* The no-photo tile must occupy exactly the photo's box, or imageless cards
   become different cards: the generic .bb-noimg sizing (bundle.css: width
   100%, max-width 96px, square aspect) ties with the rule above at one class
   each, so the winner per property fell to stylesheet order and imageless
   tiles came out 96px wide and photo-height short, warping the row and the
   steppers under it. :not(.bb-box-card-matrix) outranks both sides of the
   tie and leaves matrix / gallery / pad tiles to their own rules; the
   comfortable and large card sizes already outrank this and keep their
   full-bleed square. */
.bb-box-card:not(.bb-box-card-matrix) > .bb-noimg {
	width: var(--bb-box-card-photo, 72px);
	height: var(--bb-box-card-photo, 72px);
	max-width: none;
	aspect-ratio: auto;
}

.bb-box-card-name {
	font-size: 13px;
	font-weight: 600;
	color: var(--bb-ink-soft);
	line-height: 1.3;
}

.bb-box-card-price {
	font-size: 13px;
	color: var(--bb-muted);
}

.bb-box-card-price del {
	color: var(--bb-muted-light);
	margin-right: 4px;
}

/* Variation chooser on a variable card: a compact select above the stepper. */
.bb-box-var {
	width: 100%;
	max-width: 152px;
	margin-top: 2px;
	padding: 5px 8px;
	font-size: 12.5px;
	border: 1px solid var(--bb-border-strong);
	border-radius: 8px;
	background: var(--bb-surface);
	color: var(--bb-ink);
}

/* A nudge shown only when a quantity is set but no option has been chosen. */
.bb-box-card-hint {
	display: none;
	font-size: 11.5px;
	font-weight: 600;
	color: #b91c1c;
}

.bb-box-card-pending .bb-box-card-hint {
	display: block;
}

/* A pending card flags the missing choice in red, overriding the chosen accent. */
.bb-box-card-pending,
.bb-box-card-pending.bb-box-card-chosen {
	border-color: #f0b4b4;
	box-shadow: inset 0 0 0 1px #f0b4b4;
}

/* Stepper: − [n] + */
.bb-box-stepper {
	display: inline-flex;
	align-items: center;
	margin-top: 2px;
	border: 1px solid var(--bb-border-strong);
	border-radius: 999px;
	overflow: hidden;
	background: var(--bb-surface);
}

.bb-box-dec,
.bb-box-inc {
	border: 0;
	background: var(--bb-surface-faint);
	color: var(--bb-ink);
	width: 30px;
	height: 30px;
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
}

.bb-box-dec:hover,
.bb-box-inc:hover {
	background: var(--bb-accent-bg);
	color: var(--bb-accent-deep);
}

.bb-box-full .bb-box-inc {
	opacity: 0.4;
	cursor: not-allowed;
}

/* Variety cap: dim the cards you have not chosen once the cap of different
   products is reached, so it is clear why their plus is disabled. */
.bb-box-card-locked {
	opacity: 0.55;
}

.bb-box-card-locked .bb-box-inc,
.bb-box-inc:disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.bb-box-variety {
	font-size: 12px;
	color: var(--bb-ink-soft, #6b6b6b);
}

.bb-box-qty {
	width: 38px;
	height: 30px;
	border: 0;
	border-left: 1px solid var(--bb-border);
	border-right: 1px solid var(--bb-border);
	text-align: center;
	font-size: 14px;
	font-variant-numeric: tabular-nums;
	-moz-appearance: textfield;
	appearance: textfield;
	background: var(--bb-surface);
	color: var(--bb-ink);
}

.bb-box-qty::-webkit-outer-spin-button,
.bb-box-qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

/* Sold-out card: muted, no stepper. */
.bb-box-card-oos {
	opacity: 0.55;
}

.bb-box-oos {
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--bb-muted-light);
}

@media (max-width: 480px) {
	/* A phone gets two cards a row, said outright rather than left to
	   auto-fill. A minimum column width plus the gap is a cliff: the theme
	   left this wall 307px wide on a 390px phone, Comfortable asks for
	   150px columns, and 150 + 10 + 150 = 310. Three pixels short, so
	   auto-fill dropped to ONE column, each card a screen-wide slab —
	   measured 17,053px of page against Compact's 8,111px on a 40-item
	   wall. Two columns is also what the roomier sizes are for: a bigger
	   photo, not a taller page. Matrix mode keeps its own track list. */
	.bb-box-grid:not(.bb-box-grid-matrix) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 10px;
	}

	.bb-box-grid-matrix {
		grid-template-columns: repeat(auto-fill, minmax(var(--bb-box-card-min-m, 118px), 1fr));
		gap: 10px;
	}

	.bb-box-card-img {
		width: var(--bb-box-card-photo-m, 60px);
		height: var(--bb-box-card-photo-m, 60px);
	}

	.bb-box-card:not(.bb-box-card-matrix) > .bb-noimg {
		width: var(--bb-box-card-photo-m, 60px);
		height: var(--bb-box-card-photo-m, 60px);
	}

	/* Two cards a row leave a name about 115px of line, and the two-line
	   clamp in bundle.css then cut half of a live 51-item wall: 25 names,
	   a pair of socks losing its "(US 4-9.5 / EU 34-40)". A shopper picking
	   between two near-identical items needs exactly the words that differ,
	   so on a phone the whole name shows and a long one makes its own row
	   taller. A split card's variation line is the half that differs, so it
	   is freed too; its product line keeps the one-line ellipsis, being the
	   same words on every card of that product. */
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-name:not(.bb-split-name),
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-split-name .bb-split-var {
		display: block;
		-webkit-line-clamp: unset;
		overflow: visible;
	}

	/* Free names make a row's cards differ in height. A shown price already
	   takes the card's floor (margin-top:auto in bundle.css) and carries the
	   controls down with it; with prices hidden nothing did, so a short name
	   left its control a line above its neighbour's. The control after the
	   name now takes the floor instead, exactly as the price would. A Sold
	   out line is left where it was: it is not a control, and moving it would
	   change live pages that never had a name cut. The !important outranks
	   the theme-proof margins further down. */
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-name + .bb-box-stepper,
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-name + .bb-box-var {
		margin-top: auto !important;
	}

	/* WooCommerce's own `.woocommerce img { height: auto }` outranks the
	   photo height above on every product page, so each photo took its
	   file's shape: a 600x647 shot stood 9px taller than its neighbour and
	   dropped that card's name out of line with the row. aspect-ratio squares
	   the auto height whoever set it, and max-width keeps Large's 120px
	   photo inside a card that has 114px to give. */
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-img:not(.bb-noimg),
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-zoom,
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-zoom > .bb-box-card-img {
		max-width: 100%;
	}

	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-img:not(.bb-noimg),
	.bb-box-grid .bb-box-card:not(.bb-box-card-matrix) > .bb-box-card-zoom > .bb-box-card-img {
		height: auto;
		aspect-ratio: 1 / 1;
	}
}

/* -----------------------------------------------------------------
 * Card size (the slot's own "Card size" choice). Compact is the
 * original numbers above and carries NO class, so every box saved
 * before the choice existed renders exactly as it always has. The
 * two bigger sizes widen the column floor and the photo together
 * (fewer cards fit a row, which is the point) by setting ONLY the
 * custom properties the base rules read: the layout declarations
 * stay in one place, on desktop and on phones alike.
 * ----------------------------------------------------------------- */
.bb-box-cards-comfortable {
	--bb-box-card-min: 185px;
	--bb-box-card-gap: 14px;
	--bb-box-card-photo: 110px;
	--bb-box-card-min-m: 150px;
	--bb-box-card-photo-m: 92px;
	--bb-box-gallery-min: 250px;
	--bb-box-gallery-photo: 190px;
}

.bb-box-cards-large {
	--bb-box-card-min: 240px;
	--bb-box-card-gap: 16px;
	--bb-box-card-photo: 160px;
	--bb-box-card-min-m: 165px;
	--bb-box-card-photo-m: 120px;
	--bb-box-gallery-min: 300px;
	--bb-box-gallery-photo: 230px;
}

.bb-box-cards-large .bb-box-card-name {
	font-size: 14px;
}

/* -----------------------------------------------------------------
 * At the two opt-in sizes the photograph takes the card: edge to
 * edge on top, the name centred beneath it, the price on its own
 * line under that. The photo bleeds past the card's padding with
 * negative margins, so no track or flex sizing ever reads the
 * image's natural width. Matrix cards are excluded: their looks
 * address the bare img directly.
 *
 * The tile grid card is excluded too, from every rule in this block.
 * A card size is a size for a PRODUCT card, and the tile grid is not
 * one: it spans the whole row and holds a tile for every colour. It
 * was caught by these selectors all the same, so on Comfortable it
 * was capped at 210px and centred in its row, one tile to a line and
 * 670px tall where Compact needs 164px, with its 46px thumbnail grown
 * to the width of the card and its name moved to the middle. It keeps
 * the row it was given at every size (spec 79).
 *
 * Name and price stay the card's own children. Pairing them in a
 * row of their own cost the layout pass its two guarantees: the
 * price's margin-top:auto no longer reached the card, so prices
 * stopped sharing one line across a row, and the price drifted to
 * wherever the name's last wrapped line ended.
 * ----------------------------------------------------------------- */
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid),
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) {
	overflow: hidden;
}

/* Each rung caps its own card, which is what makes Card size a card SIZE.
   The rungs used to differ only by --bb-box-card-min, and a 1fr track
   stretches to fill the row, so two rungs landing on the same column count
   rendered the same card: measured 276px against 275px at every width, the
   1px being the 14/16px gap. The photo is width:100% on a 1/1 ratio and so
   inherited that sameness, and the --bb-box-card-photo tokens are never read
   by this card at all. justify-self centres the capped card in the column it
   was given, so the TRACKS still fill the row and the row's own alignment is
   untouched — only the card is smaller. Compact keeps the shared rule. */
/* width:100% with the cap is what makes the card FILL its track up to the cap
   instead of shrinking to its own content. Without it the card is a
   shrink-to-fit box, and two things follow: a percentage width on a child
   cannot resolve (so the full-bleed photo below silently fell back to the
   content box), and a card whose product has no photo has nothing setting a
   width at all, so it collapsed to the width of its name. On a 32-product
   pool that read as fourteen different card widths in one grid. The cap and
   the centring are untouched, so the intent above still holds. */
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) {
	max-width: 210px;
	width: 100%;
	justify-self: center;
}

.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) {
	max-width: 290px;
	width: 100%;
	justify-self: center;
}

/* Everything from here to the end of this media block is the ROOMY PHOTO: the
   card's picture bled to the card's edges as a square. It is deliberately
   fenced above phone width. The size classes already declare what a phone
   should use (--bb-box-card-photo-m: 92px on Comfortable, 120px on Large) and
   the phone block near the top of this file reads exactly those, but these
   rules are more specific and used to sit outside any media query, so they
   overrode it and a phone got a full-card-width square instead. Measured on a
   40-item wall at 390px: the page stood 17,053px tall on Comfortable against
   8,111px on Compact, 20,391px on Large. A photo one column wide is fine; a
   photo one SCREEN wide turns a wall into a scroll with no end. Keep the fence:
   these rules must never apply where only one card fits a row. */
@media (min-width: 481px) {

.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom,
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-img,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-img {
	align-self: stretch;
	width: auto;
	margin: -12px -10px 0;
}

.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-img,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-img {
	width: 100%;
	max-width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	border-radius: 9px 9px 0 0;
}

/* The photo is meant to bleed over the card's padding: the block above pulls it
   out with margin: -12px -10px 0. But the rule that follows it re-declares
   width:100% and max-width:100% at the same specificity, so it WINS on width
   and pins the photo to the CONTENT box. The negative left margin still moved
   it, so the left edge came out flush and the right edge landed exactly the
   10px of padding short: measured 1px inset on the left against 21px on the
   right. Restoring the width HERE, after that rule, is what makes the bleed
   symmetrical. The +20px is the two horizontal margins.
   The zoom wrapper is listed because photo preview puts it between the card
   and the photo, and that state has to bleed identically. */
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom,
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-img,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-img {
	width: calc( 100% + 20px );
	max-width: none;
}

/* Inside the zoom wrapper the photo fills the wrapper, which is already bled. */
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom > .bb-box-card-img,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) > .bb-box-card-zoom > .bb-box-card-img {
	width: 100%;
	max-width: 100%;
	margin: 0;
}

}

/* The card centres its column, so a child is only as wide as its own
   text. Stretch both lines to the card and centre the text inside
   them, so the price sits under the middle of the photo on every
   card whatever the name did. */
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-name,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-name,
.bb-box-cards-comfortable .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-price,
.bb-box-cards-large .bb-box-card:not(.bb-box-card-matrix):not(.bb-box-card-tilegrid) .bb-box-card-price {
	align-self: stretch;
	text-align: center;
}

/* -----------------------------------------------------------------
 * Click-to-enlarge on the card photo: opens the shared design
 * lightbox (builder js), exactly as the choice-slot thumbs do. The
 * wrapper hosts the magnifier badge (an img cannot carry a pseudo
 * element) and the small hover lift is the invitation to click, not
 * the way to see the image; the lightbox is.
 * ----------------------------------------------------------------- */
.bb-box-card-zoom {
	position: relative;
	display: inline-flex;
}

.bb-box-card-zoom img[data-full] {
	cursor: zoom-in;
}

@media (prefers-reduced-motion: no-preference) {
	.bb-box-card-zoom img[data-full] {
		transition: transform 0.14s ease;
	}

	.bb-box-card-zoom:hover img[data-full] {
		transform: scale(1.06);
	}
}

.bb-box-card-zoom img[data-full]:focus-visible {
	outline: 2px solid var(--bb-accent, #3466e6);
	outline-offset: 2px;
}

.bb-box-card-zoom::after {
	content: "";
	position: absolute;
	top: 4px;
	right: 4px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: rgba( 17, 24, 39, 0.7 ) center / 10px 10px no-repeat
		url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cline x1='15.5' y1='15.5' x2='21' y2='21'/%3E%3C/svg%3E" );
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.12s;
}

.bb-box-card-zoom:hover::after,
.bb-box-card-zoom:has( img:focus-visible )::after {
	opacity: 0.92;
}

/* No hover on touch: the badge stays quietly visible so the tap is
 * discoverable, dimmer than the hover state so 30 cards do not shout. */
@media ( hover: none ) {
	.bb-box-card-zoom::after {
		opacity: 0.55;
	}
}

/* A wrapper with no photo inside never happens (the no-photo tile is a
 * span outside the wrapper), so no empty-state rule is needed. */

/* The peek itself: a medium centred preview, sized to read detail while
 * the page stays in view; a click on it steps up to the big look. It and
 * its scrim CATCH the pointer, so a click over the preview can never
 * reach a control underneath it. */
.bb-box-peek {
	position: fixed;
	left: 50%;
	top: 50%;
	transform: translate( -50%, -50% );
	z-index: 99990;
	padding: 6px;
	background: #fff;
	border-radius: 12px;
	box-shadow: 0 10px 34px rgba( 17, 24, 39, 0.28 );
	cursor: zoom-in;
}

.bb-box-peek img {
	display: block;
	max-width: min( 420px, 86vw );
	max-height: 62vh;
	border-radius: 8px;
}

.bb-box-peek-big {
	cursor: zoom-out;
}

.bb-box-peek-big img {
	max-width: min( 900px, 92vw );
	max-height: 85vh;
}

.bb-box-peek-scrim {
	position: fixed;
	inset: 0;
	z-index: 99989;
	background: rgba( 17, 24, 39, 0.35 );
}

@media (prefers-reduced-motion: no-preference) {
	.bb-box-peek {
		animation: bb-peek-in 0.12s ease;
	}

	@keyframes bb-peek-in {
		from { opacity: 0; }
		to { opacity: 1; }
	}
}

/* -----------------------------------------------------------------
 * Size-driven box: the customer first picks a size / pack (say
 * "3kg bucket", "Medium hamper", "500g bag") — a flat price and an exact
 * fill count — then fills it. The sizes read as a distinct pricing-tier
 * chooser (not another product card). Reusable for any "pick a pack,
 * fill it" shop.
 * ----------------------------------------------------------------- */

.bb-box-sizes {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
	gap: 12px;
	margin: 10px 0 4px;
}

.bb-box-size {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	/* The top keeps a row for the check (7px inset + 18px), so a long name
	   can use the tile's whole width and never runs under it on a phone. */
	padding: 27px 14px 14px;
	background: var(--bb-surface);
	border: 1.5px solid var(--bb-border);
	border-radius: 14px;
	cursor: pointer;
	text-align: center;
	transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease, background 0.15s ease;
}

.bb-box-size:hover {
	border-color: var(--bb-accent);
	transform: translateY(-1px);
}

.bb-box-size:focus-visible {
	outline: 2px solid var(--bb-accent);
	outline-offset: 2px;
}

/* Chosen size: a filled accent tile with a check — clearly a selection, and
   nothing like the border a chosen sweet gets. Explicit colours so the text
   stays legible on the fill whatever the theme's tokens are. */
.bb-box-size-on {
	border-color: var(--bb-accent);
	background: var(--bb-accent);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.bb-box-size-on .bb-box-size-name,
.bb-box-size-on .bb-box-size-price {
	color: #fff;
}

.bb-box-size-on .bb-box-size-meta {
	color: rgba(255, 255, 255, 0.85);
}

.bb-box-size-on .bb-box-size-check {
	background: #fff;
	color: var(--bb-accent);
}

.bb-box-size-name {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--bb-ink-soft, var(--bb-ink));
	line-height: 1.25;
}

.bb-box-size-price {
	font-size: 20px;
	font-weight: 700;
	color: var(--bb-ink);
	line-height: 1.15;
}

.bb-box-size-meta {
	font-size: 12px;
	color: var(--bb-muted);
}

/* Selected check, top-right, revealed when the size is on. */
.bb-box-size-check {
	position: absolute;
	top: 7px;
	right: 7px;
	width: 18px;
	height: 18px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: var(--bb-accent);
	color: #fff;
	opacity: 0;
	transform: scale(0.5);
	transition: opacity 0.15s ease, transform 0.15s ease;
}

.bb-box-size-on .bb-box-size-check {
	opacity: 1;
	transform: scale(1);
}

/* "Now fill it" divider between the size chooser and the item grid. */
.bb-box-fill-label {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 18px 0 12px;
}

.bb-box-fill-label::before,
.bb-box-fill-label::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--bb-border);
}

.bb-box-fill-label span {
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--bb-muted);
}

/* Until a size is chosen, the item grid is dormant — the size is the first
   decision, and picking items before it would be meaningless. */
.bb-box-needs-size .bb-box-grid {
	opacity: 0.4;
	pointer-events: none;
	filter: grayscale(0.5);
}

.bb-box-needs-size .bb-box-fill-label {
	opacity: 0.4;
}

/* A tap on that dormant area answers with the size chooser pulsed at the
   shopper (class set briefly by build-a-box.js), so a dead-looking grid
   explains itself instead of ignoring the touch. */
.bb-nudge-size .bb-box-instruction {
	color: var(--bb-accent-deep, var(--bb-accent, #3466e6));
}

@media (prefers-reduced-motion: no-preference) {
	.bb-nudge-size .bb-box-sizes {
		animation: bb-size-nudge 0.7s ease 2;
	}

	@keyframes bb-size-nudge {
		0%, 100% { box-shadow: none; }
		50% { box-shadow: 0 0 0 3px color-mix( in srgb, var(--bb-accent, #3466e6) 55%, transparent ); }
	}
}

@media (max-width: 480px) {
	.bb-box-sizes {
		grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
		gap: 10px;
	}

	.bb-box-size-price {
		font-size: 18px;
	}
}

/* -----------------------------------------------------------------
 * Box search: filter the item grid by name. Shown only for large pools
 * (dozens of choices), where a flat grid is unusable without it.
 * ----------------------------------------------------------------- */

.bb-box-search {
	position: relative;
	margin: 6px 0 12px;
}

.bb-box-search-icon {
	position: absolute;
	left: 12px;
	top: 50%;
	transform: translateY(-50%);
	color: var(--bb-muted);
	pointer-events: none;
}

.bb-box-search-input {
	width: 100%;
	box-sizing: border-box;
	/* !important so a theme restyling search inputs can't slide the text back
	   under the magnifier icon. */
	padding: 10px 14px 10px 40px !important;
	font-size: 14px;
	color: var(--bb-ink);
	background: var(--bb-surface);
	border: 1px solid var(--bb-border);
	border-radius: 10px;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.bb-box-search-input:focus {
	outline: none;
	border-color: var(--bb-accent);
	box-shadow: 0 0 0 3px var(--bb-surface-alt);
}

.bb-box-card-hidden {
	display: none !important;
}

.bb-box-noresults {
	margin: 4px 0 0;
	padding: 16px 0;
	text-align: center;
	font-size: 13px;
	color: var(--bb-muted);
}

/* Category filter chips for a large box grid: browse by category alongside
   the search box. */
.bb-box-cats {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: 0 0 14px;
}

.bb-box-cat {
	padding: 5px 13px;
	font-size: 12.5px;
	font-weight: 500;
	color: var(--bb-ink-soft, var(--bb-ink));
	background: var(--bb-surface);
	border: 1px solid var(--bb-border);
	border-radius: 999px;
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.bb-box-cat:hover {
	border-color: var(--bb-accent);
}

.bb-box-cat-on {
	color: #fff;
	background: var(--bb-accent);
	border-color: var(--bb-accent);
}

/* -----------------------------------------------------------------
 * Theme guard. Global theme form styles outrank a single class
 * (input[type="number"] is 0-1-1, .bb-box-qty is 0-1-0): measured
 * live under Flatsome, the 38x30 quantity input rendered 70x39 with
 * a 15px bottom margin and the 30x30 steppers rendered 24x45 with
 * 18px margins. Restate the geometry with the form prefix and
 * !important, mirroring the base values earlier in this file; visual
 * state (hover, chosen, disabled) stays with the base rules except
 * where the guard must repeat it to keep it alive.
 * ----------------------------------------------------------------- */

.bundle-boss-form .bb-box-stepper {
	display: inline-flex !important;
	align-items: center !important;
	width: auto !important;
	height: auto !important;
	margin: 2px 0 0 !important;
	padding: 0 !important;
}

.bundle-boss-form .bb-box-dec,
.bundle-boss-form .bb-box-inc {
	box-sizing: border-box !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 30px !important;
	height: 30px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	text-shadow: none !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	font-size: 18px !important;
	line-height: 1 !important;
	background: var(--bb-surface-faint) !important;
	color: var(--bb-ink) !important;
}

/* Repeated because the guard pins background/colour above the base rules. */
.bundle-boss-form .bb-box-dec:hover,
.bundle-boss-form .bb-box-inc:hover {
	background: var(--bb-accent-bg) !important;
	color: var(--bb-accent-deep) !important;
}

.bundle-boss-form input.bb-box-qty {
	box-sizing: border-box !important;
	width: 38px !important;
	height: 30px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-left: 1px solid var(--bb-border) !important;
	border-right: 1px solid var(--bb-border) !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	background: var(--bb-surface) !important;
	color: var(--bb-ink) !important;
	text-align: center !important;
	font-size: 14px !important;
	line-height: normal !important;
	-moz-appearance: textfield !important;
	appearance: textfield !important;
}

.bundle-boss-form select.bb-box-var {
	box-sizing: border-box !important;
	width: 100% !important;
	max-width: 152px !important;
	height: auto !important;
	min-height: 0 !important;
	margin: 2px 0 0 !important;
	padding: 5px 8px !important;
	border: 1px solid var(--bb-border-strong) !important;
	border-radius: 8px !important;
	box-shadow: none !important;
	background-color: var(--bb-surface) !important;
	color: var(--bb-ink) !important;
	font-size: 12.5px !important;
	line-height: normal !important;
}

.bundle-boss-form .bb-box-search-input {
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	border-radius: 10px !important;
	box-shadow: none !important;
	line-height: normal !important;
}

/* Size tiles are buttons; themes' global button margins/uppercase leak in. */
.bundle-boss-form .bb-box-size {
	height: auto !important;
	min-height: 0 !important;
	margin: 9px 0 0 !important;
	padding: 27px 14px 14px !important;
	text-transform: none !important;
	letter-spacing: normal !important;
}

/* A theme's button:hover / button:focus background outranks the chosen
   fill, and a tap leaves both on, so the tile just picked went white under
   its white text until the shopper tapped elsewhere. */
.bundle-boss-form .bb-box-size-on,
.bundle-boss-form .bb-box-size-on:hover,
.bundle-boss-form .bb-box-size-on:focus {
	background: var(--bb-accent) !important;
	border-color: var(--bb-accent) !important;
}

/* ---- Expanded products (split cards + the tile-grid card) ---- */

/* An expanded two-option-type product: one full-width card holding the tile
   quantity grid. The tiles and panels inside dress from the shared grid CSS. */
.bb-box-grid .bb-box-card-tilegrid { grid-column: 1 / -1; align-items: stretch; }
.bb-box-tilegrid-head { display: flex; align-items: center; gap: 12px; width: 100%; }
.bb-box-tilegrid-head .bb-box-card-img,
.bb-box-tilegrid-head .bb-noimg { width: 46px; height: 46px; min-height: 0; border-radius: 8px; object-fit: cover; flex: none; font-size: 16px; }
/* Card size reaches this card's photo too. The card keeps its full row at
   every size (spec 79); only the photo in its head grows. Compact keeps 46px. */
.bb-box-cards-comfortable .bb-box-tilegrid-head .bb-box-card-img,
.bb-box-cards-comfortable .bb-box-tilegrid-head .bb-noimg { width: 72px; height: 72px; }
.bb-box-cards-large .bb-box-tilegrid-head .bb-box-card-img,
.bb-box-cards-large .bb-box-tilegrid-head .bb-noimg { width: 96px; height: 96px; }
/* With Photo preview on, the wrapper is the flex item; it must not shrink
   either, or a narrow head squeezes the photo out of square. */
.bb-box-tilegrid-head .bb-box-card-zoom { flex: none; }
.bb-box-tilegrid-head .bb-box-card-name { flex: 1 1 auto; text-align: left; font-weight: 600; display: block; -webkit-line-clamp: unset; overflow: visible; }
.bb-box-tilegrid-head .bb-box-card-price { margin: 0; flex: none; font-size: .9em; }
.bb-box-card-tilegrid .bb-card-tiles { width: 100%; margin-top: 10px; }

/* A pool that mixes full-width grid rows with ONE plain or One card tile.
   The grid auto-fills three to seven columns, so that lone tile sat in the
   first column as a narrow, tall card beside empty space. It borrows the row
   shape of its neighbours: photo, name and price in a line, the colour and
   size chips and the stepper after them, wrapping on a narrow column. Two or
   more tiles keep the tile grid they were drawn for. The grid's own card size
   rules still size the type; only the photo follows the row head's sizes. */
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) {
	grid-column: 1 / -1;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	text-align: left;
	gap: 10px 14px;
}
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-img,
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-zoom > .bb-box-card-img {
	width: 46px;
	height: 46px;
	min-height: 0;
	font-size: 16px;
	flex: none;
}
.bb-box-cards-comfortable.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-img,
.bb-box-cards-comfortable.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-zoom > .bb-box-card-img {
	width: 72px;
	height: 72px;
}
.bb-box-cards-large.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-img,
.bb-box-cards-large.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-zoom > .bb-box-card-img {
	width: 96px;
	height: 96px;
}
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-zoom {
	flex: none;
}
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-name {
	flex: 1 1 8em;
	min-width: 8em;
	max-width: none;
	display: block;
	-webkit-line-clamp: unset;
	overflow: visible;
	text-align: left;
}
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-price {
	margin: 0;
	flex: none;
}
/* The colour and size questions sit side by side when the row has the room
   and stack when it does not; the stepper takes the end of its line. */
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-oc {
	width: auto;
	flex: 1 1 18em;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 8px 24px;
	margin: 0;
}
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-stepper {
	margin: 0 0 0 auto;
	flex: none;
	order: 1;
}
/* The "Choose an option" nudge sits between the choices and the stepper in
   the markup. Shown, it took the end of the line and pushed the stepper down
   under the sizes, then let it back up once a colour and size were picked
   (his find, 3 Oct). It takes a line of its own under the choices instead,
   so the stepper never moves. */
.bb-box-grid:not( .bb-box-grid-matrix ):has( > .bb-box-card-tilegrid ):not( :has( > .bb-box-card:not( .bb-box-card-tilegrid ) ~ .bb-box-card:not( .bb-box-card-tilegrid ) ) ) > .bb-box-card:not( .bb-box-card-tilegrid ) > .bb-box-card-hint {
	order: 2;
	flex: 1 1 100%;
	margin: -4px 0 0;
}

/* An Order Builder row that opens to the quantity grid (the table is the
   shop's choice): the grid shuts with the row and opens with it, under the
   row's head, exactly where the table sits. */
.bb-box-card-matrix > .bb-card-tiles {
	flex-basis: 100%;
	order: 99;
	min-width: 0;
	margin: 6px 0 0;
	cursor: default;
}

.bb-box-card-matrix:not(.is-open) > .bb-card-tiles {
	display: none;
}

/* -----------------------------------------------------------------
 * One card, option sets: colour swatches, then size chips, the way the
 * product's own page asks them. One combination at a time, so a chosen
 * size fills with ink and a chosen colour takes the ring. The card's list
 * of combinations stays, hidden, as the one the pick chooses from.
 * ----------------------------------------------------------------- */

.bundle-boss-form .bb-box-card select.bb-box-var[hidden] {
	display: none !important;
}

.bb-oc {
	display: flex;
	flex-direction: column;
	gap: 8px;
	width: 100%;
	margin: 6px 0 4px;
	text-align: left;
}

.bb-oc-head {
	display: flex;
	align-items: baseline;
	gap: 6px;
	min-width: 0;
	font-size: 11.5px;
	line-height: 1.3;
}

.bb-oc-name {
	flex: none;
	font-weight: 600;
	color: var(--bb-ink);
}

.bb-oc-picked {
	min-width: 0;
	overflow: hidden;
	color: var(--bb-muted);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.bb-oc-answers {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
	margin-top: 5px;
}

/* An answer the other pick rules out: there, dimmed, still pressable (a
   press clears the pick it clashes with). */
.bb-oc .bb-oc-answer.is-off:not(.is-selected) {
	opacity: 0.38;
}

/* Theme guard, the chip doctrine, sized for a card. */
.bundle-boss-form .bb-oc .bb-chip {
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 30px !important;
	height: 26px !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 8px !important;
	border: 1px solid var(--bb-border) !important;
	border-radius: 6px !important;
	box-shadow: none !important;
	background: var(--bb-surface) !important;
	color: var(--bb-text, var(--bb-ink)) !important;
	font-size: 12px !important;
	font-weight: 500 !important;
	line-height: 24px !important;
	text-align: center !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	text-shadow: none !important;
}

.bundle-boss-form .bb-oc .bb-chip:not(.is-selected):hover {
	border-color: var(--bb-muted-light) !important;
	color: var(--bb-ink) !important;
}

.bundle-boss-form .bb-oc .bb-chip.is-selected {
	border-color: var(--bb-ink) !important;
	background: var(--bb-ink) !important;
	color: var(--bb-surface) !important;
	font-weight: 600 !important;
}

.bundle-boss-form .bb-oc .bb-chip.bb-chip--swatch {
	width: 26px !important;
	min-width: 0 !important;
	padding: 3px !important;
	border-radius: 50% !important;
	line-height: 0 !important;
}

.bundle-boss-form .bb-oc .bb-chip.bb-chip--swatch.is-selected {
	border-color: var(--bb-ink) !important;
	background: var(--bb-surface) !important;
	box-shadow: 0 0 0 1px var(--bb-ink) !important;
}

/* The dot fills its chip. AddOnBoss sizes every swatch dot 40px for its
   own swatch rows, and on a card's 26px chip that dot spilled sideways, so
   the colours drew as overlapping ovals. The chip carries the selected
   ring and tick, so the dot drops AddOnBoss's own pair here. */
.bundle-boss-form .bb-oc .bb-chip.bb-chip--swatch .bb-swatch-dot {
	width: 100% !important;
	height: 100% !important;
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12) !important;
}

.bundle-boss-form .bb-oc .bb-chip.bb-chip--swatch .bb-swatch-dot::after {
	content: none !important;
}

.bundle-boss-form .bb-oc .bb-chip:focus-visible {
	outline: 2px solid var(--bb-accent, #3466e6) !important;
	outline-offset: 2px !important;
}

/* -----------------------------------------------------------------
 * Questions asked once for the whole order: a choice the shop left to
 * the customer (the print, a new artwork setup), asked ONCE after the
 * items while each item keeps its colour and size. Loaded with the box
 * styles on every bundle page. Drawn with the options engine's own chip
 * and photo card, so the question reads as it does on the product's
 * page. One answer: a chosen chip fills with ink, a chosen card takes
 * the ink ring and keeps its picture. No tick, which would say "as many
 * as you like". Waiting is amber (the store's warning tone), never the
 * accent, which belongs to things you press.
 * ----------------------------------------------------------------- */

.bb-asks {
	margin: 18px 0 4px;
}

/* Step by step: a question comes with the step of the last product it is
   about (stepper__premium_only.js places them); a step with none of them
   shows no block at all. */
.bb-stepper-active .bb-asks.bb-asks-off,
.bb-stepper-active .bb-ask.bb-ask-step-off {
	display: none;
}

.bb-ask {
	margin: 0;
	padding: 14px 16px 16px;
	background: var(--bb-surface);
	border: 1px solid var(--bb-border);
	border-radius: 12px;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.bb-ask + .bb-ask {
	margin-top: 10px;
}

/* A question behind a rule is out of the flow while its rule does not hold. */
.bb-ask[hidden] {
	display: none;
}

.bb-ask-title {
	margin: 0;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--bb-ink);
}

.bb-ask-for {
	margin: 2px 0 12px;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--bb-muted);
}

.bb-ask-answers {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/* Cards in a row share one height: a priced answer carries a second line,
   and a row of unequal cards reads as unequal answers. */
.bb-ask-answers.bb-shape-card {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
	gap: 12px 10px;
	align-items: stretch;
}

.bb-ask .bb-chip-delta {
	margin-left: 6px;
	font-weight: 500;
	color: var(--bb-muted);
	white-space: nowrap;
}

.bb-ask .bb-chip-delta .amount {
	font-size: inherit;
}

.bb-ask .bb-chip.is-selected .bb-chip-delta {
	color: inherit;
	opacity: 0.8;
}

/* Photo card: the whole picture, contained, never cropped (a print
   position cut off at the top is the wrong answer to show). */
.bb-ask .bb-chip--card {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	justify-content: flex-start;
	text-align: center;
	white-space: normal;
}

.bb-ask .bb-cc-img {
	display: block;
	width: 100%;
	height: 88px;
	padding: 4px;
	box-sizing: border-box;
	border-radius: 8px;
	object-fit: contain;
	background: var(--bb-surface-faint);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);
}

.bb-ask .bb-cc-name {
	display: block;
	margin-top: 6px;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.3;
	overflow-wrap: anywhere;
}

.bb-ask .bb-chip--card .bb-chip-delta {
	display: block;
	margin: 1px 0 0;
	font-size: 11.5px;
}

.bb-ask .bb-chip--card.is-selected .bb-cc-name {
	color: var(--bb-ink);
	font-weight: 700;
}

.bb-ask .bb-chip--card.is-selected .bb-chip-delta {
	color: var(--bb-muted);
	opacity: 1;
}

.bb-ask-select {
	width: 100%;
	max-width: 360px;
}

/* A garment is in the box and the question is still open: say so here,
   where the answer is, not only as a dead Add button. */
.bb-ask.is-needed {
	border-color: var(--bb-warn, #b45309);
	box-shadow: 0 0 0 1px var(--bb-warn, #b45309);
}

.bb-ask-need,
.bb-ask-clash {
	margin: 10px 0 0;
	font-size: 12.5px;
	font-weight: 600;
	color: var(--bb-warn, #b45309);
}

/* A section that asks for at least one answer among its questions, owed:
   the shop's sentence once, above the section, and a quiet rail on each of
   its questions. Nothing inside any one question, since none is owed alone. */
.bb-ask-secband {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	margin: 0 0 12px;
	padding: 10px 12px;
	border: 1px solid var(--bb-warn, #b45309);
	border-radius: 10px;
	background: #fff7ed;
	background: color-mix(in srgb, var(--bb-warn, #b45309) 8%, var(--bb-surface, #fff));
	color: var(--bb-warn, #b45309);
}

.bb-ask-secband[hidden] {
	display: none;
}

.bb-ask-secband-mark {
	flex: none;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: var(--bb-warn, #b45309);
	color: #fff;
	font: 700 13px/20px sans-serif;
	text-align: center;
}

.bb-ask-secband-body {
	min-width: 0;
}

.bb-ask-secband-msg {
	margin: 0;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.4;
}

.bb-ask-secband-any {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	margin: 8px 0 0;
	font-size: 12.5px;
	color: var(--bb-muted, #6b7280);
}

.bundle-boss-form .bb-ask-secband-go {
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 3px 10px !important;
	border: 1px solid var(--bb-warn, #b45309) !important;
	border-radius: 100px !important;
	box-shadow: none !important;
	background: var(--bb-surface, #fff) !important;
	color: var(--bb-text, #111) !important;
	font-size: 12.5px !important;
	font-weight: 600 !important;
	line-height: 1.4 !important;
	text-transform: none !important;
	cursor: pointer;
}

.bundle-boss-form .bb-ask-secband-go:hover,
.bundle-boss-form .bb-ask-secband-go:focus-visible {
	background: #fff7ed !important;
	outline: 2px solid var(--bb-warn, #b45309);
	outline-offset: 2px;
}

.bb-ask.is-sec-owed {
	box-shadow: inset 3px 0 0 var(--bb-warn, #b45309);
}

/* A plain question (under an item, on a slot row) has no card padding: the
 * mark sits in the gutter beside it and the words do not move. */
.bb-unit-asks .bb-ask.is-sec-owed,
.bb-row-asks .bb-ask.is-sec-owed {
	margin-left: -10px;
	padding-left: 10px;
}

/* Theme guard, the chip doctrine: geometry and the two states are pinned,
   because a theme's global button rule (uppercase, min-heights, fills)
   otherwise turns every answer into its own call-to-action. */
.bundle-boss-form .bb-ask-answers .bb-chip {
	box-sizing: border-box !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 6px 14px !important;
	border: 1px solid var(--bb-border) !important;
	border-radius: 100px !important;
	box-shadow: none !important;
	background: var(--bb-surface) !important;
	color: var(--bb-text, var(--bb-ink)) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
	line-height: 1.45 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	text-shadow: none !important;
}

.bundle-boss-form .bb-ask-answers.bb-shape-square .bb-chip {
	border-radius: 8px !important;
}

.bundle-boss-form .bb-ask-answers .bb-chip:not(.is-selected):hover {
	border-color: var(--bb-muted-light) !important;
	background: var(--bb-surface-faint) !important;
	color: var(--bb-ink) !important;
}

.bundle-boss-form .bb-ask-answers .bb-chip.is-selected {
	border-color: var(--bb-ink) !important;
	background: var(--bb-ink) !important;
	color: var(--bb-surface) !important;
	font-weight: 600 !important;
}

.bundle-boss-form .bb-ask-answers .bb-chip.bb-chip--card {
	width: 100% !important;
	height: 100% !important;
	padding: 9px 10px 8px !important;
	border-radius: 12px !important;
}

.bundle-boss-form .bb-ask-answers .bb-chip.bb-chip--card.is-selected {
	border-color: var(--bb-ink) !important;
	background: var(--bb-surface) !important;
	color: var(--bb-text, var(--bb-ink)) !important;
	box-shadow: 0 0 0 1.5px var(--bb-ink) !important;
}

.bundle-boss-form .bb-ask-answers .bb-chip:focus-visible {
	outline: 2px solid var(--bb-accent, #3466e6) !important;
	outline-offset: 2px !important;
}

.bundle-boss-form select.bb-ask-select {
	box-sizing: border-box !important;
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 8px 10px !important;
	border: 1px solid var(--bb-border-strong, var(--bb-border)) !important;
	border-radius: 8px !important;
	box-shadow: none !important;
	background-color: var(--bb-surface) !important;
	color: var(--bb-ink) !important;
	font-size: 14px !important;
	line-height: normal !important;
}

/* -----------------------------------------------------------------
 * Questions asked on each slot ("On each slot"): on the slot's own card,
 * after what it sells, under a hairline. Flat, so the card stays one card:
 * the question belongs to the slot, it is not a box inside it. None stands
 * first where the customer may leave it.
 * ----------------------------------------------------------------- */

.bb-row-asks {
	margin: 16px 0 0;
	padding: 14px 0 0;
	border-top: 1px solid var(--bb-border);
}

.bb-row-asks[hidden] {
	display: none !important;
}

.bb-row-asks .bb-ask {
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
}

.bb-row-asks .bb-ask + .bb-ask {
	margin-top: 16px;
}

.bb-row-asks .bb-ask-title {
	margin-bottom: 10px;
	font-size: 14px;
}

.bb-row-asks .bb-ask-for {
	margin: -6px 0 10px;
}

.bb-ask-opt {
	margin-left: 6px;
	font-size: 12.5px;
	font-weight: 500;
	color: var(--bb-muted);
}

.bb-ask-sum {
	margin: 8px 0 0;
	font-size: 12.5px;
	color: var(--bb-muted);
	font-variant-numeric: tabular-nums;
}

.bb-ask-sum[hidden] {
	display: none;
}

/* A slot holds something and its question is still open: the flat question
   takes the same amber ring the whole-order card does. */
.bb-row-asks .bb-ask.is-needed,
.bb-unit-asks .bb-ask.is-needed {
	padding: 10px 12px 12px;
	border: 1px solid var(--bb-warn, #b45309);
	border-radius: 10px;
	box-shadow: 0 0 0 1px var(--bb-warn, #b45309);
}

/* The questions an item's own pick puts, under that item's picks: flat like
   a slot's, indented a step so they read as the pick's follow-ups. */
.bb-unit-asks {
	margin: 10px 0 0 12px;
	padding: 0 0 0 12px;
	border-left: 2px solid var(--bb-border);
}

.bb-unit-asks:empty,
.bb-unit-asks.is-empty {
	display: none;
}

.bb-unit-asks .bb-ask {
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
}

.bb-unit-asks .bb-ask + .bb-ask {
	margin-top: 14px;
}

.bb-unit-asks .bb-ask-title {
	margin-bottom: 8px;
	font-size: 14px;
}

.bb-unit-asks .bb-ask-for {
	margin: -4px 0 8px;
}

.bb-units-table .bb-cell-asks .bb-unit-asks {
	margin: 0;
	padding: 0;
	border-left: 0;
	min-width: 200px;
}


@media (max-width: 480px) {
	.bb-ask {
		padding: 12px 12px 14px;
	}

	.bb-row-asks .bb-ask {
		padding: 0;
	}

	.bb-ask-answers.bb-shape-card {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
