/*
Theme Name: Bok Bok
Description: A custom block theme scaffolded by Studio Code.
Requires at least: 6.7
Tested up to: 6.9
Requires PHP: 7.2
Version: 0.3.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: bokbok
Tags: full-site-editing, block-patterns, block-styles, wide-blocks, accessibility-ready, style-variations
*/

@font-face {
	font-family: "Alte Haas Grotesk";
	src: url( "assets/fonts/AlteHaasGroteskRegular.ttf" ) format( "truetype" );
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Alte Haas Grotesk";
	src: url( "assets/fonts/AlteHaasGroteskBold.ttf" ) format( "truetype" );
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* WordPress inserts margin-block-start: var(--wp--style--block-gap) between the
   template's top-level sections (header part, main, footer part) — a gap that
   exists even when no markup asks for it. Zero it so sections butt edge-to-edge
   and own their vertical rhythm via padding; this does not affect block gaps
   inside nested layouts. */
.wp-site-blocks > * + * {
	margin-block-start: 0;
}

/* Same fix, one level down: the page's own sections (hero, shop, sauce,
   flavors, story, faq, cta...) are direct children of .entry-content and
   each still carries the default block-gap margin between siblings. Margins
   collapse to the larger of the two, so zeroing just one section's
   margin-top doesn't reliably close the gap — its neighbor's margin-bottom
   can still win. Any section with its own background/border needs to butt
   flush against the next, so zero this at the shared parent once instead of
   patching each section's margin individually. */
.entry-content > * + * {
	margin-block-start: 0;
}

/* Simple page/post/archive titles (page.html, single.html, archive.html,
   index.html, 404.html) sit directly under the sticky header with no hero
   band of their own, so without this they butt straight against the nav.
   Hero-driven templates (front page, shop archive, checkout) aren't in
   scope here — their hero bands are already deliberately flush. */
.bb-page-header {
	padding-top: 40px;
}

/* Legal/policy pages are plain heading+paragraph flows with no custom
   section padding of their own to carry the rhythm the zeroed
   `.entry-content > * + *` rule above assumes every section provides —
   without it back, every heading sits flush against the paragraph above,
   reading as one dense, condensed block instead of separate sections. */
.page-id-3 .entry-content > * + *,
.page-id-218 .entry-content > * + *,
.page-id-75 .entry-content > * + *,
.page-id-300 .entry-content > * + * {
	margin-block-start: 0;
}

/* Each heading is grouped with the body text under it (padding-top on the
   heading, padding-bottom on the paragraph right after it) so the pair
   reads as one section with 16px of breathing room on each side, rather
   than a heading and paragraph both carrying their own separate margin. */
.page-id-3 .entry-content > h2,
.page-id-218 .entry-content > h2,
.page-id-75 .entry-content > h2,
.page-id-300 .entry-content > h2 {
	padding-top: 16px;
}

.page-id-3 .entry-content > h2 + *,
.page-id-218 .entry-content > h2 + *,
.page-id-75 .entry-content > h2 + *,
.page-id-300 .entry-content > h2 + * {
	padding-bottom: 16px;
}

:root {
	--bb-cream: var( --wp--preset--color--cream );
	--bb-card: var( --wp--preset--color--card );
	--bb-ink: var( --wp--preset--color--ink );
	--bb-primary: var( --wp--preset--color--primary );
	--bb-terracotta: var( --wp--preset--color--turmeric );
	--bb-lime: var( --wp--preset--color--lime );
	--bb-magenta: var( --wp--preset--color--magenta );
	--bb-gold: var( --wp--preset--color--gold );
	--bb-muted: var( --wp--preset--color--muted );
	--bb-muted-text: var( --wp--preset--color--muted-text );
	--bb-border: var( --wp--preset--color--border );
	--bb-turmeric: var( --wp--preset--color--turmeric );
	--bb-berry: var( --wp--preset--color--berry ); /* calmer stand-in for magenta on large/frequent surfaces */
	--bb-moss: var( --wp--preset--color--moss ); /* calmer stand-in for lime on large/frequent surfaces */
	--bb-amber: var( --wp--preset--color--amber );
	--bb-red: var( --wp--preset--color--red );
	--bb-section-y: clamp( 3.5rem, 2rem + 5vw, 6rem );

	/* sticker outline weights, ratio 1 : 1.2 : 2.5 */
	--bb-keyline: 3px;
	--bb-gap: 4px;
	--bb-halo: 8px;
	--bb-chamfer: 10px;

	/* button system: flat offset shadow, no color-ring halo. Rest state
	   sits "lifted" at full shadow; hover/active press it straight down
	   (translateY only) while the shadow shrinks toward flush — the same
	   motion for every tier, with no fill/text color change. Tier fills
	   are chosen to each independently clear WCAG AA (4.5:1) against their
	   own text color — see the contrast-ratio comment above the tier
	   rules further down this file for the exact numbers. */
	--bb-btn-shadow: 4px;
	--bb-btn-shadow-hover: 2px;
	--bb-btn-shadow-active: 0px;
	--bb-btn-translate-hover: 1px;
	--bb-btn-translate-active: 2px;
	--bb-btn-transition-duration: 120ms;
	--bb-btn-transition-easing: ease-out;

	--bb-btn-primary-bg: var( --bb-magenta );
	--bb-btn-primary-text: var( --bb-ink );
	--bb-btn-primary-border: var( --bb-ink );

	--bb-btn-secondary-bg: var( --bb-cream );
	--bb-btn-secondary-text: var( --bb-ink );
	--bb-btn-secondary-border: var( --bb-ink );

	--bb-btn-tertiary-bg: var( --bb-lime );
	--bb-btn-tertiary-text: var( --bb-ink );
	--bb-btn-tertiary-border: var( --bb-ink );

	--bb-focus-ring-color: var( --bb-ink );
	--bb-focus-ring-width: 3px;
	--bb-focus-ring-offset: 2px;

	/* type scale: the site-wide roles that sit between theme.json's editor-
	   facing presets (small/medium/large/x-large/xx-large — headings and
	   base body size) — supporting/meta text, compact card copy, and the
	   hero/section "lede" intro paragraph that runs under most headlines.
	   Centralized here instead of repeating the same literal rem values
	   across every section's own lede/card/footer selectors. */
	--bb-fs-small: 0.875rem; /* meta, fine print, footer, addresses */
	--bb-fs-body-sm: 0.9375rem; /* compact body copy inside cards/accordions */
	--bb-fs-lede: 1.0625rem; /* intro paragraph directly under a headline */
	--bb-lh-lede: 1.7;
}

/* === typography === */
body {
	-webkit-font-smoothing: antialiased;
}

/* WP core's .wp-block-column rule sets word-break/overflow-wrap: break-word
   for long-string safety, and both properties inherit — so a heading
   nested in a column (the hero, most section titles) picks it up too. At
   display sizes/weights that's a liability: a long word that just barely
   overflows its column splits mid-letter ("EVERYTHIN/G") instead of
   wrapping whole onto the next line. Headings don't need the core
   safety-net (short, hand-written strings, not arbitrary long tokens), so
   reset to the normal word-boundary behavior. */
h1,
h2,
h3,
h4,
h5,
h6 {
	word-break: normal;
	overflow-wrap: normal;
}

/* h3s (card/flavor/product titles) read too light at the theme's default
   400 weight — bump to the display face's actual 700 cut rather than
   relying on synthetic bold, without touching font-size anywhere. */
h3 {
	font-weight: 700;
}

/* Browsers default form controls to the OS UI font, not the page's own
   font-family — without this override, every text input, select, and
   native button on the site (checkout fields, quantity steppers, search)
   would silently fall back to the system font instead of Alte Haas
   Grotesk. */
input,
select,
textarea,
button {
	font-family: inherit;
}

/* Boxed pill everywhere, for consistency: one construction (solid
   vivid-orange fill, ink text, no border) used by every section eyebrow
   site-wide instead of the plain colored-text treatment this replaced
   most places. Ink-on-terracotta clears WCAG AA at 6.57:1 — white text
   would fail here (~3.2:1), unlike the deeper --bb-primary orange. The
   hero and the other page "hero" bands (shop-hero, retail-hero) keep
   their own tighter-to-the-headline spacing, set per-section below — only
   the look of the eyebrow itself is standardized here. */
.bb-eyebrow {
	font-family: var( --wp--preset--font-family--mono );
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-size: 0.72rem;
	font-weight: 700;
	line-height: 1.4;
	color: var( --bb-ink );
	background-color: var( --bb-terracotta );
	display: inline-block;
	width: fit-content;
	padding: 0.3em 0.6em;
	margin-bottom: 0.75rem;
}

/* Standardized title-to-body rhythm for every section that runs the
   eyebrow -> heading -> body-copy pattern (the hero and the other page
   "hero" bands — shop-hero, retail-hero — keep their own, tighter-to-the-
   headline spacing and are deliberately left out here). */
.bb-sauce .bb-lede,
.bb-story-copy h2 + p,
.bb-flavors-lede {
	margin-top: 0.75rem;
}

.bb-thai {
	font-family: var( --wp--preset--font-family--thai );
	font-size: 1.5rem;
	font-weight: 400;
	line-height: 1.3;
}

/* Shared "lede" role: the intro paragraph directly under a headline,
   consistent everywhere it appears (home hero, shop/retail hero, flavors
   section, resellers list) instead of each section repeating its own copy
   of the same size/line-height. Each selector below keeps only its own
   layout extras (max-width, spacing) alongside this shared rule. */
.bb-lede p,
.bb-hero-copy p:not( .bb-eyebrow ),
.bb-shop-hero-lede p,
.bb-flavors-lede p,
.bb-retail-hero-lede p,
.bb-retail-resellers-lede p {
	color: var( --bb-ink );
	font-size: var( --bb-fs-lede );
	line-height: var( --bb-lh-lede );
}

/* === accessibility === */
/* Visible keyboard-focus ring for every interactive element site-wide. The
   default browser ring (thin, blue) both clashes with the poster/sticker
   palette and is hard to see against black borders and saturated fills —
   this swaps it for a thick offset ink ring with a cream gap (the same
   "halo" construction as the pill badges and sticker shadows), so it reads
   as part of the design language instead of a foreign browser artifact.
   :focus-visible (not :focus) keeps it keyboard-only — mouse/touch clicks
   don't trigger it, matching how sighted mouse users already expect this
   site to behave. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline: 3px solid var( --bb-ink );
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var( --bb-cream );
	border-radius: 0;
}

/* Same treatment, tuned for controls that already sit on a cream/card
   surface where the extra cream box-shadow ring would be invisible against
   its own background — the ink outline alone is enough contrast there. */
.bb-header :focus-visible,
.bb-footer :focus-visible {
	box-shadow: none;
}

/* === utilities === */
/* Paper-grain texture used behind the hero and story sections: actual noise
   (SVG feTurbulence, desaturated to grayscale) rather than a printed dot
   grid — reads as kraft-paper fiber instead of a repeating polka-dot
   pattern, and ties the page background to the same paper the bottle label
   itself is printed on. Kept faint so it's texture, not a band. */
.bb-grain {
	position: relative;
	isolation: isolate;
}

.bb-grain::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E" );
	background-size: 300px 300px;
	opacity: 0.15;
	pointer-events: none;
}

/* Market-bunting trim, bookending every page: a hard-edged diagonal
   candy-stripe in the logo's actual neon colors (magenta, lime, gold,
   terracotta) instead of a woven texture — closer to the striped awnings
   and flag bunting over a Bangkok street stall than a generic fabric swatch,
   and it puts the loudest colors in the brand palette on screen immediately
   instead of leaving them backed into occasional shadows and badges. */
.bb-ribbon,
.bb-mat-divider {
	height: 16px;
	background-image: repeating-linear-gradient(
		135deg,
		var( --bb-magenta ) 0 12px,
		var( --bb-lime ) 12px 24px,
		var( --bb-gold ) 24px 36px,
		var( --bb-primary ) 36px 48px
	);
	border-block: var( --bb-keyline ) solid var( --bb-ink );
}

/* === vernacular ===
   Reusable shape/framing primitives drawn from vintage Thai print and
   packaging: hand-painted signage, product labels, price tags, and offset
   printing. No new colors or fonts here — every rule below only changes
   shape, border, or composition, using the existing tokens. */

/* Label frame: an inset outline drawn 6px in from an element's own border,
   the classic "frame within a frame" of a printed product label or poster
   border. Applied here directly to every card component site-wide (shop,
   online-retailer, store, flavor, value-prop) so the whole card language
   reads as vintage-label framing instead of a plain single-border box —
   no content/markup changes needed since it hooks the classes those cards
   already carry. */
.bb-shop-card,
.bb-online-card,
.bb-store-card,
.bb-flavor,
.bb-card {
	position: relative;
}

.bb-shop-card::after,
.bb-online-card::after,
.bb-store-card::after,
.bb-flavor::after,
.bb-card::after {
	content: "";
	position: absolute;
	inset: 6px;
	border: 1.5px solid var( --bb-ink );
	pointer-events: none;
}

/* Ticket / price-tag shape: a notched point on one side, like a market
   price tag or a torn ticket stub. Left padding compensates for the point
   so the label text doesn't crowd it. */
.bb-ticket {
	clip-path: polygon( 0 50%, 14px 0, 100% 0, 100% 100%, 14px 100% );
	padding-left: 1.5em !important;
}

/* Poster stamp: a small rotated circular mark, the way a hand-stamped
   ink date or seal sits on vintage packaging — meant to overlap the edge
   of a framed photo, not sit inside the normal content flow. */
.bb-stamp {
	position: absolute;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 92px;
	height: 92px;
	border-radius: 50%;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-lime );
	color: var( --bb-ink );
	font-family: var( --wp--preset--font-family--mono );
	font-size: 0.6rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	line-height: 1.35;
	text-align: center;
	padding: 0.5rem;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	z-index: 3;
	pointer-events: none;
}

/* Registration marks: small printer's-crosshair ticks in two corners of a
   framed area, a quiet nod to offset-print registration guides rather than
   a literal misprint effect. */
.bb-reg-marks {
	position: relative;
}

.bb-reg-marks::before,
.bb-reg-marks::after {
	content: "";
	position: absolute;
	width: 16px;
	height: 16px;
	background:
		linear-gradient( var( --bb-ink ), var( --bb-ink ) ) center / 100% 1.5px no-repeat,
		linear-gradient( 90deg, var( --bb-ink ), var( --bb-ink ) ) center / 1.5px 100% no-repeat;
	opacity: 0.4;
	pointer-events: none;
}

.bb-reg-marks::before {
	top: 10px;
	left: 10px;
}

.bb-reg-marks::after {
	bottom: 10px;
	right: 10px;
}

/* === header === */
/* Ink, not cream: the header sat on the exact same ground as the hero
   banner right below it, so the sticky nav bar and the page content read
   as one continuous surface with only a thin keyline between them. A dark
   bar gives the header its own identity as a persistent UI layer, and the
   logo's lime/magenta outline actually pops harder against ink than it
   did against cream. */
/* WordPress wraps this template part in a plain div sized exactly to the
   header's own height, giving position: sticky on the header itself zero
   room to travel within that wrapper's containing block — it would
   compute as sticky but never visibly stick. Making the WRAPPER sticky
   instead gives it the full page height to work with, and the header
   fills it completely so it still reads as "the header sticks." */
.wp-block-template-part:has( .bb-header ) {
	position: sticky;
	top: 0;
	z-index: 20;
}

/* Cream ground with a thick terracotta top stripe and a thin ink keyline
   underneath — the header reads as its own bright, branded bar rather than
   a dark surface borrowed from the hero. Nav, logo, and icons all sit in
   the same terracotta so the whole bar reads as one coordinated mark. */
.bb-header {
	position: relative;
	isolation: isolate;
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
	color: #fff;
}

/* Floral print at full strength again, with a dark scrim so the white
   nav/logo/icons keep enough contrast against a busy, brightly-colored
   pattern in a bar that's sticky and always visible. */
.bb-header::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image:
		linear-gradient( rgba( 0, 0, 0, 0.55 ), rgba( 0, 0, 0, 0.55 ) ),
		url( "/wp-content/uploads/2026/08/header-floral-wide.png" );
	background-repeat: no-repeat;
	background-size: cover;
	background-position: center;
	pointer-events: none;
}

.bb-header a {
	color: #fff;
}

/* Logo mark: cap the height so the header row stays compact regardless of
   the source image's native size; width follows to keep it undistorted. */
.bb-header .wp-block-image {
	margin: 0;
}

.bb-header .wp-block-image img {
	height: 64px;
	width: auto;
	max-width: none;
}

.bb-checkout-header-logo {
	margin: 0;
}

.bb-checkout-header-logo img {
	height: 48px;
	width: auto;
	max-width: none;
}

.bb-header-tag {
	font-family: var( --wp--preset--font-family--mono );
	letter-spacing: 0.18em;
	text-transform: uppercase;
	font-size: 0.625rem;
	font-weight: 700;
	color: var( --bb-terracotta );
}

.bb-header-right {
	gap: 1rem;
}

.bb-nav {
	font-family: var( --wp--preset--font-family--sans );
	font-size: 0.85rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
}

/* Border is transparent at rest so hover/current don't shift the link's box
   size — same trick the button tiers use to keep sizing consistent across
   states. Magenta fill + a slight rotate on hover/current is the same
   "bordered sticker chip" language the rest of the site's nav elements use.
   Extra .bb-header qualifier so this beats WP core's own doubled-class
   ".wp-block-navigation-item__content.wp-block-navigation-item__content"
   rule (a specificity-boost trick core uses for its own defaults), which
   otherwise sets color: inherit and overrides the terracotta link color
   back to plain ink. */
.bb-header .bb-nav .wp-block-navigation-item__content {
	padding: 0.4rem 0.6rem;
	border-radius: 0;
	border: 2px solid transparent;
	color: #fff;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.bb-nav .current-menu-item > .wp-block-navigation-item__content {
	background-color: var( --bb-magenta );
	color: var( --bb-ink );
	border-color: var( --bb-ink );
}

.bb-nav .wp-block-navigation-item__content:hover {
	background-color: var( --bb-magenta );
	color: var( --bb-ink );
	border-color: var( --bb-ink );
	transform: rotate( -1.5deg );
}

/* Icon-only now, deliberately quieter than "Where to Buy"/"Order" — a
   single-product store doesn't need account/login competing for attention
   in the primary nav, so this drops the same chip/hover-box treatment the
   text links get and instead just sits there plainly, like the cart icon
   next to it. */
.bb-header .bb-nav-account .wc-block-customer-account__link {
	padding: 0.4rem;
	color: #fff;
	text-decoration: none;
	opacity: 0.85;
	transition: opacity 0.15s ease;
}

.bb-nav-account .wc-block-customer-account__link:hover {
	opacity: 1;
}

.bb-nav-account .wc-block-customer-account__account-icon {
	width: 30px;
	height: 30px;
	flex-shrink: 0;
}

/* Instagram follow link only makes sense as a mobile-menu-bottom item, not
   as an inline text link in the compact desktop bar — hidden by default,
   revealed only inside the mobile overlay below. */
.bb-nav-instagram-wrap {
	display: none;
}

/* Mobile menu overlay: WP core renders this with no theme styling at all by
   default (plain white full-screen panel, tiny default-weight links) — a
   jarring, unbranded break from the rest of the site the moment a phone
   visitor opens the hamburger. Cream + grain matches every other surface,
   and the nav links get a much larger, touch-friendly size appropriate for
   a full-screen takeover instead of the compact header-bar sizing .bb-nav
   otherwise uses. */
/* !important throughout this block: WP core writes the nav block's own
   editor-configured alignment (inherited from the compact desktop header
   bar's "justify right" layout) as inline styles on these same elements,
   which otherwise wins over any plain class rule regardless of selector
   weight. The full-screen mobile takeover deliberately overrides that
   inherited desktop alignment rather than reusing it. */
/* Full-strength floral, no dark scrim — unlike .bb-header::before, this
   overlay's links are solid chip buttons (see .is-menu-open .bb-nav
   .wp-block-navigation-item__content below), so they carry their own
   contrast against the busy pattern without needing the header's
   readability scrim. */
.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var( --bb-cream ) !important;
	background-image: url( "/wp-content/uploads/2026/08/header-floral-wide.png" ) !important;
	background-repeat: no-repeat !important;
	background-size: cover !important;
	background-position: center !important;
}

.wp-block-navigation__responsive-dialog {
	padding: 1.25rem;
}

.wp-block-navigation__responsive-container-close,
.wp-block-navigation__responsive-container-open {
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	background-color: var( --bb-card );
	color: var( --bb-ink );
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color 0.15s ease;
}

.wp-block-navigation__responsive-container-close:hover,
.wp-block-navigation__responsive-container-open:hover {
	background-color: var( --bb-muted );
}

/* Scoped to .is-menu-open: this same "-content" wrapper class is also the
   element WP core reuses for the always-visible inline desktop nav (below
   the overlay breakpoint the block never actually becomes a modal at all).
   An earlier, unscoped version of this rule forced min-height: 100vh onto
   that inline desktop instance too, inflating the whole header to full
   viewport height and pushing the entire page below the fold — exactly the
   kind of "looks broken on load" regression this audit is trying to catch. */
.is-menu-open .wp-block-navigation__responsive-container-content {
	display: flex;
	align-items: center !important;
	justify-content: center !important;
	min-height: calc( 100vh - 5rem );
}

.is-menu-open .wp-block-navigation__responsive-container-content .bb-nav.wp-block-navigation__container {
	flex-direction: column;
	align-items: stretch !important;
	justify-content: flex-start !important;
	gap: 1rem;
	width: 100% !important;
	max-width: 20rem;
	height: auto !important;
	flex: none !important;
}

.is-menu-open .bb-nav .wp-block-navigation-item {
	width: 100%;
}

.is-menu-open .bb-nav .wp-block-navigation-item__content {
	display: block;
	width: 100%;
	box-sizing: border-box;
	font-size: 1.5rem;
	/* !important: core's own navigation/style.min.css ships
	   ".is-menu-open ... .wp-block-navigation-item__content { padding: 0px }"
	   at a 4-class selector, one class heavier than this rule — without it,
	   "Where to Buy"/"Order" collapse to line-height-only height while the
	   account button (a different selector core doesn't zero) keeps its
	   padding, so the three buttons end up visibly different heights. */
	padding: 1rem 1.25rem !important;
	/* Explicit, rather than inheriting the theme's global 1.6 body
	   line-height — needed so this matches the account button's line-height
	   (set the same below) and the two end up the same height. */
	line-height: 1.2;
	text-align: center;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-card );
	/* .bb-header .bb-nav .wp-block-navigation-item__content sets white text
	   for the compact desktop bar — invisible against this chip's cream
	   background, so it needs an explicit override here. */
	color: var( --bb-ink );
	/* Same hard offset shadow as the site's button system — these read as
	   proper buttons instead of flat bordered chips, standing out more
	   clearly against the floral background above. */
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.is-menu-open .bb-nav .current-menu-item > .wp-block-navigation-item__content {
	background-color: var( --bb-lime );
}

.is-menu-open .bb-nav .wp-block-navigation-item__content:hover {
	transform: translate( calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ), calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

/* Account link sits after the nav's <ul> as a plain sibling (core only puts
   actual navigation-link items inside the list), so it needs its own copy
   of the same full-width chip-button treatment to read as one more item in
   the stack rather than a small, off-brand leftover link. */
.is-menu-open .bb-nav-account {
	width: 100%;
	max-width: 20rem;
}

.is-menu-open .bb-nav-account .wc-block-customer-account__link {
	width: 100%;
	box-sizing: border-box;
	justify-content: center;
	font-size: 1.5rem;
	line-height: 1.2;
	padding: 1rem 1.25rem;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-card );
	color: var( --bb-ink );
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.is-menu-open .bb-nav-account .wc-block-customer-account__account-icon {
	width: 1.15em;
	height: 1.15em;
}

.is-menu-open .bb-nav-account .wc-block-customer-account__link:hover {
	text-decoration: none;
	transform: translate( calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ), calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

/* Instagram: plain light text + icon, deliberately NOT a button like the
   three chips above — a quieter, secondary link sitting under the "real"
   nav actions. */
.is-menu-open .bb-nav-instagram-wrap {
	display: block;
	width: 100%;
	max-width: 20rem;
	text-align: center;
	margin-block-start: 0.5rem;
}

.is-menu-open .bb-nav-instagram {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 1rem;
	font-weight: 400;
	text-transform: none;
	letter-spacing: normal;
	color: var( --bb-ink );
	opacity: 0.65;
	text-decoration: none;
}

.is-menu-open .bb-nav-instagram:hover {
	opacity: 1;
	text-decoration: underline;
}

.is-menu-open .bb-nav-instagram-icon {
	width: 1.05em;
	height: 1.05em;
	flex-shrink: 0;
}

/* === hero === */
/* Wider side margins than the rest of the site: the hero's inner content
   pulls in from the full-width band by an extra clamp() amount on top of
   the root padding, so it reads as a distinct, more spacious "stage"
   before the tighter sections below. */
/* Same floral fabric used elsewhere on the site, filling the hero itself
   this time, shown at full strength now that the bottle photo is a
   transparent cutout rather than its own composited backdrop. */
.bb-hero {
	background-image:
		linear-gradient( rgba( 241, 226, 195, 0.85 ), rgba( 241, 226, 195, 0.85 ) ),
		url( "/wp-content/uploads/2026/08/hero-floral.png" );
	background-repeat: no-repeat;
	background-size: cover;
	background-position: center;
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: clamp( 3rem, 2rem + 4vw, 6rem );
	padding-inline: clamp( 1.25rem, 1rem + 4vw, 5rem );
	position: relative;
	overflow: hidden;
}

.bb-hero h1 {
	margin-block: 0.5rem 0;
}

.bb-hero .bb-eyebrow {
	white-space: nowrap;
	max-width: none;
}

/* Illustrated brand assets scattered around the hero stage: absolutely
   positioned so they read as stickers tossed onto the composition rather
   than inline content. Hidden below the tablet breakpoint where there is no
   spare margin for them to sit in without colliding with the copy.
   Two-layer hard-edged drop-shadow (lime + ink, no blur) instead of a single
   flat shadow gives them the same layered "peeling sticker" pop as the
   button/card shadow language, and a slow rotate-anchored float keeps them
   from reading as static debris in the corners. The rotation lives in a
   custom property so one shared keyframe can drive all three without
   fighting each sticker's own static tilt. */
/* Shared float used by anything that wants the "sticker" motion — a slow,
   gentle rise-and-settle. --bb-float-rot lets a caller add its own static
   tilt without fighting the animation's own transform; left at 0deg (the
   default) the element just floats straight up and down, unrotated. */
@keyframes bb-float {
	0%, 100% {
		transform: rotate( var( --bb-float-rot, 0deg ) ) translateY( 0 );
	}
	50% {
		transform: rotate( var( --bb-float-rot, 0deg ) ) translateY( -10px );
	}
}

.bb-hero-copy p:not( .bb-eyebrow ) {
	max-width: 46ch;
	font-size: 1.25rem;
}

/* Product jar photo reads as a poster/label insert, not a plain product
   shot: a slight rotation (the "pasted onto the page" imperfection of a
   collaged sleeve) plus the label-frame double border, plus room for the
   stamp badge to overlap its corner. */
.bb-hero-jar {
	position: relative;
}

.bb-hero-jar figure {
	width: fit-content;
	margin-inline: auto;
	animation: bb-float 5s ease-in-out infinite;
}

.bb-hero-jar img {
	border-radius: 0;
}

.bb-hero-stamp {
	bottom: -1.5rem;
	left: -1.5rem;
	transform: rotate( -10deg );
}

@media ( max-width: 640px ) {
	.bb-hero-stamp {
		width: 76px;
		height: 76px;
		font-size: 0.5rem;
		bottom: -0.75rem;
		left: -0.75rem;
	}
}

/* === button system ===
   Three tiers, each defined purely by the --bb-btn-{tier}-* tokens above —
   fill, text, and border are set once per tier; the interaction (hover,
   active, focus) is identical across all three and lives in ONE shared
   block below instead of being redeclared per tier. No tier changes fill
   or text color on hover or active: only position (translateY) and the
   offset shadow move, so the tiers stay visually distinct at every state
   instead of converging on a shared hover accent the way the old
   magenta/lime hover accents used to.

   Contrast ratios (WCAG 2.1 relative-luminance formula), each tier's
   resting fill against its own resting text color:
     Primary   --bb-magenta #FF00AA on black  →   5.83 : 1  (passes AA)
     Secondary --bb-cream   #F1E2C3 on black  →  16.41 : 1  (passes AAA)
     Tertiary  --bb-lime    #A9FF63 on black  →  17.17 : 1  (passes AAA)
   All three clear WCAG AA (4.5:1) for normal text. Primary is the only
   tier that wouldn't also clear AA with white text instead of black
   (white-on-magenta is ~1.2:1) — keep all three tiers on --bb-ink text.

   Selectors carry the extra .wp-block-button / .wp-block-button__link
   qualifiers (four classes deep) because WooCommerce's product-button block
   ships an inline `border-style: none` rule at three-class specificity —
   without the extra weight here, that rule wins the tie and the keyline
   never renders on Add to Cart buttons. */
.wp-element-button,
.wp-block-button .wp-element-button.wp-block-button__link {
	background-color: var( --bb-btn-secondary-bg );
	color: var( --bb-btn-secondary-text );
	border: var( --bb-keyline ) solid var( --bb-btn-secondary-border );
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

/* Primary — pink fill, black text. Matches the base rule's four-class
   specificity so this override actually wins instead of losing the tie
   to source order. */
.wp-block-button.bb-btn-solid .wp-element-button.wp-block-button__link {
	background-color: var( --bb-btn-primary-bg );
	color: var( --bb-btn-primary-text );
	border-color: var( --bb-btn-primary-border );
}

/* Secondary — eggshell fill, black text, ink border at the same weight as
   Primary's so the two read as one consistent stroke language rather than
   Secondary looking flimsier next to it. The untiered base rule above
   already carries these values; restated here so the tier is explicit and
   self-contained rather than "whatever's left over" when no tier class is
   present. */
.wp-block-button.bb-btn-ghost .wp-element-button.wp-block-button__link {
	background-color: var( --bb-btn-secondary-bg );
	color: var( --bb-btn-secondary-text );
	border: var( --bb-keyline ) solid var( --bb-btn-secondary-border );
}

/* Tertiary — green fill, black text (17.17:1). Two selector shapes: the
   same .wp-block-button wrapper convention as the other two tiers, plus a
   bare `.bb-btn-tertiary .wp-element-button` fallback for a tertiary
   button applied outside that wrapper convention. */
.wp-block-button.bb-btn-tertiary .wp-element-button.wp-block-button__link,
.bb-btn-tertiary .wp-element-button {
	background-color: var( --bb-btn-tertiary-bg );
	color: var( --bb-btn-tertiary-text );
	border-color: var( --bb-btn-tertiary-border );
}

/* Hover/active — identical across all three tiers, no color change.
   Rest sits "lifted" at full shadow; hover presses it 1px toward the page
   and shrinks the shadow partway; active presses it flush (2px, shadow
   flat). */
.wp-element-button:hover,
.wp-block-button .wp-element-button.wp-block-button__link:hover {
	transform: translateY( var( --bb-btn-translate-hover ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.wp-element-button:active,
.wp-block-button .wp-element-button.wp-block-button__link:active {
	transform: translateY( var( --bb-btn-translate-active ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink );
}

/* Focus ring — independent of hover/active. An outline (not a box-shadow,
   so it never competes with the depress shadow above) that appears on
   keyboard focus only, not on mouse/touch activation. */
.wp-element-button:focus-visible,
.wp-block-button .wp-element-button.wp-block-button__link:focus-visible {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

/* Disabled — any tier, any tag. !important is deliberate here: a disabled
   button must always read as inert no matter which tier's own 4-class
   selector (higher specificity than this one) also matches it. */
.wp-element-button:disabled,
.wp-element-button[aria-disabled="true"],
.bb-btn-disabled .wp-element-button {
	background-color: var( --bb-muted ) !important;
	color: var( --bb-muted-text ) !important;
	border-color: var( --bb-muted-text ) !important;
	box-shadow: none !important;
	transform: none !important;
	cursor: not-allowed !important;
	opacity: 0.6;
	pointer-events: none;
}

/* WooCommerce's mini-cart drawer ships its own button markup with no
   bb-btn-* class to hook into — mapped onto the same tier tokens by
   semantic role: checkout / "start shopping" is Primary, "view cart" is
   Secondary. !important overrides WooCommerce's own inline-styled
   defaults on these specific elements. Hover/active/focus share the exact
   same motion-only rules as the tier system above — no separate color
   states to maintain here anymore. */
.wc-block-mini-cart__footer-checkout,
.wc-block-mini-cart__shopping-button {
	background-color: var( --bb-btn-primary-bg ) !important;
	color: var( --bb-btn-primary-text ) !important;
	border: var( --bb-keyline ) solid var( --bb-btn-primary-border ) !important;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

.wc-block-mini-cart__footer-cart {
	background-color: var( --bb-btn-secondary-bg ) !important;
	color: var( --bb-btn-secondary-text ) !important;
	border: var( --bb-keyline ) solid var( --bb-btn-secondary-border ) !important;
	/* !important needed here too: this button also carries WooCommerce's
	   own "is-style-outline" class, whose built-in box-shadow: none rule
	   otherwise wins on specificity and silently drops the shadow. */
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink ) !important;
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

.wc-block-mini-cart__footer-checkout:hover,
.wc-block-mini-cart__shopping-button:hover,
.wc-block-mini-cart__footer-cart:hover {
	transform: translateY( var( --bb-btn-translate-hover ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink ) !important;
}

.wc-block-mini-cart__footer-checkout:active,
.wc-block-mini-cart__shopping-button:active,
.wc-block-mini-cart__footer-cart:active {
	transform: translateY( var( --bb-btn-translate-active ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink ) !important;
}

.wc-block-mini-cart__footer-checkout:focus-visible,
.wc-block-mini-cart__shopping-button:focus-visible,
.wc-block-mini-cart__footer-cart:focus-visible {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

/* Cart-count badge: brand lime instead of the flat cream-on-black default,
   so the one number that matters most in the header (items in cart) pops
   as its own small accent moment instead of blending into plain ink/cream. */
.wc-block-mini-cart__badge {
	background-color: var( --bb-magenta ) !important;
	color: #fff !important;
}

/* This store sells one product, so the mini-cart line item IS the cart —
   give it the same "featured card" weight as everything else (bigger
   bordered product shot, display-font name, brand-color price) instead of
   the cramped default table-row treatment that undersells the only thing
   being sold. */
.wc-block-mini-cart__items .wc-block-cart-items__row {
	padding-block: 1.5rem;
}

/* !important: WC core's mini-cart-style.css sets its own padding-right/
   display on these exact elements via a higher-specificity chain
   (.is-medium/.is-mobile/.is-small table.wc-block-cart-items ... — 4
   classes deep), which beats a 2-class theme selector regardless of
   source order. */
.wc-block-mini-cart__items .wc-block-cart-item__image {
	padding-right: 16px !important;
}

.wc-block-mini-cart__items .wc-block-cart-item__image img {
	width: 88px !important;
	height: 88px !important;
	object-fit: cover;
	border: var( --bb-keyline ) solid var( --bb-ink );
}

/* The per-unit price under the product name duplicates the line-item total
   shown on the right (identical figure whenever quantity is 1, which is the
   common case here) — the total column is the one number a customer
   actually needs at a glance. */
.wc-block-mini-cart__items .wc-block-cart-item__prices {
	display: none !important;
}

.wc-block-mini-cart__items .wc-block-components-product-name {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.25rem;
	line-height: 1.1;
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: -0.01em;
	color: var( --bb-ink );
}

.wc-block-mini-cart__items .wc-block-components-product-metadata__description p {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	color: var( --bb-muted-text );
	margin: 0.35rem 0 0;
}

.wc-block-mini-cart__items .wc-block-cart-item__total .wc-block-components-product-price__value {
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	font-size: 1.125rem;
	color: var( --bb-primary );
}

.wc-block-mini-cart__items .wc-block-cart-item__prices .wc-block-components-product-price__value {
	font-family: var( --wp--preset--font-family--mono );
	color: var( --bb-muted-text );
}

.wc-block-mini-cart__items .wc-block-components-quantity-selector {
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
}

.wc-block-mini-cart__items .wc-block-components-quantity-selector__button,
.wc-block-mini-cart__items .wc-block-components-quantity-selector__input {
	border-radius: 0;
}
/* === sauce === */
.bb-sauce {
	position: relative;
	isolation: isolate;
	padding-block: var( --bb-section-y );
}

/* Same faint street-signage motif as the flavors/story/CTA sections, same
   filter/opacity/edge-fade formula, so this section picks up the same
   "market signage" texture instead of introducing a new treatment. */
.bb-sauce::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/Frame-48097657-scaled.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-sauce h2 {
	color: var( --bb-ink );
	margin-block: 0.75rem 1.25rem;
	max-width: 22ch;
}

/* Cut-paper card: flat lime offset, zero radius — construction #4 from the
   motif library. */
/* Quiet cream fill, matching every other card on the site (shop, flavor,
   online, store): this value-prop grid sits directly beside the photo
   mosaic, and gold here competed with both the mosaic's color and gold's
   other job as the page's single closing-CTA accent. One consistent card
   language now, so the mosaic carries this section's color energy and gold
   stays a rarer, more deliberate moment further down the page. */
.bb-card {
	position: relative;
	isolation: isolate;
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 1.25rem;
}


@media ( prefers-reduced-motion: reduce ) {
	.bb-card {
		transition: none;
	}

	.bb-card:hover {
		transform: none;
	}
}

/* The two card stacks live in flow columns, so a percentage height would
   resolve against the column's own content height and overflow. A plain
   flex-stretch only matched the two cards within each column, not across
   columns — "Small batch" and "Six ingredients" could still end up
   different heights. Grid does that instead: the two column wrappers
   become `display: contents` (they disappear from layout; their 4 .bb-card
   children become direct grid items), and grid-auto-flow: column fills the
   grid in the same top-to-bottom, column-by-column order the source markup
   is already in — so row 1 is {small batch, six ingredients} and row 2 is
   {four flavors, good on everything}, each row sized to its tallest card. */
.bb-sauce .wp-block-columns .wp-block-columns {
	display: grid;
	grid-template-columns: 1fr 1fr;
	grid-template-rows: repeat( 2, 1fr );
	grid-auto-flow: column;
	gap: 1rem;
}

.bb-sauce .wp-block-columns .wp-block-columns > .wp-block-column {
	display: contents;
}

.bb-sauce .wp-block-columns .wp-block-columns > .wp-block-column > .bb-card {
	margin-top: 0 !important;
}

.bb-card h3 {
	margin: 0 0 0.5rem;
}

/* Teal, matching the supporting/meta text used elsewhere (flavor card
   labels, product meta) now that the fill is cream instead of gold. */
.bb-card p {
	color: var( --bb-muted-text );
	font-size: var( --bb-fs-small );
	line-height: 1.6;
	margin: 0;
}

/* Photo mosaic: a scaffold of overlapping, rotated frames standing in for
   real community photography (Thai movie-poster collage composition —
   several photos at different sizes overlapping, not one clean rectangle).
   Each slot is a genuine (empty) core/image block, not a plain div, so
   clicking one in the editor opens WordPress's own upload/media-library
   picker — the wrapping .bb-mosaic-item group supplies the frame/shadow/
   rotation and stays put once a real photo fills the image block inside it. */
.bb-sauce-mosaic-col {
	position: relative;
}

.bb-mosaic {
	position: relative;
	width: 100%;
	aspect-ratio: 3 / 4;
}

.bb-mosaic-item {
	position: absolute;
	background-color: var( --bb-muted );
	border: var( --bb-keyline ) solid var( --bb-ink );
	overflow: hidden;
}

.bb-mosaic-item figure {
	width: 100%;
	height: 100%;
	margin: 0;
}

.bb-mosaic-item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.bb-mosaic-1 {
	top: 0;
	left: 0;
	width: 66%;
	height: 60%;
	transform: rotate( -2deg );
	box-shadow: 6px 6px 0 0 var( --bb-lime );
	z-index: 2;
}

/* Same mosaic-tile classes are reused in the Our Story section below —
   this photo's shadow there is brand orange instead of the shared default. */
#our-story .bb-mosaic-1 {
	box-shadow: 6px 6px 0 0 var( --bb-amber );
}

.bb-mosaic-2 {
	top: calc( 8% + 40px );
	right: -3%;
	width: 46%;
	height: 42%;
	transform: rotate( 4deg );
	box-shadow: 6px 6px 0 0 var( --bb-magenta );
	z-index: 3;
}

.bb-mosaic-3 {
	bottom: 10%;
	left: calc( 4% + 24px );
	width: 42%;
	height: 38%;
	transform: rotate( 5deg );
	box-shadow: 6px 6px 0 0 var( --bb-muted-text );
	z-index: 1;
}

.bb-mosaic-4 {
	bottom: -3%;
	right: 3%;
	width: 46%;
	height: 44%;
	transform: rotate( -4deg );
	box-shadow: 6px 6px 0 0 var( --bb-primary );
	z-index: 2;
}

/* The Chalung road-sign photo is a transparent cutout, not a rectangular
   snapshot, so it doesn't take the other tiles' opaque background/ink
   border/object-fit crop — it floats center-stage over the collage instead,
   like the hero section's sticker cutouts (drop-shadow instead of a frame). */
.bb-mosaic-sign {
	top: 50%;
	left: 50%;
	width: 50%;
	height: auto;
	aspect-ratio: 4 / 3;
	transform: translate( -50%, -50% );
	background-color: transparent;
	border: none;
	box-shadow: none;
	overflow: visible;
	z-index: 4;
	filter: drop-shadow( 3px 3px 0 var( --bb-lime ) ) drop-shadow( 7px 7px 0 var( --bb-ink ) );
}

.bb-mosaic-sign img {
	object-fit: contain;
}

/* Extra .bb-story qualifier so this beats the later, equal-specificity
   ".bb-story img" ink-border rule below — that rule is meant for the
   section's rectangular photos, not this transparent sign cutout. */
.bb-story .bb-mosaic-sign img {
	border: none;
}

@media ( max-width: 767px ) {
	.bb-mosaic-sign {
		width: 54%;
	}
}

@media ( max-width: 767px ) {
	.bb-mosaic {
		aspect-ratio: 1 / 1;
		max-width: 420px;
		margin-inline: auto;
	}

	/* Photo collage reads as the section's lead image, so it goes first on
	   mobile even though it's second in the markup (text column, then
	   image column) — order only reorders the visual stack, not the
	   underlying DOM, so screen-reader/tab order is unaffected. */
	.bb-sauce-mosaic-col {
		order: -1;
		margin-bottom: 1.5rem;
	}
}

/* Ingredient tags: price-tag/ticket shapes (a notched point on the left,
   like a market price tag) in three alternating colors so each tag is its
   own bold color-block instead of three identical teal chips. Teal was
   also the wrong choice on its own terms: green is reserved for accents
   elsewhere on the site, not a fill this prominent. */
.bb-pills {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	list-style: none;
	padding: 0;
	margin: 0;
}

/* Flat cut-paper chip: solid fill, ink border, square corners — same plain
   construction as the rest of the site's tags and badges, no rounded
   sticker shape or gradient halo ring. */
/* True rounded pill, no border/shadow: every button on the site is now a
   square, ink-bordered, hard-shadowed box, so a tag sharing that same
   language read as clickable. Round + borderless + flat reads as an
   informational label instead. */
.bb-pills li {
	font-family: var( --wp--preset--font-family--mono );
	background-color: var( --bb-magenta );
	border-radius: 999px;
	padding: 0.4rem 1rem;
	font-size: 0.7rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var( --bb-ink );
}

.bb-pills li:nth-child(2) {
	background-color: var( --bb-lime );
}

.bb-pills li:nth-child(3) {
	background-color: var( --bb-primary );
}

/* === flavors === */
/* A full-bleed neon-lime halftone read as blaring at this scale, so lime is
   now an accent (card shadows, heading plate shadow) on the same faint
   ink-on-cream grain the hero uses, rather than the section's own fill —
   still energetic, but the four cards (and their text) are what's vibrant,
   not the ground they sit on. */
.bb-flavors {
	position: relative;
	isolation: isolate;
	background-color: var( --bb-amber );
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.22'/%3E%3C/svg%3E" );
	background-size: 300px 300px;
	color: var( --bb-ink );
	padding-block: var( --bb-section-y );
	border-block: var( --bb-keyline ) solid var( --bb-ink );
}

/* Same faint street-photo motif as the story/CTA/home-shop/retail-hero
   sections, grayscaled via filter here since this source photo starts in
   color: a Bangkok street of signage, low-opacity behind the lime fill so
   it reads as texture, not a competing photo. Short 20px fades at top and
   bottom stop it cutting off hard against this section's own keylines. */
.bb-flavors::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/pexels-tonywuphotography-18911914-1-scaled.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

/* Mortar-and-pestle composition: the section's one "higher-impact" asset.
   Static now, not a floating sticker — it sits in its own column beside the
   headline as a supporting image, the way a magazine spread pairs a photo
   with its lede rather than scattering it as decoration. Still gets the
   same layered drop-shadow as the hero's stickers so the illustration
   language stays consistent, minus the position/animation that made it
   read as decoration rather than content.
   align-self: stretch (overriding the block's own is-vertically-aligned-
   center) makes this column match the row's height — set by the text
   column's natural content height — instead of centering at its own
   intrinsic size. The image then fills that height (capped by max-width so
   it can't outgrow the column), so it reads larger without ever pushing the
   row taller than the text beside it. */
.bb-flavors-mortar-col {
	max-width: 320px;
	align-self: stretch !important;
}

.bb-flavors-mortar {
	height: 100%;
	filter: drop-shadow( 3px 3px 0 var( --bb-lime ) ) drop-shadow( 7px 7px 0 var( --bb-ink ) );
	transform: rotate( 3deg );
}

.bb-flavors-mortar img {
	height: 100% !important;
	width: auto;
	max-width: 100%;
}

@media ( max-width: 767px ) {
	.bb-flavors-head {
		flex-wrap: wrap;
	}

	/* Stacked order matches reading order here: the illustration reads as
	   a lead-in image above the headline instead of an afterthought
	   dropped below the text and lede paragraph. */
	.bb-flavors-mortar-col {
		order: -1;
		max-width: 140px;
		margin-inline: auto;
		margin-bottom: 1rem;
	}
}

/* The 4 flavor cards squeeze too narrow at tablet widths to stay side by
   side — same single-column stack the cards already fall into below the
   767px mobile breakpoint, just extended up through the tablet range
   where WP core's own column-stacking hasn't kicked in yet. */
@media ( max-width: 1024px ) {
	.bb-flavors .wp-block-columns:not( .bb-flavors-head ) {
		flex-direction: column;
	}
}

.bb-flavors h2 {
	color: var( --bb-ink );
	margin-block: 0.75rem 1.25rem;
}

.bb-flavors-lede p {
	max-width: 52ch;
}

/* Matches the .bb-card language used in the section above (.bb-sauce):
   solid black outline, square corners, same fill — one consistent card
   look across sections instead of this one standing out with a rounded
   magenta double-ring plaque. */
/* The name/label group and icon sit side by side up top; the description
   drops out of that row to run full width underneath instead of being
   squeezed into the narrower left column. */
.bb-flavor {
	position: relative;
	padding: 1.75rem;
	height: 100%;
	border-radius: 0;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-card );
	transition: transform 0.2s ease;
}

.bb-flavor:hover {
	transform: translateY( -3px );
}

.bb-flavor-top {
	display: flex;
	align-items: center;
	gap: 1rem;
}

/* No explicit min-width here — leaving it at the flex default (auto) means
   this column can never shrink narrower than its own text's natural
   wrapping points (whole words/Thai syllable clusters). An explicit
   min-width: 0 previously let the row's flex algorithm squeeze it down to
   almost nothing at tablet widths, forcing Thai script and "(WAN)"-style
   labels to wrap one character per line; a fixed min-width fixed that but
   also made wider icons (sugar, chili) wrap to their own row below the
   copy at desktop width while narrower icons (vinegar, salt) stayed
   inline, an inconsistent look across the four cards. */
.bb-flavor-copy {
	flex: 1 1 auto;
}

/* Sits smaller and second — the transliteration is a pronunciation aid,
   not the headline. Parenthesized in the content itself. */
.bb-flavor .bb-thai {
	color: var( --bb-primary );
	font-size: 1.375rem;
	font-weight: 700;
	margin: 0 0 0.15rem;
}

/* Pre-existing bug: ".bb-flavors .bb-eyebrow" is a plain descendant selector,
   so it was also painting these per-card transliteration labels ("(wan)",
   "(priao)"...) as solid magenta pills meant only for the section-level
   eyebrow above. Explicit resets here (same specificity, declared later)
   strip that back down to plain text. */
.bb-flavor .bb-eyebrow {
	color: var( --bb-muted-text );
	background-color: transparent;
	border: none;
	display: block;
	padding: 0;
	margin: 0 0 0.5rem;
}

/* The English name is the card's headline — clearly the largest and
   boldest of the three labels (Thai script, phonetic, English) instead of
   sitting smaller than the decorative Thai line above it. */
.bb-flavor h3 {
	color: var( --bb-ink );
	font-size: 1.75rem;
	margin: 0;
}

/* Branded sticker illustrations are this card's featured visual, not a
   supporting note — large, in its own right-hand container, centered
   vertically against the copy column. Sized by height with width left
   auto so each icon's own aspect ratio (they aren't all square) renders
   undistorted. */
.bb-flavor-icon-wrap {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Same two-layer hard-edged drop-shadow as the section's own mortar-and-
   pestle illustration (and the hero's sticker cutouts), so these read as
   part of the same "sticker" family instead of a plain flat icon. */
.bb-flavor-icon-wrap img.bb-flavor-icon {
	width: auto;
	height: 6rem;
	margin: 0;
	filter: drop-shadow( 7px 7px 0 var( --bb-ink ) );
}

.bb-flavor p {
	color: var( --bb-ink );
	font-size: var( --bb-fs-body-sm );
	line-height: 1.6;
	margin: 0.5rem 0 0;
}

/* === story === */
.bb-story {
	position: relative;
	isolation: isolate;
	margin-block: 0;
	background-color: var( --bb-lime );
	padding-block: var( --bb-section-y );
}

/* Same faint texture formula as the other sections. */
.bb-story::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/Frame-48097662-scaled.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-story h2 {
	color: var( --bb-ink );
	margin-block: 0.75rem 1.25rem;
	max-width: 24ch;
}

.bb-story-copy p:not( .bb-eyebrow ) {
	color: var( --bb-ink );
	font-size: 1rem;
	line-height: 1.75;
}

.bb-story img {
	border-radius: 0;
	border: var( --bb-keyline ) solid var( --bb-ink );
}

.bb-quote {
	border-left: var( --bb-halo ) solid var( --bb-primary );
	padding-left: 1rem;
	margin: 0;
	font-style: normal;
	color: var( --bb-ink );
}

.bb-stat .bb-eyebrow {
	color: var( --bb-muted-text );
	margin: 0 0 0.25rem;
}

.bb-stat p:last-child {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.125rem;
	color: var( --bb-ink );
	margin: 0;
}

/* === faq === */
.bb-faq {
	border-top: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: var( --bb-section-y );
}

/* Centered like .bb-cta's heading: text-align lives on the wrapping group
   (bb-faq-head) rather than the h2 itself, since the h2 is display: inline
   for the clone-plate effect and its own text-align would be inert. */
.bb-faq-head {
	text-align: center;
}

.bb-faq h2 {
	color: var( --bb-ink );
	margin-block: 0.75rem 0;
}

.bb-faq-list {
	border-top: 2px solid var( --bb-ink );
}

.bb-faq-list .wp-block-details {
	border-bottom: 2px solid var( --bb-ink );
	padding: 0;
}

.bb-faq-list summary {
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.1rem 0.25rem;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1rem;
	line-height: 1.35;
	transition: color 0.15s steps(2);
}

.bb-faq-list summary::-webkit-details-marker {
	display: none;
}

.bb-faq-list summary::after {
	content: "";
	flex: none;
	width: 9px;
	height: 9px;
	margin-right: 0.35rem;
	border-right: 2px solid var( --bb-muted-text );
	border-bottom: 2px solid var( --bb-muted-text );
	transform: rotate( 45deg );
	transition: transform 0.25s ease;
}

.bb-faq-list .wp-block-details[open] summary::after {
	transform: rotate( -135deg );
}

.bb-faq-list summary:hover {
	color: var( --bb-primary );
}

.bb-faq-list .wp-block-details > *:not( summary ) {
	color: var( --bb-ink );
	font-size: var( --bb-fs-body-sm );
	line-height: 1.7;
	margin: 0 0 1.1rem;
	max-width: 68ch;
	padding-inline: 0.25rem;
}

.bb-faq-foot {
	text-align: center;
	margin-top: 2.5rem;
}

.bb-faq-foot p {
	color: var( --bb-ink );
	font-size: var( --bb-fs-small );
	margin-bottom: 1.25rem;
}

/* === cta === */
/* Acid lime, the brand's signature accent, for this closing band. Lime is
   light, so every text/button color here is ink, not cream: ink-on-lime
   clears ~15:1, cream-on-lime barely clears ~1.3:1. */
/* A street-stall photo sits behind the lime, desaturated and faint — a
   motif, not a photo section. Grayscale + low opacity live on ::before (not
   the section itself) so the filter/opacity never touches the real text or
   buttons; a second layer (::after) adds a halftone dot screen over the
   photo via mix-blend-mode, reusing the same dot-screen language as the
   flavors section's texture instead of inventing a new one. */
.bb-cta {
	position: relative;
	overflow: hidden;
	background-color: var( --bb-lime );
	padding-block: clamp( 3rem, 2rem + 4vw, 4.5rem );
	border-top: var( --bb-keyline ) solid var( --bb-ink );
	/* The h2 below is display: inline for its clone-plate effect, so
	   centering it has to come from this containing block instead of the
	   heading's own (inert, on an inline box) text-align. */
	text-align: center;
}

.bb-cta::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: url( "/wp-content/uploads/2026/08/pexels-tonywuphotography-18911914-1-scaled.png" );
	background-size: cover;
	background-position: center 78%;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.16;
	z-index: 0;
	pointer-events: none;
}

.bb-cta > * {
	position: relative;
	z-index: 1;
}

.bb-cta h2 {
	color: var( --bb-ink );
	margin-bottom: 1.75rem;
	max-width: 30ch;
	margin-inline: auto;
}

/* Small closing line under the main CTA band — deliberately quiet (plain
   text + icon, no button/card treatment) rather than another feature
   section, just a low-key nudge toward the Instagram account. */
.bb-ig-cta {
	text-align: center;
	padding-block: 2rem;
}

.bb-ig-cta-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var( --wp--preset--font-family--mono );
	font-size: 0.8rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var( --bb-ink );
	text-decoration: none;
}

.bb-ig-cta-link:hover {
	color: var( --bb-primary );
	text-decoration: underline;
}

.bb-ig-cta-icon {
	width: 1.2em;
	height: 1.2em;
	flex-shrink: 0;
}

.bb-ig-cta-handle {
	display: inline-block;
	margin-top: 0.35rem;
	font-family: var( --wp--preset--font-family--mono );
	font-size: 0.75rem;
	color: var( --bb-muted-text );
	text-decoration: none;
}

.bb-ig-cta-handle:hover {
	color: var( --bb-primary );
	text-decoration: underline;
}

/* === footer === */
.bb-footer {
	background-color: var( --bb-cream );
	border-top: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: clamp( 2.5rem, 2rem + 3vw, 4rem ) 2rem;
}

/* Plain transparent logo mark, sized to match the header treatment — no
   bordered plate around it. (An earlier "signboard" version added a bordered
   background box here; on a transparent PNG that box reads as an opaque
   background the logo doesn't actually have, so it's gone.) */
.bb-footer-brand {
	display: inline-block;
	margin: 0 0 0.75rem;
}

.bb-footer-brand img {
	height: 48px;
	width: auto;
}

.bb-footer-legal {
	font-family: var( --wp--preset--font-family--mono );
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-size: 0.6875rem;
	font-weight: 700;
	color: var( --bb-terracotta );
	margin: 0 0 0.75rem;
}

.bb-footer p {
	color: var( --bb-ink );
	font-size: var( --bb-fs-small );
	line-height: 1.65;
}

/* Column headings read as small shelf-category labels: a short colored
   underline rule instead of plain caps text sitting alone. */
.bb-footer h3 {
	display: inline-block;
	font-family: var( --wp--preset--font-family--mono );
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-size: 0.6875rem;
	font-weight: 700;
	color: var( --bb-ink );
	margin: 0 0 0.9rem;
	border-bottom: 3px solid var( --bb-primary );
	padding-bottom: 0.4rem;
}

.bb-footer-top > .wp-block-column:nth-child( 3 ) h3 {
	border-bottom-color: var( --bb-magenta );
}

.bb-footer-links {
	list-style: none;
	padding: 0;
	margin: 0;
	display: grid;
	gap: 0.55rem;
}

.bb-footer-links a,
.bb-footer-contact a {
	font-size: var( --bb-fs-small );
	color: var( --bb-ink );
	transition: color 0.15s steps(2);
}

.bb-footer-links a:hover,
.bb-footer-contact a:hover {
	color: var( --bb-primary );
}

.bb-footer .wp-block-social-links .wp-social-link {
	background-color: var( --bb-lime );
	color: var( --bb-ink );
	border-radius: 0;
	border: 2px solid var( --bb-ink );
}

.bb-footer-base {
	border-top: 2px solid var( --bb-ink );
	margin-top: 2.5rem;
	padding-top: 1.25rem;
}

.bb-footer-base p {
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.05em;
	font-size: 0.7rem;
	margin: 0;
}

.bb-footer-legal-links a {
	color: var( --bb-ink );
	transition: color 0.15s steps( 2 );
}

.bb-footer-legal-links a:hover {
	color: var( --bb-primary );
}

/* === motion === */
/* Reveal-on-scroll: elements are visible by default so the block editor and
   no-JS visitors always see finished content. reveal.js adds .bb-reveal-ready
   to opt in to the hidden start state, then .bb-in as each section scrolls in. */
.bb-reveal-ready .bb-reveal {
	opacity: 0;
	transform: translateY( 18px );
}

.bb-reveal-ready .bb-reveal.bb-in {
	opacity: 1;
	transform: none;
	transition: opacity 0.7s ease, transform 0.7s cubic-bezier( 0.16, 1, 0.3, 1 );
}

@media ( prefers-reduced-motion: reduce ) {
	.bb-reveal-ready .bb-reveal,
	.bb-reveal-ready .bb-reveal.bb-in {
		opacity: 1;
		transform: none;
		transition: none;
	}

	/* Button system: keep the shadow change (still a visible state cue)
	   but drop the translateY press motion. !important is needed because
	   the tier selectors below (.wp-block-button .wp-element-button
	   .wp-block-button__link:hover, 4 classes deep) otherwise outrank this
	   plain .wp-element-button:hover override on specificity alone. */
	.bb-flavor:hover,
	.wp-element-button:hover,
	.wp-element-button:active,
	.wc-block-mini-cart__footer-checkout:hover,
	.wc-block-mini-cart__footer-checkout:active,
	.wc-block-mini-cart__shopping-button:hover,
	.wc-block-mini-cart__shopping-button:active,
	.wc-block-mini-cart__footer-cart:hover,
	.wc-block-mini-cart__footer-cart:active,
	.wc-block-checkout .wc-block-components-checkout-place-order-button:hover,
	.wc-block-checkout .wc-block-components-checkout-place-order-button:active,
	.single-product .single_add_to_cart_button:hover,
	.single-product .single_add_to_cart_button:active {
		transform: none !important;
	}

	* {
		animation: none !important;
		scroll-behavior: auto !important;
	}
}

/* === home shop === */
/* Same whisper-of-magenta base as .bb-story, for the same reason: an opaque
   ground with a hint of brand color instead of plain cream, light enough
   that ink text keeps full contrast. */
.bb-home-shop {
	position: relative;
	isolation: isolate;
	margin-top: 0;
	background-color: var( --bb-magenta );
	padding-block: clamp( 2rem, 1.5rem + 2vw, 3rem );
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
}

/* Same faint texture formula as the other sections, same edge-fade so it
   doesn't switch on/off hard against this section's own top/bottom
   keylines. */
.bb-home-shop::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/Frame-48097660.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-home-shop h2 {
	color: var( --bb-ink );
}

.bb-home-shop-link a {
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.8rem;
	color: var( --bb-primary );
	font-weight: 700;
	text-decoration: none;
}

.bb-home-shop-link a:hover {
	text-decoration: underline;
}

.bb-home-shop-grid .wc-block-product-template {
	gap: 1.25rem !important;
	margin-top: 2rem !important;
}

/* Single featured product on the home page: with only one SKU to sell, this
   is a spotlight, not a grid card — big photo, full price hierarchy, a
   supporting trust line, and a button sized to its own text instead of
   stretching to fill the grid cell the way shop-archive cards do. Full width
   of the section (no capped max-width) so it lines up with the "Grab a jar"
   heading row above it instead of floating narrower with mismatched margins. */
.bb-home-featured .wc-block-product-template {
	display: block !important;
	margin-top: 2rem !important;
	width: 100%;
}

/* This is the site's one product spotlight, not just another bordered card —
   a lime sticker-ring (the same "colored gap, then a ring" construction as
   the ingredient pills) around the usual ink border and offset shadow lifts
   it a level above the plain single-shadow cards used everywhere else, so
   it reads as the page's featured "shop now" moment rather than a listing
   that happens to be alone in its section. */
.bb-home-featured .bb-shop-card {
	display: grid;
	grid-template-columns: minmax( 0, 22rem ) minmax( 0, 1fr );
	gap: 0.4rem 3rem;
	align-items: center;
	padding: 2rem;
	height: auto;
	border-width: 4px;
	box-shadow: none;
}

/* No whole-card hover here (unlike the plain grid .bb-shop-card this
   inherits from): only the title link and the Add to Cart button inside
   are actually clickable, so animating the entire card on hover read as a
   false "this whole square is a button" affordance. Explicitly cancels
   the base .bb-shop-card:hover lift/shadow-grow this element would
   otherwise still pick up. */
.bb-home-featured .bb-shop-card:hover {
	transform: none;
	box-shadow: none;
}

/* min-width: 0 overrides the grid item's default "auto" minimum size,
   which is based on its content's intrinsic size — without it, a
   high-resolution product photo can force this column (and the whole
   grid) wider than the minmax(0, 22rem) track allows, pushing the card
   past the section's normal margins. Same fix as .bb-direct-card-image. */
.bb-home-featured .bb-shop-card .wc-block-components-product-image {
	grid-column: 1;
	min-width: 0;
	align-self: center;
	margin: 0;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border: var( --bb-keyline ) solid var( --bb-ink );
}

/* The <a> WooCommerce wraps the image in has no explicit height of its own
   (it shrinks to the photo's natural size), so the img's height:100% below
   had nothing definite to resolve against and fell back to the photo's own
   aspect ratio — this is what left a blank gap under the photo inside the
   square frame. Giving the link itself 100% height closes that gap in the
   chain. */
.bb-home-featured .bb-shop-card .wc-block-components-product-image a {
	display: block;
	height: 100%;
}

/* !important: the img itself carries native width/height attributes
   (1024x737) plus WooCommerce core's own product-image.css rule
   (`.wc-block-components-product-image img { height: auto; ... }`) — the
   combination keeps the image sized to its own intrinsic aspect ratio
   instead of filling this square frame, which is exactly the gap under the
   photo this rule is fixing. */
.bb-home-featured .bb-shop-card .wc-block-components-product-image img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover !important;
}

/* Title/meta/price/note/CTA now live in one wrapping group (bb-shop-card-content)
   instead of five separate grid items each pinned to their own row. That old
   layout put the image (spanning every row) and the text (four "auto" rows
   plus a flexible last row) in the same grid — whenever the square image was
   taller than the text's natural height, the extra space got distributed
   across the "auto" rows too, not just the trailing flexible one, which
   pried every line apart from the next. A single flex column sized to its
   own content sidesteps that distribution entirely: the text stays exactly
   as tight as its own margins say, and the whole block centers next to the
   image via align-items on the grid, the same as before. */
.bb-home-featured .bb-shop-card .bb-shop-card-content {
	grid-column: 2;
	display: flex;
	flex-direction: column;
}

/* Kills WordPress's automatic "flow" block-gap (the theme's global 1.5rem
   blockGap, applied via margin-top on every child after the first) so
   spacing between title/meta/price/note/CTA comes only from the explicit
   margins below — otherwise it stacks on top of them, which is exactly
   what was prying these lines apart even after they'd been grouped. */
.bb-home-featured .bb-shop-card .bb-shop-card-content > * {
	margin-top: 0 !important;
}

.bb-home-featured .bb-shop-card h3 {
	font-size: var( --wp--preset--font-size--x-large );
	line-height: 1;
	margin: 0 0 0.5rem;
	text-transform: none;
}

.bb-home-featured .bb-shop-card .bb-shop-card-meta {
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.75rem;
	color: var( --bb-muted-text );
	margin: 0 0 0.75rem;
}

.bb-home-featured .bb-shop-card .wc-block-components-product-price {
	font-size: 2rem;
	font-weight: 700;
	margin: 0 0 0.5rem;
}

.bb-home-featured .bb-shop-card .bb-shop-card-note {
	color: var( --bb-ink );
	font-size: var( --bb-fs-body-sm );
	line-height: 1.6;
	margin: 0 0 0.75rem;
}

.bb-home-featured .bb-shop-card [data-block-name="woocommerce/add-to-cart-with-options"] {
	align-self: flex-start;
	width: auto;
	margin-top: 1.5rem;
}

.bb-home-featured .bb-shop-card .wp-block-button .wp-element-button {
	width: auto;
	padding-inline: 2.5rem;
}

.bb-home-featured .bb-shop-card .bb-add-to-cart-row .wp-block-woocommerce-product-button {
	flex: 0 0 auto;
	width: auto;
	margin-top: 0;
	padding-top: 0;
	display: flex;
}

.bb-home-featured .bb-shop-card .bb-add-to-cart-row {
	width: auto;
	align-items: stretch;
}

@media ( max-width: 640px ) {
	.bb-home-featured .bb-shop-card {
		grid-template-columns: 1fr;
		gap: 0.4rem;
		padding: 1.25rem;
	}

	.bb-home-featured .bb-shop-card .wc-block-components-product-image,
	.bb-home-featured .bb-shop-card .bb-shop-card-content {
		grid-column: 1;
	}

	.bb-home-featured .bb-shop-card .wc-block-components-product-image {
		max-width: 14rem;
		margin: 0 auto 1rem;
	}

	.bb-home-featured .bb-shop-card h3 {
		margin-top: 0.75rem;
	}

	.bb-home-featured .bb-shop-card [data-block-name="woocommerce/add-to-cart-with-options"] {
		width: 100%;
	}

	.bb-home-featured .bb-shop-card .wp-block-button .wp-element-button {
		width: 100%;
	}
}

/* === shop === */
.bb-shop-hero {
	padding-block: clamp( 3rem, 2rem + 4vw, 5.5rem ) var( --bb-section-y );
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
}

/* Same faint street-stall motif as the story/CTA/home-shop/retail-hero
   sections, for a consistent texture language across every page's top
   band. Lives on ::after (not ::before, already spoken for by .bb-grain's
   noise texture on this element); the sticky header's own bottom keyline
   sits right above this section, so both edges fade the same short 20px
   as elsewhere rather than cutting off hard against it. */
.bb-shop-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/pexels-tonywuphotography-18911914-1-scaled.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.06;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-shop-hero h1 {
	margin-block: 0.5rem 0;
}

.bb-shop-hero-lede p {
	max-width: 52ch;
	margin-top: 1.25rem;
}

.bb-shop-grid {
	position: relative;
	isolation: isolate;
	background-color: var( --bb-magenta );
	padding-block: var( --bb-section-y );
}

/* Same faint-texture formula as .bb-shop-hero above it, but a different
   source image (the .bb-home-shop motif instead of the street-stall photo)
   so the two stacked sections don't repeat the same picture. */
.bb-shop-grid::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/Frame-48097660.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-shop-collection .wc-block-product-template {
	gap: 1.25rem !important;
}

.bb-shop-card {
	position: relative;
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 0.85rem;
	height: 100%;
	display: flex;
	flex-direction: column;
	box-shadow: none;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.bb-shop-card:hover {
	transform: translate( -2px, -2px );
	box-shadow: none;
}

/* Title/price/add-to-cart wrapped in one flex column so the "pin the button
   to the card's bottom edge" trick (margin-top: auto below) still has a
   single flex-formatting-context child to push against, the same fix
   applied to the home page's featured card. flex: 1 lets this wrapper fill
   whatever height .bb-shop-card doesn't use on the image, so the auto
   margin still resolves to the card's own bottom edge, not just the
   wrapper's. */
.bb-shop-card-content {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-width: 0;
}

@media ( prefers-reduced-motion: reduce ) {
	.bb-shop-card {
		transition: none;
	}

	.bb-shop-card:hover {
		transform: none;
	}
}

.bb-shop-card .wc-block-components-product-image {
	border-radius: 0;
	overflow: hidden;
	margin-bottom: 0.35rem;
	aspect-ratio: 1 / 1;
}

.bb-shop-card .wc-block-components-product-image img {
	border-radius: 0;
	object-fit: cover;
	width: 100%;
	height: 100%;
}

.bb-shop-card .wp-block-post-title {
	font-size: var( --bb-fs-body-sm );
	line-height: 1.25;
	margin-top: 0.6rem;
	margin-bottom: 0.15rem;
}

.bb-shop-card .wp-block-post-title a {
	color: var( --bb-ink );
}

.bb-shop-card .wp-block-post-title a:hover {
	text-decoration: underline;
}

.bb-shop-card .wc-block-components-product-price {
	font-family: var( --wp--preset--font-family--mono );
	color: var( --bb-primary );
	font-weight: 700;
	font-size: 1.25rem;
	margin-top: 0.25rem;
	margin-bottom: 0.5rem;
}

.bb-shop-card .wc-block-components-product-price del {
	color: var( --bb-muted-text );
	opacity: 0.7;
	margin-right: 0.4rem;
}

.bb-shop-card .wp-block-button {
	margin-top: auto;
	padding-top: 0.65rem;
	width: 100%;
}

.bb-shop-card .wp-block-button .wp-element-button {
	width: 100%;
	padding-top: 0.55rem;
	padding-bottom: 0.55rem;
}

/* Quantity stepper + Add to Cart button, replacing the old single button
   that silently incremented "N in cart" on every click with no way to
   choose a quantity or see it before adding. */
.bb-shop-card [data-block-name="woocommerce/add-to-cart-with-options"] {
	margin-top: auto;
	padding-top: 0.65rem;
	width: 100%;
}

.bb-shop-card .bb-add-to-cart-row {
	display: flex;
	align-items: stretch;
	gap: 0.5rem;
	width: 100%;
}

/* Overrides the generic .bb-shop-card .wp-block-button rule above, which
   still matches this element (it also carries the plain wp-block-button
   class) and was leaving a stray margin-top: auto + padding-top from the
   old vertical-stack layout — that pushed the button toward the bottom of
   the row instead of stretching to match the stepper's height, throwing
   the two out of vertical alignment. */
.bb-shop-card .bb-add-to-cart-row .wp-block-woocommerce-product-button {
	flex: 1 1 0%;
	width: auto;
	min-width: 0;
	margin-top: 0;
	padding-top: 0;
	display: flex;
}

.bb-shop-card .bb-add-to-cart-row .wp-block-woocommerce-product-button .wp-element-button {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
}

.bb-shop-card .bb-qty-stepper {
	flex: 0 0 auto;
}

.bb-shop-card .wc-block-components-quantity-selector {
	display: flex;
	align-items: stretch;
	height: 100%;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-card );
}

.bb-shop-card .wc-block-components-quantity-selector__button {
	width: 2.1rem;
	border: none;
	background: transparent;
	color: var( --bb-ink );
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	font-size: 1rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.bb-shop-card .wc-block-components-quantity-selector__button:hover:not(:disabled) {
	background-color: var( --bb-muted );
}

.bb-shop-card .wc-block-components-quantity-selector__button:disabled {
	opacity: 0.35;
	cursor: default;
}

.bb-shop-card .wc-block-components-quantity-selector__input {
	width: 2.25rem;
	border: none;
	border-inline: var( --bb-keyline ) solid var( --bb-ink );
	background: transparent;
	text-align: center;
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	color: var( --bb-ink );
	-moz-appearance: textfield;
}

.bb-shop-card .wc-block-components-quantity-selector__input::-webkit-outer-spin-button,
.bb-shop-card .wc-block-components-quantity-selector__input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.bb-shop-card .bb-stock-indicator {
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 0.75rem;
	color: var( --bb-muted-text );
}

/* Solo-product spotlight: with only one SKU in the collection this grid
   read as a single small card lost in a lot of empty page, so it borrows
   the home page's featured-product treatment (big photo, lime sticker-ring,
   content vertically centered beside the image) instead of the plain
   grid-card look built for a full shelf. Scoped to :only-child so it's
   self-retiring — the moment a second product is added, this stops
   matching and both cards fall back to the ordinary grid card below,
   with no further changes needed here. */
.bb-shop-collection:not(.bb-home-featured) .wc-block-product-template:has( > li:only-child ) {
	grid-template-columns: 1fr !important;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card {
	display: grid;
	grid-template-columns: minmax( 0, 22rem ) minmax( 0, 1fr );
	gap: 0.4rem 3rem;
	align-items: center;
	padding: 2rem;
	height: auto;
	border-width: 4px;
	box-shadow:
		0 0 0 4px var( --bb-cream ),
		10px 10px 0 0 var( --bb-ink );
}

/* No whole-card hover: only the title link and Add to Cart button inside
   are actually clickable, so animating the entire card read as a false
   "this whole square is a button" affordance. Explicitly cancels the base
   .bb-shop-card:hover lift/shadow-grow this element would otherwise still
   pick up. Same fix as the home page's featured card. */
.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card:hover {
	transform: none;
	box-shadow:
		0 0 0 4px var( --bb-cream ),
		10px 10px 0 0 var( --bb-ink );
}

/* min-width: 0 overrides the grid item's default "auto" minimum size,
   which is based on its content's intrinsic size — without it, a
   high-resolution product photo can force this column (and the whole
   grid) wider than the minmax(0, 22rem) track allows, pushing the card
   past the page's normal margins. Same fix as .bb-direct-card-image. */
.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .wc-block-components-product-image {
	grid-column: 1;
	min-width: 0;
	margin: 0 0 0.35rem;
	aspect-ratio: 1 / 1;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card-content {
	grid-column: 2;
	flex: none;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .wp-block-post-title {
	font-size: var( --wp--preset--font-size--x-large );
	line-height: 1.15;
	margin-top: 0;
	margin-bottom: 0.5rem;
	text-transform: none;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .bb-shop-card-note {
	color: var( --bb-ink );
	font-size: var( --bb-fs-body-sm );
	line-height: 1.6;
	margin: 0 0 0.75rem;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .wc-block-components-product-price {
	font-size: 2rem;
	margin-top: 0;
	margin-bottom: 0.75rem;
}

.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card [data-block-name="woocommerce/add-to-cart-with-options"] {
	margin-top: 0;
	align-self: flex-start;
	width: auto;
	min-width: 18rem;
}

@media ( max-width: 640px ) {
	.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card {
		grid-template-columns: 1fr;
		padding: 1.25rem;
	}

	.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .wc-block-components-product-image,
	.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card-content {
		grid-column: 1;
	}

	.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card .wc-block-components-product-image {
		max-width: 16rem;
		margin: 0 auto 1rem;
	}

	.bb-shop-collection:not(.bb-home-featured) li:only-child .bb-shop-card [data-block-name="woocommerce/add-to-cart-with-options"] {
		width: 100%;
		min-width: 0;
	}
}

/* Base quantity-stepper look shared by every WooCommerce quantity control
   on the site (shop cards, single product, and the cart page's line
   items) so the interaction reads the same everywhere instead of the
   plugin's default thin gray box. */
.wc-block-components-quantity-selector {
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
}

.wc-block-components-quantity-selector__button {
	color: var( --bb-ink );
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
}

.wc-block-components-quantity-selector__input {
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	color: var( --bb-ink );
}

/* Single product page's Add to Cart form (classic quantity + button),
   matched to the same bordered-mono stepper used on shop cards so the
   interaction feels identical everywhere it appears. */
.bb-add-to-cart form.cart {
	display: flex;
	align-items: stretch;
	gap: 0.6rem;
	flex-wrap: wrap;
	margin-top: 0.5rem;
}

.bb-add-to-cart .wc-block-components-quantity-selector {
	display: flex;
	align-items: stretch;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-card );
}

.bb-add-to-cart .wc-block-components-quantity-selector__button {
	width: 2.4rem;
	border: none;
	background: transparent;
	color: var( --bb-ink );
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.bb-add-to-cart .wc-block-components-quantity-selector__button:hover {
	background-color: var( --bb-muted );
}

.bb-add-to-cart .wc-block-components-quantity-selector__input {
	width: 3rem;
	border: none;
	border-inline: var( --bb-keyline ) solid var( --bb-ink );
	background: transparent;
	text-align: center;
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	font-size: 1rem;
	color: var( --bb-ink );
	-moz-appearance: textfield;
}

.bb-add-to-cart .wc-block-components-quantity-selector__input::-webkit-outer-spin-button,
.bb-add-to-cart .wc-block-components-quantity-selector__input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.bb-add-to-cart .single_add_to_cart_button {
	padding-inline: 2rem;
}

.bb-shop-card .wp-block-read-more {
	margin-top: auto;
	padding-top: 0.65rem;
	display: block;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	background-color: var( --bb-cream );
	color: var( --bb-ink );
	border-radius: 0;
	border: var( --bb-keyline ) solid var( --bb-ink );
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	padding-block: 0.55rem;
	font-size: 0.875rem;
	font-weight: 400;
	text-decoration: none;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.bb-shop-card .wp-block-read-more:hover {
	background-color: var( --bb-magenta );
	transform: translate( calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ), calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.wc-block-components-product-sale-badge {
	background-color: var( --bb-lime );
	color: var( --bb-ink );
	border-radius: 0;
	border: 2px solid var( --bb-ink );
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	font-weight: 700;
}

/* === retail === */
.bb-retail-hero {
	position: relative;
	isolation: isolate;
	padding-block: clamp( 3rem, 2rem + 4vw, 5.5rem ) var( --bb-section-y );
}

/* Same faint street-stall motif as the homepage's story and closing CTA
   sections, tying this page's hero back to the same "started as a street
   stall" thread. Fades at the top/bottom edges rather than cutting off
   hard at the section boundary. */
.bb-retail-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/09/Frame-48097663.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.06;
	-webkit-mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	mask-image: linear-gradient( to bottom, transparent 0, black 20px, black calc( 100% - 20px ), transparent 100% );
	pointer-events: none;
}

.bb-retail-hero > .wp-block-group {
	align-items: center;
	gap: clamp( 2rem, 1rem + 3vw, 3.5rem );
}

.bb-retail-hero-copy {
	flex: 1 1 55%;
	min-width: 0;
}

.bb-retail-hero-image {
	flex: 1 1 40%;
	margin: 0;
}

.bb-retail-hero-image img {
	border-radius: 0;
	border: var( --bb-keyline ) solid var( --bb-ink );
	width: 100%;
	height: auto;
	display: block;
}

.bb-retail-hero h1 {
	margin-block: 0.5rem 0;
	margin-inline: 0;
	max-width: 20ch;
}

.bb-retail-hero-lede p {
	max-width: 52ch;
	margin-top: 1.25rem;
}

.bb-retail-search label {
	display: block;
	margin-bottom: 0.6rem;
}

.bb-retail-search input {
	width: 100%;
	max-width: 420px;
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	background-color: var( --bb-card );
	color: var( --bb-ink );
	padding: 0.85rem 1.1rem;
	font-size: 1rem;
	font-family: var( --wp--preset--font-family--sans );
}

.bb-retail-search input::placeholder {
	color: var( --bb-muted-text );
}

.bb-retail-instore {
	background-color: var( --bb-muted );
	border-block: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: var( --bb-section-y );
}

.bb-retail-instore h2 {
	color: var( --bb-ink );
	margin-bottom: 1.25rem;
}

.bb-retail-city {
	margin-top: 2.5rem;
}

.bb-retail-city:first-of-type {
	margin-top: 0;
}

.bb-retail-city-title {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0 0 1rem;
}

.bb-retail-city-title .bb-pin {
	color: var( --bb-primary );
	flex: none;
	width: 18px;
	height: 18px;
}

.bb-retail-city-title h3 {
	margin: 0;
}

/* Real grid instead of manually-batched rows of three wp:columns — any
   number of stores in a city auto-flows into place, so adding a 7th (or
   4th, or 10th) retailer never again means an unevenly-filled row or
   empty filler columns just to keep the grid rectangular. */
.bb-retail-grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	align-items: stretch;
	gap: 1.5rem;
}

/* WordPress's own "flow" layout CSS (`.is-layout-flow > * + *`) adds its
   block-gap margin-top to every child but the first regardless of this
   group's own `display: grid` override — which is exactly why the second
   and third card in each row sat 24px lower than the first. The grid's own
   `gap` already handles spacing, so this margin is pure conflict; zero it. */
.bb-retail-grid.is-layout-flow > * {
	margin-block-start: 0;
}

@media ( max-width: 781px ) {
	.bb-retail-grid {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( max-width: 480px ) {
	.bb-retail-grid {
		grid-template-columns: 1fr;
	}
}

/* Fixed height, not just per-row stretch: a wrapping grid still reads as
   uneven if row 1 is 167px (a two-line store name) and row 2 is 122px (all
   one-liners) — every card needs to match every other card, not just its
   own row-mates, for the grid to actually look like a grid. 168px comfortably
   fits the longest current combination (two-line name + two-line address). */
.bb-store-card {
	position: relative;
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 1.25rem;
	height: 145px;
	box-shadow: none;
}

.bb-store-card h4 {
	margin: 0 0 0.5rem;
}

.bb-store-card-address {
	color: var( --bb-muted-text );
	font-size: var( --bb-fs-body-sm );
	margin: 0 0 0.9rem;
}

.bb-store-card a.bb-store-link {
	color: var( --bb-primary );
	font-size: var( --bb-fs-small );
	text-decoration: underline;
	text-underline-offset: 3px;
}

.bb-retail-direct {
	position: relative;
	isolation: isolate;
	background-color: var( --bb-magenta );
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: var( --bb-section-y );
}

/* Same faint-texture formula as .bb-home-shop's own magenta band, so this
   section reads as the same pink-plus-texture language as the home page. */
.bb-retail-direct::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url( "/wp-content/uploads/2026/08/Frame-48097660.png" );
	background-size: cover;
	background-position: center;
	filter: grayscale( 1 ) contrast( 1.15 );
	opacity: 0.1;
	pointer-events: none;
}

.bb-retail-direct h2 {
	color: var( --bb-ink );
	margin-bottom: 1.75rem;
}

/* This is the highest-margin way to buy — its own spotlight treatment
   (full width, product photo, thick border, lime sticker-ring) instead of
   just another card in the online-retailer grid, echoing the same
   "featured, not just listed" language as the home page's shop card.
   width: 100% only — no max-width: none — so it still respects the
   section's normal 1152px contentSize constraint like every sibling
   section (in-store/online retailers) instead of stretching to the full
   alignfull bleed width, which read as broken once the thick sticker-ring
   shadow had almost no clearance left before the viewport edge. */
.bb-direct-card {
	width: 100%;
	display: grid;
	grid-template-columns: minmax( 0, 18rem ) minmax( 0, 1fr );
	align-items: center;
	gap: 0.5rem 2.5rem;
	padding: 2rem;
	border-width: 4px;
}

/* Extra .bb-online-card qualifier so this beats the later, equal-specificity
   ".bb-online-card { box-shadow: ... }" rule instead of losing the source-
   order tie (both are otherwise a single class, and this file has since
   grown enough above it that .bb-online-card now lands after this rule). */
.bb-online-card.bb-direct-card {
	box-shadow: none;
}

/* min-width: 0 overrides the grid item's default "auto" minimum size,
   which is based on its content's intrinsic size — without it, a
   high-resolution source image can force this column (and the whole grid)
   wider than the minmax(0, 18rem) track actually allows, pushing the card
   past the section's normal margins regardless of the img's own
   width/object-fit rules below. */
.bb-direct-card-image {
	grid-column: 1;
	min-width: 0;
	margin: 0;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border: var( --bb-keyline ) solid var( --bb-ink );
}

.bb-direct-card-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Icon, heading, copy, and button now live in one flex column
   (bb-direct-card-content) instead of four separate grid items each pinned
   to their own "auto"/"1fr" row. That old layout put the image (spanning
   every row) and the four text rows in the same grid, so whenever the
   square image was taller than the text's natural height the extra space
   got distributed across the "auto" rows too — pulling the button away
   from the copy instead of keeping it grouped, and via the shared
   .bb-online-card .wp-block-buttons rule's margin-top: auto, pushing it
   further still. A single grid item sized to its own content sidesteps
   that: the group centers as one block against the image via this grid's
   own align-items, and internal spacing comes only from the explicit
   margins below. */
.bb-direct-card-content {
	grid-column: 2;
	display: flex;
	flex-direction: column;
}

.bb-direct-card-content > * {
	margin-top: 0 !important;
}

.bb-direct-card-content .wp-block-buttons {
	margin-top: 0.75rem !important;
}

@media ( max-width: 640px ) {
	.bb-direct-card {
		grid-template-columns: 1fr;
		gap: 0.75rem;
		padding: 1.25rem;
	}

	.bb-direct-card-image,
	.bb-direct-card-content {
		grid-column: 1;
	}

	.bb-direct-card-image {
		max-width: 14rem;
		margin: 0 auto 0.5rem;
	}
}

.bb-retail-online {
	padding-block: var( --bb-section-y );
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
}

.bb-retail-online h2 {
	color: var( --bb-ink );
	margin-bottom: 2.5rem;
}

.bb-online-card {
	position: relative;
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 1.5rem;
	height: 100%;
	box-shadow: none;
}

.bb-online-card-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 0;
	border: 2px solid var( --bb-ink );
	background-color: var( --bb-muted );
	color: var( --bb-primary );
	margin: 0 0 1rem;
}

.bb-online-card-icon svg {
	width: 20px;
	height: 20px;
}

.bb-online-card h3 {
	margin: 0 0 0.5rem;
}

.bb-online-card p {
	color: var( --bb-ink );
	font-size: var( --bb-fs-small );
	line-height: 1.6;
	margin: 0 0 1.25rem;
}

.bb-online-card .wp-block-buttons {
	margin-top: auto;
}

/* Cards live in flow columns; stretch to equal height and pin the button row
   to the bottom of each card regardless of description length. */
.bb-retail-online .wp-block-columns > .wp-block-column {
	display: flex;
	flex-direction: column;
}

.bb-retail-online .wp-block-columns > .wp-block-column > .bb-online-card {
	display: flex;
	flex-direction: column;
	flex: 1;
}

.bb-retail-resellers {
	background-color: var( --bb-muted );
	border-block: var( --bb-keyline ) solid var( --bb-ink );
	padding-block: var( --bb-section-y );
}

.bb-retail-resellers h2 {
	color: var( --bb-ink );
	margin-bottom: 0.75rem;
}

.bb-retail-resellers-lede p {
	max-width: 46ch;
	margin: 0 0 2rem;
}

.bb-retail-resellers-lede a {
	color: var( --bb-primary );
	text-decoration: underline;
	text-underline-offset: 3px;
}

.bb-reseller-row {
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 1.1rem 1.4rem;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
}

.bb-reseller-row + .bb-reseller-row {
	margin-top: 0.9rem;
}

.bb-reseller-row h4 {
	margin: 0;
}

.bb-reseller-row p {
	color: var( --bb-muted-text );
	font-size: var( --bb-fs-small );
	margin: 0;
}

@media ( max-width: 781px ) {
	.bb-reseller-row {
		flex-direction: column;
		align-items: flex-start;
		gap: 0.35rem;
	}
}

@media ( max-width: 781px ) {
	.bb-retail-hero > .wp-block-group {
		flex-wrap: wrap;
	}

	.bb-retail-hero-copy,
	.bb-retail-hero-image {
		flex-basis: 100%;
	}
}

/* === checkout ===
   Distraction-free checkout is a deliberate, standard e-commerce pattern
   (WooCommerce ships its own minimal header for this page, dropping the
   main nav and footer on purpose so nothing pulls a shopper away mid
   purchase) — kept intact here. What wasn't intentional: that minimal
   header rendering with zero brand styling at all (plain black text link,
   no border, system font), which read as a broken/unfinished page at the
   most trust-sensitive step in the funnel. This restores the brand marks
   (logo treatment, cream ground, keyline) without restoring the distracting
   nav links themselves. */
.bb-checkout-header {
	background-color: var( --bb-cream );
	border-bottom: var( --bb-keyline ) solid var( --bb-ink );
}

.bb-checkout-header .wc-block-mini-cart__button,
.bb-checkout-header .wc-block-cart-link {
	color: var( --bb-ink );
}

.wc-block-checkout .wc-block-components-checkout-step__title {
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	letter-spacing: -0.01em;
}

/* Shipping/payment method names ("USPS Flat Rate", "Credit Card") read the
   same weight as the plain description text under them — bolding the name
   itself separates the choice from its explanation. */
.wc-block-checkout .wc-block-components-radio-control__label,
.wc-block-checkout .wc-block-components-payment-method-label {
	font-weight: 700;
}

#wc-elavon-converge-credit-card {
	background-color: var( --bb-card );
	padding: 0.75rem 1rem;
	text-align: center;
}

.wc-block-checkout .wc-block-components-text-input input,
.wc-block-checkout .wc-block-components-combobox-control input,
.wc-block-checkout select {
	border-radius: 0 !important;
	border-color: var( --bb-ink ) !important;
}

/* Tertiary tier (green fill) — the checkout's final submit gets the same
   token-driven fill/border/shadow/hover as every other button, instead of
   its own one-off flat color-swap hover. */
.wc-block-checkout .wc-block-components-checkout-place-order-button {
	border-radius: 0;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
	background-color: var( --bb-btn-tertiary-bg ) !important;
	color: var( --bb-btn-tertiary-text ) !important;
	border: var( --bb-keyline ) solid var( --bb-btn-tertiary-border ) !important;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

.wc-block-checkout .wc-block-components-checkout-place-order-button:hover {
	transform: translateY( var( --bb-btn-translate-hover ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.wc-block-checkout .wc-block-components-checkout-place-order-button:active {
	transform: translateY( var( --bb-btn-translate-active ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink );
}

.wc-block-checkout .wc-block-components-checkout-place-order-button:focus-visible {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

/* On mobile the "Continue to Payment" / "Place Order" button lives at the
   bottom of a long scrolling form — pinning it to the viewport means a
   shopper never has to scroll back down to find it. Padding is added back
   to the form so the fixed bar doesn't cover the last field/checkbox. */
@media ( max-width: 781px ) {
	.wc-block-checkout__actions {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 40;
		margin: 0;
		padding: 0.75rem 1rem calc( 0.75rem + env( safe-area-inset-bottom ) );
		background-color: var( --bb-cream );
		border-top: var( --bb-keyline ) solid var( --bb-ink );
	}

	.wc-block-checkout__main {
		padding-bottom: 6rem;
	}
}

/* === cart page ===
   "Proceed to checkout" is the one thing this page wants a shopper to do —
   it was rendering as a plain ink-outline button (our secondary-action
   style), same visual weight as "Add coupons," which under-sells the only
   primary action on the page. Color/shadow/hover now come from the shared
   .wp-element-button system; only the type treatment is set here. */
.wc-block-cart__submit-button {
	border-radius: 0;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
}

/* === pay for order (checkout/order-pay) ===
   This endpoint used to render as a bare, unbranded payment form — no
   product, no visual trust signals, default-gray gateway box, a tiny
   unstyled submit button. The PHP side (functions.php) injects a real
   order summary (product photo, name, qty, line total, subtotal/total,
   a secure-checkout note) since the gateway in use here falls back to a
   legacy template whose own line-items table isn't rendering in this
   block-theme flow; everything below restyles that summary plus the
   existing meta bar/payment form/button to read as one designed page
   instead of two mismatched fragments. */
.woocommerce-order-pay .entry-content {
	max-width: 32rem;
	margin-inline: auto;
	padding-block: clamp( 2rem, 1.5rem + 2vw, 3.5rem );
}

/* Superseded by .bb-pay-summary below (order number, total, and payment
   method all reappear there with product context attached) — keeping both
   would just repeat the same four facts twice at the top of the page.
   Which classic elements actually render here varies by how this page was
   reached (some flows also render WooCommerce's own plain product/qty/
   totals table, form-pay.php's table.shop_table) — hide both regardless,
   since .bb-pay-summary always covers the same info with a product photo
   attached. */
.woocommerce-order-pay ul.order_details,
.woocommerce-order-pay table.shop_table {
	display: none;
}

.bb-pay-back-link {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	padding-block: 0.75rem;
	margin-bottom: 0.5rem;
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --bb-ink );
	text-decoration: none;
}

.bb-pay-back-link:hover {
	color: var( --bb-primary );
}

.bb-pay-back-link svg {
	flex: none;
}

.bb-pay-summary {
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	padding: 1.5rem;
	margin-bottom: 1.5rem;
}

.bb-pay-summary-eyebrow {
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.1em;
	font-size: var( --bb-fs-small );
	font-weight: 700;
	color: var( --bb-muted-text );
	margin: 0 0 1rem;
}

.bb-pay-summary-items {
	list-style: none;
	margin: 0;
	padding: 0;
}

.bb-pay-summary-item {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding-block: 1rem;
	border-bottom: 1px solid var( --bb-muted );
}

.bb-pay-summary-item-image {
	flex: none;
	display: block;
	width: 64px;
	height: 64px;
	border: var( --bb-keyline ) solid var( --bb-ink );
	overflow: hidden;
}

.bb-pay-summary-item-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.bb-pay-summary-item-info {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.bb-pay-summary-item-name {
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1rem;
	line-height: 1.2;
	color: var( --bb-ink );
}

.bb-pay-summary-item-qty {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	color: var( --bb-muted-text );
}

.bb-pay-summary-item-total {
	flex: none;
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	color: var( --bb-ink );
}

.bb-pay-summary-totals {
	padding-top: 0.75rem;
}

.bb-pay-summary-totals-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 0.4rem;
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-body-sm );
	color: var( --bb-muted-text );
}

.bb-pay-summary-totals-row--method {
	display: none;
}

.bb-pay-summary-totals-row--grand {
	margin-top: 0.4rem;
	padding-top: 0.85rem;
	border-top: var( --bb-keyline ) solid var( --bb-ink );
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1.25rem;
	color: var( --bb-ink );
}

.bb-pay-summary-trust {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	margin: 1rem 0 0;
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	color: var( --bb-muted-text );
}

.bb-pay-summary-trust svg {
	flex: none;
	color: var( --bb-muted-text );
}

/* Order-review form: the gateway's own payment box shipped with WooCommerce's
   flat gray/lavender default styling — recast to the same card language as
   the summary above (ink border, cream fill) instead of two visually
   unrelated boxes stacked on the page. */
.woocommerce-order-pay #payment,
.woocommerce-order-pay .payment_box {
	background: none;
	padding: 0;
}

/* !important throughout: WooCommerce core ships
   ".woocommerce-checkout #payment div.payment_box" (an ID selector) for
   this exact box, and this page's body carries the woocommerce-checkout
   class too — that ID-weighted rule otherwise beats any class-only
   override regardless of source order. */
.woocommerce-order-pay .payment_box {
	background-color: var( --bb-card ) !important;
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0 !important;
	padding: 1.5rem !important;
	margin-top: 0 !important;
}

.woocommerce-order-pay .payment_box::before {
	content: none !important;
	display: none !important;
}

.woocommerce-order-pay .payment_box p:first-child {
	margin-top: 0;
	color: var( --bb-muted-text );
	font-size: var( --bb-fs-body-sm );
}

.woocommerce-order-pay .form-row label {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --bb-ink );
}

.woocommerce-order-pay .form-row .required {
	color: var( --bb-red );
}

.woocommerce-order-pay .form-row input.input-text {
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	background-color: var( --bb-cream );
	padding: 0.65em 0.75em;
}

.woocommerce-order-pay .form-row input.input-text:focus {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

/* Place order: the one action on this page — full-width, same Tertiary
   (green) tier as the block-checkout's own place-order button, instead of
   a browser-default <button class="button">. This markup isn't a
   .wp-element-button, so it needs its own complete button treatment. */
.woocommerce-order-pay #place_order {
	display: block;
	width: 100%;
	margin-top: 1.5rem;
	padding: 0.95em 1.5em;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
	font-size: 1rem;
	background-color: var( --bb-btn-tertiary-bg );
	color: var( --bb-btn-tertiary-text );
	border: var( --bb-keyline ) solid var( --bb-btn-tertiary-border );
	border-radius: 0;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

.woocommerce-order-pay #place_order:hover {
	transform: translateY( var( --bb-btn-translate-hover ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.woocommerce-order-pay #place_order:active {
	transform: translateY( var( --bb-btn-translate-active ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink );
}

.woocommerce-order-pay #place_order:focus-visible {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

/* Payment-method radio row (only shows on some flows into this page —
   others go straight to .payment_box) and the terms/privacy text below
   the form: same restyle treatment as everything else here, since both
   otherwise render in WooCommerce's unstyled defaults. */
.woocommerce-order-pay ul.wc_payment_methods {
	list-style: none;
	margin: 0 0 1rem;
	padding: 0;
}

.woocommerce-order-pay ul.wc_payment_methods label {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1rem;
	color: var( --bb-ink );
}

.woocommerce-order-pay .woocommerce-terms-and-conditions-wrapper {
	margin-top: 1.5rem;
}

.woocommerce-order-pay .woocommerce-privacy-policy-text p {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	color: var( --bb-muted-text );
}

.woocommerce-order-pay .woocommerce-privacy-policy-text a {
	color: var( --bb-ink );
}

.woocommerce-order-pay .form-row.terms {
	margin-top: 0.75rem !important;
}

.woocommerce-order-pay .form-row.terms input[type="checkbox"] {
	width: 1.1em;
	height: 1.1em;
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	accent-color: var( --bb-ink );
}

/* Validation errors ("Card number is missing", etc.) were rendering in
   WooCommerce's flat white/pink default notice style — the one element on
   this page still visually disconnected from everything else. */
.woocommerce-order-pay .woocommerce-error {
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-red );
	border-radius: 0;
	padding: 1rem 1.25rem;
	margin-bottom: 1.5rem;
	list-style: none;
}

.woocommerce-order-pay .woocommerce-error li {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	color: var( --bb-ink );
	font-size: var( --bb-fs-body-sm );
}

.woocommerce-order-pay .woocommerce-error li::before {
	content: "";
	flex: none;
	width: 0.5rem;
	height: 0.5rem;
	background-color: var( --bb-red );
}

/* Smaller screens: the summary/payment cards' desktop padding and the
   display-font product name were eating a disproportionate share of a
   375px viewport — tighten the whole page down a size instead of just
   letting it scale down as a smaller version of the desktop layout. */
@media ( max-width: 480px ) {
	.woocommerce-order-pay .entry-content {
		padding-inline: 1rem;
	}

	.bb-pay-summary,
	.woocommerce-order-pay .payment_box {
		padding: 1rem !important;
	}

	.bb-pay-summary-item {
		gap: 0.65rem;
		padding-block: 0.75rem;
	}

	.bb-pay-summary-item-image {
		width: 48px;
		height: 48px;
	}

	.bb-pay-summary-item-name {
		font-size: 0.875rem;
	}

	.bb-pay-summary-totals-row--grand {
		font-size: 1.0625rem;
	}

	.woocommerce-order-pay .form-row {
		margin-bottom: 0.75rem !important;
	}

	.woocommerce-order-pay .form-row input.input-text {
		padding: 0.5em 0.65em;
		font-size: 0.9375rem;
	}

	.woocommerce-order-pay #place_order {
		padding: 0.8em 1.25em;
		font-size: 0.9375rem;
	}
}

/* Place-order button (block checkout): this gateway's fallback flow briefly
   swaps the button's label for a plain checkmark icon right before
   redirecting to the payment step/processor — reading as "already done"
   while the request may still be in flight. Suppress both of WooCommerce's
   own icons (the checkmark, and its unstyled real spinner) and always show
   one consistent spinner for the whole "--loading" state instead, so the
   button never implies success before it's actually confirmed. */
.wc-block-components-checkout-place-order-button__icon,
.wc-block-components-checkout-place-order-button--loading .wc-block-components-spinner {
	display: none !important;
}

.wc-block-components-checkout-place-order-button--loading {
	position: relative;
}

.wc-block-components-checkout-place-order-button--loading .wc-block-components-checkout-place-order-button__text {
	visibility: hidden;
}

.wc-block-components-checkout-place-order-button--loading::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 1.1em;
	height: 1.1em;
	margin: -0.55em 0 0 -0.55em;
	border: 2px solid var( --bb-ink );
	border-top-color: transparent;
	border-radius: 50%;
	animation: bb-spin 0.6s linear infinite;
}

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

@media ( prefers-reduced-motion: reduce ) {
	.wc-block-components-checkout-place-order-button--loading::after {
		animation: none;
	}
}

/* === order confirmation (checkout/order-received "thank you" page) ===
   The default WooCommerce thank-you page reads as a flat receipt — order
   meta, a plain table, and two address columns, all the same visual weight
   as the pay-for-order form even though this is the one guaranteed "it
   worked" moment in checkout. Restructured (via templates/order-
   confirmation.html, overriding WC Blocks' bundled template) into a clear
   hierarchy: celebratory hero first, what's shipping second (with the
   product image WooCommerce doesn't show by default — see the
   woocommerce_order_item_name filter in functions.php), receipt details
   third, addresses last. */
.bb-confirmation {
	padding-bottom: clamp( 2.5rem, 2rem + 2vw, 4rem );
}

/* Real halftone-print street photo (same "Frame" asset family used as a
   faint 0.1-opacity whisper texture elsewhere — story/sauce/CTA sections),
   shown at full opacity here instead of faded, under a translucent moss
   wash so the section still reads as green rather than a photo. */
.bb-confirmation-hero {
	background-image:
		linear-gradient( rgba( 143, 174, 85, 0.82 ), rgba( 143, 174, 85, 0.82 ) ),
		url( "/wp-content/uploads/2026/08/Frame-48097656-scaled.png" );
	background-repeat: no-repeat;
	background-size: cover;
	background-position: center;
	padding-block: clamp( 2.5rem, 2rem + 2vw, 4rem ) clamp( 2rem, 1.6rem + 1.6vw, 3rem );
	text-align: center;
	margin-bottom: clamp( 1.5rem, 1.2rem + 1vw, 2.5rem );
}

.bb-confirmation-check {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 88px;
	height: 88px;
	margin: 0 auto 1.5rem;
	border-radius: 50%;
	border: var( --bb-keyline ) solid var( --bb-ink );
	background-color: var( --bb-lime );
	color: var( --bb-ink );
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transform: rotate( -4deg );
	animation: bb-confirmation-pop 0.5s cubic-bezier( 0.34, 1.56, 0.64, 1 ) both;
}

@keyframes bb-confirmation-pop {
	from {
		transform: rotate( -4deg ) scale( 0.5 );
		opacity: 0;
	}
	to {
		transform: rotate( -4deg ) scale( 1 );
		opacity: 1;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.bb-confirmation-check {
		animation: none;
	}
}

.bb-confirmation-hero .wc-block-order-confirmation-status h1 {
	font-family: var( --wp--preset--font-family--bebas );
	font-size: clamp( 2.25rem, 1.9rem + 1.4vw, 3rem );
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: 0.01em;
	margin: 0 0 0.5rem;
}

.bb-confirmation-hero .wc-block-order-confirmation-status p {
	max-width: 32rem;
	margin-inline: auto;
	font-size: var( --bb-fs-lede );
	line-height: var( --bb-lh-lede );
	color: var( --bb-ink );
}

.bb-confirmation-hero .wc-block-order-confirmation-status-description {
	margin-top: 1.5rem;
}

/* Guest checkout's "confirm your email" gate — same form/button language
   as the rest of the site instead of WooCommerce's unstyled default. */
.bb-confirmation-hero .woocommerce-form.woocommerce-verify-email {
	max-width: 22rem;
	margin: 1.5rem auto 0;
	text-align: left;
}

.bb-confirmation-hero .woocommerce-verify-email .form-row label {
	display: block;
	margin-bottom: 0.4rem;
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --bb-ink );
}

.bb-confirmation-hero .woocommerce-verify-email input.input-text {
	/* !important: WC core ships `#verify-email { width: 50% }` in
	   order-confirmation-status.css — an ID selector beats any class
	   combination here. */
	width: 100% !important;
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	background-color: #fff;
	padding: 0.65em 0.75em;
}

.bb-confirmation-hero .woocommerce-verify-email .login-submit {
	margin-top: 1rem;
}

.bb-confirmation-hero .woocommerce-verify-email input[type="submit"] {
	display: block;
	width: 100%;
	padding: 0.8em 1.4em;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
	font-size: 1rem;
	background-color: var( --bb-btn-tertiary-bg );
	color: var( --bb-btn-tertiary-text );
	border: var( --bb-keyline ) solid var( --bb-btn-tertiary-border );
	border-radius: 0;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	cursor: pointer;
}


/* Featured-product spotlight: the order-confirmation-totals block's plain
   table, restyled as a product card row (image via the item-name filter)
   with the totals/grand-total treatment carried over from the pay-for-
   order page for a consistent receipt language site-wide. */
.bb-confirmation-spotlight {
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	padding: 1.75rem;
	margin-bottom: 1.75rem;
}

.bb-confirmation-spotlight .bb-eyebrow {
	background-color: var( --bb-terracotta );
}

.bb-confirmation-spotlight .wc-block-order-confirmation-totals__table {
	width: 100%;
	border-collapse: collapse;
	margin-top: 0.75rem;
}

.bb-confirmation-spotlight .wc-block-order-confirmation-totals__table thead {
	display: none;
}

.bb-confirmation-spotlight .wc-block-order-confirmation-totals__table tbody tr {
	border-bottom: 1px solid var( --bb-muted );
}

.bb-confirmation-spotlight .wc-block-order-confirmation-totals__product {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding-block: 1rem;
}

.bb-confirmation-item-media {
	flex: none;
	display: block;
	width: 88px;
	height: 88px;
	border: var( --bb-keyline ) solid var( --bb-ink );
	overflow: hidden;
}

.bb-confirmation-item-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.bb-confirmation-item-name {
	flex: 1;
	min-width: 0;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1.0625rem;
	line-height: 1.25;
	color: var( --bb-ink );
}

.bb-confirmation-item-name a {
	color: inherit;
	text-decoration: none;
}

.bb-confirmation-spotlight .product-quantity {
	flex: none;
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	font-weight: 700;
	color: var( --bb-muted-text );
	border: 1px solid var( --bb-muted-text );
	padding: 0.2em 0.5em;
}

.bb-confirmation-spotlight .wc-block-order-confirmation-totals__total {
	font-family: var( --wp--preset--font-family--mono );
	font-weight: 700;
	color: var( --bb-ink );
	text-align: right;
	white-space: nowrap;
	padding-left: 1rem;
}

.bb-confirmation-spotlight tfoot th,
.bb-confirmation-spotlight tfoot td {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-body-sm );
	color: var( --bb-muted-text );
	font-weight: 400;
	text-align: right;
	padding-top: 0.6rem;
}

.bb-confirmation-spotlight tfoot .wc-block-order-confirmation-totals__label {
	text-align: left;
}

.bb-confirmation-spotlight tfoot tr:last-child th,
.bb-confirmation-spotlight tfoot tr:last-child td {
	padding-top: 0.85rem;
	margin-top: 0.4rem;
	border-top: var( --bb-keyline ) solid var( --bb-ink );
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-size: 1.25rem;
	color: var( --bb-ink );
}

/* Receipt strip: order #, date, email, payment — a horizontal "ticket
   stub" row instead of WooCommerce's vertical definition list, since none
   of these four values need their own line. */
.bb-confirmation-meta {
	background-color: var( --bb-muted );
	border: var( --bb-keyline ) solid var( --bb-ink );
	padding: 1.25rem 1.5rem;
	margin-bottom: 1.75rem;
}

.bb-confirmation-meta .wc-block-order-confirmation-summary-list {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 2rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.bb-confirmation-meta .wc-block-order-confirmation-summary-list-item {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.bb-confirmation-meta .wc-block-order-confirmation-summary-list-item__key {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-small );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --bb-muted-text );
}

.bb-confirmation-meta .wc-block-order-confirmation-summary-list-item__value {
	font-family: var( --wp--preset--font-family--mono );
	font-size: var( --bb-fs-body-sm );
	color: var( --bb-ink );
}

/* Addresses: secondary hierarchy, same label-frame card language used for
   shop/store cards site-wide. */
.bb-confirmation-addresses {
	margin-bottom: 1.75rem;
}

.bb-confirmation-addresses .wc-block-order-confirmation-shipping-wrapper,
.bb-confirmation-addresses .wc-block-order-confirmation-billing-wrapper {
	background-color: var( --bb-card );
	border: var( --bb-keyline ) solid var( --bb-ink );
	padding: 0.85rem 1rem;
}

.bb-confirmation-address-heading {
	font-family: var( --wp--preset--font-family--mono ) !important;
	font-size: var( --bb-fs-small ) !important;
	font-weight: 700 !important;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --bb-muted-text ) !important;
	margin: 0 0 0.4rem !important;
}

.bb-confirmation-addresses address {
	font-style: normal;
	font-size: var( --bb-fs-small );
	line-height: 1.4;
	color: var( --bb-ink );
}

.bb-confirmation-cta {
	margin-top: 2rem;
	clear: both;
}

@media ( max-width: 480px ) {
	.bb-confirmation-hero {
		padding-block: 2rem 1.5rem;
	}

	.bb-confirmation-check {
		width: 72px;
		height: 72px;
	}

	.bb-confirmation-spotlight,
	.bb-confirmation-meta {
		padding: 1.25rem;
	}

	.bb-confirmation-item-media {
		width: 64px;
		height: 64px;
	}

	.bb-confirmation-item-name {
		font-size: 0.9375rem;
	}

	.bb-confirmation-spotlight tfoot tr:last-child th,
	.bb-confirmation-spotlight tfoot tr:last-child td {
		font-size: 1.0625rem;
	}

	.bb-confirmation-addresses {
		gap: 1rem !important;
	}
}

/* === single product (default WooCommerce markup) === */

/* Product content alone is short enough that the footer crept up into the
   first viewport; give the page bottom the same section rhythm used
   elsewhere on the site so it clears the fold before the footer starts. */
.single-product main {
	padding-bottom: var( --bb-section-y );
}

.single-product .woocommerce-breadcrumb {
	display: block;
	padding-top: 40px;
	font-family: var( --wp--preset--font-family--mono );
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.7rem;
	color: var( --bb-muted-text );
}

.single-product .woocommerce-product-gallery__image img {
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
}

/* Belt-and-suspenders alongside the zoom_enabled/photoswipe_enabled filters
   in functions.php: hide the magnifying-glass "view full-screen" trigger
   even if a future WooCommerce update renders it unconditionally. */
.single-product .woocommerce-product-gallery__trigger {
	display: none;
}

/* Match the product-card title font (.bb-shop-card .wp-block-post-title,
   which inherits the "display" family) instead of the site-wide h1's
   Bebas Neue, so product titles read consistently in cards and on the
   single product page. Sized to match the other prominent (non-grid)
   product title context — the single-item featured card — rather than
   the site-wide h1's xx-large clamp, which read as oversized here. */
.bb-product-info .wp-block-post-title {
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--x-large );
	line-height: 1.05;
	text-transform: none;
}

/* Full description now sits directly under the title, ahead of price/add-
   to-cart, instead of its own wide row below the columns — reads as
   supporting copy rather than the main body text, so it drops a size. */
.single-product .bb-product-description {
	font-size: var( --bb-fs-body-sm );
	line-height: 1.6;
	color: var( --bb-muted-text );
	text-wrap: pretty;
}

/* Tighter vertical rhythm for the eyebrow/title/description/price/cart
   stack than the site-wide 1.5rem block gap — they read as one connected
   unit, not separate sections. */
.bb-product-info > * {
	margin-block: 0.85rem 0;
}

.bb-product-info > :first-child {
	margin-block-start: 0;
}

.single-product .woocommerce-Price-amount {
	font-family: var( --wp--preset--font-family--mono );
	color: var( --bb-primary );
	font-weight: 700;
}

.single-product .cart .button,
.single-product .single_add_to_cart_button {
	font-family: var( --wp--preset--font-family--display );
	font-weight: 700;
	text-transform: uppercase;
	border-radius: 0;
}

/* Primary tier (pink/magenta fill) — the site's primary-action color,
   matching Add to Cart's role as the main CTA on the page.
   !important is required: this button also renders with the block-based
   markup's own .wp-element-button + .wp-block-button__link classes, and
   the button system's own ".wp-block-button .wp-element-button
   .wp-block-button__link" base rule (3 classes) otherwise outranks this
   2-class selector and wins the eggshell fill instead. */
.single-product .single_add_to_cart_button {
	background-color: var( --bb-btn-primary-bg ) !important;
	color: var( --bb-btn-primary-text ) !important;
	border: var( --bb-keyline ) solid var( --bb-btn-primary-border ) !important;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition:
		transform var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing ),
		box-shadow var( --bb-btn-transition-duration ) var( --bb-btn-transition-easing );
}

.single-product .single_add_to_cart_button:hover {
	transform: translateY( var( --bb-btn-translate-hover ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.single-product .single_add_to_cart_button:active {
	transform: translateY( var( --bb-btn-translate-active ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink );
}

.single-product .single_add_to_cart_button:focus-visible {
	outline: var( --bb-focus-ring-width ) solid var( --bb-focus-ring-color );
	outline-offset: var( --bb-focus-ring-offset );
}

.single-product .quantity .qty {
	border: 2px solid var( --bb-ink );
	border-radius: 0;
	background-color: var( --bb-cream );
	color: var( --bb-ink );
}

.single-product table.woocommerce-product-attributes,
.single-product .woocommerce-tabs ul.tabs li {
	font-family: var( --wp--preset--font-family--mono );
}

.single-product .woocommerce-tabs ul.tabs li.active {
	border-bottom: 2px solid var( --bb-primary );
}

.single-product .related.products h2 {
	font-size: var( --wp--preset--font-size--large );
}

.single-product .related.products ul.products li.product {
	border: var( --bb-keyline ) solid var( --bb-ink );
	box-shadow: 6px 6px 0 0 var( --bb-lime );
	padding: 0.85rem;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.single-product .related.products ul.products li.product:hover {
	transform: translate( -3px, -3px );
	box-shadow: 8px 8px 0 0 var( --bb-lime );
}

.single-product .related.products ul.products li.product img {
	border-radius: 0;
}

.single-product .related.products ul.products li.product .button {
	border-radius: 0;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
}

/* === my account === */
/* Register form's terms/privacy consent checkbox — same checkbox/label
   language as the order-pay page's own terms checkbox, so "accept and
   continue" reads the same way anywhere on the site it appears. */
.bb-register-terms {
	margin-top: 0.75rem;
}

.bb-register-terms label {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
	font-size: var( --bb-fs-body-sm );
	color: var( --bb-ink );
}

.bb-register-terms input[type="checkbox"] {
	flex: none;
	width: 1.1em;
	height: 1.1em;
	margin-top: 0.2em;
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	accent-color: var( --bb-ink );
}

.bb-register-terms a {
	color: var( --bb-ink );
	text-decoration: underline;
}

.bb-register-terms .required {
	color: var( --bb-red );
}

/* Address book "Add/Edit" link: WooCommerce's default markup floats it to
   the right of the section heading. Stack it under the heading instead and
   dress it as a beige sticker button, matching the site's other CTAs. */
.woocommerce-Address-title.title {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.9rem;
}

.woocommerce-Address-title .edit {
	display: inline-block;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
	font-size: 0.875rem;
	letter-spacing: 0.02em;
	text-decoration: none;
	padding: 0.6em 1.2em;
	background-color: var( --bb-muted );
	color: var( --bb-ink );
	border: var( --bb-keyline ) solid var( --bb-ink );
	box-shadow: 0 0 0 var( --bb-gap ) var( --bb-cream ), 0 0 0 calc( var( --bb-gap ) + var( --bb-halo ) ) var( --bb-berry );
	transition: transform 0.12s steps(2);
}

.woocommerce-Address-title .edit:hover {
	transform: translate( -2px, -2px );
	box-shadow: 0 0 0 var( --bb-gap ) var( --bb-cream ), 0 0 0 calc( var( --bb-gap ) + var( --bb-halo ) ) var( --bb-moss );
}

@media ( prefers-reduced-motion: reduce ) {
	.woocommerce-Address-title .edit:hover {
		transform: none;
	}
}

/* Log out is a destructive action, set apart in red from the rest of the
   account nav (which stays ink/primary). */
.woocommerce-MyAccount-navigation-link--customer-logout a {
	color: var( --bb-red );
}

.woocommerce-MyAccount-navigation-link--customer-logout a:hover {
	color: var( --bb-red );
	text-decoration: underline;
}

/* The register column runs longer than login (extra "reset password" +
   privacy-policy copy), so the two columns land at different heights.
   Shrinking this supporting text is the smaller, more contained fix
   compared to reflowing both columns into an equal-height layout. */
#customer_login .u-column2 p {
	font-size: var( --bb-fs-small );
	line-height: 1.4;
}

/* === retail-responsive === */

/* === responsive === */
@media ( max-width: 781px ) {
	.bb-header-inner {
		gap: 0.75rem;
	}

	.bb-sauce .wp-block-columns .wp-block-columns {
		grid-template-columns: 1fr;
		grid-template-rows: none;
		grid-auto-flow: row;
	}

	.bb-hero-copy p {
		max-width: none;
	}

	/* Bottle reads as the lead visual on mobile — same "photo above the
	   copy" reorder already used for the flavors section's mortar image —
	   instead of the text/buttons pushing it below the fold. */
	.bb-hero-jar {
		order: -1;
	}

	.bb-story-stats {
		gap: 1.25rem;
	}

	.bb-footer-base {
		margin-top: 1.75rem;
	}
}

/* === contact form (Jetpack) ===
   Jetpack's own classes (grunion-field*, pushbutton-wide — its legacy
   "Grunion" contact-form codename), restyled to match the site's existing
   input and button language instead of the plugin's plain default look. */
.grunion-field-label {
	display: block;
	font-weight: 700;
	margin-bottom: 0.35rem;
}

/* Plain white — a visibly different shade from both the page's cream
   background and the .bb-contact-card it sits on, so the fields read as
   "type here" instead of blending into the card behind them. */
.grunion-field {
	width: 100%;
	border: var( --bb-keyline ) solid var( --bb-ink ) !important;
	border-radius: 0 !important;
	background-color: #fff;
	color: var( --bb-ink );
	font-family: var( --wp--preset--font-family--sans );
	padding: 0.6em 0.8em;
}

.pushbutton-wide {
	display: inline-block;
	font-family: var( --wp--preset--font-family--display );
	text-transform: uppercase;
	font-weight: 700;
	font-size: 0.875rem;
	letter-spacing: 0.02em;
	background-color: var( --bb-cream );
	color: var( --bb-ink );
	border: var( --bb-keyline ) solid var( --bb-ink );
	border-radius: 0;
	padding: 0.7em 1.4em;
	box-shadow: var( --bb-btn-shadow ) var( --bb-btn-shadow ) 0 0 var( --bb-ink );
	transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, color 0.15s ease;
	cursor: pointer;
}

.pushbutton-wide:hover {
	background-color: var( --bb-magenta );
	transform: translate( calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ), calc( var( --bb-btn-shadow ) - var( --bb-btn-shadow-hover ) ) );
	box-shadow: var( --bb-btn-shadow-hover ) var( --bb-btn-shadow-hover ) 0 0 var( --bb-ink );
}

.pushbutton-wide:active {
	transform: translate( var( --bb-btn-shadow ), var( --bb-btn-shadow ) );
	box-shadow: var( --bb-btn-shadow-active ) var( --bb-btn-shadow-active ) 0 0 var( --bb-ink );
}

/* Contact page: the section otherwise butts straight against the footer
   below (WP's block-gap margins between top-level sections are zeroed
   elsewhere in this file). No top padding here — .bb-page-header above
   already spaces the "Contact" title off the nav, and the natural block
   gap between the title and this section is enough on its own. */
.bb-contact {
	padding-bottom: 40px;
}

/* Contact page: form card gets extra breathing room over the .bb-card
   default so paired 50%-width fields (first/last name) don't feel cramped
   against the border. */
.bb-contact-card {
	padding: 1.75rem;
}

.bb-contact-card .wp-block-jetpack-contact-form {
	row-gap: 1.1rem;
}

/* The submit button is a direct flex child of the form (not wrapped by
   .contact-submit, which Jetpack leaves empty as an error-message slot), so
   the usual text-align-on-wrapper trick does nothing — push the button
   itself to the row's end instead. It also inherits the same flex-grow
   the fields use to fill their row, so margin-left: auto alone has no free
   space to consume until flex-grow is switched off here first. */
.bb-contact-card .pushbutton-wide {
	flex: 0 0 auto;
	width: auto;
	margin-left: auto;
	margin-top: 0.25rem;
}

@media ( max-width: 781px ) {
	.bb-contact-columns > .wp-block-column {
		flex-basis: 100% !important;
	}
}
