/* ============================================================
   420market.pl — motyw „market420" v0.1.0 (Fala 1)
   Port design systemu z prototypu (prototyp/styl.css) na markup
   WordPressa/WooCommerce. Tokeny :root i nazwy komponentów 1:1
   z prototypem; adaptacje WP/Woo i wtyczek na końcu pliku.
   Zasady nadrzędne: lekkość (zero webfontów, zero JS-frameworków),
   mobile-first, kwadratowe kafle produktów (stałe proporcje = zero CLS).
   ============================================================ */
:root{
  --zielen:#262624;        /* główny ciemny marki */
  --zielen-2:#3b3b38;      /* hover / gradient ciemnego */
  --zielen-tlo:#e6faf8;    /* pastelowe tło teal */
  --akcent:#00CDBF;        /* teal 420market: CTA, akcenty */
  --akcent-2:#00b3a7; --akcent-tekst:#00857c;
  --tusz:#262624;          /* tekst główny */
  --tusz-2:#4b5563;        /* tekst drugorzędny */
  --linia:#e7e7e5;
  --tlo:#ffffff;
  --tlo-2:#f8f8f7;
  --blad:#b91c1c;
  --ok:#15803d;
  --r:14px; --r-s:8px;
  --cien:0 1px 2px rgba(21,26,23,.06),0 8px 24px -12px rgba(21,26,23,.18);
  --max:1200px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;color:var(--tusz);background:var(--tlo)}
img{max-width:100%;height:auto;display:block}

/* To NIE jest kosmetyka - bez tej reguly reset img{display:block} wyzej LAMIE
   atrybut hidden na obrazkach. Styl autora bije styl przegladarki niezaleznie od
   specyficznosci, wiec img{display:block} wygrywa z wbudowanym [hidden]{display:none}
   i element oznaczony jako ukryty... jest widoczny.

   Objaw zgloszony 26.08: w wysuwanym mini-koszyku kazdy produkt mial DWIE
   miniatury. WooCommerce renderuje tam dwa obrazki naraz - jeden w linku, drugi
   bez - i przelacza je atrybutem hidden przez Interactivity API. Nasz reset
   odslanial ten, ktory mial zostac schowany.

   Specyficznosc [hidden] to (0,1,0) i bije img (0,0,1), wiec wystarcza bez
   !important. Regula jest globalna celowo: ten sam mechanizm psuje kazdy
   obrazek przelaczany atrybutem, nie tylko koszyk. */
[hidden]{display:none}
a{color:var(--akcent-tekst);text-decoration:none}
a:hover{color:var(--tusz)}
.srodek{max-width:var(--max);margin:0 auto;padding:0 20px}
h1,h2,h3,h4,h5,h6{line-height:1.25;font-weight:700}
h1{font-size:clamp(26px,4vw,38px)}
h2{font-size:clamp(21px,3vw,28px)}
h3{font-size:18px}
/* 🔴 h4–h6 nie mialy ZADNEJ reguly stopnia pisma, wiec zostawaly przy 16 px —
   nieodroznialne od pogrubionego akapitu. Regulamin sklepu ma 27 naglowkow h4
   (kazdy paragraf) i 3 naglowki h2: cala jego struktura byla dla czytelnika
   niewidoczna. Rozne stopnie sa tanim sposobem na pokazanie hierarchii tam,
   gdzie tresc pisal ktos inny niz autor motywu. */
h4{font-size:16.5px}
h5{font-size:15px}
h6{font-size:13.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--tusz-2)}
.sekcja{padding:44px 0}
.sekcja--szara{background:var(--tlo-2)}
.sekcja__naglowek{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:22px}
.sekcja__naglowek a{font-size:14px;font-weight:600;white-space:nowrap}

/* ---------- pasek górny + nagłówek ---------- */
.topbar{background:var(--zielen);color:#d6d6d3;font-size:13px;text-align:center;padding:7px 12px}
.topbar b{color:#fff}
.naglowek{border-bottom:1px solid var(--linia);background:#fff;position:sticky;top:0;z-index:50}
.naglowek__rzad{display:flex;align-items:center;gap:18px;padding:14px 0}
.logo{font-size:24px;font-weight:800;letter-spacing:-.5px;color:var(--tusz);white-space:nowrap}
.logo span{color:var(--zielen)}
.logo em{color:var(--akcent);font-style:normal}
.logo img{max-height:44px;width:auto}
.szukaj{flex:1;display:flex;position:relative}
.szukaj input{width:100%;padding:11px 44px 11px 16px;border:2px solid var(--linia);border-radius:999px;font-size:15px;background:var(--tlo-2)}
.szukaj input:focus{outline:none;border-color:var(--zielen)}
.szukaj button{position:absolute;right:5px;top:50%;transform:translateY(-50%);border:0;background:var(--zielen);color:#fff;width:34px;height:34px;border-radius:50%;cursor:pointer;display:grid;place-items:center}
.ikony{display:flex;gap:16px;align-items:center}
.ikona{display:flex;flex-direction:column;align-items:center;gap:2px;font-size:11px;color:var(--tusz-2)}
.ikona svg{width:22px;height:22px;stroke:var(--tusz)}
.ikona--koszyk{position:relative}
/* licznik sztuk: tekst CIEMNY na akcencie. Biel na #00CDBF daje 2,03:1, czyli
   poniżej progu WCAG AA (4,5:1) — a przy tym stopniu pisma był to najgorzej
   czytelny element nagłówka. #123330 na akcencie to 6,72:1, tak samo jak
   .btn--glowny i .plakietka--nowosc. Bliźniacza reguła dla licznika bloku
   Mini-Cart: assets/css/bloki.css (.wc-block-mini-cart__badge). */
.ikona--koszyk .licznik{position:absolute;top:-4px;right:2px;background:var(--akcent);color:#123330;font-size:11px;font-weight:700;min-width:17px;height:17px;border-radius:9px;display:grid;place-items:center}
/* podpowiedzi szukajki (na żywo wypełnia je motyw.js ze Store API);
   widocznością steruje WYŁĄCZNIE klasa --otwarte z JS — reguła :focus-within
   pokazywała pustą ramkę przy każdym fokusie pola i wygrywała z Escape */
.szukaj__wyniki{display:none;position:absolute;top:calc(100% + 6px);left:0;right:0;background:#fff;border:1px solid var(--linia);border-radius:var(--r-s);box-shadow:var(--cien);overflow:hidden;z-index:60}
.szukaj__wynik{display:flex;gap:10px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--linia)}
.szukaj__wynik:last-child{border-bottom:0}
.szukaj__wynik img{width:40px;height:40px;object-fit:contain;background:var(--tlo-2);border-radius:6px}
.szukaj__wynik small{color:var(--tusz-2)}

/* ---------- nawigacja / mega-menu (CSS hover) ----------
   🔴 RUNDA 4 (20.08): selektory paska NIE PASOWAŁY do markupu.
   Realna struktura (header.php, OBA tryby menu — z wp_nav_menu i z nawigacji
   zastępczej budowanej z kategorii sklepu):
     <nav class="nav"><div class="srodek"><ul><li><a>…</a><div class="mega">…
   czyli <ul> jest WNUKIEM .nav, nie dzieckiem — reguły pisane jako `.nav>ul>li`
   nie trafiały w nic. Zmierzone w Chrome: li miało position:static, a miało
   font-weight:400, padding:0px i display:inline (globalny reset *{padding:0}).
   Dwa skutki naraz, oba widoczne na żywym sklepie:
     1) .mega (position:absolute;left:0) szukała najbliższego POZYCJONOWANEGO
        przodka i znajdowała .naglowek (position:sticky) — panel przyklejał się
        do lewej krawędzi okna (megaX=0) zamiast wisieć pod swoją pozycją
        (liX=140). To błąd P13 z weryfikacji;
     2) pasek szedł bez pogrubienia, bez wypełnienia i bez podświetlenia
        na hover (błąd P11).
   Weryfikacja 0.1.1 tego nie złapała, bo liczyła wyłącznie liczbę linków.

   Selektory wypisane w OBU wariantach (`>ul` i `>.srodek>ul`): motyw ma zostać
   sprawny także wtedy, gdyby szablon kiedyś wypisał <ul> wprost w <nav>.
   Zagnieżdżonych <ul> w pasku nie ma — mega to <div class="mega"> z kolumnami
   (inc/walker-mega.php i bliźniaczy markup nawigacji zastępczej), więc
   `.nav ul` i `.nav li` dotyczą wyłącznie listy paska.
   ⚠ .wyroznione musi mieć podniesioną specyficzność: wariant `>.srodek>ul>li>a`
   ma (0,2,3) i bez tego wygrywałby z dotychczasowym `.nav .wyroznione>a` (0,2,1),
   czyli „Promocje" straciłyby kolor akcentu. */
.nav{border-top:1px solid var(--linia)}
.nav ul{list-style:none;display:flex;gap:2px;flex-wrap:wrap;justify-content:space-between;width:100%}
.nav>ul>li,.nav>.srodek>ul>li{position:relative}
.nav>ul>li>a,.nav>.srodek>ul>li>a{display:block;padding:11px 12px;font-weight:700;font-size:14.5px;color:var(--tusz);border-radius:var(--r-s) var(--r-s) 0 0}
.nav>ul>li:hover>a,.nav>.srodek>ul>li:hover>a{background:var(--zielen-tlo);color:var(--zielen)}
.nav .wyroznione>a,.nav>.srodek>ul>li.wyroznione>a{color:var(--akcent-2)}
.mega{display:none;position:absolute;left:0;top:100%;background:#fff;border:1px solid var(--linia);border-radius:0 var(--r-s) var(--r-s) var(--r-s);box-shadow:var(--cien);padding:18px 22px;min-width:460px;max-width:min(96vw,1000px);z-index:55}
/* 🔑 Liczba kolumn dopasowuje sie do zawartosci, nie jest zamrozona na dwoch.
   Mega jest od 28.08 DWUPOZIOMOWA: kolumna to podkategoria, a linki w niej to
   jej dzieci (np. „Waporyzatory przenosne" → Storz & Bickel, Arizer, Fenix).
   Przy sztywnych `1fr 1fr` trzecia i czwarta kolumna laduje pod pierwsza,
   co przy czterech grupach robi z megi dwa pietra zamiast jednego rzedu. */
.nav li:hover .mega{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:4px 34px}
/* Naglowek kolumny jest odsylaczem do wlasnego archiwum — tak samo jak
   u konkurencji, i slusznie: „Waporyzatory stacjonarne" to strona, na ktora
   ktos chce wejsc, a nie sama etykieta grupy. */
.mega .kolumna h4 a{color:inherit;text-decoration:none}
.mega .kolumna h4 a:hover{color:var(--zielen)}
/* Skutek uboczny zakotwiczenia megi w <li>: panel szerokości 460 px otwierany
   pod pozycją z prawej strony paska wychodziłby poza kontener 1200 px i dawał
   poziomy pasek przewijania całej strony (dokładnie ta klasa błędu, którą
   audyty łapały przy galerii PDP). Pozycje z prawej otwierają więc panel
   w lewo — prawa krawędź megi równa się prawej krawędzi pozycji.
   Dwa warunki naraz, bo pasek ma zmienną liczbę pozycji:
     :nth-child(n+5)        — długie menu (żywy sklep: 8 mega + Promocje + Blog),
     :nth-last-child(-n+2)  — menu krótkie, gdzie justify-content:space-between
                              odsuwa ostatnie pozycje na sam prawy skraj.
   Poniżej 980 px panel dodatkowo się zwęża (min-width:0 jest konieczne —
   przy min-width:460px żadne max-width nic nie zmienia). 55vw wyszło z pomiaru:
   przy 800 px panel odwrócony w lewo z samym `width:min(460px,100vw-28px)`
   wychodził 4 px poza lewą krawędź okna, przy 55vw (440 px) mieści się z zapasem,
   a przy 980 px nadal ma pełne 460 px. Mega i tak znika całkiem poniżej 640 px. */
.nav li:nth-child(n+5)>.mega,.nav li:nth-last-child(-n+2)>.mega{left:auto;right:0}
@media(max-width:980px){
  .mega{min-width:0;width:min(460px,55vw)}
}
.mega h4{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--tusz-2);margin:8px 0 4px;grid-column:span 1}
.mega a{display:block;padding:5px 0;font-size:14px;color:var(--tusz)}
.mega a:hover{color:var(--zielen)}
.mega .kolumna{display:flex;flex-direction:column}

/* ---------- przyciski, plakietki ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:0;cursor:pointer;font-weight:700;font-size:15px;border-radius:999px;padding:13px 26px;transition:background .15s}
.btn--glowny{background:var(--akcent);color:#123330}
.btn--glowny:hover{background:var(--akcent-2);color:#123330}
.btn--drugi{background:var(--zielen);color:#fff}
.btn--drugi:hover{background:var(--zielen-2);color:#fff}
.btn--obrys{background:#fff;border:2px solid var(--zielen);color:var(--zielen)}
.btn--maly{padding:8px 16px;font-size:13.5px}
.plakietka{display:inline-block;font-size:11.5px;font-weight:700;padding:3px 10px;border-radius:999px;letter-spacing:.02em}
.plakietka--redakcja{background:#fff;color:var(--tusz);border:1.5px solid var(--tusz)}
.plakietka--promo{background:var(--tusz);color:#5adfd4}
.plakietka--nowosc{background:var(--akcent);color:#123330}
.plakietka--gratis{background:#e0faf7;color:var(--akcent-tekst);border:1px solid #b8ede8}
.plakietka--brak{background:#f3f4f6;color:var(--tusz-2)}

/* ---------- hero + kafle kategorii ---------- */
.hero{background:linear-gradient(115deg,var(--zielen) 0%,var(--zielen-2) 70%);color:#fff;border-radius:var(--r);overflow:hidden;display:grid;grid-template-columns:1.2fr 1fr;align-items:center;margin-top:22px}
.hero__tekst{padding:44px 40px}
.hero__tekst .nadtytul{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#5adfd4}
.hero__tekst h1{color:#fff;margin:8px 0 12px}
.hero__tekst p{color:#cfcfcb;max-width:44ch;margin-bottom:22px}
.hero__cena{font-size:15px;margin-bottom:18px}.hero__cena b{font-size:26px;color:#fff}
.hero__cena s{color:#8f8f8b;margin-left:8px}
.hero__obraz{padding:26px;display:grid;place-items:center}
.hero__obraz img{max-height:340px;object-fit:contain;filter:drop-shadow(0 18px 30px rgba(0,0,0,.35))}
/* hero bez zdjęcia (brak wskazanego załącznika — front-page.php nie renderuje
   wtedy kolumny obrazu): tekst bierze całą szerokość zamiast zostawiać pustą połowę */
.hero--bez-obrazu{grid-template-columns:1fr}
/* auto-fit zamiast repeat(3,1fr): kafel bez potwierdzonego adresu docelowego
   nie jest w ogóle renderowany (front-page.php), a wtedy pozostałe mają wypełnić
   szerokość, nie zostawiać dziury po nieistniejącym trzecim */
.kafle-promo{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin-top:14px}
.kafel-promo{display:flex;align-items:center;gap:14px;background:var(--tlo-2);border:1px solid var(--linia);border-radius:var(--r);padding:16px 18px;color:var(--tusz);font-weight:600;font-size:14.5px}
.kafel-promo:hover{border-color:var(--zielen)}
.kafle-kat{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.kafel-kat{background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:18px;text-align:center;color:var(--tusz);transition:border-color .15s,box-shadow .15s}
.kafel-kat:hover{border-color:var(--zielen);box-shadow:var(--cien);color:var(--tusz)}
.kafel-kat img{width:100%;aspect-ratio:1;object-fit:contain;margin-bottom:10px}
.kafel-kat b{display:block;font-size:15px}
.kafel-kat small{color:var(--tusz-2)}

/* ---------- kafel produktu (stałe proporcje = zero CLS) ---------- */
.siatka-prod{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.prod{background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:14px;position:relative;display:flex;flex-direction:column;transition:box-shadow .15s,border-color .15s}
.prod:hover{box-shadow:var(--cien);border-color:#c9d6cd}
.prod__plakietki{position:absolute;top:12px;left:12px;display:flex;flex-direction:column;gap:5px;z-index:2;align-items:flex-start}
/* B3 (20.08): kwadrat NIEZALEŻNY od proporcji pliku.
   Zmierzone na żywym sklepie: kontener miał 278 px szerokości i 375 px wysokości
   MIMO aspect-ratio:1, bo obraz kafla bywa pionowy (Woo tnie m420-kafel do
   kwadratu tylko wtedy, gdy oryginał jest odpowiednio duży — przy mniejszym
   zostaje proporcja oryginału, tu 278×359). Kafle rosły do 583 px i siatka się
   rozjeżdżała.
   Dwie przyczyny naraz:
     1) obraz w normalnym przepływie podnosił automatyczne minimum wysokości
        elementu flex (.prod to kolumna flex, min-height:auto liczy się z treści);
     2) max-height:100% nic nie dawało — procent liczony od wysokości, która sama
        zależy od treści, przeglądarka traktuje jak „none" (odwołanie cykliczne).
   Naprawa: oba zdjęcia kafla wypadają z przepływu (position:absolute; inset:0),
   więc o wysokości decyduje WYŁĄCZNIE aspect-ratio, a object-fit:contain mieści
   całe zdjęcie w kwadracie bez przycinania (w sklepie ucięty produkt to błąd).
   min-height:0 zdejmuje automatyczne minimum flexa, gdyby do środka trafiło
   jeszcze coś w przepływie. Selektor potomka (a nie „>") jest odporny na
   opakowanie obrazka w <picture> przez wtyczkę optymalizującą — takie opakowanie
   nie jest pozycjonowane, więc obraz i tak liczy się względem .prod__foto,
   a samo opakowanie zostaje puste (zero wysokości).
   Ta sama reguła obsługuje kafle w karuzelach (.karuzela__tor) — tor podaje
   tylko szerokość slajdu, kwadrat robi się tu. Kafle kategorii mają własny
   mechanizm (.kafel-kat img: width:100% + aspect-ratio:1 na SAMYM obrazie),
   który nie ma tej wady, bo wysokość liczy się z proporcji, nie z treści.

   🔴 RUNDA 4 (20.08): PODNIESIONA SPECYFICZNOŚĆ SELEKTORA OBRAZU.
   Kwadrat kontenera trzymał się, ale samo zdjęcie na stronach WooCommerce
   dalej było źle ułożone: `.prod__foto img` ma (0,1,1) i przegrywa
   z niezdejmowanym arkuszem woocommerce-general —
     `.woocommerce ul.products li.product a img{width:100%;height:auto;
      display:block;margin:0 0 1em;box-shadow:none}`  (0,3,3)
   (obraz kafla SIEDZI w <a class="prod__foto">, więc reguła trafia).
   Zmierzone w Chrome przy klasie .woocommerce na <body>: zdjęcie pionowe
   278×359 wychodziło 278×278 (uratowane przypadkiem przez max-height:100%,
   które przy pozycjonowaniu bezwzględnym rozwiązuje się względem definitywnej
   wysokości kontenera), ale zdjęcie POZIOME 600×300 → 278×139 przyklejone
   do GÓRY kwadratu i 139 px pustego pola pod nim; do tego margin:0 przegrywał
   z margin:0 0 1em. Ten sam test bez klasy .woocommerce (strona główna) dawał
   poprawne 278×278 — czyli height:100% było po prostu przebijane.
   Problem uderzał szeroko, bo add_image_size('m420-kafel',600,600,true) nie
   generuje kadru dla oryginałów mniejszych niż 600 px i nie regeneruje starych
   mediów, więc sporo kart spada na pełny rozmiar o dowolnych proporcjach.
   Naprawa: powtórzone klasy (.prod.prod .prod__foto.prod__foto) dają (0,4,1),
   czyli więcej klas niż (0,3,3) Woo — wygrywamy niezależnie od kolejności
   arkuszy i BEZ !important, zgodnie z zasadą motywu. Selektor nie wymaga
   przodka .woocommerce, więc ta sama reguła obowiązuje na stronie głównej. */
.prod__foto{aspect-ratio:1;display:grid;place-items:center;margin-bottom:10px;min-height:0}
.prod.prod .prod__foto.prod__foto img{position:absolute;inset:0;width:100%;height:100%;max-width:100%;max-height:100%;margin:0;object-fit:contain;object-position:center}
.prod__nazwa{font-size:14.5px;font-weight:600;color:var(--tusz);line-height:1.35;min-height:2.7em}
.prod__ocena{font-size:12.5px;color:var(--tusz-2);margin:4px 0}
.prod__ocena .gwiazdki{color:#f5a623;letter-spacing:1px}
.prod__cena{margin-top:auto;padding-top:8px;font-size:17px;font-weight:800}
.prod__cena s{font-size:13.5px;color:var(--tusz-2);font-weight:500;margin-right:7px}
.prod__cena .teraz{color:var(--akcent-tekst)}
.prod__koszyk{margin-top:10px}
.prod__koszyk .btn{width:100%}
/* linia Omnibus „Najniższa cena z 30 dni przed obniżką" (renderuje inc/omnibus.php):
   na kaflu między ceną a przyciskiem koszyka, na PDP tuż pod ceną — w obu miejscach
   jak wyciszony <small> prototypu; kwota z wc_price bez pogrubienia (to informacja
   prawna, nie oferta) */
.m420-omnibus{margin:2px 0 0;font-size:12px;line-height:1.4;font-weight:400;color:var(--tusz-2)}
.m420-omnibus .woocommerce-Price-amount{font-weight:400}

/* ---------- pasek zaufania ---------- */
.zaufanie{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.zaufanie__el{display:flex;gap:12px;align-items:flex-start;background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:16px}
.zaufanie__el svg{width:26px;height:26px;flex:none;stroke:var(--akcent-2)}
.zaufanie__el b{display:block;font-size:14.5px}
.zaufanie__el small{color:var(--tusz-2);font-size:13px;line-height:1.45;display:block}
/* Liczby zaufania. Był to goły rząd tekstu bez tła i ramek — jedyna sekcja
   strony głównej, która nie wyglądała jak reszta motywu. Teraz kafle na tym
   samym rastrze co „Kupuj według marki": białe pole, ramka --linia, promień --r.
   Czwarty kafel (nazwa portalu) ma mniejszy stopień, bo to nie liczba tylko
   nazwa i przy 26 px łamała się na dwie linijki. */
.dowod{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.dowod__el{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  text-align:center;background:#fff;border:1px solid var(--linia);border-radius:var(--r);
  padding:22px 14px;transition:border-color .15s,box-shadow .15s}
.dowod__el:hover{border-color:var(--akcent);box-shadow:var(--cien)}
.dowod__ikona{width:26px;height:26px;stroke:var(--akcent-2);fill:none;margin-bottom:10px;
  stroke-linecap:round;stroke-linejoin:round}
.dowod__el b{display:block;font-size:26px;line-height:1.15;color:var(--akcent-tekst);letter-spacing:-.02em}
.dowod__el b.dowod__b--male{font-size:17px;line-height:1.25}
.dowod__el small{display:block;margin-top:5px;color:var(--tusz-2);font-size:13px;line-height:1.35}
@media(max-width:820px){.dowod{grid-template-columns:repeat(2,1fr)}}
@media(max-width:420px){.dowod__el{padding:16px 10px}.dowod__el b{font-size:22px}}

/* ---------- kategoria: filtry ---------- */
.uklad-kat{display:grid;grid-template-columns:250px 1fr;gap:26px;align-items:start}
.filtry{position:sticky;top:130px;display:flex;flex-direction:column;gap:4px}
.filtry__reset{font-size:13px;margin-bottom:6px}
.filtr{border:1px solid var(--linia);border-radius:var(--r-s);background:#fff}
.filtr summary{padding:11px 14px;font-weight:700;font-size:14px;cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center}
.filtr summary::after{content:"▾";color:var(--tusz-2)}
.filtr[open] summary::after{content:"▴"}
.filtr__cialo{padding:2px 14px 12px;display:flex;flex-direction:column;gap:7px;font-size:14px}
.filtr__cialo label{display:flex;align-items:center;gap:8px;color:var(--tusz);cursor:pointer}
.filtr__cialo .ile{margin-left:auto;color:var(--tusz-2);font-size:12.5px}
.chipy{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}
.chip{border:1px solid var(--linia);background:#fff;border-radius:999px;padding:7px 15px;font-size:13.5px;font-weight:600;color:var(--tusz)}
.chip:hover,.chip--aktywny{border-color:var(--zielen);background:var(--zielen-tlo);color:var(--zielen)}
.sortowanie{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px;font-size:14px;color:var(--tusz-2)}
.sortowanie select{padding:8px 12px;border:1px solid var(--linia);border-radius:var(--r-s);font-size:14px}
.paginacja{display:flex;gap:6px;justify-content:center;margin-top:28px}
.paginacja a{min-width:38px;height:38px;display:grid;place-items:center;border:1px solid var(--linia);border-radius:var(--r-s);font-weight:600}
.paginacja .biezaca{background:var(--zielen);color:#fff;border-color:var(--zielen)}
/* ---------- opis kategorii ----------
   Nowy układ (kontrakt z woocommerce/archive-product.php):
     1) .opis-kat--krotki — 2-3 zdania NAD siatką produktów, bez zwijania;
     2) <section class="sekcja sekcja--opis-kat"> POD produktami, a w niej
        <h2> + <div class="opis-kat opis-kat--pelny proza">pełny opis</div>.
   Wzorzec wyglądu: prototyp/kategoria.html (pełny opis w sekcji z jasnym tłem
   pod listingiem). Zwijanie opisu (.opis-kat--zwijany) USUNIĘTE 19.08 razem
   z martwym progiem M420_OPIS_ZWIJANY_ZNAKI — w nowym układzie długi tekst
   i tak nie zasłania produktów, bo w całości siedzi pod listingiem.
   Szerokość kolumny tekstu: 76ch (dłuższe wiersze męczą przy czytaniu). */
.opis-kat{max-width:76ch}
/* opis zwykle dostaje klasę .proza; te dwie reguły ratują wypadek, gdy szablon
   jej nie doda — globalny reset *{margin:0} skleiłby wtedy akapity w blok */
.opis-kat p,.opis-kat ul{margin-bottom:12px}
.opis-kat ul{padding-left:22px}
.opis-kat h3{margin:16px 0 6px}
/* 1) krótki wstęp nad produktami — 2-3 zdania, nigdy nie przycinany */
.opis-kat--krotki{max-width:76ch;margin:0 0 18px;color:var(--tusz-2);font-size:15.5px}
.opis-kat--krotki p{margin-bottom:8px}
.opis-kat--krotki p:last-child{margin-bottom:0}
/* 2) pełny opis pod produktami. Szablon renderuje pas jak w prototypie:
   <section class="sekcja sekcja--szara"> → .srodek → h2 → .opis-kat--pelny.proza,
   czyli tło (--tlo-2) i padding sekcji dają klasy bazowe. Tu zostaje sam blok
   tekstu; margin-top to odstęp od nagłówka (globalny reset zeruje marginesy h2).
   .sekcja--opis-kat to zapasowy uchwyt, gdyby pas miał kiedyś stanąć bez
   .sekcja--szara — daje ten sam wygląd bez klas bazowych. */
.sekcja--opis-kat{background:var(--tlo-2);padding:44px 0}
.opis-kat--pelny{max-width:76ch;margin-top:14px}
.opis-kat--pelny>h2:first-child{margin-bottom:14px}
.opis-kat--pelny h3{margin:18px 0 6px}

/* ---------- karta produktu ---------- */
/* 🔴 RUNDA 4 (P5): okruszki dostają oddech od przyklejonego nagłówka.
   Zmierzone na żywym sklepie: nav.woocommerce-breadcrumb miał padding-top:0
   i stał tuż pod nagłówkiem wysokim na 99 px — linia ścieżki wyglądała jak
   doklejona do paska nawigacji, a H1 zaczynał się od razu pod nią.
   Rytm: 26 px nad, 16 px pod. Świadomie MNIEJ niż 44 px sekcji (.sekcja) —
   okruszki są linią pomocniczą, nie sekcją, a bezpośrednio pod nimi stoi H1
   z własnym rozmiarem; pełne 44 px rozrywałoby parę „ścieżka + tytuł".
   Ta sama wartość obowiązuje okruszki Woo (blok „okruszki Woo" niżej w pliku,
   tam z podniesioną specyficznością wobec woocommerce-general). */
.okruszki{font-size:13px;color:var(--tusz-2);margin:0;padding:26px 0 16px}
.okruszki a{color:var(--tusz-2)}
.uklad-pdp{display:grid;grid-template-columns:1.05fr 1fr;gap:36px;align-items:start}
/* opakowanie galerii PDP (kolumna gridu .uklad-pdp); min-width:0 = szeroka zawartość nie rozpycha kolumny */
.galeria{min-width:0}
.galeria__glowne{aspect-ratio:1;border:1px solid var(--linia);border-radius:var(--r);display:grid;place-items:center;padding:20px;background:#fff}
.galeria__glowne img{max-height:100%;object-fit:contain}
.galeria__miniatury{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-top:8px}
.galeria__miniatury a{aspect-ratio:1;border:1px solid var(--linia);border-radius:var(--r-s);display:grid;place-items:center;padding:6px;background:#fff}
.galeria__miniatury a.aktywna{border-color:var(--zielen);border-width:2px}
.buybox h1{font-size:clamp(22px,3vw,30px);margin-bottom:6px}
.buybox__ocena{font-size:14px;color:var(--tusz-2);margin-bottom:14px}
.buybox__ocena .gwiazdki{color:#f5a623}
.buybox__cena{font-size:32px;font-weight:800;margin:6px 0 2px}
.buybox__cena s{font-size:19px;color:var(--tusz-2);font-weight:500;margin-right:10px}
.buybox__cena .teraz{color:var(--akcent-tekst)}
.dostepnosc{font-size:14px;margin-bottom:14px}
.dostepnosc--jest{color:var(--ok);font-weight:600}
.dostepnosc--brak{color:var(--blad);font-weight:600}
.warianty{margin:14px 0}
.warianty b{font-size:14px}
.warianty__lista{display:flex;gap:8px;margin-top:8px}
.wariant{width:38px;height:38px;border-radius:50%;border:2px solid var(--linia);cursor:pointer;display:grid;place-items:center}
.wariant--aktywny{border-color:var(--zielen);box-shadow:0 0 0 2px var(--zielen-tlo)}
.wariant span{width:26px;height:26px;border-radius:50%;display:block}
.dodaj-rzad{display:flex;gap:10px;margin:16px 0 6px}
.dodaj-rzad .ilosc{width:78px;padding:0 0 0 14px;border:2px solid var(--linia);border-radius:999px;font-size:16px}
.dodaj-rzad .btn{flex:1}
/* komplet (FBT) — checkboxy DOMYŚLNIE ODZNACZONE (wymóg prawny) */
.komplet{border:2px solid var(--zielen-tlo);background:var(--zielen-tlo);border-radius:var(--r);padding:16px;margin:16px 0}
.komplet h3{font-size:15.5px;margin-bottom:10px}
.komplet label{display:flex;gap:10px;align-items:center;padding:7px 0;font-size:14.5px;cursor:pointer}
.komplet label img{width:44px;height:44px;object-fit:contain;background:#fff;border-radius:var(--r-s);border:1px solid var(--linia)}
.komplet label .cena{margin-left:auto;font-weight:700;white-space:nowrap}
.komplet label .cena s{color:var(--tusz-2);font-weight:400;font-size:12.5px;margin-right:5px}
.komplet__suma{border-top:1px dashed #b8ede8;margin-top:8px;padding-top:10px;display:flex;justify-content:space-between;font-size:15px}
.komplet__suma .oszczedzasz{color:var(--ok);font-weight:700}
/* rząd zaufania pod przyciskiem koszyka */
.zaufanie-mini{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:14px 0}
.zaufanie-mini a{display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center;font-size:11.5px;color:var(--tusz-2);padding:10px 4px;border:1px solid var(--linia);border-radius:var(--r-s)}
.zaufanie-mini svg{width:20px;height:20px;stroke:var(--akcent-2)}
/* sekcje opisu: desktop rozwinięte, mobile akordeony */
.pdp-sekcja{border-top:1px solid var(--linia);padding:26px 0}
.pdp-sekcja>h2{margin-bottom:14px}
.pdp-sekcja .proza{max-width:76ch}
.proza p,.proza ul{margin-bottom:12px}
.proza ul{padding-left:22px}
table.spec{width:100%;border-collapse:collapse;font-size:14.5px;max-width:640px}
table.spec th,table.spec td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--linia)}
table.spec th{width:44%;color:var(--tusz-2);font-weight:600}
details.faq{border:1px solid var(--linia);border-radius:var(--r-s);margin-bottom:8px;background:#fff}
details.faq summary{padding:13px 16px;font-weight:600;cursor:pointer;list-style:none;display:flex;justify-content:space-between}
details.faq summary::after{content:"+";color:var(--zielen);font-size:19px}
details.faq[open] summary::after{content:"–"}
details.faq .faq__tresc{padding:0 16px 14px;color:var(--tusz-2);font-size:14.5px}
/* opinie */
.opinie{display:grid;grid-template-columns:280px 1fr;gap:30px;align-items:start}
.histogram{display:flex;flex-direction:column;gap:6px}
.histogram__srednia{font-size:40px;font-weight:800}
.histogram__rzad{display:flex;align-items:center;gap:8px;font-size:13px}
.histogram__pas{flex:1;height:8px;background:var(--linia);border-radius:4px;overflow:hidden}
.histogram__pas i{display:block;height:100%;background:#f5a623}
.opinia{border-bottom:1px solid var(--linia);padding:14px 0}
.opinia__meta{font-size:13px;color:var(--tusz-2);margin-bottom:4px}
.opinia__meta .zweryfikowany{color:var(--ok);font-weight:600}
/* ---------- sticky „Do koszyka" (render: inc/pdp.php na wp_footer) ----------
   🔴 RUNDA 4 (P3): pasek działa TAKŻE NA DESKTOPIE.
   Do 20.08 jedyna reguła pokazująca go stała w @media(max-width:640px), więc
   na dużym ekranie element siedział w DOM z display:none — Paweł zgłosił brak
   paska na karcie produktu.

   Widocznością steruje WYŁĄCZNIE klasa stanu .sticky-atc--widoczny, którą
   nadaje i zdejmuje motyw.js po wyjściu buyboksa poza widok (ten sam wzorzec
   co .szukaj__wyniki--otwarte). Bez klasy pasek jest schowany — świadomie,
   bo pasek widoczny od pierwszej klatki dublowałby przycisk zakupu stojący
   tuż obok w buyboksie.

   Kształt zależy od ekranu:
     desktop — pełna belka przy dolnej krawędzi, treść zawężona do --max,
     mobile  — dotychczasowa pigułka (blok @media(max-width:640px) niżej).

   🔴 RUNDA 5 — WARSTWY: z-index 45, czyli PONIŻEJ nagłówka (.naglowek ma 50).
   Do 0.1.2 pasek stał na 70 i przykrywał WSZYSTKO, co renderuje się wewnątrz
   nagłówka: sticky nagłówek tworzy własny kontekst układania, więc jego
   zawartość — drawer mini-koszyka (bloki.css), podpowiedzi szukajki (60)
   i mega-menu (55) — maluje się z wartością 50 nagłówka, nie własną.
   Objaw z karty produktu: otwarty mini-koszyk miał dolne przyciski („Przejdź
   do kasy", „Zobacz koszyk") przykryte paskiem „Do koszyka".
   Do tej pory ratowała to jedna reguła w bloki.css wisząca na klasie stanu
   `drawer-open` z bloku WooCommerce — czyli na CUDZEJ nazwie klasy, która może
   zniknąć z wydaniem wtyczki i zabrać naprawę ze sobą, po cichu.
   Teraz zależność jest strukturalna i nie ma czego pilnować: pasek stoi
   przy DOLNEJ krawędzi okna, a nagłówek przy górnej — geometrycznie nigdy
   się nie stykają, więc obniżenie paska pod nagłówek nic nie zasłania,
   a wszystko, co z nagłówka wyjeżdża na ekran, jest odtąd nad paskiem.
   Pasek dalej stoi nad treścią strony (ta ma z-index auto) i PONIŻEJ bramki
   18+ (100), więc nigdy nie przykryje ekranu weryfikacji wieku. Pasek wtyczki
   podglądu motywu ma z-index 99999 i zostaje na wierzchu. */
.sticky-atc{display:none}
.sticky-atc--widoczny{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:45;align-items:center;gap:18px;background:#fff;border-top:1px solid var(--linia);box-shadow:0 -8px 24px -14px rgba(21,26,23,.35);
  /* Treść w kolumnie --max, dokładnie jak .srodek, ale BEZ dodatkowego
     opakowania w markupie (pasek renderuje się w stopce jako jeden <div>).
     Dopełnienie boczne = połowa nadmiaru ponad 1200 px + 20 px światła;
     max() pilnuje, żeby na wąskim ekranie zostało minimum 20 px marginesu
     (procent liczy się tu od szerokości okna — element jest position:fixed). */
  padding:12px max(20px,calc((100% - var(--max)) / 2 + 20px))}
/* Kolejność w markupie to <b>cena</b><small>nazwa</small> (inc/pdp.php).
   Na belce czyta się naturalniej „nazwa — cena", więc odwracamy oś wiersza
   zamiast zmieniać szablon; kolejność odczytu dla czytnika ekranu zostaje. */
.sticky-atc--widoczny>div{display:flex;flex-direction:row-reverse;justify-content:flex-end;align-items:baseline;gap:12px;min-width:0}
.sticky-atc--widoczny b{font-size:19px;font-weight:800;white-space:nowrap}
.sticky-atc--widoczny small{min-width:0;font-size:15px;font-weight:600;color:var(--tusz);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sticky-atc--widoczny .btn{margin-left:auto;flex:none}
/* Rezerwacja miejsca w stopce: pasek jest position:fixed, więc bez tego
   przykrywałby notę 18+ i informację o pełnoletniości — czyli treść, która
   musi być widoczna. Rezerwacja jest STAŁA (nie zależy od klasy stanu):
   doklejanie jej razem z paskiem przesuwałoby stronę pod kursorem w trakcie
   przewijania. Poza kartą produktu paska nie ma, stąd warunek .single-product. */
.single-product .stopka__prawna{padding-bottom:96px}

/* ---------- blog ---------- */
.siatka-blog{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.wpis-kafel{background:#fff;border:1px solid var(--linia);border-radius:var(--r);overflow:hidden;color:var(--tusz)}
.wpis-kafel:hover{box-shadow:var(--cien)}
.wpis-kafel img{aspect-ratio:16/9;object-fit:cover;width:100%}
.wpis-kafel div{padding:16px}
.wpis-kafel .kat{font-size:12px;font-weight:700;color:var(--zielen);text-transform:uppercase;letter-spacing:.05em}
.wpis-kafel h3{font-size:16.5px;margin:6px 0}
.wpis-kafel small{color:var(--tusz-2)}
.artykul{max-width:76ch;margin:0 auto}
.artykul h2{margin:28px 0 12px}
.artykul p,.artykul ul{margin-bottom:14px}
.artykul ul{padding-left:22px}
.cta-box{background:var(--zielen-tlo);border:1px solid #cfe4d6;border-radius:var(--r);padding:20px;margin:24px 0;display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.cta-box img{width:84px;height:84px;object-fit:contain;background:#fff;border-radius:var(--r-s)}
.cta-box b{display:block;margin-bottom:2px}

/* ---------- stopka ---------- */
.stopka{background:var(--tusz);color:#c8cec9;margin-top:60px;font-size:14px}
.stopka a{color:#c8cec9}.stopka a:hover{color:#fff}
.stopka__kolumny{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:28px;padding:40px 0}
/* Liczba torów = liczba REALNIE wyrenderowanych kolumn. footer.php pomija kolumnę,
   która nie ma ani przypisanego menu, ani domyślnych linków (np. sklep bez stron
   pomocy), więc przy sztywnych czterech torach ostatnia ćwiartka stopki zostawała
   pusta, a kolumny nie wypełniały szerokości. Modyfikator dolicza footer.php.
   auto-fit tu nie wchodzi: repeat(auto-fit,…) nie łączy się w jednym zapisie
   z torem elastycznym (1.4fr) — przeglądarka odrzuciłaby całą deklarację. */
.stopka__kolumny--1{grid-template-columns:1fr}
.stopka__kolumny--2{grid-template-columns:1.4fr 1fr}
.stopka__kolumny--3{grid-template-columns:1.4fr 1fr 1fr}
.stopka__kolumny--4{grid-template-columns:1.4fr 1fr 1fr 1fr}
.stopka h4{color:#fff;font-size:14px;margin-bottom:12px}
.stopka li{list-style:none;padding:3px 0}
.stopka__opis{line-height:1.55}
.stopka__platnosci{border-top:1px solid #2c332e;padding:16px 0;display:flex;gap:10px;align-items:center;flex-wrap:wrap;font-size:12.5px;color:#9aa39c}
.platnosc{background:#fff;color:var(--tusz);border-radius:5px;padding:3px 9px;font-weight:700;font-size:11.5px}
.stopka__prawna{border-top:1px solid #2c332e;padding:14px 0 26px;font-size:12px;color:#9aa39c;line-height:1.55}
.znak18{display:inline-grid;place-items:center;width:34px;height:34px;border:2px solid #c8cec9;border-radius:50%;font-weight:800;font-size:12px;color:#fff;margin-right:10px;vertical-align:middle}

/* ---------- bramka 18+ (dialog; brak CLS — overlay poza flow) ---------- */
.bramka{position:fixed;inset:0;background:rgba(10,14,11,.78);backdrop-filter:blur(4px);z-index:100;display:grid;place-items:center;padding:20px}
.bramka[hidden]{display:none}
.bramka__okno{background:#fff;border-radius:var(--r);max-width:430px;padding:34px;text-align:center}
.bramka__okno .znak{width:64px;height:64px;border:3px solid var(--zielen);border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:20px;color:var(--zielen);margin:0 auto 16px}
.bramka__okno h2{margin-bottom:10px}
.bramka__okno p{color:var(--tusz-2);font-size:14.5px;margin-bottom:20px}
.bramka__przyciski{display:flex;gap:10px;justify-content:center}

/* ---------- responsywność ---------- */
@media(max-width:980px){
  .siatka-prod{grid-template-columns:repeat(3,1fr)}
  .kafle-kat{grid-template-columns:repeat(3,1fr)}
  .uklad-pdp{grid-template-columns:1fr}
  .uklad-kat{grid-template-columns:1fr}
  .filtry{position:static;flex-direction:row;flex-wrap:wrap}
  .filtr{flex:1 1 180px}
  .hero{grid-template-columns:1fr}
  .hero__obraz{order:-1;padding-bottom:0}
  .stopka__kolumny{grid-template-columns:1fr 1fr}
  .opinie{grid-template-columns:1fr}
  .siatka-blog{grid-template-columns:1fr 1fr}
  .zaufanie{grid-template-columns:1fr 1fr}
  .kafle-promo{grid-template-columns:1fr}
}
@media(max-width:640px){
  .siatka-prod{grid-template-columns:repeat(2,1fr)}
  .kafle-kat{grid-template-columns:repeat(2,1fr)}
  .naglowek__rzad{flex-wrap:wrap}
  .szukaj{order:3;flex-basis:100%}
  .siatka-blog{grid-template-columns:1fr}
  .nav ul{overflow-x:auto;flex-wrap:nowrap;white-space:nowrap;gap:14px;padding:4px 2px}
  /* oba warianty struktury paska — patrz komentarz przy bloku nawigacji */
  .nav>ul>li>a,.nav>.srodek>ul>li>a{padding:13px 16px;font-size:15px}
  .mega{display:none!important} /* mega-menu tylko desktop */
  /* akordeony sekcji opisu tylko na mobile */
  .pdp-sekcja--akordeon>h2{cursor:pointer;position:relative}
  .pdp-sekcja--akordeon>h2::after{content:"▾";position:absolute;right:0;color:var(--tusz-2)}
  .pdp-sekcja--akordeon.zwiniete>*:not(h2){display:none}
  /* sticky pasek dodania do koszyka — na telefonie zostaje PIGUŁKA (wygląd
     z prototypu): odsunięta od krawędzi, zaokrąglona, nazwa pod ceną.
     Pozycjonowanie i widoczność bierze z bloku bazowego (.sticky-atc--widoczny
     wyżej w pliku) — tu tylko różnice kształtu. Reguły są zapisane na klasie
     stanu, a nie na samej .sticky-atc, żeby na obu szerokościach ekranu
     decydował ten sam przełącznik z motyw.js. */
  .sticky-atc--widoczny{left:10px;right:10px;bottom:10px;border:1px solid var(--linia);border-radius:999px;box-shadow:var(--cien);padding:8px 8px 8px 18px;gap:12px}
  .sticky-atc--widoczny>div{display:block;min-width:0}
  .sticky-atc--widoczny b{font-size:16px}
  .sticky-atc--widoczny small{color:var(--tusz-2);display:block;font-size:11px;font-weight:400;line-height:1.1}
  .sticky-atc--widoczny .btn{margin-left:auto;padding:10px 20px}
  /* pigułka jest niższa od belki — mniejsza rezerwacja w stopce */
  .single-product .stopka__prawna{padding-bottom:86px}
}

/* ---------- filtry jako rozwijane przyciski (kategoria, wersja 2) ---------- */
.pasek-filtrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:16px 0}
.pasek-filtrow>span{font-size:13px;color:var(--tusz-2);margin-right:2px}
details.filtr-btn{position:relative}
.filtr-btn summary{list-style:none;cursor:pointer;border:1.5px solid var(--linia);background:#fff;border-radius:999px;padding:9px 16px;font-size:13.5px;font-weight:600;display:flex;align-items:center;gap:7px;white-space:nowrap}
.filtr-btn summary::-webkit-details-marker{display:none}
.filtr-btn summary::after{content:"▾";color:var(--tusz-2)}
.filtr-btn[open] summary{border-color:var(--tusz)}
.filtr-btn summary .ile-w{background:var(--akcent);color:#123330;font-size:11px;font-weight:800;min-width:18px;height:18px;border-radius:9px;display:grid;place-items:center;padding:0 5px}
.filtr-btn__panel{position:absolute;top:calc(100% + 6px);left:0;background:#fff;border:1px solid var(--linia);border-radius:var(--r-s);box-shadow:var(--cien);padding:12px 16px;min-width:230px;z-index:40;display:flex;flex-direction:column;gap:8px;font-size:14px}
.filtr-btn__panel label{display:flex;align-items:center;gap:8px;cursor:pointer}
.filtr-btn__panel .ile{margin-left:auto;color:var(--tusz-2);font-size:12.5px}
.filtr-btn--prawy{margin-left:auto}
@media(max-width:640px){.filtr-btn--prawy{margin-left:0}}
/* ---------- licznik wysyłki na karcie produktu ---------- */
.wysylka-licznik{display:flex;gap:12px;align-items:flex-start;background:var(--zielen-tlo);border:1px solid #b8ede8;border-radius:var(--r-s);padding:12px 15px;font-size:14px;margin:12px 0;line-height:1.45}
.wysylka-licznik svg{width:22px;height:22px;flex:none;stroke:var(--akcent-2);margin-top:2px}
.wysylka-licznik b.czas{font-variant-numeric:tabular-nums;color:var(--akcent-tekst)}
.wysylka-licznik small{display:block;color:var(--tusz-2);margin-top:2px}

/* ---------- marki na stronie głównej ---------- */
.marki{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.marka-kafel{display:grid;place-items:center;background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:22px 12px;font-weight:800;font-size:16.5px;letter-spacing:.01em;color:var(--tusz);text-align:center}
.marka-kafel small{font-weight:600;color:var(--tusz-2);font-size:12px;margin-top:3px}
.marka-kafel:hover{border-color:var(--akcent);box-shadow:var(--cien);color:var(--tusz)}
@media(max-width:980px){.marki{grid-template-columns:repeat(2,1fr)}}
/* (usunięte 20.08) .prod__foto--brak — klasa martwa: żaden szablon motywu jej
   nie wypisywał. Kafel produktu (woocommerce/content-product.php) polega na
   placeholderze podstawianym przez samo Woo, a kafel kategorii ma własny
   mechanizm .kafel-kat__zastepnik (styl inline z front-page.php). Reguła
   zostawała mylącym śladem — sugerowała istniejący komponent. */

/* ---------- karuzele, rotator, drawer, pre-order ---------- */

/* topbar-rotator: 3 klikalne slajdy, czysty CSS, stała wysokość 34px = zero CLS;
   cykl 12 s (4 s/slajd), pauza na hover, przy prefers-reduced-motion stoi slajd 1.

   B1 (20.08): slajdy NIE robią już crossfade. Poprzednie keyframes gasiły slajd
   w oknie 29–33 % cyklu i zapalały go w oknie 96–100 %, a przy przesunięciu
   sąsiada o 1/3 cyklu (4 s) oba okna nachodziły na siebie — na żywym sklepie
   widać było dwa półprzezroczyste teksty naraz w tym samym miejscu.
   Teraz każdy slajd dostaje własną trzecią część cyklu i gaśnie do zera ZANIM
   ruszy następny (przerwa, nie zakładka):
     0 %      opacity 0 — slajd czeka
     1,5 %    pełna widoczność (wejście 0,18 s)
     31 %     nadal pełna widoczność (≈3,7 s na przeczytanie)
     33 %     opacity 0 (wyjście 0,24 s) — zgaszony po 3,96 s
     33,33 %  startuje slajd następny (animation-delay 4 s) → ~40 ms pustej przerwy
   Kontener zachowuje stałe 34 px, więc mimo zmiany nadal zero CLS.

   visibility (w keyframes i w stanie bazowym): slajdy leżą jeden na drugim
   (position:absolute) i KAŻDY jest linkiem. Samo opacity:0 zostawia link
   klikalny — niewidoczny slajd 3 przez pierwsze 8 s przykrywałby widoczny
   slajd 1 i przechwytywał kliknięcia (styl bazowy obowiązuje w fazie
   animation-delay, bo fill-mode to none). visibility:hidden wyłącza naraz
   wyświetlanie, trafienia myszą i kolejność tabulacji. Interpolacja visibility
   trzyma wartość „visible" przez cały odcinek przejścia, więc zanikanie
   i pojawianie się dalej widać płynnie. */
.topbar--rotator{position:relative;height:34px;padding:0;overflow:hidden}
.topbar--rotator .topbar__slajd{position:absolute;inset:0;line-height:34px;text-align:center;padding:0 12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#d6d6d3;opacity:0;visibility:hidden;animation:topbar-obrot 12s linear infinite}
/* bezpiecznik: gdy animacje w ogóle nie działają (reduced-motion, wyłączone
   animacje w przeglądarce), pasek pokazuje pierwszy slajd zamiast pustki.
   Deklaracje z keyframes i tak biją zwykłe reguły autora, więc przy działającej
   animacji ta reguła niczego nie psuje. */
.topbar--rotator .topbar__slajd:first-child{opacity:1;visibility:visible}
.topbar--rotator .topbar__slajd b{color:#fff}
.topbar--rotator .topbar__slajd:hover{color:#fff}
.topbar--rotator .topbar__slajd:nth-child(2){animation-delay:4s}
.topbar--rotator .topbar__slajd:nth-child(3){animation-delay:8s}
.topbar--rotator:hover .topbar__slajd,.topbar--rotator:focus-within .topbar__slajd{animation-play-state:paused}
@keyframes topbar-obrot{
  0%{opacity:0;visibility:hidden}
  1.5%{opacity:1;visibility:visible}
  31%{opacity:1;visibility:visible}
  33%{opacity:0;visibility:hidden}
  100%{opacity:0;visibility:hidden}
}
@media (prefers-reduced-motion:reduce){
  .topbar--rotator .topbar__slajd{animation:none}
}

/* karuzela kafli produktowych: 5 w widoku desktop, scroll-snap, strzałki;
   scrollbar ukryty, ale tor dalej przewijalny (kółko/gest).

   Kontrakt markupu: tor ZAWSZE siedzi wewnątrz .karuzela
   (front-page.php i inc/pdp.php renderują <div class="karuzela"> … </div>),
   a przy kaflach Woo torem jest <ul class="products karuzela__tor">.
   Siatka gridowa dla ul.products (blok „siatka produktów Woo" niżej) CELOWO
   omija tory karuzel przez :not(.karuzela__tor) — dzięki temu obie rodziny
   reguł nigdy nie walczą o ten sam element i kolejność w pliku nic nie zmienia. */
.karuzela{position:relative}
.karuzela__tor{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;scrollbar-width:none;-ms-overflow-style:none;padding:2px}
.karuzela__tor::-webkit-scrollbar{display:none}
.karuzela .karuzela__tor>*{flex:none;width:calc((100% - 4 * 14px) / 5);scroll-snap-align:start}
/* kafle Woo w torze — muszą przebić woocommerce-layout.css, który narzuca
   li.product float:left i szerokość procentową (22,05% = dwa kafle na tor):
     .woocommerce ul.products li.product                                (0,3,2)
     .woocommerce ul.products.columns-1…6 li.product                    (0,4,2)
     .woocommerce ul.products[class*=columns-] li.product:nth-child(2n) (0,5,2)
   Nasza reguła ma (0,6,2) — powtórzona klasa .product — więc wygrywa niezależnie
   od kolejności arkuszy. Zamiast !important podniesiony selektor (bez wyjątków
   do pilnowania), zgodnie z zasadą motywu.

   🔴 RUNDA 5 — BEZ PRZEDROSTKA :is(.woocommerce,.woocommerce-page). Do 0.1.2
   obie reguły zaczynały się od klasy <body>, której STRONA GŁÓWNA NIE MA
   (front-page.php to zwykła strona, nie widok Woo). Skutek: na głównej tor
   wracał do `.karuzela__tor` (0,1,0), a to przegrywa z `ul.products{padding:0}`
   (0,1,1) stojącym niżej w tym pliku — tor tracił swoje 2 px oddechu. Ponieważ
   tor ma overflow-x:auto (a to przycina także w pionie), cień .prod:hover był
   na głównej obcinany przy krawędziach, a na kategorii i karcie produktu nie:
   ta sama karuzela wyglądała inaczej na dwóch typach stron.
   Utracony przedrostek zastępuje POWTÓRZONA klasa .products — specyficzność
   zostaje ta sama ((0,4,1) i (0,6,2)), a reguły działają wszędzie tam, gdzie
   jest markup karuzeli, niezależnie od klas <body>. */
.karuzela ul.products.products.karuzela__tor{display:flex;margin:0;padding:2px}
.karuzela ul.products.products.karuzela__tor>li.product.product{flex:none;width:calc((100% - 4 * 14px) / 5);max-width:none;min-width:0;margin:0;padding:0;float:none;clear:none;scroll-snap-align:start}
.karuzela__strzalka{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:50%;background:#fff;border:1px solid var(--linia);box-shadow:var(--cien);display:grid;place-items:center;cursor:pointer;z-index:5;padding:0}
.karuzela__strzalka svg{width:18px;height:18px;stroke:var(--tusz)}
.karuzela__strzalka:hover{border-color:var(--zielen)}
.karuzela__strzalka--lewa{left:-10px}
.karuzela__strzalka--prawa{right:-10px}
/* tor krótszy niż widok = nie ma czego przewijać. Klasę nadaje i zdejmuje
   motyw.js (moduł karuzel, przy starcie, po `load` i po zmianie rozmiaru okna),
   bo próg 5/3/2 kafli zmienia się razem z media queries. Bez tego sekcja
   „Podobne produkty" z trzema kaflami albo kategoria z czterema produktami
   pokazywały dwa aktywne kółka, których kliknięcie nic nie robiło.
   display:none, a nie samo wygaszenie: przycisk bez działania nie ma też
   trafiać do kolejności tabulacji ani do czytnika ekranu. */
.karuzela--bez-strzalek .karuzela__strzalka{display:none}
/* „Podobne produkty" na karcie produktu: nagłówek sekcji stoi PRZED .karuzela
   (wyjmuje go z markupu Woo inc/pdp.php), dokładnie jak na stronie głównej —
   inaczej strzałki z top:50% środkowałyby się na bloku obejmującym nagłówek
   (zmierzone 20.08: środek strzałki 18 px nad środkiem kafla).
   Kreska nad nagłówkiem powtarza rytm sekcji opisu (.pdp-sekcja). */
.sekcja__naglowek--powiazane{border-top:1px solid var(--linia);padding-top:26px;margin-top:8px}
.karuzela--powiazane{margin-bottom:10px}

/* kafel bogaty: drugie zdjęcie na hover + swatche wariantów.
   position:relative na .prod__foto jest układem odniesienia dla OBU zdjęć kafla
   (patrz blok „kafel produktu" wyżej — po poprawce B3 z przepływu wypada także
   zdjęcie główne). Pozycjonowanie i skalowanie drugiego zdjęcia zapewnia tamta
   reguła; tu zostaje samo przenikanie na hover. */
.prod__foto{position:relative}
.prod__foto .prod__foto-drugie{opacity:0;transition:opacity .25s}
.prod:hover .prod__foto-drugie{opacity:1}

/* Zdjecie glowne MUSI sie chowac, a nie tylko dawac sie przykryc. Wczesniej
   drugie zdjecie wjezdzalo na wierzch - przy zdjeciach z bialym tlem nikt tego
   nie widzial, ale produkty z PRZEZROCZYSTYM tlem przeswitywaly i na hoverze
   pokazywaly dwa obrazy naraz (zgloszone 26.08).

   Warunek :has(.prod__foto-drugie) jest konieczny, nie ozdobny: bez niego kafel
   z jednym zdjeciem robilby sie na hoverze PUSTY. Chowamy glowne zdjecie
   wylacznie wtedy, gdy jest czym je zastapic. */
.prod__foto:has(.prod__foto-drugie)>img:not(.prod__foto-drugie){transition:opacity .25s}
.prod:hover .prod__foto:has(.prod__foto-drugie)>img:not(.prod__foto-drugie){opacity:0}
.prod__swatche{display:flex;align-items:center;gap:6px;margin-top:6px}
.prod__swatche span{width:16px;height:16px;border-radius:50%;border:1px solid var(--linia);flex:none}
.prod__swatche small{color:var(--tusz-2);font-size:12px;margin-left:2px}

/* suwak ceny: dwa range nałożone na siebie, wypełnienie toru przez --p-min/--p-max (ustawia JS) */
.suwak-ceny{--p-min:10%;--p-max:70%;display:flex;flex-direction:column;gap:10px}
.suwak-ceny__tor{position:relative;height:24px}
.suwak-ceny__tor::before{content:"";position:absolute;left:0;right:0;top:50%;height:6px;transform:translateY(-50%);border-radius:3px;background:linear-gradient(to right,var(--linia) var(--p-min),var(--akcent) var(--p-min),var(--akcent) var(--p-max),var(--linia) var(--p-max))}
.suwak-ceny__tor input[type=range]{position:absolute;inset:0;width:100%;height:100%;margin:0;-webkit-appearance:none;appearance:none;background:none;pointer-events:none}
.suwak-ceny__tor input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;border-radius:50%;background:#fff;border:2px solid var(--zielen);box-shadow:var(--cien);pointer-events:auto;cursor:grab}
.suwak-ceny__tor input[type=range]::-moz-range-track{background:none;border:0}
.suwak-ceny__tor input[type=range]::-moz-range-thumb{width:20px;height:20px;border-radius:50%;background:#fff;border:2px solid var(--zielen);box-shadow:var(--cien);pointer-events:auto;cursor:grab}
.suwak-ceny__pola{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--tusz-2)}
.suwak-ceny__pola input[type=number]{width:76px;padding:8px 10px;border:1.5px solid var(--linia);border-radius:var(--r-s);font-size:14px;color:var(--tusz)}
.suwak-ceny__pola input[type=number]:focus{outline:none;border-color:var(--zielen)}

/* raty PayU w buyboksie — ramka; treść renderuje wtyczkowy widget PayU
   (adaptacja kontenera wtyczki na końcu pliku, bez własnej tabelki rat) */
.raty-payu{border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;margin:12px 0;font-size:14px}
.raty-payu summary{display:flex;align-items:center;gap:10px;padding:11px 14px;cursor:pointer;list-style:none;font-weight:600}
.raty-payu summary::-webkit-details-marker{display:none}
.raty-payu summary::after{content:"▾";margin-left:auto;color:var(--tusz-2)}
.raty-payu[open] summary::after{content:"▴"}
.raty-payu .platnosc{border:1px solid var(--linia);flex:none}
.raty-payu__tresc{padding:0 14px 12px}
.raty-payu__tresc p{color:var(--tusz-2);font-size:13px}

/* pasek postępu do darmowej dostawy (próg 200 zł); wypełnienie stylem inline */
.pasek-dostawy{font-size:13px;color:var(--tusz-2)}
.pasek-dostawy b{color:var(--tusz)}
.pasek-dostawy__tekst{display:block;margin-bottom:6px}
.pasek-dostawy__tor{height:8px;background:var(--linia);border-radius:4px;overflow:hidden}
.pasek-dostawy__tor i{display:block;height:100%;background:var(--akcent);border-radius:4px}
.pasek-dostawy--pelny .pasek-dostawy__tekst{color:var(--ok);font-weight:600}

/* drawer mini-koszyka (wysuwany z prawej) — klasy prototypu; produkcyjny
   drawer to blok Woo Mini-Cart stylowany w bloki.css tym samym wyglądem */
.drawer__tlo{position:fixed;inset:0;background:rgba(10,14,11,.55);z-index:80}
.drawer__tlo[hidden]{display:none}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(400px,100%);background:#fff;z-index:90;transform:translateX(100%);transition:transform .25s;display:flex;flex-direction:column;overflow-y:auto;box-shadow:-8px 0 30px rgba(21,26,23,.18)}
.drawer--otwarty{transform:translateX(0)}
.drawer__naglowek{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--linia)}
.drawer__naglowek h3{font-size:17px}
.drawer__zamknij{border:0;background:none;font-size:26px;line-height:1;cursor:pointer;color:var(--tusz-2);padding:2px 8px}
.drawer__zamknij:hover{color:var(--tusz)}
.drawer .pasek-dostawy{padding:14px 18px;border-bottom:1px solid var(--linia)}
.drawer__pozycje{padding:0 18px}
.drawer__pozycja{display:flex;gap:12px;align-items:center;padding:14px 0;border-bottom:1px solid var(--linia)}
.drawer__pozycja img{width:64px;height:64px;object-fit:contain;background:var(--tlo-2);border-radius:var(--r-s);flex:none}
.drawer__pozycja b{display:block;font-size:14px;line-height:1.35}
.drawer__pozycja small{color:var(--tusz-2)}
.drawer__cena{margin-left:auto;font-weight:700;white-space:nowrap}
.drawer__dosprzedaz{margin:14px 18px;border:1.5px dashed var(--akcent);border-radius:var(--r-s);padding:12px;display:flex;gap:10px;align-items:center;font-size:13.5px}
.drawer__dosprzedaz img{width:48px;height:48px;object-fit:contain;background:var(--tlo-2);border-radius:var(--r-s);flex:none}
.drawer__dosprzedaz .btn{margin-left:auto;flex:none}
.drawer__stopka{margin-top:auto;position:sticky;bottom:0;background:#fff;border-top:1px solid var(--linia);padding:14px 18px;display:flex;flex-direction:column;gap:8px}
.drawer__stopka .btn{width:100%}
.drawer__suma{display:flex;justify-content:space-between;align-items:baseline;font-size:14.5px;margin-bottom:2px}
.drawer__suma b{font-size:18px}

/* wskaźnik kroków checkoutu: aktywny --zielen, przyszły szary, łączniki liniami */
.kroki{list-style:none;display:flex;align-items:center;justify-content:center;margin:22px 0;font-size:14px;font-weight:600;color:var(--tusz-2)}
.kroki__krok{display:flex;align-items:center;gap:8px}
.kroki__krok span{width:30px;height:30px;border-radius:50%;background:var(--linia);color:var(--tusz-2);display:grid;place-items:center;font-weight:700;font-size:14px}
.kroki__krok+.kroki__krok::before{content:"";width:46px;height:2px;background:var(--linia);margin:0 12px}
.kroki__krok--aktywny{color:var(--zielen)}
.kroki__krok--aktywny span{background:var(--zielen);color:#fff}

/* order bump w checkoucie — checkbox DOMYŚLNIE ODZNACZONY (art. 22 dyr. 2011/83/UE) */
.order-bump{display:flex;gap:12px;align-items:center;border:2px solid var(--akcent);background:var(--zielen-tlo);border-radius:var(--r);padding:14px 16px;cursor:pointer;font-size:14.5px;margin:14px 0}
.order-bump input[type=checkbox]{width:18px;height:18px;accent-color:var(--akcent-2);flex:none}
.order-bump img{width:56px;height:56px;object-fit:contain;background:#fff;border-radius:var(--r-s);border:1px solid var(--linia);flex:none}
.order-bump__tekst small{display:block;color:var(--tusz-2);font-size:12px;margin-top:2px}
.order-bump__cena{display:block;font-weight:800;margin-top:2px}
.order-bump__cena s{color:var(--tusz-2);font-weight:500;font-size:13px;margin-right:6px}

/* metody płatności: radio-karty (klasy prototypu — produkcyjne radio-karty
   bloków checkoutu styluje bloki.css tym samym wyglądem) */
.platnosci{display:flex;flex-direction:column;gap:10px}
.platnosci__karta{display:grid;grid-template-columns:auto auto 1fr;align-items:center;gap:8px 12px;border:2px solid var(--linia);border-radius:var(--r);padding:14px 16px;cursor:pointer;background:#fff;transition:border-color .15s,background .15s}
.platnosci__karta:has(:checked){border-color:var(--zielen);background:var(--zielen-tlo)}
.platnosci__karta input[type=radio]{width:18px;height:18px;accent-color:var(--zielen)}
.platnosci__karta .platnosc{border:1px solid var(--linia);justify-self:start}
.platnosci__opis{font-size:13px;color:var(--tusz-2)}
.platnosci__blik{grid-column:2/-1}
.platnosci__blik input{width:190px;height:44px;padding:0 14px;border:1.5px solid var(--linia);border-radius:var(--r-s);font-size:16px;letter-spacing:.18em;font-variant-numeric:tabular-nums;background:#fff}
.platnosci__blik input:focus{outline:none;border-color:var(--zielen)}

/* rządek wybranego Paczkomatu (mapa jest wtyczkowa — modal Geowidget InPost) */
.geowidget{border:1px solid var(--linia);border-radius:var(--r);overflow:hidden;background:#fff}
.geowidget__mapa{height:220px;background:var(--tlo-2)}
.geowidget__mapa svg{width:100%;height:100%;display:block}
.geowidget__punkt{display:flex;align-items:center;gap:10px;padding:12px 16px;font-size:14px;border-top:1px solid var(--linia);flex-wrap:wrap}
.geowidget__punkt .btn{margin-left:auto}

/* przedsprzedaż: plakietka + odliczanie do premiery (stała szerokość segmentów = zero CLS) */
.plakietka--preorder{background:var(--zielen);color:#5adfd4}
.odliczanie-premiery{display:flex;gap:10px;margin:14px 0}
.odliczanie-premiery__segment{width:74px;text-align:center;background:var(--tlo-2);border:1px solid var(--linia);border-radius:var(--r-s);padding:10px 0 8px}
.odliczanie-premiery__segment b{display:block;font-size:26px;line-height:1.15;font-variant-numeric:tabular-nums}
.odliczanie-premiery__segment small{color:var(--tusz-2);font-size:11.5px;text-transform:uppercase;letter-spacing:.05em}

/* szkielet sekcji wideo na kartę produktu */
.wideo-szkielet{aspect-ratio:16/9;background:linear-gradient(115deg,var(--zielen),var(--zielen-2));border-radius:var(--r);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;color:#d6d6d3}
.wideo-szkielet__play{width:72px;height:72px;border-radius:50%;background:#fff;border:0;display:grid;place-items:center;cursor:pointer;box-shadow:var(--cien)}
.wideo-szkielet__play:hover{background:var(--akcent)}
.wideo-szkielet__play svg{width:26px;height:26px;margin-left:5px;fill:var(--zielen)}
.wideo-szkielet small{font-size:13.5px}

/* responsywność karuzel/drawera/kroków */
@media(max-width:980px){
  /* 3 kafle w torze — oba warianty osobno (patrz komentarz przy karuzeli);
     nie łączymy ich w jedną listę selektorów, żeby ewentualny brak wsparcia
     dla :is() nie unieważnił także reguły podstawowej.
     🔴 RUNDA 5: wariant dla kafli Woo stracił przedrostek :is(.woocommerce,…)
     — dokładnie jak reguła bazowa toru — bo bez tego na stronie głównej
     (brak klasy .woocommerce na <body>) baza (0,6,2) biła tę media query
     i tor zostawał pięciokafelkowy na tablecie. */
  .karuzela .karuzela__tor>*{width:calc((100% - 2 * 14px) / 3)}
  .karuzela ul.products.products.karuzela__tor>li.product.product{width:calc((100% - 2 * 14px) / 3)}
}
@media(max-width:640px){
  /* 2,2 kafla — użytkownik widzi, że tor da się przewinąć */
  .karuzela .karuzela__tor>*{width:44%}
  .karuzela ul.products.products.karuzela__tor>li.product.product{width:44%}
  .karuzela__strzalka{display:none}
  .drawer{width:100%}
  .kroki{font-size:12.5px}
  .kroki__krok span{width:26px;height:26px;font-size:12.5px}
  .kroki__krok+.kroki__krok::before{width:16px;margin:0 8px}
  .odliczanie-premiery__segment{width:62px}
  .odliczanie-premiery__segment b{font-size:21px}
  .platnosci__blik input{width:100%}
}

/* ---------- KOSZYK I ZAMÓWIENIE (klasy prototypu — bloki produkcyjne w bloki.css) ---------- */

/* układ dwukolumnowy: treść po lewej + podsumowanie sticky po prawej */
.uklad-zakupy{display:grid;grid-template-columns:1fr 360px;gap:26px;align-items:start;margin-top:10px}
.uklad-zakupy .pasek-dostawy{margin-bottom:14px}
.powrot{display:inline-block;font-size:13px;color:var(--tusz-2);margin-bottom:8px}

/* lista pozycji koszyka */
.koszyk-pozycje{background:#fff;border:1px solid var(--linia);border-radius:var(--r)}
.pozycja{display:grid;grid-template-columns:88px 1fr auto auto;grid-template-areas:"foto info stepper cena";gap:14px;align-items:center;padding:16px;border-bottom:1px solid var(--linia)}
.pozycja:last-child{border-bottom:0}
.pozycja__foto{grid-area:foto;width:88px;aspect-ratio:1;display:grid;place-items:center;background:var(--tlo-2);border-radius:var(--r-s);padding:6px}
.pozycja__foto img{max-height:100%;object-fit:contain}
.pozycja__info{grid-area:info;min-width:0}
.pozycja__nazwa{display:block;font-weight:600;color:var(--tusz);font-size:14.5px;line-height:1.35}
.pozycja__info small{color:var(--tusz-2);font-size:12.5px}
.pozycja__usun{display:inline-block;border:0;background:none;padding:0;margin-top:4px;font-size:13px;color:var(--tusz-2);text-decoration:underline;cursor:pointer}
.pozycja__usun:hover{color:var(--blad)}
.pozycja .stepper{grid-area:stepper}
.pozycja__cena{grid-area:cena;font-weight:800;font-size:16px;white-space:nowrap}

/* stepper ilości (−/+) */
.stepper{display:inline-flex;align-items:center;border:1.5px solid var(--linia);border-radius:999px;background:#fff}
.stepper button{width:34px;height:34px;border:0;background:none;font-size:17px;line-height:1;cursor:pointer;color:var(--tusz);border-radius:50%}
.stepper button:hover{background:var(--tlo-2)}
.stepper span{min-width:28px;text-align:center;font-weight:700;font-variant-numeric:tabular-nums}

/* kod rabatowy (details) */
.kod-rabatowy{border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;margin:14px 0}
.kod-rabatowy summary{padding:12px 16px;font-weight:600;font-size:14px;cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center}
.kod-rabatowy summary::-webkit-details-marker{display:none}
.kod-rabatowy summary::after{content:"▾";color:var(--tusz-2)}
.kod-rabatowy[open] summary::after{content:"▴"}
.kod-rabatowy__pola{display:flex;gap:8px;padding:0 16px 14px}
.kod-rabatowy__pola input{flex:1;min-width:0;padding:10px 14px;border:1.5px solid var(--linia);border-radius:999px;font-size:14px}
.kod-rabatowy__pola input:focus{outline:none;border-color:var(--zielen)}

/* cross-sell w kolumnie pozycji: siatka 3 kafli */
.siatka-prod--3{grid-template-columns:repeat(3,1fr)}
.koszyk-crosssell{margin-top:28px}
.koszyk-crosssell h2{font-size:20px;margin-bottom:14px}

/* podsumowanie (sticky na desktopie; top = wysokość sticky nagłówka) */
.podsumowanie{position:sticky;top:130px;background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:20px}
.podsumowanie h2{font-size:18px;margin-bottom:10px}
.podsumowanie__pozycja{display:flex;gap:10px;align-items:center;padding:8px 0 12px;border-bottom:1px solid var(--linia);margin-bottom:6px;font-size:13.5px}
.podsumowanie__pozycja img{width:48px;height:48px;object-fit:contain;background:var(--tlo-2);border-radius:var(--r-s);flex:none}
.podsumowanie__pozycja b{font-weight:600;line-height:1.35}
.podsumowanie__pozycja .cena{margin-left:auto;font-weight:700;white-space:nowrap}
.podsumowanie__rzad{display:flex;justify-content:space-between;gap:12px;font-size:14.5px;padding:5px 0;color:var(--tusz-2)}
.podsumowanie__rzad b{color:var(--tusz);white-space:nowrap}
.podsumowanie__suma{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--linia);margin-top:8px;padding-top:12px;font-weight:700}
.podsumowanie__suma b{font-size:22px}
.podsumowanie .btn{width:100%;margin-top:14px}
.podsumowanie__drobne{display:block;color:var(--tusz-2);font-size:12.5px;margin-top:10px;line-height:1.5}
.podsumowanie .zaufanie-mini{grid-template-columns:1fr 1fr;margin:14px 0 0}

/* formularz zamówienia */
.form-sekcja{background:#fff;border:1px solid var(--linia);border-radius:var(--r);padding:20px;margin-bottom:16px}
.form-sekcja>h2{font-size:18px;margin-bottom:4px}
.form-sekcja__nota{color:var(--tusz-2);font-size:13.5px;margin-bottom:14px}
.pole{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.pole label{font-size:13.5px;font-weight:600}
.pole input{padding:11px 14px;border:1.5px solid var(--linia);border-radius:var(--r-s);font-size:15px;background:#fff}
.pole input:focus{outline:none;border-color:var(--zielen)}
.pole small{color:var(--tusz-2);font-size:12.5px}
.pola-rzad{display:grid;grid-template-columns:1fr 1fr;gap:0 12px}
.wymagane{color:var(--blad)}

/* dostawa: radio-karty (wzorzec jak .platnosci__karta), rozwinięcie przez :has(:checked) */
.dostawa{display:flex;flex-direction:column;gap:10px}
.dostawa__karta{border:2px solid var(--linia);border-radius:var(--r);background:#fff;transition:border-color .15s,background .15s}
.dostawa__karta:has(input[type=radio]:checked){border-color:var(--zielen);background:var(--zielen-tlo)}
.dostawa__wybor{display:flex;align-items:center;gap:12px;padding:14px 16px;cursor:pointer}
.dostawa__wybor input[type=radio]{width:18px;height:18px;accent-color:var(--zielen);flex:none}
.dostawa__nazwa b{display:block;font-size:14.5px}
.dostawa__nazwa small{color:var(--tusz-2);font-size:12.5px}
.dostawa__cena{margin-left:auto;font-weight:700;white-space:nowrap}
.dostawa__rozwiniecie{display:none;padding:0 16px 16px}
.dostawa__karta:has(input[type=radio]:checked) .dostawa__rozwiniecie{display:block}

/* zgody + finał zamówienia */
.zgody{display:flex;flex-direction:column;gap:10px;font-size:14px}
.zgody label{display:flex;gap:10px;align-items:flex-start;cursor:pointer;line-height:1.45}
.zgody input[type=checkbox]{width:18px;height:18px;accent-color:var(--zielen);flex:none;margin-top:2px}
.zgody small{display:block;color:var(--tusz-2);font-size:12.5px}
.kup-final .btn{width:100%;font-size:16.5px;padding:15px 26px}
.nota-platnosci{display:flex;gap:8px;align-items:center;justify-content:center;color:var(--tusz-2);font-size:12.5px;margin-top:10px;text-align:center}
.nota-platnosci svg{width:16px;height:16px;flex:none;stroke:var(--akcent-2)}

/* placeholder miniatury w order bumpie (produkt bez zdjęcia) */
.order-bump__brak{width:56px;aspect-ratio:1;display:grid;place-items:center;background:var(--tlo-2);border:1px solid var(--linia);border-radius:var(--r-s);font-size:26px;flex:none}

/* responsywność koszyka i zamówienia */
@media(max-width:980px){
  .uklad-zakupy{grid-template-columns:1fr}
  .podsumowanie{position:static}
}
@media(max-width:640px){
  .pozycja{grid-template-columns:72px 1fr auto;grid-template-areas:"foto info info" "foto stepper cena";align-items:start;gap:10px 12px}
  .pozycja__foto{width:72px}
  .pozycja .stepper{align-self:center;justify-self:start}
  .pozycja__cena{align-self:center}
  .siatka-prod--3{grid-template-columns:repeat(2,1fr)}
  .pola-rzad{grid-template-columns:1fr}
}

/* ============================================================
   ADAPTACJE WORDPRESS / WOOCOMMERCE
   Markup generowany przez WP/Woo dostaje wygląd design systemu.
   ============================================================ */

/* --- drobiazgi WP: pasek admina nad sticky nagłówkiem, klasa czytników ekranu --- */
.admin-bar .naglowek{top:32px}
@media(max-width:782px){.admin-bar .naglowek{top:46px}}
/* 🔑 Ponizej 600 px rdzen WordPressa przestawia #wpadminbar na position:absolute
   (wp-includes/css/admin-bar.css) — pasek odjezdza z ekranem zamiast wisiec u gory.
   Nasze `top:46px` zostawialo wtedy pusta luke nad przyklejonym naglowkiem przez
   cala dlugosc strony. Widzieli to WYLACZNIE zalogowani; klient ma tu zero. */
@media(max-width:600px){.admin-bar .naglowek{top:0}}
.screen-reader-text{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);word-wrap:normal}

/* --- kontener treści szablonów WooCommerce (karta produktu) ---
   Motyw ŚWIADOMIE nie ma single-product.php: kartę produktu renderuje szablon
   wtyczki, a ten opakowuje treść w global/wrapper-start.php, czyli
   <div id="primary" class="content-area"><main id="main" class="site-main">.
   Nasza klasa .srodek na te elementy nie wchodzi (nie wypisuje ich żaden nasz
   szablon), więc do 19.08 karta produktu leciała od krawędzi do krawędzi okna,
   podczas gdy nagłówek i stopka trzymały 1200 px. Tu odtwarzamy .srodek
   na kontenerze wtyczki — obejmuje też sekcje .pdp-sekcja i karuzelę
   „Podobne produkty", bo obie renderują się w środku tego wrappera. */
#primary.content-area{max-width:var(--max);margin:0 auto;padding:0 20px}

/* --- podpowiedzi szukajki: stan „otwarte" nadaje i zdejmuje motyw.js ---
   (jedyny przełącznik widoczności listy — patrz komentarz przy .szukaj__wyniki) */
.szukaj__wyniki--otwarte{display:block}
.szukaj__wynik b{font-size:14px}

/* --- siatka produktów Woo: ul.products = .siatka-prod, li = .prod ---
   Kafle renderuje woocommerce/content-product.php klasami prototypu;
   tu zerujemy listę i domyślne style Woo (float, szerokości, marginesy).

   Dlaczego selektory są tak rozbudowane: arkusz woocommerce-layout.css układa
   listing na floatach i szerokościach procentowych —
     .woocommerce ul.products li.product{width:22.05%;float:left}        (0,3,2)
     .woocommerce ul.products.columns-1…6 li.product{width:…}            (0,4,2)
     .woocommerce ul.products[class*=columns-] li.product (smallscreen)  (0,4,2)
     …ta sama reguła z :nth-child(2n)                                    (0,5,2)
   — i przy równej/wyższej specyficzności bije proste `ul.products li.prod` (0,2,2).
   Skutkiem był kafel szerokości 22% komórki gridu (zmierzone na żywo 19.08).
   Motyw zdejmuje oba arkusze Woo (inc/zasoby.php), ale ma zostać sprawny także
   wtedy, gdy któryś wróci wczytany przez wtyczkę — dlatego reguły siatki mają
   specyficzność (0,6,2) (powtórzona klasa .products/.product) i wygrywają
   niezależnie od kolejności arkuszy. Zamiast !important podniesiony selektor.
   Warianty .columns-1…6 są dla nas bez znaczenia: liczbę kolumn ustala grid.
   Tory karuzel wyłączamy przez :not(.karuzela__tor) — mają własne szerokości
   slajdów w bloku „karuzela kafli produktowych". */
ul.products{list-style:none;margin:0;padding:0}
/* 🔴 RUNDA 4 (P7): pseudoelementy czyszczące floaty z arkusza woocommerce-general.
   Woo trzyma `.woocommerce ul.products::after,.woocommerce ul.products::before
   {content:" ";display:table}` (0,2,2), a nasze `ul.products::before/::after`
   miało (0,1,2) — przegrywało. W kontenerze display:grid oba pseudoelementy
   stają się PEŁNOPRAWNYMI KOMÓRKAMI: zmierzone na kategorii gridTemplateColumns
   4×279,5 px, ::before i ::after po 279,5 px, pierwszy li.product startował
   na x=434 (kolumna 2), a czwarty produkt spadał do drugiego rzędu — pierwszy
   wiersz pokazywał 3 kafle zamiast 4. W torach karuzel (display:flex) te same
   pseudoelementy miały szerokość 0, ale dokładały dwie przerwy gap po 14 px,
   przez co tor startował 14 px od krawędzi.
   Dlatego druga reguła ma (0,3,2) — wygrywa i obejmuje OBA warianty toru
   (siatkę i karuzelę), bo pseudoelement jest szkodliwy w każdym z nich.
   Strony bez klasy .woocommerce na <body> (m.in. strona główna) reguły Woo
   w ogóle nie dotyczyły — stąd pomiar 0.1.1 tego nie złapał. */
ul.products::before,ul.products::after{content:none}
:is(.woocommerce,.woocommerce-page) ul.products.products::before,
:is(.woocommerce,.woocommerce-page) ul.products.products::after{content:none;display:none}
ul.products:not(.karuzela__tor){display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
ul.products:not(.karuzela__tor)>li{float:none;clear:none;width:auto;max-width:none;min-width:0;margin:0;padding:0}
:is(.woocommerce,.woocommerce-page) ul.products.products:not(.karuzela__tor){display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:0;padding:0;float:none}
:is(.woocommerce,.woocommerce-page) ul.products.products:not(.karuzela__tor)>li.product.product{float:none;clear:none;width:auto;max-width:none;min-width:0;margin:0;padding:0}
/* 🔴 RUNDA 4 (P9): wewnętrzny margines kafla WRACA po zerowaniu reguł Woo.
   `.prod{padding:14px}` ma (0,1,0) i przegrywało z trzema własnymi regułami
   motywu — `ul.products:not(.karuzela__tor)>li` (0,2,2),
   `:is(…) ul.products.products:not(.karuzela__tor)>li.product.product` (0,6,2)
   oraz bliźniaczą regułą toru karuzeli w bloku „karuzela kafli produktowych".
   Zmierzone w Chrome: padding kafla 0 px przy ramce 1 px i promieniu 14 px,
   czyli zdjęcie i nazwa produktu dotykały ramki. Samo usunięcie `padding:0`
   z tamtych reguł NIE wystarczy: woocommerce-layout trzyma własne
   `.woocommerce ul.products li.product{padding:0}` (0,3,2), a arkusz może
   wrócić wczytany przez wtyczkę — dlatego zerowanie zostaje, a padding
   przywraca osobna reguła o wyższej specyficzności.
   Kolejność klas: `ul.products.products>li.product.product.prod.prod.prod`
   = 7 klas (0,7,2), czyli ponad każdą z powyższych — bez remisu, więc kolejność
   w pliku nic nie zmienia.
   Selektor CELOWO nie wyklucza .karuzela__tor — kafel ma wyglądać tak samo
   na listingu i w karuzeli („Podobne produkty", karuzele strony głównej).

   🔴 RUNDA 5 — JEDEN SELEKTOR ZAMIAST DWÓCH. Wcześniej padding wracał parą
   reguł: (0,7,2) z przedrostkiem :is(.woocommerce,.woocommerce-page) dla stron
   sklepu i (0,4,2) bez przedrostka dla strony głównej. Ten drugi wariant był
   za słaby — gdy reguły toru karuzeli przestały wisieć na klasie <body>
   (poprawka 2 px oddechu w bloku „karuzela kafli produktowych"), ich (0,6,2)
   z `padding:0` zaczęłoby zerować margines kafli na stronie głównej.
   Powtórzenie klasy .prod daje (0,7,2) na KAŻDEJ stronie, bez zależności od
   klas <body> i bez remisów. */
ul.products.products>li.product.product.prod.prod.prod{padding:14px}
@media(max-width:980px){
  ul.products:not(.karuzela__tor){grid-template-columns:repeat(3,1fr)}
  :is(.woocommerce,.woocommerce-page) ul.products.products:not(.karuzela__tor){grid-template-columns:repeat(3,1fr)}
}
@media(max-width:640px){
  ul.products:not(.karuzela__tor){grid-template-columns:repeat(2,1fr)}
  :is(.woocommerce,.woocommerce-page) ul.products.products:not(.karuzela__tor){grid-template-columns:repeat(2,1fr)}
}

/* --- plakietka „Promocja!" Woo ukryta: mamy własne plakietki z Omnibusem --- */
.onsale{display:none}

/* --- gwiazdki Woo: przemalowane na #f5a623, bez zależności od fontu „star" ---
   Markup Woo: <div class="star-rating"><span style="width:X%">…</span></div>.
   Rysujemy ★★★★★ zwykłym tekstem: szary spód + pomarańczowe wypełnienie
   przycięte szerokością span (procent oceny). */
.star-rating{position:relative;display:inline-block;overflow:hidden;font-family:inherit;font-size:14px;line-height:1.1;letter-spacing:2px;white-space:nowrap;width:auto;height:auto;color:#f5a623}
.star-rating::before{content:"★★★★★";color:var(--linia);float:none}
.star-rating span{position:absolute;top:0;left:0;overflow:hidden;white-space:nowrap;padding-top:1.5em;height:0}
.star-rating span::before{content:"★★★★★";color:#f5a623;position:absolute;top:0;left:0}
.prod .star-rating{font-size:12.5px}
/* gwiazdki wyboru oceny w formularzu opinii (Woo rysuje linki 1–5) */
p.stars a{color:#f5a623;text-decoration:none}

/* --- buybox karty produktu: <div class="summary"> z szablonu Woo ---
   Druga kolumna .uklad-pdp (opakowanie zakłada inc/pdp.php na hookach
   woocommerce_before/after_single_product_summary). min-width:0 jest tu
   obowiązkowe — bez tego długa nazwa produktu albo szeroka tabelka wariantów
   rozpycha kolumnę gridu i wypycha galerię poza kontener.
   Typografia tytułu i ceny jak .buybox h1 / .buybox__cena z prototypu. */
.woocommerce div.product .summary{min-width:0;margin:0}
.woocommerce div.product .summary>.product_title{font-size:clamp(22px,3vw,30px);margin-bottom:6px}
.woocommerce div.product .summary>p.price{font-size:32px;font-weight:800;margin:6px 0 2px;color:var(--tusz)}
.woocommerce div.product .summary>p.price del{font-size:19px;color:var(--tusz-2);font-weight:500;margin-right:10px;opacity:1}
.woocommerce div.product .summary>p.price ins{color:var(--akcent-tekst);text-decoration:none;font-weight:800}

/* --- galeria produktu Woo: funkcjonalność wtyczkowa (zoom/lightbox/slider),
   motyw dokłada kwadrat, ramki, miniatury i strzałki jak .galeria z prototypu ---

   🔴 RUNDA 4 (P4) — trzy zgłoszenia Pawła naraz: zdjęcie główne ZAWSZE
   kwadratowe i całe widoczne, miniatury w jednej linii, strzałki ‹ › na
   zdjęciu głównym.

   1) DLACZEGO POWTÓRZONE KLASY. Motyw zdejmuje woocommerce-layout, ale
   woocommerce-general zostaje (inc/zasoby.php) i trzyma dla WNĘTRZA galerii
   rodzinę reguł zakotwiczoną w `div.product div.images`:
     .woocommerce div.product div.images img                          (0,3,3)
     .woocommerce div.product div.images .flex-control-thumbs         (0,4,2)
     .woocommerce div.product div.images .flex-control-thumbs li      (0,4,3)
     .woocommerce div.product div.images .flex-control-thumbs li img  (0,4,4)
   ⚠ PUŁAPKA LICZENIA, na której ta poprawka wyłożyła się dwa razy:
   `div.product` i `div.images` dokładają KLASY .product i .images (nie tylko
   elementy), a `.flex-control-thumbs` w selektorze Woo to KOLEJNA klasa.
   Zmierzone w Chrome po pierwszym podejściu (selektory z trzema klasami):
   miniatura pozioma 109×62 px zamiast 109×109 px; po drugim (cztery klasy):
   miniatury dalej dotykały kadru, bo `margin:0` Woo z (0,4,2) bije nasze
   (0,4,0) liczbą elementów, a szósta i siódma miniatura znikały pod
   `overflow:hidden` bez możliwości przewinięcia.
   Dlatego reguły miniatur mają PIĘĆ klas (powtórzona .flex-control-thumbs),
   a reguły kadru i strzałek — cztery. Wygrywamy bez !important i niezależnie
   od kolejności arkuszy. Powtórzenie tej samej klasy nie zmienia ZAKRESU
   dopasowania (element albo ma tę klasę, albo nie), więc jest bezpieczne.

   2) DLACZEGO KWADRAT NA KAŻDYM SLAJDZIE, NIE TYLKO NA PIERWSZYM. FlexSlider
   (add_theme_support('wc-product-gallery-slider')) owija figurę w
   <div class="flex-viewport"> i ustala jego wysokość ze slajdu — przy kadrach
   o różnych proporcjach wysokość galerii skakałaby przy każdej zmianie
   zdjęcia, a razem z nią cała kolumna buyboksa obok. aspect-ratio:1 na slajdzie
   daje wszystkim kadrom tę samą wysokość, równą szerokości kolumny.
   Reguła obowiązuje też PRZED startem slidera (WP Rocket odkłada JS do
   pierwszej interakcji), bo nie zależy od klas dokładanych przez skrypt.

   3) DLACZEGO WYSOKOŚĆ NA <a>, A NIE display:grid NA SLAJDZIE. FlexSlider
   wpisuje slajdom style INLINE (m.in. width w px, float i display:block),
   a styl inline bije każdą naszą regułę bez !important — układ musi więc
   działać przy display:block. Stąd łańcuch: kwadrat trzyma aspect-ratio
   slajdu, link rozciąga się na 100 % jego wnętrza (z zapasowym aspect-ratio,
   gdyby procentowa wysokość nie miała się od czego odbić), a zdjęcie mieści
   się w tym polu przez object-fit:contain. Contain, a nie cover — ucięty
   produkt w sklepie to błąd, nie kadrowanie.

   4) WYKLUCZENIE img:not(.zoomImg). Przy wc-product-gallery-zoom jquery.zoom
   wstrzykuje DRUGI <img class="zoomImg">, pozycjonowany bezwzględnie
   i przesuwany o ujemne offsety. Narzucenie mu width/height/object-fit
   zabiłoby powiększenie. */
.woocommerce-product-gallery{position:relative;min-width:0}
.woocommerce-product-gallery__wrapper{margin:0}
/* tor slidera. FlexSlider nakłada na .flex-viewport styl inline
   (position:relative;overflow:hidden) i do rundy 5 kadrowanie toru stało
   WYŁĄCZNIE na tym stylu — czyli na tym, że skrypt w ogóle wystartował.
   WP Rocket odracza JS do pierwszej interakcji, więc do tej chwili tor był
   nieprzycięty. Ta reguła jest bezpiecznikiem: powtarza to, co i tak zrobi
   skrypt, plus zamyka tor w szerokości kolumny. */
.woocommerce-product-gallery.woocommerce-product-gallery .flex-viewport.flex-viewport{position:relative;overflow:hidden;width:100%;max-width:100%;border-radius:var(--r)}
/* slajd = kwadratowa ramka jak .galeria__glowne z prototypu (padding 20 px)

   🔴 RUNDA 5: RAMKA ZJECHAŁA ZE SLAJDU NA <a> — zgłoszenie „dwa zdjęcia obok
   siebie". Winna była arytmetyka FlexSlidera zderzona z globalnym
   `*{box-sizing:border-box}` (linia 26). Skrypt liczy
   boxPadding = slajd.outerWidth() − slajd.width(), czyli przy padding:20px
   i border:1px wychodziło 42 px; potem wpisuje slajdom inline width
   itemW−42, ALE przewija o pełne itemW. Różnica 42 px kumuluje się z każdym
   kolejnym slajdem, więc na pierwszym kadrze nic nie widać, a na piątym
   sąsiedni kadr wchodzi w widok.
   Deklaracje pudełkowe (padding, border, tło, promień) muszą więc siedzieć
   NIŻEJ niż element, który FlexSlider mierzy. Na slajdzie zostaje tylko to,
   co nie generuje boxPadding: proporcja, min-width i przycinanie.
   Po zmianie w konsoli:
   `var fs=jQuery('.woocommerce-product-gallery').data('flexslider');
    console.log(fs.w, fs.itemW, fs.computedW, fs.boxPadding)`
   — boxPadding ma być 0, a computedW równe itemW.
   ⚠ Ramka na <a> działa tylko dlatego, że box-sizing jest globalnie
   border-box: padding mieści się wewnątrz width/height:100%, a nie dokłada
   się do nich. */
.woocommerce-product-gallery.woocommerce-product-gallery .woocommerce-product-gallery__image.woocommerce-product-gallery__image{aspect-ratio:1;min-width:0;overflow:hidden}
.woocommerce-product-gallery.woocommerce-product-gallery .woocommerce-product-gallery__image.woocommerce-product-gallery__image>a{display:block;width:100%;height:100%;aspect-ratio:1;padding:20px;border:1px solid var(--linia);border-radius:var(--r);background:#fff}
.woocommerce-product-gallery.woocommerce-product-gallery .woocommerce-product-gallery__image.woocommerce-product-gallery__image img:not(.zoomImg){display:block;width:100%;height:100%;max-width:100%;max-height:100%;margin:0;object-fit:contain;object-position:center}

/* miniatury slidera: <ol class="flex-control-nav flex-control-thumbs">
   (to LISTA NUMEROWANA — skrypt galerii Woo generuje <ol>, nie <ul>).
   Kolumny nie są liczone sztywno, tylko przez auto-fill z minimum 64 px:
   przy zmierzonych 576 px szerokości kolumny galerii wychodzi osiem kafli
   po ~67 px (do rundy 5 było pięć po ~109 px — Paweł: „miniaturki za duże,
   mieszczą się cztery i połowa piątej"). Na węższej kolumnie liczba kafli
   spada sama, bez media query.
   ⚠ auto-fill, NIE auto-fit: auto-fit zwija puste tory, więc galeria
   z trzema zdjęciami rozciągnęłaby te trzy miniatury na całą szerokość
   i znowu zrobiły się z nich kafle po 190 px. auto-fill zostawia puste tory,
   czyli miniatura ma ten sam rozmiar niezależnie od tego, ile ich jest.
   Każda miniatura kwadratowa i w całości widoczna, aktywna z obrysem marki.
   Galeria z więcej niż ośmioma zdjęciami: zamiast drugiego rzędu (miniatury
   „zawijały się", zgłoszenie P4) tor zostaje JEDNĄ linią z przewijaniem
   w poziomie — osiem kafli w widoku, reszta na dosunięcie. Próg :has() i
   dzielnik w grid-auto-columns MUSZĄ chodzić w parze z liczbą kafli
   w widoku: przy niezgodności ostatni kafel w widoku jest ucięty w połowie
   i wygląda to na przypadkowy błąd, a nie na zapowiedź przewijania.
   Warunek stoi na :has(); przeglądarka bez :has() pomija tę regułę i wraca
   do zwykłej siatki auto-fill z zawijaniem — nic się nie psuje.
   Kwadrat trzyma <li>, a miniatura WYPADA Z PRZEPŁYWU (position:absolute;
   inset:0) — dokładnie jak zdjęcie kafla produktu po poprawce B3.
   Zmierzone przed tą zmianą: przy samym height:100% na obrazku kwadrat się
   NIE trzymał (miniatura pionowa 300×700 rozpychała komórkę do 235 px zamiast
   109 px), bo <li> jest elementem siatki i ma automatyczne minimum wysokości
   liczone z treści — wysokość zależała od obrazka, a procentowa wysokość
   obrazka od wysokości <li>, czyli odwołanie cykliczne i procent rozwiązywany
   jak „auto". Po wyjęciu z przepływu o wysokości decyduje WYŁĄCZNIE
   aspect-ratio, a min-height:0 zdejmuje to automatyczne minimum. */
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs{list-style:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:6px;margin:8px 0 0;padding:0}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs:has(li:nth-child(9)){grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:max(64px, calc((100% - 7 * 6px) / 8));overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs li{position:relative;margin:0;padding:0;list-style:none;aspect-ratio:1;min-width:0;min-height:0;scroll-snap-align:start}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs li img{position:absolute;inset:0;width:100%;height:100%;max-width:100%;max-height:100%;margin:0;object-fit:contain;border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;padding:4px;cursor:pointer;opacity:.75}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs li img.flex-active,
.woocommerce-product-gallery.woocommerce-product-gallery .flex-control-thumbs.flex-control-thumbs.flex-control-thumbs li:hover img{border-color:var(--zielen);border-width:2px;opacity:1}

/* strzałki ‹ › na zdjęciu głównym — markup FlexSlidera:
   <ul class="flex-direction-nav"><li class="flex-nav-prev"><a class="flex-prev">…
   Motyw ignorował tę rodzinę do rundy 4, więc nawigacja (gdyby się pojawiła)
   szła jako gołe linki z tekstem „Previous"/„Next".

   ⚠ WooCommerce startuje galerię z directionNav:false, więc do rundy 4 tej
   listy w ogóle NIE BYŁO W DOM i cała ta sekcja była martwym CSS-em. Włącza ją
   filtr woocommerce_single_product_carousel_options — m420_galeria_opcje
   w inc/pdp.php (sekcja 5, runda 5). Zmiana tamtego filtru na false zabija
   strzałki, mimo że te style zostają na miejscu; przy jednym zdjęciu FlexSlider
   nie startuje (allowOneSlide:false) i strzałek też nie ma — celowo.

   Kotwiczenie: <ul> jest dzieckiem .woocommerce-product-gallery (position:relative
   wyżej), a ta obejmuje ZDJĘCIE RAZEM Z MINIATURAMI — samo top:50% zsunęłoby
   strzałki poniżej środka kadru (ta sama klasa błędu, co środkowanie strzałek
   karuzeli „Podobne produkty" na bloku z nagłówkiem). Dlatego lista dostaje
   left/right:0 i aspect-ratio:1: przy definitywnej szerokości równej szerokości
   galerii jej wysokość równa się dokładnie kwadratowi zdjęcia głównego,
   a strzałki środkują się względem niego.
   pointer-events:none na liście (a auto na samych przyciskach) zostawia
   kliknięcia w środku kadru lightboxowi i lupce zoomu.
   Wnętrze galerii jest przycinane (overflow:hidden — bezpiecznik z rundy 2),
   więc strzałki stoją 10 px WEWNĄTRZ ramki, a nie na ujemnych offsetach jak
   .karuzela__strzalka. Wygląd (40 px, biel, obrys, cień) — jak tam.
   opacity/left i right zapisane wprost: własny arkusz FlexSlidera chowa
   strzałki poza :hover (`.flexslider:hover .flex-prev`, (0,3,0)); nasze
   selektory z powtórzoną klasą galerii mają (0,4,1)–(0,5,1) i wygrywają,
   a strzałki są widoczne zawsze — na dotyku hover nie istnieje. */
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav.flex-direction-nav{position:absolute;top:0;left:0;right:0;aspect-ratio:1;margin:0;padding:0;list-style:none;pointer-events:none;z-index:6}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav.flex-direction-nav li{margin:0;padding:0;list-style:none}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:50%;background:#fff;border:1px solid var(--linia);box-shadow:var(--cien);display:grid;place-items:center;cursor:pointer;pointer-events:auto;opacity:1;text-decoration:none;text-indent:0;
  /* tekst „Previous"/„Next" z FlexSlidera zostaje w drzewie dostępności,
     ale znika z widoku — rysunek strzałki robi ::before z własnym stopniem pisma */
  font-size:0;color:transparent}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a::before{font-size:23px;line-height:1;font-weight:700;color:var(--tusz)}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a.flex-prev{left:10px;right:auto}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a.flex-next{right:10px;left:auto}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a.flex-prev::before{content:"‹"}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a.flex-next::before{content:"›"}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a:hover{border-color:var(--zielen)}
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a:focus-visible{outline:2px solid var(--zielen);outline-offset:2px}
/* koniec toru: FlexSlider dokłada .flex-disabled (animationLoop:false) */
.woocommerce-product-gallery.woocommerce-product-gallery .flex-direction-nav a.flex-disabled{opacity:.35;box-shadow:none;cursor:default}
/* lupka (trigger lightboxa) w rogu galerii */
.woocommerce-product-gallery__trigger{position:absolute;top:10px;right:10px;z-index:9;width:38px;height:38px;border-radius:50%;background:#fff;border:1px solid var(--linia);box-shadow:var(--cien);display:grid;place-items:center}

/* --- komunikaty Woo (message/error/info) w design systemie --- */
.woocommerce-message,.woocommerce-error,.woocommerce-info{list-style:none;margin:14px 0;padding:13px 16px 13px 44px;border-radius:var(--r-s);border:1px solid var(--linia);background:#fff;font-size:14.5px;position:relative}
.woocommerce-message::before,.woocommerce-error::before,.woocommerce-info::before{position:absolute;left:16px;top:12px;font-weight:800}
.woocommerce-message{border-color:#b8e6c4;background:#effaf1}
.woocommerce-message::before{content:"✓";color:var(--ok)}
.woocommerce-error{border-color:#f2c4c4;background:#fdf2f2}
.woocommerce-error::before{content:"!";color:var(--blad)}
.woocommerce-error li{margin:0 0 4px;list-style:none}
.woocommerce-info{border-color:#b8ede8;background:var(--zielen-tlo)}
.woocommerce-info::before{content:"i";color:var(--akcent-tekst);font-style:italic;font-family:Georgia,serif}
.woocommerce-message .button,.woocommerce-error .button,.woocommerce-info .button{float:right;font-weight:700;color:var(--akcent-tekst);background:none;border:0;padding:0;cursor:pointer}

/* --- paginacja Woo → wygląd .paginacja --- */
.woocommerce-pagination{margin-top:28px}
.woocommerce-pagination ul{list-style:none;display:flex;gap:6px;justify-content:center;margin:0;padding:0;border:0}
.woocommerce-pagination ul li{border:0;margin:0}
.woocommerce-pagination ul li a,.woocommerce-pagination ul li span{min-width:38px;height:38px;display:grid;place-items:center;padding:0 6px;border:1px solid var(--linia);border-radius:var(--r-s);font-weight:600;color:var(--tusz)}
.woocommerce-pagination ul li a:hover{border-color:var(--zielen);color:var(--zielen)}
.woocommerce-pagination ul li span.current{background:var(--zielen);color:#fff;border-color:var(--zielen)}

/* --- pasek nad listingiem: licznik wyników + select sortowania Woo --- */
.woocommerce-result-count{font-size:14px;color:var(--tusz-2);margin:0}
.woocommerce-ordering{margin:0}
.woocommerce-ordering select{padding:8px 12px;border:1px solid var(--linia);border-radius:var(--r-s);font-size:14px;background:#fff;color:var(--tusz);cursor:pointer}
.woocommerce-ordering select:focus{outline:none;border-color:var(--zielen)}

/* --- okruszki Woo (gdy szablon używa woocommerce_breadcrumb) ---
   🔴 RUNDA 4 (P5): odstęp od nagłówka jak w .okruszki (26/16 px).
   Sama reguła `.woocommerce-breadcrumb` (0,1,0) NIE wystarczała: arkusz
   woocommerce-general trzyma `.woocommerce .woocommerce-breadcrumb
   {margin:0 0 1em;padding:0}` (0,2,0) i to on wygrywał — stąd zmierzone
   padding-top:0 na karcie produktu. Druga reguła powtarza klasę okruszków,
   ma (0,3,0) i wygrywa liczbą klas, bez !important.
   Margines zerujemy świadomie: `0 0 1em` z Woo dokładałoby do dolnego
   dopełnienia ~16 px, więc odstęp pod ścieżką byłby dwa razy większy niż
   zaplanowany i inny niż w okruszkach naszych szablonów.
   Stopień pisma i kolor też idą w regule o wyższej specyficzności: Woo maluje
   ścieżkę własnym `font-size:.92em;color:#767676` (selektor z :where(), które
   nie dokłada specyficzności, więc też (0,2,0)) i wygrywało z naszym (0,1,0).
   Skutek był drobny, ale widoczny: okruszki sklepu miały inny szary i inny
   rozmiar niż okruszki bloga. */
.woocommerce-breadcrumb{font-size:13px;color:var(--tusz-2);margin:0;padding:26px 0 16px}
:is(.woocommerce,.woocommerce-page) .woocommerce-breadcrumb.woocommerce-breadcrumb{font-size:13px;color:var(--tusz-2);margin:0;padding:26px 0 16px}
:is(.woocommerce,.woocommerce-page) .woocommerce-breadcrumb.woocommerce-breadcrumb a{color:var(--tusz-2)}
.woocommerce-breadcrumb a{color:var(--tusz-2)}
.woocommerce-breadcrumb a:hover{color:var(--tusz)}

/* --- formularz dodania do koszyka (PDP): ilość + przycisk jak .dodaj-rzad --- */
form.cart{display:flex;flex-wrap:wrap;gap:10px;align-items:stretch;margin:16px 0 6px}
form.cart .quantity{display:flex}
form.cart .quantity .qty{width:78px;padding:0 0 0 14px;border:2px solid var(--linia);border-radius:999px;font-size:16px;background:#fff}
form.cart .quantity .qty:focus{outline:none;border-color:var(--zielen)}
form.cart .single_add_to_cart_button{flex:1;min-width:200px}
/* formularz wariacji: tabela atrybutów bez ramek, przycisk „Wyczyść" dyskretnie */
form.cart table.variations{border-collapse:collapse;width:100%;margin-bottom:6px}
form.cart table.variations td,form.cart table.variations th{border:0;padding:4px 0;text-align:left;font-size:14px}
form.cart .reset_variations{font-size:13px;color:var(--tusz-2);text-decoration:underline}
form.cart .woocommerce-variation-price{font-size:20px;font-weight:800;margin:6px 0}
form.cart .woocommerce-variation-availability{font-size:14px}
form.cart .variations_button{display:flex;gap:10px;flex:1 1 100%}
form.cart select{padding:8px 12px;border:1.5px solid var(--linia);border-radius:var(--r-s);font-size:14px;background:#fff}
p.stock.in-stock{color:var(--ok);font-weight:600;font-size:14px}
p.stock.out-of-stock{color:var(--blad);font-weight:600;font-size:14px}

/* --- lista i formularz opinii Woo (markup komentarzy) w stylu .opinia --- */
#reviews .commentlist{list-style:none;margin:0;padding:0}
#reviews .commentlist li{border-bottom:1px solid var(--linia);padding:14px 0}
#reviews .comment_container img.avatar{display:none} /* bez gravatarów — lekkość i RODO */
#reviews .comment-text .meta{font-size:13px;color:var(--tusz-2);margin-bottom:4px}
#reviews .comment-text .description{font-size:14.5px}
#reviews .woocommerce-review__verified{color:var(--ok);font-weight:600;font-style:normal}
#review_form .comment-reply-title{font-size:18px;font-weight:700;display:block;margin-bottom:10px}
#review_form .comment-form-rating label,#review_form .comment-form-comment label,#review_form .comment-form-author label,#review_form .comment-form-email label{font-size:13.5px;font-weight:600;display:block;margin-bottom:5px}
/* Same pola formularza opinii ubiera wspólna rodzina „pola formularzy klasycznych"
   na końcu pliku (B5) — ta sama wysokość i ten sam obrys fokusu, co logowanie,
   rejestracja i edycja adresu. Wcześniej stały tu osobne reguły z wypełnieniem
   11/14 px, czyli o 6 px niższe pole niż w reszcie sklepu. */
#review_form p{margin-bottom:12px}
#review_form .form-submit input[type=submit]{display:inline-flex;align-items:center;justify-content:center;border:0;cursor:pointer;font-weight:700;font-size:15px;border-radius:999px;padding:13px 26px;background:var(--zielen);color:#fff;transition:background .15s}
#review_form .form-submit input[type=submit]:hover{background:var(--zielen-2)}

/* --- zamienniki reguł ze ZDEJMOWANYCH arkuszy Woo (layout + smallscreen) ---
   inc/zasoby.php zdejmuje woocommerce-layout.css i woocommerce-smallscreen.css
   (powód: motyw ma własną siatkę na CSS Grid — patrz komentarz w tamtym pliku).
   Razem z nimi znikają rodziny reguł, których motyw nie miał czym zastąpić.
   Wszystkie dotyczą KLASYCZNYCH widoków Woo — koszyk i zamówienie są blokowe
   i ubiera je assets/css/bloki.css. Układ dwukolumnowy karty produktu
   (`div.images` + `div.summary`) odtwarza .uklad-pdp z inc/pdp.php. */

/* 1) dwie kolumny w „Moje konto": logowanie + rejestracja oraz adres rozliczeniowy
   i adres dostawy. Zamiast `.col-1/.col-2{width:48%;float:left}` — grid, bo floaty
   wymagały czyszczenia i rozjeżdżały wysokości kart. */
:is(.woocommerce,.woocommerce-page) .col2-set{display:grid;grid-template-columns:1fr 1fr;gap:26px;align-items:start}
:is(.woocommerce,.woocommerce-page) .col2-set>.col-1,:is(.woocommerce,.woocommerce-page) .col2-set>.col-2{float:none;width:auto;max-width:none;min-width:0}

/* 2) pola imię/nazwisko obok siebie w formularzach klasycznych (rejestracja,
   edycja adresu, śledzenie zamówienia) — odpowiednik .form-row-first/.form-row-last. */
:is(.woocommerce,.woocommerce-page) form .form-row{margin-bottom:12px}
:is(.woocommerce,.woocommerce-page) form .form-row-first{float:left;width:calc(50% - 8px);clear:both}
:is(.woocommerce,.woocommerce-page) form .form-row-last{float:right;width:calc(50% - 8px)}
:is(.woocommerce,.woocommerce-page) form .form-row-wide,:is(.woocommerce,.woocommerce-page) form .clear{clear:both}

/* 3) tabele klasyczne na telefonie („Moje konto": lista zamówień, szczegóły,
   pobrania) — odpowiednik woocommerce-smallscreen: nagłówek tabeli znika,
   a każda komórka staje się wierszem z etykietą z atrybutu data-title.
   Bez tego tabela zostaje kolumnowa i wyjeżdża poza szerokość ekranu. */
@media(max-width:640px){
  :is(.woocommerce,.woocommerce-page) .col2-set{grid-template-columns:1fr}
  :is(.woocommerce,.woocommerce-page) form .form-row-first,:is(.woocommerce,.woocommerce-page) form .form-row-last{float:none;width:100%}
  /* Szkielet 1:1 jak w woocommerce-smallscreen (sprawdzony układ): blokowe są
     KOMÓRKI, wiersze zostają wierszami tabeli — inaczej trzeba by przebudować
     całe pudełko tabeli. Separator rysuje ostatnia komórka wiersza. */
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive thead{display:none}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tbody th{display:none}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td{display:block;width:auto;text-align:right;clear:both;border:0;padding:6px 12px}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td:last-child{border-bottom:1px solid var(--linia);padding-bottom:12px}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr:last-child td:last-child{border-bottom:0}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td::before{content:attr(data-title) ": ";float:left;font-weight:600;color:var(--tusz-2)}
  /* komórki z przyciskami: bez etykiety i do lewej (nazwy klas różnią się
     między wydaniami Woo — łapiemy stare i nowe naraz) */
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.actions::before,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.order-actions::before,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.woocommerce-orders-table__cell-order-actions::before,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.download-actions::before,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.product-remove::before{display:none}
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.actions,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.order-actions,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.woocommerce-orders-table__cell-order-actions,
  :is(.woocommerce,.woocommerce-page) table.shop_table_responsive tr td.download-actions{text-align:left}
}

/* ============================================================
   ADAPTACJE WTYCZEK (WCBoost swatches, PayU raty)
   Motyw nie dubluje pracy wtyczek — tylko ubiera ich markup.
   ============================================================ */

/* --- WCBoost Variation Swatches: kropki kolorów jak .wariant z prototypu --- */
.wcboost-variation-swatches{list-style:none;display:flex;gap:8px;flex-wrap:wrap;margin:8px 0;padding:0}
.wcboost-variation-swatches__item{margin:0;cursor:pointer}
.wcboost-variation-swatches__item--color,.wcboost-variation-swatches__item.swatch-color{width:38px;height:38px;border-radius:50%;border:2px solid var(--linia);background:#fff;display:grid;place-items:center;padding:0;box-shadow:none}
.wcboost-variation-swatches__item--color span,.wcboost-variation-swatches__item--color .wcboost-variation-swatches__color{width:26px;height:26px;border-radius:50%;display:block}
.wcboost-variation-swatches .selected,.wcboost-variation-swatches__item[aria-checked=true]{border-color:var(--zielen);box-shadow:0 0 0 2px var(--zielen-tlo)}
/* swatche tekstowe (rozmiary itp.) jak chipy */
.wcboost-variation-swatches__item--label,.wcboost-variation-swatches__item--button{border:1px solid var(--linia);background:#fff;border-radius:999px;padding:7px 15px;font-size:13.5px;font-weight:600;color:var(--tusz)}
.wcboost-variation-swatches__item--label.selected,.wcboost-variation-swatches__item--button.selected{border-color:var(--zielen);background:var(--zielen-tlo);color:var(--zielen)}

/* --- widget rat PayU: kontener wtyczki w ramce jak .raty-payu ---
   Wtyczka wstawia pusty span#installment-mini-{ID}, a SDK PayU
   (OpenPayU.Installments.miniInstallment) sam go wypełnia i obsługuje modal.
   Motyw NICZEGO nie liczy i nie rysuje własnej tabelki rat — tylko ramka.
   Pusty kontener (WP Rocket opóźnia JS) nie zostawia pustej ramki. */
[id^="installment-mini-"]{display:block;border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;margin:12px 0;padding:11px 14px;font-size:14px}
[id^="installment-mini-"]:empty{display:none;margin:0;padding:0;border:0}

/* --- ceny Woo w kaflu listingu: get_price_html() oddaje <del>/<ins>, prototyp
   stylował <s>/.teraz — mapujemy 1:1 (dopisane przy budowie content-product.php) --- */
.prod__cena del{font-size:13.5px;color:var(--tusz-2);font-weight:500;margin-right:7px}
.prod__cena ins{color:var(--akcent-tekst);text-decoration:none}
/* link „Zobacz koszyk", który skrypt AJAX Woo dokleja w kaflu po dodaniu produktu */
.prod__koszyk .added_to_cart{display:block;text-align:center;margin-top:6px;font-size:13px;font-weight:600;color:var(--akcent-tekst)}

/* ============================================================
   RUNDA 2 — poprawki z AUDYT-TYPOW-STRON.md (20.08.2026)
   N2 galeria przed startem FlexSlidera · N6 przyciski klasyczne Woo
   · N8 układ strony „Moje konto".
   Sekcja stoi na KOŃCU pliku ŚWIADOMIE: część reguł wygrywa z arkuszem
   woocommerce-general remisem specyficzności, a ten jest wypisywany PRZED
   naszym (kolejność wymuszona priorytetem 20 w inc/zasoby.php). Tam, gdzie
   remis nie wystarcza, selektor jest podniesiony — bez !important.
   ============================================================ */

/* --- N2: galeria produktu ZANIM ruszy FlexSlider ---
   Skrypt galerii Woo startuje dopiero po wykonaniu JS, a WP Rocket odkłada
   skrypty do pierwszej interakcji użytkownika. Do tego czasu <figure> trzyma
   wszystkie kadry naraz: na żywym sklepie dawało to galerię szerokości
   11 059 px przy oknie 1280 px i poziomy pasek przewijania CAŁEJ strony.

   Mechanika naprawy: FlexSlider owija .woocommerce-product-gallery__wrapper
   w <div class="flex-viewport"> i dopiero potem klonuje/przesuwa slajdy.
   Dopóki tego nie zrobi, wrapper jest BEZPOŚREDNIM dzieckiem galerii — i tylko
   wtedy selektor z dwoma „>" pasuje. Po inicjalizacji wrapper ma nowego
   rodzica, więc reguła przestaje obowiązywać sama z siebie (nie trzeba jej
   zdejmować JS-em), slider działa normalnie, a sklonowane slajdy wewnątrz
   .flex-viewport nigdy nie są chowane.

   Kombinator „~" zamiast :not(:first-child): chowamy każdy kadr POPRZEDZONY
   innym kadrem. Dzięki temu reguła zostaje poprawna także wtedy, gdy wtyczka
   (albo nowsze wydanie Woo) wstawi do figury cokolwiek przed pierwszym
   zdjęciem — przy :not(:first-child) pierwszy kadr zniknąłby razem z resztą.

   🔴 RUNDA 4 (20.08): PODNIESIONA SPECYFICZNOŚĆ — reguła DO TEJ PORY PRZEGRYWAŁA.
   Sprawdzone w realnym arkuszu sklepu (woocommerce.css pobrany 20.08):
     .woocommerce div.product div.images .woocommerce-product-gallery__image
     :nth-child(n+2){width:25%;display:inline-block}                    (0,5,2)
   — czyli Woo CELOWO pokazuje kadry 2+ jako paseczki 25 %, a nasze
   `display:none` miało (0,4,0) i przegrywało liczbą klas. Do rundy 4 karta
   produktu pokazywała więc przed startem slidera duży kadr plus rządek
   miniaturek-kadrów, i to nie przez chwilę: WP Rocket odkłada JS do pierwszej
   interakcji, więc taki stan potrafi trwać, dopóki klient nie ruszy myszą.
   Powtórzone klasy dają (0,6,0) — wygrywamy liczbą klas. */
.woocommerce-product-gallery.woocommerce-product-gallery>.woocommerce-product-gallery__wrapper.woocommerce-product-gallery__wrapper>.woocommerce-product-gallery__image~.woocommerce-product-gallery__image{display:none}
/* ten sam warunek „przed inicjalizacją": pojedynczy kadr ma zająć kolumnę,
   a nie rozpychać jej szerokością wszystkich zdjęć (gdyby jakiś arkusz wtyczki
   ustawił figurze display:flex). Po starcie slidera FlexSlider i tak wpisuje
   szerokość stylem inline, a ta reguła już nie pasuje. */
.woocommerce-product-gallery>.woocommerce-product-gallery__wrapper{display:block;width:auto;max-width:100%}
/* drugi bezpiecznik: cokolwiek jeszcze wyjedzie poza kolumnę galerii,
   nie rozepchnie strony w poziomie (osobna reguła zamiast dopisku do
   deklaracji wyżej — tamta opisuje pozycjonowanie, ta przycinanie) */
.woocommerce-product-gallery{overflow:hidden}

/* miniatury slidera: siatkę (auto-fill, minimum 64 px) i ramki daje blok
   „galeria produktu Woo" wyżej w pliku;
   tu zdejmujemy floaty z woocommerce-general, który trzyma
   `.woocommerce div.product div.images .flex-control-thumbs li{width:25%;float:left}`
   ze specyficznością (0,4,3). W gridzie float jest ignorowany, ale width:25%
   ścisnąłby każdą miniaturę do ćwiartki toru (ta sama wada, co kafle 62 px
   na listingu). Dokładamy do selektora klasę .woocommerce-product-gallery —
   siedzi na TYM SAMYM elemencie co div.images — więc mamy (0,5,3) i wygrywamy
   niezależnie od kolejności arkuszy.
   position:static na liście: gdyby doszedł arkusz flexslidera z
   `.flex-control-nav{position:absolute;bottom:-40px}`, miniatury wypadłyby poza
   galerię, a nasze świeże overflow:hidden by je przycięło. */
.woocommerce div.product div.images.woocommerce-product-gallery .flex-control-thumbs{position:static;width:auto;bottom:auto;text-align:left}
.woocommerce div.product div.images.woocommerce-product-gallery .flex-control-thumbs li{width:auto;float:none;margin:0;padding:0;list-style:none}
.woocommerce div.product div.images.woocommerce-product-gallery .flex-control-thumbs li img{opacity:.75;margin:0;cursor:pointer}
.woocommerce div.product div.images.woocommerce-product-gallery .flex-control-thumbs li img.flex-active,
.woocommerce div.product div.images.woocommerce-product-gallery .flex-control-thumbs li:hover img{opacity:1;border-color:var(--zielen);border-width:2px}

/* --- N6: klasyczne przyciski WooCommerce w design systemie ---
   woocommerce-general (zostawiony świadomie — patrz inc/zasoby.php) maluje je
   szaro: tło #e9e6ed, tekst #515151, promień 3 px. Zmierzone na „Moje konto":
   przycisk „Zaloguj się" stał obok naszych zaokrąglonych przycisków marki
   i wyglądał jak element z innej strony.
   Wzór: .btn--drugi z prototypu; wariant .alt (główna akcja Woo, np. „Dodaj do
   koszyka" na karcie produktu, „Kupuję i płacę" w klasycznym zamówieniu) —
   .btn--glowny, czyli tło --akcent i tekst #123330. Biały tekst na tym akcencie
   NIE spełniałby kontrastu, dlatego kolor tekstu jest ciemny.

   Zakres selektorów — dwa świadome wykluczenia:
   1) `form:not(.szukaj)` — szukajka w nagłówku ma bezklasowy
      <button type="submit"> w okrągłym polu (searchform.php); bez tego
      warunku rodzina zamieniłaby lupkę w pigułkę 13/26 px na KAŻDEJ
      stronie sklepowej (body dostaje klasę .woocommerce);
   2) `:not([class*="wc-block"])` — przyciski bloków koszyka/zamówienia
      należą do assets/css/bloki.css i tam mają własny wygląd. */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce .button,
.woocommerce form:not(.szukaj) button[type=submit]:not([class*="wc-block"]),
.woocommerce #respond input#submit{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:0;cursor:pointer;font-weight:700;font-size:15px;line-height:1.2;border-radius:999px;padding:13px 26px;background:var(--zielen);color:#fff;text-decoration:none;text-shadow:none;box-shadow:none;transition:background .15s}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce .button:hover,
.woocommerce form:not(.szukaj) button[type=submit]:not([class*="wc-block"]):hover,
.woocommerce #respond input#submit:hover{background:var(--zielen-2);color:#fff}
/* dostępność: widoczny obrys przy nawigacji klawiaturą (ciemny obrys czytelny
   i na ciemnym przycisku drugorzędnym, i na turkusowym głównym) */
.woocommerce a.button:focus-visible,
.woocommerce button.button:focus-visible,
.woocommerce input.button:focus-visible,
.woocommerce .button:focus-visible,
.woocommerce form:not(.szukaj) button[type=submit]:not([class*="wc-block"]):focus-visible,
.woocommerce #respond input#submit:focus-visible{outline:2px solid var(--zielen);outline-offset:2px}
/* wariant .alt = główna akcja Woo. Rdzeń trzyma `.woocommerce a.button.alt`
   (0,3,1) — nasze selektory mają tę samą specyficzność i stoją dalej w kolejce
   arkuszy, więc wygrywają remis. */
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce form:not(.szukaj) button[type=submit].alt:not([class*="wc-block"]){background:var(--akcent);color:#123330}
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce form:not(.szukaj) button[type=submit].alt:not([class*="wc-block"]):hover{background:var(--akcent-2);color:#123330}
/* stan wyłączony: rdzeń Woo daje przyciskom `color:inherit` (0,3,1), co na
   naszym ciemnym tle zrobiłoby ciemny tekst na ciemnym. Przywracamy kolory
   obu wariantów; reguła dla .alt ma (0,4,1), więc jest odporna na kolejność. */
.woocommerce a.button.disabled,
.woocommerce button.button.disabled,
.woocommerce button.button:disabled,
.woocommerce input.button:disabled{color:#fff;opacity:.55;cursor:not-allowed}
.woocommerce a.button.alt.disabled,
.woocommerce button.button.alt.disabled,
.woocommerce button.button.alt:disabled,
.woocommerce input.button.alt:disabled{color:#123330}
/* przyciski wewnątrz komunikatów Woo („Zobacz koszyk" przy dodaniu produktu)
   zostają płaskim linkiem z sekcji „komunikaty Woo". Ta sekcja jest WCZEŚNIEJ
   w pliku i ma tę samą specyficzność co rodzina .button, więc bez poniższego
   zastrzeżenia zmieniłyby się w ciemną pigułkę wewnątrz zielonego paska. */
.woocommerce-message a.button,.woocommerce-error a.button,.woocommerce-info a.button,
.woocommerce-message button.button,.woocommerce-error button.button,.woocommerce-info button.button{background:none;color:var(--akcent-tekst);border-radius:0;padding:0;font-size:14.5px}
.woocommerce-message a.button:hover,.woocommerce-error a.button:hover,.woocommerce-info a.button:hover,
.woocommerce-message button.button:hover,.woocommerce-error button.button:hover,.woocommerce-info button.button:hover{background:none;color:var(--tusz)}

/* --- N8: układ strony „Moje konto" (dokończenie zamienników za
   woocommerce-layout.css) ---
   Zdjęty arkusz dawał `.woocommerce-MyAccount-navigation{float:left;width:30%}`
   i `.woocommerce-MyAccount-content{float:right;width:68%}`. Runda 1 odtworzyła
   tylko .col2-set (logowanie/rejestracja, adresy), więc panel klienta został
   jednokolumnowy. Zamiast floatów — grid 250px + reszta, jak .uklad-kat.

   Kontenerem jest <div class="woocommerce"> wypisywany przez shortcode konta.
   Warunek :has() jest KONIECZNY: ten sam kontener obsługuje widok
   niezalogowanego (formularz logowania w .col2-set), a tam tor 250px byłby
   błędem. Gdy przeglądarka nie zna :has(), cała reguła jest pomijana i strona
   zostaje jednokolumnowa — czyli w stanie sprzed tej poprawki, nic się nie psuje.
   (Motyw już korzysta z :has() — .platnosci__karta, .dostawa__karta.) */
.woocommerce-account .woocommerce:has(>.woocommerce-MyAccount-navigation){display:grid;grid-template-columns:250px 1fr;gap:26px;align-items:start}
/* komunikaty („Zapisano zmiany") są PIERWSZYM dzieckiem kontenera — bez tego
   zajęłyby komórkę nawigacji i zepchnęły obie kolumny o rząd niżej */
.woocommerce-account .woocommerce>.woocommerce-notices-wrapper{grid-column:1/-1}
.woocommerce-account .woocommerce>.woocommerce-MyAccount-content{min-width:0}
/* nawigacja konta jak karty: pozycja aktywna wyróżniona akcentem (ramka
   i pasek z lewej). Tekst zostaje ciemny — #00857c na pastelowym tle daje
   4,2:1, czyli poniżej progu AA dla tego stopnia pisma. */
.woocommerce-account .woocommerce-MyAccount-navigation ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.woocommerce-account .woocommerce-MyAccount-navigation li{margin:0;padding:0;list-style:none}
.woocommerce-account .woocommerce-MyAccount-navigation li a{display:block;padding:11px 14px;border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;font-size:14.5px;font-weight:600;color:var(--tusz)}
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover{border-color:var(--zielen);background:var(--tlo-2);color:var(--tusz)}
.woocommerce-account .woocommerce-MyAccount-navigation li a:focus-visible{outline:2px solid var(--zielen);outline-offset:2px}
.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a{border-color:var(--akcent);background:var(--zielen-tlo);color:var(--tusz);box-shadow:inset 3px 0 0 var(--akcent)}
@media(max-width:980px){
  /* jedna kolumna, a nawigacja przechodzi w rządek chipów nad treścią */
  .woocommerce-account .woocommerce:has(>.woocommerce-MyAccount-navigation){grid-template-columns:1fr;gap:18px}
  .woocommerce-account .woocommerce-MyAccount-navigation ul{flex-direction:row;flex-wrap:wrap;gap:8px}
  .woocommerce-account .woocommerce-MyAccount-navigation li a{border-radius:999px;padding:8px 16px;font-size:13.5px}
  .woocommerce-account .woocommerce-MyAccount-navigation li.is-active a{box-shadow:none;background:var(--zielen-tlo);border-color:var(--akcent)}
}

/* ---------- strona 404 (szablon 404.php) ----------
   Klasy .m420-404* nie miały ANI JEDNEJ reguły w tym pliku ani w bloki.css:
   „404" renderowało się jako zwykły akapit w rozmiarze bazowym, sekcja szła
   do lewej krawędzi, a jedyny odstęp między szukajką a chipami dawał domyślny
   margines .chipy. Reszta wyglądu stoi na klasach wspólnych (.srodek, .sekcja,
   .chipy, .chip, .btn--glowny, .btn--obrys) — tu tylko to, czego nie ma gdzie
   indziej. Kolumna wyśrodkowana i wąska, bo cała strona to jeden komunikat. */
.m420-404{max-width:640px;margin:0 auto;text-align:center}
.m420-404__kod{font-size:clamp(58px,13vw,104px);line-height:1;font-weight:800;letter-spacing:-.03em;color:var(--akcent);font-variant-numeric:tabular-nums}
.m420-404 h1{margin:2px 0 12px}
.m420-404__lead{color:var(--tusz-2);max-width:52ch;margin:0 auto}
/* szukajka stoi tu w kolumnie tekstu, nie w rzędzie nagłówka: .szukaj ma flex:1,
   co poza kontenerem flex nic nie robi — szerokość wyznacza to opakowanie */
.m420-404__szukaj{max-width:460px;margin:26px auto 0}
.m420-404__naglowek{font-size:16px;font-weight:700;color:var(--tusz-2);margin-top:30px}
/* .chipy ma margin:14px 0 i wyrównanie do lewej — na 404 mają być pod nagłówkiem, na środku */
.m420-404 .chipy{justify-content:center;margin:12px 0 0}
.m420-404__powrot{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:30px}

/* ============================================================
   RUNDA 3 — B5: pola formularzy KLASYCZNYCH (Woo + WordPress)
   Sekcja stoi na końcu pliku z tego samego powodu, co rodzina przycisków N6:
   woocommerce-general jest wypisywany PRZED naszym arkuszem (priorytet 20
   w inc/zasoby.php), więc przy remisie specyficzności wygrywa reguła stojąca
   dalej. Tam, gdzie remis to za mało, selektor jest podniesiony — bez !important.
   ============================================================ */

/* Zmierzone na /moje-konto/: pole logowania miało 31 px wysokości i promień 4 px,
   czyli wygląd domyślny przeglądarki — woocommerce-general nie nadaje polom ani
   wypełnienia, ani ramki. Obok pól blokowego zamówienia (50 px, ramka --linia,
   promień --r-s) wyglądało jak element z innej strony.
   Tu klasyczne formularze dostają ten sam wygląd co checkout. Wysokość ~50 px
   budujemy WYPEŁNIENIEM, nie sztywnym height: 14+14 px padding + 15 px pisma
   przy interlinii 1,25 (≈18,7 px) + 2×1,5 px ramki ≈ 50 px. Sztywna wysokość
   ucinałaby pole, gdyby przeglądarka podstawiła większy stopień pisma.

   Zakres — `form .form-row` obejmuje wszystkie klasyczne widoki Woo: logowanie,
   rejestrację, przypomnienie hasła, edycję adresu, śledzenie zamówienia
   i klasyczne zamówienie. Drugi człon rodziny to formularze komentarzy: blog
   (WordPress) i opinie o produkcie (#review_form).

   Trzy świadome wykluczenia:
   1) `:not([class*="wc-block"])` — pola bloków koszyka i zamówienia mają własny
      wygląd w assets/css/bloki.css i NIE należą do tej rodziny (przy okazji
      podnosi to specyficzność do (0,4,2), więc reguła wygrywa z woocommerce-general
      niezależnie od kolejności arkuszy);
   2) szukajka nagłówka — jej pole nie ma klasy .input-text i nie siedzi
      w .form-row (searchform.php), więc nie łapie się w żaden z tych selektorów
      mimo klasy .woocommerce na <body> podstron sklepu;
   3) pola liczby sztuk (.qty, stepper) — też poza .form-row, zostają pigułkami. */
:is(.woocommerce,.woocommerce-page) form .form-row :is(input.input-text,textarea,select):not([class*="wc-block"]),
:is(.comment-form,#commentform,#review_form) :is(input[type=text],input[type=email],input[type=url],input[type=tel],textarea){
  box-sizing:border-box;width:100%;margin:0;padding:14px 16px;
  border:1.5px solid var(--linia);border-radius:var(--r-s);background:#fff;
  color:var(--tusz);font-family:inherit;font-size:15px;line-height:1.25;
  box-shadow:none;transition:border-color .15s}
/* pole wielowierszowe: wyższe światło między wierszami i uchwyt tylko w pionie
   (poziome rozciąganie rozwala kolumnę formularza) */
:is(.woocommerce,.woocommerce-page) form .form-row textarea:not([class*="wc-block"]),
:is(.comment-form,#commentform,#review_form) textarea{min-height:120px;line-height:1.55;resize:vertical}
/* fokus: ciemna ramka marki plus obrys. Obrys, a nie sam cień — cień znika
   w trybie wysokiego kontrastu i przy wymuszonych kolorach, a pole musi być
   rozpoznawalne także dla osoby chodzącej po formularzu klawiaturą.
   #262624 na bieli daje ok. 14:1, więc ostrzega z zapasem ponad próg 3:1. */
:is(.woocommerce,.woocommerce-page) form .form-row :is(input.input-text,textarea,select):not([class*="wc-block"]):focus,
:is(.comment-form,#commentform,#review_form) :is(input[type=text],input[type=email],input[type=url],input[type=tel],textarea):focus{
  border-color:var(--zielen);outline:2px solid var(--zielen);outline-offset:1px}

/* etykiety w konwencji motywu (wzór .pole label z prototypu). Wykluczone
   etykiety pól wyboru: przy display:block zgoda i „Zapamiętaj mnie" spadłyby
   pod kwadracik, a pogrubienie 13,5 px fałszuje wagę tekstu zgody. */
:is(.woocommerce,.woocommerce-page) form .form-row label:not(.woocommerce-form__label-for-checkbox):not(.inline){display:block;margin:0 0 5px;font-size:13.5px;font-weight:600;line-height:1.4;color:var(--tusz)}
:is(.comment-form,#commentform) p:not(.comment-form-cookies-consent)>label{display:block;margin:0 0 5px;font-size:13.5px;font-weight:600;line-height:1.4;color:var(--tusz)}
/* gwiazdka pola wymaganego i stany walidacji na tokenach motywu zamiast
   czerwieni/zieleni z woocommerce-general (#a00 / #69bf29) */
:is(.woocommerce,.woocommerce-page) form .form-row .required{color:var(--blad);text-decoration:none;border:0}
:is(.woocommerce,.woocommerce-page) form .form-row.woocommerce-invalid :is(input.input-text,select){border-color:var(--blad)}
:is(.woocommerce,.woocommerce-page) form .form-row.woocommerce-validated input.input-text{border-color:var(--ok)}
/* podgląd hasła: woocommerce-general kotwiczy oczko w stałym `top:.7em`, co przy
   polu 31 px wypadało pod tekstem, a przy naszym 50 px byłoby jeszcze wyżej —
   pozycjonujemy je względem środka pola */
:is(.woocommerce,.woocommerce-page) form .form-row .password-input{display:block;position:relative}
:is(.woocommerce,.woocommerce-page) form .form-row .show-password-input{position:absolute;top:50%;right:14px;transform:translateY(-50%);margin:0;cursor:pointer}

/* Wybór kraju i województwa na „Moje konto → Adresy" podmienia selectWoo
   (select2 dostarczany przez WooCommerce): oryginalny <select> chowa się, a jego
   miejsce zajmuje kontrolka wtyczki o wysokości 28 px i promieniu 4 px. Obok
   naszych pól 50 px wyglądała jak formularz z innego sklepu, więc ubieramy ją
   tak samo. Stylujemy WYŁĄCZNIE kontrolkę zamkniętą — rozwiniętą listę select2
   dokleja do <body>, poza kontener .woocommerce, więc zostaje w wyglądzie wtyczki.
   Globalne box-sizing:border-box sprawia, że 50 px obejmuje ramkę: wnętrze ma
   47 px i tyle wynosi interlinia tekstu oraz wysokość strzałki (wyśrodkowanie). */
:is(.woocommerce,.woocommerce-page) .select2-container .select2-selection--single{height:50px;border:1.5px solid var(--linia);border-radius:var(--r-s);background:#fff;transition:border-color .15s}
:is(.woocommerce,.woocommerce-page) .select2-container--default .select2-selection--single .select2-selection__rendered{line-height:47px;padding-left:16px;padding-right:34px;color:var(--tusz);font-size:15px}
:is(.woocommerce,.woocommerce-page) .select2-container--default .select2-selection--single .select2-selection__arrow{top:0;right:10px;height:47px;width:20px}
:is(.woocommerce,.woocommerce-page) :is(.select2-container--focus,.select2-container--open) .select2-selection--single{border-color:var(--zielen);outline:2px solid var(--zielen);outline-offset:1px}

/* ============================================================
   RUNDA 4 — P10: shortcode produktów W TREŚCI respektuje columns-N
   ============================================================
   Zgłoszenie Pawła (przykład: /szlify-w-bongach/). Shortcode [products]
   wypisuje <div class="woocommerce columns-3"> → <ul class="products columns-3">,
   a siatka motywu narzucała KAŻDEJ liście produktów repeat(4,1fr) (blok
   „siatka produktów Woo" wyżej). Skutki w tekście wpisu: trzy kafle rozjeżdżały
   się na cztery tory i zostawiały dziurę, a pojedynczy produkt zajmował
   ćwiartkę szerokości kolumny tekstu i wyglądał jak pomyłka składu.

   Docelowe zachowanie (ustalenia z 20.08):
     produktów | desktop                    | ≤640 px
     1         | 50 % szerokości tekstu     | 100 %
     2         | 2 kolumny                  | 2 kolumny
     3         | 3 kolumny, pełna szerokość | 2 kolumny
     4         | 4 kolumny, pełna szerokość | 2 kolumny
   „Pełna szerokość" = cała kolumna tekstu (.artykul ma gorset 76ch) — kafle
   nie wychodzą poza obręb prozy, bo wyłamywanie ich ujemnymi marginesami
   rozjeżdżałoby rytm wpisu.

   🔴 ZAKRES CELOWO OGRANICZONY DO KONTENERÓW TREŚCI. Listing kategorii ma
   zostać czterokolumnowy — tam ul.products nie ma żadnego z tych przodków:
     .artykul       — wpis (single.php) i strona statyczna (page.php),
     .proza         — opisy PDP i pełny opis kategorii,
     .entry-content — zapas na treść składaną wtyczkami/blokami; żaden szablon
                      motywu tej klasy nie wypisuje, ale wtyczki bywają uparte.

   Specyficzność: bazowa reguła siatki to
   `:is(.woocommerce,.woocommerce-page) ul.products.products:not(.karuzela__tor)`
   = (0,4,2). Selektory poniżej mają PIĘĆ klas (kontener + .products
   + .products + .columns-N + :not) czyli (0,5,1) — wygrywają liczbą klas,
   bez !important i niezależnie od kolejności arkuszy. Wykluczenie
   .karuzela__tor jak w regułach bazowych: tor karuzeli ma własne szerokości
   slajdów i nigdy nie ma być gridem.
   Wariantów columns-5/6 nie obsługujemy osobno — zostają przy czterech torach.

   🔴 RUNDA 5 — SAM TEN BLOK NIE WYSTARCZAŁ. `columns-N` NIE oznacza liczby
   produktów: WC_Shortcode_Products bierze N z atrybutu `columns`, a ten
   domyślnie równa się ustawieniu sklepu (zwykle 4) niezależnie od tego, ile
   produktów pętla zwróci. Dla `[products ids="123"]` i `[products limit="3"]`
   bez jawnego `columns=` lista dostawała więc columns-4 i reguły niżej dawały
   repeat(4,1fr) — czyli dokładnie objaw, który miały naprawić.
   Klasę normalizuje do LICZBY KAFLI filtr m420_shortcode_kolumny
   (inc/listing.php, hook woocommerce_product_loop_start). Reguły poniżej
   zostają bez zmian i są odtąd karmione prawdziwą liczbą produktów;
   jeśli kiedyś znów zaczną chybiać, sprawdzaj NAJPIERW tamten filtr. */

/* odstęp od akapitów: reset *{margin:0} + `ul.products{margin:0}` skleiłyby
   siatkę z tekstem nad nią i pod nią */
:is(.artykul,.proza,.entry-content) ul.products.products:not(.karuzela__tor){margin:18px 0}
:is(.artykul,.proza,.entry-content) ul.products.products.columns-1:not(.karuzela__tor){grid-template-columns:1fr;max-width:50%}
:is(.artykul,.proza,.entry-content) ul.products.products.columns-2:not(.karuzela__tor){grid-template-columns:repeat(2,1fr)}
:is(.artykul,.proza,.entry-content) ul.products.products.columns-3:not(.karuzela__tor){grid-template-columns:repeat(3,1fr)}
:is(.artykul,.proza,.entry-content) ul.products.products.columns-4:not(.karuzela__tor){grid-template-columns:repeat(4,1fr)}
@media(max-width:980px){
  /* w kolumnie tekstu cztery kafle robią się na tablecie za wąskie na nazwę
     produktu (min-height:2.7em w .prod__nazwa to trzy wiersze) */
  :is(.artykul,.proza,.entry-content) ul.products.products.columns-4:not(.karuzela__tor){grid-template-columns:repeat(3,1fr)}
}
@media(max-width:640px){
  :is(.artykul,.proza,.entry-content) ul.products.products.columns-1:not(.karuzela__tor){max-width:none}
  :is(.artykul,.proza,.entry-content) ul.products.products:is(.columns-2,.columns-3,.columns-4):not(.karuzela__tor){grid-template-columns:repeat(2,1fr)}
}

/* ============================================================
   RUNDA 6 — modale (render: inc/modal.php na wp_footer, obsługa: motyw.js (f))
   ============================================================
   Jedno okno dla trzech zastosowań: kafelki zaufania, wyjaśnienie rat BNPL
   i warunki gwarancji. Rodzina klas jest osobna od `.bramka` (18+) świadomie —
   bramka ma własny, wąski i wyśrodkowany kształt „zapytania", a modal to okno
   z czytaną treścią: szersze (560 px), tekst do lewej, z własnym przewijaniem.
   Warstwa overlaya jest wspólna z bramką co do wartości, bo obie zasłaniają
   cały sklep i nigdy nie są otwarte naraz.

   🔴 WARSTWY. z-index:100 = miejsce bramki 18+ w drabinie motywu
   (sticky-atc 45 → nagłówek 50 → mega 55 → szukajka 60 → 100 → drawer
   mini-koszyka 9999). Wystarcza dla wszystkiego, co renderuje sklep, ALE NIE
   dla drawera mini-koszyka. Gdy powstanie wyzwalacz modala wewnątrz drawera,
   podnieść tę jedną wartość do 10050 — i tylko wtedy, nie na zapas.
   Warunkiem działania tej liczby jest render POZA <header> (patrz inc/modal.php).

   Widocznością steruje wyłącznie atrybut `hidden` zdejmowany z JS — nie klasa
   stanu. Domyślne `display` dla [hidden] przegrywa z `display:grid` reguły
   bazowej, stąd jawna reguła `.m420-modal[hidden]` tuż pod nią (ten sam układ
   co przy `.bramka`). */
.m420-modal{position:fixed;inset:0;background:rgba(10,14,11,.78);backdrop-filter:blur(4px);z-index:100;display:grid;place-items:center;padding:20px}
.m420-modal[hidden]{display:none}
/* max-height + overflow: warunki gwarancji potrafią być dłuższe niż ekran,
   a okno bez własnego przewijania urwałoby je bez śladu (tło ma zablokowany
   scroll na czas otwarcia). min() domyka to od góry na dużym monitorze —
   okno rozciągnięte na 1400 px wysokości czyta się gorzej niż zwarty blok. */
.m420-modal__okno{position:relative;background:#fff;border-radius:var(--r);max-width:560px;width:100%;padding:28px;text-align:left;max-height:min(86vh,800px);overflow:auto}
/* Krzyżyk nad treścią, w rogu okna. position:absolute wymaga, żeby okno miało
   position:relative (wyżej) — inaczej uciekłby do narożnika overlaya. */
.m420-modal__zamknij{position:absolute;top:10px;right:12px;width:34px;height:34px;display:grid;place-items:center;border:0;background:none;cursor:pointer;font-size:26px;line-height:1;color:var(--tusz-2);border-radius:50%}
.m420-modal__zamknij:hover{background:var(--tlo-2);color:var(--tusz)}
/* Miejsce na krzyżyk: bez tego długi tytuł wchodzi pod przycisk. */
.m420-modal__okno h2{font-size:21px;margin-bottom:14px;padding-right:38px}
.m420-modal__tresc{color:var(--tusz-2);font-size:14.5px;line-height:1.6}
/* Reset motywu zeruje marginesy i wcięcia list (*{margin:0;padding:0}),
   więc treść modala musi odzyskać rytm akapitów u siebie. */
.m420-modal__tresc>*+*{margin-top:10px}
.m420-modal__tresc ul,.m420-modal__tresc ol{padding-left:20px}
.m420-modal__tresc li{margin-bottom:4px}
.m420-modal__tresc b,.m420-modal__tresc strong{color:var(--tusz)}
/* Przycisk domykający na pełną szerokość okna (wzór ze strony wzorcowej:
   440×46). .btn jest inline-flex, więc sama szerokość nie wystarczy — wysokość
   pilnuje min-height, bo krótki napis przy padding:13px daje ~44 px. */
.m420-modal__ok{width:100%;min-height:46px;margin-top:22px}

@media(max-width:640px){
  /* Na telefonie oddech overlaya zjada szerokość okna, a marginesy wewnętrzne
     28 px zostawiają na tekst mniej niż 280 px. Okno dostaje też więcej wysokości
     — na małym ekranie 86vh to często niecałe pół strony warunków. */
  .m420-modal{padding:12px}
  .m420-modal__okno{padding:22px 18px;max-height:min(92vh,800px)}
  .m420-modal__okno h2{font-size:19px}
}


/* ==========================================================================
 * RUNDA 7 (26.08) — pigułka odroczonych płatności pod ceną
 * ========================================================================== */

/* Wygląd pigułki, nie przycisku: ma zapraszać do kliknięcia, ale nie konkurować
   wagą z „Dodaj do koszyka" stojącym kilkanaście pikseli niżej. Stąd obrys
   zamiast wypełnienia i waga 500 zamiast 700. */
.bnpl{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--linia);
  border-radius:999px;background:#fff;padding:4px 10px;font-size:14px;font-weight:500;
  color:var(--tusz);cursor:pointer;margin:4px 0 2px;line-height:1.4}
.bnpl:hover{border-color:var(--zielen)}
.bnpl b{font-weight:700}


/* ==========================================================================
 * RUNDA 8 (26.08) — sekcja „Wyroznione" nad listingiem kategorii
 * ========================================================================== */

/* Sekcja MUSI odcinac sie od listingu. Te same produkty pojawiaja sie nizej
   w glownej petli (swiadomie - wyciecie ich przez post__not_in rozjezdza
   stronicowanie), wiec bez wyraznej ramy powtorzenie czyta sie jak usterka,
   a nie jak polecenie. Stad tlo, obrys i wlasny naglowek. */
.polecane-kat{background:var(--tlo-2);border:1px solid var(--linia);border-radius:var(--r);
  padding:18px 18px 6px;margin:0 0 22px}
.polecane-kat__tytul{margin:0 0 14px;font-size:1.15rem;letter-spacing:-.02em}
/* Kafle w srodku sekcji stoja na bialym, zeby odciac sie od jej tla. */
.polecane-kat .prod{background:#fff;border-radius:var(--r-s);padding:10px}

/* Kafle podkategorii na listingu: ta sama siatka co na stronie glownej,
   ale z oddechem pod spodem, bo zaraz pod nimi zaczyna sie pasek filtrow. */
.kafle-kat--podkategorie{margin-bottom:22px}


/* ==========================================================================
 * RUNDA 8 (26.08) — karta zaufania pod przyciskiem koszyka
 * ========================================================================== */

.karta-zaufania{background:#fff;border:1px solid var(--linia);border-radius:var(--r);
  margin:14px 0 4px;overflow:hidden}

/* Wiersz jest siatka 48px + reszta, zeby ikony staly w jednej pionowej linii
   niezaleznie od tego, ile linijek ma tekst obok. */
.karta-zaufania__wiersz{display:grid;grid-template-columns:44px 1fr auto;align-items:start;
  gap:0 12px;padding:14px 16px;width:100%;text-align:left;background:none;border:0;
  font:inherit;color:inherit}
/* Kreska TYLKO miedzy wierszami - nie nad pierwszym i nie pod ostatnim. */
.karta-zaufania__wiersz+.karta-zaufania__wiersz{border-top:1px solid var(--linia)}
.karta-zaufania__wiersz--klik{cursor:pointer}
.karta-zaufania__wiersz--klik:hover{background:var(--tlo-2)}
.karta-zaufania__wiersz--klik:focus-visible{outline:2px solid var(--zielen);outline-offset:-2px}

.karta-zaufania__ikona{display:grid;place-items:center;width:44px;height:44px;
  border-radius:50%;background:var(--tlo-2)}
.karta-zaufania__ikona svg{width:20px;height:20px;stroke:var(--zielen);fill:none}

.karta-zaufania__tresc{min-width:0;display:block;line-height:1.45}
.karta-zaufania__tresc b{display:block;font-size:14.5px;font-weight:700;color:var(--tusz)}
.karta-zaufania__tresc small{display:block;margin-top:2px;font-size:13px;color:var(--tusz-2)}

.karta-zaufania__platnosci{display:flex;flex-wrap:wrap;gap:5px;margin-top:7px}

/* Punkty w dwoch kolumnach - przy czterech pozycjach daje to rowny kwadrat
   zamiast dlugiej kolumny spychajacej reszte karty w dol. */
.karta-zaufania__punkty{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:4px 12px;margin-top:7px}
.karta-zaufania__punkt{position:relative;padding-left:19px;font-size:13px;color:var(--tusz-2)}
/* Ptaszek rysowany tlem, nie znakiem - nie wejdzie do zaznaczenia i nie zostanie
   odczytany przez czytnik ekranu jako smiec. */
.karta-zaufania__punkt::before{content:"";position:absolute;left:0;top:4px;width:13px;height:13px;
  background:no-repeat center/13px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2314806a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4 4L19 7'/%3E%3C/svg%3E")}

.karta-zaufania__szewron{align-self:center;color:var(--tusz-2);font-size:20px;line-height:1}

@media(max-width:560px){
  .karta-zaufania__punkty{grid-template-columns:1fr}
}


/* ==========================================================================
 * RUNDA 9 (26.08) — uwagi Pawla po obejrzeniu 0.5.0
 * ========================================================================== */

/* --- 1. Galeria produktu trzyma sie ekranu na desktopie ---------------------
   Kolumna z opisem jest znacznie dluzsza od galerii, wiec po przewinieciu
   buyboxa lewa polowa ekranu robila sie biala az do konca strony. `top:130px`
   to ta sama wartosc, ktorej uzywaja filtry listingu i podsumowanie koszyka —
   wysokosc przyklejonego naglowka.

   ⚠ Sticky dziala tu tylko dlatego, ze .uklad-pdp ma `align-items:start`.
   Przy `stretch` element gridu ma wysokosc calej komorki i nie ma sie po czym
   przesuwac — wygladaloby to na „sticky nie dziala". */
/* 🔴 SPECYFICZNOSC (0,4,2), nie (0,2,0). Pierwsza wersja tej reguly celowala
   w `.uklad-pdp>.woocommerce-product-gallery` i NIE dzialala: kontener galerii
   ma tez klase `images`, wiec reguly WooCommerce `.woocommerce div.product
   div.images` (0,3,2) trzymaly `position:relative`. Objaw byl mylacy — `top:130px`
   z naszej reguly SIE STOSOWALO (nikt inny nie ustawia `top`), a samo `position`
   przegrywalo. Wygladalo to, jakby przegladarka ignorowala `sticky`.

   ⚠ Nie dopisywac tu !important: wystarczy wejsc klasami wyzej niz rodzina Woo. */
@media(min-width:981px){
  .woocommerce div.product .uklad-pdp>div.images.woocommerce-product-gallery,
  .uklad-pdp>.galeria{position:sticky;top:130px}
}

/* --- 2. Podkategorie: szesc kolumn na desktopie, dwie na telefonie ---------
   Kafle podkategorii sa mniejsze niz kafle dzialow na stronie glownej i jest
   ich wiecej, wiec cztery kolumny zostawialy pod nimi duzo pustego miejsca. */
.kafle-kat--podkategorie{grid-template-columns:repeat(6,1fr);gap:12px}
.kafle-kat--podkategorie .kafel-kat{padding:12px}
.kafle-kat--podkategorie .kafel-kat b{font-size:13.5px;line-height:1.3}
.kafle-kat--podkategorie .kafel-kat small{font-size:11.5px}
@media(max-width:1100px){ .kafle-kat--podkategorie{grid-template-columns:repeat(4,1fr)} }
@media(max-width:820px){ .kafle-kat--podkategorie{grid-template-columns:repeat(3,1fr)} }
@media(max-width:560px){ .kafle-kat--podkategorie{grid-template-columns:repeat(2,1fr)} }

/* --- 3. Paginacja w kolkach -----------------------------------------------
   Wczesniej numery mialy maly promien i stykaly sie bokami, wiec caly pasek
   czytal sie jak jeden sklejony pasek. Kolka pasuja do reszty motywu (pigulki
   filtrow, przyciski) i rozdzielaja numery wizualnie. */
/* 🔴 Kwadrat wokol kolka rysowalo <li>, nie <a>. WooCommerce daje liscie wlasna
   ramke i tlo, a nasza regula stylowala tylko wnetrze — stad „kolko w kwadracie".
   Zdejmujemy ramke z <li> i dajemy odstep na liscie, nie na elemencie. */
.woocommerce-pagination ul{gap:10px;border:0;background:none}
.woocommerce-pagination ul li{border:0;background:none;overflow:visible;display:block}
.woocommerce-pagination ul li a,
.woocommerce-pagination ul li span{min-width:40px;height:40px;padding:0;border-radius:999px;
  display:grid;place-items:center;background:#fff}
.woocommerce-pagination ul li a:hover{background:var(--tlo-2);border-color:var(--zielen)}
/* Strzalki „poprzednia/nastepna" dostaja owal zamiast kola — miesci sie w nich slowo. */
.woocommerce-pagination ul li a.prev,
.woocommerce-pagination ul li a.next{padding:0 16px;min-width:0}

/* --- 4. Moje konto: dwie kolumny niezaleznie od opakowania -----------------
   🔴 Poprzednia regula celowala w `.woocommerce:has(>.woocommerce-MyAccount-navigation)`
   i na zywym sklepie NIE dzialala — nawigacja szla przez cala szerokosc, a tabela
   zamowien ladowala pod nia. Znaczy to, ze nawigacja nie jest bezposrednim
   dzieckiem `.woocommerce` (WooCommerce albo wtyczka wklada wlasne opakowanie).

   🔑 Zamiast zgadywac nazwe tego opakowania, celujemy w DOWOLNY element, ktory
   jest bezposrednim rodzicem nawigacji. Kombinator `>` w :has() sprawia, ze
   regula trafia wylacznie w ten jeden element, a nie we wszystkich przodkow. */
.woocommerce-account *:has(>.woocommerce-MyAccount-navigation){display:grid;
  grid-template-columns:250px minmax(0,1fr);gap:26px;align-items:start}
.woocommerce-account .woocommerce-MyAccount-navigation{min-width:0}
.woocommerce-account .woocommerce-MyAccount-content{min-width:0}
/* Tabela zamowien rozpychala sie waskimi kolumnami z lamanymi datami. */
.woocommerce-account .woocommerce-MyAccount-content table.woocommerce-orders-table{width:100%}
.woocommerce-account .woocommerce-orders-table td,
.woocommerce-account .woocommerce-orders-table th{white-space:nowrap}
.woocommerce-account .woocommerce-orders-table td.woocommerce-orders-table__cell-order-actions{
  display:flex;flex-wrap:wrap;gap:6px}
@media(max-width:820px){
  .woocommerce-account *:has(>.woocommerce-MyAccount-navigation){grid-template-columns:1fr;gap:18px}
  .woocommerce-account .woocommerce-orders-table td,
  .woocommerce-account .woocommerce-orders-table th{white-space:normal}
}


/* --- 5. „Czesto kupowane razem" — pas nad opisem -------------------------
   🔴 Bylo to sticky w waskiej kolumnie obok opisu i nie dalo sie tego uratowac
   samym CSS: przyklejony element nie ma jak sie zatrzymac, gdy sasiednia kolumna
   sie konczy, wiec plynal jeszcze kilkaset pikseli nad pustka. Teraz to pas
   pelnej szerokosci NAD opisem — bez sticky i widoczny wczesniej.

   Na desktopie siatka czterech kolumn, na telefonie tor przewijany palcem. */
.pasujace{margin:0 0 26px}
.pasujace__tytul{margin:0 0 14px;font-size:1.15rem;letter-spacing:-.02em}
.pasujace__lista{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}

/* 🔴 position:relative NIE jest ozdobnikiem — trzyma w kafelku absoluty rdzenia.
   WooCommerce wstawia w cene `<span class="screen-reader-text">` z position:absolute
   i BEZ wlasnego `left`. Bez bloku zawierajacego na kafelku ich blokiem zawierajacym
   staje sie `div.product` (position:relative), wiec span ladowal w pozycji statycznej
   Z WNETRZA przewijanego toru — czyli kilkaset pikseli za prawa krawedzia ekranu —
   i rozpychal CALA strone. Na telefonie dawalo to 220 px bialego pasa obok produktu.
   `overflow-x:auto` toru tego nie lapie: absolut z blokiem zawierajacym POZA torem
   nie jest przez tor przycinany. */
.pasujace__el{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--linia);
  border-radius:var(--r);padding:12px;transition:border-color .15s,box-shadow .15s}
.pasujace__el:hover{border-color:var(--zielen);box-shadow:var(--cien)}
.pasujace__link{display:flex;flex-direction:column;gap:8px;color:var(--tusz);flex:1}
.pasujace__link:hover{color:var(--tusz)}
/* Zdjecie na calej szerokosci kafla, kwadrat — jak w kaflach listingu. Wczesniej
   bylo wciete w kolumne 56 px i nazwa lamala sie po dwoch znakach. */
.pasujace__foto{display:block;background:var(--tlo-2);border-radius:var(--r-s);padding:8px}
.pasujace__foto img{width:100%;aspect-ratio:1;object-fit:contain;display:block}
.pasujace__opis{min-width:0;display:block}
.pasujace__opis b{font-size:13.5px;font-weight:600;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pasujace__cena{display:block;margin-top:6px;font-size:15px;font-weight:800;color:var(--tusz)}
.pasujace__cena del{font-weight:500;font-size:13px;color:var(--tusz-2);margin-right:6px}
.pasujace__cena ins{text-decoration:none;color:var(--zielen)}

.pasujace__dodaj{display:block;width:100%;margin-top:10px;padding:9px 12px;border-radius:999px;
  border:1.5px solid var(--zielen);background:#fff;color:var(--zielen);font-size:13.5px;
  font-weight:700;cursor:pointer;text-align:center;line-height:1.3}
.pasujace__dodaj:hover{background:var(--zielen);color:#fff}
.pasujace__dodaj.dodany{border-color:var(--akcent);background:var(--akcent);color:#123330}

/* Telefon: tor przewijany palcem. Kafle maja stala szerokosc, zeby kolejny
   wystawal zza krawedzi i bylo widac, ze da sie przewinac. */
@media(max-width:820px){
  .pasujace__lista{display:flex;overflow-x:auto;gap:12px;padding-bottom:6px;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch}
  .pasujace__el{flex:0 0 62%;max-width:220px;scroll-snap-align:start}
}
@media(max-width:1100px) and (min-width:821px){
  .pasujace__lista{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* ==========================================================================
 * RUNDA 10 (26.08) — komentarze pod wpisem
 * ========================================================================== */

/* Sekcja komentarzy nie byla ostylowana w ogole: WordPress renderowal ja golymi
   znacznikami, wiec pod zadbanym wpisem stal blok z innej epoki. Stylujemy
   klasami rdzenia, bo motyw nie ma wlasnego comments.php i nie chcemy go zakladac
   tylko po to, zeby zmienic nazwy klas. */
.comments-area{margin-top:34px;padding-top:26px;border-top:1px solid var(--linia)}
.comments-area .comments-title,
.comments-area .comment-reply-title{font-size:1.25rem;margin:0 0 18px;letter-spacing:-.02em}
.comment-list{list-style:none;margin:0 0 26px;padding:0;display:flex;flex-direction:column;gap:14px}
.comment-list ol.children{list-style:none;margin:14px 0 0 26px;padding:0;display:flex;
  flex-direction:column;gap:14px;border-left:2px solid var(--linia);padding-left:16px}
.comment-list li.comment,.comment-list li.pingback{background:#fff;border:1px solid var(--linia);
  border-radius:var(--r);padding:16px 18px}
.comment-list .comment-meta{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.comment-list .comment-author img.avatar{border-radius:50%;width:38px;height:38px}
.comment-list .comment-author .fn{font-weight:700;font-style:normal;color:var(--tusz)}
.comment-list .comment-metadata,.comment-list .comment-metadata a{font-size:12.5px;color:var(--tusz-2)}
.comment-list .comment-content{font-size:15px;line-height:1.65}
.comment-list .comment-content p{margin:0 0 10px}
.comment-list .comment-content p:last-child{margin-bottom:0}
.comment-list .reply a{display:inline-block;margin-top:8px;font-size:13px;font-weight:700;color:var(--zielen)}
.comment-list .comment-awaiting-moderation{display:block;margin-top:8px;font-size:13px;color:var(--tusz-2)}

.comment-respond{background:var(--tlo-2);border:1px solid var(--linia);border-radius:var(--r);padding:20px}
.comment-form{display:grid;gap:12px}
.comment-form .comment-notes,.comment-form .logged-in-as{grid-column:1/-1;margin:0;font-size:13px;color:var(--tusz-2)}
.comment-form p{margin:0}
.comment-form label{display:block;margin-bottom:5px;font-size:13.5px;font-weight:600}
.comment-form input[type=text],.comment-form input[type=email],
.comment-form input[type=url],.comment-form textarea{width:100%;padding:11px 13px;
  border:1px solid var(--linia);border-radius:var(--r-s);background:#fff;font:inherit}
.comment-form input:focus,.comment-form textarea:focus{outline:2px solid var(--zielen);outline-offset:-1px;border-color:var(--zielen)}
.comment-form textarea{min-height:120px;resize:vertical}
.comment-form .comment-form-cookies-consent{display:flex;align-items:flex-start;gap:8px}
.comment-form .comment-form-cookies-consent label{margin:0;font-weight:400;font-size:13px}
.comment-form .form-submit{margin:0}
.comment-form .submit{padding:12px 26px;border:0;border-radius:999px;background:var(--akcent);
  color:#123330;font-weight:700;font-size:15px;cursor:pointer}
.comment-form .submit:hover{background:var(--akcent-2)}
@media(min-width:640px){
  .comment-form{grid-template-columns:1fr 1fr}
  .comment-form .comment-form-comment,.comment-form .form-submit,
  .comment-form .comment-form-cookies-consent{grid-column:1/-1}
}

/* Podobne wpisy pod artykulem — ta sama siatka co kafle bloga na glownej. */
.podobne-wpisy{margin-top:34px;padding-top:26px;border-top:1px solid var(--linia)}
.podobne-wpisy__tytul{font-size:1.25rem;margin:0 0 16px;letter-spacing:-.02em}
.podobne-wpisy__lista{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.podobne-wpis{background:#fff;border:1px solid var(--linia);border-radius:var(--r);overflow:hidden;
  color:var(--tusz);display:flex;flex-direction:column;transition:border-color .15s,box-shadow .15s}
.podobne-wpis:hover{border-color:var(--zielen);box-shadow:var(--cien);color:var(--tusz)}
.podobne-wpis img{width:100%;aspect-ratio:16/9;object-fit:cover}
.podobne-wpis__tresc{padding:12px 14px 14px}
.podobne-wpis__tresc b{display:block;font-size:14.5px;line-height:1.35;font-weight:700}
.podobne-wpis__tresc small{display:block;margin-top:6px;font-size:12.5px;color:var(--tusz-2)}
@media(max-width:820px){ .podobne-wpisy__lista{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media(max-width:520px){ .podobne-wpisy__lista{grid-template-columns:1fr} }


/* ==========================================================================
 * RUNDA 11 (26.08) — slider banerow + pasek „Do koszyka" w naglowku
 * ========================================================================== */

/* --- Slider ---------------------------------------------------------------
   🔑 Slajdy leza JEDEN NA DRUGIM w gridzie (wszystkie w komorce 1/1), a nie
   w przewijanym torze. Dzieki temu wysokosc sekcji bierze sie z najwyzszego
   slajdu i nie skacze przy zmianie — a przelaczanie to sama zmiana krycia,
   czyli jedna wlasciwosc, ktora przegladarka animuje na karcie graficznej.

   ⚠ Slajdy nieaktywne maja `visibility:hidden`, nie samo `opacity:0`. Bez tego
   ich przyciski zostaja w kolejnosci tabulacji i czytelnik klawiatury wpada
   w niewidzialne odsylacze. */
/* Odstęp SYMETRYCZNY: tyle samo nad banerem co pod nim. Wcześniej baner
   przylegał do paska kategorii (zmierzone: 1 px od menu, 18 px do sekcji
   „Promocje tygodnia") i wyglądał, jakby był doklejony do nawigacji.

   `touch-action:pan-y` oddaje przeglądarce PIONOWE przewijanie, a poziome
   zostawia nam — bez tego przeciągnięcie palcem po banerze albo przewijało
   stronę, albo blokowało ją całkiem. */
.slider{position:relative;border-radius:var(--r);overflow:hidden;margin:18px 0;
  /* `pinch-zoom` obok `pan-y`: bez niego szczypanie nad banerem przestawało
     powiększać stronę, a to jedyny sposób, w jaki część osób czyta drobny druk. */
  touch-action:pan-y pinch-zoom;-webkit-user-select:none;user-select:none;
  display:grid;grid-template-areas:"slajd";isolation:isolate}
.slider__tor{display:grid;grid-template-areas:"slajd";grid-area:slajd}
/* ⚠ `visibility` i `transform` MUSZĄ być w liście przejścia.
   Bez `visibility` slajd znikał natychmiast, a nowy dopiero się wyłaniał — przez
   ułamek sekundy nie było widać żadnego i baner mrugał na biało. Bez `transform`
   podgląd przeciągania wracał SKOKIEM zamiast płynnie dojechać.
   `visibility` przełącza się skokowo, ale opóźnione o czas przejścia krycia,
   więc slajd znika dopiero wtedy, gdy jest już przezroczysty. */
.slider__slajd{grid-area:slajd;position:relative;opacity:0;visibility:hidden;
  transition:opacity .45s ease,transform .3s ease,visibility 0s linear .45s}
.slider__slajd.jest-aktywny{transition:opacity .45s ease,transform .3s ease,visibility 0s}
.slider__slajd.jest-aktywny{opacity:1;visibility:visible}
.slider__obraz{display:block}
.slider__obraz img{display:block;width:100%;aspect-ratio:8/3;object-fit:cover}

/* Tekst na lewej polowie — dokladnie to bezpieczne pole, o ktorym mowia opisy
   pol w customizerze. Gradient tylko po lewej, zeby nie przygaszac produktu
   po prawej stronie zdjecia. */
.slider__tresc{position:absolute;inset:0;display:flex;flex-direction:column;
  justify-content:center;gap:10px;padding:0 clamp(20px,5vw,56px);max-width:52%;color:#fff}
.slider__slajd::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(10,14,11,.78) 0%,rgba(10,14,11,.55) 38%,rgba(10,14,11,0) 66%)}
.slider__tresc>*{position:relative;z-index:1}
.slider__tresc .nadtytul{color:var(--akcent);font-weight:700;font-size:13px;letter-spacing:.04em;text-transform:uppercase}
.slider__tresc h2{margin:0;color:#fff;font-size:clamp(1.35rem,2.4vw + .5rem,2.35rem);line-height:1.12;letter-spacing:-.03em}
.slider__tresc p{margin:0;color:rgba(255,255,255,.9);font-size:clamp(14px,1vw + 8px,16.5px);max-width:44ch}
.slider__tresc .btn{align-self:flex-start;margin-top:4px}

.slider__kropki{position:absolute;left:0;right:0;bottom:14px;z-index:2;
  display:flex;justify-content:center;gap:8px}
.slider__kropka{width:10px;height:10px;padding:0;border:0;border-radius:50%;
  background:rgba(255,255,255,.45);cursor:pointer;transition:background .2s,transform .2s}
.slider__kropka:hover{background:rgba(255,255,255,.75)}
.slider__kropka.jest-aktywna{background:#fff;transform:scale(1.25)}
.slider__kropka:focus-visible{outline:2px solid #fff;outline-offset:3px}

@media(max-width:820px){
  .slider__obraz img{aspect-ratio:1}
  .slider__tresc{max-width:100%;padding:0 20px 34px;justify-content:flex-end}
  .slider__slajd::before{background:linear-gradient(0deg,rgba(10,14,11,.85) 0%,rgba(10,14,11,.35) 45%,rgba(10,14,11,0) 75%)}
}
/* Kto wylaczyl animacje w systemie, dostaje twarde przelaczenie. */
@media(prefers-reduced-motion:reduce){ .slider__slajd{transition:none} }

/* --- Pasek „Do koszyka" ZOSTAJE NA DOLE, na kazdej szerokosci --------------
   🔴 Wersja gorna (0.9.0) zostala USUNIETA na polecenie Pawla 26.08: przykrywala
   wysuwany mini-koszyk, ktory tez wchodzi od gory. Dwa panele walczace o ten sam
   pas ekranu to gorszy problem niz ten, ktory pasek gorny mial rozwiazac.

   Zostaje wiec dotychczasowy `.sticky-atc` przy dolnej krawedzi — i teraz
   naprawde na KAZDEJ szerokosci, bo reguly chowajacej go na komputerze juz nie
   ma. Kciuk siega do dolu, mysz tez tam trafi, a mini-koszyk ma gore dla siebie. */

/* Tekst opisowy strony glownej: waska kolumna dla czytelnosci, odsylacze
   podkreslone — to nie ozdoba, tylko nawigacja do kategorii. */
.proza-glowna{max-width:78ch}
.proza-glowna h2{font-size:clamp(1.3rem,1.6vw + .6rem,1.8rem);margin:0 0 12px;letter-spacing:-.025em}
.proza-glowna h3{font-size:1.05rem;margin:22px 0 8px;letter-spacing:-.015em}
.proza-glowna p{margin:0 0 12px;font-size:15.5px;line-height:1.7;color:var(--tusz-2)}
.proza-glowna a{color:var(--zielen);text-decoration:underline;text-underline-offset:2px}
.proza-glowna a:hover{color:var(--zielen-2)}
.proza-glowna strong{color:var(--tusz)}


/* ==========================================================================
 * RUNDA 12 (28.08) — logotypy operatorow platnosci i przewoznikow
 * ========================================================================== */

/* 🔑 BIALA PLAKIETKA POD KAZDYM LOGOTYPEM. Powod jest praktyczny, nie estetyczny:
   BLIK ma wlasna czarna plytke, PayPo czarny tekst, PayU ciemnozielony,
   a Paczkomaty i raty PayU przyszly z bialym tlem wtopionym w plik. Na ciemnym
   pasku stopki czesc znikala, czesc pokazywala biale prostokaty. Plakietka
   zalatwia wszystkie przypadki naraz i wyglada tak samo na kazdym tle. */
.logo-oper{display:inline-flex;align-items:center;background:#fff;border-radius:6px;
  padding:4px 6px;line-height:0;flex:none}
.logo-oper img{display:block;height:24px;width:auto}

/* Przewoznicy sa o szesc pikseli wyzsi — patrz komentarz przy m420_logotypy():
   „InPost Kurier" jest dwuwierszowy i przy wysokosci platnosci bylby nieczytelny. */
.karta-zaufania__logo .logo-oper img[alt*="InPost"],
.stopka__platnosci .logo-oper img[alt*="InPost"]{height:30px}

.karta-zaufania__logo{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.stopka__platnosci .logo-oper{margin:0}

/* Pasek stopki laczy teraz obrazki i napisy, wiec wyrownujemy je do srodka
   w pionie — inaczej napisy „usiadlyby" na dolnej krawedzi plakietek. */
.stopka__platnosci{align-items:center;row-gap:8px}


/* Pigulka „0 zl dzisiaj" z logotypami: mniejsze niz w karcie zaufania, bo caly
   element ma byc lekki i nie konkurowac wzrokowo z przyciskiem zakupu kilkanascie
   pikseli nizej. Plakietka traci tu tlo — pigulka sama jest biala, wiec drugie
   biale pole w srodku wygladaloby jak podwojna ramka. */
.bnpl .logo-oper{background:none;padding:0}
.bnpl .logo-oper img{height:18px}


/* ==========================================================================
 * RUNDA 13 (28.08) — odstep nad komentarzami
 * ========================================================================== */

/* Komentarze wychodza spod `comments_template()` i w single.php stoja ZARAZ
   za sekcja „Podobne artykuly". Bez wlasnego marginesu obie sekcje sklejaja sie
   w jeden blok i nie widac, gdzie konczy sie jedna, a zaczyna druga.

   ⚠ Celujemy w `#comments`, bo motyw nie ma wlasnego `comments.php` — znacznik
   pochodzi z rdzenia WordPressa i tylko to id jest w nim pewne. Gdyby kiedys
   doszedl wlasny szablon, ta regula dalej zadziala. */
#comments{margin-top:40px;padding-top:28px;border-top:1px solid var(--linia)}
#comments .comment-reply-title,
#comments .comments-title{font-size:1.15rem;letter-spacing:-.02em;margin:0 0 16px}


/* --- Strona „Promocje" ----------------------------------------------------
   Baner ten sam co na stronie glownej, tylko bez przycisku — jestesmy juz na
   stronie, do ktorej ten baner prowadzi. Nagłowek slajdu jest tu <h1>, wiec
   dostaje wieksza wage niz na glownej, gdzie stoi jako <h2>. */
.slider--promocje{margin-bottom:24px}
.slider--promocje .slider__tresc h1{margin:0;color:#fff;
  font-size:clamp(1.5rem,2.6vw + .5rem,2.5rem);line-height:1.1;letter-spacing:-.03em}
.promocje__tytul{margin:8px 0 22px}
.promocje__pusto{padding:34px 0;color:var(--tusz-2)}


/* Akapit z odsylaczami do podkategorii, doklejany filtrem do opisu kategorii.
   Odcinamy go kreska od tresci opisu, bo to nawigacja, a nie ciag dalszy tekstu. */
.kat-linki{margin-top:18px;padding-top:14px;border-top:1px solid var(--linia);
  font-size:14.5px;color:var(--tusz-2)}
.kat-linki a{color:var(--zielen);font-weight:600}

/* ==========================================================================
 * RUNDA 15 (29.08) — kasa bez rozpraszaczy + panel kategorii na telefon
 * ========================================================================== */

/* --- Kasa: nagłówek to samo logo, na środku ------------------------------- */
.m420-kasa .naglowek__rzad{justify-content:center;padding:18px 0}
.m420-kasa .naglowek{border-bottom:1px solid var(--linia)}
.m420-kasa .logo{margin:0}
.stopka--kasa{background:var(--tlo-2);color:var(--tusz-2);border-top:1px solid var(--linia);
  margin-top:40px;padding:20px 0;font-size:13px}
.stopka--kasa__prawne{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 18px;margin-bottom:8px}
.stopka--kasa__prawne a{color:var(--tusz-2);text-decoration:underline}
.stopka--kasa__prawne a:hover{color:var(--tusz)}
.stopka--kasa__nota{text-align:center;color:var(--tusz-2)}

/* --- Kapsułka „Wszystkie kategorie" ---------------------------------------
 * Na telefonie pasek kategorii był przewijany w bok: widać było trzy pozycje
 * z ośmiu, a podkategorii nie widać wcale, bo mega otwiera się na najechanie,
 * którego na dotyku nie ma. Kapsułka jest w HTML zawsze — chowa ją CSS powyżej
 * 820 px, więc obrót telefonu ani cache strony nie robią skoku układu. */
.nav__kapsulka{display:none}
@media(max-width:820px){
  .nav>.srodek>ul,.nav>ul{display:none}
  .nav>.srodek{padding-top:8px;padding-bottom:8px}
  .nav__kapsulka{display:inline-flex;align-items:center;gap:9px;width:100%;
    padding:11px 16px;border:1px solid var(--linia);border-radius:999px;background:var(--tlo-2);
    font:inherit;font-weight:700;font-size:15px;color:var(--tusz);cursor:pointer}
  .nav__kapsulka svg{width:18px;height:18px;stroke:currentColor;flex:none}
  .nav__kapsulka[aria-expanded="true"]{background:var(--zielen-tlo);border-color:var(--akcent)}
}

/* --- Panel z pełnym drzewem kategorii ------------------------------------- */
.katmenu[hidden]{display:none}
.katmenu{position:fixed;inset:0;z-index:1200}
.katmenu__tlo{position:absolute;inset:0;background:rgba(21,26,23,.45)}
.katmenu__panel{position:absolute;inset:0 auto 0 0;width:min(92vw,420px);background:#fff;
  display:flex;flex-direction:column;box-shadow:var(--cien)}
.katmenu__pasek{flex:none;display:flex;align-items:center;justify-content:space-between;
  padding:14px 18px;border-bottom:1px solid var(--linia);font-size:16px}
.katmenu__x{border:0;background:none;font:inherit;font-size:26px;line-height:1;
  color:var(--tusz-2);cursor:pointer;padding:0 4px}
.katmenu__lista{list-style:none;margin:0;padding:0;flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch}
.katmenu__poz{border-bottom:1px solid var(--linia)}

/* Akordeon na <details> — działa też przy niezaładowanym skrypcie motywu. */
.katmenu__glowa{list-style:none;cursor:pointer;padding:14px 18px;font-weight:700;font-size:15.5px;
  display:flex;align-items:center;justify-content:space-between}
.katmenu__glowa::-webkit-details-marker{display:none}
.katmenu__glowa::after{content:"";width:9px;height:9px;flex:none;margin-left:12px;
  border-right:2px solid var(--tusz-2);border-bottom:2px solid var(--tusz-2);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s ease}
.katmenu__sekcja[open]>.katmenu__glowa::after{transform:rotate(-135deg) translate(-3px,-3px)}
.katmenu__sekcja[open]>.katmenu__glowa{background:var(--tlo-2)}
.katmenu__tresc{padding:4px 18px 14px}
.katmenu__link{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 0;color:var(--tusz);font-size:14.5px;text-decoration:none}
.katmenu__link:hover{color:var(--akcent-tekst)}
.katmenu__poz>.katmenu__link{padding:14px 18px;font-weight:700;font-size:15.5px}
.katmenu__link--wszystko{font-weight:700;color:var(--akcent-tekst)}
.katmenu__ile{flex:none;font-size:12px;color:var(--tusz-2);font-weight:500}
/* Etykieta grupy („Wysokość", „Filtracja") — z tej samej mapy co kolumny megi. */
.katmenu__grupa{display:block;padding:12px 0 2px;font-size:11px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--tusz-2)}
/* Trzeci poziom drzewa (marki pod „Waporyzatory przenośne") — wcięcie i kreska
   z lewej, żeby nie zlewał się z poziomem wyżej. Bez tego panel mieszałby
   „Waporyzatory stacjonarne" z „Arizer" na jednej wysokości. */
.katmenu__link--wnuk{padding-left:14px;font-size:13.5px;color:var(--tusz-2);
  border-left:2px solid var(--linia);margin-left:2px}
.katmenu__link--wnuk:hover{border-left-color:var(--akcent);color:var(--akcent-tekst)}

/* --- Hamburger: menu serwisowe na telefonie ------------------------------
 * Kapsułka „Wszystkie kategorie" prowadzi do towaru, hamburger do wszystkiego
 * innego: pomoc, konto, klub, regulamin. Rozdzielone celowo — jedno menu
 * z kategoriami i regulaminem naraz nie mówi klientowi, czego się w nim
 * spodziewać. Ikona siedzi w rzędzie ikon obok konta i koszyka. */
.ikona--menu{display:none;border:0;background:none;font:inherit;cursor:pointer}
@media(max-width:820px){.ikona--menu{display:flex}}
.ikona--menu[aria-expanded="true"]{color:var(--akcent-tekst)}

.sermenu[hidden]{display:none}
.sermenu{position:fixed;inset:0;z-index:1200}
.sermenu__tlo{position:absolute;inset:0;background:rgba(21,26,23,.45)}
/* Panel z PRAWEJ — hamburger stoi po prawej stronie rzędu ikon, a panel kategorii
   wjeżdża z lewej. Dwie różne strony = od razu widać, które menu się otworzyło. */
.sermenu__panel{position:absolute;inset:0 0 0 auto;width:min(88vw,360px);background:#fff;
  display:flex;flex-direction:column;box-shadow:var(--cien)}
.sermenu__pasek{flex:none;display:flex;align-items:center;justify-content:space-between;
  padding:14px 18px;border-bottom:1px solid var(--linia);font-size:16px}
.sermenu__x{border:0;background:none;font:inherit;font-size:26px;line-height:1;
  color:var(--tusz-2);cursor:pointer;padding:0 4px}
.sermenu__tresc{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 18px 22px}
.sermenu__sekcja{padding:14px 0;border-bottom:1px solid var(--linia)}
.sermenu__sekcja:last-of-type{border-bottom:0}
.sermenu__glowa{display:block;margin-bottom:6px;font-size:11px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--tusz-2)}
.sermenu__link{display:block;padding:9px 0;color:var(--tusz);font-size:15.5px;
  font-weight:600;text-decoration:none}
.sermenu__link:hover{color:var(--akcent-tekst)}
.sermenu__prawne{display:flex;flex-wrap:wrap;gap:6px 16px;padding-top:14px;
  border-top:1px solid var(--linia);font-size:12.5px}
.sermenu__prawne a{color:var(--tusz-2);text-decoration:underline}

/* --- Strona podziękowania: powitanie, kroki i konfetti -------------------- */
.podziek{background:var(--zielen-tlo);border:1px solid var(--linia);border-radius:var(--r);
  padding:26px 24px;margin:0 0 26px}
.podziek__glowa{text-align:center;margin-bottom:22px}
.podziek__emoji{display:block;font-size:44px;line-height:1;margin-bottom:8px}
.podziek__tytul{font-size:clamp(24px,4vw,34px);line-height:1.2;letter-spacing:-.02em;margin:0}
.podziek__lead{margin:6px 0 0;color:var(--tusz-2)}
.podziek__kroki{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.podziek__krok{display:flex;gap:12px;align-items:flex-start;background:#fff;
  border:1px solid var(--linia);border-radius:var(--r);padding:16px}
.podziek__krok svg{width:22px;height:22px;flex:none;margin-top:2px;
  stroke:var(--akcent-2);fill:none;stroke-linecap:round;stroke-linejoin:round}
.podziek__krok b{display:block;font-size:15px;line-height:1.3}
.podziek__krok small{display:block;margin-top:4px;color:var(--tusz-2);font-size:13px;line-height:1.4}
@media(max-width:820px){.podziek__kroki{grid-template-columns:1fr}.podziek{padding:22px 16px}}

/* Konfetti — jak plakietki w CannNotes. Warstwa jest przezroczysta dla klikniec
   i sprząta się sama po ~6 s (skrypt w inc/podziekowanie.php). */
.konfetti{position:fixed;inset:0;pointer-events:none;z-index:1300;overflow:hidden}
.konfetti__el{position:absolute;top:-8vh;will-change:transform,opacity;
  animation:m420-spadanie linear forwards}
@keyframes m420-spadanie{
  0%{transform:translate3d(0,0,0) rotate(0);opacity:0}
  8%{opacity:1}
  100%{transform:translate3d(var(--znos,0),112vh,0) rotate(var(--obrot,180deg));opacity:.9}
}
@media(prefers-reduced-motion:reduce){.konfetti{display:none}}

/* ==========================================================================
 * RUNDA 16 (29.08) — rytm nagłówków w treści
 * ==========================================================================
 *
 * Globalny reset `*{margin:0}` (linia 26) zeruje marginesy WSZYSTKIM nagłówkom.
 * Komponenty (sekcje, karuzele, kafle) mają własne odstępy i tak ma zostać —
 * ale w PROZIE oznaczało to nagłówki sklejone z tekstem:
 *
 *   .artykul h2  → margin-bottom 12 px  (za mało przy stopniu 21–28 px)
 *   .artykul h3  → BRAK reguły, czyli 0 px — nagłówek dotykał akapitu
 *   .proza  h2/h3 → BRAK reguł, czyli 0 px — opisy produktów i kategorii
 *
 * Ustawiamy jeden rytm dla wszystkich pojemników treści. Odstęp GÓRNY jest
 * wyraźnie większy od dolnego — nagłówek ma należeć do tekstu POD sobą,
 * a nie wisieć pośrodku między dwoma akapitami.
 *
 * ⚠ Selektor jest celowo wąski: tylko pojemniki prozy. Wpisanie tego w gołe
 * `h2{}` rozjechałoby nagłówki sekcji na stronie głównej, tytuł buyboxa,
 * nagłówki kolumn megi i kartę podziękowania — wszystkie mają własne odstępy.
 */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) h2{margin:38px 0 16px}
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) h3{margin:30px 0 12px}
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) h4{margin:24px 0 10px}
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) h5,
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) h6{margin:20px 0 8px}

/* Pierwszy element pojemnika nie odpycha się od góry — inaczej sekcja zaczyna
   się dziurą, a przy akordeonach karty produktu wygląda to na usterkę. */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content)>:is(h2,h3,h4,h5,h6):first-child{margin-top:0}

/* Dwa nagłówki pod rząd (h2 + h3 jako podtytuł) nie potrzebują pełnego odstępu
   między sobą — inaczej między „Najczęstsze pytania" a pierwszym pytaniem
   robi się 50 px pustki. */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) :is(h2,h3,h4)+:is(h3,h4,h5){margin-top:16px}

/* Nagłówek po liście albo tabeli — te elementy mają własny margines dolny,
   więc pełny odstęp górny nagłówka dokłada się do niego i robi wyrwę. */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) :is(ul,ol,table,figure,blockquote)+:is(h2,h3,h4){margin-top:26px}

/* --- Strona „Marki" (page-marki.php) --------------------------------------
 * Ten sam kafel co na stronie głównej, ale z logotypem, gdy marka je ma.
 * Logo w polu o STAŁEJ wysokości i `object-fit:contain` — logotypy mają skrajnie
 * różne proporcje (Storz & Bickel jest szeroki i płaski, DynaVap kwadratowy),
 * a bez wspólnego pola kafle miałyby różną wysokość i siatka by się rozjechała. */
.marki--strona{grid-template-columns:repeat(4,1fr);gap:12px}
.marka-kafel--logo{padding:16px 12px;gap:2px}
.marka-kafel__logo{width:auto;max-width:100%;height:44px;object-fit:contain;margin-bottom:8px;
  mix-blend-mode:multiply}
.marka-kafel__nazwa{font-weight:800;font-size:15px;line-height:1.2}
@media(max-width:900px){.marki--strona{grid-template-columns:repeat(3,1fr)}}
@media(max-width:620px){.marki--strona{grid-template-columns:repeat(2,1fr)}}

/* --- Formularz kontaktowy (Contact Form 7) --------------------------------
 * Motyw stylizował pola formularza komentarza, recenzji i checkoutu, ale nie
 * Contact Form 7 — jego pola mają WŁASNE klasy (.wpcf7-form-control), których
 * żaden selektor nie obejmował. Na jedynej stronie, przez którą klient pisze do
 * sklepu, wszystkie cztery pola miały domyślny wygląd przeglądarki, a szerokość
 * wymuszał atrybut `size="40"` z konfiguracji wtyczki (~300 px zamiast całej
 * kolumny). `width:100%` bije atrybut `size`/`cols`, więc nie trzeba ruszać
 * ustawień wtyczki. */
.wpcf7-form-control-wrap{display:block}
.wpcf7 :is(input[type=text],input[type=email],input[type=url],input[type=tel],input[type=date],input[type=number],select),
.wpcf7 textarea{
  box-sizing:border-box;width:100%;margin:0;padding:14px 16px;
  border:1.5px solid var(--linia);border-radius:var(--r-s);background:#fff;
  color:var(--tusz);font-family:inherit;font-size:15px;line-height:1.25;
  box-shadow:none;transition:border-color .15s}
.wpcf7 textarea{min-height:150px;line-height:1.55;resize:vertical}
.wpcf7 :is(input,textarea,select):focus{
  border-color:var(--zielen);outline:2px solid var(--zielen);outline-offset:1px}
.wpcf7 label{display:block;margin-bottom:16px;font-weight:600;font-size:14.5px;color:var(--tusz)}
.wpcf7 label .wpcf7-form-control-wrap{margin-top:6px}
/* Przycisk: ten sam kształt co CTA motywu — pełna szerokość na telefonie,
   bo domyślny „Wyślij" był szary i wielkości przycisku systemowego. */
.wpcf7 input[type=submit]{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:0 28px;border:0;border-radius:999px;cursor:pointer;
  background:var(--akcent);color:#06312e;font:inherit;font-weight:800;font-size:15.5px;
  transition:background .15s,transform .06s}
.wpcf7 input[type=submit]:hover{background:var(--akcent-2)}
.wpcf7 input[type=submit]:active{transform:translateY(1px)}
.wpcf7 input[type=submit]:focus-visible{outline:2px solid var(--zielen);outline-offset:2px}
@media(max-width:620px){.wpcf7 input[type=submit]{width:100%}}
/* Komunikaty walidacji: kolory z palety motywu zamiast domyślnej czerwieni CF7. */
.wpcf7 .wpcf7-not-valid-tip{color:var(--blad);font-size:13px;margin-top:5px}
.wpcf7 :is(input,textarea).wpcf7-not-valid{border-color:var(--blad)}
.wpcf7 .wpcf7-response-output{
  margin:18px 0 0;padding:14px 16px;border:1.5px solid var(--linia);
  border-radius:var(--r-s);font-size:14.5px;background:var(--tlo-2)}
.wpcf7 form.sent .wpcf7-response-output{border-color:var(--ok);background:#f0fdf4;color:#14532d}
.wpcf7 form:is(.invalid,.unaccepted,.failed) .wpcf7-response-output{
  border-color:var(--blad);background:#fef2f2;color:#7f1d1d}

/* --- Zastępnik kafla kategorii bez zdjęcia -------------------------------
 * Reguła mieszkała w stylu wstawianym z front-page.php, więc obowiązywała
 * WYŁĄCZNIE na stronie głównej. Na archiwach kategorii ten sam znacznik był
 * całkiem nieostylowany — pusty span bez wymiarów, przez co kafel bez zdjęcia
 * był o obrazek niższy od sąsiadów i siatka się rwała. Reguła należy do
 * arkusza, nie do jednego szablonu. */
.kafel-kat .kafel-kat__zastepnik{display:flex;align-items:center;justify-content:center;
  aspect-ratio:1;margin-bottom:10px;padding:12px;background:var(--tlo-2);
  border-radius:var(--r-s);color:var(--tusz-2);opacity:.5;text-align:center;
  font-size:13px;font-weight:800;line-height:1.3;text-transform:uppercase;
  letter-spacing:.08em;overflow:hidden}

/* --- Listy numerowane w treści ------------------------------------------
 * Globalny reset `*{padding:0}` zdejmuje wcięcie także listom <ol>, a motyw
 * nadawał `padding-left` tylko listom <ul>. Numery wychodziły poza kolumnę
 * tekstu — najlepiej widać to w opisach kategorii z instrukcjami krok po kroku. */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) ol{padding-left:24px;margin-bottom:14px}
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) ol li{margin-bottom:6px}
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) :is(ul,ol) :is(ul,ol){margin:6px 0 0}

/* Poziome linie w treści — po resecie przylegały do tekstu bez odstępu. */
:is(.artykul,.proza,.proza-glowna,.opis-kat,.entry-content) hr{
  border:0;border-top:1px solid var(--linia);margin:28px 0}

/* Nagłówek drugiego i kolejnych slajdów na /promocje/ to <h2> (jeden H1 na
   stronę), ale ma wyglądać identycznie jak pierwszy. */
.slider--promocje .slider__tresc h2{margin:0;color:#fff;
  font-size:clamp(26px,4vw,38px);line-height:1.15;letter-spacing:-.02em}
/* Nagłówek akordeonu jest na telefonie przyciskiem — pokazujemy fokus. */
.pdp-sekcja--akordeon>h2:focus-visible{outline:2px solid var(--akcent);outline-offset:3px;border-radius:var(--r-s)}
/* Odsyłacz do konta pod formularzem 420Club. */
.klub-konto{margin-top:10px;font-size:14px;color:var(--tusz-2)}
.klub-konto a{color:var(--akcent-tekst);text-decoration:underline;text-underline-offset:2px}

/* Slajd w trakcie przeciągania — bez animacji krycia, żeby podgląd nadążał
   za palcem; przejście wraca zaraz po puszczeniu. */
/* Poza telefonem nagłówek zostaje przyklejony i w przepływie, więc rozpórka
   ma być zerowa — inaczej nad treścią stanąłby pusty pas. */
.m420-rozporka{height:0}

.slider__slajd.przesuwany{transition:none}

/* 🔴 ZDJĘCIE SLAJDU NIE MOŻE BYĆ PRZECIĄGALNE.
   Obrazek ma domyślnie `draggable=true`. Wciśnięcie myszy nad zdjęciem
   uruchamiało systemowe „przeciągnij obrazek", a przeglądarka przerywała nasz
   gest (`dragstart` → `pointercancel`). Objaw był mylący: baner dawał się
   przeciągać po lewej stronie, gdzie leży tekst, a po prawej — nad zdjęciem —
   nie reagował wcale. JS blokuje jeszcze samo zdarzenie `dragstart`. */
.slider img,.slider picture{-webkit-user-drag:none;user-drag:none;
  -webkit-touch-callout:none;pointer-events:none}
/* Blokada zaznaczania dotyczy przeciągania, nie treści — nagłówek i opis slajdu
   mają dać się zaznaczyć i skopiować. */
.slider__tresc{-webkit-user-select:text;user-select:text}
/* Kursor mówi, że baner da się złapać. Tylko tam, gdzie jest mysz —
   na dotyku `hover` nie istnieje, a kursor i tak jest niewidoczny. */
@media(hover:hover){
  .slider{cursor:grab}
  .slider:active{cursor:grabbing}
}

/* ==========================================================================
 * RUNDA 18 (31.08) — sekcja „Bestsellery" na pełną szerokość + zwijany nagłówek
 * ========================================================================== */

/* --- „Bestsellery" na listingu: na telefonie do samych krawędzi -----------
 * Sekcja siedzi w `.srodek` (padding 20 px) i miała jeszcze własne 18 px, więc
 * z 390 px ekranu na kafle zostawało 314 — dwie kolumny po 149 px. Po zdjęciu
 * obu marginesów kafel rośnie do 188 px, czyli o ponad ćwierć.
 *
 * `calc(50% - 50vw)` wychodzi poza kolumnę niezależnie od tego, ile ten padding
 * akurat wynosi — sztywne `-20px` rozjechałoby się przy pierwszej zmianie
 * odstępu w `.srodek`. Nagłówek sekcji zostaje wyrównany do reszty strony,
 * bo tekst dochodzący do krawędzi ekranu czyta się źle. */
@media(max-width:820px){
  /* Sekcja wychodzi poza kolumnę, ale NIE do samej krawędzi: 12 px oddechu
     zostaje, żeby kafle nie przylegały do ścianek ekranu. Przy 20 px kolumny
     i 18 px własnego paddingu kafel miał 149 px; teraz ma 176 px — nadal
     o ponad 18% więcej, a produkty mają margines. */
  .polecane-kat{
    margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
    max-width:100vw;padding-left:12px;padding-right:12px;
    border-radius:0;border-left:0;border-right:0}
  .polecane-kat__tytul{padding-left:8px;padding-right:8px}
}

/* --- Nagłówek: wyszukiwarka i kategorie chowają się przy przewijaniu -------
 * Zmierzone na telefonie 390 px: cały nagłówek ma 261 px, z czego wyszukiwarka
 * 43 px i pasek „Wszystkie kategorie" 65 px. Zwinięcie tych dwóch oddaje
 * treści 108 px — ponad dwie piąte nagłówka — a rząd z logo, kontem, koszykiem
 * i menu zostaje na miejscu, bo to jedyna stała nawigacja na telefonie.
 *
 * ⚠ `max-height` zamiast `display:none`: znikający element nie da się animować,
 * a skok o 108 px przy każdym drgnięciu palca wygląda jak usterka. Wartości
 * `max-height` w stanie otwartym są celowo z zapasem — dokładna wysokość
 * zależy od długości tekstu w kapsułce. */
/* 🔴🔴 ZWIJANIE NIE MOŻE PRZESUWAĆ TREŚCI.
 * Nagłówek jest przyklejony, ale nadal zajmuje miejsce w przepływie — więc
 * zmniejszenie go o 143 px podciągało CAŁĄ stronę o te 143 px w górę, w trakcie
 * przewijania. Wyglądało to jak szarpnięcie, a nie jak chowanie paska.
 *
 * Na telefonie nagłówek jest więc WYJĘTY Z PRZEPŁYWU (`position:fixed`), a jego
 * miejsce trzyma rozpórka o stałej wysokości pełnego nagłówka
 * (`--m420-naglowek`, mierzona raz w JS). Zwinięcie odsłania wtedy więcej
 * treści, zamiast ją przesuwać: strona stoi w miejscu, rusza się tylko pasek.
 *
 * `top` nagłówka zjeżdża do zera dopiero, gdy pasek promocyjny wyjedzie
 * z ekranu — inaczej przykryłby go od pierwszej chwili. */
@media(max-width:820px){
  .naglowek{position:fixed;left:0;right:0;top:var(--m420-topbar,34px);
    transition:top .2s ease}
  .naglowek--przyklejony{top:0}
  /* Zapas 261 px to zmierzona wysokość pełnego nagłówka przy 390 px szerokości.
     Inline'owy skrypt w header.php i tak nadpisuje ją realnym pomiarem, zanim
     reszta strony zostanie ułożona — ta wartość jest tylko na wypadek
     wyłączonego JavaScriptu. */
  .m420-rozporka{height:var(--m420-naglowek,261px)}
  .admin-bar .naglowek{top:calc(var(--m420-topbar,34px) + 46px)}
  .admin-bar .naglowek--przyklejony{top:0}

  .naglowek .szukaj,.naglowek .nav{
    overflow:hidden;
    transition:max-height .24s ease,opacity .16s ease,margin .24s ease}
  .naglowek .szukaj{max-height:80px}
  .naglowek .nav{max-height:120px}
  .naglowek--zwiniety .szukaj{max-height:0;opacity:0;margin-top:0;margin-bottom:0}
  .naglowek--zwiniety .nav{max-height:0;opacity:0;border-top-color:transparent}
  /* Bez tego po zwinięciu zostaje pusty odstęp między wierszami rzędu. */
  .naglowek--zwiniety .naglowek__rzad{row-gap:0}
}
/* Kto wyłączył animacje w systemie, dostaje twarde przełączenie zamiast suwania. */
@media(prefers-reduced-motion:reduce){
  .naglowek .szukaj,.naglowek .nav{transition:none}
}
