/*
 * Okno powiekszenia zdjecia produktu.
 *
 * Hummingbird daje temu oknu bootstrapowa klase .modal-xl (sztywne 1140px
 * szerokosci) i nie ogranicza jego wysokosci. Przy kwadratowych zdjeciach -
 * a taki jest caly nasz katalog - obraz miał wtedy ~1140px wysokosci, czyli
 * wiecej niz ekran laptopa (na 1366x768 okno wychodzilo poza ekran o 464px).
 * Bialy modal wystajacy poza krawedz czytal sie jako wielka biala ramka.
 *
 * Poprawka: obraz miesci sie w wysokosci ekranu (object-fit: contain zamiast
 * fill, ktory rozciagal), a okno zwega sie do szerokosci obrazu - inaczej
 * biale ramki wracaja, tyle ze po bokach.
 */
.product-images-modal .modal-dialog {
    /* Jeden rozmiar liczony z ekranu, a nie z obrazka. Wczesniej okno dopasowywalo
       sie do aktualnego zdjecia, wiec przy przechodzeniu na kolejne - jeszcze
       niezaladowane - kurczylo sie do pustego bialego prostokata. */
    --asc-bok: min(1140px, 94vw, calc(100vh - 3rem));
    width: var(--asc-bok);
    max-width: var(--asc-bok);
    margin-inline: auto;
}

/* Naglowek chowamy do rogu - zostaje sam przycisk zamkniecia nad grafika,
   dzieki czemu tlo konczy sie tam, gdzie zdjecie, a nie 80px nizej. */
.product-images-modal .modal-header {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 5;
    padding: .5rem;
    border: 0;
    background: none;
}

.product-images-modal .modal-content {
    width: 100%;
    padding: 6px;              /* delikatna ramka dokola grafiki */
    border-radius: 10px;
    background: #fff;
}

.product-images-modal .modal-body,
.product-images-modal__body {
    padding: 0;
}

/* Nasze zdjecia sa kwadratowe - z gory rezerwujemy im miejsce, wiec przelaczanie
   miedzy nimi nie przesuwa okna i nie widac bialego przeskoku. */
.product-images-modal .carousel,
.product-images-modal .carousel-inner,
.product-images-modal .carousel-item {
    aspect-ratio: 1 / 1;
}

.product-images-modal .carousel-item img,
.product-images-modal__carousel img {
    width: 100%;
    height: 100%;
    max-height: none;
    object-fit: contain;
    display: block;
    border-radius: 6px;
}

/*
 * Marka producenta ukryta na karcie produktu (i w szybkim podgladzie).
 *
 * Caly katalog ma jedna marke - wlasna - wiec nazwa pod tytulem produktu i wiersz
 * "Marca" w zakladce szczegolow nic klientowi nie mowia, a odnosnik do strony marki
 * wyprowadza z karty w miejsce, ktore niczego nie dodaje.
 *
 * Zostaje w TRESCI STRONY, znika z WIDOKU:
 *  - dane strukturalne (JSON-LD "brand") sa nietkniete - to z nich Google czyta marke
 *    do wynikow rozszerzonych, wiec SEO nic nie traci,
 *  - display:none, a nie technika "visually-hidden": tamta zostawia odnosnik w drzewie
 *    dostepnosci i W KOLEJNOSCI TABULACJI, czyli fokus klawiatury wpadalby w niewidzialny
 *    link - to gorszy blad dostepnosci niz brak informacji o marce,
 *  - to nie jest ukrywanie tekstu pod SEO (cloaking): nie chowamy fraz dla robota,
 *    tylko powtorzenie informacji, ktora i tak jest w danych strukturalnych.
 *
 * Cofniecie: usun te dwie reguly. Marka wroci w oba miejsca bez zmian w motywie.
 */
.product__manufacturer {
    display: none !important;
}

.details__item--manufacturer {
    display: none !important;
}

/*
 * Odstep nazwa -> cena. Motyw daje nazwie klase mb-1 wlasnie dlatego, ze pod nia
 * stoi marka (4 px), wiec po jej ukryciu cena przyklejala sie do tytulu i czytala
 * jak jego czesc.
 *
 * ⚠ Odstepu NIE odzyskujemy nadpisaniem `.product__name.mb-1` - i to nie dlatego,
 * ze brakuje specyficznosci. Hummingbird trzyma narzedziowe klasy Bootstrapa
 * (`.mb-1{margin-bottom:.25rem!important}`) w warstwie kaskady `@layer utilities`,
 * a dla deklaracji `!important` kolejnosc warstw jest ODWROTNA: kod bez warstwy jest
 * najslabszy. Nasze `!important` przegrywalo wiec z motywem niezaleznie od selektora
 * (sprawdzone: wstrzykniecie tej samej reguly na koniec dokumentu tez nie dzialalo).
 *
 * Dlatego dokladamy odstep od drugiej strony i BEZ `!important`: dla deklaracji
 * zwyklych kolejnosc warstw jest normalna, a kod bez warstwy wygrywa z warstwowym.
 */
.page-product .product__prices {
    /* marginesy sasiadow sie zlewaja (collapsing), wiec liczy sie wieksza z wartosci:
       4 px z mb-1 nazwy i 12 px stad - czyli odstep konczy sie na 12 px */
    margin-top: .75rem;
}

/*
 * Powiekszalnik obrazkow w tresci redakcyjnej (patrz views/js/lightbox.js).
 *
 * Wlasny, bo okno motywu jest generowane z `$product.images`, wiec istnieje
 * tylko na karcie produktu. Rysunki przyciskow sa z CSS-a, nie z fontu ikon:
 * Font Awesome na froncie NIE ISTNIEJE (motyw wczytuje Material Icons), a caly
 * kroj pod trzy znaki to zly interes.
 */
.afl-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;              /* nad naglowkiem przyklejonym i paskiem informacyjnym */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: clamp(.75rem, 3vw, 2.5rem);
    background: rgb(0 0 0 / 82%);
}

/* ⚠ Bez tego atrybut `hidden` NIE DZIALA: regula przegladarki
   `[hidden]{display:none}` ma najnizsza mozliwa specyficznosc, wiec `display:flex`
   powyzej ja bije i okno bylo widoczne od wejscia na strone. */
.afl-overlay[hidden] {
    display: none;
}

/* Strona pod spodem nie przewija sie, gdy okno jest otwarte. */
body.afl-open {
    overflow: hidden;
}

.afl-figure {
    margin: 0;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
}

.afl-image {
    display: block;
    /* Miesci sie w ekranie w obu wymiarach; `contain` w kontrze do `fill`, ktory
       rozciagalby obraz o innych proporcjach niz okno. */
    max-width: 100%;
    max-height: calc(100vh - 7rem);
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: var(--bs-border-radius, 10px);
    background: #fff;
}

.afl-caption {
    margin: 0;
    color: #fff;
    font-size: .875rem;
    text-align: center;
    text-wrap: balance;
}

.afl-close,
.afl-nav {
    flex: 0 0 auto;
    /* ⚠ Cel dotykowy 44 px (WCAG 2.5.5) - te przyciski sa uzywane glownie
       na telefonie, gdzie klient nie ma ani Escape, ani strzalek. */
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgb(255 255 255 / 12%);
    color: #fff;
    cursor: pointer;
    position: relative;
}

.afl-close:hover,
.afl-nav:hover {
    background: rgb(255 255 255 / 24%);
}

.afl-close:focus-visible,
.afl-nav:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

.afl-close {
    position: absolute;
    top: clamp(.5rem, 2vw, 1.25rem);
    right: clamp(.5rem, 2vw, 1.25rem);
}

/* Krzyzyk i strzalki z ramek, wiec biora kolor tekstu i skaluja sie z nim. */
.afl-close::before,
.afl-close::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: 16px;
    height: 2px;
    background: currentcolor;
    translate: -50% -50%;
}

.afl-close::before { rotate: 45deg; }
.afl-close::after { rotate: -45deg; }

.afl-nav::before {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: 11px;
    height: 11px;
    border-top: 2px solid currentcolor;
    border-right: 2px solid currentcolor;
    translate: -50% -50%;
}

.afl-nav--prev::before { rotate: -135deg; margin-left: 2px; }
.afl-nav--next::before { rotate: 45deg; margin-left: -2px; }

.afl-nav[hidden] { display: none; }

.afl-counter {
    position: absolute;
    bottom: clamp(.5rem, 2vw, 1.25rem);
    left: 50%;
    translate: -50% 0;
    margin: 0;
    color: rgb(255 255 255 / 78%);
    font-size: .8125rem;
    font-variant-numeric: tabular-nums;
}

/* Na telefonie strzalki schodza pod obraz - po bokach zjadalyby jego szerokosc. */
@media (max-width: 575px) {
    .afl-overlay {
        flex-wrap: wrap;
        align-content: center;
    }

    .afl-figure {
        order: 1;
        flex: 1 0 100%;
    }

    .afl-nav { order: 2; }
    .afl-image { max-height: calc(100vh - 11rem); }
}

/*
 * Mikroruch licznika koszyka (patrz views/js/cart-pulse.js).
 *
 * Sam podskok, bez zmiany koloru: licznik ma na komputerze tlo `--bs-tertiary-bg`,
 * a na telefonie `--bs-primary`, wiec jedna zmiana barwy nie wygladalaby tak samo
 * w obu miejscach - a `transform` wyglada.
 *
 * ⚠ `transform` NIE rusza ukladu strony, wiec naglowek nie drgnie. Powiekszenie przez
 * `font-size` albo `padding` przesuwaloby sasiadow w pasku naglowka przy kazdym
 * dodaniu do koszyka.
 */
@keyframes abf-badge-pop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.3); }
    100% { transform: scale(1); }
}

.abf-badge-pop {
    /* Lekkie przestrzelenie na koncu - ruch konczy sie "dosiadem", a nie wyhamowaniem;
       bez tego 340 ms czyta sie jak opoznienie, a nie jak reakcja. */
    animation: abf-badge-pop .34s cubic-bezier(.34, 1.56, .64, 1) both;
}

/* ⚠ Bez ruchu przy `prefers-reduced-motion` - i nie zastepujemy go niczym innym:
   okno "dodano do koszyka" jest samo w sobie pelna informacja zwrotna, wiec nikt
   nie traci tu tresci, tylko ozdobnik. */
@media (prefers-reduced-motion: reduce) {
    .abf-badge-pop {
        animation: none;
    }
}

/*
 * Warstwa confetti na potwierdzeniu zamowienia (patrz views/js/confetti.js).
 *
 * ⚠ `pointer-events: none` jest tu warunkiem, nie ozdobnikiem: plotno przykrywa
 * caly ekran, a pod nim stoi blok polecanych produktow z kilkunastoma przyciskami
 * szybkiego podgladu. Bez tego przez dwie sekundy po zakupie strona bylaby martwa.
 */
.abf-confetti {
    position: fixed;
    inset: 0;
    z-index: 2000;              /* nad naglowkiem przyklejonym i paskiem informacyjnym */
    pointer-events: none;
}

/*
 * Pisanie w polu wyszukiwarki przewijalo strone do gory.
 *
 * Motyw ustawia na <html> `scroll-padding-top` rowne wysokosci naglowka plus 16 px
 * (`theme.js`, funkcja liczaca `--scroll-padding-top`), zeby kotwica nie ladowala pod
 * przyklejonym naglowkiem. Chromium honoruje ten odstep TAKZE przy odslanianiu karetki
 * podczas pisania - a kazde pole naglowka lezy z definicji WEWNATRZ tego pasa, wiec
 * przegladarka uznaje je za zaslonione i przewija strone w gore, zeby je "odslonic".
 * Naglowek jest przyklejony, wiec pole ani drgnie, warunek nigdy nie zostaje spelniony
 * i przy kazdym nacisnieciu klawisza strona jedzie kawalek wyzej - az do samej gory.
 *
 * Zmierzone na kategorii przy oknie 1400x900: sam fokus 2000 -> 1316 px, potem -61 px
 * na kazda litere. Po poprawce 2000 px przez caly czas pisania.
 *
 * ⚠ To NIE jest usterka wyszukiwarki - ten sam skok daje dowolne pole tekstowe wstawione
 * do przyklejonego naglowka (sprawdzone swiezym `<input>`), a znika, gdy naglowek
 * przestaje byc `sticky`. ⚠ Ujemny `scroll-margin-top` na polu NIE wystarcza: znosi
 * dokladnie polowe skoku, niezaleznie od wartosci (sprawdzone od -100 do -3000 px).
 *
 * ⚠ `!important` jest tu konieczny, bo motyw ustawia odstep STYLEM INLINE na <html>;
 * regula z arkusza bije styl inline wylacznie jako `!important`.
 *
 * Odstep znika tylko na czas pisania w naglowku, wiec kotwice na stronie dzialaja jak
 * dotad (sprawdzone: `scrollIntoView` po odejsciu fokusu nadal zostawia 172 px).
 */
html:has(.js-sticky-header :is(input, textarea):focus) {
    scroll-padding-top: 0 !important;
}

/*
 * Ikona zwrotu w blokach zaufania (blockreassurance) byla jasniejsza od pozostalych.
 *
 * Ikony paczki `pack3` sklada sie z dwoch warstw: `#fill` (jasne tlo, celowo
 * `opacity="0.3"`) i `#color` (wlasciwy rysunek, pelne krycie). W pliku
 * `views/img/reassurance/pack3/return.svg` warstwa `#color` ma dodatkowo
 * `opacity="0.7"` - jako JEDYNA z 37 ikon wszystkich trzech paczek. Zmierzone na
 * karcie produktu: krycie 0,7 wobec 1 przy trzech sasiednich ikonach.
 *
 * ⚠ Poprawki NIE robimy w pliku SVG, choc to tam siedzi wada: blockreassurance to
 * modul natywny, ktory jedzie w paczce wydania PrestaShopa, wiec krok kopiowania
 * plikow przy kazdej aktualizacji rdzenia przywrocilby oryginal - a ikona zjasnialaby
 * z powrotem bez zadnego sygnalu. Regula w naszym module przezywa aktualizacje.
 *
 * ⚠ Zdejmujemy krycie WYLACZNIE warstwie `#color`. Ustawienie `opacity: 1` na
 * wszystkich sciezkach zabraloby jasne tlo, ktore w tej paczce jest czescia rysunku.
 *
 * Atrybut prezentacyjny `opacity` w SVG ma najnizsza wage, wiec zwykla deklaracja
 * z arkusza go bije - `!important` nie jest potrzebny.
 */
.blockreassurance svg [id="color"],
.blockreassurance_product svg [id="color"],
#block-reassurance svg [id="color"] {
    opacity: 1;
}

/*
 * Probka koloru na miniaturze: pokazujemy ja tylko wtedy, gdy jest z czego wybierac.
 *
 * Motyw rysuje pod kazda miniatura probki kolorow (`variant-links.tpl`) pod warunkiem
 * `{if $product.main_variants}`, czyli takze przy JEDNEJ wartosci. Zmierzone na tym
 * katalogu: kolor ma 2517 aktywnych produktow, a wiecej niz jeden kolor tylko 114
 * (82 po dwa, 21 po trzy, 11 po piec). Czyli 2403 produkty - 95,5% tych z kolorem -
 * pokazywaly pojedyncze kolko, ktore nie dawalo zadnego wyboru: odnosnik prowadzi
 * do tej samej karty produktu.
 *
 * ⚠ Na miniaturze probka NIE MA nazwy koloru - to samo kolko, a `title`/`aria-label`
 * widzi wylacznie czytnik ekranu. Nie niesie wiec informacji ponad zdjecie produktu,
 * inaczej niz selektor wariantu na karcie produktu (tam obok kolka stoi nazwa, dlatego
 * `ASG_HIDE_GROUPS` chowa "Model", a koloru nie chowa).
 *
 * Zysk jest podwojny: znika martwy odnosnik z KOLEJNOSCI TABULACJI (2403 kafelki), a sama
 * obecnosc probek staje sie sygnalem "ten produkt ma wybor koloru" zamiast ozdobnika
 * stojacego prawie wszedzie.
 *
 * ⚠ `display: none`, a nie technika "visually-hidden" - ta sama zasada co przy ukryciu
 * marki wyzej: element ukryty wizualnie zostaje w tabulacji, czyli fokus klawiatury
 * wpadalby w niewidzialny link.
 *
 * ⚠ Kryterium jest to samo, ktore ma juz `hookActionPresentProductListing` tego modulu
 * (`count($variants) < 2` - podmiana zdjecia przy najechaniu tez pomija produkty
 * jednokolorowe), wiec obie funkcje traktuja "jeden kolor" tak samo.
 *
 * Przegladarka bez `:has()` (sprzed 2023) pokaze probke jak dotad - degradacja bezpieczna.
 *
 * Cofniecie: usun te regule. Probka wroci na wszystkich kafelkach bez zmian w motywie.
 */
.product-miniature__variants:has(> a:only-child) {
    display: none;
}

/**
 * Ocena z opinii wyrownana do CYFR ceny, a nie do pudelka linii (2026-09-07)
 * ---------------------------------------------------------------------------
 * Zgloszenie uzytkownika: gwiazdki obok ceny "sa raczej na spodzie linii".
 *
 * ⚠ POMIAR PUDELEK MOWIL, ZE JEST DOBRZE - i to jest cala trudnosc tej poprawki.
 * `getBoundingClientRect()` na cenie i na ocenie dawal srodki w tym samym pikselu
 * (336,97 = 336,97), bo rodzic ma `align-items: center`. Rozjazd siedzial WEWNATRZ
 * pudelek: pudelko ceny obejmuje descender fontu, wiec jego srodek lezy nizej niz
 * srodek korpusu cyfr. Zmierzone na tuszu (zrzut w skali 6x, obwiednia niebialych
 * pikseli): korpus cyfr 326,67-344,01, gwiazdki 328,01-345,01, czyli gwiazdki
 * +1,17 px za nisko, a ich dolna krawedz 1 px PONIZEJ linii bazowej cyfr - i to
 * wlasnie widzi oko, bo linia bazowa jest odniesieniem przy czytaniu.
 *
 * ⚠ Pierwszy pomiar tuszu tez sklamal (-0,25 px, czyli "idealnie"), bo obejmowal
 * PRZECINEK w "18,90" - jego descender zanizal srodek ceny o 1,42 px. Rozstrzyga
 * obwiednia samych cyfr, bez przecinka i bez znaku waluty.
 *
 * ⚠ PRZYCZYNA NIE JEST W OCENIE, tylko w niecalkowitej wysokosci linii ceny:
 * `line-height: 27.6px` (24px x 1,15). Gwiazdki maja 20 px, wiec `align-items: center`
 * daje im offset (27,6 - 20) / 2 = 3,8 px, czyli konczacy sie ulamkiem - a rysowanie
 * zaokragla go raz w gore, raz w dol, ZALEZNIE OD POZYCJI ELEMENTU NA STRONIE.
 * Zmierzone na tym samym produkcie: +1,17 px przy 1400 px szerokosci i +0,17 px
 * przy 390 px, przy identycznym foncie 24px.
 *
 * ⚠ Dlatego korekta w rodzaju `top: -1px` jest ZGADYWANIEM, nie poprawka: sprawdzona
 * w przegladarce naprawiala 1400 px (+1,17 -> +0,17) i PSULA 390 px (+0,17 -> -0,83).
 * Tak samo `margin-bottom: 2px`. A `align-self: baseline` na bloku oceny wyrzuca ja
 * o 2,83 px ZA WYSOKO, bo linia bazowa kontenera flex to linia bazowa jego pierwszej
 * pozycji - ta sama pulapka, ktora opisuje CLAUDE.md przy podpisie autora bloga.
 *
 * Poprawka jest wiec U ZRODLA: wysokosc linii ceny zaokraglona w gore do pelnego
 * piksela. Offset gwiazdek staje sie calkowity i zaokraglanie znika. Zmierzone po
 * zmianie: +0,17 px na 1400 px I na 390 px, linia bazowa cyfr rowna dolnej krawedzi
 * gwiazdek co do piksela. Zostajace 0,17 px to 1/6 piksela, ponizej progu widocznosci.
 *
 * ⚠ Zapis NIE ZAWIERA ani stopnia pisma (24px), ani mnoznika motywu (1,15): `1lh` to
 * biezaca wysokosc linii, a `round(up, ..., 1px)` podnosi ja do pelnego piksela. Dzieki
 * temu regula nie zestarzeje sie na sklepie rodziny o innej typografii - inaczej niz
 * rownowazny dzis zapis `line-height: 28px`, ktory przy foncie 20px bylby za luzny.
 * Przegladarka bez `round()` zignoruje deklaracje i zostanie stan sprzed poprawki,
 * czyli rozjazd do 1,2 px - degradacja lagodna.
 *
 * ⚠ Zawezone do linii ceny NA KARCIE PRODUKTU (`.product__prices-inline`), zeby nie
 * ruszac wysokosci linii ceny w koszyku, w kasie i na kafelkach listingu.
 *
 * Cofniecie: usun te regule. Wroci rozjazd zalezny od pozycji elementu na stronie.
 */
.product__prices-inline .product__price {
    line-height: round(up, 1lh, 1px);
}

/**
 * Cena na karcie produktu w pigulce w kolorze marki (2026-09-22)
 * ---------------------------------------------------------------------------
 * Propozycja uzytkownika: cena "wygladala surowo". Wybrany wariant z trzech
 * pokazanych na zrzutach (jasne tlo marki / pelny kolor / akcent) - pelny kolor.
 *
 * ⚠ TLO JEST O TON CIEMNIEJSZE OD `--bs-primary` I TO JEST WARUNEK, NIE GUST.
 * Bialy na `#00baff` (koszulkowy) ma kontrast 2,22:1 - ponizej progu 3:1, ktory
 * WCAG 1.4.3 daje nawet duzemu, pogrubionemu tekstowi. `color-mix` z 17% czerni
 * daje `#009ad3` = 3,2:1, czyli prawie dokladnie kolor, ktorym motyw pisal cene
 * dotad (`#009ad0`) - klient widzi ten sam odcien, tylko odwrocony. Na garibald
 * (`#4e5b31`) wychodzi ciemna oliwka, bialy ma tam z zapasem.
 * ⚠ Mieszamy z TOKENEM, a nie wpisujemy koloru, bo modul jedzie na sklepy obu
 * marek. Pierwsza deklaracja to zapas dla przegladarki bez `color-mix`.
 *
 * ⚠ Wysokosc linii zostaje z reguly wyzej (ocena wyrownana do cyfr) - pigulka
 * doklada tylko padding, wiec `align-items: center` rodzica nadal srodkuje gwiazdki.
 *
 * ⚠ Zawezone do karty produktu (`.product__prices-inline`): koszyk, kasa i kafelki
 * listingu zostaja bez zmian. Szybki podglad ma ten sam szablon ceny, wiec tez
 * dostaje pigulke - to ta sama karta w oknie.
 *
 * Cofniecie: usun te regule.
 */
.product__prices-inline .product__price {
    background-color: var(--bs-primary-text-emphasis);
    background-color: color-mix(in srgb, var(--bs-primary) 83%, #000);
    color: #fff;
    font-weight: 800;
    border-radius: 50rem;
    padding: 0.2em 0.8em;
    box-shadow: 0 2px 8px rgba(var(--bs-primary-rgb), 0.3);
}

/**
 * Blok ceny ciaśniej - bez pustego miejsca pod pigulka (2026-09-22)
 * ---------------------------------------------------------------------------
 * Zgloszenie uzytkownika: pod cena "sporo wolnej przestrzeni". Zmierzone na
 * 1400 px: 44 px pod pigulka wobec 12 px nad nia. Dwa zrodla:
 *
 * 1. 12 px to `gap` bloku ceny (flex, kolumna) przed `.product__tax-infos`,
 *    ktory na wiekszosci produktow jest PUSTY: etykiete "z VAT" zdjeto
 *    2026-09-07, a przycisk tabeli rozmiarow renderowany tam hookiem `after_price`
 *    `ababinksizecharts` PRZENOSI JS-em pod wybor rozmiaru. Kontener ma wtedy
 *    zero wysokosci, a odstep i tak zajmuje miejsce.
 *    ⚠ Warunek to "brak ELEMENTU w etykiecie", a nie `:empty` - po przeniesieniu
 *    zostaja biale znaki, a dla CSS to nie jest pusty element. Zestaw
 *    (`ababinkpacks`), warianty wzoru i ekopodatek sa elementami, wiec zostaja.
 *    ⚠ Ukryty zostalby tez goly tekst "No tax" (sklep bez podatkow) - nasze
 *    sklepy maja podatki wlaczone; przy sklepie bez nich trzeba to obejsc.
 *
 * 2. 32 px to wspolny rytm sekcji karty w motywie (`margin-block-end: 2rem` od
 *    `md`, 1,25rem ponizej). Cena dostaje na komputerze to samo 1,25rem, co na
 *    telefonie: jest jednym wierszem i siedzi pod tytulem, wiec pelna przerwa
 *    sekcji odrywala ja od opisu.
 *
 * Zmierzone po zmianie: 44 px -> 20 px na 1400 px, 32 -> 20 na 390 px.
 */
.product__prices-block > .product__tax-infos:not(:has(.product__tax-label *)):not(:has(.product__ecotax-price)) {
    display: none;
}

.page-product .product__prices {
    margin-block-end: 1.25rem;
}

/**
 * Bloki modulow pod przyciskiem zakupu - odstep tylko z kontenera (2026-09-22)
 * ---------------------------------------------------------------------------
 * Zgloszenie uzytkownika: uklad karty "bardziej kompaktowy". Najwieksza luka strony:
 * miedzy zegarem wysylki, propozycjami (`ababinkcrosssell`, `.axs`) i ofertami
 * zestawow (`ababinkpacks`, `.abp-item-block`) stalo 52 px na 390 px i 64 px na
 * 1400 px - wizualnie, z paddingiem ramek, do 90 i 101 px.
 *
 * ⚠ Przyczyna: `.product__additional-info` jest kolumna flex z WLASNYM `gap`
 * (20 px / 32 px od `md`), a moduly niosa marginesy 16 px z gory i z dolu - pisane
 * pod zwykly przeplyw blokowy, gdzie by sie zlaly. W flexie marginesy sie NIE
 * zlewaja, tylko sumuja z `gap`: 16 + 20 + 16.
 *
 * Zerujemy je TU, w kontekscie kontenera motywu, a nie w modulach - te same bloki
 * stoja w oknie koszyka i w szybkim podgladzie, gdzie ich margines jest potrzebny.
 * Rytm zostaje z `gap` motywu, wiec jest ten sam co reszty karty.
 *
 * Zmierzone po zmianie: 52 -> 20 px (390 px), 64 -> 32 px (1400 px).
 */
.product__additional-info > * {
    margin-block: 0;
}

/**
 * Zegar wysylki na karcie produktu jako karta w kolorze marki (2026-09-22)
 * ---------------------------------------------------------------------------
 * Decyzja uzytkownika z trzech makiet (obecny / mala ikona / karta z tlem): karta.
 * Ten sam wyglad, ktory `ababinkshippingtimer` 1.2.0 daje zegarowi w koszyku
 * i w kasie (`.sg_delivery_timer--cart`), wiec klient widzi jeden blok w calej
 * sciezce zakupu. Ikona 80 -> 48 px, tekst do lewej zamiast wysrodkowanego.
 * Zmierzone na makiecie: 100 -> 67 px na komputerze, 116 -> 113 px na telefonie
 * (tam zysk zjada padding karty - to wybor wygladu, nie zwartosci).
 *
 * ⚠ Tutaj, a nie w module zegara, bo produkcja stoi na starszej wersji modulu
 * (1.2.0 czeka na poligonie) - regula nie zalezy od jego wersji. Po wydaniu 1.2.0
 * na wszystkie sklepy mozna ja przeniesc do modulu jako wyglad domyslny.
 * ⚠ Kolor z `--bs-primary`, nie z `--ast-brand` modulu - tamten token jest
 * dopiero w 1.2.0. `!important` przy ikonie, bo modul daje ja z `!important`.
 * ⚠ Szybki podglad (2026-09-22) ma zegar w INNYM miejscu: nie ma `displayProductAdditionalInfo`,
 *   wiec zegar przychodzi hookiem `displayProductActions` pod przyciskiem - stad druga pula
 *   selektorow `.quickview`. Bez niej podglad pokazywal stary wyglad (ikona 80 px, tekst na srodku).
 */
.product__additional-info .sg_delivery_timer,
.quickview .sg_delivery_timer {
    max-width: none;
    gap: 12px;
    padding: 0.6rem 0.75rem;
    border-radius: 0.75rem;
    background: color-mix(in srgb, var(--bs-primary) 6%, #fff);
}

/* w podgladzie zegar siedzi w wierszu flex obok przycisku - bez tego karta ma szerokosc tekstu */
.quickview .sg_delivery_timer {
    flex: 1 1 100%;
    width: 100%;
}

.product__additional-info .sg_timer_icon img,
.quickview .sg_timer_icon img {
    height: 48px !important;
}

.product__additional-info .sg_timer_text,
.quickview .sg_timer_text {
    text-align: left;
}

.product__additional-info .sg_timer_note,
.quickview .sg_timer_note {
    margin-top: 2px;
}

/**
 * Sekcja wyboru wariantu oddzielona subtelnym tlem (2026-09-07)
 * ---------------------------------------------------------------------------
 * Propozycja uzytkownika. Sekcja z atrybutami stala bez tla, bez ramki i bez
 * odstepu od opisu (`margin-top: 0`), wiec czytala sie jak KOLEJNY AKAPIT OPISU,
 * a nie jak jedyne miejsce, w ktorym klient musi cos wybrac przed zakupem.
 * Widac to najlepiej przy grupie jednowartosciowej: `ASG_HIDE_GROUPS` chowa sama
 * kontrolke, a napis zostaje - wiec wiersz "Typ: Damske - super slim" jest golym
 * zdaniem, nieodroznialnym od prozy nad nim.
 *
 * ⚠ TLO WCHODZI WARUNKOWO i to nie jest ostroznosc na wyrost. Zmierzone na tym
 * katalogu (aktywne produkty z kombinacjami, 10 520 sztuk):
 *
 *     zmiennych grup | produktow
 *     ---------------|----------
 *              **0** | **3253 (31%)**
 *                  1 |      4370
 *                  2 |      2882
 *                  3 |        15
 *
 * U prawie jednej trzeciej produktow w tej sekcji NIE MA ANI JEDNEJ KONTROLKI -
 * same napisy. Pudelko wokol nich obiecywaloby wybor, ktorego nie ma; to ta sama
 * klasa bledu, co pojedyncza probka koloru na miniaturze (regula wyzej w tym pliku).
 *
 * ⚠⚠ WARUNEK MUSI LICZYC OPCJE, A NIE SPRAWDZAC OBECNOSC KONTROLKI. `ababinkskugroup`
 * chowa grupe jednowartosciowa przez `display:none` NA SAMEJ KONTROLCE (nigdy przez
 * `disabled` - to wylaczaloby pole z formularza), wiec `<select>` i `[role=radiogroup]`
 * ZOSTAJA W DOM. `:has(select)` trafialoby wiec takze w produkt bez zadnego wyboru.
 * Stad `option:nth-child(2)` i `[role="radiogroup"] > :nth-child(2)`, czyli "istnieje
 * kontrolka majaca co najmniej dwie wartosci".
 *
 * ⚠⚠ ZAGNIEZDZONE `:has()` JEST NIEPRAWIDLOWE I ODRZUCA CALA REGULE - PO CICHU.
 * Pierwsza wersja brzmiala `.product__variants:has(> .product-variant > select:has(>
 * option:nth-child(2)))` i wygladala poprawnie; specyfikacja zabrania jednak `:has()`
 * wewnatrz `:has()`. Zmierzone `document.querySelectorAll()`: zagniezdzona postac rzuca
 * **SyntaxError**, plaska daje **1 trafienie na produkcie z wyborem i 0 na produkcie
 * bez wyboru**. W arkuszu nie byloby wyjatku - przegladarka po prostu pominelaby regule,
 * czyli tlo nie pojawiloby sie nigdzie, przy CSS wygladajacym na wlasciwy.
 *
 * ⚠ SAMO TLO, BEZ OBRAMOWANIA - bo tuz pod ta sekcja stoi `ababinkcrosssell`, ktory
 * jest juz pudelkiem z ramka na bieli. Dwa identyczne pudelka jedno pod drugim robia
 * z kolumny formularz w kratke; roznica materialu (szare tlo bez ramki wobec bieli
 * w ramce) rozdziela je bez dokladania trzeciego akcentu.
 *
 * ⚠ Kolory z TOKENOW motywu, nie wpisane - moduł jedzie na szesc sklepow rodziny
 * i musi dzialac w trybie ciemnym. Zmierzony kontrast tekstu (`#3f4347`) na tle
 * `--bs-tertiary-bg` (`#f3f5f6`): **9,12:1**, czyli AAA. Samo tlo wobec bieli strony
 * to 1,09:1 - celowo tyle, zeby oddzielic sekcje, a nie zrobic z niej drugiego bohatera.
 *
 * ⚠ Regula siedzi W MODULE, a nie w forku motywu, choc `product-variants.tpl` jest
 * plikiem motywu: fork ma juz 11 przerobionych szablonow do scalania przy podnoszeniu
 * Hummingbirda, a arkusz modulu jest POZA warstwami kaskady, wiec wygrywa z motywem
 * bez `!important`.
 *
 * ⚠ Ten sam szablon wciaga SZYBKI PODGLAD - regula obejmuje go swiadomie, bo tam
 * sekcja wariantow ma ten sam problem; sprawdzone, ze padding nie zwaza kolumny
 * ponizej czytelnosci.
 *
 * Zmierzone po zmianie: 1400 px - pudelko 569 x 224 px, 390 px - 366 x 224 px, zero
 * przewijania w bok na obu; produkt bez zadnej zmiennej grupy zostaje bez tla.
 * Przegladarka bez `:has()` (sprzed 2023) pokaze sekcje jak dotad - degradacja lagodna.
 *
 * Cofniecie: usun te regule. Sekcja wroci do stanu bez tla, bez zmian w motywie.
 */
.product__variants:has(option:nth-child(2), [role="radiogroup"] > :nth-child(2)) {
    padding: .875rem 1rem;
    background: var(--bs-tertiary-bg);
    border-radius: var(--bs-border-radius, .5rem);
}

/**
 * Zdjecie produktu wyglada na klikalne, bo jest klikalne.
 *
 * Klikniecie otwiera okno powiekszenia (`views/js/product-zoom.js`); bez kursora
 * nikt by sie tego nie domyslil, a ulatwienie, o ktorym klient nie wie, nie jest
 * ulatwieniem.
 *
 * ⚠ Regula ZAWEZONA `:has()` do karuzeli, ktora NAPRAWDE ma przycisk lupy - a wiec
 * do galerii, gdzie jest co otworzyc. Bez tego warunku kursor obiecywalby
 * powiekszenie takze tam, gdzie skrypt niczego nie zrobi (galeria bez zdjec,
 * zaslepka "brak obrazka"), czyli klient klikalby w pustke. Ten sam znacznik czyta
 * arkusz i skrypt - jeden warunek zamiast dwoch, wiec nie ma jak sie rozjechac.
 *
 * ⚠ Karuzela OKNA jest z tego wylaczona swiadomie (`.js-product-carousel` to
 * karuzela glowna, okno ma wlasna klase): w otwartym oknie nie ma juz czego
 * powiekszac, wiec kursor musi tam zostac zwykly.
 *
 * ⚠ Znacznik `data-abf-zoom` na `<html>` stawia SAM SKRYPT. Bez niego kursor sie
 * nie pojawia - czyli przegladarka, w ktorej skrypt sie nie wykonal, nie obiecuje
 * powiekszenia, ktorego nie da rady otworzyc. Sprawdzone dwustronnie: przy
 * zablokowanym pliku JS kursor jest domyslny.
 *
 * ⚠ Przegladarka bez `:has()` (sprzed 2023) dostaje kursor domyslny, a klikniecie
 * dziala dalej - degradacja lagodna, bez stanu do rozjechania.
 *
 * Cofniecie: usun te regule razem z rejestracja `ababinkfront-powiekszenie-galerii`
 * w `hookActionFrontControllerSetMedia()`. Zostaje przycisk lupy, czyli zachowanie
 * sprzed zmiany.
 */
[data-abf-zoom] .js-product-carousel:has(.product__zoom) .carousel-item img {
    cursor: zoom-in;
}

/**
 * ...ale NIE w szybkim podgladzie.
 *
 * ⚠ Tam skrypt swiadomie nie przejmuje kliku (patrz `IN_MODAL` w `product-zoom.js`),
 * wiec kursor musi mowic to samo, co robi klikniecie - czyli nic.
 *
 * ⚠⚠ Reguly wyzej NIE ODSIEWA samo `:has(.product__zoom)`: motyw chowa tam przycisk
 * (`display:none`), a `:has()` sprawdza OBECNOSC W DRZEWIE, nie widocznosc - wiec bez
 * tej reguly zdjecie w podgladzie obiecywaloby powiekszenie kursorem i nie robiloby
 * nic po kliknieciu. Martwa kontrolka jest w tym projekcie gorsza niz jej brak.
 */
[data-abf-zoom] .modal .js-product-carousel .carousel-item img {
    cursor: auto;
}
