/*
 * Catalogue grid: artwork archive (shop / product category / product tag).
 *
 * Implements docs/17_VISUAL_DESIGN.md, "Catalog grid (archive-product.php —
 * task #55)", v2 pass matched against the binding mockup
 * `wordpress/mockup/podoba-v2.html?p=catalogue` (`.cat-head`, `.filters`,
 * `.grid`/`.card`, `.pager`). Loaded only on WooCommerce product-archive
 * views (see inc/enqueue.php) — never sitewide.
 *
 * Mobile-first: base rules target ~375px, min-width media queries widen the
 * layout upward (agency standard, .claude/rules — no max-width cascades).
 * All color/type values come from theme.json via the CSS custom properties
 * WordPress generates from it (--wp--preset--*) — no hex/font literals here,
 * per docs/17 "Hard rules" #1.
 */

/* Page head: "Catalogue" + count line, mockup `.cat-head`. Extra top
 * padding approximates the mockup's `.cat-head{padding:clamp(2.2rem,5vh,
 * 3.6rem) ...}`.
 *
 * Container width/padding: an earlier pass (task #55) capped this view at
 * `.site-main`'s sitewide `max-width: 1200px` plus a `+2rem` widening, so
 * the grid always reached exactly 4 columns on any desktop-or-wider
 * viewport. Skeptik review (docs/17 v2's own rule: "where this document
 * and the mockup disagree, the mockup wins") measured this against the
 * binding mockup at 1280px via CDP `getBoundingClientRect()` and found a
 * real, reproducible mismatch: the mockup's `.grid`/`.cat-head`/`.filters`
 * carry NO fixed max-width at all — only a fluid `--pad:
 * clamp(1.25rem,4vw,3.5rem)` side padding — so its column count grows
 * continuously with viewport width rather than snapping to 4 as soon as a
 * fixed cap is reached; at exactly 1280px this fluid math (see
 * `ul.products` below) yields 3 columns, not 4. Reproduced here exactly —
 * same `--pad` formula, no max-width — so the two stay in step at every
 * width, not just the two spot-checked ones. Deliberately NOT applied to
 * the sitewide `.site-main` default (front page, single artwork, static
 * pages keep their existing 1200px reading-width cap — out of this task's
 * scope) — scoped to `.woocommerce-archive` only. */
.site-main.woocommerce-archive {
	max-width: none;
	padding-top: clamp(1.75rem, 1.1rem + 3vw, 3.1rem);
	padding-right: clamp(1.25rem, 4vw, 3.5rem);
	padding-left: clamp(1.25rem, 4vw, 3.5rem);
}

.woocommerce-archive .page-title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	font-size: clamp(2.2rem, 1.85rem + 1.75vw, 3rem);
	color: var(--wp--preset--color--foreground);
	margin: 0 0 0.35rem;
}

/* Count line: "N works · oil on canvas" (inc/catalog-grid.php's
 * jost_snoj_render_catalog_count()) — replaces WooCommerce's default
 * "Showing 1-16 of N results" text per the v2 mockup's `.cat-head .count`. */
.jost-snoj-catalog-count {
	color: var(--wp--preset--color--muted);
	font-size: 0.9rem;
	margin: 0 0 2rem;
}

/* ===================================================================
 * Filter row: Series / Year / Size / Availability
 * (inc/catalog-filters.php — task "Katalog: razširjeni filtri")
 *
 * Quiet rows of text links, never pills, tabs or <select> dropdowns —
 * docs/17's "no decorative UI" thesis and the v2 mockup's `.filters`
 * (`wordpress/mockup/podoba-v2.html?p=catalogue`), which this extends from
 * one group to four while keeping the same type treatment (uppercase micro-
 * label, muted until active, ochre underline when active).
 *
 * Mobile-first: base rules are the collapsed "Filters" disclosure at ~375px;
 * the >=700px media query at the end of this block opens it into a plain
 * row. That breakpoint is shared with the primary nav (style.css) and with
 * assets/js/main.js — change all three together.
 * =================================================================== */
.jost-snoj-filters {
	margin: 0 0 2.4rem;
	border-bottom: 1px solid var(--wp--preset--color--line);
	padding-bottom: 0.75rem;
}

/* "Filters" toggle: plain text, no icon font, no marker triangle — same
 * treatment as the header's "Menu" toggle (style.css `.menu-toggle`). */
.jost-snoj-filters__toggle {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 12px 2px;
	color: var(--wp--preset--color--foreground);
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	cursor: pointer;
	list-style: none;
}

.jost-snoj-filters__toggle::-webkit-details-marker {
	display: none;
}

/* Active-filter count in the collapsed toggle ("Filters (2)"), so a shared
 * filtered URL announces itself on mobile before the panel is opened. Ochre
 * — the one accent already used for the active-filter underline, so the
 * same colour means the same thing in both places. */
.jost-snoj-filters__active-count {
	margin-left: 0.4rem;
	color: var(--wp--preset--color--accent);
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.06em;
}

/* Stacked groups on mobile: one group per row, so no group's option list
 * can ever be pushed sideways past the viewport. */
.jost-snoj-filters__panel {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding-bottom: 0.5rem;
}

.jost-snoj-filter-group__label {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.68rem;
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

.jost-snoj-filter-group ul {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 1.6rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.jost-snoj-filter-group li {
	display: flex;
	align-items: center;
	/* Keeps the option link and its "×" control the agency-standard >=8px
	 * apart, so neither is a mis-tap risk for the other. */
	gap: 8px;
	margin: 0;
}

.jost-snoj-filter-group a {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	/* Generous vertical padding keeps the tap target >= 44px tall even
	 * though the link reads as plain text, not a button. */
	min-height: 44px;
	padding: 10px 2px;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	text-decoration: none;
}

.jost-snoj-filter-group a:hover {
	color: var(--wp--preset--color--foreground);
}

/* Option counts: same micro-label size, tabular so the parenthesised
 * numbers don't jitter the row as the counts change between views. */
.jost-snoj-filter-count {
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.06em;
}

/* Active filter: ink text + an ochre underline (not colour alone — agency
 * standard). `text-decoration` (not `border-bottom`) so the rule hugs the
 * text baseline regardless of the link's padded 44px tap-target box, same
 * technique already used for the header's active nav item (style.css
 * `.primary-menu .current-menu-item > a`). */
.jost-snoj-filter-group li.is-active > a:first-child {
	color: var(--wp--preset--color--foreground);
}

/* The rule underlines the option LABEL only — not its count. Underlining
 * the whole link drew a second, detached stroke under "(13)", reading as
 * two underlined things rather than one active filter with a tally. */
.jost-snoj-filter-group li.is-active > a:first-child > .jost-snoj-filter-label,
.jost-snoj-section-filter li.is-active > a:first-child {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 1px;
	text-underline-offset: 6px;
}

/* "×" remove control: its own 44x44 tap target next to the active option.
 * The glyph is a real text × (U+00D7) — no icon font, per docs/17. */
.jost-snoj-filter-remove {
	justify-content: center;
	min-width: 44px;
	padding: 10px 0;
	font-size: 0.95rem;
	line-height: 1;
	letter-spacing: 0;
	text-decoration: none;
}

.jost-snoj-filter-remove:hover {
	color: var(--wp--preset--color--accent);
}

/* Desktop: the disclosure disappears as a control (the inline script in
 * inc/catalog-filters.php has already forced it open) and the groups lay
 * out as a single wrapping row of labelled clusters — the mockup's
 * `.filters{display:flex;gap:2rem;flex-wrap:wrap}`, one cluster per group.
 * `min-width: 0` on each group lets a long series name wrap inside its own
 * cluster rather than forcing the row wider than the viewport. */
@media (min-width: 700px) {
	.jost-snoj-filters__toggle {
		display: none;
	}

	.jost-snoj-filters__panel {
		flex-direction: row;
		flex-wrap: wrap;
		gap: 0.4rem 2.4rem;
		padding-bottom: 0;
	}

	.jost-snoj-filter-group {
		display: flex;
		align-items: baseline;
		flex-wrap: wrap;
		gap: 0 1.2rem;
		min-width: 0;
	}
}

/* The "Default sorting" <select> WooCommerce would normally render next to
 * this is removed entirely (inc/catalog-grid.php) — meaningless in
 * catalogue mode (no price, no reviews, no purchase history to sort by)
 * and, per docs/17_VISUAL_DESIGN.md's "no decorative UI" thesis and the v2
 * mockup, better omitted than styled. No `.woocommerce-ordering select`
 * rule is needed here as a result. */

/* Designed empty state (inc/catalog-filters.php's
 * jost_snoj_render_catalog_no_results()) — replaces WooCommerce's default
 * `.woocommerce-info` "No products were found matching your selection."
 * notice, which is both the wrong register for artworks and an unstyled
 * shop notice. Quiet body text plus one accent link back out; the filter
 * row above it stays rendered, so the "×" controls remain reachable. */
.jost-snoj-catalog-empty {
	margin: 0;
	padding: clamp(2rem, 5vw, 3.5rem) 0;
	color: var(--wp--preset--color--muted);
}

.jost-snoj-catalog-empty p {
	margin: 0 0 0.9rem;
	font-family: var(--wp--preset--font-family--text);
	font-size: 1rem;
}

.jost-snoj-catalog-empty__reset {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--wp--preset--color--accent);
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	text-decoration: underline;
	text-underline-offset: 6px;
}

.jost-snoj-catalog-empty__reset:hover {
	color: var(--wp--preset--color--accent-ink);
}

/* Grid: WooCommerce's own loop wrapper (ul.products), restyled as a CSS
 * grid rather than the float/column-class layout WooCommerce ships by
 * default. Track minimum (272px) and gap are copied verbatim from the
 * mockup's `.grid{grid-template-columns:repeat(auto-fill,minmax(272px,
 * 1fr));gap:clamp(1.4rem,2.5vw,2.4rem)}` — NOT docs/17 prose's `280px`/
 * fixed 16-24px gutter tokens — per docs/17 v2's own precedence rule
 * ("where this document and the mockup disagree, the mockup wins") and
 * the Skeptik finding above: with the container's max-width also removed
 * (see `.site-main.woocommerce-archive` above), this combination is what
 * actually reproduces the mockup's column count at every viewport width
 * (1 column ~375-600px, growing continuously afterwards — 3 columns at
 * 1280px, 4 at ~1350px+ — rather than snapping straight to 4 as soon as a
 * fixed desktop container width is reached). No separate `min-width:700px`
 * gap override needed any more — the clamp() is already fluid. */
.woocommerce-archive ul.products {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
	gap: clamp(1.4rem, 2.5vw, 2.4rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Embedded galleries stay one-column first, then honour their validated
 * two/three-column setting without introducing a fixed content width. */
.jost-snoj-gallery.woocommerce-archive ul.products {
	grid-template-columns: minmax(0, 1fr);
}

/* Beat WooCommerce's float grid on non-archive pages regardless of enqueue
 * order; the outer gallery class makes these resets deliberately stronger. */
.jost-snoj-gallery.woocommerce-archive ul.products li.product {
	float: none;
	width: auto;
	margin: 0;
}

@media (min-width: 700px) {
	.jost-snoj-gallery.woocommerce-archive[data-columns="2"] ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.jost-snoj-gallery.woocommerce-archive[data-columns="3"] ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* ---------------------------------------------------------------------------
 * Divi page-builder compatibility for the [jost_snoj_galerija] shortcode.
 *
 * The category subpages (galerija-*) embed the shortcode inside a Divi
 * et_pb_text module. Divi's WooCommerce integration then (a) injects an empty
 * .et_shop_image/.et_overlay wrapper before the theme's own card media — whose
 * Divi positioning pulls the card out of the grid and overlaps the caption —
 * and (b) paints every link inside .et_pb_text with Divi's blue link colour,
 * turning the card captions blue. Both are neutralised here, scoped to
 * .jost-snoj-gallery so the real /catalogue/ archive (no Divi wrapper) is never
 * affected. !important is deliberate: it is the reliable way to win against
 * Divi's own high-specificity (sometimes !important) module CSS on these pages.
 * ------------------------------------------------------------------------- */
.jost-snoj-gallery .et_shop_image,
.jost-snoj-gallery .et_overlay {
	display: none !important;
}

.jost-snoj-gallery.woocommerce-archive ul.products {
	display: grid !important;
	grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)) !important;
	gap: clamp(1.4rem, 2.5vw, 2.4rem) !important;
	float: none !important;
	width: 100% !important;
	margin: 0 !important;
	padding: 0 !important;
}

/* WooCommerce's default stylesheet (not dequeued on this non-archive Divi page,
 * unlike the real catalogue archive) adds a clearfix `ul.products::before/
 * ::after`. Inside a CSS grid those pseudo-elements become real grid items,
 * stealing the first cells and pushing the first artwork into the second
 * column with a large empty gap. Remove them here. */
.jost-snoj-gallery.woocommerce-archive ul.products::before,
.jost-snoj-gallery.woocommerce-archive ul.products::after {
	display: none !important;
	content: none !important;
}

.jost-snoj-gallery.woocommerce-archive ul.products li.product {
	float: none !important;
	clear: none !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	position: static !important;
}

.jost-snoj-gallery a.woocommerce-LoopProduct-link,
.jost-snoj-gallery .jost-snoj-card__title {
	color: var(--wp--preset--color--foreground) !important;
}

.jost-snoj-gallery .jost-snoj-card__title-translation,
.jost-snoj-gallery .jost-snoj-card__year,
.jost-snoj-gallery .jost-snoj-card__legend,
.jost-snoj-gallery .jost-snoj-card__specs {
	color: var(--wp--preset--color--muted) !important;
}

/* WooCommerce's own default stylesheet (assets/css/woocommerce.css, loaded
 * sitewide by the plugin regardless of theme — see inc/enqueue.php's
 * `jost_snoj_disable_woocommerce_default_styles()` for why that stylesheet
 * is dequeued on this view specifically) styles `li.product` for its own
 * float-based grid: `.woocommerce-page ul.products li.product{float:left;
 * width:22.05%;margin:0 3.8% 2.992em 0}`. `width`/`float`/`position` are
 * NOT properties this rule declared before this fix, so — even with the
 * plugin's default stylesheet dequeued here as belt-and-braces — any other
 * plugin/mu-plugin that enqueues equivalent CSS would silently win on
 * exactly those three properties (no specificity contest needed when only
 * one rule sets a property at all). Resetting them explicitly is what
 * actually makes every `li.product` fill its CSS grid cell: without this,
 * the *grid track* sizes correctly (`ul.products` above has enough
 * specificity to win `display:grid`) but each *item* inside shrinks to
 * ~22% of that track's width, leaving a large empty tile with a tiny
 * ~90px-wide thumbnail in the corner — the exact bug this task fixes.
 */
.woocommerce-archive ul.products li.product {
	margin: 0;
	padding: 0;
	list-style: none;
	float: none;
	width: auto;
	position: static;
	/* Grid items default to `min-width: auto`, i.e. their content's
	 * min-content size — which, for a descendant <img>, is computed from
	 * its *intrinsic* pixel dimensions (e.g. 1024px wide) because a
	 * percentage `max-width` can't be resolved during that intrinsic-size
	 * pass. Left unset, every artwork's full intrinsic width would set a
	 * floor on this grid item (and the shared track alongside it),
	 * blowing the whole row past the viewport at narrow widths — a
	 * horizontal-scroll violation of the agency's mobile-first standard,
	 * confirmed via an actual 390px render. `min-width: 0` overrides that
	 * default so the item (and everything nested inside it) can shrink to
	 * the grid track's actual size instead. See
	 * https://css-tricks.com/preventing-a-grid-blowout/. */
	min-width: 0;
}

/* The whole card (image + caption) is one link — WooCommerce opens/closes
 * this <a> around the thumbnail/title/meta hooks by default; we only swap
 * what's rendered inside it (see inc/catalog-grid.php). No gap here — the
 * spacing between tile and caption comes from .jost-snoj-card__cap's own
 * top padding (mockup `.card a{display:block}`, `.card-cap{padding:.85rem
 * .1rem 0 …}`). */
.woocommerce-archive a.woocommerce-loop-product__link {
	display: flex;
	flex-direction: column;
	min-width: 0;
	color: inherit;
	text-decoration: none;
}

/* Surface tile: 4:5, artwork image `object-fit: contain` with a 9% inner
 * padding on all sides (mockup `.card-media{padding:9%}`) — the image never
 * touches the tile's own hairline border. `min-width: 0` — same grid-
 * blowout guard as li.product above, needed again here because this is
 * itself a flex container (a flex item's automatic minimum size is also
 * its content's min-content size by default). */
.jost-snoj-card__media {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 0;
	aspect-ratio: 4 / 5;
	padding: 9%;
	background-color: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	overflow: hidden;
	transition: box-shadow 250ms ease;
}

.jost-snoj-card__media img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	/* margin: 0 — same defense-in-depth reasoning as the li.product reset
	 * above: WooCommerce's default stylesheet's `ul.products li.product a
	 * img` rule sets `margin:0 0 1em`, which would otherwise add an
	 * unwanted gap below the image inside this flex card. */
	margin: 0;
	object-fit: contain;
	transition: transform 200ms ease;
}

.jost-snoj-card__media .jost-snoj-artwork-placeholder {
	width: 60%;
	height: 60%;
	border: 1px dashed var(--wp--preset--color--line);
}

/* Hover/focus: tile shadow + a barely-perceptible image scale (mockup
 * `.card a:hover .card-media{box-shadow:var(--shadow)}`,
 * `.card a:hover .card-media img{transform:scale(1.022)}`) — no overlays,
 * no icons, per docs/17. */
.woocommerce-archive a.woocommerce-loop-product__link:hover .jost-snoj-card__media,
.woocommerce-archive a.woocommerce-loop-product__link:focus-visible .jost-snoj-card__media {
	box-shadow: var(--wp--custom--shadow--exhibit);
}

@media (prefers-reduced-motion: no-preference) {
	.woocommerce-archive a.woocommerce-loop-product__link:hover .jost-snoj-card__media img,
	.woocommerce-archive a.woocommerce-loop-product__link:focus-visible .jost-snoj-card__media img {
		transform: scale(1.022);
	}
}

/* Caption row: title left, year right, ONE line
 * (`justify-content: space-between`) — mockup `.card-cap`. */
.jost-snoj-card__cap {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.8rem;
	padding: 0.85rem 0.1rem 0;
}

.jost-snoj-card__title-group {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.jost-snoj-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 400;
	font-size: 1.02rem;
	line-height: 1.3;
	color: var(--wp--preset--color--foreground);
	margin: 0;
	transition: color 180ms ease;
}

.jost-snoj-card__title-translation {
	margin-top: 4px;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.82rem;
	font-style: italic;
	line-height: 1.3;
}

.woocommerce-archive a.woocommerce-loop-product__link:hover .jost-snoj-card__title,
.woocommerce-archive a.woocommerce-loop-product__link:focus-visible .jost-snoj-card__title {
	color: var(--wp--preset--color--accent);
}

.jost-snoj-card__year {
	flex: 0 0 auto;
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.78rem;
	color: var(--wp--preset--color--muted);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.jost-snoj-gallery__warning {
	margin: 0;
	padding: 1rem;
	border: 1px solid var(--wp--preset--color--line);
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--foreground);
}

/* ===================================================================
 * Card legend — SECOND caption line (template-parts/card-legend.php)
 *
 * Row 1 above is untouched (serif title left · tabular year right); this is
 * the quiet muted line under it: "technique · W × H cm" left, availability
 * right. This block is the AUTHORITY for the legend's look; the front page's
 * "Selected works" grid mirrors it scoped to `.jost-snoj-front-grid` in
 * assets/css/front-page.css (that file already re-declares the whole card
 * caption the same way — the two stylesheets are enqueued on disjoint views,
 * so a shared rule is not reachable across them). Change both together.
 *
 * Deliberately austere: no badge, no pill, no border, no second accent
 * colour — docs/17's "no decorative UI" thesis. The only ink beyond muted
 * grey is a single 7px dot.
 * =================================================================== */
.jost-snoj-card__legend {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.8rem;
	/* 4px, the agency spacing scale's small-element exception: this line is
	 * a continuation of the caption above it, not a new block. */
	padding: 4px 0.1rem 0;
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.78rem;
	line-height: 1.35;
	color: var(--wp--preset--color--muted);
}

/* Left cell: technique · size. MUST NOT wrap to a second line (task
 * acceptance criterion) — an over-long technique such as "olje in metalni
 * akril na platnu" is truncated with an ellipsis instead of pushing the card
 * taller and knocking the grid's rows out of alignment. `min-width: 0` is
 * required for `text-overflow` to ever fire inside a flex row: without it
 * this cell's automatic minimum size is its own min-content width, so it
 * refuses to shrink below the longest word and overflows the card (and, at
 * 390px, the viewport) rather than ellipsing — the same grid/flex blowout
 * guard already applied to li.product and .card__media above. */
.jost-snoj-card__specs {
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font-variant-numeric: tabular-nums;
}

/* Right cell: availability, small-caps, never shrinking or wrapping so the
 * dot + label always read as one unit at the card's right edge. The label is
 * `muted` (5.3:1 on `background`), NOT the green — at 0.78rem this is small
 * text and #5B8A5E would land at 3.9:1, under WCAG 2.2 AA's 4.5:1. The
 * colour lives in the dot only (3.9:1 clears the 3:1 non-text threshold),
 * and the state is always ALSO spelled out in words, so the meaning never
 * depends on colour alone (agency accessibility standard #2). */
.jost-snoj-card__status {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	gap: 0.45rem;
	font-size: 0.68rem;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	white-space: nowrap;
}

/* 7px dot — same treatment as the single-artwork availability line
 * (assets/css/single-artwork.css `.jost-snoj-artwork__availability::before`,
 * docs/17 v2: "availability with 7px green (#5B8A5E) dot + small-caps"), so
 * the grid and the single view speak the same visual language. */
.jost-snoj-card__status::before {
	content: "";
	flex-shrink: 0;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background-color: var(--wp--preset--color--line);
}

/* Green only for genuinely available work. Sold / reserved / not-for-sale
 * keep a neutral grey dot — one accent state, not a traffic-light palette. */
.jost-snoj-card__status--available::before {
	background-color: var(--wp--preset--color--available);
}

.jost-snoj-card__status--sold::before,
.jost-snoj-card__status--reserved::before,
.jost-snoj-card__status--nfs::before {
	background-color: var(--wp--preset--color--muted);
}

/* Pagination: WooCommerce's own `loop/pagination.php` (not overridden —
 * `<nav class="woocommerce-pagination"><ul class="page-numbers">…`),
 * restyled as a centered, tabular-numeral row with the active page in a
 * `surface` box — mockup `.pager`. */
.woocommerce-archive .woocommerce-pagination {
	margin: clamp(2rem, 4vw, 3.2rem) 0 0;
}

.woocommerce-archive .woocommerce-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce-archive .woocommerce-pagination .page-numbers li {
	display: block;
}

.woocommerce-archive .woocommerce-pagination a.page-numbers,
.woocommerce-archive .woocommerce-pagination span.page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0.5rem 0.85rem;
	border: 1px solid transparent;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--text);
	font-size: 0.9rem;
	font-variant-numeric: tabular-nums;
	text-decoration: none;
}

.woocommerce-archive .woocommerce-pagination a.page-numbers:hover {
	color: var(--wp--preset--color--accent);
}

/* Active page: ink text in a surface box with a hairline border — mockup
 * `.pager a.on{color:var(--ink);border-color:var(--line);background:var(--surface)}`. */
.woocommerce-archive .woocommerce-pagination span.page-numbers.current {
	color: var(--wp--preset--color--foreground);
	border-color: var(--wp--preset--color--line);
	background-color: var(--wp--preset--color--surface);
}
