/**
 * Haat — layout layer.
 *
 * Containers, the page grid, and the header/footer chrome.
 *
 * @package Haat
 */

/* ── Container ───────────────────────────────────────────────────────────
 * Every contained element in the theme uses this one class, and its measure
 * comes from a single token, so Customizer > Layout > Page width moves the
 * whole store at once. */
.haat-container {
	width: 100%;
	max-width: var( --haat-page-width );
	margin-inline: auto;
	padding-inline: var( --haat-gutter );
}

.haat-site {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.haat-main {
	flex: 1 0 auto;
	padding-block: 2rem 4rem;
}

/* ── Page grid ───────────────────────────────────────────────────────────*/
.haat-layout {
	display: grid;
	gap: 2rem;
	align-items: start;
}

.haat-layout--with-sidebar {
	grid-template-columns: minmax( 0, 1fr );
}

@media ( min-width: 960px ) {
	/* The MAIN column comes first in the source order — the templates render
	 * content then call get_sidebar() — so both tracks have to be placed
	 * explicitly. Without that, main lands in track one and inherits the 17rem
	 * sidebar width, which squeezes a 24-product grid into a narrow strip while
	 * the filter widgets spread across the rest of the page. */
	.haat-layout--with-sidebar {
		grid-template-columns: 17rem minmax( 0, 1fr );
	}

	.haat-layout--with-sidebar .haat-layout__main {
		grid-column: 2;
		grid-row: 1;
	}

	.haat-layout--with-sidebar .haat-layout__sidebar {
		grid-column: 1;
		grid-row: 1;
	}

	/* Moving the sidebar to the right is a track swap, not a DOM reorder, so
	 * filter widgets still reach a screen reader before the product grid. */
	.haat-layout--sidebar-right {
		grid-template-columns: minmax( 0, 1fr ) 17rem;
	}

	.haat-layout--sidebar-right .haat-layout__main {
		grid-column: 1;
	}

	.haat-layout--sidebar-right .haat-layout__sidebar {
		grid-column: 2;
	}
}

.haat-layout__main {
	min-width: 0;
}

.haat-layout__sidebar {
	min-width: 0;
}

@media ( max-width: 959px ) {
	/* Below the breakpoint the shop filters live in a drawer instead — see
	 * haat_wc_filter_drawer(). Hiding the column rather than stacking it keeps
	 * a phone user from scrolling past a full filter list to reach the grid. */
	.haat-shop-has-sidebar .haat-layout__sidebar {
		display: none;
	}
}

.haat-layout--full {
	grid-template-columns: minmax( 0, 1fr );
}

/* ── Top bar ─────────────────────────────────────────────────────────────*/
.haat-topbar {
	background: var( --haat-secondary );
	color: var( --haat-secondary-foreground );
	font-size: var( --haat-text-sm );
	/* A hairline mixed from the bar's OWN text colour rather than from
	 * --haat-border. The border token is tuned for the page, so on the dark
	 * chrome it is either invisible (light scheme) or indistinguishable (dark).
	 * Deriving the edge from the bar's foreground means it is always a faint
	 * lightening of whatever the bar happens to be, in every scheme and under
	 * any merchant palette. Without it the announcement bar and the header bar
	 * below it merge into one shapeless band in dark mode. */
	border-bottom: 1px solid color-mix( in oklab, var( --haat-secondary-foreground ) 14%, transparent );
}

.haat-topbar__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	min-height: 2.5rem;
	flex-wrap: wrap;
}

.haat-topbar__announcement {
	margin: 0;
}

.haat-topbar__announcement a,
.haat-topbar__menu a {
	color: inherit;
	opacity: 0.9;
}

.haat-topbar__announcement a:hover,
.haat-topbar__menu a:hover {
	opacity: 1;
}

.haat-topbar__menu {
	display: flex;
	gap: 1.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

@media ( max-width: 767px ) {
	.haat-topbar__nav {
		display: none;
	}

	.haat-topbar__inner {
		justify-content: center;
		text-align: center;
	}
}

/* ── Header bar ──────────────────────────────────────────────────────────*/
.haat-header__bar {
	background: var( --haat-surface );
	border-bottom: 1px solid var( --haat-border );
}

.haat-has-sticky-header .haat-header__bar[data-haat-sticky="true"] {
	position: sticky;
	top: 0;
	z-index: var( --haat-z-sticky );
}

/* Added by assets/js/navigation.js once the bar has actually left its resting
 * position, so the shadow appears only when there is content behind it. */
.haat-header__bar.is-stuck {
	box-shadow: var( --haat-shadow-soft );
}

.haat-header__bar-inner {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	min-height: var( --haat-header-height );
}

.haat-header__menu-toggle {
	display: none;
	padding: 0.5rem;
	background: none;
	border: 0;
	color: inherit;
}

.haat-header__menu-icon,
.haat-header__menu-icon::before,
.haat-header__menu-icon::after {
	display: block;
	width: 20px;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	content: "";
}

.haat-header__menu-icon::before { transform: translateY( -6px ); }
.haat-header__menu-icon::after { transform: translateY( 4px ); }

.haat-branding {
	display: flex;
	flex-direction: column;
	justify-content: center;
	flex-shrink: 0;
}

.haat-branding__title {
	margin: 0;
	font-size: var( --haat-text-xl );
	font-weight: var( --haat-weight-black );
	letter-spacing: -0.02em;
}

.haat-branding__title a {
	color: var( --haat-foreground );
}

.haat-branding__tagline {
	margin: 0;
	font-size: var( --haat-text-xs );
	color: var( --haat-muted-foreground );
}

/* ── The logo, in every position it appears ──────────────────────────────
 * align-self matters more than it looks. .haat-branding is a COLUMN flex
 * container, so its default align-items:stretch pulls a replaced element out to
 * the container's full width — and max-height then clamps the height
 * independently, so the image is squashed rather than scaled. In the header the
 * container happens to be shrink-to-fit and the result looked correct; in the
 * footer, where the brand column is 381px wide, the same markup rendered the
 * logo at 381x48 against a natural 506x144. It looked stretched because it was.
 *
 * A fixed height with width:auto (rather than max-height) plus object-fit is
 * belt and braces: the ratio is preserved even if some future container has
 * another opinion about the width. */
.haat-branding .custom-logo,
/*
 * `.haat-branding` is repeated on EVERY selector here, not just the first.
 *
 * A comma-separated list does not share the prefix: written as
 * `.haat-branding .custom-logo, .haat-branding__logo-inverse` the header logo
 * scored 0-2-0 and the other two only 0-1-0 -- which lost to WooCommerce's own
 * `.woocommerce img { height: auto }` at 0-1-1. So the footer logo rendered at
 * its natural 338x96 on every shop, product and cart page while the header was
 * correct, and the front page looked fine because WooCommerce's stylesheet does
 * not apply there. That is also why the existing footer-logo test passed: it
 * only ever looked at the front page.
 */
.haat-branding .haat-branding__logo-dark,
.haat-branding .haat-branding__logo-inverse {
	align-self: flex-start;
	height: var( --haat-logo-height );
	width: auto;
	max-width: 100%;
	object-fit: contain;
}

/* Both logos are in the DOM; CSS picks one. The dark variant is hidden by
 * default so a store that has not supplied one shows nothing extra.
 *
 * `.haat-branding` is on this selector for the same reason as the sizing rule
 * above: bare, it is 0-1-0 and loses to any `<ancestor> img` rule at 0-1-1 --
 * `.haat-entry__content img` here. Wherever the branding is printed inside page
 * content (the account screen prints it above the sign-in card) BOTH logos
 * showed, the light-ink one rendering as a ghost under the real one. */
.haat-branding .haat-branding__logo-dark {
	display: none;
}

@media ( prefers-color-scheme: dark ) {
	:root:not( [data-haat-scheme="light"] ) .haat-branding .custom-logo {
		display: none;
	}

	:root:not( [data-haat-scheme="light"] ) .haat-branding__logo-dark {
		display: block;
	}
}

:root[data-haat-scheme="dark"] .haat-branding .custom-logo {
	display: none;
}

:root[data-haat-scheme="dark"] .haat-branding__logo-dark {
	display: block;
}

/* ── Header search ───────────────────────────────────────────────────────
 * One pill, one height, one type size. Three separate controls sit inside it —
 * a select, a text input and a submit — and each arrives with its own browser
 * defaults, so most of the rules below are about making the seams disappear.
 */
.haat-header__search {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 44rem;
}

.haat-search {
	display: flex;
	align-items: stretch;
	height: 2.875rem;
	background: var( --haat-surface );
	border: 1px solid var( --haat-border );
	border-radius: var( --haat-radius-full );
	overflow: hidden;
	transition: border-color var( --haat-duration-fast ) var( --haat-ease-out ),
		box-shadow var( --haat-duration-fast ) var( --haat-ease-out );
}

/* Neutral at rest, accent on focus. A permanently accent-coloured 2px pill
 * competes with the buttons for attention and makes the header look like it is
 * shouting before anyone has typed anything. */
.haat-search:focus-within {
	border-color: var( --haat-primary );
	box-shadow: 0 0 0 3px color-mix( in oklab, var( --haat-primary ) 16%, transparent );
}

/* ── Category scope ──────────────────────────────────────────────────────*/
.haat-search__scope-wrap {
	position: relative;
	display: flex;
	align-items: center;
	flex-shrink: 0;
	max-width: 12rem;
}

/* The divider is an inset pseudo-element rather than a border on the select,
 * so it stops short of the pill's rounded ends instead of running into them. */
.haat-search__scope-wrap::before {
	content: "";
	position: absolute;
	top: 22%;
	bottom: 22%;
	right: 0;
	width: 1px;
	background: var( --haat-border );
}

.haat-search__scope-wrap::after {
	content: "";
	position: absolute;
	right: 0.85rem;
	width: 0.7rem;
	height: 0.7rem;
	background: var( --haat-muted-foreground );
	pointer-events: none;
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E" );
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

/*
 * The rules here are more specific than they look because base.css styles form
 * controls by attribute — input[type="search"] scores 0-1-1 and beat the plain
 * .haat-search__field class at 0-1-0. The input therefore kept its own 1px
 * border and 10px radius, drawing a second rounded rectangle INSIDE the pill.
 * Matching the attribute selector is what actually removes it.
 */
.haat-search select.haat-search__scope,
.haat-search input[type="search"].haat-search__field {
	height: 100%;
	background: transparent;
	border: 0;
	border-radius: 0;
	font-size: var( --haat-text-sm );
	line-height: 1;
	box-shadow: none;
	outline: none;
}

.haat-search select.haat-search__scope {
	width: 100%;
	padding: 0 2.1rem 0 1.15rem;
	color: var( --haat-muted-foreground );
	/* The native arrow is drawn by the platform and matches nothing else in the
	 * header — different size, different colour, different metal on every OS. */
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	cursor: pointer;
	text-overflow: ellipsis;
}

.haat-search input[type="search"].haat-search__field {
	flex: 1 1 auto;
	min-width: 0;
	padding-inline: 1.1rem;
	color: var( --haat-foreground );
	/* Safari draws its own clear button and rounds the field; both fight the
	 * pill this control sits inside. */
	-webkit-appearance: none;
	appearance: none;
}

.haat-search input[type="search"].haat-search__field::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.haat-search__field::placeholder {
	color: var( --haat-muted-foreground );
	opacity: 1;
}

/* ── Submit ──────────────────────────────────────────────────────────────*/
.haat-search__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	flex-shrink: 0;
	height: 100%;
	padding-inline: 1.4rem;
	background: var( --haat-primary );
	color: var( --haat-primary-foreground );
	border: 0;
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-semibold );
	line-height: 1;
	transition: background var( --haat-duration-fast ) var( --haat-ease-out );
}

.haat-search__submit:hover {
	background: var( --haat-flame-600 );
}

/* A real magnifier, as a mask over currentColor — the same technique as every
 * other icon in the theme. The previous one was a bordered circle with a
 * rotated pseudo-element for the handle, which never quite met the lens and
 * looked hand-drawn next to the masked icons beside it. */
.haat-search__icon {
	width: 1.05rem;
	height: 1.05rem;
	flex-shrink: 0;
	background: currentColor;
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.6-3.6'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.6-3.6'/%3E%3C/svg%3E" );
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
}

@media ( max-width: 1023px ) {
	/* The wrapper, not the select — hiding only the select would leave its
	 * divider and chevron floating in an otherwise empty slot. */
	.haat-search__scope-wrap,
	.haat-search__submit-text {
		display: none;
	}
}

@media ( max-width: 767px ) {
	.haat-header__menu-toggle {
		display: block;
	}

	.haat-header__bar-inner {
		flex-wrap: wrap;
		padding-block: 0.75rem;
		gap: 0.75rem;
	}

	/* The search field drops to its own full-width row rather than competing
	 * with the logo and the cart for a phone's horizontal space. */
	.haat-header__search {
		order: 5;
		flex-basis: 100%;
	}
}

/* ── Header actions ──────────────────────────────────────────────────────*/
.haat-header__actions {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex-shrink: 0;
	margin-left: auto;
}

.haat-action {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	padding: 0.5rem 0.65rem;
	border-radius: var( --haat-radius-md );
	color: var( --haat-foreground );
	transition: background var( --haat-duration-fast ) var( --haat-ease-out );
}

.haat-action:hover {
	background: var( --haat-muted );
	text-decoration: none;
}

.haat-action__text {
	display: flex;
	flex-direction: column;
	line-height: 1.25;
}

.haat-action__label {
	font-size: var( --haat-text-xs );
	color: var( --haat-muted-foreground );
}

.haat-action__value {
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-semibold );
	white-space: nowrap;
}

.haat-action__icon {
	position: relative;
	width: 1.35rem;
	height: 1.35rem;
	flex-shrink: 0;
	background: currentColor;
	/* Icons are CSS masks over a single currentColor block rather than inline
	 * SVG files. That way an icon inherits its colour from the token system,
	 * costs no extra request, and cannot go stale against a re-skin. */
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.haat-action__icon--user {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E" );
}

.haat-action__icon--heart {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1.1a5.5 5.5 0 0 0-7.8 7.8l1.1 1L12 21l7.7-7.6 1.1-1a5.5 5.5 0 0 0 0-7.8z'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1.1a5.5 5.5 0 0 0-7.8 7.8l1.1 1L12 21l7.7-7.6 1.1-1a5.5 5.5 0 0 0 0-7.8z'/%3E%3C/svg%3E" );
}

.haat-action__icon--compare {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 3v18M17 3v18M3 8h8M13 16h8'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 3v18M17 3v18M3 8h8M13 16h8'/%3E%3C/svg%3E" );
}

.haat-action__icon--cart {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'/%3E%3Ccircle cx='20' cy='21' r='1'/%3E%3Cpath d='M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h9.7a2 2 0 0 0 2-1.6L23 6H6'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'/%3E%3Ccircle cx='20' cy='21' r='1'/%3E%3Cpath d='M1 1h4l2.7 13.4a2 2 0 0 0 2 1.6h9.7a2 2 0 0 0 2-1.6L23 6H6'/%3E%3C/svg%3E" );
}

.haat-action__count {
	position: absolute;
	top: -0.4rem;
	right: -0.5rem;
	min-width: 1.15rem;
	padding: 0 0.25rem;
	background: var( --haat-primary );
	color: var( --haat-primary-foreground );
	border-radius: var( --haat-radius-full );
	font-size: 0.65rem;
	font-weight: var( --haat-weight-bold );
	line-height: 1.15rem;
	text-align: center;
	/* The badge sits on a masked element, so it would be masked away with it.
	 * Isolating it back out is cheaper than moving it to a sibling. */
	-webkit-mask: none;
	mask: none;
}

.haat-action__count.is-empty {
	display: none;
}

@media ( max-width: 1023px ) {
	.haat-action__text {
		display: none;
	}

	.haat-action--compare,
	.haat-action--wishlist {
		display: none;
	}
}

/* ── Category bar ────────────────────────────────────────────────────────*/
.haat-catbar {
	position: relative;
	background: var( --haat-surface );
	border-bottom: 1px solid var( --haat-border );
}

.haat-catbar__inner {
	display: flex;
	align-items: stretch;
	gap: 1.5rem;
	min-height: 3rem;
}

.haat-catbar__all {
	position: relative;
	display: flex;
	align-items: center;
}

.haat-catbar__all-trigger {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	height: 100%;
	padding-inline: 1.1rem;
	background: var( --haat-primary );
	color: var( --haat-primary-foreground );
	border: 0;
	font-weight: var( --haat-weight-semibold );
	font-size: var( --haat-text-sm );
}

.haat-catbar__all-icon,
.haat-catbar__all-icon::before,
.haat-catbar__all-icon::after {
	display: block;
	width: 16px;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	content: "";
}

.haat-catbar__all-icon::before { transform: translateY( -5px ); }
.haat-catbar__all-icon::after { transform: translateY( 3px ); }

.haat-catbar__panel {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: var( --haat-z-dropdown );
	min-width: 18rem;
	padding: 0.5rem 0;
	background: var( --haat-surface );
	border: 1px solid var( --haat-border );
	border-radius: 0 0 var( --haat-radius-lg ) var( --haat-radius-lg );
	box-shadow: var( --haat-shadow-pop );
	/* Clipped rather than display:none so the panel stays in the tab order and
	 * the open/close stays a pure CSS transition. `visibility` is what makes it
	 * genuinely non-interactive while closed. */
	visibility: hidden;
	opacity: 0;
	transform: translateY( -0.4rem );
	transition: opacity var( --haat-duration-fast ) var( --haat-ease-out ),
		transform var( --haat-duration-fast ) var( --haat-ease-out ),
		visibility 0s linear var( --haat-duration-fast );
}

.haat-catbar__all.is-open .haat-catbar__panel,
.haat-catbar__all:hover .haat-catbar__panel,
.haat-catbar__all:focus-within .haat-catbar__panel {
	visibility: visible;
	opacity: 1;
	transform: translateY( 0 );
	transition-delay: 0s;
}

.haat-catbar__list,
.haat-catbar__primary-list {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
}

.haat-catbar__list {
	flex-direction: column;
}

.haat-catbar__primary-list {
	align-items: stretch;
	gap: 0.25rem;
}

/* ── Nav overflow ────────────────────────────────────────────────────────*/
.haat-catbar__primary {
	display: flex;
	align-items: stretch;
	min-width: 0;
	flex: 1 1 auto;
}

.haat-catbar__primary-list {
	flex: 1 1 auto;
	min-width: 0;
	/*
	 * NO overflow here — this rule had `overflow: hidden` and it clipped every
	 * mega panel flat, because the panels are absolutely positioned out of this
	 * list. Same trap as the hero rail (see rule 24): overflow on one axis makes
	 * a scroll container, and a scroll container clips on both.
	 *
	 * It was there to stop items spilling during the measurement pass, which it
	 * turns out is not needed: reflow() appends, measures and moves within one
	 * synchronous function, so the browser never paints the intermediate state.
	 */
	flex-wrap: wrap;
}

/*
 * Wrapping is the no-JS fallback: without the script nothing is ever moved into
 * More, and a nowrap row would push items off the side of the page with no way
 * to reach them. A wrapped second line is ugly but usable.
 *
 * The script adds this class, and only then does the row commit to one line —
 * which is what makes the width measurement meaningful, because a wrapping row
 * reports every item as fitting.
 */
.haat-catbar__primary-list.is-measured {
	flex-wrap: nowrap;
}

.haat-catbar__more {
	position: relative;
	display: flex;
	align-items: center;
	flex-shrink: 0;
}

.haat-catbar__more[hidden] {
	display: none;
}

.haat-catbar__more-trigger {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-block: 0.4rem;
	padding: 0.4rem 0.9rem;
	background: transparent;
	border: 0;
	border-radius: var( --haat-radius-md );
	color: var( --haat-foreground );
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-medium );
	white-space: nowrap;
}

.haat-catbar__more-trigger:hover,
.haat-catbar__more.is-open .haat-catbar__more-trigger {
	background: var( --haat-flame-50 );
	color: var( --haat-flame-700 );
}

.haat-catbar__more.is-open .haat-mega__chevron {
	transform: rotate( 180deg );
}

.haat-catbar__more-list {
	position: absolute;
	top: calc( 100% + 0.5rem );
	right: 0;
	z-index: var( --haat-z-dropdown );
	min-width: 14rem;
	max-height: min( 70vh, 30rem );
	overflow-y: auto;
	margin: 0;
	padding: 0.5rem;
	background: var( --haat-surface );
	border: 1px solid var( --haat-border );
	border-radius: var( --haat-radius-lg );
	box-shadow: var( --haat-shadow-pop );
	list-style: none;
	visibility: hidden;
	opacity: 0;
	transition: opacity var( --haat-duration-fast ) var( --haat-ease-out ),
		visibility 0s linear var( --haat-duration-fast );
}

.haat-catbar__more.is-open .haat-catbar__more-list {
	visibility: visible;
	opacity: 1;
	transition-delay: 0s;
}

/* An item moved into More is a plain row. Its own flyout panel is suppressed —
 * a panel that flies out of a panel has nowhere to go on a narrow window,
 * which is the exact case that put the item here. Its children are listed
 * inline instead, so nothing becomes unreachable. */
.haat-catbar__more-list > .haat-mega__item {
	display: block;
}

.haat-catbar__more-list .haat-mega {
	position: static;
	width: auto;
	min-width: 0;
	max-width: none;
	max-height: none;
	padding: 0 0 0.35rem 0.75rem;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	visibility: visible;
	opacity: 1;
	overflow: visible;
}

.haat-catbar__more-list .haat-mega__columns {
	columns: 1;
}

.haat-catbar__more-list .haat-mega__item--column {
	margin-bottom: 0.5rem;
}

.haat-catbar__more-list .haat-mega__link {
	white-space: normal;
}

.haat-catbar__more-list > .haat-mega__item > .haat-mega__link {
	padding: 0.5rem 0.75rem;
	border-radius: var( --haat-radius-md );
	font-weight: var( --haat-weight-medium );
}

/* The trigger chevron is meaningless once the item is stacked open. */
.haat-catbar__more-list .haat-mega__chevron {
	display: none;
}

.haat-catbar__cta {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin-left: auto;
	padding-inline: 0.5rem;
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-semibold );
	color: var( --haat-flame-600 );
}

.haat-catbar__cta-dot {
	width: 0.5rem;
	height: 0.5rem;
	background: var( --haat-flame-500 );
	border-radius: 50%;
	animation: haat-pulse-soft 2.4s ease-in-out infinite;
}

@media ( max-width: 959px ) {
	.haat-catbar {
		display: none;
	}
}

/* ── Mega menu ───────────────────────────────────────────────────────────*/
.haat-mega__item {
	position: relative;
	list-style: none;
}

.haat-mega__link {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.6rem 1.1rem;
	color: var( --haat-foreground );
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-medium );
	white-space: nowrap;
}

.haat-catbar__primary-list > .haat-mega__item > .haat-mega__link {
	/* Inset from the bar rather than filling it. A hover that runs the full
	 * height of the row reads as a block of colour bolted to the chrome; a
	 * pill with air above and below reads as a control. */
	margin-block: 0.4rem;
	padding-block: 0.4rem;
	border-radius: var( --haat-radius-md );
}

.haat-mega__link:hover {
	background: var( --haat-flame-50 );
	color: var( --haat-flame-700 );
	text-decoration: none;
}

/* A drawn chevron rather than two rotated borders. The border trick is never
 * quite centred — the rotation pivots on the box corner, so it needs a nudge
 * that is only right at one size — and its stroke ends are mitred where every
 * other icon in the theme has round caps. */
.haat-mega__chevron {
	width: 0.62rem;
	height: 0.62rem;
	flex-shrink: 0;
	background: currentColor;
	opacity: 0.55;
	transition: transform var( --haat-duration-fast ) var( --haat-ease-out ),
		opacity var( --haat-duration-fast ) var( --haat-ease-out );
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E" );
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
}

.haat-mega__item--trigger:hover > .haat-mega__link .haat-mega__chevron,
.haat-mega__item--trigger:focus-within > .haat-mega__link .haat-mega__chevron {
	opacity: 1;
	transform: rotate( 180deg );
}

/* A top-level trigger in the vertical "All categories" panel points its
 * chevron sideways, because its panel opens to the right rather than below. */
.haat-catbar__list > .haat-mega__item > .haat-mega__link .haat-mega__chevron {
	margin-left: auto;
	transform: rotate( -90deg );
}

.haat-catbar__list > .haat-mega__item--trigger:hover > .haat-mega__link .haat-mega__chevron,
.haat-catbar__list > .haat-mega__item--trigger:focus-within > .haat-mega__link .haat-mega__chevron {
	transform: rotate( -90deg );
}

.haat-mega {
	position: absolute;
	top: 0;
	left: 100%;
	z-index: var( --haat-z-dropdown );
	/* Sized to its contents, within bounds.
	 *
	 * A fixed 34rem left a short brand list half empty; a fixed 22rem was too
	 * narrow for a six-group category tree to fit even TWO tracks once padding
	 * was subtracted, so the whole tree stacked into one tall column that ran
	 * off the bottom of the screen. max-content lets a wide tree spread and a
	 * short list stay compact, and the max-width stops it reaching the edge. */
	/* A definite width, so the columns above have something to divide — but
	 * scaled to how much is actually in the panel. A fixed 46rem meant a
	 * category with two groups (Kitchen, Furniture) rendered two short columns
	 * and a third of empty white panel beside them.
	 *
	 * The wide value is the BASE and the narrow ones are subtractive, so a
	 * browser without :has() support falls back to today's behaviour rather
	 * than to a 19rem panel that would clip a deep tree. */
	width: min( 44rem, 92vw );
	padding: 1.25rem 1.5rem;
	background: var( --haat-surface );
	border: 1px solid var( --haat-border );
	border-radius: var( --haat-radius-lg );
	box-shadow: var( --haat-shadow-pop );
	visibility: hidden;
	opacity: 0;
	transition: opacity var( --haat-duration-fast ) var( --haat-ease-out ),
		visibility 0s linear var( --haat-duration-fast );
}

/* Under the horizontal primary menu the panel drops downward and spans the
 * container instead of flying out sideways. */
/* Fewer than five entries: narrower. Fewer than two: narrower still.
 * Three short links do not need the full 44rem slab — Deals was rendering
 * three items across a panel wide enough for twelve. */
.haat-mega:not( :has( .haat-mega__columns > :nth-child( 5 ) ) ) {
	width: min( 30rem, 92vw );
}

.haat-mega:not( :has( .haat-mega__columns > :nth-child( 2 ) ) ) {
	width: min( 19rem, 92vw );
}

.haat-catbar__primary-list .haat-mega {
	top: calc( 100% + 0.5rem );
	left: 0;
}

/* The 0.5rem of air above the panel is dead space the pointer has to cross, and
 * a gap with nothing in it drops the hover and closes the panel mid-movement.
 * This invisible bridge spans it so the panel stays open on the way down. */
.haat-catbar__primary-list .haat-mega::before {
	content: "";
	position: absolute;
	top: -0.5rem;
	left: 0;
	right: 0;
	height: 0.5rem;
}

/* A tall category tree would otherwise run off the bottom of the viewport with
 * no way to reach the rest of it. */
.haat-mega {
	max-height: min( 70vh, 34rem );
	overflow-y: auto;
	overscroll-behavior: contain;
}

.haat-mega__item--trigger:hover > .haat-mega,
.haat-mega__item--trigger:focus-within > .haat-mega,
.haat-mega__item--trigger.is-open > .haat-mega {
	visibility: visible;
	opacity: 1;
	transition-delay: 0s;
}

/* Multi-column, not grid.
 *
 * This was `repeat( auto-fit, minmax( 10.5rem, 1fr ) )`, which cannot work
 * here: auto-fit needs a DEFINITE container width to compute a repetition
 * count, and the panel sizes to its content — so the count resolved to 1 and a
 * six-group category tree stacked into one column that ran off the bottom of
 * the screen. (The footer grid had the identical bug for the identical reason.)
 *
 * Multi-column flows items into as many columns as fit and never needs the
 * container measured first. break-inside keeps a heading with its own links
 * rather than splitting a group across the fold.
 */
.haat-mega__columns {
	display: block;
	columns: 10.5rem 3;
	column-gap: 2.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.haat-mega__columns > .haat-mega__item {
	display: block;
	break-inside: avoid;
	-webkit-column-break-inside: avoid;
	page-break-inside: avoid;
}

/* A column that heads a group of children still needs air beneath it, and
 * space before whatever follows. */
.haat-mega__columns > .haat-mega__item--column {
	margin-bottom: 1.35rem;
}

/* A column HEADING is an item that actually has children. The second selector
 * here used to be `.haat-mega__columns > .haat-mega__item > .haat-mega__link`,
 * which matched every depth-1 item — so a panel of plain links (Brands, or a
 * list of collections) rendered each one as a bold, underlined section title
 * with nothing beneath it. The panel looked empty when it was in fact full. */
.haat-mega__item--column > .haat-mega__link {
	padding: 0 0 0.5rem;
	font-weight: var( --haat-weight-bold );
	font-size: var( --haat-text-sm );
	color: var( --haat-foreground );
	border-bottom: 1px solid var( --haat-border );
}

/* A leaf in the columns grid is just a link. */
.haat-mega__columns > .haat-mega__item:not( .haat-mega__item--column ) > .haat-mega__link {
	padding: 0.4rem 0;
	font-size: var( --haat-text-sm );
	color: var( --haat-muted-foreground );
}

.haat-mega__columns > .haat-mega__item:not( .haat-mega__item--column ) > .haat-mega__link:hover {
	background: none;
	color: var( --haat-primary );
}

.haat-mega__item--column > .haat-mega__link:hover {
	background: none;
}

.haat-mega__links {
	margin: 0.6rem 0 0;
	padding: 0;
	list-style: none;
}

.haat-mega__links .haat-mega__link {
	padding: 0.3rem 0;
	font-weight: var( --haat-weight-normal );
	color: var( --haat-muted-foreground );
	white-space: normal;
}

.haat-mega__links .haat-mega__link:hover {
	background: none;
	color: var( --haat-flame-600 );
}

/* ── Breadcrumb bar ──────────────────────────────────────────────────────*/
.haat-breadcrumb-bar {
	padding-block: 0.75rem;
	background: var( --haat-muted );
	border-bottom: 1px solid var( --haat-border );
	font-size: var( --haat-text-sm );
}

.haat-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	color: var( --haat-muted-foreground );
}

.haat-breadcrumb a {
	color: var( --haat-muted-foreground );
}

.haat-breadcrumb a:hover {
	color: var( --haat-primary );
}

.haat-breadcrumb__sep {
	opacity: 0.5;
}

/* ── Footer ──────────────────────────────────────────────────────────────*/
.haat-footer {
	margin-top: auto;
	background: var( --haat-secondary );
	color: var( --haat-secondary-foreground );
}

.haat-footer a {
	color: var( --haat-secondary-foreground );
	opacity: 0.85;
}

.haat-footer a:hover {
	opacity: 1;
}

.haat-footer__main {
	padding-block: 3.5rem 2.5rem;
}

.haat-footer__grid {
	display: grid;
	gap: 2.5rem;
	grid-template-columns: minmax( 0, 1fr );
}

@media ( min-width: 768px ) {
	/* An explicit count, from --haat-footer-cols, which the template sets from
	 * the number of filled widget areas.
	 *
	 * This was repeat( auto-fit, minmax( 9rem, 1fr ) ) sitting after a 1.4fr
	 * track. auto-fit can only compute a repetition count when the other tracks
	 * are definite, and 1.4fr is not — so the count resolved to one and every
	 * footer column stacked into a single vertical run. */
	.haat-footer__grid {
		grid-template-columns: 1.6fr repeat( var( --haat-footer-cols, 3 ), minmax( 0, 1fr ) );
	}

	/* No brand column: the link columns take the whole measure. */
	.haat-footer__grid:not( :has( .haat-footer__brand ) ) {
		grid-template-columns: repeat( var( --haat-footer-cols, 3 ), minmax( 0, 1fr ) );
	}
}

/* The brand column is a stack, and its parts need to be spaced as one.
 * .haat-branding is itself a flex column with no gap, so the logo sat directly
 * on the blurb beneath it — the two read as one block of collided content
 * rather than as a mark with supporting text. */
.haat-footer__brand {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.1rem;
}

.haat-footer__brand > * {
	margin: 0;
}

.haat-footer__brand .haat-branding__title a,
.haat-footer .haat-widget__title {
	color: var( --haat-secondary-foreground );
}

.haat-footer__blurb {
	max-width: 32ch;
	font-size: var( --haat-text-sm );
	opacity: 0.75;
}

.haat-footer .haat-widget__title {
	margin-bottom: 1rem;
	font-size: var( --haat-text-sm );
	font-weight: var( --haat-weight-bold );
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.haat-footer .haat-widget ul {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: 0.55rem;
	font-size: var( --haat-text-sm );
}

.haat-socials {
	display: flex;
	gap: 0.6rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.haat-socials__link {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border: 1px solid color-mix( in oklab, currentColor 30%, transparent );
	border-radius: var( --haat-radius-full );
	transition: background var( --haat-duration-fast ) var( --haat-ease-out );
}

.haat-socials__link:hover {
	background: color-mix( in oklab, currentColor 12%, transparent );
}

.haat-socials__icon {
	width: 1.05rem;
	height: 1.05rem;
	background: currentColor;
	opacity: 0.9;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

/* Social icons as CSS masks over currentColor, so they inherit the footer's
 * ink in both schemes and cost no extra request. This was a plain rounded
 * square placeholder, which rendered as four blank chips in the footer of
 * every store — the single most 'unfinished template' detail on the page. */
.haat-socials__link--facebook .haat-socials__icon {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M15.5 3H13a4.5 4.5 0 0 0-4.5 4.5V10H6v3h2.5v8h3v-8H14l.5-3h-3V7.5A1.5 1.5 0 0 1 13 6h2.5z'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M15.5 3H13a4.5 4.5 0 0 0-4.5 4.5V10H6v3h2.5v8h3v-8H14l.5-3h-3V7.5A1.5 1.5 0 0 1 13 6h2.5z'/%3E%3C/svg%3E" );
}

.haat-socials__link--instagram .haat-socials__icon {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M7.5 2.5h9A5 5 0 0 1 21.5 7.5v9a5 5 0 0 1-5 5h-9a5 5 0 0 1-5-5v-9a5 5 0 0 1 5-5m4.5 5.5a4 4 0 1 0 0 8 4 4 0 0 0 0-8m5.2-1.7a1 1 0 1 0 0 2 1 1 0 0 0 0-2'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M7.5 2.5h9A5 5 0 0 1 21.5 7.5v9a5 5 0 0 1-5 5h-9a5 5 0 0 1-5-5v-9a5 5 0 0 1 5-5m4.5 5.5a4 4 0 1 0 0 8 4 4 0 0 0 0-8m5.2-1.7a1 1 0 1 0 0 2 1 1 0 0 0 0-2'/%3E%3C/svg%3E" );
}

.haat-socials__link--x .haat-socials__icon {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M3 3h5.2l4.6 6.3L18.4 3H21l-7 8.1L21.5 21H16.3l-4.9-6.7L5.6 21H3l7.4-8.6z'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M3 3h5.2l4.6 6.3L18.4 3H21l-7 8.1L21.5 21H16.3l-4.9-6.7L5.6 21H3l7.4-8.6z'/%3E%3C/svg%3E" );
}

.haat-socials__link--youtube .haat-socials__icon {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M22 12s0-3.4-.4-5a2.6 2.6 0 0 0-1.8-1.8C18 4.8 12 4.8 12 4.8s-6 0-7.8.4A2.6 2.6 0 0 0 2.4 7C2 8.6 2 12 2 12s0 3.4.4 5a2.6 2.6 0 0 0 1.8 1.8c1.8.4 7.8.4 7.8.4s6 0 7.8-.4A2.6 2.6 0 0 0 21.6 17c.4-1.6.4-5 .4-5M10 15.2V8.8l5.2 3.2z'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M22 12s0-3.4-.4-5a2.6 2.6 0 0 0-1.8-1.8C18 4.8 12 4.8 12 4.8s-6 0-7.8.4A2.6 2.6 0 0 0 2.4 7C2 8.6 2 12 2 12s0 3.4.4 5a2.6 2.6 0 0 0 1.8 1.8c1.8.4 7.8.4 7.8.4s6 0 7.8-.4A2.6 2.6 0 0 0 21.6 17c.4-1.6.4-5 .4-5M10 15.2V8.8l5.2 3.2z'/%3E%3C/svg%3E" );
}

.haat-socials__link--linkedin .haat-socials__icon {
	-webkit-mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M6.5 3.5a2 2 0 1 1 0 4 2 2 0 0 1 0-4M4.8 9h3.4v11.5H4.8zM11 9h3.3v1.6c.5-.9 1.6-1.9 3.4-1.9 3 0 3.8 1.9 3.8 4.6v7.2h-3.4v-6.4c0-1.5-.3-2.6-1.7-2.6s-2 1-2 2.5v6.5H11z'/%3E%3C/svg%3E" );
	mask-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M6.5 3.5a2 2 0 1 1 0 4 2 2 0 0 1 0-4M4.8 9h3.4v11.5H4.8zM11 9h3.3v1.6c.5-.9 1.6-1.9 3.4-1.9 3 0 3.8 1.9 3.8 4.6v7.2h-3.4v-6.4c0-1.5-.3-2.6-1.7-2.6s-2 1-2 2.5v6.5H11z'/%3E%3C/svg%3E" );
}


.haat-footer__legal {
	padding-block: 1.25rem;
	border-top: 1px solid color-mix( in oklab, currentColor 18%, transparent );
	font-size: var( --haat-text-sm );
}

.haat-footer__legal-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
}

.haat-footer__copyright {
	margin: 0;
	opacity: 0.8;
}

.haat-footer__legal-menu {
	display: flex;
	flex-wrap: wrap;
	gap: 1.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.haat-footer__payments-image {
	max-height: 1.75rem;
	width: auto;
}

/* The footer branding is always on dark chrome, so its fallback title has to be
 * light too — the default .haat-branding__title colour is the page foreground,
 * which is dark ink. Its image sizing is handled with the other logo variants
 * further up; repeating max-height here is what re-introduced the stretch. */
.haat-branding--inverse .haat-branding__title a,
.haat-branding--inverse .haat-branding__tagline {
	color: var( --haat-secondary-foreground );
}
