/*
 * Hydro Shield — Products catalogue page (/products/).
 *
 * REDESIGNED (direct follow-up command): moved away from the COMMAND 09
 * "2 large + 3 balanced" editorial/marketing layout to a real showroom
 * catalogue — one uniform 5-up grid of compact product tiles that open an
 * in-page detail overlay on click, plus a compact Packages section. The
 * Hero block below is unchanged from COMMAND 09. Own visual identity, own
 * class prefix (hs-cat) — does not reuse or modify any homepage/product-
 * page/navbar/footer stylesheet.
 *
 * Card technique is still the "image is the whole card, not a separate top
 * block over a disconnected grey body" device proven on the homepage's
 * product rail (template-parts/product-showcase.php's .hs-rail__card) —
 * media/scrim/body stacked as absolute layers over one aspect-ratio box —
 * just laid out as uniform tiles now instead of two differently-sized tiers.
 */

/* ================= 1. Compact Hero =================
 * Deliberately NOT the homepage's full-bleed cinematic background — a
 * catalogue page should get the visitor to the product grid quickly. One
 * static, contained image (same "contained/rounded" treatment as
 * protection-info.css's .hs-protect__media), not a slider. Unchanged from
 * the previous version of this page. */

.hs-cat-hero {
	position: relative;
	background: var(--hs-color-bg);
	overflow: hidden;
}

/* ================= Hero ambient background =================
 * Direct request: a few very-low-opacity images cycling continuously
 * BEHIND the whole Hero (copy + right-side image both), not just another
 * visible photo — purely a quiet ambient texture. Same stacked-slides
 * timer-crossfade device this site's own product-page hero sliders already
 * use (see page-ppf.js's runSlider()), just driven at a low target opacity
 * instead of 1 — see assets/js/page-products.js. */
.hs-cat-hero__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

.hs-cat-hero__bg-slide {
	position: absolute;
	inset: 0;
	opacity: 0;
}

.hs-cat-hero__bg-slide.is-active {
	/* The "very low opacity" itself — also the JS crossfade's target value,
	   kept in sync there since GSAP animates an inline opacity. */
	opacity: 0.1;
}

.hs-cat-hero__bg-slide img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hs-cat-hero__inner {
	position: relative;
	z-index: 1;
	max-width: 1360px;
	margin: 0 auto;
	padding: var(--hs-space-6) var(--hs-space-4) var(--hs-space-5);
	display: flex;
	align-items: center;
	gap: var(--hs-space-6);
}

.hs-cat-hero__copy {
	flex: 1 1 420px;
	max-width: 460px;
}


.hs-cat-hero__heading {
	margin: 0 0 var(--hs-space-3);
	font-size: clamp(2.1rem, 4vw, 3.1rem);
	font-weight: 700;
	line-height: 1.08;
	letter-spacing: -0.01em;
	text-transform: uppercase;
	color: var(--hs-color-text);
}

.hs-cat-hero__text {
	margin: 0;
	font-size: 1.02rem;
	line-height: 1.6;
	color: var(--hs-color-text-muted);
}

.hs-cat-hero__media {
	flex: 1 1 420px;
	max-width: 560px;
	position: relative;
	aspect-ratio: 5 / 4;
	border-radius: 10px;
	overflow: hidden;
	background: var(--hs-color-graphite);
	box-shadow: inset 0 0 0 1px rgba(240, 240, 232, 0.1);
}

.hs-cat-hero__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ================= SECTION 1 — Product Catalogue ================= */

.hs-cat-products {
	background: var(--hs-color-off-white);
	border-top: 1px solid rgba(26, 26, 29, 0.08);
	padding-top: var(--hs-space-6);
	padding-bottom: var(--hs-space-6);
}

.hs-cat-products__inner {
	max-width: 1360px;
	margin: 0 auto;
	padding: 0 var(--hs-space-4);
}

.hs-cat-products__intro {
	max-width: 640px;
	margin: 0 0 var(--hs-space-5);
}

.hs-cat-products__heading {
	margin: 0 0 var(--hs-space-2);
	font-size: clamp(1.6rem, 2.8vw, 2.2rem);
	font-weight: 700;
	letter-spacing: -0.005em;
	text-transform: uppercase;
	color: var(--hs-color-graphite);
}

.hs-cat-products__text {
	margin: 0;
	font-size: 1rem;
	line-height: 1.55;
	color: var(--hs-color-grey-dark);
}

/* ================= Filter + grid layout =================
 * FOLLOW-UP (direct client request — mirror alva.com.my/products.php's
 * filter, IA only): a fixed-width sidebar filter panel beside the grid,
 * same sidebar-checkbox-plus-Clear-All mechanic as that reference page,
 * scoped to the one filterable dimension this catalogue actually has (see
 * page-products.php's header comment). Stacks to filter-above-grid on
 * narrower viewports (see Responsive below) rather than a drawer/modal —
 * simplest honest translation of "sidebar" to a layout that still has to
 * work at phone width. */

.hs-cat-layout {
	display: grid;
	grid-template-columns: 176px 1fr;
	gap: var(--hs-space-5);
	align-items: start;
}

/* FOLLOW-UP: no longer position: sticky — with 5 category groups and 15
   series checkboxes (see page-products.php), the panel's own content
   (~855px) is now taller than a typical viewport itself, so a sticky+
   scroll-clipped box was hiding the last checkboxes rather than helping
   (confirmed via a real clientHeight vs scrollHeight check, not just a
   screenshot artifact). A plain block that scrolls with the page keeps
   every option reachable without an awkward nested scroll area. */
/* FOLLOW-UP (direct feedback — "small banao, no gaps"): padding and every
   gap/font size below shrunk again, on top of the earlier size pass. */
.hs-cat-filter {
	padding: 12px;
	border: 1px solid rgba(26, 26, 29, 0.1);
	border-radius: 8px;
	background: var(--hs-color-graphite);
}

.hs-cat-filter__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 8px;
}

.hs-cat-filter__heading {
	margin: 0;
	font-size: 0.74rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--hs-color-text);
}

.hs-cat-filter__clear {
	appearance: none;
	background: none;
	border: none;
	padding: 0;
	cursor: pointer;
	font: inherit;
	font-size: 0.64rem;
	font-weight: 600;
	color: var(--hs-color-text-muted);
	text-decoration: underline;
	text-decoration-color: rgba(240, 240, 232, 0.3);
	transition: color var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-filter__clear:hover,
.hs-cat-filter__clear:focus-visible {
	color: var(--hs-color-accent);
}

.hs-cat-filter__group {
	margin: 0;
	padding: 0;
	border: none;
}

/* Visually hidden (a real <legend> is still needed for screen readers on a
   <fieldset>, but the per-category labels below already carry the visible
   heading role — no separate global .screen-reader-text utility exists in
   this theme's CSS to reuse, so this is scoped locally). */
.hs-cat-filter__sr-legend {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* One group per category that HAS series (see page-products.php) — the
   category name as a mini-heading, its series checkboxes beneath. Matches
   ALVA's own sidebar grouping shape (category header + series checkboxes),
   just with this site's own real category/series data. */
.hs-cat-filter__category + .hs-cat-filter__category {
	margin-top: 8px;
	padding-top: 8px;
	border-top: 1px solid rgba(240, 240, 232, 0.08);
}

.hs-cat-filter__category-label {
	margin: 0 0 3px;
	font-size: 0.58rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--hs-color-text-muted);
}

.hs-cat-filter__option {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 2px 0;
	font-size: 0.7rem;
	color: var(--hs-color-text-muted);
	cursor: pointer;
}

/* PPS (no series) renders as one standalone checkbox at its category's own
   "level" — bumped up to read at the same visual weight as a category
   label, not indented like a series option under it. */
.hs-cat-filter__option--standalone {
	font-size: 0.72rem;
	font-weight: 600;
	color: var(--hs-color-text);
}

.hs-cat-filter__option input[type='checkbox'] {
	width: 13px;
	height: 13px;
	accent-color: var(--hs-color-accent);
	cursor: pointer;
}

.hs-cat-filter__option:hover span {
	color: var(--hs-color-text);
}

.hs-cat-empty {
	display: none;
	margin: var(--hs-space-5) 0 0;
	padding: var(--hs-space-5);
	text-align: center;
	border: 1px dashed rgba(26, 26, 29, 0.16);
	border-radius: 8px;
	font-size: 0.94rem;
	color: var(--hs-color-grey-dark);
}

.hs-cat-empty:not([hidden]) {
	display: block;
}

/* ================= Catalogue grid =================
 * One uniform row of equally-sized product tiles inside the filterable
 * area — a real showroom lineup, not an asymmetric "hero card vs.
 * supporting card" hierarchy. Wraps to 3, then 2, then 1 column as the
 * viewport narrows (see Responsive below) rather than staying cramped.
 *
 * FOLLOW-UP (direct feedback — "cards buhat baray hain... products baich
 * rahay hain na kay blogs read karna hai"): now that the grid holds 15
 * series cards (see page-products.php), 3-up read as bloated, closer to a
 * blog/article grid than a product listing. Bumped to 5-up with a tighter
 * gap; card internals shrunk to match (see .hs-cat-card__info below).
 *
 * RESPONSIVE FIX (2026-09-25): the fixed `repeat(5, 1fr)` forced exactly 5
 * columns immediately at the 1024px sidebar-layout breakpoint regardless of
 * how little room was left beside the 176px filter — at 1024px itself that
 * squeezed each card down to ~146px (visibly more cramped than the 3-column
 * stacked layout one pixel below it at 1023px, and than 768/820's own
 * cards). `repeat(auto-fill, minmax(180px, 1fr))` fixes this at the root:
 * the browser only ever creates as many columns as actually fit at a sane
 * 180px minimum, so at 1024px it self-heals to 4 columns (~184px cards)
 * instead of forcing a 5th column into too little space. At the actual
 * approved desktop widths this page was designed at (1280px/1440px+, where
 * 176px sidebar + gaps still leave enough room for 5 real columns) the
 * math resolves to exactly 5 columns at exactly the same card width as
 * before (197px/213px) — verified via computed styles, pixel-identical, no
 * visual regression. */
.hs-cat-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: var(--hs-space-2);
}

/* Hidden by the filter — see assets/js/page-products.js's initFilter(). */
.hs-cat-card[hidden] {
	display: none;
}

/* ================= Card =================
 * REDESIGNED (direct follow-up, 2026-09-17): the previous version was a
 * "cinematic overlay" tile — one full-bleed background photo with a dark
 * scrim and text floating on top, plus a giant 01/02/03 number — which
 * read as a portfolio/blog card, not a product one (direct feedback, with
 * a Shopee-style commerce listing as the visual-hierarchy reference — its
 * design/branding was NOT copied, only the IMAGE -> NAME -> SHORT INFO ->
 * CTA BUTTON hierarchy). Rebuilt as an actual product tile: a CONTAINED
 * square product photo (not full-card background), then a separate
 * solid-background info panel below it — normal block flow, not stacked
 * absolute layers, so the card's height is simply image + info, no forced
 * aspect-ratio on the outer button. Still a <button>, not a link — click
 * still opens the in-page product-detail overlay (assets/js/page-
 * products.js); that overlay's own "View Full Product" link is what
 * actually navigates to the product page — unchanged. */

.hs-cat-card {
	display: flex;
	flex-direction: column;
	width: 100%;
	border-radius: 8px;
	overflow: hidden;
	background: var(--hs-color-graphite);
	border: 1px solid rgba(26, 26, 29, 0.1);
	padding: 0;
	font: inherit;
	text-align: left;
	cursor: pointer;
	color: inherit;
	transition: transform var(--hs-duration-base) var(--hs-ease-standard), box-shadow var(--hs-duration-base) var(--hs-ease-standard);
}

.hs-cat-card:hover,
.hs-cat-card:focus-visible {
	transform: translateY(-4px);
	box-shadow: 0 24px 40px -22px rgba(26, 26, 29, 0.45);
}

.hs-cat-card:focus-visible {
	outline: 2px solid var(--hs-color-accent);
	outline-offset: 3px;
}

/* Contained product photo — a normal, bounded image area (like a real
   product listing photo), not a full-card cinematic background.
   FOLLOW-UP (direct feedback — shrink card height further): squared off
   1/1 made the photo taller than it needs to be at this card width; 4/3
   keeps it compact without cropping so tight it stops reading as the
   actual product photo. */
.hs-cat-card__media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--hs-color-bg);
}

.hs-cat-card__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--hs-ease-standard);
}

.hs-cat-card:hover .hs-cat-card__media img,
.hs-cat-card:focus-visible .hs-cat-card__media img {
	transform: scale(1.05);
}

/* Solid product-information panel BELOW the photo — not text scrimmed
   over the image. This is what makes it read as a product tile rather
   than an editorial/portfolio card.
   FOLLOW-UP (direct feedback — cards read too big/blog-like, then "desc
   text hata do, height chooti karo"): the description line is gone
   entirely (see page-products.php) — the panel is now just kicker + name
   + CTA, and padding shrunk again now that there's one less line to space
   around. */
/* ALIGNMENT FIX (2026-09-25): .hs-cat-grid is a CSS Grid, which by default
   stretches every card in a row to match the row's tallest neighbour — so
   a card next to one whose name wraps to 2 lines was already being made
   taller, but this panel had no flex-grow, so the extra height just
   appeared as empty space AFTER the CTA button instead of the CTA moving
   to stay pinned to the card's bottom edge. `flex: 1` lets this panel
   actually fill that stretched height; the CTA is pinned to its bottom
   via `margin-top: auto` below — same proven fix already used for the
   homepage rail's matching card (see .hs-rail__card-body/-action in
   product-showcase.css). Net effect: the CTA now sits at the same Y
   position across every card in a row regardless of title line count. */
.hs-cat-card__info {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: 8px 10px 10px;
	border-top: 1px solid rgba(240, 240, 232, 0.08);
}

/* Subtle secondary label (e.g. "PPF") — replaces the old giant 01/02/03
   editorial numbering entirely; small and muted, not a focal element. */
.hs-cat-card__kicker {
	font-size: 0.6rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--hs-color-text-muted);
	margin-bottom: 3px;
}

/* Name + price on one row (2026-09-22, direct request — real prices on
   every product card site-wide, same device as the homepage rail's
   .hs-rail__card-top). */
.hs-cat-card__top {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 6px;
	margin-bottom: 6px;
}

.hs-cat-card__name {
	font-size: 0.86rem;
	font-weight: 700;
	letter-spacing: 0.005em;
	color: var(--hs-color-off-white);
}

.hs-cat-card__price {
	flex: 0 0 auto;
	font-size: 0.62rem;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: var(--hs-color-accent);
	white-space: nowrap;
}

/* Clearly visible FILLED CTA — enough visual weight that this reads as a
   selectable product action, not a quiet text link. Filled off-white (the
   same primary-button treatment every other CTA on this site already
   uses) with a small cyan arrow as the one accent — cyan stays a refined
   accent, not a neon full-cyan button fill. */
.hs-cat-card__cta {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 5px;
	width: 100%;
	margin-top: auto;
	padding: 8px 10px;
	border-radius: var(--hs-radius-sm);
	background: var(--hs-color-off-white);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	color: var(--hs-color-graphite);
	transition: background var(--hs-duration-fast) var(--hs-ease-standard), transform var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-card__cta-arrow {
	display: inline-block;
	color: var(--hs-color-accent);
	transition: transform var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-card:hover .hs-cat-card__cta,
.hs-cat-card:focus-visible .hs-cat-card__cta {
	background: #ffffff;
}

.hs-cat-card:hover .hs-cat-card__cta-arrow,
.hs-cat-card:focus-visible .hs-cat-card__cta-arrow {
	transform: translateX(3px);
}


/* ================= Product-detail overlay =================
 * A spacious two-column panel (large image left, info right), not a
 * generic centered modal box. Hidden by default via opacity/visibility
 * (not display:none) so GSAP can animate it in/out; assets/js/page-
 * products.js toggles .is-open and drives the actual tween. */

.hs-cat-overlay {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--hs-space-4);
	visibility: hidden;
	opacity: 0;
	transition: opacity var(--hs-duration-base) var(--hs-ease-standard), visibility 0s var(--hs-duration-base);
}

.hs-cat-overlay.is-open {
	visibility: visible;
	opacity: 1;
	transition: opacity var(--hs-duration-base) var(--hs-ease-standard), visibility 0s;
}

.hs-cat-overlay__scrim {
	position: absolute;
	inset: 0;
	background: rgba(10, 10, 11, 0.72);
}

.hs-cat-overlay__panel {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 980px;
	max-height: 88vh;
	overflow: auto;
	display: grid;
	grid-template-columns: 1.2fr 1fr;
	background: var(--hs-color-graphite);
	border: 1px solid rgba(240, 240, 232, 0.12);
	border-radius: 10px;
	box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.6);
}

.hs-cat-overlay__close {
	position: absolute;
	top: 14px;
	right: 14px;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	border: 1px solid rgba(240, 240, 232, 0.2);
	background: rgba(26, 26, 29, 0.55);
	color: var(--hs-color-off-white);
	cursor: pointer;
	transition: border-color var(--hs-duration-fast) var(--hs-ease-standard), background var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-overlay__close:hover,
.hs-cat-overlay__close:focus-visible {
	border-color: var(--hs-color-accent);
	background: rgba(26, 26, 29, 0.85);
}

.hs-cat-overlay__close:focus-visible {
	outline: 2px solid var(--hs-color-accent);
	outline-offset: 2px;
}

.hs-cat-overlay__media {
	position: relative;
	min-height: 320px;
	background: var(--hs-color-bg);
}

.hs-cat-overlay__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ================= Overlay image navigation =================
 * Direct follow-up: each product will eventually carry many images, so the
 * overlay's media area gets left/right controls + a counter. Circular,
 * translucent-dark buttons (not giant default browser-style arrows) stay
 * readable over any photo — light or dark — because the backdrop behind
 * the icon is always the same dark chip regardless of what's under it,
 * not a border/shadow that depends on image contrast. */

.hs-cat-overlay__nav {
	position: absolute;
	top: 50%;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	margin-top: -20px;
	border-radius: 50%;
	border: 1px solid rgba(240, 240, 232, 0.22);
	background: rgba(26, 26, 29, 0.55);
	color: var(--hs-color-off-white);
	cursor: pointer;
	transition: background var(--hs-duration-fast) var(--hs-ease-standard), border-color var(--hs-duration-fast) var(--hs-ease-standard), transform var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-overlay__nav:hover,
.hs-cat-overlay__nav:focus-visible {
	background: rgba(26, 26, 29, 0.85);
	border-color: var(--hs-color-accent);
}

.hs-cat-overlay__nav:focus-visible {
	outline: 2px solid var(--hs-color-accent);
	outline-offset: 2px;
}

.hs-cat-overlay__nav:active {
	transform: scale(0.94);
}

.hs-cat-overlay__nav--prev {
	left: 14px;
}

.hs-cat-overlay__nav--next {
	right: 14px;
}

/* Hidden entirely (not just visually) when a product has 1 image or
   fewer — no reason to show navigation with nothing to navigate to.
   Toggled via this class in assets/js/page-products.js. */
.hs-cat-overlay__nav[hidden],
.hs-cat-overlay__counter[hidden] {
	display: none;
}

.hs-cat-overlay__counter {
	position: absolute;
	left: 14px;
	bottom: 14px;
	z-index: 2;
	padding: 5px 10px;
	border-radius: 999px;
	background: rgba(26, 26, 29, 0.55);
	border: 1px solid rgba(240, 240, 232, 0.18);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	color: var(--hs-color-off-white);
}

.hs-cat-overlay__info {
	padding: var(--hs-space-6) var(--hs-space-5);
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.hs-cat-overlay__number {
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	color: var(--hs-color-accent);
	margin-bottom: var(--hs-space-3);
}

.hs-cat-overlay__kicker {
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--hs-color-text-muted);
	margin-bottom: 6px;
}

.hs-cat-overlay__name {
	margin: 0 0 var(--hs-space-3);
	font-size: clamp(1.5rem, 2.6vw, 2rem);
	font-weight: 700;
	line-height: 1.15;
	color: var(--hs-color-text);
}

.hs-cat-overlay__desc {
	margin: 0 0 var(--hs-space-4);
	font-size: 1rem;
	line-height: 1.6;
	color: var(--hs-color-text-muted);
	max-width: 44ch;
}

.hs-cat-overlay__link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	align-self: flex-start;
	font-size: 0.9rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--hs-color-graphite);
	background: var(--hs-color-off-white);
	border: 1px solid var(--hs-color-off-white);
	padding: 13px 22px;
	border-radius: var(--hs-radius-sm);
	transition: background var(--hs-duration-fast) var(--hs-ease-standard), transform var(--hs-duration-fast) var(--hs-ease-standard), box-shadow var(--hs-duration-fast) var(--hs-ease-standard);
}

.hs-cat-overlay__link:hover,
.hs-cat-overlay__link:focus-visible {
	background: #ffffff;
	transform: translateY(-1px);
	box-shadow: 0 10px 24px -12px rgba(0, 0, 0, 0.55);
}

.hs-cat-overlay__link:focus-visible {
	outline: 2px solid var(--hs-color-accent);
	outline-offset: 3px;
}

/* Body scroll lock while the overlay is open — scoped to this page only
   (the class is added/removed exclusively by page-products.js). */
body.hs-cat-overlay-open {
	overflow: hidden;
}

/* ================= Responsive ================= */

@media (max-width: 1023.98px) {
	.hs-cat-hero__inner {
		flex-direction: column-reverse;
		align-items: stretch;
		padding-top: var(--hs-space-5);
	}

	.hs-cat-hero__copy,
	.hs-cat-hero__media {
		max-width: none;
	}

	.hs-cat-hero__media {
		aspect-ratio: 16 / 9;
	}

	.hs-cat-layout {
		grid-template-columns: 1fr;
	}

	/* FILTER FIX (2026-09-25): the panel used to run `flex-wrap` on the
	   category groups, which lays them out strictly left-to-right/top-to-
	   bottom in DOM order — so a short group (e.g. 2-item PPS) landing next
	   to a tall one (5-item Colour Wrap) left a large dead gap under the
	   short group instead of the next group flowing up into it (confirmed
	   via computed-style row measurements: at 731px PPS's row left ~140px
	   of empty space below it before Coating even started). A CSS
	   multi-column layout balances column heights automatically instead of
	   placing items into fixed rows, so groups pack tightly with no
	   leftover dead space regardless of how uneven their item counts are —
	   this is what actually makes the panel "compact" rather than merely
	   narrower. `column-width` is a minimum/hint, not a fixed count, so the
	   browser fits as many ~130px columns as the available width allows:
	   1 column on the narrowest phones, 2 around 375-480px, up to 4-5 on
	   tablet widths — no separate breakpoint needed for each step. */
	.hs-cat-filter__group {
		column-width: 112px;
		column-gap: var(--hs-space-3);
	}

	.hs-cat-filter__category {
		break-inside: avoid;
		padding-bottom: var(--hs-space-3);
	}

	.hs-cat-filter__category:last-child {
		padding-bottom: 0;
	}

	.hs-cat-filter__category + .hs-cat-filter__category {
		margin-top: 0;
		padding-top: 0;
		border-top: none;
	}

	.hs-cat-filter__category-label {
		margin-bottom: 4px;
	}

	.hs-cat-grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.hs-cat-overlay__panel {
		grid-template-columns: 1fr;
	}

	.hs-cat-overlay__media {
		min-height: 260px;
	}

	.hs-cat-overlay__info {
		padding: var(--hs-space-5) var(--hs-space-4);
	}
}

/* CARD SIZING FIX (2026-09-25): this tier used to force 2 columns for the
 * entire 640-767.98px range, with no upper cap on how wide that let each
 * card grow — at 731px specifically that meant a ~338px card (measured via
 * computed styles), dramatically larger than its 235px neighbour one pixel
 * above the breakpoint at 768px, and far outside the 180-260px range every
 * other product card on this page sits in. Removing this tier lets that
 * range fall through to the 1023.98px tier's own `repeat(3, 1fr)` rule
 * instead (below), which was already correct for 768px/820px — 731px now
 * gets 3 sensibly-sized ~222px columns rather than 2 oversized ones. The
 * true "cards get cramped, switch to 2 columns" cutoff stays at 639.98px,
 * in the tier below, unchanged. */

@media (max-width: 639.98px) {
	.hs-cat-hero__inner {
		padding-top: var(--hs-space-4);
		padding-bottom: var(--hs-space-4);
		gap: var(--hs-space-4);
	}

	.hs-cat-products {
		padding-top: var(--hs-space-5);
		padding-bottom: var(--hs-space-5);
	}

	/* 2-up even at phone width — the cards are compact product tiles now
	   (not full-width blog-style cards), same as most commerce grids keep
	   at this size. */
	.hs-cat-grid {
		grid-template-columns: repeat(2, 1fr);
		gap: var(--hs-space-2);
	}

	.hs-cat-overlay {
		padding: 0;
	}

	.hs-cat-overlay__panel {
		max-height: 100vh;
		height: 100%;
		border-radius: 0;
	}
}

/* Extremely narrow phones — 2 columns at this width shrinks each card to
   ~90-150px (page padding + grid gap eat a large share of the viewport),
   too cramped for a readable name/price/CTA. One column keeps every card
   genuinely usable instead of forcing tiny cards; matches the same
   359.98px tier already used for the homepage's product circles. */
@media (max-width: 359.98px) {
	.hs-cat-grid {
		grid-template-columns: 1fr;
	}

	/* At this width the filter panel's own content area (~150-180px after
	   page/panel padding) is too narrow for two genuinely comfortable
	   112px columns (see the 1023.98px tier above) — `column-width` was
	   either collapsing back to 1 tall column, or (tried during QA) forcing
	   a 3rd column so narrow that long labels like "Multi-Layer Ceramic
	   Coating" wrapped 4 lines deep, which pushed the total height up
	   instead of down. `column-count: 2` (a fixed count, not a width hint)
	   guarantees exactly 2 balanced columns at any width in this tier,
	   which is what actually keeps the panel short here — scoped to just
	   this phone-width tier so it never affects the wider 731px/768px/820px
	   cases above, which already read cleanly with more columns. */
	.hs-cat-filter__group {
		column-count: 2;
		column-width: auto;
		column-gap: var(--hs-space-3);
	}
}

/* ================= Reduced motion ================= */

@media (prefers-reduced-motion: reduce) {
	.hs-cat-card,
	.hs-cat-card__media img,
	.hs-cat-card__cta,
	.hs-cat-card__cta-arrow,
	.hs-cat-overlay,
	.hs-cat-overlay__link,
	.hs-cat-overlay__nav,
	.hs-cat-overlay__media img {
		transition: none;
	}
}
