product-list — Wrapper pro výpis produktů — grid layout s row-gap a visible-count info

app/components/Eshop/product-list.latte
{*
	Product List — wrapper pro výpis produktů s grid layoutem.

	Parametry:
	- $items         (array)         pole produktů (hodnota je libovolný objekt; renderer předává do $itemTemplate)
	- $itemTemplate  (string)        cesta k Latte template pro jednotlivý produkt
	- $visibleCount  (string|null)   text typu "Zobrazeno 12 z 48 produktů" (volitelně)
	- $rowClass      (string)        extra třída na .product-list__row (default 'row')
*}
{var $items = $items ?? []}
{var $itemTemplate = $itemTemplate ?? null}
{var $visibleCount = $visibleCount ?? null}
{var $rowClass = $rowClass ?? 'row'}

<div class="product-list">
	{if $visibleCount}
		<span class="product-list__visible-count">{$visibleCount}</span>
	{/if}

	<div class="product-list__row {$rowClass}">
		{if $itemTemplate}
			{foreach $items as $item}
				{include $itemTemplate, item => $item}
			{/foreach}
		{else}
			{include #items}
		{/if}
	</div>
</div>
resources/sass/components/eshop/_product-list.scss
// ─── Configurable variables (override before @import) ──────────────────
$cgui-product-list-margin-bottom:          40px !default;
$cgui-product-list-row-gap:                40px !default;
$cgui-product-list-visible-count-size:     15px !default;
$cgui-product-list-visible-count-margin:   25px !default;
// ───────────────────────────────────────────────────────────────────────

.product-list {
	margin-bottom: $cgui-product-list-margin-bottom;
}

.product-list__row {
	row-gap: $cgui-product-list-row-gap;
}

.product-list__visible-count {
	display: block;
	font-size: $cgui-product-list-visible-count-size;
	margin-bottom: $cgui-product-list-visible-count-margin;
}