/* >>> isa-design-system | odcisk b65a9eca6ff8 >>>
   Generowane przez `npm run gen-wp-sklepy`. NIE EDYTUJ TEGO PLIKU —
   edytuj docs/wordpress-sklepy/warstwy/ i uruchom generator ponownie.
   Cofnięcie na produkcji: dezaktywacja wtyczki isa-design-system. */
/* --- tokeny: WYPROWADZONE z src/styles/global.css, nie edytuj tutaj --- */
body.isa-ds {
  --isa-red: #cb092a;
  --isa-red-dark: #cb092a;
  --isa-red-darker: #a8071f;
  --isa-red-soft: #ffe3e8;
  --isa-red-ink: #cb092a;
  --error-ink: #cb092a;
  --success-ink: #177349;
  --ink: #0a0a0a;
  --ink-2: #1d1d1f;
  --ink-3: #424245;
  --ink-4: #61616b;
  --line: #d2d2d7;
  --line-2: #e8e8ed;
  --bg: #ffffff;
  --bg-2: #f5f5f7;
  --bg-3: #fbfbfd;
  --always-dark: #0a0a0a;
  --always-dark-2: #1d1d1f;
  --always-dark-ink: #f5f5f7;
  --always-dark-ink-muted: #98989d;
  --always-dark-line: #2c2c2e;
  --always-dark-red: #ff4d68;
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-xl: 32px;
  --maxw: 1280px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --siatka-kolor: #d2d2d7;
  --siatka-skok: 18px;
  --track-fe: #e66b1a;

  /* most do palety Kadence — komponenty motywu idą za naszymi kolorami
     bez ani jednej naszej reguły (MAPA_PALETY w scripts/gen-wp-sklepy.mjs) */
  --global-palette1: var(--isa-red); /* akcent marki — jedyna pozycja zgodna na obu sklepach przed zmianą */
  --global-palette2: var(--isa-red-darker); /* drugi akcent; zastępuje fiolet #7400fc (.com) i granat #215387 (.online) */
  --global-palette3: var(--ink); /* najciemniejszy — nagłówki */
  --global-palette4: var(--ink-2); /* ciemny — tekst wyróżniony */
  --global-palette5: var(--ink-3); /* tekst pomocniczy; to on malował linki menu na .com */
  --global-palette6: var(--ink-4); /* tekst wyciszony */
  --global-palette7: var(--bg-2); /* tło pomocnicze / karty */
  --global-palette8: var(--bg-3); /* tło jaśniejsze */
  --global-palette9: var(--bg); /* biel; na .com było #efefef i służyło za kolor tekstu na czerwonym przycisku */
}

/* ===== 05-most-kadence.css ===== */
/* Most do motywu: to, czego przedefiniowanie palety nie łapie.
 *
 * Paleta (MAPA_PALETY w generatorze) obsługuje komponenty, które czytają --global-palette*.
 * Zostają trzy miejsca, gdzie Kadence trzyma kolor poza paletą — zmierzone
 * w docs/wordpress-sklepy/pomiar-startowy.md §1. */

/* Tło strony: SZARE, kafle BIAŁE — decyzja właściciela 2026-09-15.
 *
 * To jest świadome odstępstwo od serwisu, który ma odwrotnie (białe tło, kafle na --bg-2).
 * Powód jest funkcjonalny, nie estetyczny: sklep to siatka kafli produktów, a białe kafle
 * na szarym tle same rysują swoje granice. Pierwsza wersja szła za serwisem i właściciel
 * zgłosił, że kafle zniknęły — bo białe na białym odcina już tylko włosowa ramka.
 *
 * Zmierzone wartosci zastane: #efefef (.com wszędzie), #F7FAFC (.online produkt i koszyk),
 * #ededed (.online archiwum, spoza palety). Zastępuje je jeden token.
 */
body.isa-ds {
  background-color: var(--bg-2);
  color: var(--ink);
}

body.isa-ds.post-type-archive-product,
body.isa-ds.tax-product_cat {
  background-color: var(--bg-2);
}

/* Kontener treści: szerokość systemu zamiast domyślnej motywu. */
body.isa-ds .content-container,
body.isa-ds .site-container {
  max-width: var(--maxw);
}

/* Linki w treści — Kadence maluje je paletą 5 (tekst pomocniczy), więc po zmapowaniu
 * wyszłyby szare. W systemie link w treści jest czerwienią tekstową. */
body.isa-ds .entry-content a:not(.button):not(.wp-block-button__link) {
  color: var(--isa-red-ink);
  text-underline-offset: 2px;
}
body.isa-ds .entry-content a:not(.button):not(.wp-block-button__link):hover {
  color: var(--isa-red-darker);
}

/* Obramowania i separatory motywu na token linii. */
body.isa-ds hr,
body.isa-ds .entry-content hr {
  border-color: var(--line-2);
}

/* ===== 10-typografia.css ===== */
/* Typografia systemu na sklepie.
 *
 * Stan zastany (pomiar-startowy.md §2): rodzina jest już wspólna (Poppins, self-host),
 * ale reszta nie. Trzy z czterech zmierzonych h1 mają wagę 400, wszystkie nagłówki mają
 * letter-spacing `normal`, a body 16px na .com wobec 17px na .online.
 * System serwisu: body 17px/1.5/-0.01em, nagłówki 700/-0.035em/1.12.
 *
 * Skali `clamp()` nie przenosimy w wersji landingowej (`.t-display` sięga 92 px) — sklep
 * to strona zadaniowa, nie okładka. Bierzemy trzy dolne stopnie skali. */

/* Interlinia 1,5 — dokładnie jak `body` serwisu.
 *
 * ⚠️ WYCOFANE ODSTĘPSTWO. Stało tu 1,6 z uzasadnieniem „sklep ma długie opisy w kolumnie
 * zwężonej przez sidebar, więc gęstszy skład czyta się gorzej". Uzasadnienie było
 * ODWRÓCONE: interlinię dobiera się do DŁUGOŚCI WIERSZA i to długi wiersz wymaga większego
 * odstępu, żeby oko trafiło w początek następnego. Wąska kolumna potrzebuje MNIEJSZEJ
 * interlinii, nie większej — argument przemawiał więc za 1,5, a wyciągnięto z niego 1,6.
 *
 * Do tego reguła `max-width: 68ch` niżej i tak trzyma wiersz w zakresie czytelnym, czyli
 * przesłanka o „długich opisach" nie opisuje stanu faktycznego tego arkusza.
 *
 * Rozjazd zmierzony 2026-09-15 porównaniem wyliczonych stylów obu serwisów: body sklepu
 * 27,2 px wobec 25,5 px na Astro przy identycznym 17 px i tej samej rodzinie. Żadna bramka
 * go nie widziała, bo obie strony są poprawne każda z osobna — rozjazd istnieje wyłącznie
 * MIĘDZY nimi, a sklep ma być przedłużeniem serwisu, nie jego wariantem. */
body.isa-ds {
  font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: -0.01em;
}

/* Akapity w treści dostają górną granicę długości wiersza. Bez niej opis produktu
 * na 1440 px biegnie przez całą szerokość kontenera — ok. 120 znaków w wierszu, dwa razy
 * więcej niż zakres czytelny (45-75). */
body.isa-ds .entry-content p,
body.isa-ds .woocommerce-product-details__short-description p {
  max-width: 68ch;
}

/* Nagłówki — skala serwisu, wiązana z ROZMIAREM, nie z poziomem znacznika.
 *
 * Serwis ma cztery stopnie i w każdym tracking oraz interlinia zależą od stopnia:
 *   .t-display 92px  −0,045em  1,08
 *   .t-h1      72px  −0,035em  1,10
 *   .t-h2      48px  −0,030em  1,12
 *   .t-h3      30px  −0,020em  1,18
 * Im większy stopień, tym ciaśniej — bo przy dużym piśmie odstępy optycznie rosną.
 * `.t-display` i `.t-h1` pomijamy: sklep to strona zadaniowa, nie okładka; największy
 * stopień na sklepie to 48 px, czyli odpowiednik `.t-h2`.
 *
 * ⚠️ POPRZEDNIA WERSJA SKLEJAŁA h1 Z h2 W JEDEN STOPIEŃ i przez to przeczyła sama sobie:
 * `body.isa-ds h1, body.isa-ds h2` deklarowało −0,035em, a stojąca niżej reguła
 * `body.isa-ds .page-title` −0,030em i to ona wygrywała kaskadę. Zmierzone po `cssRules`
 * 2026-09-15: na h1 archiwum trafiały obie moje reguły, wynik −1,44 px przy 48 px.
 * Wartość wychodziła poprawna PRZYPADKIEM — przez kolejność, nie przez zamysł. Dwie własne
 * reguły mówiące o tym samym elemencie co innego to defekt nawet wtedy, gdy wynik się zgadza,
 * bo znika przy pierwszej zmianie kolejności warstw.
 *
 * Teraz stopień przypisuje się do rozmiaru, a nie do znacznika: h2 o 33 px dostaje stopień
 * `.t-h3`, a nie ten sam co h1 o 48 px. */
body.isa-ds h1,
body.isa-ds h2,
body.isa-ds h3,
body.isa-ds h4 {
  font-weight: 700;
  color: var(--ink);
  text-wrap: balance;
}
/* Stopień 48 px — odpowiednik .t-h2 serwisu. */
body.isa-ds h1 {
  letter-spacing: -0.03em;
  line-height: 1.12;
}
/* Stopień 30–33 px — odpowiednik .t-h3. h2 na sklepie mierzy 33 px (zmierzone na karcie
 * produktu), więc należy tu, a nie do stopnia h1. */
body.isa-ds h2 {
  letter-spacing: -0.02em;
  line-height: 1.18;
}
/* Poniżej skali serwisu: h3 i h4 schodzą ku wartościom tekstu ciągłego. Interlinia luźniejsza
 * niż 1,18 jest tu celowa — te nagłówki w sklepie regularnie łamią się na dwie linie. */
body.isa-ds h3,
body.isa-ds h4 {
  letter-spacing: -0.015em;
  line-height: 1.3;
}

/* Odstęp nad nagłówkiem większy niż pod nim — nagłówek należy do tekstu POD sobą.
 * Bez tej pary Kadence daje symetryczne marginesy i sekcje zlewają się w jedną płachtę. */
body.isa-ds .entry-content h2,
body.isa-ds .entry-content h3 {
  margin-top: 1.8em;
  margin-bottom: 0.6em;
}

/* Tytuł strony/archiwum — stopień .t-h2 serwisu (48 px), ten sam co h1 wyżej.
 *
 * Interlinia podana JAWNIE, choć powtarza wartość z reguły h1. To nie jest nadmiar:
 * zmierzone 2026-09-15 — `.page-title` i `.entry-title` dawały 1,15, a `.product_title`
 * 1,12, czyli dwa tytuły tego samego stopnia na sąsiednich stronach sklepu miały różną
 * interlinię. Brało się to stąd, że tylko jedna z trzech reguł ją ustawiała, a reszta
 * dziedziczyła z ogólnego h1. */
body.isa-ds .entry-title,
body.isa-ds .page-title,
body.isa-ds h1.entry-title {
  font-size: clamp(30px, 3.4vw, 48px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.12;
}

/* Tytuł produktu.
 *
 * Kadence ma dla niego regułę `.woocommerce div.product .product_title{font-weight:600}`
 * o specyficzności (0,3,1) — bije `body.isa-ds .product_title` (0,2,1). Zmierzone
 * dochodzeniem po `cssRules` 2026-09-15: w h1 na karcie produktu trafiają dokładnie dwie
 * reguły wagi — `h1{800}` Kadence i ta Woo z 600, i to ona wygrywa.
 *
 * Powtarzamy jej kształt z prefiksem zasięgu (0,4,2) zamiast sięgać po !important —
 * ten sam chwyt co program-b2b.css na obcym motywie.
 *
 * ⚠️ Pierwsza wersja celowała w `.elementor-widget-woocommerce-product-title` i nie
 * trafiała w nic: widget nazywa się `single-product-title`, a sam tytuł i tak nosi
 * zwykłe klasy Woo. Elementor nie miał z tym nic wspolnego. */
body.isa-ds .product_title,
body.isa-ds.single-product .entry-title,
body.isa-ds .woocommerce div.product .product_title,
body.isa-ds div.product .product_title {
  font-size: clamp(30px, 3.4vw, 48px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.12;
  color: var(--ink);
}

body.isa-ds h2 {
  font-size: clamp(23px, 2.4vw, 33px);
  letter-spacing: -0.03em;
}

body.isa-ds h3 {
  font-size: clamp(20px, 2vw, 26px);
  letter-spacing: -0.02em;
}

/* Krótki opis produktu pełni rolę leadu. */
body.isa-ds .woocommerce-product-details__short-description {
  font-size: clamp(17px, 1.4vw, 20px);
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: var(--ink-3);
}

/* Tekst drobny i pomocniczy. */
body.isa-ds .woocommerce-result-count,
body.isa-ds .product_meta,
body.isa-ds .woocommerce-breadcrumb {
  font-size: 14px;
  color: var(--ink-4);
  letter-spacing: 0;
}

/* Okruszki: cel dotykowy 24 px wg WCAG 2.5.8 — ta sama reguła co .okruszki w serwisie. */
body.isa-ds .woocommerce-breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--ink-3);
}
body.isa-ds .woocommerce-breadcrumb a:hover {
  color: var(--isa-red-ink);
}

/* Cena. W serwisie cena jest jednym z dwóch miejsc z wagą 700 poza nagłówkami
 * (.cd-price: 40px/700/-0.03em), a cena przekreślona jest wyciszona, nie czerwona. */
body.isa-ds .woocommerce-Price-amount {
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
}
body.isa-ds del .woocommerce-Price-amount,
body.isa-ds del {
  font-weight: 500;
  color: var(--ink-4);
  letter-spacing: 0;
}
body.isa-ds ins {
  text-decoration: none;
}
body.isa-ds.single-product p.price .woocommerce-Price-amount {
  font-size: 40px;
}
/* Kwota na listingu: 18 px, nie 20.
 *
 * Przy 20 px w kafelku trzykolumnowej siatki para „990,00 zl" + „z VAT" nie mieściła się
 * w jednym wierszu i dopisek spadał pod kwotę — złapane na zrzucie porównawczym.
 * Dodatkowo sama kwota nie może się łamać w środku. */
body.isa-ds ul.products li.product .price .woocommerce-Price-amount {
  font-size: 18px;
  white-space: nowrap;
}
/* Przy przecenie w kaflu stoją obok siebie DWIE kwoty i sufiks „z VAT". Przy 18 px na
 * kazdej „z VAT" spadal do drugiej linii (zlapane na zrzucie 2026-09-15). Kwota przekreslona
 * i sufiks są podrzędne wobec ceny aktualnej — mniejsze zwalniają miejsce i cała fraza
 * mieści się w jednym wierszu, a hierarchia staje się czytelniejsza. */
body.isa-ds ul.products li.product .price del,
body.isa-ds ul.products li.product .price del .woocommerce-Price-amount {
  font-size: 14px;
}
body.isa-ds ul.products li.product .price .woocommerce-price-suffix {
  font-size: 13px;
  color: var(--ink-4);
  white-space: nowrap;
}

/* Odstępy w bloku ceny. Zmierzone na żywo na .online 2026-09-15 — obie wartości brały się
 * z samej spacji tekstowej w znaczniku, bez żadnego marginesu, więc nie skalowały się
 * ze stopniem pisma i przy dużych kwotach znikały:
 *   · strona produktu: `del` → `ins` 5,5 px przy kwocie 40 px — litera „ł" ceny przekreślonej
 *     dotykała pierwszej cyfry ceny aktualnej (reguła `margin-right` istniała WYŁĄCZNIE
 *     dla kafla listingu, `ul.products li.product .price del`, i nie obejmowała produktu);
 *   · listing i produkt: `ins` → sufiks 2,7 px przy kwocie 18 px/700 — czytało się „złbrutto".
 * Odstęp daje margines, nie spacja: `.woocommerce-Price-amount` ma `letter-spacing: -0.03em`
 * i wagę 700, które dodatkowo zjadają światło między znakami. */
body.isa-ds .summary p.price del,
body.isa-ds div.product p.price del {
  margin-right: 14px;
}
/* Cena przekreślona na stronie produktu: 24 px, nie 40.
 *
 * ⚠️ Marginesy wyżej trzeba było czymś opłacić. Blok ceny na produkcie ma 407,8 px treści
 * (del 190,7 + ins 166,1 + sufiks 51) przy kolumnie 378–438 px na dużych szerokościach —
 * czyli mieścił się zapasem 12,7 px, a +20 px marginesów zrzuciło „brutto" do drugiej linii
 * na 900 / 1024 / 1440 px (zmierzone na żywo zaraz po wgraniu). Zmniejszenie kwoty
 * przekreślonej zwalnia ~76 px i przywraca jeden wiersz z zapasem 26,7 px, a przy okazji
 * daje tę samą hierarchię co w kaflu: cena aktualna dominuje, poprzednia jest podrzędna.
 *
 * ⚠️ Na 375 i 768 px fraza łamie się NADAL (kolumna 311–315 px < 351 px) — to stan ZASTANY,
 * nie skutek tych reguł: przy zapasie 5,5 px sufiks spadał tam do drugiej linii również
 * przed zmianą. Zejście w jeden wiersz na telefonie wymaga zmniejszenia ceny AKTUALNEJ
 * poniżej 40 px, czyli decyzji o typografii, nie poprawki odstępu. */
body.isa-ds.single-product p.price del .woocommerce-Price-amount,
body.isa-ds.single-product p.price del {
  font-size: 24px;
}
body.isa-ds .price .woocommerce-price-suffix {
  margin-left: 6px;
}

/* Informacja Omnibus o najniższej cenie z 30 dni. Na .online wtyczka Simple Custom CSS
 * malowała ją czystą czerwienią 14 px — to komunikat prawny, nie alarm. */
body.isa-ds .iworks-omnibus {
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-4);
  letter-spacing: 0;
}

/* ===== 20-przyciski-formularze.css ===== */
/* Przyciski i pola formularzy.
 *
 * Stan zastany (pomiar-startowy.md §3): SZEŚĆ różnych przycisków „dodaj do koszyka"
 * w jednej marce — wysokości 30/40/43/46/50 px, promienie 100 i 120 px, dwa kolory tekstu
 * (#ffffff i #efefef), wagi 400 i 700.
 *
 * Najgorszy przypadek: na archiwum .com Kadence renderuje CTA w trybie
 * `woo-archive-btn-text` — przezroczyste tło, fioletowy tekst, 30 px wysokości. Główne
 * wezwanie do zakupu na liście kursów nie wygląda tam jak przycisk.
 *
 * System: .btn = 48 px, promień 999 px, waga 500, 15 px, ls -0.01em, hover z uniesieniem
 * o 1 px i cieniem w kolorze marki. */

body.isa-ds .button,
body.isa-ds .wp-block-button__link,
body.isa-ds .add_to_cart_button,
body.isa-ds .single_add_to_cart_button,
body.isa-ds .checkout-button,
body.isa-ds input[type="submit"],
body.isa-ds button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--isa-red-dark);
  color: #fff;
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  /* ⚠️ `normal`, nie `nowrap`. Zmierzone 2026-09-16 na .com przy 601 px: `nowrap` w parze
   * z `max-width: 100%` to sprzeczne polecenia — „nie łam" i „nie wychodź poza rodzica"
   * naraz. Przeglądarka wykonuje oba i przycina napis: `clientWidth` 101 przy `scrollWidth`
   * 117, na ekranie „YBIERZ OPC" zamiast „WYBIERZ OPCJĘ”. Przycisk, który się nie mieści,
   * ma się ZŁAMAĆ, nie stracić litery — złamany jest tylko wyższy, ucięty kłamie. */
  white-space: normal;
  max-width: 100%;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s, transform 0.22s var(--ease),
    box-shadow 0.25s;
}

body.isa-ds .button:hover,
body.isa-ds .wp-block-button__link:hover,
body.isa-ds .add_to_cart_button:hover,
body.isa-ds .single_add_to_cart_button:hover,
body.isa-ds .checkout-button:hover,
body.isa-ds input[type="submit"]:hover,
body.isa-ds button[type="submit"]:hover {
  background: var(--isa-red-darker);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 12px 26px -12px color-mix(in srgb, var(--isa-red) 72%, transparent);
}

body.isa-ds .button:active,
body.isa-ds .add_to_cart_button:active,
body.isa-ds .single_add_to_cart_button:active,
body.isa-ds .checkout-button:active {
  transform: translateY(0) scale(0.97);
}

/* Widoczna obwódka fokusu. Kadence zdejmuje `outline` na przyciskach Woo, a bez niej
 * ścieżka zakupu jest nieprzechodnia z klawiatury (WCAG 2.4.7). */
body.isa-ds .button:focus-visible,
body.isa-ds .add_to_cart_button:focus-visible,
body.isa-ds .single_add_to_cart_button:focus-visible,
body.isa-ds .checkout-button:focus-visible,
body.isa-ds input[type="submit"]:focus-visible,
body.isa-ds button[type="submit"]:focus-visible,
body.isa-ds a:focus-visible,
body.isa-ds input:focus-visible,
body.isa-ds select:focus-visible,
body.isa-ds textarea:focus-visible {
  outline: 2px solid var(--isa-red);
  outline-offset: 2px;
}

/* Przycisk wtórny — „wróć do sklepu", „zaktualizuj koszyk". W systemie to .btn-outline. */
body.isa-ds .button.wc-backward,
body.isa-ds button[name="update_cart"],
body.isa-ds .woocommerce-message .button,
body.isa-ds .woocommerce-info .button {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink);
}
body.isa-ds .button.wc-backward:hover,
body.isa-ds button[name="update_cart"]:hover,
body.isa-ds .woocommerce-message .button:hover,
body.isa-ds .woocommerce-info .button:hover {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
  box-shadow: none;
}

/* Przycisk nieaktywny — Woo wyłącza „zaktualizuj koszyk", dopóki nic nie zmieniono. */
body.isa-ds .button:disabled,
body.isa-ds .button[disabled],
body.isa-ds button[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* CTA na listingu. Kadence ma tam wariant „przycisk jako tekst" — na .com właśnie tak
 * wyglądało jedyne wezwanie do zakupu na liście kursów. */
body.isa-ds ul.products li.product .button,
body.isa-ds .woo-archive-btn-text ul.products li.product .button {
  background: var(--isa-red-dark);
  color: #fff;
  font-size: 16px;
  padding: 0 20px;
}

/* Wąskie ekrany: przycisk może się złamać, zamiast wyjechać poza kadr.
 * Ta sama reguła co @max-400px w systemie. */
@media (max-width: 400px) {
  body.isa-ds .button,
  body.isa-ds .add_to_cart_button,
  body.isa-ds .single_add_to_cart_button,
  body.isa-ds .checkout-button {
    white-space: normal;
    height: auto;
    padding-block: 10px;
    overflow-wrap: anywhere;
  }
}

/* --- Pola formularzy (Field.astro: h48, promień 32 px, ramka --line, fokus --ink) --- */

body.isa-ds input[type="text"],
body.isa-ds input[type="email"],
body.isa-ds input[type="tel"],
body.isa-ds input[type="number"],
body.isa-ds input[type="password"],
body.isa-ds input[type="search"],
body.isa-ds input[type="url"],
body.isa-ds select,
body.isa-ds textarea,
body.isa-ds .select2-container .select2-selection--single {
  min-height: 48px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--bg);
  color: var(--ink);
  font-family: inherit;
  font-size: 16px;
  letter-spacing: -0.01em;
  transition: border-color 0.2s;
}

body.isa-ds textarea {
  min-height: 120px;
  padding: 14px 16px;
  line-height: 1.6;
}

body.isa-ds input:hover,
body.isa-ds select:hover,
body.isa-ds textarea:hover {
  border-color: var(--ink-3);
}

body.isa-ds input:focus,
body.isa-ds select:focus,
body.isa-ds textarea:focus {
  border-color: var(--ink);
}

body.isa-ds ::placeholder {
  color: var(--ink-4);
}

/* Etykiety pól — w systemie 12 px, wersaliki, rozstrzelone, --ink-4. */
body.isa-ds .woocommerce form .form-row label,
body.isa-ds .woocommerce-billing-fields label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-4);
}
body.isa-ds .required {
  color: var(--isa-red-ink);
  text-decoration: none;
}

/* Cel dotykowy zgód wg WCAG 2.5.8 — ta sama wartość co .zgoda-pole w serwisie. */
body.isa-ds input[type="checkbox"],
body.isa-ds input[type="radio"] {
  width: 24px;
  height: 24px;
  accent-color: var(--isa-red-dark);
}

/* Komunikaty Woo — kolory semantyczne systemu zamiast domyślnej zieleni motywu. */
body.isa-ds .woocommerce-message,
body.isa-ds .woocommerce-info,
body.isa-ds .woocommerce-error {
  border-radius: var(--r-md);
  border: 1px solid var(--line-2);
  border-top-width: 2px;
  background: var(--bg-2);
  color: var(--ink-2);
  font-size: 15px;
}
body.isa-ds .woocommerce-message {
  border-top-color: var(--success-ink);
}
body.isa-ds .woocommerce-info {
  border-top-color: var(--ink-3);
}
body.isa-ds .woocommerce-error {
  border-top-color: var(--error-ink);
  color: var(--error-ink);
}


/* ⚠️ Selektora `.woocommerce ul.products` NIE zakladamy jako ścieżki.
 *
 * Zmierzone 2026-09-15 przez `element.matches()` na żywym `.online`: kontener `.woocommerce`
 * NIE jest tam przodkiem `ul.products`, więc cały człon nie trafiał w nic i przycisk zostawał
 * przy promieniu 120 px mimo pozornie wyższej specyficzności. Reguły pisane "na oko" z wiedzy
 * o WooCommerce chybiają na Kadence.
 *
 * Wariant działający: `body.isa-ds.isa-ds ul.products li.product .product-action-wrap .button`
 * (0,6,3) bije `.woocommerce ul.products.woo-archive-btn-button .product-action-wrap .button`
 * (0,6,1). Warianty z `.woocommerce` zostają na wypadek innej struktury, ale nie liczymy na nie. */

/* --- Podbicie specyficzności: trzy reguły Kadence, które biją blok wyżej ---
 *
 * Zmierzone 2026-09-15 dochodzeniem po `cssRules` na żywych stronach (nie z dokumentacji
 * motywu). Każda pozycja niesie regułę, którą pokonuje, i jej wagę:
 *
 * 1. `.woocommerce ul.products:not(.woo-archive-btn-button) li:where(…) .button:not(.kb-button)`
 *    (0,5,2) ustawia `display:inline`. To nie jest kosmetyka: element `inline` IGNORUJE
 *    `min-height`, więc przycisk na archiwum .com miał 33 px mimo `min-height:48px`.
 * 2. `.kadence-cart-button-medium-large.woocommerce div.product .button.single_add_to_cart_button`
 *    (0,6,1) ustawia `height:50px` — a `height` bije `min-height` niezależnie od wagi.
 * 3. `.woocommerce ul.products.woo-archive-btn-button .product-action-wrap .button:not(.kb-button)`
 *    (0,6,1) ustawia `border-radius:120px` (tylko .online).
 *
 * Podbijamy powtórzeniem klasy zasięgu (`body.isa-ds.isa-ds`), nie `!important` — budżet
 * wyjątków pilnuje reguła R7 strażnika i startuje z zerem. */

body.isa-ds.isa-ds ul.products li.product .product-action-wrap .button,
body.isa-ds.isa-ds ul.products li.product .button,
body.isa-ds.isa-ds .woocommerce ul.products li.product .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  min-height: 48px;
  border-radius: 999px;
  line-height: 1.2;
  padding: 0 20px;
  /* Stopień pisma MUSI być tutaj: Kadence ma dla CTA listingu regułę `font-size: 80%`
   * o specyficzności (0,5,2), która biła deklarację z bloku bazowego — zmierzone 13,6 px
   * zamiast żądanych 14. */
  font-size: 16px;
  font-weight: 600;
  /* Odstępu między tekstem a ikoną NIE dajemy przez `gap`. Kadence wstawia do przycisku
   * TRZY elementy `.kadence-svg-iconset` (strzalka, spinner, ptaszek), z których widoczny
   * jest jeden, a dwa mają zero szerokości — ale `gap` dolicza się do KAŻDEGO. Zmierzone:
   * tekst 18 px od lewej krawędzi i 62 px od prawej, czyli wizualnie przyklejony do lewej
   * przy poprawnym `justify-content: center`. */
  gap: 0;
  /* Tlo i kolor MUSZĄ być tutaj, nie tylko w bloku bazowym: Kadence maluje CTA listingu
   * własną regułą o tej samej klasie specyficzności. Bez tego przycisk miał poprawną
   * wysokość i promien, a zostawał gołym tekstem — czyli asercje na wymiarach przechodziły,
   * a wezwanie do zakupu dalej nie wyglądało jak przycisk (złapane na zrzucie 2026-09-15). */
  background: var(--isa-red-dark);
  color: #fff;
  font-weight: 500;
}
body.isa-ds.isa-ds ul.products li.product .product-action-wrap .button:hover,
body.isa-ds.isa-ds ul.products li.product .button:hover {
  background: var(--isa-red-darker);
  color: #fff;
}

body.isa-ds.isa-ds .woocommerce div.product .button.single_add_to_cart_button,
body.isa-ds.isa-ds div.product .button.single_add_to_cart_button {
  height: 48px;
  min-height: 48px;
  line-height: 1.2;
  border-radius: 999px;
  padding: 0 22px;
}

/* Ikony stanu w CTA listingu — zdjęte z przepływu.
 *
 * Kadence renderuje w przycisku trzy `<span class="kadence-svg-iconset">`: strzałkę,
 * spinner ładowania i ptaszek potwierdzenia. Widoczny jest zawsze jeden, ale wszystkie
 * trzy liczą się do układu flex — a `gap` dolicza się także do tych o zerowej szerokości.
 * Zmierzone przed zmianą: tekst 18 px od lewej i 62 px od prawej, przy poprawnym
 * `justify-content: center`. */
body.isa-ds.isa-ds ul.products li.product .button {
  position: relative;
}
body.isa-ds.isa-ds ul.products li.product .button .kadence-svg-iconset {
  display: none;
}

/* ⚠️ Strzałkę na CTA listingu USUWAMY, nie przesuwamy.
 *
 * Przymiarka pośrednia stawiała ją jako element absolutny przy prawej krawędzi
 * (`right: 14px`) z symetrycznym padding 40/40. Zmierzone na zrzucie: przy tekście
 * „Wybierz opcje" i kafelku szerokości ok. 160 px strzałka NACHODZIŁA NA OSTATNIĄ LITERĘ —
 * bo tekst jest środkowany względem całej szerokości, a strzałka stoi poza tym rachunkiem.
 *
 * Do wyboru były trzy drogi i tylko jedna spełnia prośbę „bardziej wycentrowane":
 * asymetryczny padding (tekst przestaje być na środku), węższy tekst (łamie się na dwie
 * linie w kafelku), albo zdjęcie strzałki. Strzałka nie niosła informacji — przycisk
 * w kafelku produktu i tak jest jednoznaczny — więc znika ona, a nie środek. */
body.isa-ds.isa-ds ul.products li.product .button {
  padding-right: 22px;
  padding-left: 22px;
}

/* Pole wyboru potrzebuje miejsca na strzalke.
 *
 * Regula ogolna dla pol daje `padding: 0 16px`, ale `select` rysuje wlasna strzalke po
 * prawej — przy 16 px tekst wchodzi pod nia. Zmierzone na dropdownie kategorii:
 * `padding-right: 0px`, `appearance: none` (Kadence zdejmuje natywny wyglad i podklada
 * wlasna ikone w tle). Dajemy 40 px z prawej i zostawiamy ikone motywu w spokoju. */
body.isa-ds select {
  padding-right: 40px;
}
/* Pole szukania wewnatrz rozwijanej listy (Select2) NIE jest pastylka — to pole w kadrze
 * dropdownu, gdzie promien 32 px wyglada jak balon. */
body.isa-ds .select2-container .select2-search__field,
body.isa-ds .select2-dropdown input {
  border-radius: var(--r-sm);
  min-height: 40px;
  padding: 0 12px;
}

/* ===== 30-listing-produkt.css ===== */
/* Listing kursów i karta produktu.
 *
 * Odpowiednik `.card-tile` z serwisu (87 użyć): tło --bg-2, ramka jako `inset box-shadow`
 * zamiast `border` (żeby nie dokładać 2 px do wymiarów), promień 32 px, uniesienie o 4 px
 * przy najechaniu, zdjęcie powiększane do 1,04.
 *
 * Powód, dla którego ta warstwa musi iść razem z tłem: po zmianie tła strony na biel
 * karty produktów zniknęły — wcześniej odcinały się bielą od szarego #efefef. Widoczne
 * na zrzucie porównawczym 2026-09-15. */

/* --- Kafel produktu --- */

/* Kafel MUSI odcinac sie od tla NIEZALEZNIE od tego, co pod nim lezy.
 *
 * Zmierzone na ZYWEJ stronie 2026-09-15 (wtyczka aktywna na .online): na listingu kafel
 * bialy na tle --bg-2 mial roznice jasnosci 9,3 i byl widoczny; w sekcji „Podobne produkty"
 * na karcie produktu roznica wynosila ZERO — bo tresc karty siedzi na BIALEJ plycie motywu,
 * wiec bialy kafel na bialym tle znikal. Zgloszenie wlasciciela: „zlewaja sie boxy z tlem".
 *
 * Ramka idzie na --line (wyrazniejsza), nie --line-2, ktora gubi sie na bieli. Kafel
 * przestaje zalezec od kontekstu — to wazniejsze niz subtelnosc ramki.
 *
 * ⚠️ Poprzednia asercja tego NIE zlapala, bo porownywala kafel z tlem BODY, a nie z realnym
 * rodzicem — cel swiecil na zielono przy widocznym bugu. */
body.isa-ds ul.products li.product {
  background: var(--bg);
  border-radius: var(--r-xl);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
  transition: transform 0.22s var(--ease), box-shadow 0.25s;
}

body.isa-ds ul.products li.product:hover {
  transform: translateY(-4px);
  box-shadow: inset 0 0 0 1px var(--line), 0 24px 50px -26px rgba(0, 0, 0, 0.3);
}

body.isa-ds ul.products li.product img {
  transition: transform 0.5s var(--ease);
}
body.isa-ds ul.products li.product:hover img {
  transform: scale(1.04);
}

/* Kadence rozdziela kafel na obrazek i `.product-details` — wnętrze dostaje oddech
 * systemu, a nie domyślny motywu. */
body.isa-ds ul.products li.product .product-details,
body.isa-ds ul.products li.product .entry-content-wrap {
  padding: 20px;
  background: transparent;
}

/* Kafle w wierszu kończyły się na różnych wysokościach, bo tytuł jednego łamie się
 * w dwie linie. Kolumna z akcją dosuwana do dołu wyrównuje przyciski w jednej linii —
 * ta sama zasada co stopka `.card-tile` w serwisie.
 *
 * ODSTĘPY SĄ USTANDARYZOWANE — `gap`, nie marginesy poszczególnych elementow.
 * Zmierzone przed zmianą (2026-09-15, oba sklepy): tytuł i cena sklejone (luka 0 px),
 * `.price` z marginesem 4 px na .com i 14,57 px na .online — bo Kadence liczy go w `em`,
 * więc skakał razem ze stopniem pisma. Odstęp akcji: 47,09 px na .com, 0,02 px na .online.
 * Żadnej z tych liczb nikt nie wybrał; wzięły się z dziedziczenia.
 * Teraz jest jedna wartosc (--kafel-odstep) i dosunięcie akcji do dolu. */
body.isa-ds ul.products li.product {
  --kafel-odstep: 12px;
  display: flex;
  flex-direction: column;
}
body.isa-ds ul.products li.product .product-details,
body.isa-ds ul.products li.product .entry-content-wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  gap: var(--kafel-odstep);
}
/* Marginesy własne elementów zerujemy — inaczej sumują sie z `gap` i wracamy do chaosu. */
body.isa-ds ul.products li.product .product-details > *,
body.isa-ds ul.products li.product .entry-content-wrap > * {
  margin-top: 0;
  margin-bottom: 0;
}
/* Cena i przycisk to JEDNA grupa dosunieta do dolu kafla.
 *
 * Wczesniej do dolu szla sama akcja, wiec pustka ladowala MIEDZY cena a przyciskiem —
 * i to w kazdym kaflu inna, bo zalezala od liczby linii tytulu. Zmierzone: cena na 543 px
 * w dwoch kaflach i 518 px w trzecim, pustka 39 px wobec 64 px. Zgloszenie wlasciciela:
 * „bardzo brzydko sie to zawija".
 *
 * Teraz elastyczna przestrzen jest POD TYTULEM, a cena z przyciskiem stoja razem przy dolnej
 * krawedzi — czyli w calym rzedzie na tej samej wysokosci, bez sztywnej wysokosci tytulu
 * (ta wymuszalaby pustke takze tam, gdzie nazwa kursu jest krotka). */
body.isa-ds ul.products li.product .price {
  margin-top: auto;
}
body.isa-ds ul.products li.product .product-action-wrap {
  padding-top: var(--kafel-odstep);
  /* Sam action-wrap też jest kolumną z odstępem — inaczej jego własne dzieci się sklejają.
   * Zmierzone 2026-09-15 na .com: widget rat PayU (`.payu-mini-installments-widget`) kończy
   * się na 824 px, a przycisk zaczyna na 824 px — zero odstępu, „raty przylegają do buttona"
   * (zgłoszenie właściciela). Rodzic miał `display: block`, więc `gap` z kafla go nie dotykał.
   * Na .online widgetu rat nie ma, więc `gap` nic tam nie zmienia. */
  display: flex;
  flex-direction: column;
  gap: var(--kafel-odstep);
}
/* Znaczniki niewidoczne (screen-reader-text, dane GTM) nie mogą dokładać pustego odstępu
 * przez `gap` — wyjmujemy je z przepływu kolumny. */
body.isa-ds ul.products li.product .product-action-wrap > .screen-reader-text,
body.isa-ds ul.products li.product .product-action-wrap > .gtm4wp_productdata {
  display: none;
}

/* Tytuł kafla. Interlinia 1,3 zamiast 1,2: przy dwóch liniach — a tak lamie sie większość
 * nazw kursów — 1,2 sklejało wiersze. Stopień nieco wyższy, bo to główny nośnik informacji
 * na listingu i konkuruje z ceną. */
body.isa-ds ul.products li.product .woocommerce-loop-product__title {
  font-size: clamp(17px, 1.5vw, 20px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--ink);
  /* ⚠️ LINE-CLAMP USUNIETY — nie dziala tu i ucinal tekst w polowie linii.
   *
   * Zmierzone na zywej stronie: tytul ma `display: flow-root`, bo Kadence nadpisuje nasze
   * `-webkit-box`. A `-webkit-line-clamp` dziala WYLACZNIE przy `display: -webkit-box` —
   * bez niego jest ignorowany, tekst renderuje wszystkie cztery linie, a `overflow: hidden`
   * przycina czwarta W POLOWIE WYSOKOSCI LITER. Dokladnie to widac bylo na zrzutach:
   * ucięty pasek tekstu nachodzacy na cene (zgloszenie wlasciciela, dwa razy).
   *
   * Zamiast walczyc o specyficznosc prefiksowanej wlasciwosci — rezygnujemy z obcinania.
   * Pelny tytul jest bezpieczny na kazdym silniku (WebKit bywa tu kapryśny), a rowna
   * wysokosc kafli w rzedzie i tak zapewnia siatka; cena z przyciskiem sa dosuniete do dolu,
   * wiec dluzsza nazwa nie rozjezdza rytmu. Mniej magii CSS = mniej ryzyka. */
  /* ⚠️ `break-word`, NIE `anywhere`. Zmierzone 2026-09-16 na .com przy 601 px (siatka
   * schodzi tam do dwóch bardzo wąskich kolumn): `anywhere` przełamało tytuł W ŚRODKU
   * WYRAZU — „Kurs / wieczorow / y AI Academy". Różnica nie jest kosmetyczna: `anywhere`
   * wolno łamać słowo nawet wtedy, gdy zmieściłoby się w osobnej linii, `break-word` łamie
   * dopiero, gdy słowo nie mieści się w CAŁEJ szerokości. Dla nazw kursów, które bywają
   * długie, ale nigdy dłuższe od kolumny, `break-word` wystarcza i nie tnie wyrazów.
   *
   * Warstwa 45 ma komentarz ostrzegający dokładnie przed `anywhere` przy kwotach — ta sama
   * pułapka wróciła tutaj piętro wyżej, bo ostrzeżenie stało przy jednym użyciu zamiast
   * przy właściwości. Żadna reguła bramki tego nie widzi: R2 mierzy przepełnienie pionowe,
   * R8 przycięcie poziome, a przełamany wyraz mieści się w boksie i nic nie przepełnia. */
  overflow-wrap: break-word;
}

body.isa-ds ul.products li.product a:hover .woocommerce-loop-product__title {
  color: var(--isa-red-ink);
}

/* --- Kafle w „Podobne produkty" i „Może Cię zainteresować" ---
 *
 * ⚠️ TU NIE POMAGA KOLEJNOŚĆ, TYLKO SPECYFICZNOŚĆ — i to jest cała nauka tej reguły.
 *
 * Zgłoszenie właściciela ze zrzutem: „brak wewnętrznych marginesów w tych boxach, no
 * i w ogóle niespójność z kaflami na stronie głównej sklepu". Zmierzone porównawczo,
 * kafel do kafla, na 1440 px:
 *   listing główny   → padding detali 20/20/20/20, tytuł 29 px od krawędzi kafla
 *   podobne produkty → padding detali 20/ 0/20/ 0, tytuł  0 px od krawędzi kafla
 *
 * Czyli poziomy padding był ZEROWANY tylko w tym jednym kontekście. Dochodzenie po
 * `cssRules` pokazało rzecz nieoczywistą: moja reguła stoi OSTATNIA W KASKADZIE (9 z 9
 * źródeł ustawiających tę własność) i mimo to przegrywa. Wygrywa ósma —
 * `.woocommerce.single-product.content-style-boxed .products ul.products…` z `woocommerce.min.css`
 * Kadence — bo ma więcej klas. Przy nierównej specyficzności pozycja w pliku nie znaczy nic.
 *
 * To odwrotna sytuacja niż przy snippetach, gdzie przegrywaliśmy WŁAŚNIE przez kolejność
 * (wstrzykują się po nas przy równej specyficzności). Dwa różne mechanizmy, dwa różne
 * lekarstwa: tam trzeba było podwoić klasę, tu dopasować się kształtem do przeciwnika.
 *
 * ⚠️ PIERWSZA POPRAWKA NIE WYSTARCZYŁA i policzenie specyficzności pokazało dlaczego.
 * Selektor TRAFIAŁ (`element.matches()` → true), a mimo to przegrywał:
 *   Kadence  (0,8,2)  `.woocommerce.single-product.content-style-boxed .products ul.products…`
 *   moja     (0,6,3)  `body.isa-ds.single-product .related ul.products li.product …`
 * Osiem klas bije sześć; liczba elementów rozstrzyga dopiero przy równych klasach. Dlatego
 * „selektor trafia" i „reguła działa" to dwie różne rzeczy, a sprawdzenie pierwszego nie
 * dowodzi drugiego — trzeba było policzyć obie strony.
 *
 * Potrojone `.isa-ds` daje (0,8,3): tyle samo klas co Kadence, o jeden element więcej.
 * To MINIMUM wystarczające, nie zapas na wyrost — gdyby Kadence dołożył kiedyś klasę,
 * reguła przegra i trzeba będzie policzyć na nowo, zamiast dokładać w ciemno.
 *
 * Powtórzenie klasy zamiast `!important`, bo `!important` wygrywa ze WSZYSTKIM, także
 * z przyszłymi regułami, których jeszcze nie ma — a to przenosi problem, nie rozwiązuje.
 * Ten sam chwyt co `body.isa-ds.isa-ds` w warstwie 45, tam z innego powodu (kolejność,
 * nie specyficzność).
 *
 * Nazwa sekcji to `.up-sells`, nie `.upsells` — zmierzone w DOM; `.upsells` nie trafiało w nic. */
body.isa-ds.isa-ds.isa-ds.single-product .related ul.products li.product .product-details,
body.isa-ds.isa-ds.isa-ds.single-product .related ul.products li.product .entry-content-wrap,
body.isa-ds.isa-ds.isa-ds.single-product .up-sells ul.products li.product .product-details,
body.isa-ds.isa-ds.isa-ds.single-product .up-sells ul.products li.product .entry-content-wrap,
body.isa-ds.isa-ds.isa-ds.single-product .cross-sells ul.products li.product .product-details,
body.isa-ds.isa-ds.isa-ds.single-product .cross-sells ul.products li.product .entry-content-wrap {
  padding-left: 20px;
  padding-right: 20px;
}

/* --- Dwa poziomy nazwy: kurs jako etykieta, ścieżka jako tytuł ---
 *
 * Oferta ma strukturę, której płaska nazwa nie pokazywała. Jest KURS („Machine Learning
 * Masters", „PythON: Academy") i jest ŚCIEŻKA albo pakiet w jego ramach („Ścieżka Początek",
 * „Optymalizacja i zarządzanie modelami"). Na listingu czytało się to jako jeden długi ciąg
 * i pięć wariantów tego samego kursu wyglądało na pięć niepowiązanych produktów — widać to
 * było na zrzucie po podmianie grafik, gdzie pięć kafli ML Masters stało się wizualnie
 * nierozróżnialnych.
 *
 * ⚠️ NAZWA W BAZIE ZOSTAJE NIETKNIĘTA — idzie na fakturę. Rozbicia dokonuje
 * `isa_ds_tytul_na_kaflu()` w PHP, wyłącznie przy renderowaniu listingu; `post_title`
 * nie jest ani zmieniany, ani zapisywany.
 *
 * Etykieta bierze kształt `eyebrow` z systemu — ten sam, co nagłówki kolumn stopki
 * (`#colophon .widget-title`) i tytuł banera RODO: 13 px, waga 600, wersaliki, tracking
 * dodatni. Dodatni, bo przy wersalikach litery zlewają się bez rozstrzelenia — to jedyne
 * miejsce w tym arkuszu, gdzie światło międzyliterowe jest większe od zera, i właśnie
 * dlatego nie jest błędem. */
body.isa-ds ul.products li.product .isa-kurs {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 3px;
}

/* Ścieżka niesie rozróżnienie, więc zostaje przy stopniu tytułu — zmienia się tylko to,
 * że nie musi już mieścić w sobie nazwy kursu. */
body.isa-ds ul.products li.product .isa-sciezka {
  display: block;
}

/* Najechanie podświetla całość, nie samą ścieżkę — kafel jest jednym celem kliknięcia. */
body.isa-ds ul.products li.product a:hover .isa-kurs {
  color: var(--isa-red-ink);
}

/* Cena na listingu.
 *
 * ⚠️ NIE rób z tego kontenera flex. Pierwsza wersja miała `display:flex; gap:8px`
 * i rozbiła cenę na osobne elementy flex — przez co dopisek „z VAT" odrywał się do nowej
 * linii pod kwotę (złapane na zrzucie porównawczym). Cena z sufiksem to JEDEN ciąg tekstu
 * i ma płynąć jak tekst; odstęp między kwotami daje margines, nie `gap`. */
/* Cena na listingu. Stopień ustawiony na SAMYM `.price`, nie tylko na kwocie: na .online
 * kontener miał 14,57 px odziedziczone, więc dopisek „brutto" był mniejszy od kwoty obok. */
body.isa-ds ul.products li.product .price {
  color: var(--ink);
  font-size: 15px;
  line-height: 1.4;
}
body.isa-ds ul.products li.product .price del {
  margin-right: 8px;
}

/* Plakietka „Promocja!" — odpowiednik `.pill-red` z serwisu.
 * Widoczności NIE zmieniamy: na .online jest ukryta świadomą regułą właściciela. */
body.isa-ds .onsale,
body.isa-ds span.onsale {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 12px;
  border-radius: 999px;
  background: var(--isa-red-soft);
  color: var(--isa-red-ink);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1;
}

/* --- Nagłówek archiwum --- */

/* Pastelowy gradient `linear-gradient(135deg,#8beaf6,#e8bae6,#f1dabe)` stoi na obu sklepach
 * i nie ma nic wspólnego z paletą marki — to jedyne miejsce, gdzie sklepy były zgodne,
 * i akurat zgodne w błędzie. Zastępujemy go poświatą w kolorze marki, tym samym wzorem
 * co `.hero-grad` w serwisie. */
body.isa-ds .page-hero-section,
body.isa-ds .entry-hero-container-inner,
body.isa-ds .product-hero-section {
  background: var(--bg);
  background-image: radial-gradient(
      ellipse 60% 80% at 20% 0%,
      color-mix(in srgb, var(--isa-red) 10%, transparent),
      transparent 60%
    ),
    radial-gradient(
      ellipse 50% 70% at 85% 10%,
      color-mix(in srgb, var(--isa-red) 6%, transparent),
      transparent 62%
    );
  border-bottom: 1px solid var(--line-2);
}

/* Sortowanie i licznik wyników — pasek narzędzi listingu. */
body.isa-ds .woocommerce-ordering select,
body.isa-ds .orderby {
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg);
  font-size: 14px;
  padding: 0 40px 0 16px;
}

/* --- Karta produktu --- */

body.isa-ds div.product .woocommerce-product-gallery__image img,
body.isa-ds div.product .woocommerce-product-gallery img {
  border-radius: var(--r-lg);
}

/* Blok ceny na karcie — w serwisie cena stoi w kafelku z ramką, nie luzem na tle. */
body.isa-ds div.product p.price,
body.isa-ds div.product .price {
  color: var(--ink);
  line-height: 1.2;
}

/* Warianty produktu (termin kursu) — tabela wyboru. */
body.isa-ds .variations th,
body.isa-ds .variations td {
  border: 0;
  padding: 6px 0;
}
body.isa-ds .variations label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-4);
}
body.isa-ds .reset_variations {
  font-size: 13px;
  color: var(--ink-4);
}

/* Metadane produktu (kategoria, SKU) — najniższy stopień hierarchii. */
body.isa-ds .product_meta {
  padding-top: 16px;
  border-top: 1px solid var(--line-2);
}

/* Zakładki i „Podobne produkty" — nagłówki sekcji zamiast domyślnych motywu. */
body.isa-ds .related > h2,
body.isa-ds .upsells > h2,
body.isa-ds .up-sells > h2 {
  font-size: clamp(23px, 2.4vw, 33px);
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-bottom: 24px;
}

/* Ilość sztuk — w sklepie kursowym to liczba miejsc, więc pole ma być czytelne. */
body.isa-ds .quantity input.qty {
  min-height: 48px;
  width: 80px;
  text-align: center;
  border-radius: 999px;
  border: 1px solid var(--line);
}

/* Przycisk na kaflu — węższy wyściółka niż przycisk samodzielny.
 *
 * Warstwa 20 daje przyciskom `padding: 0 22px`, co jest dobre dla przycisku stojącego
 * w treści, ale nie dla przycisku w kolumnie siatki. Na .com przy 601 px siatka schodzi
 * do dwóch wąskich kolumn i 44 px samej wyściółki zjada tyle, że „WYBIERZ OPCJĘ" przestaje
 * się mieścić. Samo `white-space: normal` z warstwy 20 już chroni przed UCIĘCIEM napisu;
 * to tutaj chroni przed łamaniem go na dwie linie w typowej szerokości kolumny. */
body.isa-ds ul.products li.product .button,
body.isa-ds ul.products li.product .add_to_cart_button {
  padding-inline: 14px;
}

/* ===== 35-etykiety.css ===== */
/* Etykiety produktów — „Promocja −28%", „Przedsprzedaż", „Ostatnie 3 miejsca", „Nowość".
 *
 * Zastępują naklejki wtapiane w grafikę produktu. Powód nie jest estetyczny: naklejka
 * na obrazku wymaga podmiany pliku, gdy promocja się kończy, a procent policzony w głowie
 * potrafi się rozjechać z ceną w koszyku. Tutaj tekst przychodzi z `isa_ds_etykiety()`
 * w PHP i liczy się z `regular_price` vs `sale_price` przy każdym wyświetleniu.
 *
 * Kształt 1:1 z komponentem `<Badge>` serwisu Astro (`src/components/ui/Badge.astro`):
 * pastylka, 12 px, waga 500, `rounded-full`, tło „soft" + tekst w mocnym odcieniu tej samej
 * rodziny. Warianty nie-markowe biora kolory z palety Tailwinda tak samo jak tam — dlatego
 * stoja tu jako wartosci, a nie tokeny: w systemie serwisu one rowniez nie sa tokenami. */

/* ⚠️ Etykiety leza NA grafice — i ta decyzja byla raz odwrocona, wiec warto wiedziec czemu.
 *
 * Pierwsza wersja kladla je na zdjeciu i wygladalo to zle: „−33%" zaslonilo wypalony na
 * grafice tytul „Pakiet Python + Power BI", a „−29%" nazwy „Webflow" i „Power BI Academy".
 * Grafiki mialy wtedy zajety KAZDY rog — tytul w lewym gornym, plakietki kategorii w lewym
 * dolnym, logo technologii w prawym gornym, naklejka „promocja" w prawym dolnym. Dlatego
 * druga wersja przeniosla etykiety pod grafike: komunikat przestawal zalezec od TRESCI pliku.
 *
 * Decyzja wlasciciela 2026-09-15 cofa to swiadomie: etykiety wracaja na grafike, bo pod nia
 * wygladaja slabo, a grafiki produktowe zostana przerobione tak, zeby zrobic im miejsce.
 * Przeslanka poprzedniej wersji („kazdy rog zajety") przestaje obowiazywac razem z tamtymi
 * plikami — nie jest wiec odwroceniem wniosku, tylko zmiana faktu, na ktorym wniosek stal.
 *
 * Co z tamtej wersji ZOSTAJE, bo bylo sluszne niezaleznie od polozenia: tresc etykiety nadal
 * liczy sie z `regular_price`/`sale_price` w PHP, a nie jest malowana w pliku. Zmiana dotyczy
 * wylacznie tego, GDZIE etykieta stoi — nie tego, skad bierze sie jej tresc.
 *
 * Czytelnosc na dowolnym zdjeciu zalatwia separacja, nie zmiana palety: kolory zostaja te
 * z `<Badge>` serwisu, a od tla odcina je cien plus wewnetrzna obwodka. Gdyby zamiast tego
 * wzmocnic same kolory, etykiety na sklepie przestalyby pasowac do tych w serwisie. */
body.isa-ds .isa-etykiety {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 4px;
}

/* Na kaflu listingu: warstwa nad grafika.
 *
 * Rodzicem jest `a.woocommerce-loop-image-link`, ktory ma juz `position: relative` i obejmuje
 * dokladnie obszar zdjecia (zmierzone: 294x167 przy kaflu 294x401) — nie trzeba wiec niczego
 * pozycjonowac dodatkowo. `right` domyka pas, zeby przy dwoch etykietach druga zawinela sie
 * do nowej linii zamiast wyjsc poza kadr.
 *
 * Etykiety zostaja WEWNATRZ linku, wiec klikniecie w nie prowadzi do produktu tak samo jak
 * klikniecie w zdjecie — nie trzeba `pointer-events: none` i nie powstaje martwe pole. */
body.isa-ds ul.products li.product .isa-etykiety {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  z-index: 2;
  margin-bottom: 0;
}

/* Separacja od zdjecia: cien pod pastylka. */
body.isa-ds ul.products li.product .isa-etykieta {
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.28);
}

/* ⚠️ NA KAFLU WSZYSTKIE PASTYLKI SA BIALE — i to jest wynik pomiaru, nie gustu.
 *
 * Etykieta lezy na zdjeciu, wiec liczy sie kontrast PASTYLKI WOBEC TLA, nie tylko tekstu
 * wobec pastylki. WCAG 1.4.11 stawia dla elementu nietekstowego prog 3:1. Tlo jest przy tym
 * nieprzewidywalne i zmienia sie z kazdym produktem, wiec wariant musi dzialac na kazdym.
 *
 * Droga do tego wniosku prowadzila przez dwa bledne warianty i oba warto znac:
 *   1. PASTEL (`--isa-red-soft` #ffe3e8) — zmierzone na zrzucie z zywej strony: „−33%"
 *      na rozowo-fioletowym gradiencie obecnej grafiki praktycznie znikalo. Pastel zaklada
 *      jednolite jasne podloze strony; zdjecie takiego nie daje.
 *   2. PELNY KOLOR MARKI (`--isa-red-dark` #cb092a) — poprawil sytuacje na dzisiejszych
 *      zdjeciach i bylby KATASTROFA na nowych. Nowe grafiki produktowe to gradienty w barwach
 *      sciezek, a `--track-ai` (#f20b32) to niemal ta sama czerwien co etykieta promocji.
 *      Policzone dla czterech gradientow, ktore realnie powstaja:
 *        czerwien #cb092a → 1,20 / 1,35 / 1,11 / 1,79 : 1   (prog 3:1 — wszystkie ZLE)
 *        biel    #ffffff → 4,84 / 4,31 / 6,48 / 3,24 : 1   (wszystkie przechodza)
 *      Czerwona pastylka na czerwonym torze AI dawalaby 1,35:1, czyli plame.
 *
 * Biel jest jedynym tlem, ktore odcina sie od KAZDEGO nasyconego gradientu, a przy tym stoi
 * blizej `<Badge>` serwisu niz wariant pelny: tam tez jest jasne tlo i mocny tekst tej samej
 * rodziny. Rozroznienie miedzy etykietami niesie wiec KOLOR TEKSTU, nie kolor tla.
 *
 * Kontrast tekstu na bieli (prog 4,5:1 dla 12 px): promocja 5,81 · nowosc 5,86 ·
 * przedsprzedaz 5,82 po przyciemnieniu · bestseller 16,83. Surowy `--track-fe` dawalby 3,24
 * i dlatego jako JEDYNY jest tu mieszany z ciemnym tokenem. */
body.isa-ds ul.products li.product .isa-etykieta {
  background: #fff;
}
body.isa-ds ul.products li.product .isa-etykieta--promocja {
  color: var(--isa-red-dark);
  font-weight: 600;
}
body.isa-ds ul.products li.product .isa-etykieta--nowosc {
  color: var(--success-ink);
}
body.isa-ds ul.products li.product .isa-etykieta--przedsprzedaz {
  /* Pomarancz sciezki frontendowej przyciemniony `--always-dark-2` do 5,82:1 na bieli.
   * Token „always-dark", nie `--ink-2`: etykieta lezy na zdjeciu, ktore nie odwraca sie
   * z motywem, wiec przyciemnienie tez nie moze. */
  color: color-mix(in srgb, var(--track-fe) 70%, var(--always-dark-2));
}
body.isa-ds ul.products li.product .isa-etykieta--bestseller {
  color: var(--ink-2);
  box-shadow:
    0 1px 4px rgba(0, 0, 0, 0.28),
    inset 0 0 0 1px var(--line);
}
/* „Ostatnie miejsca" to jedyny wyjatek od bieli: pilnosc ma byc widoczna z daleka,
 * a ta etykieta pojawia sie rzadko i nigdy obok promocji na tym samym kaflu. */
body.isa-ds ul.products li.product .isa-etykieta--ostatnie {
  background: var(--isa-red-dark);
  color: #fff;
}

body.isa-ds .isa-etykieta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1;
  white-space: nowrap;
}

/* Promocja — czerwien marki, ten sam wariant co `red`/`accent` w Badge serwisu. */
body.isa-ds .isa-etykieta--promocja {
  background: var(--isa-red-soft);
  color: var(--isa-red-ink);
}

/* Przedsprzedaz — pomaranczowy, jak wariant `orange`. Informacja o czasie, nie o cenie,
 * wiec swiadomie INNY kolor niz promocja; inaczej klient czyta ja jako rabat. */
body.isa-ds .isa-etykieta--przedsprzedaz {
  /* Pomarancz z tokenow systemu (--track-fe, sciezka frontendowa), nie z palety Tailwinda.
   * Tlo mieszane z biela, bo etykieta lezy na zdjeciu i musi miec pelne krycie. */
  background: color-mix(in srgb, var(--track-fe) 16%, #fff);
  color: color-mix(in srgb, var(--track-fe) 78%, var(--ink));
}

/* Ostatnie miejsca — pilnosc. Mocniejszy kontrast niz promocja, bo to ostrzezenie. */
body.isa-ds .isa-etykieta--ostatnie {
  background: var(--isa-red-dark);
  color: #fff;
  font-weight: 600;
}

/* Nowosc — zielen, wariant `green`. */
body.isa-ds .isa-etykieta--nowosc {
  background: color-mix(in srgb, var(--success-ink) 14%, #fff);
  color: var(--success-ink);
}

/* Bestseller — najspokojniejszy z calej piatki: to nie jest wezwanie do pospiechu,
 * tylko informacja spoleczna, wiec nie konkuruje z promocja o uwage. */
body.isa-ds .isa-etykieta--bestseller {
  background: var(--bg-2);
  color: var(--ink-2);
  box-shadow: inset 0 0 0 1px var(--line);
}

/* Osoby z ustawieniem „mniej ruchu" i tak nic tu nie traca — etykiety sa statyczne. */

/* ===== 50-naglowek-stopka.css ===== */
/* Nagłówek i stopka — to one mówią klientowi „jesteś wciąż w tym samym serwisie".
 *
 * Stan zastany: nagłówek `.com` ma linki w kolorze #514d7c i ikonę koszyka #5500fc
 * (fiolet spoza marki), `.online` w #215387 (granat). Stopki są czarne na obu, ale jedna
 * pisze tekstem #e5e5e5, druga #ffffff, i mają różne kolory najechania (#ff0000 vs brak).
 *
 * System: nagłówek to szkło (`--bg` 80% + blur), link `--ink-3` → `--ink`, wysokość
 * wiersza 60 px; stopka stoi na `--always-dark` (#0a0a0a), nie na czystej czerni. */

/* Ikona domku jako maska SVG w `data:`.
 *
 * Nie emoji i nie font ikonowy: emoji renderuje się inaczej na każdym systemie, a font
 * ikonowy to kolejny zasób do pobrania. Maska bierze kolor z `background-color`, więc
 * idzie za motywem i za stanem najechania bez drugiej definicji.
 *
 * Kształt celowo pełny (`fill`), nie konturowy — przy 20 px kontur o grubości 1,5 px
 * robi się szary i gubi czytelność obok tekstu tej samej wagi. */
body.isa-ds {
  --isa-ikona-domek: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 3.2 3 10.3V21h6v-6h6v6h6V10.3z'/></svg>");
}

/* --- Nagłówek --- */

/* Naglowek ma PELNE tlo, nie szklo.
 *
 * Serwis Astro ma tu `color-mix(var(--bg) 88%, transparent)` + `backdrop-filter: blur(20px)`
 * i tam to dziala, bo jego naglowek jest zaprojektowany jako sticky nad wlasna trescia.
 * Na Kadence naglowek bywa uslicky'owany skryptem motywu — i wtedy przez polprzezroczyste
 * tlo PRZESWITUJE tresc strony. Zgloszenie wlasciciela ze zrzutem: tytul strony widoczny
 * na pasku z logo i menu. Zmierzone: `background: color(srgb 1 1 1 / 0.88)`.
 *
 * Przy okazji znika `backdrop-filter` — to jeden z najdrozszych efektow w przegladarce
 * (wymusza osobna warstwe kompozycji na kazdej klatce przewijania), a przy nieprzezroczystym
 * tle nie daje NIC. Mniej pracy GPU na telefonach. */
body.isa-ds #masthead,
body.isa-ds .site-header {
  background: var(--bg);
  border-bottom: 1px solid var(--line-2);
  box-shadow: none;
}

body.isa-ds #masthead a,
body.isa-ds .site-header .header-navigation a {
  color: var(--ink-3);
  font-size: 14px;
  letter-spacing: -0.01em;
  transition: color 0.2s;
}

body.isa-ds #masthead a:hover,
body.isa-ds .site-header .header-navigation a:hover,
body.isa-ds #masthead .current-menu-item > a {
  color: var(--ink);
}

/* Cel dotykowy pozycji menu — WCAG 2.5.8.
 *
 * ⚠️ ODSTĘPY MIĘDZY POZYCJAMI NIE ISTNIEJĄ — zmierzone: `li` stoją stykiem (0 px),
 * a cały rytm robi padding wewnątrz `<a>`. I właśnie dlatego był nierówny: zwykłe linki
 * miały 8,4 px, a „Kontakt" 16 px, bo jest stylizowany na pigułkę. Odstęp ustawiamy więc
 * `gap` na liście, a padding linków zrównujemy — inaczej każdy nowy przycisk w menu
 * znów rozjedzie rytm. */
body.isa-ds #masthead ul#primary-menu,
body.isa-ds #masthead .header-navigation > div > ul,
body.isa-ds #masthead .primary-menu-container > ul {
  display: flex;
  align-items: center;
  gap: 4px;
}

body.isa-ds #masthead .header-navigation li > a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding-inline: 12px;
}

/* --- Okruszki (breadcrumbs) ---
 *
 * Zmierzone na karcie produktu: stopień **9 px**, kolor rgb(24,44,68) — granat spoza
 * palety marki — i podkreślenie na każdym ogniwie. Dziewięć pikseli to poniżej progu
 * czytelności; okruszki mają prowadzić, a nie zmuszać do mrużenia oczu.
 *
 * Podkreślenie zdejmujemy ze stanu spoczynku i zostawiamy na najechaniu: przy czterech
 * ogniwach obok siebie ciągła linia zlewa całą ścieżkę w jeden pasek i gubi granice
 * między poziomami. Ostatnie ogniwo (bieżąca strona) nie jest linkiem, więc dostaje
 * mocniejszy kolor — to ono mówi „tu jesteś". */
body.isa-ds .kadence-breadcrumbs,
body.isa-ds .woocommerce-breadcrumb,
body.isa-ds .entry-breadcrumbs {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-4);
  letter-spacing: -0.01em;
}
body.isa-ds .kadence-breadcrumbs a,
body.isa-ds .woocommerce-breadcrumb a,
body.isa-ds .entry-breadcrumbs a {
  color: var(--ink-3);
  text-decoration: none;
  transition: color 0.2s;
}
body.isa-ds .kadence-breadcrumbs a:hover,
body.isa-ds .woocommerce-breadcrumb a:hover,
body.isa-ds .entry-breadcrumbs a:hover {
  color: var(--isa-red-ink);
  text-decoration: underline;
}
/* Separator „/" ma być cichszy od ogniw, bo nie niesie treści — tylko je rozdziela. */
body.isa-ds .kadence-breadcrumbs .kadence-bc-sep,
body.isa-ds .kadence-breadcrumbs > span > span:not(a) {
  color: var(--line);
  padding-inline: 2px;
}

/* --- Widget listy kategorii ---
 *
 * Kadence renderuje go raz jako listę, raz jako `<select>` (zależnie od ustawienia
 * widgetu). Stylujemy oba, bo na `.online` jest dziś select z wybraną kategorią i wygląda
 * jak element formularza z innego systemu — inny promień, inna wysokość, inna typografia
 * niż wszystko wokół. */
body.isa-ds .widget_product_categories select,
body.isa-ds .widget select.dropdown_product_cat {
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  font-family: inherit;
}
body.isa-ds .widget_product_categories ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
body.isa-ds .widget_product_categories ul li a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: 15px;
  transition: background 0.2s, color 0.2s;
}
body.isa-ds .widget_product_categories ul li a:hover {
  background: var(--bg-2);
  color: var(--isa-red-ink);
}
/* Licznik produktów — informacja drugorzędna, więc cichsza i nie konkuruje z nazwą. */
body.isa-ds .widget_product_categories ul li .count {
  color: var(--ink-4);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}


/* --- Powrót do serwisu: ikona domku ---
 *
 * Decyzja właściciela: „w menu nie powinno być »infoshareacademy.com« tylko »Strona
 * Główna« albo w ogóle ikona domku". Wybrana ikona, bo etykieta tekstowa miała dwa
 * problemy naraz: „infoshareacademy.com" zjadało 17 znaków pasa nagłówka, a „Strona
 * główna" myliłoby się ze stroną główną SKLEPU, w którym klient właśnie jest.
 *
 * ⚠️ TEKST ZOSTAJE W HTML, znika tylko wizualnie. Czytnik ekranu nadal przeczyta
 * „infoShare Academy", więc nikt nie traci informacji, dokąd prowadzi link — ikona domku
 * bez etykiety jest dla niewidomego użytkownika pusta. To jest cała różnica między
 * „ukryj tekst" a „usuń tekst"; `font-size: 0` na rodzicu i przywrócenie w `::before`
 * robi pierwsze, `display: none` zrobiłoby drugie.
 *
 * Domek narysowany jako maska SVG w `data:`, nie znak z fontu — emoji renderują się
 * inaczej na każdym systemie (na Windows kolorowy, na macOS inny kształt), a maska
 * bierze kolor z `background`, więc idzie za motywem i za stanem najechania.
 *
 * ⚠️ Ryzyko, które trzeba znać: konwencja webowa czyta domek jako „strona główna TEJ
 * witryny", a to link na INNĄ domenę.
 *
 * Wcześniej stało tu, że ikona jest przy prawych ikonach (szukajka, koszyk) i że to
 * sąsiedztwo rozbraja ryzyko. Właściciel 2026-09-16: „domek nie może być na 3. pozycji,
 * musi być pierwszy" — i pozycja pierwsza jest poprawna, bo konwencja, którą to ryzyko
 * przywołuje, umieszcza domek właśnie tam. Trzecie miejsce było najgorsze z możliwych:
 * ani konwencja, ani narzędzie. Ryzyko pomyłki zostaje i rozbraja je co innego —
 * `title`/tekst dla czytnika mówi „infoShare Academy", nie „strona główna", a link
 * prowadzi na domenę marki, czyli tam, gdzie klient i tak spodziewa się wrócić.
 * Gdyby mimo to myliła, alternatywą jest etykieta „Akademia" (8 znaków).
 *
 * ⚠️ SELEKTOR IDZIE PO KLASIE `isa-domek`, NIE PO ADRESIE. Wcześniej celował w
 * `a[href="https://infoshareacademy.com/"]` — i to działało dokładnie tak długo, jak długo
 * adres się nie zmieniał. W chwili, gdy właściciel zdecydował, że domek ma prowadzić na
 * stronę główną SKLEPU, selektor przestałby trafiać i ikona zniknęłaby bez śladu w logach:
 * pozycja menu wróciłaby do zwykłego tekstu. Klasa nadana pozycji menu przeżywa każdą
 * zmianę adresu i działa tak samo na obu sklepach, które mają różne domeny. */
body.isa-ds #masthead .header-navigation li.isa-domek > a {
  position: relative;
  font-size: 0;
  width: 40px;
  padding-inline: 0;
  justify-content: center;
}
body.isa-ds #masthead .header-navigation li.isa-domek > a::before {
  content: "";
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: var(--isa-ikona-domek) center / 20px 20px no-repeat;
  mask: var(--isa-ikona-domek) center / 20px 20px no-repeat;
}

/* --- CTA w nagłówku: wyróżniony jest KOSZYK ---
 *
 * ⚠️ DRUGA WERSJA TEJ SEKCJI. Pierwsza wyróżniała pełną czerwienią „Zaloguj się do kursu"
 * i było to błędne — wychwycił to właściciel: „w sklepie wyróżnionym buttonem CTA
 * powinien być koszyk/zamówienie".
 *
 * Uzasadnienie pierwszej wersji brzmiało sensownie (wracający klient VOD chce wejść
 * w kupiony kurs, nie kupować drugi raz) i mimo to prowadziło do złego wniosku, bo
 * mierzyło CZĘSTOŚĆ INTENCJI zamiast WARTOŚCI ŚCIEŻKI. Logowanie WYPROWADZA ze sklepu
 * na platformę kursową — wyróżniając je, sklep najmocniejszym akcentem wizualnym
 * pokazywał wyjście, a nie drogę do domknięcia zakupu. Koszyk robi dokładnie odwrotnie:
 * jest jedynym elementem nagłówka, który niesie STAN TRANSAKCJI i prowadzi do kasy.
 *
 * ⚠️ WYRÓŻNIENIE JEST WARUNKOWE — i to jest odpowiedź na benchmark, który częściowo
 * przeczy temu rozwiązaniu. Zmierzone na ośmiu serwisach (brave.courses, sages.pl,
 * mate.academy, learnit.com.pl, aihero.pl, jsystems.pl, udemy.com, coursera.org): koszyk
 * ma tylko jsystems i Udemy, OBA jako ikonę bez tła; logowanie nigdzie nie ma tła;
 * wyróżniony przycisk, gdy jest, to rejestracja albo „przeglądaj kursy".
 *
 * Próbka jest jednak mieszana — pięć z ośmiu to strony kursów z formularzem kontaktowym,
 * nie sklepy, więc koszyka nie mają, bo nie mają czego w nim trzymać. Zostaje Udemy
 * z milionami produktów, gdzie stały czerwony przycisk byłby hałasem.
 *
 * Stąd wariant warunkowy: PUSTY koszyk wygląda jak u nich — ikona w kolorze marki.
 * NIEPUSTY staje się pełnym przyciskiem, bo wtedy niesie stan i jest jedyną drogą do
 * domknięcia zakupu. To jest heurystyka Nielsena H1 (widoczność statusu systemu)
 * wyrażona kolorem: interfejs krzyczy dopiero wtedy, gdy ma o czym.
 *
 * Hierarchia po poprawce, od najmocniejszego:
 *   1. koszyk — pełna czerwień, jak `.btn-red` serwisu
 *   2. „Kontakt" — obrys, jak `.btn-outline` (reguła czeka; pozycji nie ma jeszcze w menu)
 *   3. „Zaloguj się do kursu" — zwykły link, bez tła i bez ramki
 * Jeden przycisk wypełniony w całym nagłówku: dwa konkurują o uwagę i żaden nie wygrywa.
 *
 * Struktura koszyka zmierzona na żywo (Kadence, nie standardowy WooCommerce):
 *   button.drawer-toggle.header-cart-button  113×31, tło białe, promień 100px
 *     └ span.header-cart-total               23×23, promień 999px  ← licznik
 * Celujemy w PRZYCISK, nie w link — w tym motywie koszyk to `<button>` otwierający
 * szufladę, nie `<a href>`. Selektor po `a[href*="koszyk"]` nie trafiał w nic. */
body.isa-ds #masthead .header-cart-button:has(.header-cart-is-empty-false),
body.isa-ds #masthead .drawer-toggle.header-cart-button:has(.header-cart-is-empty-false) {
  min-height: 48px;
  padding: 0 18px;
  border-radius: 999px;
  background: var(--isa-red-dark);
  color: #fff;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  transition:
    background 0.2s ease,
    color 0.2s ease;
}
body.isa-ds #masthead .header-cart-button:has(.header-cart-is-empty-false):hover,
body.isa-ds #masthead .drawer-toggle.header-cart-button:has(.header-cart-is-empty-false):hover {
  background: var(--isa-red-darker);
  color: #fff;
}

/* Pusty koszyk zostaje ikoną w kolorze marki — bez tła, bez pastylki.
 * Kadence sam oznacza stan klasą `header-cart-is-empty-false` na liczniku, więc nie
 * potrzeba do tego ani PHP, ani JS. */
body.isa-ds #masthead .header-cart-button:not(:has(.header-cart-is-empty-false)) {
  background: transparent;
  color: var(--isa-red-ink);
}
/* Etykieta i ikona wewnątrz przycisku dziedziczą biel — Kadence koloruje je osobno.
 *
 * ⚠️ `:not(.header-cart-total)` NIE JEST OZDOBNIKIEM. Pierwsza wersja miała tu goły
 * selektor uniwersalny i pomalowała na biało TAKŻE licznik, który leży wewnątrz przycisku
 * — a licznik ma białe tło. Zmierzone na żywo zaraz po wdrożeniu: tło rgb(255,255,255)
 * i kolor rgb(255,255,255), czyli cyfra niewidoczna. Klasyczny skutek selektora `*`:
 * trafia też w to, o czym się nie pomyślało. */
body.isa-ds #masthead .header-cart-button:has(.header-cart-is-empty-false) *:not(.header-cart-total),
body.isa-ds #masthead .drawer-toggle.header-cart-button:has(.header-cart-is-empty-false) *:not(.header-cart-total) {
  color: #fff;
}

/* Licznik: odwrócenie kontrastu. Na czerwonym przycisku biała pastylka z czerwoną cyfrą
 * czyta się lepiej niż czerwona na czerwonym — i to jest powód, dla którego poprzednia
 * reguła („tło `--isa-red-dark`") była podwójnie zła: nie trafiała w element (zmierzone
 * tło pozostawało szare rgb(245,245,247)), a gdyby trafiła, zlałaby licznik z tłem. */
body.isa-ds #masthead .header-cart-total,
body.isa-ds #masthead .kadence-cart-total {
  background: #fff;
  color: var(--isa-red-dark);
  border-radius: 999px;
  min-width: 20px;
  height: 20px;
  font-size: 11px;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}

/* „Zaloguj się do kursu" — świadomie ZWYKŁY LINK.
 * Reguła istnieje po to, żeby cofnąć poprzednie wyróżnienie, gdyby gdzieś zostało,
 * i żeby kolejna osoba widziała, że to decyzja, a nie przeoczenie. */
body.isa-ds #masthead .header-navigation li > a[href*="/login"] {
  background: transparent;
  border: 0;
  padding: 0;
  color: inherit;
}

/* „Kontakt" — obrys `.btn-outline` serwisu.
 *
 * Nagłówek serwisu (`src/components/layout/Header.astro`) trzyma DOKŁADNIE JEDEN przycisk
 * wypełniony i jeden obrysowy. Sklep powtarza ten układ z zamienionymi rolami: wypełniony
 * jest koszyk (decyzja właściciela — w sklepie to on jest następnym krokiem), obrysowy
 * zostaje Kontakt. To nie jest drugie CTA konkurujące z koszykiem, tylko druga ranga.
 *
 * ⚠️ WYMIARY IDĄ ZA KOSZYKIEM, NIE ZA SERWISEM. Zmierzone 2026-09-16 na żywo: przycisk
 * koszyka ma 48 px wysokości i 18 px padding, w serwisie przyciski mają 36 i 16. Reguła
 * stała wcześniej na 40/16 — czyli nie zgadzała się z ŻADNYM z tych dwóch wzorców i dawała
 * w jednym pasku dwie pigułki różnej wysokości. Wyrównanie do sąsiada bije wierność
 * wobec innej strony: różnicę 48 vs 40 w tym samym rzędzie widać, różnicę wobec serwisu
 * oglądanego w innej karcie — nie. Wysokości serwisu świadomie NIE kopiujemy w dół,
 * bo 36 px to gorszy cel dotykowy niż 48. */
body.isa-ds #masthead .header-navigation li > a[href*="/kontakt"] {
  min-height: 48px;
  padding: 0 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  background: transparent;
  font-size: 15px;
  font-weight: 500;
  transition:
    border-color 0.2s ease,
    color 0.2s ease;
}
body.isa-ds #masthead .header-navigation li > a[href*="/kontakt"]:hover {
  border-color: var(--isa-red-dark);
  color: var(--isa-red-ink);
}

/* Koszyk POZA nagłówkiem (np. widget w treści) — sam kolor marki, bez kształtu przycisku.
 *
 * ⚠️ Stała tu wcześniej DRUGA reguła na `.header-cart-total`, z czerwonym tłem licznika,
 * i przeczyła tej wyżej. Dwie własne reguły mówiące co innego o tym samym elemencie to
 * defekt nawet wtedy, gdy wynik przypadkiem wychodzi dobrze — wystarczy zmiana kolejności
 * warstw i wygrywa ta druga. Ten sam błąd zdarzył się dziś na nagłówkach (h1 kontra
 * .page-title), więc tym razem usuwam zamiast dokładać specyficzności.
 *
 * Wariant nagłówkowy licznika (biała pastylka na czerwonym przycisku) jest wyżej. */
body.isa-ds .header-cart-wrap a:not(.header-cart-button),
body.isa-ds .header-cart-wrap .kadence-header-cart-wrap a:not(.header-cart-button) {
  color: var(--isa-red-ink);
}

/* Rozwijane podmenu — kształt kart systemu, nie domyślny motywu. */
body.isa-ds .header-navigation ul ul.sub-menu,
body.isa-ds #masthead .sub-menu {
  border-radius: var(--r-md);
  border: 1px solid var(--line-2);
  background: var(--bg);
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.05);
  padding: 8px;
}
body.isa-ds #masthead .sub-menu a {
  border-radius: var(--r-sm);
  font-size: 14px;
}
body.isa-ds #masthead .sub-menu a:hover {
  background: var(--bg-2);
}

/* --- Stopka --- */

/* --- Blok metod płatności w stopce ---
 *
 * Styl CZEKA NA TREŚĆ, której jeszcze nie ma w DOM — i to jest świadome. Widgety stopki
 * siedzą za allowlistą roli `claude_produkty`: `GET /wp/v2/widgets` i `/wp/v2/sidebars`
 * zwracają 403 `claude_trasa_niedozwolona` na OBU sklepach (zmierzone dwoma osobnymi
 * kontami). To ta sama celowa granica, która chroni zamówienia — nie luka do obejścia.
 * Treść wkleja więc człowiek w Kadence Footer Builder; reguły poniżej sprawią, że od razu
 * będzie wyglądać jak reszta systemu, bez drugiej rundy poprawek.
 *
 * ⚠️ BANER MUSI MÓWIĆ PRAWDĘ O TYM, CZYM KLIENT ZAPŁACI. Zmierzone na żywych kasach obu
 * sklepów (realny koszyk, bez składania zamówienia):
 *   `.online` → Autopay · Raty PayU 0% · Kup teraz, zapłać za 30 dni   (trzy)
 *   `.com`    → Autopay · Raty PayU 0%                                 (dwie)
 * Istniejący baner na `.com` jest przy tym NIEPEŁNY: pokazuje samą grafikę Autopay
 * z logotypami banków i pomija PayU, mimo że raty są tam aktywne. Skopiowanie go na
 * `.online` jeden do jednego powieliłoby ten błąd i dołożyło drugi — `.online` ma o jedną
 * metodę więcej. To informacja handlowa, nie ozdoba.
 *
 * Wysokość logotypów wyrównana do 28 px niezależnie od proporcji pliku: znaki operatorów
 * mają różne kadry (Autopay to szeroki pas z bankami, PayU kwadratowy znak), więc równanie
 * po szerokości dałoby jeden wielki i jeden mikroskopijny. */
body.isa-ds .isa-stopka-platnosci {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}

body.isa-ds .isa-stopka-platnosci__metoda {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Jasna płytka pod logotypem — ten sam powód co przy piktogramach na kaflach: pliki
 * operatorów mają ciemne elementy, a stopka stoi na `--always-dark`. Bez podkładu
 * znaki banków znikają. */
body.isa-ds .isa-stopka-platnosci__logo {
  height: 28px;
  width: auto;
  max-width: 100%;
  padding: 4px 8px;
  border-radius: var(--r-sm);
  background: #fff;
}

body.isa-ds .isa-stopka-platnosci__etykieta {
  font-size: 12px;
  line-height: 1.35;
  color: var(--always-dark-ink-muted);
}

/* Poniżej 480 px metody schodzą pod siebie — dwa logotypy obok siebie z etykietą
 * „Raty PayU 0% · Kup teraz, zapłać za 30 dni" nie mieszczą się w jednym wierszu. */
@media screen and (max-width: 480px) {
  body.isa-ds .isa-stopka-platnosci {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
}


/* `--always-dark` zamiast czystej czerni: to ten sam kafel, co ciemne sekcje serwisu,
 * i jako jedyny token NIE odwraca się z motywem — stopka ma zostać ciemna zawsze. */
body.isa-ds #colophon,
body.isa-ds .site-footer {
  background: var(--always-dark);
  color: var(--always-dark-ink);
  border-top: 0;
}

body.isa-ds #colophon,
body.isa-ds #colophon p,
body.isa-ds #colophon li {
  font-size: 14px;
  letter-spacing: -0.01em;
  line-height: 1.6;
}

body.isa-ds #colophon a {
  color: var(--always-dark-ink-muted);
  transition: color 0.2s;
}
body.isa-ds #colophon a:hover {
  /* Czerwień na ciemnym tle musi być jaśniejsza niż na białym — to ten sam powód,
   * dla którego serwis trzyma osobny token `--always-dark-red`. */
  color: var(--always-dark-red);
}

/* Nagłówki kolumn stopki — odpowiednik `.eyebrow` z serwisu. */
body.isa-ds #colophon .widget-title,
body.isa-ds #colophon h2,
body.isa-ds #colophon h3 {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--always-dark-ink);
}

/* Pasek dolny — najniższy stopień hierarchii, oddzielony włosową linią. */
body.isa-ds #colophon .site-bottom-footer-wrap,
body.isa-ds .footer-bottom {
  border-top: 1px solid var(--always-dark-line);
  color: var(--always-dark-ink-muted);
  font-size: 13px;
}

/* Cele dotykowe w stopce — ta sama reguła co `.stopka-link` w serwisie. */
body.isa-ds #colophon a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding-block: 2px;
}

/* --- Wysepki na jasnym tle WEWNĄTRZ ciemnej stopki ---
 *
 * ⚠️ REGRESJA WNIESIONA PRZEZ TEN ARKUSZ. Reguły wyżej zakładają, że cała stopka stoi na
 * `--always-dark`, i malują tekst jasnym `--always-dark-ink`. Założenie jest fałszywe:
 * baner o połączeniu spółek na `.online` niesie WŁASNE jasne tło (#f7f8fa) wpisane w treść
 * widgetu, więc dostał jasny tekst na jasnym tle.
 *
 * Zmierzone 2026-09-16 na produkcji, cztery szerokości (375/601/900/1440), ten sam wynik
 * na każdej — CZTERY elementy poniżej progu WCAG 1.4.3, nie jeden:
 *   · nagłówek „Informacja o zmianie Administratora Danych" — 1,02:1 (próg 4,5)
 *   · link „infoshareacademy.com"        — 2,70:1
 *   · link „Polityce Prywatności"        — 2,70:1
 *   · link „online@infoshareacademy.com" — 2,70:1
 * Nagłówek przy 1,02:1 jest fizycznie nieczytelny, a wśród linków jest adres kontaktowy
 * sklepu — czyli zepsuta była droga kontaktu, nie ozdobnik.
 *
 * Naprawa idzie DWIEMA drogami, bo jedna by nie wystarczyła:
 *   1. `.isa-rodo-banner` — klasa, która istnieje dziś w treści banera. Działa natychmiast.
 *   2. `.has-background` i `[style*="background"]` — każdy PRZYSZŁY blok Gutenberga z własnym
 *      tłem. Bez tego następny taki widget powtórzy defekt, a nikt go nie zauważy, bo
 *      defekt jest niewidoczny dosłownie: biały tekst na białym tle nie rzuca się w oczy,
 *      on znika.
 * Sam `.isa-rodo-banner` byłby łatą na jeden przypadek; sam selektor ogólny nie trafiłby
 * w baner, bo ten trzyma tło w arkuszu treści, nie w atrybucie `style`.
 *
 * ⚠️ Reguła zakłada, że wysepka jest JASNA. Wysepka ciemniejsza od stopki dostałaby tu
 * ciemny tekst i zepsułaby się tak samo, tylko w drugą stronę. CSS nie umie zapytać
 * o jasność tła, więc tego przypadku nie da się objąć regułą — objęłaby go dopiero
 * asercja kontrastu w bramce (`check-sklep-live.mjs` mierzy dziś nagłówek, nie stopkę). */
body.isa-ds #colophon .isa-rodo-banner,
body.isa-ds #colophon .has-background,
body.isa-ds #colophon [style*="background-color"] {
  color: var(--ink-2);
}
body.isa-ds #colophon .isa-rodo-banner :is(h1, h2, h3, h4, strong, b),
body.isa-ds #colophon .has-background :is(h1, h2, h3, h4, strong, b),
body.isa-ds #colophon [style*="background-color"] :is(h1, h2, h3, h4, strong, b) {
  color: var(--ink);
}
body.isa-ds #colophon .isa-rodo-banner a,
body.isa-ds #colophon .has-background a,
body.isa-ds #colophon [style*="background-color"] a {
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 2px;
}
body.isa-ds #colophon .isa-rodo-banner a:hover,
body.isa-ds #colophon .has-background a:hover,
body.isa-ds #colophon [style*="background-color"] a:hover {
  color: var(--isa-red-ink);
}

/* Pasek dolny na wąskim ekranie — copyright i ikony pod sobą, nie obok.
 *
 * Zmierzone 2026-09-16 przy 375 px: sekcja paska dolnego to `flex` w rzędzie, w którym
 * copyright dostaje 279 px, a blok ikon społecznościowych zabiera z tego 88 px po prawej.
 * Efekt: nazwa spółki łamie się na pięć linii obok dwóch ikonek, a cały pasek rośnie do
 * 156 px wysokości. Kadence nie zwija tego wiersza samo — wiersze stopki ma rozstawiane
 * ustawieniem motywu, które działa dopiero od jego własnego progu.
 *
 * Próg 600 px, nie 768: przy 601 px ten sam wiersz mieści się bez łamania (zmierzone —
 * copyright dostaje 505 px i jedną linię), więc zwijanie tabletu byłoby psuciem tego,
 * co działa. 601 px to jedna z szerokości, na których ten projekt szuka błędów właśnie
 * dlatego, że nie widać ich ani na telefonie, ani na desktopie. */
@media screen and (max-width: 600px) {
  body.isa-ds #colophon .site-bottom-footer-inner-wrap,
  body.isa-ds #colophon .site-footer-bottom-section-1 {
    flex-direction: column;
    align-items: center;
    gap: 12px;
    text-align: center;
  }
  /* Blok ikon przestaje być kolumną obok tekstu i staje się własnym rzędem. */
  body.isa-ds #colophon .site-bottom-footer-inner-wrap .footer-widget-area {
    width: auto;
  }
}

/* ===== 60-ozdobniki-efekty.css ===== */
/* Ozdobniki i efekty — warstwa, która sprawia, że sklep czyta się jako ta sama strona,
 * a nie jako osobny system w podobnych kolorach.
 *
 * REGUŁA UŻYCIA (skill ui-design-expert, zasada #7, z handoffu):
 *   · co trzecia sekcja, nigdy dwie ozdobione z rzędu — siatka wszędzie kasuje efekt,
 *     dla którego się ją wstawia;
 *   · NIGDY przy polach formularza, tabelach i podsumowaniach;
 *   · przy formularzu ozdoba może stać wyłącznie w kolumnie obok, nigdy w boksie.
 *
 * W sklepie znaczy to dokładnie tyle: faktura pod nagłówkiem archiwum i separator nad
 * sekcją „Podobne produkty". Koszyk, kasa i konto zostają czyste — pilnuje tego reguła R6
 * strażnika, nie dobre chęci. */

/* --- Faktura sekcji: siatka punktów --- */

/* Odpowiednik `.siatka-punktow` z serwisu, 1:1 na tokenach (dlatego flipuje z motywem
 * i nie wnosi ani jednej nowej wartości do palety). */
body.isa-ds .siatka-punktow,
body.isa-ds .page-hero-section {
  position: relative;
}

body.isa-ds .page-hero-section::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px, var(--siatka-kolor) 1.1px, transparent 0);
  background-size: var(--siatka-skok) var(--siatka-skok);
  /* Maska wygasza deseń po obu stronach, żeby żył w pasie, a nie biegł pod tytuł.
   * W serwisie brak tej maski dał deseń NA karcie z ceną (W-183). */
  /* `rgba(0,0,0,1)` nie jest tu KOLOREM, tylko pełnym kryciem maski — czerń i biel w masce
   * znaczą „widoczne"/„ukryte", nie odcień. Zapis w tej formie, bo `#000` słusznie zapala
   * regułę R2 strażnika (surowa wartość), a forma rgba z zerami jest na jego liście
   * wyjątków razem z cieniami. */
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    rgba(0, 0, 0, 1) 22%,
    rgba(0, 0, 0, 1) 78%,
    transparent
  );
  mask-image: linear-gradient(
    90deg,
    transparent,
    rgba(0, 0, 0, 1) 22%,
    rgba(0, 0, 0, 1) 78%,
    transparent
  );
  opacity: 0.55;
  z-index: 0;
}

/* Treść nagłówka ZAWSZE nad deseniem. */
body.isa-ds .page-hero-section > * {
  position: relative;
  z-index: 1;
}

/* --- Separator sekcji --- */

/* Odpowiednik `.separator-sekcji`: włosowa linia z 40 px akcentu na początku.
 * Stawiamy go nad „Podobne produkty" — jedynym miejscem karty produktu, gdzie zaczyna
 * się nowa sekcja i czytelnik potrzebuje sygnału, że temat się zmienia. */
/* Sekcja „Podobne produkty" to wyodrebniony blok na szarym tle.
 *
 * Dwa powody naraz. Po pierwsze przywraca uklad „biale kafle na szarym", ktory na listingu
 * dziala, a tutaj byl zlamany — tresc karty produktu siedzi na bialej plycie motywu.
 * Po drugie oddziela ofertę dodatkowa od tresci kupowanego produktu, zamiast zlewac je
 * w jedna plachte. */
body.isa-ds .related,
body.isa-ds .upsells,
body.isa-ds .up-sells {
  position: relative;
  margin-top: 56px;
  padding: 40px 28px 32px;
  border-top: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background: var(--bg-2);
}

body.isa-ds .related::before,
body.isa-ds .upsells::before,
body.isa-ds .up-sells::before {
  content: "";
  position: absolute;
  left: 28px;
  top: -1px;
  width: 40px;
  height: 2px;
  background: var(--isa-red);
}

/* --- Efekty --- */

/* Przejścia tej samej krzywej co w serwisie (`--ease`) — to ona daje wrażenie jednego
 * systemu bardziej niż same kolory. */
body.isa-ds a,
body.isa-ds .button,
body.isa-ds ul.products li.product,
body.isa-ds img {
  transition-timing-function: var(--ease);
}

/* Galeria produktu: powiększenie 1,04 przy najechaniu — ten sam gest co `.card-tile`. */
body.isa-ds div.product .woocommerce-product-gallery__image {
  overflow: hidden;
  border-radius: var(--r-lg);
}
body.isa-ds div.product .woocommerce-product-gallery__image img {
  transition: transform 0.5s var(--ease);
}
body.isa-ds div.product .woocommerce-product-gallery__image:hover img {
  transform: scale(1.04);
}

/* Poświata marki pod kartą produktu — odpowiednik `.glow-red`, wyciszony, bo na stronie
 * transakcyjnej ma być tłem, nie bohaterem. */
body.isa-ds.single-product .site-container > .content-container {
  position: relative;
}
body.isa-ds.single-product .site-container > .content-container::before {
  content: "";
  position: absolute;
  top: -60px;
  right: -40px;
  width: 420px;
  height: 420px;
  max-width: 60vw;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at center,
    color-mix(in srgb, var(--isa-red) 12%, transparent),
    transparent 70%
  );
  filter: blur(40px);
}
body.isa-ds.single-product .site-container > .content-container > * {
  position: relative;
  z-index: 1;
}

/* Osoby, które proszą system o mniej ruchu, dostają mniej ruchu. */
@media (prefers-reduced-motion: reduce) {
  body.isa-ds *,
  body.isa-ds *::before,
  body.isa-ds *::after {
    transition-duration: 0.01ms;
    animation-duration: 0.01ms;
  }
  body.isa-ds ul.products li.product:hover {
    transform: none;
  }
  body.isa-ds ul.products li.product:hover img,
  body.isa-ds div.product .woocommerce-product-gallery__image:hover img {
    transform: none;
  }
}

/* ===== 40-koszyk-checkout.css ===== */
/* Koszyk, kasa i konto — jedyne miejsce, gdzie błąd kosztuje pieniądze.
 *
 * DLATEGO TA WARSTWA JEST INNA OD POZOSTAŁYCH:
 *   · wolno w niej wyłącznie WYGLĄD — kolor, tło, obramowanie, promień, krój, cień,
 *     wysokość kontrolki, odstępy;
 *   · zakazane jest wszystko, co przestawia UKŁAD — `display`, `position`, `float`,
 *     `grid-template-*`, `flex-direction`, `order`, `visibility`, `overflow`;
 *   · zakazane są ozdobniki (siatka, poświata, gradient).
 * Pilnuje tego reguła R6 w `scripts/check-sklep-css.mjs`, nie dobre chęci.
 *
 * Powód nie jest estetyczny: objaw błędu układu w kasie bywa widoczny dopiero przy jednym
 * sposobie płatności albo przy jednej zawartości koszyka — czyli w warunkach, których
 * bramka nie odtworzy, a klient owszem.
 *
 * Stan zmierzony 2026-09-15 na koszyku Z ZAWARTOŚCIĄ (wcześniejsze pomiary szły na pustym,
 * więc nie mierzyły niczego): oba sklepy mają klasyczny koszyk Woo, identyczną tabelę
 * i ten sam zestaw elementów. Różni się przycisk „Przejdź do płatności" — 45 px na .com,
 * 50 px na .online — i promień 100 px zamiast pastylki. */

/* --- Blok informacyjny o fakturze i KSeF (na kasie, NAD „Dane rozliczeniowe") ---
 *
 * Treść generuje WordPress wprost w treści strony „Zamówienie" (post-8, PRZED shortcode'em
 * `[woocommerce_checkout]`) — poza zasięgiem tej warstwy leży PHP/markup, w zasięgu jest
 * wyłącznie wygląd. Zgłoszenie właściciela 2026-09-15: blok przejmuje pierwszy ekran kasy
 * i krzyczy głośniej niż przycisk zakupu. Zmierzone na żywo (koszyk z zawartością, nie
 * pusty — wcześniejsze pomiary sklepów szły na pustym i nic z tego nie widziały):
 *
 *   szerokość | blok (przed→po) | „Dane rozliczeniowe" (przed→po) | „Twoje zamówienie" (przed→po)
 *   375 px    | 696 → 589 px    | 1054 → 931 px (nadal poniżej zgięcia — to długość treści)
 *   414 px    | 599 → 517 px    | 957 → 859 px (już w pierwszym ekranie)
 *   768 px    | 377 → 304 px    | 736 → 647 px                    | 1562 → 1473 px
 *   1024 px   | 353 → 280 px    | 718 → 630 px                    | 1546 → 1457 px
 *   1440 px   | 353 → 280 px    | 695 → 606 px                    | 648 → 560 px (z zapasem, nie na styk)
 *
 * Zero przycięć (`scrollWidth === clientWidth`) na żadnej szerokości, przed i po.
 *
 * Największy pojedynczy winowajca: trzeci akapit niesie klasy RDZENIA WordPressa
 * `has-theme-palette-1-background-color has-theme-palette-9-color` — pełne tło w kolorze
 * `--global-palette1` (w tym systemie zmapowanym na czerwień marki) z białym tekstem, czyli
 * dokładnie ten sam rejestr wizualny co przycisk „Kupuję i płacę". W kasie czerwień ma
 * znaczyć WYŁĄCZNIE akcję/błąd — tu oznaczała neutralną informację podatkową i przejmowała
 * uwagę na wejściu. Treść zostaje w całości; zmienia się wyłącznie oprawa, na ten sam
 * spokojny „kafel informacyjny" co klauzula RODO niżej w tym pliku — żeby oba komunikaty
 * czytały się jako jedna rodzina „informacja", nie „alarm".
 *
 * ⚠️ `background`/`color` nie da się nadpisać wprost: WordPress ustawia je przez
 * `!important` w inline `<style>` generowanym per-strona (`.has-theme-palette-1-background-
 * color{background-color:var(--wp--preset--color--theme-palette-1) !important}`, analogicznie
 * kolor). Zamiast wchodzić w budżet `!important` (R7, poza zakresem tego briefu), nadpisujemy
 * NIŻEJ LEŻĄCĄ zmienną, którą ten `!important` konsumuje — `!important` nie chroni WARTOŚCI
 * zmiennej, tylko deklarację, która z niej korzysta. Zmienna jest zdefiniowana na `:root` bez
 * `!important`, więc zwykła reguła na TYM SAMYM elemencie (nie na `:root`) wygrywa przez zwykłe
 * dziedziczenie — element zawsze bije wartość odziedziczoną po przodku, niezależnie od tego,
 * jak przodek ją ustawił. Redefinicja jest scelowana na SAM ten akapit (dwie klasy razem, nie
 * osobno), więc nie rusza żadnego innego miejsca na stronie, które mogłoby czytać tę samą
 * zmienną globalną. Zero `!important` po naszej stronie, zero surowych kolorów (R2, R7 czyste). */
body.isa-ds.woocommerce-checkout .entry-content .has-theme-palette-9-color.has-theme-palette-1-background-color {
  --wp--preset--color--theme-palette-1: var(--bg-2);
  --wp--preset--color--theme-palette-9: var(--ink-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  padding: 16px 20px;
  font-size: 15px;
  line-height: 1.55;
  margin-bottom: 16px;
}

/* Odstęp między akapitami bloku — motyw dawał 32 px po KAŻDYM z trzech akapitów (domyślny
 * odstęp WP core dla bloku akapitu), co samo z siebie dokładało ~65 px ponad samą treść.
 * 16 px starcza do rozdzielenia akapitów bez rozpychania strony. `margin` nie jest
 * właściwością układu (R6) — nie przestawia niczego, tylko zagęszcza istniejący przepływ
 * blokowy; działa identycznie przy każdej zawartości koszyka i każdej metodzie płatności. */
body.isa-ds.woocommerce-checkout .entry-content #pozakupie {
  margin-bottom: 16px;
}

/* --- Tabela pozycji --- */

body.isa-ds.woocommerce-cart .shop_table,
body.isa-ds.woocommerce-checkout .shop_table {
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  border-collapse: separate;
  border-spacing: 0;
  background: var(--bg);
}

body.isa-ds.woocommerce-cart .shop_table th,
body.isa-ds.woocommerce-checkout .shop_table th {
  border-bottom: 1px solid var(--line-2);
  color: var(--ink-4);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

body.isa-ds.woocommerce-cart .shop_table td,
body.isa-ds.woocommerce-checkout .shop_table td {
  border-top: 1px solid var(--line-2);
  color: var(--ink-2);
  font-size: 15px;
}

body.isa-ds.woocommerce-cart .cart_item .product-name a {
  color: var(--ink);
  font-weight: 500;
}
body.isa-ds.woocommerce-cart .cart_item .product-name a:hover {
  color: var(--isa-red-ink);
}

body.isa-ds.woocommerce-cart .shop_table img {
  border-radius: var(--r-sm);
}

/* Krzyżyk „usuń pozycję" — cel dotykowy 24 px i kolor ostrzegawczy dopiero przy najechaniu,
 * żeby czerwień nie krzyczała z tabeli przy każdym wejściu do koszyka. */
body.isa-ds.woocommerce-cart .product-remove a.remove {
  width: 24px;
  height: 24px;
  line-height: 24px;
  border-radius: 999px;
  color: var(--ink-4);
  font-size: 18px;
}
body.isa-ds.woocommerce-cart .product-remove a.remove:hover {
  background: var(--isa-red-soft);
  color: var(--error-ink);
}

/* --- Podsumowanie --- */

body.isa-ds .cart_totals {
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background: var(--bg-2);
  padding: 24px;
}

/* Nagłówek podsumowania NIE dostaje skali sekcyjnej.
 *
 * Kolumna podsumowania jest wąska (ok. 300 px), wiec `clamp(20px, 2vw, 26px)` łamał
 * „Podsumowanie koszyka" na dwie linie, a kwotę łączną razem z dopiskiem o VAT na trzy.
 * Złapane na zrzucie porównawczym koszyka 2026-09-15. Skala systemu obowiązuje tam,
 * gdzie jest miejsce; w wąskiej kolumnie wygrywa czytelność liczby. */
body.isa-ds .cart_totals h2 {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-bottom: 16px;
}

body.isa-ds .cart_totals .shop_table {
  border: 0;
  background: transparent;
}
body.isa-ds .cart_totals .shop_table th,
body.isa-ds .cart_totals .shop_table td {
  border: 0;
  border-bottom: 1px solid var(--line-2);
  padding-block: 12px;
}

/* Kwota do zapłaty — jedyna liczba na tej stronie, która ma się rzucać w oczy. */
body.isa-ds .cart_totals .order-total th,
body.isa-ds .cart_totals .order-total td {
  border-bottom: 0;
  color: var(--ink);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
}

/* Dopisek o VAT to informacja podatkowa, nie część kwoty — ma nie konkurować z liczbą
 * i nie rozpychać wiersza.
 *
 * ⚠️ Pierwsza wersja miała tu `display:block`, żeby dopisek szedł do osobnej linii.
 * Reguła R6 strażnika słusznie to odrzuciła i zostało usunięte, nie złagodzone: w kasie
 * nie przestawiamy układu, bo objaw takiej zmiany potrafi wyjść dopiero przy innej
 * zawartości koszyka albo innej metodzie płatności. Sam mniejszy stopień pisma załatwia
 * rozpychanie wiersza bez dotykania przepływu. */
body.isa-ds .cart_totals .order-total small,
body.isa-ds .cart_totals .includes_tax,
body.isa-ds .cart_totals .tax_label {
  color: var(--ink-4);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
}

/* Odnośnik o ratach — drobny, bo to opcja, nie główna ścieżka.
 *
 * ⚠️ `:not(.button)` NIE jest ozdobnikiem. Pierwsza wersja brzmiała
 * `.cart_totals a { font-size: 14px }` i złapała także „Przejdź do płatności" — bo główny
 * przycisk kasy to w WooCommerce `<a class="checkout-button">`, stojący wewnątrz
 * `.cart_totals`. Skutek: najważniejszy przycisk sklepu zmalał do 14 px, dokładnie wtedy,
 * gdy właściciel prosił o WIĘKSZE teksty na przyciskach. Złapane przez cel „tekst przycisku
 * co najmniej 16 px" — reguła na `a` w kontenerze zawsze łapie też przyciski-linki. */
body.isa-ds .cart_totals a:not(.button):not(.checkout-button) {
  font-size: 14px;
}

/* --- Kupon --- */

body.isa-ds.woocommerce-cart .coupon input#coupon_code {
  min-height: 48px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg);
  font-size: 15px;
  padding: 0 18px;
}

/* Przycisk „Wykorzystaj rabat" na wąskich ekranach — pozwolenie na zawinięcie tekstu.
 *
 * ⚠️ Zmierzone na żywo 2026-09-15 na 375 px: przycisk miał `clientWidth` 149 px przy
 * `scrollWidth` 162 px i `white-space: nowrap` z motywu, więc napis kończył się na
 * „Wykorzystaj rabo" — ucięty w połowie słowa. Prostokąt przycisku mieścił się w rodzicu
 * (`getBoundingClientRect` dawał przeciek 0), a strona nie miała poziomego scrolla — dlatego
 * ani R5, ani żaden pomiar prostokątów tego nie widział. Kryterium przycięcia treści to
 * `scrollWidth > clientWidth`, nie geometria prostokątów.
 *
 * Zawijanie zamiast zmniejszania pisma: 16 px na przycisku to próg ustalony z właścicielem,
 * a 48 px wysokości to jednocześnie próg celu dotykowego — obu nie ruszamy. To jest
 * pozwolenie na łamanie linii, nie przestawienie układu; `min-height` zamiast `height`
 * zostawia miejsce na drugą linię bez zmiany przepływu. */
@media screen and (max-width: 520px) {
  body.isa-ds.isa-ds.woocommerce-cart .coupon .button {
    white-space: normal;
    height: auto;
    min-height: 48px;
    line-height: 1.25;
    padding-block: 10px;
    padding-inline: 12px;
  }
}

/* --- Kasa --- */

body.isa-ds.woocommerce-checkout .woocommerce-billing-fields h3,
body.isa-ds.woocommerce-checkout #order_review_heading {
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 700;
  letter-spacing: -0.02em;
}

body.isa-ds.woocommerce-checkout #payment,
body.isa-ds.woocommerce-checkout .woocommerce-checkout-payment {
  border-radius: var(--r-lg);
  border: 1px solid var(--line-2);
  background: var(--bg-2);
}

body.isa-ds.woocommerce-checkout #payment ul.payment_methods {
  border-bottom: 1px solid var(--line-2);
}
body.isa-ds.woocommerce-checkout #payment ul.payment_methods li {
  color: var(--ink-2);
  font-size: 15px;
}
body.isa-ds.woocommerce-checkout #payment .payment_box {
  border-radius: var(--r-md);
  background: var(--bg);
  color: var(--ink-3);
  font-size: 14px;
}

/* Zgody i klauzule — ten sam kształt co `.klauzula-rodo` w serwisie.
 *
 * ⚠️ `text-align: left` DOPISANY 2026-09-15, nie ozdobnik. Zgłoszenie właściciela: klauzula
 * na kasie wychodzi justowana, z „rzekami" białych dziur między słowami w wąskiej kolumnie —
 * dokładnie to, przed czym ostrzega komentarz w warstwie 45 (snippet Simple Custom CSS and
 * JS na .online niesie `div.woocommerce-privacy-policy-text{text-align:justify}` w inline
 * `<style>`, specyficzność (0,1,1), bez `!important`). Ta reguła nigdy wcześniej nie CLAIMowała
 * właściwości `text-align`, więc przeglądarka o nią pytała WYŁĄCZNIE snippet — brak własnego
 * twierdzenia nie jest zaprzeczeniem cudzego (ta sama lekcja co `.includes_tax` w warstwie 45).
 * Specyficzność TEJ reguły (0,2,1: `body`+`.isa-ds`+`.woocommerce-privacy-policy-text`) już
 * bije snippet (0,1,1) bez potrzeby podwajania klasy — zmierzone żywym wstrzyknięciem
 * `<style>` 2026-09-15: `getComputedStyle(...).textAlign` przeszło z `justify` na `left`. */
body.isa-ds .woocommerce-privacy-policy-text,
body.isa-ds .woocommerce-terms-and-conditions-wrapper {
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--bg-2);
  padding: 14px 16px;
  color: var(--ink-3);
  font-size: 13px;
  line-height: 1.65;
  text-align: left;
}

/* Główny przycisk zapłaty — najważniejszy element w całym serwisie, więc dostaje
 * pełną wysokość systemu, a nie 45 px z jednego sklepu i 50 px z drugiego. */
body.isa-ds.woocommerce-cart .checkout-button,
body.isa-ds.woocommerce-checkout #place_order,
body.isa-ds.woocommerce-checkout button#place_order {
  min-height: 48px;
  border-radius: 999px;
  background: var(--isa-red-dark);
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
body.isa-ds.woocommerce-cart .checkout-button:hover,
body.isa-ds.woocommerce-checkout #place_order:hover {
  background: var(--isa-red-darker);
  color: #fff;
}

/* --- Moje konto --- */

body.isa-ds.woocommerce-account .woocommerce-MyAccount-navigation ul {
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background: var(--bg-2);
  padding: 8px;
}
body.isa-ds.woocommerce-account .woocommerce-MyAccount-navigation li a {
  border-radius: var(--r-sm);
  color: var(--ink-3);
  font-size: 15px;
  padding: 10px 14px;
}
body.isa-ds.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a {
  background: var(--bg);
  color: var(--ink);
  font-weight: 500;
}

/* --- Podbicie nad snippetami Simple Custom CSS and JS (zmierzone na .online) ---
 *
 * Sklep .online ma 14 snippetow CSS wstrzykiwanych INLINE, wiec ladowanych PO naszym
 * arkuszu — przy rownej specyficznosci wygrywaja one. Zmierzone na zywym koszyku:
 *   · `Zaktualizuj koszyk` miał tlo rgb(66,66,69) zamiast przezroczystego (snippet
 *     „Zmiana koloru przycisku gdy nie jest w stanie hover"),
 *   · `.coupon .button` mial rgb(168,7,31) zamiast czerwieni marki rgb(203,9,42).
 *
 * Podbijamy powtorzeniem klasy zasiegu (0,3,x) zamiast `!important` — snippety uzywaja
 * zwyklej specyficznosci, wiec to wystarcza i nie zabiera nikomu mozliwosci nadpisania.
 * Gdy snippety zostana wylaczone, te reguly nadal sa poprawne (nie zaleza od ich istnienia). */

body.isa-ds.isa-ds.woocommerce-cart table.cart td.actions .button[name="update_cart"],
body.isa-ds.isa-ds button[name="update_cart"] {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink);
}
body.isa-ds.isa-ds.woocommerce-cart table.cart td.actions .button[name="update_cart"]:hover,
body.isa-ds.isa-ds button[name="update_cart"]:hover {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}
body.isa-ds.isa-ds.woocommerce-cart table.cart .coupon .button,
body.isa-ds.isa-ds .coupon .button {
  background: var(--isa-red-dark);
  color: #fff;
}
body.isa-ds.isa-ds.woocommerce-cart table.cart .coupon .button:hover,
body.isa-ds.isa-ds .coupon .button:hover {
  background: var(--isa-red-darker);
  color: #fff;
}

/* ===== 45-przejete-ze-snippetow.css ===== */
/* Funkcje przejęte ze snippetów Simple Custom CSS and JS (.online).
 *
 * PO CO TA WARSTWA ISTNIEJE: na `.online` żyje 14 snippetów CSS wstrzykiwanych inline.
 * Sześć z nich koliduje z design systemem (ustawiają wysokość przycisków na 38 px, malują
 * komunikat Omnibus na czerwono, przestawiają kolory przycisków koszyka). Żeby dało się je
 * wyłączyć BEZ utraty tego, co niosły sensownego, ich FUNKCJE mieszkają tutaj.
 *
 * Reguły poniżej są bezpieczne w obu stanach: gdy snippety jeszcze działają, robią to samo
 * (żadnej szkody z duplikacji), a gdy zostaną wyłączone — przejmują. Dzięki temu wyłączanie
 * nie musi być skoordynowane co do minuty.
 *
 * ⚠️ POWYŻSZE NIE OBOWIĄZUJE DLA REGUŁ, KTÓRE CZEGOŚ NIE PRZEJMUJĄ, TYLKO COŚ COFAJĄ.
 * Zdanie „gdy snippety jeszcze działają, robią to samo" jest prawdziwe wyłącznie dla reguł
 * duplikujących zachowanie snippetu. Reguła, która ma cudzą deklarację ODWRÓCIĆ (jak
 * `white-space: normal` na `.includes_tax` niżej), z duplikacji nie korzysta w ogóle:
 * musi wygrać kaskadę, bo snippety wstrzykują się PO naszym arkuszu.
 *
 * Dlatego takie reguły noszą podwojony `body.isa-ds.isa-ds` i to NIE jest ozdobnik
 * specyficzności do wyczyszczenia przy porządkach. Zmierzone 2026-09-15: usunięcie
 * `white-space: nowrap` z tej warstwy nie zmieniło na żywo NICZEGO, bo pominięcie deklaracji
 * u siebie nie jest nadpisaniem cudzej — dopiero jawne `normal` z wyższą specyficznością
 * zadziałało. Ta sama konstrukcja co asercja negatywna: brak własnego twierdzenia nie jest
 * zaprzeczeniem cudzego.
 *
 * Po wyłączeniu snippetów takie reguły stają się bezczynne, nie szkodliwe — zostają.
 *
 * ⚠️ Czego świadomie NIE przejmujemy i dlaczego:
 *   · `text-align: justify` na klauzuli RODO — justowanie wąskiej kolumny robi „rzeki" białych
 *     dziur między słowami i psuje czytelność tekstu prawnego, który i tak jest trudny.
 *   · `color: red` na `summary` i na Omnibusie — czerwień to w tym systemie sygnał akcji
 *     (przyciski) albo błędu, nie koloru tekstu informacyjnego.
 *   · `height: 38px` na przyciskach koszyka — system ma 48 px i to jest jednocześnie próg
 *     celu dotykowego.
 *   · dwa snippety JS (ukrycie widgetu PageSpeed Ninja, podmiana nagłówka koszyka na
 *     „Produkty w koszyku") — to zachowanie, nie wygląd; zostają w snippetach. */

/* --- Suma częściowa na kasie: ukryta (decyzja sprzed tego wdrożenia, zachowana) ---
 *
 * Przy jednej pozycji w koszyku „Kwota" i „Łącznie" pokazują to samo, więc wiersz sumy
 * częściowej tylko powtarza liczbę. To była świadoma decyzja właściciela — przenosimy ją
 * z snippetu, nie zmieniamy. */
body.isa-ds.woocommerce-checkout table.shop_table tr.cart-subtotal {
  display: none;
}

/* --- Blok „po zakupie" na stronie podziękowania --- */
body.isa-ds.woocommerce-order-received #pozakupie {
  display: none;
}

/* --- Dopisek o VAT w podsumowaniu kasy ---
 *
 * Snippet dawał mu 10 px i zakaz łamania. Stopień podnosimy do 12 px (10 px jest poniżej
 * progu czytelności dla informacji podatkowej).
 *
 * ⚠️ `white-space: nowrap` USUNIĘTY — był tu i PRZYCINAŁ liczbę. Zmierzone na żywo
 * 2026-09-15 przy trzech sztukach w koszyku: na 375 px cała tabela podsumowania wystawała
 * +27 px poza `#order_review` i tekst kończył się na „(zawiera 443,17 zł VA" — bez
 * zamykającego „T)". Na 601 i 1440 px komórka miała `scrollWidth` większy od `clientWidth`
 * o 14–16 px, czyli to samo przycięcie, tylko płytsze.
 *
 * Powód, dla którego snippet mógł sobie na `nowrap` pozwolić, a my nie: on dawał 10 px,
 * my dajemy 12 px — ten sam tekst jest o ~20% szerszy. Zakaz łamania przy szerszym tekście
 * zamienia problem estetyczny (dopisek w dwóch liniach) w defekt funkcjonalny (ucięta kwota
 * podatku na kasie). Dwie linie są akceptowalne, ucięta liczba nie jest.
 *
 * ⚠️ Ta wartość NIE była widziana przez R6 w `check-sklep-css`: `white-space` nie stoi na
 * liście `WLASCIWOSCI_UKLADU`, choć `nowrap` rozpycha wiersz dokładnie tak samo jak
 * odrzucony wcześniej `display: block` (patrz komentarz w warstwie 40). Reguła dopisana
 * przy tej naprawie. */
/* ⚠️ `body.isa-ds.isa-ds` NIE jest ozdobnikiem specyficzności — jest konieczne.
 *
 * Samo USUNIĘCIE `white-space: nowrap` z naszego arkusza niczego nie zmieniło: zmierzone
 * po wgraniu, `small.includes_tax` na żywo NADAL miało `nowrap` i `scrollWidth` 131 px przy
 * szerokości 66 px. Źródłem jest żywy snippet Simple Custom CSS and JS, wstrzykiwany PO
 * naszym arkuszu (nasz stoi na pozycji 17 z 37 źródeł).
 *
 * Stąd lekcja szersza niż ta jedna reguła: „przejęcie funkcji snippetu" działa tylko dla
 * tego, co snippet ROBI. Nie da się w ten sposób przejąć rezygnacji z czegoś — żeby cofnąć
 * cudzą deklarację, trzeba ją nadpisać, a nie pominąć u siebie. Ta reguła zostaje potrzebna
 * także po wyłączeniu snippetu (będzie wtedy bezczynna, nie szkodliwa). */
body.isa-ds.isa-ds.woocommerce-checkout table.shop_table .includes_tax,
body.isa-ds.isa-ds .cart_totals .includes_tax {
  font-size: 12px;
  color: var(--ink-4);
  white-space: normal;
}

/* --- Ten sam dopisek na wąskim ekranie: własna linia ---
 *
 * ⚠️ POZWOLENIE NA ZAWIJANIE NIE WYSTARCZYŁO i to jest tu cała nauka. Reguła wyżej zdjęła
 * `nowrap`, a mimo to reguła R8 bramki `check-sklep-live` zmierzyła 2026-09-15 na żywo:
 * checkout@375 przycięte o 10 px, checkout@414 o 3 px — „(zawiera 295,45 zł VA".
 *
 * Zmierzona przyczyna leży piętro niżej niż zawijanie:
 *   · `.includes_tax` jest `inline-block`, więc kurczy się do RESZTKI linii po kwocie głównej
 *     — `clientWidth` 41 px, choć rodzic `<td>` ma 106 px i `overflow: visible`,
 *   · WooCommerce wstawia NBSP (U+00A0) między kwotę a walutę, więc „443,17 zł" jest jednym
 *     nierozdzielnym fragmentem o szerokości ~50 px.
 * Fragment nierozdzielny szerszy niż pole nie zawinie się nigdy — `white-space: normal` daje
 * pozwolenie na łamanie tam, gdzie nie ma czego złamać.
 *
 * Dlatego `display: block`: dopisek bierze pełną szerokość komórki i staje pod kwotą, zamiast
 * dzielić z nią linię. To jest zmiana układu w strefie transakcyjnej, więc ma jawny wpis
 * w `WYJATKI_UKLAD` strażnika — nie osłabiamy reguły, tylko nazywamy ten jeden przypadek.
 *
 * ⚠️ Czego świadomie NIE robimy: `overflow-wrap: anywhere` złamałoby kwotę w środku liczby
 * („443,1 / 7 zł"), co przy podatku jest gorsze niż ucięcie — czytelnik zobaczyłby inną sumę.
 * Zmniejszenie pisma poniżej 12 px też odpada: to informacja podatkowa, nie ozdobnik. */
@media screen and (max-width: 480px) {
  body.isa-ds.isa-ds.woocommerce-checkout table.shop_table .includes_tax,
  body.isa-ds.isa-ds .cart_totals .includes_tax {
    display: block;
    /* ⚠️ `display: block` SAM NIE WYSTARCZYŁ i to jest druga połowa tej naprawy.
     *
     * Po wdrożeniu samego `block` bramka zmierzyła przycięcie WIĘKSZE niż przed nią
     * (10 → 12 px na 375). Dochodzenie: element dostał `display: block` poprawnie, ale
     * miał `max-width: 50%` z układu responsywnej tabeli WooCommerce — 50% z 78 px
     * treściowych komórki to 39 px, dokładnie tyle, ile zmierzono. Blok nie bierze
     * szerokości rodzica, kiedy piętro dalej stoi ograniczenie szerokości.
     *
     * Reguła `max-width: 50%` ma sens dla PARY etykieta/wartość w wierszu — ale ten
     * dopisek nie jest wartością w parze, tylko przypisem pod kwotą. */
    max-width: 100%;
    margin-top: 2px;
  }
}

/* --- Responsywna tabela koszyka poniżej 719 px ---
 *
 * WooCommerce w układzie mobilnym dokleja przed każdą komórką etykietę nagłówka przez
 * `td::before`. W ostatnim wierszu podsumowania ta etykieta dubluje tekst stojący obok,
 * więc snippet ją chował. Zachowujemy. */
@media screen and (max-width: 719px) {
  body.isa-ds .cart-collaterals .cart_totals .shop_table_responsive tr:last-child td::before {
    display: none;
  }
}

/* --- Miniatura produktu w koszyku na wąskich ekranach ---
 *
 * Snippet ograniczał ją do 60 px, żeby wiersz nie rozjechał się na telefonie. Zachowujemy
 * ograniczenie, ale bez `display:block` i `margin:0 auto` — wyśrodkowanie zostawiamy
 * układowi tabeli, bo to jest przestawianie układu w strefie transakcyjnej. */
@media screen and (max-width: 767px) {
  body.isa-ds.woocommerce-cart table.cart img {
    max-width: 60px;
    height: auto;
  }
}
body.isa-ds { --isa-sklep-odcisk: "b65a9eca6ff8"; }

/* <<< isa-design-system | odcisk b65a9eca6ff8 <<< */
