/* ============================================================================
   BENIS SHOES — COMMERCE
   ----------------------------------------------------------------------------
   Product card, listing pages, filtering, product detail, cart, checkout,
   order confirmation, account and wishlist.

   There is exactly ONE product card in this theme (.product-card). Home rails,
   the shop grid, category pages, search results, wishlist and cross-sells all
   render the same partial and the same class. Density is controlled by the
   grid around it, never by a second card definition.
   ========================================================================== */

/* ============================================================================
   PRODUCT CARD
   ========================================================================== */

/* A soft bordered card.
   ----------------------------------------------------------------------------
   An earlier pass removed the card box entirely so the image plate WAS the
   card. That read cleanly on a page of photography, but with most of this
   catalogue on the branded placeholder it left the grid looking like loose
   tiles floating on white with nothing holding a product together.

   The border is a hairline and the radius is one step above the plate's (18 vs
   14), so the card reads as a frame around the image rather than a second box
   competing with it — a card and its contents should never share a radius. */
.product-card {
	position: relative;
	display: flex;
	flex-direction: column;
	block-size: 100%;
	padding: var(--space-2);
	background-color: var(--surface);
	border: 1px solid var(--neutral-100);
	border-radius: 18px;
	transition: border-color var(--duration-base) var(--ease),
	            box-shadow var(--duration-base) var(--ease),
	            transform var(--duration-base) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
	.product-card:hover {
		border-color: var(--blue-200);
		box-shadow: 0 10px 28px rgb(1 125 178 / 0.1);
		transform: translateY(-2px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.product-card { transition: none; }
	.product-card:hover { transform: none; }
}

/* THE PLATE — where the product lives inside the card.
   ----------------------------------------------------------------------------
   Three decisions, all load-bearing:

   - 3/4, not 4/5. Footwear is photographed wide, but the taller plate gives the
     shoe more vertical room in a grid column and lets the image carry more of
     the card's weight, which is the point.
   - The cool blue tint is the brand showing through before any photography
     loads, and it is the ground the branded placeholder was drawn against.
   - 14px radius: softer than utility chrome, tighter than the 32px hero.
     Benis is soft; a catalogue of bubbles is not. */
.product-card__media {
	position: relative;
	aspect-ratio: var(--ratio-product);
	overflow: hidden;
	border-radius: var(--radius-media);
	background: linear-gradient(168deg, var(--blue-50) 0%, var(--neutral-50) 68%);
	margin-block-end: 0.8125rem;
}

.product-card__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	transition: transform var(--duration-slow) var(--ease-out);
}

/* The branded placeholder is a COMPLETE 800x800 tile — it carries its own
   gradient ground and rounded corners, it is not a transparent illustration.
   Containing it inside a tinted plate therefore drew a second, lighter panel
   inside the first: a visible box-in-a-box on every unphotographed product.
   Letting it cover the plate makes it read as one intentional branded tile.
   The shoe is centred in the artwork, so the vertical crop is harmless. */
.product-card__img--placeholder {
	object-fit: cover;
}

/* The second image is a desktop nicety only. It is never the sole route to
   information, and it is not loaded on touch devices. */
.product-card__media img.is-hover {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity var(--duration-base) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
	.product-card:hover .product-card__media img.is-hover { opacity: 1; }
	.product-card:hover .product-card__media img:not(.is-hover) { transform: scale(1.03); }
}

/* ── Badges ──────────────────────────────────────────────────────────────── */

/* Badges are stamped on the plate, in the corner opposite the wishlist.
   Because they are filled pills they carry their own contrast and stay legible
   over any photography, which is exactly what the pill is for. Status belongs
   on the image: it has to be readable while scanning a grid, and pushing it
   into the body buried it under the title. */
.product-card__badges {
	position: absolute;
	inset-block-start: 0.6875rem;
	inset-inline-start: 0.6875rem;
	z-index: var(--z-raised);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-1);
}

.product-card__meta-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-2);
}

/* ── Wishlist ────────────────────────────────────────────────────────────── */

/* Integrated, not a floating puck.
   ----------------------------------------------------------------------------
   The permanent white circle was the second-loudest piece of app chrome on the
   card. It exists to solve one real problem — a thin dark heart vanishes
   against dark photography — so the puck is kept for the states that need it
   and the default state solves contrast with a drop-shadow instead.

   drop-shadow (not box-shadow) follows the glyph's alpha, so the heart gets a
   soft light halo that reads on a navy boot and disappears on a white plate.
   The puck then arrives on hover and stays while saved, which is also the
   feedback that makes the toggle feel tactile. */
.product-card__wishlist {
	position: absolute;
	inset-block-start: 0.5rem;
	inset-inline-end: 0.5rem;
	z-index: var(--z-raised);
	/* The full 44px touch floor. The glyph inside stays 18px — it is the hit
	   area that has to be forgiving, not the mark. */
	inline-size: 2.75rem;
	block-size: 2.75rem;
	display: grid;
	place-items: center;
	border-radius: 50%;
	background-color: transparent;
	color: var(--neutral-800);
	filter: drop-shadow(0 1px 2px rgb(255 255 255 / 0.9));
	transition: color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease),
	            box-shadow var(--duration-fast) var(--ease),
	            transform var(--duration-fast) var(--ease);
}

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

/* Always visible, on every device. Hiding a save control behind hover means it
   does not exist on touch — which is the primary canvas here — and it made the
   card's top corner flicker on desktop as the pointer crossed the grid. */
.product-card__wishlist:hover,
.product-card__wishlist:focus-visible,
.product-card__wishlist.is-active {
	background-color: rgb(255 255 255 / 0.94);
	box-shadow: var(--shadow-xs);
	filter: none;
}

/* Saved state: berry, and the glyph fills. Colour alone would not be a state a
   colour-blind shopper can read, so the fill carries it. */
.product-card__wishlist.is-active { color: var(--accent); }
.product-card__wishlist.is-active svg { fill: currentColor; }

/* A small physical acknowledgement on tap — the only motion on the card. */
.product-card__wishlist:active { transform: scale(0.88); }

/* Declared LAST so it actually wins. An earlier pass left a second
   `:hover { transform: scale(1.12) }` / `:active { scale(0.94) }` pair below
   this block, which both fought the puck treatment above and silently defeated
   the reduced-motion reset — same specificity, later in the file. */
@media (prefers-reduced-motion: reduce) {
	.product-card__wishlist { transition: none; }
	.product-card__wishlist:active { transform: none; }
}

/* ── Body ────────────────────────────────────────────────────────────────── */

/* ── Actions — add to cart + quick look ──────────────────────────────────────
   Docked to the foot of the plate rather than stacked under the price, so the
   card's text block stays a clean three-line unit and the actions read as
   belonging to the product image.

   On pointer devices they slide up on hover. On touch there is no hover, so
   they are simply always visible — hiding a buy button behind an interaction
   that does not exist on the primary canvas would mean it does not exist. */
.product-card__actions {
	position: absolute;
	inset-inline: var(--space-2);
	inset-block-end: var(--space-2);
	z-index: var(--z-raised);
	display: flex;
	align-items: center;
	gap: var(--space-2);
}

.product-card__add {
	flex: 1 1 auto;
	min-inline-size: 0;
	/* Frosted so a long Persian label never fights the photography behind it. */
	box-shadow: 0 2px 10px rgb(15 27 42 / 0.16);
}

.product-card__add span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.product-card__quick {
	flex: 0 0 auto;
	inline-size: 2.25rem;
	block-size: 2.25rem;
	border-radius: 10px;
	background-color: rgb(255 255 255 / 0.94);
	backdrop-filter: blur(6px);
	box-shadow: 0 2px 10px rgb(15 27 42 / 0.16);
	color: var(--neutral-800);
}

.product-card__quick:hover {
	background-color: var(--neutral-0);
	color: var(--text-link);
}

/* The hover reveal is pointer-only. Note the guard is `hover: hover`, not a
   width query: a small laptop still has a pointer, and a large tablet does not. */
@media (hover: hover) and (pointer: fine) {
	.product-card__actions {
		opacity: 0;
		transform: translateY(0.5rem);
		transition:
			opacity var(--duration-base) var(--ease),
			transform var(--duration-base) var(--ease-out);
	}

	.product-card:hover .product-card__actions,
	.product-card:focus-within .product-card__actions {
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.product-card__actions { transition: none; }
}

.product-card__actions .btn { padding-inline: var(--space-3); }

/* Narrow cards.
   ----------------------------------------------------------------------------
   At 390px a two-column grid leaves each card about 171px wide. Minus the
   insets that is ~155px, and the quick-look button plus its gap takes 44 of it
   — so the add button gets ~110px. "افزودن به سبد" plus a bag icon does not fit
   in that, and the label was rendering as "افزودن ب…".

   The icon is what goes: it is decoration next to a label that already says
   exactly this. Type size and padding tighten with it, and the button is
   allowed to shrink below its content width so the two controls always share
   the row rather than one pushing the other off the plate. */
@media (max-width: 599px) {
	/* The card's own border and padding took 16px out of an already narrow
	   column, which pushed the add-to-cart label back into truncation
	   ("افزودن به س…"). The card gives some of that back here, and the actions
	   sit flush to the plate's edge. */
	.product-card { padding: 0.375rem; }

	.product-card__actions {
		inset-inline: 0.25rem;
		inset-block-end: 0.25rem;
		gap: 0.25rem;
	}

	/* 40px rather than 44 — still a comfortable target, and the 4px it returns
	   is the difference between the label fitting and not. */
	.product-card__quick {
		inline-size: 2.5rem;
		block-size: 2.5rem;
	}

	.product-card__add {
		font-size: var(--text-caption);
		padding-inline: var(--space-2);
	}

	.product-card__add svg { display: none; }
}

/* Touch sizing is gated on POINTER, not width.
   ----------------------------------------------------------------------------
   A 768px tablet is a touch device and needs the full 44px target; a 768px
   browser window on a laptop does not. A width breakpoint cannot tell those
   apart, and using one left the actions at 36px on every tablet. `hover: none`
   is the same signal that decides whether the actions are revealed on hover at
   all, so the two rules agree by construction. */
@media (hover: none) {
	.product-card__add {
		--btn-height: 2.75rem;
	}

	/* Above the narrow breakpoint only — below 600px the 40px size set there
	   wins, because the label fitting matters more than the last 4px of target
	   and 40px is still comfortably tappable. */
	@media (min-width: 600px) {
		.product-card__quick {
			inline-size: 2.75rem;
			block-size: 2.75rem;
		}
	}
}

/* Information sits on the page ground, not in a box.
   ----------------------------------------------------------------------------
   Deliberately uneven spacing rather than one uniform gap: the category and the
   title belong together as an identifying pair, and the price is a separate
   fact that earns air above it. An even stack of three rows read as a list of
   unrelated strings. */
.product-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	flex: 1 1 auto;
	/* Optical alignment. The plate has a 14px radius, so text flush to its
	   mathematical edge looks inset; a hair of padding lines the text up with
	   where the eye reads the plate's edge to be. */
	padding-inline: 0.125rem;
}

.product-card__body .price { margin-block-start: 0.3125rem; }

/* The category is a small brand-coloured label, not grey micro-type. It is one
   of the recurring places the Benis blue appears in the catalogue, and it gives
   the card a coloured anchor above the title. blue-800 is 6.92:1 on white, so
   it is legal at this size — the logo blue itself never carries text. */
.product-card__cat {
	font-size: 0.6875rem;
	font-weight: var(--weight-semibold);
	color: var(--text-link);
}

/* Medium, not regular. The title is what a shopper actually scans for, and
   dropping it to 400 to let the price "carry the only weight" left the card
   with no readable entry point. Price still outranks it, by weight not size. */
.product-card__title {
	font-size: 0.9375rem;
	font-weight: var(--weight-medium);
	line-height: var(--leading-snug);
	color: var(--text);
	/* Two-line clamp keeps every card in a row the same height regardless of
	   Persian title length, which is what stops the grid from jumping. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* The whole card is clickable via a stretched link, but only the title is the
   actual anchor — so the accessible name is the product name, not "image". */
.product-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Controls that sit above the stretched link need to outrank it. */
.product-card__wishlist,
.product-card__badges,
.product-card__actions { z-index: var(--z-raised); }

.product-card__price { margin-block-start: var(--space-1); }

/* ── Colour indicator ────────────────────────────────────────────────────── */

/* Colour indicator.
   ----------------------------------------------------------------------------
   Bare 14px dots in a row read as status lights, not as a colourway — and when
   a product's colours carry no colour meta they all fell back to the same grey,
   so the row said nothing at all.

   Swatches now OVERLAP, each cut out from its neighbour by a ring of card
   colour. That is how a colourway is shown on a real storefront: one object
   made of several colours, rather than a queue of separate dots. They are also
   bigger, because 14px cannot show a colour. */
.product-card__colors {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: var(--space-2);
	min-block-size: 1.25rem;
}

.product-card__swatch {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	border-radius: 50%;
	/* The ring is the card's own colour, so the discs read as cut out of the
	   card rather than outlined in grey. */
	box-shadow:
		0 0 0 2px var(--surface),
		0 0 0 3px rgb(15 27 42 / 0.12);
}

/* Overlap, minus the first — margin-inline-start is the RIGHT side in RTL, so
   each swatch tucks under the one before it in reading order. */
.product-card__swatch + .product-card__swatch {
	margin-inline-start: -0.5rem;
}

/* When no colour resolves, the count is stated instead. As plain grey micro-type
   it looked like a leftover string; as a small tinted chip it reads as
   information the card is choosing to give you. */
.product-card__colors-more {
	font-size: 0.6875rem;
	font-weight: var(--weight-semibold);
	color: var(--text-link);
	background-color: var(--brand-soft);
	padding-inline: var(--space-2);
	padding-block: 0.125rem;
	border-radius: var(--radius-pill);
	font-variant-numeric: proportional-nums;
}

/* ── Out of stock ────────────────────────────────────────────────────────── */

/* Dim the PRIMARY image only.
   ----------------------------------------------------------------------------
   This was `.product-card.is-outofstock .product-card__media img`, which also
   matched the second, hover-only photograph. That image is stacked absolutely
   over the first and kept at `opacity: 0` by a selector scoring (0,2,1); this
   one scores (0,3,1), so it won and forced the hidden image to 0.55 — two
   photographs of the same shoe, both half-transparent, printed on top of each
   other on every sold-out card.

   `:not(.is-hover)` takes the dim back to the image it was meant for, and the
   rule below keeps the second one out of the way for good: a product that
   cannot be bought has no reason to animate under the cursor. */
.product-card.is-outofstock .product-card__media img:not(.is-hover) { opacity: 0.55; }

.product-card.is-outofstock .product-card__media img.is-hover { opacity: 0; }

@media (hover: hover) and (pointer: fine) {
	.product-card.is-outofstock:hover .product-card__media img.is-hover { opacity: 0; }
	.product-card.is-outofstock:hover .product-card__media img:not(.is-hover) { transform: none; }
}

.product-card__stockout {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	padding-block: var(--space-2);
	text-align: center;
	background-color: rgb(15 27 42 / 0.78);
	color: var(--text-inverse);
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
}

/* ============================================================================
   PRODUCT GRID
   ----------------------------------------------------------------------------
   The canonical density for any grid of product cards — shop, category,
   search, wishlist, related. Templates use this class and never set
   --grid-min inline, which is how the homepage and the PLP previously ended up
   with different densities.

   The mobile floor is 8.5rem (136px) rather than something more generous
   because two columns must survive a 320px viewport: at 320px the content box
   is 288px, so a larger minimum silently collapses the grid to one column —
   which is exactly what 11rem did at 390px. Cards stretch via 1fr, so the
   minimum governs the column COUNT, not the rendered card width.
   ========================================================================== */

.product-grid {
	display: grid;
	gap: var(--space-4);
	grid-template-columns: repeat(auto-fill, minmax(var(--grid-min), 1fr));
	--grid-min: 8.5rem;
}

@media (min-width: 480px)  { .product-grid { --grid-min: 10.5rem; } }
@media (min-width: 768px)  { .product-grid { --grid-min: 12rem; gap: var(--space-5); } }
@media (min-width: 1280px) { .product-grid { --grid-min: 13.5rem; } }

/* ============================================================================
   PRODUCT LISTING PAGE
   ========================================================================== */

/* An editorial masthead rather than a page title. The generous block above it
   is doing real work: it separates the catalogue from the header chrome and
   gives the category a moment of its own before the grid starts. */
/* The air is a DESKTOP luxury.
   On a phone the masthead was spending 40px above the eyebrow and 32px below
   the title, on top of the breadcrumb's own block padding — so a 390×844 screen
   gave 300px to chrome before the first product, better than a third of the
   viewport, and the shopper arrived at a shop page with no shop on it. The
   editorial separation still reads at 20px when the whole column is narrow;
   it is the wide layout that needs the bigger interval to feel deliberate. */
.plp__head {
	padding-block: var(--space-5);
	border-block-end: 1px solid var(--border);
	margin-block-end: var(--space-4);
}

@media (min-width: 768px) {
	.plp__head {
		padding-block: var(--space-12) var(--space-8);
		margin-block-end: var(--space-6);
	}
}

/* Brand-blue eyebrow — the same kicker treatment the homepage sections use, so
   the PLP masthead is recognisably part of the same family. */
.plp__kicker {
	display: block;
	font-size: var(--text-caption);
	font-weight: var(--weight-semibold);
	color: var(--text-link);
	margin-block-end: var(--space-3);
}

/* Bold, not light. Persian display type at weight 300 reads as thin and
   under-set rather than editorial — the script has finer strokes than a Latin
   face at the same weight, so light weights lose the headline entirely. */
.plp__title {
	font-size: var(--text-h1);
	font-weight: var(--weight-bold);
	letter-spacing: var(--tracking-heading);
	line-height: 1.25;
}

.plp__desc {
	margin-block-start: var(--space-4);
	color: var(--text-muted);
	font-size: var(--text-label);
	font-weight: var(--weight-regular);
	line-height: var(--leading-normal);
	max-inline-size: 52ch;
}

/* ── Toolbar ─────────────────────────────────────────────────────────────── */

/* No rule under the toolbar — the masthead above already carries one, and two
   horizontal lines within 100px of each other made the page feel ruled like a
   spreadsheet. */
.plp__toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	margin-block-end: var(--space-6);
}

.plp__count {
	font-size: var(--text-caption);
	font-weight: var(--weight-medium);
	color: var(--text-muted);
	font-variant-numeric: tabular-nums;
}

.plp__count strong {
	color: var(--text);
	font-weight: var(--weight-semibold);
}

/* The sort control loses its field chrome. A bordered <select> next to a
   bordered button reads as a form; stripped back to type with a chevron it
   reads as a retail control. */
.plp__controls .select {
	border-color: transparent;
	background-color: transparent;
	background-position: left var(--space-2) center;
	padding-inline-start: var(--space-2);
	padding-inline-end: var(--space-10);
	min-block-size: 2.25rem;
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
	inline-size: auto;
}

html[dir="ltr"] .plp__controls .select {
	background-position: right var(--space-2) center;
}

.plp__controls .select:hover {
	border-color: transparent;
	color: var(--text-link);
}

.plp__controls { display: flex; align-items: center; gap: var(--space-2); }

/* The filter trigger is mobile/tablet only; desktop has the rail. */
.plp__filter-trigger { display: inline-flex; }

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

.plp__filter-count {
	display: inline-grid;
	place-items: center;
	min-inline-size: 1.25rem;
	block-size: 1.25rem;
	padding-inline: 0.25rem;
	border-radius: var(--radius-pill);
	background-color: var(--neutral-900);
	color: var(--text-inverse);
	font-size: var(--text-caption);
	font-variant-numeric: tabular-nums;
}

.plp__filter-count[data-count="0"] { display: none; }

/* ── Applied filter chips ────────────────────────────────────────────────── */

.plp__applied {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
	margin-block-end: var(--space-5);
}

.plp__applied:empty { display: none; }

/* ── Filter rail ─────────────────────────────────────────────────────────── */

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

.filters__title {
	display: flex;
	align-items: center;
	justify-content: space-between;
	inline-size: 100%;
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	min-block-size: var(--tap-target);
}

.filters__title svg {
	inline-size: 1rem;
	block-size: 1rem;
	color: var(--icon-muted);
	transition: transform var(--duration-base) var(--ease);
}

.filters__title[aria-expanded="false"] svg { transform: rotate(-90deg); }

.filters__body { padding-block-start: var(--space-2); }
.filters__body[hidden] { display: none; }

.filters__options {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	max-block-size: 15rem;
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* ── Size filter — a grid of chips, not a checkbox list ──────────────────── */

.filters__sizes {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
	gap: var(--space-2);
}

.filters__size {
	min-block-size: 2.5rem;
	display: grid;
	place-items: center;
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-sm);
	font-size: var(--text-label);
	/* Proportional: these are standalone numerals in their own box, not a
	   column to align. Tabular forces every digit to the widest advance, which
	   in Estedad visibly pulled "41" apart into "4 1". */
	font-variant-numeric: proportional-nums;
	cursor: pointer;
	transition: border-color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease);
}

.filters__size input { position: absolute; opacity: 0; pointer-events: none; }

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

.filters__size:has(input:checked) {
	background-color: var(--neutral-900);
	border-color: var(--neutral-900);
	color: var(--text-inverse);
}

.filters__size:has(input:focus-visible) {
	outline: 2px solid var(--border-focus);
	outline-offset: 2px;
}

/* ── Colour filter ───────────────────────────────────────────────────────── */

.filters__colors {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
}

.filters__color {
	position: relative;
	inline-size: 2rem;
	block-size: 2rem;
	border-radius: 50%;
	border: 1px solid rgb(15 27 42 / 0.15);
	cursor: pointer;
}

.filters__color input { position: absolute; opacity: 0; pointer-events: none; }

/* Selection is a ring, plus the swatch keeps its accessible name in a label —
   colour alone never carries the selected state. */
.filters__color:has(input:checked) {
	box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--neutral-900);
}

.filters__color:has(input:focus-visible) {
	box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--border-focus);
}

/* ── Price ───────────────────────────────────────────────────────────────── */

.filters__price-values {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
	margin-block-start: var(--space-3);
	font-size: var(--text-small);
	color: var(--text-muted);
	font-variant-numeric: tabular-nums;
}

/* ── Mobile filter sheet ─────────────────────────────────────────────────── */

.filter-sheet__actions {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: var(--space-3);
}

/* ============================================================================
   PRODUCT DETAIL PAGE
   ========================================================================== */

/* On a phone this is a single column and the gap is pure vertical cost between
   the photograph and the decision below it — 32px of nothing, on a screen where
   the 3:4 image already takes more than half the viewport and سایز was landing
   under the fold because of it. The two-column desktop layout keeps its
   generous gutter in the 1024px block below, where the gap is horizontal. */
.pdp {
	display: grid;
	gap: var(--space-5);
	padding-block-end: var(--space-10);
}

@media (min-width: 768px) {
	.pdp {
		gap: var(--space-8);
		padding-block-end: var(--space-12);
	}
}

@media (min-width: 1024px) {
	.pdp {
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
		gap: var(--space-12);
		align-items: start;
	}
}

/* ── Gallery ─────────────────────────────────────────────────────────────── */

.gallery { display: grid; gap: var(--space-3); }

/* FRAMED on a phone, not full-bleed.
   ----------------------------------------------------------------------------
   A 3:4 box at the full width of a 390px column is 474px tall. Added to the
   announcement strip, the header and the title block, that left سایز under the
   fold on every phone: the first screen of a product page showed a photograph
   and nothing a shopper could decide with. They had to scroll to find out
   whether the shoe even came in their size.

   The frame is narrowed rather than the ratio changed. 3:4 still holds exactly,
   corner to corner, so nothing is cropped — the photograph is simply presented
   inset and centred, which is the same framed treatment the campaign hero and
   the cards use. Full-bleed was never the Benis look anyway.

   76% is not a round number by accident: it is what brings the size chips, and
   the colour row behind them, above the fold on the phones this shop is
   actually opened on. */
@media (max-width: 1023px) {
	.gallery {
		/* 84%, up from 76%. The narrower frame was chosen only to pull سایز and
		   رنگ above the fold, and it did — but it left the product floating in
		   a wide band of empty canvas and reading as timid. The thumbnail row
		   below now carries part of that job, so the picture can have the width
		   back without pushing the choices off the screen. */
		max-inline-size: 84%;
		margin-inline: auto;
	}
}

/* ONE COLUMN, thumbnails underneath.
   ----------------------------------------------------------------------------
   The rail used to be a 5.5rem column beside the frame. With a 3:4 photograph
   720px tall and a catalogue that carries two or three images, that column was
   two small frames at the top and 500px of empty canvas below them — a hole
   next to the most important picture on the page, and the thumbnails read as
   loose chips floating beside the product rather than as part of it.

   A row beneath the frame has no dead space at any count, lets the thumbnails
   be larger, and centres naturally. It also removes the grid-column pinning
   that the single-image case needed. */
@media (min-width: 1024px) {
	.gallery {
		grid-template-columns: minmax(0, 1fr);
		align-items: start;
		position: sticky;
		inset-block-start: calc(var(--header-height-lg) + var(--space-4));

		/* Capped, because the frame is 3:4 and the column is wide. Left to fill
		   it the photograph came out 835px tall, and with the thumbnail row
		   under it the gallery was taller than the viewport it is supposed to
		   stick inside. At 34rem the frame is ~725px and the whole block still
		   fits a 900px laptop screen with the header above it. */
		max-inline-size: 34rem;
	}
}

/* A framed plate, like every other surface in this theme. The frame had a
   radius but no edge, so against the warm canvas a photograph with pale
   corners simply bled into the page and the product had no boundary. */
.gallery__main {
	position: relative;
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-lg);
	overflow: hidden;
	background-color: var(--surface-soft);
	border: 1px solid var(--border);
	order: -1;
}

/* No desktop override of `order`. The frame keeps the `order: -1` set above at
   every width, which is what puts it ABOVE the thumbnail row — the markup has
   the thumbnails first, so source order alone would stack them on top of the
   product. The `grid-column: 2` pin that used to live here went with the second
   column; it existed because a single-image product has no rail, so the frame
   became the grid's first item and landed in the narrow thumbnail column. */

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

/* Mobile: a swipeable track with snap points rather than a JS carousel. */
@media (max-width: 1023px) {
	.gallery__track {
		display: grid;
		grid-auto-flow: column;
		grid-auto-columns: 100%;
		gap: var(--space-2);
		overflow-x: auto;
		/* Mandatory is right HERE, unlike the content rails: this is a
		   one-image-per-frame gallery, so landing between two photographs is
		   never a valid resting position. */
		scroll-snap-type: inline mandatory;
		overscroll-behavior-inline: contain;
		scrollbar-width: none;
		border-radius: var(--radius-lg);
	}

	.gallery__track::-webkit-scrollbar { display: none; }
	.gallery__track > * { scroll-snap-align: center; }
}

.gallery__counter {
	position: absolute;
	inset-block-end: var(--space-3);
	inset-inline-end: var(--space-3);
	padding-inline: var(--space-3);
	padding-block: var(--space-1);
	border-radius: var(--radius-pill);
	background-color: rgb(15 27 42 / 0.72);
	color: var(--text-inverse);
	font-size: var(--text-caption);
	font-variant-numeric: tabular-nums;
}

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

/* ── Thumbnails — ONE component, two sizes ───────────────────────────────────
   These used to be `display: none` below 1024px, so a phone had no thumbnails
   at all: the only clue that a product had a second photograph was a small
   «۱ / ۲» pill in the corner of the frame, and the only way to reach it was to
   guess that the image could be swiped. A row of real thumbnails says both
   things at once — how many pictures there are, and that they are tappable —
   and it costs no new markup, because the buttons were always in the DOM.

   Tapping one scrolls the swipe track to that slide; swiping the track updates
   which thumbnail is marked. Both directions were already wired.
   ========================================================================== */

.gallery__thumbs {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	gap: var(--space-2);
	/* Centred under a centred frame on a phone. */
	justify-content: center;
}

.gallery__thumbs:has(> :only-child) { display: none; }

@media (min-width: 1024px) {
	.gallery__thumbs {
		gap: var(--space-3);
		/* Aligned to the frame's edge rather than centred: with two thumbnails
		   under a 540px frame, centring leaves them adrift in the middle with
		   no relationship to anything. */
		justify-content: flex-start;
	}
}

/* 88px, not 72. At 4.5rem a shoe photograph is too small to tell one angle
   from another, which is the entire job of a thumbnail — the shopper was
   clicking them to find out what they were. */
.gallery__thumb {
	/* 56px on a phone, 88px from 1024 up — see the media query below. */
	inline-size: 3.5rem;
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-md);
	overflow: hidden;
	border: 1px solid var(--border);
	background-color: var(--surface-soft);
	cursor: pointer;
	transition:
		border-color var(--duration-fast) var(--ease),
		box-shadow var(--duration-fast) var(--ease);
}

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

@media (hover: hover) {
	.gallery__thumb:hover { border-color: var(--border-strong); }
}

/* The selected frame is marked with the BRAND ring, not a black border.
   A 2px black outline on a warm canvas reads as a focus rectangle — a browser
   default someone forgot to style. The ring is drawn with box-shadow so it sits
   outside the border box and the thumbnail does not shift by a pixel when it
   becomes current, which is what a border-width change was doing to the whole
   rail every time the shopper picked a different image. */
.gallery__thumb[aria-current="true"] {
	border-color: var(--brand);
	box-shadow: 0 0 0 2px var(--brand);
}

@media (min-width: 1024px) {
	.gallery__thumb { inline-size: 5.5rem; }
}

/* ── Product info column ─────────────────────────────────────────────────── */

/* Four gaps separate the shopper from the size chips — brand, title, price,
   form — so every step down this column costs four times what it looks like.
   16px is still a clear break between blocks at 390px; 20px was buying air the
   first screen could not afford. */
.pdp__info { display: flex; flex-direction: column; gap: var(--space-4); }

@media (min-width: 768px) {
	.pdp__info { gap: var(--space-5); }
}

.pdp__brand {
	font-size: var(--text-label);
	color: var(--text-muted);
}

.pdp__title {
	font-size: var(--text-h1);
	line-height: var(--leading-tight);
}

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

.pdp__stock {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-label);
}

.pdp__stock--in { color: var(--green-700); }
.pdp__stock--low { color: var(--amber-700); }
.pdp__stock--out { color: var(--text-muted); }

.pdp__stock svg { inline-size: 1rem; block-size: 1rem; }

/* ── Variation blocks ────────────────────────────────────────────────────── */

.variation { display: flex; flex-direction: column; gap: var(--space-3); }

.variation__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3);
}

.variation__label {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
}

/* The chosen value is echoed beside the label so the current selection is
   readable without scanning the chips for the highlighted one. */
.variation__value {
	font-size: var(--text-label);
	color: var(--text-muted);
	font-weight: var(--weight-regular);
}

/* The size guide is the control that prevents the single most common reason
   for a return, so it must be easy to hit. The text stays small and quiet; the
   BOX is padded out to a thumb-sized target, and the negative inline margin
   keeps the underline visually aligned with the label opposite it. */
.variation__guide {
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
	color: var(--text-link);
	text-decoration: underline;
	text-underline-offset: 0.2em;
	padding-block: var(--space-3);
	padding-inline: var(--space-2);
	margin-inline-end: calc(-1 * var(--space-2));
	margin-block: calc(-1 * var(--space-3)) 0;
}

/* ── SIZE CHIPS ──────────────────────────────────────────────────────────
   This is the highest-impact control on the page. Sizes are always visible
   buttons — never a <select>. Availability is communicated by three things at
   once (strikethrough, muted colour, disabled state) so it never depends on
   colour alone.                                                            */

/* 3.25rem, not 3.5rem. A women's shoe run is normally six sizes (36–41), and at
   390px a 3.5rem floor fits exactly five — so the sixth dropped onto a row of
   its own and the block read as "5 sizes, plus something else". 52px still
   clears the 44px tap target comfortably, and the chips stretch to fill the row
   anyway; the floor only decides how many fit. */
.size-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(3.25rem, 1fr));
	gap: var(--space-2);
}

@media (min-width: 480px) {
	.size-grid { grid-template-columns: repeat(auto-fill, minmax(4rem, 1fr)); }
}

.size-chip {
	position: relative;
	min-block-size: 3rem;     /* comfortably over the 44px tap floor */
	display: grid;
	place-items: center;
	padding-inline: var(--space-2);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-md);
	background-color: var(--surface);
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	/* Proportional: these are standalone numerals in their own box, not a
	   column to align. Tabular forces every digit to the widest advance, which
	   in Estedad visibly pulled "41" apart into "4 1". */
	font-variant-numeric: proportional-nums;
	color: var(--text);
	cursor: pointer;
	transition: border-color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.size-chip:hover:not(:disabled) { border-color: var(--neutral-900); }

.size-chip[aria-pressed="true"] {
	background-color: var(--neutral-900);
	border-color: var(--neutral-900);
	color: var(--text-inverse);
}

.size-chip:disabled {
	cursor: not-allowed;
	color: var(--icon-muted);
	background-color: var(--surface-soft);
	border-color: var(--border);
}

/* A diagonal rule reads as "unavailable" faster than a colour change and
   survives greyscale, which a colour-only treatment would not. */
.size-chip:disabled::after {
	content: "";
	position: absolute;
	inset-inline: 0.5rem;
	inset-block-start: 50%;
	block-size: 1px;
	background-color: currentColor;
	transform: rotate(-14deg);
}

.size-chip:focus-visible {
	outline: 2px solid var(--border-focus);
	outline-offset: 2px;
}

/* ── Colour swatches ─────────────────────────────────────────────────────── */

.swatch-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }

.swatch {
	position: relative;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	border-radius: 50%;
	border: 1px solid rgb(15 27 42 / 0.15);
	cursor: pointer;
	transition: box-shadow var(--duration-fast) var(--ease);
}

.swatch[aria-pressed="true"] {
	box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--neutral-900);
}

.swatch:focus-visible {
	outline: none;
	box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--border-focus);
}

.swatch:disabled { opacity: 0.35; cursor: not-allowed; }

/* ── Validation ──────────────────────────────────────────────────────────
   The message renders directly beneath the selector it refers to, not at the
   top of the form, so the user does not have to hunt for what went wrong. */

.variation__error {
	display: none;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--danger);
}

.variation__error.is-visible { display: flex; }

.variation__error svg { inline-size: 1rem; block-size: 1rem; flex-shrink: 0; }

.variation.has-error .size-chip:not(:disabled) { border-color: var(--danger); }

/* ── Buy row ─────────────────────────────────────────────────────────────── */

.pdp__buy {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	align-items: stretch;
}

/* min-inline-size: 0 is what actually lets it shrink. A flex item's automatic
   minimum size is its min-content width, and this button's min-content is an
   icon plus "افزودن به سبد خرید" — so without this it refuses to go below about
   230px and pushes the row wider than the column. */
.pdp__buy .btn {
	flex: 1 1 auto;
	min-inline-size: 0;
}

/* Phones: the CTA gets a row to itself.
   ----------------------------------------------------------------------------
   Three controls on one line needs roughly 410px. At 390px the row overflowed
   the viewport — and because nothing clips the document any more, that pushed
   the WHOLE page sideways: the product title, the breadcrumb and the size chips
   were all cut off at the right edge. It was not a product-page bug, it was the
   page-wide symptom of one row 20px too wide.

   Quantity and wishlist share the line above, which also matches how the stepper
   is actually used — almost nobody buys two of the same shoe in the same size,
   so it does not deserve to take width away from the primary action. */
@media (max-width: 767px) {
	.pdp__buy .qty { order: 1; }

	.pdp__wishlist {
		order: 2;
		margin-inline-start: auto;
	}

	.pdp__buy .btn {
		order: 3;
		flex-basis: 100%;
	}
}

/* ── Reassurance — compact, not a wall of badges ─────────────────────────── */

.reassure {
	display: grid;
	gap: var(--space-3);
	padding: var(--space-4);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface-soft);
}

.reassure__item {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	font-size: var(--text-small);
	line-height: var(--leading-snug);
}

.reassure__item svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	color: var(--text-muted);
	flex-shrink: 0;
	margin-block-start: 0.125rem;
}

.reassure__item strong { display: block; font-weight: var(--weight-semibold); }

/* ── Sticky mobile purchase bar ──────────────────────────────────────────── */

.buy-bar {
	position: fixed;
	inset-inline: 0;
	/* Sits directly above the mobile bottom nav, never on top of it.
	   --mobile-nav-clearance, NOT --mobile-nav-height: the nav is a floating
	   pill, so the space it occupies is its tap row plus its padding, border
	   and the gap it floats above the edge. Against the height alone this bar
	   sat 22px inside the nav and its button was partly buried. */
	inset-block-end: calc(var(--mobile-nav-clearance) + var(--space-2));
	z-index: var(--z-sticky);
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-3) var(--gutter);
	background-color: var(--surface);
	border-block-start: 1px solid var(--border);
	box-shadow: 0 -4px 16px rgb(15 27 42 / 0.06);

	/* Hidden means OFF THE SCREEN, not "down a bit".
	   ------------------------------------------------------------------------
	   This was `translateY(100%)`, which slides the bar down by its own height —
	   and the bar does not start at the bottom edge, it starts a whole nav
	   clearance above it. So its resting position was not off-screen at all: it
	   landed square on top of the floating bottom nav and sat there, over the
	   navigation, on every product page, whether or not the real add-to-cart
	   button was in view. The two bugs read as one thing ("this bar is always
	   there, on top of my nav") and they were.

	   The travel now includes the offset it is inset by, so the bar clears the
	   viewport completely, and pointer-events stops the parked bar from eating
	   taps meant for the nav underneath it. */
	transform: translateY(calc(100% + var(--mobile-nav-clearance) + var(--space-2)));
	pointer-events: none;
	transition: transform var(--duration-base) var(--ease-out);
}

.buy-bar.is-visible {
	transform: none;
	pointer-events: auto;
}

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

.buy-bar__price { flex-shrink: 0; }
.buy-bar .btn { flex: 1 1 auto; }

body.has-buy-bar { padding-block-end: calc(var(--mobile-nav-clearance) + 5.5rem); }

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

/* ── Size guide table ────────────────────────────────────────────────────── */

.size-guide__table { font-size: var(--text-label); }

.size-guide__table th,
.size-guide__table td {
	padding: var(--space-3);
	border-block-end: 1px solid var(--border);
	font-variant-numeric: tabular-nums;
	text-align: start;
}

.size-guide__table thead th {
	background-color: var(--surface-soft);
	font-weight: var(--weight-semibold);
}

/* On mobile the table scrolls horizontally inside its own container rather
   than forcing the page to scroll. */
.size-guide__scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* ── Badges on the plate ─────────────────────────────────────────────────── */

.pdp__badges {
	position: absolute;
	inset-block-start: var(--space-3);
	inset-inline-start: var(--space-3);
	display: flex;
	gap: var(--space-2);
	z-index: var(--z-raised);
}

/* ── Rating ──────────────────────────────────────────────────────────────── */

.pdp__rating {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.pdp__rating:hover { color: var(--text); }

/* ── Short description ───────────────────────────────────────────────────
   Capped at the readable measure even though the buy column is already
   narrow, because on a 1440px screen the column is wide enough to run past
   it. */
.pdp__excerpt {
	color: var(--text-muted);
	line-height: var(--leading-normal);
	max-inline-size: 46ch;
}

.pdp__excerpt p + p { margin-block-start: var(--space-3); }

/* ── Variation stack ─────────────────────────────────────────────────────── */

/* The interval between سایز and رنگ is the last thing standing between the
   colour row and the fold on a phone, so it goes to 16px there. They are two
   halves of one decision, not two sections; 24px of air between them was
   spacing them apart like separate topics. */
.pdp__variations {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

@media (min-width: 768px) {
	.pdp__variations { gap: var(--space-6); }
}

/* WooCommerce's attribute selects. Present for Woo to read, never shown and
   never focusable — the chips above them are the real control. */
.variation__native { display: none; }

/* The form is a direct child of the flex info column, so it needs to carry the
   same rhythm rather than collapsing its blocks against each other. */
.pdp__info form.cart {
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}

/* Woo prints the resolved variation's price and stock line in here. It is
   redundant with the price row above on a single-attribute product, so it only
   earns space once it actually has content. */
.single_variation_wrap .single_variation:empty { display: none; }

.single_variation .price { font-size: var(--text-body-lg); }

/* The variation's own availability line. It is more precise than the
   product-level one at the top of the column — "only 2 left" is about the size
   the shopper just picked — so it is kept and styled to match rather than
   suppressed. */
.single_variation .stock,
.woocommerce-variation-availability .stock {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-label);
	color: var(--green-700);
}

.single_variation .stock.out-of-stock,
.woocommerce-variation-availability .stock.out-of-stock { color: var(--text-muted); }

/* ── Wishlist, beside the CTA ────────────────────────────────────────────── */

.pdp__wishlist { flex-shrink: 0; }

.pdp__wishlist.is-active {
	color: var(--accent);
	border-color: var(--accent);
}

/* ── Out of stock ────────────────────────────────────────────────────────── */

.pdp__oos {
	padding: var(--space-5);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface-soft);
	text-align: center;
}

.pdp__oos-title {
	font-weight: var(--weight-semibold);
	margin-block-end: var(--space-2);
}

.pdp__oos-text {
	font-size: var(--text-small);
	color: var(--text-muted);
	margin-block-end: var(--space-4);
}

/* ── Meta strip ──────────────────────────────────────────────────────────
   SKU and sharing are the quietest things in the column and sit below a
   hairline, so they read as a footnote to the buy box rather than as another
   thing to decide about. */
.pdp__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	padding-block-start: var(--space-5);
	border-block-start: 1px solid var(--border);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.pdp__sku strong {
	font-weight: var(--weight-medium);
	color: var(--text);
}

.pdp__share {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

/* ── Size guide modal contents ───────────────────────────────────────────── */

.size-guide__lead {
	color: var(--text-muted);
	line-height: var(--leading-normal);
	margin-block-end: var(--space-5);
}

.size-guide__tips {
	display: grid;
	gap: var(--space-3);
	margin-block-start: var(--space-5);
}

.size-guide__tips li {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	font-size: var(--text-small);
	line-height: var(--leading-snug);
	color: var(--text-muted);
}

.size-guide__tips svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	flex-shrink: 0;
	color: var(--brand);
	margin-block-start: 0.125rem;
}

.size-guide__tips strong { color: var(--text); font-weight: var(--weight-semibold); }

/* The EU column is the one a Persian shopper actually knows, so it is the row
   header and carries the ink; the conversions beside it stay muted. */
.size-guide__table tbody th {
	font-weight: var(--weight-semibold);
	color: var(--text);
}

.size-guide__table tbody td { color: var(--text-muted); }


/* ============================================================================
   MINI CART
   ----------------------------------------------------------------------------
   The drawer is a shopping surface, not a receipt. Each line gets a real
   product plate, a working stepper and its own subtotal; the foot carries the
   total, the shipping note and both routes out.
   ========================================================================== */

.mini-cart__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.mini-cart__item {
	position: relative;
	display: grid;
	grid-template-columns: 4.5rem minmax(0, 1fr);
	gap: var(--space-3);
	padding: var(--space-3);
	padding-inline-end: var(--space-8);
	background-color: var(--surface-soft);
	border-radius: var(--radius-lg);
}

/* The same tinted plate the product cards use, so a cart line reads as the
   same object the shopper just tapped. */
.mini-cart__media {
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-md);
	overflow: hidden;
	background: linear-gradient(168deg, var(--blue-50) 0%, var(--neutral-50) 68%);
}

.mini-cart__media img { inline-size: 100%; block-size: 100%; object-fit: cover; }

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

.mini-cart__title {
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	line-height: var(--leading-snug);
	color: var(--text);
}

/* Size and colour are not optional detail in a shoe cart — they are how the
   customer verifies the order is right. Always rendered, never truncated. */
.mini-cart__meta {
	font-size: var(--text-small);
	color: var(--text-muted);
}

.mini-cart__meta p { margin: 0; }

.mini-cart__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
	margin-block-start: var(--space-2);
}

/* ── Stepper ─────────────────────────────────────────────────────────────── */

.mini-cart__qty {
	display: inline-flex;
	align-items: center;
	background-color: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	overflow: hidden;
}

.mini-cart__step {
	inline-size: 2rem;
	block-size: 2rem;
	display: grid;
	place-items: center;
	color: var(--text-muted);
	cursor: pointer;
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.mini-cart__step:hover:not(:disabled) {
	background-color: var(--brand-soft);
	color: var(--text-link);
}

.mini-cart__step:disabled { opacity: 0.45; cursor: not-allowed; }

.mini-cart__step svg { inline-size: 0.875rem; block-size: 0.875rem; }

.mini-cart__count {
	min-inline-size: 2rem;
	text-align: center;
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
	font-variant-numeric: proportional-nums;
}

.mini-cart__price {
	font-size: var(--text-label);
	font-weight: var(--weight-bold);
	white-space: nowrap;
}

/* Remove sits in the line's own corner rather than in the row of controls, so
   destroying a line can never be mistaken for decrementing it. */
.mini-cart__remove {
	position: absolute;
	inset-block-start: var(--space-2);
	inset-inline-end: var(--space-2);
	inline-size: 1.75rem;
	block-size: 1.75rem;
	display: grid;
	place-items: center;
	border-radius: 50%;
	color: var(--icon-muted);
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

.mini-cart__remove:hover {
	background-color: var(--danger-surface);
	color: var(--danger);
}

.mini-cart__remove svg { inline-size: 0.875rem; block-size: 0.875rem; }

/* ── Foot ────────────────────────────────────────────────────────────────── */

/* Sticky, so the total and the checkout button stay reachable however long the
   cart gets — the drawer scrolls, this does not leave with it. */
.mini-cart__foot {
	position: sticky;
	inset-block-end: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin-block-start: var(--space-5);
	padding-block-start: var(--space-4);
	background-color: var(--surface);
	border-block-start: 1px solid var(--border);
}

.mini-cart__subtotal {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	font-size: var(--text-body);
	font-weight: var(--weight-semibold);
}

.mini-cart__subtotal strong {
	font-size: var(--text-h3);
	font-weight: var(--weight-bold);
}

.mini-cart__note {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.mini-cart__note svg {
	inline-size: 1rem;
	block-size: 1rem;
	color: var(--brand-active);
	flex-shrink: 0;
}

/* ── Empty ───────────────────────────────────────────────────────────────── */

.mini-cart__empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: var(--space-2);
	padding-block: var(--space-12);
}

.mini-cart__empty-icon {
	display: grid;
	place-items: center;
	inline-size: 4.5rem;
	block-size: 4.5rem;
	border-radius: 50%;
	background: linear-gradient(168deg, var(--blue-50), var(--neutral-50));
	color: var(--brand-active);
	margin-block-end: var(--space-2);
}

.mini-cart__empty-icon svg { inline-size: 1.75rem; block-size: 1.75rem; }

.mini-cart__empty-title {
	font-size: var(--text-body-lg);
	font-weight: var(--weight-bold);
}

.mini-cart__empty-text {
	font-size: var(--text-label);
	color: var(--text-muted);
	margin-block-end: var(--space-4);
}

/* ============================================================================
   CART PAGE
   ========================================================================== */

.cart-layout { display: grid; gap: var(--space-8); }

@media (min-width: 1024px) {
	.cart-layout {
		grid-template-columns: minmax(0, 1fr) 22rem;
		align-items: start;
	}

	.cart-layout__summary {
		position: sticky;
		inset-block-start: calc(var(--header-height-lg) + var(--space-4));
	}
}

.cart-item {
	display: grid;
	grid-template-columns: 5rem minmax(0, 1fr);
	gap: var(--space-4);
	padding-block: var(--space-5);
	border-block-end: 1px solid var(--border);
}

@media (min-width: 768px) {
	.cart-item {
		grid-template-columns: 6rem minmax(0, 1fr) auto;
		align-items: start;
	}
}

.cart-item__media {
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-md);
	overflow: hidden;
	background-color: var(--surface-soft);
}

.cart-item__media img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.cart-item__title { font-size: var(--text-body); font-weight: var(--weight-medium); }

.cart-item__meta {
	font-size: var(--text-small);
	color: var(--text-muted);
	margin-block-start: var(--space-1);
}

.cart-item__controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	margin-block-start: var(--space-3);
	flex-wrap: wrap;
}

@media (min-width: 768px) {
	.cart-item__controls { justify-content: flex-start; }
}

/* ── Summary ─────────────────────────────────────────────────────────────── */

.summary__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block: var(--space-2);
	font-size: var(--text-label);
}

.summary__row--total {
	padding-block-start: var(--space-4);
	margin-block-start: var(--space-2);
	border-block-start: 1px solid var(--border);
	font-size: var(--text-body-lg);
	font-weight: var(--weight-semibold);
}

.summary__label { color: var(--text-muted); }
.summary__row--total .summary__label { color: var(--text); }

.summary__value { font-variant-numeric: tabular-nums; }

/* ── Coupon ──────────────────────────────────────────────────────────────── */

.coupon { display: flex; gap: var(--space-2); }
.coupon .input { flex: 1 1 auto; }

/* ── Free-shipping progress ──────────────────────────────────────────────── */

.ship-progress__bar {
	block-size: 0.375rem;
	border-radius: var(--radius-pill);
	background-color: var(--surface-sunken);
	overflow: hidden;
	margin-block-start: var(--space-2);
}

.ship-progress__fill {
	block-size: 100%;
	border-radius: inherit;
	background-color: var(--brand);
	transition: inline-size var(--duration-slow) var(--ease-out);
}

/* ── Cart line item, continued ───────────────────────────────────────────── */

/* The price is the third column on desktop and the last thing in the body on a
   phone, where a third column would leave the title about 90px wide. */
.cart-item__price {
	font-weight: var(--weight-semibold);
	font-variant-numeric: proportional-nums;
	white-space: nowrap;
	align-self: center;
	grid-column: 2;
}

@media (min-width: 768px) {
	.cart-item__price {
		grid-column: 3;
		align-self: start;
		padding-block-start: var(--space-1);
	}
}

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

.cart-item__stock {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: var(--space-2);
	font-size: var(--text-small);
	color: var(--amber-700);
}

.cart-item__stock svg { inline-size: 1rem; block-size: 1rem; }

/* Removal is a quiet text action, not a red button. It sits beside the stepper
   because that is where someone goes when they are reconsidering the line —
   "fewer" and "none" are the same decision at different strengths. */
.cart-item__remove {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
	transition: color var(--duration-fast) var(--ease);
}

.cart-item__remove:hover { color: var(--danger); }
.cart-item__remove svg { inline-size: 1rem; block-size: 1rem; }

/* The last line has the summary below it on a phone and nothing after it on
   desktop; either way a trailing rule is a line to nowhere. */
.woocommerce-cart-form__contents > .cart-item:last-child { border-block-end: none; }

.cart-layout__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	padding-block-start: var(--space-5);
}

/* ── Free-shipping meter ─────────────────────────────────────────────────── */

.ship-progress {
	padding: var(--space-4);
	border-radius: var(--radius-lg);
	background-color: var(--surface-brand);
	margin-block-end: var(--space-5);
}

.ship-progress__text {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--blue-900);
}

.ship-progress__text svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	flex-shrink: 0;
}

.ship-progress__text strong { font-weight: var(--weight-semibold); }

/* Once the threshold is met the bar has nothing left to report, so the whole
   component switches to a completed state rather than sitting at 100%. */
.ship-progress.is-unlocked { background-color: var(--success-surface); }
.ship-progress.is-unlocked .ship-progress__text { color: var(--green-700); }
.ship-progress.is-unlocked .ship-progress__bar { display: none; }

/* ── Order summary panel ─────────────────────────────────────────────────── */

.summary { display: flex; flex-direction: column; gap: var(--space-4); }

.summary__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3);
}

.summary__title { font-size: var(--text-h3); }

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

.summary__rows {
	padding-block: var(--space-2);
	border-block-start: 1px solid var(--border);
}

/* A discount is the one row that is good news, so it is the one row that gets
   colour. Berry rather than green: green beside a price reads as a stock
   status, and this palette already uses green for availability. */
.summary__row--discount .summary__value { color: var(--accent); }

.summary__row--discount .summary__label { color: var(--text); }

.summary__remove {
	margin-inline-start: var(--space-2);
	font-size: var(--text-caption);
	color: var(--text-muted);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.summary__remove:hover { color: var(--danger); }

/* "Calculated at checkout" is a sentence, not an amount — it must not sit in
   the tabular figure column pretending to be one. */
.summary__value--note {
	font-size: var(--text-small);
	font-weight: var(--weight-regular);
	color: var(--text-muted);
	font-variant-numeric: normal;
}

.summary__assurances {
	display: grid;
	gap: var(--space-2);
	padding-block-start: var(--space-4);
	border-block-start: 1px solid var(--border);
}

.summary__assurances li {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.summary__assurances svg {
	inline-size: 1rem;
	block-size: 1rem;
	flex-shrink: 0;
	color: var(--icon-muted);
}

/* The coupon sits above the totals it changes, and its own label keeps it from
   reading as part of the summary rows. */
.coupon-field { margin-block-end: var(--space-1); }
.coupon .btn { flex-shrink: 0; }


/* ============================================================================
   CHECKOUT
   ========================================================================== */

.checkout-layout { display: grid; gap: var(--space-8); }

@media (min-width: 1024px) {
	.checkout-layout {
		grid-template-columns: minmax(0, 1fr) 24rem;
		align-items: start;
	}

	.checkout-layout__summary {
		position: sticky;
		inset-block-start: calc(var(--header-height-lg) + var(--space-4));
	}
}

.checkout-section + .checkout-section {
	margin-block-start: var(--space-8);
	padding-block-start: var(--space-8);
	border-block-start: 1px solid var(--border);
}

.checkout-section__title {
	font-size: var(--text-h3);
	margin-block-end: var(--space-5);
}

/* Checkout is a single column on mobile, full stop. Two-column name fields on
   a 390px screen are the classic source of mis-taps. */
.form-grid { display: grid; gap: var(--space-4); }

@media (min-width: 640px) {
	.form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.form-grid__full { grid-column: 1 / -1; }
}

/* ── Selectable option rows — shipping and payment ───────────────────────── */

.option-row {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-4);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-md);
	cursor: pointer;
	transition: border-color var(--duration-fast) var(--ease),
	            background-color var(--duration-fast) var(--ease);
}

.option-row + .option-row { margin-block-start: var(--space-3); }

.option-row:hover { border-color: var(--neutral-400); }

.option-row:has(input:checked) {
	border-color: var(--neutral-900);
	background-color: var(--surface-soft);
}

.option-row:has(input:focus-visible) {
	outline: 2px solid var(--border-focus);
	outline-offset: 2px;
}

.option-row__body { flex: 1 1 auto; min-inline-size: 0; }
.option-row__title { font-size: var(--text-label); font-weight: var(--weight-medium); }
.option-row__desc { font-size: var(--text-small); color: var(--text-muted); }
.option-row__price { font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }

/* ── Order review items ──────────────────────────────────────────────────── */

.review-item {
	display: grid;
	grid-template-columns: 3rem minmax(0, 1fr) auto;
	gap: var(--space-3);
	align-items: center;
	padding-block: var(--space-3);
}

.review-item + .review-item { border-block-start: 1px solid var(--border); }

.review-item__media {
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-xs);
	overflow: hidden;
	background-color: var(--surface-soft);
}

.review-item__media img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* ── Review item, continued ──────────────────────────────────────────────── */

.review-item__body { min-inline-size: 0; }

.review-item__title {
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	/* Two lines, then ellipsis. A Persian product name in a 24rem sidebar runs
	   to four lines if left alone, and the price column then floats beside a
	   paragraph. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.review-item__meta {
	font-size: var(--text-caption);
	color: var(--text-muted);
	margin-block-start: var(--space-1);
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1) var(--space-2);
}

/* Woo emits variation data as <dl><dt>/<dd>. Flattened to an inline run so
   "رنگ: قهوه‌ای" and "سایز: ۳۹" sit on one line instead of a four-row list. */
.review-item__meta dl,
.review-item__meta p { display: contents; }

/* The quantity had no rule at all, so it ran together with the variation data
   beside it — "رنگ: مشکی سایز: ۳۹ تعداد: ۱" reads as one string. It is a
   different kind of fact from the variation attributes, so it gets a separator
   rather than more text. */
.review-item__qty {
	padding-inline-start: var(--space-2);
	border-inline-start: 1px solid var(--border);
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

/* Nothing to separate from when it is the only thing on the line. */
.review-item__qty:first-child {
	padding-inline-start: 0;
	border-inline-start: 0;
}

.review-item__meta dt { font-weight: var(--weight-regular); }
.review-item__meta dt::after { content: ":"; }
.review-item__meta dd { margin-inline-end: var(--space-2); }

.review-item__price {
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
	white-space: nowrap;
	align-self: start;
}

.review-items { margin-block-end: var(--space-4); }

/* ── Shipping options ────────────────────────────────────────────────────── */

.review-shipping {
	padding-block: var(--space-4);
	border-block-start: 1px solid var(--border);
}

.review-shipping__label {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	margin-block-end: var(--space-3);
}

/* Inside the 24rem summary the rows have to be tighter than the payment rows
   in the main column, or two shipping options fill the visible panel. */
.review-shipping .option-row {
	padding: var(--space-3);
	align-items: center;
}

.shipping-options__note {
	font-size: var(--text-small);
	color: var(--text-muted);
	line-height: var(--leading-snug);
}

.shipping-options__note--warn {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	color: var(--amber-700);
}

.shipping-options__note--warn svg {
	inline-size: 1rem;
	block-size: 1rem;
	flex-shrink: 0;
	margin-block-start: 0.125rem;
}

/* ── Payment methods ─────────────────────────────────────────────────────── */

.payment-methods { display: grid; gap: var(--space-3); }

/* .option-row sets its own top margin for consecutive siblings; inside this
   grid the gap already does that job. */
.payment-method .option-row + .option-row,
.payment-methods .option-row + .option-row { margin-block-start: 0; }

.option-row__logo {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	flex-shrink: 0;
}

.option-row__logo img {
	block-size: 1.5rem;
	inline-size: auto;
	max-inline-size: 5rem;
	object-fit: contain;
}

.option-row__desc p { margin: 0; }
.option-row__desc { display: block; margin-block-start: var(--space-1); }

/* The gateway's own fields, revealed under the selected row. The inset border
   ties the box to the row above it rather than letting it float as a second
   unrelated panel. */
.payment-method__box {
	margin-block-start: var(--space-2);
	padding: var(--space-4);
	border-radius: var(--radius-md);
	background-color: var(--surface-soft);
	font-size: var(--text-small);
	color: var(--text-muted);
	line-height: var(--leading-snug);
}

.payment-method__box p:last-child { margin-block-end: 0; }

.payment-methods__empty {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	padding: var(--space-4);
	border-radius: var(--radius-md);
	background-color: var(--warning-surface);
	color: var(--amber-700);
	font-size: var(--text-small);
	line-height: var(--leading-snug);
}

.payment-methods__empty svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	flex-shrink: 0;
}

.place-order { margin-block-start: var(--space-6); }

/* Woo's terms checkbox, when the shop uses one. */
.woocommerce-terms-and-conditions-wrapper { margin-block-end: var(--space-4); }

/* ── Checkout trust strip ────────────────────────────────────────────────── */

.checkout-trust {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
	margin-block-start: var(--space-8);
	padding-block-start: var(--space-6);
	border-block-start: 1px solid var(--border);
}

@media (min-width: 640px) {
	.checkout-trust { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.checkout-trust li {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.checkout-trust svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	flex-shrink: 0;
	color: var(--brand);
}

/* A quiet inline link for "edit basket" in the summary header — not a .btn,
   because it must not read as an action competing with "place order". */
.btn--text-link {
	font-size: var(--text-small);
	color: var(--text-link);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.btn--text-link:hover { color: var(--blue-900); }

/* On a phone the summary follows the form. It is reference material while
   typing on desktop, but at 390px a panel above the first field just pushes the
   form off screen — and the totals are re-stated on the confirmation page
   anyway. */
@media (max-width: 1023px) {
	.checkout-layout__summary { order: 2; }
	.checkout-layout__main { order: 1; }
	.checkout-layout { display: flex; flex-direction: column; }
}


/* ============================================================================
   PAY FOR ORDER — the gateway hand-off (/checkout/order-pay/)
   ----------------------------------------------------------------------------
   Deliberately narrow and deliberately short. The order is already placed and
   the totals are already agreed; re-listing the basket here would invite a
   shopper to re-open a decision they have finished making. One number, one
   button.

   See woocommerce/checkout/order-receipt.php — the button itself is printed by
   the payment plugin, and its WooCommerce classes are mapped onto .btn in
   04-components.css.
   ========================================================================== */

.order-pay {
	max-inline-size: 34rem;
	margin-inline: auto;
	padding-block: var(--space-8) var(--space-10);
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}

/* The gateway-choice half of the page (form-pay.php) carries a full item list
   with thumbnails, so it needs more room than the hand-off half, which carries
   four lines and a button. Same component, one more column of breathing space. */
.order-pay--form { max-inline-size: 44rem; }

.order-pay--form #payment { margin-block-start: var(--space-6); }

.order-pay--form .place-order { margin-block-start: var(--space-5); }

.order-pay__head { text-align: center; }

.order-pay__title { font-size: var(--text-h2); }

.order-pay__lead {
	color: var(--text-muted);
	margin-block-start: var(--space-2);
	line-height: var(--leading-normal);
}

.order-pay__card {
	padding: var(--space-5);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface);
}

.order-pay__rows { gap: var(--space-3); }

/* The amount is the one thing on this page that must not be skimmed past. */
.order-pay__rows .summary__row--total .summary__value {
	font-size: var(--text-h3);
	color: var(--text-link);
}

/* THE GATEWAY'S OWN MARKUP LANDS HERE.
   We do not control what is inside — a form, a bare <input>, an anchor, and on
   a misconfigured gateway a loose text node carrying an error. So this lays out
   whatever arrives instead of assuming a structure: the flex column catches
   stray text, and the nested form gets the same treatment because plugins wrap
   their buttons about half the time. */
.order-pay__gateway,
.order-pay__gateway form {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	line-height: var(--leading-normal);
}

/* Full width, because it is the only action on the page. */
.order-pay__gateway .button {
	inline-size: 100%;
	--btn-height: 3.125rem;
	font-size: var(--text-body);
}

/* A gateway that prints raw <br> between its controls would otherwise add
   phantom rows to the flex column. */
.order-pay__gateway br { display: none; }

/* Shown when the gateway printed no button at all — see order-receipt.php.
   Deliberately NOT styled as a hard failure: the order is intact and the money
   has not moved, so this is an interruption with two ways forward, not an
   error page. The danger tint would tell the shopper something went wrong with
   their purchase, which is not what happened. */
.order-pay__error {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	padding: var(--space-5);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-lg);
	background-color: var(--surface-soft);
	text-align: center;
}

.order-pay__error p {
	color: var(--text-muted);
	font-size: var(--text-small);
	line-height: var(--leading-normal);
}

.order-pay__note {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	font-size: var(--text-small);
	color: var(--text-muted);
	text-align: center;
}

.order-pay__note svg {
	inline-size: 1rem;
	block-size: 1rem;
	flex-shrink: 0;
}


/* ============================================================================
   ORDER CONFIRMATION
   ========================================================================== */

.order-success {
	text-align: center;
	padding-block: var(--space-10) var(--space-8);
}

.order-success__icon {
	inline-size: 3.5rem;
	block-size: 3.5rem;
	margin-inline: auto;
	margin-block-end: var(--space-4);
	display: grid;
	place-items: center;
	border-radius: 50%;
	background-color: var(--success-surface);
	color: var(--green-700);
}

.order-success__icon svg { inline-size: 1.75rem; block-size: 1.75rem; }

.order-success__title { font-size: var(--text-h1); }

.order-success__text {
	color: var(--text-muted);
	margin-block-start: var(--space-2);
	max-inline-size: 46ch;
	margin-inline: auto;
}

.order-meta {
	display: grid;
	gap: var(--space-4);
	grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
	padding: var(--space-5);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface-soft);
	text-align: start;
}

.order-meta__label {
	font-size: var(--text-caption);
	color: var(--text-muted);
	margin-block-end: var(--space-1);
}

.order-meta__value {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	font-variant-numeric: tabular-nums;
	word-break: break-word;
}

/* Failure is not a variant of success: the tick becomes a cross and the surface
   drops the green entirely, so a failed payment can never be skimmed as a
   completed one. */
.order-success__icon--failed {
	background-color: var(--danger-surface);
	color: var(--red-700);
}

.order-success__steps {
	justify-content: center;
	margin-block-start: var(--space-6);
}

.order-detail {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	max-inline-size: 48rem;
	margin-inline: auto;
}

.order-detail__section { display: block; }

.order-address {
	font-style: normal;
	line-height: var(--leading-normal);
	color: var(--text-muted);
}

.order-address__phone {
	margin-block-start: var(--space-2);
	color: var(--text);
	font-weight: var(--weight-medium);
}

/* The confirmation reuses .review-item inside a panel, where the panel already
   supplies the outer padding — so the first and last rows should not add their
   own. */
.panel > .review-item:first-child { padding-block-start: 0; }

/* ── Single order view ───────────────────────────────────────────────────── */

.order-view { display: flex; flex-direction: column; gap: var(--space-8); }

.order-view__status { display: flex; flex-direction: column; gap: var(--space-2); }

.order-view__status-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
}

.order-view__eyebrow {
	display: block;
	font-size: var(--text-small);
	color: var(--text-muted);
}

.order-view__status-label {
	font-size: var(--text-h3);
	font-weight: var(--weight-semibold);
}

.order-view__status .btn { align-self: flex-start; margin-block-start: var(--space-3); }

/* The shop's notes to the customer, as a timeline. The rule down the inline
   edge is what turns a list of paragraphs into a sequence of events. */
.order-notes {
	display: grid;
	gap: var(--space-5);
	padding-inline-start: var(--space-5);
	border-inline-start: 2px solid var(--border);
}

.order-notes__item { position: relative; }

.order-notes__item::before {
	content: "";
	position: absolute;
	inset-inline-start: calc(-1 * var(--space-5) - 5px);
	inset-block-start: 0.45rem;
	inline-size: 0.5rem;
	block-size: 0.5rem;
	border-radius: 50%;
	background-color: var(--brand);
}

.order-notes__time {
	display: block;
	font-size: var(--text-caption);
	color: var(--text-muted);
	font-variant-numeric: tabular-nums;
}

.order-notes__body {
	margin-block-start: var(--space-1);
	font-size: var(--text-label);
	line-height: var(--leading-snug);
}

.order-notes__body p:last-child { margin-block-end: 0; }

.order-details,
.order-details__customer { display: block; }

.order-details__customer { margin-block-start: var(--space-8); }

.address-card__phone {
	display: block;
	margin-block-start: var(--space-2);
	color: var(--text);
	font-weight: var(--weight-medium);
}

/* A purchase note is shop guidance attached to the product — care, sizing.
   Tinted so it reads as a message rather than as more product metadata. */
.review-item__note {
	margin-block-start: var(--space-2);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-xs);
	background-color: var(--surface-brand);
	font-size: var(--text-caption);
	color: var(--blue-900);
	line-height: var(--leading-snug);
}

.review-item__note p:last-child { margin-block-end: 0; }

.account-form__foot {
	margin-block-start: var(--space-8);
	padding-block-start: var(--space-6);
	border-block-start: 1px solid var(--border);
}

/* ============================================================================
   ACCOUNT
   ========================================================================== */

/* `minmax(0, 1fr)`, not the implicit `auto` column. The menu below is a
   horizontal scroller whose flex row is ~700px wide at any viewport; an `auto`
   track is floored by that min-content size, so the single mobile column grew
   to 700px and dragged the whole account page into horizontal overflow — the
   scroller never scrolled because it was never constrained. `min-width: 0` on
   the items is the same guard one level down. */
.account-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-6);
}

.account-layout__nav,
.account-layout__content { min-inline-size: 0; }

@media (min-width: 1024px) {
	.account-layout {
		grid-template-columns: 16rem minmax(0, 1fr);
		gap: var(--space-8);
		align-items: start;
	}
}

/* Mobile: the account menu is a horizontal scroller, not a stacked list that
   pushes the actual content below the fold.

   It bleeds to the screen edges. A scroller that stops at the gutter looks
   like a menu that was cut off by a bug; one that runs off the edge of the
   screen, with the last item fading out, reads as a menu that continues. The
   negative margin is exactly the container's own padding and the same value
   returns as padding, so the FIRST item still lines up with the page's
   content edge. */
.account-nav {
	display: flex;
	gap: var(--space-2);
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	/* Proximity, matching .rail: a deliberate horizontal swipe snaps, a
	   vertical page scroll that clips this row is left alone. */
	scroll-snap-type: inline proximity;
	scrollbar-width: none;
	padding-block-end: var(--space-2);
	border-block-end: 1px solid var(--border);

	margin-inline: calc(var(--gutter) * -1);
	padding-inline: var(--gutter);
	scroll-padding-inline: var(--gutter);

}

/* The trailing edge fades so the clipped item reads as "there is more" rather
   than as a word that got chopped. Gated on a class benis-ui.js sets only when
   the row genuinely overflows — a fade over a menu that already fits dims a
   real item for no reason. Masks take physical directions, so the writing
   direction is spelled out. */
.account-nav.is-scrollable {
	-webkit-mask-image: linear-gradient(to left, #000 calc(100% - 2.5rem), transparent);
	        mask-image: linear-gradient(to left, #000 calc(100% - 2.5rem), transparent);
}

[dir="ltr"] .account-nav.is-scrollable {
	-webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
	        mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
}

.account-nav::-webkit-scrollbar { display: none; }

.account-nav__link { scroll-snap-align: start; }

@media (min-width: 1024px) {
	.account-nav {
		flex-direction: column;
		overflow: visible;
		border-block-end: none;
		padding-block-end: 0;
		margin-inline: 0;
		padding-inline: 0;
		-webkit-mask-image: none;
		        mask-image: none;
	}
}

.account-nav__link {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	/* Never shrink: a flex item that squeezes turns the scroller into five
	   half-legible labels instead of a row you can push. */
	flex: 0 0 auto;
	padding-inline: var(--space-4);
	min-block-size: var(--tap-target);
	border-radius: var(--radius-md);
	font-size: var(--text-label);
	font-weight: var(--weight-medium);
	color: var(--text-muted);
	white-space: nowrap;
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

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

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

.account-nav__link.is-active {
	background-color: var(--neutral-900);
	color: var(--text-inverse);
}

/* ── Orders ──────────────────────────────────────────────────────────────── */

.order-card {
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: var(--space-5);
}

.order-card + .order-card { margin-block-start: var(--space-4); }

.order-card__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block-end: var(--space-4);
	border-block-end: 1px solid var(--border);
}

.order-card__number {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	font-variant-numeric: tabular-nums;
}

.order-card__date { font-size: var(--text-small); color: var(--text-muted); }

.order-card__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block-start: var(--space-4);
}

/* Thumbnails of what was ordered — far more scannable than a text list. */
.order-card__thumbs { display: flex; gap: var(--space-2); }

.order-card__thumb {
	inline-size: 2.75rem;
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-xs);
	overflow: hidden;
	background-color: var(--surface-soft);
}

.order-card__thumb img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* ── Identity band ───────────────────────────────────────────────────────────
   Constant across every account endpoint, so moving between orders and
   addresses never loses the anchor. It sits on the page canvas rather than in
   a card: it is a label for this whole area, not an object inside it. */

.account-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	padding-block: var(--space-4) var(--space-5);
}

/* This band repeats above every endpoint, so on a phone its height is a tax
   paid on each page. Tightened here and given its desktop room back below. */
@media (min-width: 1024px) {
	.account-head {
		gap: var(--space-6);
		padding-block: var(--space-8) var(--space-6);
	}
}

.account-head__id {
	display: flex;
	align-items: center;
	gap: var(--space-4);
	min-inline-size: 0;
}

/* A monogram, not a photo upload. The shop has no avatars and Gravatar on a
   synthetic phone-based email address returns the same grey silhouette for
   every customer — an initial in brand blue is at least theirs. */
.account-head__avatar {
	display: grid;
	place-items: center;
	inline-size: 3rem;
	block-size: 3rem;
	border-radius: 50%;
	background-color: var(--brand);
	color: var(--text-on-brand);
	font-size: var(--text-body-lg);
	font-weight: var(--weight-bold);
	flex-shrink: 0;
}

@media (min-width: 640px) {
	.account-head__avatar {
		inline-size: 3.5rem;
		block-size: 3.5rem;
		font-size: var(--text-h3);
	}
}

.account-head__name {
	display: block;
	font-size: var(--text-h3);
	line-height: var(--leading-tight);
}

.account-head__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1) var(--space-3);
	margin-block-start: var(--space-1);
	font-size: var(--text-small);
	color: var(--text-muted);
}

/* A separator between the meta items, drawn rather than typed, so it never
   becomes a stray character when one of the two is missing. */
.account-head__meta > * + *::before {
	content: "·";
	margin-inline-end: var(--space-3);
	color: var(--icon-muted);
}

/* ── Stats ───────────────────────────────────────────────────────────────── */

/* On a phone these numbers are ONE object, not three or four loose chips.
   Bordered chips with their own gaps wrapped into an uneven 2 + 1 (or 2 + 1 + 1
   once the "in progress" count appears), and the arrangement changed under the
   customer as orders came and went. A single card divided by hairlines reads
   the same at every count. */
.account-stats {
	display: flex;
	flex-wrap: wrap;
	/* The dividers ARE the gap: the card's own background shows through a
	   1px seam. Every cell grows, so a wrapped row is always filled edge to
	   edge and the seam can never widen into a visible block. */
	gap: 1px;
	inline-size: 100%;
	background-color: var(--border);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	overflow: hidden;
}

/* Label and number share ONE line on a phone. Stacked, three of them cost
   about 140px of an 812px screen before the customer reaches anything they
   came for — and this band repeats above every endpoint. Inline they cost
   44px and say exactly the same thing. */
.account-stats__item {
	display: flex;
	align-items: baseline;
	justify-content: center;
	gap: var(--space-2);
	flex: 1 1 auto;
	min-inline-size: 0;
	padding: var(--space-3);
	background-color: var(--surface);
}

.account-stats__item dt {
	font-size: var(--text-caption);
	color: var(--text-muted);
	white-space: nowrap;
}

.account-stats__item dd {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
	white-space: nowrap;
}

/* From tablet up there is room to stack again, the card shrinks to its numbers
   and sits opposite the name instead of stretching half-a-screen-wide cells
   across 768px. */
@media (min-width: 640px) {
	.account-stats { inline-size: auto; }

	.account-stats__item {
		display: block;
		flex: 0 1 auto;
		min-inline-size: 5.5rem;
		padding: var(--space-3) var(--space-4);
	}

	.account-stats__item dd {
		font-size: var(--text-body-lg);
		margin-block-start: var(--space-1);
	}
}

/* "In progress" is the only number on this row that can change today, so it is
   the only one that gets the brand tint. */
.account-stats__item--live {
	background-color: var(--surface-brand);
}

.account-stats__item--live dd { color: var(--blue-900); }

@media (min-width: 640px) {
	.account-stats__item--wide dd { font-size: var(--text-body); }
}

/* ── Secondary links under the nav ───────────────────────────────────────── */

.account-links {
	display: none;
	margin-block-start: var(--space-6);
	padding-block-start: var(--space-5);
	border-block-start: 1px solid var(--border);
}

/* Desktop only. On a phone the nav is already a scroller and these three are
   reachable from the bottom bar, so repeating them would just add a column of
   links between the menu and the content. */
@media (min-width: 1024px) {
	.account-links {
		display: grid;
		gap: var(--space-1);
	}
}

.account-links__item {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding-inline: var(--space-4);
	min-block-size: 2.5rem;
	border-radius: var(--radius-md);
	font-size: var(--text-small);
	color: var(--text-muted);
	transition: background-color var(--duration-fast) var(--ease),
	            color var(--duration-fast) var(--ease);
}

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

.account-links__item svg { inline-size: 1rem; block-size: 1rem; }

.account-links__item em {
	margin-inline-start: auto;
	font-style: normal;
	font-size: var(--text-caption);
	font-weight: var(--weight-semibold);
	color: var(--blue-800);
}

/* Signing out is the one destructive item in the menu. */
.account-nav__link--out { color: var(--text-muted); }
.account-nav__link--out:hover { color: var(--danger); background-color: var(--danger-surface); }

/* ── Endpoint content ────────────────────────────────────────────────────── */

.account-content__head { margin-block-end: var(--space-5); }

.account-content__title {
	font-size: var(--text-h3);
	letter-spacing: var(--tracking-heading);
}

.account-content__sub {
	margin-block-start: var(--space-1);
	color: var(--text-muted);
	font-size: var(--text-small);
}

/* The endpoint title only has to outrank the panel headings under it. At h2 on
   a phone it competed with the customer's own name in the band above and with
   "آخرین سفارش‌ها" right below, so three lines of heading stacked before any
   content. It gets its full size back where the column is wide. */
@media (min-width: 1024px) {
	.account-content__head { margin-block-end: var(--space-6); }
	.account-content__title { font-size: var(--text-h2); }
	.account-content__sub {
		margin-block-start: var(--space-2);
		font-size: var(--text-label);
	}
}

.account-intro {
	color: var(--text-muted);
	font-size: var(--text-label);
	margin-block-end: var(--space-5);
	max-inline-size: 52ch;
}

.account-panels { display: flex; flex-direction: column; gap: var(--space-8); }

.account-panel__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-4);
	margin-block-end: var(--space-4);
}

.account-panel__title { font-size: var(--text-h3); }

.account-panel__more {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	font-size: var(--text-small);
	color: var(--text-link);
	white-space: nowrap;
}

.account-panel__more svg { inline-size: 1rem; block-size: 1rem; }

/* ── Notice card — the "you owe us money" banner ─────────────────────────── */

.notice-card {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-4);
	padding: var(--space-5);
	border-radius: var(--radius-lg);
	background-color: var(--warning-surface);
}

.notice-card__icon {
	display: grid;
	place-items: center;
	inline-size: 2.5rem;
	block-size: 2.5rem;
	border-radius: 50%;
	background-color: var(--surface);
	color: var(--amber-700);
	flex-shrink: 0;
}

.notice-card__icon svg { inline-size: 1.25rem; block-size: 1.25rem; }

.notice-card__body { flex: 1 1 14rem; min-inline-size: 0; }
.notice-card__body strong { display: block; color: var(--amber-700); }

.notice-card__body p {
	font-size: var(--text-small);
	color: var(--text-muted);
	margin-block-start: var(--space-1);
}

/* ── Order progress track ────────────────────────────────────────────────── */

.order-track {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	gap: var(--space-2);
	margin-block: var(--space-4);
}

.order-track__step {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	font-size: var(--text-caption);
	color: var(--text-muted);
}

/* The dot is a full-width bar, not a circle: a row of four bars reads as a
   progress meter at a glance, where four dots read as bullet points. */
.order-track__dot {
	block-size: 0.25rem;
	border-radius: var(--radius-pill);
	background-color: var(--surface-sunken);
}

.order-track__step.is-done .order-track__dot { background-color: var(--green-500); }
.order-track__step.is-done .order-track__label { color: var(--text-muted); }

.order-track__step.is-now .order-track__dot { background-color: var(--brand); }

.order-track__step.is-now .order-track__label {
	color: var(--text);
	font-weight: var(--weight-semibold);
}

/* ── Order card, continued ───────────────────────────────────────────────── */

.order-card__number:hover { color: var(--text-link); }

.order-card__date { display: block; margin-block-start: var(--space-1); }

.order-card__thumb {
	position: relative;
	flex-shrink: 0;
}

.order-card__qty {
	position: absolute;
	inset-block-end: -0.25rem;
	inset-inline-end: -0.25rem;
	min-inline-size: 1.125rem;
	padding-inline: 0.25rem;
	border-radius: var(--radius-pill);
	background-color: var(--neutral-900);
	color: var(--text-inverse);
	font-size: 0.625rem;
	font-style: normal;
	font-weight: var(--weight-semibold);
	text-align: center;
	line-height: 1.125rem;
}

.order-card__thumb--more {
	display: grid;
	place-items: center;
	background-color: var(--surface-sunken);
	color: var(--text-muted);
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
}

.order-card__total {
	text-align: end;
	margin-inline-start: auto;
}

.order-card__total em {
	display: block;
	font-style: normal;
	font-size: var(--text-caption);
	color: var(--text-muted);
}

.order-card__total strong {
	font-size: var(--text-label);
	font-weight: var(--weight-semibold);
}

.order-card__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin-block-start: var(--space-4);
	padding-block-start: var(--space-4);
	border-block-start: 1px solid var(--border);
}

.order-list { display: block; }

/* ── Wishlist strip on the dashboard ─────────────────────────────────────── */

.fav-strip {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 8rem;
	gap: var(--space-3);
	overflow-x: auto;
	scrollbar-width: none;
	padding-block-end: var(--space-2);
}

.fav-strip::-webkit-scrollbar { display: none; }

.fav-strip__media {
	position: relative;
	display: block;
	aspect-ratio: var(--ratio-product);
	border-radius: var(--radius-md);
	overflow: hidden;
	background-color: var(--surface-soft);
}

.fav-strip__media img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.fav-strip__oos {
	position: absolute;
	inset-block-end: var(--space-2);
	inset-inline: var(--space-2);
	padding-block: 0.125rem;
	border-radius: var(--radius-xs);
	background-color: rgb(15 27 42 / 0.78);
	color: var(--text-inverse);
	font-size: var(--text-caption);
	font-style: normal;
	text-align: center;
}

.fav-strip__name {
	display: block;
	margin-block-start: var(--space-2);
	font-size: var(--text-small);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.fav-strip__price {
	display: block;
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
}

.fav-strip__price del { display: none; }

/* ── Address cards ───────────────────────────────────────────────────────── */

.address-grid {
	display: grid;
	gap: var(--space-4);
}

@media (min-width: 640px) {
	.address-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.address-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-5);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface);
}

/* An unset address gets a dashed edge — it reads as a slot waiting to be
   filled rather than as a card that failed to load. */
.address-card.is-empty {
	border-style: dashed;
	background-color: transparent;
}

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

.address-card__kind svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	color: var(--icon-muted);
}

.address-card address {
	font-style: normal;
	font-size: var(--text-small);
	line-height: var(--leading-normal);
	color: var(--text-muted);
	flex: 1 1 auto;
}

.address-card__none {
	font-size: var(--text-small);
	color: var(--text-muted);
	flex: 1 1 auto;
}

/* ── Shortcut tiles ──────────────────────────────────────────────────────── */

.tile-grid {
	display: grid;
	gap: var(--space-3);
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 768px) {
	.tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.tile {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	padding: var(--space-4);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface);
	transition: border-color var(--duration-fast) var(--ease),
	            box-shadow var(--duration-fast) var(--ease);
}

.tile:hover {
	border-color: var(--brand);
	box-shadow: var(--shadow-sm);
}

.tile svg {
	inline-size: 1.25rem;
	block-size: 1.25rem;
	color: var(--brand);
	margin-block-end: var(--space-1);
}

.tile strong { font-size: var(--text-label); font-weight: var(--weight-semibold); }
.tile span { font-size: var(--text-caption); color: var(--text-muted); }

.tile--out:hover { border-color: var(--danger); }
.tile--out svg { color: var(--icon-muted); }


/* ============================================================================
   AUTH
   ========================================================================== */

.auth {
	max-inline-size: 26rem;
	margin-inline: auto;
	padding-block: var(--space-12);
}

.auth__title { font-size: var(--text-h2); text-align: center; }

.auth__sub {
	text-align: center;
	color: var(--text-muted);
	font-size: var(--text-label);
	margin-block-start: var(--space-2);
	margin-block-end: var(--space-8);
}

.auth__switch {
	text-align: center;
	margin-block-start: var(--space-6);
	font-size: var(--text-label);
	color: var(--text-muted);
}

.auth__switch a { color: var(--text-link); font-weight: var(--weight-medium); }

/* The split screen. The aside is not decoration — it answers "why sign in?"
   with what an account actually gives you here. Below 1024px it is removed
   rather than stacked: on a phone the only thing that should be on screen is
   the two fields and the button. */
.auth-split {
	display: grid;
	gap: var(--space-8);
	align-items: center;
	padding-block: var(--space-8);
}

/* WooCommerce places the account form directly under main, without a
   container. Give it the same phone gutter as the rest of the storefront. */
@media (max-width: 639px) {
	.woocommerce-account .auth-split { padding-inline: var(--gutter); }
}

@media (min-width: 1024px) {
	.auth-split {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: var(--space-16);
		padding-block: var(--space-16);
	}
}

.auth-split__aside {
	display: none;
	padding: var(--space-10);
	border-radius: var(--radius-2xl);
	background-color: var(--surface-brand);
}

@media (min-width: 1024px) {
	.auth-split__aside { display: block; }
}

.auth-split__eyebrow {
	display: block;
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
	color: var(--blue-800);
	margin-block-end: var(--space-3);
}

.auth-split__title {
	font-size: var(--text-h1);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-heading);
	color: var(--blue-900);
}

.auth-split__text {
	margin-block-start: var(--space-4);
	color: var(--neutral-700);
	line-height: var(--leading-normal);
	max-inline-size: 36ch;
}

.auth-split__points {
	display: grid;
	gap: var(--space-4);
	margin-block-start: var(--space-8);
}

.auth-split__points li {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	font-size: var(--text-label);
	color: var(--neutral-800);
}

.auth-split__points svg {
	inline-size: 1.25rem;
	block-size: 1.25rem;
	color: var(--blue-700);
	flex-shrink: 0;
}

/* Inside the split the card is already centred by the grid, so it drops the
   auto margins and the vertical padding it uses when standing alone. */
.auth-split .auth {
	padding-block: 0;
	inline-size: 100%;
}

.auth__form { display: grid; gap: var(--space-5); }

.auth__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	font-size: var(--text-small);
}

/* Both of these are real destinations, not footnotes — "forgot your password"
   is the entire recovery path — so they get a thumb-sized row rather than a
   23px line of text. */
.auth__meta a {
	color: var(--text-link);
	display: inline-flex;
	align-items: center;
	min-block-size: 2.5rem;
}

.auth__meta a:hover { text-decoration: underline; }

.auth__switch a {
	display: inline-flex;
	align-items: center;
	min-block-size: 2.5rem;
}

/* ── Password field with a reveal control ────────────────────────────────── */

.password { position: relative; }

/* Room for the button, on the inline-end edge — which is the LEFT in this
   document, so the padding has to be logical rather than padding-right. */
.password .input { padding-inline-end: var(--tap-target); }

.password__toggle {
	position: absolute;
	inset-inline-end: 0;
	inset-block-start: 0;
	inline-size: var(--tap-target);
	block-size: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--icon-muted);
	background: none;
	border: none;
	cursor: pointer;
	transition: color var(--duration-fast) var(--ease);
}

.password__toggle:hover { color: var(--text); }
.password__toggle svg { inline-size: 1.125rem; block-size: 1.125rem; }

.password__toggle[aria-pressed="true"] { color: var(--text-link); }

/* ============================================================================
   WISHLIST
   ========================================================================== */

.wishlist-grid { --grid-min: 13rem; }

/* ============================================================================
   WOOCOMMERCE RESETS
   ----------------------------------------------------------------------------
   WooCommerce ships markup this theme cannot fully template away. Rather than
   fighting each instance with !important in a later layer, the leaking pieces
   are neutralised once, here, at the source.
   ========================================================================== */

.woocommerce-notices-wrapper:empty { display: none; }

/* ── Notices ─────────────────────────────────────────────────────────────
   Woo's error, success and info messages had no rules at all, so every
   "coupon applied", "please choose a size" and failed sign-in rendered as a
   bare bulleted list in the browser default face — on the cart, the checkout,
   the account and the sign-in screen alike.

   Each state pairs its colour with a leading glyph, so none of the three
   depends on colour alone to be told apart. */
.woocommerce-error,
.woocommerce-message,
.woocommerce-info,
.woocommerce-noreviews {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	padding: var(--space-4) var(--space-5);
	border-radius: var(--radius-md);
	border-inline-start: 3px solid;
	font-size: var(--text-label);
	line-height: var(--leading-snug);
	margin-block-end: var(--space-5);
	list-style: none;
}

.woocommerce-error li,
.woocommerce-message li,
.woocommerce-info li {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
}

.woocommerce-error li::before,
.woocommerce-message li::before,
.woocommerce-info li::before {
	flex-shrink: 0;
	font-weight: var(--weight-bold);
	/* Latin glyphs inside an RTL run: without their own direction context the
	   bidi algorithm can park them at the wrong end of the line. */
	direction: ltr;
}

.woocommerce-error {
	background-color: var(--danger-surface);
	border-color: var(--red-500);
	color: var(--red-700);
}

.woocommerce-error li::before { content: "!"; }

.woocommerce-message {
	background-color: var(--success-surface);
	border-color: var(--green-500);
	color: var(--green-700);
}

.woocommerce-message li::before { content: "\2713"; }

.woocommerce-info,
.woocommerce-noreviews {
	background-color: var(--surface-brand);
	border-color: var(--blue-400);
	color: var(--blue-900);
}

.woocommerce-info li::before { content: "i"; font-style: italic; }

/* Woo puts a "view basket" / "sign in" button inside some notices. It must not
   arrive as a full-width block shoving the message aside. */
.woocommerce-error .button,
.woocommerce-message .button,
.woocommerce-info .button {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	min-block-size: 2.25rem;
	padding-inline: var(--space-4);
	border-radius: 10px;
	background-color: var(--action);
	color: var(--action-text);
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
}

.woocommerce-error a:not(.button),
.woocommerce-message a:not(.button),
.woocommerce-info a:not(.button) {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	font-weight: var(--weight-semibold);
}


/* Woo's default breadcrumb, result count and ordering markup are replaced by
   this theme's own toolbar; the originals are unhooked in PHP, and these
   rules only catch instances rendered by plugins we do not control. */
.woocommerce-breadcrumb,
.woocommerce-result-count,
.woocommerce-ordering { margin: 0; }

/* The star rating font ships with Woo; only its colour needs aligning. */
.star-rating { color: var(--amber-500); }

.screen-reader-text {
	position: absolute !important;   /* Woo core class; must win over plugin CSS */
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ============================================================================
   QUICK VIEW
   ----------------------------------------------------------------------------
   A two-column dialog on desktop, stacked on mobile. It deliberately shows LESS
   than the product page: one image, the essentials, and a route to the full
   page. A quick view that tries to be the PDP is just a worse PDP in a box.
   ========================================================================== */

/* NOTHING here scrolls.
   ----------------------------------------------------------------------------
   The panel used to be a grid of intrinsically sized rows: a 3:4 image at the
   full width of a 375px sheet is 457px tall on its own, so the contents ran
   past the bottom and the "quick" view had to be scrolled before the price was
   even visible. It is a flex column now, and the IMAGE is the flexible part —
   it takes whatever height is left after the words and the buttons, so the
   whole panel always ends where the sheet ends. */
.quickview {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	min-block-size: 0;
}

/* Below the two-column breakpoint the sheet is given a DEFINITE height and the
   photograph absorbs whatever the words and buttons leave over. Without a
   definite height there is nothing for the image to flex against, so the panel
   sizes to its contents — which is how a 3:4 image at the full width of a
   375px screen (457px of it) pushed the price and the button off the bottom
   and turned a glance into a scroll. */
@media (max-width: 719px) {
	#quick-view .modal__panel { block-size: 85svh; }

	#quick-view .overlay__body {
		display: flex;
		overflow: hidden;
	}

	#quick-view .quickview { flex: 1 1 auto; }
}

@media (min-width: 720px) {
	.quickview {
		display: grid;
		grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
		gap: var(--space-6);
		align-items: start;
	}
}

.quickview__media {
	overflow: hidden;
	border-radius: var(--radius-lg);
	background: linear-gradient(168deg, var(--blue-50) 0%, var(--neutral-50) 68%);
	/* Shrinks to fit, never below the point where it stops being a photograph. */
	flex: 1 1 auto;
	min-block-size: 7rem;
}

@media (min-width: 720px) {
	.quickview__media {
		flex: none;
		aspect-ratio: var(--ratio-product);
	}
}

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

/* Same reasoning as the card: the branded placeholder is a finished tile with
   its own ground, so it covers rather than being inset inside another panel. */
.quickview__placeholder { object-fit: cover; }

.quickview__info {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	flex: 0 0 auto;
}

.quickview__cat {
	font-size: var(--text-caption);
	font-weight: var(--weight-semibold);
	color: var(--text-link);
}

.quickview__title {
	font-size: var(--text-h3);
	font-weight: var(--weight-bold);
	line-height: var(--leading-tight);
}

/* Two lines, then an ellipsis. The panel has a fixed budget and a long excerpt
   would spend it by squeezing the photograph instead of itself. */
.quickview__desc {
	color: var(--text-muted);
	font-size: var(--text-label);
	line-height: var(--leading-normal);
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
}

@media (min-width: 720px) {
	.quickview__desc {
		-webkit-line-clamp: 4;
		line-clamp: 4;
	}
}

.quickview__row {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-3);
}

.quickview__label {
	font-size: var(--text-small);
	font-weight: var(--weight-semibold);
	color: var(--text-muted);
	min-inline-size: 2.5rem;
}

.quickview__colors {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.quickview__dot {
	inline-size: 1.25rem;
	block-size: 1.25rem;
	border-radius: 50%;
	border: 1px solid rgb(15 27 42 / 0.16);
}

.quickview__actions {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin-block-start: var(--space-2);
}

.quickview__oos {
	color: var(--text-muted);
	font-size: var(--text-label);
}

.quickview__loading {
	display: grid;
	place-items: center;
	min-block-size: 14rem;
}

/* The `.quickview__size` chip and its selected / sold-out / armed states lived
   here. Sizes moved to the product page, so the rules went with them rather
   than staying as styling for markup nothing emits any more. */

/* ============================================================================
   REVIEWS
   ----------------------------------------------------------------------------
   The card here is `.review-card`, deliberately NOT `.review-item` — that name
   belongs to the order line-item grid used by the checkout summary and the
   order pages. The two collided before, and reviews were being laid out as
   order rows.
   ========================================================================== */

.reviews { display: grid; gap: var(--space-8); }

.reviews__summary {
	display: grid;
	gap: var(--space-6);
	padding: var(--space-6);
	border-radius: var(--radius-lg);
	background-color: var(--surface-soft);
}

@media (min-width: 640px) {
	.reviews__summary {
		grid-template-columns: auto minmax(0, 1fr);
		gap: var(--space-10);
		align-items: center;
	}
}

.reviews__average { text-align: center; }

.reviews__score {
	font-size: var(--text-display);
	font-weight: var(--weight-bold);
	line-height: 1;
	font-variant-numeric: proportional-nums;
}

.reviews__count {
	font-size: var(--text-small);
	color: var(--text-muted);
	margin-block-start: var(--space-2);
}

.reviews__average .star-rating { margin-inline: auto; margin-block-start: var(--space-2); }

.reviews__bars { display: grid; gap: var(--space-2); }

.reviews__bar {
	display: grid;
	grid-template-columns: 1.5rem minmax(0, 1fr) 2rem;
	align-items: center;
	gap: var(--space-3);
	font-size: var(--text-small);
	color: var(--text-muted);
}

.reviews__bar-track {
	block-size: 0.375rem;
	border-radius: var(--radius-pill);
	background-color: var(--surface-sunken);
	overflow: hidden;
}

.reviews__bar-fill {
	display: block;
	block-size: 100%;
	border-radius: inherit;
	background-color: var(--amber-500);
}

.reviews__bar-count { text-align: end; font-variant-numeric: tabular-nums; }

/* ── A review ────────────────────────────────────────────────────────────── */

.reviews__list { display: grid; gap: var(--space-5); }

.review-card {
	padding: var(--space-5);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--surface);
}

.review-card__head {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin-block-end: var(--space-3);
}

/* An initial, not a Gravatar. This shop's accounts are created from a phone
   number with a synthetic email, so Gravatar returns the identical grey
   silhouette for every reviewer. */
.review-card__avatar {
	display: grid;
	place-items: center;
	inline-size: 2.5rem;
	block-size: 2.5rem;
	border-radius: 50%;
	background-color: var(--surface-brand);
	color: var(--blue-800);
	font-weight: var(--weight-bold);
	flex-shrink: 0;
}

.review-card__author { font-weight: var(--weight-semibold); font-size: var(--text-label); }

.review-card__date {
	display: block;
	font-size: var(--text-caption);
	color: var(--text-muted);
}

.review-card__rating { margin-inline-start: auto; }

.review-card__verified {
	display: inline-flex;
	margin-block-end: var(--space-3);
}

.review-card__verified svg { inline-size: 0.75rem; block-size: 0.75rem; }

.review-card__text {
	color: var(--text-muted);
	line-height: var(--leading-normal);
	font-size: var(--text-label);
}

.review-card__text p:last-child { margin-block-end: 0; }

.reviews__empty,
.reviews__signin {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--text-muted);
	font-size: var(--text-label);
}

.reviews__empty svg { inline-size: 1.125rem; block-size: 1.125rem; flex-shrink: 0; }
.reviews__signin a { color: var(--text-link); font-weight: var(--weight-medium); }

/* ── Review form ─────────────────────────────────────────────────────────── */

.review-form {
	padding-block-start: var(--space-8);
	border-block-start: 1px solid var(--border);
}

.review-form__title { font-size: var(--text-h3); }

.review-form__note {
	font-size: var(--text-small);
	color: var(--text-muted);
	margin-block: var(--space-2) var(--space-5);
}

.review-form__form { display: grid; gap: var(--space-5); max-inline-size: 36rem; }
.review-form__form .form-submit { margin: 0; }

/* ── Star input ──────────────────────────────────────────────────────────
   The classic CSS-only star picker. Inputs are rendered 5→1 in source order so
   that `~` can reach every star AFTER the checked one — which, because the row
   is laid out in reverse, is every star visually before it. */

.star-input {
	display: inline-flex;
	flex-direction: row-reverse;
	justify-content: flex-end;
	gap: var(--space-1);
}

.star-input input {
	position: absolute;
	opacity: 0;
	inline-size: 1px;
	block-size: 1px;
}

.star-input label {
	font-size: 1.75rem;
	line-height: 1;
	color: var(--neutral-300);
	cursor: pointer;
	transition: color var(--duration-fast) var(--ease);
}

.star-input label:hover,
.star-input label:hover ~ label,
.star-input input:checked ~ label {
	color: var(--amber-500);
}

.star-input input:focus-visible + label {
	outline: 2px solid var(--border-focus);
	outline-offset: 2px;
	border-radius: var(--radius-xs);
}

/* WooCommerce's "Additional information" table — the attributes tab. Core
   markup we cannot template away without losing plugin-added rows, so it is
   restyled in place: a definition list read as rows, not a grey data grid. */
.shop_attributes {
	inline-size: 100%;
	font-size: var(--text-label);
	border-collapse: collapse;
}

.shop_attributes th,
.shop_attributes td {
	padding-block: var(--space-3);
	padding-inline: 0;
	border-block-end: 1px solid var(--border);
	text-align: start;
	vertical-align: top;
}

.shop_attributes th {
	inline-size: 10rem;
	font-weight: var(--weight-semibold);
	color: var(--text);
}

.shop_attributes td { color: var(--text-muted); }
.shop_attributes td p { margin: 0; }
.shop_attributes tr:last-child th,
.shop_attributes tr:last-child td { border-block-end: none; }

/* ============================================================================
   FLASH SALE BAND — «شگفت‌انگیزها»
   ----------------------------------------------------------------------------
   An ink panel on the light canvas, sitting between the service strip and the
   first product row. The inversion is the point: this is the one section of the
   homepage that is time-limited, and it has to read as a different KIND of
   thing from the rails above and below it, not as another heading with cards.

   Dark, but not anonymous — the panel carries a cyan wash in its upper corner
   and a cyan CTA, so it belongs to Benis rather than to every flash-sale strip
   on the Persian web. The product cards stay exactly as they are elsewhere:
   white on ink is the strongest they ever look, and forking the card component
   for one section is how two card components start drifting apart.
   ========================================================================== */

/* Less air above it than a normal section. The service strip immediately before
   it is a thin band, not a block of content, so a full section gap on top of
   the strip's own padding left the dark panel floating a long way below the
   thing it follows. */
.flash { padding-block-start: var(--space-5); }

.flash__panel {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	border-radius: var(--radius-xl);
	padding-block: var(--space-5);
	background-color: var(--surface-inverse);
}

/* The wash. A radial rather than a gradient sweep, anchored at the inline-start
   top corner — which is where the title sits in both directions, so the light
   falls on the words instead of on empty panel. */
.flash__panel::before {
	content: "";
	position: absolute;
	inset-block-start: -40%;
	inset-inline-start: -10%;
	inline-size: 70%;
	block-size: 160%;
	z-index: -1;
	background: radial-gradient(
		closest-side,
		rgb(81 202 254 / 0.28) 0%,
		rgb(81 202 254 / 0) 100%
	);
	pointer-events: none;
}

.flash__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3);
	padding-inline: var(--space-5);
	margin-block-end: var(--space-5);
}

.flash__title {
	flex: 1 1 100%;
	font-size: var(--text-h3);
	font-weight: var(--weight-bold);
	color: var(--text-inverse);
	line-height: var(--leading-tight);
}

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

/* ── Countdown ───────────────────────────────────────────────────────────── */

/* A chip cut into the panel rather than laid on top of it: a translucent white
   fill over the ink reads as a recess, which is what a status readout should
   be. A solid lighter box would compete with the CTA beside it.

   Paired with the CTA at the inline-end of the bar from 768px up — see the
   margin rule further down. The clock and «مشاهده همه» are one group: both are
   about acting on the campaign, while the title is what the campaign IS. */
.flash__timer {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	padding-inline: var(--space-2) var(--space-3);
	padding-block: 0.3125rem;
	border-radius: var(--radius-pill);
	background-color: rgb(255 255 255 / 0.1);
	border: 1px solid rgb(255 255 255 / 0.16);
	color: var(--text-inverse);
	font-size: var(--text-small);
}

.flash__timer svg {
	inline-size: 1.125rem;
	block-size: 1.125rem;
	color: var(--brand);
	flex-shrink: 0;
}

.flash__timer-label {
	color: var(--neutral-300);
	white-space: nowrap;
}

/* On a narrow phone the words «تا پایان» are the 65px that push the clock and
   the CTA onto separate rows — three stacked rows for a bar that is one idea.
   The clock icon already says the chip is a countdown, so the label goes and
   the two sit together. The accessible sentence beside them is untouched. */
@media (max-width: 479px) {
	.flash__timer-label { display: none; }
}

/* LTR, inside an RTL page — and this is not a slip.
   ----------------------------------------------------------------------------
   A clock is a positional notation, not a phrase: the leftmost field is the
   largest unit, the same way it is on every watch face, departure board and
   video player in the world. Left in the document's RTL flow the fields laid
   out largest-on-the-right, so ۰۲:۱۸:۳۹ read as seconds, minutes, hours from
   the left — the sequence ran backwards and the whole thing was unreadable at
   a glance.

   This is the same treatment the footer credit and the contact phone number
   already get: the sentence around them stays Persian, the numeral stays in its
   own direction. The digits themselves remain Persian. */
.flash__clock {
	display: inline-flex;
	direction: ltr;
	align-items: center;
	gap: 0.0625rem;
	font-size: var(--text-label);
	font-weight: var(--weight-bold);
	line-height: 1;
}

/* Each segment is a fixed box. Tabular figures alone are not enough: the box
   stops the whole clock shuffling sideways when the day segment appears, and
   the fixed width means ۰۹ and ۱۰ occupy the same space to the pixel. */
.flash__seg {
	min-inline-size: 1.75ch;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

/* The colon is a tick mark between fields, not a character being read. Lighter
   than the digits and nudged up off the baseline, because Persian numerals sit
   high and a baseline colon hangs below them. */
.flash__sep {
	color: rgb(255 255 255 / 0.45);
	transform: translateY(-0.05em);
}

.flash__seg[hidden], .flash__sep[hidden] { display: none; }

.flash__all svg {
	inline-size: 1rem;
	block-size: 1rem;
}

/* ── How the bar splits ──────────────────────────────────────────────────── */

/* Phone: the title owns its own row, so the second row simply spreads — clock
   at the start, CTA at the far end. Clustering them would leave a hole. */
.flash__all { margin-inline-start: auto; }

/* From 768px everything is one row, and the auto margin moves UP to the clock
   so that the clock and the CTA travel together to the inline-end. In an RTL
   bar that puts the button hard against the left edge with the countdown
   immediately beside it, and the title alone at the right. */
@media (min-width: 768px) {
	.flash__timer { margin-inline-start: auto; }
	.flash__all { margin-inline-start: 0; }
}

/* ── Rail inside the panel ───────────────────────────────────────────────── */

/* The shared .rail computes its inset from the container's own centring, which
   is right for a rail that spans the page and wrong for one living inside a
   padded panel — there it produced a first card that did not line up with the
   heading above it. Inside the panel the inset is simply the panel's padding,
   and the last card is still allowed to run out past the edge so the rail
   reads as scrollable. */
.flash__rail {
	--rail-inset: var(--space-5);
	padding-block-end: 0;
}

/* ── Desktop filter rail — a card, not a bare column ─────────────────────────
   The rail had no surface of its own. Every other grouping in this theme — the
   product card, the service strip, the flash panel, the mobile sheet — is a
   soft rounded container, and the filters were the one place that was just
   controls resting on the page. That is what made them read as unfinished.
   ========================================================================== */

.filter-rail {
	background-color: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: var(--space-5);
	box-shadow: var(--shadow-sm);
}

.filter-rail__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding-block-end: var(--space-4);
	margin-block-end: var(--space-2);
	border-block-end: 1px solid var(--border);
}

.filter-rail__title {
	font-size: var(--text-label);
	font-weight: var(--weight-bold);
}

/* Quiet until there is something to clear — it is a destructive-ish action and
   should not compete with the filters themselves for attention. */
.filter-rail__clear {
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
	color: var(--text-muted);
	transition: color var(--duration-fast) var(--ease);
}

.filter-rail__clear:hover { color: var(--text-link); }

/* The group heading's chevron sat at the opposite end of the whole column from
   its own label, because `justify-content: space-between` had the rail's full
   width to spread across. Inside the card it has a boundary to sit against. */
.filter-rail .filters__title {
	font-weight: var(--weight-semibold);
}
