/*
Krok 3.3a: pelny wlasny uklad (kokpit) dla produktu 862 - zastepuje
poprzednie style z Krokow 3.1-3.2 (byla to para kafli w standardowym
.btx-bento-grid, teraz to jeden wlasny blok pelnej szerokosci). Wszystkie
wartosci na tokenach --btx-* z bento-uikit.css, zero wartosci na sztywno.
*/

/*
Bez jawnej wysokosci na kontenerze siatki wiersz "1fr" nie ma do czego sie
odniesc - w praktyce rozciaga sie do wysokosci najwiekszej zawartosci, a
rail/panel (rozciagniete na oba wiersze) rosna razem z nim bez ograniczen,
mimo overflow-y:auto ponizej (scroll wymaga OKRESLONEJ wysokosci przodka).
Stad jawne "height" tutaj - to ono realnie ogranicza kafle boczne i
uruchamia scroll w ich wnetrzu.

Boczne kolumny NA SZTYWNO w px (byly "352px ... 480px") oznaczaly ze caly
balast przy zwezaniu okna spadal WYLACZNIE na srodkowa kolumne (canvas) -
zmierzone live (2026-08-21, user zglosil zrzuty z prawdziwych ekranow
1920/1440/1280px pokazujace nachodzacy tekst): canvas mial tam kolejno
tylko ~736/328/192px, kontra ~1280px na szerszym monitorze gdzie
projektowano ten layout pierwotnie. "clamp(min, vw, max)" pozwala obu
bocznym kolumnom PLYNNIE zwezac sie miedzy sensownym minimum a obecnym
maksimum w miare jak robi sie ciasniej, wiec canvas nie jest juz jedynym
"amortyzatorem" - przy 1280px daje to canvasowi ~512px zamiast 192px.
*/
.btx-stamp-cockpit
{
    /*
     * Nowy token "zaokraglony kwadrat zamiast pigulki" dla przyciskow/
     * kontrolek - user zapytal teoretycznie o sitewide przesiadke z
     * "--btx-radius-pill" na cos mniej okraglego, zdecydowal zaczac
     * TYLKO w tym module (nie dotykac bento-uikit.css/reszty sklepu
     * jeszcze). Zdefiniowany lokalnie tu (nie w :root globalnym), zeby
     * pozniejszy sitewide rollout byl swiadoma, osobna decyzja, nie
     * przypadkowym efektem ubocznym.
     */
    --btx-radius-control: 16px;
    /*
     * Radiusy TYLKO w tym module (user: "czy dasz rade radiusy skalowac
     * proporcjonalnie... narazie tylko kreator"). PIERWSZA wersja uzywala
     * clamp()-a plynnie skalowanego z "vw" (szerokosc viewportu) - user
     * potem zglosil: "przyciski wygladaja inaczej, na wyzszej rozdzielczosci
     * sa wyzsze wiec radiusy powinny byc wieksze" - okazalo sie ze FIZYCZNY
     * rozmiar przyciskow/kontrolek w tym module NIE rosnie plynnie z "vw"
     * wcale - jest binarnie przelaczany trybem "compact" (media query
     * ponizej: szerokosc 992-1700px LUB wysokosc <=820px = male kontrolki,
     * bo tak zdefiniowano juz wczesniej, patrz komentarz przy tej media
     * query nizej). Plynny radius na "vw" i binarny rozmiar na innym
     * warunku dawaly niespojna strefe (np. 1390-1700px szerokosci) gdzie
     * promien byl JUZ pelny (14px) ale przyciski WCIAZ male (compact,
     * 34px zamiast 40px) - zaokraglenie nieproporcjonalne do realnego
     * rozmiaru. Fix: radius TEZ binarny, na TEJ SAMEJ media query co
     * rozmiar (nizej) - oba zawsze przelaczaja sie RAZEM, w tym samym
     * momencie, zero niespojnej strefy przejsciowej.
     *
     * Doprecyzowanie (user: "radiusy to powieksz bo chodzilo mi o to zeby
     * wygladaly jak te male a nie zeby te male wygladaly jak duze") -
     * warstwa "compact" (media query nizej) zostaje BEZ ZMIAN (user
     * chwalil ten wyglad juz wczesniej), ale warstwa "pelna" (poza
     * compact, ponizej) podniesiona WYRAZNIE ponad dawny sitewide-parytet
     * x1.333 (28/21px itd.) - pierwsza proba, do doprecyzowania wizualnie.
     */
    --btx-radius-xs: 5px;
    --btx-radius-sm: 10px;
    --btx-radius-md: 14px;
    --btx-radius-lg: 20px;
    --btx-radius-xl: 24px;
    --btx-radius-2xl: 32px;
    display: grid;
    /*
     * "%" zamiast "vw" (user: "czemu na 1920 canvas jest mniejszy niz na
     * 1440?") - "%" w torach siatki liczy sie wzgledem WLASNEJ szerokosci
     * kontenera (kokpitu), "vw" wzgledem calego viewportu. Ponizej kokpit
     * dostaje "min(95vw, 1320px)" - powyzej ~1390px viewportu ten cap
     * (1320px) wygrywa i kokpit PRZESTAJE rosnac, ale boczne kolumny na
     * "vw" NADAL rosly z viewportem (bo vw nie wie ze rodzic sie juz nie
     * powieksza), az trafialy w swoj wlasny gorny limit (352/480px) -
     * zabierajac przy tym ~170px srodkowej kolumnie canvasu na szerokim
     * ekranie wzgledem tego samego, "zamrozonego" 1320px kokpitu na 1440px.
     * Zmierzone live: stageWidth 491px (1440) vs 328px (1920), mimo ze
     * cockpitWidth identyczne (1320px) w obu przypadkach. "%" naturalnie
     * przestaje rosnac razem z kontenerem, wiec canvas jest teraz spojny
     * na kazdym szerokim ekranie.
     */
    /*
     * Doprecyzowanie (user: "dasz rade zeby jeszcze poszerzal sie lewy i
     * prawy panel do szerokosci elementow na str glownej?" -> dopytany
     * `AskUserQuestion`, potwierdzone: chodzi po prostu o wiecej luzu, nie
     * o konkretna wartosc z konkretnego elementu). Fix wyzej ("%" zamiast
     * "vw") mial skutek uboczny - przy kokpicie zamrozonym na 1320px,
     * 20%/26% z 1320 (264/343px) i tak wypadalo PONIZEJ starych minimow
     * (280/360px), wiec panele byly przez to NA STALE przypiete do
     * wlasnego minimum na kazdym szerokim ekranie (>=~1390px viewportu) -
     * caly przyrost szedl wylacznie do canvasu. Wspolczynniki procentowe
     * podniesione (20%->24%, 26%->32%) tak zeby przy zamrozonym 1320px
     * kontenerze realnie wypadaly W przedziale miedzy minimum a maximum
     * (316.8px/422.4px), a nie ponizej minimum - panele TERAZ realnie
     * rosna na szerokich ekranach, nie tylko canvas. Minimalna wartosc
     * (280/360, "najmniejsza desktopowa" ktora user lubi) CELOWO bez
     * zmian - przy 992px (nieujarzmiony kokpit, ~942px) nowe % i tak
     * nadal wypadaja ponizej minimum, wiec floor dziala identycznie jak
     * wczesniej, zero regresji na najmniejszym desktopowym ekranie.
     */
    /*
     * Prawa kolumna zwezona na najnizszej rozdzielczosci (user: "zwez ten
     * prawy kafel poszerzajac srodkowe...o 15 procent ale tylko na tej
     * najnizszej rozdzielczosci"). PIERWSZA proba obnizala TYLKO dolny
     * "podlogowy" prog clamp() (360->306px) - user zglosil ze "nadal sie
     * nie zmienilo", bo floor realnie dziala WYLACZNIE tuz przy ~992px
     * (gdzie % juz spada ponizej niego) - przy jakimkolwiek szerszym
     * "najnizszym desktopowym" oknie (np. 1200-1700px, caly praktyczny
     * zakres trybu "compact") sama procentowa wartosc (32%) JUZ przebijala
     * stary floor, wiec zmiana floora byla bez wplywu w calym tym zakresie.
     * Fix: baza (poza compact) BEZ ZMIAN, ale wewnatrz media query trybu
     * "compact" (ten sam warunek co radiusy/rozmiary przyciskow nizej)
     * dopisane WLASNE, wezsze `grid-template-columns` dla calej prawej
     * kolumny - dziala wiec spojnie w CALYM praktycznym zakresie "najnizszej
     * rozdzielczosci", nie tylko na samym dnie 992px.
     */
    grid-template-columns: clamp(280px, 24%, 360px) 1fr clamp(360px, 32%, 460px);
    grid-template-rows: 1fr auto;
    grid-template-areas:
        "rail canvas panel"
        "rail controls panel";
    gap: var(--btx-gap-lg);
    height: 820px;
    margin-bottom: 60px;
}

/*
 * Kolizja z bento-product.css znaleziona przy debugowaniu fluidnych
 * radiusow wyzej - "#product .btx-tile { border-radius:21px !important }"
 * (992-1440px) to STARY, hardcoded tier dla zwyklych kafli PDP (media/
 * buybox/opis), NIE ma nic wspolnego z kokpitem, ale "#product .btx-tile"
 * (1 ID + 1 klasa) jest specyficznosciowo SILNIEJSZY niz generyczne
 * ".btx-tile { border-radius:var(--btx-radius-2xl) !important }" z
 * bento-uikit.css - wiec w tym jednym zakresie viewportu bezgłośnie
 * przebijal moj nowy, fluidny token, "zamrazajac" kafle kokpitu na
 * sztywne 21px (znalezione przez rekursywne przeszukanie WSZYSTKICH
 * arkuszy, wlacznie z regulami zagniezdzonymi w @media - pierwszy plytki
 * skan tylko po top-level regulach tego nie zlapal). Fix scoped TYLKO do
 * kokpitu (nie ruszam bento-product.css - user: "narazie tylko kreator") -
 * "#product .btx-stamp-cockpit .btx-tile" (1 ID + 2 klasy) ma WYZSZA
 * specyficznosc niz kolidujaca reguła, wiec bezpiecznie odzyskuje
 * kontrole z powrotem do var(--btx-radius-2xl) (teraz fluidnego).
 */
#product .btx-stamp-cockpit .btx-tile
{
    border-radius: var(--btx-radius-2xl) !important;
}

/*
Full-bleed breakout - identyczny mechanizm i identyczne wartosci co
#product .btx-bento-grid w bento-product.css (ten sam kontener nadrzedny
#product .container, wiec ten sam trik dziala tu tak samo). Bez tego
kokpit zostaje uwiezniony w waskim max-width:990px kontenera.

Wysokosc/margines na "wypelnij strone bez scrolla" (2026-08-21, user) -
zmierzone na zywo w DOM (getBoundingClientRect): odstep miedzy dolna
krawedzia belki nawigacji (".btx-desktop-islands") a gorna krawedzia
kokpitu to 35px, a gorna krawedz kokpitu (nav+breadcrumb+istniejace
odstepy) startuje na 127px od gory viewportu - stad
"calc(100vh - 127px - 35px)" (127+35=162, dokladnie tyle miejsca zajmuje
WSZYSTKO nad kokpitem PLUS ten sam odstep u dolu) i margines dolny 35px
(identyczny jak gorny). Scoped do desktop (>=992px, tak jak reszta tego
bloku) - mobile nie jest jeszcze zaprojektowany pod pelnoekranowy kokpit
bez scrolla (osobny, otwarty temat audytu).

Szerokosc 85vw→95vw (2026-08-21, ten sam fix co "clamp()" na kolumnach
wyzej, ta sama przyczyna) - 15% martwego marginesu po bokach bylo zbyt
duzo kosztem canvasu na ekranach 1280-1920px. 95vw zostawia wciaz
czytelny, symetryczny oddech od krawedzi (5%, ~96px przy 1920px) ale
oddaje reszte tam gdzie realnie potrzeba.
*/
@media (min-width: 992px)
{
    /*
    Doprecyzowanie #3 (user: "wez np szerokosc banera i taka szerokosc
    maja miec elementy kreatora razem wziete" - po tym jak "min(95vw,
    1320px)" z doprecyzowania #2 nizej okazal sie zbyt ciasny na 1920px).
    Cel: ta sama, SZERSZA "full-bleed" formula co #carousel (baner glowny)
    i .btx-category-stacks na homepage (bento-home.css) - "calc(85vw -
    64px)", BEZ gornego capu (banera tez nie ma - rosnie dalej na
    ultrawide). Zmierzone live na biurotex.eu/ przy 1920px:
    #carousel.getBoundingClientRect().width = 1555.25px - ta sama formula
    tu daje 1568px w tym samym viewporcie (male ~13px rozjechanie, bez
    ustalonej przyczyny - prawdopodobnie zaokraglenia miedzy kilkoma
    zagniezdzonymi calc(), nieistotne wizualnie), wiec kokpit i baner sa
    TERAZ tej samej skali szerokosci.

    "max()" miedzy STARA formula ("min(95vw,1320px)", doprecyzowanie #2)
    a NOWA ("85vw-64px") - bez tego sama nowa formula regresowala kokpit
    na WASKICH desktopach: przy 992px stara dawala 942px, nowa tylko
    779px (85vw rosnie WOLNIEJ niz 95vw, a "-64px" jeszcze bardziej
    to pogarsza w tym zakresie) - user chwalil WLASNIE te "najmniejsza
    desktopowa" proporcje przy okazji radiusow wyzej, wiec zero regresji
    tam. "max()" gwarantuje ze ZAWSZE wygrywa wieksza z dwoch - w
    praktyce: 992-~1628px kokpit zachowuje sie DOKLADNIE jak dotychczas
    (stara formula wygrywa, wlacznie z plateau na 1320px miedzy ~1390 a
    ~1628px), dopiero powyzej ~1628px nowa formula przejmuje i kokpit
    rosnie dalej w strone szerokosci banera. Zmierzone: 992px → 779.2px
    (779.2px BY BYLO bez max(), z max() zostaje faktyczne 942.4px -
    patrz mierzenie live w rejestrze).

    "margin-left" to standardowy "vw breakout" (element w waskim,
    wysrodkowanym rodzicu wyskakuje na pelna szerokosc viewportu) -
    ogolny wzor to "50% - (wlasna_szerokosc / 2)", gdzie "wlasna_szerokosc"
    musi byc DOKLADNIE tym samym wyrazeniem co "width" powyzej (max()
    powtorzony identycznie), inaczej wysrodkowanie sie rozjezdza.
    */
    .btx-stamp-cockpit
    {
        width: max(min(95vw, var(--btx-container-width)), calc(85vw - 64px)) !important;
        max-width: max(min(95vw, var(--btx-container-width)), calc(85vw - 64px)) !important;
        margin-left: calc(50% - max(min(95vw, var(--btx-container-width)), calc(85vw - 64px)) / 2) !important;
        box-sizing: border-box !important;
        margin-bottom: 35px !important;
    }

    /*
    "100dvh" po "100vh" (user: przerwa strzalki do stopki "wyjezdza i od
    razu przeskakuje w dol" - zlapane z nagrania ekranu, nie zgadywane:
    pasek Safari chowa/pokazuje sie w trakcie scrolla, co przelicza "vh"
    w locie i psulo animacje). "100vh" to bezpieczny fallback dla
    przegladarek bez wsparcia "dvh" (CSS po prostu ignoruje
    nierozpoznana wartosc, zostaje pierwsza) - druga deklaracja tej samej
    wlasciwosci wygrywa TYLKO gdy jest zrozumiala.
    */
    body.product-id-862
    {
        height: 100vh;
        height: 100dvh;
        overflow: hidden;
    }

    html:has(body.product-id-862)
    {
        overflow: hidden !important;
    }

    /*
    Pasek przewijania ukryty (user: "wylacz pokazywanie sie scrollbara na
    tej str") - scroll na tej stronie jest i tak wylacznie sterowany
    przyciskiem-strzalka (patrz initStampScrollToFooter() w JS), wiec
    widoczny pasek podczas animacji/w stanie otwartym byl zbednym
    elementem UI. "scrollbar-width"/"-ms-overflow-style" to standardowe
    wlasciwosci (Firefox/legacy Edge), "::-webkit-scrollbar" to
    webkitowy odpowiednik (Chrome/Safari) - scroll dalej dziala
    normalnie, znika tylko sam widoczny pasek.
    */
    html:has(body.product-id-862),
    body.product-id-862
    {
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    html:has(body.product-id-862)::-webkit-scrollbar,
    body.product-id-862::-webkit-scrollbar
    {
        display: none;
    }
}

/*
User: "margines gorny taki jak dolny" - zmierzone live ze 127px gornego
odstepu (viewport top do kokpitu) SKLADA SIE z: paska nawigacji fixed
(nie liczy sie do normalnego ukladu, "body{padding-top:102px}" globalnie
rezerwuje mu miejsce, TEGO NIE RUSZAMY - zmniejszenie kladloby tresc POD
fixed navem na kazdej stronie sklepu) + DODATKOWE 25px paddingu na
"#wrapper" (globalny, wspoldzielony kontener PrestaShop -
#wrapper{padding-top:25px}).

Odkryte PO pierwszym wdrozeniu (user: "na duzych za maly"): pasek
nawigacji (.btx-desktop-islands, custom.css) NIE ma stalej wysokosci -
70px w zakresie 992-1440px (wlasny tryb "compact" nawigacji), 92px
powyzej 1440px. "body{padding-top:102px}" jest STALE (nie zalezy od
faktycznej wysokosci nava), wiec oryginalne 127px gory bylo zaprojektowane
POD PELNY nav (92px): 127-92=35px odstepu - DOKLADNIE tyle co dol,
zamierzona symetria. W waskim (compact-nav) zakresie ten sam staly 127px
dawal wiec NADMIAROWY odstep (127-70=57px) - TU i TYLKO TU jest bezpiecznie
odzyskiwalne miejsce. Zejscie do "padding-top:0" na #wrapper (ponizej,
scoped do max-width:1440px) daje 102px gory, czyli 102-70=32px - blisko
docelowych 35px, przyjete jako wystarczajaco bliskie (nie warto dalej
docinac o pojedyncze px kosztem czytelnosci formuly). W PELNYM zakresie
nawigacji (>=1441px) #wrapper NIE jest tu ruszany - zostaje oryginalne
globalne 25px, bo tam 127px gory bylo JUZ poprawne (35px), a wczesniejsza,
bledna wersja fixu zdejmowala te 25px WSZEDZIE naraz i psula wlasnie ten
szerszy zakres (10px zamiast 35px).
*/
@media (min-width: 992px) and (max-width: 1440px)
{
    .btx-stamp-cockpit
    {
        height: calc(100vh - 137px) !important;
        height: calc(100dvh - 137px) !important;
    }

    body.product-id-862 #wrapper
    {
        padding-top: 0 !important;
    }
}

@media (min-width: 1441px)
{
    .btx-stamp-cockpit
    {
        height: calc(100vh - 162px) !important;
        height: calc(100dvh - 162px) !important;
    }
}

/*
Tryb "compact" (2026-08-21, user: realny MacBook Air M1, 1440x674 -
"wszystko za duze, canvas za maly"). Miniaturka(120px)/tytul(hero,40px)/
padding naglowka byly ZAWSZE tej samej, sztywnej wielkosci niezaleznie od
efektywnej rozdzielczosci ekranu - na szerokim monitorze zewnetrznym
(gdzie te wartosci byly dobierane) to OK, ale na mniejszym/nizszym oknie
laptopa (typowe MacBook Air/14" Pro: 1440-1512px szerokosci, czesto
niepelnoekranowe okno = jeszcze mniej wysokosci niz 100vh) ten sam,
duzy "balast" chromu zjada nieproporcjonalnie duzo z i tak juz
ograniczonej przestrzeni, kosztem samego canvasu (najwazniejszej,
tworczej czesci). Dwa niezalezne warunki (szerokosc LUB wysokosc) bo
oba niezaleznie ograniczaja przestrzen na typowym laptopie.
*/
@media (min-width: 992px) and (max-width: 1700px),
       (min-width: 992px) and (max-height: 820px)
{
    /*
     * Mala warstwa radiusow - TA SAMA media query co reszta trybu
     * "compact" nizej (rozmiary przyciskow/kontrolek), wiec promien i
     * fizyczny rozmiar elementu ZAWSZE przelaczaja sie razem. Patrz
     * komentarz przy --btx-radius-* w bazowej regule .btx-stamp-cockpit
     * wyzej w pliku - to jest jego "compact" polowa.
     *
     * Doprecyzowanie #2 (user: "nadal wydaje mi sie ze za male radiusy w
     * tej malej wersji") - poprzednia proba (x0.75 wzgledem nowych
     * pelnych wartosci) nadal za mala wg usera. Podniesione ponownie, tym
     * razem x0.9 (blizej pelnej warstwy) - jesli i to za malo/za duzo,
     * kolejna iteracja wizualna.
     */
    .btx-stamp-cockpit
    {
        --btx-radius-control: 14px;
        --btx-radius-xs: 4.5px;
        --btx-radius-sm: 9px;
        --btx-radius-md: 13px;
        --btx-radius-lg: 18px;
        --btx-radius-xl: 22px;
        --btx-radius-2xl: 29px;
    }

    /*
     * Prawa kolumna zwezona o 15% w calym praktycznym zakresie "najnizszej
     * rozdzielczosci" (user, doprecyzowanie #2: pierwsza proba - sam floor
     * clamp() - dzialala tylko tuz przy 992px, bo % (32%) juz przebijal
     * stary floor przy szerszych "compact" oknach typu 1200-1700px). Cala
     * kolumna PRZELICZONA razy 0.85 (min/%/max), TA SAMA media query co
     * radiusy/rozmiary wyzej/nizej - wezsza kolumna obowiazuje w CALYM
     * zakresie trybu compact, nie tylko na samym dnie.
     */
    .btx-stamp-cockpit
    {
        grid-template-columns: clamp(280px, 24%, 360px) 1fr clamp(306px, 27.2%, 391px);
    }

    .btx-stamp-canvas-header
    {
        padding: var(--btx-tile-padding) !important;
    }

    .btx-stamp-controls
    {
        min-height: 130px !important;
    }

    .btx-stamp-controls-grid
    {
        gap: var(--btx-spacing-sm) !important;
    }

    /*
    Doprecyzowanie (user: "nie lepiej troche pomniejszyc elementow?" -
    zamiast polegac WYLACZNIE na scrollu poziomym z fixu wyzej). Kazdy
    zaoszczedzony piksel tutaj to piksel mniej potrzebny w scrollu -
    steppery/B-I scisniete z 38/40px do 30/34px (wciaz >=30px, bezpieczny
    cel dotykowy), trigger czcionki dostaje mniejszy padding/font (JS
    ".btx-stamp-custom-select" i tak mierzy SWOJA naturalna szerokosc na
    zywo z renderowanego DOM - mniejszy font/padding tutaj automatycznie
    zmniejsza to co JS wymusi, bez dotykania samego JS).
    */
    .btx-stamp-stepper,
    .btx-stamp-bi-group,
    .btx-stamp-bi-btn,
    .btx-stamp-align-row,
    .btx-stamp-align-btn,
    .btx-stamp-pos-btn
    {
        height: 34px !important;
    }

    .btx-stamp-align-btn
    {
        width: 34px !important;
    }

    .btx-stamp-stepper-btn
    {
        width: 26px !important;
        height: 26px !important;
        margin: 4px !important;
    }

    .btx-stamp-bi-btn
    {
        width: 34px !important;
    }

    .btx-stamp-stepper-val
    {
        font-size: 10px !important;
    }

    /*
    Podwojna klasa w selektorze (nie sam ".btx-stamp-custom-select-value-
    row") - ta sama regula bazowa (linia ~1269, "height:40px !important")
    siedzi NIZEJ w tym pliku, wiec przy rownej specyficznosci i obu
    !important wygrywalaby kolejnoscia w kaskadzie (zmierzone: wysokosc
    zostawala 40px mimo tej reguly). Wyzsza specyficznosc gwarantuje
    wygrana niezaleznie od kolejnosci.
    */
    .btx-stamp-controls-grid .btx-stamp-custom-select-value-row,
    .btx-stamp-canvas-header-colors .btx-stamp-custom-select-value-row,
    .btx-stamp-rail .btx-stamp-custom-select-value-row
    {
        height: 34px !important;
        padding: 6px 10px !important;
        font-size: var(--btx-text-sm) !important;
    }

    /*
    Lista opcji tez wchodzi do pomiaru JS (".btx-stamp-custom-select"
    rebuild() liczy naturalna szerokosc z NAJSZERSZEJ z (wiersz wartosci,
    KAZDA opcja)) - najdluzsza opcja ("Times New Roman (Tinos)"/"Myriad
    Pro (Arimo)") wymuszala szerokosc triggera nawet po zmniejszeniu
    samego triggera wyzej. Ten sam mniejszy rozmiar tu = mniejszy
    wymuszony total.
    */
    .btx-stamp-custom-select-option
    {
        font-size: var(--btx-text-sm) !important;
        padding: 7px 8px !important;
    }

    .btx-stamp-custom-select-options-inner
    {
        overflow: hidden !important;
    }

    /*
    Doprecyzowanie #2 (user: "tylko steppery sie zmienily, inputy i
    buttony tez pomniejsz") - reszta ujednoliconej 40px siatki kontrolek
    (rundy z wczesniej w tej samej sesji) zostala pominieta w pierwszym
    przebiegu trybu "compact", przez co wygladala niespojnie obok juz
    zmniejszonych steppera/B-I. Wszystko sprowadzone do tych samych 34px
    co reszta.
    */
    /*
    User (po probie z celowo mniejszymi strzalkami - "a to strzalki sa za
    duze" - cofnietej ponizej): "maja miec takie same ksztalty i radiusy
    dokladnie takie same" - strzalki (".btx-stamp-controls-nav") i numerki
    (".btx-stamp-controls-dot") wracaja do TEGO SAMEGO rozmiaru co
    ".btx-stamp-bi-btn" (34px w tym trybie) - identyczny rozmiar + juz
    wspolny token promienia (--btx-radius-control) razem gwarantuja
    identyczny ksztalt, bez zgadywania proporcji.
    */
    .btx-stamp-brand-filter-btn,
    .btx-stamp-add-line,
    .btx-stamp-controls-nav,
    .btx-stamp-controls-dot,
    .btx-stamp-line-action,
    .btx-stamp-line-num
    {
        height: 34px !important;
    }

    .btx-stamp-controls-nav,
    .btx-stamp-controls-dot,
    .btx-stamp-line-action,
    .btx-stamp-line-num
    {
        width: 34px !important;
    }

    /*
    Input wersu dziedziczy "height:40px !important" z globalnej
    ".btx-tile input[type='text']" (bento-account.css) - ten sam problem
    specyficznosci co przy fixie "pill shape" wczesniej w tej sesji, stad
    ten sam dluzszy selektor + !important zeby bezpiecznie przebic.
    */
    .btx-stamp-panel .btx-stamp-lines input.btx-stamp-line-input
    {
        height: 34px !important;
    }
}

@media (min-width: 768px) and (max-width: 991px)
{
    .btx-stamp-cockpit
    {
        width: 92.5vw !important;
        max-width: 92.5vw !important;
        margin-left: calc(50% - 46.25vw) !important;
        box-sizing: border-box !important;
    }
}

/*
2026-08-31, user: "mozemy miec wieksza szerokosc, ustaw... szerokosc
poprostu jak elementy na innych stronach" - ten sam "vw breakout" full-
bleed wzorzec juz istnieje dla tabletu (768-991px, wyzej) i desktopu
(992px+, patrz na gorze pliku) - PRAWDZIWY mobile (<768px) nigdy nie
dostal wlasnej wersji, wiec ".btx-stamp-cockpit" tam po prostu dziedziczyl
zwykla szerokosc kolumny ".container" (dziedziczonej z rdzenia motywu,
padding ~12px z kazdej strony) - karta (".btx-stamp-mobile-card") DOKLADAL
do tego WLASNY margines 16px, dajac razem ~28px z kazdej strony zamiast
standardowych 16px, ktorych uzywaja WSZYSTKIE inne elementy w sklepie
(zmierzone live na biurotex.eu: ".container{padding:16px}", karty typu
".btx-category-card" siegaja dokladnie do tej krawedzi). Fix: "width:100vw"
+ "margin-left:calc(50% - 50vw)" - standardowy, precyzyjny full-bleed
(kokpit wychodzi DOKLADNIE na krawedzie realnego viewportu, niezaleznie
od tego ile paddingu ma akurat ".container" rdzenia motywu) - jedyny
margines ktory zostaje to WLASNY 16px karty, dokladnie jak inne strony.
*/
@media (max-width: 767px)
{
    .btx-stamp-cockpit
    {
        width: 100vw !important;
        max-width: 100vw !important;
        margin-left: calc(50% - 50vw) !important;
        box-sizing: border-box !important;
    }
}

/*
Stopka przebudowana (2026-08-27, user): rzad 1 = Zatwierdz (lewo) + Cena
(prawo), rzad 2 = Dodaj do koszyka (pelna szerokosc, wlasny rzad ponizej).
*/
.btx-stamp-panel-footer
{
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-sm);
    padding-top: var(--btx-spacing-sm);
    /* "--btx-neutral-300" (bylo "--btx-border-color"=neutral-200, jasniejszy) - user 2026-08-28: "dolny separator nad cena zrob taki sam" jak pozostale 2 w module (.btx-stamp-divider, rail-section-header) */
    border-top: 1px solid var(--btx-neutral-300);
}

.btx-stamp-panel-footer-top
{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--btx-spacing-sm);
}

/*
Cena powiekszona i pokolorowana jak w module druku (user: "cene powieksz
i zrob w kolorze takim jak np w wydrukach") - ten sam wzorzec co
".btx-print-queue-total" w btxprintconfigurator (40px/900/warning),
zamiast dawnych "--btx-text-h4"/800/text-primary.
*/
.btx-stamp-bar-price
{
    font-size: 40px;
    font-weight: 900;
    color: var(--btx-color-warning, #f59e0b);
    line-height: 1;
    letter-spacing: -0.02em;
    white-space: nowrap;
}

@media (min-width: 992px) and (max-width: 1700px),
       (min-width: 992px) and (max-height: 820px)
{
    .btx-stamp-bar-price
    {
        font-size: 30px;
    }
}

/*
Wlasny styl (NIE globalne ".btx-btn-primary"/".btx-btn-secondary" -
user: "oba te buttony sa pill shape a maja byc prostokatne jak reszta na
tej str") - prostokatny "--btx-radius-control" jak kazda inna kontrolka
modulu, zamiast pelnego promienia pigulki z globalnego systemu.

Zatwierdz = glowny CTA na starcie (user: "zatwierdz musi byc glownym
cta"), Dodaj do koszyka ukryty do momentu zatwierdzenia. Po kliknieciu
(".btx-stamp-cockpit.is-locked", patrz lockStampEditor()/
unlockStampEditor()) role sie ZAMIENIAJA - Zatwierdz staje sie
drugorzednym "Edit design", Dodaj do koszyka (teraz pelna szerokosc,
wlasny rzad) przejmuje wyglad glownego CTA (user: "dopiero dodaj do
koszyka ma sie stac glownym cta jak kliknie sie zatwierdz").
*/
.btx-stamp-confirm,
.btx-stamp-cta
{
    height: 40px;
    padding: 0 20px;
    border-radius: var(--btx-radius-control);
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    cursor: pointer;
    transition: background var(--btx-transition-fast, 0.15s), border-color var(--btx-transition-fast, 0.15s), color var(--btx-transition-fast, 0.15s);
}

.btx-stamp-confirm
{
    flex-shrink: 0;
    border: none;
    background: var(--btx-color-primary);
    color: #ffffff;
}

/*
2026-08-31, user (mobile): "po zatwierdzeniu button zatwierdz sie zmienia
w 2 buttony dodaj do koszyka i edytuj (icon)" - ikona ukryta WSZEDZIE
domyslnie (desktop zostaje czysto tekstowy, jak zawsze byl - odkrywana
TYLKO w mobilnym, zatwierdzonym stanie, patrz sekcja "Wersja mobile/
tablet" nizej w pliku).
*/
.btx-stamp-confirm-edit-icon
{
    display: none;
}

.btx-stamp-cta
{
    width: 100%;
    /*
    Prawdziwa przyczyna "niewidocznosci" (user) to nie byl sam border -
    "--btx-bg-tile" (#ececed) to niemal ten sam szary co tlo panelu
    (".btx-tile"), wiec caly przycisk zlewal sie z otoczeniem. Teraz
    dokladnie taki styl jak WIEKSZOSC przyciskow w Kreatorze (user:
    "ustaw taki styl jak ma wiekszosc buttonow" - solidne biale tlo,
    17 innych miejsc w tym pliku uzywa "#ffffff", nie "--btx-bg-tile"),
    "--btx-border-input" (ciemniejszy) zostaje.
    */
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-secondary);
}

.btx-stamp-cockpit.is-locked .btx-stamp-confirm
{
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-secondary);
}

.btx-stamp-cockpit.is-locked .btx-stamp-cta
{
    border: none;
    background: var(--btx-color-primary);
    color: #ffffff;
}

@media (hover: hover)
{
    .btx-stamp-confirm:not(:disabled):hover,
    .btx-stamp-cockpit.is-locked .btx-stamp-cta:not(:disabled):hover
    {
        background: var(--btx-color-primary-hover);
    }

    .btx-stamp-cta:not(:disabled):hover,
    .btx-stamp-cockpit.is-locked .btx-stamp-confirm:not(:disabled):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-confirm:not(:disabled):active,
.btx-stamp-cta:not(:disabled):active
{
    transform: scale(0.97);
}

.btx-stamp-cta:disabled,
.btx-stamp-confirm:disabled
{
    opacity: 0.4;
    cursor: not-allowed;
}

/*
Krok 7: tryb "zatwierdzone" (user: "zapisywanie projektu takie
zatwierdzenie ktore wylacza miarki i podswietlenie wiersza i wylacza
edycje", doprecyzowanie: "Dodaj do koszyka" dopiero po zatwierdzeniu) -
"pointer-events:none" na CALYCH strefach edycji zamiast recznego
"disabled" na kazdym pojedynczym elemencie osobno. Wybrane celowo - w tych
strefach sa RAZEM natywne kontrolki (input/select/button, wspieraja
"disabled") I customowe widgety bez natywnego stanu disabled (uchwyt
przeciagania numerka wersu, customowy dropdown czcionki/koloru, przyciski
pozycji logo) - pojedyncze "disabled" omineloby te drugie, blanket
"pointer-events" gwarantuje kompletnosc bez wymieniania kazdego typu
kontrolki z osobna. Opacity jako dodatkowa, wizualna wskazowka "zablokowane".
*/
.btx-stamp-cockpit.is-locked .btx-stamp-canvas-header-colors
{
    pointer-events: none;
    opacity: 0.55;
}

/*
User: "te 2 elementy sie nie blokuja wizualnie" (dropdown czcionki +
"Przejdz do kategorii") - ".btx-stamp-custom-select-panel" (WSPOLNA klasa
dla WSZYSTKICH 4 customowych selectow: czcionka/kategoria/kolor automatu/
kolor tuszu) ma wlasny "z-index:100" - mimo ze element jest "position:
static" (teoretycznie z-index bez pozycjonowania nie powinien miec
znaczenia), empirycznie (zweryfikowane elementFromPoint() + testowa
czerwona warstwa) i tak wygrywa z warstwa "::after" powyzej (kafle
rail/controls). Opacity bezposrednio NA TYM elemencie omija caly problem
stackingu (dziala niezaleznie od z-index, bo redukuje kanal alfa calego
poddrzewa jako grupe) - bezpieczne, bo pod spodem i tak jest juz w pelni
nieprzezroczysty kafel (nie strona), wiec nie wraca bug "siatka przebija".
*/
.btx-stamp-cockpit.is-locked .btx-stamp-custom-select-panel
{
    opacity: 0.55;
}

/*
User: "jak sa narzedzia zlockowane to niech to sie nie robi
przezroczyste bo siatka przebija" - "rail"/"controls"/"panel" sa CALYMI
".btx-tile" (wlasne, nieprzezroczyste tlo "--btx-bg-tile"), wiec dawny
"opacity:0.55" na CALYM kaflu przenikal przez WLASNE tlo kafla i
odslaniat kropkowana siatke tla strony pod spodem (widoczne jako
"dziurawy" efekt). Fix: kafel zostaje w pelni nieprzezroczysty,
zamiast tego ciemniejsza/przyciemniona kropka wizualna to osobna
warstwa "::after" (position:absolute, TEN SAM kolor tla co kafel -
"var(--btx-bg-tile)" - w 55% kryciu) NA WIERZCHU tresci - efekt "zawartosc
kafla przyblakla", bez ujawniania czegokolwiek za kaflem. "position:relative"
+ "overflow:hidden" na ".btx-tile" (bazowa regula) przycina warstwe do
zaokraglonych rogow za darmo.
*/
.btx-stamp-cockpit.is-locked .btx-stamp-rail,
.btx-stamp-cockpit.is-locked .btx-stamp-controls,
.btx-stamp-cockpit.is-locked .btx-stamp-panel,
/*
2026-08-31, rozbicie na 3 panele mobile - ".btx-stamp-panel" na mobile
jest teraz PUSTA/"display:none" (tresc zyje w "#btx-stamp-mobile-panel2"/
"#btx-stamp-mobile-panel3"), wiec bez tego dopisku przyciemnienie po
zatwierdzeniu przestaloby dzialac na mobile - dodane tu, nie w osobnej
regule scoped do mobile, bo dziala identycznie (position:relative +
overflow:hidden z bazowego ".btx-tile" nie dotyczy tych 2 wrapperow -
patrz ich wlasna regula ".btx-stamp-mobile-subpanel" nizej w sekcji
mobile, ktora dopisuje "position:relative").
*/
.btx-stamp-cockpit.is-locked .btx-stamp-mobile-subpanel
{
    pointer-events: none;
}

.btx-stamp-cockpit.is-locked .btx-stamp-rail::after,
.btx-stamp-cockpit.is-locked .btx-stamp-controls::after,
.btx-stamp-cockpit.is-locked .btx-stamp-panel::after,
.btx-stamp-cockpit.is-locked .btx-stamp-mobile-subpanel::after
{
    content: '';
    position: absolute;
    inset: 0;
    background: var(--btx-bg-tile);
    opacity: 0.55;
    z-index: 1;
    pointer-events: none;
}

/*
Stopka prawego kafelka (cena + Zatwierdz/Dodaj do koszyka) MA zostac
normalna mimo ze rodzic ".btx-stamp-panel" jest zablokowany - "pointer-events:
auto" odzyskuje klikalnosc (dziecko nadpisuje "none" rodzica), a
"position:relative"+"z-index" wyzszy niz warstwa "::after" (z-index:1)
podnosi ja WIZUALNIE ponad przyciemnienie, zeby nie byla przyblakla.
*/
.btx-stamp-cockpit.is-locked .btx-stamp-panel-footer
{
    pointer-events: auto;
    position: relative;
    z-index: 2;
}

.btx-stamp-cockpit.is-locked .btx-stamp-dim-overlay
{
    display: none;
}

/*
Scroll NIE na samym .btx-tile (bordery zaokraglone --btx-radius-2xl) tylko
na wewnetrznym .btx-stamp-scroll - pasek przegladarki nie respektuje
border-radius rodzica w wielu silnikach, wiec przy overflow wprost na
zaokraglonym kaflu scrollbar wystawal poza gorny naroznik (zglosil
uzytkownik, widoczne w zrzucie ekranu). Wciecie z paddingu kafla
wystarcza, zeby pasek zostal w srodku.

Fade gorny/dolny - DRUGA proba (pierwsza, prosty mask-image na calym
elemencie, blakla tez wlasny pasek przewijania - ::-webkit-scrollbar jest
czescia tej samej warstwy co reszta). Fix: DWIE warstwy maski nakladane na
siebie (mask-image to lista gradientow, jak background-image) - pierwsza
(szerokosc do "prawy pasek minus 9px") robi pionowy fade tylko na obszarze
kart, druga (waski pasek 9px po prawej, tam gdzie realnie siedzi
scrollbar) jest w calosci NIEPRZEZROCZYSTA, wiec ten skrawek nigdy nie
blednie niezaleznie od scrolla.
*/
.btx-stamp-scroll
{
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /*
    "scrollbar-gutter: stable" - BEZ tego caly ponizszy przelicznik
    margin/padding zakladal ze pasek przewijania ZAWSZE jest realnie
    wyrenderowany (rail z duza liczba kart zwykle tak ma), ale prawy
    panel czesto MIESCI sie bez przewijania - wtedy przegladarka nie
    rezerwuje miejsca na pasek wcale, wiec "cofniecie" tresci ponizej
    ladowalo o ~13px za blisko prawej krawedzi (user: "prawy padding w
    prawym kafelku jest zamaly"). "stable" wymusza STALA rezerwacje tego
    miejsca niezaleznie od tego czy pasek faktycznie sie pokazuje, wiec
    ponizsza matematyka dziala identycznie w obu przypadkach.
    */
    scrollbar-gutter: stable;
    /*
    Karty maja siegac do naturalnej granicy 24px paddingu kafla
    ".btx-stamp-rail" (bez wlasnego dodatkowego wciecia), a pasek
    przewijania (13px) ma wisiec dokladnie na SRODKU tego paddingu (user:
    "karty produktow rozszerz do granicy paddingu kafelka a slider scrolla
    ma byc idealnie w polowie paddingu jakby na nim"). Technika: ten box
    jest SZERSZY niz wizualny kontener (ujemny margin-right wypycha go w
    padding rodzica), a padding-right o tej samej wartosci cofa faktyczna
    tresc (karty) z powrotem do normalnej granicy - wiec karty tego
    rozszerzenia "nie widza", tylko sam box (i przez to natywny pasek,
    ktory zawsze renderuje sie dokladnie na prawej krawedzi swojego boxu).
    Wzor margin: E = (padding_kafla + szerokosc_paska) / 2 = (24 + 13) / 2
    = 18.5px - dokladnie tyle, zeby pasek (flush do prawej krawedzi
    rozszerzonego boxu) wypadl w idealnym srodku 24px paddingu.
    Wzor padding: pasek DODATKOWO zabiera 13px z tresci (osobna warstwa,
    NIE to samo co margin/padding boxu) - zeby karty mimo to siegaly do
    normalnej granicy 24px, padding-right = E - szerokosc_paska =
    18.5 - 13 = 5.5px (nie E, jak przy pierwszej, blednej probie).
    */
    margin-right: -18.5px;
    padding-right: 5.5px;
    /*
    padding-top/bottom = MUSI byc >= dystansu zanikania w masce ponizej
    (10px). Bez tego w spoczynku (scroll na samej gorze) fade i tak lekko
    nachodzil na gorna krawedz pierwszej karty, bo maska nie wie nic o
    pozycji scrolla - zawsze zaczyna blaknac od 0px swojego wlasnego
    pudelka. Padding = pierwsza karta zaczyna sie DOPIERO tam, gdzie
    gradient juz w pelni doszedl do nieprzezroczystosci (zglosil
    uzytkownik, widoczne na zrzucie ekranu).
    */
    padding-top: 10px;
    padding-bottom: 10px;
    scrollbar-width: thin;
    scrollbar-color: var(--btx-neutral-400) transparent;
    /*
    Druga warstwa maski (zawsze niematowa, 13px) musi pokrywac PELNA
    szerokosc paska (13px), nie tylko widoczny kciuk (11px) - inaczej fade
    gorny/dolny lekko przycinalby brzegi toru przewijania. 13px = ta sama
    wartosc co "::-webkit-scrollbar { width: 13px }" nizej.
    */
    -webkit-mask-image:
        linear-gradient(to bottom, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%),
        linear-gradient(#000, #000);
    -webkit-mask-size: calc(100% - 13px) 100%, 13px 100%;
    -webkit-mask-position: left top, right top;
    -webkit-mask-repeat: no-repeat, no-repeat;
    mask-image:
        linear-gradient(to bottom, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%),
        linear-gradient(#000, #000);
    mask-size: calc(100% - 13px) 100%, 13px 100%;
    mask-position: left top, right top;
    mask-repeat: no-repeat, no-repeat;
}

/*
Kciuk paska (11px widoczny) wewnatrz 13px toru - "border:1px solid
transparent" + "background-clip:padding-box" na thumbie tworzy 1px
odstep z kazdej strony (13-2=11px), zamiast probowac przesuwac caly
natywny pasek przegladarki (niemozliwe/niepewne cross-browser).
*/
.btx-stamp-scroll::-webkit-scrollbar
{
    width: 13px;
}

.btx-stamp-scroll::-webkit-scrollbar-track
{
    background: transparent;
}

.btx-stamp-scroll::-webkit-scrollbar-thumb
{
    background: var(--btx-neutral-400);
    background-clip: padding-box;
    border: 1px solid transparent;
    border-radius: var(--btx-radius-pill);
}

/*
szyna modeli (lewa) - wysokosc narzucona przez siatke (rail rozciaga sie
na wiersze canvas+controls). Sam kafel NIE scrolluje (zostaje przy
domyslnym .btx-tile { overflow: hidden }, ktore poprawnie tnie do
zaokraglonych rogow) - scrolluje tylko .btx-stamp-scroll w srodku.
*/
.btx-stamp-rail
{
    grid-area: rail;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/*
Padding kafla NIE ma sie zmniejszac pod pasek przewijania (user: "slider
scrolla ma nie affectowac paddingu") - wczesniej ".btx-stamp-rail" mial
"padding-right:12px" zamiast standardowych 24px z ".btx-tile", co robilo
caly kafel wizualnie nierowny wzgledem sasiadow, a etykieta ponizej musiala
to na sile kompensowac wlasnym "padding-right". Teraz kafel trzyma pelne,
rowne 24px na kazdej stronie jak kazdy inny ".btx-tile" - miejsce dla
paska przewijania robi WYLACZNIE ".btx-stamp-scroll" (wlasny padding-right
8px, patrz nizej), w srodku kafla, wiec zewnetrzna krawedz zostaje nietknieta.
*/
.btx-stamp-section-label
{
    font-size: var(--btx-text-sm);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--btx-text-tertiary);
    margin: 0 0 var(--btx-spacing-sm);
}

.btx-stamp-section-label-row
{
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.btx-stamp-section-label-row .btx-stamp-section-label
{
    margin-bottom: 0;
}

/*
 * Mniejszy, przygaszony wariant .btx-stamp-bi-btn - to narzedzie
 * debugowe/QA (przywrocone: user "przywroc button pobierania ale taki
 * icon"), nie ma konkurowac wizualnie z realnymi kontrolkami.
 */
/* Przeniesiony z naglowka "Text lines" do prawego dolnego rogu canvasu (user 2026-08-27) - ten sam wzorzec pozycjonowania co ".btx-stamp-canvas-zoom-badge" (przeciwny rog), tlo/ramka dodane zeby bylo widoczne na kropkowanym tle canvasu zamiast zlewac sie z niim jak w spokojnym miejscu przy etykiecie. Rozdzielony na 2 przyciski (2026-08-28, SVG debug + PNG watermark) - wrapper trzyma pozycjonowanie, oba przyciski zostaja prostymi elementami w rzedzie obok siebie. */
.btx-stamp-download-buttons
{
    position: absolute;
    bottom: var(--btx-spacing-sm);
    right: var(--btx-spacing-sm);
    z-index: 2;
    display: flex;
    gap: 6px;
}

.btx-stamp-download-svg-btn
{
    width: 28px;
    height: 28px;
    border: 1px solid var(--btx-border-color);
    border-radius: var(--btx-radius-sm);
    background: var(--btx-bg-input);
    color: var(--btx-text-tertiary);
}

.btx-stamp-download-svg-btn .btx-stamp-icon
{
    width: 16px;
    height: 16px;
}

@media (hover: hover)
{
    .btx-stamp-download-svg-btn:hover
    {
        color: var(--btx-text-primary);
    }
}

.btx-stamp-download-svg-btn:active
{
    transform: scale(0.9);
}

/*
Filtr marki (Wszystko/Trodat/Colop) - ten sam wzorzec pigulek co
".btx-stamp-pos-btn" (pozycja logo) nizej w tym pliku - sztywny/aktywny
stan przez ".is-active", nie osobny nowy komponent.

Poprzednia wersja miala "padding-right:22px" (zawezala rzad do szerokosci
kart automatow, nie calego kafla) - user cofnal ta decyzje: "te buttony
nad to na cala szerokosc dropdown tez" - teraz pelna szerokosc kafla, tak
samo jak dropdown ("Jump to category...") ponizej, oba rzedy konczą sie w
tym samym miejscu.
*/
.btx-stamp-brand-filter
{
    display: flex;
    gap: 6px;
    margin-bottom: var(--btx-spacing-sm);
}

.btx-stamp-brand-filter-btn
{
    flex: 1;
    height: 40px;
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-color);
    background: #ffffff;
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    color: var(--btx-text-secondary);
    cursor: pointer;
}

.btx-stamp-brand-filter-btn.is-active
{
    background: var(--btx-color-primary);
    color: #ffffff;
    border-color: var(--btx-color-primary);
}

/*
Brakujacy hover/active (audyt spojnosci 2026-08-28, user: "zacznijmy od
audytu odstepow miedzy elementami, hoverow i clickow") - ten sam wzorzec
co ".btx-stamp-pos-btn" (identyczna struktura: bialy bg, border, .is-active
wypelnienie primary) - bg-input na hover, border-hover+scale na active,
":not(.is-active)" zeby nie przebijac juz podswietlonego filtra.
*/
@media (hover: hover)
{
    .btx-stamp-brand-filter-btn:not(.is-active):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-brand-filter-btn:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.95);
}

/*
Dropdown-nawigacja do sekcji podkategorii (user: "dodac wybor pod kat...
zmiana kat w dropdownie powyzej powoduje scroll listy do danej podkat",
potem "styl dropdowna taki sam jak inne dropdowny", potem "zmniejsz tan
input i dodaj tam ikonke help... zamien wiersze kolejnoscia") - dropdown
dzieli teraz rzad z przyciskiem pomocy (samouczek - na razie tylko
placeholder, tresc dojdzie pozniej) zamiast zajmowac cala szerokosc sam.
Kolejnosc wierszy w szynie ZAMIENIONA: ten rzad (kategoria+help) teraz
NAD filtrem marki (Wszystkie/Trodat/Colop), odwrotnie niz poprzednio.
*/
.btx-stamp-category-row
{
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: var(--btx-spacing-sm);
}

.btx-stamp-category-row .btx-dropdown-container.btx-stamp-custom-select
{
    flex: 1;
    min-width: 0;
}

/*
"border-color" na "--btx-border-input" (nie "--btx-border-color") -
dokladnie taki sam odcien co ramka sasiadujacego dropdownu
(".btx-stamp-custom-select-panel" uzywa "--btx-border-input"), user:
"button ma cos z borderem nie tak" - "--btx-border-color" bylo widocznie
jasniejsze/slabsze niz sasiad, mimo ze oba wygladaly "poprawnie" osobno.
*/
.btx-stamp-category-help-btn
{
    flex-shrink: 0;
    /*
    40px - taki sam rozmiar jak reszta kontrolek kokpitu (steppery, B/I
    itp.). Pierwsza proba (wlasny staly promien 10px na 34px) user
    odrzucil - "powiekszyc do rozmiaru jak reszta" zamiast zmniejszac
    promien. Teraz 40px + "--btx-radius-control" (16px) daje ta sama
    proporcje co sasiednie kontrolki full-size.
    */
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-tertiary);
    cursor: pointer;
}

.btx-stamp-category-help-btn .btx-stamp-icon
{
    width: 18px;
    height: 18px;
}

/*
Hover/active ujednolicone (2026-08-28, user: "button help nie ma efektow")
- byly, ale bardzo slabe (tylko color+border na hover, sam scale bez tla
na active) - niewidoczne na tle reszty modulu po audycie spojnosci.
Dokladnie ten sam jezyk co brand-filter-btn/pos-btn/align-btn (bg-input
hover, border-hover+scale active).
*/
@media (hover: hover)
{
    .btx-stamp-category-help-btn:hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
        color: var(--btx-text-primary);
    }
}

.btx-stamp-category-help-btn:active
{
    background: var(--btx-border-hover);
    color: var(--btx-text-primary);
    transform: scale(0.9);
}

.btx-stamp-rail-section-header
{
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--btx-text-xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--btx-text-tertiary);
    padding: var(--btx-spacing-sm) 4px 2px;
    scroll-margin-top: 4px;
}

/*
Tytul kategorii wysrodkowany, z liniami-separatorami po obu stronach
(user: "te tytuly sekcji, kategorii dajj na srodku a po obu jego str
dodaj liknie"). JS ustawia zwykly "textContent" (nie innerHTML), wiec
tekst jest zwyklym anonimowym flex-itemem obok tych dwoch pseudo-elementow
- "flex:1" na obu rozciaga linie rownomiernie po obu stronach.
*/
.btx-stamp-rail-section-header::before,
.btx-stamp-rail-section-header::after
{
    content: '';
    flex: 1;
    /* "1px" (bylo 2px, user 2026-08-28: "separatory sa za grube i w prawym i lewym panelu") */
    height: 1px;
    /* --btx-border-color (neutral-200) byl ledwo widoczny - neutral-300, ten sam token co --btx-border-hover/--btx-border-input */
    background: var(--btx-neutral-300);
}

.btx-stamp-rail-section-header:first-child
{
    padding-top: 2px;
}

.btx-stamp-rail-items
{
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-xs);
}

.btx-stamp-rail-item
{
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.05);
    border-radius: var(--btx-radius-lg);
    padding: var(--btx-spacing-xs);
}

.btx-stamp-rail-item.is-selected
{
    background: #ffffff;
    border-color: var(--btx-color-primary);
}

.btx-stamp-rail-item-main
{
    display: flex;
    align-items: stretch;
    gap: var(--btx-spacing-sm);
    cursor: pointer;
}

/*
"max-width" dodany (user: "zawartosc kafelkow po lewej musimy tez
pomniejszyc" - zauwazone na monitorze 2K/2560px). Kolumna szyny sama w
sobie jest juz plynna (patrz "clamp()" na ".btx-stamp-cockpit" u gory
pliku, 280-352px), ale "40%" liczone z JEJ maksimum (352px) dawalo
miniaturki do ~141px - bez gornego ograniczenia rosly wraz z kolumna bez
konca. "max-width" nie koliduje z "width:40%" (przegladarka bierze
mniejsza z dwoch), wiec na waskich oknach nadal skaluje sie plynnie w
dol, tylko gora jest teraz spiete.
*/
.btx-stamp-rail-thumb
{
    width: 40%;
    max-width: 96px;
    aspect-ratio: 1;
    border-radius: var(--btx-radius-md);
    object-fit: cover;
    flex-shrink: 0;
}

/*
Placeholder dla produktow bez zdjecia (user: "zdjecia nie ma produkt") -
".btx-stamp-rail-thumb" na "<div>" zamiast "<img>" (dziedziczy rozmiar/
promien z reguly wyzej), wypelnione ikonka pieczatki wysrodkowana na
lekko przygaszonym tle zamiast pustego/zlamanego "<img>" bez "src".
*/
.btx-stamp-rail-thumb-placeholder
{
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--btx-bg-input);
    color: var(--btx-text-tertiary);
}

.btx-stamp-rail-thumb-placeholder svg
{
    width: 44%;
    height: 44%;
}

.btx-stamp-rail-right
{
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--btx-spacing-xs);
}

.btx-stamp-rail-text
{
    min-width: 0;
}

/* --btx-text-sm(12px)→--btx-text-xs(11px), ten sam powod co przy miniaturce wyzej - drobne pomniejszenie tresci karty na wszystkich szerokosciach. */
.btx-stamp-rail-shape
{
    font-size: var(--btx-text-xs);
    font-weight: 800;
    text-transform: uppercase;
    color: var(--btx-text-tertiary);
}

/* clamp() plynny (13-14px, ten sam powod/mechanizm co tytul canvasu wyzej w pliku) - lekko mniejszy niz poprzednie sztywne 15px na calej szerokosci, nie tylko w oknie "compact". */
/*
Marquee w petli po najechaniu (user: "takie samo przejezdzanie zrob w
tytulach w lewym panelu ale bez redirecta") - identyczny wzorzec/helper
JS co tytul na canvasie ("setupMarqueeText()"), ale BEZ klikalnosci/
przejscia na produkt (to bylo zgloszenie tylko dla tytulu canvasu, tutaj
user wyraznie zastrzegl "bez redirecta"). Wczesniej dlugie nazwy po prostu
lamaly sie na 2 linie (zwykle zawijanie tekstu) - teraz jedna linia,
przycieta, z przewijaniem na hover.
*/
.btx-stamp-rail-name
{
    font-size: clamp(13px, 11.93px + 0.11vw, 14px);
    font-weight: 700;
    color: var(--btx-text-primary);
    margin-top: 1px;
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
}

/* Gradientowe zanikanie na krawedziach - ten sam wzorzec/uzasadnienie (w tym korekta "fade tylko z prawej w spoczynku, oba boki dopiero na hover") co ".btx-stamp-canvas-header-model.is-scrollable" wyzej w pliku, tylko wezszy fade (mniejszy font). */
.btx-stamp-rail-name.is-scrollable
{
    -webkit-mask-image: linear-gradient(to right, black, black calc(100% - 20px), transparent);
    mask-image: linear-gradient(to right, black, black calc(100% - 20px), transparent);
}

@media (hover: hover)
{
    .btx-stamp-rail-item:hover .btx-stamp-rail-name.is-scrollable
    {
        -webkit-mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
        mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
    }
}

.btx-stamp-rail-name-track
{
    display: inline-flex;
    white-space: nowrap;
}

.btx-stamp-rail-name-track span
{
    padding-right: 40px;
}

/*
Trigger zmieniony z ":hover" na samej wazkiej nazwie na hover CALEJ karty
produktu (user: "slider tytulu ma byc po hoverze na cala karte prod") -
uzytkownik moze najechac gdziekolwiek na karte (miniaturke, ksztalt,
wymiary), nie tylko na sam, waski pasek nazwy, zeby zobaczyc przewijanie.
*/
@media (hover: hover)
{
    .btx-stamp-rail-item:hover .btx-stamp-rail-name.is-scrollable .btx-stamp-rail-name-track
    {
        animation: btx-stamp-select-marquee 6s linear infinite;
    }
}

.btx-stamp-rail-dims
{
    font-size: var(--btx-text-xs);
    color: var(--btx-text-secondary);
    margin-top: 1px;
}

.btx-stamp-rail-color
{
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
}

.btx-stamp-rail-swatch
{
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.btx-stamp-rail-color-empty
{
    font-size: var(--btx-text-sm);
    color: var(--btx-text-tertiary);
}

/* canvas (srodek) */
/*
"!important" niezbedny (user: "kafel z canvasem ma za duze marginesy,
zrob takie jak w bocznych kaflach") - baza ".btx-tile" narzuca padding
24px na wszystkich 4 stronach TEZ z "!important" (patrz komentarz przy
".btx-stamp-rail" nizej), wiec zwykle "padding:0" tutaj bylo cicho
ignorowane - canvas-wrap mial cala sciezke: 24px (przebijajacy sie
padding tile) + 16px (wlasny margines ".btx-stamp-canvas-surface" na
dole/bokach) = ~40px odstepu od krawedzi kafla do samego pola canvasu,
zamiast zamierzonych samych 16px zarzadzanych recznie przez surface
(naglowek i tak ma WLASNY padding, patrz ".btx-stamp-canvas-header").
*/
.btx-stamp-canvas-wrap
{
    grid-area: canvas;
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0 !important;
}

/*
"flex-wrap:wrap" (2026-08-21, koniec sesji, user: "na 1920/1440 elementy
sie nie mieszcza, tytul zachodzi na kolory") - przy waskiej kolumnie
canvasu miniaturka(120px, sztywna) + kolory(sztywne, "flex-shrink:0"
nizej) + tytul hero(40px) razem nie mieszcza sie w jednym rzedzie. Bez
wrapowania caly balast spadal na tytul (jedyny element z "flex-shrink"
dozwolonym), ktory scisniety ponizej wlasnej naturalnej szerokosci slow
zaczynal sie lamac na 2 linie i wizualnie zachodzil na sasiadow. Teraz
gdy nie ma miejsca, kolory po prostu spadaja NIZEJ na wlasny rzad zamiast
wpychac sie na sile obok - zero nachodzenia tekstu niezaleznie od
szerokosci ekranu.
*/
.btx-stamp-canvas-header
{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--btx-spacing-xs) var(--btx-spacing-sm);
    padding: var(--btx-tile-padding);
}

/*
Bez "min-width:0" domyslny "min-width:auto" flex-itema to szerokosc
najdluzszego SLOWA (tekst domyslnie sie nie lamie w polslowia) - to jest
PODLOGA ponizej ktorej ten blok juz nie da sie scisnac, wiec przy braku
miejsca to CALY RZAD (patrz "flex-wrap" na rodzicu) robi sie szerszy/
nizszy, a nie tytul zapada sie w nieskonczonosc. Uwaga: NIE "max-content"
(probowane, cofniete) - to wymuszaloby szerokosc calej NIEZLAMANEJ linii
specyfikacji ("Rozmiar odbicia: 26 x 9 mm..."), co na waskich szerokosciach
(np. 1440px) samo zaczynalo wystawac poza kafel. "auto"/min-content
pozwala specyfikacji normalnie zawijac sie na kilka linii (to juz nie
jest problem - to zwykly tekst akapitowy bez ryzyka nachodzenia), chroni
tylko przed lamaniem POJEDYNCZYCH SLOW tytulu.
*/
/*
Aktualizacja (nazwy produktow wydluzone o linie - "Trodat 4642" ->
"Trodat Printy 4642"/"Trodat Professional 5204"): tytul dostal marquee w
petli po najechaniu (patrz ".btx-stamp-canvas-header-model" nizej), wiec
NIE lamie sie juz na slowach - stary powod "min-width:auto" (ochrona przed
lamaniem w polslowia) odpada, "min-width:0" pozwala teraz kolumnie skurczyc
sie do dostepnego miejsca zeby "overflow:hidden" na tytule realnie mial co
przycinac zamiast rozpychac caly rzad.
*/
.btx-stamp-canvas-header-id
{
    flex: 1;
    min-width: 0;
}

/*
"line-height" jawnie (user: "sprawdz gorny padding w kaflu srodkowym" -
realna przyczyna to nie padding, tylko line-height) - cala strona ma
globalne "body{line-height:20px}" (SZTYWNY px, nie mnoznik), dziedziczone
domyslnie przez kazdy element bez wlasnej deklaracji. Dla tytulu na
hero(40px) to dawalo line-height o POLOWE mniejszy niz sam font (20px
zamiast ~44-48px), wizualnie "gniotac" tekst i zmniejszajac realna
przestrzen nad/pod nim mimo poprawnego paddingu naglowka. Naprawione
tokenem uzywanym juz w reszcie UI Kitu do naglowkow
("--btx-line-height-heading", 1.2).
*/
/*
Font plynny "clamp()" zamiast dwoch sztywnych stanow (user: "3 breakpointy
wystarcza czy oprzemy sie o dynamiczne skalowanie?" → "zrob to" - pilotaz
przed ewentualnym rollout na reszte sklepu). Wczesniej: 40px domyslnie,
22px (--btx-text-h3) w trybie "compact" (<=1700px szer. LUB <=820px wys.)
- twardy skok na granicy, zero skalowania powyzej 1700px (stad user:
"na 2K wszystko wyglada tak samo jak na 1920, tylko wiecej pustki"). Teraz
skaluje sie CIAGLE miedzy tymi samymi, juz zaakceptowanymi wartosciami
(22px/40px) na calej szerokosci 992-1920px, bez martwej strefy powyzej.
Formula: linear interpolation "wartosc = Ypx + Zvw", wyliczona z 2 punktow
(22px @ 992px, 40px @ 1920px) - clamp() na koncach pilnuje zakresu.
*/
/*
"width:100%" DOPISANE (user: "przechodzi w petle" nie dzialalo -
zmierzone: bez jawnej szerokosci element sam kurczyl/rosl do tresci
("shrink-to-fit"), wiec "scrollWidth" ZAWSZE bylo rowne "clientWidth"
(nigdy nie ma wlasnego overflow, bo po prostu rosnie zamiast go miec) -
dlugi tytul przelewal sie na sasiednia kolumne "KOLOR" zamiast byc
przyciety. Rodzic (".btx-stamp-canvas-header-id") juz mial poprawne
"flex:1;min-width:0" - brakowalo tylko tego, zeby TYTUL faktycznie
wypelnial (nie przekraczal) przyznana mu przez rodzica szerokosc.
*/
.btx-stamp-canvas-header-model
{
    font-size: clamp(16px, -9.66px + 2.59vw, 40px);
    line-height: var(--btx-line-height-heading, 1.2);
    font-weight: 800;
    color: var(--btx-text-primary);
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
}

/*
Gradientowe zanikanie na krawedziach (user: "dorob takie zanikanie do
gradientu tam gdzi przycina tytuly") - "mask-image" zamiast nakladki z
"background: linear-gradient" bo maskuje sama PRZEZROCZYSTOSCC, wiec
dziala identycznie niezaleznie od koloru tla pod spodem (nie trzeba
dopasowywac hexa tla przy kazdej zmianie stylu naglowka). "-webkit-"
prefiks wymagany w Safari (przegladarka referencyjna projektu).

KOREKTA (user: "jak nie slidują to lewa krawedz ma nie byc tego
zanikania") - w spoczynku tekst NIE jest przyciety z lewej (zaczyna sie
dokladnie od x=0), wiec maska w spoczynku fejduje TYLKO prawa krawedz.
Fade z lewej strony ma sens DOPIERO w trakcie animacji petli (tekst
realnie przejezdza przez lewa krawedz) - stad osobna, szersza maska
(oba boki) wylacznie w ":hover" (ktora i tak jest jedynym trigerem
animacji, patrz "@media (hover:hover)" nizej).
*/
.btx-stamp-canvas-header-model.is-scrollable
{
    -webkit-mask-image: linear-gradient(to right, black, black calc(100% - 32px), transparent);
    mask-image: linear-gradient(to right, black, black calc(100% - 32px), transparent);
}

@media (hover: hover)
{
    .btx-stamp-canvas-header-model.is-scrollable:hover
    {
        -webkit-mask-image: linear-gradient(to right, transparent, black 32px, black calc(100% - 32px), transparent);
        mask-image: linear-gradient(to right, transparent, black 32px, black calc(100% - 32px), transparent);
    }
}

/* Klikalny tytul -> strona produktu (user: "na clicku niech przechodzi na str produktu"). */
.btx-stamp-canvas-header-model.is-clickable
{
    cursor: pointer;
}

@media (hover: hover)
{
    .btx-stamp-canvas-header-model.is-clickable:hover
    {
        color: var(--btx-color-primary);
    }
}

/*
Marquee w petli po najechaniu dla dlugich nazw modelu - ten sam wzorzec co
juz uzyty w custom-select czcionek (patrz ".btx-stamp-custom-select-option-
label", ta sama animacja "@keyframes btx-stamp-select-marquee" reuzyta
1:1). JS (updateStampHeader()) dobudowuje "-track" TYLKO gdy tytul
realnie sie nie miesci (scrollWidth > clientWidth) - krotkie nazwy
zostaja pojedyncza, statyczna kopia bez animacji.
*/
.btx-stamp-canvas-header-model-track
{
    display: inline-flex;
    white-space: nowrap;
}

.btx-stamp-canvas-header-model-track span
{
    padding-right: 40px;
}

@media (hover: hover)
{
    .btx-stamp-canvas-header-model.is-scrollable:hover .btx-stamp-canvas-header-model-track
    {
        animation: btx-stamp-select-marquee 6s linear infinite;
    }
}

.btx-stamp-canvas-header-colors
{
    display: flex;
    gap: var(--btx-spacing-sm);
    flex-shrink: 0;
}

/*
".btx-tile label" w bento-account.css narzuca globalnie "text-transform:
none !important; font-weight:700 !important" na WSZYSTKIE prawdziwe
<label> w kaflach (pomyslane pod pola formularza konta) - nasze etykiety
ponizej sa tez prawdziwymi <label>, wiec byly cicho ścinane z powrotem do
normalnego case'u mimo deklaracji "uppercase" tutaj (user: "wybierz
automat ma dobra wielkosc" - to <p>, nie <label>, dlatego jej to nie
dotyczylo i wygladala inaczej). "!important" + druga klasa w selektorze
(specyficznosc wyzsza niz ".btx-tile label") przebija to bezpiecznie.
*/
.btx-stamp-canvas-header-colors .btx-stamp-color-field label
{
    display: block;
    text-align: center;
    font-size: var(--btx-text-micro) !important;
    font-weight: 800 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.06em;
    color: var(--btx-text-tertiary) !important;
    margin-bottom: 4px;
}

.btx-stamp-color-field select
{
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    border-radius: var(--btx-radius-sm);
    padding: 6px 10px;
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-xs);
    font-weight: 600;
    color: var(--btx-text-primary);
}

/* clamp() plynny, patrz komentarz przy ".btx-stamp-canvas-header-model" - punkty kalibracyjne pomniejszone (user: "jeszcze pomniejsz ten napis") z 14/18px na 12/15px @ 992/1920px. */
.btx-stamp-canvas-header-specs
{
    font-size: clamp(12px, 8.79px + 0.32vw, 15px);
    line-height: var(--btx-line-height-heading, 1.2);
    color: var(--btx-text-tertiary);
    margin-top: clamp(4px, -2.41px + 0.65vw, 10px);
}

/*
Wciety "sunken" panel (user: "wydzielil w taki sposob jak jest wydzielona
przestrzen na upload w 2 kreatorze naszym tym wydrukow") - dokladnie
skopiowany przepis z ".btx-print-surface" w print-configurator.css
(ciemniejsze "--btx-neutral-300", promien "--btx-radius-md", wewnetrzny
cien dajacy wrazenie "zaglebienia" zamiast plaskiego tla). Wzor kropek
zostaje (user: "ten pattern kropek mi sie podoba") - rysowany NAD tym
ciemniejszym tlem jako osobna warstwa background-image.
*/
/*
"min-height:0" (user: "canvas u mnie u dolu ucina") - "flex:1" samo w
sobie NIE wystarcza zeby ten element mogl sie skurczyc ponizej naturalnej
wysokosci swojej tresci - domyslny "min-height:auto" flex-itema blokowal
scurcie, gdy stage/canvas ponizej zaczely zadac "height:100%" (patrz
nizej). Skutek: surface (i wszystko w nim) robilo sie WYZSZE niz
dostepna przestrzen w kaflu, wystajac ponizej i zostajac obciete przez
globalne "overflow:hidden" na zaokraglonych rogach kafla.
*/
.btx-stamp-canvas-surface
{
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 var(--btx-spacing-md) var(--btx-spacing-md);
    border-radius: var(--btx-radius-md);
    background-color: var(--btx-neutral-200);
    background-image: radial-gradient(var(--btx-neutral-300) 1.5px, transparent 1.5px);
    background-size: 20px 20px;
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.15);
    padding: var(--btx-spacing-sm);
}

/*
Info o pomniejszeniu skali rysowania dla modeli z duzym polem odbicia,
ktore inaczej nie zmiescilyby sie w stalym oknie canvasu (user: "daj w
rogu canvasu info ze jest zoom") - patrz updateStampPxPerMm() w JS,
ktore pokazuje/ukrywa ten element i ustawia tekst "Zoom XX%".
*/
/*
Rozdzielone na dwa niezalezne rogi (user: "zoom przesun na lewo i daj mu
style jak buttonowi lupy a button lupy daj w rog") - plakietka "Zoom XX%"
(info o skali dopasowania) w LEWYM gornym rogu, ostylowana jak przycisk
lupy (ten sam border/radius/tlo, nie osobny "pill"). Przycisk lupy sam w
PRAWYM gornym rogu, bez wspolnego wrappera (byl potrzebny tylko gdy oba
dzielily jeden rog).
*/
.btx-stamp-canvas-zoom-badge
{
    position: absolute;
    top: var(--btx-spacing-sm);
    left: var(--btx-spacing-sm);
    z-index: 2;
    padding: 4px 10px;
    border: 1px solid var(--btx-border-color);
    border-radius: var(--btx-radius-sm);
    background: var(--btx-bg-input);
    color: var(--btx-text-secondary);
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-xs);
    font-weight: 700;
}

.btx-stamp-canvas-stage
{
    position: relative;
}

/*
Tlo/radius na SAMYM STAGE (nie na "canvas" jako selektorze) - Fabric.js
tworzy DWA elementy <canvas> w tym kontenerze: .lower-canvas (rysunek) i
.upper-canvas (przezroczysta nakladka do obslugi klikniec, ulozona NAD
dolnym). Selektor "canvas" bez ograniczenia lapal oba i malowal gorna,
niewidzialna nakladke na biale tlo - wszystko narysowane na dolnym platnie
znikalo pod nia mimo ze obiekty realnie byly dodane (potwierdzone przez
DevTools: getObjects() zwracalo poprawna liczbe, po prostu nic nie bylo
widac). Samo tlo bialego prostokata usuniete na prosbe uzytkownika - canvas
ma zlewac sie z siatka kropek .btx-stamp-canvas-surface, bez wlasnego
tla/obwodki.
*/
.btx-stamp-canvas-stage
{
    overflow: hidden;
}

/*
Canvas MIAL staly, natywny rozmiar 600x240px, rozciagany do wypelnienia
kolumny wylacznie przez ten CSS ("width/height:100%!important" ponizej,
"object-fit:contain" zeby zachowac proporcje 600:240 jak `<img>`) - to
dzialalo wizualnie (canvas "wypelnial" dostepna przestrzen), ale
rozciagalo maly, staly raster (nigdy nie zmienial FIZYCZNEGO rozmiaru
bufora), co dawalo rozmycie (user: "tragiczna jakosc podgladu") - im
szerszy monitor, tym wiecej rozciagania.
Fix (2026-08-24): "resizeStampCanvasForRetina()" w JS TERAZ faktycznie
zmienia rozmiar bufora Fabrica ("canvas.setDimensions()", wlasna metoda
Fabric.js - w przeciwienstwie do samych atrybutow HTML aktywuje tez jego
wbudowana obsluge devicePixelRatio) na rzeczywisty, zmierzony rozmiar
kolumny - Fabric sam ustawia wtedy POPRAWNE inline "style width/height"
na obu platnach (i na ".canvas-container"), wiec zewnetrzne CSS
"100%!important" nie jest juz potrzebne (i przeszkadzaloby, dublujac
rozciaganie ponad to co juz ustawil Fabric).
*/
/*
"96%" zamiast "100%" (user: "za duze wszystko jest jeszcze, pomniejszmy
minimalnie wszystko") - drobny margines bezpieczenstwa (2% luzu z kazdej
strony) zamiast dokladnego 1:1 wypelnienia, wysrodkowany automatycznie
przez rodzica (".btx-stamp-canvas-surface", flex align/justify:center).
"min-height:0"/"min-width:0" - ten sam powod co przy surface wyzej,
zeby stage tez mogl sie skurczyc ponizej naturalnej wysokosci tresci
zamiast wypychac otoczenie.
*/
/*
"display:flex;align-items/justify-content:center" DOPISANE (2026-08-24,
razem z fixem retina) - odkad canvas dostaje SWOJ WLASNY, zmierzony
rozmiar przez "canvas.setDimensions()" (moze byc WEZSZY niz caly ten box,
gdy proporcja stage nie jest dokladnie 600:240 - patrz
resizeStampCanvasForRetina()), ".canvas-container" (normalny "position:
relative" div Fabric.js, NIE absolutny) bez flexa zostawalby przypiety do
lewego-gornego rogu zamiast wysrodkowany (user: "ramka odbicia nie jest
wycentrowana") - flex na rodzicu centruje go automatycznie niezaleznie od
finalnego rozmiaru, dokladnie jak dawniej robil to "object-fit:contain".
*/
.btx-stamp-canvas-stage
{
    width: 96%;
    height: 96%;
    min-width: 0;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
Bug (zoom, 2026-08-24/25): ".canvas-container" dostaje od Fabrica poprawny
inline "width/height" (np. 797px po zoomie x2), ale jako dziecko flexa BEZ
"flex-shrink:0" przegladarka domyslnie SCISKA jego wlasne pudelko layoutowe
z powrotem do szerokosci sceny (429px) - mimo ze realne platna <canvas> w
srodku (position:absolute, wiec nie licza sie do auto-sizingu rodzica)
zostaja swoich prawdziwych 797px. Efekt: "justify-content:center" centrowal
kontener tak jakby mial 429px, a realna tresc wystawala ~370px w prawo i
byla ucinana przez "overflow:hidden" sceny - stad zdjecie usera pokazujace
ramke odbicia i tekst uciekajace w prawo poza kadr przy aktywnym zoomie.
Fix: "flex-shrink:0" wymusza zeby pudelko flexa ZAWSZE odpowiadalo
prawdziwemu, ustawionemu przez Fabric rozmiarowi - wtedy centrowanie i
"overflow:hidden" (symetryczne przyciecie nadmiaru z obu stron) dzialaja
na tych samych, spojnych liczbach.
*/
.canvas-container
{
    flex-shrink: 0;
}

/*
"inset:0;width/height:100%" wraca (byl przez chwile zastapiony recznym
JS-owym offsetem, ktory okazal sie niestabilny - patrz duzy komentarz przy
przenoszeniu tego elementu w resizeStampCanvasForRetina()) - TERAZ
bezpieczny, bo overlay jest DZIECKIEM ".canvas-container" (nie sasiadem w
".btx-stamp-canvas-stage"), a container ma dokladnie taki sam rozmiar co
sam canvas (Fabric.js go tak ustawia) - "100%" tutaj znaczy "100% canvasu",
nie "100% calego, szerszego stage".
*/
.btx-stamp-dim-overlay
{
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

/*
kontrolki aktywnego wersu (pod canvasem) - header (licznik wersow) PRZY
GORNEJ krawedzi kafla (user: "daj caly ten wybor wersow blizej gornej
krawedzi kafelka"), reszta (suwaki/select) nadal wycentrowana w
pozostalej przestrzeni ponizej (".btx-stamp-controls-grid" dostaje
flex:1 + align-content:center zamiast centrowac WSZYSTKO razem jako
jeden blok).
*/
/*
"min-height:260px" (2026-08-21, koniec sesji, user: "mozemy tez zmniejszyc
znacznie wysokosc dolnego kafelka a powiekszyc canvas") - ta wartosc
zostala z fazy suwakow (Krok 3.3d), zanim doszly kompaktowe steppery.
Realna zawartosc (header 40px + odstep 16px + wiersz kontrolek 40px +
padding kafla 24px×2) to ok. 144px - reszta byla martwa przestrzenia
wymuszona przez ta stala (".btx-stamp-controls-grid" ma "flex:1", wiec
po prostu naciagal sie i centrowal 40px-owy wiersz w srodku pustego
260px pudelka). Obnizone do 160px (lekki zapas nad realna tresci) -
kokpit ma stala wysokosc calosci (patrz ".btx-stamp-cockpit"), a rzad
"canvas" jest "1fr", wiec kazdy px oddany tutaj automatycznie trafia do
canvasu ponizej.
*/
/*
Przebudowa (user: "w 1 linii... od lewej z tytulem na gorze wers, na
dole same 1 2 3 4 ze strzalkami, i wtedy mozna buttony styl przeniesc do
1 linii... i wtedy mozna poszerzyc dolne steppery jeszcze") -
".btx-stamp-controls-nav-block" (nawigacja+B/I+pelna szerokosc) teraz
zwarty w JEDNYM rzedzie (bylo: osobny rzad nawigacji + "Styl" jako
kolumna w gridzie). "flex-direction:column" (NIE "row") - zmierzone live:
panel ".btx-stamp-controls" ma STALA, ograniczona szerokosc (512px na
desktopie, narzucona przez zewnetrzny grid layoutu) - postawienie
nav-blocku OBOK grida w jednym wspolnym rzedzie kazalo im DZIELIC te sama
szerokosc, wiec steppery w gridzie realnie ZMALALY (96px->55px) mimo
mniejszej liczby kolumn - dokladne przeciwienstwo celu. Nav-block zostaje
wiec swoim WLASNYM, waskim rzedem (lewo wyrownanym), grid ponizej dostaje
z powrotem CALA szerokosc panelu dla siebie - to jedyny sposob zeby
"steppery szersze" i "nawigacja+styl w 1 linii" dzialaly ROWNOCZESNIE.
*/
.btx-stamp-controls
{
    grid-area: controls;
    min-height: 160px;
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-sm);
}

/*
Pager, Styl i Justowanie w JEDNYM wierszu (justowanie doszlo 2026-08-24,
przeniesione tu z osobnego rzedu ponizej - user: "aliigment tekstu mial
byc obok stylow"). Z 3 dziecmi "justify-content:space-between" (poprzednie
podejscie, dobre dla 2) rozstawialoby srodkowe pole na SRODKU calego
rzedu zamiast przy prawej krawedzi obok "Justowania" - zamiast tego pager
(pierwsze dziecko) dostaje "flex:1", wiec sam wchlania cala luzna
przestrzen, a Styl+Justowanie zostaja ciasno zgrupowane przy prawej
krawedzi (odstep miedzy nimi to zwykly "gap" bloku).
*/
.btx-stamp-controls-nav-block
{
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--btx-spacing-sm);
}

/*
User (2026-08-25): "SELECT LINE ma byc po lewej stronie kafelka i
rozrastac sie w prawo calosc, tytul i licznik po prawej [tj. razem, nie
rozjechane], ale tytul ma byc wycentrowany zawsze wzgledem licznika" -
odwrotnosc poprzedniej decyzji (ktora centrowala etykiete+pager wzgledem
CALEJ szerokosci tej kolumny, patrz komentarz przy ".btx-stamp-controls-
pager"). "display:flex;flex-direction:column;align-items:center" sprawia
ze etykieta i pager NIE sa juz rozciagane na pelna szerokosc kolumny -
kazde kurczy sie do wlasnej naturalnej tresci i centruje WZGLEDEM SIEBIE
NAWZAJEM (wezszy element automatycznie centruje sie pod/nad szerszym), a
caly ten zwarty blok siedzi przy LEWEJ krawedzi kolumny (bo to pierwsze
dziecko rzedu ".btx-stamp-controls-nav-block", nic go nie przesuwa w
prawo). Sama kolumna zostaje "flex:1" - dalej rosnie i spycha STYL/
ALIGNMENT do prawej krawedzi kafelka, zmienia sie tylko POZYCJA TRESCI
wewnatrz niej, nie jej szerokosc.
*/
.btx-stamp-controls-nav-block > .btx-stamp-control-field:first-child
{
    /*
    "flex:1" samo w sobie NIE wystarczylo - "align-items:center" centruje
    dzieci wzgledem PELNEJ szerokosci pudelka flexa (219px, cala
    zarezerwowana kolumna), a nie wzgledem siebie nawzajem w ciasnym
    opakowaniu (zmierzone live: srodek etykiety i pagera pokrywal sie ze
    SRODKIEM CALEJ KOLUMNY, nie z lewa krawedzia - dokladnie stary
    problem, inny mechanizm). Fix: "flex:0 1 auto" (bez grow) kurczy
    pudelko do naturalnej szerokosci tresci, a "margin-right:auto"
    pochlania cala reszte wolnego miejsca w rzedzie jako NIEWIDOCZNY
    margines PO tym pudelku - to dalej spycha STYL/ALIGNMENT do prawej
    krawedzi kafelka (funkcjonalny odpowiednik dawnego "flex:1"), ale bez
    rozciagania samego pudelka z tresci=nia.
    */
    flex: 0 1 auto;
    min-width: 0;
    margin-right: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/*
"flex:1; min-width:0" (user: "popraw ... ze napis wybierz wiersz nie
jest pomiedzy strzalkami" - przeniesiony do wnetrza ".btx-stamp-controls-
pager" w tpl, miedzy strzalki, tam gdzie normalnie siedza "dots") - bez
tego flex-item z domyslnym "min-width:auto" odmawialby zawiniecia
dluzszego tekstu ponizej naturalnej szerokosci, wypychajac pager w scroll
zamiast pozwolic tekstowi zlamac sie na kilka linii (ten sam wzorzec
pulapki flexboksa co gdzie indziej w tym pliku).
*/
.btx-stamp-controls-title
{
    flex: 1;
    min-width: 0;
    text-align: center;
    font-size: var(--btx-text-sm);
    font-weight: 700;
    color: var(--btx-text-secondary);
    margin: 0;
}

/*
Pager (strzalki + kolka) - "overflow-x:auto" jako siatka bezpieczenstwa
gdy jest duzo wersow (do 8, patrz btx_stamp_line_pricing) i kolka nie
miesca sie w waskim (170px) lewym bloku obok strzalek - w typowym
przypadku (1-4 wersy) miesci sie bez scrolla, przy wiekszej liczbie
scrolluje zamiast lamac uklad.
*/
/*
"justify-content:center" dopisane (user: "Select line nie jest
wycentrowane idealnie nad numerkami") - kolka (".btx-stamp-controls-dots")
NIE MAJA "flex:1" (w przeciwienstwie do placeholder-tekstu ".btx-stamp-
controls-title", ktory ma i sam sie centruje przez "text-align:center" na
calej szerokosci) - bez tego caly blok [strzalka][kolka][strzalka] siedzial
przy LEWEJ krawedzi pola (zwykly flex bez justify), podczas gdy etykieta
"SELECT LINE" nad nim byla centrowana wzgledem CALEJ szerokosci pola -
rozjazd miedzy nimi. "justify-content:center" centruje caly blok jako
jednostke, zgodnie z etykieta powyzej, niezaleznie od tego czy widac kolka
czy placeholder.
*/
.btx-stamp-controls-pager
{
    display: flex;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    max-width: 100%;
}

/*
Licznik wersow jak "kropki" paginacji (user: strzalki same w sobie byly
malo widoczne) - kolka z numerami miedzy strzalkami, aktywne wypelnione
kolorem primary, kazde klikalne (bezposredni skok, nie tylko krok po
kroku). Renderowane w JS - patrz updateStampControlsTitle().
*/
.btx-stamp-controls-dots
{
    display: none;
    align-items: center;
    gap: 4px;
}

/*
Same cyfry zamiast pelnego "Wers N" (user: "na dole same 1 2 3 4") - male
okragle znaczniki zamiast szerokich pigulek z tekstem, zeby zmiescily sie
obok strzalek w waskim lewym bloku. Border (nawet ciemniejszy
--btx-border-input) wciaz byl za slaby (user: "totalnie niewidoczne") -
wypelnione tlo zamiast obwodki. Ten sam wzorzec co juz istniejacy
".btx-stamp-line-num"/".is-active" w panelu WERSY (nieaktywny = jasny
szary fill "--btx-bg-input", aktywny = pelny kolor primary).
*/
/*
40x40px - user (po przejsciu przez 24px/40px/32px): "maja miec takie same
ksztalty i radiusy dokladnie takie same" - DOKLADNIE ten sam rozmiar co
".btx-stamp-bi-btn" (nie posrednia wartosc). Przy roznych rozmiarach ten
sam token promienia daje INNA proporcje promien/bok (mniejszy bok = wiekszy
udzial promienia = blizej okregu) - jedyny sposob na naprawde IDENTYCZNY
ksztalt to identyczny rozmiar, nie tylko identyczny token promienia.
*/
.btx-stamp-controls-dot
{
    width: 40px;
    height: 40px;
    padding: 0;
    flex-shrink: 0;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: var(--btx-bg-input);
    color: var(--btx-text-secondary);
    font-family: var(--btx-font-family);
    font-size: 15px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.btx-stamp-controls-dot.is-active
{
    background: var(--btx-color-primary);
    border-color: var(--btx-color-primary);
    color: #ffffff;
}

@media (hover: hover)
{
    .btx-stamp-controls-dot:not(.is-active):hover
    {
        background: var(--btx-border-hover);
        color: var(--btx-text-primary);
    }
}

/*
Brakujacy :active (audyt spojnosci 2026-08-28) - hover juz uzywa
"--btx-border-hover" (najciemniejszy krok palety), wiec active dostaje
TEN SAM kolor + scale (kropka i tak nie moze sciemniec bardziej w tej
palecie) - namacalny efekt kliku na dotyk.
*/
.btx-stamp-controls-dot:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.9);
}

/*
Strzalki jako pelny przycisk PRIMARY (user: "a jakby primary dac?") - w
odroznieniu od kolek (ktore musza rozrozniac aktywny/nieaktywny stan)
strzalki nie maja takiego rozroznienia, wiec moga byc od razu w pelni
wypelnione bez utraty czytelnosci ktoregokolwiek stanu. PO probie z
celowo mniejszym rozmiarem (36px, kompensata optycznego "ciezaru"
wypelnienia) user zdecydowal: "maja miec takie same ksztalty i radiusy
dokladnie takie same" - wraca do 40px, IDENTYCZNIE jak ".btx-stamp-bi-btn"
obok (ten sam rozmiar + juz wspolny token promienia = gwarantowanie
identyczny ksztalt, wizualny "ciezar" wypelnienia zaakceptowany jako
mniej wazny niz literalna identycznosc).
*/
/*
Biale tlo + obwodka (user: "borderow nie maja te biale", "moze strzalki
nie rob czarne") - dawniej pelne wypelnienie "--btx-color-primary" (patrz
odrzucony komentarz "Strzalki jako pelny przycisk PRIMARY" wyzej w
historii pliku) - teraz DOKLADNIE ten sam jezyk co ".btx-stamp-bi-btn"
(biale tlo, 1px obwodka, tekst/ikona w kolorze secondary), hover tez
identyczny wzorzec (obwodka+kolor primary zamiast zmiany tla).
*/
.btx-stamp-controls-nav
{
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

/*
Hover ujednolicony (2026-08-28, user: "w dolnym kafelku co button to inny
hover") - byl "border+tekst→primary", jedyny w calym dolnym kaflu odstajacy
od dominujacego jezyka reszty kontrolek (bg-input na hover, border-hover
na active - stepper/align-btn/dropdown czcionki w tym samym kaflu).
*/
@media (hover: hover)
{
    .btx-stamp-controls-nav:not(:disabled):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-controls-nav:not(:disabled):active
{
    background: var(--btx-border-hover);
    transform: scale(0.9);
}

.btx-stamp-controls-nav:disabled
{
    opacity: 0.3;
    cursor: not-allowed;
}

/*
"minmax(0, Nfr)" zamiast samego "Nfr" (2026-08-21, user: realny MacBook
Air M1 1440x674 - pole "Interlinia" realnie ucinane po prawej krawedzi
kafla). Goly "fr" ma DOMYSLNE "min-width:auto" - kolumna nigdy nie
scisnie sie ponizej min-content swojej zawartosci (np. wymuszonej
szerokosci triggera fonta z JS), wiec przy waskiej kolumnie canvasu caly
rzad po prostu WYSTAWAL poza kafel (zmierzone live: potrzebne 724px,
dostepne 591.6px) zamiast sie scisnac. "minmax(0,...)" pozwala kazdej
kolumnie scisnac sie do zera w razie potrzeby - rzad zawsze miesci sie w
dostepnej szerokosci.
*/
/*
Historia tego selektora (2026-08-21, MacBook Air M1 1440x674 - "wszystko
za duze, canvas za maly"): najpierw "minmax(0,1fr)" na kazdej kolumnie -
overflow (Interlinia ucinana). Potem "minmax(64px,1fr)" - za malo, sam
".btx-stamp-stepper" ma DWA przyciski 38px ("-"/"+", stale) = 76px
fixed narzutu, wiec wartosc w srodku dostawala realnie ~20px i dalej sie
ucinala. Potem "minmax(120px,1fr)" na trzech numerycznych kolumnach -
naprawilo steppery, ALE odslonilo kolejny, niezalezny problem: pole
czcionki (custom-select) ma WLASNA logike szerokosci w JS
(".btx-stamp-custom-select" rebuild(): "width = Math.max(naturalWidth,
parentWidth)" liczone z tresci listy opcji), kompletnie ignorujaca
przydzielona mu kolumne gridu - przy zbyt waskiej kolumnie (1.6fr
scisniete do ~82px) dropdown i tak renderowal sie na swoja NATURALNA
szerokosc (~150-200px) i WIZUALNIE NACHODZIL na sasiednia kolumne
(Rozmiar), bo elementy gridu domyslnie nie sa przycinane do wlasnej
komorki.

Finalne, odporne podejscie: "repeat(5, auto)" - kazda kolumna dostaje
DOKLADNIE tyle miejsca ile realnie potrzebuje jej zawartosc (zero
wymuszonego sciskania ponizej naturalnego minimum, zero ryzyka
nachodzenia), a caly wiersz jako calosc dostaje "overflow-x:auto" -
jesli 5 kolumn o naturalnych rozmiarach faktycznie nie miesci sie w
dostepnej szerokosci kafla (skrajny przypadek), wiersz kontrolek po
prostu przewija sie w poziomie, zamiast lamac/nachodzic na siebie.
"min-width:0" niezbedny bo grid jest jednoczesnie flex-itemem
(".btx-stamp-controls" to "display:flex") - bez tego domyslny
"min-width:auto" flex-itema zablokowalby scurcie ponizej sumy
naturalnych szerokosci wszystkich kolumn, uniemozliwiajac scroll (caly
kafel zostalby rozepchniety zamiast przewijac tylko ten jeden rzad).
*/
/*
5 kolumn "auto" -> 4 kolumny "1fr" (user: "wtedy mozna poszerzyc dolne
steppery jeszcze") - "Styl" (B/I) przeniesiony do lewego bloku
(".btx-stamp-controls-nav-block"), zostaja Czcionka/Rozmiar/Sciśniecie/
Interlinia. "auto" dopasowywalo kolumny do naturalnej tresci (waskie,
tyle ile potrzeba) - "1fr" (rowne czesci) rozciaga je na CALA dostepna
szerokosc rzedu, wiec kazdy stepper realnie urosl, nie tylko zajal
zwolnione miejsce po "Styl". "minmax(0,1fr)" (nie samo "1fr") zapobiega
przepchnieciu kolumny przez naturalna min-szerokosc tresci (klasyczna
pulapka grida - patrz analogiczny fix przy "min-width:0" na panelu
steperа gdzie indziej w tym pliku).
*/
.btx-stamp-controls-grid
{
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--btx-spacing-md);
    flex: 1;
    min-width: 0;
    align-content: center;
    overflow-x: auto;
}

/*
Justowanie per wers (backlog 2026-08-24, user: "do tekstu dodajmy opcje
justowania... kazdego wersu osobno") - PRZENIESIONE (doprecyzowanie tego
samego dnia, user: "aliigment tekstu mial byc obok stylow a nie linie
nizej") z ".btx-stamp-controls-grid" do ".btx-stamp-controls-nav-block",
obok pola "Styl" - stad grid wrocil do 4 kolumn wyzej, a rozmiar przyciskow
teraz DOKLADNIE jak ".btx-stamp-bi-btn" (40px/34px, nie "flex:1;padding:8px"
jak wczesniej) - user: "rozmiary buttonow od aliigmentu... sa za male",
sasiaduja teraz bezposrednio z grupa B/I wiec musza wygladac spojnie.
Wizualnie podobne do ".btx-stamp-pos-btn" (kotwica logo), ale CELOWO
osobna klasa - to inna funkcja (justowanie tekstu, nie pozycja logo), nie
chcemy przypadkowego sprzezenia gdyby ktos kiedys zmienil jedno pod katem
drugiego.
*/
.btx-stamp-align-row
{
    display: flex;
    gap: 6px;
    height: 40px;
}

.btx-stamp-align-btn
{
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    padding: 8px;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-color);
    background: #ffffff;
    color: var(--btx-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

@media (hover: hover)
{
    .btx-stamp-align-btn:not(.is-active):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-align-btn:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.95);
}

.btx-stamp-align-btn.is-active
{
    background: var(--btx-color-primary);
    color: #ffffff;
    border-color: var(--btx-color-primary);
}

.btx-stamp-align-btn:disabled
{
    opacity: 0.4;
    cursor: not-allowed;
}

.btx-stamp-control-field-bold
{
    display: flex;
    flex-direction: column;
}

.btx-stamp-toggle
{
    display: inline-flex;
    align-items: center;
    gap: var(--btx-spacing-xs);
    font-size: var(--btx-text-sm);
    color: var(--btx-text-primary);
    cursor: pointer;
}

.btx-stamp-logo-remove-bg-field
{
    margin-top: var(--btx-spacing-sm);
}

.btx-stamp-logo-preview-compare
{
    display: flex;
    gap: var(--btx-spacing-sm);
}

.btx-stamp-logo-preview-col
{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    /* miniatury maja wypelniac cala dostepna szerokosc kafla (user), nie zostawac przy stalym 96px */
    flex: 1;
    min-width: 0;
}

.btx-stamp-logo-preview-label
{
    font-size: var(--btx-text-micro);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--btx-text-tertiary);
}

/*
 * Szachownica pod podgladem - odroznia REALNA przezroczystosc (widac wzor)
 * od bialego koloru tla wgranego pliku (wzoru nie widac, bo zaslania go
 * oplicity biel) - user od razu widzi ktora sytuacja go dotyczy.
 */
.btx-stamp-logo-preview-raw
{
    /* szerokosc rosnie razem z kolumna (flex:1 na rodzicu), "aspect-ratio" zamiast stalej wysokosci - kwadrat zostaje kwadratem przy kazdej szerokosci */
    width: 100%;
    aspect-ratio: 1;
    border-radius: var(--btx-radius-sm);
    border: 1px solid var(--btx-border-input);
    background-image: repeating-conic-gradient(var(--btx-bg-input) 0% 25%, #ffffff 0% 50%);
    background-size: 12px 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.btx-stamp-logo-preview-raw img
{
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/*
Jeden przycisk-przelacznik zamiast palety klikalnych swatchy (user,
2026-08-25: "tylko kolor tla i zblizone ma byc usuwany ale mega
dokladnie, i ma byc tylko switch usun kolor") - kolor tla wykrywany
automatycznie z rogow obrazka (patrz detectLogoBackgroundColor() w JS),
usuwanie po odleglosci euklidesowej z ciasnym progiem (BTX_STAMP_BG_REMOVE_THRESHOLD).
Ten sam wzorzec ".is-active" co reszta toggle'ow w kreatorze.
*/
.btx-stamp-remove-bg-toggle
{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--btx-spacing-xs);
    width: 100%;
    margin-top: var(--btx-spacing-sm);
    padding: 8px 12px;
    border: 1px solid var(--btx-border-input);
    border-radius: var(--btx-radius-control);
    background: var(--btx-bg-input);
    color: var(--btx-text-secondary);
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 600;
    cursor: pointer;
}

.btx-stamp-remove-bg-toggle .btx-stamp-icon
{
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

@media (hover: hover)
{
    .btx-stamp-remove-bg-toggle:not(.is-active):hover
    {
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-remove-bg-toggle:active
{
    transform: scale(0.98);
}

.btx-stamp-remove-bg-toggle.is-active
{
    background: var(--btx-color-primary);
    color: #ffffff;
    border-color: var(--btx-color-primary);
}

.btx-stamp-toggle input
{
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.btx-stamp-toggle-track
{
    position: relative;
    width: 40px;
    height: 22px;
    border-radius: var(--btx-radius-pill);
    background: var(--btx-border-color);
    transition: background var(--btx-transition-fast);
}

.btx-stamp-toggle-track::before
{
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    transition: transform var(--btx-transition-fast);
}

.btx-stamp-toggle input:checked + .btx-stamp-toggle-track
{
    background: var(--btx-color-primary);
}

.btx-stamp-toggle input:checked + .btx-stamp-toggle-track::before
{
    transform: translateX(18px);
}

.btx-stamp-toggle input:disabled + .btx-stamp-toggle-track
{
    opacity: 0.5;
    cursor: not-allowed;
}

/*
"text-align: left" jawnie - bez tego wyciekal ".label, label
{ text-align: right }" z bazowego motywu Classic (theme.css), ktorego
zaden nasz selektor wczesniej nie nadpisywal (user zglosil etykiety
wyrownane do prawej zamiast do lewej).

"!important" + wyzsza specyficznosc (druga klasa w selektorze) - z tego
samego powodu co ".btx-stamp-color-field label" wyzej: ".btx-tile label"
w bento-account.css bije to "!important"-em (text-transform:none,
font-weight:700), mimo deklaracji "uppercase"/800 tutaj.
*/
/*
"margin-bottom:4px" (bylo "var(--btx-spacing-xs)"=8px) - user: "ustaw
odleglosc tytulu inputu od inputu taka jak w przypadku inputow kolo
canvasu" - dopasowane do ".btx-stamp-color-field label" (Kolor automatu/
Kolor tuszu w naglowku canvasu), ktore od zawsze uzywalo 4px. Selektor
rozszerzony o ".btx-stamp-controls-nav-block" (user: "dodaj do 1 linii
inputowe tez tytuly") - pager/styl w lewym bloku dostaly te sama
etykiete (wspolny selektor zamiast duplikowania calej reguly).
*/
.btx-stamp-controls-grid .btx-stamp-control-field label,
.btx-stamp-controls-nav-block .btx-stamp-control-field label,
.btx-stamp-logo-controls .btx-stamp-control-field label
{
    display: block;
    text-align: center;
    font-size: var(--btx-text-micro) !important;
    font-weight: 800 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.06em;
    color: var(--btx-text-tertiary) !important;
    margin-bottom: 4px;
}

.btx-stamp-control-field select
{
    width: 100%;
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    border-radius: var(--btx-radius-sm);
    padding: 10px 12px;
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 600;
    color: var(--btx-text-primary);
}

.btx-stamp-control-field select:disabled
{
    opacity: 0.5;
    cursor: not-allowed;
}

/*
Stepper "- wartosc +" (makieta "Wariant A", zaakceptowana przez usera)
zastepujacy suwaki Rozmiar/Sciśniecie/Interlinia - wizualnie 1:1
skopiowany z juz istniejacego licznika ilosci w koszyku
(".bootstrap-touchspin" w bento-cart.css): pigulka na "--btx-bg-input",
plywajace okragle przyciski na "--btx-bg-tile" + "--btx-shadow-tile"
("kafelek w kafelku"), wartosc wysrodkowana i pogrubiona. Logika w JS
(initStampSteppers()) - ten blok to tylko wyglad.
*/
/*
Druga wersja steppera (user: "gubia sie strasznie, zrobmy je z samego
konturu i nieco grubsze") - poprzednia (cienka 1px obwodka + oddzielne
male przyciski) wciaz za malo widoczna. Nowy przepis: SAM kontur, bez
wypelnienia tla, segmentowany podzial (pionowe linie miedzy -/wartosc/+)
zamiast osobnych "babelkow" z wlasnym tlem/cieniem - jeden spojny ksztalt
zamiast trzech sklejonych elementow. Scoped na razie TYLKO do tego
modulu (nie do sitewide ".bootstrap-touchspin" w koszyku) - user chce to
najpierw dopracowac tu, sitewide rollout to osobny temat.

Obwodka 2px na "--btx-border-hover" (2026-08-21, korekta) - przy ujednoliceniu
CALEJ siatki kontrolek do wspolnej rodziny 34-40px user zauwazyl ze
steppery/B-I mialy INNA (grubsza, ciemniejsza) obwodke niz reszta
inputow w tym module ("bordery stepperow za grube, inne niz inputow").
Sprowadzone do tego samego 1px "--btx-border-input" co inputy/dropdowny/
kosz/numerek - jeden spojny jezyk obwodki w calym module.
*/
/*
"align-items:center" (bylo "stretch") - proba (user: "zrob na probe tak
ze + i - to sa buttony wewnatrz steppera kwadratowe i odstepy od boku
gory i dolu sa takie same") - "stretch" rozciagal przyciski na PELNA
wysokosc steperа (bez odstepu gora/dol) - "center" pozwala przyciskom
miec WLASNA, mniejsza wysokosc (patrz ".btx-stamp-stepper-btn" nizej) z
rownym marginesem wokol, zamiast zlewac sie z krawedziami pigulki.
*/
.btx-stamp-stepper
{
    position: relative;
    display: flex;
    align-items: center;
    height: 40px;
    background: #ffffff;
    border: 1px solid var(--btx-border-input);
    border-radius: var(--btx-radius-control);
    overflow: hidden;
}

/*
Pasek postepu (user: "dodaj tez paski postepu do stepperow", kolejne
doprecyzowania: "zeby nie zachodzil na -/+ i byl wypelnieniem prostokata
z tekstem, z opcja przesuwania jak slider", pozniej "ten pasek postepu
tez niech bedzie taki jak te buttony"). "top/bottom:4px" + "border-radius:
10px" - DOKLADNIE ten sam inset/promien co ".btx-stamp-stepper-btn"
(kwadratowe przyciski +/-), zeby pasek czytal sie jako czesc tej samej
rodziny ksztaltow, nie osobny, plaski prostokat na pelna wysokosc.
Polprzezroczysty ("opacity", nie plaski jasny kolor) zeby czarny tekst
wartosci zostal czytelny NIEZALEZNIE od tego ile paska jest wypelnione.
"left"/"width" ustawiane w JS wprost z pozycji ".btx-stamp-stepper-val"
(patrz updateStepperFill() w JS) - odporne na dowolny uklad wewnatrz
steperа. Istniejacy "overflow:hidden" na ".btx-stamp-stepper" tnie pasek
do tych samych zaokraglonych rogow co reszta steperа.
*/
/*
Domyslnie zaokraglone TYLKO z lewej (user: "prawa krawedz byla bez
zaokraglen, dopiero maja sie blizej 100% pojawiac") - lewa krawedz to
STALY punkt (zawsze start pola wartosci), prawa to ROSNACY koniec paska -
plaska dopoki nie dojdzie do faktycznej prawej krawedzi (100%), wtedy
JS (updateStepperFill()) przelacza na promien z obu stron, zeby zlac sie
z zaokragleniem calego steperа. Bez tego prawy koniec wygladalby jak
oderwana "pigulka" plywajaca w srodku, nie jak realny postep.
*/
.btx-stamp-stepper-fill
{
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 0;
    width: 0;
    border-radius: calc(var(--btx-radius-control) - 4px) 0 0 calc(var(--btx-radius-control) - 4px);
    background: var(--btx-color-primary);
    opacity: 0.1;
    pointer-events: none;
    transition: width var(--btx-transition-fast), border-radius var(--btx-transition-fast);
}

/*
Kwadratowe (width===height), margines 4px na kazdej stronie zamiast
rozciagania na pelna wysokosc (patrz "align-items:center" na rodzicu
wyzej) - odstep gora/dol/lewo/prawo teraz identyczny. Pionowy divider
(":first-child"/"last-child" border) usuniety - nie pasuje juz do
plywajacego, kwadratowego przycisku, wlasny "border-radius" + tlo na
hover wystarcza do odroznienia od reszty pigulki.

Promien = "promien steperа minus margines" (--btx-radius-control - 4px),
NIE dowolny mniejszy token, zeby naroznik przycisku byl KONCENTRYCZNY
wzgledem naroznika calej pigulki (standardowa zasada zagniezdzonych
zaokraglonych prostokatow - inner = outer - padding). Dziala bezpiecznie
w obu trybach (polowa boku 16px baza/13px compact, promien zawsze < obu).

Fluidne (2026-08-24, user: "radiusy buttonow i inputow" dalej sztywne po
przejsciu --btx-radius-control na clamp() wyzej) - "10px" bylo tu
poprawne TYLKO przy oryginalnym, sztywnym --btx-radius-control:14px;
odkad token jest fluidny (10.5px-14px), wzor "outer-4px" musi byc
przeliczany w CSS przez calc(), zeby koncentrycznosc zostala zachowana
NA KAZDYM viewporcie, nie tylko przy pelnym 1920px desktopie.
*/
.btx-stamp-stepper-btn
{
    width: 32px;
    height: 32px;
    margin: 4px;
    flex-shrink: 0;
    border: none;
    border-radius: calc(var(--btx-radius-control) - 4px);
    background: transparent;
    color: var(--btx-text-primary);
    font-size: 18px;
    font-weight: 700;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.05s ease;
}

@media (hover: hover)
{
    .btx-stamp-stepper-btn:not(:disabled):hover
    {
        background: var(--btx-bg-input);
    }
}

/*
Brakujacy click/tap effect (user: "buttony nie maja click effectu") -
dotad tylko ":hover" (zero feedbacku na dotyk, gdzie hover nie dziala).
PIERWSZA WERSJA uzywala pelnego "--btx-color-primary" (czarny) - user:
"nwm czy taki czarny siedzi bo flashuje to po oczach, inny trzeba click
zrobic" - za ostry, nagly kontrast przy kazdym kliku. Fix: "--btx-border-
hover" (jasnoszary, juz uzywany w module do hover numerkow) - wyraznie
ciemniejszy od ":hover" (`--btx-bg-input`), ale bez ostrego, czarnego
blysku. "scale(0.9)" zostaje - sitewide wzorzec przyciskow ikonowych
(".btx-btn-icon:active" w bento-uikit.css).
*/
.btx-stamp-stepper-btn:not(:disabled):active
{
    background: var(--btx-border-hover);
    transform: scale(0.9);
}

/*
"--btx-text-md"(15px)→"--btx-text-sm"(12px), DRUGA zmiana w tym miejscu
(user: "a jakby w stepperach smniejszyc czcionke?") - odwraca poprzedni
audyt fontow (2026-08-21), ktory swiadomie podbil 12px→15px z tym samym
uzasadnieniem co ponizej (GLOWNY odczyt wartosci steppera, byl
najmniejszym tekstem w rzedzie mimo bycia najwazniejszym). Teraz po
ujednoliceniu szerokosci (`min-width:34px` wyzej) user zdecydowal ze
mniejszy tekst wyglada lepiej - jesli w przyszlosci ktos znajdzie ten
komentarz i zdziwi sie "dlaczego nie md skoro to najwazniejsza wartosc" -
to swiadoma, powtorna decyzja, nie przeoczenie.
*/
/*
"min-width:34px" (user: "zeby oba steppery mialy tyle co ten prawy?") -
bez tego kazdy stepper byl tak szeroki jak jego WLASNA aktualna wartosc
("0%" bylo widocznie wezsze niz "100%"/"24 px" - zmierzone live: 80.7px
vs 95.1px/93.6px), wiec caly rzad wygladal niespojnie i "skakal" przy
kazdej zmianie liczby cyfr. 34px = zmierzona live szerokosc najszerszej
aktualnej wartosci (Interlinia "100%"), wspolna dla wszystkich trzech -
teraz maja identyczna szerokosc calosci NIEZALEZNIE od aktualnej liczby
cyfr (dziala tez w drugą strone - stabilizuje uklad przy przyszlych
wiekszych wartosciach typu "160%").
*/
.btx-stamp-stepper-val
{
    position: relative;
    z-index: 1;
    flex: 1;
    min-width: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
    font-family: var(--btx-font-family);
    font-size: 10px;
    font-weight: 800;
    color: var(--btx-text-primary);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    touch-action: none;
    user-select: none;
}

.btx-stamp-stepper-btn:disabled
{
    opacity: 0.4;
    cursor: not-allowed;
}

/*
Pogrubienie/Kursywa jako dwa kwadratowe przyciski "B"/"I" (ten sam rzad
wysokosci co stepper obok - 40px) zamiast dwoch pelnych przelacznikow -
patrz initStampBiToggles() w JS. Aktywny stan (klasa "is-active" -
odzwierciedla stan ukrytego checkboxa) na pelnym kolorze primary, tak
samo jak inne "aktywne" pigulki/kolka w tym module.
*/
.btx-stamp-bi-group
{
    display: flex;
    gap: 6px;
    height: 40px;
}

.btx-stamp-bi-btn
{
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-secondary);
    font-family: var(--btx-font-family);
    font-size: 15px;
    font-weight: 800;
    cursor: pointer;
}

.btx-stamp-bi-btn.btx-stamp-bi-italic
{
    font-style: italic;
}

.btx-stamp-bi-btn.is-active
{
    background: var(--btx-color-primary);
    border-color: var(--btx-color-primary);
    color: #ffffff;
}

.btx-stamp-bi-btn:disabled
{
    opacity: 0.5;
    cursor: not-allowed;
}

/*
"Pelna szerokosc" reuzywa bazy ".btx-stamp-bi-btn" (kwadrat 40px, ten sam
jezyk co B/I), ale ma w srodku SVG ikone (".btx-stamp-icon") zamiast
liter B/I - te centrowaly sie domyslnym wyrownaniem tekstu przycisku, SVG
(domyslnie "inline") potrzebuje jawnego flex, inaczej nie wysrodkuje sie
tak samo dokladnie.
*/
#btx-stamp-full-width-toggle
{
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
Hover ujednolicony (2026-08-28, user: "w dolnym kafelku co button to inny
hover") - byl "border+tekst→primary" (razem z controls-nav jedyne 2
odstajace od dominujacego jezyka reszty dolnego kafla - bg-input hover,
border-hover active).
*/
@media (hover: hover)
{
    .btx-stamp-bi-btn:not(.is-active):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-bi-btn:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.9);
}

/*
Custom dropdown (2026-08-21, przebudowa na JEDEN element) - natywny
select zostaje w DOM jako jedyne zrodlo prawdy (patrz
initBtxCustomSelect() w JS), tylko wizualnie ukryty. Poprzednie podejscie
(trigger + menu jako dwa OSOBNE elementy "zszywane" wspolnym promieniem/
zero-gapem/dopasowana szerokoscia) przeszlo w tej sesji 4 rundy poprawek
i za kazdym razem znajdowal sie nowy sposob w jaki widac bylo ze to dwa
obiekty (przerwa, cien menu malujacy sie na trigerze, rozjazd promieni w
trakcie animacji) - jedyny naprawde odporny fix to zrobienie tego jako
FAKTYCZNIE jeden element (".btx-stamp-custom-select-panel"). Wiersz z
wartoscia i lista opcji sa teraz DZIECMI tego samego panelu - jeden
border/tlo/promien/cien, wiec fizycznie nie moga sie rozjechac ani zle
namalowac wzgledem siebie.
*/
.btx-stamp-custom-select-native
{
    display: none;
}

/*
".btx-dropdown-container" (reuzywana klasa z menu nawigacji w custom.css)
niesie ze soba "height:100%" - w tym kontenerze rozciagal nasz select na
pelna wysokosc WIERSZA gridu (dopasowana do najwyzszego pola obok,
np. stepper Rozmiaru), po czym panel (faktyczna widoczna pigulka) byl
"align-items:center" wysrodkowany W TEJ rozciagnietej, niewidocznej
ramce - stad wizualnie caly input czcionki siedzial nizej niz reszta
rzedu w dolnym kaflu (user: "wyrownaj input czcionki do 1 linii").
Podwojna klasa w selektorze (0,2,0) gwarantuje wygrana z ".btx-dropdown-
container" (0,1,0) niezaleznie od kolejnosci plikow.
*/
.btx-dropdown-container.btx-stamp-custom-select
{
    width: 100%;
    height: auto;
}

/*
Trigger czcionki przyciety NA STALE, nie tylko w trybie "compact" (user:
"pomniejsz ten input czcionek, mozesz poprostu przycinac nazwe wewnatrz
tego podgladowego" - dopowiedzenie do wczesniejszego fixu ktory mial ten
sam cap, ale TYLKO w compact media query). JS (".btx-stamp-custom-select"
rebuild()) mierzy naturalna szerokosc triggera z NAJDLUZSZEJ opcji na
liscie ("Times New Roman (Tinos)"), nie z aktualnie wybranej wartosci -
bez tego capa nawet krotkie "Arial (Arimo)" dziedziczylo te sama, szeroka
pigulke na KAZDEJ szerokosci ekranu, nie tylko waskiej. "max-width" (inna
wlasciwosc niz "width" ustawiane inline przez JS) przycina bezpiecznie -
".btx-stamp-custom-select-value" ma juz "text-overflow:ellipsis" (baza
pliku wyzej), wiec zamkniety trigger elegancko sie przycina "...". Wolne
miejsce w rzedzie kontrolek (".btx-stamp-controls-grid") mozna teraz
oddac steppero (Rozmiar/Sciśniecie/Interlinia) - patrz kolejne zgloszenie.
*/
/*
 * "max-width:110px" (poprzednia wersja) zostawial dropdown WEZSZY niz
 * jego wlasny grid-track (4 rowne kolumny, "minmax(0,1fr)") - reszta
 * steperow (Rozmiar/Sciśniecie/Interlinia) wypelnia swoja kolumne w
 * 100%, wiec font-dropdown mial widoczna "martwa" przerwe po prawej
 * (user: "ustaw rowne odstepy miedzy inputami... dostosuj szerokosc
 * dropdownu z czcionkami"). Fix: "width:100%" - wypelnia TERAZ dokladnie
 * tyle samo miejsca co sasiednie pola, gap miedzy wszystkimi 4 polami
 * realnie rowny. Wewnetrzny ellipsis (".btx-stamp-custom-select-value")
 * juz istnieje, wiec dlugie nazwy fontow nadal poprawnie sie przycinaja.
 */
.btx-stamp-controls-grid .btx-dropdown-container.btx-stamp-custom-select
{
    max-width: 100%;
}

/*
Panel w normalnym flow gdy zamkniety (przyczynia sie do layoutu jak
zwykly input) - JS przy otwarciu przelacza go na position:fixed
(ucieczka z globalnego overflow:hidden ".btx-tile", zapamietana pozycja
zeby nie bylo skoku) i z powrotem na zamknieciu, patrz openPanel()/
closePanel() w stamp-creator.js.

Promien na sztywno, jednym tokenem "--btx-radius-control" na wszystkich
4 rogach, w kazdym stanie (zamkniety/otwarty/gora/dol) - wczesniejsze
podejscie roznicowalo gorne/dolne rogi osobnymi wartosciami dobranymi pod
POLOWE aktualnej wysokosci triggera (zeby zamkniety stan wygladal jak
pelna, niecapowana pigulka), co bylo krucha zaleznoscia od konkretnego
px triggera. Odkad token jest bezpiecznie mniejszy niz polowa
jakiejkolwiek wysokosci triggera w tym module (40px), nie ma juz ryzyka
capowania - jedna wartosc starczy, niezaleznie od tego czy trigger to
font czy kolor.
*/
/*
"min-width:0" NIEZBEDNY (znaleziony live w DevTools, nie zgadywany) -
".btx-dropdown-container" (baza z custom.css) jest "display:flex", wiec
"panel" (jego jedyne dziecko) to FLEX ITEM z domyslnym "min-width:auto" -
to znaczy ze mimo "overflow:hidden" na etykietach opcji (patrz marquee
nizej w pliku), panel i tak odmawial scurczenia sie ponizej NATURALNEJ
(nieprzycietej) szerokosci najdluzszej opcji, wypychajac cala liste poza
110px kontenera mimo jego "max-width". Klasyczna pulapka flexboksa -
"overflow:hidden" tnie WIDOK, ale nie zmienia wkladu elementu do
min-content ancestora, dopoki jawnie nie wylaczy sie flexowego
"min-width:auto".
*/
/*
"width:100%" DOPISANE - panel jest jedynym dzieckiem ".btx-dropdown-
container" (display:flex), wiec bez jawnej szerokosci flexowy domyslny
"flex:0 1 auto" kurczyl go do naturalnej tresci (etykieta+chevron) zamiast
wypelniac kontener. Niewidoczne dopoki "container.style.width" (JS,
Math.max(naturalWidth, parentWidth)) bylo bliskie naturalWidth (waskie
kolumny gridu) - odsloniete dopiero przy SZEROKIM rodzicu (dropdown
"Jump to category..." w calej szynie modeli), gdzie parentWidth znaczaco
przewyzsza natural, zostawiajac martwe miejsce po prawej stronie pigulki.
*/
.btx-stamp-custom-select-panel
{
    display: block;
    width: 100%;
    min-width: 0;
    background: #ffffff;
    border: 1px solid var(--btx-border-input);
    border-radius: var(--btx-radius-control);
    transition: box-shadow 0.2s ease;
    z-index: 100;
}

.btx-stamp-custom-select.is-open .btx-stamp-custom-select-panel
{
    box-shadow: var(--btx-shadow-dropdown);
}

/*
Rozwijanie w gore (patrz openPanel() w JS) - trigger zostaje WIZUALNIE
na dole (tam gdzie siedziala zamknieta pigulka, kotwiczona przez
"bottom" nie "top"), lista opcji rosnie NAD nim. "column-reverse"
odwraca KOLEJNOSC RENDEROWANIA (dziecko-1=trigger nadal jest pierwsze w
DOM, wiec fokus/tab-order i tak zostaje logiczny), nie porzadek w DOM.
*/
.btx-stamp-custom-select-panel.opens-upward
{
    display: flex;
    flex-direction: column-reverse;
}

.btx-stamp-custom-select.is-open .btx-stamp-custom-select-panel.opens-upward .btx-stamp-custom-select-value-row
{
    border-bottom: none;
    border-top: 1px solid var(--btx-border-color);
}

/*
Wysokosc na sztywno (!important, zeby nadpisac ".btx-dropdown-trigger
{ height:44px }" z custom.css - reuzywana klasa nawigacji) - user zglosil
ze zamkniete pigulki byly za wysokie. 40px = standardowa wysokosc inputu
w calym sklepie (".btx-form-control", patrz rejestr wdrozen). Rozmiar
tekstu podbity z --btx-text-sm na --btx-text-md (user: "tekst jest za
maly").
*/
.btx-stamp-custom-select-value-row
{
    width: 100%;
    height: 40px !important;
    display: flex;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    border-radius: var(--btx-radius-control);
    background: transparent;
    padding: 8px 16px;
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-md);
    font-weight: 600;
    color: var(--btx-text-primary);
    justify-content: space-between;
    align-items: center;
    text-align: left;
    cursor: pointer;
}

.btx-stamp-custom-select.is-open .btx-stamp-custom-select-value-row
{
    border-bottom: 1px solid var(--btx-border-color);
}

.btx-stamp-custom-select-value-row:disabled
{
    opacity: 0.5;
    cursor: not-allowed;
}

/*
Brakujacy hover/active (audyt spojnosci 2026-08-28) - wzorzec transparent-bg
(stepper/D-pad: bg-input na hover, border-hover na active), nie
pill-toggle (brak .is-active/bialego tla u tego komponentu).
"border-radius" wyzej dopisany zeby wypelnienie hover/active nie
wystawalo poza zaokraglone rogi rodzica (".btx-stamp-custom-select-panel").
*/
@media (hover: hover)
{
    .btx-stamp-custom-select-value-row:not(:disabled):hover
    {
        background: var(--btx-bg-input);
    }
}

.btx-stamp-custom-select-value-row:not(:disabled):active
{
    background: var(--btx-border-hover);
}

.btx-stamp-custom-select-value
{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.btx-stamp-custom-select-chevron
{
    width: 12px;
    height: 12px;
    flex-shrink: 0;
    color: var(--btx-text-tertiary);
}

/*
Jedyna animacja w calym komponencie: wysokosc listy opcji z 0 do
naturalnej tresci (scrollHeight liczony w JS przy otwarciu, patrz
openPanel()). BLAD ktory tu byl (znaleziony przez usera - zamkniete
pigulki byly za wysokie): padding NIE MOZE zejsc ponizej swojej
deklarowanej wartosci nawet przy "height:0" (box-sizing:border-box
zapobiega ujemnemu content-box, ale nie kompresuje samego paddingu) -
wiec ten element mial min. ~12px wysokosci mimo "height:0" dopoki padding
siedzial bezposrednio na nim. Padding przeniesiony na wewnetrzny
".btx-stamp-custom-select-options-inner" - TEN element (bez wlasnego
paddingu) faktycznie zwija sie do 0px.
*/
.btx-stamp-custom-select-options
{
    overflow: hidden;
    height: 0;
    transition: height 0.2s ease;
}

.btx-stamp-custom-select-options-inner
{
    padding: 6px;
}

.btx-stamp-custom-select-option
{
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    border: none;
    background: transparent;
    border-radius: var(--btx-radius-sm);
    padding: 9px 10px;
    font-size: var(--btx-text-md);
    font-weight: 500;
    color: var(--btx-text-primary);
    text-align: left;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
}

@media (hover: hover)
{
    .btx-stamp-custom-select-option:hover
    {
        background: var(--btx-bg-input);
        transform: none;
    }
}

/*
Brakujacy :active (audyt spojnosci 2026-08-28) - bez "scale" (pozycja na
liscie, nie samodzielny przycisk - skalowanie calego wiersza wygladaloby
niespojnie z reszta listy), tylko ciemniejsze tlo jak reszta modulu.
*/
.btx-stamp-custom-select-option:active
{
    background: var(--btx-border-hover);
}

.btx-stamp-custom-select-option svg
{
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    color: var(--btx-color-primary);
    visibility: hidden;
}

.btx-stamp-custom-select-option[aria-selected="true"] svg
{
    visibility: visible;
}

/*
Marquee w petli po najechaniu (user: "na wysunietym niech sie przesuwa w
petli po najechaniu") - dla dlugich nazw, ktore nie miesca sie w liscie
(np. czcionek po zmniejszeniu triggera, patrz ".btx-dropdown-container.
btx-stamp-custom-select" nizej w pliku). "label" = okno "overflow:hidden"
o szerokosci dostepnej w rzedzie, domyslnie z JEDNA kopia tekstu
(przycinana zwykle - "white-space:nowrap" tu, nie tylko na torze, bo tor
dobudowuje sie w JS DOPIERO gdy tekst realnie nie miesci sie, patrz
rebuild()). Gdy nie miesci sie, JS podmienia tresc na "track" = dwie
identyczne kopie tekstu obok siebie - animacja jedzie od 0 do -50%
(dokladnie szerokosc JEDNEJ kopii), wiec w momencie skoku z powrotem do
0% druga kopia jest PIKSEL-W-PIKSEL tym samym widokiem co start - zero
widocznego "szarpniecia". ".is-scrollable" wlacza animacje TYLKO wtedy -
krotkie nazwy ("Arial", "Czarny") zostaja pojedyncza, statyczna kopia.
*/
.btx-stamp-custom-select-option-label
{
    flex: 1;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
}

/* Gradientowe zanikanie na krawedziach - ten sam wzorzec/uzasadnienie (w tym korekta "fade tylko z prawej w spoczynku, oba boki dopiero na hover") co ".btx-stamp-canvas-header-model.is-scrollable" wyzej w pliku. */
.btx-stamp-custom-select-option-label.is-scrollable
{
    -webkit-mask-image: linear-gradient(to right, black, black calc(100% - 20px), transparent);
    mask-image: linear-gradient(to right, black, black calc(100% - 20px), transparent);
}

.btx-stamp-custom-select-option-label-track
{
    display: inline-flex;
    white-space: nowrap;
}

.btx-stamp-custom-select-option-label-track span
{
    padding-right: 28px;
}

@media (hover: hover)
{
    .btx-stamp-custom-select-option-label.is-scrollable:hover
    {
        -webkit-mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
        mask-image: linear-gradient(to right, transparent, black 20px, black calc(100% - 20px), transparent);
    }

    .btx-stamp-custom-select-option-label.is-scrollable:hover .btx-stamp-custom-select-option-label-track
    {
        animation: btx-stamp-select-marquee 5s linear infinite;
    }
}

@keyframes btx-stamp-select-marquee
{
    from
    {
        transform: translateX(0);
    }

    to
    {
        transform: translateX(-50%);
    }
}

/*
Szerokosc panelu liczona w JS z realnej tresci - najszerszej z (wiersz
wartosci, kazda opcja) - dla AKTUALNIE zaladowanych danych, NIE zgadywana
na sztywno pod hipotetyczna przyszla liste kolorow (patrz rebuild() w
stamp-creator.js).

Dawniej trigger koloru mial osobny, mniejszy wariant (32px/text-sm) niz
trigger czcionki (40px/text-md) - user: "inputy od kolorow na pewno sa za
male, daj wszystkie inputy narazie na 40px". Wariant koloru usuniety -
oba triggery i tak dzielily ten sam ".btx-stamp-custom-select-value-row",
wiec bez override'u automatycznie dziedziczy baza (40px/text-md) ponizej.
*/

/* panel tresci (prawa) - scroll na .btx-stamp-scroll w srodku, patrz komentarz przy .btx-stamp-rail */
.btx-stamp-panel
{
    grid-area: panel;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/*
2026-08-31, "#btx-stamp-lines-logo-scroll" (ID dopisany przy rozbiciu na
3 panele mobile) zamiast selektora po rodzicu ".btx-stamp-panel" - ten
konkretny scroll (wersy+logo) na mobile fizycznie przenosi sie do
"#btx-stamp-mobile-panel3" (patrz "syncStampMobileTabs()"), wiec selektor
po ID dziala IDENTYCZNIE bez wzgledu na to, w ktorym rodzicu aktualnie
siedzi (desktop: ".btx-stamp-panel", mobile: "#btx-stamp-mobile-panel3").
*/
#btx-stamp-lines-logo-scroll
{
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-xs);
}

.btx-stamp-lines
{
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-xs);
}

/*
Pager kart wersow w prawym panelu USUNIETY (2026-08-27, user: "ten
licznik wersow i przelaczanie calkiem wypierdol z prawego panelu") -
panel renderuje teraz wszystkie karty naraz, scrolluje sie jak reszta.
Pager "SELECT LINE" ponizej canvasu to inny mechanizm, zostaje bez zmian.
*/

/*
Plaski wiersz, bez ramki/tla karty (user: "wyjebiemy ramki itd") -
przelaczanie ktory wers edytowac stylem przeniesione do strzalek w
dolnym kaflu controls, ten panel to juz tylko edycja tekstu (nr/input/
kosz), wiec nie potrzebuje wygladu "klikalnej karty".
*/
.btx-stamp-line-card
{
    display: flex;
    align-items: center;
    gap: var(--btx-spacing-xs);
    padding: var(--btx-spacing-xs) 0;
    border-bottom: 1px solid var(--btx-border-color);
}

.btx-stamp-line-card:last-child
{
    border-bottom: none;
}

/*
Podbite z 20px do 40px (user: "ten numerek obok wersu tez powinien miec
40px") - dolaczyl do reszty ujednoliconej siatki kontrolek w tym module.
Promien wrocil do "--btx-radius-control" (byl "--btx-radius-sm" specjalnie
dobrany pod stary, maly 20px box - przy 40px nie ma juz ryzyka capowania,
wiec ten sam token co inne kwadratowe 40px kontrolki, np. ".btx-stamp-
line-action" obok). Tekst przy audycie fontow (2026-08-21) tez podbity
"--btx-text-sm"→"--btx-text-md" - ten sam rozmiar co konceptualnie
analogiczny "numerek wersu" w dolnym kaflu (".btx-stamp-controls-dot"),
zeby oba miejsca pokazujace numer aktywnego wersu wygladaly tak samo
wazne.
*/
.btx-stamp-line-num
{
    position: relative;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--btx-radius-control);
    background: var(--btx-bg-input);
    color: var(--btx-text-tertiary);
    font-size: var(--btx-text-md);
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.btx-stamp-line-card.is-active .btx-stamp-line-num
{
    background: var(--btx-color-primary);
    color: #ffffff;
}

/*
Cyfra aktywnego wersu = uchwyt do przeciagania, NA STALE (user: "chodzi
mi o to zeby ikona byla na wybranym caly czas" - doprecyzowanie do
pierwszej wersji, ktora pokazywala chwytak tylko na hover/w trakcie
przeciagania). Cyfra i ikona chwytaka naklejone na siebie (oba
"position:absolute", rodzic "position:relative" ustawiony wyzej) -
przelaczane sama opacity wedlug ".is-active", zero przeplywu layoutu.
*/
.btx-stamp-line-num-digit,
.btx-stamp-line-num-grip
{
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.btx-stamp-line-num-grip
{
    opacity: 0;
}

.btx-stamp-line-num-grip .btx-stamp-icon
{
    width: 16px;
    height: 16px;
    fill: currentColor;
    stroke: none;
}

.btx-stamp-line-card.is-active .btx-stamp-line-num
{
    touch-action: none;
}

.btx-stamp-line-card.is-active .btx-stamp-line-num-digit
{
    opacity: 0;
}

.btx-stamp-line-card.is-active .btx-stamp-line-num-grip
{
    opacity: 1;
}

.btx-stamp-line-card.is-dragging
{
    position: relative;
    z-index: 20;
    box-shadow: var(--btx-shadow-tile, 0 8px 20px rgba(0, 0, 0, 0.12));
    background: #ffffff;
    border-bottom-color: transparent;
    border-radius: var(--btx-radius-control);
    padding-left: var(--btx-spacing-xs);
    padding-right: var(--btx-spacing-xs);
    cursor: grabbing;
}

.btx-stamp-line-card:not(.is-dragging)
{
    transition: transform 0.15s ease;
}

/*
Klikniecie numerka przelacza aktywny wers (user: "niech kliknieccie w
numerek w prawym panelu tez przelacza wers aktywny") - ten sam mechanizm
co focus na inpucie (patrz buildLineCard() w JS), teraz dostepny tez bez
wchodzenia w edycje tekstu. Hover tylko na nieaktywnym numerku - aktywny
juz ma pelne primary tlo, nie potrzebuje dodatkowej wskazowki.
*/
@media (hover: hover)
{
    .btx-stamp-line-num:hover
    {
        background: var(--btx-border-input);
    }

    .btx-stamp-line-card.is-active .btx-stamp-line-num:hover
    {
        background: var(--btx-color-primary-hover, var(--btx-color-primary));
        cursor: grab;
    }
}

/*
".btx-tile input[type='text']" w bento-account.css narzuca globalny
wyglad inputa z !important na kazdej wlasciwosci (w tym border-radius:
--btx-radius-pill) - wygrywalo to z ta regula mimo ustawionego tokenu,
stad realnie renderowal sie pill. Wysokosc/padding/tlo/border z tamtej
reguly (40px, --btx-bg-input, --btx-border-input) sa spojne z reszta
UI kitu, wiec zostawiamy je - przebijamy !important tylko tam gdzie
kreator ma byc inny (zaokraglenie, kolor tekstu wpisywanej tresci).
Sam !important nie wystarczyl - selektor musi tez miec specyficznosc
>= (0,2,1) tamtej reguly, stad dluzszy lancuch klas zamiast samego
".btx-stamp-line-input".
*/
/*
2026-08-31: "#btx-stamp-lines" (ID) zamiast rodzica ".btx-stamp-panel" -
przy rozbiciu na 3 panele mobile "#btx-stamp-lines" przenosi sie do
"#btx-stamp-mobile-panel3", ID-owy selektor dziala niezaleznie od
aktualnego rodzica (i ma WYZSZA specyficznosc niz usuniety lancuch 3
klas, wiec fix wyzej dalej bezpiecznie przebija kolidujacy !important).

🐛→✅ Realny bug znaleziony live (user: "input wersu nadal jest pill
shape... wgl brakuje stylow"): powyzszy komentarz mylnie zakladal ze
"height/padding/tlo/border sa spojne, zostawiamy je" - to prawda TYLKO
gdy input realnie ma przodka ".btx-tile" (selektor bazowy to
".btx-tile input[type='text']"). Po rozbiciu na 3 panele mobile input
siedzi w "#btx-stamp-mobile-panel2/3" (zwykle "<div>", NIE ".btx-tile")
- na mobile ZERO przodkow z ta klasa, wiec cala bazowa regula PRZESTAJE
DOTYCZYC tego inputa (nie tylko border-radius, WSZYSTKO: wysokosc,
padding, tlo, border, font-size). Realny skutek: input dostawal
domyslny padding przegladarki (~1px 2px) i wysokosc ~26px - przy takiej
wysokosci NASZ WLASNY promien (16px) jest wizualnie przycinany przez
przegladarke do polowy wysokosci (~13px), czyli wyglada jak pelna
pigulka, mimo ze CSS deklaruje poprawna wartosc. DRUGI, powazniejszy
skutek: brak wymuszonego "font-size:16px" - na iOS Safari input z
font-size <16px wyzwala AUTOMATYCZNY ZOOM strony przy fokusie, co
najpewniej tlumaczy TEZ zglaszany bug "po odpaleniu klawiatury canvas
wywala poza ekran" (viewport nagle sie skaluje, cala geometria liczona
w JS przestaje sie zgadzac). Fix: caly zestaw wlasciwosci z bazowej
reguly przepisany TU wprost (nie polegamy juz na dziedziczeniu przez
".btx-tile", ktorego na mobile nie ma).
*/
#btx-stamp-lines input.btx-stamp-line-input
{
    flex: 1;
    min-width: 0;
    width: 100%;
    max-width: 100%;
    height: 40px;
    padding: 0 18px;
    background: var(--btx-bg-input);
    border: 1px solid var(--btx-border-input);
    border-radius: var(--btx-radius-control) !important;
    color: var(--btx-text-primary) !important;
    font-family: var(--btx-font-family);
    font-size: 16px;
    font-weight: 600;
    outline: none;
    box-shadow: none;
    appearance: none;
    -webkit-appearance: none;
}

.btx-stamp-line-actions
{
    display: flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
}

.btx-stamp-line-action
{
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.btx-stamp-line-action.is-remove:hover
{
    color: var(--btx-color-danger);
    border-color: var(--btx-color-danger);
}

/*
Wyrownane do prawdziwego stylu przyciskow UI Kitu (".btx-btn-secondary"
w bento-uikit.css: pelne tlo, ciagly border na "--btx-border-input",
pigulka) - user: "buttony od logo i dodawania wiersza sa ledwo widoczne
i nijak sie maja do ui kitu". Wczesniej: przerywana ramka na najjasniejszym
"--btx-border-color" + przezroczyste tlo = wygladalo jak nieaktywny
placeholder, nie klikalny przycisk.
*/
.btx-stamp-add-line
{
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: center;
    width: 100%;
    height: 40px;
    /* bez tego flex-column (".btx-stamp-scroll") sciskal wysokosc ponizej 40px gdy duzo wersow nie miesci sie w widoku (user: "niech ma stala wysokosc a nie zmniejsza sie") */
    flex-shrink: 0;
    padding: 0 16px;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-input);
    background: #ffffff;
    color: var(--btx-text-secondary);
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    cursor: pointer;
    margin-top: 2px;
}

@media (hover: hover)
{
    .btx-stamp-add-line:not(:disabled):hover
    {
        background: var(--btx-bg-input);
        border-color: currentColor;
        color: var(--btx-text-primary);
    }
}

.btx-stamp-add-line:disabled
{
    opacity: 0.4;
    cursor: not-allowed;
}

.btx-stamp-line-warning
{
    display: none;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--btx-color-warning);
}

.btx-stamp-line-warning.is-visible
{
    display: flex;
}

.btx-stamp-overflow-warning
{
    display: none;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    background: var(--btx-color-danger-light);
    color: #b91c1c;
    border: 1px solid rgba(220, 38, 38, 0.15);
    border-radius: var(--btx-radius-lg);
    font-size: var(--btx-text-body);
    font-weight: 600;
}

.btx-stamp-overflow-warning svg
{
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}

.btx-stamp-overflow-warning.is-visible
{
    display: flex;
}

/*
Przelacznik "Cały automat" / "Sama gumka" (Krok 2 integracji gumki -
[[project-stamp-creator-module]]) - ten sam wzorzec pigulek co filtr
marki w railu (".btx-stamp-brand-filter-btn"), zeby nie wymyslac nowego
stylu dla identycznego "dwuopcjowego przelacznika".
*/
.btx-stamp-variant-toggle,
.btx-stamp-source-toggle
{
    display: flex;
    gap: 6px;
}

/*
"margin-bottom" TYLKO na variant-toggle, nie na obu naraz (2026-08-28,
user: "w dolnym kafelku... popraw spacingi", zrzut ekranu pokazywal 24px
nad separatorem vs 8px pod nim) - source-toggle jest NAD separatorem,
ktory ma juz WLASNY "margin:8px 0" - oba sa bezposrednimi dziecmi flexa
".btx-stamp-panel" (marginesy MIEDZY flex-itemami sie NIE zwijaja, tylko
sumuja), wiec dawny wspolny "margin-bottom:16px" na source-toggle DODAWAL
SIE do 8px separatora (24px), podczas gdy pod separatorem byle jego wlasne
8px zostawaly same (bo variant-toggle nie ma margin-top). Variant-toggle
(pod nim NIE ma separatora, tylko ".btx-stamp-scroll" z lista wersow)
nadal potrzebuje pelnych 16px odstepu - dostaje je tu, osobno.
*/
.btx-stamp-variant-toggle
{
    margin-bottom: var(--btx-spacing-sm);
}

.btx-stamp-variant-btn,
.btx-stamp-source-btn
{
    flex: 1;
    height: 40px;
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-color);
    background: #ffffff;
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    color: var(--btx-text-secondary);
    cursor: pointer;
}

.btx-stamp-variant-btn.is-active,
.btx-stamp-source-btn.is-active
{
    background: var(--btx-color-primary);
    color: #ffffff;
    border-color: var(--btx-color-primary);
}

/*
Brakujacy hover/active (audyt spojnosci 2026-08-28) - ten sam wzorzec co
".btx-stamp-pos-btn"/".btx-stamp-brand-filter-btn" wyzej (identyczna
struktura, dzielona regula zrodlowa dla obu przelacznikow).
*/
@media (hover: hover)
{
    .btx-stamp-variant-btn:not(.is-active):hover,
    .btx-stamp-source-btn:not(.is-active):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-variant-btn:not(.is-active):active,
.btx-stamp-source-btn:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.95);
}

/*
"margin:16px 0" (bylo 8px, user 2026-08-28: "daj wszedzie po 16") - ten
sam token co reszta wiekszych odstepow miedzy sekcjami w prawym panelu
(np. margin-bottom variant-toggle przed lista wersow), zeby WSZYSTKIE
odstepy wokol separatorow (i miedzy nimi a sasiadujacymi sekcjami) byly
jednolite 16px, niezaleznie od tego czy kontekst to flex (marginesy sie
sumuja) czy normalny block-flow (marginesy sie zwijaja) - oba przypadki
przeliczone i zweryfikowane, patrz rejestr wdrozen.
*/
.btx-stamp-divider
{
    /* "1px" (bylo 2px, user 2026-08-28: "separatory sa za grube i w prawym i lewym panelu") - dopasowane do rail-section-header::before/::after w lewym panelu, ten sam token koloru */
    height: 1px;
    background: var(--btx-neutral-300);
    margin: var(--btx-spacing-sm) 0;
}

/*
Kontrast podbity tak samo jak ".btx-stamp-add-line" wyzej (user: "buttony
od logo... ledwo widoczne") - zostaje przerywana ramka (uniwersalny
sygnal "tu upusc/wgraj plik", w odroznieniu od pelnego przycisku akcji),
ale na ciemniejszym "--btx-border-input" zamiast najjasniejszego tokenu,
plus wyrazniejszy tekst i wlasny hover.

Rozmiar tekstu ("--btx-text-body", 14px) byl niespojny z ".btx-stamp-
add-line" obok (12px, "--btx-text-sm") - oba to ten sam typ komponentu
(uppercase, bold, przycisk akcji w prawym panelu), wiec przy audycie
rozmiarow fontow (2026-08-21) ujednolicone do tego samego "--btx-text-sm".
*/
.btx-stamp-dropzone
{
    border: 1.5px dashed var(--btx-border-input);
    border-radius: var(--btx-radius-control);
    padding: var(--btx-spacing-md);
    text-align: center;
    color: var(--btx-text-secondary);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    cursor: pointer;
}

@media (hover: hover)
{
    .btx-stamp-dropzone:hover
    {
        border-color: var(--btx-color-primary);
        color: var(--btx-text-primary);
    }
}

/*
Brakujacy :active (audyt spojnosci 2026-08-28) - duzy, pelnoszeroki
element (nie mala ikonka), wiec subtelniejszy "scale(0.98)" niz
icon-buttony (0.9) - te same 2 wlasciwosci co hover (border+tekst) plus
lekkie tlo, zeby klikniecie bylo namacalne rowniez na dotyk.
*/
.btx-stamp-dropzone:active
{
    border-color: var(--btx-color-primary);
    color: var(--btx-text-primary);
    background: var(--btx-bg-input);
    transform: scale(0.98);
}

.btx-stamp-dropzone.has-logo
{
    border-style: solid;
    border-color: var(--btx-color-primary);
    color: var(--btx-text-primary);
}

.btx-stamp-logo-controls
{
    display: flex;
    flex-direction: column;
    gap: var(--btx-spacing-sm);
    margin-top: var(--btx-spacing-sm);
}

/*
D-pad po jednej stronie, reszta kontrolek (Rozmiar logo + Pozycja) po
drugiej (user: "daj po 1 str dpad a po 2 wszystkie buttony i steper") -
D-pad ma stala szerokosc (114px, dopasowana do wlasnego SVG), kolumna
obok dostaje reszte miejsca ("flex:1").
*/
.btx-stamp-logo-controls-row
{
    display: flex;
    gap: var(--btx-spacing-md);
    align-items: flex-start;
}

/* D-pad i Pozycja rozsuniete na krance rzedu (nie rozciagniete same przyciski - patrz komentarz przy ".btx-stamp-logo-position-field" nizej) */
.btx-stamp-logo-dpad-row
{
    justify-content: space-between;
}

/*
Layout przebudowany (2026-08-27, user): oba steppery ("Logo size",
"Divider position") teraz w jednym rzedzie NAD D-padem
(".btx-stamp-logo-steppers-row" - kazde pole "flex:1", rowna szerokosc),
a "Position" jako siatka 2x2 PO PRAWEJ stronie D-pada (nie pod nim) -
gorny rzad Left/Right, dolny Top/Center (kolejnosc w HTML odpowiada
kolejnosci czytania gridu). ".btx-stamp-logo-controls-col" (dawny
wspolny wrapper dla stepperow+pozycji w jednej kolumnie obok D-pada) juz
nieuzywany, usuniety.
*/
.btx-stamp-logo-steppers-row .btx-stamp-control-field
{
    flex: 1;
    min-width: 0;
}

/*
Trzecia (finalna) wersja rozmiaru przyciskow Pozycji (user 2026-08-27:
"wysokosc: taka jak inne buttony, szerokosc: dopasowana do miejsca
dostepnego") - D-pad ma STALY rozmiar 114px (user: "dpada nie ruszaj"),
pole Pozycji ROSNIE ("flex:1") i wypelnia reszte rzedu na szerokosc, ale
WYSOKOSC siatki jest juz NIEZALEZNA od D-pada - stale 2x40px (ten sam
standard co reszta przyciskow modulu, np. ".btx-stamp-add-line"), nie
114px/2.
*/
.btx-stamp-logo-dpad-field
{
    flex-shrink: 0;
}

.btx-stamp-logo-position-field
{
    flex: 1;
    min-width: 0;
}

.btx-stamp-pos-grid
{
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(2, 40px);
    gap: var(--btx-spacing-md);
    width: 100%;
    margin-top: 8px;
}

/*
Ikony zamiast tekstu (user: "moze zmienmy te buttony lewo prawo na
jakies ikonki") - kazda ikona to mini-diagram (kwadrat=logo, linie=tekst)
pokazujacy DOKLADNIE co dana opcja robi, bez potrzeby czytania podpisu
(podpis zostaje w aria-label/title dla dostepnosci). "display:flex"
potrzebny do wysrodkowania SVG - tekst centrowal sie przez
"text-align:center", ikona (domyslnie "inline") tego nie robi.
*/
/*
Siatka 2x2 (".btx-stamp-pos-grid" wyzej) zamiast rzedu 4 przyciskow -
kazdy przycisk to teraz komorka gridu, wypelnia ja calkowicie
(domyslne "align-items:stretch" gridu), bez sztywnego "height:40px"
(niepasujacego do wysokosci komorki 114px/2) ani "flex:1" (bez efektu
w kontekscie gridu).
*/
.btx-stamp-pos-btn
{
    padding: 8px;
    border-radius: var(--btx-radius-control);
    border: 1px solid var(--btx-border-color);
    background: #ffffff;
    color: var(--btx-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

/*
Brakujacy stan hover (user: "hovery d pada nie maja marginow i nie sa
zaokraglone" - przy audycie wyszlo ze ".btx-stamp-pos-btn" nie mial
ZADNEGO hovera, tylko ".is-active"). Ten sam wzorzec co D-pad
(--btx-bg-input w spoczynku/hover, --btx-border-hover na active) - ":not(.is-active)"
zeby hover nie przebijal wizualnie juz aktywnego (podswietlonego) przycisku.
*/
@media (hover: hover)
{
    .btx-stamp-pos-btn:not(.is-active):hover
    {
        background: var(--btx-bg-input);
        border-color: var(--btx-border-hover);
    }
}

.btx-stamp-pos-btn:not(.is-active):active
{
    background: var(--btx-border-hover);
    transform: scale(0.95);
}

.btx-stamp-pos-btn.is-active
{
    background: var(--btx-color-primary);
    color: #ffffff;
    border-color: var(--btx-color-primary);
}

/* Ten sam wzorzec co ".btx-stamp-remove-bg-toggle" (pigulka z ikona), ale w tonacji "danger" - to usuwa logo CALKOWICIE, wiec ma wygladac bardziej konsekwentnie niz zwykly szary toggle (user: "button usun logo zrob jakis ladny" - poprzednio: goly tekst bez tla/ramki/paddingu). */
.btx-stamp-remove-logo
{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--btx-spacing-xs);
    width: 100%;
    margin-top: var(--btx-spacing-sm);
    padding: 8px 12px;
    border: 1px solid var(--btx-color-danger);
    border-radius: var(--btx-radius-control);
    background: transparent;
    color: var(--btx-color-danger);
    font-family: var(--btx-font-family);
    font-size: var(--btx-text-sm);
    font-weight: 700;
    cursor: pointer;
}

.btx-stamp-remove-logo .btx-stamp-icon
{
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

@media (hover: hover)
{
    .btx-stamp-remove-logo:hover
    {
        background: var(--btx-color-danger);
        color: #ffffff;
    }
}

/*
Brakujacy :active (audyt spojnosci 2026-08-28) - BEZ "@media (hover:hover)"
celowo, w odroznieniu od hovera powyzej - na dotyku hover nigdy sie nie
uruchamia, wiec bez tego klikniecie na telefonie nie dawaloby ZADNEGO
efektu wizualnego na tym (destrukcyjnym) przycisku. Sam "scale" (bez
zmiany koloru) - nie ma sensownego "ciemniejszego czerwonego" tokenu w
palecie, a hover i tak juz zapewnia pelne czerwone tlo na urzadzeniach
z myszka.
*/
.btx-stamp-remove-logo:active
{
    transform: scale(0.97);
}

/*
D-pad zamiast dwoch osobnych stepperow (poziomy widoczny + pionowy
schowany za usunietym juz "Wiecej ustawien") - user: "to przesuwanie logo
to chyba d-pad bedzie lepszy" → doprecyzowanie: D-pad OBOK kotwic Left/
Top/Right (nie zamiast), jako doszlifowanie pozycji po wybraniu kotwicy.
Kazdy przycisk to pojedyncze klikniecie = nudge o 5% w danym kierunku
(logika kierunku w JS, patrz initLogoDpad()).

Ksztalt PRAWDZIWEGO krzyza (user: "nie no taki krzyzyk", "zaokraglony",
"ten w srodku kwadracik tez zaokraglij") - nie 4 osobne kafelki z
odstepami (pierwsza proba), tylko JEDNA, zlaczona bryla. Zamiast CSS
"clip-path:path()" (niepewne wsparcie w Safari, jedynej wspieranej
przegladarce w tym projekcie) - dekoracyjny SVG w tle (12 zaokraglonych
rogow krzyza przez luki "Q", plus zaokraglony kwadracik na srodku gdzie
sie krzyzuja ramiona) rysuje CALY ksztalt/obrys/promien, "pointer-events:
none" zeby nie przeszkadzal klikaniu. 4 prawdziwe przyciski siedza NA
WIERZCHU (przezroczyste w spoczynku, wiec widac biale tlo SVG pod spodem)
- kazdy zaokraglony TYLKO na swoich dwoch zewnetrznych rogach (promien 10,
pasujacy do SVG), wewnetrzne rogi (przy zbiegu ramion) zostaja proste -
niewidoczne minus w praktyce, bo to tylko 10px naroznik hover/active tla,
nie sam obrys.
*/
.btx-stamp-logo-dpad
{
    position: relative;
    width: 114px;
    height: 114px;
    margin: 8px auto 0;
    display: grid;
    grid-template-columns: repeat(3, 38px);
    grid-template-rows: repeat(3, 38px);
}

.btx-stamp-logo-dpad-shape
{
    position: absolute;
    top: 0;
    left: 0;
    width: 114px;
    height: 114px;
    fill: #ffffff;
    stroke: var(--btx-border-input);
    stroke-width: 1px;
    pointer-events: none;
}

.btx-stamp-logo-dpad-shape rect
{
    fill: none;
    stroke: var(--btx-border-color);
    stroke-width: 1px;
}

/*
Dwie wersje tla D-pada (promien 16/14px) zamiast jednej sztywnej (byla
10px, niespojna z reszta tokenu "--btx-radius-control" - user zauwazyl
niespojnosc "pozycja logo" vs D-pad). SVG "d" nie moze czytac zmiennej
CSS, wiec zamiast dynamicznej regeneracji - DWIE gotowe sciezki
(wygenerowane parametrycznie z tych samych wzorow co oryginal, R=16/14),
przelaczane TA SAMA binarna media query co reszta tokenow radius (patrz
nizej w pliku) - promien przycisku (border-radius) i promien tla (SVG)
zawsze zmieniaja sie razem.
*/
.btx-stamp-logo-dpad-shape-compact
{
    display: none;
}

.btx-stamp-dpad-btn
{
    position: relative;
    border: none;
    background: transparent;
    color: var(--btx-text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.btx-stamp-dpad-btn .btx-stamp-icon
{
    width: 18px;
    height: 18px;
}

/*
"margin:4px" (2026-08-28, user: "ksztalt ok ale sa za duze") - bez tego
przyciski wypelnialy CALA komorke gridu 38x38 krawedz-w-krawedz, wiec
wypelnienie hover/active wygladalo nieproporcjonalnie duze na tle
stepperow (tam identyczny margines 4px na 40px torze daje 32px przycisk).
Dotyczy TYLKO zewnetrznych 4 (up/left/right/down) - user nie zglosil ze
srodek tez jest za duzy, tylko ze ma za maly promien (patrz nizej).
*/
.btx-stamp-dpad-up
{
    grid-column: 2;
    grid-row: 1;
    margin: 4px;
    border-radius: calc(var(--btx-radius-control) - 4px);
}

.btx-stamp-dpad-left
{
    grid-column: 1;
    grid-row: 2;
    margin: 4px;
    border-radius: calc(var(--btx-radius-control) - 4px);
}

.btx-stamp-dpad-right
{
    grid-column: 3;
    grid-row: 2;
    margin: 4px;
    border-radius: calc(var(--btx-radius-control) - 4px);
}

.btx-stamp-dpad-down
{
    grid-column: 2;
    grid-row: 3;
    margin: 4px;
    border-radius: calc(var(--btx-radius-control) - 4px);
}

/*
Srodek D-pada = reset nudge do 50/50 (patrz JS initLogoDpad()). Promien
"var(--btx-radius-control)" (16px/14px) - user chcial WIEKSZY promien,
ale konkretnie na TRWALE WIDOCZNYM tle (SVG "<rect rx>" w
".btx-stamp-logo-dpad-shape" w .tpl, widoczne w spoczynku - dopisane
osobno, promien CSS buttona sam w sobie jest niewidoczny bez tla), NIE
na samym hoverze - hover dostal wlasny dopisek nizej ("za duzy" -
margines).

"margin:4px" (doprecyzowanie tego samego dnia, user: "co do jego hovera
to jest za duzy") - dokladnie ten sam wzorzec co juz zastosowany do
up/left/right/down - box hover kurczy sie z pelnej komorki 38x38 do
30x30, wpasowuje sie WEWNATRZ trwale widocznego, wiekszego kwadratu SVG
(rx=16) zamiast wypelniac go krawedz-w-krawedz.
*/
.btx-stamp-dpad-center
{
    grid-column: 2;
    grid-row: 2;
    margin: 4px;
    border-radius: var(--btx-radius-control);
}

.btx-stamp-dpad-center .btx-stamp-icon
{
    width: 16px;
    height: 16px;
}

/*
Zdublowany blok hover/active usuniety (byl identyczny dwa razy, jedyna
roznica - "active" scale 0.92 vs 0.9 - poniewaz kaskada rozstrzygala na
korzysc pozniejszego bloku, realnie i tak zawsze dzialalo 0.9; ten
duplikat byl martwym kodem).
*/
@media (hover: hover)
{
    .btx-stamp-dpad-btn:not(:disabled):hover
    {
        background: var(--btx-bg-input);
    }
}

.btx-stamp-dpad-btn:not(:disabled):active
{
    background: var(--btx-border-hover);
    transform: scale(0.9);
}

.btx-stamp-dpad-btn:disabled
{
    opacity: 0.4;
    cursor: not-allowed;
}

/*
D-pad/Pozycja "compact" - tylko tlo SVG (dekoracyjne, "pointer-events:
none") przelacza sie na wersje z mniejszym promieniem (14px), zeby
wizualnie pasowac do reszty tokenow trybu compact. Promien SAMYCH
przyciskow (border-radius) juz NIE wymaga tu osobnego override'u odkad
uzywa "calc(var(--btx-radius-control) - 4px)" (patrz regula bazowa
wyzej) - token sam przelacza sie 16px→14px w tej samej media query
(patrz baza pliku), wiec wartosc przycisku podaza za nim automatycznie.
*/
@media (min-width: 992px) and (max-width: 1700px),
       (min-width: 992px) and (max-height: 820px)
{
    .btx-stamp-logo-dpad-shape-full
    {
        display: none;
    }

    .btx-stamp-logo-dpad-shape-compact
    {
        display: block;
    }
}

.btx-stamp-icon
{
    width: 16px;
    height: 16px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
}

@media (hover: hover)
{
    .btx-stamp-rail-item:not(.is-selected):hover
    {
        background: #ffffff;
    }

    .btx-stamp-line-action:hover
    {
        color: var(--btx-text-secondary);
    }
}

/*
Wersja mobile/tablet - historia decyzji o pozycjonowaniu canvasu:

1) "position:sticky" (pierwsza proba, 2026-08-28) NIE ZADZIALAL -
zweryfikowane live (canvas uciekal calkowicie ze scrollem zamiast sie
zatrzymac). Przyczyna: ".btx-product-page"/"main" (przodkowie POZA
modulem, w rdzeniu szablonu) maja "overflow-x:hidden" - to LICZY SIE
dla przegladarki jako "kontener przewijania" przy wyliczaniu "stuck"
nawet gdy w praktyce nic w nim nie przewija, co psuje pozycjonowanie
sticky wzgledem realnego viewportu.

2) "position:fixed" + reczne JS-owe domierzanie "top"/"left"/"width" +
osobny "spacer" rezerwujacy miejsce w ukladzie + chowanie canvasu na
czas klawiatury (2026-08-28 do 2026-08-31) - DZIALAL na desktopie w
symulacji, ale zrodlil cala serie realnych bugow na prawdziwych iOS
Safari, wszystkie ze wspolnego zrodla: "position:fixed" jest
zakotwiczone wzgledem LAYOUT viewportu, ktory NIE odzwierciedla tego co
user faktycznie widzi (VISUAL viewport) gdy klawiatura jest otwarta/w
trakcie animacji. Objawy: canvas "uciekal" poza ekran przy otwieraniu
klawiatury, byl widoczny przez ulamek sekundy w zlym miejscu przy
swiezym zaladowaniu strony, wysokosc panelu zakladek ponizej byla zle
liczona przy DRUGIM i kolejnych otwarciach klawiatury. Po kilku rundach
lataniania kolejnych przypadkow brzegowych (patrz `03-REJESTR_WDROZEN.md`,
wpisy z 2026-08-31) - user: "scalmy canvas z kafelkiem w 1 kafelek".

3) OBECNIE (2026-08-31): canvas jest zwyklym, GORNYM dzieckiem tej samej
karty co zakladki (".btx-stamp-mobile-card", wstawiany tam przez JS w
"syncStampMobileTabs()") - zero wlasnego pozycjonowania, scrolluje sie
razem z reszta karty jak KAZDY inny element w normalnym przeplywie.
Cala klasa bugow z punktu 2 znika razem z mechanizmem ktory je
powodowal - kompromis: canvas juz nie zostaje "przyklejony" w polu
widzenia przy scrollowaniu ponizej niego (user zaakceptowal ten
kompromis jako lepszy niz kruchosc poprzedniego rozwiazania).
*/
@media (max-width: 991px)
{
    /*
    Grid -> flex column (2026-08-28, druga iteracja mobile - user: "zakladki
    Wybor automatu/Controls na swipe horizontal, dolny kafelek wypelnia do
    granicy ekranu, scroll TYLKO wewnatrz obu kafelkow"). Grid-area
    wymagaloby ze kazdy JS-owy wrapper (nav zakladek, viewport swipe'a,
    pasek stopki) tez dostal jakis "grid-area" - flex column ustawia
    kolejnosc po prostu POZYCJA W DOM (JS wstawia elementy we wlasciwym
    miejscu przez insertBefore/appendChild), prostsze przy dynamicznym
    przenoszeniu wielu elementow.
    */
    .btx-stamp-cockpit
    {
        display: flex;
        flex-direction: column;
        height: auto;
        /*
        Bazowa (desktopowa, grid) regula ".btx-stamp-cockpit" ustawia
        "gap: var(--btx-gap-lg)" - w tym flex-column ukladzie dokladalo
        sie to jako dodatkowa 16px przerwa MIEDZY spacerem canvasu a
        ".btx-stamp-mobile-card" (ktora ma juz WLASNY "margin-top:12px"),
        wiec odstep byl podwojnie liczony. Zerujemy, zeby odstepy pod
        canvasem kontrolowaly wylacznie marginesy poszczegolnych bloków.
        */
        gap: 0;
        /*
        2026-09-01, user: "nadal jest tam jakis element, i nie jest tak
        nisko jak powinno" + caly ciag "nie wraca w pierwotne polozenie"
        po zamknieciu klawiatury. ZMIERZONE na zywo (zdalny inspektor):
        kokpit konczy sie na 696px przy "innerHeight" 695px - czyli
        IDEALNIE - ale bazowa (desktopowa) regula ".btx-stamp-cockpit"
        ustawia "margin-bottom: 60px", ktorego ten mobilny blok nigdy nie
        zerowal. Ten margines rozciagal dokument do 756px, dajac ~60px
        PUSTEJ przestrzeni pod karta (widoczny "element"/ciemny pas) - i,
        co wazniejsze, byl JEDYNYM powodem dla ktorego strona w ogole
        MOGLA sie przewinac. Dlatego iOS po schowaniu klawiatury nie
        wracal do zera: mial legalne ~40px zapasu, na ktorym mogl
        wyladowac. Zerujemy - dokument = wysokosc ekranu, zero zapasu
        scrolla, wiec natywny mechanizm nie ma juz GDZIE zostawic
        offsetu (fix strukturalny, zamiast walki JS-em ze scrollem -
        patrz [[feedback-mobile-simplicity]]).
        */
        margin-bottom: 0;
    }

    /*
    2026-08-31, user (zrzut ekranu): "jak sie strona laduje to na ulamek
    sekundy widac takie gowno" - miedzy pierwszym malowaniem strony a
    momentem gdy JS skonczy skladac mobilny uklad (dopiero PO async
    fetchu modeli - patrz "syncStampMobileLayout()" w stamp-creator.js)
    przegladarka przez chwile maluje SUROWY markup z .tpl: rail/canvas/
    controls/panel jako 4 OSOBNE, niepolaczone bloki jedne pod drugim,
    kazdy w swoim bazowym (desktopowym) wygladzie - widoczny, brzydki
    "flash" nakladajacych sie/nieposkladanych elementow. Fix: kokpit
    schowany ("visibility:hidden", NIE "display:none" - ten drugi
    zerowalby wysokosc i psul scroll/measure w JS dzialajacym w tle,
    podczas gdy "visibility" tylko czyni go niewidocznym, ale nadal
    "obecnym" dla layoutu/pomiarow) dopoki JS nie dopisze klasy
    ".btx-stamp-mobile-ready" (koniec PIERWSZEGO udanego przebiegu
    "syncStampMobileLayout()") - user widzi od razu gotowy, poskladany
    uklad zamiast posredniego, "surowego" stanu.
    */
    .btx-stamp-cockpit:not(.btx-stamp-mobile-ready)
    {
        visibility: hidden;
    }

    /*
    2026-08-31, user: "na stronie kreatora mozemy zablokowac navbara w
    mniejszej wersji zeby sie nie powiekszal" - pasek nawigacji sklepu
    normalnie sam sie kurczy/rozszerza przy scrollu (JS w header.tpl,
    klasa ".is-shrunk" na ".v0-mobile-header" ponizej 768px / ".is-scrolled"
    na ".btx-desktop-islands" w zakresie 768-991px). Na TEJ stronie
    (`body.product-id-862`, ten sam page-scoping co reszta modulu) na
    stale wymuszamy WYGLAD "skurczonego" stanu, niezaleznie od faktycznej
    klasy - obie strony (".v0-mobile-header"/".btx-desktop-islands") sa
    elementami CORE motywu (custom.css), wiec to CELOWO tylko wizualny
    override przez wyzsza specyficznosc/"!important", zero ingerencji w
    JS/TPL motywu (zlota zasada Presty - stylizuj, nie edytuj). Efekt
    uboczny (pozadany): "syncStampCanvasTopOffset()" mierzy WYSOKOSC tego
    paska na biezaco, wiec przypiety canvas automatycznie sledzi ten
    teraz-stale-mniejszy nagłówek - mniej martwej przestrzeni nad
    kokpitem "za darmo", bez zmian w JS.
    */
    body.product-id-862 .v0-mobile-header .v0-mobile-header-inner
    {
        height: 16px !important;
    }

    body.product-id-862 .v0-mobile-header .v0-logo-img
    {
        max-height: 30px !important;
        width: 62px !important;
    }

    body.product-id-862 .v0-mobile-header .v0-mobile-logo-island a
    {
        height: 30px !important;
    }

    /*
    2026-08-31, user: "zrob wiekszy ten kafelek, zeby takiej dziury nad
    nim nie bylo... odleglosc od navbara od gory ma byc taka jak
    elementow na innych stronach, ale od tego wiekszego navbara" -
    zmierzone na zywo przez zdalny inspektor na prawdziwym telefonie:
    57px pustej przestrzeni miedzy dolem navbara (realnie 46px, po
    zmniejszeniu wyzej) a gora kokpitu. Przyczyna: TA SAMA, juz raz
    naprawiona (patrz "body{padding-top:102px}"/"#wrapper{padding-
    top:25px}" w bloku "@media (min-width:992px) and (max-width:1440px)"
    wyzej w pliku) niespojnosc - globalne, STALE odstepy motywu rezerwuja
    miejsce dla navbara w jego PELNYM, domyslnym rozmiarze, niezaleznie
    od faktycznej (na tej stronie wymuszonej mniejszej, wyzej) wysokosci.
    Fix nigdy nie zostal rozszerzony na prawdziwy mobile/tablet.

    User doprecyzowal: navbar MA zostac maly (46px, jak teraz) - ale
    ODSTEP pod nim ma byc TAKI SAM jak na innych stronach sklepu POD ICH
    (pelnowymiarowym, 78px) navbarem.

    PIERWSZA proba pomiaru (2px) byla BLEDNA - zlapala niewlasciwy
    element ("main"/wrapper bez wizualnego znaczenia, nie realna
    tresc). Po porownaniu realnych zrzutow ekranu z telefonu (strona
    glowna vs kreator) user zauwazyl "na gorze za maly" - poprawny
    pomiar (na REALNYM, widocznym pierwszym elemencie tresci, karuzeli
    "#carousel" na stronie glownej): odstep miedzy dolem navbara (78px)
    a gora karuzeli = 27px, nie 2px. Przycinamy "body" do faktycznej
    wysokosci TEGO (46px) navbara + TEJ (27px) zmierzonej przerwy.
    */
    body.product-id-862
    {
        /* 2026-08-31, user po zrzutach: "minimalnie mniejszy ten odstep" - 73px->65px. */
        padding-top: 65px !important;
    }

    body.product-id-862 #wrapper
    {
        padding-top: 0 !important;
    }

    /*
    2026-08-31, user: "stopke strony wywal calkowicie ze str kreatora na
    mobile" - prawdziwa stopka sklepu (rdzen motywu, "<footer id="footer">",
    linki/social/copyright pod cala strona) chowana WYLACZNIE na tej
    stronie na mobile/tablet - reszta sklepu bez zmian. Kreator jest
    samowystarczalna, jednoekranowa "aplikacja" (canvas przypiety + karta
    z cena), realna stopka sklepu ponizej niej nie mialaby tu sensu
    (uzytkownik i tak nigdy tam nie doscrolluje w normalnym uzyciu).
    */
    body.product-id-862 #footer
    {
        display: none !important;
    }

    /*
    2026-08-31, user: "ten button/strzalke sluzaca do scrolla do stopki
    tez wywal" - ".btx-stamp-scroll-footer" (strzalka-chevron, domyslnie
    stylowana TYLKO na desktopie w bloku "@media (min-width:992px)"
    nizej, wiec na mobile i tak renderowala sie jako zwykly,
    niestylowany <button> w normalnym przeplywie DOM, POZA widocznym
    ekranem - stad niewidoczna w dotychczasowych testach) traci sens
    teraz gdy stopka strony i tak jest schowana (nie ma juz do czego
    scrollowac).
    */
    #btx-stamp-scroll-footer
    {
        display: none !important;
    }

    /*
    2026-08-31, user: "i wywal scrolla strony, jedynie zawartosc kafelka
    niech sie scrolluje" - ta sama technika co juz dawno dziala na
    desktopie (patrz "body.product-id-862" w bloku "@media (min-width:
    992px)" wyzej w pliku - "height:100dvh; overflow:hidden" na body +
    "overflow:hidden" na html), TERAZ tez na mobile/tablet. Bezpieczne bo
    zmierzone live: przy scrollY:0 nad kokpitem jest TYLKO zarezerwowana
    przestrzen na fixed header (zero realnej tresci typu breadcrumb/tytul
    strony do "zgubienia"), a cala strona (`document.documentElement.
    scrollHeight`) byla tylko ~120px wyzsza niz sam viewport - ten
    margines to resztki po juz ukrytej stopce/strzalce scrolla wyzej, nie
    realna tresc. Scroll dalej dziala - ale WYLACZNIE wewnatrz aktywnego
    slajdu karty (".btx-stamp-mobile-tabs-track > .btx-stamp-rail/.btx-
    stamp-panel", juz maja "overflow-y:auto" z wczesniejszej pracy nad
    zakladkami).
    */
    body.product-id-862
    {
        height: 100vh;
        height: 100dvh;
        overflow: hidden;
    }

    /*
    2026-09-01 - PRAWDZIWA przyczyna buga "strona nie wraca w pierwotne
    polozenie po zamknieciu klawiatury" (6 nieudanych prob korygowania
    scrolla JS-em, patrz komentarz w "stamp-creator.js").

    Globalna regula "html { min-height: 100vh }" (bento-uikit.css) na iOS
    liczy sie dla ekranu BEZ paska Safari, wiec <html> byl ~40px WYZSZY
    niz realnie widoczny obszar. Zmierzone na zywym iPhonie: innerHeight
    695px, tresc konczyla sie na 696px, ale computed "min-height" = 735px
    i "documentElement.scrollHeight" = 735px -> 40px zapasu scrolla.
    Po schowaniu klawiatury iOS mial wiec LEGALNE 40px, na ktorych
    zostawal - i zaden JS nie mogl tego trwale cofnac, bo przegladarka
    miala pelne prawo tam wrocic.

    "overflow: hidden" ponizej NIE wystarcza: natywny mechanizm iOS
    przewijajacy do inputu pod klawiatura OMIJA je (zmierzone - scrollY
    dochodzil do 231px mimo "overflow:hidden"). Jedyne co dziala to
    ZEROWY zapas scrolla, czyli <html> dokladnie tak wysoki jak realnie
    widoczny obszar - "100dvh".

    Scoped TYLKO na te strone (nie globalnie): przy "dvh" tlo strony
    konczy sie na krawedzi dolnego paska Safari i nie siega juz pod
    niego - na dlugich, normalnie scrollowanych podstronach to zbedne
    ryzyko wizualne (user: "to spowodowalo szary pasek na dole ekranu
    tam gdzie adres"), a problem z klawiatura wystepuje wylacznie tutaj,
    bo tylko ta strona ma z zalozenia miescic sie w ekranie bez scrolla.
    */
    html:has(body.product-id-862)
    {
        min-height: 100dvh;
        height: 100dvh;
        overflow: hidden !important;
    }

    html:has(body.product-id-862),
    body.product-id-862
    {
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    html:has(body.product-id-862)::-webkit-scrollbar,
    body.product-id-862::-webkit-scrollbar
    {
        display: none;
    }
}

@media (min-width: 768px) and (max-width: 991px)
{
    body.product-id-862 .btx-desktop-islands
    {
        top: var(--btx-gap-lg, 24px) !important;
        left: var(--btx-gap-xl, 32px) !important;
        right: var(--btx-gap-xl, 32px) !important;
        padding: 0 !important;
    }

    body.product-id-862 .btx-desktop-islands::before
    {
        opacity: 0 !important;
    }

    body.product-id-862 .btx-desktop-islands .btx-logo-tinted
    {
        height: 49px !important;
    }

    body.product-id-862 .btx-island-group-left.btx-pill-group
    {
        top: 0 !important;
    }
}

@media (max-width: 991px)
{
    /*
    2026-08-31, user: "scalmy canvas z kafelkiem w 1 kafelek... zrob tak
    ze jest maly margin pomiedzy krawedzia canvasu a kafla" - canvas jest
    TERAZ zwyklym, GORNYM dzieckiem ".btx-stamp-mobile-card" (wstawiany
    tam przez JS, "syncStampMobileTabs()"), wiec dziedziczy jej biale tlo/
    obwodke/cien/promien (".btx-tile" nadal ma wlasny padding - zerujemy
    go tu, zeby canvas mogl siegac az do krawedzi karty poza wlasnym,
    zamierzonym marginesem ponizej) - "!important" bo ".btx-tile" ustawia
    padding jako "!important".
    */
    .btx-stamp-canvas-wrap
    {
        background: none !important;
        border: none !important;
        box-shadow: none !important;
        border-radius: 0 !important;
        padding: 0 !important;
    }

    /*
    2026-08-31, user: "jak sie pojawia klawiatura to wers niech sie
    odrywa... i podaza za klawiatura" - odradzone (ten sam wzorzec co
    caly dzien psul robote). Nastepnie wypróbowany "tryb pelnoekranowej
    edycji" (chowanie canvasu/kropek/stopki na fokusie inputu wersu,
    klasa ".is-editing-wers" + przycisk "Gotowe") - COFNIETY CALKOWICIE
    (user: "dale scrolluje za ekran") - sama zmiana LAYOUTU w reakcji na
    fokus (nawet bez "position:fixed") bila sie z natywnym mechanizmem
    iOS liczacym wlasny scroll pod klawiature w TYM SAMYM momencie.
    Canvas na fokusie inputu wersu NIE jest juz w zaden sposob ruszany -
    patrz komentarz przy "document.addEventListener('focusin', ...)"
    (usuniety) w stamp-creator.js.
    */

    /*
    2026-08-31, user: "zmniejsz odstep miedzy wersami" - bazowa
    (dzielona z desktopem) regula ".btx-stamp-lines" ma "gap:var(--btx-
    spacing-xs)", a kazdy ".btx-stamp-line-card" DOKLADA wlasny "padding:
    var(--btx-spacing-xs) 0" (gora+dol) - razem 3x ten sam token miedzy
    dwoma wersami. Na mobile (gdzie ekran jest ciasniejszy, a tryb
    pelnoekranowej edycji chce zmiescic jak najwiecej wersow na raz)
    scisniete do wartosci mniejszych niz token.
    */
    .btx-stamp-lines
    {
        gap: 4px;
    }

    .btx-stamp-line-card
    {
        padding: 6px 0;
    }

    /*
    2026-08-31, user: "ukryj tytul pieczatki i rozm odbicia, canvas daj
    wyzej" - na mobile ".btx-stamp-canvas-header-colors" jest juz
    wyprowadzony do wyspy sterowania (syncStampControlsMergeMobile()),
    wiec w headerze zostaje tylko tytul/specyfikacja - calosc chowamy,
    zeby podglad wskoczyl wyzej bez martwego odstepu.
    */
    .btx-stamp-canvas-header
    {
        display: none;
    }

    /*
    2026-08-31, user: "zrob tak ze jest maly margin pomiedzy krawedzia
    canvasu a kafla" - maly, rowny margines na wszystkie 4 strony (canvas
    jako wyraznie odzielony "pod-kafelek" wewnatrz bialej karty, zamiast
    przyklejony do jej krawedzi) - promien z tokenu "--btx-radius-md"
    (nie sztywne 20px karty, celowo NIECO mniejszy niz promien
    zewnetrznej karty - typowy wzorzec zagniezdzonego elementu).

    2026-08-31, DALSZY dopisek, user: "czemu siatka nie siega do samego
    dolu? mozesz powiekszyc wysokosc" - bazowa (desktopowa) regula
    ".btx-stamp-canvas-surface" ma "flex:1" (rozciaga sie, zeby wypelnic
    dostepna wysokosc RODZICA-flex-columny) - na desktopie to dzialalo,
    bo ".btx-stamp-canvas-wrap" siedzial w wysokiej kolumnie grida z
    okreslona wysokoscia. Na mobile canvas-wrap jest teraz zwyklym
    blokiem w normalnym przeplywie karty (bez wlasnej, wymuszonej
    wysokosci) - "flex:1" nie ma tu do czego sie rozciagac, wiec surface
    kurczyl sie do naturalnej wysokosci swojej TRESCI (samego stage'u,
    96% + padding), zamiast wypelniac widoczny "kafelek" kropek az do
    dolu. Fix: "aspect-ratio" dopasowany do logicznych wymiarow platna
    Fabric.js (600x240px, patrz "BTX_STAMP_LOGICAL_WIDTH/HEIGHT" w JS) -
    surface TERAZ sam skaluje sie proporcjonalnie do szerokosci karty,
    kropki siegaja az do krawedzi (stage w srodku ma tylko wlasny, maly
    padding 4%, nie dodatkowa "martwa" przestrzen wynikajaca z braku
    wysokosci rodzica).
    */
    .btx-stamp-canvas-surface
    {
        flex: none;
        aspect-ratio: 600 / 240;
        margin: 12px;
        border-radius: var(--btx-radius-md);
    }

    /*
    Zakladki "Wybor automatu"/"Ustawienia" na swipe (2026-08-28, user: "a
    nie da sie zrobic tak ze przelaczanie... jest na swipe horizontal
    dolny kafelek wypelnia do granicy ekranu przestrzen a dopiero wewnatrz
    obu kafelkow sie scrolluja elementy") - JS (`syncStampMobileTabs()`)
    przenosi ".btx-stamp-rail" i ".btx-stamp-panel" (juz scalony z
    controls) do wspolnego "toru" ("#btx-stamp-mobile-tabs-track",
    szerokosc 200%, "transform:translateX()" pokazuje jeden z dwoch slajdow
    po 50% szerokosci kazdy = 100% viewportu). Wysokosc viewportu liczona w
    JS na biezaco (`syncStampMobileTabHeights()`) jako "100vh minus dol
    przypietego canvasu minus wysokosc paska stopki" - "dolny kafelek
    wypelnia do granicy ekranu", scroll TYLKO wewnatrz aktywnego slajdu.
    */
    /*
    "Opcja E" z makiety (2026-08-28, user: "dolny kafelek jak w A... tylko
    zeby to na dole to byl osobny kafelek") - nav+viewport TERAZ zyja
    razem w JEDNYM wrapperze ("#btx-stamp-mobile-card" w JS), zeby caly
    dolny blok wygladal jak JEDNA, osobna, w pelni zaokraglona karta z
    marginesem, nie trzy luzne elementy. PIERWOTNIE gorne rogi tu, dolne
    na pasku stopki ponizej (te same 16px marginesy boczne, bez przerwy,
    czytaly sie jako jedna ciagla bryla) - ale to zalozylo ze pasek stopki
    ZAWSZE ma podobna szerokosc/tresc co karta.

    2026-08-31, trzeci dopisek tego samego dnia, user: "zaokraglij dol
    kafelka" - po tym jak pasek stopki zostal zredukowany do samej ceny,
    fuzja "jedna ciagla bryla" przestala miec sens (maly pasek ceny
    wygladal jak OSOBNY element) - dolne rogi zaokraglone, obwodka na
    wszystkie 4 boki. Nastepnie CZWARTY dopisek: "stopke strony wywal
    calkowicie... i ta cene wrzuc na kafelek a nie na osobny" - osobny,
    position:fixed pasek stopki ZNIKA calkowicie, ".btx-stamp-panel-
    footer" (cena) wraca jako zwykle, WEWNETRZNE dziecko TEJ SAMEJ karty
    (patrz regula ponizej), wiec margines dolny (12px, jak gora) TERAZ
    faktycznie odsuwa cala karte (viewport + cena w srodku) od dolnej
    krawedzi ekranu - to na tej wartosci opiera sie tez wyliczenie
    wysokosci viewportu w JS (`syncStampMobileTabHeights()`,
    "cardBottomMargin").
    */
    .btx-stamp-mobile-card
    {
        display: flex;
        flex-direction: column;
        min-height: 0;
        /*
        2026-08-31, user: "wez ten odstep miedzy canvasem a kafelkiem
        zmniejsz" - gorny margines 12px->8px (dolny ZOSTAJE 12px, na tej
        wartosci opiera sie "cardBottomMargin" w JS,
        `syncStampMobileTabHeights()` - zmiana tylko gory, nie dolu).
        */
        margin: 8px 16px 12px;
        background: #ffffff;
        border: 1px solid var(--btx-border-color);
        border-radius: 20px;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
        overflow: hidden;
    }

    /*
    Cena (".btx-stamp-panel-footer") jako WEWNETRZNE, ostatnie dziecko
    karty (pod viewportem) - poza karta traci dziedziczony padding
    ".btx-tile" ktory mial jako dziecko ".btx-stamp-panel" (teraz jest
    bezposrednim dzieckiem karty, nie panelu), wiec wlasny padding
    doklejony recznie (te same 16px co reszta tresci karty). "flex-
    shrink:0" - nie ma sie scisniec kosztem viewportu wyzej.

    2026-08-31 dopisek, user: "pomniejsz ciut cene daj po prawej od ceny
    button zatwierdz, i po zatwierdzeniu button zatwierdz sie zmienia w 2
    buttony dodaj do koszyka i edytuj (icon)" - z kolumny (cena+confirm w
    gornym rzedzie, CTA w OSOBNYM, pelnoszerokim rzedzie ponizej, jak na
    desktopie) na JEDEN rzad (row) - cena, CTA i confirm/edit dziela TEN
    SAM wiersz. ".btx-stamp-panel-footer-top" (dawny wrapper na
    cena+confirm) dostaje "display:contents" - znika z drzewa BOXOW (ale
    zostaje w DOM), jego dzieci staja sie bezposrednimi flex-itemami TEGO
    rzedu, obok CTA (ktory w DOM jest jej rodzenstwem, nie dzieckiem) -
    bez tego cena+confirm bylyby uwiezione w oddzielnym, zagniezdzonym
    boxie.
    */
    /*
    "gap" tu NIE nadpisany osobno - bazowa (kolumnowa) regula
    ".btx-stamp-panel-footer" ma juz wlasny "gap:var(--btx-spacing-sm)"
    (16px), ktory w tym rzedzie dziala DOKLADNIE tak samo (odstep miedzy
    KAZDA para sasiadujacych flex-itemow: cena↔CTA, CTA↔confirm) - user
    zauwazyl "Dodaj do koszyka" zawijajace sie na 2 linie (za waskie), a
    przyczyna byla PODWOJNIE liczona przerwa (ten "gap" + wlasny
    "margin-left" na CTA, usuniety ponizej) plus zbedny
    "justify-content:space-between" (zbedny skoro "flex:1" na CTA i tak
    juz sam wypelnia cala wolna przestrzen).
    */
    .btx-stamp-mobile-card > .btx-stamp-panel-footer
    {
        flex-direction: row;
        align-items: center;
        flex-shrink: 0;
        padding: var(--btx-spacing-sm) var(--btx-gap-lg, 16px) var(--btx-gap-lg, 16px);
    }

    .btx-stamp-mobile-card .btx-stamp-panel-footer-top
    {
        display: contents;
    }

    /* "ciut" mniejsza (40px -> 26px) - w jednym, ciasniejszym rzedzie z 2 przyciskami obok. */
    .btx-stamp-mobile-card .btx-stamp-bar-price
    {
        font-size: 26px;
    }

    /*
    "Dodaj do koszyka" schowany dopoki NIE zatwierdzone (na mobile, w
    odroznieniu od desktopu gdzie jest zawsze widoczny-ale-disabled) -
    user chce dokladnie 1 przycisk przed zatwierdzeniem, 2 po. "order:1"
    (miedzy cena a confirm/edit) - w DOM jest OSTATNI (rodzenstwo
    ".btx-stamp-panel-footer-top", nie jej dziecko), ale wizualnie ma
    wypasc PRZED przyciskiem confirm/edit (user: "dodaj do koszyka i
    edytuj", w tej kolejnosci).
    */
    .btx-stamp-mobile-card .btx-stamp-cta
    {
        display: none;
        width: auto;
        flex: 1;
        order: 1;
        padding: 0 12px;
        white-space: nowrap;
    }

    .btx-stamp-cockpit.is-locked .btx-stamp-mobile-card .btx-stamp-cta
    {
        display: block;
    }

    .btx-stamp-mobile-card .btx-stamp-confirm
    {
        order: 2;
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
    }

    /*
    Zatwierdzone: przycisk Confirm kurczy sie do samej ikonki (edytuj) -
    tekst chowany, ikona SVG (domyslnie ukryta - patrz baza nizej w
    pliku) pokazana, przycisk kwadratowy zamiast szerokiego z paddingiem
    tekstowym.
    */
    .btx-stamp-cockpit.is-locked .btx-stamp-mobile-card .btx-stamp-confirm
    {
        width: 40px;
        padding: 0;
    }

    .btx-stamp-cockpit.is-locked .btx-stamp-mobile-card .btx-stamp-confirm-label
    {
        display: none;
    }

    .btx-stamp-cockpit.is-locked .btx-stamp-mobile-card .btx-stamp-confirm-edit-icon
    {
        display: block;
        width: 18px;
        height: 18px;
    }

    /*
    2026-08-31, user: "zamienmy wybierz automat i projekt na kropki takie
    male... zaoszczedzimy wiecej miejsca w ktore mozemy dac cene" - byle 2
    duze przyciski-pigulki z tekstem (40px wysokosci, pelna szerokosc)
    zamienione na male kropki (wskaznik pozycji jak w karuzeli), zeby
    odzyskac wysokosc paska.
    */
    .btx-stamp-mobile-tabnav
    {
        display: flex;
        /*
        2026-08-31 dopisek, user: "te kropki od strony, blizej siebie i
        blizej krawedzi i pod spodem tez mniejszy odstep" - gap 8px→4px
        (blizej siebie), "justify-content:center"→"flex-start" (przy lewej
        krawedzi zamiast na srodku), "margin-bottom" 8px→4px.

        2026-08-31, KOLEJNY dopisek (user zmienil zdanie po zobaczeniu na
        zywo): "na srodek te kropki daj, nadal sa za nisko, w ich
        przypadku mozemy zignorowac padding kafelka" - "flex-start"→
        "center" z powrotem (na srodek). "nadal za nisko" mimo
        poprzedniego zmniejszenia "padding-top" (14px) - user explicite
        pozwolil zignorowac standardowy padding karty TYLKO dla kropek
        (nie jest to token uzywany gdzie indziej w karcie), wiec zejscie
        na sztywne 4px zamiast trzymania sie 14px/16px konwencji reszty
        tresci. Bezpieczne mimo zerowego niemal odstepu od gornej,
        zaokraglonej krawedzi karty (20px promien) - kropki sa
        WYSRODKOWANE poziomo, wiec fizycznie nie wchodza w strefe, gdzie
        zaokraglenie realnie "ucina" rogi (tylko skrajne ~20px szerokosci
        po bokach).
        */
        /* 2026-08-31, kolejny dopisek: "te kropki jeszcze bilizej siebie daj" - 4px->0px (dotykaja sie touch-targetami 32x32, same kropki dalej maja czytelny odstep miedzy soba bo sa mniejsze niz box). */
        gap: 0;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        /*
        2026-08-31, user: "przyblizmy kropki na odleglosc tych 12px zeby
        bylo rowno" - "padding-top:4px" tutaj DOKLADAL sie do WLASNEGO
        marginesu ".btx-stamp-canvas-surface" (12px, ten sam co margines
        wokol canvasu z kazdej strony) dajac razem 16px zamiast
        jednolitych 12px wszedzie. Zejscie do "padding-top:0" - kropki
        siedzą TERAZ dokladnie 12px od dolu canvasu, ta sama wartosc co
        margines samego canvasu.
        */
        padding: 0 var(--btx-gap-lg, 16px) 0;
        margin-bottom: 4px;
    }

    /*
    Przycisk sam jest wiekszym, niewidocznym touch-targetem - widoczna
    "kropka" to dopiero "::after", mniejsza i wysrodkowana w jego
    srodku.

    2026-08-31, user: "blizej siebie te kropki ustaw" - "gap:0" na
    rodzicu (wyzej) juz nie ma czego dalej scisnac (przyciski i tak sie
    dotykaja), wiec jedyny sposob na wizualne zblizenie samych KROPEK
    to zmniejszenie SZEROKOSCI przycisku (odleglosc miedzy srodkami =
    szerokosc przycisku, skoro dotykaja sie bez przerwy) - 32px->22px.
    Wysokosc zostaje 32px (nie wplywa na POZIOMY odstep, a wieksza
    wysokosc to wciaz wygodniejszy cel dla kciuka w pionie).
    */
    .btx-stamp-mobile-tab-btn
    {
        flex: none;
        width: 22px;
        height: 32px;
        padding: 0;
        border: none;
        border-radius: 50%;
        background: none;
        cursor: pointer;
        position: relative;
    }

    .btx-stamp-mobile-tab-btn::after
    {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: var(--btx-border-input);
        transform: translate(-50%, -50%);
        transition: background var(--btx-transition-fast, 0.15s), width var(--btx-transition-fast, 0.15s), height var(--btx-transition-fast, 0.15s);
    }

    .btx-stamp-mobile-tab-btn.is-active::after
    {
        width: 10px;
        height: 10px;
        background: var(--btx-color-primary);
    }

    @media (hover: hover)
    {
        .btx-stamp-mobile-tab-btn:not(.is-active):hover::after
        {
            background: var(--btx-border-hover);
        }
    }

    .btx-stamp-mobile-tab-btn:active::after
    {
        transform: translate(-50%, -50%) scale(0.85);
    }

    .btx-stamp-mobile-tabs-viewport
    {
        flex-shrink: 0;
        overflow: hidden;
        /*
        2026-08-31, user: "nadal nie jest to szer canvasu" - ten padding
        (16px boki) DOKLADAL sie do WLASNEGO 12px paddingu kazdego slajdu
        (rail/panel2/panel3, patrz regula na ".btx-stamp-mobile-tabs-track
        > .btx-stamp-rail, ... .btx-stamp-mobile-subpanel" nizej), dajac
        razem ~28-29px zamiast jednolitych 12px jak canvas. Zerujemy -
        margines z kazdej strony ma teraz kontrolowac WYLACZNIE sam slajd
        (rail/panel2/panel3), nie viewport (ktory jest tylko oknem
        przycinajacym tor 3 slajdow, bez wlasnego wizualnego marginesu).
        */
        padding: 0;
        /*
        2026-08-31, user: "wgl panele moge wewnatrz przesuwac na wszystkie
        strony a ma byc tylko pionowy scroll i swipe" - "touch-action:pan-y"
        pierwotnie dopisany TEZ tutaj, na tym elemencie.

        2026-08-31, DRUGI dopisek (user: "controlsow stylu nie widze...
        panel sie nie scrolluje") - realny, prawdopodobny root cause:
        TEN element ("viewport") ma "overflow:hidden" i SAM W SOBIE
        NIGDY nie scrolluje - to tylko okno przycinajace tor 3 slajdow.
        Faktyczny scroll dzieje sie w DZIECKU (rail/panel2/panel3, maja
        "overflow-y:auto"), gdzie "touch-action:pan-y" JUZ jest ustawiony
        (patrz nizej w pliku). Ustawienie GO TEZ na tym nie-scrollujacym
        przodku bylo zbedne, a w Safari na iOS potrafi to (znany,
        udokumentowany w wielu miejscach problem WebKita) powodowac ze
        przegladarka gubi/zle przydziela gest dotykowy miedzy przodkiem a
        dzieckiem, w skrajnym przypadku BLOKUJAC realny scroll w dziecku
        zamiast go pozwolic. Usuniete stad - zostaje WYLACZNIE na
        elemencie ktory faktycznie scrolluje.
        */
    }

    /*
    2026-08-31, user: "musimy rozbic to na 3 panele" - z 2 na 3 slajdy
    (rail / "#btx-stamp-mobile-panel2" / "#btx-stamp-mobile-panel3"),
    szerokosc toru 200%->300%, kazdy slajd 50%->33.3333%.
    */
    .btx-stamp-mobile-tabs-track
    {
        display: flex;
        width: 300%;
        height: 100%;
        transition: transform 0.25s ease;
    }

    .btx-stamp-mobile-tabs-track > .btx-stamp-rail,
    .btx-stamp-mobile-tabs-track > .btx-stamp-mobile-subpanel
    {
        flex: 0 0 33.3333%;
        min-width: 0;
        max-height: none;
        height: 100%;
        overflow-y: auto;
        /* Ten sam powod co "touch-action:pan-y" na ".btx-stamp-mobile-tabs-viewport" wyzej - TU realnie dzieje sie scroll dotykiem (rail/panel2/panel3 maja "overflow-y:auto"), nie na samym viewporcie. */
        touch-action: pan-y;
        /*
        Wlasna karta ".btx-tile" zdjeta (tlo/obwodka/cien/promien) - to
        TERAZ ".btx-stamp-mobile-card" (wyzej) daje caly wyglad karty
        dolnemu blokowi, rail/panel2/panel3 maja byc tu tylko WEWNETRZNA
        zawartoscia, nie druga, zagniezdzona karta w karcie. Ta sama
        technika wyzszej specyficznosci + wlasny "!important" co reszta
        kolizji z ".btx-tile" w tym pliku. "#btx-stamp-mobile-panel2"/
        "#btx-stamp-mobile-panel3" to nowe, zwykle "<div>" (nie ".btx-tile"
        w ogole), wiec nie MAJA tego tla do zdjecia - regula tu jest wiec
        dla nich no-opem, ale zostaje wspolna z railem dla jednego
        miejsca prawdy o rozmiarze/scrollu slajdu.
        */
        background: none !important;
        border: none !important;
        box-shadow: none !important;
        border-radius: 0 !important;
        /*
        2026-08-31, user: "poszerz dol kazdego z 3 paneli tak zeby
        odstepy do krawedzi kafelka byly takie jak w przypadku canvasu" -
        DALSZY dopisek: "chodzilo mi glownie o odstepy po bokach" - rail/
        panel2/panel3 dziedziczyly 16px paddingu na WSZYSTKICH stronach
        (".btx-tile"/"--btx-tile-padding" - token wspoldzielony z resztą
        sklepu), podczas gdy canvas ma swoj WLASNY, wezszy 12px margines
        (patrz ".btx-stamp-canvas-surface" wyzej). Ujednolicone na 12px
        NA WSZYSTKICH 4 STRONACH (nie tylko dol) - "!important" bije
        zarowno ".btx-tile" (rail) jak i wlasna regule
        ".btx-stamp-mobile-subpanel" (panel2/panel3, ponizej w pliku, bez
        wlasnego !important).
        */
        padding: 12px !important;
        /*
        2026-08-31, user (zrzut z telefonu): "na liscie... jest jakies
        pojebane przyciecie ktore przycina do zaokraglenia i na dole i na
        gorze listy" - lista (np. automatow) przewija sie WEWNATRZ tego
        slajdu, ktory sam siedzi tuz przy zaokraglonych (20px) rogach
        karty ".btx-stamp-mobile-card" - scrollujaca sie tresc byla wiec
        obcinana ostro/plasko tuz obok widocznej krzywizny rogu, co
        wygladalo niespojnie. Ten sam wzorzec "mask-image" fade co juz
        gdzie indziej w module (np. ".btx-stamp-canvas-header-model"), ale
        w pionie (do gory/dolu) zamiast w poziomie - miekkie zanikniecie
        zamiast twardego przeciecia.
        */
        -webkit-mask-image: linear-gradient(to bottom, transparent, black 16px, black calc(100% - 16px), transparent);
        mask-image: linear-gradient(to bottom, transparent, black 16px, black calc(100% - 16px), transparent);
    }

    /*
    Wlasny padding "#btx-stamp-mobile-panel2"/"#btx-stamp-mobile-panel3"
    (rail/dawny panel mialy go "za darmo" z ".btx-tile"; te 2 to zwykle,
    nowe "<div>" bez zadnego stylu) - te same 16px co reszta karty, plus
    "position:relative" wymagane przez warstwe przyciemnienia "::after"
    przy zatwierdzonym stanie (patrz ".is-locked .btx-stamp-mobile-subpanel"
    wyzej w pliku).
    */
    .btx-stamp-mobile-subpanel
    {
        display: flex;
        flex-direction: column;
        /*
        2026-08-31, user: "chodzilo mi o odstep pomiedzy switchem
        zaprojektuj a wersami" - "gap" w flexboksie DODAJE SIE do
        wlasnego marginesu dzieci (nie zwija sie jak w normalnym block-
        flow), wiec odstep switch->WERSY = ten gap + wlasny "margin"
        dividera ponizej. Zmniejszone z "--btx-spacing-sm" na 8px.
        */
        gap: 8px;
        padding: var(--btx-tile-padding);
        position: relative;
    }

    #btx-stamp-mobile-panel2 .btx-stamp-divider
    {
        margin: 4px 0;
    }

    .btx-stamp-mobile-tabs-track > .btx-stamp-rail .btx-stamp-scroll,
    .btx-stamp-mobile-tabs-track > .btx-stamp-mobile-subpanel .btx-stamp-scroll
    {
        flex: none;
        overflow-y: visible;
        /*
        2026-08-31, user: "po lewej nie" (odstepy po bokach niesymetryczne) -
        bazowa regula ".btx-stamp-scroll" (wyzej w pliku) ma "margin-right:
        -18.5px"/"padding-right:5.5px" - desktopowy trik centrujacy WLASNY
        (13px) pasek przewijania w 24px paddingu kafla. Na mobile "scroll"
        w ogole juz nie scrolluje (linijka wyzej, "overflow-y:visible" -
        scrolluje sam rail/panel), wiec tego paska tu NIGDY nie ma - ale
        margines/padding z bazowej reguly i tak zostawaly aktywne,
        przesuwajac tresc asymetrycznie (bliziej prawej krawedzi niz
        lewej). Zerujemy oba dla symetrycznych 12px z kazdej strony.
        */
        margin-right: 0;
        padding-right: 0;
    }

    /*
    Historia tego dnia (2026-08-31): cena+CTA byly kolejno wyciagane do
    osobnego, position:fixed paska stopki, potem redukowane do samej ceny,
    az user zdecydowal "stopke strony wywal calkowicie... i ta cene
    wrzuc na kafelek a nie na osobny" - osobny pasek
    (".btx-stamp-mobile-footer-bar") ZNIKA calkowicie z CSS/JS, cena
    wraca jako zwykle dziecko karty. Nastepnie ("pomniejsz ciut cene daj
    po prawej od ceny button zatwierdz...") OBA przyciski (Confirm i CTA)
    wracaja jako widoczne, w tym samym rzedzie co cena - patrz pelna
    regula ".btx-stamp-mobile-card > .btx-stamp-panel-footer" i sasiednie
    wyzej w pliku (sekcja "Wersja mobile/tablet").
    */

    /*
    Scalenie z prawym panelem (2026-08-28, user: "scal ogolnie te 2 panele
    ...w 1 panel na mobile") - "syncStampControlsMergeMobile()" w JS
    przenosi caly "#btx-stamp-controls" jako dziecko ".btx-stamp-panel".
    Selektor po KONTEKSCIE DOM (nie po klasie-znaczniku), bo to WCIAZ ten
    sam element/te same reguly co na desktopie - zdejmujemy mu tu tylko
    WLASNE tlo kafla (".btx-tile" jest "!important", stad ta sama technika
    wyzszej specyficznosci + wlasny "!important" co przy szerokosci
    przypietego canvasu wyzej), zeby wygladal jak WEWNETRZNA sekcja
    panelu, nie osobny, zagniezdzony box.
    */
    #btx-stamp-mobile-panel3 .btx-stamp-controls
    {
        padding: 0 !important;
        background: none !important;
        border: none !important;
        box-shadow: none !important;
        border-radius: 0 !important;
        margin-bottom: var(--btx-spacing-sm);
    }

    /*
    2026-08-31, bug zglosila realny zrzut ekranu z telefonu: "poprzycinane
    sa elementy wewnatrz kafelka" - "Wybierz wers" (etykieta+pager) w
    ".btx-stamp-controls-nav-block" (baza pliku: "flex:0 1 auto;
    min-width:0" na pierwszym polu, celowo tak zeby DLUGI tekst tytulu
    ("Wybierz wers tekstu, aby edytowac jego styl") mogl sie zawijac na
    desktopie zamiast wypychac pager w scroll) - w WASKIM, scalonym
    panelu mobile suma szerokosci 3 pol (nav-block, Styl, Wyrownanie) NIE
    miesci sie w rzedzie, a "min-width:0" pozwala temu POLU skurczyc sie
    do ZERA (potwierdzone live: "getBoundingClientRect().width === 0"),
    podczas gdy Styl/Wyrownanie (bez "min-width:0") zachowuja swoja pelna
    szerokosc. Wewnatrz zerowego pudelka "align-items:center" centruje
    etykiete+pager NA PUNKCIE (srodek pudelka), wiec tresc wystaje
    SYMETRYCZNIE w lewo/prawo od tego punktu - lewa polowa kazdego slowa
    ("Wyb-ierz", "we-rs") wychodzi POZA lewa krawedz karty i jest ucinana
    przez jej "overflow:hidden" (stad w zrzucie widac tylko "ierz"/"rs").
    Fix: na mobile ten rzad WRAPUJE, a pierwsze pole dostaje wymuszone
    100% szerokosci (wlasny, pelny wiersz) - Styl+Wyrownanie spadaja
    razem na kolejny wiersz, gdzie obie razem swobodnie sie miesza.
    */
    #btx-stamp-mobile-panel3 .btx-stamp-controls-nav-block
    {
        flex-wrap: wrap;
        gap: var(--btx-spacing-xs);
    }

    /*
    2026-08-31, user: "nadal realnie na telefonie nie widze controlsow
    styli, a na symulacji telefonu w chromie na kompie niby sa" - poprzednia
    wersja opierala "Styl"+"Wyrownanie" siedzace OBOK siebie na jednym
    wierszu na CIASNEJ, wyliczonej "na sztywno" matematyce (2x132px+8px
    gap <= 274px szerokosci testowanej w tym narzedziu) - dziala to TYLKO
    dopoki realna szerokosc panelu jest >= tej wartosci. Rozne modele
    telefonow maja rozne realne szerokosci CSS (np. iPhone SE ~320-375px
    efektywnej tresci, wezsze niz testowane 274px WEWNATRZ panelu), a to
    narzedzie testowe (oparte na Chrome) i tak nie odtwarza realnego
    Safari na iOS - stad rozbieznosc "w symulatorze widac, na telefonie
    nie". Zamiast dalej zgadywac/docinac konkretna liczbe px, usuniete
    ryzyko CALKOWICIE: "Styl" i "Wyrownanie" TEZ dostaja `flex-basis:100%`
    (jak juz "Wybierz wers" wyzej) - kazde pole ZAWSZE na wlasnym, pelnym
    wierszu, niezaleznie od szerokosci ekranu - nie ma juz zadnej
    matematyki "czy sie zmiesci obok siebie", wiec nie ma jak przestac byc
    widocznym z powodu przepelnienia.
    */
    #btx-stamp-mobile-panel3 .btx-stamp-controls-nav-block > .btx-stamp-control-field
    {
        flex-basis: 100%;
        min-width: 100%;
        margin-right: 0;
    }

    /*
    "Kolor automatu"/"Kolor tuszu" przeniesione tu z naglowka canvasu
    (2026-08-28, user: "przenies do tej samej wyspy co masz sterowanie
    czcionka zeby odchudzic canvas") - na desktopie te pola siedza w
    WASKIM naglowku (intrinsic/kompaktowa szerokosc), tutaj maja caly
    pelnowymiarowy rzad do dyspozycji jak reszta pol tego panelu, wiec
    dostaja te sama, pelnoszerokosciowa traktowanie (flex:1 kazde pole,
    select 100%) zamiast wyglądac na przypadkowo malutkie/przyklejone do
    lewej.
    */
    .btx-stamp-controls .btx-stamp-canvas-header-colors
    {
        width: 100%;
        margin-bottom: var(--btx-spacing-sm);
    }

    .btx-stamp-controls .btx-stamp-canvas-header-colors .btx-stamp-color-field
    {
        flex: 1;
        min-width: 0;
    }

    .btx-stamp-controls .btx-stamp-canvas-header-colors select
    {
        width: 100%;
        height: 40px;
        padding: 8px 12px;
    }
}

/*
Strzalka do stopki - PRZEBUDOWANE #2 (2026-08-21, koniec sesji, user:
"nie da sie tak zeby przejezdzala strona a nie stopka wjezdzala?").
Wersja "bottom sheet" (stopka jako osobny panel position:fixed
najezdzajacy NAD nieruchoma strona) zdjeta - stopka wraca do zwyklego,
normalnego miejsca w ukladzie strony (bez zadnych nadpisan
"position"/"transform" - domyslny "position:relative" z "custom.css"
zostaje nietkniety). Ruch daje teraz PRAWDZIWE przewiniecie strony
(patrz initStampScrollToFooter() w JS - blokada scrolla zdejmowana tylko
na czas animacji, wraca automatycznie po jej zakonczeniu) - to
".btx-stamp-cockpit" (i wszystko nad stopka) wizualnie "przejezdza" w
gore, a nie stopka najezdza od dolu.
*/
@media (min-width: 992px)
{
    /*
    "sama ikona, polprzezroczyste" (user, korekta #1) - goly chevron bez
    tla/ramki. "bialy chevron szerszy i pod kafelkiem" (korekta #2) -
    kafel ma "margin-bottom:35px", pod nim jest waski ciemny pasek tla
    strony - szeroki plaski SVG (viewBox 64x20 w tpl) dopasowany do tego
    paska, kolor na sztywno bialy (token tekstu bylby ciemny/niewidoczny
    poza bialymi kaflami). "grubszy" (korekta #3) - "stroke-width" 2→3.

    Bez animowanego "bottom" (bylo w wersji "bottom sheet", zeby przycisk
    jechal NAD wysuwajaca sie stopka) - przycisk jest "position:fixed",
    wiec przy realnym scrollu strony i tak zawsze zostaje w tym samym
    miejscu na ekranie, nic nie trzeba doganiac.
    */
    .btx-stamp-scroll-footer
    {
        position: fixed;
        left: 50%;
        bottom: 6px;
        transform: translateX(-50%);
        z-index: 601;
        width: 48px;
        height: 18px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: none;
        background: transparent;
        color: #ffffff;
        opacity: 0.35;
        cursor: pointer;
    }

    .btx-stamp-scroll-footer .btx-stamp-icon
    {
        width: 40px;
        height: 12px;
        stroke: currentColor;
        stroke-width: 4;
        stroke-linecap: round;
        stroke-linejoin: round;
        fill: none;
        transform: rotate(0deg);
        transition: transform 0.6s ease;
    }

    /*
    Prosty flip o 180 stopni (user 2026-08-28: "sie obraca jak beben w
    pralce zamiast 180 stopni raz" - zawrocenie wczesniejszej decyzji
    "odwroc go o 1080 stopni", 3 pelne obroty, ktora byla tu wczesniej).

    Baza ma JAWNE "rotate(0deg)" (nie samo "brak transform") - bez tego
    stan poczatkowy to "none", a przejscie "none"→"rotate(180deg)" Safari
    potrafi interpolowac inaczej niz Chrome (dekompozycja przez macierz
    zamiast wprost po wartosci kata). Oba stany (otwarte/zamkniete)
    uzywaja TEJ SAMEJ funkcji transform ("rotate()"), wiec nie ma juz
    dwuznacznosci przy interpolacji w zadnej przegladarce.
    */
    .btx-stamp-scroll-footer.is-open .btx-stamp-icon
    {
        transform: rotate(180deg);
    }

    @media (hover: hover)
    {
        .btx-stamp-scroll-footer:hover
        {
            opacity: 1;
        }
    }

    /*
    Brakujacy :active (audyt spojnosci 2026-08-28) - BEZ media query,
    zeby dzialal tez na dotyk (przycisk jest praktycznie zawsze uzywany
    na mobile - scroll do stopki). Sam "opacity" (bez "transform:scale"),
    bo element ma juz wlasny "transform:translateX(-50%)" do centrowania
    - dopisanie scale() wymagaloby laczenia obu funkcji w jednej
    wlasciwosci, niepotrzebne ryzyko dla drobnego, jednorazowego przycisku.
    */
    .btx-stamp-scroll-footer:active
    {
        opacity: 1;
    }
}

/*
 * Powiekszenie na hover, wersja 3 (user: "niech ucina dopiero na granicy
 * canvasa, niech miarki znikaja na zoomie"). Skalowana jest WEWNETRZNA
 * tresc (`.btx-stamp-hover-zoom-inner`, klasa dopisywana przez JS w
 * initStampHoverZoom()), NIE zewnetrzny kontener - ten dziala jako staly
 * "wizjer" przycinajacy powiekszona tresc do swoich wlasnych granic.
 * Cel hover/przyciecia dla canvasu to TERAZ `.btx-stamp-canvas-surface`
 * (caly szary kafel z siatka kropek), nie wciety `.btx-stamp-canvas-stage`
 * - user chcial wykorzystac cala dostepna przestrzen do powiekszenia, nie
 * ucinac tuz przy wewnetrznym 96% wcieciu. `overflow:hidden` dopisany
 * ponizej wlasnie na `.btx-stamp-canvas-surface` z tego powodu.
 * `transform-origin` (ustawiany w JS na kazdy mousemove) sprawia ze
 * powiekszenie "podaza" za kursorem zamiast zawsze rosnac tylko ze srodka.
 */
@media (hover: hover)
{
    .btx-stamp-logo-preview-raw:hover .btx-stamp-hover-zoom-inner
    {
        transform: scale(2);
    }
}

/*
 * Canvas glowny: zoom TERAZ prawdziwa zmiana rozdzielczosci bufora
 * (resizeStampCanvasForRetina(), "zoomMultiplier"), NIE CSS
 * "transform:scale()" (byl tu wczesniej, usuniety - user: "na zoomie to
 * juz wgl [nieostre]", transform rozciagal juz-wyrenderowane piksele,
 * dajac rozmycie niezaleznie od bazowej ostrosci). ".is-zoomed" zostaje
 * TYLKO do ukrywania miarek ponizej - lupa panelu logo (osobna, hover-owa
 * kontrolka na podgladach before/after) nadal uzywa CSS transform, to
 * jej NIE dotyczy.
 */
.btx-stamp-canvas-surface.is-zoomed #btx-stamp-dim-overlay
{
    opacity: 0;
}

.btx-stamp-canvas-surface
{
    overflow: hidden;
}

.btx-stamp-hover-zoom-inner
{
    transition: transform var(--btx-transition-fast);
    /*
     * Domyslny srodek (user: "ma poprostu powiekszac z orginem w srodku
     * idealnie bez opcji przesuwania" - o zoomie canvasu). Podglady logo
     * (before/after) nadpisuja to inline przez JS (attachPanZoom(),
     * podazanie za kursorem) - ten default dotyczy WYLACZNIE canvasu,
     * ktory od tej zmiany juz nie dostaje zadnego inline transform-origin.
     */
    transform-origin: 50% 50%;
}

#btx-stamp-dim-overlay
{
    transition: opacity var(--btx-transition-fast);
}
