/*
 * Panel zakupu na karcie produktu (mobile-first).
 *
 * Plik jest osobny CELOWO: style.css ma 3800 linii i wchodzi do sklejki
 * style-responsive.bundle.css, ktora linkuje takze panel admina. Nowy uklad karty
 * lepiej trzymac obok, zeby dalo sie go wycofac jednym wpisem w head.phtml.
 *
 * Zasada: wszystko ponizej dotyczy TELEFONU. Desktop dostaje korekty na koncu,
 * w bloku min-width 1140 - tam przycisk zakupu jest nad zgieciem i nie ma czego ratowac.
 */

/* ── galeria przesuwalna OD PIERWSZEJ KLATKI, bez JS ─────────────────────
   Zmierzone 11.08.2026 na produkcji (Pixel 7, procesor 6x wolniej, wolne 4G):
   galeria zaczynala reagowac na przesuniecie dopiero po 5,2 s, bo Swiper czeka
   na wczytanie wlasnej biblioteki. Nagrania Clarity pokazywaly dokladnie ten
   objaw: klient probuje przesunac zdjecie, nic sie nie dzieje, klient wychodzi.
   Usuniecie initWhenIdle dalo tylko 0,3 s - reszta to czas ladowania biblioteki,
   wiec JS tu nie pomoze. Pomaga natywne przewijanie ze scroll-snap: dziala
   od pierwszej klatki, zero JS. Gdy Swiper wstanie, dokłada klase
   swiper-initialized i te reguly gasna same. */
.product-view-slider:not(.swiper-initialized) > .swiper-wrapper {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.product-view-slider:not(.swiper-initialized) > .swiper-wrapper::-webkit-scrollbar {
    display: none;
}

.product-view-slider:not(.swiper-initialized) .product-view-slide {
    flex: 0 0 100%;
    scroll-snap-align: center;
}

/* ── galeria na telefonie: krótsza, z kropkami ───────────────────────────
   Zmierzone: przy pełnej galerii i pasku miniatur przycisk zakupu leży na 1455 px
   przy ekranie 839 px. Skrócenie zdjęcia i zamiana paska miniatur na kropki oddaje
   około 240 px i dopiero wtedy komplet sprzedający mieści się nad zgięciem.
   Miniatury wracają na desktopie, gdzie wysokości nie brakuje. */
@media screen and (max-width: 1139px) {
    /* Kadr 1:1. Zdjecie WYPELNIA kadr (cover): zdjecia maja wlasne pelnokadrowe tlo
       z produktem w centrum, wiec przyciecie gora-dol obcina tlo, nie produkt.
       Bez cover pionowe 9:16 staloby waskim paskiem miedzy bialymi marginesami -
       czyli dokladnie odwrotnosc "zdjecie sprzedaje". */
    .galeria-kwadrat .product-view-slide {
        aspect-ratio: 1;
    }

    /* <picture> to tylko kontener wyboru zrodla - musi byc przezroczysty dla ukladu,
       inaczej obraz w srodku nie ma do czego odniesc wysokosci 100%. */
    .product-view-slide-picture {
        display: block;
        width: 100%;
        height: 100%;
    }

    .galeria-kwadrat .product-view-slide img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .product-view-nav-slider {
        display: none;
    }

    /* Kropki NA zdjeciu, nie pod nim: odzyskuja ~26 px pierwszego ekranu.
       Ciemna pigulka pod spodem jest konieczna - nasze zdjecia maja jasne, kremowe tla
       i kropki bez niej znikaja. Blur sprawia, ze pigulka nie wyglada jak naklejka. */
    .product-view-slider-kropki {
        /* Wysrodkowanie przez left:50% + translateX, NIE przez left:0;right:0
           z width:fit-content - ta para sie wyklucza i wygrywa rozciagniecie
           na cala szerokosc kadru (zmierzone 12.08.2026: pigulka 361 px zamiast
           obejmowac same kropki). */
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 10px;
        z-index: 3;
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 6px;
        width: fit-content;
        margin: 0 auto;
        padding: 6px 9px;
        border-radius: 999px;
        background: rgba(20, 24, 16, .34);
        backdrop-filter: blur(6px);
        -webkit-backdrop-filter: blur(6px);
        pointer-events: auto;
    }

    /* Trzy klasy zamiast dwoch: arkusz Swipera laduje sie PO tym pliku (addLib
       dokłada go nizej w <head>), wiec przy rownej szczegolowosci wygrywaly jego
       wartosci - kropki mialy 8x8 i margines 4 px zamiast 6x6 z odstepem 6. */
    /* Swiper dokłada kontenerowi klasy swiper-pagination-bullets i -horizontal,
       a jego regula .swiper-horizontal > .swiper-pagination-bullets ustawia
       left: 0 i width: 100% ze szczegolowoscia wyzsza niz selektor jednoklasowy.
       Stad pigulka rozciagnieta na caly kadr (zmierzone: 361 px). Trzy klasy
       wygrywaja i przywracaja pigulke obejmujaca same kropki. */
    .product-view-slider .product-view-slider-kropki.swiper-pagination-horizontal,
    .product-view-slider .product-view-slider-kropki.swiper-pagination-bullets {
        left: 50%;
        right: auto;
        width: auto;
        transform: translateX(-50%);
        /* Swiper ma bottom: var(--swiper-pagination-bottom, 8px) z ta sama
           szczegolowoscia co selektor jednoklasowy, wiec 10 px z makiety
           trzeba powtorzyc tutaj. */
        bottom: 10px;
    }

    .product-view-slider .product-view-slider-kropki .swiper-pagination-bullet {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: rgba(255, 255, 255, .55);
        opacity: 1;
        margin: 0;
        transition: background-color .15s ease-out, transform .15s ease-out;
    }

    .product-view-slider .product-view-slider-kropki .swiper-pagination-bullet-active {
        background: #fff;
        transform: scale(1.25);
    }
}

/* Kropki na KAZDYM ekranie (decyzja wlasciciela 12.08.2026). Pasek miniatur
   pod zdjeciem znika takze na komputerze: kropki mowia to samo - ile jest zdjec
   i ktore ogladasz - a nie zabieraja ~120 px wysokosci pod galeria.
   Miniatury zostaja w HTML (Swiper trzyma na nich synchronizacje), tylko ich
   nie pokazujemy. */
@media screen and (min-width: 1140px) {
    /* Pasek miniatur znika takze na komputerze. Bezpiecznie, bo photos.phtml
       nie tworzy juz dla niego Swipera ani nie podaje go jako thumbs - samo
       display: none psulo galerie (zdjecie skakalo). */
    .product-view-nav-slider {
        display: none;
    }

    /* Rozmiaru zdjecia na komputerze NIE ruszamy: ma zostac 9:16, tak jak bylo
       (decyzja wlasciciela 12.08.2026 po dwoch moich probach - najpierw contain,
       potem cover z limitem 620 px; obie zmienialy kadr, ktory ma byc bez zmian).

       Konsekwencja, ktora trzeba znac: przy zdjeciu ~850 px wysokosci pigulka
       z kropkami siedzi na jego dolnej krawedzi, czyli okolo 830 px od gory
       strony - na ekranie 864 px widac ja dopiero po drobnym przewinieciu.
       Podniesienie jej wyzej albo skrocenie zdjecia to zmiana ukladu, nie
       poprawka bledu. */

    /* Kadr 9:16 na komputerze. Slajd mial proporcje 4:5 z motywu, a zdjecia sa
       pionowe 9:16 - obraz wpisywal sie w kadr i zostawaly szerokie biale pola
       po bokach (zgloszone przez wlasciciela 12.08.2026). Kadr o proporcji zdjecia
       + cover = fotografia wypelnia ramke, bez bieli. */
    .product-view-slide {
        aspect-ratio: 9 / 16;
    }

    /* Kadr zostaje 9:16, ale okno galerii nie moze byc wyzsze niz ekran - inaczej
       zdjecie ma 1207 px, a pigulka z kropkami laduje 500 px pod zgieciem i klient
       jej nie widzi. 70vh zostawia miejsce na naglowek i okruszki, a cover
       przycina zdjecie zamiast dodawac biale pola. */
    .product-view-slider,
    .product-view-slider .swiper-wrapper,
    .product-view-slide {
        max-height: 70vh;
    }

    /* Kropki pozycjonowaly sie wzgledem WRAPPERA, wiec po ograniczeniu galerii
       ladowaly 21 px pod zdjeciem - a slider ma overflow: hidden, wiec je ucinal.
       Stad "nie widac pigulki" mimo ze pomiar pokazywal ja nad zgieciem.
       position: relative na sliderze robi z niego uklad odniesienia i kropki
       siadaja NA zdjeciu. */
    .product-view-slider {
        position: relative;
    }

    /* Kropki liczą sie od WRAPPERA (Swiper przenosi element paginacji poza slider),
       a wrapper jest o ~33 px wyzszy niz zdjecie - stad pigulka ladowala pod
       fotografia i overflow: hidden slidera ja ucinal. bottom: 46 px sadza ja
       NA zdjeciu. Zmierzone: dol kropek 779 przy dolnej krawedzi zdjecia 791. */
    /* PELNY styl pigulki. Dotad wszystkie jej wlasciwosci - position, tlo, blur,
       padding - siedzialy w bloku max-width: 1139px, wiec na komputerze element
       byl STATYCZNY i lezal pod zdjeciem jako zwykly pasek bez tla. Stad
       "nie widac pigulki" mimo poprawnych pomiarow szerokosci i pozycji. */
    .product-view-slider .product-view-slider-kropki.swiper-pagination-horizontal,
    .product-view-slider .product-view-slider-kropki.swiper-pagination-bullets {
        position: absolute;
        bottom: 14px;
        z-index: 3;
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 6px;
        padding: 6px 9px;
        border-radius: 999px;
        background: rgba(20, 24, 16, .34);
        backdrop-filter: blur(6px);
        -webkit-backdrop-filter: blur(6px);
    }

    .product-view-slide img,
    .product-view-slide-picture {
        width: 100%;
        height: 100%;
        max-width: none;
        max-height: none;
        object-fit: cover;
    }

    /* Te same trzy rzeczy co na telefonie: pigulka obejmuje kropki (Swiper daje
       jej width: 100%), kropki maja 6 px, aktywna jest biala i wieksza.
       Powtorzone swiadomie - reguly mobilne siedza w bloku max-width, a przy
       resztce sesji bezpieczniej powtorzyc szesc linii niz przenosic caly blok. */
    .product-view-slider .product-view-slider-kropki.swiper-pagination-horizontal,
    .product-view-slider .product-view-slider-kropki.swiper-pagination-bullets {
        left: 50%;
        right: auto;
        width: auto;
        /* max-width przebija width dokladnie tak, jak min-width przebijalo je
           przy liczniku ilosci - Swiper trzyma tu width: 100%. */
        max-width: fit-content;
        transform: translateX(-50%);
        bottom: 12px;
    }

    .product-view-slider .product-view-slider-kropki .swiper-pagination-bullet {
        width: 6px;
        height: 6px;
        margin: 0;
        opacity: 1;
        background: rgba(255, 255, 255, .55);
    }

    .product-view-slider .product-view-slider-kropki .swiper-pagination-bullet-active {
        background: #fff;
        transform: scale(1.25);
    }
}

/* ── wiersz ocen: mniejszy, ZAWSZE jedna linia ───────────────────────────
   "56 recenzji ★★★★★ 5.0 317 sprzedanych" ma byc jedna cicha linia miedzy
   tytulem a cena - na 412 px miescil sie przypadkiem, na 320 px lamal sie
   na dwie. Mniejsza czcionka i mniejsze gwiazdki daja zapas na kazdym
   telefonie, a tresc (licznik opinii i sprzedanych) zostaje bez zmian. */
@media screen and (max-width: 1139px) {
    /* Odstep zdjecie -> kreska -> nagłowek mial 50 px, z czego 37,5 px samego luzu
       nad H1. Na telefonie to czysta strata pierwszego ekranu: 26 px odzyskane,
       kreska zostaje po srodku nowej przerwy, wiec podzial nadal jest czytelny. */
    .product-view-top-inner {
        gap: 24px;
    }

    .product-view-top-content:before {
        top: -12px;
    }

    .product-view-rating {
        margin-bottom: 4px;
        gap: 10px;
        flex-wrap: nowrap;
        white-space: nowrap;
        font-size: 12.5px;
    }

    .product-view-rating .rating-summary {
        gap: 6px;
    }

    /* WSZYSTKIE czesci wiersza w jednym rozmiarze. Bez tego "56 recenzji" trzymalo
       15 px z reguly bazowej .rating-summary-count, reszta miala 12,5 px - rozne
       wysokosci pudelek dawaly rozjezdzajace sie linie bazowe (zmierzone: 644 vs 643
       vs 641 px). Jeden rozmiar dla calego wiersza rozwiazuje to u zrodla. */
    .product-view-rating .rating-summary-nr,
    .product-view-rating .rating-summary-count,
    .product-view-rating .product-view-saleCount {
        font-size: 12.5px;
        line-height: 1.2;
    }

    /* Ocena i licznik sprzedanych sa pogrubione, opinie zwykle - hierarchia w wierszu
       ma isc od najwazniejszego (ocena) do kontekstu (ile osob kupilo). */
    .product-view-rating .rating-summary-nr {
        font-weight: 700;
    }


    .product-view-saleCount {
        font-size: 12.5px;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* Kropki rozdzielajace i ZLOTE gwiazdki obowiazuja na karcie na KAZDYM ekranie -
   decyzja wlasciciela z 11.08 dotyczyla karty produktu, nie telefonu; desktop
   z zielonymi gwiazdkami i bez kropek wyszedl na makiecie 12.08 jako regres.
   Selektor jest zawezony do .product-view-rating (istnieje tylko w gorze karty),
   wiec opinie i histogramy nizej zostaja zielone (default w style.css). */
.product-view-rating .rating-summary-count::before,
.product-view-rating .product-view-saleCount::before {
    content: "·";
    margin-right: 6px;
    color: rgba(0, 0, 0, .35);
}

/* Gwiazdki to JEDEN svg 126x21 z piecioma gwiazdkami naraz (sprite) - skalujemy
   calosc, zachowujac proporcje 6:1. Ustawienie "szerokosci gwiazdki" tutaj
   zgniata piec gwiazdek do jednej kropki - sprawdzone na wlasnym bledzie.
   Odcien z makiety wariantow (artifact 87748f77) w ciemnym motywie: jasniejsze
   i cieplejsze zloto niz brazowy #876C38 z palety marki. */
.product-view-rating .rating-summary-stars svg:not([width="0"]) {
    width: 84px;
    height: 14px;
    color: #C4A46A;
}

/* Kolejnosc w wierszu ocen: gwiazdki, srednia, liczba opinii, liczba sprzedanych.
   Dotychczas liczba opinii szla PRZED gwiazdkami (order -1), przez co wiersz zaczynal
   sie od liczby bez kontekstu. Teraz czyta sie jak zdanie: "piec gwiazdek, 5.0,
   z 56 opinii, 318 sprzedanych". Dotyczy obu szerokosci - kolejnosc to nie kwestia
   miejsca, tylko sensu. */
.product-view-rating .rating-summary-stars {
    order: 0;
}

.product-view-rating .rating-summary-nr {
    order: 1;
}

.product-view-rating .rating-summary-count {
    order: 2;
}

.panel-zakupu {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 13px;
    margin: 12px 0 6px;
    border: 1px solid rgba(0, 0, 0, .1);
    border-radius: 16px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 6px 20px rgba(0, 0, 0, .05);
}

/* ── cena ───────────────────────────────────────────────────────────────── */

.panel-cena-rzad {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.panel-cena .price-box {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
}

.panel-cena .price-gross,
.panel-cena .price-net {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
}

.panel-cena .price {
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.05;
}

/* Obnizka: nowa cena zostaje duza, stara maleje i jest przekreslona.
   Kolejnosc w markupie to nowa-stara, wiec czytamy w naturalnej kolejnosci. */
.panel-cena .price-old {
    font-size: 16px;
    font-weight: 500;
    color: #8a8f83;
    text-decoration: line-through;
}

.panel-cena .price-new {
    color: #b3261e;
}

/* B2B: etykieta "netto" nie moze wygladac jak czesc kwoty */
.panel-cena .price-net > .caption,
.panel-cena label.caption {
    display: block;
    width: 100%;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #6b7264;
}

.panel-cena-jednostka {
    margin-top: 2px;
    font-size: 13px;
    color: #6b7264;
}

.panel-cena-jednostka strong {
    color: #333;
    font-weight: 650;
}

.panel-znaczniki {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 5px;
    flex-shrink: 0;
}

.panel-znacznik {
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .01em;
    padding: 6px 9px;
    border-radius: 999px;
    white-space: nowrap;
}

/* Promocja i cena grupy lojalnosciowej to DWA rozne komunikaty i nie moga wygladac
   tak samo: obnizka jest czasowa i dotyczy wszystkich, cena grupy jest staly przywilej
   tego klienta. Czerwien = pilne, zloto = twoje. */
.panel-znacznik-promocja {
    background: #FBE9E7;
    color: #b3261e;
}

.panel-znacznik-lojalnosc {
    background: #F6EFE0;
    color: #876C38;
}

/* Etykieta produktu w panelu (Bestseller, HIT) - wchodzi w miejsce plakietki
   cenowej, gdy tej nie ma. Kolory bierze z panelu, wiec tutaj tylko ksztalt.
   Mniejsza waga niz plakietka rabatu: wyroznienie marketingowe nie ma krzyczec
   glosniej niz informacja o cenie, tylko wypelnic puste miejsce. */
.panel-znacznik-etykieta {
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* B2B: jeden podpis nad paskiem wariantow zamiast slowa "netto" przy kazdej
   z szesciu cen. Pomylka netto/brutto u klienta hurtowego jest kosztowna,
   a sama liczba w kaflu nie mowi, ktora to kwota. */
.panel-wybor-netto {
    align-self: flex-end;
    margin-bottom: -3px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: #8a8f83;
}

.panel-dostepnosc {
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
}

.panel-zakupu .shop-product-history-price-before-discount {
    font-size: 11.5px;
    line-height: 1.4;
    color: #8a8f83;
    margin-top: -6px;
}

.panel-zakupu .shop-product-history-price-before-discount:empty {
    display: none;
}

/* ── wybor wariantu ─────────────────────────────────────────────────────── */

.panel-wybor {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.panel-wybor-etykieta {
    font-size: 12px;
    font-weight: 600;
    color: #6b7264;
}

.panel-wybor-etykieta strong {
    color: #333;
    font-weight: 650;
}

/* Segmenty: 2-3 opcje z krotka etykieta (waga, kolor). Rowne kolumny, bo roznica
   miedzy nimi to jedna liczba i oko ma je porownac, a nie czytac. */
.panel-wybor-segmenty .panel-wybor-lista {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 7px;
}

.panel-wybor-segmenty .panel-opcja {
    display: block;
    padding: 9px 6px;
    text-align: center;
    border: 1.5px solid rgba(0, 0, 0, .12);
    border-radius: 11px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    line-height: 1.25;
    min-height: 48px;
}

/* Kafelki: kolekcje (3-5 pozycji). Nazwa wlasna typu "Isan" nie znaczy nic bez zdjecia,
   a roznica w cenie siega 200 zl - wiec kazdy kafelek pokazuje zdjecie i kwote.
   Przewijanie poziome zamiast zawijania: trzy widoczne i czwarty wystajacy zza krawedzi
   to czytelny sygnal, ze jest ich wiecej. */
/* Pasek: 4 i wiecej opcji tekstowych w JEDNYM rzedzie, przewijanym w bok.
   Siatka 2x2 kosztowala dwa rzedy przy czterech opcjach, a klient B2B widzi
   ich szesc - trzy rzedy zsuwaly cene o pol ekranu. Czwarta opcja jest przy
   krawedzi celowo ucieta: to jedyny sygnal, ze mozna przewijac, i tanszy
   niz strzalka albo kropki. */
.panel-wybor-pasek .panel-wybor-lista {
    display: flex;
    gap: 7px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.panel-wybor-pasek .panel-wybor-lista::-webkit-scrollbar {
    display: none;
}

.panel-wybor-pasek .panel-opcja {
    flex: 0 0 auto;
    min-width: 96px;
    display: block;
    padding: 9px 6px;
    text-align: center;
    border: 1.5px solid rgba(0, 0, 0, .12);
    border-radius: 11px;
    background: #fff;
    text-decoration: none;
    color: inherit;
}

.panel-wybor-kafelki .panel-wybor-lista {
    display: flex;
    gap: 9px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.panel-wybor-kafelki .panel-wybor-lista::-webkit-scrollbar {
    display: none;
}

.panel-wybor-kafelki .panel-opcja {
    flex: 0 0 auto;
    width: 88px;
    text-align: center;
    text-decoration: none;
    color: inherit;
}

.panel-opcja-foto {
    display: block;
    width: 88px;
    height: 88px;
    border: 1.5px solid rgba(0, 0, 0, .12);
    border-radius: 12px;
    overflow: hidden;
    background: #F2F4EC;
}

.panel-opcja-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.panel-opcja-nazwa {
    display: block;
    font-size: 12.5px;
    font-weight: 640;
    color: #333;
}

.panel-wybor-kafelki .panel-opcja-nazwa {
    margin-top: 5px;
    font-size: 11.5px;
}

.panel-opcja-cena {
    display: block;
    font-size: 11.5px;
    color: #6b7264;
    margin-top: 1px;
}

.panel-opcja-wybrana {
    border-color: var(--color-primary);
    background: #F1F6E7;
}

/* W pasku regula .panel-wybor-pasek .panel-opcja jest bardziej szczegolowa niz
   .panel-opcja-wybrana, wiec nadpisywala zielona ramke szarym borderem - wybrany
   wariant wygladal jak niewybrany (widac na zrzutach z 12.08). Ta sama obwodka
   co przy kolekcji: kolor marki + druga linia od wewnatrz. */
.panel-wybor-pasek .panel-opcja-wybrana {
    border-color: var(--color-primary);
    background: #F1F6E7;
    box-shadow: inset 0 0 0 .5px var(--color-primary);
}

.panel-wybor-kafelki .panel-opcja-wybrana .panel-opcja-foto {
    border-color: var(--color-primary);
    border-width: 2px;
}

.panel-opcja-wybrana .panel-opcja-nazwa {
    color: #2E4F00;
}

/* ── prog ilosciowy ─────────────────────────────────────────────────────── */

/* Jedna linia, nie drabinka kafli. Drabinka wyglada lepiej, ale zmierzone: spycha
   przycisk zakupu o 34 px, ponizej pierwszego ekranu. Pelna drabinka pracuje
   w koszyku, gdzie klient wie juz, ze kupuje, i zastanawia sie ile.

   Wlasne pastelowe tlo, bo goly tekst zlewal sie z reszta panelu (uwaga wlasciciela
   11.08). Tlo mowi tez "to jest do dotkniecia" - klik ustawia ilosc progu. */
.panel-prog {
    appearance: none;
    border: 1px dashed rgba(61, 104, 0, .35);
    border-radius: 10px;
    background: #F1F6E7;
    padding: 8px 11px;
    text-align: left;
    font: inherit;
    font-size: 12.5px;
    line-height: 1.4;
    color: #4a5142;
    cursor: pointer;
}

.panel-prog strong {
    color: #2E4F00;
    font-weight: 680;
}

.panel-prog:active {
    transform: scale(.985);
}

/* ── termin wysylki ─────────────────────────────────────────────────────── */

.termin-wysylki {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 11px;
    border: 1px solid rgba(0, 0, 0, .1);
    border-radius: 12px;
    background: #F4F6EF;
}

.termin-wiersz {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 14px;
    line-height: 1.35;
}

.termin-kropka {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #8a8f83;
    flex: 0 0 auto;
    align-self: center;
}

.termin-kropka-dzis {
    background: var(--color-primary);
}

.termin-kropka-czeka {
    background: #876C38;
}

.termin-glowny {
    font-weight: 650;
    color: #333;
}

.termin-zegar {
    margin-left: auto;
    font-size: 12.5px;
    color: #6b7264;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.termin-doreczenie {
    font-size: 12.5px;
    color: #6b7264;
    padding-left: 15px;
}

.termin-wysylki-przelew {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
}

.termin-wysylki-kompaktowy {
    padding: 0;
    border: 0;
    background: transparent;
}

/* ── akcje i szybkie platnosci ──────────────────────────────────────────── */

/* Miejsce na widget InPost Pay. Wedlug dokumentacji InPostu widget stoi DOKLADNIE
   pod przyciskiem "Dodaj do koszyka", wiec kontener istnieje od poczatku - wdrozenie
   nie bedzie wymagalo przebudowy panelu, tylko wstawienia skryptu. Pusty nie zajmuje
   miejsca, wiec dzis nie zostawia dziury. */
.panel-szybkie-platnosci:empty {
    display: none;
}

.panel-szybkie-platnosci {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── krotki opis pod panelem ────────────────────────────────────────────
   Jedyny kawalek ciaglego tekstu w gorze karty. Bez wlasnej typografii czytal sie
   jak zlepek: jeden blok szesciu linii bez punktow zaczepienia. Trzy rzeczy to
   naprawiaja i wszystkie sa w CSS, nie w tresci:
   1. akapity rozdzielone swiatlem, wiec kazda mysl ma wlasny blok,
   2. wieksze interlinie (1,6) - przy 15 px to roznica miedzy czytaniem a skanowaniem,
   3. wsparcie dla etykiet: <strong> na poczatku akapitu staje sie ciemniejszym,
      krotkim naglowkiem wiersza ("Smak: ..."), wiec oko ma po czym skakac. */
.product-teaser {
    margin: 18px 0 8px;
    font-size: 15px;
    line-height: 1.6;
    color: #4a5142;
}

.product-teaser p {
    margin: 0 0 10px;
}

.product-teaser p:last-child {
    margin-bottom: 0;
}

/* Etykieta wiersza: "Smak:", "Skad:", "Jak pic:". Ciemniejsza i lekko wezsza
   niz tekst, zeby prowadzila wzrok, a nie krzyczala. */
.product-teaser p > strong:first-child {
    color: #2f3329;
    font-weight: 650;
}

/* ── podtytul i porcje ──────────────────────────────────────────────────── */

/* Jedno zdanie pod nazwa: czym produkt JEST. Cicha typografia - to wyjasnienie,
   nie drugi naglowek, i ma sie czytac RAZEM z nazwa, wiec przylega do niej
   (odstep mniejszy niz do wiersza z ocenami nizej).
   Jedna linia zawsze: dluzszy podtytul zostaje uciety wielokropkiem zamiast
   zawijac sie na drugi wiersz i spychac cene. Panel ostrzega o limicie ~50 znakow. */
.product-podtytul {
    margin: 3px 0 10px;
    font-size: 14px;
    line-height: 1.35;
    color: #6b7264;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Nazwa ma z motywu margin-bottom: 15px, wiec podtytul stal 13 px od nazwy,
   a tylko 10 px od wiersza ocen - czytal sie jako czesc ocen, nie nazwy.
   Kasujemy TEN margines wylacznie, gdy podtytul faktycznie jest (:has), zeby
   produkt bez podtytulu zachowal dotychczasowy odstep. Zmierzone po zmianie:
   nazwa -> podtytul 3 px, podtytul -> oceny 10 px. */
.product-view-title:has(+ .product-podtytul) {
    margin-bottom: 0;
}

.panel-cena-porcje {
    color: #6b7264;
    font-weight: 400;
}

/* ── bullety ────────────────────────────────────────────────────────────── */

/* Bullety leza NAD panelem (renderuje je index.phtml): korzysci pracuja przed
   decyzja. Sciezka odwrotna - pod przyciskiem - to blad starego paska zaufania. */
.panel-bullety {
    list-style: none;
    /* 16 px nad soba: bullety to osobna mysl, nie ciag dalszy wiersza z ocenami.
       Przy 4 px czytaly sie jak podpis pod gwiazdkami. */
    margin: 16px 0 12px;
    padding: 0;
    display: grid;
    gap: 9px;
}

.panel-bullet {
    display: grid;
    grid-template-columns: 15px 1fr;
    gap: 9px;
    align-items: start;
    /* 15 px zamiast 13,5: to nie podpis, tylko trzy zdania, ktore maja przekonac.
       Zmierzone na iPhone 14 Pro - przy 15 px kazdy argument nadal miesci sie
       w jednej linii, wiec czytelnosc nie kosztuje ani jednego piksela wiecej. */
    font-size: 15px;
    line-height: 1.4;
    color: #2f3329;
}

.panel-bullet-ikona {
    width: 20px;
    height: 20px;
    object-fit: contain;
}

/* Ptaszek zamiast kropki. Kropka jest neutralnym punktem listy, ptaszek niesie
   znaczenie "to juz zalatwione" - przy argumentach, ktore zbijaja obawy, to nie
   ozdoba, tylko czesc komunikatu. SVG w tle, wiec zero dodatkowych zapytan.
   Warianty odrzucone (ptaszek w kolku +17 px, blok z tlem +79 px i zawijanie
   drugiego argumentu): scripts/audyt/warianty-bulletow.js. */
.panel-bullet-kropka {
    width: 15px;
    height: 15px;
    margin-top: 3px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.6l3.4 3.4L13.5 4.4' fill='none' stroke='%233D6800' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center/contain;
}

/* ── wiersz zakupu: licznik + przycisk ──────────────────────────────────
   Wyglad z makiety mial te style w SKRYPCIE makiety, nie w tym arkuszu - stad
   produkcja wygladala inaczej niz to, co bylo zatwierdzone (zmierzone 12.08.2026:
   licznik i przycisk po 295 px przy 345 px szerokosci, czyli lamaly sie na dwa
   rzedy; przycisk mial grubosc 400 i promien 20 px zamiast 11).
   Reguly sa zawezone do .panel-zakupu, wiec koszyk i inne miejsca z tym samym
   komponentem zostaja bez zmian. */
.panel-zakupu .product-view-basket-inner-quantity-btn {
    display: flex;
    align-items: stretch;
    gap: 8px;
    /* Regula bazowa komponentu pozwala na zawijanie, a przycisk ma width: 100%,
       wiec licznik 104 + przycisk 295 nie miescily sie w 295 px wiersza i przycisk
       ladowal POD licznikiem (zmierzone 12.08.2026: wrapper 108 px wysokosci,
       top przycisku o 58 px nizej niz licznika). */
    flex-wrap: nowrap;
}

/* Licznik zajmuje tyle, ile potrzebuje - reszta wiersza nalezy do przycisku,
   bo to on jest celem. */
.panel-zakupu .shop-quantity-box {
    /* STALA szerokosc, nie min-width: input w srodku ma flex: 1, wiec przy
       'auto' rozpychal licznik do 250 px i przycisk zakupu kurczyl sie do 32 px
       (zmierzone 12.08.2026 na trzech szerokosciach telefonu). */
    flex: 0 0 104px;
    width: 104px;
    /* min-width MUSI byc nadpisany: style.css ustawia komponentowi min-width: 152px,
       a min-width przebija width niezaleznie od kolejnosci arkuszy - stad licznik
       trzymal 152 px i zjadal przycisk zakupu. To bylo prawdziwe zrodlo problemu,
       nie zawijanie ani box-sizing. */
    min-width: 104px;
    /* border-box, bo komponent liczy szerokosc jak content-box: bez tego
       padding i ramka doliczaly sie do 104 px i licznik wychodzil szerszy,
       zjadajac przycisk zakupu (zmierzone: przycisk 62 px na ekranie 320). */
    box-sizing: border-box;
    /* Rowna wysokosc z przyciskiem: komponent liczy sobie wysokosc z zawartosci
       (zmierzone 30 px przy przycisku 50) i wiersz wygladal na zlozony z dwoch
       roznych rzeczy. */
    min-height: 50px;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border: 1px solid rgba(0, 0, 0, .12);
    border-radius: 11px;
    background: #fff;
    padding: 0 4px;
}

/* Wyzsza szczegolowosc (trzy klasy): reguly bazowe komponentu wygrywaly
   z dwuklasowym selektorem i licznik zostawal 30 px wysoki przy przycisku 50. */
.panel-zakupu .product-view-basket-inner-quantity-btn .shop-quantity-box {
    height: 50px;
    min-height: 50px;
}

.panel-zakupu .shop-quantity-box .input-qty {
    /* Wypelnia srodek miedzy minusem a plusem. Staly 40 px nie dzialal, bo
       .action sa pozycjonowane ABSOLUTNIE (patrz nizej) i input wchodzil pod
       przycisk minus - liczba byla zaslonieta i wygladalo, jakby jej nie bylo. */
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    height: auto;
    padding: 0;
    border: 0;
    background: transparent;
    text-align: center;
    font-size: 15px;
    font-weight: 650;
    color: #333;
    box-shadow: none;
}

/* Komponent ustawia +/- absolutnie i daje im wlasne ramki - stad "prostokaty"
   w srodku pola i rozjechany srodek. W panelu wracaja do przeplywu, wiec
   flex ustawia je sam: minus, liczba, plus. */
/* Kolejnosc w HTML to input, plus, minus - flex ustawia ja po ludzku: - 1 +.
   Zmiana szablonu byłaby ryzykowna, bo ten sam markup obsluguje koszyk. */
.panel-zakupu .shop-quantity-box .qty-down {
    order: 1;
}

.panel-zakupu .shop-quantity-box .input-qty {
    order: 2;
}

.panel-zakupu .shop-quantity-box .qty-up {
    order: 3;
}

.panel-zakupu .shop-quantity-box .action {
    position: static;
    flex: 0 0 30px;
    border: 0;
    background: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 44px;
    cursor: pointer;
    color: #6b7264;
    font-size: 17px;
    line-height: 1;
    user-select: none;
}

.panel-zakupu .product-view-basket-inner-quantity-btn button[type="submit"] {
    /* width: auto + min-width: 0 sa konieczne: bez nich szerokosc 100% z reguly
       bazowej trzyma przycisk przy 295 px i wiersz sie lamie mimo nowrap. */
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    min-height: 50px;
    border-radius: 11px;
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: .01em;
}

/* Etykieta i dostepnosc na srodku swojej kolumny zamiast dosuniete do prawej -
   przy dluzszym tekscie ("Produkt dostepny") ostatnia litera dotykala krawedzi
   panelu. Srodkowanie daje ten sam margines z obu stron. */
.panel-zakupu .panel-znaczniki {
    align-items: center;
    text-align: center;
}

/* Odstep po kafelku terminu: formularz koszyka wnosil wlasne marginesy, ktore
   po usunieciu szarego pudla zostaly jako dziura. Panel ma wlasny rytm (gap),
   wiec w jego obrebie zerujemy marginesy formularza. */
.panel-zakupu form,
.panel-zakupu .product-view-basket-inner {
    margin-top: 0;
    margin-bottom: 0;
}

/* Rytm panelu to 10 px (jego wlasny gap). Kontener formularza koszyka wnosil
   WLASNY gap 18 px, przez co odstep przed wierszem zakupu wynosil 30 px zamiast
   10 - jedyna nierowna przerwa w panelu. Zerujemy go w obrebie panelu. */
.panel-zakupu .product-view-basket-inner {
    gap: 0;
}

/* Pusty slot na szybkie platnosci (InPost Pay - jeszcze nieuruchomione) siedzial
   miedzy terminem a wierszem zakupu jako element o zerowej wysokosci. W kolumnie
   flex z gap 10 px kosztowal DWA odstepy zamiast jednego, czyli 30 px zamiast 10 -
   jedyna nierowna przerwa w panelu. :empty usuwa go z ukladu, dopoki nic w nim nie ma. */
.panel-zakupu .panel-szybkie-platnosci:empty {
    display: none;
}

/* Szare pudlo wokol formularza koszyka. Panel JEST juz karta - bialy prostokat
   z ramka - wiec drugie tlo w srodku robi karte w karcie. W makiecie go nie bylo.
   Zabieramy tez padding 20 px, bo panel ma wlasny (13 px). */
.panel-zakupu .shop-product-offer-box {
    background: none;
    padding: 0;
    border: 0;
    border-radius: 0;
}

/* Ikona koszyka zapadala sie do 0x0: przycisk jest kontenerem flex, a span.icon
   nie mial wlasnego rozmiaru ani zakazu kurczenia. SVG w srodku ma 12x16. */
.panel-zakupu .product-view-basket-inner-quantity-btn button[type="submit"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.panel-zakupu .product-view-basket-inner-quantity-btn button[type="submit"] .icon {
    flex: 0 0 auto;
    width: 12px;
    height: 16px;
}

.panel-zakupu .product-view-basket-inner-quantity-btn button[type="submit"] .icon svg {
    display: block;
    width: 12px;
    height: 16px;
}

/* Waskie telefony (<=380 px): przy liczniku 104 px na przycisk zostawalo 110 px
   i napis "DODAJ DO KOSZYKA" byl uciety (sprawdzone na 320x568). Licznik oddaje
   12 px, a napis schodzi o polpunktu - tekst zostaje ten sam, bo skrot w rodzaju
   "Do koszyka" to inna obietnica niz ta z makiety. */
@media screen and (max-width: 380px) {
    .panel-zakupu .shop-quantity-box {
        flex: 0 0 84px;
        width: 84px;
        min-width: 84px;
    }

    .panel-zakupu .shop-quantity-box .action {
        flex: 0 0 26px;
    }

    .panel-zakupu .product-view-basket-inner-quantity-btn button[type="submit"] {
        font-size: 12.5px;
        padding-left: 6px;
        padding-right: 6px;
        letter-spacing: 0;
    }
}

/* ── desktop: panel zostaje, ale przestaje udawac karte ─────────────────── */

@media screen and (min-width: 1140px) {
    .panel-zakupu {
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        gap: 16px;
        margin-top: 0;
    }

    .panel-cena .price {
        font-size: 34px;
    }

    /* Na duzym ekranie kolekcja i pasek mieszcza sie bez przewijania.
       Przewijanie w bok zostaje mechanizmem TELEFONU: mysz nie ma naturalnego
       gestu przewijania poziomego, a przy szerokosci kolumny ~660 px wszystkie
       opcje i tak wchodza w dwa rzedy najwyzej. */
    .panel-wybor-kafelki .panel-wybor-lista,
    .panel-wybor-pasek .panel-wybor-lista {
        flex-wrap: wrap;
        overflow: visible;
    }

    /* Podtytul przy H1 36 px: 14 px wygladalo jak przypis, nie jak druga polowa
       naglowka. Prawa kolumna ma ~660 px, wiec dlugi podtytul nadal siedzi
       w jednej linii (nowrap z regul bazowych zostaje jako bezpiecznik). */
    .product-podtytul {
        font-size: 16px;
        margin-bottom: 12px;
    }

    /* Przy cenie 34 px i przycisku 50 px linia progu i termin w rozmiarach
       telefonowych wygladaly jak drobny druk. Jeden krok wiekszosci wystarczy -
       to nadal informacja pomocnicza, nie drugi naglowek. */
    .panel-prog {
        font-size: 14.5px;
    }

    .termin-wysylki .termin-glowny {
        font-size: 15.5px;
    }

    .termin-wysylki .termin-doreczenie,
    .termin-wysylki .termin-zegar {
        font-size: 14px;
    }
}
