/* WooCommerce — warstwa bazowa. Karta produktu i archiwum dostana wlasny plik przy przepisywaniu szablonow. */

.woocommerce-notices-wrapper:empty { display: none; }

.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	list-style: none;
	margin: 0 0 var(--kd-gap);
	padding: 14px 18px;
	border-radius: var(--kd-radius-md);
	background: var(--kd-color-surface);
	border-left: 4px solid var(--kd-color-primary);
	/* Woo rysuje wlasna kreske u gory (#1e85be) — obcy niebieski w naszej palecie. */
	border-top: 0;
}
.woocommerce-error { border-left-color: var(--kd-color-error); }

/*
 * Woo stawia przed komunikatem ikone z wlasnego fontu, ale w paczce jest samo `.ttf` —
 * `@font-face` prosi najpierw o `woff2` i `woff`, wiec na checkoucie wychodzil pusty kwadrat.
 * Do tej pory zaslanial to Elementor Pro wlasnym stylem `e-wc-info-notice`.
 */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before { content: none; }

/* Woo ustawia siatke floatami (li.first{clear:both}) — w gridzie to rozbija wiersze. */
.woocommerce ul.products,
ul.products {
	display: grid;
	gap: var(--kd-gap);
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	list-style: none;
	margin: 0;
	padding: 0;
}
.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }
.woocommerce ul.products li.product,
ul.products li.product {
	float: none;
	clear: none;
	width: auto;
	margin: 0;
}
/* Karta produktu — wymiary i typografia przepisane z widgetu Elementora na kategorii. */
.woocommerce ul.products li.product,
ul.products li.product {
	display: flex;
	flex-direction: column;
	/* Karta przestaje byc kaflem: zero zaokraglenia, zero wypelnienia na najechaniu.
	   W gablocie jubilerskiej towar stoi na tym samym tle co reszta strony, a wzrok
	   prowadzi odstep, nie pudelko. Wyrownanie do lewej — jak podpis pod eksponatem. */
	text-align: left;
	padding: 0 0 var(--kd-space-3);
}
/* Najechanie dziala na nazwe (wloskowate podkreslenie) i na sam kadr zdjecia. Karta w spoczynku
   zostaje bez cienia i bez tla — tak stoi towar u W.KRUK i Pandory. Rozmycie jest odpowiedzia
   na kursor, nie stanem spoczynku, i siedzi pod zdjeciem, bo to ono niesie hierarchie. */
.woocommerce ul.products li.product:hover .woocommerce-loop-product__title,
ul.products li.product:hover .woocommerce-loop-product__title {
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
}
.kd-card__media { transition: box-shadow var(--kd-motion-fast) var(--kd-ease); }
.woocommerce ul.products li.product:hover .kd-card__media,
ul.products li.product:hover .kd-card__media {
	box-shadow: var(--kd-shadow-card-hover);
}

.woocommerce ul.products li.product > a.woocommerce-LoopProduct-link,
ul.products li.product > a.woocommerce-LoopProduct-link {
	display: flex;
	flex-direction: column;
	flex: 1;
	color: inherit;
}

.kd-card__media { position: relative; margin-bottom: var(--kd-space-1); }
/* Staly kadr 1:1 — bez tego karty w wierszu maja rozne wysokosci i cena skacze. */
.woocommerce ul.products li.product .kd-card__media img,
ul.products li.product .kd-card__media img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: var(--kd-radius-md);
	margin: 0;
}
/* Promien musi siedziec takze na oprawie, nie tylko na obrazku: `overflow` przycina zawartosc,
   ale cien rysuje sie po ksztalcie oprawy — bez tego pod zaokraglonym zdjeciem bylby ostry kant. */
.kd-card__media { overflow: hidden; border-radius: var(--kd-radius-md); }

.kd-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--kd-space-1);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title,
ul.products li.product .woocommerce-loop-product__title {
	font-family: var(--kd-font-body);
	font-size: var(--kd-body-size);
	font-weight: 400;
	letter-spacing: 0;
	line-height: 1.45;
	color: var(--kd-color-text);
	margin: 0;
	padding: 0;
	/* Nazwy sa dlugie („Naszyjnik z ametystem — naturalny — spokoj i intuicja”) i schodzily
	   do pieciu wierszy na telefonie: przy sasiedzie na dwoch wierszach siatka wygladala
	   na przypadkowa. Dwa wiersze to caly rodzaj kamienia — reszta jest na stronie produktu. */
	/* ⚠️ Obcinanie po dwoch wierszach ZDJETE: nazwa jest teraz skladana z dwoch czesci
	   (`kd_loop_title_parts()` w `inc/woo-hooks.php`), wiec nie ma czego obcinac. */
	overflow: hidden;
}

.woocommerce ul.products li.product .price,
ul.products li.product .price {
	display: block;
	font-family: var(--kd-price-family, var(--kd-font-heading));
	font-size: var(--kd-price-size);
	font-weight: var(--kd-price-weight, 500);
	line-height: var(--kd-price-lh, 1.2);
	color: var(--kd-color-text);
	margin: 0;
}

/* Reguly przycisku i gwiazdek w siatce zdjete razem ze znacznikami (`inc/woo-hooks.php`) —
   karta w siatce niesie zdjecie, nazwe i cene, nic wiecej. */

.price del { color: var(--kd-color-text-muted); font-weight: 400; margin-right: 6px; }
.price ins { text-decoration: none; color: var(--kd-color-accent-sale); }

/* Woo maluje cene i badge na oliwkowo (#77a464) — kolory sklepu sa w tokenach. */
.woocommerce div.product p.price,
.woocommerce div.product span.price,
.woocommerce ul.products li.product .price {
	color: var(--kd-color-text);
}

/* Cyfry o rownej szerokosci — w kolumnach koszyka i podsumowania kwoty stoja pod soba. */
.price,
.amount,
.woocommerce-Price-amount,
.order-total .amount,
.cart_totals td { font-variant-numeric: tabular-nums; }
.woocommerce div.product p.price ins,
.woocommerce ul.products li.product .price ins { color: var(--kd-color-accent-sale); }

/* Woo pozycjonuje badge absolutnie, ale punkt odniesienia ma dac motyw — bez tego
   „Promocja!" ucieka w naroznik strony. */
.woocommerce ul.products li.product,
ul.products li.product { position: relative; }
.woocommerce ul.products li.product span.onsale,
ul.products li.product span.onsale {
	position: absolute;
	top: 8px;
	left: 8px;
	right: auto;
	margin: 0;
	z-index: 1;
}

/* Znaczek ma byc przypisem, nie naklejka. Tresc skrocila sie do „−30%" (`inc/woo-hooks.php`),
   wiec i pudelko schodzi: cyfry o rownej szerokosci, zerowy tracking, ciasne wypelnienie. */
.woocommerce span.onsale,
span.onsale {
	display: inline-block;
	min-height: 0;
	min-width: 0;
	line-height: 1.3;
	background: var(--kd-color-accent-sale);
	color: var(--kd-color-text-on-primary);
	font-family: var(--kd-font-body);
	font-size: var(--kd-label-size);
	font-weight: 500;
	letter-spacing: 0;
	text-transform: none;
	font-variant-numeric: tabular-nums;
	padding: 3px 7px;
	border-radius: var(--kd-radius-sm);
}

.woocommerce button.button:disabled,
.woocommerce button.button:disabled[disabled],
.woocommerce button.button.alt:disabled,
.woocommerce button.button.alt:disabled[disabled],
.woocommerce a.button.disabled,
.woocommerce button.button.disabled,
.woocommerce button.button.alt.disabled,
.woocommerce input.button.disabled {
	background: var(--kd-color-surface);
	color: var(--kd-color-text-muted);
	box-shadow: none;
	border-color: var(--kd-color-border);
}

/*
 * Naglowek kategorii bez pudelka. Byla to plaszczyzna w kolorze marki z wysrodkowanym
 * opisem SEO — najwiekszy pojedynczy sygnal „szablon" na calej stronie. Zostaje sam tytul
 * do lewej, opis w waskiej kolumnie i wloskowata linia zamiast tla. Wyjscie z gradientu
 * odejmuje takze caly kaskadowy problem „bialy tekst na kolorze": tresc jest teraz
 * na tle strony, wiec dziedziczy normalny kontrast.
 */
/*
 * ⚠️ Bez linii pod spodem. Do 21.09.2026 naglowek archiwum konczyl sie kreska na calej
 * szerokosci, a 40 px nizej zaczynal sie pasek filtrow, ktory ma WLASNA gorna krawedz
 * (`.kd-filters__panel`, border-top). Zmierzone na `/naszyjniki-z-kamieniami-naturalnymi/`
 * przy 1440 px: linia na 559 px i druga na 599 px, miedzy nimi pusty pas. Dwie rownolegle
 * kreski przez cala strone to nie podzial, tylko niedoróbka — zostaje ta, ktora nalezy
 * do paska narzedzi, bo to ona oddziela opis od oferty.
 */
.kd-shop-hero {
	padding: 0 0 var(--kd-space-4);
	margin-bottom: var(--kd-space-5);
	text-align: left;
}
.kd-shop-hero__title { margin-bottom: var(--kd-space-2); }
.kd-shop-hero__lead {
	max-width: 68ch;
	margin-inline: 0;
	position: relative;
	color: var(--kd-color-text-muted);
}
.kd-shop-hero__lead :last-child { margin-bottom: 0; }
.kd-shop-hero__lead a { color: var(--kd-color-accent); text-decoration: underline; }
.kd-shop-hero__lead strong { font-weight: 500; color: var(--kd-color-text); }
/* Przelacznik jest sterowany etykieta „Czytaj dalej" i ma zniknac. Wymiary z `!important`,
   bo globalne `input[type="checkbox"]` (selektor atrybutu) bije klase i robilo z niego
   niewidzialny kwadrat 24 px w srodku naglowka kategorii. */
.kd-lead-toggle {
	position: absolute;
	width: 1px !important;
	height: 1px !important;
	opacity: 0;
	pointer-events: none;
}
.kd-lead-more { display: none; }

/* Pasek narzedzi trzyma trzy rzeczy: filtry, licznik wynikow i sortowanie. Siatka z nazwanymi
   obszarami, bo na pulpicie i na telefonie ustawiaja sie inaczej, a kolejnosc w kodzie zostaje
   ta sama (filtry → licznik → sortowanie). */
.kd-shop-toolbar {
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-areas:
		"filtry  filtry"
		"licznik sortowanie";
	align-items: center;
	gap: var(--kd-space-2);
	margin-bottom: var(--kd-gap);
}
/* ⚠️ `min-width: 0` jest tu warunkiem, a nie ozdoba. Komorka siatki ma domyslnie `min-width: auto`,
   wiec `<select>` z najdluzsza opcja („Sortuj wg ostatnio dodanych") narzucal kolumnie 265 px,
   pasek robil sie 402 px i przewijal w bok cala strone przy 390 px. Widac to bylo dopiero na
   stronach z listingiem w tresci (`/dzien-babci-dziadka/`, `/ametyst/`) — na archiwum kategorii
   kontener jest szerszy i nadmiar sie miescil. */
.kd-shop-toolbar > * { min-width: 0; }
.kd-shop-toolbar select { max-width: 100%; }
.kd-shop-toolbar .kd-filters { grid-area: filtry; margin-bottom: 0; }
.kd-shop-toolbar .woocommerce-result-count { grid-area: licznik; margin: 0; }
.kd-shop-toolbar .woocommerce-ordering { grid-area: sortowanie; margin: 0; justify-self: end; }

.woocommerce-result-count, .woocommerce-ordering { color: var(--kd-color-text-muted); font-size: var(--kd-body-sm-size); }

/* Paginacja zostala w domyslnym Woo (fiolet #816F98 na #EBE9EB, 3,65:1) — nikt jej nie przykryl,
   bo Elementor mial wlasny widget listy produktow. */
.woocommerce nav.woocommerce-pagination ul {
	border: 0;
	display: flex;
	/* Przy 36 produktach numery + „nastepna" nie mieszcza sie w 390 px i wystawaly 9 px poza ekran. */
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px;
	margin: var(--kd-gap) 0 0;
}
.woocommerce nav.woocommerce-pagination ul li { border: 0; margin: 0; overflow: visible; }
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	/* `min-width` na elemencie liniowym nic nie robi — numery mialy 30 px wysokosci. */
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 8px 12px;
	border-radius: var(--kd-radius-sm);
	background: var(--kd-color-surface);
	color: var(--kd-color-text);
	font-weight: 500;
	text-decoration: none;
}
/* ⚠️ Numer strony to nawigacja po liscie, a nie akcja, wiec nie bierze akcentu. Biezaca strona
   byla pelnym turkusowym kwadratem, czyli najmocniejszym kolorem na calym archiwum — mocniejszym
   niz cokolwiek, co prowadzi do zakupu. Ta sama poprawka stoi w `main.css` dla `.pagination`
   (wpisy bloga); oba selektory musza sie zgadzac, inaczej sklep i blog licza strony inaczej. */
.woocommerce nav.woocommerce-pagination ul li a:hover,
.woocommerce nav.woocommerce-pagination ul li a:focus {
	background: var(--kd-color-surface-deep);
	color: var(--kd-color-text);
}
.woocommerce nav.woocommerce-pagination ul li span.current {
	background: var(--kd-color-text);
	color: var(--kd-color-background);
	font-weight: 600;
}

/* --- pusta lista produktow: wyszukiwanie bez trafien, kategoria bez towaru --- */

.kd-empty { display: grid; gap: var(--kd-space-3); }

.kd-empty__lead {
	margin: 0;
	font-size: var(--kd-h4-size);
	font-weight: 600;
}

.kd-empty__hint { margin: calc(-1 * var(--kd-space-2)) 0 0; color: var(--kd-color-text-muted); }

.kd-empty .kd-search { max-width: 520px; }

.kd-empty__cats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kd-space-1);
}

.kd-empty__heading { margin: 0; }

/*
 * W koszyku nie ma nad wskazowka zdania wiodacego, wiec ujemny margines z `.kd-empty__hint`
 * przykleilby ja do komunikatu Woo. Przycisk „Wróć do sklepu" drukuje sie PO tym bloku
 * (szablon `cart/cart-empty.php`) i potrzebuje wlasnego odstepu.
 */
.kd-empty--cart { margin-block: var(--kd-space-4); }
.kd-empty--cart .kd-empty__hint { margin-top: 0; }
.kd-empty--cart + .return-to-shop { margin-top: var(--kd-space-4); }

/* Woo ma wlasne szare przyciski o wyzszej specyficznosci niz nasz .button. */
.woocommerce #respond input#submit,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt {
	font-family: var(--kd-font-body);
	font-weight: var(--kd-button-weight);
	text-transform: var(--kd-button-transform);
	letter-spacing: var(--kd-button-ls);
	padding: 12px 22px;
	border: var(--kd-btn-border);
	border-radius: var(--kd-radius-button);
	background: var(--kd-btn-bg);
	color: var(--kd-btn-text);
	box-shadow: var(--kd-shadow-button);
}
.woocommerce #respond input#submit:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover {
	background: var(--kd-btn-hover-bg);
	color: var(--kd-btn-text);
	box-shadow: var(--kd-shadow-button-hover);
}

/* --- strona produktu (zastepuje szablony Elementora #5623 / #11851 / #6569) --- */

/* Proporcje kolumn i odstepy zmierzone na produkcji: 615 / 655 px w kontenerze 1280,
   przerwa 10 px, prawa kolumna z paddingiem 48 px. */
.single-product div.product,
.single-product .kd-pdp-top {
	display: grid;
	grid-template-columns: minmax(0, 615fr) minmax(0, 655fr);
	column-gap: 10px;
	align-items: start;
}
/* Zakladki i „Inni kupili" sa rodzenstwem galerii, wiec domyslnie wpadaja do kolumn.
   Od 23.09.2026 galeria i boks zakupu stoja we wlasnym `.kd-pdp-top` (inc/woo-hooks.php, powod:
   przyklejona galeria). `:is(div.product, .kd-pdp-top)` dziala przy obu ukladach, wiec strona
   podana jeszcze ze starej kopii w cache nie rozsypie sie w chwili wdrozenia. */
.single-product div.product > * { grid-column: 1 / -1; }
.single-product :is(div.product, .kd-pdp-top) > .woocommerce-product-gallery { grid-column: 1; grid-row: 1; }
.single-product :is(div.product, .kd-pdp-top) > .summary { grid-column: 2; grid-row: 1; }

.single-product :is(div.product, .kd-pdp-top) > .summary {
	display: flex;
	flex-direction: column;
	gap: 15px;
	/* Tylko odstep od zdjecia. Do 23.09.2026 bylo 48 px z kazdej strony: tytul stal 48 px nizej
	   niz gora zdjecia, a na tablecie padding zjadal 27% kolumny i tytul lamal sie na 7 wierszy. */
	padding: 0 0 0 48px;
	margin: 0;
}
/* `div.summary { margin-bottom: 2em }` z woocommerce.css ma (0,3,2) i wygrywa z `margin: 0` wyzej. */
body.single-product div.product div.summary { margin-bottom: 0; }
.single-product :is(div.product, .kd-pdp-top) > .summary > * { margin: 0; }
/* Clearfix WooCommerce (`::before`/`::after` z `display: table`) w kontenerze flex to dwa puste
   elementy: kazdy dokladal 8 px odstepu, wiec pole ilosci stalo 8 px na prawo od ceny. */
body.single-product div.product form.cart::before,
body.single-product div.product form.cart::after { display: none; }
body.single-product div.product form.cart div.quantity { margin: 0; }
@media (min-width: 768px) and (max-width: 1024px) {
	.single-product :is(div.product, .kd-pdp-top) > .summary { padding: 0 0 0 var(--kd-space-3); }
}

/*
 * Zanim wystartuje suwak galerii, wszystkie zdjecia produktu stoja jedno pod drugim: przy 390 px
 * galeria ma 3 595 px zamiast 438 px i cala strona ponizej — z cena i przyciskiem — zjezdza
 * o ponad trzy tysiace pikseli w dol, a po sekundzie wraca. Mierzone CLS strony produktu: 0,30
 * przy progu 0,10. To najgorszy wynik w calym serwisie i jedyna strona z niezerowym CLS.
 *
 * Sa trzy stany, nie dwa, i pierwsza proba poprawki widziala tylko pierwszy z nich:
 *
 * 1. HTML z serwera — zdjecia stoja jedno pod drugim, opakowania `.flex-viewport` jeszcze nie ma.
 * 2. Suwak zamontowany, ale jeszcze nie zmierzony — `.flex-viewport` JUZ JEST, tasma dostala
 *    `width: 800%`, a poszczegolne klatki nie maja jeszcze wlasnego `width: 350px`. Kazda klatka
 *    jest wiec szeroka na cala tasme (2 800 px) i zdjecie w niej ma 2 800 x 2 800.
 * 3. Po zmierzeniu — `.flex-viewport` dostaje `height: 350px` wpisane w atrybut `style`.
 *
 * Stad `:not(:has(.flex-viewport))` samo nic nie dawalo: w chwili, gdy strona sie ukladala,
 * opakowanie juz istnialo. Ramke rezerwuje `aspect-ratio: 1` na opakowaniu — zdjecia produktow
 * sa kwadratowe, wiec wysokosc wychodzi dokladnie ta, ktora suwak wpisze chwile pozniej.
 *
 * Proporcja obowiazuje TYLKO w stanie 2, do chwili wpisania `height`. Przy wpisanej wysokosci
 * `aspect-ratio` liczy z niej SZEROKOSC, a suwak mierzy klatki szerokoscia opakowania: przy zdjeciu
 * 900 x 945 (5 ze 122 produktow ma zdjecie glowne niekwadratowe, galerie maja ich wiecej)
 * opakowanie roslo z kazdym przeliczeniem, 584 -> 644 -> 793 -> 1327 px, wchodzilo na tytul
 * i pokazywalo pasek nastepnego zdjecia; na telefonie przewijalo strone w bok (818 px przy 390).
 * Przy zdjeciach poziomych kurczylo sie odwrotnie (322 px w kolumnie 584). Zmierzone 22.09.2026.
 */
.woocommerce-product-gallery:not(:has(.flex-viewport)) .woocommerce-product-gallery__image:not(:first-child) {
	display: none;
}
.woocommerce-product-gallery .flex-viewport:not([style*="height"]) {
	aspect-ratio: 1;
}

/* Miniatury galerii stawaly w rzedzie w roznych wysokosciach — 108 ze 122 zdjec nie ma na dysku
   pliku 400x400 (§C), wiec Woo bierze oryginal i kazdy ma inne proporcje. Wymuszamy kwadrat
   samym kadrowaniem; `src`/`srcset` zostaja nietkniete, bo od nich zalezy lightbox. */
.woocommerce div.product .flex-control-thumbs li img {
	aspect-ratio: 1;
	object-fit: cover;
	width: 100%;
	height: auto;
}

.kd-sale-tag {
	align-self: flex-start;
	padding: 0;
	background: none;
	color: var(--kd-color-accent-sale);
	font-size: var(--kd-label-size);
	font-weight: var(--kd-label-weight, 500);
	letter-spacing: var(--kd-label-ls, 0);
	text-transform: var(--kd-label-transform, none);
	text-align: left;
}

.kd-divider {
	width: 100%;
	height: 0;
	margin: 0;
	border: 0;
	border-top: 1px solid var(--kd-color-border);
}
/* Karta „Najczesciej kupowane razem" ma wlasna ramke; kreska 15 px nad nia robila podwojna linie. */
.kd-divider:has(+ .kd-bump) { display: none; }

/* Tytul i cena na karcie produktu ida z tokenow: `h2` dla nazwy, rola `price` dla kwoty
   (o krok wieksza niz w siatce). Sztywne 30/25 px wracaly do skali kitu Elementora. */
.single-product div.product .product_title {
	font-size: var(--kd-h2-size);
	font-weight: var(--kd-h2-weight);
	line-height: var(--kd-h2-lh);
	letter-spacing: var(--kd-h2-ls, 0);
}
/* Na tablecie kolumna tekstu ma 300 do 400 px i nazwa w roli `h2` szla na 5 do 7 wierszy. */
@media (min-width: 768px) and (max-width: 1024px) {
	.single-product div.product .product_title { font-size: var(--kd-h3-size); line-height: 1.2; }
}
/* Podtytul pod nazwa (`_kd_subtitle`): korzysc po ludzku, cichszy od nazwy. */
.single-product div.product .kd-product-subtitle {
	margin: 0;
	font-size: var(--kd-body-size);
	line-height: 1.4;
	color: var(--kd-color-text-muted);
}
.single-product div.product p.price {
	font-family: var(--kd-price-family, var(--kd-font-heading));
	font-size: calc(var(--kd-price-size) * 1.25);
	font-weight: var(--kd-price-weight, 500);
	color: var(--kd-color-text);
}
.single-product div.product p.price ins { font-weight: inherit; }

/* Wtyczka Omnibus dokleja swoj komunikat do ceny (wymog prawny — poprzednia najnizsza cena). */
.iworks-omnibus,
p.iworks-omnibus { font-size: var(--kd-body-sm-size); color: var(--kd-color-text-muted); margin: 0; }

.woocommerce-product-details__short-description h2,
.woocommerce-product-details__short-description h3 {
	font-size: var(--kd-h3-size);
	font-weight: 500;
	margin-bottom: var(--kd-space-2);
}
.woocommerce-product-details__short-description :last-child { margin-bottom: 0; }

/* Dostepnosc. Reguly nie mozna zaczepic o `.woocommerce div.product` — ten motyw nie owija
   produktu klasa `.woocommerce`, wiec stary selektor nigdy nie zadzialal i na stronie stalo
   „118 w magazynie" w kolorze o kontrascie 3,41:1. Liczbe magazynu chowa filtr w PHP,
   tutaj zostaje samo zdanie o dostepnosci. */
.single-product div.product p.stock {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 var(--kd-space-2);
	font-size: var(--kd-body-size);
	font-weight: 500;
}
.single-product div.product p.stock.in-stock { color: var(--kd-color-success); }
.single-product div.product p.stock.available-on-backorder,
.single-product div.product p.stock.out-of-stock { color: var(--kd-color-error); }
.single-product div.product p.stock::before {
	content: "";
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
	flex: none;
}

/* Pole ilosci i przycisk zajmuja 380 px, nie cala szerokosc kolumny — jak na produkcji. */
.single-product form.cart {
	display: flex;
	gap: var(--kd-space-1);
	align-items: stretch;
	margin: 0;
	max-width: 380px;
}
.single-product form.cart .quantity input {
	width: 58px;
	height: 100%;
	text-align: center;
	font-size: var(--kd-body-size);
}
.woocommerce div.product form.cart .single_add_to_cart_button {
	flex: 1;
	padding: 10px 16px;
}
/* Apple Pay, Google Pay i Link (wtyczka Stripe) stoja pod przyciskiem zakupu i maja miec jego
   szerokosc. Na pelnej kolumnie (526 px) byly trzy czarno-zielone pasy szersze od glownego
   przycisku o 146 px i to one, a nie „Dodaj do koszyka", rzadzily boksem zakupu. */
.single-product .summary #wc-stripe-express-checkout-element { max-width: 380px; }
/* Miedzy przyciskiem a Apple Pay bylo 63 px: `margin-bottom: 2em` formularza z woocommerce.css (0,3,2)
   bil nasze `margin: 0`, a Stripe dopisuje ramce `margin-top: 1em` w atrybucie style (stad !important).
   Zostaje sam odstep boksu, 15 px, wiec oba sposoby zaplaty czytaja sie jako jedna grupa. */
body.single-product div.product form.cart { margin-bottom: 0; }
.single-product .summary #wc-stripe-express-checkout-element { margin-top: 0 !important; margin-bottom: 0 !important; }

.product-intencja-wrapper { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.intencja-label {
	font-size: var(--kd-label-size);
	font-weight: 500;
	color: var(--kd-color-text-muted);
	text-transform: uppercase;
	letter-spacing: 1px;
	white-space: nowrap;
}
.intencja-value {
	font-size: var(--kd-caption-size);
	font-weight: 500;
	color: var(--kd-color-accent);
	padding: 5px 16px;
	background: none;
	border: 1px solid var(--kd-color-border);
	border-left: 2px solid currentColor;
	letter-spacing: .3px;
}

.kd-trust { display: flex; flex-wrap: wrap; gap: var(--kd-space-1); }
.kd-trust__item {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 11px 0;
	background: none;
	color: var(--kd-color-text-muted);
	font-size: var(--kd-body-sm-size);
	font-weight: 400;
}
.kd-trust__item .kd-icon { width: 18px; height: 18px; flex: none; }

/* ⚠️ Na telefonie `flex-wrap` uklada znaczki po dwa w rzedzie, czyli w kolumnach po 165 px,
   i KAZDA etykieta lamie sie na dwa wiersze. Zmierzone 21.09.2026 na karcie produktu: caly
   blok zaufania zajmowal 250 px pionu tuz pod przyciskiem zakupu, w miejscu, gdzie kazdy
   piksel nalezy do decyzji o kupnie. Jedna kolumna miesci te same cztery zdania w jednym
   wierszu kazde. Na pulpicie kolumna jest szeroka i podzial na dwa zostaje. */
@media (max-width: 767px) {
	.kd-trust { flex-direction: column; gap: 0; }
	.kd-trust__item { padding: 7px 0; }
}

/* Na karcie produktu znaczki stoja w siatce: dwie kolumny, gdy kazda ma co najmniej 220 px,
   inaczej jedna. `flex-wrap` ukladal je w postrzepione rzedy, a przy kolumnie 262 do 433 px
   (tablet, maly laptop) lamal „Wysylka od 9,99 zl, darmowa od 99 zl" na cztery wiersze.
   `max()` w minimum pilnuje, zeby przy szerokiej kolumnie nie zrobily sie trzy kolumny i sierota. */
.single-product .summary .kd-trust {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(max(220px, calc((100% - var(--kd-space-3)) / 2)), 1fr));
	column-gap: var(--kd-space-3);
	row-gap: 0;
}
.single-product .summary .kd-trust__item {
	align-items: flex-start;
	padding: 7px 0;
	line-height: 1.45;
}
.single-product .summary .kd-trust__item .kd-icon { margin-top: 1px; }
/* Bez tego „99 zl" zostawalo samo w drugim wierszu. */
.single-product .summary .kd-trust__item > span { text-wrap: balance; }

/* Stoi w miejscu gwiazdek Woo, wiec ma wygladac jak one, nie jak kolejny znaczek. */
.kd-store-rating {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 var(--kd-space-1);
	font-size: var(--kd-body-sm-size);
	color: var(--kd-color-text-muted);
}
.kd-store-rating strong { color: var(--kd-color-text); }
.kd-store-rating .kd-icon { width: 16px; height: 16px; color: #F5A623; }

/* W checkoucie znaczki stoja pod „Kupuje i place" — na calej szerokosci kolumny. */
.woocommerce-checkout .kd-trust { margin-top: var(--kd-space-2); }

.single-product .product_meta { font-size: var(--kd-body-sm-size); line-height: 1.5; }
.single-product .product_meta > span { display: block; }

/*
 * „(19 opinii klienta)" gubilo spacje po liczbie. Winne bylo `inline-flex` postawione tu
 * dla celu dotykowego: Woo sklada ten odnosnik z `<span class="count">19</span>` i golego
 * tekstu, a kontener elastyczny robi z kazdego z nich osobny element i USUWA odstep miedzy
 * nimi. `inline-block` daje ten sam cel 40 px i zostawia tekst tekstem.
 *
 * Wysokosc nie zalezy od interlinii: `min-height` trzyma dolna granice sam z siebie,
 * a wypelnienie tylko ustawia napis w pionie.
 */
.woocommerce-review-link {
	display: inline-block;
	min-height: 40px;
	min-width: 40px;
	padding-block: 9px;
}

/* Woo rysuje zakladki jako szare „teczki" z ramkami i pseudoelementami — produkcja ma sam tekst. */
.woocommerce-tabs { margin-top: var(--kd-space-5); }
.woocommerce div.product .woocommerce-tabs ul.tabs {
	display: flex;
	gap: var(--kd-space-3);
	list-style: none;
	margin: 0 0 var(--kd-space-3);
	padding: 0;
	border-bottom: 1px solid var(--kd-color-border);
}
.woocommerce div.product .woocommerce-tabs ul.tabs li {
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { content: none; }
.woocommerce div.product .woocommerce-tabs ul.tabs li a {
	display: flex;
	align-items: center;
	min-height: 44px;
	padding: 10px 0;
	/* „Opis" mial 30,5 px szerokosci — wysokosc byla, brakowalo drugiego wymiaru. */
	min-width: 40px;
	justify-content: center;
	font-size: var(--kd-caption-size);
	font-weight: 700;
	color: var(--kd-color-text-muted);
	text-shadow: none;
}

/*
 * Kategorie i znaczniki zostaja ZDANIEM, a nie siatka celow dotykowych.
 *
 * Bylo tu `min-height: 40px` na kazdym odnosniku. Skutek: czternascie znacznikow bestsellera
 * zamienialo sie w czternascie klockow po 40 px, laczonych przecinkami, ktore zostawaly na
 * starej linii bazowej — trzy wiersze z dziurami. WCAG 2.5.8 ma na to wyjatek „Inline":
 * odnosnik plynacy w wierszu, otoczony tekstem, ktory celem nie jest, nie musi miec 24 px.
 * Ta lista jest dokladnie takim przypadkiem — i tak samo widzi ja nasz wlasny pomiar
 * (`tech-audit/scripts/etapC.js`, warunek na `display: inline` plus tekst wokol).
 */
.single-product .product_meta a {
	display: inline;
	padding-inline: 2px;
	margin-inline: -2px;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active a { color: var(--kd-color-primary); }
/* Woo powtarza w panelu tytul zakladki („Opis") — na produkcji jest ukryty. */
#tab-description > h2:first-child { display: none; }
/* Opis szedl przez cala szerokosc kontenera: 1 200 px to ~150 znakow w wierszu, dwa razy
   wiecej niz oko potrafi sledzic bez gubienia poczatku nastepnego wiersza. Tabela atrybutow
   zostaje szeroka — tam wiersz to dwie komorki, nie zdanie. */
.woocommerce-Tabs-panel--description p,
.woocommerce-Tabs-panel--description ul,
.woocommerce-Tabs-panel--description ol,
.woocommerce-Tabs-panel--description h2,
.woocommerce-Tabs-panel--description h3,
.woocommerce-Tabs-panel--description h4 { max-width: 68ch; }
.woocommerce-product-attributes { width: 100%; border-collapse: collapse; }
.woocommerce-product-attributes th,
.woocommerce-product-attributes td { text-align: left; padding: 8px 0; font-size: var(--kd-body-sm-size); }
.woocommerce-product-attributes th { font-weight: 700; }
.woocommerce-product-attributes td p { margin: 0; }

.single-product .related > h2,
.single-product .upsells > h2 { font-size: var(--kd-h3-size); font-weight: 600; line-height: 1.25; margin-bottom: var(--kd-space-2); }
.single-product .related,
.single-product .upsells {
	margin-top: var(--kd-space-5);
	padding-top: var(--kd-space-4);
	border-top: 1px solid var(--kd-color-border);
}
/* „Inni kupili" zwraca czesto trzy produkty, a siatka auto-fill robila cztery kolumny
   i zostawiala pusty pas po prawej. Trzy produkty dostaja trzy kolumny. */
@media (min-width: 768px) {
	.single-product :is(.related, .upsells) ul.products:has(> li:nth-child(3):last-child) {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}
/* Okruszki maja klase `.kd-container` wewnatrz `main.kd-container`, wiec margines boczny
   liczyl sie dwa razy i sciezka stala 32 px na prawo od zdjecia. */
.single-product .kd-breadcrumbs { padding-inline: 0; padding-top: 0; }

/* Galeria jedzie z ekranem, dopoki opis jest dluzszy — tak samo jak na produkcji.
   ⚠️ Do 23.09.2026 ta regula nie dzialala wcale: `woocommerce.css` ma
   `.woocommerce div.product div.images.woocommerce-product-gallery { position: relative }` (0,4,2),
   a stary selektor mial (0,3,1). Galeria odjezdzala w gore i obok opisu zostawala pusta kolumna.
   Nowy ma (0,4,3) i dziala TYLKO w `.kd-pdp-top`: przyklejony element nie wychodzi poza rodzica,
   a przy rodzicu `div.product` zdjecie jechaloby przez opinie, opis i FAQ (inc/woo-hooks.php).
   `top` liczy przyklejony naglowek (znak + powietrze + ramka, jak `.kd-header__inner` w main.css),
   inaczej naglowek przykrywa gorne 70 px zdjecia. Ponizej 740 px wysokosci okna (laptop 1366 x 657)
   zdjecie z miniaturami sie nie miesci i przyklejenie chowaloby miniatury, wiec galeria zostaje w miejscu. */
@media (min-width: 1025px) and (min-height: 740px) {
	body.single-product div.kd-pdp-top > div.images.woocommerce-product-gallery {
		position: sticky;
		top: calc(var(--kd-logo-h) + var(--kd-space-4) + 1px + var(--kd-space-3));
	}
}

@media (max-width: 767px) {
	/* `minmax(0, 1fr)`, nie `1fr`: kolumna `1fr` ma minimum `auto`, wiec jeden szeroki element
	   (ramka Stripe z Apple Pay i Google Pay obok siebie) rozpycha cala kolumne poza okno. */
	.single-product div.product,
	.single-product .kd-pdp-top { grid-template-columns: minmax(0, 1fr); }
	.single-product :is(div.product, .kd-pdp-top) > .woocommerce-product-gallery,
	.single-product :is(div.product, .kd-pdp-top) > .summary { grid-column: 1; }
	.single-product :is(div.product, .kd-pdp-top) > .summary { grid-row: auto; padding: var(--kd-space-3) 0 0; }
	.single-product :is(div.product, .kd-pdp-top) > .woocommerce-product-gallery { padding: 0; }
	.single-product div.product .product_title { font-size: var(--kd-h2-size); }
	.single-product div.product p.price { font-size: var(--kd-h3-size); }
	.woocommerce-tabs ul.tabs { gap: var(--kd-space-2); overflow-x: auto; }
	.woocommerce ul.products,
	ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--kd-space-2); }

	.kd-shop-hero { padding: 0 0 var(--kd-space-3); margin-bottom: var(--kd-space-3); }
	/* Dwa wiersze, nie trzy. Na 390 px caly wstep nad siatka zajmowal 690 px — klient przewijal
	   ekran i pol, zanim zobaczyl pierwszy produkt. Kazdy wiersz opisu to 26 px tej drogi. */
	.kd-shop-hero__lead--collapsible .kd-shop-hero__text {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		overflow: hidden;
	}
	.kd-lead-toggle:checked ~ .kd-shop-hero__text { display: block; overflow: visible; }
	.kd-lead-more {
		display: inline-flex;
		align-items: center;
		min-height: 40px;
		margin-top: var(--kd-space-1);
		font-size: var(--kd-body-sm-size);
		font-weight: 600;
		color: var(--kd-color-accent);
		text-decoration: underline;
		cursor: pointer;
	}
	.kd-lead-more__close,
	.kd-lead-toggle:checked ~ .kd-lead-more .kd-lead-more__open { display: none; }
	.kd-lead-toggle:checked ~ .kd-lead-more .kd-lead-more__close { display: inline; }
	.kd-lead-toggle:focus-visible ~ .kd-lead-more { outline: 2px solid currentColor; outline-offset: 2px; }

	/* Na telefonie „Filtruj" i sortowanie dziela jeden rzad, licznik schodzi pod nie na drobne
	   pismo. Wczesniej byly to trzy pelnoszerokosciowe rzedy — pole formularza na cala szerokosc
	   wygladalo jak ankieta, a nie jak listing. */
	/* ⚠️ `justify-self: end` na sortowaniu zdejmowalo z niego rozciaganie do kolumny, wiec pole
	   bralo szerokosc najdluzszej opcji (268 px w kolumnie 227 px) i **nachodzilo na przycisk
	   „Filtruj"** — zaokraglona ramka pola przecinala napis. `max-width: 100%` nie ratowalo,
	   bo 100% liczy sie od rodzica, ktory sam byl juz za szeroki. Na telefonie oba narzedzia
	   dziela rzad po polowie i oba sa rozciagniete. */
	/* ⚠️ Pole sortowania SKAKALO PIONOWO przy kazdym rozwinieciu filtra i to nie byla usterka
	   pola, tylko skutek dwoch rzeczy naraz. Po pierwsze `.kd-filters` to JEDEN element siatki,
	   ktory trzyma przycisk „Filtruj" RAZEM z calym rozwijanym panelem — wiec komorka „filtry"
	   rosla z 48 px do kilkuset, a `align-items: center` z reguly bazowej ustawiala sortowanie
	   w polowie tej wysokosci. Po drugie panel dziedziczyl po tej komorce szerokosc **polowy
	   ekranu**, wiec nazwy kategorii lamaly sie na dwa wiersze przy pustej prawej polowie.
	   `display: contents` zdejmuje z `.kd-filters` wlasne pudelko: przycisk i panel staja sie
	   osobnymi komorkami siatki, przycisk zostaje przy sortowaniu w pierwszym rzedzie, a panel
	   dostaje caly rzad na pelna szerokosc. Pudelko `.kd-filters` nie jest tu do niczego
	   potrzebne — `position: relative` obsluguje wysuwana liste tylko na pulpicie, na telefonie
	   lista i tak wraca do przeplywu (`position: static` w `filters.css`). */
	.kd-shop-toolbar {
		grid-template-columns: 1fr 1fr;
		grid-template-areas: none;
		align-items: start;
		/* Rzedy rozdzielamy marginesami, nie `row-gap`: rzad panelu istnieje takze wtedy, gdy
		   panel jest schowany (`display: none`), wiec odstep miedzy rzedami doliczylby sie
		   dwa razy i pasek uroslby o kilka pikseli przy zamknietych filtrach. */
		column-gap: var(--kd-space-2);
		row-gap: 0;
	}
	.kd-shop-toolbar .kd-filters { display: contents; }
	/* `min-width: 0` z reguly bazowej lapie tylko bezposrednie dzieci paska, a po `display: contents`
	   elementami siatki sa wnuki — bez tego `<select>` z najdluzsza opcja znow rozepchnalby kolumne. */
	.kd-shop-toolbar .kd-filters__toggle,
	.kd-shop-toolbar .kd-filters__panel { min-width: 0; }
	.kd-shop-toolbar .kd-filters__toggle { grid-area: 1 / 1 / 2 / 2; }
	.kd-shop-toolbar .woocommerce-ordering { grid-area: 1 / 2 / 2 / 3; justify-self: stretch; }
	.kd-shop-toolbar .kd-filters__panel { grid-area: 2 / 1 / 3 / 3; }
	.kd-shop-toolbar .woocommerce-result-count {
		grid-area: 3 / 1 / 4 / 3;
		margin-top: var(--kd-space-2);
		font-size: var(--kd-caption-size);
	}
	.kd-shop-toolbar select { width: 100%; max-width: 100%; }
	/* Oba elementy w rzedzie musza miec te sama wysokosc, inaczej rzad wyglada na przekrzywiony:
	   przycisk mial 40 px z samych odstepow, pole 49 px. 48 px to takze cel dotykowy z DESIGN.md. */
	.kd-shop-toolbar .kd-filters__toggle,
	.kd-shop-toolbar select {
		min-height: 48px;
		width: 100%;
	}
	.kd-shop-toolbar .kd-filters__toggle { justify-content: center; }

	/* ⚠️ Zero wypelnienia po bokach. Karta nie ma ramy (decyzja z S8: towar stoi na tym samym
	   tle co strona), wiec 8 px wciecia nie wciskalo niczego w ramke — przesuwalo zdjecia
	   o 8 px wzgledem naglowkow sekcji i okruszkow. Na telefonie dawalo to dwie krawedzie
	   na jednej stronie: napisy na 20 px, zdjecia na 28 px. */
	.woocommerce ul.products li.product,
	ul.products li.product { padding: 0 0 var(--kd-space-2); }
	.woocommerce ul.products li.product .woocommerce-loop-product__title,
	ul.products li.product .woocommerce-loop-product__title { font-size: var(--kd-body-sm-size); }
	.woocommerce ul.products li.product .price,
	ul.products li.product .price { font-size: var(--kd-body-size); }
	.woocommerce ul.products li.product .button,
	ul.products li.product .button { font-size: var(--kd-caption-size); padding: 8px 14px; }
}

/* Tabele Mojego konta na telefonie (zamowienia, metody platnosci, pliki do pobrania).
   Motyw nie laduje arkusza `woocommerce-smallscreen`, wiec bez tego `table.my_account_orders`
   (5 kolumn) wraca przy 390 px do ukladu tabelarycznego i przewija strone w bok — a `main.css`
   jej nie uratuje (`table:not(.shop_table)`). Ta strona NIE JEST w 56 widokach `etapC.js`,
   wiec pomiar tego nie zlapie. Sam koszyk ma wlasny uklad nizej i tych regul nie potrzebuje. */
@media (max-width: 640px) {
	.woocommerce table.shop_table_responsive,
	.woocommerce table.shop_table_responsive tbody { display: block; width: 100%; }

	.woocommerce table.shop_table_responsive thead { display: none; }
}

/*
 * =====================================================================================
 * Koszyk jako lista pozycji.
 * =====================================================================================
 *
 * Wlascicielka zglosila „koszyk wyglada nieprofesjonalnie" (16.08). Przyczyna: motyw
 * praktycznie nie stylizowal tabeli produktow, wiec wyglad bral sie z `woocommerce.css` —
 * obwodka `rgba(0,0,0,.1)`, promien **5 px** (nie ma go w skali motywu 4/6/8), czerwony
 * krzyzyk `#a00 !important`, wypelnienie komorek 9x12 px. Ta sama klasa problemu co przy
 * kasie w N22: brudzil cudzy arkusz, nie motyw.
 *
 * Wybor wlascicielki: lista pozycji w stylu W.KRUK / Apart — bez naglowka kolumn
 * „Produkt / Cena / Ilosc / Kwota" i bez ramki wokol calosci. Uklad mobilny jest **baza**,
 * pulpitowy nadpisaniem od 768 px; wczesniej miedzy 641 a 767 px koszyk stal na golej
 * tabeli Woo z naglowkiem kolumn.
 *
 * ⚠️ Zakres celowo na `.woocommerce-cart-form__contents`, a NIE na `shop_table_responsive`:
 *    te sama klase nosza `myaccount/orders.php`, `myaccount/payment-methods.php`,
 *    `order/order-downloads.php` i `cart-totals.php`. `.kd` w selektorze nie jest ozdoba —
 *    `woocommerce.css` opisuje te tabele przez `.woocommerce table.shop_table` (0,2,1),
 *    a `kd-woo` zalezy od `kd-main`, nie od `woocommerce-general`, wiec kolejnosc arkuszy
 *    nie jest gwarantowana i wygrywamy swoistoscia.
 * ⚠️ `display: grid` siedzi na `tr`, nigdy na `form` ani `table`: `$.blockUI` wstrzykuje
 *    nakladke jako dziecko formularza przy kazdym odswiezeniu AJAX — jako element siatki
 *    rozsypalaby uklad.
 */

.kd.woocommerce-cart .woocommerce-cart-form { margin: 0; }

/* ⚠️ Uklad tabelaryczny trzeba zdjac z CALEGO drzewa. Samo `tr { display: block }` w tabeli,
   ktora nadal jest `display: table`, wpada w anonimowa komorke i liczy sie z szerokoscia
   KOLUMNY, nie tabeli — zmierzone w N22 (191 -> 231 px zamiast 316). */
.kd.woocommerce-cart table.shop_table.woocommerce-cart-form__contents,
.kd.woocommerce-cart .woocommerce-cart-form__contents > tbody,
.kd.woocommerce-cart .woocommerce-cart-form__contents > tfoot { display: block; width: 100%; }

.kd.woocommerce-cart table.shop_table.woocommerce-cart-form__contents {
	border: 0;
	border-radius: 0;
	margin: 0 0 var(--kd-space-3);
}

/* Naglowek kolumn znika razem z etykietami `data-title`. „Cena: 129 zl" nad „Kwota: 129 zl"
   to dokladnie ten bazodanowy wyglad, ktory zostal odrzucony — cene jednostkowa od kwoty
   rozroznia hierarchia (13 px wyszarzone vs 15 px/600 w kolorze tresci). */
.kd.woocommerce-cart .woocommerce-cart-form__contents > thead { display: none; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td::before { content: none; }

.kd.woocommerce-cart .woocommerce-cart-form__contents > tbody > tr { display: block; }

.kd.woocommerce-cart .woocommerce-cart-form__contents td,
.kd.woocommerce-cart .woocommerce-cart-form__contents th {
	display: block;
	width: auto;
	min-width: 0;
	padding: 0;
	border: 0;
	text-align: left;
	vertical-align: baseline;
}

/*
 * Pozycja koszyka. Kolejnosc DOM w `cart.php` (x · foto · nazwa · cena · ilosc · kwota)
 * rozni sie od kolejnosci wizualnej — rozwiazuje to `grid-template-areas`, bez linii JS.
 *
 * Baza (telefon):        pulpit od 768 px:
 *   foto  nazwa    x       foto  nazwa   ilosc  kwota  x
 *   foto  cena/szt.        foto  cena
 *   foto  ilosc  kwota
 */
.kd.woocommerce-cart .woocommerce-cart-form__contents > tbody > tr.cart_item {
	display: grid;
	grid-template-columns: var(--kd-cart-thumb, 72px) minmax(0, 1fr) auto;
	grid-template-areas:
		"thumb name  remove"
		"thumb price price"
		"thumb qty   subtotal";
	column-gap: var(--kd-space-2);
	row-gap: 6px;
	align-items: center;
	padding: var(--kd-space-2) 0;
	/* Wloskowata linia pod kazda pozycja i nad pierwsza — zamiast ramki wokol calej tabeli. */
	border-bottom: 1px solid var(--kd-color-border);
}

.kd.woocommerce-cart .woocommerce-cart-form__contents > tbody > tr.cart_item:first-child {
	border-top: 1px solid var(--kd-color-border);
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-thumbnail { grid-area: thumb; align-self: start; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name { grid-area: name; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-price { grid-area: price; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-quantity { grid-area: qty; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-subtotal { grid-area: subtotal; text-align: right; }
/* `align-self: start` na telefonie: nazwa potrafi zajac cztery wiersze, a wysrodkowany krzyzyk
   wisialby wtedy w polowie wysokosci pozycji, z dala od tego, co usuwa. Na pulpicie wraca
   do srodka (nizej), bo tam obejmuje oba wiersze opisu. */
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-remove {
	grid-area: remove;
	justify-self: end;
	align-self: start;
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name {
	/* Nazwa NIE jest przycinana: 61 ze 122 tytulow ma ponad 60 znakow i rozni sie dopiero
	   na koncu („…siła i motywacja" vs „…mądrość i komunikacja"). Ucieta nazwa robilaby
	   z dwoch bransoletek to samo. Zamiast tego stopien mniej niz na pulpicie. */
	font-size: var(--kd-body-sm-size);
	line-height: 1.35;
	font-weight: 600;
	overflow-wrap: anywhere;
}
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name a { color: var(--kd-color-text); }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name a:hover { color: var(--kd-color-primary); }

/* Warianty i dopiski wtyczek (m.in. zdanie Omnibusa o najnizszej cenie) schodza o stopien —
   inaczej rozpychaja pozycje i konkuruja z nazwa. */
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name .variation,
.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name dl.variation {
	margin: 4px 0 0;
	font-size: var(--kd-caption-size);
	font-weight: 400;
	color: var(--kd-color-text-muted);
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-price {
	font-size: var(--kd-caption-size);
	color: var(--kd-color-text-muted);
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-subtotal {
	font-size: var(--kd-body-size);
	font-weight: 600;
	color: var(--kd-color-text);
	white-space: nowrap;
}

/*
 * ⚠️ Krzyzyk „usun" MUSI miec 40 x 40 px. WooCommerce 11 daje temu odnosnikowi `role="button"`,
 * ktory `etapC.js` lapie, a zwolnienie WCAG 2.5.8 wymaga `display: inline` — `inline-flex`
 * przez nie nie przechodzi.
 * ⚠️ `.woocommerce a.remove` ma `color: var(--wc-red) !important`, wiec nasze `color` tez musi
 * miec `!important` — przy dwoch `!important` rozstrzyga swoistosc (nasze 0,4,2 > ich 0,1,1).
 */
.kd.woocommerce-cart td.product-remove a.remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	font-size: var(--kd-h3-size);
	line-height: 1;
	border-radius: var(--kd-radius-sm);
	color: var(--kd-color-text-muted) !important;
	background: none;
	/* Krzyzyk jest ikona, nie odnosnikiem w tresci — regula sciezki zakupu
	   (`modules/checkout/checkout.css`) podkreslala go razem z nazwami produktow
	   i pod ikonka stala kreska. */
	text-decoration: none;
}

/* Czerwien dopiero pod kursorem: usuniecie pozycji to akcja nieodwracalna, ale nie alarm. */
.kd.woocommerce-cart td.product-remove a.remove:hover,
.kd.woocommerce-cart td.product-remove a.remove:focus-visible {
	color: var(--kd-color-error) !important;
	background: var(--kd-color-surface);
}

/*
 * Wiersz kuponu i „Zaktualizuj koszyk".
 *
 * ⚠️ `colspan="6"` po zdjeciu ukladu tabelarycznego jest martwy — szerokosc niesie
 *    `display: block` na `tr`.
 * ⚠️ `flex-wrap` na `.coupon` jest warunkiem, nie ozdoba: przy zlym kodzie WooCommerce
 *    wstrzykuje w ten sam `div.coupon` komunikat `.coupon-error-notice` z `flex-basis: 100%` —
 *    bez zawijania scisnie pole do zera.
 */
.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kd-space-2);
	padding: var(--kd-space-3) 0 0;
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions .coupon {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kd-space-1);
	float: none;
	flex: 1 1 260px;
	min-width: 0;
	padding: 0;
	border: 0;
}

.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions .coupon label { display: none; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions .coupon .input-text { flex: 1 1 140px; min-width: 0; }
.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions .button { float: none; }

/* ⚠️ `!important` nie jest tu ostroznoscia: WooCommerce maluje ten komunikat
   `color: var(--wc-red) !important` (zmierzone `rgb(170,0,0)` mimo naszej reguly o swoistosci
   0,5,1). Przy dwoch `!important` rozstrzyga swoistosc. Odcien #a00 przechodzi kontrast,
   ale jest spoza palety — czerwien bledu w calym sklepie to `--kd-color-error`. */
.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions .coupon-error-notice {
	flex-basis: 100%;
	margin: 0;
	font-size: var(--kd-caption-size) !important;
	color: var(--kd-color-error) !important;
}

/* Na telefonie „Zaktualizuj koszyk" idzie pod kupon i na pelna szerokosc — w jednym rzedzie
   z polem kuponu zostawaloby mu ~90 px i lamalby napis na trzy wiersze. */
.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions button[name="update_cart"] {
	flex: 1 1 100%;
}

@media (min-width: 768px) {
	.kd.woocommerce-cart .woocommerce-cart-form__contents > tbody > tr.cart_item {
		--kd-cart-thumb: 88px;
		grid-template-columns: var(--kd-cart-thumb) minmax(0, 1fr) auto auto 40px;
		grid-template-areas:
			"thumb name  qty subtotal remove"
			"thumb price qty subtotal remove";
		column-gap: var(--kd-space-2);
		row-gap: 4px;
		padding: var(--kd-space-2) 0;
	}

	.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-name { font-size: var(--kd-body-size); }

	.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-quantity,
	.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-subtotal,
	.kd.woocommerce-cart .woocommerce-cart-form__contents td.product-remove { align-self: center; }

	/* „Zaktualizuj koszyk" odepchniety w prawo, kupon zostaje przy lewej krawedzi. */
	.kd.woocommerce-cart .woocommerce-cart-form__contents td.actions button[name="update_cart"] {
		flex: 0 0 auto;
		margin-left: auto;
	}
}

/* --- koszyk: cele dotykowe ---
   Kasa dostala te obsluge w `modules/checkout`, ale koszyk stoi na golym znaczniku Woo:
   „Zaktualizuj koszyk" mial 33 px, „Oblicz koszty wysyłki" 21 px, a etykieta metody
   dostawy 20 px. Wysokosc bierzemy z wypelnienia, zeby uklad zostal ten sam. */

.woocommerce-cart table.shop_table td.actions .button {
	min-height: 44px;
	padding-inline: var(--kd-space-2);
}

.woocommerce-cart a.shipping-calculator-button {
	display: inline-flex;
	align-items: center;
	min-height: 40px;
}

/* Woo trzyma `ul#shipping_method li label { display: inline }` — slabszy selektor przegrywa. */
.woocommerce-cart ul#shipping_method li {
	display: flex;
	align-items: center;
	gap: var(--kd-space-1);
	margin: 0;
}

.woocommerce-cart ul#shipping_method li label {
	display: flex;
	align-items: center;
	/* `display:flex` zjada spacje miedzy „Kurier:" a kwota — odstep musi wrocic jako `gap`. */
	gap: .3em;
	flex: 1;
	min-height: 44px;
	margin: 0;
	cursor: pointer;
}

/* Pole ilosci rozlewalo sie na cala szerokosc kafelka i wygladalo jak pole tekstowe. */
.woocommerce-cart .quantity input.qty {
	width: 4.5rem;
	min-width: 44px;
	text-align: center;
}

/* „Zaktualizuj koszyk" jest wylaczony, dopoki ilosc sie nie zmieni. Jako przycisk pelny
   wygladal na zepsuty — w wersji obrysowej stan wylaczony czyta sie jako „jeszcze nie teraz". */
.woocommerce-cart table.shop_table td.actions button[name="update_cart"] {
	background: none;
	border: 1px solid var(--kd-color-border);
	color: var(--kd-color-text-muted);
}

/*
 * Zdjecie w wierszu koszyka. Woo trzyma `table.cart img { width: 32px }` — wisiorek schodzil
 * do 32 px i czytal sie jako ciemna plamka, a to jedyne potwierdzenie „kupuje to, co chcialam".
 * Rozmiar bierze `--kd-cart-thumb` z wiersza (72 px telefon, 88 px pulpit), zeby zdjecie i kolumna
 * siatki nie mogly sie rozjechac.
 *
 * Kadr kwadratowy, bo bez pliku 400x400 (§C) Woo podaje oryginal — bransoletka wychodzila
 * plaskim owalem 72x45 px. Ten sam zabieg co przy miniaturach galerii.
 */
.kd.woocommerce-cart table.cart td.product-thumbnail img {
	width: var(--kd-cart-thumb, 72px);
	height: auto;
	aspect-ratio: 1;
	object-fit: cover;
	border-radius: var(--kd-radius-sm);
	display: block;
}

/*
 * Kupon obok CTA. Przycisk „Wykorzystaj kupon" byl pelnym turkusem, dokladnie takim samym jak
 * „Przejdz do platnosci" — dwa rownorzedne wezwania w jednym widoku. Obrys zostawia kolor
 * jednemu przyciskowi, ktory faktycznie prowadzi dalej.
 */
.woocommerce-cart table.shop_table td.actions .coupon button {
	background: none;
	border: 1px solid var(--kd-color-text);
	color: var(--kd-color-text);
}

/*
 * Pole na kod kuponu to jedyne pole formularza w calym sklepie, ktore Woo maluje po swojemu:
 * obwodka #CFC8D8 (liliowy) i 34 px wysokosci. Reszta pol na kasie stoi na tokenach, wiec to jedno
 * odstawalo.
 *
 * ⚠️ Sprostowanie dawnego komentarza: ta regula NIE bila selektora `#content table.cart …` —
 * motyw ma `id="kd-content"`, wiec tamten selektor w ogole nie pasuje. Prawdziwy przeciwnik
 * (`.woocommerce table.cart td.actions .coupon .input-text`) ma DOKLADNIE te sama swoistosc
 * co dawna wersja tej reguly (0,5,2) i wygrywala wylacznie kolejnosc arkuszy, ktora nie jest
 * gwarantowana. `.kd` i `table.cart` daja (0,6,2) i koncza remis.
 */
.kd.woocommerce-cart table.cart.shop_table td.actions .coupon .input-text {
	min-height: 44px;
	padding: 12px 14px;
	border: var(--kd-input-border);
	border-radius: var(--kd-radius-input);
	background: var(--kd-input-bg);
	color: var(--kd-input-text);
}

/*
 * Pulpit: tabela po lewej, podsumowanie po prawej.
 *
 * W jednej kolumnie „Przejdz do platnosci" rozciagal sie na 1 216 px i robil z przycisku
 * turkusowy pas przez cala szerokosc strony — czyli dokladnie to, czego wlascicielka nie chciala
 * widziec po redesignie. W dwoch kolumnach ten sam przycisk ma 380 px i wraca do roli akcentu,
 * a podsumowanie z kwota stoi na wysokosci produktow zamiast pod nimi.
 *
 * `:has()` pilnuje, zeby pusty koszyk (bez `.cart-collaterals`) nie dostal siatki z pusta kolumna.
 */
@media (min-width: 1024px) {
	.woocommerce-cart .woocommerce:has(.cart-collaterals) {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 380px;
		gap: 0 var(--kd-space-4);
		align-items: start;
	}

	.woocommerce-cart .woocommerce:has(.cart-collaterals) > .woocommerce-notices-wrapper {
		grid-column: 1 / -1;
	}
}

/* --- podsumowanie koszyka: ta sama tabela co na kasie ---
   Koszyk i kasa to dwa kroki tej samej sciezki i pokazuja to samo podsumowanie, a wygladaly inaczej:
   tu zostawal promien 5 px i szary `rgba(0,0,0,0.2)` prosto z `woocommerce.css` (zmierzone).
   Rozpis regul jest celowo taki sam jak w `modules/checkout/checkout.css` — jedna tabela, jeden wyglad. */

.kd.woocommerce-cart .cart_totals table.shop_table,
.kd.woocommerce-cart .cart_totals table.shop_table tbody { display: block; }

.kd.woocommerce-cart .cart_totals table.shop_table {
	width: 100%;
	border: 1px solid var(--kd-color-border);
	border-radius: var(--kd-radius-md);
	overflow: hidden;
	margin: 0 0 var(--kd-space-2);
}

.kd.woocommerce-cart .cart_totals table.shop_table tr {
	display: flex;
	align-items: baseline;
	gap: var(--kd-space-2);
	padding: var(--kd-space-2);
	border-top: 1px solid var(--kd-color-border);
}

.kd.woocommerce-cart .cart_totals table.shop_table th,
.kd.woocommerce-cart .cart_totals table.shop_table td {
	display: block;
	padding: 0;
	border: 0;
	text-align: left;
}

.kd.woocommerce-cart .cart_totals table.shop_table tr > *:first-child { flex: 1; min-width: 0; }
.kd.woocommerce-cart .cart_totals table.shop_table tr > *:last-child { text-align: right; }
.kd.woocommerce-cart .cart_totals table.shop_table tr:first-child { border-top: 0; }
.kd.woocommerce-cart .cart_totals table.shop_table tr.order-total { border-top: 1px solid var(--kd-color-border-strong); }

/* Wiersz wysylki na pelna szerokosc — komorka miala 246 px i lamala „Kurier (darmowa wysylka)"
   na dwa wiersze, a pod spodem stoi jeszcze kalkulator wysylki. Ta sama poprawka co na kasie. */
.kd.woocommerce-cart .cart_totals table.shop_table tr.shipping { display: block; }
.kd.woocommerce-cart .cart_totals table.shop_table tr.shipping th { margin-bottom: 6px; }

/* Po zdjeciu ukladu wierszowego komorka z lista metod jest ostatnim dzieckiem i brala wyrownanie
   do prawej z reguly o kwotach — nazwa metody uciekala do krawedzi. */
.kd.woocommerce-cart .cart_totals table.shop_table tr.shipping > * { text-align: left; }

/* Wiersz zastosowanego kuponu. Odnosnik „[Usun]" stal pelnym akcentem, tak samo mocno jak kwota
   rabatu — a to czynnosc wycofujaca, nie zacheta. Nawiasy kwadratowe sa w napisie WooCommerce
   (`__( '[Remove]' )`), CSS ich nie zdejmie; zostaja do decyzji wlascicielki.
   Bez `min-height`: odnosnik plynie w zdaniu, wiec obejmuje go zwolnienie WCAG 2.5.8. */
.kd.woocommerce-cart .cart_totals a.woocommerce-remove-coupon {
	margin-left: 6px;
	font-size: var(--kd-caption-size);
	color: var(--kd-color-text-muted);
	text-decoration: underline;
}
.kd.woocommerce-cart .cart_totals a.woocommerce-remove-coupon:hover { color: var(--kd-color-error); }

/* --- „co dalej" po zakupie --- */

.kd-thanks {
	margin: var(--kd-space-3) 0 var(--kd-space-4);
	padding: var(--kd-space-3);
	border-radius: var(--kd-radius);
	background: var(--kd-color-surface);
}
.kd .kd-thanks__title {
	font-size: var(--kd-h3-size);
	line-height: 1.3;
	font-weight: 600;
	letter-spacing: 0;
	margin: 0 0 var(--kd-space-2);
}
.kd-thanks__list {
	list-style: none;
	margin: 0 0 var(--kd-space-3);
	padding: 0;
	display: grid;
	gap: var(--kd-space-2);
}
.kd-thanks__list li {
	display: flex;
	align-items: flex-start;
	gap: var(--kd-space-1);
	font-size: var(--kd-body-size);
	line-height: 1.55;
}
.kd-thanks__list .kd-icon {
	flex: none;
	margin-top: 2px;
	color: var(--kd-color-primary);
}
.kd-thanks__back { display: inline-flex; }

/* --- rytm typograficzny koszyka i kasy ---
   Tytul „Zamowienie" w skali artykulu (34,84 px na telefonie) zjada jedna trzecia pierwszego
   ekranu formularza, przez ktory ma przejsc 84% ruchu. Na scieszce zakupu tytul jest etykieta
   miejsca, nie naglowkiem tresci. */
.woocommerce-cart .kd-entry__title,
.woocommerce-checkout .kd-entry__title {
	font-size: var(--kd-h2-size);
	line-height: 1.2;
	margin-bottom: var(--kd-space-2);
}

/* Po zmniejszeniu tytulu strony naglowki sekcji (29 px ze skali artykulu) byly WIEKSZE od niego —
   odwrocona hierarchia. Sekcja na sciezce zakupu jest etykieta bloku, nie tytulem tresci. */
.kd.woocommerce-cart .cart_totals > h2,
.kd.woocommerce-checkout #order_review_heading,
.kd.woocommerce-checkout .woocommerce-billing-fields > h3,
.kd.woocommerce-checkout .woocommerce-shipping-fields > h3,
.kd .woocommerce-order-details__title,
.kd .woocommerce-column__title,
.kd .woocommerce-customer-details h2 {
	font-size: var(--kd-h3-size);
	line-height: 1.3;
	font-weight: 600;
	letter-spacing: 0;
	margin: 0 0 var(--kd-space-2);
}

@media (max-width: 767px) {
	.woocommerce-cart .kd-entry__title,
	.woocommerce-checkout .kd-entry__title { font-size: var(--kd-h2-size); }

	.kd.woocommerce-cart .cart_totals > h2,
	.kd.woocommerce-checkout #order_review_heading,
	.kd.woocommerce-checkout .woocommerce-billing-fields > h3,
	.kd.woocommerce-checkout .woocommerce-shipping-fields > h3,
	.kd .woocommerce-order-details__title,
	.kd .woocommerce-column__title,
	.kd .woocommerce-customer-details h2 { font-size: var(--kd-h4-size); }

	/* Ten sam powod na kategorii: naglowek w kaflu zajmowal trzy wiersze nad siatka produktow. */
	
}

/* --- pokaz haslo (logowanie, rejestracja, zmiana hasla) --- */

/*
 * WooCommerce 10.9 dokłada ten przycisk JavaScriptem, ale NIE dostarcza juz dla niego stylow —
 * `woocommerce.css` nie ma ani jednej reguly na `.show-password-input`. Bez nich pusty `<button>`
 * lapal skore przyciskow motywu: turkusowy prostokat 66 × 38 px, bez napisu, wchodzacy na pole
 * hasla. Wygladalo to jak niedomalowany element, a klikniecie odslanialo haslo.
 *
 * Rysujemy oko maska, nie tlem — dzieki temu barwa idzie z `color`, a nie jest wpisana w plik SVG.
 * Nazwa dla czytnika ekranu jest w `aria-label`, ktory Woo ustawia i przelacza samo.
 */
.woocommerce .password-input {
	display: block;
	position: relative;
}

.woocommerce .password-input .input-text {
	padding-right: 52px;
}

.woocommerce .show-password-input {
	position: absolute;
	top: 50%;
	right: 4px;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	min-height: 0;
	padding: 0;
	border: 0;
	border-radius: var(--kd-radius-sm);
	background: none;
	box-shadow: none;
	color: var(--kd-color-text-muted);
	cursor: pointer;
}

.woocommerce .show-password-input:hover,
.woocommerce .show-password-input.display-password { color: var(--kd-color-secondary); }

.woocommerce .show-password-input::after {
	content: '';
	display: block;
	width: 20px;
	height: 20px;
	margin: 0 auto;
	background-color: currentColor;
	-webkit-mask: var(--kd-eye) center / 20px 20px no-repeat;
	mask: var(--kd-eye) center / 20px 20px no-repeat;
}

.woocommerce .show-password-input.display-password::after {
	-webkit-mask-image: var(--kd-eye-off);
	mask-image: var(--kd-eye-off);
}

.woocommerce .password-input {
	--kd-eye: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.8 12S5.6 5.2 12 5.2 22.2 12 22.2 12 18.4 18.8 12 18.8 1.8 12 1.8 12Z'/%3E%3Ccircle cx='12' cy='12' r='3.1'/%3E%3C/svg%3E");
	--kd-eye-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.8 12S5.6 5.2 12 5.2 22.2 12 22.2 12 18.4 18.8 12 18.8 1.8 12 1.8 12Z'/%3E%3Ccircle cx='12' cy='12' r='3.1'/%3E%3Cpath d='M4 20 20 4'/%3E%3C/svg%3E");
}

/* ============================================================================
   Pierwszy ekran strony produktu na telefonie (21.09.2026)
   ============================================================================
   Zmierzone PRZED, okno 390 x 844: okruszki 158/72, galeria 230/438 (zdjecie 350
   plus pas miniatur 88), tytul 722/86, ocena 823/48, cena 902/36, opis krotki 953/124,
   dostepnosc 1092/25, przycisk zakupu 1148. Klientka musiala przewinac ekran i jeszcze
   jedna trzecia, zanim zobaczyla cene i przycisk. Konwersja na telefonie 0,18 procent
   wobec 0,32 na pulpicie przy 84 procentach sesji z telefonu.

   Zabieramy okolo 380 px, nie kasujac ani jednej informacji: opis krotki schodzi pod
   przycisk (PHP, `inc/woo-hooks.php`), dostepnosc wchodzi w wiersz z cena, pas miniatur
   zamienia sie w kropki, okruszki i odstepy schodza do jednego wiersza.
   ========================================================================== */
@media (max-width: 767px) {
	/* Okruszki: jeden wiersz z przewijaniem w poziomie zamiast trzech zawinietych.
	   Sciezka jest potrzebna (powrot do kategorii), ale nie za cene 72 px. */
	.single-product .kd-breadcrumbs {
		/* Pas sciety z 75 do ok. 48 px. Byl to trzeci najwyzszy element nad przyciskiem zakupu,
		   a niesie jedno zdanie sciezki. Cel dotykowy odnosnika zostaje bez zmian. */
		margin-bottom: var(--kd-space-1);
		padding-block: 0 2px;
		font-size: var(--kd-caption-size);
		line-height: 1.6;
		white-space: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
	}
	.single-product .kd-breadcrumbs::-webkit-scrollbar { display: none; }

	/*
	 * Pas miniatur (88 px) zamienia sie w kropki (7 px). Miniatury na telefonie i tak byly
	 * nieczytelne — 60 px kwadrat na zdjecie, ktore rozni sie od sasiada odcieniem tla.
	 * Palec przesuwa galerie, kropki mowia, ile jest zdjec i ktore oglada.
	 * Flexslider dopisuje `.flex-active` do OBRAZU w miniaturze, stad `:has()` na pozycji listy.
	 */
	/* `body … div.images` bije `.woocommerce div.product div.images .flex-control-thumbs` (0,4,1)
	   z woocommerce.css, ktory zostawial pod zdjeciem swoj margines. */
	body.single-product div.product div.images .flex-control-thumbs {
		display: flex;
		justify-content: center;
		gap: 7px;
		margin: var(--kd-space-2) 0 0;
		padding: 0;
	}
	/* `flex: 0 0 7px` jest konieczne: sam `width` przegrywal z ukladem flex i kropka rozciagala
	   sie do 82 px (zmierzone). Obraz gasi `opacity` z dopiskiem `!important`, bo arkusz
	   flexslidera ustawia `.flex-control-thumbs .flex-active { opacity: 1 }` i laduje sie po nas. */
	.single-product .woocommerce-product-gallery .flex-control-thumbs li {
		flex: 0 0 7px;
		width: 7px;
		height: 7px;
		margin: 0;
		border-radius: 999px;
		background: var(--kd-color-border-strong);
		overflow: hidden;
		transition: background var(--kd-motion-fast) var(--kd-ease);
	}
	.single-product .woocommerce-product-gallery .flex-control-thumbs li:has(img.flex-active) {
		background: var(--kd-color-text);
	}
	.single-product .woocommerce-product-gallery .flex-control-thumbs li img {
		width: 100%;
		height: 100%;
		opacity: 0 !important;   /* sam obraz znika, zostaje kolo; klikalnosc i dostepnosc zostaja */
		aspect-ratio: auto;
	}

	/* Nad okruszkami stalo 40 px odstepu z kontenera tresci plus 16 px wlasnego. Na telefonie
	   to 56 px bieli miedzy naglowkiem a pierwsza informacja. */
	.single-product main.kd-entry { padding-top: var(--kd-space-2); }
	.single-product .kd-breadcrumbs { padding-top: 0; }

	/* Blok podsumowania oddycha mniej: 15 px odstepu miedzy kazda para elementow to przy
	   osmiu elementach 120 px samego powietrza nad przyciskiem. */
	.single-product :is(div.product, .kd-pdp-top) > .summary { gap: 10px; padding-top: var(--kd-space-2); }

	/*
	 * ⚠️ Tytul zostaje w roli `h2`, a nie `h3`.
	 *
	 * Zmierzone 21.09.2026 na telefonie: nazwa produktu miala 20 px, a cena nad nia 24 px —
	 * jedyny H1 w sklepie mniejszy od kazdego innego (pozostale strony maja 30 px) i mniejszy
	 * od ceny tuz pod nim. Nazwa jest jedynym tekstem, ktory robi z pozycji w katalogu rzecz;
	 * cena gorujaca nad nazwa przesuwa strone w strone dyskontu. Interlinia 1,15 kupuje z powrotem
	 * te kilkanascie pikseli, ktore wieksze pismo zabiera.
	 */
	.single-product div.product .product_title { font-size: var(--kd-h2-size); line-height: 1.15; }

	/* Ocena w jednym wierszu, mniejszymi gwiazdkami. Bylo 48 px na dwa wiersze. */
	.single-product div.product .woocommerce-product-rating {
		display: flex;
		align-items: center;
		gap: 8px;
		margin: 0;
		font-size: var(--kd-caption-size);
	}
	.single-product div.product .woocommerce-product-rating .kd-star-rating { margin: 0; }
	.single-product div.product .woocommerce-product-rating a { margin: 0; }

	/* Cena i dostepnosc dziela wiersz: cena po lewej, stan po prawej, drobnym pismem. */
	.single-product div.product p.price {
		display: inline-flex;
		align-items: baseline;
		flex-wrap: wrap;
		gap: 8px;
		/* Krok ponizej nazwy produktu i krok powyzej roli `price` z siatki — kwota ma byc
		   czytelna od razu, ale nie ma byc najwiekszym napisem na ekranie. */
		font-size: calc(var(--kd-price-size) * 1.15);
	}
	/* Kreska nad cena byla jedynym elementem, ktory nie niosl informacji. */
	.single-product :is(div.product, .kd-pdp-top) > .summary > .kd-divider:first-of-type { display: none; }

	/* Opis krotki stoi teraz POD przyciskiem — dajemy mu oddech, ktorego nie mial nad nim. */
	.single-product .woocommerce-product-details__short-description {
		margin-top: var(--kd-space-2);
		padding-top: var(--kd-space-2);
		border-top: 1px solid var(--kd-color-border);
	}
}

/* Propozycja „najczesciej kupowane razem" na stronie produktu: nad przyciskiem, jeden wiersz.
   Wzorzec z Missomy (blok „Style It With" stoi 292 px NAD przyciskiem zakupu). U nas do tej
   pory jedyna propozycja stala 2 567 px POD nim i byla losowa. */
.kd-bump--pdp {
	border: 0;
	border-top: 1px solid var(--kd-color-border);
	border-bottom: 1px solid var(--kd-color-border);
	border-radius: 0;
	padding: var(--kd-space-2) 0;
}
.kd-bump--pdp .kd-bump__item { grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; }
.kd-bump--pdp .kd-bump__name { font-size: var(--kd-body-sm-size); overflow-wrap: break-word; }

/*
 * Pasek newslettera schodzi ze strony produktu na telefonie.
 *
 * „Zapisz sie do newslettera, zyskaj -10%" to zachęta konkurencyjna wobec zakupu i zabiera
 * 44 px z pierwszego ekranu dokladnie tam, gdzie walczymy o kazdy piksel. Na kazdej innej
 * stronie pasek zostaje; strona produktu ma miec jeden cel. Ta sama zasada co przy kasie,
 * gdzie naglowek jest odchudzony (`header.php:18`).
 */
@media (max-width: 767px) {
	body.single-product .kd-announce { display: none; }
}

/*
 * Dostepnosc pod cena: zielona kropka z poswiata i zielony napis, na kazdej szerokosci.
 * Do 23.09.2026 styl mial tylko telefon, a pulpit pokazywal „Produkt dostepny" i „Brak
 * w magazynie" tym samym czarnym pismem 16 px co opis (Robert: „suche i srednio wyglada").
 * Zielen #0B6B4F ma na bieli 6,6:1, bordo bledu 9,5:1.
 */
.single-product .kd-availability {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: -4px 0 0;
	font-size: var(--kd-body-sm-size);
	font-weight: 500;
	color: var(--kd-color-success);
}
.single-product .kd-availability::before {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	margin-left: 3px;
	border-radius: 999px;
	background: currentColor;
	box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 16%, transparent);
}
.single-product .kd-availability.is-out { color: var(--kd-color-error); }

/* Termin dostawy pod przyciskami zakupu: ikona, dwa konkretne dni pogrubione, a przed 12:00
   cichsza zacheta. Liczy go `kd_delivery_estimate()` z dni roboczych i swiat. */
.kd-delivery {
	display: grid;
	grid-template-columns: 18px minmax(0, 1fr);
	column-gap: 10px;
	row-gap: 2px;
	margin: var(--kd-space-1) 0 0;
	font-size: var(--kd-body-sm-size);
	line-height: 1.45;
	color: var(--kd-color-text-muted);
}
.kd-delivery > .kd-icon { width: 18px; height: 18px; margin-top: 1px; color: var(--kd-color-text); }
.kd-delivery p { margin: 0; }
.kd-delivery__when { color: var(--kd-color-text); }
.kd-delivery__when strong { font-weight: 600; }
.kd-delivery__note { grid-column: 2; font-size: var(--kd-caption-size); }

/* ============================================================================
   Sekcje pod boksem zakupu, w miejsce zakladek WooCommerce
   ============================================================================
   Zakladki „Opis / Informacje dodatkowe / Opinie" byly najbardziej rozpoznawalnym elementem
   WooCommerce w sklepie, a przy okazji chowaly 19 opinii i 27 KB tekstu w `display: none`.
   Teraz tresc stoi jedna pod druga, kazda sekcja z wlasnym naglowkiem i kotwica.
   ========================================================================== */
.kd-pdp-section {
	margin-top: var(--kd-space-5);
	padding-top: var(--kd-space-4);
	border-top: 1px solid var(--kd-color-border);
}
.kd-pdp-section > .kd-section-title,
.kd-reviews .kd-section-title {
	margin: 0 0 var(--kd-space-3);
	font-size: var(--kd-h3-size);
	font-weight: var(--kd-h3-weight);
	line-height: var(--kd-h3-lh);
}

/*
 * Opis produktu pod „O tym kamieniu". Od 23.09.2026 opisy maja wlasne naglowki H2 i tabele, a stara
 * regula miary (`.woocommerce-Tabs-panel--description`) zeszla razem z zakladkami. Zmierzone na
 * 1440 px: wiersz 1 216 px, czyli ok. 150 znakow, i naglowki opisu 34 px nad tytulem sekcji 22 px.
 * Naglowek w opisie jest teraz krok PONIZEJ tytulu sekcji, a tekst trzyma miare jak w artykulach.
 */
.kd-pdp-section .kd-entry__content > :is(p, ul, ol, h2, h3, h4, table) { max-width: 72ch; }
.kd-pdp-section .kd-entry__content :is(h2, h3) {
	margin: var(--kd-space-4) 0 var(--kd-space-1);
	font-size: var(--kd-h4-size);
	font-weight: var(--kd-h4-weight, 600);
	line-height: 1.35;
	letter-spacing: 0;
}
.kd-pdp-section .kd-entry__content > :first-child { margin-top: 0; }

/* Dwie tabele danych na stronie produktu (tabela w opisie i atrybuty) maja wygladac tak samo:
   etykieta do lewej, wartosc zwykla, wloskowata linia miedzy wierszami. Arkusz WooCommerce daje
   atrybutom kursywe, zebre i kropkowane linie (0,2,2), a th w tabeli opisu stal wysrodkowany. */
.single-product .kd-pdp-section table:not(.shop_table) {
	border-collapse: collapse;
	border: 0;
	margin: 0;
}
.single-product .kd-pdp-section table:not(.shop_table) :is(th, td) {
	padding: 9px var(--kd-space-3) 9px 0;
	border: 0;
	border-bottom: 1px solid var(--kd-color-border);
	background: none;
	font-size: var(--kd-body-sm-size);
	font-style: normal;
	line-height: 1.5;
	text-align: left;
	vertical-align: top;
}
.single-product .kd-pdp-section table:not(.shop_table) th {
	width: auto;
	font-weight: 600;
	white-space: nowrap;
}
.single-product .kd-pdp-section table:not(.shop_table) td p { margin: 0; }

/* FAQ produktu stoi w `.kd-seo-wrapper` (aliasy kolorow dla harmonijki), ktory na kategoriach jest
   osobnym, wysrodkowanym blokiem 1 200 px z wlasnym wcieciem. Na produkcie ma byc zwykla sekcja:
   ta sama krawedz, ta sama kreska nad nia i taki sam tytul jak „O tym kamieniu" (bez turkusowej belki). */
.single-product .kd-faq.kd-seo-wrapper {
	max-width: none;
	margin: var(--kd-space-5) 0 0;
	padding: var(--kd-space-4) 0 0;
	border-top: 1px solid var(--kd-color-border);
}
.single-product .kd-faq > .kd-section-title {
	display: block;
	margin: 0 0 var(--kd-space-3);
	padding: 0;
	border: 0;
	font-size: var(--kd-h3-size);
	font-weight: var(--kd-h3-weight);
	line-height: var(--kd-h3-lh);
	color: var(--kd-color-text);
}
.single-product .kd-faq > .kd-section-title::before { content: none; }
/* Odpowiedz miala 13 px w kolorze drugorzednym przy tekscie strony 16 px. */
.single-product .kd-faq .kd-faq-a { font-size: var(--kd-body-sm-size); line-height: 1.65; color: var(--kd-color-text); }
.single-product .kd-faq .kd-faq-a > * { max-width: 72ch; }

/* Trzy najnowsze opinie zaraz pod zakupem. Cytat, podpis, data. Bez ramek i bez awatarow. */
.kd-reviews {
	margin-top: var(--kd-space-5);
	padding-top: var(--kd-space-4);
	border-top: 1px solid var(--kd-color-border);
}
/* Ocena stoi POD tytulem, nie przy prawej krawedzi. Przy `space-between` liczba ladowala
   1 100 px od naglowka, do ktorego sie odnosi, i czytalo sie to jak osobny element strony. */
.kd-reviews__head { margin-bottom: var(--kd-space-3); }
.kd-reviews__head .kd-section-title { margin-bottom: 4px; }
.kd-reviews__score {
	margin: 0;
	font-size: var(--kd-body-sm-size);
	color: var(--kd-color-text-muted);
}
.kd-reviews__score strong { font-weight: 500; color: var(--kd-color-text); }

/* Zdanie o pochodzeniu opinii. Ma byc czytelne, ale nie ma konkurowac z ocena — stoi
   w rozmiarze podpisu i w kolorze tekstu drugorzednego, jak nota pod tabela. */
.kd-reviews__note {
	max-width: 62ch;
	margin: var(--kd-space-1) 0 0;
	font-size: var(--kd-caption-size);
	color: var(--kd-color-text-muted);
}
.kd-reviews__list {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--kd-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}
.kd-review {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: var(--kd-space-3);
	background: var(--kd-color-surface);
	border-radius: var(--kd-radius-md);
}
/*
 * Gwiazdki oceny sa od 21.09.2026 rysunkiem, nie znakiem (`kd_rating_stars()`), wiec odstep
 * miedzy nimi robi `gap`, a nie `letter-spacing`, i wielkosc `width`/`height`, a nie `font-size`.
 * 15 px odpowiada wysokosci wersalika przy `caption` — rzad gwiazdek ma tez sam ciezar co dotad.
 *
 * Gwiazdka pusta dostaje wlasny `color`: `kd_icon('star-empty')` rysuje ja obrysem w
 * `currentColor`, a `currentColor` czyta `color` TEGO SAMEGO elementu, wiec wystarczy tu.
 * Obrys w kolorze tekstu bylby w rzedzie mocniejszy niz gwiazdka pelna; `border_strong` jest
 * zgodny z DESIGN.md („ikony ida w text, text_muted albo border").
 */
.kd-review__rating { margin: 0; color: var(--kd-color-text); }
.kd-review__stars { display: inline-flex; align-items: center; gap: 2px; }
.kd-review__stars .kd-icon { width: 15px; height: 15px; }
.kd-review__stars .kd-icon--star-empty { color: var(--kd-color-border-strong); }
.kd-review__text { font-size: var(--kd-body-size); line-height: 1.6; }
.kd-review__text p { margin: 0; }
.kd-review__text p + p { margin-top: .5em; }
.kd-review__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: auto 0 0;
	font-size: var(--kd-caption-size);
	color: var(--kd-color-text-muted);
}
.kd-review__meta strong { font-weight: 500; color: var(--kd-color-text); }
.kd-review__verified {
	font-size: var(--kd-label-size);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--kd-color-success);
}
.kd-reviews__more { margin: var(--kd-space-3) 0 0; }

/* Rozwijane sekcje opinii: `<summary>` udaje przycisk, wiec musi stracic wlasny znacznik listy. */
.kd-reviews__all,
.kd-review-form__box { margin-top: var(--kd-space-3); }
.kd-reviews__all > summary,
.kd-review-form__box > summary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	list-style: none;
	cursor: pointer;
}
.kd-reviews__all > summary::-webkit-details-marker,
.kd-review-form__box > summary::-webkit-details-marker { display: none; }
.kd-reviews__all[open] > summary,
.kd-review-form__box[open] > summary { margin-bottom: var(--kd-space-3); }
.kd-reviews__all > .kd-reviews__list { margin-top: 0; }

@media (max-width: 767px) {
	/* Na telefonie opinie ida jedna pod druga: trzy kolumny po 110 px to trzy slowa w wierszu. */
	.kd-reviews__list { grid-template-columns: 1fr; gap: var(--kd-space-2); }
	.kd-pdp-section { margin-top: var(--kd-space-4); padding-top: var(--kd-space-3); }
}

/* --- komplet opinii i formularz ---
   Do 21.09.2026 ta sekcja byla surowym szablonem WooCommerce: drugi naglowek „Opinie", pole oceny
   24 x 24 px i formularz bez zadnej klasy motywu. Znacznik jest teraz wlasny (`inc/product-page.php`),
   wiec styl moze byc taki sam jak w reszcie sklepu. */
/* Rozwinieta lista ma te same trzy kolumny co zajawka nad nia (do 23.09.2026 miala dwie, wiec
   po rozwinieciu karty nagle robily sie szersze od tych, ktore klient wlasnie przeczytal). */
.kd-reviews__less-label { display: none; }
.kd-reviews__all[open] .kd-reviews__more-label { display: none; }
.kd-reviews__all[open] .kd-reviews__less-label { display: inline; }
/* Formularz rozwija sie w sekcji opinii, zaraz pod przyciskiem, wiec kreski nad nim juz nie ma. */
.kd-reviews .comment-respond { margin: 0; padding: 0; border: 0; }
/* Zwiniete „Pokaż pozostałe" i „Napisz opinię" stoja w jednym wierszu; rozwiniety zajmuje caly. */
.kd-reviews > details:not([open]) { display: inline-block; margin-right: var(--kd-space-2); vertical-align: top; }
.kd-reviews .kd-review-form { max-width: 560px; }
.kd-review-form__title {
	margin: 0 0 var(--kd-space-1);
	font-size: var(--kd-h4-size);
	font-weight: var(--kd-h4-weight);
}
.kd-review-form__note {
	margin: 0 0 var(--kd-space-3);
	font-size: var(--kd-body-sm-size);
	color: var(--kd-color-text-muted);
}
.kd-review-form p { margin: 0 0 var(--kd-space-2); }
.kd-review-form label {
	display: block;
	margin-bottom: 6px;
	font-size: var(--kd-body-sm-size);
	font-weight: 500;
}
.kd-review-form input[type="text"],
.kd-review-form input[type="email"],
.kd-review-form textarea,
.kd-review-form select {
	width: 100%;
	min-height: 48px;
	padding: 10px 12px;
	font: inherit;
	font-size: var(--kd-body-size);
	color: var(--kd-input-text);
	background: var(--kd-input-bg);
	border: var(--kd-input-border);
	border-radius: var(--kd-radius-input);
	transition: border-color var(--kd-motion-fast) var(--kd-ease), box-shadow var(--kd-motion-fast) var(--kd-ease);
}
.kd-review-form textarea { min-height: 120px; resize: vertical; }
.kd-review-form :is(input, textarea, select):focus-visible {
	outline: none;
	border-color: var(--kd-input-focus-border);
	box-shadow: var(--kd-shadow-input-focus);
}
.kd-review-form .form-submit { margin: var(--kd-space-3) 0 0; }
.kd-review-form .submit { width: auto; }

/* Zgoda na zapamietanie danych. Domyslne pole wyboru WordPressa ma 24 x 24 px i wychodzi
   w pomiarze jako za maly cel dotykowy. Pole jest tu przezroczyste i rozciagniete na caly
   wiersz etykiety, a widoczny kwadracik rysuje `::before` — klikalne jest cale 44 px wysokosci. */
.kd-review-form .kd-check {
	position: relative;
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
}
.kd-review-form .kd-check input[type="checkbox"] {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}
.kd-review-form .kd-check label {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0;
	font-weight: 400;
	color: var(--kd-color-text-muted);
	cursor: pointer;
}
.kd-review-form .kd-check label::before {
	content: "";
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	border: 1px solid var(--kd-color-border-strong);
	border-radius: var(--kd-radius-sm);
	background: #fff center / 12px no-repeat;
	transition: border-color var(--kd-motion-fast) var(--kd-ease), background-color var(--kd-motion-fast) var(--kd-ease);
}
.kd-review-form .kd-check input:checked + label::before {
	border-color: var(--kd-color-primary);
	background-color: var(--kd-color-primary);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5'/%3E%3C/svg%3E");
}
.kd-review-form .kd-check input:focus-visible + label::before {
	border-color: var(--kd-input-focus-border);
	box-shadow: var(--kd-shadow-input-focus);
}

/* Gwiazdki oceny.
   Skrypt WooCommerce podmienia `#rating` na `p.stars > span > a`. Wtyczka daje kazdemu odnosnikowi
   pudelko 1em (24 px) i rysuje gwiazde pseudoelementem `::before` ustawionym bezwzglednie w rogu
   (`top: 0; left: 0`) wlasnym krojem ikon. Cel dotykowy z DESIGN.md to 44 px, wiec powiekszamy
   pudelko i przesuwamy gwiazde na srodek — samo `display: inline-flex` nic by nie dalo, bo
   pseudoelement jest wyjety z ukladu.
   Selektor musi zaczynac sie od `.kd`: regula wtyczki `.woocommerce p.stars a` to (0,2,2),
   czyli tyle samo co `.kd-review-form p.stars a` — o wyniku decydowalaby kolejnosc wczytania
   arkuszy, a ta zalezy od tego, ktory modul akurat kolejkuje swoje style. */
.kd .kd-review-form p.stars {
	display: flex;
	align-items: center;
	margin: 0 0 var(--kd-space-2);
}
.kd .kd-review-form p.stars > span { display: flex; }
.kd .kd-review-form p.stars a {
	width: 44px;
	height: 44px;
	font-size: 24px;
	color: var(--kd-color-text);
	border-radius: var(--kd-radius-sm);
}
.kd .kd-review-form p.stars a::before {
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}
.kd .kd-review-form p.stars a:focus-visible {
	outline: 2px solid var(--kd-color-primary);
	outline-offset: -2px;
}

@media (max-width: 767px) {
	.kd-reviews .kd-review-form { max-width: none; }
}

/* --- zwijanie tresci SEO pod siatka produktow ---
   Powod i pomiar: `kd_archive_seo_content()` w `inc/woo-hooks.php`. Tresc zostaje w kodzie
   strony (`max-height`, nie `display: none`), wiec Google ja czyta, a `Ctrl+F` ja znajduje. */
.kd-seo-collapse { position: relative; }
.kd-seo-collapse__toggle { position: absolute; opacity: 0; pointer-events: none; }
.kd-seo-collapse__body {
	max-height: 560px;
	overflow: hidden;
}
.kd-seo-collapse__body::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 400px;
	height: 160px;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--kd-color-background));
	pointer-events: none;
}
.kd-seo-collapse__toggle:checked ~ .kd-seo-collapse__body { max-height: none; }
.kd-seo-collapse__toggle:checked ~ .kd-seo-collapse__body::after { display: none; }
.kd-seo-collapse__label {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin-top: var(--kd-space-3);
	cursor: pointer;
}
/* Strzalka z dwoch krawedzi ramki, nie ze znaku „▾”: Poppins tego znaku nie ma, wiec szedlby
   z kroju systemowego i wygladalby inaczej na kazdym urzadzeniu. Ten sam wzorzec co rozeta
   filtrow (`.kd-filters__legend::after`). */
.kd-seo-collapse__label::after {
	content: "";
	width: 6px;
	height: 6px;
	border-right: 1px solid currentColor;
	border-bottom: 1px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	transition: transform var(--kd-motion-fast) var(--kd-ease);
	flex-shrink: 0;
}
.kd-seo-collapse__toggle:checked ~ .kd-seo-collapse__label::after {
	transform: translateY(1px) rotate(-135deg);
}
.kd-seo-collapse__close,
.kd-seo-collapse__toggle:checked ~ .kd-seo-collapse__label .kd-seo-collapse__open { display: none; }
.kd-seo-collapse__toggle:checked ~ .kd-seo-collapse__label .kd-seo-collapse__close { display: inline; }
/* Fokus na ukrytym polu musi byc widoczny na etykiecie, inaczej osoba na klawiaturze
   nie wie, gdzie jest. To ten sam wzorzec co przy zgodzie w formularzu opinii. */
.kd-seo-collapse__toggle:focus-visible ~ .kd-seo-collapse__label {
	outline: 2px solid var(--kd-color-primary);
	outline-offset: 2px;
}


/* ---- Nazwa w siatce: tozsamosc + korzysc ---- */
/* Trzy wiersze, nie dwa: „Naszyjnik z awenturynem geometrycznym" (37 znakow) w kolumnie
   167 px nie miesci sie w dwoch, a slowo „geometrycznym" jest wlasnie tym, co odroznia go
   od „Naszyjnika z awenturynem naturalnym" obok. Rzad i tak zrownuje wysokosci kafli, wiec
   trzeci wiersz nie kosztuje nic — patrz `margin-top: auto` przy wierszu ceny nizej. */
.woocommerce ul.products li.product .kd-loop-title__main,
ul.products li.product .kd-loop-title__main {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}
.woocommerce ul.products li.product .kd-loop-title__tail,
ul.products li.product .kd-loop-title__tail {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
	margin-top: 2px;
	font-size: var(--kd-caption-size, 13px);
	line-height: 1.35;
	color: var(--kd-color-text-muted);
}

/* ---- Wiersz ceny w siatce: cena + ile taniej ---- */
.woocommerce ul.products li.product .kd-loop-pricerow,
ul.products li.product .kd-loop-pricerow {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--kd-space-1);
	width: 100%;
}
.woocommerce ul.products li.product .kd-loop-pricerow .price,
ul.products li.product .kd-loop-pricerow .price { margin: 0; }
/* Sam napis, bez wypelnienia: plakietka ma byc przypisem przy cenie, a nie naklejka
   na fotografii. Bordo zostaje JEDYNYM nasyconym kolorem w kaflu, dlatego nowa cena
   wraca do koloru tresci — inaczej w jednym wierszu stalyby dwie czerwone rzeczy. */
.woocommerce ul.products li.product .kd-loop-sale,
ul.products li.product .kd-loop-sale {
	color: var(--kd-color-accent-sale);
	font-size: var(--kd-caption-size, 13px);
	font-weight: 500;
	white-space: nowrap;
}
.woocommerce ul.products li.product .price ins,
ul.products li.product .price ins { color: var(--kd-color-text); }

/* ⚠️ Ceny w siatce staly na 13 roznych wysokosciach i w rzedzie zgadzaly sie tylko 3 razy
   na 8: kazdy kafel konczyl sie tam, gdzie skonczyl mu sie tytul. Kafel jest elementem
   siatki, wiec rzad i tak rozciaga go do swojej wysokosci — wystarczy oddac te nadwyzke
   wierszowi ceny. Po zmianie ceny zgadzaja sie w 8 rzedach na 8, a dluzsza nazwa nie
   przesuwa juz ceny sasiada. */
.woocommerce ul.products li.product,
ul.products li.product { height: 100%; }
.woocommerce ul.products li.product .kd-loop-pricerow,
ul.products li.product .kd-loop-pricerow { margin-top: auto; }

/*
 * Gwiazdki oceny (`kd_stars_fraction()`): rzad pusty pod spodem, rzad pelny przyciety u gory.
 * Wypelnienie ulamkowe robi `width` w procentach na warstwie wierzchniej — tak samo jak
 * w WooCommerce, tylko rysunkiem zamiast webfontu. Znacznik celowo NIE nosi klasy
 * `star-rating`, wiec nie ma tu nic do zerowania po wtyczce (powod w `inc/woo-hooks.php`).
 */
/*
 * `inline-flex`, bo wlasny znacznik jest `<div>`, a WooCommerce robil z `.star-rating` element
 * plywajacy. Bez tego odnosnik „(19 opinii)" spadal pod gwiazdki — na pulpicie, gdzie blok
 * oceny nie jest flexem (ta regula siedzi w `@media (max-width: 767px)`).
 */
.kd-star-rating { display: inline-flex; vertical-align: middle; line-height: 0; }
.kd-stars { position: relative; display: inline-flex; line-height: 0; color: var(--kd-color-text); }
.kd-stars__empty,
.kd-stars__full { display: inline-flex; gap: 2px; }
.kd-stars__empty { color: var(--kd-color-border-strong); }
.kd-stars__full { position: absolute; inset-block-start: 0; inset-inline-start: 0; overflow: hidden; }
.kd-stars .kd-icon { flex: none; width: 15px; height: 15px; }
