/*
 * Storefront — siatka produktów, karta, nagłówek archiwum, paginacja.
 *
 * Arkusz ładowany wyłącznie tam, gdzie pojawiają się produkty. Strony prawne
 * i kontaktowe nie potrzebują tego kodu (§48).
 *
 * Wartości pochodzą z tokenów zdefiniowanych w base.css, które są aliasami
 * presetów z theme.json. Ten plik nie wprowadza nowych wartości koloru,
 * odstępu ani rozmiaru pisma.
 */

/* ==========================================================================
   1. Nagłówek archiwum
   ========================================================================== */

.woocommerce-products-header {
	margin-block-end: var(--zu-space-4);
}

.woocommerce-products-header__title {
	margin: 0;
}

/*
 * Opis kategorii. Szerokość ograniczona do kolumny tekstowej — pełna szerokość
 * kontenera daje wiersze zbyt długie, żeby wygodnie je czytać.
 */
.term-description,
.woocommerce-product-search-form-description,
.page-description {
	max-width: var(--zu-container-text);
	margin-block-start: var(--zu-space-2);
	color: var(--zu-ink-soft);
}

/*
 * Pasek nad siatką: liczba wyników po lewej, sortowanie po prawej.
 * Na wąskim ekranie schodzą pod siebie, bo select potrzebuje szerokości.
 */
.zu-shop-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--zu-space-2);
	margin-block-end: var(--zu-space-3);
	padding-block-end: var(--zu-space-2);
	border-block-end: 1px solid var(--zu-line);
}

.woocommerce-result-count {
	margin: 0;
	color: var(--zu-ink-muted);
	font-size: var(--zu-text-sm);
}

.woocommerce-ordering {
	margin: 0;
}

.woocommerce-ordering select {
	width: auto;
	min-width: 14rem;
	padding-block: 0.45rem;
	border-radius: var(--zu-radius-pill);
	font-size: var(--zu-text-sm);
}

/* ==========================================================================
   2. Siatka produktów
   ========================================================================== */

/*
 * Siatka zastępuje układ oparty na float, który WooCommerce nadal stosuje.
 *
 * Liczba kolumn jest jawna, nie wyliczana przez auto-fill. Przy auto-fill
 * szerokość okna decydowała o liczbie kolumn niezależnie od filtra
 * `loop_shop_columns`, więc PHP deklarował trzy kolumny, a siatka rysowała
 * cztery. Jedna deklaracja, jeden wynik.
 *
 * Dwie kolumny na telefonie: jedna marnuje przestrzeń i wymusza długie
 * przewijanie przy katalogu tej wielkości.
 */
.woocommerce ul.products,
ul.products {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--zu-space-4) var(--zu-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 48rem) {
	.woocommerce ul.products,
	ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/*
 * Cztery kolumny na szerokim ekranie. Pierwotnie zatrzymaliśmy się na trzech,
 * ale po obejrzeniu realnego katalogu decyzja się nie obroniła: przy szerokości
 * kontenera 1200 px trzy kolumny dają karty o zdjęciu ~380 px, przez co
 * dwadzieścia produktów zajmuje ponad cztery tysiące pikseli przewijania.
 * Cztery kolumny zachowują oddech, a skanowanie katalogu staje się realne.
 */
@media (min-width: 75rem) {
	.woocommerce ul.products,
	ul.products {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/*
 * The home page's strips hold exactly four products and go four-up from 64rem.
 *
 * The shared grid reaches four columns at 75rem, which is right for `/sklep/` — an
 * archive of unknown length, where a trailing orphan is ordinary. A strip of exactly
 * four is different: between 64rem and 75rem it rendered 3 + 1, one card alone on a
 * second row, twice on the same page. Same finding as the trust and delivery grids,
 * same answer: where the count is known, say it.
 *
 * `/sklep/` is untouched — this class is only ever applied by
 * `parts/home/products.php`.
 */
/*
 * `ul.products.zu-products--four`, not the bare class, and the reason is arithmetic.
 *
 * The shared rule is `.woocommerce ul.products, ul.products` — 0,1,2 and 0,1,1. A
 * single class is 0,1,0 and loses to both, so the first version of this override was
 * in the stylesheet, matched the element, and changed nothing: the strips kept
 * rendering three columns. It showed up the moment the column counts were measured
 * rather than assumed.
 *
 * Two columns from 48rem so four products are 2 + 2, four from 64rem so they are one
 * row. Never three, which for a strip of exactly four is always 3 + 1.
 */
@media (min-width: 48rem) {
	ul.products.zu-products--four,
	.woocommerce ul.products.zu-products--four {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 64rem) {
	ul.products.zu-products--four,
	.woocommerce ul.products.zu-products--four {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/*
 * Sekcje produktowe poza archiwum (np. strona główna) mogą chcieć innej
 * gęstości — klasa modyfikatora pozwala to ustawić bez dublowania reguł siatki.
 */
@media (min-width: 48rem) {
	.zu-products--three {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
	content: none;
}

/*
 * Neutralizacja szerokości narzucanej przez arkusz layoutu WooCommerce.
 *
 * Wtyczka rozdaje szerokości procentowe regułami w rodzaju
 * `.woocommerce ul.products.columns-3 li.product { width: 30.75% }`.
 * Selektor z klasą `columns-N` ma wyższą specyficzność niż prosty
 * `ul.products li.product`, więc sam reset nie wystarczał — element siatki
 * dostawał 30% szerokości toru i karta kurczyła się do kilkudziesięciu pikseli.
 *
 * Selektor atrybutu wyrównuje specyficzność, a nasz arkusz ładuje się później,
 * więc wygrywa. To świadomie mniej inwazyjne niż wyrzucenie całego
 * woocommerce-layout.css: tamten arkusz obsługuje również układ formularzy
 * zamówienia, których jeszcze nie przepisaliśmy (§49).
 */
.woocommerce ul.products li.product,
.woocommerce ul.products[class*='columns-'] li.product,
ul.products[class*='columns-'] li.product,
ul.products li.product {
	width: auto;
	min-width: 0;
	margin: 0;
	float: none;
	clear: none;
}

/* Na najwęższych ekranach ciaśniejsze odstępy, żeby karta zachowała szerokość. */
@media (max-width: 30rem) {
	.woocommerce ul.products,
	ul.products {
		gap: var(--zu-space-3) var(--zu-space-2);
	}
}

/* ==========================================================================
   3. Karta produktu
   ========================================================================== */

.zu-card {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	gap: var(--zu-space-2);
}

/* --- Zdjęcie --- */

/*
 * Stała proporcja dla wszystkich kart. Katalog ma zdjęcia w różnych
 * proporcjach, a bez tego siatka faluje i każdy wiersz ma inną wysokość.
 * object-fit: cover kadruje, zamiast deformować — zniekształcone zdjęcie
 * produktu to gorszy błąd niż utrata marginesu.
 */
.zu-card__media {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var(--zu-radius);
	background-color: var(--zu-surface);
}

/*
 * `aspect-ratio` rather than `height: 100%`, and that is a stage 9 bug fix.
 *
 * The frame gets its height from `aspect-ratio` on `.zu-card__media`, which is not a
 * definite height — so `height: 100%` on the image never resolved, and the image fell
 * back to its own intrinsic proportions. Nothing showed, because
 * `woocommerce_thumbnail` is a hard 400 × 400 crop: every image was already square, so
 * "width 100 %, height whatever the file says" produced a square by coincidence.
 *
 * It stopped being a coincidence the moment one card asked for an uncropped photograph.
 * A 2:3 image rendered 282 × 399 inside a 282 × 282 frame and `overflow: hidden` cut the
 * bottom off — the exact defect the whole-photograph mode exists to remove, reintroduced
 * one layer down. Giving the image the same square box the frame has makes `object-fit`
 * the only thing deciding what happens to the photograph, which is what both modes assume.
 */
.zu-card__image {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

/*
 * Whole-photograph cards, per product.
 *
 * Stage 9. The square frame stays — `aspect-ratio` is on `.zu-card__media`, not here —
 * so a contained card sits in the grid at exactly the same height as its neighbours and
 * the row does not wave. What changes is that the photograph is fitted inside the frame
 * instead of filling it, which is the only way to show a bottle that is taller than the
 * frame without cutting through its label.
 *
 * The padding stops the product touching the frame's edge. Without it a 2:3 photograph
 * runs the full height and reads as cramped next to cards that crop.
 *
 * **Proportional, not a fixed 24 px, and that is a review correction.** A flat
 * `--zu-space-3` is 18 % of a 136 px frame at 320 px and 8 % of a 282 px one at 1440 —
 * so the bottle was painted 59 px wide inside a 136 px box on a small phone, 43 % of the
 * frame, next to neighbours that fill theirs edge to edge. A percentage keeps the
 * product at the same share of its card at every width.
 *
 * `--zu-surface` is the frame's own background (set on `.zu-card__media`), so the
 * letterboxing is the card's surface rather than a second colour.
 */
.zu-card__image--whole {
	object-fit: contain;
	padding: 8%;
	box-sizing: border-box;
}

.zu-card:hover .zu-card__image {
	transform: scale(1.03);
}

/*
 * The category tile joined the product card here after a frontend review emulated
 * `prefers-reduced-motion: reduce` and watched `.zu-path__image` still scale to
 * 1.04 on hover. The global block only shortens `transition-duration` to 0.01ms, so
 * the zoom did not stop — it became instantaneous, which is worse than the animation
 * for the person who asked not to see it.
 */
@media (prefers-reduced-motion: reduce) {
	.zu-card:hover .zu-card__image,
	.zu-path:hover .zu-path__image {
		transform: none;
	}
}

/* Zastępnik ma tę samą proporcję co zdjęcie, więc brak fotografii nie rusza siatki. */
.zu-card__image--empty {
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--zu-blush);
	color: var(--zu-gold-decor);
}

/* --- Plakietki --- */

.zu-card__badges {
	/*
	 * The badge sits above the stretched link, so without this a click on it —
	 * a very natural place to click — did nothing instead of opening the product.
	 */
	pointer-events: none;
	position: absolute;
	inset-block-start: var(--zu-space-2);
	inset-inline-start: var(--zu-space-2);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--zu-space-1);
	z-index: 2;
}

/*
 * Plakietka zawsze niesie tekst. Sam kolor nie komunikuje promocji ani braku
 * dostępności — patrz kontrakt dostępności w ARCHITECTURE.md §13.
 */
.zu-badge {
	display: inline-block;
	padding: 0.3rem 0.6rem;
	border-radius: var(--zu-radius-pill);
	font-size: var(--zu-text-label);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.2;
}

.zu-badge--sale {
	background-color: var(--zu-accent-deep);
	color: var(--zu-surface);
}

.zu-badge--out {
	background-color: var(--zu-surface);
	color: var(--zu-ink-soft);
	border: 1px solid var(--zu-line);
}

/* --- Treść --- */

.zu-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--zu-space-1);
	flex: 1;
}

/*
 * Nazwa produktu krojem tekstowym, nie display. Bodoni jest didone o wysokim
 * kontraście — świetnie wygląda w nagłówku sekcji, a w kilkunastu punktach
 * i w trzech wierszach staje się męczący. Nagłówki sekcji zostają w Bodoni,
 * karty czytamy Lexendem.
 */
.zu-card__title {
	margin: 0;
	font-family: var(--zu-font-sans);
	font-size: var(--zu-text-sm);
	font-weight: 400;
	line-height: 1.45;
	letter-spacing: 0;
	text-wrap: pretty;

	/*
	 * Ograniczenie do trzech wierszy jest decyzją wizualną, nie obcięciem danych.
	 * Pełna nazwa zostaje w dokumencie — czytnik ekranu ją przeczyta, wyszukiwarka
	 * zaindeksuje, a użytkownik zobaczy w całości na stronie produktu.
	 * Ucinanie po stronie PHP zabrałoby tę informację wszystkim naraz.
	 */
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/*
 * Four lines on the narrowest screen.
 *
 * Three lines fit about 43 characters at 320 px, and the real catalogue has 87-character
 * names that do not diverge until character 48. Found by the independent stage 6
 * frontend review: three different Thuya top coats all rendered as "Lakier
 * nawierzchniowy Gel ON-OFF Top Coat S…", two of them at the same price, separable
 * only by a thumbnail of a black bottle on white.
 *
 * A fourth line moves the divergence point past the clamp. Above 390 px the names
 * differ anyway, so the rule ends where it stops being needed — and the clamp stays a
 * visual decision rather than a truncation of data: the full name is still in the
 * document.
 */
@media (max-width: 29.99em) {

	.zu-card__title {
		-webkit-line-clamp: 4;
		line-clamp: 4;
	}
}

.zu-card__link {
	color: var(--zu-ink);
	text-decoration: none;
}

/*
 * Rozciągnięty odnośnik: klikalna jest cała karta, ale w drzewie dostępności
 * jest jeden odnośnik do produktu, a nie osobny dla zdjęcia i tytułu.
 */
.zu-card__link::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
}

.zu-card:hover .zu-card__link {
	color: var(--zu-accent-deep);
}

/*
 * The focus ring is drawn around the card, not around the link text alone.
 *
 * Removing the link's own outline lives inside the same @supports as the rule
 * that restores it. Split apart, a browser without :has() got a card with NO
 * focus indicator at all on the shop's main interactive element. A rule that
 * takes something away must never apply more widely than the one that gives it back.
 */
@supports selector(:has(*)) {
	.zu-card__link:focus-visible {
		outline: none;
	}

	.zu-card:has(.zu-card__link:focus-visible) {
		outline: var(--zu-focus-width) solid var(--zu-focus-color);
		outline-offset: 6px;
		border-radius: var(--zu-radius);
	}
}

/* --- Cena --- */

.zu-card__price {
	font-size: var(--zu-text-sm);
	color: var(--zu-ink);
}

.zu-card__price .woocommerce-Price-amount {
	font-weight: 500;
	white-space: nowrap;
}

/* Cena sprzed promocji — wyciszona i przekreślona, ale nadal czytelna. */
.zu-card__price del {
	margin-inline-end: 0.4rem;
	color: var(--zu-ink-muted);
	font-weight: 400;
}

.zu-card__price del .woocommerce-Price-amount {
	font-weight: 400;
}

/*
 * WooCommerce podaje cenę promocyjną w <ins>, które przeglądarki podkreślają.
 * Podkreślenie w cenie wygląda jak odnośnik, więc je zdejmujemy — informację
 * niesie plakietka „Promocja" i przekreślona cena obok.
 */
.zu-card__price ins {
	text-decoration: none;
	color: var(--zu-accent-deep);
	background: none;
}

/* --- Dostępność --- */

.zu-card__stock {
	margin: 0;
	font-size: var(--zu-text-label);
	letter-spacing: 0.04em;
}

.zu-card__stock--out {
	color: var(--zu-ink-muted);
}

.zu-card__stock--low {
	color: var(--zu-accent-deep);
}

/* --- Akcje --- */

/* z-index wynosi przycisk ponad rozciągnięty odnośnik karty. */
/*
 * Spacing as margin, not padding: padding created a full-width strip above the
 * button that swallowed clicks and did nothing with them.
 */
.zu-card__actions {
	position: relative;
	z-index: 2;
	margin-block-start: auto;
	padding-block-start: 0;
}

.zu-card__actions .button {
	width: 100%;
}

/*
 * Przy dwóch kolumnach na telefonie karta ma około 170 px, a „Dodaj do koszyka"
 * z domyślnym odstępem wewnętrznym nie mieści się w jednym wierszu. Skracamy
 * odstęp zamiast etykiety — tekst przycisku niesie informację, margines nie.
 */
@media (max-width: 30rem) {
	.zu-card__actions .button {
		padding-inline: 0.75rem;
	}
}

/* Potwierdzenie „Zobacz koszyk" po dodaniu produktu bez przeładowania strony. */
.zu-card__actions .added_to_cart {
	display: inline-block;
	margin-block-start: var(--zu-space-1);
	font-size: var(--zu-text-label);
	color: var(--zu-accent-deep);
}

/* ==========================================================================
   4. Stan pusty listingu
   ========================================================================== */

.zu-shop-empty {
	max-width: var(--zu-container-text);
	padding-block: var(--zu-space-4);
}

.zu-shop-empty__title {
	margin-block-start: var(--zu-space-1);
}

.zu-shop-empty__text {
	margin-block: var(--zu-space-2) var(--zu-space-3);
	color: var(--zu-ink-soft);
}

.zu-shop-empty .zu-search {
	max-width: 26rem;
}

.zu-shop-empty__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--zu-space-2);
	margin-block-start: var(--zu-space-3);
}

/* ==========================================================================
   5. Paginacja WooCommerce
   ========================================================================== */

/*
 * Selektory odwzorowują kształt selektorów WooCommerce
 * (`.woocommerce nav.woocommerce-pagination ul li a`), bo wtyczka rysuje tu
 * zwartą ramkę z obramowaniami między elementami. Niższa specyficzność dawała
 * efekt pośredni: nasze odstępy nie działały, a obramowania wtyczki zostawały,
 * przez co paginacja wyglądała na zepsutą. Wyrównanie kształtu selektora
 * rozwiązuje to bez !important.
 */
nav.woocommerce-pagination {
	margin-block-start: var(--zu-space-5);
	text-align: center;
}

.woocommerce nav.woocommerce-pagination ul,
nav.woocommerce-pagination ul {
	display: inline-flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--zu-space-1);
	margin: 0;
	padding: 0;
	border: 0;
	white-space: normal;
	list-style: none;
}

.woocommerce nav.woocommerce-pagination ul li,
nav.woocommerce-pagination ul li {
	border: 0;
	margin: 0;
	padding: 0;
	float: none;
	overflow: visible;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span,
nav.woocommerce-pagination ul li a,
nav.woocommerce-pagination ul li span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;
	min-height: 2.75rem;
	padding: 0 0.75rem;
	border: 1px solid var(--zu-line);
	border-radius: var(--zu-radius-pill);
	color: var(--zu-ink);
	text-decoration: none;
	font-size: var(--zu-text-sm);
	line-height: 1;
	background: none;
	transition: border-color var(--zu-transition), color var(--zu-transition);
}

.woocommerce nav.woocommerce-pagination ul li a:hover,
.woocommerce nav.woocommerce-pagination ul li a:focus,
nav.woocommerce-pagination ul li a:hover,
nav.woocommerce-pagination ul li a:focus {
	border-color: var(--zu-accent-deep);
	color: var(--zu-accent-deep);
	background: none;
}

.woocommerce nav.woocommerce-pagination ul li span.current,
nav.woocommerce-pagination ul li span.current {
	background-color: var(--zu-accent-deep);
	border-color: var(--zu-accent-deep);
	color: var(--zu-surface);
}

.woocommerce nav.woocommerce-pagination ul li span.dots,
nav.woocommerce-pagination ul li span.dots {
	border-color: transparent;
	background: none;
}

/* ==========================================================================
   6. Strona główna
   ========================================================================== */

/*
 * The home page grew from four sections to eight. What follows is organised in the
 * order a visitor meets it — hero, paths, brand, trust, delivery, closing — rather
 * than by component type, because that is the order somebody debugging the page
 * scrolls through it.
 *
 * Two rules the whole section keeps:
 *
 *   - every colour is a token alias from theme.json, never a fresh value;
 *   - every band declares its own background, so sections can be reordered in
 *     front-page.php without one of them inheriting the wrong ground.
 */

/*
 * The home page is a stack of full-bleed bands, each carrying its own background
 * and its own vertical padding. `.site-main` adds 2.5rem above and below, which on
 * every other page is the page gutter and here is a strip of cream between the
 * header and the blush hero — 40 px that reads as a rendering fault rather than as
 * spacing. The bands own their rhythm; main should not add to it.
 */
.zu-home {
	padding-block: 0;
}

/*
 * Nagłówek sekcji. Etykieta „eyebrow" nad nagłówkiem to wzorzec przeniesiony
 * z prototypu — porządkuje stronę bez dokładania linii i ramek.
 */
/*
 * More air under a section header than inside it.
 *
 * The eyebrow, the title and the content below were all a similar distance apart —
 * `--zu-space-1` between eyebrow and title, `--zu-space-3` before the content — so
 * the header did not read as a group, it read as two more lines in the stack. An
 * eyebrow belongs to its title; the pair belongs above the section.
 *
 * Tightening the inside and opening the outside is the whole change. It is the
 * cheapest way to give a page vertical rhythm, and the owner's word for what was
 * missing — "nijakość" — is largely this: everything evenly spaced is everything
 * equally important.
 */
.zu-section__header {
	margin-block-end: var(--zu-space-4);
}

.zu-section__title {
	margin-block-start: 0.35rem;
	text-wrap: balance;
}

.zu-section__footer {
	margin-block-start: var(--zu-space-4);
}

/* --- Hero --- */

/*
 * Fluid rather than the fixed 6rem it used to be.
 *
 * On a 390 px screen the hero now carries a picture as well as the type, and a flat
 * 96 px of padding on top of that pushed the first line of the heading below the
 * fold on a short phone. `clamp` keeps the generous opening on a desktop — where
 * the band is wide and needs the air — and gives a phone 48 px, which is still
 * clearly a hero and not a header.
 */
/*
 * Tighter than it was, and the number came from a render rather than from taste.
 *
 * It used to open at `clamp(3rem, 7vw, 6rem)` — 96 px of nothing above the eyebrow at
 * 1440, with the same again below the buttons, on a band that was already taller than
 * its content because the photograph set the height. The owner's note was that the
 * hero "has too much empty space, especially vertically and between the content and
 * the portrait", and the padding was half of that; the other half is answered by the
 * proof row below, which gives the text column something to stand on.
 */
.zu-hero {
	padding-block: clamp(2rem, 4vw, 3.5rem) clamp(2rem, 4vw, 3.5rem);
	background-color: var(--zu-blush);
	border-block-end: 1px solid var(--zu-line);
}

/*
 * Treść hero jest węższa niż kontener — duży krój display przy pełnej
 * szerokości dawałby wiersze zbyt długie, żeby je wygodnie czytać.
 *
 * Ograniczenie idzie przez wewnętrzny blok, a nie przez nadpisanie marginesów
 * kontenera: `margin-inline: 0` zdejmowało automatyczne centrowanie i hero
 * przyklejał się do lewej krawędzi okna.
 */
.zu-hero__content {
	max-width: 46rem;
}

.zu-hero__title {
	margin-block-start: var(--zu-space-2);
}

.zu-hero__lead {
	margin-block-start: var(--zu-space-3);
	max-width: 46ch;
}

.zu-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--zu-space-2);
	margin-block-start: var(--zu-space-4);
}

/*
 * The proof row.
 *
 * Three facts, separated by rules rather than boxed. Boxes here would make three
 * little cards under two buttons and read as a dashboard; a rule between columns is
 * the editorial version of the same division and stays quiet.
 *
 * `auto-fit` is deliberately not used: the count is three and known. Below 34rem they
 * stack, and the rule moves from the inline start to the block start so the divider
 * still divides.
 */
.zu-hero__proof {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--zu-space-2);
	margin-block-start: var(--zu-space-4);
	padding-block-start: var(--zu-space-3);
	border-block-start: 1px solid var(--zu-gold-decor);
}

.zu-hero__fact {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
}

.zu-hero__fact-figure {
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-h2);
	line-height: 1;
	color: var(--zu-ink);
}

.zu-hero__fact-body {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	margin: 0;
}

.zu-hero__fact-label {
	font-size: var(--zu-text-sm);
	font-weight: 500;
	color: var(--zu-ink);
}

.zu-hero__fact-detail {
	font-size: var(--zu-text-label);
	letter-spacing: 0.04em;
	color: var(--zu-ink-muted);
}

@media (min-width: 34rem) {
	.zu-hero__proof {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--zu-space-3);
	}

	.zu-hero__fact + .zu-hero__fact {
		padding-inline-start: var(--zu-space-3);
		border-inline-start: 1px solid var(--zu-line);
	}
}

/*
 * Portret właścicielki.
 *
 * Below the two-column breakpoint the figure simply follows the text, which is why
 * the base state here is "a picture in a column" and the grid is switched on later
 * rather than switched off. A phone gets the words first, where they belong.
 */
.zu-hero__portrait {
	margin: var(--zu-space-4) 0 0;
	max-width: 22rem;
}

.zu-hero__portrait picture {
	display: block;
}

.zu-hero__portrait img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--zu-radius);
	/*
	 * The photograph was taken against a near-white wall and the hero band is
	 * blush, so without an edge its top right corner dissolves into the section.
	 * One hairline in the existing line token fixes that without putting a frame
	 * around her.
	 */
	border: 1px solid var(--zu-line);
}

.zu-hero__portrait-caption {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	margin-block-start: var(--zu-space-2);
}

.zu-hero__portrait-name {
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-lead);
	line-height: 1.2;
	color: var(--zu-ink);
}

.zu-hero__portrait-role {
	font-size: var(--zu-text-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--zu-ink-muted);
}

/*
 * Two columns once there is room for the text to keep a readable measure beside a
 * picture. 56rem rather than a round 900px: below it the lead drops under about
 * forty characters a line, which is where a paragraph starts reading as a column
 * of fragments.
 */
@media (min-width: 56rem) {
	.zu-hero--with-portrait .zu-hero__inner {
		display: grid;
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
		gap: var(--zu-space-5);
		align-items: center;
	}

	.zu-hero--with-portrait .zu-hero__content {
		max-width: none;
	}

	.zu-hero--with-portrait .zu-hero__portrait {
		margin: 0;
		max-width: none;
		justify-self: end;
		width: min(100%, 26rem);
	}
}

/* --- Ścieżki zakupowe --- */

.zu-paths {
	background-color: var(--zu-bg);
}

/*
 * A ladder of explicit counts, not `auto-fit`, and a frontend review is why.
 *
 * `auto-fit` with a 15rem floor resolved to **three** columns everywhere between
 * 836 and 1111 px. Three of these four grids hold exactly four items by construction
 * — four trust pillars and four delivery points are fixed in `inc/brand.php`, and a
 * product strip asks for four — so at 1024, which is iPad landscape and a common
 * laptop width, they each rendered 3 + 1 and the page showed stacked orphans.
 *
 * The categories grid is the one that varies: it renders whatever top-level terms the
 * taxonomy has, which is four on the migrated catalogue and six while the demo
 * fixtures are installed. Four pinned columns give 4 or 4 + 2 rather than 3 + 1, which
 * is why the count is pinned rather than fitted here as well. `auto-fit` is the right
 * tool when the count is unknown; a lower bound of four is not unknown enough.
 *
 * The phone is a separate problem and needs a separate answer — see the horizontal
 * tile below. Changing the column count alone did nothing there, because at 390 the
 * grid was already one column.
 */
.zu-paths__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--zu-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}


@media (min-width: 34rem) {
	.zu-paths__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/*
 * Four across from 64rem. Pinned rather than fitted: with five or six categories
 * this gives 4 + 1 or 4 + 2 instead of letting the track count drift to five and
 * orphaning one at the widest sizes.
 */
@media (min-width: 64rem) {
	.zu-paths__grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.zu-path {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--zu-line);
	border-radius: var(--zu-radius);
	background-color: var(--zu-surface);
	transition: border-color var(--zu-transition);
}

.zu-path:hover {
	border-color: var(--zu-accent-deep);
}

/*
 * A fixed 4:5 box, so a row of tiles lines up whatever shape the product
 * photographs happen to be. `aspect-ratio` on the link rather than on the image
 * keeps the box reserved even for a category that has no picture at all.
 */
.zu-path__media {
	display: block;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background-color: var(--zu-blush);
}

/*
 * No photograph is a valid state, and this is what it looks like: the same centred
 * glyph the product card uses, on the blush ground, rather than a stock picture of
 * something the shop does not sell.
 *
 * It used to be an empty rectangle — which, standing beside tiles that do have
 * photographs, is indistinguishable from an image that failed to load. The card had
 * solved this already; the tile was not reusing the answer.
 */
.zu-path__media--empty {
	display: flex;
	align-items: center;
	justify-content: center;
	border-block-end: 1px solid var(--zu-line);
	color: var(--zu-gold-decor);
}

.zu-path__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.zu-path:hover .zu-path__image {
	transform: scale(1.04);
}

.zu-path__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 0.2rem;
	padding: var(--zu-space-3);
}

/*
 * A tile with no subcategories centres what it does have.
 *
 * The grid stretches every card to the tallest, and the tallest is whichever category
 * has the most chips. A card with none therefore inherits that height and pins its
 * name and count to the top, leaving the rest blank: measured at 1440,
 * **135 px of empty white** under "Akcesoria do paznokci", and 160 to 183 px at 1024.
 *
 * On the production catalogue that is **two of the four cards** — "Rzęsy" and
 * "Akcesoria do paznokci" have no children — so this is what the shop will actually
 * look like, not a fixture artefact. Equal heights are still right; what was wrong is
 * that the spare height all fell below the text, which reads as an unfinished card
 * rather than as a roomy one. Centring turns one 135 px hole into two 68 px margins.
 *
 * Found by an independent frontend review.
 */
.zu-path__body:not(:has(.zu-path__children)) {
	justify-content: center;
}

.zu-path__title {
	margin: 0;
	font-size: var(--zu-text-lead);
	line-height: 1.2;
}

.zu-path__link {
	color: var(--zu-ink);
	text-decoration: none;
}

/*
 * The whole tile is the target, not just the words.
 *
 * An `::after` stretched over the card gives a pointer the large hit area the
 * design implies, while the accessible name and the keyboard stop stay on the real
 * link. The picture link above it is already `aria-hidden` and out of the tab
 * order, so this adds a target without adding a second announcement.
 */
.zu-path__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.zu-path__link:hover,
.zu-path:hover .zu-path__link {
	color: var(--zu-accent-deep);
}

.zu-path__count {
	margin: 0;
	font-size: var(--zu-text-label);
	letter-spacing: 0.04em;
	color: var(--zu-ink-muted);
}

/*
 * Subcategories sit above the card overlay. Without the stacking context the
 * `::after` that makes the tile clickable would swallow them, and every child link
 * would quietly open the parent category instead.
 *
 * `margin: auto 0 0` pins the list to the bottom, so tiles with children and tiles
 * without still agree on where their content ends.
 */
.zu-path__children {
	position: relative;
	z-index: 1;
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 0.5rem;
	margin: auto 0 0;
	padding: var(--zu-space-2) 0 0;
	list-style: none;
}

/*
 * The list item carries the 44 px, not the chip.
 *
 * The target has to be 44 px and the pill must not be, so the height goes on the row
 * and the chip is centred inside it. That also makes the spacing self-evident rather
 * than arithmetic: because the item and the tap area are the same box, two rows cannot
 * overlap at any row gap.
 *
 * The first attempt did it the other way round — kept 28 px items and widened the row
 * gap to 1 rem to make room for a target that overhung them. It did not work, and the
 * measurement said so: 4 overlapping pairs at 320 px, 4 at 390, 2 at 768. An
 * inline-block's box and its line box are not the same height, so the gap was never
 * between what it looked like it was between. Enlarging a target without giving it a
 * box to live in moves the defect instead of fixing it.
 */
.zu-path__children li {
	display: flex;
	align-items: center;
	min-height: 2.75rem;
}

/*
 * 44 px of target, without a 44 px pill.
 *
 * Measured at 390 px these were **28 px tall** — above WCAG 2.2 SC 2.5.8's 24 px floor
 * and well under the 44 px the brief asks for, which is the size a thumb actually
 * needs. A frontend review recorded it and the last round carried it rather than
 * fixing it.
 *
 * Padding the pill to 44 px would make five of them a wall of lozenges under a
 * thumbnail. So the *pill* keeps its proportions and the *target* is grown around it:
 * a transparent `::after` that extends the hit area vertically to 44 px without moving
 * anything. The chips still read as chips, and a thumb lands on them.
 *
 * `position: relative` on the anchor keeps that box tied to the chip, and the list's
 * own `z-index: 1` keeps all of it above the tile's stretched link — without which a
 * tap on a chip would open the parent category instead, which is the defect the
 * comment above this one records.
 */
.zu-path__children a {
	position: relative;
	display: inline-block;
	padding: 0.2rem 0.55rem;
	border: 1px solid var(--zu-line);
	border-radius: var(--zu-radius-pill);
	background-color: var(--zu-bg);
	font-size: var(--zu-text-label);
	color: var(--zu-ink-soft);
	text-decoration: none;
	transition: border-color var(--zu-transition), color var(--zu-transition);
}

.zu-path__children a::after {
	content: '';
	position: absolute;
	inset-inline: 0;
	top: 50%;
	height: 44px;
	transform: translateY(-50%);
}

.zu-path__children a:hover {
	border-color: var(--zu-accent-deep);
	color: var(--zu-accent-deep);
}

/*
 * On a phone the tile lies down: square thumbnail on the left, everything else on
 * the right.
 *
 * Measured before: the category band was **2 642 px of a 7 623 px page — 34.7 %**.
 * Four photographs, each 445 px tall on a 844 px screen, which is a gallery rather
 * than navigation and cannot be compared at a glance. That is an over-correction of
 * the very complaint the band exists to answer: the categories were too quiet, and
 * the fix made them the loudest thing on the page.
 *
 * Horizontal rather than merely a wider aspect, because the picture is there to
 * identify a category, not to be admired — 96 px is enough to recognise a lash tray
 * from a lamp, and it puts the name, the count and the subcategory chips on the same
 * line of sight as the image instead of below it.
 */
@media (max-width: 33.999rem) {
	.zu-path {
		display: grid;
		grid-template-columns: 6rem minmax(0, 1fr);
		align-items: stretch;
	}

	/*
	 * Fills its track, and `aspect-ratio` has to go for it to.
	 *
	 * The first version kept `aspect-ratio: 1` and added `height: 100%`. With a
	 * definite height from the row, a square ratio computes the *width* from it — so
	 * the tile holding five subcategory chips grew to 290 px tall, the thumbnail grew
	 * to 290 px wide, and it burst out of a 6 rem track and under the text. Visible
	 * immediately in a screenshot and invisible in the rule.
	 *
	 * The grid track decides the width and the row decides the height; the image
	 * inside already has `object-fit: cover`, which is what crops the photograph to
	 * whatever box that produces.
	 */
	.zu-path__media {
		aspect-ratio: auto;
		width: 100%;
		height: 100%;
		border-block-end: 0;
	}

	.zu-path__media--empty {
		border-inline-end: 1px solid var(--zu-line);
	}

	.zu-path__body {
		padding: var(--zu-space-2) var(--zu-space-3);
	}

	/*
	 * The chips sit under the count rather than pinned to the bottom: in a 6rem-tall
	 * tile `margin-block-start: auto` would strand them against the lower edge.
	 */
	.zu-path__children {
		margin-block-start: 0;
		padding-block-start: var(--zu-space-1);
	}
}

/* --- Marka --- */

.zu-brand {
	padding-block: var(--zu-space-6);
	background-color: var(--zu-deep);
	color: var(--zu-deep-muted);
}

.zu-brand__inner {
	display: grid;
	gap: var(--zu-space-5);
}

.zu-eyebrow--on-deep {
	color: var(--zu-surface-2);
}

.zu-brand__title {
	margin-block: var(--zu-space-1) var(--zu-space-3);
	font-size: var(--zu-text-h1);
	color: var(--zu-surface);
}

.zu-brand__text {
	margin-block: 0 var(--zu-space-2);
	max-width: 54ch;
	color: var(--zu-deep-muted);
}

/*
 * The right-hand column: a quotation and three milestones.
 *
 * It used to be the quotation alone, and one quotation opposite three paragraphs is
 * not a column — the owner's note was that the right side looks too empty, and the
 * measurement agreed: the quote filled about a third of the height the grid gave it.
 *
 * The fix is more of what the column is for rather than more of its spacing. No larger
 * type, no card, no invented illustration, no padding: a second element that belongs
 * there, set as a list so the three read as a sequence instead of as a row of boxes.
 *
 * Stacked, it follows the story rather than leading it, and that is a change. The
 * quotation carried `order: -1` inherited from the award card before it, for a reason
 * that has now expired: it was pulled above "Poznaj całą historię" so the supporting
 * material did not land after the ask. The ask is gone with the page it opened, so
 * there is nothing left to get in front of, and source order is the reading order —
 * heading, story, then the quotation and the three dates that back it up.
 */
.zu-brand__aside {
	display: flex;
	flex-direction: column;
	gap: var(--zu-space-4);

	/*
	 * The same measure the story uses, and only while the two are stacked.
	 *
	 * The milestone hairlines are full-bleed inside their column, and stacked that
	 * column is the whole container while `.zu-brand__text` stops at `54ch`. Measured
	 * at 895px — the last width before the two-column layout — the rules ran 823px
	 * under sentences 373px wide, with the paragraph above them ending at 524px: three
	 * long lines with short text hanging off the left end. Sharing the story's measure
	 * lines the two up. The two-column rule below drops it, because side by side the
	 * column is already narrower than this.
	 */
	max-width: 54ch;
}

/*
 * A quotation, not a card.
 *
 * The bordered box is gone with the award it replaced. A rule on the inline edge and
 * the display face at reading size is the editorial version of the same emphasis, and
 * it does not need to fill a rectangle to look finished — which is what made the old
 * three-line card look marooned in a full-width band.
 */
.zu-brand__quote {
	margin: 0;
	padding-inline-start: var(--zu-space-3);
	border-inline-start: 2px solid var(--zu-gold-decor);
}

.zu-brand__quote-text {
	margin: 0;
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-lead);
	line-height: 1.35;
	color: var(--zu-surface);
}

.zu-brand__quote-source {
	margin-block-start: var(--zu-space-2);
	font-size: var(--zu-text-label);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--zu-deep-muted);
}

.zu-brand__quote-source cite {
	font-style: normal;
}

/*
 * The milestones.
 *
 * A hairline above each rather than a border around each: the same decision the trust
 * pillars made, and for the same reason — four boxes on one page and three more here
 * would turn a magazine into a dashboard. The rule is `--zu-deep-line` rather than
 * gold, because the quotation above already owns the gold and two gold edges in one
 * column compete.
 *
 * Deliberately NOT the hero's shape. The hero sets the same three facts side by side
 * with vertical rules between them, as quick proof; these run down the column as a
 * history, with the figure above its sentence rather than beside it. Same facts, two
 * jobs, two typographic answers.
 */
.zu-brand__milestones {
	display: flex;
	flex-direction: column;
	gap: var(--zu-space-3);
	margin: 0;
}

.zu-brand__milestone {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	padding-block-start: var(--zu-space-2);
	border-block-start: 1px solid var(--zu-deep-line);
}

.zu-brand__milestone-figure {
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-h2);
	line-height: 1;
	color: var(--zu-surface-2);
}

.zu-brand__milestone-text {
	margin: 0;
	font-size: var(--zu-text-sm);
	line-height: 1.45;
	color: var(--zu-deep-muted);
}

@media (min-width: 56rem) {
	/*
	 * A little wider than it was — 0.6fr held one quotation comfortably and crowds a
	 * quotation plus three milestones, which is what pushed "Mistrzostwach Stylizacji
	 * Rzęs" onto four lines at 1024.
	 */
	.zu-brand__inner {
		grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
		align-items: start;
	}

	/* The grid track is the measure here; the stacked cap would only fight it. */
	.zu-brand__aside {
		max-width: none;
	}
}

/* --- Zaufanie i dostawa --- */

/*
 * Two sections, one grid. They carry different content — reasons on one, practical
 * facts on the other — but they are the same shape, and giving each its own set of
 * near-identical rules is how two things that should stay aligned stop being.
 */
/*
 * The same explicit ladder as the category tiles, and for the same reason — which
 * the comment on that grid already spelled out while this one kept `auto-fit`.
 *
 * It named four grids: "four categories, four trust pillars, four delivery points
 * and four products per strip … at 1024 four sections in a row each rendered 3 + 1".
 * Only the categories were converted. A frontend review swept 176 viewport widths
 * and found `auto-fit` still resolving to **three columns from 784 to 1044 px**, so
 * at 1024 — iPad landscape, and a common laptop — the two sections carrying this
 * shop's only selling copy each showed 3 + 1, with the newly visible gold hairline
 * drawing a one-column rule across a four-column row.
 *
 * Both arrays are fixed at four entries in `inc/brand.php`. The count is known; the
 * grid should not be guessing it.
 */
.zu-trust__grid,
.zu-delivery__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--zu-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 34rem) {
	.zu-trust__grid,
	.zu-delivery__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 64rem) {
	.zu-trust__grid,
	.zu-delivery__grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/*
 * A rule above each item rather than a box around it. Four boxed cards here and
 * four boxed tiles in the paths section would make the page read as a grid of
 * boxes; the line keeps the rhythm without the weight.
 *
 * The rule is `--zu-gold-decor` rather than `--zu-line` now: at 1.17:1 the hairline
 * was present in the markup and absent from the page, so the section read as four
 * columns of grey text with nothing holding them. Decorative, so the low contrast is
 * allowed — but it has to be visible to be worth having.
 */
.zu-trust__item,
.zu-delivery__item {
	padding-block-start: var(--zu-space-3);
	border-block-start: 1px solid var(--zu-gold-decor);
}

.zu-trust__term,
.zu-delivery__term {
	margin: 0 0 0.35rem;
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-lead);
	line-height: 1.25;
	color: var(--zu-ink);
}

/*
 * Two lines' worth of room for every heading once the items sit side by side.
 *
 * "Marka własna i sprawdzone marki" wraps at four columns and its neighbours do not,
 * so one body paragraph started a line lower than the other three and the row lost
 * its baseline. Reserving the space costs nothing when a heading fits on one line
 * and keeps the bodies aligned when one does not.
 *
 * `2.5em` is two lines at this element's own `line-height: 1.25`, so it follows the
 * type scale instead of pinning a pixel value that stops being two lines the moment
 * the scale moves. Stacked, there is no row to align to, so the rule does not apply.
 */
@media (min-width: 34rem) {
	.zu-trust__term,
	.zu-delivery__term {
		min-height: 2.5em;
	}
}

/*
 * Body size, not metadata size.
 *
 * These two sections carry the shop's only selling copy, and they were set at
 * `--zu-text-sm` — 14px, the size this stylesheet uses for a card title, a price and
 * a result count. Measured against their own headings the step was 20px to 14px,
 * which is a drop of a third and reads as a caption rather than as something meant
 * to be read.
 *
 * At `--zu-text-base` the ratio is 20/16 and the copy sits where the eye expects
 * prose. It costs four lines of extra height across the two sections and buys the
 * difference between skimming and reading.
 */
.zu-trust__text,
.zu-delivery__text {
	margin: 0;
	font-size: var(--zu-text-base);
	line-height: 1.6;
	color: var(--zu-ink-soft);
}

/*
 * The numeral. Display face, gold, and set above its heading rather than beside it
 * — beside it, four numbers in a row compete with the four headings for the same
 * horizontal scan; above, each one is a marker for its own column.
 *
 * `--zu-gold-decor` is the 4.01:1 token this stylesheet reserves for borders, lines
 * and large text.
 *
 * **This does not qualify as large text and an earlier version of this comment said
 * it did.** WCAG's threshold is 24px regular or 18.66px bold; the numeral renders at
 * 20px regular Bodoni Moda. `DESIGN_REFERENCE.md` already records the token as
 * 4.01 · FAIL for normal text, so the claim contradicted the project's own table.
 *
 * The exemption that does apply is the other one: the numeral is `aria-hidden`,
 * carries no information, and the section reads identically without it. 1.4.3 does
 * not apply to pure decoration. Correct outcome, wrong reason — recorded because the
 * next person to move this token will read the reason, not re-measure the outcome.
 */
.zu-trust__index {
	display: block;
	margin-block-end: var(--zu-space-1);
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-lead);
	line-height: 1;
	color: var(--zu-gold-decor);
	letter-spacing: 0.02em;
}

.zu-delivery {
	background-color: var(--zu-blush);
	border-block: 1px solid var(--zu-line);
}

.zu-delivery__icon {
	display: block;
	margin-block-end: var(--zu-space-2);
	color: var(--zu-accent-deep);
}

/* --- Próg darmowej dostawy --- */

/*
 * A pill the width of its sentence, not a bar the width of the page.
 *
 * It was 1 160 x 110 px of white holding one centred line — a frontend review called
 * it "a very wide, very empty white bar", which is exactly what a full-width box
 * around eight words is. Shrink-wrapped and centred now, so it reads as a statement
 * rather than as an empty container.
 */
.zu-shipping-note {
	display: table;
	margin: var(--zu-space-4) auto 0;
	padding: var(--zu-space-2) var(--zu-space-4);
	border: 1px solid var(--zu-gold-decor);
	border-radius: var(--zu-radius-pill);
	background-color: var(--zu-surface);
	font-family: var(--zu-font-display);
	font-size: var(--zu-text-lead);
	color: var(--zu-ink);
	text-align: center;
}

/* --- Zamknięcie --- */

.zu-closing {
	padding-block: var(--zu-space-6);
	background-color: var(--zu-bg);
}

.zu-closing__inner {
	max-width: var(--zu-container-text);
	text-align: center;
}

.zu-closing__title {
	margin: 0;
	font-size: var(--zu-text-h1);
}

.zu-closing__text {
	margin-block: var(--zu-space-2) var(--zu-space-4);
	font-size: var(--zu-text-lead);
	color: var(--zu-ink-soft);
}

.zu-closing__actions {
	margin: 0;
}
