/**
 * Bluerizon frontend — structural styles for core elements.
 * Visual identity comes from tokens.css + per-node styles; this file only
 * provides layout scaffolding that both the live site and the preview share.
 */

.bz-content { font-family: var(--bz-font); color: var(--bz-text); }

/* Section */
.bz-section { position: relative; display: flex; }
/* The inner wrapper FILLS the section, so: (a) position:absolute children
   anchor to the full section area, and (b) the section's flex settings —
   routed here by BZ_Style — arrange the actual elements. */
.bz-section-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
/* Background zoom. The chain is mobile → tablet → desktop → 1, so a value set
   once on desktop keeps applying on narrower screens until it is overridden.
   Only sections that actually zoom are clipped, so headings that deliberately
   overflow their section elsewhere are unaffected. */
.bz-section--bg-zoom { overflow: hidden; }
.bz-section--bg-zoom > .bz-section-bg {
	transform: scale(var(--bz-bg-scale, 1));
}
@media (max-width: 1023px) {
	.bz-section--bg-zoom > .bz-section-bg {
		transform: scale(var(--bz-bg-scale-t, var(--bz-bg-scale, 1)));
	}
}
@media (max-width: 767px) {
	.bz-section--bg-zoom > .bz-section-bg {
		transform: scale(var(--bz-bg-scale-m, var(--bz-bg-scale-t, var(--bz-bg-scale, 1))));
	}
}

/* Per-device artwork. The desktop image only steps aside for a band that
   actually HAS a variant (--has-tablet / --has-mobile, set by the renderer),
   so a section with a mobile-only variant keeps its desktop artwork on
   tablet instead of going blank. */
.bz-section-bg--tablet,
.bz-section-bg--mobile { display: none; }
@media (max-width: 1023px) and (min-width: 768px) {
	.bz-section-bg--desktop.bz-section-bg--has-tablet { display: none; }
	.bz-section-bg--tablet { display: block; }
}
@media (max-width: 767px) {
	.bz-section-bg--desktop.bz-section-bg--has-mobile { display: none; }
	.bz-section-bg--tablet.bz-section-bg--has-mobile { display: none; }
	.bz-section-bg--tablet:not(.bz-section-bg--has-mobile) { display: block; }
	.bz-section-bg--mobile { display: block; }
}
.bz-section-overlay { position: absolute; inset: 0; z-index: 1; }
.bz-section-inner { position: relative; z-index: 2; width: 100%; min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.bz-container { max-width: var(--bz-container); margin: 0 auto; padding: 0 24px; }
/* Contained sections add one structural wrapper around the user's nodes.
   That wrapper must participate in the section's flex layout; otherwise
   Section-level Align/Justify controls arrange only the wrapper while the
   actual Heading/Text children stay in normal block flow. Inheriting the
   inner flex contract makes "center + top" and the other layout controls
   behave identically for contained and edge-to-edge sections. */
.bz-section-inner > .bz-container {
	box-sizing: border-box;
	width: 100%;
	min-width: 0;
	flex: 1 1 auto;
	display: inherit;
	flex-direction: inherit;
	flex-wrap: inherit;
	justify-content: inherit;
	align-items: inherit;
	align-content: inherit;
	justify-items: inherit;
	gap: inherit;
	row-gap: inherit;
	column-gap: inherit;
	grid-template-columns: inherit;
	grid-template-rows: inherit;
	grid-auto-flow: inherit;
	grid-auto-columns: inherit;
	grid-auto-rows: inherit;
}
/* Full-height = an exact viewport SLIDE. Exact height (not just min-)
   makes it a definite basis, so height:100% chains inside (row -> column ->
   image) resolve and object-fit:cover crops to the slide instead of the
   image's natural size inflating the section (= phantom inner scroll). */
.bz-full-height { height: 100vh; height: 100svh; min-height: 100vh; min-height: 100svh; overflow: hidden; }

/* Snap slides fill the LOCKED viewport height.
   --sk-vh is measured once by the theme and only updated on a real viewport
   change, so the slide does not resize while the browser toolbar animates.
   dvh is the fallback for a document rendered without the theme's JS: still
   correct, just with the toolbar reflow. */
.bz-content.bz-snap-desktop .bz-snap.bz-full-height,
.bz-content.bz-snap-tablet .bz-snap.bz-full-height,
.bz-content.bz-snap-mobile .bz-snap.bz-full-height {
	/* lvh is the LARGE viewport: the height with the browser toolbar
	   retracted. It never changes, and it is never smaller than what the
	   visitor can see — so a slide can neither leave a gap when the toolbar
	   hides (svh did) nor resize mid-scroll and move the snap point under
	   your finger (dvh did). The bottom sliver hidden while the toolbar is
	   up costs nothing: slide content is centred. */
	/* The WordPress admin bar sits above everything and is NOT part of the
	   viewport a snap slide can use. Left out of the maths it produces exactly
	   the report: every snap position shows a strip of the previous section at
	   the top, and the fixed header looks padded away from the edge. Logged-out
	   visitors never saw it, which is why it survived every header fix. */
	/* dvh is what the platform recommends for full-page snap: it is exactly
	   the visible height at every moment. It reflows while the toolbar
	   animates — a cosmetic cost on a gesture — but a slide is never taller
	   than the screen and never shorter, so no section can bleed into the
	   next and no line can hide behind the phone's navigation bar. */
	height: calc(100dvh - var(--sk-admin-h, 0px));
	min-height: calc(100dvh - var(--sk-admin-h, 0px));
}
/* Inside a slide nothing may outgrow it: rows and columns are capped at the
   slide height (empirically, % height chains through flex don't always
   resolve, letting a tall image extend its column past the section). */
.bz-full-height .bz-row, .bz-full-height .bz-col { max-height: 100%; }
.bz-full-height .bz-col:not(.bz-col--fit) { overflow: hidden; }
/* auto (filmstrip) columns stay unclipped: their images can't outgrow the
   slide by construction, and the caption hangs just below the photo — the
   section-level clip still guards the slide boundary itself. */
/* Logged-in WordPress view: the fixed admin bar reduces the visible snapport.
   Give each slide that exact visible height and align snap points below the
   bar. Visitors are unaffected; the editor canvas overrides this back to
   100svh because it deliberately removes theme/admin chrome. */
/* A WordPress admin bar reduces the actually visible viewport even when a
   section is full-height without snap. Keep the slide inside that snapport. */
body.admin-bar .bz-full-height {
	height: calc(100svh - 32px) !important;
	min-height: calc(100svh - 32px) !important;
}
@media (max-width: 782px) {
	body.admin-bar .bz-full-height {
		height: calc(100svh - 46px) !important;
		min-height: calc(100svh - 46px) !important;
	}
}

/* Device-independent page setting: desktop/tablet/mobile each opt in on an
   exact, non-overlapping media band. The legacy aggregate class remains only
   as a compatibility marker; it no longer enables snap by itself. */
@media (min-width: 1024px) {
	html:has(.bz-content.bz-snap-desktop) { scroll-snap-type: y mandatory; }
	.bz-content.bz-snap-desktop .bz-snap { scroll-snap-align: start; }
	html:has(body.admin-bar .bz-content.bz-snap-desktop) { scroll-padding-top: 32px; }
}
@media (min-width: 768px) and (max-width: 1023px) {
	html:has(.bz-content.bz-snap-tablet) { scroll-snap-type: y mandatory; }
	.bz-content.bz-snap-tablet .bz-snap { scroll-snap-align: start; }
	html:has(body.admin-bar .bz-content.bz-snap-tablet) { scroll-padding-top: 32px; }
}
@media (max-width: 767px) {
	html:has(.bz-content.bz-snap-mobile) { scroll-snap-type: y mandatory; }
	.bz-content.bz-snap-mobile .bz-snap { scroll-snap-align: start; }
	html:has(body.admin-bar .bz-content.bz-snap-mobile) { scroll-padding-top: 46px; }
}

/* Grid */

/* Generic nestable layout wrapper. It is a normal block <div> by default;
   users can switch it to flex/grid from Layout without inheriting Row's
   12-column assumptions. */
.bz-layout-container { min-width: 0; box-sizing: border-box; }

.bz-row { display: flex; flex-wrap: wrap; gap: var(--bz-grid-gap); }
/* Rows may contain regular elements directly as well as Columns. Direct
   elements form a full-width row item by default and can still be overridden
   by per-node width/flex styles in the builder. */
.bz-row > :not(.bz-col) { min-width: 0; flex: 0 0 100%; }
.bz-col { min-width: 0; flex: 1 1 0; }
.bz-col--1 { flex-basis: calc(8.333% - var(--bz-grid-gap)); }
.bz-col--2 { flex-basis: calc(16.666% - var(--bz-grid-gap)); }
.bz-col--3 { flex-basis: calc(25% - var(--bz-grid-gap)); }
.bz-col--4 { flex-basis: calc(33.333% - var(--bz-grid-gap)); }
.bz-col--5 { flex-basis: calc(41.666% - var(--bz-grid-gap)); }
.bz-col--6 { flex-basis: calc(50% - var(--bz-grid-gap)); }
.bz-col--7 { flex-basis: calc(58.333% - var(--bz-grid-gap)); }
.bz-col--8 { flex-basis: calc(66.666% - var(--bz-grid-gap)); }
.bz-col--9 { flex-basis: calc(75% - var(--bz-grid-gap)); }
.bz-col--10 { flex-basis: calc(83.333% - var(--bz-grid-gap)); }
.bz-col--11 { flex-basis: calc(91.666% - var(--bz-grid-gap)); }
.bz-col--12 { flex-basis: 100%; }

/* ---------------------------------------------------------------------------
   Per-device column spans.

   The desktop span is the base; a tablet or phone only carries a class when
   someone has actually set a span for that device in the editor, so documents
   authored before this existed render byte-identically.

   Mobile is nested inside the tablet range on purpose — a phone that sets only
   a tablet span should still honour it, the same way `style_mobile` falls back
   through `style_tablet`.

   The breakpoints are the same 1023/767 the builder uses everywhere else
   (BZ_Style::BP_TABLET / BP_MOBILE); they are not a second set of numbers to
   keep in step.
   ------------------------------------------------------------------------ */
@media (max-width: 1023px) {
	.bz-col-t--1 { flex-basis: calc(8.333% - var(--bz-grid-gap)); }
	.bz-col-t--2 { flex-basis: calc(16.666% - var(--bz-grid-gap)); }
	.bz-col-t--3 { flex-basis: calc(25% - var(--bz-grid-gap)); }
	.bz-col-t--4 { flex-basis: calc(33.333% - var(--bz-grid-gap)); }
	.bz-col-t--5 { flex-basis: calc(41.666% - var(--bz-grid-gap)); }
	.bz-col-t--6 { flex-basis: calc(50% - var(--bz-grid-gap)); }
	.bz-col-t--7 { flex-basis: calc(58.333% - var(--bz-grid-gap)); }
	.bz-col-t--8 { flex-basis: calc(66.666% - var(--bz-grid-gap)); }
	.bz-col-t--9 { flex-basis: calc(75% - var(--bz-grid-gap)); }
	.bz-col-t--10 { flex-basis: calc(83.333% - var(--bz-grid-gap)); }
	.bz-col-t--11 { flex-basis: calc(91.666% - var(--bz-grid-gap)); }
	.bz-col-t--12 { flex-basis: 100%; }
	.bz-col-t--fill { flex: 1 1 0; width: auto; min-width: 0; flex-basis: 0; }
	.bz-col-t--fit { flex: 0 0 auto; width: auto; min-width: 0; flex-basis: auto; }
}
@media (max-width: 767px) {
	.bz-col-m--1 { flex-basis: calc(8.333% - var(--bz-grid-gap)); }
	.bz-col-m--2 { flex-basis: calc(16.666% - var(--bz-grid-gap)); }
	.bz-col-m--3 { flex-basis: calc(25% - var(--bz-grid-gap)); }
	.bz-col-m--4 { flex-basis: calc(33.333% - var(--bz-grid-gap)); }
	.bz-col-m--5 { flex-basis: calc(41.666% - var(--bz-grid-gap)); }
	.bz-col-m--6 { flex-basis: calc(50% - var(--bz-grid-gap)); }
	.bz-col-m--7 { flex-basis: calc(58.333% - var(--bz-grid-gap)); }
	.bz-col-m--8 { flex-basis: calc(66.666% - var(--bz-grid-gap)); }
	.bz-col-m--9 { flex-basis: calc(75% - var(--bz-grid-gap)); }
	.bz-col-m--10 { flex-basis: calc(83.333% - var(--bz-grid-gap)); }
	.bz-col-m--11 { flex-basis: calc(91.666% - var(--bz-grid-gap)); }
	.bz-col-m--12 { flex-basis: 100%; }
	.bz-col-m--fill { flex: 1 1 0; width: auto; min-width: 0; flex-basis: 0; }
	.bz-col-m--fit { flex: 0 0 auto; width: auto; min-width: 0; flex-basis: auto; }
}

@media (max-width: 767px) {
	.bz-row--stack { flex-direction: column; }
	.bz-row--stack > .bz-col { flex-basis: 100%; }
	/* A phone span set deliberately in the editor beats the row's automatic
	   stacking. Two classes, so it outranks `.bz-row--stack > .bz-col` — the
	   width is still 100% for every column that did not ask for anything. */
	.bz-row--stack > .bz-col[class*="bz-col-m--"] { flex-basis: auto; }
}

/* Heading */
.bz-heading { margin: 0 0 0.5em; font-family: var(--bz-font); }
.bz-heading--display { font-family: var(--bz-font-display); font-weight: var(--bz-display-weight); text-transform: uppercase; font-size: var(--bz-fs-display-lg); letter-spacing: 0.01em; line-height: 1.05; }
.bz-heading--watermark { font-family: var(--bz-font-display); font-weight: var(--bz-display-weight); text-transform: uppercase; font-size: var(--bz-fs-display-xl); opacity: 0.18; line-height: 1; }
.bz-heading--two-tone .bz-tone-a { color: var(--bz-white); }
.bz-heading--two-tone .bz-tone-b { color: var(--bz-sage); }
.bz-heading-link { text-decoration: none; color: inherit; }

/* Text */
.bz-text { font-size: var(--bz-fs-body); line-height: 1.7; }
.bz-text p { margin: 0 0 1em; }

/* Image */
.bz-image { margin: 0; overflow: hidden; }
/* The inner img FOLLOWS the figure (the element node styles land on):
   height:100% resolves against the figure — when the figure has no explicit
   height it computes to auto (natural ratio, today's behavior); when the
   user sets Height/Aspect on the Image element, the img fills it and
   object-fit/position set in the inspector are inherited and crop properly. */
.bz-image img { display: block; width: 100%; height: 100%; object-fit: inherit; object-position: inherit; }
.bz-caption { font-size: var(--bz-fs-caption); text-transform: uppercase; letter-spacing: 0.03em; margin-top: 8px; }

/* Video */
.bz-video { display: block; width: 100%; height: auto; }

/* Button */
.bz-btn { display: inline-block; padding: 14px 32px; font-size: 13px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; text-decoration: none; border-radius: var(--bz-radius); transition: opacity 0.2s, background 0.2s; cursor: pointer; }
.bz-btn--primary { background: var(--bz-sage-dark); color: var(--bz-white); border: 1px solid var(--bz-sage-dark); }
.bz-btn--outline { background: transparent; color: var(--bz-ink); border: 1px solid var(--bz-border-strong); }
.bz-btn--link { background: none; border: none; padding: 0; color: inherit; text-decoration: underline; }
.bz-btn:hover { opacity: 0.85; }

/* Icon list */
/* The font-size default lives on the LIST, not on the items: the inspector
   targets the element (.bz-icon-list), and a declaration on the li would
   stop that value from ever reaching the text — the control would change the
   document and do nothing on screen. Same reason .bz-icon-list li inherits. */
.bz-icon-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; font-size: var(--bz-fs-body); }
.bz-icon-list li { display: flex; align-items: flex-start; gap: 14px; font-size: inherit; }
.bz-icon { width: 24px; height: 24px; flex: 0 0 auto; }
.bz-icon--check { position: relative; }
.bz-icon--check::after { content: ""; position: absolute; left: 4px; top: 2px; width: 12px; height: 7px; border-left: 3px solid var(--bz-sage-dark); border-bottom: 3px solid var(--bz-sage-dark); transform: rotate(-45deg); }

/* Card */
.bz-card { display: block; text-decoration: none; color: var(--bz-text-secondary); border: 1px solid var(--bz-border); background: var(--bz-cream-soft); font-size: 13px; font-weight: 300; line-height: 1.6; }
.bz-card-img { display: block; width: 100%; height: auto; }
.bz-card-title { padding: 16px 16px 0; font-weight: 600; font-size: 14px; text-transform: uppercase; letter-spacing: 0.02em; }
/* Typography applied to the Card node must reach its body copy. Previous
   hard-coded values here made the inspector's Font size/weight/line-height
   controls appear dead on both the canvas and live page. */
.bz-card-text { padding: 8px 16px 16px; font: inherit; color: inherit; }
.bz-card-text > :first-child { margin-top: 0; }
.bz-card-text > :last-child { margin-bottom: 0; }

/* Product */
.bz-product {
	display: block;
	text-decoration: none;
	color: inherit;
	font-family: inherit;
	font-size: var(--bz-fs-caption);
	font-weight: 400;
	line-height: 1.35;
}
.bz-product-media { display: block; overflow: hidden; }
.bz-product img { display: block; width: 100%; height: auto; }
.bz-product-name {
	display: block;
	margin-top: 10px;
	font: inherit;
	color: inherit;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}
.bz-product-excerpt {
	display: block;
	margin-top: 7px;
	font-family: inherit;
	font-size: .92em;
	font-weight: inherit;
	line-height: 1.45;
	color: inherit;
	text-transform: none;
}
.bz-product-excerpt p { margin: 0; }
.bz-product-price {
	display: block;
	margin-top: 8px;
	font-family: inherit;
	font-size: .96em;
	font-weight: inherit;
	line-height: inherit;
	color: inherit;
}

/* Form */
.bz-form { display: grid; gap: 14px; max-width: 480px; }
.bz-form input, .bz-form textarea { padding: 14px; border: 1px solid var(--bz-text-muted); border-radius: var(--bz-radius); font-family: inherit; font-size: 13px; text-transform: uppercase; letter-spacing: 0.02em; background: transparent; }
.bz-form textarea { min-height: 120px; resize: vertical; }
.bz-form .bz-hp { position: absolute; left: -9999px; }

/* Slider */
/*
 * THE HEIGHT CHAIN THROUGH A SLIDER.
 *
 * height:100% only resolves against a parent that has a height of its own, and
 * a slider has two wrappers the node tree does not show: .bz-slider-track,
 * which holds the slides, and .bz-slide-inner, which holds their content.
 * Neither carried a height, so a full-height Slider containing a full-height
 * Slide containing a full-height Product produced nothing — every one of those
 * 100% values was measured against an element that was as tall as its content
 * and no taller. Three settings that all looked right and one broken link
 * between them.
 *
 * The track inherits the slider's height and the slides stretch to fill it;
 * the inner wrapper follows. Sliders that are sized by their content are
 * unaffected, because 100% of auto is still auto.
 */
.bz-slider { position: relative; overflow: hidden; }
.bz-slider-track { display: flex; align-items: stretch; height: 100%; transition: transform 0.5s ease; }
.bz-slide { position: relative; flex: 0 0 100%; min-width: 0; display: flex; flex-direction: column; }
.bz-slide-inner { position: relative; z-index: 2; flex: 1 1 auto; min-height: 0; }
.bz-slider-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 3; width: 44px; height: 44px; border: none; background: rgba(255,255,255,0.7); cursor: pointer; font-size: 18px; line-height: 1; }
.bz-slider-arrow--prev { left: 12px; }
.bz-slider-arrow--next { right: 12px; }
.bz-slider-dots { position: absolute; bottom: 14px; left: 0; right: 0; z-index: 3; display: flex; justify-content: center; gap: 8px; }
.bz-slider-dots button { width: 9px; height: 9px; border-radius: 50%; border: none; background: rgba(255,255,255,0.5); cursor: pointer; padding: 0; }
.bz-slider-dots button[aria-current="true"] { background: var(--bz-white); }

/* Spacer */
.bz-spacer { width: 100%; }

/* Column sizing modes. Fill participates in the Row and receives the spare
   width; fit-content shrink-wraps media/explicitly sized compositions. */
.bz-col--fill { flex: 1 1 0; width: auto; min-width: 0; }
.bz-col--fit { flex: 0 0 auto; width: auto; min-width: 0; }
/* The img is a DIRECT child with height:100% — with a definite height chain
   (row Height -> column -> figure) the browser derives its width from the
   natural aspect ratio, so the column shrink-wraps to the photo exactly and
   photos glue edge-to-edge. The caption hangs ABSOLUTELY below the photo:
   zero layout impact (can't widen the column, can't wrap the row), rendered
   at the photo's width on the section background — as designed. */
.bz-col--fit .bz-image { height: 100%; position: relative; overflow: visible; }
.bz-col--fit .bz-image img { width: auto; height: 100%; max-width: none; }
.bz-col--fit .bz-image figcaption { position: absolute; top: 100%; left: 0; right: 0; margin-top: 10px; }

/* Editor-only recovery state. Live pages omit unresolved products entirely. */
.bz-product--missing {
	display: grid;
	gap: 6px;
	min-height: 140px;
	place-content: center;
	padding: 20px;
	border: 1px dashed #b9b3aa;
	background: rgba(249, 248, 247, .8);
	color: #6b665f;
	text-align: center;
	font-size: 12px;
}
.bz-product--missing strong { color: #8e2f23; font-size: 13px; }

/* 1.9.31 — native horizontal swipe without blocking vertical page scroll. */
.bz-slider { touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.bz-slider-track { will-change: transform; }
.bz-slider img { -webkit-user-drag: none; user-drag: none; }

/* ---- Reusable blocks ---- */
.bz-block { display: contents; }
.bz-block--empty,
.bz-block--error {
	display: block;
	padding: 18px;
	border: 1px dashed #b9b2a6;
	background: rgba(0,0,0,.02);
	color: #7a746a;
	font: 400 13px/1.5 Montserrat, system-ui, sans-serif;
	text-align: center;
}
.bz-block--error { border-color: #c07a7a; color: #a44; }


/* ===========================================================================
   SECTION BACKGROUND — the box is not negotiable
   ---------------------------------------------------------------------------
   The builder gives the owner three controls over a section background: fit,
   focal position and zoom. It gives them NO control over its box, because the
   box is always "the whole section" — that is what a background is.

   So any rule that narrows this element is a bug by definition, and there is
   no legitimate declaration for !important to trample. Theme rules that size
   phone artwork to a design-width axis kept catching it and leaving the
   section colour showing down both sides.
   ======================================================================== */
.bz-section > .bz-section-bg {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
	max-height: none !important;
	margin: 0 !important;
	left: 0 !important;
	right: 0 !important;
	top: 0 !important;
}

/* ===========================================================================
   ACCORDION
   ---------------------------------------------------------------------------
   The element and its runtime already existed; this file had nothing for it,
   so a built accordion rendered as a bare <details> — grey triangle, no rules,
   no spacing — and read as "the builder cannot do accordions".

   Built on <details>/<summary> rather than on divs and a click handler,
   because the browser then gives keyboard support, the open/closed state, and
   find-in-page that opens the panel containing the match, for free. Those are
   the three things hand-rolled accordions get wrong.
   ======================================================================== */
.bz-accordion { display: block; width: 100%; }

.bz-accordion-item {
	border-top: 1px solid var(--bz-rule, rgba(25, 37, 53, .12));
}
.bz-accordion-item:last-child {
	border-bottom: 1px solid var(--bz-rule, rgba(25, 37, 53, .12));
}

.bz-accordion-head {
	display: flex;
	align-items: center;
	gap: 20px;
	padding: 22px 0;
	cursor: pointer;
	list-style: none;          /* Firefox */
	font-family: var(--bz-font);
	font-size: 1.05rem;
	line-height: 1.4;
	color: inherit;
}
/* The default disclosure triangle, removed in favour of the marker below. */
.bz-accordion-head::-webkit-details-marker { display: none; }
.bz-accordion-head::marker { content: ''; }

.bz-accordion-title { flex: 1 1 auto; min-width: 0; }

/* A plus that becomes a minus: two bars, one of which rotates away. Drawn
   rather than typed so it lines up at any font size and needs no icon font. */
.bz-accordion-marker {
	position: relative;
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	opacity: .55;
	transition: opacity .18s ease;
}
.bz-accordion-marker::before,
.bz-accordion-marker::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	height: 1.5px;
	background: currentColor;
	transform: translateY(-50%);
	transition: transform .22s ease;
}
.bz-accordion-marker::after { transform: translateY(-50%) rotate(90deg); }
.bz-accordion-item[open] .bz-accordion-marker::after { transform: translateY(-50%) rotate(0); }
.bz-accordion-item[open] .bz-accordion-marker { opacity: 1; }

.bz-accordion-head:hover .bz-accordion-marker { opacity: 1; }
.bz-accordion-head:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
}

/* Marker on the left, or gone entirely. */
.bz-accordion--marker-left .bz-accordion-head { flex-direction: row-reverse; }
.bz-accordion--marker-none .bz-accordion-marker { display: none; }

.bz-accordion-panel {
	padding: 0 0 24px;
	max-width: 70ch;
	line-height: 1.7;
	opacity: .85;
}
.bz-accordion--marker-left .bz-accordion-panel { padding-left: 34px; }
.bz-accordion-panel > :first-child { margin-top: 0; }
.bz-accordion-panel > :last-child { margin-bottom: 0; }

/*
 * The opening slide.
 *
 * interpolate-size lets a browser animate to `auto`, which is the only height
 * that is correct for arbitrary content. Where it is unsupported the panel
 * simply appears — the accordion still works, it just does not slide. That is
 * the right way round: a missing animation is nothing, a broken height is a
 * clipped answer.
 */
@supports (interpolate-size: allow-keywords) {
	html { interpolate-size: allow-keywords; }

	.bz-accordion-item::details-content {
		block-size: 0;
		overflow: hidden;
		opacity: 0;
		transition: block-size .32s ease, opacity .26s ease, content-visibility .32s allow-discrete;
		transition-behavior: allow-discrete;
	}
	.bz-accordion-item[open]::details-content {
		block-size: auto;
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bz-accordion-item::details-content,
	.bz-accordion-marker::before,
	.bz-accordion-marker::after { transition: none; }
}

@media (max-width: 767px) {
	.bz-accordion-head { padding: 18px 0; gap: 14px; font-size: 1rem; }
	.bz-accordion-panel { padding-bottom: 20px; }
}

/* ===========================================================================
   TABS
   ---------------------------------------------------------------------------
   Same story as the accordion: element, runtime and ARIA were all in place,
   and there was no CSS — so the panels stacked on top of each other and the
   tab strip looked like a row of browser buttons.
   ======================================================================== */
.bz-tabs { display: block; width: 100%; }

.bz-tabs-list {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	justify-content: var(--bz-tabs-align, flex-start);
	border-bottom: 1px solid var(--bz-rule, rgba(25, 37, 53, .12));
}

.bz-tabs-btn {
	appearance: none;
	background: transparent;
	border: 0;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;          /* sit on the list's rule, not above it */
	padding: 12px 18px;
	cursor: pointer;
	font: inherit;
	font-size: .95rem;
	letter-spacing: .04em;
	color: inherit;
	opacity: .6;
	transition: opacity .18s ease, border-color .18s ease;
}
.bz-tabs-btn:hover { opacity: .85; }
.bz-tabs-btn.is-active {
	opacity: 1;
	border-bottom-color: currentColor;
}
.bz-tabs-btn:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }

/* Only the selected panel is shown. The others keep their markup so the tab
   strip does not resize as the browser lays them out. */
.bz-tabs-panel { display: none; padding: 26px 0 0; line-height: 1.7; }
.bz-tabs-panel.is-active { display: block; }
.bz-tabs-panel > :first-child { margin-top: 0; }
.bz-tabs-panel > :last-child { margin-bottom: 0; }

/* Side tabs: the strip becomes a column beside the panels. */
@media (min-width: 768px) {
	.bz-tabs--left { display: grid; grid-template-columns: minmax(140px, 220px) 1fr; gap: 32px; }
	.bz-tabs--left .bz-tabs-list {
		flex-direction: column;
		flex-wrap: nowrap;
		gap: 2px;
		border-bottom: 0;
		border-right: 1px solid var(--bz-rule, rgba(25, 37, 53, .12));
		align-items: stretch;
		justify-content: flex-start;
	}
	.bz-tabs--left .bz-tabs-btn {
		text-align: left;
		border-bottom: 0;
		border-right: 2px solid transparent;
		margin: 0 -1px 0 0;
	}
	.bz-tabs--left .bz-tabs-btn.is-active { border-right-color: currentColor; }
	.bz-tabs--left .bz-tabs-panel { padding: 0; }
}

@media (max-width: 767px) {
	.bz-tabs-btn { padding: 10px 14px; font-size: .9rem; }
	.bz-tabs-panel { padding-top: 20px; }
}

/* ===========================================================================
   A SECTION THAT IS ITSELF A LINK
   ---------------------------------------------------------------------------
   An overlay rather than a wrapper: an <a> may not contain another <a>, and a
   section that holds a product card or a button holds several. See the note in
   render_section().

   z-index 1 puts it above the background and below the content, so a real link
   inside the section still receives the click and this one catches everything
   else. Keyboard users reach the inner links normally; this overlay is
   aria-hidden and not tabbable, so it adds no duplicate stop.
   ======================================================================== */
.bz-section--linked { position: relative; }

.bz-section-link {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	/* No text, no outline of its own — the section is the affordance. */
	font-size: 0;
	text-decoration: none;
}

/*
 * Everything except the overlay is lifted above it.
 *
 * The overlay is rendered as the last child of the inner wrapper, so without
 * this it would paint over its own siblings and swallow every link inside the
 * section — the exact failure the overlay exists to avoid. The :not() keeps it
 * from lifting itself.
 */
.bz-section--linked .bz-section-inner > *:not(.bz-section-link) {
	position: relative;
	z-index: 2;
}

.bz-section--linked { cursor: pointer; }
