/* ============================================================================
   BENIS SHOES — NAVIGATION
   ----------------------------------------------------------------------------
   Header, primary navigation, category menu, mobile drawer, search panel,
   mobile bottom bar and footer.

   Search is the part of this file with the strongest constraint: it must never
   become a full-screen takeover. On desktop it is an anchored panel bounded to
   --search-panel-w (44rem / ~704px). On mobile it is a sheet pinned under the
   header with an internally scrolling result list — the page stays visible
   behind it, so it reads as a control on the store, not a separate app.
   ========================================================================== */

/* ============================================================================
   HEADER
   ========================================================================== */

.site-header {
	position: sticky;
	inset-block-start: 0;
	z-index: var(--z-header);
	background-color: var(--surface);
	border-block-end: 1px solid var(--border);
}

/* ── Header/hero continuity ──────────────────────────────────────────────────
   On the homepage the header sits on the hero's own ground with no rule under
   it, so navigation and campaign read as one continuous surface instead of a
   bar stacked above a pasted-in image. The divider comes back as soon as the
   page scrolls, where the header is over content and needs the separation.
   Reuses `.is-scrolled`, already toggled by benis-navigation.js — no second
   scroll listener for the same piece of state. */
.home .site-header,
.benis-hero-page .site-header {
	background-color: transparent;
	border-block-end-color: transparent;
	transition:
		background-color var(--duration-base) var(--ease),
		border-color var(--duration-base) var(--ease);
}

.home .site-header.is-scrolled,
.benis-hero-page .site-header.is-scrolled {
	background-color: rgb(255 255 255 / 0.88);
	backdrop-filter: blur(14px);
	border-block-end-color: var(--border);
}

/* Mobile is a THREE-COLUMN grid, not a flex row.
   ----------------------------------------------------------------------------
   The flex row let four elements fight over 390px: the logo got squeezed to a
   sliver and the search placeholder truncated mid-word ("جستجو در محد"). A grid
   with a centred middle column pins the logo to the optical centre regardless
   of how wide the controls beside it are, which is also why the two side
   columns are given equal minimum width. */
.header__bar {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--space-2);
	block-size: var(--header-height);
}

@media (min-width: 1024px) {
	.header__bar {
		display: flex;
		block-size: var(--header-height-lg);
		gap: var(--space-6);
	}
}

/* ── Logo ────────────────────────────────────────────────────────────────── */

.header__logo {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	grid-column: 2;
}

@media (min-width: 1024px) {
	.header__logo {
		justify-content: flex-start;
		/* Reserved box so the header does not jump while the logo decodes. */
		min-inline-size: 6.5rem;
	}
}

/* No mask, no forced square. The file is the lockup on transparency, so the
   height is set and the width follows the artwork. The circular badge spent
   most of its box on the disc; frameless, every pixel of the box is logo, so
   the same footprint carries a visibly larger mark. */
.header__logo img {
	block-size: 2.75rem;
	inline-size: auto;
	object-fit: contain;
}

@media (min-width: 1024px) {
	.header__logo img { block-size: 3.5rem; }
}

/* ── Primary nav — desktop only ──────────────────────────────────────────── */

.primary-nav { display: none; }

@media (min-width: 1024px) {
	.primary-nav {
		display: flex;
		align-items: center;
		gap: var(--space-1);
		/* Centred in the bar rather than pushed left by the logo. A nav that
		   starts immediately after the logo and trails off toward the search
		   field reads as leftover space; centring gives the header an axis.

		   `flex-shrink: 1` with a zero basis means the NAV gives up width first
		   when the bar gets tight, protecting the search field's minimum. */
		flex: 0 1 auto;
		justify-content: center;
		margin-inline: auto;
		min-inline-size: 0;
		overflow: hidden;
	}
}

/* The rule under a nav item grows from the reading edge on hover, matching the
   tertiary button's underline. One interaction idea, used in both places. */
.primary-nav__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	padding-inline: var(--space-3);
	padding-block: var(--space-2);
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	color: var(--text);
	white-space: nowrap;
	transition: color var(--duration-fast) var(--ease);
}

.primary-nav__link::after {
	content: "";
	position: absolute;
	inset-block-end: 0.25rem;
	inset-inline-end: var(--space-3);
	inline-size: 0;
	block-size: 2px;
	border-radius: var(--radius-pill);
	background-color: var(--brand);
	transition: inline-size var(--duration-base) var(--ease);
}

html[dir="ltr"] .primary-nav__link::after {
	inset-inline-end: auto;
	inset-inline-start: var(--space-3);
}

@media (hover: hover) {
	.primary-nav__link:hover { color: var(--text-link); }

	.primary-nav__link:hover::after,
	.primary-nav__item[aria-expanded="true"] > .primary-nav__link::after {
		inline-size: calc(100% - var(--space-6));
	}
}

/* The current section gets weight AND a rule, so it is never communicated by
   colour alone. The rule is already drawn, so it only has to be revealed. */
.primary-nav__link[aria-current="page"] {
	font-weight: var(--weight-semibold);
	color: var(--text-link);
}

.primary-nav__link[aria-current="page"]::after {
	inline-size: calc(100% - var(--space-6));
}

/* The promo link is the one nav item allowed to carry colour on its own. */
.primary-nav__link--sale {
	color: var(--berry-600);
	font-weight: var(--weight-semibold);
}

.primary-nav__link--sale::after { background-color: var(--berry-500); }

.primary-nav__link svg {
	inline-size: 0.875rem;
	block-size: 0.875rem;
	color: var(--icon-muted);
	transition: transform var(--duration-fast) var(--ease);
}

.primary-nav__item[aria-expanded="true"] svg { transform: rotate(180deg); }

/* ── Mega menu — categories ──────────────────────────────────────────────── */

.mega {
	position: absolute;
	inset-inline: 0;
	inset-block-start: 100%;
	background-color: var(--surface);
	border-block-start: 1px solid var(--border);
	box-shadow: var(--shadow-md);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-0.5rem);
	transition: opacity var(--duration-fast) var(--ease),
	            transform var(--duration-fast) var(--ease),
	            visibility var(--duration-fast) var(--ease);
}

.mega.is-open {
	opacity: 1;
	visibility: visible;
	transform: none;
}

/* The desktop-only menu must leave mobile layout entirely; an invisible
   two-column panel can still widen a narrow document. */
@media (max-width: 1023px) {
	.mega,
	.mega.is-open { display: none; }
}

/* Two levels, side by side: the categories on the reading edge, the selected
   category's children beside them. The left column is fixed at 15rem so the
   right one never resizes as the selection moves down the list — a panel whose
   layout shifts under the pointer is the fastest way to make a hover menu feel
   broken. */
.mega__inner {
	display: grid;
	grid-template-columns: 15rem minmax(0, 1fr);
	gap: var(--space-10);
	padding-block: var(--space-6);
	/* A floor, so short categories do not give the panel a different height
	   from tall ones as the selection changes. */
	min-block-size: 16rem;
}

.mega__cats {
	display: flex;
	flex-direction: column;
	gap: 2px;
	border-inline-end: 1px solid var(--border);
	padding-inline-end: var(--space-6);
	margin-inline-end: calc(-1 * var(--space-4));
}

.mega__cat {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-inline: var(--space-3);
	min-block-size: 2.5rem;
	border-radius: var(--radius-md);
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	color: var(--text-muted);
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.mega__cat svg {
	inline-size: 0.875rem;
	block-size: 0.875rem;
	opacity: 0;
	transition: opacity var(--duration-fast) var(--ease);
}

/* The tinted row and the arrow together say "this is the one you are reading",
   which the right column alone cannot — the two are far enough apart on a wide
   header that the connection has to be drawn. */
.mega__cat.is-active,
.mega__cat:hover,
.mega__cat:focus-visible {
	background-color: var(--surface-brand);
	color: var(--blue-900);
}

.mega__cat.is-active svg { opacity: 1; }

.mega__panels { position: relative; }

/* Only the selected panel is in the flow. `display: none` rather than opacity,
   so the hidden panels' links are out of the tab order — otherwise tabbing
   through the menu would walk every category's children in turn. */
.mega__panel { display: none; }
.mega__panel.is-active { display: block; }

.mega__col-title {
	font-size: var(--text-h3);
	font-weight: var(--weight-semibold);
	margin-block-end: var(--space-4);
}

/* Children flow into columns rather than one long list: a category with nine
   subcategories should not make the panel nine rows tall. */
.mega__list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
	gap: var(--space-1) var(--space-6);
	margin-block-end: var(--space-5);
}

.mega__list a {
	display: block;
	padding-block: var(--space-2);
	font-size: var(--text-label);
	color: var(--text-muted);
}

.mega__list a:hover { color: var(--text-link); }

/* Shown when a category has no children. It states what IS there rather than
   leaving the column blank — and blank is the only other honest option, since
   showing the previous category's children would misreport the selection. */
.mega__empty {
	font-size: var(--text-label);
	color: var(--text-muted);
	margin-block-end: var(--space-5);
}

.mega__all {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	color: var(--text-link);
}

.mega__all svg {
	inline-size: 1rem;
	block-size: 1rem;
	transition: transform var(--duration-fast) var(--ease);
}

.mega__all:hover svg { transform: translateX(-3px); }

/* ── Header actions ──────────────────────────────────────────────────────── */

/* The utility icons read as one cluster, separated from the search field by a
   hairline rather than by guessing at a gap. Three loose marks floating beside
   a pill is what made the old header feel unresolved. */
.header__utils {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	/* Third grid column on mobile, pinned to the outer edge so the centred
	   logo stays centred whatever sits beside it. */
	grid-column: 3;
	grid-row: 1;
	justify-content: flex-end;
}

@media (min-width: 1024px) {
	.header__utils {
		margin-inline-start: var(--space-3);
		padding-inline-start: var(--space-3);
		border-inline-start: 1px solid var(--border);
	}
}

.header__action {
	position: relative;
}

/* The cart and wishlist counts are the only numbers in the header, so they
   must read instantly — a filled dot, not a subtle superscript. */
.header__count {
	position: absolute;
	inset-block-start: 0.25rem;
	inset-inline-end: 0.25rem;
	min-inline-size: 1.125rem;
	block-size: 1.125rem;
	padding-inline: 0.25rem;
	display: grid;
	place-items: center;
	border-radius: var(--radius-pill);
	background-color: var(--accent);
	color: var(--text-inverse);
	font-size: 0.6875rem;
	font-weight: var(--weight-semibold);
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

.header__count:empty,
.header__count[data-count="0"] { display: none; }

/* ── Announcement strip ──────────────────────────────────────────────────── */

/* The service strip is a BRAND surface, not a black bar. It is the first thing
   on the page and the first opportunity to say Benis, and a cyan band above a
   white header is a long-standing part of this storefront's identity.

   Ink on the brand blue, never white: #51CAFE carries white at 1.87:1 and dark
   ink at 9.28:1, so the accessible pairing and the brand-correct pairing are
   the same choice here. */
.announce {
	background: linear-gradient(90deg, var(--blue-300) 0%, var(--blue-400) 55%, var(--blue-500) 100%);
	color: var(--text-on-brand);
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
	text-align: center;
	padding-block: var(--space-2);
	padding-inline: var(--gutter);
}

/* ONE line, always.
   The default copy is long enough to wrap at 390px, where it took two lines and
   ~56px of the first viewport before the shopper saw anything — and a wrapped
   promo strip reads as a layout accident rather than a banner. Truncating keeps
   the bar a fixed 36px; the shop owner controls the copy in the Customizer and
   should keep it short. */
.announce .container {
	display: block;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	line-height: 1.6;
}

@media (max-width: 599px) {
	.announce {
		font-size: var(--text-caption);
		padding-block: 0.4375rem;
	}
}

.announce a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	font-weight: var(--weight-semibold);
}

/* The optional call to action, when the Customizer has both a label and a URL.
   It sits inline after the message because the strip is one non-wrapping line —
   floated to an edge it would be the first thing the ellipsis ate. */
.announce__link { margin-inline-start: var(--space-2); }

/* ============================================================================
   SEARCH
   ----------------------------------------------------------------------------
   Bounded on every breakpoint. Never position:fixed covering the viewport.
   ========================================================================== */

.search { position: relative; }

/* ── Desktop: inline field that opens an anchored panel ──────────────────── */

/* A soft pill. Search is one of the three things Benis puts in front of the
   shopper immediately, and the rounded field is part of how the header reads
   as friendly rather than administrative. Pills are otherwise reserved for
   badges and chips, so this is a deliberate exception, not a default. */
.search__form {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	inline-size: 100%;
	max-inline-size: var(--search-field-w, 18rem);
	/* A floor as well as a ceiling. The nav grew to fill the bar and squeezed
	   this to 207px at 1440, which clipped its own placeholder — a search field
	   too narrow to state what it searches. The nav shrinks first now. */
	min-inline-size: 15rem;
	padding-inline: var(--space-4);
	block-size: 2.75rem;
	background-color: var(--surface-soft);
	border: 1px solid transparent;
	border-radius: var(--radius-pill);
	transition: border-color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease);
}

/* Focus is a brand moment: the field lifts to white and takes a blue ring. */
.search__form:focus-within {
	background-color: var(--surface);
	border-color: var(--border-focus);
	box-shadow: var(--shadow-focus);
}

.search__input {
	flex: 1 1 auto;
	min-inline-size: 0;
	border: none;
	background: none;
	font-size: var(--text-label);
	color: var(--text);
	/* Fill the field's full height. The input's own content box is 25px inside
	   a 44px field, so without this the top and bottom 9px of what LOOKS like
	   the search box are dead — a tap that lands near the edge does nothing,
	   which on a phone is most of them. */
	align-self: stretch;
}

.search__input:focus-visible { outline: none; }

/* The field is type="search", so WebKit draws its OWN clear button as soon as
   there is a value — sitting right beside `.search__clear` and giving the
   shopper two ✕ that do slightly different things. The theme's button is the
   one that also resets the results panel, so the native one goes. */
.search__input::-webkit-search-cancel-button,
.search__input::-webkit-search-decoration,
.search__input::-webkit-search-results-button,
.search__input::-webkit-search-results-decoration {
	-webkit-appearance: none;
	appearance: none;
	display: none;
}

.search__icon {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	color: var(--icon-muted);
	flex-shrink: 0;
}

.search__clear { flex-shrink: 0; }
.search__clear[hidden] { display: none; }

/* ── The panel ───────────────────────────────────────────────────────────── */

.search__panel {
	--search-panel-w: 44rem;   /* ~704px, inside the 560-720 target band */

	position: absolute;
	inset-block-start: calc(100% + var(--space-2));
	inset-inline-end: 0;
	inline-size: var(--search-panel-w);
	max-inline-size: calc(100vw - var(--space-8));
	/* Deliberately a LOCAL value, not --z-drawer. The panel is a child of the
	   sticky header, which already opens a stacking context at --z-header, so
	   anything here only ever competes with the header's own children — a
	   drawer-level number just made the intent look like something it was not.
	   The page-wide layering the panel actually needs comes from the header. */
	z-index: var(--z-raised);
	background-color: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-lg);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	/* Bounded height with internal scrolling — the panel never grows past the
	   viewport and never becomes a page. */
	max-block-size: min(32rem, calc(100svh - var(--header-height-lg) - var(--space-8)));
	opacity: 0;
	visibility: hidden;
	transform: translateY(-0.375rem);
	transition: opacity var(--duration-fast) var(--ease),
	            transform var(--duration-fast) var(--ease),
	            visibility var(--duration-fast) var(--ease);
}

.search__panel.is-open {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.search__results {
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: var(--space-2);
}

.search__group-title {
	padding: var(--space-2) var(--space-3);
	font-size: var(--text-caption);
	font-weight: var(--weight-semibold);
	color: var(--text-muted);
	letter-spacing: 0.02em;
}

/* ── Result row ──────────────────────────────────────────────────────────── */

.search__result {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-md);
	transition: background-color var(--duration-fast) var(--ease);
}

.search__result:hover,
.search__result.is-active {
	background-color: var(--surface-soft);
}

.search__result-media {
	inline-size: 3rem;
	block-size: 3.75rem;
	border-radius: var(--radius-sm);
	overflow: hidden;
	flex-shrink: 0;
	background-color: var(--surface-sunken);
}

.search__result-media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

.search__result-body { flex: 1 1 auto; min-inline-size: 0; }

.search__result-title {
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	/* Long Persian product names truncate rather than wrapping the row to
	   three lines and destroying the list's scan rhythm. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.search__result-meta {
	font-size: var(--text-small);
	color: var(--text-muted);
}

.search__foot {
	border-block-start: 1px solid var(--border);
	padding: var(--space-3);
	flex-shrink: 0;
}

/* ── Suggestion pills — recent and popular terms ─────────────────────────── */

.search__suggestions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	padding: var(--space-3);
}

.search__suggestion {
	padding-inline: var(--space-3);
	padding-block: var(--space-2);
	border: 1px solid var(--border);
	border-radius: var(--radius-pill);
	font-size: var(--text-small);
	color: var(--text);
	transition: border-color var(--duration-fast) var(--ease);
}

.search__suggestion:hover { border-color: var(--neutral-900); }

/* ── Mobile search ───────────────────────────────────────────────────────── */

@media (max-width: 1023px) {
	/* The field is ALWAYS visible on mobile, and it now gets its OWN full-width
	   row under the logo line. Benis leads with search on a phone — the
	   catalogue is browsed by model name far more than by menu — but sharing the
	   top row with the logo and the icons left it around 140px wide, which
	   truncated the placeholder mid-word ("جستجو در محد"). A second row costs
	   about 52px and makes the most-used control full width.

	   The panel still opens on focus, so no JS behaviour changes, and the
	   magnifier toggle is redundant once the field is on screen. */
	.header__bar {
		grid-template-rows: var(--header-height) auto;
		block-size: auto;
		padding-block-end: var(--space-2);
	}

	.search {
		position: static;
		grid-column: 1 / -1;
		grid-row: 2;
		min-inline-size: 0;
	}

	.search [data-search-toggle] { display: none; }

	.search__form {
		max-inline-size: none;
	}

	.search__panel {
		/* Anchored to the BOTTOM OF THE HEADER, not to a hand-computed offset.
		   It used to be fixed at `--header-height + 3.5rem`, a number that was
		   only ever right for one header layout — it ignored the announcement
		   bar entirely, so before the page scrolled the panel opened on top of
		   the very field being typed into. .site-header is sticky, which makes
		   it the containing block, so `inset-block-start: 100%` tracks whatever
		   height the header actually has. */
		position: absolute;
		inset-block-start: 100%;
		inset-inline: var(--space-3);
		inline-size: auto;
		max-inline-size: none;
		max-block-size: min(60svh, 28rem);
	}
}

/* ============================================================================
   MOBILE DRAWER NAVIGATION
   ----------------------------------------------------------------------------
   The menu was a white slab of plain text rows: correct, and indistinguishable
   from any other WordPress theme's drawer. On a phone this panel covers most of
   the screen, so it is one of the largest single impressions the brand makes —
   and it was spending that impression on nothing.

   What it carries now is the same identity the rest of the storefront already
   has, not a new one: a floating rounded surface rather than a full-height
   slab, a soft blue wash behind the brand mark, the blue eyebrow that labels
   sections everywhere else, and the catalogue CTA in the logo blue pinned to
   the bottom so the panel resolves into an action instead of empty white.
   ========================================================================== */

/* Floating, not bolted to the edge: the outer corners are square against the
   viewport and the INNER edge is rounded, which is what makes it read as a
   panel sliding over the page rather than a second screen. */
.drawer--nav {
	inline-size: min(18rem, 80vw);
	background-color: var(--surface);
	border-start-end-radius: var(--radius-xl);
	border-end-end-radius: var(--radius-xl);
	overflow: hidden;
}

/* ── Head ─────────────────────────────────────────────────────────────────── */

.nav-drawer__head {
	align-items: center;
	padding-block: var(--space-4);
	background:
		radial-gradient(120% 140% at 100% 0%, var(--blue-50) 0%, transparent 70%);
	border-block-end-color: var(--neutral-100);
}

.nav-drawer__brand {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	min-inline-size: 0;
}

/* The shipped mark is a 360x360 disc on a black square — the same asset the
   header masks to a circle, and for the same reason. */
.nav-drawer__logo {
	inline-size: auto;
	block-size: 2.5rem;
	object-fit: contain;
	flex-shrink: 0;
}

.nav-drawer__brand-text {
	display: flex;
	flex-direction: column;
	min-inline-size: 0;
}

.nav-drawer__brand-text strong {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
}

.nav-drawer__brand-text span {
	font-size: var(--text-caption);
	color: var(--text-muted);
	line-height: var(--leading-snug);
}

/* A white puck, the same object as the wishlist control on a product card. */
.nav-drawer__close {
	background-color: var(--surface);
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-sm);
	flex-shrink: 0;
}

.nav-drawer__close:hover { background-color: var(--surface-soft); }

/* ── Sections ─────────────────────────────────────────────────────────────── */

.nav-drawer__section + .nav-drawer__section {
	margin-block-start: var(--space-5);
	padding-block-start: var(--space-5);
	border-block-start: 1px solid var(--neutral-100);
}

/* The blue eyebrow, identical in role to .section-head__kicker on the homepage
   — this is the cheap, repeated place the brand colour earns its keep. */
.nav-drawer__label {
	font-size: var(--text-caption);
	font-weight: var(--weight-semibold);
	color: var(--text-link);
	/* Matches the rows' own inline padding so the eyebrow and the labels it
	   introduces sit on one edge. */
	padding-inline: var(--space-3);
	margin-block-end: var(--space-2);
}

.nav-drawer__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	inline-size: 100%;
	min-block-size: var(--tap-target);
	padding-block: var(--space-2);
	padding-inline: var(--space-3);
	border-radius: var(--radius-md);
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	color: var(--text);
	transition: background-color var(--duration-fast) var(--ease);
}

/* Pressed state matters more than hover here — this panel is only ever touched.
   The soft blue pill is the same active treatment the floating bottom bar uses,
   so "where I am" looks the same in both navigations. */
.nav-drawer__link:hover,
.nav-drawer__link:active {
	background-color: var(--brand-soft);
}

.nav-drawer__link--sub {
	font-size: var(--text-label);
	font-weight: var(--weight-regular);
	color: var(--text-muted);
	min-block-size: 2.25rem;
}

/* The sublist is indented by a blue rule rather than by padding, so an open
   category reads as a branch of the row above it instead of a second list. */
.nav-drawer__sublist {
	margin-inline-start: var(--space-4);
	padding-inline-start: var(--space-2);
	border-inline-start: 2px solid var(--blue-100);
}

/* The drill-down chevron points the way the reader travels: LEFT in RTL,
   right in LTR. The markup ships a chevron-left, so RTL needs no transform at
   all and LTR is the case that flips.
   This was the other way round — RTL flipped the chevron to point right, back
   toward where the reader came from, and LTR left it pointing left. Both
   directions were indicating "back" on a control that goes forward. */
.nav-drawer__link svg {
	inline-size: 1rem;
	block-size: 1rem;
	color: var(--icon-muted);
}

html[dir="ltr"] .nav-drawer__link svg { transform: scaleX(-1); }

.nav-drawer__toggle[aria-expanded="true"] svg.nav-drawer__chevron {
	transform: rotate(180deg);
}

.nav-drawer__sublist[hidden] { display: none; }

/* ── Foot ────────────────────────────────────────────────────────────────────
   Pinned below the scrolling body, so it is reachable without scrolling to the
   end of the categories — and so the panel ends on the brand's blue rather than
   on whatever row happened to be last. */
.nav-drawer__foot {
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	padding: var(--space-4);
	padding-block-end: max(var(--space-4), env(safe-area-inset-bottom));
	background-color: var(--surface-soft);
	border-block-start: 1px solid var(--neutral-100);
}

.nav-drawer__social {
	display: flex;
	justify-content: center;
	gap: var(--space-2);
}

.nav-drawer__social a {
	display: grid;
	place-items: center;
	inline-size: 2.25rem;
	block-size: 2.25rem;
	border-radius: var(--radius-pill);
	background-color: var(--surface);
	color: var(--text-muted);
	box-shadow: var(--shadow-xs);
	transition: color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease);
}

.nav-drawer__social a:hover {
	background-color: var(--brand-soft);
	color: var(--text-link);
}

.nav-drawer__social svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
}

/* ============================================================================
   MOBILE BOTTOM BAR
   ----------------------------------------------------------------------------
   Only shown on small screens. It is the reason the mobile header can stay at
   56px: browse, search, wishlist and cart live down here within thumb reach,
   so the header only carries the logo and the menu.
   ========================================================================== */

/* A FLOATING pill, not a docked bar.
   ----------------------------------------------------------------------------
   This is the most recognisable piece of Benis on a phone: the bar lifts off
   the bottom edge, carries its own radius and shadow, and the destination you
   are on becomes a filled brand capsule. An edge-to-edge white strip with a
   black active label is the platform default — correct, and completely
   anonymous.

   The float is also why the rest of the page can keep its soft containers: the
   navigation reads as another floating surface rather than as chrome bolted to
   the viewport. */
.mobile-nav {
	position: fixed;
	inset-inline: var(--space-3);
	inset-block-end: calc(var(--mobile-nav-gap) + env(safe-area-inset-bottom, 0px));
	z-index: var(--z-sticky);
	display: flex;
	align-items: center;
	gap: var(--space-1);
	/* The padding is a token because --mobile-nav-clearance has to add it back
	   when working out how much room the pill really takes. */
	padding: var(--mobile-nav-pad);
	border-radius: var(--radius-xl);

	/* Real glass, not a flat translucent panel.
	   The vertical gradient gives the surface a light source, the saturation
	   boost keeps the page's colour alive through it instead of washing to
	   grey, and the inset hairline along the top edge is the highlight that
	   makes it read as a physical sheet rather than a low-opacity div. */
	background-image: linear-gradient(
		180deg,
		rgb(255 255 255 / 0.95) 0%,
		rgb(255 255 255 / 0.84) 100%
	);
	backdrop-filter: blur(24px) saturate(180%);
	-webkit-backdrop-filter: blur(24px) saturate(180%);
	border: 1px solid rgb(255 255 255 / 0.85);

	/* Three layers, each doing one job: the inset highlight lights the top
	   edge, the tight shadow sits the bar ON the page, and the wide negative-
	   spread one lifts it off. One blurred shadow reads as a flat card with a
	   smudge under it. */
	box-shadow:
		inset 0 1px 0 rgb(255 255 255 / 0.9),
		0 2px 8px rgb(15 27 42 / 0.05),
		0 18px 44px -10px rgb(15 27 42 / 0.28);
}

/* Browsers without backdrop-filter get an opaque bar rather than a see-through
   one — the labels are 11px and must not sit over moving content. */
@supports not (backdrop-filter: blur(1px)) {
	.mobile-nav { background-image: none; background-color: var(--surface); }
}

/* Four destinations, no raised centre button.
   ----------------------------------------------------------------------------
   A FAB was tried here and removed. It duplicated the header's search field,
   and centring it broke under RTL: `inset-inline-start: 50%` resolves against
   the RIGHT edge while `translate` stays physical, so the disc landed half its
   own width off-centre, sitting on top of the neighbouring icon with its
   page-coloured notch showing beside it as a white smear.

   The bar's character comes from the active state and its proportions instead,
   which is where it belongs — a tab bar should read as four equal
   destinations, not as decoration with items around it. */

@media (min-width: 1024px) {
	.mobile-nav { display: none; }
}

.mobile-nav__item {
	position: relative;
	isolation: isolate;
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.1875rem;
	min-block-size: var(--mobile-nav-height);
	border-radius: 15px;
	font-size: 0.6875rem;
	font-weight: var(--weight-medium);
	color: var(--text-muted);
	transition:
		color var(--duration-base) var(--ease),
		transform var(--duration-fast) var(--ease);
}

/* The capsule is a pseudo-element rather than a background on the item itself,
   because it has to SCALE from the centre as it comes in — and animating a
   background cannot do that. `isolation: isolate` on the item gives it a
   stacking context so z-index here stays local and cannot reach the bar's own
   glass. */
.mobile-nav__item::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;

	/* The same treatment as .btn--primary: a fill with a light source, and an
	   inset hairline along the bottom that behaves like a printed edge. It is
	   what stops a flat cyan rectangle reading as a default component-library
	   highlight — and it ties the active destination to the brand's CTA, which
	   is the other place this exact blue appears.

	   background-color stays underneath as the fallback if the gradient is ever
	   unsupported. */
	background-color: var(--brand);
	background-image: linear-gradient(
		180deg,
		var(--blue-300) 0%,
		var(--brand) 55%,
		var(--blue-500) 100%
	);

	/* A cyan-tinted glow, not a neutral drop shadow: the capsule should look
	   lit rather than stuck on top of the glass. */
	box-shadow:
		0 6px 16px -6px rgb(1 125 178 / 0.7),
		inset 0 -2px 0 rgb(1 125 178 / 0.28);
	opacity: 0;
	transform: scale(0.72);
	transition:
		opacity var(--duration-base) var(--ease-out),
		transform var(--duration-base) var(--ease-out);
}

.mobile-nav__item svg {
	inline-size: 1.375rem;
	block-size: 1.375rem;
	transition: transform var(--duration-base) var(--ease-out);
}

/* A real press state. There is no hover on a phone, so the tap itself has to
   acknowledge the touch. */
.mobile-nav__item:active { transform: scale(0.93); }

/* ── Active destination ──────────────────────────────────────────────────────
   The brand fill carrying DARK ink — the same pairing as the primary CTA, and
   the only accessible one: #51CAFE is 1.87:1 with white and 9.28:1 with ink.

   Three signals again, none of them colour alone: the capsule is a SHAPE that
   appears, the icon lifts and grows, and the label goes semibold. An 11px
   label distinguished only by hue is not a state everyone can read.

   `aria-expanded="true"` is the same state for the one item that opens a panel
   instead of going somewhere: دسته‌بندی is lit while its drawer is on screen,
   and goes out when it closes. The overlay controller sets that attribute on
   the trigger, so nothing here needs its own script. */
.mobile-nav__item[aria-current="page"],
.mobile-nav__item[aria-expanded="true"] {
	color: var(--text-on-brand);
	font-weight: var(--weight-semibold);
}

.mobile-nav__item[aria-current="page"]::after,
.mobile-nav__item[aria-expanded="true"]::after {
	opacity: 1;
	transform: none;
}

.mobile-nav__item[aria-current="page"] svg,
.mobile-nav__item[aria-expanded="true"] svg {
	transform: translateY(-1px) scale(1.08);
}

@media (prefers-reduced-motion: reduce) {
	.mobile-nav__item,
	.mobile-nav__item::after,
	.mobile-nav__item svg { transition: none; }

	.mobile-nav__item:active { transform: none; }

	.mobile-nav__item[aria-current="page"] svg,
	.mobile-nav__item[aria-expanded="true"] svg { transform: none; }
}

/* No count badge rules live here any more. The saved-items count was the only
   thing the bar ever counted, and that moved to the header when دسته‌بندی took
   its slot — `.header__count` styles it there. */

/* Pages with a sticky purchase bar add this so the two never stack on top of
   each other. Set in PHP on the body, not guessed at in JS.
   The floating bar needs its own gap accounted for on top of its height. */
body.has-mobile-nav {
	padding-block-end: calc(var(--mobile-nav-clearance) + var(--space-4));
}

@media (min-width: 1024px) {
	body.has-mobile-nav { padding-block-end: 0; }
}

/* ============================================================================
   FOOTER
   ========================================================================== */

/* A FLOATING PANEL, not a slab the page ends on.
   ----------------------------------------------------------------------------
   The footer was a full-bleed dark rectangle: correct, conventional, and the
   single most anonymous surface on the site. It is also the last thing every
   visitor sees, and it was spending that on a default.

   It is now inset from the viewport on all four sides and fully rounded, so it
   reads as one more floating surface — the same object language as the mobile
   bottom bar, the product cards and the search panel. That silhouette is only
   possible because the page canvas behind it is no longer pure white (see
   --surface-page); on white there was nothing for the panel to float against,
   which is part of why a dark rectangle was the only option before.

   The brand-gradient hairline that used to cap the top edge is gone with it: a
   2px rule announcing an edge is redundant once the edge is a 32px radius. */
.site-footer {
	position: relative;
	/* Establishes a block formatting context so the support card's negative
	   top margin moves the CARD up out of the footer, instead of collapsing
	   through .container into the footer's own margin and dragging the whole
	   panel up the page — which is the same thing to the layout engine and
	   completely different on screen. */
	display: flow-root;
	background-color: var(--neutral-900);
	color: var(--neutral-300);
	/* Room above for the support card, which is pulled up out of this box. */
	margin-block: calc(var(--section-gap) + var(--space-10)) var(--gutter);
	margin-inline: var(--gutter);
	border-radius: var(--radius-2xl);
	/* A wash of brand colour bleeding up from the top edge. The footer was a
	   flat black slab; this is the one place a large dark area can carry the
	   brand without competing with product photography. */
	background-image:
		radial-gradient(90% 120% at 82% -20%, rgb(1 125 178 / 0.5) 0%, transparent 62%),
		linear-gradient(180deg, rgb(1 96 137 / 0.22) 0%, transparent 38%);
}

/* ── Support card ────────────────────────────────────────────────────────────
   Pulled up so it sits half on the page and half on the footer. Positioned, so
   it draws above the footer's own gradient rather than under it. */
.footer__cta {
	position: relative;
	z-index: var(--z-raised);
	margin-block: calc(var(--space-10) * -1) var(--space-8);
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	padding: var(--space-5) var(--space-6);
	border-radius: var(--radius-xl);
	background-color: var(--brand);
	color: var(--text-on-brand);
	box-shadow: var(--shadow-md);
}

@media (min-width: 768px) {
	.footer__cta {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-8);
		padding: var(--space-6) var(--space-8);
	}
}

.footer__cta-text {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	min-inline-size: 0;
}

.footer__cta-text strong {
	font-size: var(--text-body-lg);
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
}

.footer__cta-text span {
	font-size: var(--text-label);
	/* Dark ink at 78% on cyan still measures well past AA; it is the secondary
	   line of a pair, so it steps back without reaching for a grey that would
	   go muddy on a saturated fill. */
	color: rgb(15 27 42 / 0.78);
}

.footer__cta-actions {
	display: flex;
	gap: var(--space-3);
	flex-shrink: 0;
}

.footer__cta-actions .btn { flex: 1 1 auto; }

@media (max-width: 359px) {
	.footer__cta-actions { flex-direction: column; min-inline-size: 0; }
	.footer__cta-actions .btn { inline-size: 100%; min-inline-size: 0; }
}

@media (min-width: 768px) {
	.footer__cta-actions .btn { flex: 0 0 auto; }
}

/* The subordinate action on a cyan fill. `.btn--secondary` would put a grey
   hairline and a blue-tint hover on top of the brand colour — invisible on one
   side and self-cancelling on the other. This is ink on a translucent white. */
.footer__cta-alt {
	background-color: rgb(255 255 255 / 0.55);
	color: var(--text-on-brand);
}

.footer__cta-alt:hover { background-color: rgb(255 255 255 / 0.8); }

.footer__top {
	display: grid;
	gap: var(--space-8);
	padding-block: 0 var(--space-10);
}

@media (min-width: 768px) {
	.footer__top {
		grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
		gap: var(--space-10);
	}
}

/* Square, masked to a circle — the file is a 360x360 badge on a black square,
   the same asset the header carries. Declared 120x40 it rendered squashed with
   its corners showing. */
.footer__logo {
	block-size: 4rem;
	inline-size: auto;
	object-fit: contain;
	margin-block-end: var(--space-4);
}

.footer__links {
	display: grid;
	gap: var(--space-6);
}

@media (min-width: 768px) {
	.footer__links {
		grid-column: 2 / -1;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--space-8);
	}
}

.footer__tagline {
	font-size: var(--text-label);
	color: var(--neutral-400);
	max-inline-size: 32ch;
}

/* Each column is headed by a short cyan rule. It is the same device as the blue
   eyebrow on the homepage sections and in the drawer — one mark, repeated, is
   what makes a brand colour read as a system rather than as an accent someone
   liked. */
.footer__title {
	position: relative;
	display: block;
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	color: var(--neutral-0);
	padding-inline-start: var(--space-4);
	padding-block-end: var(--space-3);
	margin-block-end: var(--space-3);
}

.footer__title::after {
	content: "";
	position: absolute;
	inset-block-end: 0;
	/* Aligned with the links' text, which is indented to leave room for the
	   hover dot — so the whole column hangs off one edge. */
	inset-inline-start: var(--space-4);
	inline-size: 1.75rem;
	block-size: 2px;
	border-radius: var(--radius-pill);
	background-color: var(--brand);
}

.footer__list { display: flex; flex-direction: column; gap: var(--space-1); }

/* Hover moves the link toward the reading edge and lights a small cyan dot in
   the space it leaves, instead of underlining. An underline on a dark footer
   thickens the row and reads as a visited state; this reads as a pointer. */
.footer__list a {
	position: relative;
	display: inline-block;
	font-size: var(--text-label);
	color: var(--neutral-300);
	padding-block: var(--space-1);
	padding-inline-start: var(--space-4);
	transition: color var(--duration-fast) var(--ease);
}

.footer__list a::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: 50%;
	inline-size: 0.375rem;
	block-size: 0.375rem;
	margin-block-start: -0.1875rem;
	border-radius: var(--radius-pill);
	background-color: var(--brand);
	opacity: 0;
	transition: opacity var(--duration-fast) var(--ease);
}

.footer__list a:hover { color: var(--neutral-0); }

/* Phones: the footer is a long list of small text links, and 33px rows put two
   of them inside one thumb. The type stays the same size; only the row grows. */
@media (max-width: 767px) {
	.footer__list a {
		display: flex;
		align-items: center;
		min-block-size: 2.5rem;
	}
}

.footer__list a:hover::before { opacity: 1; }

/* On mobile the link groups collapse. The <details> element gives keyboard and
   screen-reader behaviour for free, so no JS is needed for this. */
@media (max-width: 767px) {
	.footer__group summary {
		display: flex;
		align-items: center;
		justify-content: space-between;
		min-block-size: var(--tap-target);
		cursor: pointer;
		list-style: none;
	}

	.footer__group summary::-webkit-details-marker { display: none; }

	.footer__group summary .footer__title { margin-block-end: 0; }

	.footer__group summary svg {
		inline-size: 1rem;
		block-size: 1rem;
		transition: transform var(--duration-base) var(--ease);
	}

	.footer__group[open] summary svg { transform: rotate(180deg); }

	.footer__group .footer__list { padding-block: var(--space-2) var(--space-4); }

	.footer__group + .footer__group { border-block-start: 1px solid rgb(255 255 255 / 0.1); }
}

/* Desktop: no disclosure behaviour, the lists are simply open. */
@media (min-width: 768px) {
	.footer__group summary { list-style: none; pointer-events: none; }
	.footer__group summary svg { display: none; }
}

/* Centred and stacked rather than pushed to opposite ends.
   The two lines are a copyright and a credit — neither is an action, and
   space-between was pinning them to the far corners of a 1280px panel with a
   metre of empty rule between them. Centred, they read as one closing note. */
.footer__bottom {
	border-block-start: 1px solid rgb(255 255 255 / 0.1);
	padding-block: var(--space-5);
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--neutral-400);
}

/* The credit is Latin, and carries `lang="en" dir="ltr"` in the markup. This is
   the exception 01-tokens.css describes: a genuinely Latin string may be opened
   up locally, scoped to :lang(en), and never through a shared label class that
   would also catch Persian. */
.footer__made:lang(en) {
	font-size: var(--text-caption);
	letter-spacing: 0.03em;
	color: var(--neutral-500);
}

.footer__made a {
	color: var(--neutral-300);
	transition: color var(--duration-fast) var(--ease);
}

.footer__made a:hover { color: var(--brand); }

.footer__social {
	display: flex;
	gap: var(--space-2);
	margin-block-start: var(--space-5);
}

.footer__social-link {
	inline-size: var(--tap-target);
	block-size: var(--tap-target);
	display: grid;
	place-items: center;
	border: 1px solid rgb(255 255 255 / 0.16);
	border-radius: var(--radius-md);
	color: var(--neutral-300);
	transition: border-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.footer__social-link:hover {
	color: var(--text-on-brand);
	border-color: transparent;
	background-color: var(--brand);
}

.footer__social svg { inline-size: 1.125rem; block-size: 1.125rem; }

/* ── Licences and trust seals ───────────────────────────────────────────────
   The badges are third-party markup of unpredictable size and colour, so each
   one is dropped onto a light plate. Iranian trust seals are almost always
   supplied as artwork meant for a white background; on a dark footer they
   otherwise render as a black-on-black rectangle. */

/* Centred, and stacked under its own caption.
   The band used to be one flex row with `margin-inline-end: auto` on the label,
   which pinned the caption to one edge and the plates to the other — two or
   three small badges stranded at the far side of a 1440px footer, with the
   whole middle empty. A seal row is a closing statement, not a sidebar: it
   belongs on the page's centre line, which is also where the copyright line
   below it sits. */
.footer__seals {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	padding-block: var(--space-6);
	border-block-start: 1px solid rgb(255 255 255 / 0.1);
	text-align: center;
}

.footer__seals-label {
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
	color: var(--neutral-300);
}

.footer__seals-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-3);
}

.footer__seal {
	display: grid;
	place-items: center;
	min-inline-size: 4.5rem;
	min-block-size: 4.5rem;
	padding: var(--space-2);
	background-color: var(--neutral-0);
	border-radius: var(--radius-lg);
	transition: transform var(--duration-fast) var(--ease);
}

@media (hover: hover) {
	.footer__seal:hover { transform: translateY(-2px); }
}

/* Whatever the badge ships as, it is constrained to the plate. */
.footer__seal img,
.footer__seal a img {
	max-inline-size: 4.5rem;
	block-size: auto;
	display: block;
}

.footer__made { color: var(--neutral-500); }

/* The credit link is the one place in the footer's bottom rule that should be
   reachable, so it gets a real hover rather than inheriting muted grey. */
.footer__made a {
	color: var(--neutral-300);
	text-decoration: underline;
	text-underline-offset: 0.25em;
	text-decoration-color: rgb(255 255 255 / 0.3);
	transition: color var(--duration-fast) var(--ease),
	            text-decoration-color var(--duration-fast) var(--ease);
}

.footer__made a:hover {
	color: var(--brand);
	text-decoration-color: var(--brand);
}

/* Payment/trust marks stay small and monochrome — reassurance, not decoration. */
.footer__trust {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	align-items: center;
}

.footer__trust img {
	block-size: 2rem;
	inline-size: auto;
	opacity: 0.75;
}

/* ============================================================================
   BREADCRUMB
   ----------------------------------------------------------------------------
   Rendered by marsi_breadcrumb() on every template except the front page, and
   until now carried no rules at all — it rendered as a bare bulleted list
   under the header on the PDP, the cart, the account and every content page.

   Two decisions worth stating:

   Separators come from CSS, not markup. The PHP builds a `$separator` variable
   and never prints it — each crumb is just an <li> — so a `li + li::before`
   slash is the only way to get one, and it is also the right way: a separator
   is presentational and should not reach a screen reader as a list item.

   The slash is forced to LTR. In an RTL document a bare "/" adjacent to
   Persian text is resolved as neutral by the bidi algorithm and flips to the
   wrong side of the crumb, so it needs its own direction context.
   ========================================================================== */

/* Asymmetric, and tighter on a phone. The trail is orientation, not content:
   it belongs close under the header, and every heading below it carries its own
   top padding — so an equal 16px on both sides was a second gap stacked on the
   one already there. On a 390px screen those duplicated intervals were most of
   why the shop page opened on an empty band. */
.breadcrumb-wrap {
	padding-block: var(--space-3) var(--space-2);
	font-size: var(--text-small);
}

@media (min-width: 768px) {
	.breadcrumb-wrap { padding-block: var(--space-4); }
}

.breadcrumb-list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
	color: var(--text-muted);
}

.breadcrumb-list li {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	min-inline-size: 0;
}

.breadcrumb-list li + li::before {
	content: "/";
	display: inline-block;
	direction: ltr;
	color: var(--icon-muted);
	/* The slash is a rule, not a word: it should not carry the weight of the
	   crumbs on either side of it. */
	font-weight: var(--weight-regular);
}

.breadcrumb-list a {
	color: var(--text-muted);
	transition: color var(--duration-fast) var(--ease);
}

.breadcrumb-list a:hover { color: var(--text); }

/* The current page is the one crumb that is not a link, so it carries the ink
   the links do not. It also truncates: a product title is the last crumb on
   every PDP and is routinely longer than the three crumbs before it combined,
   which on a phone wrapped the trail onto three lines. */
.breadcrumb-list .current {
	color: var(--text);
	font-weight: var(--weight-medium);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-inline-size: 18ch;
}

@media (min-width: 768px) {
	.breadcrumb-list .current { max-inline-size: 40ch; }
}

/* ── Account menu ────────────────────────────────────────────────────────────
   A hover/focus panel under the header's user icon. It opens on :focus-within
   as well as :hover so the keyboard reaches it — a hover-only menu is a menu
   that does not exist for anyone tabbing through the header.
   ========================================================================== */

.account-menu {
	position: relative;
	display: flex;
}

.account-menu__panel {
	position: absolute;
	inset-block-start: calc(100% + var(--space-2));
	/* Anchored to the icon's inline-end so the panel opens INTO the page rather
	   than off the edge of the viewport — this icon sits near the header's
	   corner in both directions. */
	inset-inline-end: 0;
	z-index: var(--z-dropdown, 300);
	min-inline-size: 11rem;
	padding: var(--space-2);
	border-radius: var(--radius-lg);
	background-color: var(--surface);
	border: 1px solid var(--border);
	box-shadow: var(--shadow-lg);

	/* Hidden by clipping, not display:none, so the panel can transition and so
	   its links stay out of the tab order while closed. */
	opacity: 0;
	visibility: hidden;
	transform: translateY(-0.25rem);
	transition:
		opacity var(--duration-fast) var(--ease),
		transform var(--duration-fast) var(--ease),
		visibility 0s linear var(--duration-fast);
}

.account-menu:hover .account-menu__panel,
.account-menu:focus-within .account-menu__panel {
	opacity: 1;
	visibility: visible;
	transform: none;
	transition-delay: 0s;
}

.account-menu__greeting {
	padding: var(--space-2) var(--space-3);
	font-size: var(--text-caption);
	color: var(--text-muted);
	border-block-end: 1px solid var(--border);
	margin-block-end: var(--space-1);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.account-menu__link {
	display: block;
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	font-size: var(--text-label);
	color: var(--text);
	white-space: nowrap;
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.account-menu__link:hover {
	background-color: var(--surface-soft);
	color: var(--text-link);
}

/* Leaving is not the same kind of action as arriving. */
.account-menu__link--danger { color: var(--accent); }
.account-menu__link--danger:hover {
	background-color: var(--surface-soft);
	color: var(--accent);
}
