Design System

Product card grid

The canonical responsive grid for product / treatment cards. One line of CSS carries the whole pattern: repeat(auto-fill, minmax(min(--product-grid-min, 100%), --product-grid-max)).

The max track is the load-bearing part. Without a ceiling, a grid of 1fr columns stretches whatever cards it has across the full row — a product page with a single related treatment rendered one card 1240px wide and 1016px tall. With the ceiling, cards pack from the start at their natural size and a short row simply looks short.

The column count then re-flows with the viewport and needs no breakpoints: roughly 3-up inside the 1240px site container, more on a wide screen, one on mobile. min(300px, 100%) is what keeps the 300px floor from overflowing a phone narrower than that, and auto-fill (not auto-fit) preserves the empty trailing tracks so a sparse row stays left-aligned to the grid instead of drifting to the centre.

Promoted out of HQ, which had patched exactly this bug locally in .halwel-catalog-panel-grid while the storefront kept the stretch-to-fill version. Both surfaces now consume this primitive and HQ's override is gone.

import from @halwel/ui/components/product/ProductCardGrid

Variants