/*
 * Archive Download — filter drawer, results grid, pagination.
 *
 * Loaded on the two download archives and on product search, per
 * f32_is_download_archive().
 *
 * THE CATEGORY HEADER USED TO BE HERE and is not any more. It was thirty lines
 * dressing `parts/download-archive-header.html` - a teal wash, a bottom rule, a
 * title size, a 60ch description and a two-line clamp for phones - and the part
 * it dressed is gone, replaced by the `sparklestock/page-header` block, which
 * brings its own stylesheet and its own measure. The wash went with it rather
 * than being ported: it argued for a hard-edged band under a site header that
 * is already a solid block of white, and the block's answer to the same problem
 * is a Memphis strip keyed to the term, which is decoration the page earns
 * rather than chrome it inherits. Nothing else in this file referenced those
 * classes, so there is no orphan left behind - see the block's render.php for
 * what draws the header now.
 *
 * TWO LAYOUTS HAVE BEEN TRIED AND REPLACED HERE, and the reasons are worth
 * keeping because the third one inherits them. A 220px sidebar held its controls
 * in front of the products on every phone and left the grid three cards wide on
 * a 1,420px canvas. The toolbar that replaced it fixed the width but put five
 * groups of controls - twelve colour swatches, six app tiles, a popover, a count
 * and a sort - on one line above the grid, where they read as a single
 * undifferentiated band and still wrapped to four lines on a phone.
 *
 * Now every control that narrows the archive is in one off-canvas panel, and the
 * bar above the grid carries only what the visitor has already decided: what is
 * filtered, how many results that leaves, and how they are sorted. The grid gets
 * the whole page.
 */

/* ---------------------------------------------------------------------------
 * Toolbar — the bar the drawer left behind
 * ------------------------------------------------------------------------ */

.archive-toolbar {
	padding-block: 0.75rem;
	border-bottom: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);

	/*
	 * Sticky, because the trigger is now the only way to reach a filter and a
	 * 30-card grid puts it off screen almost immediately. `--f32-header-height`
	 * is set by site-header.css where the header is sticky; the fallback keeps
	 * the toolbar from hiding under it if that ever stops being true.
	 *
	 * The `toolbar` layer sits BELOW `header` on purpose - see the scale at the
	 * top of site-header.css. This bar is a sibling of the header template part
	 * and comes later in the document, so any layer at or above the header's
	 * wins the tie and cuts a band through the open category panel, which the
	 * header draws inside its own stacking context.
	 */
	position: sticky;
	top: var(--f32-header-height, 0px);
	z-index: var(--wp--custom--z-index--toolbar, 10);
	background: color-mix(in srgb, var(--wp--preset--color--page, #f9fafb) 92%, transparent);
	backdrop-filter: blur(10px);
}

.archive-toolbar__facets {
	/*
	 * The chips are allowed to shrink; the meta group is not, so the result
	 * count and the sort control never get pushed off the end of the row by a
	 * visitor who has selected six colours.
	 */
	min-width: 0;
	flex: 1 1 auto;
}

.archive-toolbar__meta {
	flex: 0 0 auto;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.875rem;
}

.archive-toolbar__count {
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Drawer trigger
 * ------------------------------------------------------------------------ */

.f32-filter-trigger {
	display: inline-flex;
	flex: none;
	align-items: center;
	gap: 0.5rem;
	margin: 0;
	padding: 0.5rem 0.9375rem;
	border: 1px solid var(--wp--preset--color--border-strong, #d1d5db);
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: var(--wp--preset--color--contrast, #fff);
	color: var(--wp--preset--color--primary, #000);
	font-family: inherit;
	font-size: 0.8125rem;
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
	cursor: pointer;
	transition: border-color 0.15s ease;
}

.f32-filter-trigger:hover {
	border-color: var(--wp--preset--color--primary, #000);
}

.f32-filter-trigger:focus-visible {
	outline: 2px solid var(--wp--preset--color--action, #1d4ed8);
	outline-offset: 2px;
}

/* 1.75 rather than the 2 in assets/css/icons.css. The trigger sits in a row of
   text-weight controls and 2 made it the loudest thing in the toolbar. Stated
   here because the icon registry strips a `stroke-width` attribute. */
.f32-filter-trigger__icon {
	width: 15px;
	height: 15px;
	stroke-width: 1.75;
}

/*
 * With filters on, the trigger stops being a way in and starts being a
 * statement about the results below it, so it takes the same accent the chips
 * beside it carry.
 */
.f32-filter-trigger.is-active {
	border-color: var(--wp--preset--color--action, #1d4ed8);
	background: color-mix(
		in srgb,
		var(--wp--preset--color--action, #1d4ed8) 8%,
		var(--wp--preset--color--contrast, #fff)
	);
	color: var(--wp--preset--color--action, #1d4ed8);
}

.f32-filter-trigger__badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.125rem;
	padding: 0.125rem 0.3125rem;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: var(--wp--preset--color--action, #1d4ed8);
	color: var(--wp--preset--color--contrast, #fff);
	font-size: 0.6875rem;
	font-weight: 700;
	line-height: 1.2;
	font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Drawer
 * ------------------------------------------------------------------------ */

/*
 * OFF-CANVAS IS THE DEFAULT STATE, not a state a script moves the panel into.
 * A stylesheet that started the panel in flow would paint the whole facet list
 * expanded on every load and collapse it a frame later. The cost is that with
 * no script there is nothing to open the panel with, which is what the
 * <noscript> block in f32_print_filter_drawer_noscript() answers.
 *
 * Everything below keys off `:root[data-f32-filters]`, never off the panel's own
 * attributes: the panel lives inside the Interactivity router region and its
 * markup is replaced on every filter click. See assets/js/filter-drawer.js.
 */
.f32-filter-drawer {
	position: fixed;

	/*
	 * The panel is a flow child of the query block, so core spaces it with
	 * `:where(.is-layout-flow) > * + *` - 24px of block-gap. On a fixed,
	 * full-height box that is not spacing, it is displacement: it moves the
	 * 100dvh panel 24px down the screen and pushes the foot, which holds the
	 * only way out of the panel, off the bottom edge.
	 */
	margin-block: 0;

	/*
	 * Anchored to the TOP and given a height, rather than stretched between
	 * top and bottom. A panel anchored to `bottom: 0` puts its footer under
	 * iOS Safari's bottom toolbar in the small-viewport state, and the footer
	 * is where the way out of the panel lives. `dvh` follows the toolbar as it
	 * retracts; the `vh` line above it is the fallback for browsers that do not
	 * know the unit.
	 */
	inset: var(--f32-admin-bar, 0px) 0 auto auto;
	height: calc(100vh - var(--f32-admin-bar, 0px));
	height: calc(100dvh - var(--f32-admin-bar, 0px));
	z-index: var(--wp--custom--z-index--modal, 40);
	display: flex;
	flex-direction: column;
	width: min(360px, 100vw - 2.5rem);
	background: var(--wp--preset--color--contrast, #fff);
	border-left: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	box-shadow: -18px 0 48px rgba(15, 20, 30, 0.16);
	visibility: hidden;
	transform: translateX(100%);

	/*
	 * Visibility is what takes the closed panel out of the tab order, so it has
	 * to flip late on the way out and immediately on the way in - otherwise the
	 * panel is either untabbable while it slides in or invisible while it
	 * slides out.
	 */
	transition:
		transform 0.26s cubic-bezier(0.32, 0.72, 0, 1),
		visibility 0s linear 0.26s;
}

/*
 * The admin bar is fixed over the top of the screen, and so is this panel, so
 * the head row - the title, Clear all and the close button - lands under it for
 * anyone logged in. The offset is a variable rather than a second `top` because
 * the height has to come off with it, or the foot goes back off the bottom.
 * Below 600px core stops fixing the admin bar and lets it scroll away with the
 * page, so there the panel takes the whole screen again.
 */
body.admin-bar .f32-filter-drawer {
	--f32-admin-bar: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar .f32-filter-drawer {
		--f32-admin-bar: 46px;
	}
}

@media screen and (max-width: 600px) {
	body.admin-bar .f32-filter-drawer {
		--f32-admin-bar: 0px;
	}
}

/*
 * Head, body and foot are injected by f32_filter_drawer_chrome() and land as
 * flow children too, so the same block-gap rule puts 24px above the body and
 * above the foot. It reads as a gap under the head row, and it takes height the
 * foot needs. The panel spaces its own parts - head and foot with padding, the
 * facets inside the body with the rule further down.
 */
.f32-filter-drawer > * {
	margin-block: 0;
}

:root[data-f32-filters="open"] .f32-filter-drawer {
	visibility: visible;
	transform: none;
	transition:
		transform 0.26s cubic-bezier(0.32, 0.72, 0, 1),
		visibility 0s;
}

.f32-filter-drawer__scrim {
	position: fixed;
	inset: 0;
	margin-block: 0;

	/* One layer under the panel it dims, and both above the header, because a
	 * drawer that takes over the screen has to cover the chrome it was opened
	 * from. */
	z-index: var(--wp--custom--z-index--scrim, 30);

	/*
	 * Light enough to read the grid through. Every control in the panel filters
	 * the moment it is clicked, and watching the products change is most of the
	 * reason the panel is worth opening at all.
	 */
	background: rgba(17, 22, 32, 0.28);
	opacity: 0;
	visibility: hidden;

	/* The scrim exists to be tapped. Without this a drag on it pans the grid
	 * underneath on touch, which reads as the modal not being modal. */
	touch-action: none;
	transition: opacity 0.26s ease, visibility 0s linear 0.26s;
}

:root[data-f32-filters="open"] .f32-filter-drawer__scrim {
	opacity: 1;
	visibility: visible;
	transition: opacity 0.26s ease, visibility 0s;
}

/*
 * The page behind a modal must not scroll. `--f32-scrollbar` is measured by the
 * script before the lock and holds the gutter open, so the grid does not jump
 * sideways by the scrollbar's width as the panel opens.
 */
:root[data-f32-filters="open"] {
	overflow: hidden;
	padding-right: var(--f32-scrollbar, 0px);
}

.f32-filter-drawer__head {
	display: flex;
	flex: none;
	align-items: center;
	gap: 0.75rem;
	padding: 1.125rem 1.25rem;
	border-bottom: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
}

.f32-filter-drawer__title {
	flex: 1 1 auto;
	margin: 0;
	font-size: 1rem;
	font-weight: 700;
	letter-spacing: -0.01em;
}

.f32-filter-drawer__clear {
	flex: none;
	color: var(--wp--preset--color--accent, #1473e6);
	font-size: 0.8125rem;
	text-decoration: none;
}

.f32-filter-drawer__clear:hover {
	text-decoration: underline;
}

.f32-filter-drawer__close {
	display: inline-flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: none;
	color: var(--wp--preset--color--muted, #6b7280);
	cursor: pointer;
}

.f32-filter-drawer__close svg {
	width: 17px;
	height: 17px;
	/* Matches the trigger that opened the drawer. See the note on
	   .f32-filter-trigger__icon for why the weight is here and not on the SVG. */
	stroke-width: 1.75;
}

.f32-filter-drawer__close:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
	color: var(--wp--preset--color--primary, #000);
}

.f32-filter-drawer__close:focus-visible,
.f32-filter-drawer__apply:focus-visible {
	outline: 2px solid var(--wp--preset--color--action, #1d4ed8);
	outline-offset: 2px;
}

.f32-filter-drawer .f32-filter-drawer__body {
	flex: 1 1 auto;
	min-height: 0;
	padding: 0 1.25rem;
	overflow-y: auto;
	overscroll-behavior: contain;
}

/*
 * One facet group per child, separated by a rule rather than by space alone:
 * three unlabelled blocks of controls is what the toolbar this replaced looked
 * like. Specificity has to clear `:where(.is-layout-flow) > *`, which core uses
 * to space flow children.
 */
.f32-filter-drawer .f32-filter-drawer__body > * {
	margin-block: 0;
	padding-block: 1.25rem;
	border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
}

.f32-filter-drawer .f32-filter-drawer__body > *:first-child {
	border-top: 0;
}

.f32-filter-drawer__foot {
	flex: none;
	padding: 1rem 1.25rem;

	/*
	 * Clear of the home indicator, and of the notch in landscape-left - the
	 * panel is anchored to the right edge, which is where `safe-area-inset-right`
	 * is non-zero. Both fall back to the flat padding everywhere else.
	 */
	padding-right: max(1.25rem, env(safe-area-inset-right, 0px));
	padding-bottom: max(1rem, env(safe-area-inset-bottom, 0px));
	border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	background: var(--wp--preset--color--contrast, #fff);
}

.f32-filter-drawer__apply {
	display: block;
	width: 100%;
	margin: 0;
	padding: 0.8125rem;
	border: 0;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: var(--wp--preset--color--primary, #000);
	color: var(--wp--preset--color--contrast, #fff);
	font-family: inherit;
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	font-variant-numeric: tabular-nums;
}

.f32-filter-drawer__apply:hover {
	background: #1f2937;
}

/* ── Facet groups ────────────────────────────────────────────────────────── */

/*
 * Three blocks write the label above a facet: the theme's own heading, and the
 * two sparklestock filters, which carry a label of their own. They are one
 * thing on screen, so they are one rule here.
 */
.f32-filter-drawer .f32-facet__title,
.f32-filter-drawer .wp-block-sparklestock-software-filter__label,
.f32-filter-drawer .wp-block-sparklestock-color-filter__label {
	display: block;
	margin: 0 0 0.75rem;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	line-height: 1.2;
	text-transform: uppercase;
}

/*
 * The search facet.
 *
 * A TOKEN MAP, NOT AN OVERRIDE. The product-search block ships neutral base
 * styles driven entirely by `--ss-search-*` properties and assumes nothing about
 * the surface it sits on, so nothing here has to out-specify it: this only says
 * which radius, border and accent the panel uses. They are the same tokens the
 * apply button and the chips read, which is what makes the field read as part of
 * the drawer rather than as the header's box pasted into it.
 *
 * The pill radius is the tell. Every other control in this panel is a pill - the
 * trigger that opened it, the chips it writes, the button that closes it - and
 * the header's field is a 10px rectangle. Two shapes, two jobs.
 */
.f32-filter-drawer .f32-facet__search {
	--ss-search-radius: var(--wp--custom--border-radius--full, 9999px);
	--ss-search-border-width: 1px;
	--ss-search-border: var(--wp--preset--color--border-strong, #d1d5db);
	--ss-search-border-focus: var(--wp--preset--color--action, #1d4ed8);
	--ss-search-shadow-focus: 0 0 0 3px
		color-mix(
			in srgb,
			var(--wp--preset--color--action, #1d4ed8) 16%,
			transparent
		);
	--ss-search-padding: 0.5625rem 0 0.5625rem 0.9375rem;
	--ss-search-submit-padding: 0 1rem;
	--ss-search-submit-bg: var(--wp--preset--color--primary, #000);
	--ss-search-submit-bg-hover: #1f2937;

	/* The field is `font: inherit`, so this is what sizes it. */
	font-size: 0.875rem;
}

/*
 * The colour filter is built as one horizontal row for the toolbar it used to
 * live in - a label beside a rail that scrolls rather than wraps. In a 360px
 * column the label goes above and the rail wraps.
 *
 * The app filter no longer needs either half of that: it renders as rows, which
 * is the block's own default and already matches the two facets on either side
 * of it. Nothing is overridden here beyond the label, which the group rule
 * above restyles for all three facets at once.
 */
.f32-filter-drawer .wp-block-sparklestock-color-filter {
	display: block;
}

.f32-filter-drawer .wp-block-sparklestock-color-filter__rail {
	flex-wrap: wrap;
	overflow: visible;
}

.f32-filter-drawer .wp-block-sparklestock-color-filter__rail {
	gap: 0.625rem;
	padding: 0;
	border-radius: 0;

	/* The tinted rail existed to hold twelve swatches together inside a busy
	 * toolbar. In a labelled group of its own it is one border too many. */
	background: none;
}

.f32-filter-drawer .wp-block-sparklestock-color-filter__swatch-circle {
	width: 26px;
	height: 26px;
}

/* The selected ring's inner band has to match what is behind it, and behind it
 * is the panel, not the tinted rail the plugin's own rule assumes. */
.f32-filter-drawer .wp-block-sparklestock-color-filter__swatch.is-active .wp-block-sparklestock-color-filter__swatch-circle {
	box-shadow:
		0 0 0 2px var(--wp--preset--color--contrast, #fff),
		0 0 0 3.5px var(--wp--preset--color--primary, #000),
		inset 0 0 0 1px rgba(0, 0, 0, 0.14);
}

/*
 * The onboarding prompt, appended after the app row for a visitor who has not
 * chosen yet. It shared a toolbar row before and had to be a single short line;
 * under the group it explains, it can simply be the caption it always was.
 */
.f32-app-onboarding {
	margin: 0.625rem 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	line-height: 1.35;
}

/* ── Category facet: sub-category links (term archive) ───────────────────── */

.f32-filter-drawer .f32-facet__terms .wp-block-term-template {
	display: flex;
	flex-direction: column;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

.f32-filter-drawer .f32-facet__terms .wp-block-term {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	margin: 0 -0.5rem;
	padding: 0.4375rem 0.5rem;
	border-radius: var(--wp--custom--border-radius--sm, 4px);
}

.f32-filter-drawer .f32-facet__terms .wp-block-term:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

.f32-filter-drawer .f32-facet__terms .wp-block-term-name {
	margin: 0;
}

.f32-filter-drawer .f32-facet__terms .wp-block-term-name a {
	color: inherit;
	text-decoration: none;
}

/* The whole row is the target, not just the term name — core/term-name and
 * core/term-count are siblings and no core block puts the count inside the
 * link, so the link is stretched over the row instead. */
.f32-filter-drawer .f32-facet__terms .wp-block-term-name a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

.f32-filter-drawer .f32-facet__terms .wp-block-term-count {
	margin: 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
}

/* ── Category facet: multi-select term list (archive root) ───────────────── */

.f32-filter-drawer .f32-facet__taxonomy {
	gap: 0;
	max-height: 15rem;
	overflow-y: auto;
	overscroll-behavior: contain;

	/*
	 * Core's vertical flex layout wraps, and a wrapping column inside a
	 * max-height is a multi-column list: twenty-seven categories came out as
	 * two columns with a horizontal scrollbar under them, each count sitting
	 * against the next column's label.
	 */
	flex-wrap: nowrap;
}

.f32-filter-drawer .f32-facet__taxonomy .wp-block-plainplugins-taxonomy-filter__item {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0 -0.5rem;
	padding: 0.4375rem 0.5rem;
	border-radius: var(--wp--custom--border-radius--sm, 4px);
	color: inherit;
	font-size: 0.875rem;
	text-decoration: none;
}

.f32-filter-drawer .f32-facet__taxonomy .wp-block-plainplugins-taxonomy-filter__item:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

.f32-filter-drawer .f32-facet__taxonomy .wp-block-plainplugins-taxonomy-filter__item-label {
	flex: 1 1 auto;
}

.f32-filter-drawer .f32-facet__taxonomy .wp-block-plainplugins-taxonomy-filter__count {
	flex: none;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
}

/* ── App facet: application rows ───────────────────────────────── */

/*
 * The block ships hairline separators and a 44px floor, which is what it should
 * look like standing on its own. In the drawer it has two neighbours - the
 * category list and, above it, the sub-category links - and all three are the
 * same control: a name, a count, and a hover band that bleeds into the panel's
 * gutter. Matching them is the whole reason this facet became rows, so the
 * separators come off and the metrics come from the siblings.
 */
.f32-filter-drawer .wp-block-sparklestock-software-filter__item {
	min-height: 0;
	margin: 0 -0.5rem;
	padding: 0.4375rem 0.5rem;
	border-top: 0;
	border-radius: var(--wp--custom--border-radius--sm, 4px);
}

.f32-filter-drawer .wp-block-sparklestock-software-filter__item:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

.f32-filter-drawer .wp-block-sparklestock-software-filter__count {
	font-size: 0.75rem;
}

/* ---------------------------------------------------------------------------
 * Active filter chips
 * ------------------------------------------------------------------------ */

/*
 * The chips share the toolbar row with the trigger now rather than owning a
 * band of their own, so the block's standalone padding comes off.
 */
.archive-toolbar .wp-block-plainplugins-active-filters {
	flex-wrap: wrap;
	padding-block: 0;
}

/*
 * "Active:" said what the chips beside it already say, and what the trigger's
 * badge now counts. Removed from the row, not from the markup: it is built in
 * PHP by two chip injectors and by the plugin, and deleting it in three places
 * to save one word is three chances to leave a bare wrapper behind.
 */
.archive-toolbar .wp-block-plainplugins-active-filters__label {
	display: none;
}

.wp-block-plainplugins-active-filters__chip {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.3125rem 0.6875rem;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: color-mix(
		in srgb,
		var(--wp--preset--color--action, #1d4ed8) 10%,
		var(--wp--preset--color--contrast, #fff)
	);
	color: var(--wp--preset--color--action, #1d4ed8);
	font-size: 0.8125rem;
	font-weight: 500;
}

.wp-block-plainplugins-active-filters__remove {
	color: currentColor;
	font-size: 0.9375rem;
	line-height: 1;
	text-decoration: none;
	opacity: 0.6;
}

.wp-block-plainplugins-active-filters__remove:hover {
	color: var(--wp--preset--color--coral, #ee383a);
	opacity: 1;
}

.wp-block-plainplugins-active-filters__clear {
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	text-decoration: underline;
}

.wp-block-plainplugins-active-filters__clear:hover {
	color: var(--wp--preset--color--primary, #000);
}

.f32-software-chip__dot {
	display: inline-block;
	flex-shrink: 0;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
}

/* ---------------------------------------------------------------------------
 * Results grid
 * ------------------------------------------------------------------------ */

.archive-download-grid {
	padding-top: var(--wp--preset--spacing--50);
}

/*
 * f32/product-card binds the price paragraph to sparklestock/edd-price, which
 * returns null for anything that is not a download. Search results can be
 * mixed, so the badge is hidden when the binding produced nothing rather than
 * painting an empty pill into every non-product card. This is what lets search
 * use the product card at all.
 */
.archive-download-grid .is-style-price-badge:empty {
	display: none;
}

/*
 * Corner badges on product cards: which of the visitor's applications this one
 * works with. Only rendered when two or more are chosen - see
 * f32_inject_corner_icons().
 *
 * A white pill rather than a brand-coloured square, because it lies over a
 * photograph and has to stay legible on any of them, and because it now carries
 * the application's name rather than a two-letter mark. They stack downward:
 * two names side by side would not clear a 156px card on a phone.
 */

.wp-block-post-featured-image {
	position: relative;
}

/*
 * TOP-LEFT, not top-right, and the move was forced rather than chosen: the Purchased
 * badge now sits on the thumbnail's top-right corner (assets/blocks/core-paragraph.css)
 * and the two would have overlapped on exactly the cards a pass holder cares about.
 * Of the two, the badge is the one that must keep the corner the eye checks first -
 * "you already own this" is the more expensive thing to miss - so the application names
 * took the other corner.
 */
.f32-corner-icons {
	position: absolute;
	top: 6px;
	left: 6px;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 3px;
}

.f32-corner-icon {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 2px 7px 2px 5px;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: rgba(255, 255, 255, 0.94);
	color: var(--wp--preset--color--primary, #000);
	font-size: 10px;
	font-weight: 600;
	line-height: 1.6;
	white-space: nowrap;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.16);
}

.f32-corner-icon__dot {
	flex: none;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
}

/* ---------------------------------------------------------------------------
 * Pagination
 * ------------------------------------------------------------------------ */

.f32-pagination {
	align-items: center;
	gap: 0.375rem;
}

/*
 * The numbers row wraps and is allowed to shrink. Neither is cosmetic: on
 * Lightroom, thirty-two pages render nine items, and at 390px that row measured
 * 482px inside a 375px page. A flex item does not shrink below its content
 * without `min-width: 0`, so the row simply hung out of the viewport and put a
 * horizontal scrollbar on the whole archive.
 */
.f32-pagination .wp-block-query-pagination-numbers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.25rem;
	min-width: 0;
}

.f32-pagination .page-numbers,
.f32-pagination .wp-block-query-pagination-previous,
.f32-pagination .wp-block-query-pagination-next {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.375rem;
	min-width: 2.25rem;
	height: 2.25rem;
	padding-inline: 0.625rem;
	border: 1px solid transparent;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	color: var(--wp--preset--color--primary, #000);
	font-size: 0.875rem;
	line-height: 1;
	text-decoration: none;
	font-variant-numeric: tabular-nums;
}

.f32-pagination .page-numbers:hover,
.f32-pagination .wp-block-query-pagination-previous:hover,
.f32-pagination .wp-block-query-pagination-next:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

/* Prev and Next are the two controls that are always worth finding, so they
 * carry a border the numbers do not. */
.f32-pagination .wp-block-query-pagination-previous,
.f32-pagination .wp-block-query-pagination-next {
	border-color: var(--wp--preset--color--border-strong, #d1d5db);
}

.f32-pagination .page-numbers.current {
	background: var(--wp--preset--color--primary, #000);
	color: var(--wp--preset--color--contrast, #fff);
	font-weight: 700;
}

.f32-pagination .page-numbers.dots {
	min-width: 1.25rem;
	padding-inline: 0;
	color: var(--wp--preset--color--muted, #6b7280);
}

.f32-pagination a:focus-visible {
	outline: 2px solid var(--wp--preset--color--action, #1d4ed8);
	outline-offset: 2px;
}

/*
 * The numbers say which page this is; they cannot say how much is behind them.
 * On Lightroom - 954 products at 30 a page - the difference between page 2 of 3
 * and page 2 of 32 is the difference between browsing and giving up.
 */
.wp-block-query > .f32-pagination__status {
	margin: 0.75rem 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Empty state
 * ------------------------------------------------------------------------ */

.f32-empty-state {
	max-width: 46ch;
	margin: var(--wp--preset--spacing--60) auto;
	padding: 1.5rem;
	border: 1px dashed var(--wp--preset--color--border-strong, #d1d5db);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	text-align: center;
}

.f32-empty-state__title {
	margin: 0 0 0.25rem;
	font-size: 1rem;
	font-weight: 700;
}

.f32-empty-state__body {
	margin: 0 0 1rem;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.875rem;
}

.f32-empty-state__action {
	display: inline-block;
	padding: 0.625rem 1.125rem;
	border-radius: var(--wp--custom--border-radius--full, 9999px);
	background: var(--wp--preset--color--primary, #000);
	color: var(--wp--preset--color--contrast, #fff);
	font-size: 0.875rem;
	font-weight: 500;
	text-decoration: none;
}

.f32-empty-state__action:hover {
	background: #1f2937;
	color: var(--wp--preset--color--contrast, #fff);
	text-decoration: none;
}

/* ---------------------------------------------------------------------------
 * Sort dropdown — base-select with fallback
 * ------------------------------------------------------------------------ */

.wp-block-plainplugins-sort-dropdown {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.wp-block-plainplugins-sort-dropdown__select {
	appearance: base-select;
	padding: 0.375rem 0.625rem;
	border: 1px solid var(--wp--preset--color--border-strong, #d1d5db);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	color: var(--wp--preset--color--primary, #1a1a1a);
	font-family: inherit;
	font-size: 0.8125rem;
	line-height: 1.5;
	cursor: pointer;
}

.wp-block-plainplugins-sort-dropdown__select::picker-icon {
	color: var(--wp--preset--color--muted, #6b7280);
}

.wp-block-plainplugins-sort-dropdown__select::picker(select) {
	padding: 0.25rem;
	border: 1px solid var(--wp--preset--color--border-strong, #d1d5db);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	box-shadow: var(--wp--preset--shadow--lg, 0 8px 24px rgba(0, 0, 0, 0.12));
}

.wp-block-plainplugins-sort-dropdown__select option {
	padding: 0.375rem 0.625rem;
	border-radius: var(--wp--custom--border-radius--sm, 4px);
	font-size: 0.8125rem;
}

.wp-block-plainplugins-sort-dropdown__select option:hover {
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

.wp-block-plainplugins-sort-dropdown__select option:checked::checkmark {
	color: var(--wp--preset--color--accent, #1473e6);
}

.wp-block-plainplugins-sort-dropdown__label {
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Loading state during Interactivity router navigation
 * ------------------------------------------------------------------------ */

/*
 * PQF sets data-loading on the router region for the duration of a filter
 * navigation. Fading the grid rather than the whole region keeps the toolbar and
 * the open drawer solid, so the control the visitor just clicked does not
 * flicker under them.
 */
.wp-block-query[data-loading="true"] .archive-download-grid {
	opacity: 0.45;
	transition: opacity 0.12s ease;
	pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * Phones
 * ------------------------------------------------------------------------ */

@media (max-width: 781px) {
	/*
	 * THE TOOLBAR STAYS STICKY HERE. It used to go static, on the reasoning
	 * that the site header stops being sticky below 900px so there is nothing
	 * to pin under — true, and beside the point once the toolbar became the
	 * only route to a filter. `--f32-header-height` is only defined above
	 * 900px, so the base rule's `0px` fallback already pins it to the top of
	 * the screen; the override was all that stood in the way. Without it a
	 * phone visitor who scrolls two cards into a thirty-card page cannot reach
	 * a filter without scrolling all the way back.
	 */
	.archive-toolbar {
		gap: 0.5rem;
	}

	/*
	 * Count and sort take their own line ABOVE the trigger, so the trigger and
	 * the chips get the full width of the screen. Sharing one line left them
	 * 176px wide, with the second chip past the right edge, and the line it
	 * saved was worth less than the ability to see what is filtered.
	 */
	.archive-toolbar__meta {
		order: -1;
		flex: 1 0 100%;
		flex-direction: row;
		justify-content: space-between;
	}

	/*
	 * THE CHIPS SCROLL, THE TRIGGER DOES NOT. This row used to be the scroll
	 * container, which put the trigger — its first child — off the left edge as
	 * soon as a visitor swiped right to read their fourth chip. Moving the
	 * overflow onto the chip block alone keeps the button that opens the panel
	 * where the visitor left it.
	 *
	 * `padding-block` is not spacing. `overflow-x: auto` forces `overflow-y` to
	 * compute to `auto` as well, so the scroller clips vertically too, and the
	 * chips' focus rings sit 2px outside their boxes.
	 */
	.archive-toolbar__facets {
		flex: 1 1 100%;
		flex-wrap: nowrap;
	}

	.archive-toolbar .wp-block-plainplugins-active-filters {
		flex: 1 1 auto;
		min-width: 0;
		flex-wrap: nowrap;
		overflow-x: auto;
		padding-block: 2px;
		scrollbar-width: none;
	}

	.archive-toolbar .wp-block-plainplugins-active-filters::-webkit-scrollbar {
		display: none;
	}

	/*
	 * TAP TARGETS. Every control below was sized for a mouse: the trigger came
	 * to 33px tall, the close button 32px square, a colour swatch 26px and a
	 * category row 34px. All of them clear the 24px WCAG 2.2 floor and none of
	 * them is comfortable with a thumb, which is the only pointer this
	 * breakpoint has. Nothing here changes above 781px.
	 */
	.f32-filter-trigger {
		min-height: 40px;
	}

	.f32-filter-drawer__close {
		width: 40px;
		height: 40px;
	}

	.f32-filter-drawer .wp-block-sparklestock-color-filter__swatch-circle {
		width: 32px;
		height: 32px;
	}

	.f32-filter-drawer .f32-facet__terms .wp-block-term,
	.f32-filter-drawer .f32-facet__taxonomy .wp-block-plainplugins-taxonomy-filter__item,
	.f32-filter-drawer .wp-block-sparklestock-software-filter__item {
		padding-block: 0.6875rem;
	}

	.f32-filter-drawer__apply {
		padding-block: 0.9375rem;
	}

	.f32-pagination .page-numbers,
	.f32-pagination .wp-block-query-pagination-previous,
	.f32-pagination .wp-block-query-pagination-next {
		min-width: 2.5rem;
		height: 2.5rem;
	}

	/*
	 * A fixed 15rem cap is a quarter of a desktop window and two thirds of the
	 * drawer body on a 568px phone, where it makes the twenty-seven categories
	 * a second scroll surface that buries Apps and Colour below it. Tying the
	 * cap to the viewport keeps the other two groups on screen.
	 */
	.f32-filter-drawer .f32-facet__taxonomy {
		max-height: 40vh;
	}
}

/* ---------------------------------------------------------------------------
 * Small phones
 * ------------------------------------------------------------------------ */

@media (max-width: 600px) {
	/*
	 * TWO COLUMNS, NOT ONE — and this one is a fight with core, on purpose.
	 *
	 * Below 600px core forces every grid post-template to a single column:
	 *
	 *   .wp-block-post-template-is-layout-grid × 4 { grid-template-columns: 1fr }
	 *
	 * Four repetitions of one class, specificity 0,4,0, so it beats anything a
	 * theme writes normally. That default is right for the content it was
	 * written for — a column of posts with excerpts is unreadable two-up on a
	 * phone — and wrong for this grid, where the card is a thumbnail, a short
	 * title and a price. One column showed roughly one and a half products a
	 * screen on a catalogue of 1,082, which undoes the reason the sidebar and
	 * then the toolbar were taken off the page in the first place.
	 *
	 * The class is repeated to clear 0,4,0 rather than reaching for !important,
	 * which is the same trade assets/blocks/core-post-template.css makes
	 * against core's generated layout classes.
	 */
	/*
	 * The card's footer stacks. It is a nowrap row of title-then-price, sized
	 * for a 210px card: at 156px the price badge takes 55px of 124px and the
	 * title breaks a character to a line. `flex-wrap: wrap` is the wrong tool
	 * and is warned against in assets/blocks/core-post-template.css — it wraps
	 * only the cards whose titles happen to be long, which is where the ragged
	 * grid came from. A column wraps all of them the same way.
	 */
	.archive-download-grid > li > .wp-block-group > .wp-block-group {
		flex-direction: column;
		align-items: flex-start;
		gap: 0.375rem;
		padding: 12px;
	}

	/*
	 * The Purchased badge's inset tracks the footer padding - 16px above, and the
	 * 12px this block just set down here. Same reason both exist: the badge sits on
	 * the thumbnail but belongs to the card's grid of edges.
	 */
	p.is-style-entitlement-badge.is-entitlement-purchased {
		top: 12px;
		right: 12px;
	}

	/*
	 * On a ~156px card the top-left brand pills and the top-right Purchased badge
	 * share one narrow band, and a long app name ("Lightroom Classic") runs under
	 * the badge. The pills stop short of the badge zone instead: the badge is ~62px
	 * plus its 12px inset, so the pills keep everything left of that.
	 */
	.f32-corner-icons {
		max-width: calc(100% - 84px);
		overflow: hidden;
	}

	/*
	 * Pagination as a block, not a row. Wrapped as a flex row the three parts
	 * came out stacked in the order Prev / numbers / Next - the two controls
	 * that belong together split apart, one above the numbers and one below.
	 * Numbers across the top, Prev and Next on the edges underneath.
	 */
	.wp-block-query .f32-pagination {
		display: grid;
		grid-template-columns: 1fr 1fr;
		row-gap: 0.75rem;
	}

	.wp-block-query .f32-pagination .wp-block-query-pagination-numbers {
		grid-row: 1;
		grid-column: 1 / -1;
	}

	/* Explicit columns, because page 1 has no Prev and Next must still sit right. */
	.wp-block-query .f32-pagination .wp-block-query-pagination-previous {
		grid-row: 2;
		grid-column: 1;
		justify-self: start;
	}

	.wp-block-query .f32-pagination .wp-block-query-pagination-next {
		grid-row: 2;
		grid-column: 2;
		justify-self: end;
	}
}

/*
 * The floor for two columns. Below 360px the pair comes to 121px a card, which
 * is a thumbnail too small to judge a product by; core's own single column is
 * the better answer down there, so this override simply stops applying.
 */
@media (min-width: 360px) and (max-width: 600px) {
	.wp-block-query .archive-download-grid.archive-download-grid.archive-download-grid.archive-download-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (prefers-reduced-motion: reduce) {
	/*
	 * These selectors have to outrank the open-state rules that set the
	 * transitions, which are `:root[data-f32-filters="open"] .f32-filter-drawer`
	 * at 0,3,0. A bare class here loses the cascade and the panel keeps sliding -
	 * 260px of opaque motion across a phone screen for a visitor who asked for
	 * none.
	 */
	.wp-block-query[data-loading="true"] .archive-download-grid,
	.f32-filter-trigger,
	:root[data-f32-filters] .f32-filter-drawer,
	:root[data-f32-filters] .f32-filter-drawer__scrim,
	:root[data-f32-filters="open"] .f32-filter-drawer,
	:root[data-f32-filters="open"] .f32-filter-drawer__scrim {
		transition: none;
	}
}
