/**
 * WooCommerce — filter sidebar, toolbar and mobile sheet
 * ==========================================================================
 * Enqueued alongside shop.css on shop and product taxonomy archives.
 *
 * The sidebar and the mobile sheet are the same element. Below the sidebar
 * breakpoint it becomes a bottom sheet; above it, a sticky column. One
 * element means one set of input IDs and one source of truth for state.
 *
 * Implements UI-LAYOUTS.md §7.3.
 *
 * @package Preloved
 * @since   1.0.0
 * ========================================================================== */

.shop__layout {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--pl-space-6);
	align-items: start;
}

@media (min-width: 1024px) {
	.shop__layout {
		grid-template-columns: 264px minmax(0, 1fr);
		gap: var(--pl-space-8);
	}
}

.shop__main { min-inline-size: 0; }


/* ==========================================================================
   1. Toolbar
   ========================================================================== */

.shop-toolbar {
	margin-block-end: var(--pl-space-5);
}

.shop-toolbar__row {
	display: flex;
	align-items: center;
	gap: var(--pl-space-3);
	padding-block-end: var(--pl-space-4);
	border-block-end: 1px solid var(--pl-line-soft);
}

.shop-toolbar__count {
	flex: 1 1 auto;
	/* Flex items floor at min-content unless told otherwise; without this the
	   count refuses to shrink and the row overflows at 320px (NFR-COMP-03). */
	min-inline-size: 0;
	color: var(--pl-text-muted);
	font-size: var(--pl-ui-sm);
	font-variant-numeric: tabular-nums;
}

.shop-toolbar__filter-btn {
	position: relative;
	min-block-size: 44px;
	padding-inline: var(--pl-space-4);
	font-size: var(--pl-ui-sm);
}

.shop-toolbar__filter-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 20px;
	block-size: 20px;
	padding-inline: 6px;
	background-color: var(--pl-primary);
	color: var(--pl-text-inverse);
	border-radius: var(--pl-radius-pill);
	font-size: var(--pl-micro);
	font-variant-numeric: tabular-nums;
}

/* `0 1 auto`, not `0 0 auto`. The select is sized by its longest option
   ("Price: high to low"), and a non-shrinkable sort group pushed the toolbar
   1px past a 320px viewport. It still never *grows*; it may now give ground
   when the row runs out of room, which only happens on the narrowest phones. */
.shop-toolbar__sort {
	display: flex;
	align-items: center;
	gap: var(--pl-space-2);
	flex: 0 1 auto;
	min-inline-size: 0;
}

.shop-toolbar__sort-label {
	margin: 0;
	color: var(--pl-text-muted);
	font-size: var(--pl-ui-sm);
	font-weight: 400;
	white-space: nowrap;
}

.shop-toolbar__sort-select {
	inline-size: auto;
	max-inline-size: 100%;
	min-block-size: 44px;
	padding-block: var(--pl-space-2);
	padding-inline: var(--pl-space-3) var(--pl-space-6);
	font-size: var(--pl-ui-sm);
	border-radius: var(--pl-radius);
	/* Native arrow removed so the control matches the rest of the system. */
	appearance: none;
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
		linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position:
		calc(100% - 18px) calc(50% + 2px),
		calc(100% - 13px) calc(50% + 2px);
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

[dir="rtl"] .shop-toolbar__sort-select {
	padding-inline: var(--pl-space-6) var(--pl-space-3);
	background-position: 18px calc(50% + 2px), 13px calc(50% + 2px);
}

/* The label is redundant next to a populated select on a narrow screen. */
@media (max-width: 639px) {
	.shop-toolbar__sort-label { display: none; }
	.shop-toolbar__count { font-size: var(--pl-caption); }
}

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


/* ==========================================================================
   2. Applied filter chips
   ========================================================================== */

.shop-toolbar__active:empty { display: none; }

.active-filters { padding-block-start: var(--pl-space-4); }

.active-filters__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--pl-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.active-filters__chip {
	display: inline-flex;
	align-items: center;
	gap: var(--pl-space-2);
	min-block-size: 32px;
	padding-inline: var(--pl-space-3);
	background-color: var(--pl-peach-100);
	border: 1px solid transparent;
	border-radius: var(--pl-radius-pill);
	color: var(--pl-orange-900);
	font-size: var(--pl-ui-sm);
	font-weight: 500;
	text-decoration: none;
	animation: pl-chip-in var(--pl-fast) var(--pl-ease-out);
	transition:
		background-color var(--pl-fast) var(--pl-ease-standard),
		border-color var(--pl-fast) var(--pl-ease-standard);
}

.active-filters__chip:hover {
	background-color: var(--pl-bg-elevated);
	border-color: var(--pl-primary);
	color: var(--pl-orange-900);
}

.active-filters__chip svg { opacity: 0.6; }
.active-filters__chip:hover svg { opacity: 1; }

@keyframes pl-chip-in {
	from { opacity: 0; transform: scale(0.94); }
	to   { opacity: 1; transform: none; }
}

.active-filters__clear {
	color: var(--pl-text-muted);
	font-size: var(--pl-ui-sm);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.active-filters__clear:hover { color: var(--pl-sale); }


/* ==========================================================================
   3. Sidebar shell
   ========================================================================== */

.shop__sidebar-head,
.shop__sidebar-foot { display: none; }

@media (min-width: 1024px) {
	.shop__sidebar {
		position: sticky;
		/* Clears the sticky header, plus a little breathing room. */
		inset-block-start: calc(var(--pl-header-height) + var(--pl-space-4));
		max-block-size: calc(100vh - var(--pl-header-height) - var(--pl-space-7));
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: thin;
		padding-inline-end: var(--pl-space-2);
	}

	.shop__sidebar::-webkit-scrollbar { inline-size: 6px; }

	.shop__sidebar::-webkit-scrollbar-thumb {
		background-color: var(--pl-line);
		border-radius: var(--pl-radius-pill);
	}
}

.filters__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--pl-space-3);
	margin-block-end: var(--pl-space-4);
	padding-block-end: var(--pl-space-4);
	border-block-end: 1px solid var(--pl-line-soft);
}

.filters__title {
	margin: 0;
	font-family: var(--pl-font-body);
	font-size: var(--pl-ui-sm);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: var(--pl-tracking-wide);
}

.filters__clear {
	color: var(--pl-text-muted);
	font-size: var(--pl-caption);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.filters__clear:hover { color: var(--pl-sale); }

/* Only meaningful without scripting; shop.js adds .filters--live. */
.filters--live .filters__submit { display: none; }

.filters__submit { margin-block-start: var(--pl-space-5); }

/* The desktop head duplicates the sheet head, which owns the mobile title. */
@media (max-width: 1023px) {
	.filters__head { display: none; }
}


/* ==========================================================================
   4. Filter groups
   ========================================================================== */

.filter-group {
	border-block-end: 1px solid var(--pl-line-soft);
}

.filter-group:last-of-type { border-block-end: 0; }

.filter-group__summary {
	display: flex;
	align-items: center;
	gap: var(--pl-space-2);
	padding-block: var(--pl-space-4);
	cursor: pointer;
	list-style: none;
	font-size: var(--pl-ui-sm);
	font-weight: 600;
	/* Stops a double-tap selecting the label text on mobile. */
	user-select: none;
}

/* Safari renders a disclosure triangle unless this is removed explicitly. */
.filter-group__summary::-webkit-details-marker { display: none; }

.filter-group__summary:focus-visible {
	outline: 2px solid var(--pl-focus);
	outline-offset: -2px;
	border-radius: var(--pl-radius-sm);
}

.filter-group__label { flex: 1 1 auto; }

.filter-group__badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 20px;
	block-size: 20px;
	padding-inline: 6px;
	background-color: var(--pl-primary);
	color: var(--pl-text-inverse);
	border-radius: var(--pl-radius-pill);
	font-size: var(--pl-micro);
	font-variant-numeric: tabular-nums;
}

.filter-group__chevron {
	color: var(--pl-text-muted);
	transition: transform var(--pl-base) var(--pl-ease-standard);
}

.filter-group[open] > .filter-group__summary .filter-group__chevron {
	transform: rotate(180deg);
}

.filter-group__body { padding-block-end: var(--pl-space-4); }

/* Shares `pl-disclosure-open`, defined in components/disclosure.css — the
   filter groups are the same disclosure component as the checkout and product
   panels, and the keyframes were duplicated here. */
@media (prefers-reduced-motion: no-preference) {
	.filter-group[open] > .filter-group__body {
		animation: pl-disclosure-open var(--pl-base) var(--pl-ease-out);
	}
}


/* Options ----------------------------------------------------------------- */

.filter-options {
	margin: 0;
	padding: 0;
	list-style: none;
}

.filter-options--list {
	display: grid;
	gap: 2px;
	/* Long brand lists scroll inside the group rather than pushing it down. */
	max-block-size: 260px;
	overflow-y: auto;
	overscroll-behavior: contain;
	scrollbar-width: thin;
}

.filter-options--grid {
	display: flex;
	flex-wrap: wrap;
	gap: var(--pl-space-2);
}

.filter-options__label {
	display: flex;
	align-items: center;
	gap: var(--pl-space-3);
	margin: 0;
	padding: var(--pl-space-2);
	border-radius: var(--pl-radius);
	color: var(--pl-text-secondary);
	font-size: var(--pl-ui-sm);
	font-weight: 400;
	cursor: pointer;
	transition:
		background-color var(--pl-fast) var(--pl-ease-standard),
		color var(--pl-fast) var(--pl-ease-standard);
}

.filter-options__label:hover {
	background-color: var(--pl-bg-sunken);
	color: var(--pl-text);
}

.filter-options__box {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	inline-size: 20px;
	block-size: 20px;
	background-color: var(--pl-bg-elevated);
	border: 1px solid var(--pl-border-field);
	border-radius: var(--pl-radius-sm);
	color: var(--pl-text-inverse);
	transition:
		background-color var(--pl-fast) var(--pl-ease-standard),
		border-color var(--pl-fast) var(--pl-ease-standard);
}

.filter-options__box svg {
	opacity: 0;
	transform: scale(0.6);
	transition:
		opacity var(--pl-fast) var(--pl-ease-out),
		transform var(--pl-fast) var(--pl-ease-out);
}

.filter-options__input:checked + .filter-options__label .filter-options__box {
	background-color: var(--pl-primary);
	border-color: var(--pl-primary);
}

.filter-options__input:checked + .filter-options__label .filter-options__box svg {
	opacity: 1;
	transform: none;
}

.filter-options__input:checked + .filter-options__label {
	color: var(--pl-text);
	font-weight: 500;
}

/*
 * The input is visually hidden, so its focus ring has to be drawn on the
 * label instead or keyboard users lose the control entirely.
 */
.filter-options__input:focus-visible + .filter-options__label {
	outline: 2px solid var(--pl-focus);
	outline-offset: 2px;
}

.filter-options__name { flex: 1 1 auto; }

.filter-options__count {
	color: var(--pl-text-muted);
	font-size: var(--pl-micro);
	font-variant-numeric: tabular-nums;
}

/* Grid style — sizes and colours read better as compact pills. */
.filter-options--grid .filter-options__item { margin: 0; }

.filter-options--grid .filter-options__label {
	min-block-size: 36px;
	padding-inline: var(--pl-space-3);
	border: 1px solid var(--pl-border-field);
	border-radius: var(--pl-radius-pill);
	font-size: var(--pl-caption);
}

.filter-options--grid .filter-options__box,
.filter-options--grid .filter-options__count { display: none; }

.filter-options--grid .filter-options__input:checked + .filter-options__label {
	background-color: var(--pl-peach-100);
	border-color: var(--pl-primary);
	color: var(--pl-orange-900);
}


/* Price ------------------------------------------------------------------- */

.price-filter__fields {
	display: flex;
	align-items: flex-end;
	gap: var(--pl-space-2);
}

.price-filter__field { flex: 1 1 0; }

.price-filter__label {
	display: block;
	margin-block-end: var(--pl-space-1);
	color: var(--pl-text-muted);
	font-size: var(--pl-micro);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: var(--pl-tracking-wide);
}

.price-filter__input {
	min-block-size: 44px;
	padding: var(--pl-space-2) var(--pl-space-3);
	font-size: var(--pl-ui-sm);
}

/* `--text-muted`, not `--text-disabled`. The disabled token is exempt from
   contrast under WCAG 1.4.3 because it marks an inactive control; this dash is
   live text carrying the meaning "from … to", and measured 2.42:1. */
.price-filter__dash {
	padding-block-end: var(--pl-space-3);
	color: var(--pl-text-muted);
}

.price-filter__hint {
	margin-block: var(--pl-space-3) 0;
	color: var(--pl-text-muted);
	font-size: var(--pl-micro);
}


/* ==========================================================================
   5. Mobile sheet
   ========================================================================== */

@media (max-width: 1023px) {
	.shop__backdrop {
		position: fixed;
		inset: 0;
		z-index: var(--pl-z-drawer);
		background-color: rgb(20 18 15 / 50%);
		animation: pl-fade-in var(--pl-base) var(--pl-ease-standard);
	}

	.shop__sidebar {
		position: fixed;
		inset-block-end: 0;
		inset-inline: 0;
		z-index: calc(var(--pl-z-drawer) + 1);
		display: flex;
		flex-direction: column;
		/* `vh` first: `dvh` is Safari 15.4+, and an unsupported unit invalidates
		   the whole declaration rather than falling back — which on iOS 15.0–15.3
		   left this fixed sheet with no height cap at all, so a long filter list
		   ran past the bottom of the screen with no way to scroll to Apply. */
		max-block-size: 88vh;
		max-block-size: 88dvh;
		background-color: var(--pl-bg-elevated);
		border-start-start-radius: var(--pl-radius-xl);
		border-start-end-radius: var(--pl-radius-xl);
		box-shadow: var(--pl-shadow-lg);
		transform: translateY(100%);
		visibility: hidden;
		transition:
			transform var(--pl-slow) var(--pl-ease-out),
			visibility var(--pl-slow);
	}

	.shop__sidebar.is-open {
		transform: translateY(0);
		visibility: visible;
	}

	.shop__sidebar-head {
		position: relative;   /* Anchors the grab handle below. */
		display: flex;
		align-items: center;
		justify-content: space-between;
		flex: 0 0 auto;
		padding: var(--pl-space-5) var(--pl-space-5) var(--pl-space-4);
		border-block-end: 1px solid var(--pl-line-soft);
	}

	/* The grab handle that tells a thumb this panel is a sheet. */
	.shop__sidebar-head::before {
		content: "";
		position: absolute;
		inset-block-start: var(--pl-space-2);
		inset-inline-start: 50%;
		inline-size: 36px;
		block-size: 4px;
		margin-inline-start: -18px;
		background-color: var(--pl-line);
		border-radius: var(--pl-radius-pill);
	}

	.shop__sidebar-title {
		margin: 0;
		font-family: var(--pl-font-display);
		font-size: var(--pl-h4);
	}

	.shop__sidebar-close {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		inline-size: 44px;
		block-size: 44px;
		margin-inline-end: calc(var(--pl-space-3) * -1);
		background: none;
		border: 0;
		border-radius: var(--pl-radius);
		color: var(--pl-text-muted);
	}

	.shop__sidebar .filters {
		flex: 1 1 auto;
		overflow-y: auto;
		overscroll-behavior: contain;
		-webkit-overflow-scrolling: touch;
		padding-inline: var(--pl-space-5);
	}

	.shop__sidebar-foot {
		display: block;
		flex: 0 0 auto;
		padding: var(--pl-space-4) var(--pl-space-5)
			calc(var(--pl-space-4) + env(safe-area-inset-bottom));
		border-block-start: 1px solid var(--pl-line-soft);
		background-color: var(--pl-bg-elevated);
	}
}

@keyframes pl-fade-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}


/* ==========================================================================
   6. Loading state
   ========================================================================== */

/*
 * The outgoing grid dims and stops taking clicks rather than being replaced
 * by a spinner. Keeping the previous results on screen means the page does
 * not collapse to zero height and throw the scroll position away.
 */
.shop__results {
	transition: opacity var(--pl-fast) var(--pl-ease-standard);
}

.shop__results.is-loading {
	opacity: 0.45;
	pointer-events: none;
}

.shop__results.is-loading .card { animation: none; }


/* --------------------------------------------------------------------------
   Nested categories
   --------------------------------------------------------------------------
   Electronics contains Printers, Cordless Phones and Speakers & Audio. Listed
   flat, those read as six unrelated siblings — "Electronics 12" beside
   "Printers 3" with nothing to say one contains the other, and a shopper
   ticking both gets the intersection rather than the union they expected.

   The indent and rule carry that relationship. Both are decorative: the tree
   order in the markup is what conveys it to a screen reader, and the checkbox
   labels remain the full category names, so nothing here is the sole carrier
   of meaning.
   -------------------------------------------------------------------------- */

.filter-options__item--child {
	position: relative;
	margin-inline-start: var(--pl-space-4);
}

.filter-options__item--child::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: calc(var(--pl-space-3) * -1);
	inline-size: 1px;
	background-color: var(--pl-line);
}

/* A child sits a step down in the hierarchy, and reads a step quieter. */
.filter-options__item--child .filter-options__name { font-size: var(--pl-ui-sm); }
