/**
 * Oyolloo Elements — site header.
 *
 * Figma: node 471:1043 (desktop), 471:3838 (mobile bar), 477:15872 (drawer).
 *   bar     96px tall, white, 1px #e0e0e0 bottom border, 140px gutters
 *   layout  three equal flex tracks so the nav sits optically centred
 *   nav     Inter 16/1.6 #1a1a1a, 24px gaps
 *   actions 16px gaps, right aligned
 *   mobile  65px bar, 79px logo, burger; drawer links 50px apart
 *
 * @package Oyolloo\Elements
 * @since   1.0.0
 */

.oe-site-header {
	position: relative;
}

.oe-site-header__bar {
	--oe-header-height: 96px;
	--oe-header-bg: var(--oe-color-white);
	--oe-header-fg: var(--oe-color-ink-strong);

	background-color: var(--oe-header-bg);
	color: var(--oe-header-fg);
	/* Figma strokes are inside the box, so a border would make the bar 97. */
	box-shadow: inset 0 -1px 0 var(--oe-color-tile-border);
}

.oe-site-header__bar--sticky {
	position: sticky;
	top: 0;
	z-index: 100;
}

/* Shadow appears only once the page has scrolled; set by the widget script. */
.oe-site-header.is-stuck .oe-site-header__bar--sticky {
	box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
}

.oe-site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--oe-space-md);
	min-height: var(--oe-header-height);
}

/*
 * The logo and the actions take the room they need; the nav takes what is left
 * and centres inside it.
 *
 * All three were equal thirds before, which centred the nav mathematically —
 * tidier on paper, but the tracks were `flex: 1 0 0`, and `flex-shrink: 0`
 * means a track whose contents outgrow a third does not shrink, it overflows
 * into its neighbour. With five menu items and a CTA that is exactly what
 * happened: the menu ran under the search and cart icons, while the logo sat in
 * a third of the bar it needed 113px of. The collapsed states below already
 * size the brand and actions this way; this brings the desktop into line.
 */
.oe-site-header__brand,
.oe-site-header__actions {
	flex: 0 0 auto;
	min-width: 0;
}

.oe-site-header__nav {
	display: flex;
	justify-content: center;
	/* Shrinkable on purpose: on a narrow desktop the menu should tighten and
	   then hand over to the burger, never lie on top of the icons. */
	flex: 1 1 auto;
	min-width: 0;
}

/* -- Brand --------------------------------------------------------------- */

.oe-site-header__logo {
	display: inline-flex;
	align-items: center;
	width: 113px;
}

.oe-site-header__logo img {
	width: 100%;
	height: auto;
	object-fit: contain;
}

.oe-site-header__wordmark {
	font-family: var(--oe-font-title);
	font-size: var(--oe-h5-size);
	font-weight: 700;
	text-transform: uppercase;
	white-space: nowrap;
}

/* -- Navigation ---------------------------------------------------------- */

.oe-site-header__menu {
	--oe-gap: var(--oe-space-md);

	display: flex;
	align-items: center;
	gap: var(--oe-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

.oe-site-header__menu > li {
	position: relative;
}

.oe-site-header__menu a {
	display: inline-block;
	color: inherit;
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size);
	line-height: var(--oe-body-leading);
	white-space: nowrap;
	transition: color 200ms var(--oe-ease, ease);
}

.oe-site-header__menu a:hover,
.oe-site-header__menu .current-menu-item > a {
	color: var(--oe-color-brand-dark);
}

/* Second level, shown on hover. */
.oe-site-header__menu .sub-menu {
	position: absolute;
	inset-inline-start: 0;
	top: 100%;
	z-index: 20;
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-2xs);
	min-width: 200px;
	margin: 0;
	padding: var(--oe-space-sm);
	list-style: none;
	background-color: var(--oe-color-white);
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-md);
	box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition:
		opacity 180ms var(--oe-ease, ease),
		transform 180ms var(--oe-ease, ease),
		visibility 180ms;
}

.oe-site-header__menu > li:hover > .sub-menu,
.oe-site-header__menu > li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.oe-site-header__hint {
	margin: 0;
	color: var(--oe-color-neutral-500);
	font-size: var(--oe-body-sm-size);
}

/* -- Actions ------------------------------------------------------------- */

.oe-site-header__actions {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--oe-space-sm);
}

.oe-site-header__icon {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	/* Figma's icon button hugs its glyph with 8px either side, so the pair sits
	   51px centre to centre. A 40px square instead spaces them 56 apart and
	   pushes the cart away from the CTA — same artwork, wrong rhythm. Height
	   stays 40 so the tap target is comfortable and the glyphs stay on the
	   bar's centre line. */
	width: auto;
	height: 40px;
	padding-block: 0;
	padding-inline: 8px;
	border-radius: var(--oe-radius-pill);
	color: inherit;
	transition: background-color 200ms var(--oe-ease, ease);
}

.oe-site-header__icon:hover {
	background-color: var(--oe-color-neutral-100);
}

.oe-site-header__icon svg {
	width: 20px;
	height: 20px;
}

/* Figma draws the cart at 20 but the magnifier at 18; one shared size makes the
   search glyph the heavier of the pair, which is the wrong way round. */
.oe-site-header__icon[data-oe-search-toggle] svg {
	width: 18px;
	height: 18px;
}

.oe-site-header__badge {
	position: absolute;
	top: 2px;
	inset-inline-end: 2px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 18px;
	height: 18px;
	padding-inline: 5px;
	border-radius: var(--oe-radius-pill);
	background-color: var(--oe-color-brand);
	color: var(--oe-color-black);
	font-family: var(--oe-font-body);
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
}

/* -- Burger -------------------------------------------------------------- */

.oe-site-header__burger {
	display: none;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 44px;
	height: 44px;
	padding: 0;
	color: inherit;
}

/*
 * Figma's menu glyph (471:3847) is three left-aligned round-capped rules of
 * different lengths. It is the artwork itself rather than three CSS boxes: at
 * this size a 1.5px box rounds down to one solid pixel row, where a 1.5px
 * stroke covers two, and the glyph came out a weight lighter than the cart
 * beside it. `menu-close.svg` is drawn at the same 1.5px for that reason —
 * the bundled 2px `cart-close` reads heavier in the same slot.
 */
.oe-site-header__burger-bars {
	position: relative;
	display: block;
	width: 24px;
	height: 24px;
}

/*
 * Both glyphs are stacked in the one 24px box and cross-faded, so the button
 * never changes size and nothing reflows mid-swap. The state comes from
 * `aria-expanded` on the button, which the drawer toggle already sets — using
 * that rather than a second class keeps the icon honest: it cannot end up
 * showing a cross over a closed drawer.
 */
.oe-site-header__burger-icon {
	position: absolute;
	inset: 0;
	display: block;
	transition: opacity 140ms ease, transform 140ms ease;
}

.oe-site-header__burger-icon--close {
	opacity: 0;
	transform: rotate(-90deg);
}

.oe-site-header__burger[aria-expanded="true"] .oe-site-header__burger-icon--menu {
	opacity: 0;
	transform: rotate(90deg);
}

.oe-site-header__burger[aria-expanded="true"] .oe-site-header__burger-icon--close {
	opacity: 1;
	transform: none;
}

.oe-site-header__burger-bars svg {
	display: block;
	width: 100%;
	height: 100%;
}

@media (prefers-reduced-motion: reduce) {
	.oe-site-header__burger-icon {
		transition: none;
	}

	/* The rotation is decoration; with no fade to carry it the half-turn just
	   reads as a glitch, so the swap becomes a straight cut. */
	.oe-site-header__burger-icon--close,
	.oe-site-header__burger[aria-expanded="true"] .oe-site-header__burger-icon--menu {
		transform: none;
	}
}

/* -- Drawer -------------------------------------------------------------- */

/* Figma 477:15373: a 487-tall panel under the bar, 24 all round and 24 between
   the nav and the action stack. Positioned absolute to the header container. */
.oe-site-header__drawer {
	position: absolute;
	inset-inline: 0;
	top: 100%;
	z-index: 150;
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-md);
	padding: var(--oe-space-md);
	background-color: var(--oe-header-bg, var(--oe-color-white));
	border-block-end: 1px solid var(--oe-color-tile-border);
	max-height: calc(100vh - var(--oe-header-height, 65px));
	overflow-y: auto;

	/* Slides in from the inline end and lies over the page — the panel is
	   absolute, so nothing below it moves. */
	transform: translateX(100%);
	opacity: 0;
	transition:
		transform 280ms var(--oe-ease, ease),
		opacity 200ms var(--oe-ease, ease),
		display 280ms allow-discrete;
}

/*
 * Closed means out of the layout, not merely invisible: parked at
 * translateX(100%) the panel hangs past the inline edge, and a still-laid-out
 * box there gives the whole page a horizontal scrollbar. `allow-discrete`
 * above holds the display flip back until the slide-out has finished.
 */
.oe-site-header__drawer[hidden] {
	display: none;
}

.oe-site-header.is-open .oe-site-header__drawer {
	transform: translateX(0);
	opacity: 1;
}

/* Without a from-state the open transition has nothing to run from — going
   display:none -> flex starts no transition on its own. */
@starting-style {
	.oe-site-header.is-open .oe-site-header__drawer {
		transform: translateX(100%);
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.oe-site-header__drawer {
		transition: none;
		transform: none;
	}
}

.oe-site-header__drawer-menu {
	display: flex;
	flex-direction: column;
	/* Figma stacks the drawer links on a 50px rhythm. */
	gap: 24px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* The theme tints visited links, which the design does not — and :visited is
   one of the few states an author may still recolour. */
.oe-site-header__menu a:visited,
.oe-site-header__drawer-menu a:visited {
	color: inherit;
}

.oe-site-header__drawer-menu a {
	display: block;
	color: var(--oe-color-ink-strong);
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size);
	line-height: var(--oe-body-leading);
}

.oe-site-header__drawer-menu .sub-menu {
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-xs);
	margin: var(--oe-space-xs) 0 0;
	padding-inline-start: var(--oe-space-sm);
	list-style: none;
}

/* -- Header search -------------------------------------------------------
   A full-screen overlay, not a band under the bar. Search is a mode you enter
   rather than a control tucked into the chrome: taking the screen removes the
   page as a competing thing to look at, and the same layout then serves every
   width instead of shrinking a header row down to a phone.

   A sibling of the bar in the markup, because a fixed overlay nested inside a
   transformed sticky header resolves against that header, not the viewport.
   ------------------------------------------------------------------------ */

.oe-site-header__search {
	position: fixed;
	inset: 0;
	/* Above the sticky bar (150) and level with the cart drawer, which is the
	   other thing that takes the whole screen. */
	z-index: 1000;
	display: flex;
	align-items: flex-start;
	justify-content: center;
}

.oe-site-header__search[hidden] {
	display: none;
}

.oe-site-header__search-scrim {
	position: absolute;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.55);
	opacity: 0;
	transition: opacity 240ms var(--oe-ease, ease);
}

.oe-site-header__search.is-open .oe-site-header__search-scrim {
	opacity: 1;
}

.oe-site-header__search-dialog {
	position: relative;
	width: 100%;
	padding-block: clamp(72px, 16vh, 160px) clamp(32px, 6vh, 64px);
	background-color: var(--oe-color-white);
	/* Slides down from the top edge, which is where the button that opened it
	   lives — the panel arrives from the thing that was pressed. */
	transform: translateY(-24px);
	opacity: 0;
	transition:
		transform 280ms var(--oe-ease, ease),
		opacity 200ms var(--oe-ease, ease);
}

.oe-site-header__search.is-open .oe-site-header__search-dialog {
	transform: none;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.oe-site-header__search-scrim,
	.oe-site-header__search-dialog {
		transition: none;
	}

	.oe-site-header__search-dialog {
		transform: none;
	}
}

.oe-site-header__search-close {
	position: absolute;
	inset-block-start: clamp(16px, 3vh, 28px);
	inset-inline-end: clamp(16px, 3vw, 40px);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	min-width: 0;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: var(--oe-color-neutral-100, #f5f5f5);
	--oe-btn-surface: var(--oe-color-neutral-100, #f5f5f5);
	color: var(--oe-color-ink-strong, #1a1a1a);
	--oe-btn-fg: var(--oe-color-ink-strong, #1a1a1a);
	cursor: pointer;
	transition: background-color 160ms var(--oe-ease, ease);
}

.oe-site-header__search-close:hover {
	background-color: var(--oe-color-neutral-200, #ebebeb);
}

.oe-site-header__search-close svg {
	width: 22px;
	height: 22px;
}

@media (prefers-reduced-motion: reduce) {
	.oe-site-header__search-close { transition: none; }
}

.oe-site-header__search-form {
	display: flex;
	align-items: center;
	gap: var(--oe-space-sm, 14px);
	/*
	 * Narrower than the site container it otherwise inherits. At 1670px the
	 * field spans nearly the whole screen, and a search box that wide reads as
	 * a page element rather than as the one thing being asked for — and the eye
	 * has to travel the full width back to the button.
	 */
	max-width: 760px;
}

.oe-site-header__search-field {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	gap: var(--oe-space-xs);
	min-width: 0;
	min-height: 64px;
	padding-inline: 24px;
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-md);
	background-color: var(--oe-color-neutral-100);
	color: var(--oe-color-ink-strong);
}

.oe-site-header__search-icon {
	display: inline-flex;
	flex-shrink: 0;
	color: var(--oe-color-muted, #6b6b6b);
}

.oe-site-header__search-icon svg {
	width: 22px;
	height: 22px;
}

/* Scoped through the wrapper, not written on the class alone: the theme styles
   bare `input` at (0,1,1) and would otherwise keep its own border and radius
   inside the pill. The drawer field is stripped the same way. */
.oe-site-header__search-field .oe-site-header__search-input {
	flex: 1 0 0;
	min-width: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: inherit;
	font-family: var(--oe-font-body);
	font-size: clamp(18px, 2.4vw, 24px);
}

/*
 * No focus ring on the field. The overlay opens with this input already
 * focused and it is the only text field on screen, so a ring marks the one
 * thing that could not be anything else — it read as an error box against the
 * brand yellow. The close button keeps its own ring, which is what a keyboard
 * user actually needs to find.
 *
 * base.css's shared ring scores (0,3,0) thanks to the [tabindex] branch in its
 * :is(), so the wrapper scope is needed to out-specify it.
 */
.oe-site-header__search .oe-site-header__search-input:focus,
.oe-site-header__search .oe-site-header__search-input:focus-visible {
	outline: none;
	box-shadow: none;
}

.oe-site-header__search-submit {
	flex-shrink: 0;
	min-height: 64px;
	padding-inline: 32px;
	border: 0;
	border-radius: var(--oe-radius-md);
	background-color: var(--oe-color-brand);
	--oe-btn-surface: var(--oe-color-brand);
	color: var(--oe-color-black);
	--oe-btn-fg: var(--oe-color-black);
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size, 16px);
	font-weight: 700;
	cursor: pointer;
	transition: background-color 160ms var(--oe-ease, ease);
}

.oe-site-header__search-submit:hover {
	background-color: var(--oe-color-brand-dark, #e0a800);
}

@media (prefers-reduced-motion: reduce) {
	.oe-site-header__search-submit { transition: none; }
}

@media (max-width: 767px) {
	.oe-site-header__search-form {
		gap: var(--oe-space-xs, 8px);
	}

	.oe-site-header__search-field {
		min-height: 54px;
		padding-inline: 16px;
	}

	.oe-site-header__search-submit {
		min-height: 54px;
		padding-inline: 18px;
	}
}

.oe-site-header__drawer-actions {
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-sm);
}

.oe-site-header__drawer-search,
.oe-site-header__drawer-cart {
	display: flex;
	align-items: center;
	gap: var(--oe-space-xs);
	min-height: 50px;
	padding-inline: 20px;
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-md);
	background-color: var(--oe-color-neutral-100);
	color: var(--oe-color-ink-strong);
}

/* The row is the control the eye sees, so the keyboard ring belongs on it —
   on the bare input it draws a second box inside the first. */
.oe-site-header__drawer-search:has(input:focus-visible) {
	outline: 2px solid var(--oe-color-brand);
	outline-offset: 2px;
}

.oe-site-header__drawer-cart {
	justify-content: center;
}

.oe-site-header__drawer-search svg,
.oe-site-header__drawer-cart svg {
	width: 20px;
	height: 20px;
	flex-shrink: 0;
}

.oe-site-header__drawer-search input {
	flex: 1 0 0;
	min-width: 0;
	border: 0;
	background: none;
	color: inherit;
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size);
}

/* The shared focus ring in base.css scores (0,3,0) because of the [tabindex]
   branch in its :is(), so the drawer scope is needed to out-specify it. */
.oe-site-header__drawer .oe-site-header__drawer-search input:focus,
.oe-site-header__drawer .oe-site-header__drawer-search input:focus-visible {
	outline: none;
}

/* -- Collapse ------------------------------------------------------------
   The root carries .oe-collapse-tablet or .oe-collapse-mobile, so the editor
   choice decides which breakpoint moves the nav into the drawer.
   ------------------------------------------------------------------------ */

@media (max-width: 1024px) {
	.oe-collapse-tablet .oe-site-header__nav,
	.oe-collapse-tablet .oe-site-header__cta {
		display: none;
	}

	.oe-collapse-tablet .oe-site-header__burger {
		display: inline-flex;
	}

	.oe-collapse-tablet .oe-site-header__brand,
	.oe-collapse-tablet .oe-site-header__actions {
		flex: 0 0 auto;
	}

	.oe-collapse-tablet .oe-site-header__inner {
		justify-content: space-between;
	}
}

@media (min-width: 1025px) {
	.oe-collapse-tablet .oe-site-header__drawer {
		display: none;
	}
}

@media (max-width: 767px) {
	.oe-site-header__bar {
		--oe-header-height: 65px;
	}

	.oe-collapse-mobile .oe-site-header__nav,
	.oe-collapse-mobile .oe-site-header__cta {
		display: none;
	}

	.oe-collapse-mobile .oe-site-header__burger {
		display: inline-flex;
	}

	.oe-collapse-mobile .oe-site-header__brand,
	.oe-collapse-mobile .oe-site-header__actions {
		flex: 0 0 auto;
	}

	.oe-site-header__actions {
		gap: 18px;
	}

	/* Search moves inside the drawer on a phone, so the bar keeps the cart
	   icon and the menu button only (Figma 471:3838). */
	.oe-site-header__icon[data-oe-search-toggle] {
		display: none;
	}

	/* Figma draws the menu button as a 64x48 neutral box, and keeps the same
	   glyph while the drawer is open rather than morphing to a cross. */
	.oe-site-header__burger {
		width: 64px;
		height: 48px;
		border-radius: var(--oe-radius-md);
		background-color: var(--oe-color-neutral-100);
		box-shadow: inset 0 0 0 1px var(--oe-color-neutral-300);
	}

	.oe-site-header__drawer {
		padding-inline: var(--oe-space-md);
	}
}

@media (min-width: 768px) {
	.oe-collapse-mobile .oe-site-header__drawer {
		display: none;
	}
}

/* ==========================================================================
   Cart drawer (Figma 472:9231 desktop, 472:10858 mobile)
   A sheet that drops under the header over a scrim, opened by the cart icon.
   Hidden until JavaScript reveals it, so the icon's href stays the no-JS path.
   Desktop splits 1160/480 into items and a payment summary; mobile stacks the
   two and runs full-bleed.
   ========================================================================== */

.oe-mini[hidden] { display: none; }

.oe-mini {
	/* The bar stack the sheet hangs from on a phone: topbar + header. */
	--oe-mini-top: 107px;
	/* Equal air above and below the sheet on a desktop. */
	--oe-mini-gap: clamp(24px, 4vh, 56px);

	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	justify-content: center;
	/*
	 * Centred, not hung from the header. Pinning it 145 below the top gave the
	 * sheet the whole viewport to grow into from there, so a full cart ran off
	 * the bottom of the screen while a deep band of scrim sat unused above it.
	 * Centring pairs with the panel's `max-height: 100%`, which is now 100% of
	 * the padded box — the sheet cannot outgrow the screen.
	 */
	align-items: center;
	padding-block: var(--oe-mini-gap);
}

.oe-mini__scrim {
	position: absolute;
	inset: 0;
	/* Figma 472:11005: 40% black with a 10px blur behind it, not a flat 50%. */
	background-color: rgba(0, 0, 0, 0.4);
	backdrop-filter: blur(10px);
	opacity: 0;
	transition: opacity 240ms var(--oe-ease, ease);
}

.oe-mini.is-open .oe-mini__scrim { opacity: 1; }

.oe-mini__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	width: min(var(--oe-container), calc(100% - 2 * var(--oe-gutter)));
	/* Written against the viewport rather than as a plain 100%: the percentage
	   resolves against this flex parent's content box, which is already the
	   screen less its padding, so the two agree today — but only by accident of
	   where the gap is applied. This says outright that the sheet is the screen
	   less the air above and below it. */
	max-height: calc(100dvh - 2 * var(--oe-mini-gap));
	background-color: var(--oe-color-white);
	border-radius: var(--oe-radius-2xl);
	overflow: hidden;
	transform: translateY(-16px);
	opacity: 0;
	transition:
		transform 280ms var(--oe-ease, ease),
		opacity 200ms var(--oe-ease, ease);
}

.oe-mini.is-open .oe-mini__panel {
	transform: none;
	opacity: 1;
}

/* -- Two columns --------------------------------------------------------- */

.oe-mini__body {
	display: grid;
	grid-template-columns: 1160fr 480fr;
	grid-template-rows: auto 1fr;
	min-height: 0;
	/* The scroll belongs to the list of plates, not to the sheet. Scrolling the
	   whole body ran a scrollbar down the summary as well and carried the
	   totals off the top of the panel — in the design (Figma 472:9498) that
	   column is `fill` height and stays where it is. */
	overflow: hidden;
}

.oe-mini__main {
	grid-column: 1;
	grid-row: 1 / -1;
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-md);
	/*
	 * 44 on the frame down to the 24 the phone used. The tablet band is what
	 * this is really for: between 768 and 1024 the sheet is about 744 wide and
	 * this column gets roughly 527 of it, so a flat 88px of padding was taking
	 * a sixth of the row before the thumbnail even started.
	 */
	padding: clamp(24px, 1.73vw + 10.7px, 44px);
	min-height: 0;
	overflow-y: auto;
}

/*
 * The total and its buttons are pinned to the bottom by the foot's own auto
 * margin rather than by `justify-content: space-between` on this column.
 *
 * With the two children it used to have, the two were the same thing. Now that
 * the documents notice sits here too, space-between would have spread three
 * blocks evenly and pushed the notice away from the summary it introduces —
 * and the empty band it was added to fill would simply have moved.
 */
.oe-mini__aside {
	grid-column: 2;
	grid-row: 1 / -1;
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-xl);
	padding: clamp(24px, 1.73vw + 10.7px, 44px);
	background-color: var(--oe-color-neutral-100);
}

.oe-mini__empty {
	grid-column: 1 / -1;
}

/* The close button floats over the sheet's top-right corner. */
.oe-mini__close {
	position: absolute;
	inset-block-start: 0;
	inset-inline-end: 0;
	z-index: 2;
	width: 72px;
	height: 72px;
}

.oe-mini__title {
	margin: 0;
	font-family: var(--oe-font-title);
	font-size: var(--oe-h4-size);
	font-weight: 600;
	line-height: 35px;
	color: var(--oe-color-ink-strong);
}

.oe-mini__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--oe-color-ink);
}

.oe-mini__close svg { width: 24px; height: 24px; }

.oe-mini__empty {
	margin: 0;
	font-family: var(--oe-font-body);
	font-size: 16px;
	line-height: 25.6px;
	color: rgba(26, 26, 26, 0.7);
}

.oe-mini__lines {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.oe-mini__line {
	display: grid;
	grid-template-columns: 140px minmax(0, 1fr);
	gap: var(--oe-space-lg);
	padding: var(--oe-space-md);
	border: 1px solid var(--oe-color-tile-border);
	border-radius: var(--oe-radius-xl);
	background-color: var(--oe-color-neutral-100);
}

.oe-mini__thumb {
	width: clamp(100px, 3.47vw + 73.4px, 140px);
	height: clamp(100px, 3.47vw + 73.4px, 140px);
	overflow: hidden;
	border-radius: 8px;
	background-color: #f3f3f3;
}

.oe-mini__thumb img { width: 100%; height: 100%; object-fit: cover; }

/*
 * Figma 472:9447: name, the options table, a rule, then a footer of two equal
 * stacks — total and quantity — with the bin sitting beside the stepper.
 */
.oe-mini__line-body {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--oe-space-sm);
	min-width: 0;
}

.oe-mini__name { grid-area: 1 / 1 / 2 / 3; }
.oe-mini__specs { grid-area: 2 / 1 / 3 / 3; }

/* The rule the design draws between the table and the footer. */
.oe-mini__line-body::after {
	content: "";
	grid-area: 3 / 1 / 4 / 3;
	border-block-start: 1px solid var(--oe-color-neutral-300);
}

/* Footer placement: the total stack on the left, the quantity stack facing it.
   Declared after the typography rules so neither one clobbers the other. */
.oe-mini__line-body > .oe-mini__total-row {
	grid-area: 4 / 1 / 6 / 2;
	align-self: end;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--oe-space-2xs);
}

.oe-mini__line-body > .oe-mini__label { grid-area: 4 / 2 / 5 / 3; }
.oe-mini__line-body > .oe-mini__row { grid-area: 5 / 2 / 6 / 3; }

.oe-mini__label {
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-sm-size);
	font-weight: 400;
	line-height: 22px;
	color: rgba(26, 26, 26, 0.6);
}

.oe-mini__name {
	margin: 0;
	font-family: var(--oe-font-title);
	font-size: var(--oe-h5-size);
	font-weight: 600;
	line-height: 26px;
	color: var(--oe-color-ink-strong);
}

/* Figma 472:9447: a bordered label/value table, 18/400 against 18/700, split
   down the middle with 16px of gutter inside each cell. */
.oe-mini__specs {
	margin: 0;
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-xs);
	background-color: var(--oe-color-white);
	overflow: hidden;
}

.oe-mini__spec {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--oe-space-sm);
	padding: 10px var(--oe-space-sm);
	border-block-start: 1px solid var(--oe-color-neutral-300);
}

.oe-mini__spec:first-child {
	border-block-start: 0;
}

.oe-mini__spec dt,
.oe-mini__spec dd {
	margin: 0;
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-lg-size);
	line-height: 22px;
	color: var(--oe-color-ink-strong);
}

.oe-mini__spec dd {
	font-weight: 700;
}

.oe-mini__label {
	font-family: var(--oe-font-body);
	font-size: 14px;
	font-weight: 400;
	line-height: 20px;
	color: rgba(26, 26, 26, 0.6);
}

.oe-mini__row {
	display: flex;
	align-items: center;
	gap: 20px;
}

.oe-mini__qty {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex: 1 1 auto;
	min-width: 0;
	height: 48px;
	padding: 12px var(--oe-space-sm);
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-md);
	background-color: var(--oe-color-white);
}

.oe-mini__qty-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 24px;
	height: 24px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--oe-color-ink-strong);
	cursor: pointer;
}

.oe-mini__qty-input {
	flex: 1 1 auto;
	min-width: 0;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: #0a0a0a;
	font-family: var(--oe-font-title);
	font-size: var(--oe-body-lg-size);
	font-weight: 500;
	line-height: 20px;
	text-align: center;
	-moz-appearance: textfield;
}

.oe-mini__qty-input::-webkit-outer-spin-button,
.oe-mini__qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* The stepper's frame is the control; the theme's own input chrome inside it
   reads as a second box, so it is scoped away here. */
.oe-mini__qty .oe-mini__qty-input,
.oe-mini__qty .oe-mini__qty-input:focus,
.oe-mini__qty .oe-mini__qty-input:focus-visible {
	box-shadow: none;
	border: 0;
	border-radius: 0;
	background: none;
	outline: none;
}

.oe-mini__qty:focus-within {
	border-color: var(--oe-color-ink-strong);
}

/* Both labels sit on the design's 22px leading, not the theme's. */
.oe-mini__label { display: block; }

.oe-mini__remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 48px;
	height: 48px;
	padding: var(--oe-space-2xs);
	border: 1px solid var(--oe-color-neutral-300);
	border-radius: var(--oe-radius-md);
	background-color: var(--oe-color-white);
	--oe-btn-surface: var(--oe-color-white);
	color: var(--oe-color-black);
	cursor: pointer;
	transition: border-color 200ms var(--oe-ease, ease), color 200ms var(--oe-ease, ease);
}

.oe-mini__remove:hover { border-color: var(--oe-color-brand); color: var(--oe-color-brand); }
.oe-mini__remove svg { width: 32px; height: 32px; }
.oe-mini__qty-btn svg { width: 24px; height: 24px; }
.oe-mini__view svg,
.oe-mini__checkout svg { width: 24px; height: 24px; }

.oe-mini__total-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
}

.oe-mini__price {
	font-family: var(--oe-font-title);
	font-size: 40px;
	font-weight: 600;
	line-height: 48px;
	color: var(--oe-color-black);
	font-variant-numeric: tabular-nums;
}

.oe-mini__summary {
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-sm);
}

.oe-mini__summary-title {
	margin: 0;
	font-family: var(--oe-font-title);
	font-size: var(--oe-h4-size);
	font-weight: 600;
	line-height: 35px;
	color: var(--oe-color-ink-strong);
}

.oe-mini__srow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--oe-space-sm);
	font-family: var(--oe-font-body);
	font-size: 20px;
	font-weight: 400;
	line-height: 32px;
	color: rgba(26, 26, 26, 0.6);
}

/* Figma sets the figure a size up from its label, and darker. */
.oe-mini__srow > span:last-child {
	font-size: 22px;
	font-weight: 500;
	line-height: 35px;
	color: rgba(26, 26, 26, 0.9);
	font-variant-numeric: tabular-nums;
}

.oe-mini__note {
	margin: 0;
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size);
	font-weight: 400;
	line-height: 19px;
	color: rgba(26, 26, 26, 0.6);
}

.oe-mini__foot {
	display: flex;
	flex-direction: column;
	gap: var(--oe-space-sm);
	margin-block-start: auto;
	padding-block-start: var(--oe-space-sm);
	border-block-start: 1px solid var(--oe-color-neutral-300);
}

.oe-mini__srow--total {
	font-family: var(--oe-font-title);
	font-size: var(--oe-h5-size);
	font-weight: 600;
	line-height: 26px;
	color: var(--oe-color-black);
}

.oe-mini__srow--total > span:last-child {
	font-family: var(--oe-font-title);
	font-size: var(--oe-h5-size);
	font-weight: 600;
	line-height: 26px;
	color: rgba(26, 26, 26, 0.9);
}

/* Empty sheet: the same panel, centred, with a way back to the builder. */
.oe-mini__empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--oe-space-sm);
	min-height: 320px;
	padding: var(--oe-space-4xl) var(--oe-space-md);
	text-align: center;
}

.oe-mini__empty-mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 72px;
	height: 72px;
	border-radius: var(--oe-radius-pill);
	background-color: var(--oe-color-neutral-100);
	color: var(--oe-color-ink-strong);
}

.oe-mini__empty-mark svg {
	width: 32px;
	height: 32px;
}

.oe-mini__empty-text {
	margin: 0;
	max-width: 34ch;
	font-family: var(--oe-font-body);
	font-size: var(--oe-body-size);
	line-height: 26px;
	color: rgba(26, 26, 26, 0.6);
}

.oe-mini__empty .oe-mini__checkout {
	margin-block-start: var(--oe-space-2xs);
	padding-inline: var(--oe-space-lg);
}

.oe-mini__checkout,
.oe-mini__view {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* Figma 472:9514/9515: 6px between the icon and the word, 16/24 padding. */
	gap: 6px;
	height: 56px;
	padding-inline: 24px;
	border-radius: 8px;
	font-family: var(--oe-font-body);
	font-size: 16px;
	font-weight: 700;
	line-height: 24px;
	letter-spacing: -0.16px;
	text-align: center;
	text-decoration: none;
	transition: background-color 200ms var(--oe-ease, ease);
	text-transform: uppercase;
}

.oe-mini__checkout {
	background-color: var(--oe-color-brand);
	--oe-btn-surface: var(--oe-color-brand);
	color: var(--oe-color-black);
	text-transform: uppercase;
}

.oe-mini__checkout:hover { background-color: var(--oe-color-brand-dark); }

.oe-mini__view {
	border: 1px solid var(--oe-color-black);
	background-color: var(--oe-color-white);
	--oe-btn-surface: var(--oe-color-white);
	color: var(--oe-color-black);
}

.oe-mini__view:hover { background-color: #f5f5f5; }
.oe-mini__view svg { width: 20px; height: 20px; }

.oe-mini.is-busy .oe-mini__body { opacity: 0.6; pointer-events: none; }

/*
 * Shown when a quantity change could not be saved. The stepper puts its number
 * back at the same moment, and a figure that silently returns to what it was
 * reads as a dead button — this says which of the two happened.
 *
 * Inside the panel, which is `overflow: hidden`, so it is clipped to the sheet
 * rather than escaping over the page behind it.
 */
.oe-mini__error {
	position: absolute;
	z-index: 2;
	inset-block-end: 0;
	inset-inline: 0;
	margin: 0;
	padding: 12px var(--oe-gutter, 20px);
	background-color: var(--oe-color-ink-strong, #1a1a1a);
	color: var(--oe-color-white, #fff);
	font-size: var(--oe-body-sm-size, 14px);
	line-height: 1.4;
	text-align: center;
	animation: oe-mini-error-in 200ms var(--oe-ease, ease);
}

@keyframes oe-mini-error-in {
	from { transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
	.oe-mini__error { animation: none; }
}

@media (max-width: 767px) {
	/* Figma 472:10858 draws this as a bottom sheet, not the side drawer the
	   desktop uses: it rises from the bottom edge, keeps a 24px radius on the
	   top two corners only, and leaves the page visible above it. */
	.oe-mini {
		align-items: flex-end;
		/* A bottom sheet: flush to the bottom edge, with the gap above it
		   capping how tall it can grow. */
		padding-block: var(--oe-mini-top) 0;
	}

	.oe-mini__panel {
		width: 100%;
		max-height: 100%;
		border-radius: var(--oe-radius-2xl) var(--oe-radius-2xl) 0 0;
		transform: translateY(-12px);
	}

	.oe-mini__body {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto;
		/*
		 * Stacked, so the whole sheet scrolls — the summary sits under the
		 * plates here rather than beside them, and there is nothing to hold
		 * still. Scrolling the list on its own, which is right on a desktop,
		 * squeezed it into whatever height was left after the summary and cut
		 * the card off mid-row.
		 */
		overflow-y: auto;
	}

	/* Stacking only — the padding clamp already reads 24 here. */
	.oe-mini__main,
	.oe-mini__aside {
		grid-column: 1;
		grid-row: auto;
	}

	.oe-mini__main {
		min-height: auto;
		overflow: visible;
	}

	.oe-mini__title { font-size: var(--oe-h5-size); line-height: 26px; }
	.oe-mini__close { width: 50px; height: 50px; inset-block-start: 12px; inset-inline-end: 10px; }

	/* The phone card shows the thumbnail beside the name, then the quantity
	   block and the price; the options table is desktop-only.
	   Figma 472:11009: 16 of padding, 8 between the thumbnail and the name,
	   16 down the card. */
	.oe-mini__line {
		grid-template-columns: 100px minmax(0, 1fr);
		align-items: center;
		gap: 16px 8px;
		padding: 16px;
	}

	/* Figma 472:11014 sets the name a size down from the desktop card's. */
	.oe-mini__name {
		font-size: 20px;
		font-weight: 500;
		line-height: 1.1;
	}

	/* Figma 472:11015 gives the price row 20 of its own, not the card's 16. */
	.oe-mini__line-body > .oe-mini__total-row { margin-block-start: 4px; }
	.oe-mini__line-body { display: contents; }
	.oe-mini__specs { display: none; }

	/*
	 * `display: contents` promotes these into the card's own grid, so the
	 * desktop row placements have to be handed back. Matched on
	 * `.oe-mini__line-body >`, not `.oe-mini__line >`: `display: contents`
	 * removes the box, not the element, so the DOM parent — and therefore what
	 * the child combinator sees — is still the body. Written the other way
	 * these never matched, and the phone kept the desktop's two-column footer,
	 * which is why the price and the stepper sat side by side.
	 */
	.oe-mini__name {
		grid-area: auto;
		grid-column: 2;
	}

	/* Figma 472:11009 draws the phone card as one column with no rule in it:
	   name, then the quantity row, then the price. The rule belongs to the
	   desktop card, where it separates the options table from the footer. */
	.oe-mini__line-body::after { display: none; }

	.oe-mini__line-body > .oe-mini__label,
	.oe-mini__line-body > .oe-mini__row {
		grid-area: auto;
		grid-column: 1 / -1;
	}

	.oe-mini__line-body > .oe-mini__total-row {
		grid-area: auto;
		grid-column: 1 / -1;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: var(--oe-space-sm);
	}

	.oe-mini__price { font-size: var(--oe-h5-size); line-height: 26px; }
}

@media (prefers-reduced-motion: reduce) {
	.oe-mini__scrim,
	.oe-mini__panel,
	.oe-mini__checkout,
	.oe-mini__view,
	.oe-mini__remove { transition: none; }

	.oe-mini__panel { transform: none; }
}
