/* =========================================================================
   Bundle builder — standalone configurator at /bundle-builder/
   =========================================================================

   Visual brief: "much more modern, but matching the rest of the site."
   Those pull against each other, so the split is deliberate —

     Layout, hierarchy and pacing come from the 2026 UX mockup: an editorial
     hero, a two-column builder with a sticky summary, full-tile targets and
     a lot more air than the current page has.

     Colour and type come from the live site. The mockup used Georgia and a
     teal-leaning navy (#142d3b); this uses Asul, Montserrat and the real
     brand navy (#050b51), so the page reads as Ding Mooncake rather than as
     a different shop with the same products.

   Everything is scoped under .dmc-bb. Flatsome ships broad rules and this
   page has to survive them without !important wherever possible — see the
   note in functions.php about source order and why the stylesheet declares
   a dependency on flatsome-main.
   ========================================================================= */

.dmc-bb {
	/* Prefer the live Flatsome custom properties; the literals are the
	   values those resolve to today and keep the page correct if the
	   variables are ever renamed. */
	--navy: var(--fs-color-primary, #050b51);
	--gold: var(--fs-color-secondary, #b29d51);
	--olive: var(--fs-color-success, #7a9c59);
	/* Brand olive is 3.07:1 on the light panel — fine as a progress fill,
	   too weak for the savings figure, which is text. */
	--olive-ink: #4d6b38;

	--ivory: #faf7f1;
	--paper: #fffdf9;
	--sand: #f1ebdf;

	/* Brand gold is a 2.5:1 foreground on ivory — fine as a rule, a border
	   or a fill, and unreadable as small text. These two are the text-safe
	   members of the same family: --gold-ink clears 4.5:1 on ivory/paper,
	   --gold-deep clears 4.5:1 behind white text. The brand gold itself is
	   never used for type below 24px. */
	--gold-ink: #6b5c2a;
	--gold-deep: #7a672f;
	--ink: #0a0a0a;
	--muted: rgba(10, 10, 10, .6);
	--line: rgba(5, 11, 81, .14);
	--line-soft: rgba(5, 11, 81, .07);
	--shadow: 0 2px 4px rgba(5, 11, 81, .04), 0 12px 32px rgba(5, 11, 81, .06);
	--shadow-lift: 0 4px 10px rgba(5, 11, 81, .07), 0 20px 48px rgba(5, 11, 81, .1);

	--display: "Asul", Georgia, "Times New Roman", serif;
	--body: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	/* ---------------------------------------------------------------------
	   Type scale

	   The first pass picked sizes per component, which drifted: 11, 12, 13,
	   14, 15, 17, 19, 20, 21, 25px all appeared, several of them a single
	   pixel apart and none of them deliberate. These are the only sizes the
	   page uses now. Ratio is roughly 1.2, and the three display sizes are
	   fluid so the hero does not need its own breakpoint.
	   ------------------------------------------------------------------ */
	--t-eyebrow: 11px;   /* uppercase labels, letter-spaced */
	--t-tiny: 12px;      /* captions, meta, fine print */
	--t-small: 13px;     /* secondary UI text, prices in lists */
	--t-body: 15px;      /* default reading size */
	--t-lead: clamp(15px, 1.5vw, 17px);
	--t-h3: clamp(17px, 1.8vw, 19px);
	--t-h2: clamp(21px, 2.4vw, 27px);
	--t-h1: clamp(27px, 3.4vw, 40px);
	--t-figure: clamp(22px, 2.6vw, 28px);  /* totals, ladder headline */

	/* ---------------------------------------------------------------------
	   Spacing scale

	   4px base. Every margin, padding and gap below is one of these — the
	   previous mix of 4/6/7/8/10/11/12/14/16/18/20/22/24/26/28px made
	   vertical rhythm impossible to see or keep.
	   ------------------------------------------------------------------ */
	--s-1: 4px;
	--s-2: 8px;
	--s-3: 12px;
	--s-4: 16px;
	--s-5: 20px;
	--s-6: 24px;
	--s-8: 32px;
	--s-10: 40px;
	--s-12: 48px;

	/* Section rhythm: the vertical space between major blocks. */
	--s-section: clamp(40px, 6vw, 80px);

	--gap: clamp(var(--s-5), 4vw, var(--s-12));

	background: var(--ivory);
	color: var(--ink);
	font-family: var(--body);
	/* Flatsome sets a page-level line-height that is too tight for the
	   longer copy blocks here. */
	line-height: 1.6;
	/* Belt and braces: nothing inside may widen the page. clip, not hidden,
	   so no accidental scroll container is created; fixed children (bar,
	   toast, sheets) are viewport-positioned and unaffected. */
	overflow-x: clip;
}

.dmc-bb *,
.dmc-bb *::before,
.dmc-bb *::after {
	box-sizing: border-box;
}

.dmc-bb__wrap {
	width: 100%;
	max-width: 1240px;
	margin: 0 auto;
	padding-inline: clamp(var(--s-4), 4vw, var(--s-10));
}

.dmc-bb img {
	display: block;
	max-width: 100%;
	height: auto;
}

/* Flatsome's global heading rules would otherwise win on specificity in a
   few places; keeping our headings on one selector each avoids a scatter
   of overrides further down. */
.dmc-bb h1,
.dmc-bb h2,
.dmc-bb h3 {
	font-family: var(--display);
	font-weight: 400;
	color: var(--navy);
	margin: 0;
	letter-spacing: -.005em;
}

/* Every control that acts like a button gets the pointer cursor. Two were
   missing it — a browser default that reads as "not clickable". */
.dmc-bb button,
.dmc-bb a[href],
.dmc-bb [role="button"] {
	cursor: pointer;
}

/* Flatsome gives every <button> a ~15px phantom right margin. In our grids
   that margin was silently shaved off each tile's width — the family cards
   measured 136px where the grid maths said 152. Our layouts space things
   with gap, never with button margins. */
.dmc-bb button {
	margin: 0;
}

/* Keyboard focus, once, for everything interactive. Previously only the
   two tile types declared it, so tabbing through the panel, the thumbnails
   and the tabs left no visible trace of where focus was. */
.dmc-bb a:focus-visible,
.dmc-bb button:focus-visible,
.dmc-bb input:focus-visible,
.dmc-bb select:focus-visible,
.dmc-bb textarea:focus-visible {
	outline: 2px solid var(--navy);
	outline-offset: 2px;
}

/* -------------------------------------------------------------------------
   Hero
   ---------------------------------------------------------------------- */

.dmc-bb__hero {
	padding-block: var(--s-section) calc(var(--s-section) * .7);
}

.dmc-bb__hero-grid {
	display: grid;
	gap: var(--gap);
	grid-template-columns: 1fr;
	align-items: start;
}

/* Grid items default to min-width:auto, which lets any wide child widen
   the column silently. Both page grids opt out once, here. */
.dmc-bb__hero-grid > *,
.dmc-bb__layout > * {
	min-width: 0;
}

@media screen and (min-width: 900px) {
	.dmc-bb__hero-grid {
		grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
		gap: clamp(var(--s-8), 5vw, calc(var(--s-12) * 1.5));
	}

	/* Zdjecie zostaje w kadrze, kiedy prawa kolumna jest dluzsza.
	   Krotki opis produktu jest edytowalny przez klienta, wiec jego dlugosc
	   jest z definicji nieprzewidywalna — bez sticky dluga tresc zostawia
	   pol ekranu pustej kolumny i klient przewija obok niczego.

	   Offset: naglowek w stanie stuck ma 64px (Theme Options
	   header_height_sticky), plus oddech. Zmienna, bo ta wartosc zyje w
	   ustawieniach motywu i moze sie zmienic bez dotykania tego pliku.

	   align-self: start jest konieczne — element rozciagniety na cala
	   wysokosc wiersza gridu nie ma sie gdzie przykleic i sticky nie robi
	   nic. Kontener ma juz align-items: start, to jest jawne zabezpieczenie
	   na wypadek zmiany tamtej reguly.

	   Sticky dziala tu mimo overflow-x: clip na wrapperze — clip, w
	   odroznieniu od hidden/auto, nie tworzy kontenera przewijania. To jest
	   powod, dla ktorego tam stoi clip, i nie wolno tego zamienic na hidden. */
	.dmc-bb__gallery {
		position: sticky;
		top: var(--dmc-hero-sticky-top, 80px);
		align-self: start;
	}
}

/* Telefon: kolumny sa jedna pod druga, wiec przyklejone zdjecie zaslanialoby
   konfigurator. Jawne wylaczenie, gdyby ktos kiedys przesunal breakpoint. */
@media screen and (max-width: 899px) {
	.dmc-bb__gallery {
		position: static;
	}
}

.dmc-bb__shot {
	margin: 0;
	overflow: hidden;
	background: var(--sand);
	box-shadow: var(--shadow);
}

.dmc-bb__shot img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

.dmc-bb__thumbs {
	display: flex;
	gap: var(--s-1);
	margin-top: var(--s-2);
	overflow-x: auto;
	/* Thumbnails scroll rather than wrap so the hero keeps its height on
	   narrow screens; the scrollbar is hidden but the gesture still works. */
	scrollbar-width: none;
}

.dmc-bb__thumbs::-webkit-scrollbar {
	display: none;
}

.dmc-bb__thumb {
	flex: 0 0 auto;
	width: 72px;
	height: 72px;
	padding: 0;
	border: 1px solid var(--line-soft);
	background: var(--paper);
	cursor: pointer;
	opacity: .62;
	transition: opacity .2s ease, border-color .2s ease;
}

.dmc-bb__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.dmc-bb__thumb.is-on {
	opacity: 1;
	border-color: var(--navy);
}

/* Hover approaches the selected look without equalling it — full opacity
   plus navy border was identical to .is-on, so exploring read as choosing. */
.dmc-bb__thumb:hover:not(.is-on) {
	opacity: .85;
	border-color: rgba(5, 11, 81, .4);
}

.dmc-bb__eyebrow {
	margin: 0 0 var(--s-2);
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--gold-ink);
}

/* Down from clamp(34px, 6vw, 60px). At the old size the name ran to three
   lines and pushed the price and the CTA below the fold on a laptop — the
   headline was winning space from the things that actually convert. */
.dmc-bb__title {
	font-size: var(--t-h1);
	line-height: 1.1;
	margin-bottom: var(--s-3);
	/* Never wider than the column. A plain 18ch resolved to ~342px and, on
	   phones whose layout viewport is narrower than 375 (Chrome iOS page
	   zoom), it blew the grid column out past the screen — every text block
	   in the column then wrapped at that phantom width and clipped at the
	   right edge. Alex's device reproduced it; a 375px emulation cannot. */
	max-width: min(18ch, 100%);
}

/* The offer half of the product name, promoted out of the headline. */
.dmc-bb__badge {
	display: inline-block;
	margin: 0 0 var(--s-4);
	padding: var(--s-1) var(--s-3);
	background: rgba(178, 157, 81, .13);
	border-left: 2px solid var(--gold);
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--gold-ink);
}

.dmc-bb__lede {
	margin: 0 0 var(--s-5);
	font-size: var(--t-lead);
	color: var(--muted);
	max-width: 46ch;
}

/* Linia promocyjna z wlasnego pola (Hero promo line). Wizualnie mocniejsza
   od krotkiego opisu, bo to jest komunikat FOMO, a nie tresc pomocnicza —
   ale bez krzyku: ten hero ma juz plakietke i drabinke cenowa. */
.dmc-bb__promo {
	margin: 0 0 var(--s-5);
	font-size: var(--t-lead);
	line-height: 1.5;
	color: var(--navy);
	max-width: 46ch;
	overflow-wrap: anywhere;
}

.dmc-bb__promo strong,
.dmc-bb__promo b {
	color: var(--navy);
}

.dmc-bb__promo a {
	color: var(--navy);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Plakietki wolane z hero. Sam wyglad pastylki definiuje site.css (ta sama
   definicja co na kazdej innej stronie produktu) — tutaj tylko odstep, bo
   tam plakietki siedza nad formularzem koszyka, a nie w tej kolumnie. */
.dmc-bb__intro .dmc-badges {
	margin: 0 0 var(--s-3);
}

/* Krotki opis z wp-admin.
   Renderuje go funkcja rdzenia WooCommerce, wiec w srodku .dmc-bb__desc
   siedzi jeszcze JEJ wrapper (.woocommerce-product-details__short-description
   albo .product-short-description, zaleznie od tego, czy szablon nadpisuje
   Flatsome). Dlatego reguly celuja i w dzieci, i w wnuki — inaczej pierwszy
   akapit odbijalby sie od hero przez marginesy wrappera.

   Tresc pisze klient, wiec styl musi zniesc to, co da sie wkleic z Worda albo
   z czatu: naglowki, listy, <br>, obrazki, dlugie URL-e. */
.dmc-bb__desc {
	margin: 0 0 var(--s-5);
	font-size: var(--t-lead);
	color: var(--muted);
	max-width: 46ch;
	overflow-wrap: anywhere;
}

.dmc-bb__desc > *:first-child,
.dmc-bb__desc > * > *:first-child {
	margin-top: 0;
}

.dmc-bb__desc > *:last-child,
.dmc-bb__desc > * > *:last-child {
	margin-bottom: 0;
}

.dmc-bb__desc p {
	margin: 0 0 var(--s-3);
}

.dmc-bb__desc h1,
.dmc-bb__desc h2,
.dmc-bb__desc h3,
.dmc-bb__desc h4 {
	margin: var(--s-4) 0 var(--s-2);
	font-size: var(--t-lead);
	line-height: 1.3;
	color: var(--navy);
}

.dmc-bb__desc ul,
.dmc-bb__desc ol {
	margin: 0 0 var(--s-3);
	padding-left: 1.15em;
}

.dmc-bb__desc li {
	margin: 0 0 var(--s-1);
}

.dmc-bb__desc a {
	color: var(--navy);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Media wklejone przez klienta nie moga rozpychac kolumny hero. Wrapper
   strony ma overflow-x: clip, wiec bez tego szeroki element nie dostalby
   nawet paska przewijania — zostalby po prostu OBCIETY. */
.dmc-bb__desc img,
.dmc-bb__desc iframe,
.dmc-bb__desc video,
.dmc-bb__desc svg {
	max-width: 100%;
	height: auto;
}

.dmc-bb__desc table,
.dmc-bb__desc pre {
	display: block;
	max-width: 100%;
	overflow-x: auto;
}

/* -------------------------------------------------------------------------
   Price ladder
   ---------------------------------------------------------------------- */

.dmc-bb__ladder {
	margin: 0 0 var(--s-5);
	padding: var(--s-3) var(--s-4);
	background: var(--paper);
	border: 1px solid var(--line);
	box-shadow: var(--shadow);
}

.dmc-bb__ladder-lead {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--s-1) var(--s-3);
	margin: 0;
}

.dmc-bb__ladder-big {
	font-family: var(--display);
	/* One step below --t-figure. The ladder is supporting information, not
	   the page's headline — at 28px it competed with the h1 above it. */
	font-size: clamp(19px, 2vw, 23px);
	line-height: 1.2;
	color: var(--navy);
}

.dmc-bb__ladder-sub {
	font-size: var(--t-small);
	color: var(--muted);
}

.dmc-bb__ladder-note {
	margin: var(--s-1) 0 0;
	font-size: var(--t-small);
	color: var(--muted);
}

.dmc-bb__rules {
	list-style: none;
	margin: var(--s-3) 0 0;
	padding: var(--s-3) 0 0;
	border-top: 1px solid var(--line-soft);
	display: flex;
	flex-direction: column;
	gap: var(--s-1);
}

.dmc-bb__rules li {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	font-size: var(--t-small);
	color: var(--muted);
}

.dmc-bb__rules li span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 26px;
	height: 20px;
	padding: 0 6px;
	flex: 0 0 auto;
	background: rgba(5, 11, 81, .06);
	color: var(--navy);
	font-size: var(--t-tiny);
	font-weight: 700;
}

.dmc-bb__rules li.is-best {
	color: var(--ink);
	font-weight: 500;
}

.dmc-bb__rules li.is-best span {
	background: var(--gold-deep);
	color: #fff;
}

.dmc-bb__note {
	margin: var(--s-3) 0 0;
	font-size: var(--t-tiny);
	color: var(--muted);
}



/* Brand buttons are square, bold and uppercase — that is the site's
   signature and the one place this page does not modernise. */
.dmc-bb__cta,
.dmc-bb__add,
.dmc-bb__confirm-btn,
.dmc-bb__sticky-add {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--s-2);
	min-height: 52px;
	padding: var(--s-3) var(--s-6);
	border: 1px solid rgba(0, 0, 0, .05);
	border-radius: 0;
	font-family: var(--body);
	font-size: var(--t-small);
	font-weight: 700;
	letter-spacing: .06em;
	/* Flatsome hands buttons a ~2.4x line-height on mobile, which padded
	   these out to 57px of mostly empty leading. Pin it. */
	line-height: 1.2;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .2s ease, color .2s ease, transform .12s ease;
}

.dmc-bb__cta {
	background: var(--navy);
	color: #fff;
	width: 100%;
	max-width: 380px;
}

.dmc-bb__cta:hover {
	background: #0a1470;
	color: #fff;
}

.dmc-bb__cta:active {
	transform: translateY(1px);
}

.dmc-bb__facts {
	list-style: none;
	margin: var(--s-6) 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--s-2) var(--s-5);
	font-size: var(--t-small);
	color: var(--muted);
}

.dmc-bb__facts li {
	position: relative;
	padding-left: var(--s-4);
}

.dmc-bb__facts li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 8px;
	width: 6px;
	height: 6px;
	background: var(--gold);
	transform: rotate(45deg);
}

/* -------------------------------------------------------------------------
   Builder layout
   ---------------------------------------------------------------------- */

.dmc-bb__layout {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap);
	padding-block: calc(var(--s-section) * .7) calc(var(--s-section) * 1.4);
	scroll-margin-top: var(--s-12);
}

@media screen and (min-width: 980px) {
	.dmc-bb__layout {
		grid-template-columns: minmax(0, 1fr) 372px;
		align-items: start;
	}
}

.dmc-bb__stepline {
	margin-bottom: var(--s-6);
	padding-bottom: var(--s-4);
	border-bottom: 1px solid var(--line);
}

.dmc-bb__h2 {
	font-size: var(--t-h2);
	line-height: 1.15;
}

.dmc-bb__help {
	margin: var(--s-2) 0 0;
	color: var(--muted);
	font-size: var(--t-body);
}

.dmc-bb__step + .dmc-bb__step {
	margin-top: var(--s-10);
}

/* Qualified with the element, because the base `.dmc-bb h3 { margin: 0 }`
   reset outranks a lone class and had been silently zeroing this margin
   since the day it was written. */
.dmc-bb h3.dmc-bb__h3 {
	display: flex;
	align-items: center;
	gap: var(--s-3);
	font-size: var(--t-h3);
	margin-bottom: var(--s-8);
}

.dmc-bb__num {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	flex: 0 0 28px;
	border-radius: 50%;
	background: var(--navy);
	color: #fff;
	font-family: var(--body);
	font-size: var(--t-small);
	font-weight: 700;
}

/* -------------------------------------------------------------------------
   Box family cards
   ---------------------------------------------------------------------- */

.dmc-bb__families {
	display: grid;
	gap: var(--s-3);
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

/* The whole card is the control. The brief is explicit that customers must
   not have to hit a small checkbox, and session recordings showed rage
   clicks on the current page's ambiguous targets. */
.dmc-bb__family {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0;
	min-height: 44px;
	padding: 0;
	border: 1px solid var(--line);
	background: var(--paper);
	text-align: left;
	cursor: pointer;
	overflow: hidden;
	transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.dmc-bb__family:hover {
	border-color: rgba(5, 11, 81, .32);
	box-shadow: var(--shadow);
	transform: translateY(-2px);
}

.dmc-bb__family.is-on {
	border-color: var(--navy);
	box-shadow: 0 0 0 1px var(--navy), var(--shadow-lift);
}

.dmc-bb__family:focus-visible {
	outline: 2px solid var(--gold);
	outline-offset: 2px;
}

.dmc-bb__family-img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background: var(--sand);
}

.dmc-bb__family-body {
	padding: var(--s-3) var(--s-4) var(--s-4);
	display: flex;
	flex-direction: column;
	gap: var(--s-1);
	flex: 1 1 auto;
}

.dmc-bb__family-name {
	font-family: var(--display);
	/* Down again from --t-lead. Product names here run long ("Assorted Lava
	   Snow Skin Mooncakes") and at 17px they wrapped to three lines, making
	   the cards uneven and pushing the price out of alignment. */
	font-size: var(--t-body);
	line-height: 1.25;
	color: var(--navy);
}

.dmc-bb__family-meta {
	font-size: var(--t-tiny);
	color: var(--muted);
}

/* A fact about the box itself, not a count of what is inside it — darker
   than the option count so it does not read as more of the same meta. */
.dmc-bb__family-note {
	margin-top: var(--s-1);
	font-size: var(--t-tiny);
	font-weight: 600;
	line-height: 1.35;
	color: var(--gold-ink);
}

.dmc-bb__family-price {
	margin-top: auto;
	padding-top: var(--s-2);
	font-size: var(--t-body);
	font-weight: 600;
	color: var(--ink);
}

.dmc-bb__family-pick {
	display: block;
	padding: var(--s-2) var(--s-4);
	border-top: 1px solid var(--line-soft);
	background: transparent;
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--navy);
}

.dmc-bb__family.is-on .dmc-bb__family-pick {
	background: var(--navy);
	color: #fff;
}

/* Count badge for a family already represented in the bundle. */
.dmc-bb__family-tally {
	position: absolute;
	top: 10px;
	right: 10px;
	min-width: 26px;
	height: 26px;
	padding: 0 var(--s-2);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--gold);
	color: #fff;
	font-size: var(--t-tiny);
	font-weight: 700;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .18);
}

/* -------------------------------------------------------------------------
   Flavour tiles
   ---------------------------------------------------------------------- */

.dmc-bb__flavours {
	display: grid;
	gap: var(--s-2);
	grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
}

.dmc-bb__flavour {
	display: flex;
	align-items: center;
	gap: var(--s-3);
	/* 60px tall to clear the 44px minimum in the brief with room to spare. */
	min-height: 76px;
	padding: var(--s-2) var(--s-3);
	border: 1px solid var(--line);
	background: var(--paper);
	text-align: left;
	cursor: pointer;
	transition: border-color .18s ease, box-shadow .18s ease;
}

.dmc-bb__flavour:hover {
	border-color: rgba(5, 11, 81, .32);
	box-shadow: var(--shadow);
}

.dmc-bb__flavour.is-on {
	border-color: var(--navy);
	box-shadow: 0 0 0 1px var(--navy);
	background: #fff;
}

.dmc-bb__flavour:focus-visible {
	outline: 2px solid var(--gold);
	outline-offset: 2px;
}

.dmc-bb__flavour[disabled] {
	opacity: .45;
	cursor: not-allowed;
}

.dmc-bb__flavour-img {
	width: 56px;
	height: 56px;
	flex: 0 0 56px;
	object-fit: cover;
	background: var(--sand);
}

.dmc-bb__flavour-copy {
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: var(--s-1);
}

.dmc-bb__flavour-name {
	font-size: var(--t-body);
	line-height: 1.35;
	color: var(--ink);
}

.dmc-bb__flavour-price {
	font-size: var(--t-small);
	font-weight: 600;
	color: var(--navy);
}

.dmc-bb__was {
	margin-left: var(--s-2);
	font-weight: 400;
	color: var(--muted);
	text-decoration: line-through;
}

.dmc-bb__oos {
	font-size: var(--t-eyebrow);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--muted);
}

.dmc-bb__confirm {
	margin-top: var(--s-5);
}

.dmc-bb__confirm-btn {
	background: var(--gold);
	color: #fff;
	width: 100%;
	max-width: 460px;
}

.dmc-bb__confirm-btn:hover {
	background: #9c8843;
}

/* -------------------------------------------------------------------------
   Summary panel
   ---------------------------------------------------------------------- */

@media screen and (min-width: 980px) {
	.dmc-bb__panel {
		position: sticky;
		/* Clears the sticky header, which is capped at 68px. */
		top: 88px;
	}
}

.dmc-bb__panel-inner {
	background: var(--paper);
	border: 1px solid var(--line);
	box-shadow: var(--shadow);
	padding: var(--s-5);
}

.dmc-bb__panel-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--s-3);
	margin-bottom: var(--s-1);
}

.dmc-bb__panel-title {
	/* Not --t-h2: the panel is a 372px sidebar and a 27px heading beside
	   13px line items reads as a second page title competing with the h1. */
	font-size: var(--t-h3);
}

.dmc-bb__count {
	font-size: var(--t-tiny);
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--muted);
	/* "1 BOX" was breaking into two stacked words beside the title. */
	white-space: nowrap;
	flex: 0 0 auto;
}

.dmc-bb__lines {
	display: flex;
	flex-direction: column;
	gap: var(--s-3);
	margin-bottom: var(--s-4);
}

.dmc-bb__empty {
	margin: 0;
	padding: var(--s-1) 0 var(--s-1);
	font-size: var(--t-small);
	color: var(--muted);
}

/* One row per box. Block flow, not a grid: with no thumbnail the name can
   take the full panel width, and the controls sit on their own line beneath
   it — the proportions the mockup uses. Rows dropped from 115px to roughly
   90px in the process, because names stopped wrapping to three lines. */
.dmc-bb__line {
	display: block;
	padding-bottom: var(--s-4);
	border-bottom: 1px solid var(--line-soft);
}

.dmc-bb__line:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.dmc-bb__line-idx {
	display: block;
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--gold-ink);
	margin-bottom: var(--s-1);
}

.dmc-bb__line-name {
	display: block;
	font-size: var(--t-body);
	font-weight: 700;
	line-height: 1.3;
	color: var(--ink);
}

.dmc-bb__line-sub {
	display: block;
	font-size: var(--t-small);
	line-height: 1.4;
	color: var(--muted);
	margin-bottom: var(--s-3);
}

.dmc-bb__line-foot {
	display: flex;
	align-items: center;
	gap: var(--s-3);
}

.dmc-bb__line-price {
	/* Pushed to the trailing edge so every row's price lines up, which is
	   what makes a summary scannable. */
	margin-left: auto;
	font-size: var(--t-body);
	font-weight: 700;
	white-space: nowrap;
}

.dmc-bb__remove {
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--body);
	font-size: var(--t-small);
	color: var(--muted);
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}

.dmc-bb__remove:hover {
	color: var(--navy);
}

.dmc-bb__qty {
	display: flex;
	align-items: center;
	gap: 2px;
	padding: 2px;
	border: 1px solid var(--line);
}

/* Visually 28px, tappable at 44px.
 *
 * The previous version made the button itself 44x44 to satisfy the touch
 * minimum, which is the literal reading of the rule and looked awful: the
 * quantity stepper became the heaviest object in the panel and outweighed
 * the price beside it. The ::after pseudo-element extends the hit area
 * past the visible bounds instead, so the target is still 44x44 for a
 * thumb while the control reads as the small utility it is.
 */
.dmc-bb__qty button {
	position: relative;
	/* 20px was too small to hit reliably. 28px reads as a utility control
	   without being a target you have to aim at. */
	width: 28px;
	height: 28px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--navy);
	font-size: var(--t-small);
	line-height: 1;
	cursor: pointer;
	transition: color .15s ease;
}

.dmc-bb__qty button::after {
	content: "";
	position: absolute;
	/* 28 + 8 + 8 = 44 tall. Horizontally +5px each side keeps the two
	   zones from meeting across the 2px gap — overlapping hit areas made
	   a tap near the count trigger whichever button painted last. */
	inset: -8px -5px;
}

/* Colour shift only — a filled hover block on a 28px button reads as a
   selected state rather than a hover. */
.dmc-bb__qty button:hover {
	color: var(--gold-ink);
	background: transparent;
}

.dmc-bb__qty button:disabled {
	opacity: .4;
}

.dmc-bb__qty span {
	min-width: 26px;
	text-align: center;
	font-size: var(--t-small);
	font-weight: 600;
	/* Tabular figures so the box does not resize between 9 and 10. */
	font-variant-numeric: tabular-nums;
}

.dmc-bb__totals {
	margin: 0 0 var(--s-4);
	padding-top: var(--s-3);
	border-top: 1px solid var(--line);
}

.dmc-bb__totals > div {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--s-3);
}

.dmc-bb__totals dt {
	font-size: var(--t-small);
	color: var(--muted);
	margin: 0;
	font-weight: 500;
}

.dmc-bb__totals dd {
	margin: 0;
	font-family: var(--display);
	font-size: var(--t-figure);
	color: var(--navy);
}

.dmc-bb__save {
	margin-top: var(--s-1);
}

.dmc-bb__save dd {
	font-family: var(--body);
	font-size: var(--t-body);
	font-weight: 700;
	color: var(--olive-ink);
}

.dmc-bb__form {
	margin: 0;
}

.dmc-bb__add {
	background: var(--gold);
	color: #fff;
	width: 100%;
	/* Full-width already carries the weight — it does not need the height
	   too. 48px stays clear of the 44px touch minimum. */
	min-height: 48px;
	padding: var(--s-2) var(--s-5);
}

.dmc-bb__add:hover:not(:disabled) {
	background: #9c8843;
}

/* Disabled still states what is missing — an inert button was the specific
   complaint about the current page. The label is set from JS. */
/* A disabled control is exempt from contrast rules, but this one carries
   the instruction telling the customer what is still missing — so it is
   held to the same 4.5:1 as any other text. */
.dmc-bb__add:disabled {
	background: var(--sand);
	color: rgba(10, 10, 10, .72);
	cursor: not-allowed;
}

.dmc-bb__reassure {
	margin: var(--s-3) 0 0;
	font-size: var(--t-tiny);
	text-align: center;
	color: var(--muted);
}

/* -------------------------------------------------------------------------
   Rating and featured review
   -------------------------------------------------------------------------
   The stars are one text node clipped by a gradient, with the fill driven by
   a --dmc-fill custom property set inline from the real average. A row of
   five separate glyphs cannot show 4.7; this can, and it stays selectable
   text with the accessible name carried by the surrounding markup.
   ---------------------------------------------------------------------- */

.dmc-bb__stars {
	background: linear-gradient(
		90deg,
		var(--gold) 0,
		var(--gold) var(--dmc-fill, 100%),
		rgba(10, 10, 10, .18) var(--dmc-fill, 100%)
	);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	letter-spacing: .1em;
	/* Sits slightly above the baseline of the number beside it. */
	line-height: 1;
}

.dmc-bb__rating {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--s-2);
	margin: 0 0 var(--s-4);
	font-size: var(--t-small);
}

.dmc-bb__rating-num {
	font-weight: 700;
	color: var(--ink);
}

.dmc-bb__rating-link {
	color: var(--muted);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.dmc-bb__rating-link:hover {
	color: var(--navy);
}

.dmc-bb__quote-wrap {
	background: var(--sand);
	padding-block: var(--s-section);
}

.dmc-bb__quote {
	max-width: 46rem;
	margin: 0 auto;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--s-4);
}

.dmc-bb__stars--lg {
	font-size: var(--t-h3);
}

.dmc-bb__quote blockquote {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	quotes: none;
}

.dmc-bb__quote blockquote p {
	margin: 0;
	font-family: var(--display);
	/* Deliberately larger than any body copy on the page — this is the one
	   place a customer's own words should outweigh ours. */
	font-size: var(--t-h2);
	line-height: 1.45;
	color: var(--navy);
}

/* Typographic quotes drawn in, rather than typed into the database value,
   so the stored review text stays exactly what the customer wrote. */
.dmc-bb__quote blockquote p::before {
	content: "\201C";
}

.dmc-bb__quote blockquote p::after {
	content: "\201D";
}

.dmc-bb__quote figcaption {
	display: flex;
	flex-direction: column;
	gap: var(--s-1);
}

.dmc-bb__quote-name {
	font-size: var(--t-small);
	font-weight: 700;
	letter-spacing: .04em;
	color: var(--ink);
}

.dmc-bb__quote-meta {
	font-size: var(--t-eyebrow);
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--muted);
}

.dmc-bb__quote-link {
	font-size: var(--t-small);
	color: var(--navy);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* -------------------------------------------------------------------------
   Product tabs — Description / Additional information / Reviews
   -------------------------------------------------------------------------
   These are WooCommerce's own markup, so the selectors are the plugin's and
   not ours. Flatsome already styles them for the product page; the rules
   here re-dress that markup to match the builder without touching how the
   real product page looks, because everything is scoped under .dmc-bb.
   ---------------------------------------------------------------------- */

.dmc-bb__tabs-wrap {
	background: var(--paper);
	border-top: 1px solid var(--line);
	padding-block: var(--s-section) var(--s-section);
}

.dmc-bb .woocommerce-tabs {
	margin: 0;
	padding: 0;
}

/* Tab strip. Scrolls sideways on narrow screens rather than wrapping into
   a ragged second row. */
.dmc-bb .woocommerce-tabs ul.tabs {
	display: flex;
	gap: clamp(var(--s-5), 3vw, var(--s-10));
	margin: 0 0 var(--s-6);
	padding: 0 0 0;
	list-style: none;
	border-bottom: 1px solid var(--line);
	overflow-x: auto;
	scrollbar-width: none;
}

.dmc-bb .woocommerce-tabs ul.tabs::-webkit-scrollbar {
	display: none;
}

/* Flatsome draws pills, dividers and a background on these; all of it has
   to come off before our own treatment reads cleanly. */
.dmc-bb .woocommerce-tabs ul.tabs li {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	border-radius: 0;
	flex: 0 0 auto;
}

/* Flatsome marks the active tab with its own 3px navy bar drawn as
   a::before at top:0. We already indicate the active tab with a gold
   underline (a::after), so the two stacked — a heavy navy rule above the
   label and a thin gold one below it. The plugin's goes. */
.dmc-bb .woocommerce-tabs ul.tabs li::before,
.dmc-bb .woocommerce-tabs ul.tabs li::after,
.dmc-bb .woocommerce-tabs ul.tabs li a::before {
	display: none;
}

.dmc-bb .woocommerce-tabs ul.tabs li a {
	display: block;
	padding: 0 0 var(--s-3);
	border: 0;
	background: none;
	font-family: var(--body);
	font-size: var(--t-tiny);
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--muted);
	text-decoration: none;
	white-space: nowrap;
	position: relative;
	transition: color .18s ease;
}

.dmc-bb .woocommerce-tabs ul.tabs li a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -1px;
	height: 2px;
	background: var(--gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .2s ease;
}

.dmc-bb .woocommerce-tabs ul.tabs li a:hover {
	color: var(--navy);
}

.dmc-bb .woocommerce-tabs ul.tabs li.active a,
.dmc-bb .woocommerce-tabs ul.tabs li.is-active a {
	color: var(--navy);
}

.dmc-bb .woocommerce-tabs ul.tabs li.active a::after,
.dmc-bb .woocommerce-tabs ul.tabs li.is-active a::after {
	transform: scaleX(1);
}

/* Panels
 *
 * No max-width here. An earlier version capped every panel at 78ch for
 * readable line length, which is right for prose and wrong for everything
 * else: Reviews is a two-column layout (list + form) and Additional
 * information is a data table, and both were squeezed into 737px of a
 * 1240px container, leaving 503px empty. The cap now applies only to the
 * panel that is actually prose.
 */
.dmc-bb .woocommerce-tabs .panel {
	margin: 0;
	padding: 0;
	font-size: var(--t-body);
	color: var(--ink);
}

/* Description is running text, so it keeps a comfortable measure. */
.dmc-bb .woocommerce-Tabs-panel--description {
	max-width: 78ch;
}

.dmc-bb .woocommerce-tabs .panel h2,
.dmc-bb .woocommerce-tabs .panel h3 {
	font-family: var(--display);
	font-size: var(--t-h2);
	color: var(--navy);
	margin: 0 0 var(--s-3);
}

.dmc-bb .woocommerce-tabs .panel p {
	margin: 0 0 var(--s-3);
	line-height: 1.7;
}

.dmc-bb .woocommerce-tabs .panel ul,
.dmc-bb .woocommerce-tabs .panel ol {
	margin: 0 0 var(--s-4) var(--s-4);
	line-height: 1.7;
}

/* Additional information table */
.dmc-bb .woocommerce-tabs table.shop_attributes {
	width: 100%;
	border: 0;
	border-collapse: collapse;
}

.dmc-bb .woocommerce-tabs table.shop_attributes th,
.dmc-bb .woocommerce-tabs table.shop_attributes td {
	padding: var(--s-3) 0;
	border: 0;
	border-bottom: 1px solid var(--line-soft);
	text-align: left;
	font-size: var(--t-body);
	vertical-align: top;
}

.dmc-bb .woocommerce-tabs table.shop_attributes th {
	width: 34%;
	font-weight: 600;
	color: var(--navy);
}

.dmc-bb .woocommerce-tabs table.shop_attributes td p {
	margin: 0;
}

/* Reviews */
.dmc-bb #reviews .commentlist {
	list-style: none;
	margin: 0 0 var(--s-6);
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--s-4);
}

.dmc-bb #reviews .commentlist li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.dmc-bb #reviews .comment_container {
	display: flex;
	gap: var(--s-3);
	padding: var(--s-4) var(--s-4);
	background: var(--ivory);
	border: 1px solid var(--line-soft);
}

.dmc-bb #reviews .comment_container img.avatar {
	width: 42px;
	height: 42px;
	flex: 0 0 42px;
	border-radius: 50%;
	position: static;
	margin: 0;
	padding: 0;
	border: 0;
}

.dmc-bb #reviews .comment-text {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

.dmc-bb #reviews .woocommerce-review__author {
	font-weight: 700;
	color: var(--navy);
}

.dmc-bb #reviews .woocommerce-review__published-date {
	color: var(--muted);
	font-size: var(--t-tiny);
}

.dmc-bb #reviews .star-rating span::before,
.dmc-bb .woocommerce-tabs .star-rating span::before {
	color: var(--gold);
}

.dmc-bb #review_form_wrapper {
	padding-top: var(--s-2);
}

.dmc-bb #reviews .comment-reply-title {
	font-family: var(--display);
	font-size: var(--t-h3);
	color: var(--navy);
}

.dmc-bb #reviews input[type="text"],
.dmc-bb #reviews input[type="email"],
.dmc-bb #reviews textarea {
	border-radius: 0;
	border: 1px solid var(--line);
	background: var(--paper);
}

.dmc-bb #reviews .form-submit input[type="submit"] {
	border-radius: 0;
	background: var(--navy);
	color: #fff;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
}

/* -------------------------------------------------------------------------
   Mobile sticky bar
   ---------------------------------------------------------------------- */

/* Reserve room for the fixed bar. Measured at 375px it is 110px tall while
   the layout only left 56px of bottom padding, so the bar sat on top of the
   last rows of the summary — including the Add to cart button it duplicates.
   The variable is read by the sections above it, so the reservation lives in
   one place. */
@media screen and (max-width: 979px) {
	.dmc-bb__layout,
	.dmc-bb__tabs-wrap {
		padding-bottom: calc(88px + env(safe-area-inset-bottom));
	}
}

/* Mobile sticky bar.
 *
 * The first version repeated the panel's own button verbatim — the screen
 * said "ADD 1 MORE BOX" twice, once in the summary and once fixed to the
 * bottom, which reads as a broken duplicate rather than a shortcut. The
 * mockup splits the job: the left side reports state, the right side is a
 * single stable action. The action label never changes, so it stops being
 * a second copy of the instruction.
 */
.dmc-bb__sticky {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 90;
	background: var(--paper);
	border-top: 1px solid var(--line);
	box-shadow: 0 -4px 18px rgba(5, 11, 81, .14);
	padding-bottom: env(safe-area-inset-bottom);
}

@media screen and (min-width: 980px) {
	/* The desktop column already carries its own Add to Cart. */
	.dmc-bb__sticky {
		display: none;
	}
}

/* Progress, mirrored from the panel so the state is legible without
   scrolling back up to it. */
.dmc-bb__sticky-track {
	display: flex;
	gap: 3px;
	height: 4px;
}

.dmc-bb__sticky-seg {
	flex: 1 1 0;
	background: rgba(5, 11, 81, .12);
	transition: background-color .3s ease;
}

.dmc-bb__sticky-seg.is-on {
	background: var(--gold);
}

.dmc-bb.is-ready .dmc-bb__sticky-seg.is-on {
	background: var(--olive);
}

/* Removed from view: the segments above and the status text already carry
   the same fact, and on a real phone this third repetition plus its padding
   helped push the bar toward a third of the screen. */
.dmc-bb__sticky-step {
	display: none;
}

.dmc-bb.is-ready .dmc-bb__sticky-step {
	color: var(--olive-ink);
}

.dmc-bb__sticky-row {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	padding: var(--s-2) var(--s-3);
}

.dmc-bb__sticky-copy {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	min-width: 0;
	flex: 1 1 auto;
	/* It is a button now, so the browser defaults have to come off. */
	padding: 0;
	border: 0;
	background: none;
	text-align: left;
	font-family: inherit;
	/* 48px so the whole state area is a comfortable target, not just the
	   chevron glyph. */
	min-height: 48px;
}

.dmc-bb__sticky-copy-text {
	display: flex;
	flex-direction: column;
	gap: 1px;
	min-width: 0;
}

.dmc-bb__chev {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	flex: 0 0 30px;
	border-radius: 50%;
	background: var(--sand);
	color: var(--navy);
	transition: transform .24s ease;
}

.dmc-bb__sticky-copy[aria-expanded="true"] .dmc-bb__chev {
	transform: rotate(180deg);
}

/* A 48px control with no pointer feedback read as static text. */
.dmc-bb__sticky-copy:hover .dmc-bb__chev {
	background: var(--navy);
	color: #fff;
}

.dmc-bb__sticky-copy:active .dmc-bb__chev {
	transform: scale(.92);
}

.dmc-bb__sticky-copy[aria-expanded="true"]:active .dmc-bb__chev {
	transform: rotate(180deg) scale(.92);
}

.dmc-bb__sticky-status {
	font-size: var(--t-tiny);
	font-weight: 700;
	color: var(--navy);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.dmc-bb__sticky-total {
	font-size: var(--t-tiny);
	color: var(--muted);
	/* One line, ellipsised — wrapping here is what grew the bar. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.dmc-bb__sticky-add {
	flex: 0 0 auto;
	min-height: 44px;
	padding: 0 var(--s-4);
	font-size: var(--t-eyebrow);
	background: var(--navy);
	color: #fff;
}

.dmc-bb__sticky-add:disabled {
	background: var(--sand);
	color: rgba(10, 10, 10, .72);
}

/* -------------------------------------------------------------------------
   Order details sheet (mobile)
   -------------------------------------------------------------------------
   A bottom sheet rather than a scroll-to-panel: on a phone the summary sits
   far below the builder, and jumping there loses the customer's place in
   the list they were choosing from. The sheet shows the same lines without
   moving them anywhere.
   ---------------------------------------------------------------------- */

.dmc-bb__sheet-wrap {
	position: fixed;
	inset: 0;
	/* Above the theme chrome. z-index:100 lost to Flatsome's header and the
	   mystickymenu plugin, so on a phone the sheet's own header — close
	   button included — rendered UNDERNEATH the site header: a modal whose
	   navigation was buried. A modal owns the whole screen or it is not a
	   modal. */
	z-index: 99999;
}

@media screen and (min-width: 980px) {
	/* The desktop panel is always on screen; a sheet would duplicate it. */
	.dmc-bb__sheet-wrap {
		display: none;
	}
}

.dmc-bb__scrim {
	position: absolute;
	inset: 0;
	/* It is a button now, for keyboard and screen-reader dismissal. */
	border: 0;
	padding: 0;
	/* 55% — strong enough to isolate the sheet without hiding that the page
	   is still there behind it. */
	background: rgba(5, 11, 81, .55);
	animation: dmc-fade .22s ease;
}

.dmc-bb__sheet {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	flex-direction: column;
	/* dvh where supported: on iOS, plain vh includes the collapsed URL-bar
	   region, so an 88vh bottom-anchored sheet poked its header above the
	   visible screen — the close button lived in the hidden strip. */
	max-height: 78vh;
	max-height: 78dvh;
	background: var(--paper);
	border-radius: 14px 14px 0 0;
	box-shadow: 0 -10px 40px rgba(5, 11, 81, .28);
	/* No translateY entrance. The dmc-rise animation could wedge at its
	   from-frame (transform stuck at translateY(100%)), leaving the whole
	   sheet parked below the viewport with its content painting through.
	   A stuck fade is a cosmetic bug; a stuck slide is a broken modal —
	   the sheet appears instantly and only the scrim fades. */
	animation: dmc-fade .2s ease;
	/* The sheet sits above the bar (z100 vs z90), so it does not need to
	   clear it — the old 112px reservation only starved 78vh viewports. */
	padding-bottom: calc(var(--s-8) + env(safe-area-inset-bottom));
}

@keyframes dmc-fade {
	from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.dmc-bb__scrim,
	.dmc-bb__sheet {
		animation: none;
	}
}

/* Hard guarantee, independent of any animation state. */
.dmc-bb__sheet {
	transform: none !important;
}

/* The dialog container takes programmatic focus on open (tabindex=-1), so
   the close button no longer wears a permanent focus ring. The container
   itself shows none — Escape and the ring-on-Tab still work. */
.dmc-bb__sheet:focus {
	outline: none;
}

.dmc-bb__sheet-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--s-3);
	padding: var(--s-5) var(--s-4) var(--s-3);
	border-bottom: 1px solid var(--line-soft);
}

.dmc-bb__sheet-eyebrow {
	margin: 0 0 var(--s-1);
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--gold-ink);
}

.dmc-bb__sheet-title {
	font-family: var(--display);
	font-size: var(--t-h2);
	color: var(--navy);
	margin: 0;
}

.dmc-bb__sheet-close {
	flex: 0 0 44px;
	width: 44px;
	height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 50%;
	background: var(--sand);
	color: var(--navy);
}

.dmc-bb__sheet-body {
	overflow-y: auto;
	/* Vertical only. The list could be dragged sideways on a phone — rows
	   floated left-right under the finger — because touch panning is
	   unconstrained by default and any sub-pixel overflow gives it
	   somewhere to go. pan-y hands the browser one axis, overflow-x kills
	   the slack, and overscroll containment stops the page behind from
	   picking up the gesture when the list hits its end. */
	overflow-x: hidden;
	touch-action: pan-y;
	overscroll-behavior: contain;
	padding: var(--s-4);
	-webkit-overflow-scrolling: touch;
	/* Flex children refuse to shrink below content without this, and the
	   list would push the footer out of the capped sheet instead of
	   scrolling. */
	min-height: 0;
}

/* Nothing inside a sheet may paint or pan outside it. */
.dmc-bb__sheet {
	overflow: hidden;
}

/* Set on <body> while the sheet is open so the page behind cannot scroll. */
.dmc-bb-locked {
	overflow: hidden;
}

/* The chat bubble ignores our stacking and floated over the open sheet's
   rows. While any sheet is up it has no business on screen. */
.dmc-bb-locked .ht-ctc.ht-ctc-chat {
	display: none !important;
}

/* -------------------------------------------------------------------------
   Toast
   ---------------------------------------------------------------------- */

/* The confirmation pill. Fully rounded on purpose — it is the one element
   that is not part of the page surface, and the shape says "notification"
   before a word is read. Buttons stay square; this is not a button. */
.dmc-bb__toast {
	position: fixed;
	left: 50%;
	/* Above the sticky bar, not inside it: the bar measures 110px and the
	   old 92px offset buried the toast's lower edge in it. Same reservation
	   as the layout uses, same safe-area. */
	bottom: calc(88px + env(safe-area-inset-bottom));
	z-index: 95;
	display: flex;
	align-items: center;
	gap: var(--s-3);
	width: max-content;
	max-width: min(92vw, 640px);
	padding: var(--s-3) var(--s-3) var(--s-3) var(--s-5);
	border-radius: 999px;
	background: #2d5738;
	color: #fff;
	box-shadow: 0 8px 28px rgba(5, 11, 81, .22);
	transform: translate(-50%, 12px);
	opacity: 0;
	pointer-events: none;
	transition: opacity .22s ease, transform .22s ease;
}

.dmc-bb__toast.is-on {
	opacity: 1;
	transform: translate(-50%, 0);
	/* Only clickable once visible, or the hidden pill would swallow taps. */
	pointer-events: auto;
}

.dmc-bb__toast-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	flex: 0 0 34px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .16);
	color: #fff;
}

.dmc-bb__toast-copy {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.dmc-bb__toast-title {
	font-size: var(--t-small);
	font-weight: 700;
	line-height: 1.3;
}

.dmc-bb__toast-sub {
	font-size: var(--t-tiny);
	color: rgba(255, 255, 255, .82);
	line-height: 1.3;
}

.dmc-bb__toast-cta {
	flex: 0 0 auto;
	min-height: 40px;
	padding: 0 var(--s-5);
	border: 0;
	border-radius: 999px;
	background: #fff;
	color: #2d5738;
	font-family: var(--body);
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color .18s ease;
}

.dmc-bb__toast-cta:hover {
	background: #eef3ef;
}

@media screen and (max-width: 979px) {
	/* The sticky bar exists across this whole range, and it already carries
	   Add to cart — a second one in the toast made three on screen between
	   641 and 979px. The toast stays informational wherever the bar shows. */
	.dmc-bb__toast-cta {
		display: none;
	}
}

@media screen and (min-width: 980px) {
	.dmc-bb__toast {
		bottom: 32px;
	}
}

/* -------------------------------------------------------------------------
   Progress toward the discount
   ---------------------------------------------------------------------- */

.dmc-bb__progress {
	margin-bottom: var(--s-4);
}

/* 8px, not 4px, and always visible.
 *
 * At 4px with a 0% fill the bar rendered as a hairline and read as a stray
 * divider rather than as progress — the first thing a customer sees is the
 * empty state, so the empty state has to look like a track waiting to fill.
 * The inset shadow gives it depth at zero; the fill then has somewhere
 * obvious to grow into. */
/* Segmented, not a continuous bar.
 *
 * Two earlier attempts — an animated percentage width, then transform:
 * scaleX — both rendered as a zero-width element in this theme's context,
 * so the bar was invisible no matter what the state said. Segments need
 * neither: each is a flex child that either carries the fill colour or
 * does not. They also read better at this scale, because "1 of 2 done" is
 * clearer as two blocks than as a half-filled line.
 */
.dmc-bb__progress-track {
	display: flex;
	gap: 4px;
	height: 8px;
}

.dmc-bb__progress-seg {
	flex: 1 1 0;
	background: rgba(5, 11, 81, .12);
	transition: background-color .3s ease;
}

.dmc-bb__progress-seg.is-on {
	background: var(--gold);
}

.dmc-bb__progress.is-unlocked .dmc-bb__progress-seg.is-on {
	background: var(--olive);
}

.dmc-bb__progress-label {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	margin: var(--s-2) 0 0;
	font-size: var(--t-tiny);
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--muted);
}

.dmc-bb__progress.is-unlocked .dmc-bb__progress-label {
	color: #4d6b38;
}

.dmc-bb__progress.is-unlocked .dmc-bb__progress-label::before {
	content: "✓";
	font-weight: 700;
}

.dmc-bb-missing {
	max-width: 640px;
	margin: var(--s-section) auto;
	padding: 0 var(--s-5);
	text-align: center;
}

/* -------------------------------------------------------------------------
   Motion preferences
   ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.dmc-bb *,
	.dmc-bb *::before,
	.dmc-bb *::after {
		transition-duration: .01ms !important;
		animation-duration: .01ms !important;
	}

	.dmc-bb__family:hover {
		transform: none;
	}
}

/* -------------------------------------------------------------------------
   Micro-motion
   -------------------------------------------------------------------------
   Two gestures only: a press acknowledges the tap, and flavour tiles enter
   with a 30ms stagger — but only when the customer opens a DIFFERENT box.
   Re-renders within the same list (selecting a tile) carry .is-static so
   the entrance never replays under their finger.
   ---------------------------------------------------------------------- */

@keyframes dmc-tile-in {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
}

.dmc-bb__flavours:not(.is-static) .dmc-bb__flavour {
	animation: dmc-tile-in .26s cubic-bezier(.22, .61, .36, 1) backwards;
}

.dmc-bb__family:active {
	transform: translateY(0) scale(.985);
}

.dmc-bb__flavour:active:not(:disabled),
.dmc-bb__cta:active,
.dmc-bb__confirm-btn:active,
.dmc-bb__add:active:not(:disabled),
.dmc-bb__sticky-add:active:not(:disabled) {
	transform: scale(.985);
	transition: transform .1s ease;
}

@media (prefers-reduced-motion: reduce) {
	/* The global .01ms rule shrinks the duration but leaves the stagger
	   delays, which would hold tiles invisible for up to 200ms. Off means
	   off. */
	.dmc-bb__flavours .dmc-bb__flavour {
		animation: none !important;
	}
}

/* -------------------------------------------------------------------------
   Click-to-Chat coexistence
   -------------------------------------------------------------------------
   The WhatsApp plugin pins itself to the same corner as the sticky bar's
   CTA. This stylesheet loads only on the builder URL, so lifting it here
   moves it above the bar on this page without touching the rest of the
   site. !important because the plugin positions with inline styles.
   Targets the shared .ht-ctc classes, never the per-device element — see
   the stack notes.
   ---------------------------------------------------------------------- */

@media screen and (max-width: 979px) {
	.ht-ctc.ht-ctc-chat {
		bottom: calc(88px + env(safe-area-inset-bottom)) !important;
	}
}

/* ---------- Breadcrumbs ---------- */

.dmc-bb__crumbs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s-2);
	margin-bottom: var(--s-5);
	font-size: var(--t-tiny);
	color: var(--muted);
}

.dmc-bb__crumbs a {
	color: var(--muted);
	text-decoration: none;
}

.dmc-bb__crumbs a:hover {
	color: var(--navy);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.dmc-bb__crumbs [aria-current] {
	color: var(--ink);
}

/* ---------- Gift card ---------- */

.dmc-bb__gift {
	margin: var(--s-4) 0 0;
	border-top: 1px solid var(--line-soft);
	padding-top: var(--s-3);
}

.dmc-bb__gift textarea {
	width: 100%;
	border: 1px solid var(--line);
	border-radius: 0;
	background: var(--paper);
	font-family: var(--body);
	font-size: var(--t-body);
	color: var(--ink);
	padding: var(--s-2) var(--s-3);
	min-height: 44px;
}

.dmc-bb__gift textarea {
	resize: vertical;
}

/* ---------- See how much you save ---------- */

.dmc-bb__savewrap {
	padding-block: 0 var(--s-8);
}

.dmc-bb__savedetails {
	border: 1px solid var(--line);
	background: var(--paper);
}

.dmc-bb__savedetails summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-3);
	min-height: 52px;
	padding: var(--s-3) var(--s-4);
	cursor: pointer;
	list-style: none;
	font-family: var(--display);
	font-size: var(--t-h3);
	color: var(--navy);
}

.dmc-bb__savedetails summary::-webkit-details-marker {
	display: none;
}

.dmc-bb__savedetails summary svg {
	flex: 0 0 auto;
	transition: transform .2s ease;
}

.dmc-bb__savedetails[open] summary svg {
	transform: rotate(180deg);
}

.dmc-bb__savetable {
	width: 100%;
	border-collapse: collapse;
	margin: 0;
	font-size: var(--t-small);
}

.dmc-bb__savetable th,
.dmc-bb__savetable td {
	padding: var(--s-3) var(--s-4);
	text-align: left;
	vertical-align: middle;
	border-top: 1px solid var(--line-soft);
	font-variant-numeric: tabular-nums;
}

.dmc-bb__savetable th {
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--muted);
}

.dmc-bb__savetable s {
	color: var(--muted);
}

.dmc-bb__savetable .is-final {
	font-weight: 700;
	color: var(--navy);
}

/* The condition on the bundle price sat loose under the last row, reading
   like a stray table row rather than a note about the table. A tinted band
   with a marker closes the card and marks it as an aside; the left padding
   matches the Box column so the two share an edge. */
.dmc-bb__savedetails > .dmc-bb__note {
	display: flex;
	align-items: flex-start;
	gap: var(--s-2);
	margin: 0;
	padding: var(--s-3) var(--s-5);
	background: var(--sand);
	line-height: 1.5;
}

.dmc-bb__savedetails > .dmc-bb__note::before {
	content: "";
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	margin-top: 1px;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23050b51' stroke-width='1.4'%3E%3Ccircle cx='8' cy='8' r='6.6'/%3E%3Cpath d='M8 7.4v4.1' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='4.8' r='.9' fill='%23050b51' stroke='none'/%3E%3C/svg%3E") center / contain no-repeat;
	opacity: .55;
}

/* Savings polish: the teaser answers "why open this?" from the closed
   state, and the save column is the one number the section exists for. */
.dmc-bb__saveteaser {
	margin-left: auto;
	font-family: var(--body);
	font-size: var(--t-tiny);
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--olive-ink);
	white-space: nowrap;
}

.dmc-bb__savedetails summary svg {
	margin-left: var(--s-2);
}

/* 5 columns will not fit 375px; the table scrolls inside its own box so
   the page never scrolls sideways. */
.dmc-bb__savescroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.dmc-bb__savetable td,
.dmc-bb__savetable th {
	white-space: nowrap;
}

.dmc-bb__savetable .is-save {
	font-weight: 700;
	color: var(--olive-ink);
}

/* Savings table columns.
 *
 * The name column used to be width:100%, so it swallowed every spare pixel
 * of the 1160px container and shoved the four price columns into a huddle
 * against the right edge — each row read as a name, a void, then four
 * unrelated fragments. Fixed proportions sit each number under its own
 * header instead. 40% clears the longest box name on one line at 1160px;
 * narrower containers wrap it, which is fine, and below 720px the table
 * scrolls inside .dmc-bb__savescroll rather than crushing.
 *
 * Scoped to ≥640px: below that the table stops being a table (see the
 * stacked-card block further down), and these column rules are specific
 * enough to outrank it.
 */
@media screen and (min-width: 640px) {
	.dmc-bb__savetable {
		table-layout: fixed;
		min-width: 720px;
	}

	.dmc-bb__savetable thead th {
		padding-bottom: var(--s-2);
		border-top: 0;
		border-bottom: 1px solid var(--line);
		color: var(--navy);
	}

	.dmc-bb__savetable th:first-child,
	.dmc-bb__savetable td:first-child {
		width: 40%;
		padding-left: var(--s-5);
		white-space: normal;
		line-height: 1.4;
	}

	.dmc-bb__savetable th:nth-child(2),
	.dmc-bb__savetable td:nth-child(2),
	.dmc-bb__savetable th:nth-child(3),
	.dmc-bb__savetable td:nth-child(3) {
		width: 13%;
	}

	.dmc-bb__savetable th:nth-child(4),
	.dmc-bb__savetable td:nth-child(4) {
		width: 16%;
	}

	.dmc-bb__savetable th:nth-child(5),
	.dmc-bb__savetable td:nth-child(5) {
		width: 18%;
		padding-right: var(--s-5);
	}

	/* The two columns this section exists for, tinted as one block so the
	   eye lands on the answer rather than scanning five equal columns. */
	.dmc-bb__savetable th:nth-child(4),
	.dmc-bb__savetable td:nth-child(4),
	.dmc-bb__savetable th:nth-child(5),
	.dmc-bb__savetable td:nth-child(5) {
		background: rgba(178, 157, 81, .07);
	}

	.dmc-bb__savetable .is-final {
		font-size: var(--t-body);
	}

	.dmc-bb__savetable tbody tr:last-child td {
		border-bottom: 1px solid var(--line-soft);
	}
}

/* On phones the table stops being a table. Five columns in a sideways
   scroller hid "You save" — the one number the section exists for — off
   the right edge. Stacked cards put it back in view: name, then the price
   journey on one line, then the saving on its own highlighted line. */
@media screen and (max-width: 639px) {
	.dmc-bb__savescroll {
		overflow-x: visible;
	}

	.dmc-bb__savetable,
	.dmc-bb__savetable tbody,
	.dmc-bb__savetable tr {
		display: block;
		width: 100%;
	}

	.dmc-bb__savetable thead {
		display: none;
	}

	.dmc-bb__savetable tr {
		padding: var(--s-3) var(--s-4);
		border-top: 1px solid var(--line-soft);
	}

	.dmc-bb__savetable td {
		display: inline;
		padding: 0;
		border: 0;
		text-align: left;
		white-space: normal;
		min-width: 0;
		width: auto;
	}

	.dmc-bb__savetable td:first-child {
		display: block;
		font-weight: 700;
		margin-bottom: var(--s-1);
	}

	/* $80.90 → $64.90 → $51.92 — struck start, bold end; the header row
	   is gone, so the progression carries its own meaning. */
	.dmc-bb__savetable td:nth-child(2)::after,
	.dmc-bb__savetable td:nth-child(3)::after {
		content: " \2192  ";
		color: var(--muted);
	}

	.dmc-bb__savetable .is-final {
		font-weight: 700;
		color: var(--navy);
	}

	.dmc-bb__savetable .is-save {
		display: block;
		margin-top: var(--s-1);
	}

	.dmc-bb__savetable .is-save::before {
		content: "You save ";
		font-weight: 600;
		color: var(--olive-ink);
	}
}

.dmc-bb__savetable th:not(:first-child),
.dmc-bb__savetable td:not(:first-child) {
	text-align: right;
}

/* <summary> is natively focusable, and Safari paints its default blue ring
   around the whole bar on click. Same treatment as everything else here:
   nothing on mouse, our navy ring for the keyboard. */
.dmc-bb__savedetails summary:focus {
	outline: none;
}

.dmc-bb__savedetails summary:focus-visible {
	outline: 2px solid var(--navy);
	outline-offset: -2px;
}

/* ---------- Family grid: two-up on phones ---------- */

@media screen and (max-width: 639px) {
	/* One card per row made each box a screen-filling monolith; two-up
	   keeps four families visible at once, which is the actual decision. */
	.dmc-bb__families {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--s-3);
	}

	.dmc-bb__family-body {
		padding: var(--s-2) var(--s-3) var(--s-3);
	}

	.dmc-bb__family-name {
		font-size: var(--t-small);
	}

	.dmc-bb__family-meta {
		display: none;
	}

	.dmc-bb__family-price {
		font-size: var(--t-tiny);
		padding-top: var(--s-1);
	}

	.dmc-bb__family-pick {
		padding: var(--s-2) var(--s-3);
		font-size: 10px;
	}

	/* The inline flavour step is desktop furniture; on phones the sheet
	   owns flavour choice. Defensive: the JS branch already prevents it. */
	.dmc-bb__step:nth-of-type(2)[hidden],
	#dmcFlavourStep {
		display: none;
	}
}

/* ---------- Flavour picker sheet ---------- */

.dmc-bb__fsheet .dmc-bb__sheet {
	max-height: 88vh;
	max-height: 88dvh;
	padding-bottom: 0;
}

.dmc-bb__fsheet-head {
	display: grid;
	grid-template-columns: 44px minmax(0, 1fr) 44px;
	align-items: center;
	gap: var(--s-2);
	padding: var(--s-4);
	border-bottom: 1px solid var(--line-soft);
}

/* Close sits right, where every native sheet puts it; DOM order keeps it
   first so keyboard users reach it immediately. */
.dmc-bb__fsheet-head .dmc-bb__sheet-close {
	grid-column: 3;
	grid-row: 1;
}

.dmc-bb__fsheet-titles {
	grid-column: 2;
	text-align: center;
	min-width: 0;
}

.dmc-bb__fsheet-idx {
	margin: 0 0 2px;
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--gold-ink);
}

.dmc-bb__fsheet-title {
	font-family: var(--display);
	font-size: var(--t-h3);
	line-height: 1.25;
	color: var(--navy);
	margin: 0;
	/* Wraps to a second line instead of ellipsising — the product name is
	   the one thing this header exists to say. */
	overflow-wrap: break-word;
}

.dmc-bb__fsheet-sub {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-3);
	padding: var(--s-3) var(--s-4) var(--s-2);
}

.dmc-bb__fsheet-h {
	font-family: var(--display);
	font-size: var(--t-h3);
	color: var(--navy);
	margin: 0;
}

.dmc-bb__fsheet-hint {
	margin: 2px 0 0;
	font-size: var(--t-tiny);
	color: var(--muted);
}

.dmc-bb__fsheet-req {
	padding: var(--s-1) var(--s-3);
	border-radius: 999px;
	background: var(--sand);
	font-size: var(--t-eyebrow);
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--gold-ink);
	white-space: nowrap;
}

.dmc-bb__fsheet-list {
	padding: 0 var(--s-4);
}

.dmc-bb__frow {
	display: flex;
	align-items: center;
	gap: var(--s-3);
	width: 100%;
	min-height: 72px;
	padding: var(--s-3) 0;
	border: 0;
	border-top: 1px solid var(--line-soft);
	background: none;
	text-align: left;
	font-family: var(--body);
	/* It is a <button>, and Flatsome's mobile button rules uppercase and
	   letter-space everything inside — flavour names are product names,
	   not labels. */
	text-transform: none;
	letter-spacing: normal;
}

.dmc-bb__frow:first-child {
	border-top: 0;
}

.dmc-bb__frow-img {
	width: 56px;
	height: 56px;
	flex: 0 0 56px;
	object-fit: cover;
	border-radius: 8px;
	background: var(--sand);
}

.dmc-bb__frow-copy {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
	flex: 1 1 auto;
}

.dmc-bb__frow-name {
	font-size: var(--t-body);
	font-weight: 700;
	line-height: 1.3;
	color: var(--ink);
}

.dmc-bb__frow-sub {
	font-size: var(--t-small);
	color: var(--muted);
}

.dmc-bb__frow-radio {
	width: 26px;
	height: 26px;
	flex: 0 0 26px;
	border: 2px solid rgba(5, 11, 81, .3);
	border-radius: 50%;
	position: relative;
	transition: border-color .18s ease;
}

.dmc-bb__frow.is-on .dmc-bb__frow-radio {
	border-color: var(--navy);
}

.dmc-bb__frow.is-on .dmc-bb__frow-radio::after {
	content: "";
	position: absolute;
	inset: 4px;
	border-radius: 50%;
	background: var(--navy);
}

.dmc-bb__frow:disabled {
	opacity: .45;
}

.dmc-bb__fsheet-foot {
	padding: var(--s-3) var(--s-4) calc(var(--s-3) + env(safe-area-inset-bottom));
	border-top: 1px solid var(--line-soft);
	background: var(--paper);
}

.dmc-bb__fsheet-foot .dmc-bb__add {
	width: 100%;
}

/* Flatsome's mobile stylesheet inherits a ~3x line-height into the bar's
   two text lines: 12px type was occupying 37px per line, which alone made
   the bar 112px tall. Pin it. */
.dmc-bb__sticky-status,
.dmc-bb__sticky-total {
	line-height: 1.3;
}

/* Order-details sheet grew a footer CTA; the base bottom padding would
   stack under it. */
#dmcSheet .dmc-bb__sheet {
	padding-bottom: 0;
}

/* Gift card as a single checkbox row. */
.dmc-bb__gift-check {
	display: flex;
	align-items: flex-start;
	gap: var(--s-3);
	min-height: 44px;
	cursor: pointer;
}

.dmc-bb__gift-check input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.dmc-bb__gift-tick {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	flex: 0 0 22px;
	margin-top: 2px;
	border: 2px solid rgba(5, 11, 81, .35);
	background: var(--paper);
	color: transparent;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.dmc-bb__gift-check input:checked + .dmc-bb__gift-tick {
	background: var(--navy);
	border-color: var(--navy);
	color: #fff;
}

.dmc-bb__gift-check input:focus-visible + .dmc-bb__gift-tick {
	outline: 2px solid var(--navy);
	outline-offset: 2px;
}

.dmc-bb__gift-check-text {
	font-size: var(--t-small);
	font-weight: 600;
	color: var(--ink);
	line-height: 1.4;
}

.dmc-bb__gift-check-text small {
	display: block;
	font-size: var(--t-tiny);
	font-weight: 400;
	color: var(--muted);
}

.dmc-bb__gift textarea {
	margin-top: var(--s-2);
	/* A message to a gift recipient is a couple of sentences, not a search
	   query — give it room to be written without scrolling inside itself. */
	min-height: 128px;
	padding: var(--s-3);
	line-height: 1.5;
}

/* ---------- Photo lightbox ---------- */

.dmc-bb__zoomable {
	cursor: zoom-in;
}

.dmc-bb__zoom-wrap {
	position: fixed;
	inset: 0;
	/* One above the sheets, which sit at 99999. Both used to share that
	   value, and because #dmcFSheet comes after #dmcZoom in the template the
	   flavour sheet won the tie and covered the photo the customer had just
	   asked to see. Zoom is always opened FROM something, so it has to be
	   the topmost layer on the page. */
	z-index: 100000;
	display: flex;
	align-items: center;
	justify-content: center;
}

.dmc-bb__zoom-wrap .dmc-bb__scrim {
	background: rgba(5, 11, 81, .78);
}

.dmc-bb__zoom {
	position: relative;
	margin: 0;
	max-width: min(94vw, 900px);
	text-align: center;
}

.dmc-bb__zoom img {
	max-width: 100%;
	max-height: 78vh;
	max-height: 78dvh;
	object-fit: contain;
	box-shadow: 0 20px 60px rgba(0, 0, 0, .4);
	background: var(--paper);
}

.dmc-bb__zoom figcaption {
	margin-top: var(--s-3);
	font-size: var(--t-small);
	font-weight: 600;
	color: #fff;
}

.dmc-bb__zoom-close {
	position: absolute;
	top: calc(-1 * var(--s-3));
	right: calc(-1 * var(--s-3));
	z-index: 1;
	box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}

/* Breadcrumbs: one line, always. On a phone the three segments wrapped to
   two rows; the middle (category) segment gives way first via ellipsis,
   the current page keeps at least a readable stub, Home never shrinks. */
@media screen and (max-width: 639px) {
	.dmc-bb__crumbs {
		flex-wrap: nowrap;
		overflow: hidden;
	}

	.dmc-bb__crumbs a,
	.dmc-bb__crumbs [aria-current] {
		white-space: nowrap;
	}

	.dmc-bb__crumbs a:not(:first-child) {
		overflow: hidden;
		text-overflow: ellipsis;
		flex: 0 4 auto;
		min-width: 40px;
	}

	.dmc-bb__crumbs [aria-current] {
		overflow: hidden;
		text-overflow: ellipsis;
		flex: 0 1 auto;
		min-width: 80px;
	}
}

/* Less dead air above the breadcrumbs on phones: the hero's 40px section
   padding made the page open with a void under the site header. */
@media screen and (max-width: 639px) {
	.dmc-bb__hero {
		padding-block-start: var(--s-3);
	}

	.dmc-bb__crumbs {
		margin-bottom: var(--s-4);
	}
}

/* ---------- Hero photo slider ---------- */

.dmc-bb__shots {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	box-shadow: var(--shadow);
	background: var(--sand);
}

.dmc-bb__shots::-webkit-scrollbar {
	display: none;
}

.dmc-bb__shots .dmc-bb__shot {
	flex: 0 0 100%;
	scroll-snap-align: start;
	margin: 0;
	box-shadow: none;
}

/* Summary line thumbnails. */
.dmc-bb__line-head {
	display: flex;
	align-items: flex-start;
	gap: var(--s-3);
}

/* Qualified: the base `.dmc-bb img { height: auto }` outranks a bare class
   and zeroed the box until the file loaded — a small layout jump per line. */
.dmc-bb img.dmc-bb__line-img {
	width: 44px;
	height: 44px;
	flex: 0 0 44px;
	object-fit: cover;
	border-radius: 6px;
	background: var(--sand);
}

.dmc-bb__line-copy {
	min-width: 0;
}

/* Quantity picker beside the confirm button. */
.dmc-bb__qtypick {
	display: flex;
	align-items: center;
	gap: var(--s-3);
	margin-bottom: var(--s-3);
}

.dmc-bb__qtypick-label {
	font-size: var(--t-small);
	font-weight: 600;
	color: var(--muted);
}

.dmc-bb__fsheet-foot .dmc-bb__qtypick {
	justify-content: space-between;
}

/* -------------------------------------------------------------------------
 * Zoom affordance on selection tiles
 * ---------------------------------------------------------------------- */

/* Painted, never clicked. The tile is a <button>, so a real button for the
   zoom cannot live inside it — nesting interactive elements is invalid and
   screen readers do not expose them. pointer-events: none keeps this purely
   decorative; zoomTarget() in the script does the hit test on the tile's
   top-right corner and lets every other click fall through to selecting. */
.dmc-bb__haszoom::after {
	content: "";
	position: absolute;
	top: var(--s-2);
	right: var(--s-2);
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: rgba(255, 253, 249, .94) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23050b51' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5L21 21M10.5 7.5v6M7.5 10.5h6'/%3E%3C/svg%3E") center / 15px 15px no-repeat;
	box-shadow: 0 1px 4px rgba(5, 11, 81, .22);
	pointer-events: none;
	z-index: 2;
}

/* The corner is a target now, so the cursor should say so before the click. */
.dmc-bb__haszoom {
	cursor: pointer;
}

/* On the box-type tiles the icon sits over the photo, which has nothing to
   collide with. On the flavour rows it sits over text, so the row has to
   give the corner back: 28px of icon, 8px of offset, 8px of breathing room.
   Without this the flavour name ran under the icon by 23px. */
.dmc-bb__flavour.dmc-bb__haszoom {
	padding-right: 44px;
}

/* The sheet's thumbnail is tapped directly, so it gets the zoom cursor
   rather than a corner icon — see the note at its zoomable() call. */
/* Sheet row: the badge sits on the thumbnail, because the row's top-right
   corner is the radio's. The whole thumbnail is the tap target, so the badge
   is decoration only and must not swallow the tap. */
.dmc-bb__frow-thumb {
	position: relative;
	flex: 0 0 56px;
	display: block;
	width: 56px;
	height: 56px;
	cursor: zoom-in;
}

.dmc-bb__frow-thumb::after {
	content: "";
	position: absolute;
	right: -4px;
	bottom: -4px;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: rgba(255, 253, 249, .96) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23050b51' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5L21 21M10.5 7.5v6M7.5 10.5h6'/%3E%3C/svg%3E") center / 12px 12px no-repeat;
	box-shadow: 0 1px 4px rgba(5, 11, 81, .26);
	pointer-events: none;
}

.dmc-bb__frow-img {
	display: block;
	cursor: zoom-in;
}

/* A sold-out tile cannot be selected, but its photo is still worth seeing. */
.dmc-bb__haszoom:disabled::after {
	opacity: .55;
}

@media (prefers-reduced-motion: no-preference) {
	.dmc-bb__haszoom::after {
		transition: transform .12s ease;
	}

	.dmc-bb__haszoom:hover::after {
		transform: scale(1.08);
	}
}

/* -------------------------------------------------------------------------
   Stan wysylania
   -------------------------------------------------------------------------
   Formularz robi zwykly POST, wiec od tapniecia do przeladowania mija czas,
   w ktorym strona wyglada na martwa. Klient tapal drugi raz i dostawal dwa
   zestawy w koszyku.

   Przyciski dostaja `disabled`, zeby zablokowac drugi submit — ale bez tego
   bloku wygladalyby wtedy jak stan "jeszcze nie mozesz", czyli szary
   :disabled powyzej. `aria-busy` odroznia "pracuje" od "nieaktywny" i musi
   wygrac z tamta regula, stad ta sama specyficznosc i pozniejsze miejsce
   w pliku.

   Kluczowy jest sticky bar: na telefonie to jedyny przycisk widoczny w
   chwili tapniecia, panelowy dmcAdd jest wtedy daleko pod foldem. */

.dmc-bb__add[aria-busy="true"],
.dmc-bb__add[aria-busy="true"]:disabled {
	background: var(--navy);
	color: #fff;
	opacity: .82;
	cursor: progress;
}

.dmc-bb__sticky-add[aria-busy="true"],
.dmc-bb__sticky-add[aria-busy="true"]:disabled {
	background: var(--navy);
	color: #fff;
	opacity: .82;
	cursor: progress;
}

.dmc-bb__toast-cta[aria-busy="true"],
.dmc-bb__toast-cta[aria-busy="true"]:disabled {
	opacity: .82;
	cursor: progress;
}

/* Spinner dostawiany po etykiecie. Inline-block zamiast ::before na samym
   przycisku, zeby nie walczyc z flexowym ukladem sticky bara. */
.dmc-bb__add[aria-busy="true"]::after,
.dmc-bb__sticky-add[aria-busy="true"]::after {
	content: "";
	display: inline-block;
	width: 1em;
	height: 1em;
	margin-left: .55em;
	vertical-align: -.15em;
	border: 2px solid rgba(255, 255, 255, .38);
	border-top-color: #fff;
	border-radius: 50%;
	animation: dmc-spin .7s linear infinite;
}

@keyframes dmc-spin {
	to { transform: rotate(360deg); }
}

/* Bez ruchu spinner zostaje statycznym pierscieniem — nadal czytelnym jako
   "cos trwa", bez animacji dla osob, ktore jej nie chca. */
@media (prefers-reduced-motion: reduce) {
	.dmc-bb__add[aria-busy="true"]::after,
	.dmc-bb__sticky-add[aria-busy="true"]::after {
		animation: none;
	}
}

/* Caly builder na czas wysylki przestaje reagowac na klikniecia — kafle,
   steppery i Remove tez. Inaczej klient zdazy zmienic zestaw, ktory jest juz
   w drodze do koszyka, i zobaczy w nim co innego niz na ekranie. */
.dmc-bb.is-busy {
	pointer-events: none;
}

.dmc-bb.is-busy .dmc-bb__sticky {
	pointer-events: auto;
}
