/* Brand Portal — base stylesheet.
 *
 * Color and typography tokens (--bp-color-*, --bp-font-*, --bp-base-font-size) are emitted
 * inline in <head> by inc/css-vars.php with sensible defaults, so they are ALWAYS defined
 * by the time this stylesheet loads. Do not re-declare them here — later declarations win
 * in the cascade and would override the brand values from Brand Settings.
 *
 * Only tokens that do NOT vary per-brand (layout sizing, radii, shadows) are defined here.
 */

:root {
	--bp-radius: 4px;
	--bp-gap: 1.5rem;
	/* 70rem = 1120px at a 16px root — the standard content column used across the theme. */
	--bp-container: 70rem;
	--bp-container-narrow: 70rem;
	--bp-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 4px 12px rgba(0, 0, 0, .06);
}

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

html { font-size: var(--bp-base-font-size); }

body {
	margin: 0;
	font-family: var(--bp-font-body);
	color: var(--bp-color-text);
	background: var(--bp-color-background);
	line-height: 1.55;
	-webkit-font-smoothing: antialiased;
	position: relative;
	/* Sticky-footer pattern: body fills the viewport, the footer's `margin-top: auto`
	 * (in the .site-footer rule) eats the leftover space so the footer pins to the
	 * bottom whenever content is shorter than the viewport. 100dvh handles the
	 * mobile URL-bar resize correctly; 100vh stays as fallback for older browsers. */
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
}
/* Paper-texture overlay. Fixed positioning so it tiles seamlessly through long scrolls
 * without any repaint cost — pointer-events:none so it never blocks clicks. */
body::before {
	content: '';
	position: fixed;
	inset: 0;
	background-image: var(--bp-bg-texture, none);
	background-repeat: repeat;
	pointer-events: none;
	z-index: 0;
}
body > * { position: relative; z-index: 1; }

h1, h2, h3, h4, h5, h6 {
	font-family: var(--bp-font-heading);
	line-height: 1.15;
	/* Balanced vertical breathing room — top space matches the bottom so headings
	 * don't feel glued to the content above them. :first-child rule below removes
	 * the top space when a heading opens a section (matches natural reading flow). */
	margin: 1.5em 0 1em;
	text-transform: var(--bp-heading-transform, none);
	letter-spacing: var(--bp-heading-letter-spacing, normal);
	color: var(--bp-color-heading, var(--bp-color-text));
}
h1:first-child, h2:first-child, h3:first-child,
h4:first-child, h5:first-child, h6:first-child { margin-top: 0; }

/* Decorative accent underline — a short horizontal bar below each heading, capped at
 * 5em so it stays proportional on wide containers. Scales with font-size (because em),
 * so h1 gets a longer bar than h4. */
h1::after, h2::after, h3::after, h4::after, h5::after, h6::after {
	content: "";
	display: block;
	width: 50%;
	max-width: 3em;
	height: 5px;
	background: var(--bp-color-accent);
	margin: .3em auto 0;
}

/*
 * Clamp max (desktop) values bumped ~30% for stronger hierarchy on large viewports.
 * Mobile minimums left at their original, comfortable values.
 * Preferred (viewport-linked) tuned so the transition between the two stays smooth.
 */
h1 { font-size: clamp(2rem, 5vw, 4.25rem); }
h2 { font-size: clamp(1.5rem, 3.5vw, 3rem); }
h3 { font-size: clamp(1.35rem, 1.8vw, 1.75rem); }

p { margin: 0 0 1em; }

a {
	color: var(--bp-color-link);
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
}
a:hover { text-decoration-thickness: 2px; }

img, svg { max-width: 100%; height: auto; display: block; }

/* -------- Utilities -------- */
.screen-reader-text {
	border: 0;
	clip: rect(1px,1px,1px,1px);
	clip-path: inset(50%);
	height: 1px;
	width: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	word-wrap: normal !important;
}

.skip-link {
	position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden;
}
.skip-link:focus {
	position: fixed; left: 1rem; top: 1rem; width: auto; height: auto;
	padding: .5rem 1rem; background: var(--bp-color-primary); color: #fff;
	border-radius: var(--bp-radius); z-index: 9999; text-decoration: none;
}

.bp-container {
	max-width: var(--bp-container);
	margin: 0 auto;
	padding: 0 1.25rem;
}
.bp-container--narrow { max-width: var(--bp-container-narrow); }

.bp-section { padding: 2rem 0; }
.bp-section--cta { padding: 1.5rem 0; text-align: center; }
.bp-section--content { padding: 1.5rem 0; text-align: center; }
.bp-section__cta-wrap { margin: 1.5rem 0 0; }
.bp-section--headline { padding: 2.5rem 0 1rem; text-align: center; }
.bp-headline__sub { margin-top: -.25rem; }
.bp-section__title { text-align: center; margin-bottom: 1.5rem; }
.bp-section__subtitle { text-align: center; opacity: .7; margin-bottom: 2rem; }

.bp-prose { font-size: 1.0625rem; }
.bp-prose > :first-child { margin-top: 0; }
.bp-prose > :last-child  { margin-bottom: 0; }

/*
 * Block-editor alignment — when admin picks "Wide width" or "Full width" on a block
 * (typically a Vimeo embed, image, or gallery), break the block out of the narrow
 * content container so it reaches the viewport edges. Standard calc trick: the
 * element's own 50% minus 50vw puts its left edge at the viewport's left edge.
 */
.bp-prose .alignfull,
.bp-section--content .alignfull {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}
.bp-prose .alignwide,
.bp-section--content .alignwide {
	width: 90vw;
	max-width: 90vw;
	margin-left: calc(50% - 45vw);
	margin-right: calc(50% - 45vw);
}
/* WP's embed blocks use a figure wrapper with its own width — reset it so the iframe
 * inside fills the alignfull / alignwide container. */
.bp-prose .wp-block-embed.alignfull .wp-block-embed__wrapper,
.bp-prose .wp-block-embed.alignwide .wp-block-embed__wrapper {
	width: 100%;
}

/*
 * Responsive media inside prose. Catches:
 *   - Raw pasted <iframe> tags (Vimeo / YouTube / etc with hardcoded width/height)
 *   - <video> / <embed> / <object> elements
 *   - WP block-editor embed wrappers
 *
 * The key: set aspect-ratio explicitly (NOT `auto`) with width:100% — the browser
 * then computes height from the ratio. Iframes don't reliably derive an intrinsic
 * aspect ratio from their HTML width/height attributes the way images do, so
 * relying on `aspect-ratio: auto` + `height: auto` collapses to UA default 150px.
 * 16:9 covers the vast majority of video embeds.
 */
.bp-prose iframe,
.bp-prose video,
.bp-prose embed,
.bp-prose object {
	display: block;
	max-width: 100%;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
}

/* -------- Buttons -------- */
.bp-button {
	display: inline-block;
	padding: .85rem 1.75rem;
	background: var(--bp-color-button);
	color: var(--bp-color-button-text);
	text-decoration: none;
	border-radius: var(--bp-radius);
	font-weight: 600;
	letter-spacing: .02em;
	transition: transform .15s ease, opacity .15s ease;
}
.bp-button:hover { opacity: .9; transform: translateY(-1px); color: var(--bp-color-button-text); }
.bp-button--large { padding: 1rem 2.25rem; font-size: 1.0625rem; }

/* -------- Header --------
 * Colors default to primary bg + white text but are independently overridable via
 * Brand Settings → Colors → "Header Background / Header Text / Header Link Hover Accent".
 * All three are fed through --bp-color-header-* custom properties in inc/css-vars.php.
 */
.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	/* Use background-color + background-image so the solid color and the
	 * --bp-bg-texture overlay can layer together. The shorthand `background:`
	 * would wipe out any image when only a color is provided. */
	background-color: var(--bp-color-header-bg);
	background-image: var(--bp-bg-texture, none);
	background-repeat: repeat;
	color: var(--bp-color-header-text);
	border-bottom: 1px solid rgba(0, 0, 0, .06);
}
.site-header__inner {
	max-width: var(--bp-container);
	margin: 0 auto;
	padding: 1rem 1.25rem;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bp-gap);
}
.site-branding {
	display: inline-flex;
	align-items: center;
	gap: .75rem;
	text-decoration: none;
	color: var(--bp-color-header-text);
	font-family: var(--bp-font-heading);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: .01em;
}
.site-branding__logo {
	max-height: 48px;
	max-width: 250px;
	width: auto;
	height: auto;
	object-fit: contain;
}

.site-nav__list {
	display: flex;
	align-items: center;
	gap: 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.site-nav__link {
	color: var(--bp-color-header-text);
	opacity: .85;
	text-decoration: none;
	font-weight: 700;
	padding: .25rem 0;
	border-bottom: 2px solid transparent;
	text-transform: uppercase;
	letter-spacing: .08em;
	font-size: .875rem;
}
.site-nav__link:hover,
.site-nav__link:focus-visible {
	border-bottom-color: var(--bp-color-header-hover);
	opacity: 1;
}

/* CTA pill — auto-applied to any nav item whose URL resolves to /shop/.
 * Accent bg + configurable pill-text color (defaults to Primary). */
.site-nav__link--cta {
	background: var(--bp-color-accent);
	color: var(--bp-color-pill-text) !important;
	padding: .625rem 1.5rem;
	border-radius: 999px;
	border: 0 !important;
	opacity: 1 !important;
	transition: transform .15s ease, opacity .15s ease;
}
.site-nav__link--cta:hover,
.site-nav__link--cta:focus-visible {
	border-bottom-color: transparent !important;
	transform: translateY(-1px);
	opacity: .92 !important;
}

.site-nav__toggle {
	display: none;
	background: none;
	border: 0;
	padding: .5rem;
	cursor: pointer;
}
.site-nav__toggle-icon,
.site-nav__toggle-icon::before,
.site-nav__toggle-icon::after {
	display: block;
	width: 24px;
	height: 2px;
	background: var(--bp-color-header-text);
	transition: transform .2s ease, opacity .2s ease;
}
.site-nav__toggle-icon { position: relative; }
.site-nav__toggle-icon::before,
.site-nav__toggle-icon::after { content: ''; position: absolute; left: 0; }
.site-nav__toggle-icon::before { top: -7px; }
.site-nav__toggle-icon::after  { top:  7px; }
.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-icon { background: transparent; }
.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-icon::before { top: 0; transform: rotate(45deg); }
.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-icon::after  { top: 0; transform: rotate(-45deg); }

@media (max-width: 720px) {
	.site-nav__toggle { display: inline-flex; }
	.site-nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		background: var(--bp-color-header-bg);
		border-top: 1px solid rgba(0, 0, 0, .12);
		display: none;
		padding: 1.5rem 1.25rem 2rem;
	}
	.site-nav.is-open { display: block; }
	.site-nav__list {
		flex-direction: column;
		/* Wider gap on mobile for easier scanning + larger touch margin between links. */
		gap: 1.75rem;
	}
	.site-nav__link {
		/* Bump font size from .875rem (≈14px) → 1.125rem (≈18px) on mobile.
		 * Also widen vertical padding so each link is a comfortable tap target. */
		font-size: 1.125rem;
		padding: .375rem 0;
	}
	.site-nav__link--cta {
		padding: .85rem 1.5rem;
		font-size: 1rem;
	}
}

/* -------- Carousel -------- */
.bp-carousel {
	position: relative;
	background: #eee;
	overflow: hidden;
}
.bp-carousel__viewport { overflow: hidden; }
.bp-carousel__track {
	display: flex;
	list-style: none;
	margin: 0;
	padding: 0;
	transition: transform .4s ease;
}
.bp-carousel__slide {
	flex: 0 0 100%;
	position: relative;
	/* --carousel-min-height is set inline on the carousel root from the ACF height preset. */
	min-height: var(--carousel-min-height, clamp(20rem, 48vw, 34rem));
	display: grid;
	place-items: center;
	color: #fff;
	background: linear-gradient(135deg, var(--bp-color-primary), var(--bp-color-accent));
}
.bp-carousel__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
}
.bp-carousel__image--placeholder {
	background: linear-gradient(135deg, var(--bp-color-primary), var(--bp-color-accent));
}
/*
 * Caption block lives below the image track — not as an overlay.
 * All captions stack in the same slot; only the one matching the active slide is shown.
 * No dark gradient on the image itself: nothing to fight for contrast.
 */
.bp-carousel__captions {
	display: grid;
	grid-template-areas: "stack";
	text-align: center;
	padding: 2rem 1.25rem 1.5rem;
	max-width: 40rem;
	margin: 0 auto;
}
.bp-carousel__caption {
	grid-area: stack;
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity .28s ease, transform .28s ease;
}
.bp-carousel__caption.is-active {
	opacity: 1;
	visibility: visible;
	transform: none;
}
.bp-carousel__heading {
	color: var(--bp-color-text);
	margin: 0 0 .5rem;
}
.bp-carousel__subheading {
	color: var(--bp-color-text);
	opacity: .8;
	font-size: 1.0625rem;
	margin: 0 0 1.25rem;
}

.bp-carousel__controls {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 1rem;
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	padding: 0 1rem;
}
.bp-carousel__nav {
	background: rgba(255,255,255,.9);
	/* Arrows always need to read on the white button — pinned dark so they don't
	 * disappear when a brand sets Text Color to white (e.g. dark-themed sites). */
	color: #1a1a1a;
	border: 0;
	width: 2.25rem; height: 2.25rem;
	border-radius: 50%;
	cursor: pointer;
	display: inline-flex; align-items: center; justify-content: center;
	font-size: 1.125rem;
	box-shadow: var(--bp-shadow);
}
.bp-carousel__nav:hover { background: #fff; }
.bp-carousel__dots { display: flex; gap: .5rem; list-style: none; margin: 0; padding: 0; }
.bp-carousel__dot {
	width: .625rem; height: .625rem; padding: 0; border: 0;
	border-radius: 50%;
	background: rgba(255,255,255,.5);
	cursor: pointer;
	transition: background .15s ease, transform .15s ease;
}
.bp-carousel__dot.is-active { background: #fff; transform: scale(1.2); }

/* -------- Instagram feed --------
 * Two render modes:
 *  - bp-instagram-feed--embed: third-party widget HTML passed through (Behold, SnapWidget, etc.)
 *  - bp-ig-follow:             fallback "Follow us on Instagram" card when no embed is set
 */
.bp-instagram-feed--embed {
	/* Let the widget provider's own styling take over; we just give it breathing room.
	 * No max-width cap — section width is already capped by the outer .bp-container. */
	padding: 0;
	margin: 0 auto;
}

.bp-ig-follow {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: 1.25rem;
	margin: 0 auto;
	padding: 1.75rem 2rem;
	border-radius: calc(var(--bp-radius) * 3);
	text-decoration: none;
	color: #fff;
	background:
		linear-gradient(135deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
	box-shadow: 0 6px 20px rgba(0,0,0,.10), 0 14px 40px rgba(0,0,0,.10);
	transition: transform .18s ease, box-shadow .18s ease;
}
.bp-ig-follow:hover,
.bp-ig-follow:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 10px 28px rgba(0,0,0,.14), 0 20px 60px rgba(0,0,0,.14);
	color: #fff;
}
.bp-ig-follow__icon {
	display: grid;
	place-items: center;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	background: rgba(255, 255, 255, .18);
	color: #fff;
}
.bp-ig-follow__meta { display: flex; flex-direction: column; gap: .125rem; }
.bp-ig-follow__label {
	font-size: .8125rem;
	text-transform: uppercase;
	letter-spacing: .12em;
	opacity: .85;
}
.bp-ig-follow__handle {
	font-family: var(--bp-font-heading);
	font-size: 1.25rem;
	font-weight: 700;
}
.bp-ig-follow__cta {
	font-weight: 600;
	white-space: nowrap;
	opacity: .95;
}
@media (max-width: 520px) {
	.bp-ig-follow { grid-template-columns: auto 1fr; gap: .875rem; padding: 1.25rem 1.25rem; }
	.bp-ig-follow__cta { display: none; }
}

/* -------- Notices (for unset integrations) -------- */
.bp-notice {
	padding: 1.25rem 1.5rem;
	border-radius: var(--bp-radius);
	background: rgba(0,0,0,.04);
	border-left: 4px solid var(--bp-color-accent);
}
.bp-notice p { margin: 0; }

/* -------- Brand Directory (network main site) -------- */
.bp-section--directory-intro { padding: 2rem 0 1rem; text-align: center; }
.bp-directory-intro__prose { text-align: center; opacity: .75; }

.bp-directory {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: 1.25rem;
}
.bp-directory__card {
	background: var(--card-bg, #fff);
	border-radius: calc(var(--bp-radius) * 2);
	overflow: hidden;
	box-shadow: var(--bp-shadow);
	transition: transform .18s ease, box-shadow .18s ease;
	border: 1px solid rgba(0, 0, 0, .06);
}
.bp-directory__card:hover,
.bp-directory__card:focus-within {
	transform: translateY(-3px);
	box-shadow: 0 6px 20px rgba(0, 0, 0, .08), 0 12px 40px rgba(0, 0, 0, .08);
}
.bp-directory__link {
	display: grid;
	grid-template-rows: 10rem auto;
	text-decoration: none;
	color: inherit;
	height: 100%;
}
.bp-directory__logo {
	background: var(--card-accent, #111);
	color: #fff;
	display: grid;
	place-items: center;
	padding: 1.5rem;
}
.bp-directory__logo img {
	max-width: 80%;
	max-height: 6rem;
	width: auto;
	height: auto;
	object-fit: contain;
}
.bp-directory__wordmark {
	font-family: var(--bp-font-heading);
	color: #fff;
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: .02em;
}
.bp-directory__meta {
	display: flex;
	flex-direction: column;
	gap: .35rem;
	padding: 1.25rem 1.5rem;
}
.bp-directory__name {
	font-family: var(--bp-font-heading);
	font-size: 1.125rem;
	font-weight: 600;
	color: var(--bp-color-text);
}
.bp-directory__tagline {
	font-size: .875rem;
	color: var(--bp-color-text);
	opacity: .7;
	line-height: 1.4;
}

/* -------- Products grid (curated Jane shelf) -------- */
.bp-products {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 1.5rem;
}
@media (max-width: 840px) {
	.bp-products { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 500px) {
	.bp-products { grid-template-columns: 1fr; }
}
.bp-products__item {
	background: #ffffff;
	/* Card bg is hardcoded white, so text inside also pins to a dark value rather
	 * than inheriting --bp-color-text (which can be white on dark-themed brands). */
	color: #1a1a1a;
	border-radius: calc(var(--bp-radius) * 2);
	overflow: hidden;
	box-shadow: var(--bp-shadow);
	transition: transform .18s ease, box-shadow .18s ease;
}
.bp-products__item:hover,
.bp-products__item:focus-within {
	transform: translateY(-2px);
	box-shadow: 0 6px 20px rgba(0,0,0,.08), 0 12px 40px rgba(0,0,0,.08);
}
.bp-products__link {
	display: flex;
	flex-direction: column;
	height: 100%;
	text-decoration: none;
	color: inherit;
}
.bp-products__link:hover,
.bp-products__link:focus-visible { color: inherit; }
.bp-products__image-wrap {
	aspect-ratio: 1 / 1;
	display: grid;
	place-items: center;
	padding: 1.25rem;
}
.bp-products__image {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}
.bp-products__meta {
	padding: 1rem 1.25rem 1.25rem;
	display: flex;
	flex-direction: column;
	gap: .35rem;
	text-align: center;
}
.bp-products__brand {
	font-size: .75rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	opacity: .65;
}
.bp-products__name {
	font-family: var(--bp-font-heading);
	font-size: 1.0625rem;
	margin: 0;
	/* Inherits from .bp-products__item (#1a1a1a) — don't bind to --bp-color-text. */
	color: inherit;
	line-height: 1.3;
}
.bp-products__kind {
	font-size: .875rem;
	opacity: .7;
}

/* -------- Retailer cards (static Shop page) --------
 * One card per retailer, each carrying a row of state pills where the brand is sold
 * through that retailer. Each pill is its own link — state-filtered for Beyond Hello,
 * direct-to-retailer for everyone else. Keeps the layout compact regardless of whether
 * a brand is in 1 state or 5. */
.bp-retailers__list {
	list-style: none;
	margin: 0 auto;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr;
	gap: 2rem;
}
/* Count-aware layout using :has() — avoids the "3 on top, 1 on bottom" feel when
 * a brand has 4 retailers. Default at >=640px is 2 columns; a brand with exactly
 * 3 retailers gets a single row of 3; a solo retailer stays narrow so it doesn't
 * stretch to half the page. */
@media (min-width: 640px) {
	.bp-retailers__list {
		grid-template-columns: repeat(2, 1fr);
	}
	.bp-retailers__list:has(> li:only-child) {
		grid-template-columns: 1fr;
		max-width: 22rem;
	}
	.bp-retailers__list:has(> li:nth-child(3):last-child) {
		grid-template-columns: repeat(3, 1fr);
		max-width: 60rem;
	}
}
.bp-retailer-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.25rem;
	padding: 2.5rem 1.75rem;
	/* Split bg so the kraft texture overlay layers on top of the primary color. */
	background-color: var(--bp-color-primary);
	background-image: var(--bp-bg-texture, none);
	background-repeat: repeat;
	color: #fff;
	border-radius: calc(var(--bp-radius) * 2);
	text-align: center;
}
.bp-retailer-card__logo {
	display: grid;
	place-items: center;
	min-height: 5rem;
	width: 100%;
}
.bp-retailer-card__logo img {
	max-height: 3.75rem;
	max-width: 80%;
	width: auto;
	height: auto;
	object-fit: contain;
	filter: brightness(0) invert(1);
}
/* Jane logo — inline SVG sized like the other retailer logos. The "Jane" path uses
 * `currentColor` (inherited = white on the dark card), heart stays yellow. */
.bp-retailer-card__svg {
	max-height: 3.75rem;
	max-width: 80%;
	width: auto;
	height: auto;
	display: block;
}
.bp-retailer-card__svg--jane { color: #fff; }
.bp-retailer-card__available {
	margin: 0;
	font-size: .75rem;
	letter-spacing: .15em;
	text-transform: uppercase;
	opacity: .65;
}
.bp-retailer-card__states {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: .5rem;
}
.bp-state-pill {
	display: inline-block;
	padding: .5rem 1rem;
	background: var(--bp-color-accent);
	color: var(--bp-color-pill-text);
	border-radius: 999px;
	font-family: var(--bp-font-heading);
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	font-size: .75rem;
	text-decoration: none;
	transition: transform .12s ease, opacity .12s ease;
	min-width: 3rem;
}
.bp-state-pill:hover,
.bp-state-pill:focus-visible {
	transform: translateY(-1px);
	opacity: .92;
	color: var(--bp-color-pill-text);
}
@media (max-width: 640px) {
	.bp-retailer-card { padding: 2rem 1.25rem; gap: 1rem; }
	.bp-retailer-card__wordmark { font-size: 2.25rem; }
}

/* -------- Store locator -------- */
.bp-locator__form {
	display: flex;
	gap: .5rem;
	flex-wrap: wrap;
	max-width: 34rem;
	margin: 0 auto 1rem;
}
.bp-locator__field {
	flex: 1;
	min-width: 10rem;
}
.bp-locator__field input {
	width: 100%;
	padding: .85rem 1rem;
	font-size: 1rem;
	font-family: inherit;
	border: 1px solid rgba(0, 0, 0, .2);
	border-radius: var(--bp-radius);
	background: #fff;
	color: #1a1a1a;
}
.bp-locator__field input::placeholder { color: #6c757d; opacity: 1; }
.bp-locator__field input:focus { outline: 2px solid var(--bp-color-accent); outline-offset: 1px; }
.bp-locator__geo {
	background: transparent;
	border: 1px solid rgba(0, 0, 0, .2);
	color: var(--bp-color-text);
	padding: .85rem 1rem;
	font-family: inherit;
	border-radius: var(--bp-radius);
	cursor: pointer;
	font-weight: 500;
}
.bp-locator__geo:hover { background: rgba(0, 0, 0, .03); }

.bp-locator__status {
	text-align: center;
	margin: .5rem 0 1.5rem;
	color: rgba(0, 0, 0, .65);
	min-height: 1.25rem;
}
.bp-locator__status.is-error { color: #b32d2e; font-weight: 500; }

.bp-locator__results {
	list-style: none;
	margin: 0 auto;
	padding: 0;
	max-width: 44rem;
	display: flex;
	flex-direction: column;
	gap: .75rem;
}
.bp-locator__card {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 1rem;
	padding: 1rem 1.25rem;
	background: #fff;
	border: 1px solid rgba(0, 0, 0, .08);
	border-radius: calc(var(--bp-radius) * 2);
	box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
}
.bp-locator__card-name {
	font-family: var(--bp-font-heading);
	font-size: 1.125rem;
	margin: 0 0 .25rem;
	color: var(--bp-color-text);
}
.bp-locator__card-addr,
.bp-locator__card-phone {
	margin: 0;
	font-size: .9rem;
	color: rgba(0, 0, 0, .7);
}
.bp-locator__card-phone a { color: inherit; }
.bp-locator__card-side {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	justify-content: space-between;
	gap: .5rem;
	text-align: right;
}
.bp-locator__card-distance {
	font-weight: 600;
	font-size: .9rem;
	color: var(--bp-color-primary);
	white-space: nowrap;
}
.bp-locator__card-link {
	font-size: .85rem;
	text-decoration: none;
	color: var(--bp-color-link);
	font-weight: 500;
}
.bp-locator__card-link:hover { text-decoration: underline; }

.bp-locator__all {
	margin-top: 2rem;
	max-width: 44rem;
	margin-left: auto;
	margin-right: auto;
}
.bp-locator__all summary {
	cursor: pointer;
	font-weight: 500;
	padding: .5rem 0;
	color: rgba(0, 0, 0, .7);
	text-align: center;
}
.bp-locator__all[open] summary { margin-bottom: 1rem; }

/* State headers inside the "all locations" list */
.bp-locator__state {
	list-style: none;
	margin: 1.25rem 0 .5rem;
	padding: 0 .5rem .25rem;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	border-bottom: 1px solid rgba(0, 0, 0, .1);
}
.bp-locator__state:first-child { margin-top: 0; }
.bp-locator__state-title {
	font-family: var(--bp-font-heading);
	font-size: 1.25rem;
	margin: 0;
	color: var(--bp-color-text);
}
.bp-locator__state-count {
	font-size: .8125rem;
	color: rgba(0, 0, 0, .55);
}

/* -------- Gravity Forms — brand-aligned styling --------
 * Overrides Gravity's default styles so the contact form inherits each brand's palette
 * + typography via --bp-* custom properties. Specific enough to win over GF's own CSS
 * without needing !important.
 */
.gform_wrapper {
	max-width: 42rem;
	margin: 0 auto;
	font-family: var(--bp-font-body);
	color: var(--bp-color-text);
}

.gform_wrapper .gform_fields {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: 1fr;
	list-style: none;
	margin: 0;
	padding: 0;
}

.gform_wrapper .gfield_label,
.gform_wrapper .gfield .gform-field-label {
	font-family: var(--bp-font-heading);
	font-weight: 600;
	font-size: .95rem;
	letter-spacing: .01em;
	color: var(--bp-color-text);
	display: block;
	margin-bottom: .5rem;
}
.gform_wrapper .gfield_required { color: #b32d2e; margin-left: 2px; font-weight: 400; }

.gform_wrapper input[type="text"],
.gform_wrapper input[type="email"],
.gform_wrapper input[type="tel"],
.gform_wrapper input[type="url"],
.gform_wrapper input[type="number"],
.gform_wrapper select,
.gform_wrapper textarea {
	width: 100%;
	padding: .85rem 1rem;
	border: 1px solid rgba(0, 0, 0, .18);
	border-radius: var(--bp-radius);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.4;
	background: #fff;
	/* Pinned dark — input backgrounds are hardcoded white, so the text inside
	 * needs a fixed dark value rather than inheriting --bp-color-text (which can
	 * be white on dark-themed brands like Hijinks → invisible text). */
	color: #1a1a1a;
	transition: border-color .15s ease, box-shadow .15s ease;
	-webkit-appearance: none;
	appearance: none;
}
/* Placeholder text — same pinning logic, slightly muted for hint hierarchy. */
.gform_wrapper input::placeholder,
.gform_wrapper textarea::placeholder {
	color: #6c757d;
	opacity: 1;
}
.gform_wrapper input:focus,
.gform_wrapper select:focus,
.gform_wrapper textarea:focus {
	outline: none;
	border-color: var(--bp-color-primary);
	box-shadow: 0 0 0 3px rgba(0, 0, 0, .08);
}
.gform_wrapper textarea { min-height: 8rem; resize: vertical; }

/* Select arrow (native appearance stripped above) */
.gform_wrapper select {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='%23666'%3E%3Cpath d='M6 8L0 0h12z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1rem center;
	background-size: .625rem;
	padding-right: 2.25rem;
}

/* Composite "Name" field: First + Last 50/50.
 * Gravity ships `gform-grid-row` (flex) on the parent and `gform-grid-col--size-auto`
 * (flex: 0 0 auto) on each child, both with higher specificity than custom class
 * selectors would normally get. !important is the cleanest override here — matches
 * Gravity's own approach of composing utility classes. */
.gform_wrapper .ginput_complex.ginput_container {
	display: grid !important;
	grid-template-columns: 1fr 1fr !important;
	gap: .75rem !important;
}
.gform_wrapper .ginput_complex.ginput_container > span {
	display: flex !important;
	flex: 1 1 0 !important;
	flex-direction: column !important;
	min-width: 0 !important;
	width: auto !important;
	max-width: none !important;
}
.gform_wrapper .ginput_complex.ginput_container > span > input {
	width: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
}
.gform_wrapper .ginput_complex.ginput_container > span > label {
	font-family: inherit;
	font-size: .75rem;
	font-weight: 500;
	opacity: .65;
	letter-spacing: .04em;
	text-transform: uppercase;
	order: 2;
	margin: .375rem 0 0;
}
@media (max-width: 520px) {
	.gform_wrapper .ginput_complex.ginput_container {
		grid-template-columns: 1fr !important;
	}
}

/* Submit button — mirrors .bp-button--large */
.gform_wrapper .gform_footer {
	margin-top: 1.75rem;
	text-align: center;
}
.gform_wrapper .gform_footer input[type="submit"],
.gform_wrapper .gform_footer button[type="submit"] {
	background: var(--bp-color-button);
	color: var(--bp-color-button-text);
	border: 0;
	padding: 1rem 2.5rem;
	font-family: var(--bp-font-heading);
	font-weight: 600;
	font-size: 1rem;
	letter-spacing: .02em;
	border-radius: var(--bp-radius);
	cursor: pointer;
	transition: opacity .15s ease, transform .15s ease;
	width: auto;
}
.gform_wrapper .gform_footer input[type="submit"]:hover,
.gform_wrapper .gform_footer button[type="submit"]:hover {
	opacity: .92;
	transform: translateY(-1px);
}

/* reCAPTCHA — widget is a fixed 304px iframe injected by Google's JS.
 * Hide Gravity's redundant "CAPTCHA*" label (the widget is self-explanatory) and
 * center the injected widget by making the container a flex row. Both the gfield_label
 * AND gform-field-label classes sit on the label element, so target both. */
.gform_wrapper .gfield--type-captcha .gfield_label,
.gform_wrapper .gfield--type-captcha .gform-field-label,
.gform_wrapper .gfield--type-captcha label.gfield_label {
	display: none !important;
}
.gform_wrapper .gfield--type-captcha .ginput_recaptcha,
.gform_wrapper .ginput_recaptcha {
	display: flex !important;
	justify-content: center !important;
	width: 100% !important;
}
.gform_wrapper .gfield--type-captcha .gfield_validation_message { text-align: center; }

/* Validation */
.gform_wrapper .gfield_error .gfield_label { color: #b32d2e; }
.gform_wrapper .gfield_error input,
.gform_wrapper .gfield_error select,
.gform_wrapper .gfield_error textarea {
	border-color: #b32d2e;
}
.gform_wrapper .gfield_validation_message,
.gform_wrapper .validation_message {
	color: #b32d2e;
	font-size: .85rem;
	margin-top: .375rem;
}
.gform_wrapper .gform_validation_errors {
	border: 1px solid rgba(179, 45, 46, .3);
	background: rgba(179, 45, 46, .06);
	border-radius: var(--bp-radius);
	padding: 1rem 1.25rem;
	margin-bottom: 1.5rem;
}
.gform_wrapper .gform_validation_errors h2 {
	color: #b32d2e;
	font-size: 1rem;
	margin: 0 0 .5rem;
}

/* Confirmation message shown after a successful send */
.gform_confirmation_message {
	text-align: center;
	padding: 2.5rem 1rem;
	font-family: var(--bp-font-heading);
	font-size: 1.25rem;
	color: var(--bp-color-text);
	background: rgba(0, 0, 0, .03);
	border-radius: calc(var(--bp-radius) * 2);
}
.gform_confirmation_message p { margin: 0; }

/* Description / instructions text under a label */
.gform_wrapper .gfield_description {
	font-size: .85rem;
	opacity: .7;
	margin-top: .375rem;
}

/* -------- Age gate --------
 * Overlay markup ships on every page (Cloudflare cache-safe). Display is toggled purely by
 * the `is-gated` class on <html>, set by a tiny inline script in <head> when the visitor
 * hasn't been verified via localStorage. No class → no overlay, no flash.
 */
.bp-age-gate { display: none; }
html.is-gated { overflow: hidden; }
html.is-gated .bp-age-gate {
	display: flex;
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, .85);
	align-items: center;
	justify-content: center;
	z-index: 9999;
	padding: 1rem;
}
.bp-age-gate__panel {
	background: var(--bp-color-background);
	color: var(--bp-color-text);
	border-radius: calc(var(--bp-radius) * 2);
	max-width: 28rem;
	width: 100%;
	padding: 2.5rem 2rem;
	text-align: center;
	box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
}
.bp-age-gate__heading {
	font-family: var(--bp-font-heading);
	margin: 0 0 .75rem;
	font-size: 1.5rem;
}
.bp-age-gate__body { margin: 0 0 1.5rem; opacity: .8; line-height: 1.5; }
.bp-age-gate__actions { display: flex; flex-direction: column; gap: .625rem; align-items: stretch; }
.bp-age-gate__btn {
	font-family: inherit;
	font-size: 1rem;
	text-decoration: none;
	text-align: center;
}
.bp-age-gate__btn--accept {
	background: var(--bp-color-button);
	color: var(--bp-color-button-text);
	padding: .85rem 1.5rem;
	border: 0;
	border-radius: var(--bp-radius);
	font-weight: 600;
	cursor: pointer;
}
.bp-age-gate__btn--accept:hover { opacity: .9; }
.bp-age-gate__btn--deny {
	color: var(--bp-color-text);
	opacity: .55;
	text-decoration: underline;
	padding: .5rem;
}
.bp-age-gate__btn--deny:hover { opacity: .8; }

/* -------- Footer (retail partners bar + one link + copyright) -------- */
.site-footer {
	/* margin-top:auto pairs with body's flex-column + min-height:100dvh to pin the
	 * footer to the viewport bottom on short pages (e.g. shop with one or two
	 * retailer cards). On long pages the auto margin collapses to 0 — no effect. */
	margin-top: auto;
	/* Split color / image so kraft-paper brands get the --bp-bg-texture overlay on top
	 * of their primary color (same pattern as the header). */
	background-color: var(--bp-color-primary);
	background-image: var(--bp-bg-texture, none);
	background-repeat: repeat;
	color: rgba(255, 255, 255, .9);
}

/* Retail partners bar (network-wide: Jushi / Beyond Hello / Nature's Remedy) */
.site-footer__partners {
	max-width: var(--bp-container);
	margin: 0 auto;
	/* Top padding bumped to replace the .site-footer margin-top:4rem we removed — that
	 * margin had to go so margin-top:auto could pin the footer to the bottom on short
	 * pages. Built-in padding gives the same content-to-footer breathing room on long
	 * pages without fighting flex layout. */
	padding: 4.5rem 1.25rem 2rem;
	border-bottom: 1px solid rgba(255, 255, 255, .1);
}
.site-footer__partners-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 2rem;
	align-items: center;
	justify-items: center;
}
@media (max-width: 900px) {
	.site-footer__partners-list { grid-template-columns: repeat(2, 1fr); }
}
.site-footer__partner a { display: inline-block; line-height: 0; opacity: .85; transition: opacity .15s ease; }
.site-footer__partner a:hover { opacity: 1; }
.site-footer__partner img {
	max-height: 3rem;
	width: auto;
	max-width: 14rem;
	object-fit: contain;
	/* All partner logos render as white silhouettes on the dark footer. `brightness(0)`
	 * paints every opaque pixel black, `invert(1)` flips it to white — so colored logos
	 * (NuLeaf's dark navy wordmark) look the same as the already-white logos from the
	 * other partners. Works regardless of each logo's source color. */
	filter: brightness(0) invert(1);
}
@media (max-width: 640px) {
	.site-footer__partners-list { grid-template-columns: 1fr; gap: 1.5rem; }
	.site-footer__partner img { max-height: 2.5rem; }
}

.site-footer__bar {
	max-width: var(--bp-container);
	margin: 0 auto;
	padding: 1.5rem 1.25rem;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem 1.5rem;
	flex-wrap: wrap;
	font-size: .875rem;
}
.site-footer__nav {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem 1.5rem;
	align-items: center;
}
.site-footer__link {
	color: inherit;
	text-decoration: none;
	text-transform: uppercase;
	letter-spacing: .08em;
	font-weight: 700;
	border-bottom: 2px solid transparent;
	padding-bottom: 2px;
	transition: border-color .15s ease;
}
.site-footer__link:hover,
.site-footer__link:focus-visible {
	border-bottom-color: var(--bp-color-header-hover, var(--bp-color-accent));
	color: inherit;
}
.site-footer__copyright {
	margin: 0;
	opacity: .75;
}
@media (max-width: 520px) {
	.site-footer__bar {
		flex-direction: column;
		gap: .75rem;
		text-align: center;
	}
	.site-footer__nav {
		justify-content: center;
		gap: .75rem 1rem;
	}
}
