/* KROJE PISMA - u nas, nie w Google.
 *
 * Powod jest zmierzony, a nie ideologiczny: podmiana kroju po doczytaniu
 * z `fonts.gstatic.com` byla JEDYNYM zrodlem przeskakiwania ukladu na
 * kazdej stronie sklepu (CLS 0,156 na stronie glownej przy progu 0,1).
 * Tekst renderowal sie krojem zastepczym i zmienial szerokosc po dojsciu
 * wlasciwego - nagłowki, pasek promocyjny, opisy produktow.
 *
 * `latin-ext` jest OBOWIAZKOWY: polskie znaki diakrytyczne siedza wlasnie
 * w tym zakresie. Bez niego "Taśmy" renderuja sie dwoma roznymi krojami
 * naraz.
 *
 * `swap`, a nie `optional`: przy `optional` przegladarka potrafi zostac
 * przy kroju zastepczym na cala wizyte, a marka sklepu siedzi w krojach.
 */
@font-face{font-family:'Bebas Neue';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/bebas-neue-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Bebas Neue';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/bebas-neue-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Oswald';font-style:normal;font-weight:400 700;font-display:swap;src:url('../fonts/oswald-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Oswald';font-style:normal;font-weight:400 700;font-display:swap;src:url('../fonts/oswald-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;src:url('../fonts/inter-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;src:url('../fonts/inter-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}

/* =========================================================================
   EgoTape — motyw WooCommerce
   Design system: black #0B0B0B + amber #F69500, Bebas Neue / Oswald / Inter
   ========================================================================= */

:root {
  /* Brand */
  --color-brand-orange:        #F69500;
  --color-brand-orange-bright: #FFA827;
  --color-brand-orange-deep:   #C77400;
  --color-brand-amber-grain:   #3A2C14;

  /* Inks */
  --color-ink-1: #0B0B0B;
  --color-ink-2: #171717;
  --color-ink-3: #1F1F1F;
  --color-ink-4: #2A2A2A;
  --color-ink-5: #3A3A3A;

  /* Bone */
  --color-bone-0: #FFFFFF;
  --color-bone-1: #F5F1EA;
  --color-bone-2: #E6E0D4;
  --color-bone-3: #B8AE9E;

  /* Semantic */
  --color-success: #4CAE6B;
  /* Czerwien bledu: jeden token dla calego motywu (audyt D9). #FF7A6E daje
     7,74:1 na --bg-page i 6,48:1 na --bg-input; poprzedni #D33A2C mial 4,13:1
     jako tekst, ponizej progu 4,5:1. Trzy literalne #FF8A80 i --et-kasa-blad
     wskazuja teraz tutaj. */
  --color-danger:  #FF7A6E;
  --color-info:    #4C8DAE;

  --bg-page:    var(--color-ink-1);
  --bg-surface: var(--color-ink-2);
  --bg-input:   var(--color-ink-3);
  --fg-default: var(--color-bone-1);
  --fg-muted:   var(--color-bone-3);
  --fg-faint:   #8A8070; /* WCAG AA ~5.06:1 na --color-ink-1 (było #6E6557, ~3.43:1) */
  --border-default: var(--color-ink-4);
  --border-strong:  var(--color-ink-5);
  /* Obrys POL i przyciskow drugorzednych (audyt D8). WCAG 1.4.11 wymaga 3:1
     dla granicy, ktora identyfikuje kontrolke; --border-default dawal 1,15:1
     na tle pola. #6F6A62 (cieply, z palety kosci): 3,07:1 na --bg-input,
     3,34:1 na --bg-surface, 3,67:1 na --bg-page. Separatory i karty zostaja
     na --border-default - to nie sa cele dotyku. */
  --border-input:   #6F6A62;

  --font-display: "Bebas Neue", "Arial Narrow", sans-serif;
  --font-heading: "Oswald", "Bebas Neue", "Arial Narrow", sans-serif;
  --font-body:    "Inter", "Helvetica Neue", Arial, sans-serif;

  --radius-3: 8px;
  --radius-pill: 999px;
  --shadow-1: 0 6px 20px rgba(0,0,0,.45);
  --shadow-2: 0 14px 40px rgba(0,0,0,.6);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* odstępy między modułami — sterowane w Personalizacji */
  --et-space-desktop: 96px;
  --et-space-mobile: 56px;
  --et-space: var(--et-space-desktop);
  --et-space-sm: calc(var(--et-space-desktop) * .5);
}

/* --- Base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg-page);
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
}
img { max-width: 100%; height: auto; }
/* Safari na iPhonie powieksza strone przy fokusie w polu ponizej 16 px i sam
   nie wraca (audyt D4/U10). `:where()` ma zerowa szczegolowosc: wygrywa tylko
   z arkuszem przegladarki (13,33 px), a kazda regula motywu nadal moze dac
   wiecej - np. wyszukiwarka 20 px, napis na pudelku 17 px. Pola motywu,
   ktore mialy 13-15 px, dostaly 16 px u siebie. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="submit"]):not([type="button"]), select, textarea) { font-size: 16px; }
/* KRÓJ MOTYWU TAKŻE W STEROWANIU BEZ WŁASNEJ REGUŁY (audyt iOS 2026-09-26).
   Arkusz iPhone'a daje przyciskom i polom `font: 11px system-ui` (Chrome:
   13,33 px), a pisma się nie dziedziczy. Sloty „Rolka 1-4" konfiguratora,
   kropki hero i krzyżyki pomocy, zgód i popupu nie miały kroju motywu -
   krzyżyk „×" wychodził na iPhonie z kroju systemowego. Zerowa waga jak
   wyżej: każda reguła motywu i wtyczki wygrywa. Rozmiar zostaje z arkusza
   przeglądarki - `inherit` podniósłby go w Chrome z 13,33 do 16 px. */
:where(button, input, select, textarea) { font-family: inherit; }
a { color: var(--color-brand-orange); text-decoration: none; }
/* NAJECHANIE TYLKO TAM, GDZIE JEST MYSZ (audyt iOS 2026-09-26).
   Safari na iPhonie nadaje `:hover` elementowi po dotknięciu i zostawia go,
   dopóki nie dotknie się czegoś innego: przycisk zostaje rozjaśniony, kolor
   w palecie konfiguratora ma pomarańczową ramkę jak wybrany. Dlatego efekty
   najechania stoją w `(hover: hover) and (pointer: fine)` - ta sama
   konwencja, co przy kartach produktów. Na dotyk odpowiada `:active`. */
@media (hover: hover) and (pointer: fine) {
  a:hover { color: var(--color-brand-orange-bright); }
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 400; letter-spacing: .04em; text-transform: uppercase; color: var(--color-bone-0); line-height: 1.05; margin: 0 0 .5em; }
h4, h5, h6 { font-family: var(--font-heading); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--color-bone-0); }
h1 { font-size: clamp(2.4rem, 5vw, 4rem); }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.8rem); }
h3 { font-size: 1.4rem; }

.container {
  width: min(100% - (var(--et-gutter, 24px) * 2), var(--et-container, 1320px));
  max-width: none;
  margin-inline: auto;
  padding: 0;
}
.site-main {
  width: min(100% - (var(--et-gutter, 24px) * 2), var(--et-container, 1320px));
  margin-inline: auto;
  padding: var(--et-space-sm) 0 var(--et-space);
}

/* Grain — sygnaturowe amber-speckle tło */
.et-grain { position: relative; }
.et-grain::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: .18;
  background-image:
    radial-gradient(circle at 12% 30%, var(--color-brand-amber-grain) 0 1.5px, transparent 2px),
    radial-gradient(circle at 78% 12%, var(--color-brand-amber-grain) 0 1px, transparent 1.6px),
    radial-gradient(circle at 55% 80%, var(--color-brand-amber-grain) 0 1.2px, transparent 1.8px),
    radial-gradient(circle at 30% 65%, var(--color-brand-amber-grain) 0 1px, transparent 1.5px),
    radial-gradient(circle at 90% 55%, var(--color-brand-amber-grain) 0 1.4px, transparent 2px);
  background-size: 220px 220px, 180px 180px, 260px 260px, 200px 200px, 240px 240px;
}
.et-grain > * { position: relative; z-index: 1; }

/* --- Dostępność: treść tylko dla czytników ekranu -------------------------- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Focus klawiatury (dostępność) ----------------------------------------- *
 * Jeden spójny pierścień focusu dla całego motywu.
 *
 * `:focus-visible` odpala się TYLKO przy nawigacji klawiaturą — kliknięcie
 * myszą nie zostawia ramki. To rozwiązuje pierwotny problem, dla którego
 * focus był wcześniej gaszony na sztywno (`outline: none` w 4 miejscach):
 * chodziło o brak brzydkiej ramki po kliknięciu, ale efektem ubocznym był
 * całkowicie niewidoczny focus przy nawigacji Tabem — m.in. w polu
 * wyszukiwarki, które ma `border: 0`, więc podświetlanie ramki nic nie dawało.
 */
:focus-visible {
  outline: 2px solid var(--color-brand-orange);
  outline-offset: 2px;
}
/* Przeglądarki wspierające :focus-visible — chowamy pierścień przy myszy.
   Starsze (bez wsparcia) zignorują tę regułę i pokażą domyślny outline,
   co jest bezpiecznym zachowaniem awaryjnym. */
:focus:not(:focus-visible) {
  outline: none;
}
/* Na ciemnym tle sam pomarańczowy pierścień bywa mało czytelny przy
   elementach w kolorze akcentu (np. przycisk CTA) — dokładamy ciemny
   kontrapunkt, żeby pierścień był widoczny na każdym tle. */
.btn:focus-visible,
button:focus-visible,
.et-palette-color:focus-visible,
.et-slot:focus-visible {
  outline-color: var(--color-brand-orange);
  box-shadow: 0 0 0 4px var(--color-ink-1);
}

/* --- Skip link (dostępność) ------------------------------------------------ */
.skip-link {
  position: absolute;
  top: -100px;
  left: 12px;
  z-index: 10000;
  background: var(--color-brand-orange, #F69500);
  color: var(--color-ink-1, #0B0B0B);
  padding: 10px 18px;
  border-radius: 4px;
  font-weight: 600;
  text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus {
  top: 12px;
}

/* --- Promo strip ---------------------------------------------------------- */
.promo {
  background: var(--color-ink-1);
  border-bottom: 1px solid var(--border-default);
  overflow: hidden;
  height: 34px;
  display: flex;
  align-items: center;
  /* ZNIKANIE PRZY KRAWĘDZIACH, zamiast ucięcia nożem.

     Zgłoszenie z przeglądu mobilnego (2026-08-13): „promo strip ucina tekst
     (»WA OD 89ZŁ«)". Pasek zapętla się poprawnie - to, co widać, to napis
     w połowie wyjazdu za lewą krawędź, czyli normalna praca marquee. Ale
     przy ostrej krawędzi „DARMOWA DOSTAWA OD 89ZŁ" ucięte na „WA OD 89ZŁ"
     czyta się jak literówka albo błąd, a nie jak ruch.

     Maska zamienia ucięcie w zanikanie: napis wchodzi i wychodzi, zamiast
     pojawiać się i znikać w pół litery. Osiem procent szerokości - tyle,
     żeby zdążyło zblednąć, i nie więcej, bo pasek ma 34 px wysokości
     i nie ma czego chować.

     `-webkit-` obok standardowego: Safari nadal potrzebuje prefiksu, a bez
     niego maski po prostu nie ma - i to na telefonie, czyli tam, gdzie
     zgłoszenie powstało. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}
.promo-track {
  display: flex;
  gap: 0;
  white-space: nowrap;
  animation: promo-scroll 30s linear infinite;
  /* Ruch idzie na GPU i nie budzi układu strony przy każdej klatce.
     Pasek chodzi bez przerwy przez cały czas wizyty, więc to jest jedyne
     miejsce na stronie, gdzie ta podpowiedź naprawdę coś oszczędza. */
  will-change: transform;
}
/* Kto prosi o mniej ruchu, dostaje nieruchomy pasek, a nie migający.
   Napisy zostają czytelne - są trzy kopie, więc pierwsza wypełnia ekran. */
@media (prefers-reduced-motion: reduce) {
  .promo-track { animation: none; }
}
.promo-item {
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  /* KOŚĆ, NIE POMARAŃCZ - audyt pulpitu: „nad foldem masz jednocześnie pasek,
     CTA, ceny, badge »Bestseller« i przycisk pomocy. Za dużo iskier naraz;
     zostaw pomarańcz dla CTA i badge, pasek daj w bieli/bone z jednym
     akcentem".

     Ten pasek chodzi BEZ PRZERWY przez całą wizytę. Kolor akcentu, który się
     rusza i nigdy nie znika, jest najgorszym możliwym miejscem na akcent:
     przyciąga oko w kółko, a nie mówi nic, czego nie powiedziałby spokojnie.

     Jeden akcent zostaje - w kropkach rozdzielających. Tyle wystarczy, żeby
     pasek należał do marki, a nie konkurował z przyciskiem pod spodem. */
  color: var(--color-bone-2);
  padding: 0 28px;
  position: relative;
}
.promo-item::before {
  content: "·";
  position: absolute; left: -3px;
  color: var(--color-brand-orange);
}
/* Pauza przy najechaniu - żeby dało się przeczytać komunikat, który akurat
   przejeżdża. Bez tego jedyną drogą jest czekanie na kolejne okrążenie. */
.promo:hover .promo-track,
.promo:focus-within .promo-track { animation-play-state: paused; }
/* DOKŁADNIE JEDNA TRZECIA, a nie 33,333%.

   W `header.php` pasek jest wypisany TRZY RAZY, więc przesunięcie o jedną
   kopię wraca dokładnie w to samo miejsce i pętla jest niewidoczna. Wpisane
   ręcznie „33.333%" to o 0,001% za mało: przy każdym obiegu zostawał ułamek
   piksela, który po kilku minutach zbierał się w widoczne szarpnięcie.
   `calc()` liczy to bez zaokrąglania. */
@keyframes promo-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% / 3)); }
}

/* --- Header --------------------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 50;
  /* Kurczenie przy przewijaniu - klasę nadaje `egotape.js`. Nagłówek NIE
     znika: znikający zabiera ze sobą koszyk i wyszukiwarkę akurat wtedy,
     gdy człowiek przegląda produkty i najczęściej ich potrzebuje. */
  transition: padding .2s var(--ease, ease);
  background: rgba(11,11,11,.94);
  /* Safari do 17 zna tylko wersję z przedrostkiem (audyt iOS 2026-09-26). */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border-default);
}
/* =========================================================================
   NAGŁÓWEK ZMNIEJSZA SIĘ PRZY PRZEWIJANIU

   Na górze strony pełny rozmiar - tam jest miejsce i to pierwsze wrażenie.
   Po przewinięciu kurczy się: niższy pasek i mniejsze logo, ale wszystkie
   przyciski zostają na miejscu i klikalne.

   Dlaczego kurczenie, a nie chowanie: znikający nagłówek zabiera koszyk
   i wyszukiwarkę dokładnie wtedy, gdy człowiek przegląda produkty - czyli
   wtedy, gdy najczęściej ich szuka. Odzyskane piksele nie są tego warte.
   ========================================================================= */
.header.header-maly .header-inner { padding-top: 6px; padding-bottom: 6px; }
/* Skurczone logo to UŁAMEK ustawionej wysokości, nie własna liczba.

   Wcześniej stało tu 26 px na sztywno. Odkąd wysokość logo jest suwakiem
   w Personalizacji (2026-08-13, prośba właściciela), sztywna liczba
   znaczyłaby, że przy większym logo nagłówek kurczy się mocniej, a przy
   mniejszym - wcale albo w drugą stronę. Sześć dziesiątych trzyma tę samą
   proporcję przy każdym ustawieniu. */
.header.header-maly .header-logo img {
  height: calc(var(--et-logo-pc, 44px) * .6);
  transition: height .2s var(--ease, ease);
}
.header .header-logo img { transition: height .2s var(--ease, ease); }
@media (prefers-reduced-motion: reduce) {
  .header,
  .header .header-logo img { transition: none; }
}
.header-inner {
  width: min(100% - (var(--et-gutter, 24px) * 2), var(--et-container, 1320px));
  max-width: none;
  margin-inline: auto;
  display: flex; align-items: center; gap: 28px;
  padding: 14px 0;
}
/* Wysokość z Personalizacji - „Logo w nagłówku, komputer/telefon".
   Szerokość zawsze `auto`: znak jest szeroki i niski, więc sterowanie
   szerokością rozjeżdżałoby proporcje przy pierwszej zmianie pliku. */
/* ZNAK NIGDY SIE NIE KURCZY.

   `.header-logo` jest elementem flex, wiec przy ciasnym naglowku oddawal
   szerokosc sasiadom - a poniewaz wysokosc jest narzucona, obrazek nie
   zmniejszal sie, tylko SPLASZCZAL. Zmierzone u zalogowanego na pulpicie
   (dochodzi przycisk narzedzi): 250 px zamiast 292 przy tej samej wysokosci,
   czyli znak zwezony o 14%. Na oko wyglada to jak inna wersja logo. */
.header-logo { flex: 0 0 auto; }
.header-logo img { height: var(--et-logo-pc, 44px); width: auto; display: block; }
/* GÓRNE MENU ZAWSZE W JEDNYM WIERSZU (2026-09-26, właściciel: „ma być
   zawsze w jednej linii, jeśli występuje, odpowiednio skalowany bez
   ucinania tekstu”).

   Rano audyt naprawiał ikony wypchnięte za ekran (sześć pozycji to 815 px,
   przy 1280 px koszyk stał na 1300-1340) i dołożył `flex-wrap` jako
   zabezpieczenie - u zalogowanego (przycisk narzędzi, +54 px) menu spadło
   do DRUGIEGO WIERSZA. Drugiego wiersza nie ma nigdy: pismo, rozstrzelenie
   i odstępy mnożą się przez `--et-nav-fit` (1 = pełny rozmiar), a funkcja
   „MENU W JEDNYM WIERSZU” w `egotape.js` zmniejsza je płynnie, aż rząd się
   zmieści - także przy szerszym piśmie innego systemu. Wartości niżej to
   punkt startu przed JS (bez mrugnięcia przy wczytaniu): zmierzone w
   Chromium i WebKit, z zapasem. Poniżej 1280 px menu jest warstwą
   (reguły „MENU JAKO WARSTWA DO 1279 PX” niżej). */
.header-nav { display: flex; margin-left: 8px; min-width: 0; --et-nav-fit: 1; }
.header-nav ul {
  display: flex; flex-wrap: nowrap;
  gap: calc(28px * var(--et-nav-fit));
  list-style: none; margin: 0; padding: 0;
}
/* Pozycje menu nigdy nie łamią się na dwie linie: przy ciasnym nagłówku
   element flex kurczy się i zawija tekst, co wygląda na usterkę. */
.header-nav a { white-space: nowrap; }
.header-nav a {
  font-family: var(--font-heading);
  font-size: calc(14px * var(--et-nav-fit)); font-weight: 500;
  letter-spacing: calc(.08em * var(--et-nav-fit)); text-transform: uppercase;
  color: var(--fg-default);
  border-bottom: 2px solid transparent;
  padding-bottom: 2px;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.header-nav .current-menu-item > a { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
@media (hover: hover) and (pointer: fine) {
  .header-nav a:hover { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
}
/* Punkt startu przed JS. Bez przycisku narzędzi rząd w pełnym rozmiarze
   mieści się od ok. 1367 px; z nim (`:has`) - od ok. 1421 px. */
@media (min-width: 1280px) and (max-width: 1439px) {
  .header-inner { gap: 20px; }
  .header-nav { margin-left: 0; --et-nav-fit: .86; }
  .header-inner:has(.et-tools-toggle) .header-nav { --et-nav-fit: .8; }
}
/* Od 1440 px nagłówek ma już stałą szerokość kontenera, więc szerszy ekran
   nie daje menu więcej miejsca - z przyciskiem narzędzi brakuje 15 px. */
@media (min-width: 1440px) {
  .header-inner:has(.et-tools-toggle) .header-nav { --et-nav-fit: .92; }
}

/* --- Narzędzia: pas pod nagłówkiem ------------------------------------- */
/* Ten sam wzorzec co pasek wyszukiwania: pełna szerokość pod nagłówkiem,
   a nie panel przyklejony do ikony. Panel wchodził na menu i nie miał
   miejsca na opis obok logo. */
.et-tools-toggle[aria-expanded="true"] { color: var(--color-brand-orange); }

/* Wejście w rozwijanym menu - tylko na telefonie. Na desktopie mamy ikonę,
   a pozycja tekstowa rozpychała tam nawigację do dwóch linii. */
.et-tools-mobile { display: none; }

.tools-bar {
  position: relative;
  border-top: 1px solid var(--border-default);
  background: var(--color-ink-2);
  animation: etToolsIn .18s var(--ease);
}
.tools-bar[hidden] { display: none; }
@keyframes etToolsIn {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .tools-bar { animation: none; }
}

.tools-bar-inner { max-width: 1280px; margin: 0 auto; padding: 14px 24px 18px; }
.tools-bar-head {
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--fg-faint);
  margin: 0 0 10px;
}
/* auto-fill z górnym ograniczeniem: jedno narzędzie nie rozciąga się na
   całą szerokość ekranu, a kolejne ustawią się obok bez zmian w kodzie. */
.tools-bar ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 380px));
}
.tool-card {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 16px;
  background: var(--bg-page);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  text-decoration: none; color: var(--fg-default);
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .12s var(--ease);
}
.tool-card:focus-visible {
  border-color: var(--color-brand-orange);
  background: var(--bg-surface);
  transform: translateY(-2px);
}
@media (hover: hover) and (pointer: fine) {
  .tool-card:hover {
    border-color: var(--color-brand-orange);
    background: var(--bg-surface);
    transform: translateY(-2px);
  }
}
.tool-logo { width: 116px; height: auto; flex: none; display: block; }
.tool-text { display: block; min-width: 0; }
.tool-name {
  display: block;
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
@media (hover: hover) and (pointer: fine) {
  .tool-card:hover .tool-name { color: var(--color-brand-orange); }
}
.tool-desc {
  display: block; margin-top: 3px;
  font-size: 12px; line-height: 1.35; color: var(--fg-muted);
}

@media (max-width: 768px) {
  .tools-bar-inner { padding: 12px 20px 16px; }
  .tools-bar ul { grid-template-columns: 1fr; }
  .tool-logo { width: 92px; }
}

.header-actions { display: flex; gap: 10px; align-items: center; margin-left: auto; }
.icon-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  background: transparent;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  color: var(--fg-default);
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
}
/* PUSTY KOSZYK NIE POKAZUJE ZERA - audyt pulpitu: „badge koszyka pokazuje
   »0«, ukryj przy pustym koszyku".

   `egotape_cart_count_html()` wypisywał atrybut `hidden` od zawsze i od
   zawsze był on bezskuteczny: `display: inline-flex` niżej bije domyślne
   `[hidden] { display: none }` z arkusza przeglądarki. Znacznik mówił
   prawdę, arkusz go nie słuchał. */
.icon-btn .badge[hidden] { display: none; }
.icon-btn .badge {
  position: absolute; top: -6px; right: -6px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  border-radius: var(--radius-pill);
}
.et-nav-toggle { display: none; }

.search-bar {
  position: relative;
  border-top: 1px solid var(--border-default);
  background: var(--color-ink-2);
}
.search-bar form {
  max-width: 1280px; margin: 0 auto;
  display: flex; align-items: center; gap: 16px;
  padding: 14px 24px;
}
.search-bar input[type="search"] {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--fg-default);
  font-family: var(--font-heading);
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: .04em;
  /* Pole wyszukiwania po iOS-owemu (audyt iOS 2026-09-26): bez tego Safari
     rysuje je jako systemowe `searchfield`, a wypełnienie brało z arkusza
     przeglądarki - na iPhonie 4/10 px, w Chrome 1/2 px, więc napis stał
     w innym miejscu na każdym telefonie. */
  -webkit-appearance: none;
  appearance: none;
  border-radius: 0;
  padding: 6px 10px;
}
.search-bar input::placeholder { color: var(--fg-faint); }
.search-bar .close {
  background: none; border: 0;
  color: var(--fg-muted);
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer;
  /* Cel dotyku 44 px - napis 12 px dawał przycisk wysoki na 16 px. */
  min-height: 44px;
  padding: 0 8px;
}
@media (hover: hover) and (pointer: fine) {
  .search-bar .close:hover { color: var(--color-brand-orange); }
}

/* --- Podpowiedzi wyszukiwania (AJAX) --------------------------------------- */
.et-search-suggestions {
  position: absolute;
  left: 0; right: 0; top: 100%;
  z-index: 60;
  max-width: 1280px; margin: 0 auto;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-top: none;
  border-radius: 0 0 var(--radius-3) var(--radius-3);
  box-shadow: 0 16px 30px rgba(0,0,0,.35);
  /* `dvh` = wysokość widocznego okna. Safari liczy `vh` od okna BEZ pasków
     narzędzi, więc 70vh sięgało pod pasek adresu; `vh` zostaje dla
     przeglądarek sprzed `dvh`. */
  max-height: 70vh;
  max-height: 70dvh;
  overflow-y: auto;
}
.et-search-suggestion {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 24px;
  color: var(--fg-default);
  text-decoration: none;
  border-bottom: 1px solid var(--border-default);
}
.et-search-suggestion:last-child { border-bottom: none; }
.et-search-suggestion.is-active {
  background: var(--color-ink-3);
}
@media (hover: hover) and (pointer: fine) {
  .et-search-suggestion:hover { background: var(--color-ink-3); }
}
.et-search-suggestion img {
  width: 44px; height: 44px;
  object-fit: cover;
  border-radius: var(--radius-3);
  background: #fff;
  flex-shrink: 0;
}
.et-search-suggestion-info {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.et-search-suggestion-title {
  font-family: var(--font-heading);
  font-size: 13px; letter-spacing: .03em; text-transform: uppercase;
  color: var(--color-bone-0);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.et-search-suggestion-price { font-size: 13px; color: var(--color-brand-orange); }
.et-search-see-all {
  justify-content: center;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
}
@media (hover: hover) and (pointer: fine) {
  .et-search-see-all:hover { color: var(--color-brand-orange); }
}
.et-search-empty {
  margin: 0; padding: 16px 24px;
  color: var(--fg-muted); font-size: 14px;
}
@media (max-width: 640px) {
  .et-search-suggestion { padding: 10px 16px; }
  .et-search-empty { padding: 16px; }
}

/* --- Buttons -------------------------------------------------------------- */
.btn,
.button,
button[type="submit"],
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 13px 24px;
  /* Dolna granica celu dotyku (audyt D5/U9): ten sam przycisk mial 39-52 px
     zaleznie od miejsca. 44 px to prog Apple; wysokosc zalezy odtad od tej
     liczby, nie od wypelnienia i kroju. */
  min-height: 44px;
  border-radius: var(--radius-3);
  border: 1px solid transparent;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  cursor: pointer;
  line-height: 1;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .1s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover,
  .woocommerce a.button:hover,
  .woocommerce button.button:hover,
  .woocommerce input.button:hover {
    background: var(--color-brand-orange-bright);
    color: var(--color-ink-1);
  }
}
/* Warianty .alt WooCommerce (Dodaj do koszyka, Kupuję i płacę) — nadpisanie fioletu */
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit.alt,
.woocommerce button.single_add_to_cart_button,
.woocommerce-checkout #place_order,
.wc-block-components-button:not(.is-link) {
  background: var(--color-brand-orange) !important;
  color: var(--color-ink-1) !important;
  min-height: 44px;
  border: 1px solid transparent;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: var(--radius-3);
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce a.button.alt:hover,
  .woocommerce button.button.alt:hover,
  .woocommerce input.button.alt:hover,
  .woocommerce button.single_add_to_cart_button:hover,
  .woocommerce-checkout #place_order:hover,
  .wc-block-components-button:not(.is-link):hover {
    background: var(--color-brand-orange-bright) !important;
    color: var(--color-ink-1) !important;
  }
}
/* WYŁĄCZONY ZNACZY „JESZCZE NIEPEŁNY", NIE „ZEPSUTY" (2026-09-26).
   Przy produkcie z wyborem kolorów przycisk czeka na komplet rolek. Szary
   prostokąt z bladym napisem - a WooCommerce dokładał jeszcze `opacity: .5`
   - czytał się jak awaria. Przerywana ramka to w motywie „do uzupełnienia",
   tak jak puste sloty rolek; tak samo rysuje się wyłączony przycisk
   konfiguratora i paska na dole (reguły przy `.et-builder-submit`). */
.woocommerce a.button.alt.disabled,
.woocommerce button.button.alt:disabled,
.woocommerce button.button.alt:disabled[disabled] {
  background: transparent !important;
  color: var(--fg-faint) !important;
  border: 1px dashed var(--border-input);
  opacity: 1;
}
.btn:active { background: var(--color-brand-orange-deep); transform: scale(.98); }
.btn-secondary { background: transparent; color: var(--color-bone-1); border-color: var(--border-input); }
@media (hover: hover) and (pointer: fine) {
  .btn-secondary:hover { background: transparent; border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
}

/* --- Hero ----------------------------------------------------------------- */
.hero {
  display: grid;
  grid-template-columns: minmax(0, var(--et-hero-left, 52%)) minmax(0, 1fr);
  gap: var(--et-hero-gap, 20px);
  /* TA SAMA SIATKA, CO KAŻDA INNA SEKCJA - audyt pulpitu (2026-08-13):
     „nagłówek PANCERZ DLA zaczyna się ~30 px dalej w prawo niż TAŚMY
     TRENINGOWE i lewa krawędź kart poniżej (...) foto hero kończy się przed
     prawą krawędzią gridu".

     Hero miało własne liczby: 1280 px szerokości i 24 px marginesu, podczas
     gdy `.container` liczy się z `--et-container` (1320) i `--et-gutter`
     (28). Przy ekranie 1440 px dawało to lewą krawędź na 104 px zamiast 88 -
     szesnaście pikseli różnicy, do których dokładało się jeszcze 20 px
     przesunięcia treści (niżej). Stąd te trzydzieści.

     Osobne liczby nie miały uzasadnienia poza tym, że hero powstało wcześniej
     niż zmienne kontenera. Teraz bierze te same, więc każda zmiana szerokości
     strony w Personalizacji rusza hero razem z resztą - i lewa linia jest
     jedna na całej stronie. Prawa krawędź zdjęcia dojeżdża tym samym do
     krawędzi siatki. */
  width: min(100% - (var(--et-gutter, 28px) * 2), var(--et-container, 1320px));
  max-width: none;
  margin-inline: auto;
  padding: var(--et-space) 0;
  background: var(--color-ink-1);
}
.hero-left { display: flex; flex-direction: column; gap: 20px; justify-content: center; }
.hero-eyebrow {
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-brand-orange);
}
/* NAPIS EGOTAPE NIE STOI JUŻ W HERO - ani na telefonie, ani na pulpicie.

   Audyt telefonu (2026-08-13) zdjął go z ekranów wąskich. Audyt pulpitu tego
   samego dnia dorzucił argument, którego wcześniej nie było: „wordmark
   z przekreśleniem nad nagłówkiem czyta się wręcz jak SKREŚLONY TEKST".

   To rozstrzyga. Przekreślenie jest częścią znaku marki i na pasku nawigacji
   czyta się jako znak; postawione bezpośrednio nad zdaniem robi z tego zdania
   coś wykreślonego. Duplikat osłabiał hierarchię, a ta interpretacja psuła
   sam komunikat.

   Element ZOSTAJE w szablonie, tylko schowany: `egotape.js` nadal pyta go
   o szerokość i sięga po kolumnę dopiero, gdy jej nie dostanie, więc powrót
   to skasowanie jednej linijki. */
.hero-strike { display: none; }
.hero-strike { max-width: 420px; }
.hero-strike img { width: 100%; height: auto; display: block; }
.hero-title { font-size: clamp(2.6rem, 5.4vw, 4.4rem); margin: 0; }
/* MIARA WIERSZA, NIE TWARDE PRZEŁAMY - audyt pulpitu: „wymuszone <br>
   w akapicie hero połamie się na innych szerokościach, zamień na max-width".

   Przełamy są wpisane w Personalizacji pod jedną konkretną szerokość ekranu
   i pod każdą inną wypadają w losowym miejscu - stąd wiersze-sieroty, które
   audyt telefonu wytknął osobno. Ukrywamy je i zostawiamy przeglądarce to,
   co robi dobrze: łamanie tekstu tam, gdzie kończy się miejsce.

   65 znaków to miara, przy której oko trafia z końca wiersza na początek
   następnego bez gubienia linijki. Treść w Personalizacji zostaje nietknięta
   - właściciel może dalej pisać przełamy, po prostu przestały decydować
   o wyglądzie. */
.hero-sub { max-width: 58ch; }
.hero-sub br { display: none; }
/* Cena pod claimem (audyt U5: pierwszy ekran telefonu nie mowil „za ile").
   Mniejsza od leadu i bez pogrubienia - to informacja, nie drugi naglowek;
   pomarancz robi z niej cene, tak jak przy produktach. Odstepy do sasiadow
   daje `gap` kolumny, ten sam co dla leadu. Lamie sie naturalnie, gdy sie
   nie miesci - nic nie jest ucinane. */
.hero-price {
  margin: 0;
  max-width: 58ch;
  font-family: var(--font-heading);
  font-size: 16px; font-weight: 400;
  letter-spacing: .02em;
  line-height: 1.4;
  color: var(--color-brand-orange);
}

/* =========================================================================
   OSOBNY OPIS NA TELEFON - tylko wtedy, gdy właściciel go napisze.

   Zgłoszenie (2026-08-13): „na mobilce opis w hero nie podoba mi się
   formatowanie, znaki nowej linii są w złym miejscu, chcę mieć nad tym
   kontrolę (na PC to jest git)".

   Sedno: przełamy wpisane pod szeroki ekran na telefonie wypadają w losowym
   miejscu, a te dobre dla telefonu psułyby pulpit. Jedno pole nie może
   obsłużyć dwóch szerokości - i żadna automatyka tego nie zgadnie, bo to
   jest decyzja o rytmie zdania, nie o łamaniu tekstu.

   Drugie pole w Personalizacji rozwiązuje to wprost. Puste znaczy „użyj
   tego samego co na komputerze" i jest stanem domyślnym, więc dopóki
   właściciel nic nie wpisze, w kodzie strony NIE MA drugiego akapitu -
   `front-page.php` w ogóle go nie wypisuje. Żadnego powielonego tekstu.

   W wersji na telefon przełamy SĄ honorowane: to jest cały powód, dla
   którego to pole istnieje. */
.hero-sub-mobile { display: none; }
.hero-sub { color: var(--fg-muted); max-width: 54ch; margin: 0; }
.hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 6px; }
.hero-right {
  border-radius: var(--radius-3);
  /* WYSOKOŚĆ HERO Z PERSONALIZACJI - „Hero: wysokość, komputer (px)".

     Ta jedna liczba rządzi całą sekcją, nie tylko zdjęciem: hero jest
     siatką dwukolumnową, więc wiersz jest tak wysoki, jak najwyższa
     z kolumn. Kolumna z tekstem ma `justify-content: center`, czyli treść
     zostaje pośrodku niezależnie od tego, ile miejsca dostanie. Wystarczy
     więc podnieść tę - i rośnie hero razem z galerią.

     Dlatego suwak jest JEDEN, mimo że zgłoszenie mówiło o dwóch rzeczach
     („wysokość hero oraz tej galerii zdjęć obok"): dwa niezależne pola
     dawałyby stany, w których mniejsza z liczb nie robi nic, i człowiek
     ciągnąłby suwak bez żadnego skutku na ekranie.

     Telefon ma własną regułę niżej i to ustawienie go nie dotyczy - tam
     zdjęcie jest tłem pod tekstem, a nie sąsiednią kolumną. */
  min-height: var(--et-hero-wysokosc-pc, 380px);
  background:
    radial-gradient(circle at 60% 40%, rgba(246,149,0,.16) 0%, transparent 60%),
    var(--color-ink-2);
  border: 1px solid var(--border-default);
}

/* --- Features ------------------------------------------------------------- */
/* =========================================================================
   PASEK KORZYŚCI - przesuwająca się wstęga pod hero

   Zastąpił siatkę czterech kafli (`.feature-grid`), która na telefonie
   schodziła do jednej kolumny i zajmowała pół ekranu, żeby powiedzieć
   cztery krótkie zdania. Treść pochodzi teraz z Personalizacji
   (`inc/pasek-korzysci.php`).

   Wstęga celowo NIE MA kontenera o stałej szerokości - jedzie przez całą
   szerokość okna, bo to ona daje wrażenie ruchu. Ograniczenie jej do
   kontenera zrobiłoby z niej pudełko z przewijanym tekstem.
   ========================================================================= */
.pasek-korzysci {
  padding: 10px 0;
  border-top: 1px solid var(--border-default);
  border-bottom: 1px solid var(--border-default);
  overflow: hidden;
  /* Bez tego pasek rozpycha stronę w bok na wąskich ekranach. */
  max-width: 100%;
}
.pasek-tor {
  display: flex;
  width: max-content;
  animation: pasek-jazda var(--pasek-czas, 28s) linear infinite;
}
/* Zatrzymanie na najechaniu i na klawiaturze - żeby dało się przeczytać
   pozycję, która akurat ucieka. Bez tego pasek jest ozdobą, a nie treścią. */
.pasek-korzysci:hover .pasek-tor,
.pasek-korzysci:focus-within .pasek-tor { animation-play-state: paused; }

.pasek-ciag { display: flex; flex: 0 0 auto; }
.pasek-poz {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 28px;
  white-space: nowrap;
  font-size: 14px;
  line-height: 1.4;
}
/* Kropka rozdzielająca zamiast obramowań - przy przesuwaniu krawędzie
   migotałyby na granicy pikseli. */
.pasek-poz::after {
  content: "";
  width: 4px;
  height: 4px;
  margin-left: 28px;
  border-radius: 50%;
  background: var(--border-default);
  align-self: center;
}
.pasek-poz strong {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: 13px;
}
.pasek-opis { color: var(--fg-muted); }

@keyframes pasek-jazda {
  from { transform: translateX(0); }
  /* -50%, bo tor niesie DWIE kopie tej samej treści. Po przejechaniu
     pierwszej druga stoi dokładnie tam, gdzie zaczynała pierwsza, więc
     powrót do zera jest niewidoczny. */
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  /* Bez ruchu wstęga musi dać się przeczytać w całości, więc zawija się
     do zwykłego wiersza i pokazuje jedną kopię. */
  .pasek-tor { animation: none; width: 100%; flex-wrap: wrap; justify-content: center; }
  .pasek-ciag { flex-wrap: wrap; justify-content: center; }
  .pasek-ciag[aria-hidden="true"] { display: none; }
  .pasek-poz { white-space: normal; }
}

/* --- Section head ---------------------------------------------------------- */
.section-head { margin: 0 0 var(--et-odstep-naglowek-karty, 40px); }
.section-head .eyebrow {
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-brand-orange);
  margin-bottom: 10px;
}
.products-section { padding: var(--et-space) 0; }
/* Odstęp pod hero na dużych ekranach - osobne ustawienie w Personalizacji.
   Dotyczy wyłącznie sekcji stojącej TUŻ pod hero; pozostałe sekcje dalej
   biorą wspólny odstęp `--et-space`, bo to jedno miejsce na stronie, gdzie
   przerwa decyduje o tym, czy widać towar. Telefon ma własną regułę wyżej
   w tym pliku i tam wygrywa zapytanie o media. */
@media (min-width: 769px) {
  .hero + section,
  .hero + * > section:first-child { padding-top: var(--et-odstep-pod-hero-pc, 96px); }
}

/* --- WooCommerce: siatka produktów ---------------------------------------- */
.woocommerce ul.products {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin: 0; padding: 0;
  list-style: none;
}
.woocommerce ul.products::before,
.woocommerce ul.products::after { display: none; }
.woocommerce ul.products li.product {
  position: relative;
  width: auto !important;
  margin: 0 !important;
  float: none !important;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden;
  box-shadow: var(--shadow-1);
  transition: box-shadow .25s var(--ease), border-color .25s var(--ease);
  display: flex;
  flex-direction: column;
}
/* Najechanie TYLKO tam, gdzie jest kursor. Na iPhonie `:hover` zostaje po
   dotknięciu karty (zgłoszenie #4, 2026-09-26: po „Dodaj do koszyka” karta
   została z pomarańczową ramką i cieniem do następnego dotknięcia). Tak samo
   niżej: ramka, cień, krążek bóstwa i przycisk. */
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product:hover { box-shadow: var(--shadow-2); }
}

.product-tag,
.woocommerce span.onsale {
  position: absolute; top: 14px; left: 14px; z-index: 3;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  min-height: 0; line-height: 1.4;
  margin: 0;
}

.et-product-well {
  position: relative;
  aspect-ratio: 1 / 1;
  display: block;
  padding: 0;
  /* CIEMNE TŁO POD GRAFIKĄ, nie białe.

     Zgłoszenie z przeglądu mobilnego (2026-08-13): „zdjęcia produktów na
     białym tle świecą w ciemnym UI, duże białe prostokąty rozbijają mrok
     brandu". Białe pole zostało tu jako podkład pod grafiki
     z przezroczystością - i pod nimi robiło dokładnie to, co pod zdjęciem
     z białym tłem: świeciło. */
  background: var(--color-ink-2);
  overflow: hidden;
}
/* Wygaszenie krawędzi kadru siedzi w `.et-product-well::before` (szukaj
   „Miękka krawędź białego kadru"). NIE dokładamy tu drugiej warstwy:
   `::after` na tym elemencie jest już zajęty przez poświatę koloru bóstwa
   i reguła z klasą `.has-talisman` i tak by wygrała - czyli powstałby kod,
   który wygląda, jakby działał, a nie robi nic. */
.et-product-well a { display: block; width: 100%; height: 100%; }
.et-product-well img,
.woocommerce ul.products li.product .et-product-well a img {
  width: 100%; height: 100%;
  object-fit: cover;
  margin: 0;
  transition: filter .35s ease, transform .35s ease;
}
.et-hover-logo {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
  z-index: 2;
}
.woocommerce ul.products li.product .et-product-well .et-hover-logo img,
.et-hover-logo img {
  width: var(--et-hover-logo-size, 34%) !important;
  height: var(--et-hover-logo-size, 34%) !important;
  object-fit: contain;
  margin: 0;
  filter: drop-shadow(0 2px 10px rgba(0,0,0,.35));
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product:hover .et-product-well > a img,
  .woocommerce ul.products li.product:hover .et-product-well > img {
    filter: blur(9px) saturate(.8);
    transform: scale(1.03);
  }
  .woocommerce ul.products li.product:hover .et-hover-logo { opacity: 1; }
}
@media (hover: none) {
  .et-hover-logo { display: none !important; }
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
  font-family: var(--font-heading);
  font-size: 15px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-bone-0);
  padding: 16px 18px 0;
}
.woocommerce ul.products li.product .price {
  font-family: var(--font-heading);
  font-size: 17px; font-weight: 600;
  color: var(--color-brand-orange) !important;
  padding: 4px 18px 0;
}
.woocommerce ul.products li.product .price del { color: var(--fg-faint); opacity: 1; }

/* =========================================================================
   JEDNA POMARAŃCZOWA ISKRA NA GRUPĘ - zgłoszenie z przeglądu mobilnego
   (2026-08-13): „za dużo pomarańczu na raz. Karty produktu: cena
   pomarańczowa ALBO przycisk, nie oba".

   Policzone na jednym ekranie telefonu: pasek promo, główne CTA hero, ceny,
   dwa razy „DODAJ DO KOSZYKA", plakietka i pływająca pomoc. Osiem plam tego
   samego koloru, z których każda krzyczy równie głośno - czyli żadna nie
   krzyczy. Kolor akcentu działa przez RZADKOŚĆ; użyty wszędzie przestaje być
   akcentem i robi się tłem.

   Zostawiamy CENĘ, a nie przycisk, i to jest wybór, nie moneta:

   - cena jest w karcie informacją, po którą człowiek naprawdę sięga wzrokiem,
     a przycisk i tak stoi zawsze w tym samym miejscu, więc nie musi się
     szukać kolorem;
   - w siatce dwóch kolumn na telefonie widać naraz cztery przyciski. Cztery
     pomarańczowe prostokąty to była ta „ściana", o której mówi zgłoszenie;
   - obrys zamiast wypełnienia nie odbiera przyciskowi klikalności: ma
     ramkę, wersaliki i pełną szerokość karty, a przy dotknięciu i najechaniu
     zapala się na pomarańczowo - czyli kolor wraca dokładnie wtedy, gdy
     niesie informację („to jest to, co właśnie klikam").

   NIE dotyczy strony produktu ani koszyka: tam „Dodaj do koszyka" jest
   JEDYNĄ akcją na ekranie, więc żadnej ściany nie tworzy i zostaje pełne.
   Selektor jest celowo ograniczony do `ul.products li.product`.
   ========================================================================= */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product a.button.alt,
.woocommerce ul.products li.product .button.add_to_cart_button {
  background: transparent !important;
  color: var(--color-bone-1) !important;
  border: 1px solid var(--border-strong) !important;
}
.woocommerce ul.products li.product .button:focus-visible {
  background: var(--color-brand-orange) !important;
  color: var(--color-ink-1) !important;
  border-color: var(--color-brand-orange) !important;
}
/* Pomarańcz przy najechaniu tylko pod kursorem - na iPhonie przycisk
   zostawał pomarańczowy po dotknięciu (przyklejony `:hover`, zgłoszenie #4). */
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product .button:hover,
  .woocommerce ul.products li.product a.button.alt:hover,
  .woocommerce ul.products li.product .button.add_to_cart_button:hover {
    background: var(--color-brand-orange) !important;
    color: var(--color-ink-1) !important;
    border-color: var(--color-brand-orange) !important;
  }
}

/* =========================================================================
   STANY PO „DODAJ DO KOSZYKA" - zgłoszenie #4 (iPhone, 2026-09-26).

   WooCommerce po dotknięciu robi z przyciskiem trzy rzeczy i każda
   rozjeżdżała kartę:
   - `.loading`: przezroczystość .25 (cały przycisk jak wyłączony) i ikona
     kręciołka z fontu WooCommerce wisząca 1em od prawej - NA napisie;
   - `.added`: znaczek „✓" doklejony za napisem (12,5 px + margines .53em).
     Przycisk ma stałą szerokość, a napis był wyśrodkowany i bez zawijania,
     więc treść wylewała się na OBIE strony: zmierzone na 393 px napis
     zaczynał się 5,6 px przed lewą krawędzią („ODAJ DO KOSZYKA");
   - odnośnik „Zobacz koszyk" dopisany POD przyciskiem, krojem treści
     (Inter 16 px, małe litery): karta rosła o 44 px, a przyciski sąsiednich
     kart zjeżdżały do nowego dna (315 -> 336 px, zmierzone).

   Teraz „Zobacz koszyk" ZAJMUJE MIEJSCE przycisku: to samo pudełko, te same
   marginesy i wysokość, więc rząd kart się nie rusza. Znaczek „✓" i obrys
   w kolorze marki mówią „dodane", napis - co dalej. Stan „zrobione" ma
   prawo do koloru, bo mówi o skutku działania, a nie zachęca do niego.
   Dodać drugą sztukę można w koszyku albo na karcie produktu. Fokus
   z klawiatury przechodzi na odnośnik (`egotape.js`, „Po dodaniu z kafelka"). */
.woocommerce ul.products li.product .button.added:has(+ .added_to_cart) { display: none; }
.woocommerce ul.products li.product .added_to_cart {
  align-self: stretch;
  margin: 8px 18px 18px;
  min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 13px 24px;
  border: 1px solid var(--color-brand-orange);
  border-radius: var(--radius-3);
  background: transparent;
  color: var(--color-brand-orange);
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  line-height: 1;
  text-align: center;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product .added_to_cart:hover {
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
  }
}
.woocommerce ul.products li.product .added_to_cart:focus-visible {
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
}
/* Dodane BEZ odnośnika - na stronie koszyka WooCommerce go nie dokłada
   („Nowe w sklepie" w pustym koszyku). Ten sam obrys i znaczek na samym
   przycisku. */
.woocommerce ul.products li.product .button.added {
  color: var(--color-brand-orange) !important;
  border-color: var(--color-brand-orange) !important;
}
/* Znaczek „✓" rysowany ramką, nie znakiem z fontu: kolor bierze z napisu,
   a przed napisem nie dokłada szerokości za tekstem (tam wylewał treść). */
.woocommerce ul.products li.product .button.added::after { content: none; }
.woocommerce ul.products li.product .button.added::before,
.woocommerce ul.products li.product .added_to_cart::before {
  content: "";
  flex: 0 0 auto;
  width: .36em; height: .68em;
  margin: -.2em .12em 0;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
/* Ładowanie: napis znika na czas żądania (nazwę dla czytnika ekranu niesie
   `aria-label`), a kręciołek stoi na środku zamiast na napisie. Bez
   przezroczystości .25 z WooCommerce - przycisk pracuje, nie jest wyłączony. */
.woocommerce ul.products li.product .button.loading {
  opacity: 1;
  color: transparent !important;
}
.woocommerce ul.products li.product .button.loading::after {
  content: "";
  position: absolute; inset: 0;
  width: 16px; height: 16px;
  margin: auto;
  border: 2px solid rgba(245, 241, 234, .25);
  border-top-color: var(--color-bone-1);
  border-radius: 50%;
  animation: et-spin .6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .woocommerce ul.products li.product .button.loading::after { animation: none; }
}

.woocommerce ul.products li.product .button {
  /* Odstęp nad przyciskiem 8 px, nie 14. Razem z zerowanym marginesem ceny
     niżej daje 8 px przerwy zamiast 23 - ta sama wartość co na telefonie,
     bo to ta sama karta, tylko szersza. */
  margin: 8px 18px 18px;
  /* Na pełną szerokość karty. Domyślnie przycisk był szeroki na tyle, ile
     miał napisu (181 px przy 233 px dostępnych), więc lewa krawędź stała
     równo z tytułem i ceną, a prawa urywała się w miejscu zależnym od
     długości słowa. Przy czterech kartach obok siebie widać to od razu. */
  align-self: stretch;
}

/* Cena niesie własny dolny margines z WooCommerce (0.5em). Odstęp pod nią
   daje już margines przycisku albo wiersz oceny, więc ten drugi jest
   zdublowany - i to on robił z 8 px przerwy 23 px. */
.woocommerce ul.products li.product .price { margin-bottom: 0; }
.woocommerce ul.products li.product .star-rating { margin: 6px 18px 0; }

/* PRZYCISKI RÓWNO U DOŁU, mimo różnej zawartości kart - audyt pulpitu:
   „karty mają nierówną wysokość (gwiazdki tylko przy 2 produktach, badge
   tylko przy niektórych)".

   Rozwiązane przez DOSUNIĘCIE przycisku do dna karty, a nie przez
   rezerwowanie miejsca na gwiazdki. Rezerwacja zostawiałaby pustą szparę pod
   każdym produktem bez opinii - czyli wizualne „tu czegoś brakuje" przy
   siedmiu z dziewięciu kart. Dosunięcie daje ten sam równy rząd przycisków,
   a karty bez oceny są po prostu luźniejsze w środku.

   `align-items: stretch` na siatce sprawia, że karty w rzędzie i tak mają
   wspólną wysokość; brakowało tylko rozdania tej wysokości w środku karty.

   CENA JEDZIE NA DÓŁ RAZEM Z PRZYCISKIEM (2026-09-26, zgłoszenia #4 i #7).
   Dosunięty był sam przycisk, więc cena stała tam, gdzie kończył się tytuł:
   w jednym rzędzie na 393 px 187 px od góry karty przy nazwie w jednym
   wierszu i 210 px przy nazwie w dwóch. Teraz odnośnik produktu (zdjęcie,
   nazwa, ocena, cena) wypełnia kartę, a cena ma `margin-top: auto` - wolne
   miejsce ląduje między oceną a ceną, a cena i przycisk stoją w jednej
   linii w całym rzędzie. Przerwa cena-przycisk jest wszędzie ta sama (8 px),
   czyli znika też skutek uboczny opisany niżej przy „Przycisk zawsze przy
   dnie kafelka". */
.woocommerce ul.products li.product { display: flex; flex-direction: column; }
/* `a.` w selektorze, bo WooCommerce ma `…li.product a.woocommerce-loop-
   product__link { display: block }` - bez tego jego reguła wygrywała. */
.woocommerce ul.products li.product a.woocommerce-loop-product__link {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}
.woocommerce ul.products li.product .woocommerce-loop-product__link .price { margin-top: auto; }
.woocommerce ul.products li.product .button { margin-top: 8px; }

/* =========================================================================
   SIATKA PRODUKTÓW Z BLOKÓW WOOCOMMERCE - „Nowe w sklepie" w pustym koszyku

   Zgłoszenie właściciela (2026-08-13): „w koszyku, jak nie ma produktów, to
   PRZYCISKI produktów są inne - brzydkie".

   Miał rację, i sprawa jest szersza niż przyciski. Pusty koszyk renderuje
   blok `wp-block-woocommerce-product-new`, który NIE UŻYWA znaczników
   `ul.products li.product` - ma własne klasy `wc-block-grid__*`. Cały
   arkusz motywu mija się z nim co do jednej reguły, więc karty dostawały
   wygląd domyślny bloków:

   - przycisk: szaroniebieska pastylka `rgb(50,55,60)` - kolor, którego nie
     ma w żadnej z palet tego sklepu,
   - tytuł POMARAŃCZOWY, a cena szara - czyli dokładnie odwrotnie niż
     w kartach motywu, gdzie pomarańcz należy do ceny,
   - karta bez tła, bez ramki i bez zaokrąglenia, naga na czerni.

   Zamiast przepisywać koszyk na klasyczne znaczniki (ryzyko przy każdej
   aktualizacji WooCommerce), ubieramy blok w te same wartości, co karty
   motywu. Jedno źródło kolorów - zmienne - więc zmiana palety rusza obie
   siatki naraz.
   ========================================================================= */
/* JEDEN WIERSZ PRZESUWANY PALCEM - na komputerze TAK SAMO jak na telefonie.

   Zgłoszenie właściciela: „powinno to być jednym wierszem zarówno na PC jak
   i mobilce, oczywiście przesuwane w prawo/lewo".

   To jest sekcja poboczna na pustym koszyku - propozycja, nie oferta.
   Siatka zawijana w rzędy rozpychała ją na pół ekranu i kazała przewijać
   stronę w dół, żeby dojść do stopki. Wiersz zajmuje stałą wysokość
   niezależnie od liczby produktów, a to, że jest ich więcej, pokazuje
   podglądem następnej karty - tak samo jak polecane na karcie produktu
   i karuzela na stronie głównej. Jedno zachowanie w całym sklepie.

   `!important` przy `display`, bo blok narzuca swój układ własnym arkuszem
   - sprawdzone pomiarem: `gridTemplateColumns` liczyło się poprawnie przy
   `display: block`, czyli reguła wyglądała na działającą i nie działała. */
.wc-block-grid__products {
  display: flex !important;
  flex-wrap: nowrap;
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0 0 10px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--color-bone-3) transparent;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
}
.wc-block-grid__product {
  /* ZDJĘCIE OGRANICZENIA SZEROKOŚCI Z BLOKU - bez tego karty mają 60 px.

     Blok układa produkty na `flex` i pilnuje liczby kolumn procentowym
     `max-width` na karcie (przy czterech kolumnach - 25%). Kiedy pojemnik
     staje się siatką, ten sam procent przestaje znaczyć „ćwiartka rzędu"
     i zaczyna znaczyć „ćwiartka MOJEJ KOLUMNY" - czyli karta kurczy się do
     jednej czwartej miejsca, które właśnie dostała. Efekt: słupki po 60 px
     z napisami literа pod literą.

     Kolumnami rządzi tutaj siatka, więc ograniczenie z bloku jest już tylko
     przeszkodą. `!important`, bo reguła bloku też je ma. */
  /* Szerokość karty liczona tak samo, jak w karuzeli na stronie głównej:
     tyle kart, ile ustawione w Personalizacji, plus ułamek następnej.
     `max-width` z bloku (procentowe, pilnujące jego własnych kolumn) musi
     zejść, bo w wierszu przewijanym znaczyłoby ułamek ułamka. */
  max-width: none !important;
  flex: 0 0 calc(
    (100% - (var(--et-slider-desktop, 4) - 1) * 24px)
    / (var(--et-slider-desktop, 4) + var(--et-slider-peek, 12) / 100)
  );
  scroll-snap-align: start;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden;
  box-shadow: var(--shadow-1);
  margin: 0;
  padding: 0 0 18px;
  display: flex;
  flex-direction: column;
  text-align: left;
}
/* ZDJĘCIE NA CAŁĄ RAMKĘ, z kadrowaniem i winietą - jak w kartach motywu.

   Zgłoszenie: „zdjęcia nie są na całą ramkę". Blok stawiał je z
   `object-fit: fill`, czyli ROZCIĄGAŁ do zadanego prostokąta zamiast
   kadrować - przy zdjęciu o innych proporcjach niż kwadrat oznacza to
   zniekształcony produkt, a przy kwadratowym białe pole dookoła rolki.

   `cover` na kwadratowym kadrze robi to samo, co `.et-product-well`
   w sklepie: wypełnia ramkę i przycina nadmiar. Winieta jest tą samą
   warstwą co tam i z tego samego powodu - biel siedzi w plikach zdjęć
   i bez wygaszenia krawędzi kończy się prostą linią na ciemnej karcie. */
.wc-block-grid__product-image {
  margin: 0;
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--color-ink-2);
  /* BLOK NA PEŁNĄ SZEROKOŚĆ, z `!important` - i to nie jest ostrożność
     na wyrost.

     Blok WooCommerce ustawia temu opakowaniu `display: inline-block`, czyli
     szerokość DOPASOWANĄ DO TREŚCI. Przy takim układzie element bierze tyle,
     ile potrzebuje, a nie tyle, ile dostaje - i jeśli wybrany przez
     przeglądarkę wariant zdjęcia jest choćby o ułamek węższy od karty, po
     prawej zostaje pasek tła. Po prawej, bo wiersz tekstu układa się od
     lewej.

     W przeglądarce testowej luka wynosiła zero na czterech szerokościach
     telefonu (360, 390, 412, 430) - zgłoszenie z prawdziwego telefonu mówiło
     co innego. Zamiast dobierać szerokość na oko, zdejmujemy sam mechanizm,
     który jako jedyny mógł taką lukę stworzyć: `block` bierze całą dostępną
     szerokość zawsze, niezależnie od tego, co jest w środku i jaki silnik
     to liczy.

     Przy okazji znika odstęp POD zdjęciem: element w linii siedzi na linii
     pisma i zostawia pod sobą miejsce na ogonki liter. */
  display: block !important;
  width: 100% !important;
}
/* =========================================================================
   ZDJĘCIE PRZYKLEJONE DO CZTERECH KRAWĘDZI KADRU - pozycjonowanie
   bezwzględne zamiast szerokości procentowej.

   ROZSTRZYGNIĘTE ZRZUTEM Z TELEFONU WŁAŚCICIELA (2026-08-13). Rozłożony na
   piksele pokazał to, czego cztery moje pomiary w przeglądarce testowej nie
   pokazały:

     karta 1:  karta 50-377,  zdjęcie 50-365   -> 12 px tła po PRAWEJ
     karta 2:  karta 403-731, zdjęcie 416-731  -> 13 px tła po LEWEJ

   Czyli zdjęcie jest o jakieś sześć pikseli CSS WĘŻSZE od karty i dosunięte
   raz do lewej, raz do prawej. Naprzemienność, którą właściciel opisał
   trzykrotnie i której nie umiałem odtworzyć.

   Poprzednia poprawka poszerzała OPAKOWANIE (`calc(100% + 2px)`) i z tego
   powodu nie mogła zadziałać: jeśli węższy jest sam obrazek, opakowanie może
   być dowolnie szerokie, a tło i tak prześwituje. Naprawiałem nie ten
   element.

   `width: 100%` na obrazku też nie wystarcza, bo blok WooCommerce wypisuje
   zdjęciom atrybuty `width`/`height`, `srcset` i `sizes`, a przeglądarka
   dobiera wariant i wylicza z niego układ - z zaokrągleniem, które przy
   szerokości ułamkowej karty wypada raz w jedną, raz w drugą stronę.

   Pozycjonowanie bezwzględne wyjmuje obrazek z tego rachunku w całości: nie
   ma już „ile procent czego", jest „przyklej się do czterech krawędzi
   kadru i wystaw o piksel poza nie". `min-width`/`min-height` pilnują, żeby
   wariant mniejszy od kadru został rozciągnięty, a nie zostawił marginesu.
   Przy `object-fit: cover` nadmiar i tak jest przycinany, więc nic z tego,
   co widać, nie ubywa.
   ========================================================================= */
.wc-block-grid__product-image img {
  /* WYMIARY PODANE WPROST, nie przez `auto` z czterema krawędziami.

     Pierwsza wersja tej reguły miała `inset: -1px` i `width: auto`, licząc
     że obrazek rozciągnie się między krawędziami. Nie rozciągnął się:
     obrazek jest elementem ZASTĘPOWANYM (ma własny rozmiar), a dla takiego
     `width: auto` znaczy „weź swój rozmiar naturalny", nawet gdy podano
     obie krawędzie poziome. Zmierzone: kadr 152 px, obrazek 300 px, czyli
     jego własna szerokość - wylewał się poza kartę zamiast ją wypełnić.

     Podanie szerokości i wysokości wprost zdejmuje tę niejednoznaczność:
     procenty liczą się od kadru, a jeden piksel zapasu z każdej strony
     wchodzi pod przycięcie. */
  position: absolute !important;
  top: -1px !important;
  left: -1px !important;
  right: auto !important;
  bottom: auto !important;
  width: calc(100% + 2px) !important;
  height: calc(100% + 2px) !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  display: block;
  object-fit: cover;
  border-radius: 0;
}
.wc-block-grid__product-image::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    radial-gradient(118% 118% at 50% 46%, transparent 40%, rgba(11, 11, 11, .34) 76%, rgba(11, 11, 11, .74) 100%),
    linear-gradient(to bottom, rgba(11, 11, 11, .30) 0%, transparent 18%);
}
/* WINIETA SŁABNIE NA MAŁEJ KARCIE.

   Zgłoszenie: „na mobilce zdjęcia nadal nie są wypełnione do końca, po
   prawej jest margines". Zmierzone na pikselach zrzutu (wiersz przez górną
   część kadru, powiększenie 3x): jasny kadr biegnie od 3 do 422 px przy
   szerokości 429 - czyli dochodzi do ramki po obu stronach, a różnica
   lewa/prawa to jeden piksel CSS. Zdjęcie WYPEŁNIA ramkę.

   Marginesem wydaje się przyciemnienie krawędzi, czyli ta winieta. Na karcie
   pulpitu (330 px) rozkłada się na tyle miejsca, że czyta się jak światło
   sceny; na karcie telefonu (142 px) ten sam procent to dwa razy węższy pas
   przy krawędzi - i zamiast miękkiego wygaszenia widać ciemny brzeg. Że
   bardziej po prawej, wynika z samego zdjęcia: produkt stoi lekko na lewo,
   więc po prawej zostaje więcej bieli, na której przyciemnienie widać.

   Na małych kartach zaczyna się więc później i kończy słabiej. Krawędź
   nadal nie jest ostrą linią bieli, ale przestaje udawać margines. */
/* NA TELEFONIE WINIETY NIE MA WCALE.

   Właściciel zgłaszał ciemną krawędź zdjęcia cztery razy z rzędu, za każdym
   razem po innej poprawce. Nie udało mi się jej odtworzyć: pomiary
   geometrii dawały zero luki na czterech szerokościach, a pomiar
   wyrenderowanych pikseli - jasność krawędzi równą środkowi z dokładnością
   do kilku punktów.

   Skoro nie umiem wskazać przyczyny, zdejmuję JEDYNĄ rzecz, która na tych
   kartach może w ogóle przyciemnić brzeg. To nie jest naprawa z diagnozy,
   tylko usunięcie podejrzanego - i tak to trzeba czytać.

   Koszt jest niewielki: winieta miała maskować twardą krawędź białego kadru
   na ciemnej karcie i na dużych kartach nadal to robi. Na karcie o
   szerokości 142 px różnica jest kosmetyczna, a pewność, że nic nie
   przyciemnia zdjęcia, warta więcej.

   Pulpit zostaje z winietą - tam właściciel napisał wprost, że jest dobrze,
   a karta ma 330 px, czyli dwa razy więcej miejsca na jej rozłożenie. */
@media (max-width: 640px) {
  .wc-block-grid__product-image::after { display: none; }
}
.wc-block-grid__product-title {
  font-family: var(--font-heading);
  font-size: 15px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  /* KOŚĆ, nie pomarańcz - pomarańcz w karcie należy do ceny. Reguła jednej
     iskry na grupę, ta sama co przy kartach w siatce motywu. */
  color: var(--color-bone-0);
  padding: 16px 18px 0;
  margin: 0;
}
.wc-block-grid__product-price,
.wc-block-grid__product-price.price {
  font-family: var(--font-heading);
  font-size: 17px; font-weight: 600;
  color: var(--color-brand-orange);
  padding: 4px 18px 0;
  margin: 0;
}
.wc-block-grid__product-add-to-cart {
  /* Przycisk dosunięty do dna karty - karty w rzędzie mają wtedy rząd
     przycisków na jednej linii, niezależnie od długości nazwy produktu. */
  margin: 8px 18px 0 !important;
  padding: 0;
  display: flex;
  margin-top: auto !important;
}
.wc-block-grid__product-add-to-cart .wp-block-button__link,
.wc-block-grid__product .wp-block-button__link.add_to_cart_button {
  /* Obrys, nie wypełnienie - dokładnie jak „Dodaj do koszyka" w siatce
     motywu, i z tego samego powodu: kilka kart naraz na ekranie. */
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  line-height: 1;
  padding: 13px 24px;
  border-radius: var(--radius-3);
  background: transparent;
  color: var(--color-bone-1);
  border: 1px solid var(--border-strong);
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.wc-block-grid__product-add-to-cart .wp-block-button__link:focus-visible {
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  border-color: var(--color-brand-orange);
}
/* Najechanie tylko pod kursorem - na dotyku przyklejało się po dotknięciu. */
@media (hover: hover) and (pointer: fine) {
  .wc-block-grid__product-add-to-cart .wp-block-button__link:hover,
  .wc-block-grid__product .wp-block-button__link.add_to_cart_button:hover {
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
    border-color: var(--color-brand-orange);
  }
}
/* Odnośnik „Zobacz koszyk", który blok dokłada po dodaniu produktu. */
.wc-block-grid__product .added_to_cart {
  display: block;
  margin: 8px 18px 0;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-brand-orange);
}

/* Na telefonie pismo mniejsze i ciaśniejsze marginesy; liczbą kolumn rządzi
   `auto-fill` wyżej i przy wąskim pojemniku koszyka schodzi do jednej. */
@media (max-width: 640px) {
  .wc-block-grid__products { gap: 14px; }

  /* BEZ OBRAMOWANIA NA TELEFONIE - druga możliwa przyczyna „szerszej ramki
     po prawej", wskazana przez właściciela i warta usunięcia niezależnie od
     tego, czy to ona.

     Karty mają szerokość UŁAMKOWĄ: przy ekranie 390 px wychodzi 142,22 px,
     przy 412 - 151,98. Obramowanie o grubości 1 px przeglądarka musi
     dociągnąć do pełnych pikseli ekranu i przy takich szerokościach jedna
     krawędź bywa grubsza od drugiej. Na jasnym zdjęciu, które dochodzi
     dokładnie do tej krawędzi, wygląda to jak margines po jednej stronie.

     Karta bez obramowania nadal czyta się jako karta: jej tło (`#171717`)
     odcina się od strony (`#0B0B0B`), a rogi są zaokrąglone. Znika za to
     jedyny element, który mógł się w ten sposób rozjechać. Na pulpicie
     obramowanie zostaje - tam karty są szersze, a właściciel napisał
     wprost, że jest dobrze. */
  .wc-block-grid__product { border: 0 !important; }

  /* =====================================================================
     ZDJĘCIE WYSTAJE O PIKSEL POZA KARTĘ - i to jest naprawa, nie sztuczka.

     Zgłoszenie właściciela, trzecie podejście, tym razem z rozstrzygającym
     szczegółem: „pierwsza karta ma margines po prawej, druga po lewej,
     trzecia znów po prawej".

     Naprzemienność jest podpisem ZAOKRĄGLANIA SUBPIKSELOWEGO. Karta ma
     szerokość ułamkową - 142,22 px przy ekranie 390 - więc kolejne karty
     w wierszu zaczynają się na 0, 156,22, 312,44, 468,66... czyli każda
     w innym ułamku piksela. Przeglądarka maluje krawędzie na pełnych
     pikselach ekranu, a `overflow: hidden` karty przycina zdjęcie w miejscu
     wyliczonym z ułamka. Gdy zaokrąglenie wypada w drugą stronę niż
     krawędź, między jasnym kadrem a ciemnym tłem karty zostaje włos tła -
     raz po prawej, raz po lewej.

     Dlatego POMIARY POKAZYWAŁY ZERO: geometria była poprawna co do
     ułamka, a problem powstawał dopiero przy malowaniu. Odległości liczone
     w `getBoundingClientRect()` tego nie widzą.

     Rozwiązanie: zdjęcie jest o piksel szersze z każdej strony i wystaje
     poza kartę, a karta je przycina. Wtedy w miejscu zaokrąglenia zawsze
     jest ZDJĘCIE, nigdy tło - niezależnie od tego, w którą stronę wypadnie
     ułamek. Kadr i tak jest przycinany (`object-fit: cover`), więc te dwa
     piksele nic nie zabierają z tego, co widać.
     ===================================================================== */
  .wc-block-grid__product-image {
    width: calc(100% + 2px) !important;
    margin-left: -1px !important;
  }
  .wc-block-grid__product {
    flex-basis: calc(
      (100% - (var(--et-slider-mobile, 2) - 1) * 14px)
      / (var(--et-slider-mobile, 2) + var(--et-slider-peek, 12) / 100)
    ) !important;
  }
  .wc-block-grid__product-title { font-size: 13px; padding: 12px 12px 0; }
  .wc-block-grid__product-price,
  .wc-block-grid__product-price.price { font-size: 15px; padding: 4px 12px 0; }
  /* `auto` U GÓRY, nie 8 px - inaczej przyciski się rozjeżdżają.

     Skrót `margin` ustawia wszystkie cztery strony, więc wpisany tu
     `8px` kasował `margin-top: auto` z reguły bazowej - a to na nim stoi
     dosunięcie przycisku do dna karty. Na telefonie nazwy produktów łamią
     się na różną liczbę wierszy („Rodzanice - Miks kolorów" na trzy,
     „Perun - Czerwony" na jeden), więc przyciski lądowały na trzech różnych
     wysokościach w jednym rzędzie. Zmierzone: trzy różne dolne krawędzie
     na cztery karty. */
  /* ODDECH POD PRZYCISKIEM - karta traci na telefonie własne wypełnienie.

     Reguła bazowa daje karcie `padding: 0 0 18px`, ale na wąskim ekranie
     arkusz bloku ją nadpisuje i zmierzone wypełnienie wynosi zero. Przycisk
     kończył się PIKSEL nad dolną krawędzią karty - wyglądał jak przyklejony
     do ramki.

     Odstęp wchodzi w margines przycisku, a nie w wypełnienie karty: karta ma
     `overflow: hidden` pod zaokrąglone rogi, więc to margines jest tu
     miejscem, które na pewno zadziała niezależnie od tego, co blok zrobi
     z `padding`. */
  .wc-block-grid__product-add-to-cart { margin: auto 12px 14px !important; }
  /* NAPIS NIE ŁAMIE SIĘ W ŚRODKU SŁOWA.

     Przy karcie 142 px na przycisk zostaje ~118 px, a „PERSONALIZUJ" pisane
     wersalikami z rozstrzeleniem liter tam nie wchodzi. Blok dzielił je więc
     w dowolnym miejscu - wychodziło „PERSONA / LIZUJ", co czyta się jak
     usterka, a nie jak zawinięty tekst.

     `word-break: keep-all` zabrania łamania wewnątrz wyrazu; wielowyrazowe
     napisy („Skomponuj zestaw") dalej zawijają się na spacji, bo tam łamanie
     jest naturalne. Do tego ciaśniejsze pismo i mniejsze wypełnienie boczne,
     żeby najdłuższy pojedynczy wyraz w sklepie zmieścił się w wierszu. */
  /* TRZY KLASY W SELEKTORZE, nie dwie - inaczej ta reguła nie działa.

     Reguła bazowa wyżej ma w grupie selektor `.wc-block-grid__product
     .wp-block-button__link.add_to_cart_button`, czyli TRZY klasy. Zapis
     z dwiema przegrywał z nią specyficznością mimo że stoi niżej w pliku -
     i to jest podstępne, bo wygląda na poprawną nadpiskę. Zmierzone na
     żywej stronie: przycisk miał `font-size: 14px` i `padding: 13px 24px`,
     czyli wartości bazowe, przy szerokości ekranu 390 px. */
  .wc-block-grid__product .wp-block-button__link.add_to_cart_button,
  .wc-block-grid__product-add-to-cart .wp-block-button__link {
    font-size: 11px;
    letter-spacing: .03em;
    padding: 12px 6px;
    word-break: keep-all;
    overflow-wrap: normal;
    hyphens: none;
  }
}

/* =========================================================================
   POLE „KRAJ / REGION" W KASIE - jedyne białe pole na ciemnej stronie.

   Znalezione audytem pokrycia (2026-08-13): przelot po stronach sklepu
   z porównaniem każdego koloru WooCommerce z paletą motywu. To był jedyny
   element w kasie, który z niej wypadał - i wypadał kompletnie: białe tło
   pod ciemnoszarym tekstem `rgb(43,45,47)`, pośród ośmiu pól w kolorze
   `#1F1F1F` z kremowym pismem.

   PRZYCZYNA TO JEDNA LITERA. Cały styl kasy w tym motywie celuje w klasy
   `wc-block-components-*`. To pole nazywa się `wc-blockS-components-select`
   - inny, starszy prefiks, którego WooCommerce używa w kilku miejscach
   obok nowego. Selektory motywu mijały je co do znaku, więc zostawało
   z wyglądem domyślnym bloków, czyli jasnym.

   Wartości przepisane z pola tekstowego obok (zmierzone: tło `#1F1F1F`,
   pismo `#F5F1EA`, ramka `#2A2A2A`, zaokrąglenie 8 px), żeby oba pola
   w tym samym wierszu formularza wyglądały jak jedno rozwiązanie, a nie
   dwa. Przez zmienne, więc zmiana palety rusza je razem.
   ========================================================================= */
.wc-blocks-components-select__container {
  background: var(--bg-input) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-3) !important;
}
.wc-blocks-components-select__select {
  background: transparent !important;
  color: var(--fg-default) !important;
  border: 0 !important;
  border-radius: var(--radius-3) !important;
}
/* Lista rozwijana jest rysowana przez system, nie przez stronę - kolor
   pozycji ustawia przeglądarka. Podajemy jawnie tło, bo bez niego część
   przeglądarek dziedziczy przezroczystość i pozycje robią się nieczytelne. */
.wc-blocks-components-select__select option {
  background: var(--color-ink-2);
  color: var(--fg-default);
}
.wc-blocks-components-select__label {
  color: var(--fg-muted) !important;
}
/* Strzałka rozwijania - domyślnie ciemna, czyli niewidoczna na ciemnym. */
.wc-blocks-components-select__expand { fill: var(--fg-muted) !important; }

/* =========================================================================
   LISTY ROZWIJANE W FORMULARZACH WOOCOMMERCE - `select`, nie `input`.

   Znalezione audytem pokrycia: pole „Twój pas w BJJ" przy rejestracji miało
   BIAŁE tło i obcą ramkę `rgba(32,7,7,.8)`, stojąc pod trzema ciemnymi
   polami tekstowymi w tym samym formularzu.

   Przyczyna jest pouczająca: pole ma klasę `woocommerce-Input input-text`,
   czyli dokładnie tę samą co pola tekstowe obok - ale reguły motywu były
   pisane jako `input.woocommerce-Input`, z nazwą znacznika. `select` z tą
   samą klasą przechodził obok nich niezauważony.

   Stąd selektory BEZ nazwy znacznika. Domyślna strzałka też schodzi:
   przeglądarka rysuje ją w kolorze tekstu systemowego, więc na ciemnym tle
   znikała - podajemy własną, tę samą co w kasie.
   ========================================================================= */
.woocommerce select.woocommerce-Input,
.woocommerce select.input-text,
.woocommerce-page select.woocommerce-Input,
.woocommerce form .form-row select,
/* Pas i belki mają klasę `input-text` jak pola tekstowe, a woocommerce.css
   daje `.woocommerce form .form-row .input-text` (0,3,1) wypełnienie 8 px:
   lista miała 38 px wysokości, a napis wchodził pod strzałkę. Ten selektor
   (0,3,2) oddaje jej wymiary z tej reguły. */
.woocommerce form .form-row select.input-text {
  width: 100%;
  /* `!important` na trzech własnościach koloru: białe tło i obca ramka idą
     z arkusza WooCommerce, który ładuje się PO motywie. Sam selektor
     pasował (sprawdzone `matches()` na żywej stronie), a mimo to pole
     zostawało białe - przegrywała kolejność, nie zapis. */
  background-color: var(--bg-input) !important;
  color: var(--fg-default) !important;
  border: 1px solid var(--border-input) !important;
  border-radius: var(--radius-3);
  padding: 12px 40px 12px 14px;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
  /* Strzałka jako tło - `appearance: none` zabiera systemową, a bez żadnej
     pole wygląda jak zwykły napis i nikt nie wie, że da się je rozwinąć. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23B8AE9E' stroke-width='2'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.woocommerce select.woocommerce-Input option,
.woocommerce form .form-row select option {
  background: var(--color-ink-2);
  color: var(--fg-default);
}
/* Bez `outline: none` (audyt D15): pierscien fokusu z `:focus-visible` u gory
   pliku dziala sam, a zmiana koloru obrysu jest tylko dodatkiem. */
.woocommerce select.woocommerce-Input:focus,
.woocommerce form .form-row select:focus {
  border-color: var(--color-brand-orange);
}

/* =========================================================================
   RAMKA FORMULARZY LOGOWANIA I REJESTRACJI - lawendowa, z domyślnego
   arkusza WooCommerce (`rgb(207,200,216)`), na czarnej stronie widoczna
   jako jasny prostokąt wokół pól.

   Znalezione tym samym audytem. Same POLA w środku były już ubrane
   (`#1F1F1F` z ramką `#2A2A2A`) - nie zauważył tego nikt, bo ramka jest
   cienka, a wygląda po prostu jak element cudzego projektu.
   ========================================================================= */
.woocommerce form.woocommerce-form-login,
.woocommerce form.woocommerce-form-register,
.woocommerce form.woocommerce-form-coupon,
.woocommerce form.checkout_coupon,
.woocommerce form.lost_reset_password {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
}

/* Formularz „Zapomniane hasło" i ustawiania nowego hasła (ta sama klasa
   `lost_reset_password`). Ramkę dostał wyżej razem z logowaniem, ale odstęp
   w środku WooCommerce daje tylko logowaniu i rejestracji - tu tekst, pole
   i przycisk stały 1 px od krawędzi („rozjechane, za blisko granic",
   zgłoszenie właściciela 2026-09-27). Odstęp jak w logowaniu: 20 px,
   na telefonie 16 px. Szerokość jak kolumna logowania: jedno pole na całą
   szerokość komputera (1320 px) wyglądało jak pasek, nie jak formularz. */
.woocommerce form.lost_reset_password { padding: 20px; max-width: 652px; }
@media (max-width: 768px) {
  .woocommerce form.lost_reset_password { padding: 16px; }
}

/* --- WooCommerce: strona produktu ----------------------------------------- */
.woo-main { padding-top: 40px; }
.woocommerce .woocommerce-breadcrumb {
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 32px;
}
.woocommerce .woocommerce-breadcrumb a { color: var(--fg-muted); }
@media (hover: hover) and (pointer: fine) {
  .woocommerce .woocommerce-breadcrumb a:hover { color: var(--color-brand-orange); }
}
/* Logowanie: „Nie pamietasz hasla?" mialo 20 px wysokosci, checkbox 13 px,
   „Pokaz haslo" 22 px (ikona WooCommerce to `::before` 22 px - zostaje,
   rosnie pole przycisku; pole hasla dostaje wiecej miejsca po prawej). */
.woocommerce form .show-password-input { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; right: .2em; }
.woocommerce form .password-input input[type="password"] { padding-right: 3rem; }
.woocommerce-LostPassword a { display: inline-block; padding: 12px 0; }
.woocommerce-form__input-checkbox { width: 18px; height: 18px; vertical-align: middle; accent-color: var(--color-brand-orange); }

/* Breadcrumb na zwykłych stronach/wpisach (poza sklepem — tam jest już
   powyższy .woocommerce-breadcrumb z rdzenia WooCommerce). */
.breadcrumb {
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 32px;
}
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: 0; list-style: none; margin: 0; padding: 0; }
.breadcrumb li:not(:last-child)::after { content: "/"; margin: 0 8px; color: var(--fg-faint); }
.breadcrumb a { color: var(--fg-muted); }
@media (hover: hover) and (pointer: fine) {
  .breadcrumb a:hover { color: var(--color-brand-orange); }
}

.woocommerce div.product { background: transparent; }
.woocommerce div.product div.images {
  background: transparent;
  border: none;
  padding: 0;
}
/* =========================================================================
   GALERIA PRODUKTU - ZDJĘCIE WYPEŁNIA POLE, BEZ RAMEK

   Zgłoszenie właściciela: „są jakieś ramki i zdjęcia nachodzą na siebie
   w podglądzie". Zmierzone w przeglądarce - dwie różne przyczyny, obie
   wyglądające jak ramka:

   1. Pojemnik miał `padding: 6%` na białym tle, czyli około 38 px białej
      obwódki dookoła zdjęcia przy szerokości 634 px. To ona wyglądała jak
      ramka i to przez nią zdjęcie nie wypełniało pola galerii.
   2. Miniatury miały `border: 1px` KAŻDA i stykały się bez odstępu
      (60 → 218 → 377 przy szerokości 158), więc sąsiadujące krawędzie
      zlewały się w ciągłe pasy - stąd wrażenie, że podglądy nachodzą
      na siebie.

   Czego NIE było, choć tak wyglądało: suwak galerii działa poprawnie,
   zdjęcia główne stoją obok siebie i nie zachodzą na siebie ani o piksel,
   konsola jest czysta.
   ========================================================================= */
.woocommerce div.product div.images .woocommerce-product-gallery__wrapper {
  background: #FFFFFF;
  border-radius: var(--radius-3);
  /* Bez wewnętrznego odstępu - zdjęcie ma wypełnić całe pole. Zaokrąglenie
     rogów trzyma `overflow`, bo obrazek sięga teraz krawędzi. */
  padding: 0;
  overflow: hidden;
}
/* POWIĘKSZENIE ZDJĘCIA NAD WSZYSTKIM (audyt iOS 2026-09-26).
   Okno PhotoSwipe (lupa na zdjęciu) ma z-index 1500, a pasek „Dodaj do
   koszyka" na telefonie 2147483000 - musi stać nad sekcjami z `.et-grain`.
   Przy otwartym zdjęciu pasek zasłaniał jego dół i zbierał dotknięcia
   (zmierzone na 393 px: `elementFromPoint` w pasie 603-659 zwracał przycisk
   paska, nie okno). Okno pełnoekranowe idzie nad pasek. */
.pswp { z-index: 2147483001; }
/* PRZESKOK UKLADU PRZY STARCIE GALERII (audyt R10: CLS 0,2-0,4 na pudelku).

   Zmierzone na osi czasu (390 px, 4G): flexslider najpierw daje wrapperowi
   `width: 400%`, a slajdom szerokosc nadaje dopiero po `load`. W miedzyczasie
   slajd jest tak szeroki jak wrapper, zdjecie z `width: 100%` roslo do
   1336 px i spychalo `.summary` o 1340 px w dol - a potem z powrotem.
   Dopoki slajd nie ma wlasnego `style`, dostaje 1/4 wrappera, czyli
   dokladnie szerokosc galerii, i `float: left` (to samo, co za chwile wpisze
   flexslider) - bez niego slajdy o szerokosci 25 % staly jako bloki jeden pod
   drugim. Po nadaniu stylu regula przestaje pasowac. */
.woocommerce-product-gallery__wrapper[style*="400%"] > .woocommerce-product-gallery__image:not([style]) { width: 25%; float: left; display: block; }
/* Dwa mniejsze przeskoki (po 0,08) zostawaly po powyzszym: przed startem
   slidera WooCommerce pokazuje 2. zdjecie jako pasek 25 % szerokosci pod
   pierwszym, a po starcie ten pasek znika i w jego miejsce wchodza miniatury
   (`.flex-control-thumbs`, 72-104 px + 12 px odstepu). Chowamy pasek od razu
   i rezerwujemy pod miniatury dokladnie tyle, ile zajma - tylko gdy zdjec
   jest wiecej niz jedno i tylko dopoki miniatur jeszcze nie ma. Slajdy 2+
   sa schowane, DOPOKI wrapper nie dostanie szerokosci procentowej: flexslider
   nadaje slajdom `style` (334 px, float) chwile PRZED `width: 400%` wrappera
   i przez ok. 0,5 s lezaly jeden pod drugim (zmierzone na osi czasu). `!important`
   przebija wpisane `display: block`. Zmierzone: CLS pudelka 0,396 -> 0 (390 px, 4G). */
.woocommerce-product-gallery__wrapper:not([style*="%"]) > .woocommerce-product-gallery__image:nth-child(n+2) { display: none !important; }
.woocommerce div.product div.images.woocommerce-product-gallery:has(.woocommerce-product-gallery__image:nth-child(2)):not(:has(.flex-control-thumbs)) { padding-bottom: calc(clamp(72px, 15%, 104px) + 12px); }
.woocommerce div.product div.images .woocommerce-product-gallery__image img {
  /* `cover`, a nie `fill`: zdjęcie o innych proporcjach niż kwadratowe pole
     byłoby przy `fill` ROZCIĄGNIĘTE, i to bez żadnego ostrzeżenia. */
  object-fit: cover;
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 0;
}
.woocommerce div.product div.images .flex-control-thumbs {
  /* Odstęp między podglądami zamiast stykających się krawędzi. */
  display: flex;
  /* ZAWIJAMY do kolejnych rzędów. Kolejne zdjęcia produktu mają dokładać
     kwadraciki POD spodem, a nie wypychać rząd poza kadr.

     Uwaga dla czytającego: zawijanie działa poprawnie WYŁĄCZNIE dlatego,
     że podglądy mają stały rozmiar (`flex: 0 0 auto` niżej). Przy
     `flex: 1 1 0` dwa pierwsze rozdymały się do połowy szerokości pola,
     a trzeci spadał sam do drugiego rzędu. */
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
  padding: 0;
}
.woocommerce div.product div.images .flex-control-thumbs li {
  /* STAŁY, NIEWIELKI ROZMIAR - podgląd ma być podglądem.
     Rozciąganie ich po równo na szerokość pola dawało przy dwóch zdjęciach
     dwa kafle po 312 px, czyli prawie tak duże jak zdjęcie główne. Liczba
     zdjęć bywa różna dla różnych produktów, więc rozmiar nie może od niej
     zależeć. */
  flex: 0 0 auto;
  width: clamp(72px, 15%, 104px);
  margin: 0;
  float: none;
}
.woocommerce div.product div.images .flex-control-thumbs li img {
  border-radius: var(--radius-3);
  /* BEZ OBRAMOWANIA. Wybrany podgląd poznaje się po pełnej jasności,
     a nie po ramce - ramka przy stykających się kafelkach dawała pasy. */
  border: 0;
  opacity: .55;
  object-fit: cover;
  width: 100%;
  aspect-ratio: 1;
  display: block;
  transition: opacity .2s var(--ease);
}
.woocommerce div.product div.images .flex-control-thumbs li img.flex-active { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .woocommerce div.product div.images .flex-control-thumbs li img:hover { opacity: 1; }
}
/* Lupa galerii: 36 px z WooCommerce, cel dotyku 44 px. `content-box` +
   wypelnienie 4 px powieksza pole, `background-clip` zostawia biale kolo
   w dawnym rozmiarze; ikona (pseudoelementy WooCommerce) przesunieta o te 4 px. */
.woocommerce div.product div.images .woocommerce-product-gallery__trigger { padding: 4px; background-clip: content-box; }
.woocommerce div.product div.images .woocommerce-product-gallery__trigger::before { left: 13px; top: 13px; }
.woocommerce div.product div.images .woocommerce-product-gallery__trigger::after { left: 26px; top: 23px; }
.woocommerce div.product .product_title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: .04em;
}
.woocommerce div.product p.price,
.woocommerce div.product span.price {
  font-family: var(--font-heading);
  font-size: 26px; font-weight: 600;
  color: var(--color-brand-orange);
}
.woocommerce div.product .woocommerce-product-details__short-description { color: var(--fg-muted); }
.woocommerce div.product form.cart { margin: 24px 0; display: flex; gap: 12px; flex-wrap: wrap; align-items: stretch; }
.woocommerce div.product form.cart div.quantity .qty {
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-3);
  color: var(--fg-default);
  height: 46px;
  width: 72px;
  font-family: var(--font-heading);
  font-size: 16px; /* bylo 13,33 px z arkusza przegladarki - zoom na iOS */
  /* Wypełnienie z arkusza przeglądarki było inne na każdym telefonie:
     iPhone 3,2/8 px, Chrome 1/2 px - cyfra stała w innym miejscu pola
     (audyt iOS 2026-09-26). */
  padding: 0 10px;
}
/* Produkt sprzedawany pojedynczo (subskrypcja) ma zamiast pola ilości ukryte
   pole i etykietę dla czytników. Pusty `div.quantity` (0x0) był jednak
   elementem flex: margines 4 px z WooCommerce i odstęp 12 px przesuwały
   przycisk zakupu - na 393 px stał na x=44 zamiast na linii kolumny 28. */
.woocommerce div.product form.cart div.quantity:not(:has(input:not([type="hidden"]))) { display: none; }
.woocommerce div.product form.cart .button { height: 46px; }

.woocommerce div.product .woocommerce-tabs ul.tabs {
  padding: 0; margin: 48px 0 0;
  border-bottom: 1px solid var(--border-default);
  display: flex; gap: 4px;
  /* Cztery zakładki (opis, opinie, dostawa, bezpieczeństwo produktu) nie
     mieszczą się w 390 px, a WooCommerce dokłada `overflow: hidden` -
     bez zawijania czwarta leżała poza ekranem i była nieosiągalna
     (audyt D1, GPSR jest wymagane prawem). */
  flex-wrap: wrap;
  overflow: visible;
}
.woocommerce div.product .woocommerce-tabs ul.tabs::before { border-color: var(--border-default); }
.woocommerce div.product .woocommerce-tabs ul.tabs li {
  background: transparent;
  border: 0; border-radius: 0;
  margin: 0;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { display: none; }
.woocommerce div.product .woocommerce-tabs ul.tabs li a {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
  padding: 12px 18px;
  border-bottom: 2px solid transparent;
}
/* Aktywna zakładka musi zdjąć BIAŁE TŁO z woocommerce.css.

   Reguła motywu wyżej zeruje tło na `li`, ale WooCommerce maluje
   `li.active` - jedna klasa więcej, więc wygrywa specyficznością i na
   ciemnej stronie zostawał biały prostokąt z pomarańczowym napisem
   (kontrast 2,28 - poniżej progu czytelności). Dlatego `li.active`
   trzeba wyzerować osobno, a nie liczyć na regułę dla `li`. */
.woocommerce div.product .woocommerce-tabs ul.tabs li.active {
  background: transparent;
  border-bottom-color: transparent;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
  color: var(--color-brand-orange);
  border-bottom-color: var(--color-brand-orange);
}
/* ZAKŁADKI NA TELEFONIE: RÓWNA SIATKA DWÓCH KOLUMN (zgłoszenie #9).

   W jednym rzędzie cztery zakładki mieszczą się dopiero od ok. 760 px.
   Zawijane jak tekst dawały na iPhonie 393 px trzy nierówne rzędy, każdy
   napis wcięty o 34 px (16 px `padding` na `li` z woocommerce.css + 18 px
   na `a`), a podkreślenie aktywnej wystawało po 18 px z obu stron napisu
   i wisiało między rzędami.

   Przewijany pas odrzucony z tego samego powodu co w nawigacji konta:
   czwarta zakładka („Bezpieczeństwo produktu”, wymagana prawem - audyt D1)
   stałaby za krawędzią ekranu ucięta w pół słowa, a to czyta się jak
   usterka, nie jak zachęta do przesunięcia.

   Siatka 2 × 2 mieści wszystko od 320 px: każda zakładka to równa komórka
   z własną kreską u dołu, aktywna ma pod całą komórką kreskę pomarańczową,
   napis stoi na środku - nic nie jest wcięte ani przesunięte. Za długi napis
   łamie się na dwa wyważone wiersze („Bezpieczeństwo / produktu”) zamiast
   wychodzić poza komórkę. Nieparzysta liczba zakładek (np. trzy) - ostatnia
   bierze cały rząd, bez pustej dziury. */
@media (max-width: 767px) {
  .woocommerce div.product .woocommerce-tabs ul.tabs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    border-bottom: 0;
  }
  .woocommerce div.product .woocommerce-tabs ul.tabs::before { display: none; }
  .woocommerce div.product .woocommerce-tabs ul.tabs li { display: flex; padding: 0; }
  .woocommerce div.product .woocommerce-tabs ul.tabs li:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .woocommerce div.product .woocommerce-tabs ul.tabs li a {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 8px 6px;
    text-align: center;
    line-height: 1.25;
    text-wrap: balance;
    border-bottom: 1px solid var(--border-default);
  }
  /* Druga kreska cieniem, nie grubszą ramką - komórki nie skaczą o 1 px. */
  .woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
    border-bottom-color: var(--color-brand-orange);
    box-shadow: inset 0 -1px 0 var(--color-brand-orange);
  }
}
.woocommerce div.product .woocommerce-tabs .panel { margin-top: 24px; color: var(--fg-muted); }

.related.products > h2,
.upsells.products > h2 { margin-top: 72px; }

/* --- WooCommerce: koszyk / checkout ---------------------------------------- */
.woocommerce table.shop_table {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  border-collapse: separate;
  background: var(--bg-surface);
}
.woocommerce table.shop_table th,
.woocommerce table.shop_table td { border-color: var(--border-default) !important; color: var(--fg-default); }
.woocommerce table.shop_table th {
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-muted);
}
.woocommerce a.remove { color: var(--fg-muted) !important; }
/* BEZ zapytania o kursor, inaczej niż reszta najechań (audyt iOS 2026-09-26):
   ta reguła GASI czerwone kółko z białym krzyżykiem z `woocommerce.css`
   (`a.remove:hover`), które na iPhonie przykleiłoby się po dotknięciu. */
.woocommerce a.remove:hover { color: var(--color-danger) !important; background: transparent; }
.woocommerce .cart-collaterals .cart_totals,
.woocommerce-checkout #order_review,
.woocommerce form.checkout .woocommerce-billing-fields,
#add_payment_method #payment, .woocommerce-cart #payment, .woocommerce-checkout #payment {
  background: var(--bg-surface);
  border-radius: var(--radius-3);
}
.woocommerce-checkout #payment div.payment_box { background: var(--color-ink-3); color: var(--fg-muted); }
.woocommerce-checkout #payment div.payment_box::before { border-bottom-color: var(--color-ink-3); }
.woocommerce-checkout #payment ul.payment_methods { border-bottom: 1px solid var(--border-default); }

/* Formularze

   BEZ `select` i BEZ skrótu `background:`. Ta reguła stoi w pliku po regule
   list rozwijanych wyżej i ma tę samą szczegółowość, więc skrót zerował
   tamtej strzałkę-obrazek (`background-image`), a `padding: 12px 14px`
   zabierał 40 px, które tamta zostawia na strzałkę. Każda lista
   `.woocommerce form .form-row select` w sklepie wyglądała przez to jak
   zwykłe pole tekstowe, bez znaku, że da się ją rozwinąć - „Twój pas
   w BJJ” przy rejestracji i w „Szczegółach konta” (2026-09-26). Listy mają
   wymiary i kolory w swojej regule, tu nie potrzebują niczego. */
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.select2-container--default .select2-selection--single,
input[type="text"], input[type="email"], input[type="tel"], input[type="password"], textarea {
  background-color: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-3);
  color: var(--fg-default);
  padding: 12px 14px;
  font-family: var(--font-body);
  font-size: 16px;
}
.woocommerce form .form-row input.input-text:focus,
input:focus, textarea:focus {
  border-color: var(--color-brand-orange);
}
.woocommerce form .form-row label { color: var(--fg-muted); font-size: 14px; }

/* Komunikaty */
.woocommerce-message, .woocommerce-info, .woocommerce-error {
  background: var(--bg-surface);
  color: var(--fg-default);
  border-top-color: var(--color-brand-orange);
  border-radius: var(--radius-3);
}
.woocommerce-error { border-top-color: var(--color-danger); }
.woocommerce-message::before { color: var(--color-success); }
.woocommerce-info::before { color: var(--color-info); }

/*
 * WooCommerce daje przyciskowi w komunikacie `float: right` i nie ma dla
 * niego żadnej reguły na wąskie ekrany — na telefonie tekst oblewał przycisk
 * i całość się rozjeżdżała. Odpinamy float zamiast przestawiać komunikat na
 * flex: `::after` w rdzeniu to clearfix (`display: table`), który jako
 * element flex dokładałby pusty odstęp.
 */
.woocommerce-message .button,
.woocommerce-info .button,
.woocommerce-error .button {
  float: none;
  display: inline-block;
  vertical-align: middle;
  margin-left: 12px;
}
@media (max-width: 560px) {
  .woocommerce-message .button,
  .woocommerce-info .button,
  .woocommerce-error .button { display: block; width: fit-content; margin: 12px 0 0; }
}

/*
 * TE SAME REGUŁY RAZ JESZCZE, Z OPAKOWANIEM `.woocommerce` W SELEKTORZE.
 *
 * Powyższe nie działały tam, gdzie są najbardziej potrzebne - na stronie
 * konta. `woocommerce-layout.css` niesie `.woocommerce .woocommerce-info
 * .button { float: right }`, czyli TRZY klasy, a reguła wyżej ma dwie
 * i przegrywa niezależnie od kolejności plików. Na stronach bez opakowania
 * `.woocommerce` tamta wersja działała i dlatego usterki nikt nie zauważył.
 *
 * Jak to wyglądało na telefonie: przycisk odpływał w prawo, a tekst oblewał
 * go wąską kolumną i łamał się w środku wyrazu („Potwie" / „rdź").
 *
 * Komunikat staje się kolumną, a przycisk dostaje `order: 2`, bo
 * w znaczniku WooCommerce stoi PRZED tekstem - bez tego wylądowałby nad
 * komunikatem, który ma tłumaczyć, po co ten przycisk.
 *
 * `::after` to clearfix rdzenia (`display: table`); w kolumnie flex byłby
 * pustym elementem dokładającym odstęp, więc go wyłączamy. `::before`
 * (ikona) jest pozycjonowany bezwzględnie, więc elementem flex nie zostaje
 * i zostaje nietknięty.
 */
@media (max-width: 560px) {
  .woocommerce .woocommerce-message,
  .woocommerce .woocommerce-info,
  .woocommerce .woocommerce-error {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
  .woocommerce .woocommerce-message::after,
  .woocommerce .woocommerce-info::after,
  .woocommerce .woocommerce-error::after { display: none; }

  .woocommerce .woocommerce-message .button,
  .woocommerce .woocommerce-info .button,
  .woocommerce .woocommerce-error .button {
    float: none;
    order: 2;
    width: 100%;
    margin: 12px 0 0;
    justify-content: center;
  }
}

/* --- About ----------------------------------------------------------------- */
.about { padding: var(--et-space) 0; border-top: 1px solid var(--border-default); background: var(--color-ink-1); }
.about-inner {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: 64px;
  align-items: center;
}
.about img.mark { width: 100%; max-width: 360px; margin: 0 auto; display: block; }
.about-copy h2 { margin-bottom: 24px; }
.about-copy h3 {
  font-family: var(--font-heading);
  font-size: 16px; font-weight: 600;
  letter-spacing: .08em;
  margin: 28px 0 8px;
}
.about-copy p { color: var(--fg-muted); margin: 0 0 12px; }

/* --- Wpisy / strony --------------------------------------------------------- */
.entry { max-width: 760px; margin: 0 auto 48px; }
.entry-title a { color: var(--color-bone-0); }
.entry-content {
  color: var(--fg-muted);
  /* Słowo dłuższe niż kolumna łamie się na jej krawędzi, zamiast wyjść poza
     ramkę i ekran (audyt iOS 2026-09-26): wykropkowane pola formularza
     odstąpienia na „Zwroty i reklamacje" miały 498 px w kolumnie 287 px,
     to samo grozi adresom i linkom wklejonym w edytorze. `break-word`, nie
     `anywhere` - nie zmienia szerokości tabel i kolumn liczonej z treści. */
  overflow-wrap: break-word;
}
.entry-content a { color: var(--color-brand-orange); }
.entry-content h2, .entry-content h3 { margin-top: 1.4em; }

/* NAGŁÓWKI ARTYKUŁU: NIGDY JUSTOWANE, ZAWSZE ZE ZBALANSOWANYMI WIERSZAMI.

   Treść artykułów przychodzi z edytora owinięta w `<div style="text-align:
   justify">`, co dziedziczyły także nagłówki - dwuwierszowy tytuł miał
   pierwszy wiersz rozciągnięty na całą kolumnę, z dziurami między wyrazami
   (zgłoszenie właściciela 2026-09-23, `/dlaczego-tejpowac/`). Reguła postawiona
   na samym nagłówku wygrywa z wartością dziedziczoną po rodzicu, więc żadne
   `!important` nie jest tu potrzebne.

   `text-wrap: balance` wyrównuje długość wierszy i przy okazji sam łamie
   tytuły po dwukropku, bo to właśnie tam wiersze wychodzą najrówniejsze.
   Zmierzone na tej stronie, 390 px:

     przed:  „Kompleksowe wsparcie: Metoda" / „Podwójnego X-Tapingu"
     po:     „Kompleksowe wsparcie:" / „Metoda Podwójnego X-Tapingu"

   Dlatego NIE wstawiamy twardych `<br>` do treści: krótki tytuł, który mieści
   się w jednym wierszu („Metoda Ochronna: „Buddy Taping""), zostaje w jednym,
   a nie dostaje łamania na siłę. */
.entry-content h1,
.entry-content h2,
.entry-content h3,
.entry-content h4 {
  text-align: left;
  text-wrap: balance;
}

@media (max-width: 640px) {
  /* SKALA NAGŁÓWKÓW NA TELEFONIE.

     `h2` z reguły bazowej ma dół `clamp()` na 1.9rem (30,4 px). Przy kolumnie
     334 px pytanie „Jak profesjonalnie stabilizować palce?" miało wtedy 442 px
     i łamało się na dwa wiersze.

     Sam stały rozmiar nie wystarczy, bo kolumna zwęża się razem z ekranem:
     21,6 px mieści to pytanie na 390 px (313 px w kolumnie 334), ale już nie
     na 360 px (kolumna 304). Stąd człon `vw`: wysokość pisma idzie za
     szerokością kolumny, a `clamp()` trzyma ją między 16 a 21,6 px.
     `h3` skaluje się tak samo, żeby hierarchia nie odwróciła się na wąskim
     ekranie i żeby balans dalej łamał tytuły po dwukropku. */
  .entry-content h2 { font-size: clamp(1rem, calc(6.3vw - 3.5px), 1.35rem); }
  .entry-content h3 { font-size: clamp(.9rem, calc(5.35vw - 3px), 1.15rem); }

  /* PODZIAŁ TYTUŁU DOKŁADNIE PO DWUKROPKU.

     Obie części (`inc/typografia.php`) stają się `inline-block`, czyli
     nierozrywalnymi kawałkami: mieszczą się obok siebie - tytuł zostaje
     w jednym wierszu; nie mieszczą - druga schodzi w całości niżej, więc
     podział wypada po dwukropku. Na szerokim ekranie oba `span`-y są zwykłym
     tekstem i nie zmieniają niczego. */
  .entry-content h2 .et-wstep,
  .entry-content h2 .et-reszta,
  .entry-content h3 .et-wstep,
  .entry-content h3 .et-reszta { display: inline-block; }

  /* Tekst wyrównany do lewej: w kolumnie 334 px justowanie bez dzielenia
     wyrazów (a polszczyzna dzieli się u nas `hyphens: manual`) zostawia rzeki
     białych dziur. Na szerokim ekranie zostaje tak, jak ustawił autor. */
  .entry-content p,
  .entry-content li { text-align: left; }
}

/* --- Film z YouTube: fasada do kliknięcia (2026-09-27) ----------------------
   Decyzja właściciela: film „w trybie bez ciasteczek, ładowany dopiero po
   kliknięciu”. Znaczniki robi `inc/youtube-facade.php` (każda ramka YouTube
   w treści), ramkę youtube-nocookie wstawia `egotape.js` po kliknięciu.

   Pudełko ma proporcje 16:9 z `aspect-ratio` i ZOSTAJE po kliknięciu -
   ramka wchodzi w to samo miejsce, więc treść pod filmem nie skacze.
   Wcześniej ramka 720x405 na telefonie ściskała się do 356x405 (szerokość
   z `max-width: 100%`, wysokość z atrybutu) i film miał czarne pasy.

   Wszystko jest w jednym `<button>`, bez `overflow: hidden` na pudełku:
   uciąłby pierścień fokusu, który rysuje się NA ZEWNĄTRZ przycisku
   (reguła `button:focus-visible` na górze arkusza). Własny `overflow`
   przycisku jego pierścienia nie tnie, za to zaokrągla rogi miniatury. */
.et-yt {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--color-ink-1);
  border-radius: var(--radius-3);
}
.et-yt-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: inherit;
  overflow: hidden;
  /* Tło zastępcze, gdy serwer nie zdobył miniatury (klasa `et-yt--plain`):
     kolory motywu, bez żadnego obcego adresu. Z miniaturą jest pod nią. */
  background: radial-gradient(120% 90% at 50% 38%, var(--color-brand-amber-grain) 0%, var(--color-ink-2) 55%, var(--color-ink-1) 100%);
  color: var(--color-bone-1);
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
}
.et-yt-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  /* `hqdefault` (zapas, gdy filmu nie ma w 1280 px) jest 4:3 z czarnymi
     pasami - `cover` ucina je dokładnie do kadru 16:9. */
  object-fit: cover;
}
/* Lekkie przyciemnienie od dołu: przycisk nie ginie na jasnym kadrze. */
.et-yt-play::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(11, 11, 11, .75) 0%, rgba(11, 11, 11, .3) 35%, rgba(11, 11, 11, .08) 100%);
  pointer-events: none;
}
.et-yt-cta {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px 0 18px;
  border-radius: var(--radius-3);
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  box-shadow: var(--shadow-1);
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .08em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background-color .2s var(--ease), transform .1s var(--ease);
}
.et-yt-icon { flex: none; width: 20px; height: 20px; fill: currentColor; }
/* Informacja na własnym ciemnym tle: miniatury mają w kadrze napisy
   z filmu (tu „Powtarzamy cały proces...”) i sam gradient nie wystarczał.
   Środek jawnie - przycisk ma go z arkusza przeglądarki, artykuł ma
   `text-align: justify`. */
.et-yt-note {
  position: absolute;
  z-index: 1;
  /* Środek przez `left` + `right` + `fit-content` + `margin: auto`, nie przez
     `left: 50%` z przesunięciem: tam dostępna szerokość to połowa pudełka
     i na telefonie zdanie łamało się na dwa wiersze. */
  left: 12px;
  right: 12px;
  bottom: 12px;
  width: -webkit-fit-content;
  width: fit-content;
  margin: 0 auto;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: rgba(11, 11, 11, .78);
  color: var(--color-bone-1);
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.35;
  text-align: center;
}
@media (hover: hover) and (pointer: fine) {
  .et-yt-play:hover .et-yt-cta { background: var(--color-brand-orange-bright); }
}
.et-yt-play:focus-visible .et-yt-cta { background: var(--color-brand-orange-bright); }
.et-yt-play:active .et-yt-cta { background: var(--color-brand-orange-deep); transform: scale(.98); }
/* Ramka po kliknięciu - w tym samym pudełku 16:9. */
.et-yt-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: inherit;
}
@media (max-width: 480px) {
  .et-yt-cta { min-height: 44px; gap: 8px; padding: 0 16px 0 14px; font-size: 14px; }
  .et-yt-note { left: 8px; right: 8px; bottom: 8px; padding: 4px 10px; font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .et-yt-cta { transition: none; }
  .et-yt-play:active .et-yt-cta { transform: none; }
}

/* --- Komentarze pod wpisem -------------------------------------------------- */
.comments-area { max-width: 760px; margin: 0 auto 48px; }
.comments-title { margin: 0 0 24px; }
.comment-list { list-style: none; margin: 0; padding: 0; }
.comment-list .children { list-style: none; margin: 0 0 0 32px; padding: 0; }
.comment-list > li { border-top: 1px solid var(--border-default); padding: 20px 0; }
.comment-author { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; }
/* Gravatar zostaje okrągły; kafla z pasem (`.et-avatar`) jest kwadratowa
 * z projektu i nie może tu dostać zaokrąglenia. */
.comment-author .avatar:not(.et-avatar) { border-radius: 50%; }
.comment-author .fn { font-style: normal; color: var(--color-bone-0); font-weight: 600; }
.comment-metadata { color: var(--fg-faint); font-size: 13px; }
.comment-metadata a { color: inherit; }
.comment-content p { color: var(--fg-muted); margin: 0 0 .6em; }
.comment-reply-link { color: var(--color-brand-orange); }
.comment-respond { margin-top: 24px; }
.comment-form p { margin: 0 0 14px; }
.comment-form label { display: block; color: var(--fg-muted); font-size: 14px; margin: 0 0 6px; }
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea { width: 100%; }

/* --- Wyniki wyszukiwania ------------------------------------------------ */
.search-header { margin: 0 0 32px; }
.search-title { margin: 0; }
.search-result-post {
  grid-column: 1 / -1;
  padding: 24px 0;
  border-bottom: 1px solid var(--border-default);
}
.search-result-post .entry-title { margin: 0 0 8px; }
.search-result-post .entry-content { margin: 0; }
.search-empty { color: var(--fg-muted); }
.search-empty a { color: var(--color-brand-orange); }

/* --- Footer ----------------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--border-default);
  background: var(--color-ink-1);
  padding: var(--et-space) 0 32px;
  margin-top: var(--et-space);
}
.footer-top {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) repeat(4, auto);
  gap: 40px 56px;
}
.footer-brand img { height: 56px; width: auto; margin-bottom: 16px; }
.footer-brand p { color: var(--fg-muted); font-size: 14px; margin: 0 0 8px; max-width: 32ch; }
.footer-mail { color: var(--color-brand-orange); }
.footer-social { display: flex; gap: 10px; margin-top: 14px; }
.footer-social .icon-btn { width: 36px; height: 36px; }
.footer-col h4, .footer-widget h4 {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-bone-0);
  margin: 0 0 14px;
}
.footer-col a, .footer-widget a {
  display: block;
  color: var(--fg-muted);
  font-size: 14px;
  padding: 5px 0;
}
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .footer-col a:hover, .footer-widget a:hover { color: var(--color-brand-orange); }
}

/* Palec potrzebuje 44 px, kursor nie.

   Przy 14 px tekstu i 5 px odstępu link w stopce ma 32 px wysokości -
   na myszy to bez znaczenia, ale kciukiem trafia się w niego obok. Warunek
   idzie po RODZAJU WSKAŹNIKA, a nie po szerokości okna: powodem jest palec,
   a nie mały ekran, więc tablet w poziomie też ma to dostać. Rośnie sam
   odstęp, więc napisy w stopce wyglądają tak samo jak wcześniej. */
@media (pointer: coarse) {
  .footer-col a, .footer-widget a { padding: 11px 0; }

  /* Adres e-mail to nie link w kolumnie, więc reguła wyżej go nie obejmuje,
     a ma ten sam problem: 19 px wysokości. Dwa pozostałe cele dotykowe
     (zgody, newsletter) siedzą na końcu pliku - ich reguły bazowe są dalej
     niż to miejsce, więc stąd by ich nie przebiły. */
  .footer-mail { display: inline-block; padding: 12px 0; }
}
.footer-widget ul { list-style: none; margin: 0; padding: 0; }
.footer-bottom {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  /* Linia pisma, nie góra pudełka: „Ustawienia plików cookies” ma na dotyk
     12 px wypełnienia (cel 44 px), więc na telefonie stało 12 px niżej niż
     „egotape.pl” w tym samym wierszu. */
  align-items: baseline;
  border-top: 1px solid var(--border-default);
  margin-top: 56px; padding-top: 24px;
  color: var(--fg-faint);
  font-size: 13px;
}

/* --- Responsive ------------------------------------------------------------- */
@media (max-width: 1024px) {
  .footer-top { grid-template-columns: 1fr 1fr; }
  .woocommerce ul.products { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  /* =======================================================================
     ZDJĘCIE JAKO TŁO CAŁEGO HERO (tylko telefon)

     Zamiast układać tekst i zdjęcie jedno pod drugim, kładziemy je na
     sobie. Hero traci przez to całą wysokość zdjęcia - bez ścinania
     choćby jednego słowa, bez zmniejszania nagłówka i bez ruszania
     treści z Personalizacji.

     Wcześniejsza próba szła drugą drogą: ścinała akapit, przyciski
     i odstępy. Właściciel obejrzał i odrzucił, i słusznie - płaciła
     proporcjami za miejsce, które tu dostajemy za darmo.
     ======================================================================= */
  .hero {
    grid-template-columns: 1fr;
    position: relative;
    isolation: isolate;
  }
  /* NA CAŁĄ SZEROKOŚĆ EKRANU - bez czarnych pasków po bokach.

     Hero jest w tym pliku dwa razy zwężane do wspólnej szerokości treści
     (`width: min(100% - margines*2, ...)` z `!important`), i obie te reguły
     stoją NIŻEJ niż ten blok. Dlatego jest tu i `body`, i `!important`:
     bez jednego i drugiego zdjęcie zostaje w ramce.

     Margines boczny wraca jako WYPEŁNIENIE, nie margines - tekst stoi
     w tej samej pionowej linii co reszta strony, a tło idzie do krawędzi. */
  body .hero {
    width: 100% !important;
    max-width: none !important;
    margin-inline: 0 !important;
    /* Wypełnienie pionowe mniejsze niż `--et-space` używane przez resztę
       sekcji. Hero jest jedynym miejscem, gdzie ten oddech kosztuje
       konkretnie: każdy piksel tutaj spycha towar poniżej krawędzi ekranu. */
    padding: var(--et-odstep-nad-logo, 16px) var(--et-gutter, 18px) 16px !important;
  }
  /* Odstępy między częściami hero. Te 8 px na przerwie razy cztery przerwy
     to 32 px, o które produkt podjeżdża wyżej - bez ruszania choćby jednej
     litery, wielkości nagłówka czy treści z Personalizacji. */
  /* TYTUŁ W JEDNEJ LINII, DOKŁADNIE POD LOGO.

     Trzy rzeczy naraz, bo bez wszystkich trzech żadna nie działa:

     1. `br` z Personalizacji jest ignorowany. Tytuł ma tam prawdziwy przełam
        linii („Pancerz dla\nTwoich palców"), więc bez tego zostałby łamany
        niezależnie od szerokości pisma.
     2. `nowrap` - inaczej przeglądarka złamałaby go z powrotem, gdy zabraknie
        miejsca, i cała robota z dopasowaniem szerokości poszłaby na marne.
     3. Ujemny margines zbija przerwę do logo. Odstęp w kolumnie hero jest
        wspólny dla wszystkich części, a tu ma być ciaśniej niż wszędzie.

     Samą WIELKOŚĆ pisma ustawia `egotape.js`: tytuł ma mieć równo tyle
     szerokości co napis EGOTAPE nad nim, a tego nie da się zapisać w CSS -
     zależy od długości zdania, które właściciel wpisuje w Personalizacji. */
  /* =======================================================================
     NAPIS EGOTAPE ZNIKA Z HERO NA TELEFONIE - zgłoszenie z przeglądu
     mobilnego (2026-08-13): „wordmark jest w headerze i sekundę niżej
     ogromny w hero, redundancja zjada pół ekranu".

     Ten sam napis dwa razy na pierwszym ekranie nie mówi dwa razy więcej -
     mówi tyle samo za podwójną cenę. W nagłówku zostaje, bo tam jest znakiem
     nawigacyjnym (klika się go, żeby wrócić na stronę główną); w hero był
     wyłącznie ozdobą, a ozdoba na telefonie kosztuje ekran.

     Odzyskane miejsce nie idzie na powietrze: claim rośnie do pełnej
     szerokości kolumny, a produkty podjeżdżają wyżej o wysokość napisu.

     Na pulpicie zostaje bez zmian - tam pion nie jest towarem deficytowym,
     a napis nad claimem buduje rytm kolumny.
     ======================================================================= */
  .hero .hero-strike { display: none; }

  /* Ujemnego marginesu już nie ma czym zbijać - stał tu po to, żeby tytuł
     przykleić do napisu nad nim. Wyrównanie do lewej wraca razem z resztą
     hero: centrowanie miało sens wyłącznie dlatego, że litery EGOTAPE stały
     pośrodku kolumny i tytuł trzymał ich oś. */
  /* WYŚRODKOWANY - życzenie właściciela przy zrównaniu szerokości wierszy.

     Przy dwóch wierszach tej samej szerokości centrowanie samo w sobie nic
     nie przesuwa (oba zajmują całą kolumnę), ale jest potrzebne z dwóch
     powodów: dopasowanie schodzi z tej strony, po której napis się MIEŚCI,
     więc wiersze wychodzą krótsze od kolumny o ułamek piksela do dwóch -
     i te ułamki mają się rozłożyć po równo na obie strony, a nie zebrać po
     prawej. Drugi powód: gdyby claim kiedyś miał trzy wiersze o różnej
     liczbie znaków, oś zostaje wspólna. */
  .hero .hero-title { white-space: nowrap; text-align: center; }
  .hero .hero-title .hero-title-fit { display: inline-block; }
  /* Wiersze claimu robią się blokami dopiero na telefonie - na pulpicie
     rozdziela je `<br>` i mają zostać zwykłym tekstem w linii. `<br>` jest
     tu ukryty regułą niżej, więc podziału pilnują same bloki i nie ma
     pustego wiersza między nimi.

     `line-height` ciaśniejszy niż domyślny: przy piśmie dwa razy większym
     standardowa interlinia rozsuwa dwa wiersze na tyle, że claim znów
     zabiera ekran, który właśnie odzyskaliśmy po napisie EGOTAPE. */
  /* Każdy wiersz dostaje WŁASNĄ wielkość pisma z `egotape.js` - stąd
     `line-height` bez jednostki: mnoży się przez wielkość TEGO wiersza,
     więc oba są ciasne tak samo. Wartość w pikselach dałaby przy większym
     wierszu litery zachodzące na siebie, a przy mniejszym dziurę. */
  .hero .hero-title .hero-title-line { display: block; white-space: nowrap; line-height: .92; }
  /* Wielkość claimu ustawia `egotape.js` z `--et-hero-claim-skala`
     (Personalizacja → „Hero - wielkość napisu na telefonie"). Tutaj nic
     nie liczymy: pismo zależy od długości zdania, a tego CSS nie zmierzy. */

  /* =======================================================================
     OPIS: PRZEŁAMY UKRYTE, WYRÓWNANIE BEZ ZMIAN - 2026-08-13.

     Notatka poniżej (z 2026-08-12) mówi wprost, czym się skończyła
     poprzednia próba i co z niej wynikło: „samo ukrycie `br` BEZ
     centrowania usuwało sieroty i skracało blok ze 179 do 128 px.
     Problemem było centrowanie, nie łamanie".

     Robimy więc dokładnie tę połowę, która działała. Powód jest nowy:
     przegląd mobilny prosi, żeby odzyskane po napisie EGOTAPE miejsce
     podciągnęło produkty wyżej, a claim urósł dwukrotnie i sam z siebie
     tego miejsca nie odda. Pięćdziesiąt pikseli z opisu to jedyny zapas,
     jaki został w hero - i jest to zapas, który nic nie kosztuje, bo
     przełamy w tym tekście były pisane pod szeroki ekran.

     Bez tego opis rozpadał się na wiersze-sieroty: „grapplerów.",
     „skórę,", „inspirowany" stały samotnie, każdy jako osobna linia.
     Tekst zostaje wyrównany do lewej i nie jest centrowany - to była ta
     część, którą właściciel odrzucił, i ona się nie zmienia. */
  /* Gdy właściciel napisał osobny opis na telefon, wchodzi on zamiast
     tamtego - razem ze swoimi przełamami, bo po to został napisany. */
  /* Nie `>`: opis siedzi teraz w `.hero-rotator` (rotator zdań, 2026-09-23). */
  .hero-left.ma-opis-mobilny .hero-sub:not(.hero-sub-mobile) { display: none; }
  .hero .hero-sub-mobile { display: block; }
  /* DWIE KLASY w selektorze, nie jedna - inaczej reguła nie zadziała.
     Kilka linijek niżej stoi `.hero .hero-sub br { display: none }` o tej
     samej specyficzności, a przy remisie wygrywa ta późniejsza. Dołożona
     klasa przechyla szalę bez uciekania się do `!important`. */
  .hero .hero-sub.hero-sub-mobile br { display: revert; }

  .hero .hero-sub br { display: none; }

  /* OPIS ZOSTAJE TAKI, JAKI BYŁ - decyzja właściciela z 2026-08-12.

     Próbowałem tu dwóch rzeczy naraz: ukryć przełamy linii wpisane pod
     szeroki ekran i wyśrodkować tekst. Wyśrodkowany akapit o zmiennej
     długości wierszy dał poszarpane obie krawędzie i wyglądał gorzej niż
     stan wyjściowy. Cofnięte w całości - opis jest wyrównany do lewej
     i honoruje przełamy z Personalizacji, dokładnie jak przedtem.

     Gdyby kiedyś wracać do tematu: samo ukrycie `br` BEZ centrowania
     usuwało sieroty („grapplerów.", „skórę,", „inspirowany" w osobnych
     wierszach) i skracało blok ze 179 do 128 px. Problemem było
     centrowanie, nie łamanie. */

  /* =======================================================================
     TRZY WEZWANIA, TRZY RÓŻNE WAGI - zgłoszenie z przeglądu mobilnego
     (2026-08-13): „dwa secondary obok siebie w tej samej wadze to szum,
     »Dlaczego tejpować?« zrób zwykłym linkiem tekstowym ze strzałką".

     Poprzedni układ stawiał „Zobacz gotowe zestawy" i „Dlaczego tejpować?"
     w dwóch równych polach siatki, obu w ramkach, oba tym samym pismem.
     Dwa przyciski tej samej wagi obok siebie zmuszają do przeczytania obu
     i wybrania - a to jest praca, której nikt nie chciał wykonać, wchodząc
     na stronę główną.

     Teraz: kupno (pełny przycisk), oglądanie (obrys), czytanie (goły
     odnośnik ze strzałką). Trzy stopnie zaangażowania i trzy różne wyglądy,
     więc oko układa je w kolejność zamiast porównywać.

     Jedna kolumna, nie dwie: przyciski na pełną szerokość nie muszą już
     mieścić się w połówce, więc wraca normalna wielkość pisma - poprzednie
     12 px z ciaśniejszym odstępem liter było ustępstwem na rzecz układu
     dwóch kolumn, którego już nie ma.
     ======================================================================= */
  .hero .hero-ctas {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
  }
  /* PRZYCISKI NA PEŁNĄ SZEROKOŚĆ, RÓWNE.

     Wcześniej „Stwórz swój 4-pak" miał 186 px, a „Zobacz gotowe zestawy"
     221 px, jeden pod drugim - dwa prostokąty różnej długości w pionie
     wyglądają na przypadek. Do tego oba miały 42 px wysokości, a poniżej
     44 px palec zaczyna chybiać. */
  /* Główna akcja zajmuje cały wiersz - ma być największym celem na
     ekranie. Pozostałe dwie dzielą wiersz niżej po połowie. */
  /* Oba przyciski na pełną szerokość i co najmniej 44 px wysokości -
     poniżej tej wartości palec zaczyna chybiać. */
  .hero .hero-ctas .btn {
    width: 100%;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
  }

  /* ODNOŚNIK, A NIE TRZECI PRZYCISK.

     Ramka zdjęta świadomie: to jest jedyny sposób, żeby oko przestało
     liczyć go razem z przyciskami. Zostaje strzałka (dopisana w szablonie),
     wersaliki i pole dotykowe 44 px - czyli wygląda jak tekst, a klika się
     jak przycisk. Wyrównany do lewej razem z resztą hero. */
  .hero .hero-ctas .hero-link {
    border: none;
    background: none;
    padding: 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    align-self: flex-start;
    font-size: 13px;
    letter-spacing: .06em;
  }
  /* `min-width: 0` NIE JEST kosmetyką - bez tego całość się rozjeżdża.

     Pole siatki ma domyślnie najmniejszą szerokość równą swojej treści.
     Tytuł bez zawijania jest szerszy niż ekran, więc rozpychał kolumnę,
     kolumna rozpychała logo (rozciągnięte na jej szerokość), a logo jest
     miarą, do której dopasowujemy tytuł. Dopasowanie goniło własny ogon:
     ten sam kod dawał 41,8 px na jednym telefonie i 25,1 px na drugim,
     a strona jechała w bok. */
  .hero { grid-template-columns: minmax(0, 1fr); }
  /* WYSOKOŚĆ HERO NA TELEFONIE - „Hero: wysokość na telefonie (px)".

     Inny mechanizm niż na komputerze i dlatego osobne ustawienie, a nie ta
     sama liczba w dwóch miejscach. Na komputerze hero jest siatką dwóch
     kolumn i wysokość bierze się ze zdjęcia obok tekstu; tutaj zdjęcie jest
     TŁEM (`position: absolute; inset: 0`), więc nie wnosi ani piksela -
     sekcja jest dokładnie tak wysoka, jak jej treść. Podniesienie zdjęcia
     nie zrobiłoby nic, bo zdjęcie i tak wypełnia to, co dostanie.

     Stąd `min-height` na całej sekcji: to jedyne miejsce, w którym da się
     tu dołożyć wysokość. Treść zostaje wyśrodkowana w pionie, bo
     `.hero-left` ma `justify-content: center`.

     Zero znaczy „tyle, ile trzeba na treść" i jest stanem domyślnym -
     dokładnie to, co strona robi dzisiaj. */
  .hero { min-height: var(--et-hero-wysokosc-mobile, 0px); }

  /* =======================================================================
     JEDNA LICZBA SKALUJE CAŁE HERO - „Hero: skala na telefonie (%)".

     Zgłoszenie właściciela: „chciałbym jakby skalować wszystko, co się
     składa na HERO, i proporcjonalnie zmniejszać/zwiększać wszystko".

     To jest lepsze postawienie sprawy niż moje poprzednie: pole wysokości
     potrafiło tylko dołożyć pustego miejsca, bo wysokość tej sekcji jest
     SUMĄ TREŚCI. Żeby hero zrobiło się niższe, musi zmaleć to, co w nim
     stoi - a wtedy ma zmaleć wszystko naraz, bo inaczej proporcje się
     rozjeżdżają.

     Skalowane jest KAŻDE pionowe źródło wysokości mierzone przy 390 px:
     wypełnienie sekcji (10+16), przerwy między częściami (12), pismo opisu
     (16/1.6), przerwa między przyciskami (10), wysokość i pismo przycisków
     (44 i 14), odnośnik (44 i 13). Claim skaluje `egotape.js` tą samą
     zmienną - patrz `celSzerokosci()`.

     DLACZEGO NIE `transform: scale()` ANI `zoom`

     `transform` rysuje mniejsze, ale zostawia pudełko w starym rozmiarze -
     hero zajmowałoby tyle samo miejsca, a wokół treści powstałaby pusta
     ramka. Czyli dokładnie odwrotnie do celu. `zoom` przelicza układ, ale
     zaburza pomiary w `getBoundingClientRect()`, na których stoi
     dopasowanie claimu - dostalibyśmy napis mierzony w jednej skali,
     a rysowany w drugiej.

     Mnożenie konkretnych wartości jest dłuższe do napisania i jedyne, które
     daje przewidywalny wynik.

     PRZYCISKI MAJĄ DOLNĄ GRANICĘ i to nie podlega skali: 44 px, ten sam próg,
     co dla każdego przycisku w motywie (audyt D5 zmierzył tu 40 px przy skali
     poniżej 1 - hero było jedynym miejscem z niższą granicą). Poniżej sekcja
     robi się ładniejsza i niesprawna, więc granica nie zależy od ustawienia.
     ======================================================================= */
  .hero {
    padding-top: calc(var(--et-odstep-nad-logo, 16px) * var(--et-hero-skala-mobile, 1)) !important;
    padding-bottom: calc(16px * var(--et-hero-skala-mobile, 1)) !important;
  }
  .hero .hero-sub {
    font-size: calc(16px * var(--et-hero-skala-mobile, 1));
    line-height: 1.6;
  }
  /* Skala hero (dziś 0,9) nie zbija ceny poniżej 15 px - to jedyna liczba
     w hero, którą klient ma przeczytać w 3 sekundy. */
  .hero .hero-price { font-size: max(15px, calc(15px * var(--et-hero-skala-mobile, 1))); }
  .hero .hero-ctas { row-gap: calc(10px * var(--et-hero-skala-mobile, 1)); }
  .hero .hero-ctas .btn {
    font-size: calc(14px * var(--et-hero-skala-mobile, 1));
    min-height: 44px;
    padding-top: calc(13px * var(--et-hero-skala-mobile, 1));
    padding-bottom: calc(13px * var(--et-hero-skala-mobile, 1));
  }
  .hero .hero-ctas .hero-link {
    font-size: calc(13px * var(--et-hero-skala-mobile, 1));
    min-height: 44px;
  }
  .hero .hero-left { min-width: 0; }
  /* Centrowanie dotyczy TYLKO tytułu. Napis EGOTAPE jest obrazkiem
     rozciągniętym na całą kolumnę i jego litery siedzą pośrodku, więc tytuł
     pod nim ma trzymać tę samą oś. Reszta hero - nadkreślenie, opis,
     przyciski - zostaje przy lewej krawędzi, bo tak stoi cała strona. */
  .hero .hero-title br { display: none; }
  /* ODSTĘPY MIĘDZY CZĘŚCIAMI HERO - jedyna rzecz w tej sekcji, którą da się
     na telefonie ZMNIEJSZYĆ, a nie tylko powiększyć.

     Zgłoszenie właściciela: „chcę móc zmniejszyć i zwiększyć, teraz rozumiem
     mogę tylko powiększyć na mobilce?". Rozumie dobrze i warto powiedzieć,
     dlaczego tak jest.

     Wysokość hero na telefonie to suma treści, nie ustawienie: claim, opis,
     trzy wezwania do działania i przerwy między nimi. `min-height` potrafi
     dołożyć pustego miejsca, ale nie potrafi skrócić zdania ani obniżyć
     przycisku, który ma 44 px, bo poniżej tego palec chybia.

     Zmierzone przy 390 px: claim 111, opis 128, przyciski 152, przerwy 24,
     wypełnienie 26 - razem 441. Z tego regulowane jest wszystko poza
     przyciskami: claim ma własny suwak wielkości, opis własne pole tekstowe,
     wypełnienie u góry - „odstęp nad logo", a przerwy między częściami
     dostają je właśnie tutaj.

     Zakres jest szczery: od zera do czterdziestu, czyli 24 px w dół i 56 px
     w górę względem dzisiejszego stanu. To nie jest dużo i nie udajemy, że
     jest - większe skrócenie hero robi się suwakiem claimu i krótszym
     opisem, bo tam siedzą prawdziwe piksele. */
  .hero .hero-left {
    gap: calc(var(--et-hero-odstepy-mobile, 12px) * var(--et-hero-skala-mobile, 1));
  }
  .hero .hero-ctas { gap: 10px; margin-top: 2px; }
  /* Dwie klasy w selektorze CELOWO: reguła dla pulpitu to
     `.hero-right.has-image`, więc pojedyncza klasa jej nie przebija
     i blok zostawał w układzie obok siebie, zapadając się do zera
     wysokości. Zdjęcia wtedy nie było widać wcale - a wyglądało to jak
     za mocna zasłona. */
  /* TRZY klasy w selektorze, nie dwie. Reguła `.hero-right.has-image` dla
     pulpitu stoi w tym pliku PÓŹNIEJ, a przy równej specyficzności wygrywa
     kolejność - moja poprzednia wersja nie miała szans i blok zostawał
     `position: relative` o zerowej wysokości. */
  .hero .hero-right,
  .hero .hero-right.has-image {
    position: absolute;
    inset: 0;
    z-index: 0;
    min-height: 0;
    border: 0;
    border-radius: 0;
  }
  /* Boczne wtapianie jest zbudowane pod układ „tekst z lewej, zdjęcie
     z prawej". Na tle całego hero zjadałoby lewą połowę kadru. */
  .hero .hero-right.has-image::before { display: none; }
  .hero-left { position: relative; z-index: 1; }

  /* ZASŁONA POD TEKSTEM - bez niej napis jest czytelny na ciemnym zdjęciu
     i znika na jasnym, a karuzela zmienia je co kilka sekund. Zasłona musi
     wystarczać dla NAJJAŚNIEJSZEGO możliwego kadru, nie dla tego, który
     akurat widać. */
  /* TRZY klasy, znowu z tego samego powodu co wyżej: `.hero-right.has-image::after`
     dla pulpitu (pomarańczowa poświata) stoi w tym pliku NIŻEJ. Poprzednia wersja
     tej reguły miała dwie klasy i przegrywała w całości - na telefonie zdjęcie szło
     bez żadnego przyciemnienia, a biały tekst leżał wprost na kadrze. */
  .hero .hero-right.has-image::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    /* TO JEDNA LINIJKA ROBI TU CAŁĄ ROBOTĘ.

       Reguła dla pulpitu maluje tym samym pseudo-elementem pomarańczową
       poświatę w trybie `screen`. Nadpisanie samego tła nie wystarczało:
       w trybie `screen` czerń jest działaniem pustym, więc zasłona była
       policzona, namalowana i niewidoczna. Zdjęcie szło pełną jasnością,
       a biały tekst leżał na kadrze bez niczego pod spodem. */
    mix-blend-mode: normal;
    /* Dwie warstwy: przyciemnienie plus delikatne prążki.

       Sama płaska zasłona musiałaby być bardzo ciemna, żeby poradzić sobie
       z najjaśniejszym kadrem karuzeli - i zdjęcie robiło się przez to
       martwe. Prążki rozbijają jasne pasma, więc to samo przyciemnienie
       wystarcza przy mniejszej mocy i zdjęcie dalej żyje. */
    background:
      repeating-linear-gradient(
        135deg,
        rgba(11, 11, 11, .10) 0 2px,
        rgba(11, 11, 11, 0) 2px 5px
      ),
      linear-gradient(
        to bottom,
        rgba(11, 11, 11, .86) 0%,
        rgba(11, 11, 11, .74) 42%,
        rgba(11, 11, 11, .82) 70%,
        /* DÓŁ SCHODZI DO PEŁNEJ CZERNI - i to nie jest kosmetyka.

           Tło hero, tło strony i tło sekcji z produktami to ten sam
           `--color-ink-1`. Dopóki zasłona kończyła się na .84, zdjęcie
           urywało się ostrą poziomą krawędzią dokładnie na styku sekcji.
           Doprowadzone do krycia 1 kadr rozpuszcza się w tej samej czerni,
           w której zaczyna się „4-PAK TAŚMY TRENINGOWE” - szwu nie ma,
           bo nie ma dwóch różnych kolorów, które mogłyby się spotkać.

           Ostatnie 30% wysokości hero to około 190 px przejścia. Krócej
           widać przejście jako pas, dłużej zjada zdjęcie. */
        var(--color-ink-1) 100%
      );
  }
  /* Tekst pomocniczy rozjaśniony: kolor stonowany dobrany pod jednolite
     tło ma na zdjęciu za mały kontrast, nawet pod zasłoną.

     Cień jest tu drugą linią obrony, nie ozdobą: zasłona jest jednakowa
     na całej wysokości, a zdjęcia nie - jedno ma jasne pasmo dokładnie
     tam, gdzie na innym jest cień. Cień działa na każdym kadrze, bo idzie
     za literami, a nie za tłem. */
  .hero-sub { color: var(--color-bone-2); text-shadow: 0 1px 3px rgba(0, 0, 0, .55); }
  .hero-price { text-shadow: 0 1px 3px rgba(0, 0, 0, .55); }
  .hero-title,
  .hero-eyebrow { text-shadow: 0 2px 6px rgba(0, 0, 0, .45); }
  /* ODSTĘP POD HERO - regulowany w Personalizacji („Odstęp pod hero na
     telefonie”). Sterowanie przez zmienną, a nie sztywną liczbą, bo to
     jedyna rzecz na tym ekranie, którą właściciel dostraja na oko - i ma
     móc to zrobić bez programisty. */
  .hero + section,
  .hero + * > section:first-child { padding-top: var(--et-odstep-pod-hero, 28px); }

  /* Strzałki karuzeli schodzą na dół, żeby nie wchodziły w nagłówek. */
  /* STEROWANIE KARUZELĄ SCHOWANE - decyzja właściciela.

     Na telefonie zdjęcie jest tłem całego hero, a trzy kółka w rogu kadru
     były jedynym elementem, który wyglądał jak odtwarzacz doklejony do
     strony sprzedażowej.

     Nie tracimy przez to sterowania: `egotape.js` na urządzeniach bez
     kursora dzieli kadr na trzy pola dotyku - lewe cofa, prawe przewija,
     środkowe zatrzymuje i wznawia. To działa dalej, bo wisi na całym
     zdjęciu, a nie na przyciskach.

     Świadomy koszt: WCAG 2.2.2 wymaga MECHANIZMU zatrzymania ruchu, a tap
     w środek kadru jest mechanizmem niewidocznym - czyli formalnie słabszym
     niż przycisk. Dlatego wyjątek niżej.

     DWIE KLASY, nie jedna. Zapytanie o media NIE podnosi specyficzności:
     bazowe `.hero-controls { display: flex }` stoi w tym pliku niżej i przy
     równej wadze wygrywało kolejnością, więc przyciski zostawały widoczne.
     To już trzecie miejsce w tym bloku z tą samą pułapką. */
  .hero .hero-controls { display: none; }
  .about-inner { grid-template-columns: 1fr; gap: 40px; }
  :root { --et-space: var(--et-space-mobile, 56px); --et-space-sm: calc(var(--et-space-mobile, 56px) * .5); }
}

/* MENU JAKO WARSTWA DO 1279 PX, NIE DO 768 (2026-09-26, audyt pulpitu).
   Pełne menu w jednym rzędzie potrzebuje co najmniej 1262 px (pomiar przy
   regułach „1280-1439 px” wyżej). Między 769 a 1279 px - tablety, iPad
   w poziomie (1024, 1180), małe laptopy - rozpychało nagłówek i wypychało
   lupę, konto i koszyk za prawą krawędź okna (przy 800 px ikony stały na
   1201-1341). Te same reguły co na telefonie, tylko szerszy zakres. */
@media (max-width: 1279px) {
  .et-nav-toggle { display: inline-flex; }
  /* =========================================================================
     MENU JAKO PELNOEKRANOWA WARSTWA

     Wczesniej menu bylo panelem doklejonym pod naglowkiem (`position:
     absolute; top: 100%`). Zajmowalo tyle miejsca, ile mialo pozycji,
     a reszta strony zostawala widoczna dookola - wiec czytalo sie jako
     KOLEJNY KAWALEK STRONY, a nie jako menu. Zgloszenie wlasciciela:
     „menu zbyt miksuje sie z reszta strony".

     Wzorzec jest standardowy dla telefonow: warstwa zajmuje caly ekran,
     tlo pod nia przestaje sie przewijac, a wyjscie jest w dwoch miejscach
     (krzyzyk u gory i ten sam przycisk MENU w pasku, ktory ja otworzyl).
     Pasek na dole zostaje widoczny z podswietlonym MENU - dzieki temu
     wiadomo, gdzie sie jest i czym to zamknac.

     Blur naglowka jest tu wylaczony nie dla wygladu: `backdrop-filter`
     tworzy blok zawierajacy dla potomkow `position: fixed`, wiec warstwa
     przykleilaby sie do naglowka zamiast do ekranu. Pod 94-procentowa
     czernia te szesc pikseli rozmycia i tak jest niewidoczne.
     ====================================================================== */
  .header { -webkit-backdrop-filter: none; backdrop-filter: none; }

  .header-nav {
    display: none;
    position: fixed;
    top: 0; left: 0; right: 0;
    /* Bez tego `margin-left: 8px` z reguły pulpitu przesuwał warstwę:
       zmierzone na 393 px - lewa krawędź na 8, pas strony widoczny obok. */
    margin-left: 0;
    bottom: calc(var(--et-pasek-dolny) + env(safe-area-inset-bottom, 0px));
    z-index: 61;
    background: var(--color-ink-1);
    border-bottom: 0;
    padding: 0 var(--et-gutter-mobile, 20px) 24px;
    overflow-y: auto;
    /* Przewijanie konczy sie na warstwie - bez tego dojechanie do konca listy
       zaczyna przewijac strone pod spodem. */
    overscroll-behavior: contain;
  }
  /* Pasek WordPressa u zalogowanych stoi nad wszystkim (z-index 99999),
     wiec warstwa zaczyna sie pod nim, a nie za nim. */
  body.admin-bar .header-nav { top: 46px; }

  .header-nav.open { display: block; animation: et-menu-wjazd .18s ease-out both; }
  @keyframes et-menu-wjazd {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .header-nav.open { animation: none; }
  }

  /* Naglowek warstwy - wstawia go `egotape.js`, bo lista pozycji przychodzi
     z `wp_nav_menu()` i nie ma jak dolozyc do niej niczego w PHP. */
  .et-menu-naglowek {
    position: sticky; top: 0;
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px;
    margin: 0 calc(var(--et-gutter-mobile, 20px) * -1) 8px;
    padding: 14px var(--et-gutter-mobile, 20px);
    background: var(--color-ink-1);
    border-bottom: 1px solid var(--border-default);
  }
  .et-menu-naglowek span {
    font-family: var(--font-heading);
    font-size: 12px; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--fg-muted);
  }
  .et-menu-zamknij {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    margin-right: -10px;
    background: none; border: 0;
    color: var(--fg-default);
    font-size: 26px; line-height: 1;
    cursor: pointer;
  }
  .et-menu-zamknij:focus-visible { color: var(--color-brand-orange); }

  /* Tlo nie przewija sie pod otwarta warstwa.

     Sama `body` nie wystarcza: gdy elementem przewijanym jest `html`
     (a jest, w normalnym ukladzie strony), zablokowanie `body` niczego nie
     daje - zmierzone, strona jechala dalej pod warstwa. Stad obie. */
  html.et-menu-otwarte,
  body.et-menu-otwarte { overflow: hidden; }

  /* Plywajace „?" ma wyzsza warstwe niz menu, wiec przy otwartym menu
     wisialoby nad nim jak przycisk nalezacy do warstwy - a nie nalezy.
     Znika razem z trescia strony, ktorej dotyczy. */
  body.et-menu-otwarte .et-faq { display: none; }

  /* Cel dotykowy w menu mobilnym.
     Wcześniej: `gap: 14px` dawał odstęp WIZUALNY, ale sam link miał
     klikalny obszar ~26 px wysokości (tekst 14 px + 2 px paddingu) —
     poniżej minimum 44 px (WCAG 2.5.5). Zmierzone w audycie na żywo.
     Teraz odstęp robi padding samego linku, więc cały wiersz jest
     klikalny. Podkreślenie (`border-bottom`) zastąpione separatorem na
     `li` — w pionowej liście podkreślenie odjechałoby od tekstu na dół
     44-pikselowego wiersza i wyglądałoby jak przypadek. */
  .header-nav ul { flex-direction: column; gap: 0; }
  .header-nav li { border-bottom: 1px solid var(--border-default); }
  .header-nav li:last-child { border-bottom: 0; }
  .header-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding-bottom: 0;
    border-bottom: 0;
  }

  .et-tools-mobile { display: block; }
  .et-tools-mobile-head {
    display: block; padding: 14px 0 6px;
    font-family: var(--font-heading);
    font-size: 11px; font-weight: 600; letter-spacing: .18em;
    text-transform: uppercase; color: var(--fg-faint);
  }
  .et-tools-mobile ul { gap: 0; }
  .et-tools-mobile li { border-bottom: 0; }
  .et-tools-mobile a { color: var(--color-brand-orange); }

  .header-nav a:hover,
  .header-nav .current-menu-item > a,
  .header-nav a.is-current { border-color: transparent; }
}
/* Dolny pasek nawigacji jest tylko do 640 px - wyżej warstwa menu schodzi
   do dna ekranu, zamiast zostawiać 56 px pasa ze stroną pod spodem. */
@media (min-width: 641px) and (max-width: 1279px) {
  .header-nav { bottom: 0; }
}
/* Nagłówek warstwy wstawia skrypt przy pierwszym otwarciu menu. Po
   poszerzeniu okna powyżej progu zostałby w rzędzie pozycji jako „Menu ×". */
@media (min-width: 1280px) {
  .et-menu-naglowek { display: none; }
}
@media (max-width: 560px) {
  /* DWIE KOLUMNY, NIE JEDNA.

     Stało tu `1fr`, czyli jeden produkt na całą szerokość: karta 334x482 px,
     z czego samo zdjęcie 332x332. Na ekranie 844 px widać było w praktyce
     JEDEN produkt, a cała lista dziesięciu miała 6956 px - siedem ekranów
     przewijania, żeby obejrzeć ofertę.

     Dwie kolumny to standard w sklepach na telefonie nie z mody, tylko
     dlatego, że pozwalają PORÓWNAĆ dwie rzeczy bez przewijania. Przy jednej
     kolumnie każde porównanie wymaga zapamiętania tego, co zjechało w górę.

     Zdjęcie schodzi do ~159 px i nadal jest większe niż kciuk, którym się
     w nie celuje. */
  .woocommerce ul.products { grid-template-columns: repeat(2, 1fr); }
  .footer-top { grid-template-columns: 1fr; }
  .header-logo img { height: var(--et-logo-mobile, 36px); }
  .header.header-maly .header-logo img { height: calc(var(--et-logo-mobile, 36px) * .6); }
}


/* --- Dodatek: pudełko prezentowe ------------------------------------------- */
.egotape-box-addon {
  flex-basis: 100%;
  margin: 4px 0 10px;
}
.egotape-box-addon label {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: 14px;
  color: var(--fg-default);
  transition: border-color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .egotape-box-addon label:hover { border-color: var(--color-brand-orange); }
}
.egotape-box-addon input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--color-brand-orange);
  cursor: pointer;
}
.egotape-box-addon .woocommerce-Price-amount { color: var(--color-brand-orange); }

/* --- Hero: zdjęcie wtopione gradientem w tło -------------------------------- */
.hero-right.has-image {
  position: relative;
  border: none;
  border-radius: 0;
  overflow: hidden;
}
.hero-right.has-image::before {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    /* lewa — mocne przejście w czerń od strony tekstu (bez zmian) */
    linear-gradient(90deg,  var(--color-ink-1) 0%, rgba(11,11,11,.55) 22%, rgba(11,11,11,0) 55%),
    /* prawa — długie, łagodne wtopienie */
    linear-gradient(270deg, var(--color-ink-1) 0%, rgba(11,11,11,.35) 12%, rgba(11,11,11,0) 40%),
    /* góra — subtelne */
    linear-gradient(180deg, var(--color-ink-1) 0%, rgba(11,11,11,.25) 10%, rgba(11,11,11,0) 32%),
    /* dół — subtelne */
    linear-gradient(0deg,   var(--color-ink-1) 0%, rgba(11,11,11,.25) 10%, rgba(11,11,11,0) 32%);
}
.hero-right.has-image::after {
  /* subtelny amber pogłos spójny z puckami */
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(60% 55% at 62% 42%, rgba(246,149,0,.08) 0%, rgba(246,149,0,0) 70%);
  mix-blend-mode: screen;
}


/* --- Pola wyboru na stronie produktu ---------------------------------------- */
.egotape-selects { flex-basis: 100%; display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; margin: 4px 0 10px; }
@media (max-width: 560px) { .egotape-selects { grid-template-columns: 1fr; } }

/*
 * Wybór kolorów na karcie produktu — ten sam komponent co konfigurator na
 * stronie głównej (`egotape_render_color_picker()`). Siatka dwukolumnowa
 * powyżej była zaprojektowana pod stare pola <select>; picker jest jednym
 * pełnowymiarowym blokiem, więc ją tu wyłączamy — inaczej wpadłby w jedną
 * kolumnę i renderował się na pół szerokości.
 *
 * Sloty przez `auto-fit` zamiast sztywnego `repeat(4, …)` z konfiguratora,
 * bo liczba rolek zależy od produktu (taśmy mają 4, pudełko 2).
 */
.egotape-selects--picker { display: block; margin: 8px 0 18px; }
.egotape-selects--picker .et-builder-slots { grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); }
.egotape-selects--picker .et-builder-palette { margin-top: 16px; }

.egotape-select-field label {
  display: block;
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: 6px;
}
.egotape-select-field abbr { color: var(--color-brand-orange); text-decoration: none; }
.egotape-select-field select {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  color: var(--fg-default);
  padding: 11px 12px;
  font-family: var(--font-body);
}
.egotape-select-field select:focus { border-color: var(--color-brand-orange); }


/* Medalion bóstwa na hover — większy niż wspólne logo */
.woocommerce ul.products li.product .et-product-well .et-hover-medallion img,
.et-hover-medallion img {
  width: var(--et-hover-medallion-size, 58%) !important;
  height: var(--et-hover-medallion-size, 58%) !important;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,.45));
}


/* --- Pasek kategorii w sklepie ---------------------------------------------- */
.et-cat-chips { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 28px; }
.et-chip {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
  background: var(--bg-surface);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  min-height: 44px; display: inline-flex; align-items: center; /* zmierzone 41 px */
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-chip:hover { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
}
.et-chip.is-active {
  color: var(--color-ink-1);
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
}


/* --- Slider produktów -------------------------------------------------------- */
.et-slider-wrap { position: relative; }
.et-slider {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--color-ink-5) transparent;
  padding-bottom: 10px;
}
.et-slider::-webkit-scrollbar { height: 6px; }
.et-slider::-webkit-scrollbar-track { background: var(--color-ink-2); border-radius: 999px; }
.et-slider::-webkit-scrollbar-thumb { background: var(--color-ink-5); border-radius: 999px; }
.et-slider::-webkit-scrollbar-thumb:hover { background: var(--color-brand-orange); }

/* siatka WooCommerce -> tor slidera */
.et-slider .woocommerce ul.products,
.et-slider ul.products {
  display: flex !important;
  grid-template-columns: none !important;
  flex-wrap: nowrap;
  gap: 20px;
  margin: 0;
  padding: 0;
}
.et-slider ul.products li.product {
  flex: 0 0 calc((100% - (var(--et-slider-desktop, 4) - 1) * 20px) / var(--et-slider-desktop, 4));
  scroll-snap-align: start;
  min-width: 0;
}

/* strzałki — gołe groty w bocznych marginesach, poza kartami */
.et-slider-wrap { padding: 0 44px; }
.et-slider-controls { display: contents; }
.et-slider-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px; height: 56px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none;
  border: none;
  padding: 0;
  /* Jaśniejsze niż `--fg-muted` - audyt: „strzałki karuzeli są szare na
     czerni, prawie niewidoczne". Na pulpicie karuzeli już nie ma (siatka
     niżej), więc dotyczy to zakresu tabletowego, gdzie strzałki zostają
     i są jedyną wskazówką, że karty jadą dalej. */
  color: var(--color-bone-2);
  cursor: pointer;
  transition: color .2s var(--ease), opacity .2s var(--ease), transform .2s var(--ease);
}
.et-slider-nav.prev { left: 0; }
.et-slider-nav.next { right: 0; }
.et-slider-nav svg { width: 30px; height: 30px; }
/* Strzałki stoją na tabletach (561-860 px), czyli też pod palcem - tam
   pomarańczowa strzałka zostawała po dotknięciu (przyklejony `:hover`). */
@media (hover: hover) and (pointer: fine) {
  .et-slider-nav:hover:not([disabled]) { color: var(--color-brand-orange); }
  .et-slider-nav.prev:hover:not([disabled]) { transform: translateY(-50%) translateX(-3px); }
  .et-slider-nav.next:hover:not([disabled]) { transform: translateY(-50%) translateX(3px); }
}
.et-slider-nav[disabled] { opacity: .25; cursor: default; }

/* =========================================================================
   NA PULPICIE TO MA BYĆ SIATKA, NIE KARUZELA - audyt pulpitu (2026-08-13):
   „9 produktów, widać 4 - na desktopie karuzela UKRYWA OFERTĘ. Grid 4x2
   sprzeda lepiej; karuzelę zostaw mobilce".

   Karuzela rozwiązuje problem WĄSKIEGO ekranu: gdy w rzędzie mieszczą się
   dwie karty, dziewięć kart to pięć rzędów przewijania w pionie i przesuwanie
   palcem jest szybsze. Na ekranie, gdzie w rzędzie stoją cztery, ten problem
   nie istnieje - zostaje sam koszt: pięć produktów schowanych za gestem,
   którego na myszy nikt nie wykonuje.

   `flex-wrap` zamiast przepisywania na `grid`: pola mają już policzoną
   szerokość przez `flex-basis` z ustawieniem z Personalizacji, więc zawijanie
   układa je w równe rzędy bez ruszania czegokolwiek innego. Strzałki
   i przewijanie w poziomie schodzą razem - nie ma czego przewijać.
   ========================================================================= */
/* JEDEN WIERSZ NA KAŻDEJ SZEROKOŚCI - wariant slidera dla sekcji, które mają
   zostać wierszem także na komputerze („Nowe w sklepie" w pustym koszyku).

   Reguła niżej zamienia slider w zawijaną siatkę od 861 px, bo na stronie
   głównej karuzela na dużym ekranie ukrywa ofertę. Tutaj jest odwrotnie:
   to sekcja poboczna, która ma zajmować jeden wiersz i nie rozpychać strony
   - i tak prosił właściciel wprost. Klasa na opakowaniu przebija tamtą
   regułę wyższą specyficznością. */
.et-slider-wiersz .et-slider {
  overflow-x: auto !important;
  scroll-snap-type: x mandatory;
  padding-bottom: 10px;
}
.et-slider-wiersz .et-slider ul.products { flex-wrap: nowrap !important; }
.et-slider-wiersz .et-slider-controls { display: none; }
/* Tytuły zawijają się zamiast być ucinane.

   Kafelki w sklepie trzymają nazwę w JEDNEJ linii, a `egotape.js` dobiera
   do niej wielkość pisma i dopiero przy nazwach za długich schodzi na dwa
   wiersze (klasa `et-tytul-lamany`). Tutaj tego dopasowania nie ma: sekcja
   powstaje przez podmianę wyniku bloku, a skrypt zdążył już policzyć swoje.
   Efekt bez tej reguły: „RODZANICE - MIKS K" ucięte przez `overflow`.

   Zamiast uczyć skrypt nowego miejsca - stała zgoda na dwa wiersze. To ta
   sama decyzja, którą on sam podejmuje w zejściu awaryjnym, i tu jest
   zawsze słuszna: karta ma na nią miejsce, a ucięta nazwa produktu nie ma
   żadnego usprawiedliwienia. */
.et-slider-wiersz .woocommerce-loop-product__title {
  white-space: normal !important;
}
/* Pudełko, w które `egotape.js` opakowuje treść tytułu, też musi wrócić do
   tekstu w linii - `inline-block` nie zawija się razem z rodzicem. Bez tej
   drugiej linijki pierwsza nie daje nic. */
.et-slider-wiersz .woocommerce-loop-product__title .et-tytul-fit {
  display: inline !important;
}
/* Zawijanie nie ratuje nazwy, gdy za szeroki jest SAM WYRAZ: na 320 px karta
   zostawia na nazwę 91 px, a „BURSZTYNOWY" przy 15 px ma 99 px - `overflow`
   ucinał końcówkę (2026-09-26). Dopasowania z `egotape.js` tu nie ma (wyżej),
   więc w wąskiej karcie pismo schodzi do 13 px (86 px). Próg: wnętrze karty
   124 px - 24 px wcięć = 100 px na wyraz. `.woocommerce` w selektorze, bo
   pismo 15 px na telefonie ustawia reguła o czterech klasach niżej w pliku. */
@container et-karta (max-width: 123.9px) {
  .et-slider-wiersz .woocommerce ul.products li.product .woocommerce-loop-product__title { font-size: 13px; }
}

@media (min-width: 861px) {
  .et-slider {
    overflow-x: visible;
    scroll-snap-type: none;
    padding-bottom: 0;
  }
  .et-slider .woocommerce ul.products,
  .et-slider ul.products {
    flex-wrap: wrap;
    row-gap: 24px;
  }
  .et-slider-wrap { padding: 0; }
  .et-slider-controls { display: none; }
}

@media (max-width: 1100px) {
  .et-slider ul.products li.product {
    flex-basis: calc((100% - 2 * 20px) / 3);
  }
}
@media (max-width: 860px) {
  .et-slider ul.products li.product {
    flex-basis: calc((100% - 20px) / 2);
  }
}
@media (max-width: 560px) {
  /* WYSTAJĄCY KAWAŁEK NASTĘPNEJ KARTY - to jest cała afordancja.

     Zgłoszenie z przeglądu mobilnego (2026-08-13): „karuzela produktów bez
     afordancji, cienki scrollbar prawie niewidoczny".

     Rzecz w tym, że karty mieściły się CO DO PIKSELA: dwie w rzędzie, równo
     do obu krawędzi. Taki układ nie różni się niczym od zwykłej siatki, więc
     nie ma powodu próbować go przesunąć - a strzałki na dotyku są ukryte
     (słusznie, palec ich nie potrzebuje).

     Ułamek karty wystający za krawędź mówi „jest tego więcej" bez jednego
     słowa i bez jednej ikony. Nic tak nie działa, bo nic innego nie jest
     widoczne w chwili, w której człowiek decyduje, czy przewijać.

     0,28 karty, nie 0,5: połowa wygląda jak zepsuty układ, a ćwierć jak
     zapowiedź. Dzielnik idzie przez `calc()` razem z ustawieniem
     z Personalizacji, więc właściciel dalej decyduje, ile kart ma być
     widocznych - podejrzenie dokłada się do jego liczby, a nie zamiast. */
  /* =====================================================================
     LICZBA KART ZNOWU Z PERSONALIZACJI - i to jest naprawa mojego błędu.

     Zgłoszenie właściciela: „karta jest za duża, powinno być widać dwa
     produkty, teraz widać jeden i tak jest rozciągnięty na pół ekranu".

     Co się stało: dokładając podgląd następnej karty (po uwadze, że jest za
     wąski i ucina tytuł w pół słowa) wpisałem szerokość karty na sztywno -
     `flex-basis: 90%`. Ustawienie „widocznych kart na telefonie" przestało
     wtedy cokolwiek robić, a widoczny produkt zrobił się jeden. Poprawiałem
     podgląd, a zmieniłem liczbę kart; to są dwie różne decyzje i od teraz
     mają dwa różne pola w Personalizacji.

     Wzór: karta = (kolumna - przerwy) / (liczba kart + podgląd). Podgląd
     jest UŁAMKIEM KARTY, więc przy dwóch kartach i 12% wystaje ~18 px -
     tyle, ile trzeba, żeby było widać, że lista jedzie dalej.

     Przy dwóch kartach na telefonie taki podgląd musi być wąski i to jest
     arytmetyka, nie wybór: dwa produkty w całości plus szeroki podgląd nie
     mieszczą się na ekranie 390 px. Dlatego krawędź była WYGASZANA maską -
     wąskie ucięcie z ostrą krawędzią czyta się jak usterka. Od 2026-09-26
     tor dochodzi do krawędzi ekranu i maski nie ma (niżej); wzór liczy się
     od tamtej pory do krawędzi ekranu, nie do marginesu.
     ===================================================================== */
  /* =====================================================================
     SUWAK DOCHODZI DO KRAWĘDZI EKRANU (2026-09-26, zgłoszenie #7).

     Tor kończył się na marginesie strony, 28 px od brzegu szkła. Po
     przesunięciu palcem karta była więc ucinana pionową linią w powietrzu -
     na zrzucie z iPhone'a skrawek karty wisiał przy x = 28 px, a z prawej
     podgląd następnej karty urywał się tak samo (stąd wcześniej maska
     wygaszająca prawy brzeg).

     Teraz pojemnik przewijania wychodzi na margines strony po obu stronach
     (ujemny margines), a pierwsza karta nadal startuje w linii tekstu (lewe
     wypełnienie i `scroll-padding` - tam też zatrzymuje się każda dojechana
     karta). Karty wjeżdżają pod krawędź ekranu, tak jak pigułki kategorii
     w sklepie (`nav.et-cat-chips` - ten sam zabieg, ta sama zmienna).
     Ucięcie na krawędzi ekranu czyta się jako „ciąg dalszy", ucięcie
     w połowie ekranu - jako usterka. Maska nie ma już czego ratować, więc
     schodzi. Na tablecie (561-860 px) zostają strzałki w bocznych
     marginesach, a tam tor musi się kończyć przed nimi - dlatego tylko tu.

     Szerokość karty liczona od lewej linii tekstu do prawej krawędzi ekranu
     (`100%` = kolumna treści + prawy margines): N kart, N przerw i podgląd.
     Podgląd jest dokładnie tym ułamkiem karty, który stoi w Personalizacji
     (25% = 37 px przy 393 px), a nie o przerwę (14 px) mniejszym. Karty są
     przy tym o 6 px szersze (393 px: 144 -> 150, 320 px: 111 -> 117). */
  .et-slider {
    margin-inline: calc(var(--et-gutter, 24px) * -1);
    padding-left: var(--et-gutter, 24px);
  }
  .et-slider ul.products li.product {
    flex-basis: calc(
      (100% - var(--et-slider-mobile, 2) * 14px)
      / (var(--et-slider-mobile, 2) + var(--et-slider-peek, 12) / 100)
    );
    scroll-snap-align: start;
  }
  /* Odstęp za ostatnią kartą to ELEMENT listy, nie prawe wypełnienie
     pojemnika: tor jest blokiem, a karty wystają z jego dziecka, więc
     wypełnienie za nimi nie wchodzi do przewijanego obszaru. Zmierzone
     (WebKit i Chromium): z wypełnieniem ostatnia karta dojeżdżała do
     392,6 px przy ekranie 393, z elementem staje na 365, w linii tekstu.
     Przerwa listy (14 px) liczy się też przed tym elementem. */
  .et-slider ul.products::after,
  .et-slider .woocommerce ul.products::after {
    content: "";
    display: block;
    flex: 0 0 max(0px, calc(var(--et-gutter, 24px) - 14px));
  }
  /* =======================================================================
     „PODOBNE PRODUKTY" I „MOŻE SPODOBA SIĘ RÓWNIEŻ" - JEDEN WIERSZ,
     PRZESUWANY PALCEM.

     Zgłoszenie właściciela (2026-08-13): „sekcja podobne produkty na
     mobilce musi być w jednym wierszu i przesuwane w prawo/lewo (te sekcje
     są w karcie każdego z produktów)".

     Obie sekcje to `ul.products`, czyli ta sama siatka co w sklepie -
     na telefonie schodziła do dwóch kolumn i przy trzech produktach dawała
     wiersz pełny i wiersz z jedną kartą oraz dziurą obok. Na dole karty
     produktu, gdzie człowiek już podjął decyzję, taka sekcja zajmuje ekran
     i nie zachęca do niczego.

     Wiersz przesuwany palcem mieści dowolną liczbę propozycji na stałej
     wysokości i pokazuje, że jest ich więcej, tym samym podglądem
     i wyjściem do krawędzi ekranu, co karuzela na stronie głównej. Ustawienia
     z Personalizacji („widocznych kart", „podgląd") działają tu tak samo,
     bo liczy się tym samym wzorem - jedno zachowanie w całym sklepie.

     `!important` przy `display`: reguła bazowa `ul.products` ma
     `display: grid !important` (potrzebne, żeby przebić własne style
     WooCommerce), więc bez tego wiersz nigdy by nie powstał.
     ======================================================================= */
  .woocommerce .related.products ul.products,
  .woocommerce .upsells.products ul.products,
  .related.products ul.products,
  .upsells.products ul.products {
    display: flex !important;
    grid-template-columns: none !important;
    flex-wrap: nowrap;
    gap: 14px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--color-bone-3) transparent;
    /* Do krawędzi ekranu, jak suwak na stronie głównej (powód wyżej, przy
       „SUWAK DOCHODZI DO KRAWĘDZI EKRANU"). Wygaszanie prawego brzegu
       zeszło razem z ucięciem, które maskowało. Na zrzucie #7 lista kończyła
       się 28 px przed krawędzią i karta przesunięta w lewo urywała się tam
       pionową linią. */
    margin-inline: calc(var(--et-gutter, 24px) * -1);
    padding: 0 0 10px var(--et-gutter, 24px);
    scroll-padding-left: var(--et-gutter, 24px);
  }
  .woocommerce .related.products ul.products li.product,
  .woocommerce .upsells.products ul.products li.product,
  .related.products ul.products li.product,
  .upsells.products ul.products li.product {
    flex: 0 0 calc(
      (100% - var(--et-slider-mobile, 2) * 14px)
      / (var(--et-slider-mobile, 2) + var(--et-slider-peek, 12) / 100)
    );
    min-width: 0;
    scroll-snap-align: start;
  }
  /* Odstęp za ostatnią kartą - ten sam element co w suwaku strony głównej.
     Tu lista sama jest torem i nowe silniki wliczyłyby prawe wypełnienie,
     ale element działa wszędzie tak samo, także w starszym Safari. */
  .woocommerce .related.products ul.products::after,
  .woocommerce .upsells.products ul.products::after {
    content: "";
    display: block;
    flex: 0 0 max(0px, calc(var(--et-gutter, 24px) - 14px));
  }

  /* Karta zatrzymuje się równo z linią tekstu strony, a nie przy krawędzi
     szkła - tor wychodzi na margines (wyżej), więc odstęp dojechanej karty
     od brzegu to właśnie margines strony. */
  .et-slider { scroll-padding-left: var(--et-gutter, 24px); }
  .et-slider .woocommerce ul.products,
  .et-slider ul.products { gap: 14px; }
  .et-slider-controls { display: none; } /* na dotyku wystarczy przesuwanie palcem */
  .et-slider-wrap { padding: 0; }

  /* Pasek przewijania: grubszy i jaśniejszy, ale NADAL nie pomarańczowy -
     patrz reguła jednej iskry przy kartach produktu. Pasek jest wskazówką,
     a nie akcją, więc nie ma prawa konkurować kolorem z ceną nad nim. */
  .et-slider { scrollbar-color: var(--color-bone-3) transparent; }
  .et-slider::-webkit-scrollbar { height: 4px; }
  .et-slider::-webkit-scrollbar-thumb { background: var(--color-bone-3); }
}


/* --- Moduł banerów ----------------------------------------------------------- */
.et-banners { padding: var(--et-space-sm) 0 calc(var(--et-space-sm) * .25); }
.et-banners-viewport { position: relative; }
.et-banners-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-3);
  scrollbar-width: none;
}
.et-banners-track::-webkit-scrollbar { display: none; }
.et-banner-slide { flex: 0 0 100%; scroll-snap-align: center; }
.et-banner-inner { display: block; }
.et-banner-inner img {
  display: block;
  width: 100%; height: auto;
  border-radius: var(--radius-3);
}
a.et-banner-inner { transition: opacity .2s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  a.et-banner-inner:hover { opacity: .93; }
}

.et-banners-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 64px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(90deg, rgba(11,11,11,.55), rgba(11,11,11,0));
  border: none; padding: 0;
  color: #fff;
  cursor: pointer;
  opacity: .75;
  transition: opacity .2s var(--ease), color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-banners-nav:hover { opacity: 1; color: var(--color-brand-orange); }
}
.et-banners-nav.prev { left: 0; border-radius: var(--radius-3) 0 0 var(--radius-3); }
.et-banners-nav.next { right: 0; background: linear-gradient(270deg, rgba(11,11,11,.55), rgba(11,11,11,0)); border-radius: 0 var(--radius-3) var(--radius-3) 0; }

.et-banners-dots { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 14px; }
.et-dot {
  width: 26px; height: 3px;
  background: var(--color-ink-5);
  border: none; padding: 0;
  cursor: pointer;
  transition: background .25s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-dot:hover { background: var(--color-bone-3); }
}
.et-dot.is-active { background: var(--color-brand-orange); }
.et-banners-pause {
  margin-left: 8px;
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 0;
  color: var(--fg-faint); cursor: pointer;
  transition: color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-banners-pause:hover { color: var(--color-brand-orange); }
}

@media (max-width: 640px) {
  .et-banners-nav { display: none; }
}


/* --- Pasek metod płatności --------------------------------------------------- */
.et-payments {
  margin-top: 48px;
  padding-top: 28px;
  border-top: 1px solid var(--border-default);
  text-align: center;
}
.et-payments-title {
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 16px;
}
.et-payments img {
  display: inline-block;
  width: 100%;
  max-width: var(--et-payments-width, 720px);
  height: auto;
}
/* jasna podkładka — dla grafik z ciemnymi napisami na przezroczystym tle */
.et-payments.has-plate .et-payments-plate {
  display: inline-block;
  background: #FFFFFF;
  border-radius: var(--radius-3);
  padding: 18px 22px;
  max-width: 100%;
}
.et-payments-note {
  font-size: 12px;
  color: var(--fg-faint);
  margin: 14px 0 0;
}
@media (max-width: 640px) {
  .et-payments.has-plate .et-payments-plate { padding: 12px 14px; }
}


/* Linia z danymi firmy w stopce (wymóg operatora płatności) */
.footer-legal {
  margin: 28px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--border-default);
  text-align: center;
  font-size: 13px;
  color: var(--fg-muted);
}
.et-payments + .footer-bottom { margin-top: 0; }


/* Przyciski w treści stron/wpisów — kolor tekstu nie może przegrać z regułą linków */
.entry-content a.btn,
.entry-content a.button,
.woocommerce .entry-content a.button,
a.btn,
a.btn:hover,
a.btn:focus,
a.btn:visited {
  color: var(--color-ink-1);
  text-decoration: none;
}
.entry-content a.btn.btn-secondary,
a.btn.btn-secondary,
a.btn.btn-secondary:visited { color: var(--color-bone-1); }
@media (hover: hover) and (pointer: fine) {
  .entry-content a.btn.btn-secondary:hover,
  a.btn.btn-secondary:hover { color: var(--color-brand-orange); }
}

/* =========================================================================
   Blokowy koszyk i zamówienie (WooCommerce Blocks)
   ========================================================================= */

/* --- Układ: szersza kolumna podsumowania -------------------------------- */
.wp-block-woocommerce-checkout .wc-block-checkout__sidebar,
.wc-block-checkout__sidebar {
  flex: 0 0 auto;
  min-width: 340px;
  max-width: 420px;
}
/* Reset z tą samą wagą co reguła wyżej. Sam `.wc-block-checkout__sidebar`
   (0,1,0) przegrywał z `.wp-block-woocommerce-checkout .wc-block-checkout__sidebar`
   (0,2,0), więc podsumowanie miało zawsze co najmniej 340 px: na 320 px kasa
   wystawała 48 px poza ekran (formularz i przycisk „Kupuję i płacę" ucięte),
   na 375 - 21 px poza kolumnę treści, na 393 - 3 px (2026-09-26). */
@media (max-width: 1000px) {
  .wp-block-woocommerce-checkout .wc-block-checkout__sidebar,
  .wc-block-checkout__sidebar { min-width: 0; max-width: none; }
}

/* --- Panel podsumowania -------------------------------------------------- */
.wc-block-components-sidebar .wc-block-components-panel,
.wc-block-components-order-summary,
.wc-block-components-totals-wrapper,
.wc-block-components-sidebar {
  background: var(--bg-surface);
  border-radius: var(--radius-3);
}

.wc-block-components-checkout-order-summary__title,
.wc-block-components-checkout-order-summary__title-text {
  font-family: var(--font-display) !important;
  font-size: 24px !important;
  font-weight: 400 !important;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-bone-0) !important;
}

/* --- Pozycja zamówienia -------------------------------------------------- */
.wc-block-components-order-summary-item {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 14px;
  align-items: start;
  padding: 14px 0;
  border-bottom: 1px solid var(--border-default);
}
.wc-block-components-order-summary-item:last-child { border-bottom: none; }

.wc-block-components-order-summary-item__image {
  margin: 0;
  background: #fff;
  border-radius: var(--radius-3);
  /* szerokość nadpisywana niżej (finalnie 88px !important);
     overflow: visible (nie hidden) — plakietka z ilością sztuk
     (.wc-block-components-order-summary-item__quantity) celowo wystaje
     w połowie poza ten róg; overflow:hidden ją przycinał. */
}
.wc-block-components-order-summary-item__image img { width: 100%; height: auto; display: block; }

.wc-block-components-order-summary-item__description { margin: 0; }
/* Blocks daje opisowi `padding: 4px 12px 12px 24px` - dodatkowe 36 px obok
   odstępu siatki (16 px). Na 393 px nazwa dostawała 79 px ze 115 px kolumny
   i łamała się na trzy wiersze („WELES - / ZIELEŃ / MILITARNA"), 40 px od
   zdjęcia; na 320 px na cztery, z samym „-" w wierszu (2026-09-26). */
.wc-block-components-order-summary .wc-block-components-order-summary-item__description { padding-left: 0; padding-right: 0; }
.wc-block-components-order-summary-item__description .wc-block-components-product-name,
.wc-block-components-order-summary-item .wc-block-components-product-name {
  font-family: var(--font-heading) !important;
  font-size: 13px !important;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-bone-0) !important;
  hyphens: none;
  word-break: normal;
  overflow-wrap: normal;
}
/* opis produktu w podsumowaniu tylko zaśmieca — chowamy */
.wc-block-components-order-summary-item__description .wc-block-components-product-metadata__description { display: none; }
.wc-block-components-order-summary-item__total-price,
.wc-block-components-order-summary-item__individual-prices {
  font-family: var(--font-heading);
  font-size: 14px;
  color: var(--color-brand-orange);
  white-space: nowrap;
}
.wc-block-components-order-summary-item__quantity {
  background: var(--color-ink-4) !important;
  border: 1px solid var(--border-strong) !important;
  color: var(--fg-default) !important;
}
.wc-block-components-order-summary-item__quantity span {
  color: var(--fg-default) !important;
}
/* dodatki (pudełko, kolory rolek) czytelnie pod nazwą */
.wc-block-components-product-details {
  margin: 8px 0 0; padding: 0; list-style: none;
  font-size: 12px; color: var(--fg-muted);
}
.wc-block-components-product-details__name { color: var(--fg-muted); font-weight: 500; }

/* --- Sumy ---------------------------------------------------------------- */
.wc-block-components-totals-item {
  font-family: var(--font-body);
  color: var(--fg-default);
  /* padding nadpisywany niżej (12px 0 !important) */
}
.wc-block-components-totals-item__label { color: var(--fg-muted); }
.wc-block-components-totals-footer-item .wc-block-components-totals-item__label,
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
  font-family: var(--font-display);
  font-size: 22px;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--color-bone-0);
}
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value { color: var(--color-brand-orange); }
.wc-block-components-totals-footer-item__tax-value,
.wc-block-components-totals-item__description { color: var(--fg-faint); font-size: 12px; }
.wc-block-components-totals-wrapper { border-top: 1px solid var(--border-default) !important; }

/* --- Formularz ----------------------------------------------------------- */
.wc-block-components-text-input input,
.wc-block-components-textarea,
.wc-block-components-combobox-control input,
.wc-block-components-select__container select {
  background: var(--bg-input) !important;
  border: 1px solid var(--border-input) !important;
  border-radius: var(--radius-3) !important;
  color: var(--fg-default) !important;
}
.wc-block-components-text-input label,
.wc-block-components-combobox-control label,
.wc-block-components-select__label { color: var(--fg-muted) !important; }
.wc-block-components-text-input.is-active label { color: var(--color-brand-orange) !important; }

/* Pole kodu BLIK (wtyczka Przelewy24): etykieta NAD polem, nie w środku.
   Blok daje temu polu „pływającą" etykietę jak adresowi e-mail, ale P24
   ustawia `is-active` od razu, więc „Kod BLIK" siedziało w górnej części
   ramki, a wpisywany kod pod nim - pole wyglądało na rozjechane
   (zgłoszenie #2, 2026-09-06). Statyczna etykieta w stylu pozostałych
   podpisów sekcji i zwykłe wypełnienie pola. */
.p24-blik-code-input.wc-block-components-text-input { margin: 10px 0 16px; display: flex; flex-direction: column; } /* dół: checkbox regulaminu P24 stykał się z ramką */
.p24-blik-code-input.wc-block-components-text-input label { order: -1; } /* w DOM etykieta stoi ZA polem */
.p24-blik-code-input.wc-block-components-text-input label {
  position: static !important;
  transform: none !important;
  display: block;
  margin: 0 0 6px;
  padding: 0;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted) !important;
}
.p24-blik-code-input.wc-block-components-text-input input {
  padding: 12px 14px !important;
  min-height: 48px;
  font-size: 18px !important; letter-spacing: .12em; /* 6 cyfr, czytelnie */
}

/* oliwkowe tło od autouzupełniania przeglądarki */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
select:-webkit-autofill,
textarea:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--bg-input) inset !important;
  box-shadow: 0 0 0 1000px var(--bg-input) inset !important;
  -webkit-text-fill-color: var(--fg-default) !important;
  caret-color: var(--fg-default);
  border-radius: var(--radius-3);
}

/* --- Cele dotyku i pismo w koszyku/kasie (audyt D6/U9/U10/U11) -----------
   Blocks daje sterowaniu iloscia 25 px wysokosci, „usun" 24 px, a „Dodaj
   kupony"/„Zaloguj sie"/„Dodaj nr mieszkania" 18 px. Ikony i napisy zostaja
   te same - rosnie tylko pole, w ktore trafia palec. `!important`, bo arkusz
   Blocks wpisuje te wymiary selektorem o czterech klasach i nazwie znacznika. */
.wc-block-components-quantity-selector { min-height: 44px !important; }
.wc-block-components-quantity-selector .wc-block-components-quantity-selector__button { min-width: 44px !important; min-height: 44px !important; }
.wc-block-components-quantity-selector input.wc-block-components-quantity-selector__input { font-size: 16px !important; min-height: 44px !important; }
.wc-block-cart-item__remove-link,
table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity .wc-block-cart-item__remove-link {
  display: inline-flex !important; align-items: center; justify-content: center;
  width: 44px !important; height: 44px !important;
}
/* Pudełko ilości rośnie razem z przyciskami (zgłoszenie #5, 2026-09-26).
   Blocks trzyma je na sztywno na 107 px, a przyciski wyżej mają po 44 px:
   44 + 40 (pole) + 44 = 128 px w 105 px wnętrza, więc „+" stał na prawej
   ramce (22 px poza nią), nachodził 10 px na kosz, a „1" nie było na środku.
   Szerokość z treści: 44 + 36 (pole, mieści „100") + 44 + 2 = 126 px, cyfra
   dokładnie pośrodku.
   Znaki w kroju motywu (na iPhonie przycisk bez kroju dostaje systemowe
   pismo z arkusza przeglądarki), a czynny przycisk w pełnym kolorze -
   Blocks daje .6 i czynnemu, i wyłączonemu, więc „+" wyglądał jak „−" przy 1 szt. */
table.wc-block-cart-items .wc-block-components-quantity-selector { width: auto; flex: 0 0 auto; }
table.wc-block-cart-items .wc-block-components-quantity-selector .wc-block-components-quantity-selector__button {
  flex: 0 0 44px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-body); font-size: 20px; line-height: 1;
  opacity: 1;
}
table.wc-block-cart-items .wc-block-components-quantity-selector .wc-block-components-quantity-selector__button:disabled { opacity: .35; }
table.wc-block-cart-items .wc-block-components-quantity-selector input.wc-block-components-quantity-selector__input {
  flex: 0 0 36px; width: 36px; min-width: 0; padding: 0;
  font-family: var(--font-body);
}
/* Wiersz pozycji w kolumnie treści (zgłoszenie #5). Na telefonie Blocks
   robi z wiersza siatkę `80px 132px` + dwie kolumny „auto", a najszerszy
   nieprzełamywalny kawałek komórki produktu to rząd ilości: 16 (wcięcie
   Blocks, zostało po układzie tabelowym) + 107 + 12 + 44 (kosz) = 179 px.
   Wiersz rósł do 341 px przy 333 dostępnych - cena i kreska pod pozycją
   wystawały 8 px poza kolumnę treści, a na 320 px 81 px (cena poza ekranem).
   Teraz: miniatura 64 px (tyle miało samo zdjęcie, resztę 80 px zjadało
   wcięcie), tekst w `minmax(0, 1fr)`, który nie rozpycha wiersza, cena w „auto". */
.wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row {
  grid-template-columns: 64px minmax(0, 1fr) auto;
}
.wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__image { padding-right: 0; }
.wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__product { grid-column: 2; }
.wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__total { grid-column: 3; grid-row: 1; align-self: start; }
/* Rząd ilości: ilość z lewej, kosz na prawym brzegu, pod ceną - dotyk „+"
   i „usuń" dzieli wtedy kilkadziesiąt pikseli (10 px na 320), a nie stoją
   obok siebie. `wrap` to siatka bezpieczeństwa: gdy miejsca zabraknie, kosz
   schodzi niżej zamiast wychodzić za ramkę. `grid-row: auto`, bo Blocks
   stawia ten rząd w drugim wierszu siatki (tak było w starym układzie). */
.wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity {
  grid-column: auto; grid-row: auto;
  align-self: stretch;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  padding-right: 0;
}
/* Rząd ilości także pod ceną, nie tylko pod tekstem: komórka produktu
   obejmuje obie kolumny jako `subgrid` - nazwa, cena jednostkowa i opis
   zostają w pierwszej (obok ceny), rząd ilości bierze obie. Na 320 px to
   180 px zamiast 114 - mieści się 126 (ilość) + 8 + 44 (kosz). Cena leży w tej
   samej kolumnie, ale tylko na górze (`align-self: start`), a rząd ilości
   jest na wierzchu na wypadek wysokiej ceny (plakietka promocji). */
@supports (grid-template-columns: subgrid) {
  .wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__product {
    grid-column: 2 / 4;
    display: grid; grid-template-columns: subgrid;
  }
  .wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__wrap {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: subgrid;
    row-gap: 4px; justify-items: start; align-content: start;
  }
  .wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__wrap > * { grid-column: 1; }
  .wc-block-cart:is(.is-mobile, .is-small, .is-medium) table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__wrap > .wc-block-cart-item__quantity {
    grid-column: 1 / -1; justify-self: stretch;
    position: relative; z-index: 1;
  }
}
.wc-block-components-panel__button { min-height: 44px !important; display: flex; align-items: center; }
.wc-block-checkout__login-prompt { display: inline-flex !important; align-items: center; min-height: 44px; margin-top: -37px !important; }
.wc-block-components-address-form__address_2-toggle { display: inline-flex !important; align-items: center; min-height: 44px; margin-top: 0 !important; }
/* Przycisk placenia: 48 px jak `.primary` w aplikacji - to jedyny przycisk, ktory bierze pieniadze. */
.wc-block-components-checkout-place-order-button { min-height: 48px !important; }
/* Nazwa produktu w koszyku to samodzielny odnosnik w komorce (18 px wysokosci);
   ujemny margines trzyma uklad, rosnie tylko pole dotyku. */
.wc-block-components-product-name { display: inline-block; padding: 12px 0; margin: -12px 0; }
/* Opis pozycji (11,4 px) i „przez InPost Paczkomat" (10,5 px): dol skali to 12 px dla tekstu. */
.wc-block-components-product-details.wc-block-components-product-details,
.wc-block-components-totals-shipping__via { font-size: 12px !important; }
/* Krótki opis pod nazwą w koszyku to osobny element (`product-metadata__description`,
   11,375 px = 13 x .875) - reguła wyżej trafia tylko dodatki i opis został drobny.
   Waga jak w arkuszu Blocks, motyw ładuje się po nim - bez `!important`. */
.wc-block-components-product-metadata .wc-block-components-product-metadata__description > p { font-size: 12px; }

/* --- Nagłówki sekcji, komunikaty, kupony --------------------------------- */
.wc-block-components-title,
.wp-block-woocommerce-checkout-fields-block h2 {
  font-family: var(--font-display) !important;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-bone-0) !important;
}
.wc-block-components-notice-banner { border-radius: var(--radius-3); }
.wc-block-components-panel__button { color: var(--fg-default) !important; }
/* Otwarty panel „Dodaj kupony": nad polem 16 px (margines nagłówka panelu),
   pod nim 4 px do kreski „Kwota" - motyw ścisnął wnętrze sekcji podsumowania
   do `padding: 4px 0`. Ten sam oddech pod polem co nad nim. */
.wc-block-components-totals-coupon .wc-block-components-panel__content { padding-bottom: 12px; }
.wc-block-components-checkbox .wc-block-components-checkbox__input { accent-color: var(--color-brand-orange); }
.wc-block-components-checkbox__label { color: var(--fg-muted); }

/* --- Strona „Zamówienie otrzymane" ------------------------------------------ */

/* Blok sprawdzania płatności wtyczki Przelewy24 (`templates/thankyou-status-loader.php`).
   Wtyczka wpisuje mu jasne tło i ciemny tekst (obcy na naszym tle), a jej
   skrypt po potwierdzeniu płatności usuwa kółko i dopisuje „Płatność została
   potwierdzona", ale NIGDY nie chowa nagłówka „Weryfikujemy status płatności"
   ani linijki „Proszę czekać..." (zgłoszenie właściciela 2026-09-21,
   zamówienie 805: w logu serwer odpowiedział „paid" 3 s po wejściu, a klient
   dalej widział „Proszę czekać"). Kółko `.p24-loader` znika przy KAŻDYM
   zakończeniu (sukces i „nie otrzymano jeszcze"), więc jego brak jest
   sygnałem „koniec sprawdzania" - wtedy chowamy nagłówek i „czekać". */
body #p24-payment-status {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  color: var(--fg-default);
  font-size: 15px;
}
body #p24-payment-status h4 { margin: 0 0 8px; font-family: var(--font-heading); font-size: 16px; letter-spacing: .04em; text-transform: uppercase; color: var(--fg-default); }
body #p24-payment-status p { margin: 0 0 6px; color: var(--fg-muted); font-size: 14px; }
body #p24-payment-status .p24-loader { border-color: var(--border-default); border-top-color: var(--color-brand-orange); }
body #p24-payment-status:not(:has(.p24-loader)) h4,
body #p24-payment-status:not(:has(.p24-loader)) #p24-wait-msg { display: none; }
body #p24-payment-status:not(:has(.p24-loader)) { padding: 12px 16px; }
body #p24-payment-status #p24-status-message strong { color: var(--fg-default) !important; font-weight: 600; }
body #p24-payment-status:not(:has(.p24-loader)) #p24-status-message strong { color: var(--color-success) !important; }
body #p24-payment-status #p24-retry-btn { background: var(--color-brand-orange); color: var(--color-ink-1); border-radius: var(--radius-3); min-height: 44px; padding: 10px 18px; font-family: var(--font-heading); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }

/* Nowy szablon tego bloku (wtyczka 1.2: `.p24-payment-status__body`, `__badge`,
   `__title`...). Kółka `.p24-loader` już nie ma wcale, więc reguła
   `:not(:has(.p24-loader))` wyżej zawsze dokładała 12px 16px do wcięcia
   samego szablonu (18px 16px): ikona 33 px od lewej krawędzi ramki, 37 px
   pustego dołu pod ostatnią linijką (zgłoszenie #8, 2026-09-26). Zostaje jedno
   wcięcie - wtyczki. Kolory przez jej własne zmienne (jej CSS mówi wprost, że
   ciemny motyw ma nadpisać te zmienne): bez miętowych kółek na ciemnym tle. */
body #p24-payment-status:has(.p24-payment-status__body) {
  padding: 0;
  --p24-ps-surface: var(--bg-surface);
  --p24-ps-border: var(--border-default);
  --p24-ps-track: var(--color-ink-4);
  --p24-ps-title: var(--fg-default);
  --p24-ps-text: var(--fg-muted);
  --p24-ps-muted: var(--fg-muted);
  --p24-ps-accent: var(--color-brand-orange);
  --p24-ps-accent-soft: rgba(246, 149, 0, .14);
  --p24-ps-success: var(--color-success);
  --p24-ps-success-soft: rgba(76, 174, 107, .16);
  --p24-ps-warning: var(--color-brand-orange);
  --p24-ps-warning-soft: rgba(246, 149, 0, .14);
  --p24-ps-danger: var(--color-danger);
  --p24-ps-danger-soft: rgba(255, 122, 110, .14);
}
/* Reguła `p` wyżej (margines pod spodem, 14 px, szary) dotyka też tytułu:
   „Płatność została potwierdzona" wyglądała jak kolejna linijka opisu.
   Odstępy nad akapitami (jak w szablonie), żaden pod ostatnim. */
body #p24-payment-status .p24-payment-status__content p { margin: 6px 0 0; }
body #p24-payment-status .p24-payment-status__title { margin-top: 0; font-size: 16px; color: var(--fg-default); }
body #p24-payment-status .p24-payment-status__badge { font-size: 12px; } /* szablon: .68rem = 10,9 px */
/* „Zapłać ponownie" (stan „nie opłacono"): wtyczka daje biały napis na
   kolorze akcentu - na pomarańczu 2,3:1. Ciemny napis jak na przycisku wyżej. */
body #p24-payment-status .p24-payment-status__pay { background: var(--color-brand-orange); border-color: var(--color-brand-orange); color: var(--color-ink-1); border-radius: var(--radius-3); min-height: 44px; padding: 12px 18px; font-family: var(--font-heading); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }

/* Wybrany paczkomat w szczegółach zamówienia: wtyczka InPost wpisuje na sztywno
   miętowe tło `#aaf8de` (`show_parcel_machine_in_order_details`), na którym nasz
   biały tekst był niewidoczny („POP-WAW577 nic nie widać", 2026-09-21).
   `!important`, bo to styl w atrybucie. */
.ep-chosen-parcel-machine {
  background: var(--bg-input) !important;
  color: var(--fg-default) !important;
  border: 1px solid var(--color-brand-orange);
  border-radius: var(--radius-3) !important;
  padding: 4px 10px !important;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .06em;
  display: inline-block;
  margin: 4px 0;
}

/* Reszta tej strony to klasyczny szablon WooCommerce (`checkout/thankyou.php`,
   `order/order-details*.php`) z jego pulpitowym arkuszem. Wszystko zawężone do
   `.woocommerce-order-received` (klasa `body` tej strony) - adresy są też
   w Moim koncie przy „Zobacz zamówienie", a tam rządzą reguły `.et-account`.
   Tabela „Szczegóły zamówienia" ma jeden komplet reguł dla obu stron - przy
   Moim koncie, nie tutaj.

   Przegląd zamówienia (numer, data, e-mail, kwota, płatność) - zgłoszenie #8.
   WooCommerce układa go w poziomy pasek: `li` z `float: left` i przerywaną
   kreską `#cfc8d8` z prawej. Na telefonie pozycje spadały jedna pod drugą,
   a kreska każdej stała tam, gdzie kończył się jej tekst - pionowe kreski
   w losowych miejscach (zmierzone na 393 px: x = 215, 190, 305, 156); lista
   wcięta o 40 px (domyślne wcięcie listy), etykiety 11,4 px. Teraz karta
   (tło i ramka jak w podsumowaniu koszyka): na telefonie wiersze „etykieta -
   wartość" jak sumy w koszyku, szerzej komórki w jednym rzędzie. */
.woocommerce-order-received .woocommerce ul.woocommerce-order-overview {
  display: flex; flex-wrap: wrap; gap: 16px 20px;
  margin: 0 0 40px; padding: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.woocommerce-order-received .woocommerce ul.woocommerce-order-overview::before,
.woocommerce-order-received .woocommerce ul.woocommerce-order-overview::after { content: none; }
.woocommerce-order-received .woocommerce ul.woocommerce-order-overview li {
  flex: 1 1 120px; max-width: 100%; /* bez `min-width: 0`: długi e-mail ma zejść do własnego rzędu, nie łamać się w połowie komórki */
  float: none; margin: 0; padding: 0; border: 0;
  font-family: var(--font-heading); font-size: 12px; line-height: 1.3;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-muted);
}
.woocommerce-order-received .woocommerce ul.woocommerce-order-overview li strong {
  display: block; margin-top: 4px;
  font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.4;
  letter-spacing: 0; text-transform: none; color: var(--fg-default);
  overflow-wrap: break-word;
}
/* Na telefonie komórki po dwie w rzędzie mają ~140 px, a e-mail i „Przelewy24 -
   PKO BP" (156 px) są dłuższe - łamały się w środku albo od „- PKO BP".
   Wiersz: etykieta z lewej, wartość z prawej; za długa wartość schodzi pod
   etykietę (nadal do prawej), zamiast łamać się w połowie. */
@media (max-width: 600px) {
  .woocommerce-order-received .woocommerce ul.woocommerce-order-overview { display: block; padding: 4px 16px; }
  .woocommerce-order-received .woocommerce ul.woocommerce-order-overview li {
    display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; column-gap: 12px;
    padding: 12px 0;
    border-top: 1px solid var(--border-default);
  }
  .woocommerce-order-received .woocommerce ul.woocommerce-order-overview li:first-child { border-top: 0; }
  .woocommerce-order-received .woocommerce ul.woocommerce-order-overview li strong { margin: 0 0 0 auto; text-align: right; overflow-wrap: anywhere; }
}

/* Adresy pod tabelą. WooCommerce zeruje odstępy w tej sekcji
   (`:last-child { margin-bottom: 0 }`, tytuł bez `margin-top`), więc gdy na
   telefonie kolumny stają jedna pod drugą, „Adres do wysyłki" stał 0 px pod
   ramką adresu rozliczeniowego. Ramka WooCommerce (czarne 10%, prawy i dolny
   bok po 2 px) była na ciemnym tle ledwo widocznym, krzywym prostokątem -
   karta jak przegląd zamówienia wyżej. */
.woocommerce-order-received .woocommerce-customer-details address {
  padding: 14px 16px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  line-height: 1.6;
}
@media (max-width: 768px) {
  .woocommerce-order-received .woocommerce-customer-details .col2-set .col-2 { margin-top: 28px; }
}

/* --- Checkout: układ dwukolumnowy + kolejność na mobile ------------------- */
@media (min-width: 900px) {
  .wc-block-checkout__form,
  .wp-block-woocommerce-checkout .wc-block-components-main + .wc-block-components-sidebar,
  .wc-block-checkout {
    align-items: flex-start;
  }
  .wc-block-checkout__main { flex: 1 1 auto; min-width: 0; }
  .wc-block-checkout__sidebar {
    flex: 0 0 360px;
    min-width: 340px;
    max-width: 420px;
    position: sticky;      /* podsumowanie jedzie razem z przewijaniem */
    top: 96px;
  }
}

@media (max-width: 899px) {
  /* podsumowanie NAD formularzem — klient widzi zamówienie od razu */
  .wc-block-checkout__sidebar { order: -1; margin-bottom: 24px; }
  .wc-block-checkout__main { order: 1; }
  .wc-block-checkout,
  .wc-block-checkout__form { display: flex; flex-direction: column; }
}

/* =========================================================================
   Checkout — korekta: jedno rozwinięte podsumowanie, układ 2-kolumnowy
   ========================================================================= */

/* 1) Duplikat podsumowania wewnątrz kolumny formularza — ukryty */
.wc-block-checkout__main .wc-block-components-checkout-order-summary,
.wc-block-checkout__main .wc-block-components-order-summary,
.wc-block-checkout__form .wc-block-components-checkout-order-summary {
  display: none !important;
}

/* 2) Podsumowanie w kolumnie bocznej zawsze rozwinięte (bez zwijania) */
.wc-block-checkout__sidebar .wc-block-components-panel__content,
.wc-block-components-checkout-order-summary .wc-block-components-panel__content,
.wc-block-components-checkout-order-summary__content {
  display: block !important;
  height: auto !important;
  overflow: visible !important;
  opacity: 1 !important;
}
.wc-block-checkout__sidebar .wc-block-components-panel__button > svg,
.wc-block-components-checkout-order-summary__title-text + svg,
.wc-block-components-checkout-order-summary .wc-block-components-panel__button svg {
  display: none !important;   /* strzałka zwijania — zbędna */
}
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary .wc-block-components-panel__button {
  pointer-events: none;
  cursor: default;
  width: 100%;
  text-align: left;
}

/* 3) Układ dwukolumnowy — wymuszony niezależnie od klas Blocks */
@media (min-width: 900px) {
  .wp-block-woocommerce-checkout,
  .wc-block-checkout {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: flex-start;
    gap: 40px;
  }
  .wc-block-checkout__main,
  .wc-block-checkout__form { flex: 1 1 auto !important; min-width: 0; width: auto !important; }
  /* flex/width/max-width tu były (380px), ale niżej jest nowsza wersja
     (360px !important) — usunięte jako martwe, zostało tylko to, czego
     nic dalej nie nadpisuje */
  .wc-block-checkout__sidebar { order: 2; }
}
@media (max-width: 899px) {
  .wp-block-woocommerce-checkout,
  .wc-block-checkout { display: flex !important; flex-direction: column !important; }
  /* `!important` na marginesie, bo arkusz WooCommerce zerował go na telefonie
     i „Dane kontaktowe" siedziało tuż pod ramką podsumowania (zgłoszenie #1,
     2026-09-06: zmierzone 0 px marginesu, 20 px samego wypełnienia). */
  .wc-block-checkout__sidebar { order: -1 !important; width: 100% !important; max-width: none !important; }
  /* Selektor z dwiema klasami, bo niżej w tym pliku jest
     `.wc-block-components-sidebar { margin: 0 !important }` (ten sam element). */
  .wp-block-woocommerce-checkout .wc-block-checkout__sidebar.wc-block-components-sidebar { margin-bottom: 36px !important; }
  .wc-block-checkout__main { order: 1 !important; }
}

/* 4) Zdjęcie produktu — całe widoczne, nie przycięte
   (width/height/padding i grid-template-columns nadpisywane dalej niżej —
   zostawione tu tylko właściwości, które nic dalej już nie nadpisuje) */
.wc-block-components-order-summary-item__image {
  background: #fff;
  border-radius: var(--radius-3);
  display: flex; align-items: center; justify-content: center;
  overflow: visible;
}
.wc-block-components-order-summary-item__image img,
.wc-block-components-order-summary-item__image .wc-block-components-order-summary-item__image-wrapper img {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  border-radius: 0;
}

/* --- Podsumowanie: większe zdjęcie i oddech przy krawędziach --------------
   (zdjęcie/grid pozycji/padding sidebaru/totals-item/total-price były tu
   też kiedyś nadpisywane, ale dalsze bloki i tak je bezwarunkowo nadpisują
   jeszcze raz — usunięte jako martwe, zostało tylko to, co realnie wygrywa) */
.wc-block-components-product-details { margin-top: 10px; line-height: 1.55; }

/* --- Checkout: oddech w panelu podsumowania + większe zdjęcie -------------
   (padding sidebaru z tego bloku usunięty jako martwy — jest jeszcze
   nowsza, bezwarunkowa wersja niżej w „Podsumowania — przebudowa") */
.wc-block-components-order-summary-item {
  grid-template-columns: 88px 1fr auto !important;
  gap: 16px !important;
  padding: 18px 0 !important;
}
.wc-block-components-order-summary-item__image {
  width: 88px !important;
  height: 88px !important;
  padding: 8px !important;
}
.wc-block-components-order-summary-item__total-price {
  padding-left: 8px;
}
/* wiersze sum — równy oddech od krawędzi */
.wc-block-components-totals-item { padding: 12px 0 !important; }
.wc-block-components-totals-footer-item { padding: 16px 0 !important; }

/* --- Checkout: szerokość kolumn i podwójna ramka podsumowania ------------- */
.wp-block-woocommerce-checkout,
.wc-block-checkout {
  width: 100%;
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
}
.wc-block-checkout__main,
.wc-block-checkout__form {
  flex: 1 1 auto !important;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
}
@media (min-width: 900px) {
  .wc-block-checkout__sidebar { flex: 0 0 360px !important; width: 360px !important; max-width: 360px !important; }
}

/* jedna ramka zamiast dwóch — wewnętrzny panel bez tła i obramowania */
.wc-block-checkout__sidebar .wc-block-components-order-summary,
.wc-block-checkout__sidebar .wc-block-components-panel,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary,
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper > .wc-block-components-panel {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* pozycje i sumy nie dotykają krawędzi panelu */
.wc-block-checkout__sidebar .wc-block-components-order-summary-item,
.wc-block-checkout__sidebar .wc-block-components-totals-item,
.wc-block-checkout__sidebar .wc-block-components-panel__button,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary__title {
  padding-left: 4px !important;
  padding-right: 4px !important;
}

/* --- Koszyk: przycisk „Przejdź do płatności” w jednej linii --------------- */
.wc-block-cart__submit-button,
.wp-block-woocommerce-cart .wc-block-cart__submit-button,
a.wc-block-cart__submit-button {
  font-size: 13px !important;
  letter-spacing: .06em !important;
  line-height: 1.2 !important;
  padding: 14px 18px !important;
  white-space: nowrap;
  min-height: 0 !important;
}
@media (max-width: 400px) {
  .wc-block-cart__submit-button { white-space: normal; font-size: 12px !important; }
}
/* Pasek z tym przyciskiem przyklejony do dołu ekranu (telefon; widać na zrzucie #5).
   Tło bierze ze strony sam skrypt Blocks (styl w atrybucie), ale poświatę nad
   paskiem (`::before`, `0 -10px 20px 10px`) rysuje kolorem hsla(0,0%,80%,.3)
   pisanym pod jasny motyw - na #0B0B0B to jasnoszara mgła na ~30 px nad
   paskiem, przez którą prześwitywały karty „Zobacz inne...". Ciemny cień
   wygasza treść pod spodem, a linia wyznacza krawędź paska. */
.wc-block-cart .wc-block-cart__submit-container--sticky { border-top: 1px solid var(--border-default); }
.wc-block-cart .wc-block-cart__submit-container--sticky::before { color: rgba(0, 0, 0, .7); }

/* =========================================================================
   Checkout / koszyk — pełna szerokość strony + jedna ramka podsumowania
   ========================================================================= */

/* 1) Strony koszyka i zamówienia nie są tekstem — nie ograniczaj ich do 760px */
.woocommerce-checkout .entry,
.woocommerce-cart .entry,
.woocommerce-checkout .entry-content,
.woocommerce-cart .entry-content {
  max-width: none !important;
  width: 100%;
  margin: 0 !important;
}
.woocommerce-checkout .entry-title,
.woocommerce-cart .entry-title { text-align: left; }

/* 2) Ramka i tło TYLKO na zewnętrznym kontenerze
   (własna reguła .wc-block-checkout__sidebar z tłem/ramką/paddingiem była
   tu wcześniej, ale niżej w „Podsumowania — przebudowa" jest identyczna
   albo nowsza wersja każdej właściwości — usunięta jako martwa) */
.wc-block-components-sidebar,
.wc-block-checkout__sidebar .wc-block-components-sidebar {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
}
/* wewnętrzne bloki bez własnych marginesów bocznych */
.wc-block-checkout__sidebar .wc-block-components-order-summary-item,
.wc-block-checkout__sidebar .wc-block-components-totals-item,
.wc-block-checkout__sidebar .wc-block-components-panel__button,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary__title,
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

/* zeruj ujemne marginesy własne bloków WooCommerce */
.wc-block-checkout__sidebar [class*="wc-block-components"],
.wc-block-cart__sidebar [class*="wc-block-components"] {
  margin-left: 0 !important;
  margin-right: 0 !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}
/* wiersze sum i pozycje — pełna szerokość wewnątrz paddingu */
.wc-block-checkout__sidebar .wc-block-components-totals-item,
.wc-block-cart__sidebar .wc-block-components-totals-item {
  width: 100% !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper,
.wc-block-cart__sidebar .wc-block-components-totals-wrapper {
  padding-left: 0 !important;
  padding-right: 0 !important;
  width: 100% !important;
}
/* cena pozycji nie może wychodzić poza kontener */
.wc-block-components-order-summary-item__total-price,
.wc-block-components-totals-item__value { padding-right: 0 !important; text-align: right; }

/* =========================================================================
   Podsumowania — przebudowa: ramka na zewnątrz, wnętrze bez własnych teł
   ========================================================================= */

/* Jedyna ramka i tło: kolumna boczna koszyka i zamówienia */
.wc-block-checkout__sidebar,
.wp-block-woocommerce-cart .wc-block-cart__sidebar,
.wc-block-cart__sidebar {
  background: var(--bg-surface) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-3) !important;
  padding: 14px 24px 20px !important;
  box-sizing: border-box !important;
  overflow: hidden;
  height: fit-content;
}

/* Wszystkie wewnętrzne kontenery: przezroczyste, bez ramek, bez marginesów */
.wc-block-checkout__sidebar .wc-block-components-sidebar,
.wc-block-checkout__sidebar .wc-block-components-panel,
.wc-block-checkout__sidebar .wc-block-components-order-summary,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary,
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper,
.wc-block-cart__sidebar .wc-block-components-sidebar,
.wc-block-cart__sidebar .wc-block-components-panel,
.wc-block-cart__sidebar .wc-block-components-order-summary,
.wc-block-cart__sidebar .wc-block-components-totals-wrapper,
.wc-block-cart__sidebar .wc-block-cart__totals-title {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  margin: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}

/* Separatory między sekcjami — cienka linia zamiast pasów tła */
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper,
.wc-block-cart__sidebar .wc-block-components-totals-wrapper {
  border-top: 1px solid var(--border-default) !important;
  padding-top: 4px !important;
  padding-bottom: 4px !important;
}
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper:first-child,
.wc-block-cart__sidebar .wc-block-components-totals-wrapper:first-child { border-top: none !important; }

/* Tytuł podsumowania koszyka w stylu motywu
   (font-family/font-size/font-weight/letter-spacing nadpisane niżej w
   „Koszyk: większy tytuł podsumowania" — usunięte stąd jako martwe) */
.wc-block-cart__totals-title {
  text-transform: uppercase;
  color: var(--color-bone-0) !important;
  text-align: left !important;
  padding: 10px 0 !important;
}

/* --- Koszyk: większy tytuł podsumowania ----------------------------------- */
.wc-block-cart__totals-title {
  font-family: var(--font-display) !important;
  font-size: 24px !important;
  font-weight: 400 !important;
  letter-spacing: .04em;
}

/* --- Zamówienie: twarde domknięcie treści wewnątrz ramki ------------------- */
/* zeruj marginesy KAŻDEGO potomka — łapie też elementy bez klas wc-block */
.wc-block-checkout__sidebar * {
  margin-left: 0 !important;
  margin-right: 0 !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}
/* pozycja zamówienia: wymuś grid ponad tabelowym układem WooCommerce */
.wc-block-checkout__sidebar .wc-block-components-order-summary-item {
  display: grid !important;
  grid-template-columns: 88px minmax(0,1fr) auto !important;
  width: 100% !important;
}
/* Na 320 px po 88 px zdjęcia, odstępach i cenie na nazwę zostaje 78 px
   („WELES - ZIELEŃ" ma 85) - mniejsze zdjęcie oddaje jej 24 px.
   `!important` jak w regułach wyżej, które nadpisuje. */
@media (max-width: 359px) {
  .wc-block-checkout__sidebar .wc-block-components-order-summary-item { grid-template-columns: 64px minmax(0,1fr) auto !important; }
  .wc-block-checkout__sidebar .wc-block-components-order-summary-item__image { width: 64px !important; height: 64px !important; padding: 6px !important; }
}
.wc-block-checkout__sidebar .wc-block-components-order-summary-item > * {
  display: block !important;   /* neutralizuje table-cell */
}
.wc-block-checkout__sidebar .wc-block-components-order-summary-item__total-price {
  justify-self: end;
  text-align: right;
}
/* wiersze sum: flex z pełną kontrolą */
.wc-block-checkout__sidebar .wc-block-components-totals-item {
  display: flex !important;
  justify-content: space-between !important;
  align-items: baseline;
  gap: 12px;
  width: 100% !important;
}
.wc-block-checkout__sidebar .wc-block-components-totals-item__value { flex: 0 0 auto; }
.wc-block-checkout__sidebar .wc-block-components-totals-item__label { flex: 1 1 auto; min-width: 0; }

/* --- Checkout: zdjęcie ramki z bloków Gutenberga wewnątrz podsumowania ----- */
.wc-block-checkout__sidebar .wp-block-woocommerce-checkout-order-summary-block,
.wc-block-checkout__sidebar .wp-block-woocommerce-checkout-totals-block,
.wc-block-checkout__sidebar [class*="wp-block-woocommerce-checkout-order-summary"],
.wc-block-checkout__sidebar .wc-block-checkout__totals {
  border: none !important;
  background: transparent !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  box-shadow: none !important;
}
/* wewnętrzne sekcje bloku podsumowania (koszty, kupony, sumy) też bez ramek */
.wc-block-checkout__sidebar [class*="wp-block-woocommerce-checkout-order-summary"] > div {
  border-left: none !important;
  border-right: none !important;
  background: transparent !important;
}
/* zapas na ostatnią literę ceny — overflow z zaokrąglenia zewnętrznej ramki */
.wc-block-checkout__sidebar { padding-right: 26px !important; }

/* --- Podsumowania: bez duplikatu ceny jednostkowej pod nazwą produktu ------ */
.wc-block-checkout__sidebar .wc-block-components-order-summary-item__individual-prices,
.wc-block-checkout__sidebar .wc-block-components-order-summary-item__description .wc-block-components-product-price,
.wc-block-cart__sidebar .wc-block-components-order-summary-item__individual-prices {
  display: none !important;
}

/* --- Checkout: dokładnie JEDNO podsumowanie — to w kolumnie bocznej -------- */
/* schowaj każde wystąpienie... */
.wp-block-woocommerce-checkout .wc-block-components-checkout-order-summary,
.wp-block-woocommerce-checkout .wc-block-components-order-summary,
.wp-block-woocommerce-checkout [class*="collapsed-order-summary"],
.wc-block-checkout [class*="collapsed-order-summary"] {
  display: none !important;
}
/* ...i przywróć wyłącznie wewnątrz sidebara */
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary,
.wc-block-checkout__sidebar .wc-block-components-order-summary {
  display: block !important;
}

/* --- Checkout mobile: dobij duplikat (klasa BLOKU, nie komponentu) --------- */
/* każde podsumowanie, które NIE jest potomkiem sidebara — ukryte */
.wp-block-woocommerce-checkout-order-summary-block:not(.wc-block-checkout__sidebar *),
.wc-block-components-checkout-order-summary:not(.wc-block-checkout__sidebar *),
.wc-block-components-order-summary:not(.wc-block-checkout__sidebar *),
.wc-block-checkout__main [class*="order-summary-block"],
.wc-block-checkout__main [class*="checkout-order-summary"] {
  display: none !important;
}

/* --- Strzałka rozwijania w podsumowaniu: ukryta na każdej głębokości ------- */
.wc-block-checkout__sidebar .wc-block-components-panel__button svg,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary__title svg,
.wc-block-checkout__sidebar [class*="order-summary"] svg[class*="chevron"],
.wc-block-checkout__sidebar .wc-block-components-panel__button .wc-block-components-panel__button-icon {
  display: none !important;
}
/* cena w nagłówku panelu zostaje, sam nagłówek nieklikalny */
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary .wc-block-components-panel__button,
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary__title {
  pointer-events: none !important;
  cursor: default !important;
}

/* Cena przy nagłówku podsumowania — dubel wobec wiersza „Łącznie” */
.wc-block-checkout__sidebar .wc-block-components-checkout-order-summary__title-price,
.wc-block-components-checkout-order-summary__title-price {
  display: none !important;
}


/* =========================================================================
   Sekcja „Stwórz swój zestaw" — slotowy konfigurator
   ========================================================================= */
.et-builder { padding: var(--et-space) 0; border-top: 1px solid var(--border-default); }
.et-builder-intro { color: var(--fg-muted); max-width: 60ch; margin: 10px 0 0; }

.et-builder-form {
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: 40px;
  align-items: start;
  margin-top: 8px;
}
.et-builder-media img {
  width: 100%; height: auto;
  background: #fff;
  border-radius: var(--radius-3);
  display: block;
}

/* sloty */
.et-builder-slots { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.et-slot {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 14px 8px 12px;
  background: var(--bg-surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-3);
  cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.et-slot .et-slot-dot {
  width: 34px; height: 34px;
  border-radius: 999px;
  background: var(--color-ink-3);
  border: 1px solid var(--border-default);
  transition: background .2s var(--ease);
}
.et-slot .et-slot-name {
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
}
.et-slot.is-filled { border-style: solid; border-color: var(--color-brand-orange); }
.et-slot.is-filled .et-slot-name { color: var(--fg-default); }
/* Po dotknięciu na iPhonie ramka zostawała na slocie i na kolorze palety -
   wyglądały jak wybrane (audyt iOS 2026-09-26, zasada przy `a:hover`). */
@media (hover: hover) and (pointer: fine) {
  .et-slot:hover { border-color: var(--color-brand-orange); }
}

/* paleta */
.et-builder-palette { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.et-palette-color {
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: 13px;
  transition: border-color .2s var(--ease), transform .1s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-palette-color:hover { border-color: var(--color-brand-orange); }
}
/* Na urządzeniach dotykowych paleta musi spełniać minimalny rozmiar celu
   (44×44 px wg WCAG 2.5.5). Przy `padding: 9px 14px` i foncie 13px wychodziło
   ~34 px — a to element klikany najczęściej w całym konfiguratorze (4 razy
   przy składaniu zestawu). Na desktopie zostawiamy gęstszy układ. */
@media (hover: none) {
  .et-palette-color { min-height: 44px; }
}
.et-palette-color:active { transform: scale(.97); }
.et-palette-color.is-soldout,
.et-palette-color:disabled {
  opacity: .4;
  cursor: not-allowed;
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .et-palette-color.is-soldout:hover { border-color: var(--border-default); }
}
.et-palette-dot {
  width: 16px; height: 16px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25);
}
.et-palette-count {
  position: absolute; top: -7px; right: -6px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  border-radius: 999px;
}

/* podsumowanie + akcje */
.et-builder-summary { color: var(--fg-muted); font-size: 14px; margin: 18px 0 0; min-height: 1.4em; }
.et-builder-actions { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-top: 16px; }
.et-builder-price,
.et-builder-price .woocommerce-Price-amount {
  font-family: var(--font-heading);
  font-size: 24px; font-weight: 600;
  color: var(--color-brand-orange);
}
/* Wyłączony = przerywana ramka, jak puste sloty (zasada przy przyciskach
   `.button.alt` wyżej). Pasek na dole na stronie głównej tak samo - na karcie
   produktu to samo robi reguła `.single-product .et-sticky-btn[disabled]`. */
.et-builder-submit[disabled],
.et-builder-sticky .et-sticky-btn[disabled] {
  background: transparent;
  border: 1px dashed var(--border-input);
  color: var(--fg-faint);
  cursor: not-allowed;
}
.et-builder-more { margin-top: 14px; font-size: 13px; }
.et-builder-more a { color: var(--fg-muted); display: inline-block; padding: 12px 0; /* cel 44 px, zmierzone 16 */ }
@media (hover: hover) and (pointer: fine) {
  .et-builder-more a:hover { color: var(--color-brand-orange); }
}

.et-builder-crosssell {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-default);
  font-size: 13px;
  color: var(--fg-muted);
}
.et-builder-crosssell-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .et-builder-crosssell-link:hover { color: var(--color-brand-orange-bright); }
}
.et-builder-crosssell-link { min-height: 44px; display: inline-flex; align-items: center; /* cel dotyku, zmierzone 21 px */ }

@media (max-width: 860px) {
  .et-builder-form { grid-template-columns: 1fr; gap: 24px; }
  .et-builder-media { max-width: 420px; margin: 0 auto; }
  .et-builder-slots { grid-template-columns: repeat(4, 1fr); gap: 8px; }
  .et-slot .et-slot-dot { width: 28px; height: 28px; }
}

/*
 * TELEFON: cały konfigurator ma się zmieścić w jednym ekranie.
 *
 * Przycisk „Stwórz swój 4-pak” w hero ma pokazywać komplet: grafikę, cztery
 * sloty rolek, osiem kolorów i pole metalowego pudełka. Zmierzone na 390x844
 * ten komplet miał 783 px przy 775 px miejsca pod przyklejonym nagłówkiem -
 * brakowało ośmiu pikseli, a na prawdziwym Safari z paskami narzędzi znacznie
 * więcej.
 *
 * Samo przewinięcie tego nie rozwiąże, bo problem nie jest w tym, GDZIE się
 * zatrzymamy, tylko że treść jest wyższa niż ekran. Dlatego skracamy dwie
 * rzeczy, które da się skrócić bez straty: grafika jest kolista, więc węższa
 * ramka to niższa grafika przy nadal widocznej całości, a odstęp w siatce
 * formularza jest czysto dekoracyjny.
 */
@media (max-width: 768px) {
  .et-builder-form { gap: 14px; }
  /* WYSOKOŚĆ GRAFIKI LICZONA OD EKRANU, NIE W PIKSELACH.

     Ta wartość zmieniała się trzy razy w dwa dni: 240 px (żeby zmieścić
     komplet), potem pełna szerokość (bo wyglądała na przypadkowo
     zmniejszoną), teraz z powrotem mniejsza, żeby było widać przycisk
     „Dodaj zestaw do koszyka". Za każdym razem chodziło o TO SAMO pytanie:
     ile zostaje pod grafiką. To jest pytanie o wysokość ekranu, więc miara
     też jest w jego wysokości - i jest ustawieniem w Personalizacji, żeby
     kolejna zmiana zdania nie wymagała programisty.

     Zmierzone przy 26%: przycisk kończy się na 833 px przy oknie 844.
     Szerokość zostaje bez ograniczenia - grafika zwęża się sama, bo
     zachowuje proporcje. */
  .et-builder-media img,
  .et-builder-media canvas,
  .et-box3d-canvas { max-height: var(--et-konfig-grafika, 26vh); width: auto; margin-inline: auto; }
  .et-builder-media { text-align: center; }

  /* PEŁNA SZEROKOŚĆ - decyzja właściciela z 2026-08-12.

     Stało tu `max-width: 240px`, żeby cały konfigurator (grafika, cztery
     sloty, osiem kolorów, pole pudełka) zmieścił się w jednym ekranie po
     kliknięciu „Stwórz swój 4-pak". Cena tego była taka, że zdjęcie
     produktu i podgląd 3D zajmowały niecałe dwie trzecie szerokości
     telefonu i wyglądały na przypadkowo zmniejszone.

     Świadomy koszt: komplet NIE mieści się już w jednym ekranie - pole
     „metalowe pudełko" wypada poniżej krawędzi i trzeba do niego
     przewinąć. Wybrane większe zdjęcie zamiast jednego ekranu. */
  .et-builder-media { max-width: 100%; }
}

/*
 * Niskie telefony (iPhone SE i pokrewne, około 667 px wysokości okna).
 *
 * Przy 240 px grafiki komplet miał 677 px na 614 px miejsca. Warunek jest
 * na WYSOKOŚCI okna, nie na modelu urządzenia: to samo dotyczy każdego
 * telefonu trzymanego poziomo i każdej przeglądarki z grubym paskiem
 * narzędzi, a lista modeli i tak zestarzeje się szybciej niż ta reguła.
 */
@media (max-width: 768px) and (max-height: 700px) {
  /* Na niskich ekranach zostaje samo ściśnięcie odstępów. Zwężanie
     grafiki zdjęte razem z regułą wyżej - z tego samego powodu. */
  .et-builder-form { gap: 10px; }
}


/* Konfigurator: własna grafika (bez tła) i checkboxy dodatków */
.et-builder-media img.et-builder-custom-img {
  background: transparent;
  border-radius: 0;
  filter: drop-shadow(0 18px 40px rgba(0,0,0,.55));
}
.et-builder-addons { margin-top: 18px; display: flex; flex-direction: column; gap: 10px; }
.et-builder-addon {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--fg-default);
  font-size: 14px;
  cursor: pointer;
}
.et-builder-addon input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--color-brand-orange);
  cursor: pointer;
}
.et-builder-addon .woocommerce-Price-amount { color: var(--color-brand-orange); }


/* Paleta konfiguratora z medalionami bóstw */
.et-builder-palette { gap: 14px; }
.et-palette-color.has-medallion {
  flex-direction: column;
  padding: 12px 10px 10px;
  border-radius: var(--radius-3);
  min-width: 92px;
}
.et-palette-medallion {
  width: 56px; height: 56px;
  object-fit: contain;
  display: block;
  transition: transform .15s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-palette-color.has-medallion:hover .et-palette-medallion { transform: scale(1.08); }
}
.et-palette-color.has-medallion .et-palette-name { font-size: 12px; }
.et-slot .et-slot-dot { width: 44px; height: 44px; }
@media (max-width: 860px) {
  .et-palette-color.has-medallion { min-width: calc(25% - 11px); padding: 10px 6px 8px; }
  .et-palette-medallion { width: 44px; height: 44px; }
}

/* Paleta konfiguratora: zawsze 4 kafelki w wierszu, skalowane do szerokości */
.et-builder-palette {
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
.et-palette-color,
.et-palette-color.has-medallion {
  width: 100%;
  min-width: 0;
  justify-content: center;
}
.et-palette-medallion {
  width: 62%;
  max-width: 84px;
  height: auto;
  aspect-ratio: 1 / 1;
}
.et-palette-color.has-medallion .et-palette-name {
  white-space: normal;      /* pełna nazwa w dwóch wierszach zamiast „…” */
  overflow: visible;
  text-overflow: clip;
  max-width: 100%;
  line-height: 1.2;
  hyphens: auto;
}
@media (max-width: 480px) {
  .et-builder-palette { gap: 8px; }
  .et-palette-color.has-medallion .et-palette-name { font-size: 11px; } /* dol skali: 11 px na podpis (audyt D3) */
}
/* NAJWĘŻSZE TELEFONY: TRZY KOLORY W RZĘDZIE (audyt iOS 2026-09-26).
   „Bursztynowy" ma przy 11 px 68 px, a kafel przy czterech w rzędzie
   zostawia na napis 48 px przy 320 px (napis ucięty na ramce: „Bursztynow")
   i 56 px przy 360 px (napis na samej ramce). Mniejszego pisma nie ma
   (dół skali 11 px), dzielenia wyrazów po polsku Safari nie zna. Trzy
   w rzędzie dają ok. 70 px - od 375 px zostają cztery. */
@media (max-width: 374px) {
  .et-builder-palette { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* Hero: pokaz slajdów na prawej stronie */
.hero-right { position: relative; }
.hero-right .hero-slide {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
}
.hero-right .hero-slide.is-active { opacity: 1; }
/* Gotowe na `<img fetchpriority="high">` zamiast tla CSS (audyt R9): jesli
   `front-page.php` wlozy obrazek do slajdu, wypelni go tak samo jak tlo. */
.hero-right .hero-slide > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
@media (prefers-reduced-motion: reduce) {
  .hero-right .hero-slide { transition: none; }
}

/* Hero: gradientowe wtopienie NAD slajdami (zniknęło po dodaniu pokazu) */
.hero-right .hero-slide { z-index: 1; }
.hero-right.has-image::before { z-index: 2; }
.hero-right.has-image::after  { z-index: 3; }

.hero-controls {
  position: absolute;
  bottom: 16px; right: 16px;
  z-index: 5;
  display: flex; gap: 8px;
  opacity: 0;
  /*
   * Czego nie widać, w to nie można kliknąć.
   *
   * Sam `opacity: 0` zostawiał w prawym dolnym rogu zdjęcia prostokąt
   * ok. 112x32 px, który dalej łapał dotknięcia: na telefonie palec trafiał
   * w ukryty przycisk pauzy i karuzela zatrzymywała się bez widocznego
   * powodu, zamiast zadziałać zgodnie z podziałem lewa/środek/prawa.
   */
  pointer-events: none;
  transition: opacity .2s var(--ease);
}
.hero-pause, .hero-nav {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(11, 11, 11, .5);
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 50%;
  color: var(--color-bone-0, #fff);
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .hero-pause:hover, .hero-nav:hover { background: rgba(11, 11, 11, .75); color: var(--color-brand-orange); }
}

/* Mysz: sterowanie odsłania się na hover, żeby nie zaśmiecać kadru. */
@media (hover: hover) and (pointer: fine) {
  .hero-right:hover .hero-controls { opacity: 1; pointer-events: auto; }
}
/* Klawiatura (Tab) - zawsze, niezależnie od typu wskaźnika. */
.hero-right:focus-within .hero-controls { opacity: 1; pointer-events: auto; }

/*
 * Dotyk: sterowanie widoczne na stałe.
 *
 * Warunek jest dokładnym zaprzeczeniem reguły hover wyżej i tego samego
 * sprawdzenia w `egotape.js` - CSS i JS muszą się tu zgadzać co do znaku.
 *
 * Dlaczego widoczne, a nie tylko odcięte od dotyku: zdjęcia zmieniają się
 * same co kilka sekund, a bez hovera jedynym sposobem zatrzymania ich byłby
 * niewidoczny tap w środek kadru - o którym nikt nie wie. Kontrolka, której
 * nie widać, nie jest kontrolką (WCAG 2.2.2 „Pause, Stop, Hide” wymaga
 * mechanizmu, a nie sekretu). Tap w lewą/prawą/środkową część zdjęcia
 * zostaje jako skrót dla tych, którzy go znajdą.
 */
@media not all and (hover: hover) and (pointer: fine) {
  .hero-controls { opacity: 1; pointer-events: auto; }
}

/*
 * Ograniczony ruch: `egotape.js` startuje karuzelę wstrzymaną, więc jedyną
 * drogą do pozostałych zdjęć są przyciski - bez nich zostaje jedno zdjęcie
 * i żadnego śladu, że są następne. Pokazujemy je od razu, bez animowania.
 */
@media (prefers-reduced-motion: reduce) {
  .hero-controls { opacity: 1; pointer-events: auto; transition: none; }
}

/*
 * ...i ten sam wyjątek musi przebić schowanie na telefonie.
 *
 * Przy ograniczonym ruchu karuzela startuje wstrzymana. Bez przycisków
 * zostałoby jedno zdjęcie i żaden ślad, że są następne - a użytkownik, który
 * poprosił o mniej ruchu, nie poprosił o mniej treści.
 */
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .hero .hero-controls { display: flex; }
}

/*
 * Przerwa między przyklejonym menu a logo w hero - PULPIT.
 *
 * `body` i `!important` nie z lenistwa: wypełnienie hero jest w tym pliku
 * ustawiane trzy razy, w tym dwa razy z `!important`, i wszystkie te reguły
 * stoją NIŻEJ niż blok telefonu. Bez podniesionej wagi ustawienie
 * z Personalizacji nie miałoby żadnego skutku - a to najczęstszy sposób,
 * w jaki psuły się tu poprzednie zmiany.
 */
@media (min-width: 769px) {
  body .hero { padding-top: var(--et-odstep-nad-logo-pc, 96px) !important; }
}

/*
 * Treść hero dosunięta w prawo - PULPIT, ustawienie z Personalizacji.
 *
 * PO CO TO BYŁO I DLACZEGO DOMYŚLNIE JEST TERAZ ZERO
 *
 * Wartość istniała po to, żeby wyrównać tytuł do LITER napisu EGOTAPE: napis
 * jest obrazkiem szerszym niż jego litery, bo kreska przekreślenia wystaje po
 * obu stronach. Napis zniknął z hero (audyt: czytał się jak skreślony tekst),
 * więc znikł też jedyny powód, dla którego treść miała nie stać na lewej
 * linii strony.
 *
 * Domyślne zero, a nie skasowanie ustawienia: właściciel może chcieć odsunąć
 * treść od krawędzi z innego powodu i pole zostaje mu do dyspozycji.
 *
 * Druga reguła (`margin-left: 56px` od 861 px) zniknęła w całości. Robiła to
 * samo, tyle że inną liczbą i na innym progu, przez co przy szerokościach
 * 769-860 px obowiązywała jedna wartość, a powyżej dwie naraz - obie
 * z `!important`. Nie było tego czym uzasadnić poza kolejnością powstawania.
 */
@media (min-width: 769px) {
  body .hero .hero-eyebrow,
  body .hero .hero-title,
  body .hero .hero-sub,
  body .hero .hero-ctas { margin-left: var(--et-hero-przesuniecie-pc, 0px) !important; }
}


/* =========================================================================
   Sklep — siatka premium
   ========================================================================= */
.woocommerce .products-header + ul.products,
.woocommerce ul.products {
  gap: 28px;
}
.woocommerce ul.products li.product {
  border-radius: var(--radius-3);
  overflow: hidden;
  box-shadow: 0 1px 0 rgba(255,255,255,.03) inset;
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product:hover {
    box-shadow:
      0 18px 44px rgba(0,0,0,.5),
      0 2px 10px rgba(246,149,0,.08);
  }
}
/* gwiazdki na kartach i PDP w brand amber */
.woocommerce .star-rating span::before,
.woocommerce .star-rating::before { color: var(--color-brand-orange); }
.woocommerce ul.products li.product .star-rating {
  margin: 6px 18px 0;
  font-size: 12px;
}


/* Stopka: kolumna marki — mail i ikony wyśrodkowane względem logo */
.footer-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: fit-content;
}
.footer-brand img { margin-bottom: 16px; }
.footer-brand p { text-align: center; }
.footer-social { justify-content: center; }
@media (max-width: 768px) {
  .footer-brand { width: 100%; align-items: center; }
}


/* Stopka: kolumny linków dosunięte w prawo, luz zbiera kolumna marki */
@media (min-width: 1025px) {
  .footer-top { justify-content: end; }
  .footer-brand { justify-self: start; }
}


/* Karty produktów na telefonie: „Dodaj do koszyka" (i „Zobacz koszyk", które
   po dodaniu zajmuje jego miejsce) na całą szerokość karty. */
@media (max-width: 640px) {
  .woocommerce ul.products li.product .button,
  .woocommerce ul.products li.product .added_to_cart {
    /* NAPIS ZAWIJA SIĘ, ZAMIAST WYCHODZIĆ POZA PRZYCISK (2026-09-26, #4).
       Było `nowrap` w przycisku o szerokości karty: „DODAJ DO KOSZYKA" ma
       102 px, a karta suwaka zostawia na napis 99,5 px przy 393 px i 67 px
       przy 320 px - napis wystawał z obu stron i przycisk go ucinał („DDAJ
       DO KOSZYK" na 320 px). Na 393 px trzymał się jeszcze na wypełnieniu,
       ale wystarczył znaczek „✓" po dodaniu, żeby wylał się i tam.
       Teraz napis, który się nie mieści, łamie się na spacji na dwa równe
       wiersze (`balance`), nigdy w środku wyrazu. Wysokość przycisków
       w rzędzie wyrównuje reguła „WĄSKA KARTA" przy celach dotyku. */
    white-space: normal;
    text-wrap: balance;
    overflow-wrap: normal;
    font-size: 12px; /* 11 px czytalo sie jak przycisk drugorzedny (audyt U11) */
    letter-spacing: .04em;
    padding: 12px 8px;
    /* CIASNIEJ NIŻ NA PULPICIE.

       Zmierzone na 390 px: między ceną a przyciskiem było 22 px (8,5 px
       własnego marginesu ceny plus 14 px marginesu przycisku), a pod
       przyciskiem 37 px. Na karcie szerokiej na 162 px takie odstępy
       zjadają więcej miejsca niż sam przycisk.

       Marginesy boczne zostają 18 px - to one trzymają przycisk w jednej
       pionowej linii z tytułem i ceną. */
    margin: 8px 18px 12px;
    /* Na pełną szerokość karty. Domyślnie przycisk jest szeroki na tyle,
       ile ma napisu (`align-self: flex-start` niżej w pliku), więc lewa
       krawędź stała równo z tytułem i ceną, a prawa urywała się w losowym
       miejscu. Przy dwóch kartach obok siebie widać to od razu. */
    align-self: stretch;
  }

  /* Węższe wcięcia boczne niż na pulpicie. Kafelek ma na telefonie 160 px,
     więc dwa razy po 18 px zjadało ponad jedną piątą jego szerokości -
     a to właśnie ta szerokość decyduje, jak małe musi być pismo tytułu,
     żeby nazwa zmieściła się w jednej linii. Wcięcia zmieniamy razem dla
     tytułu, ceny, oceny i przycisku, żeby wszystko stało w jednej pionowej
     linii. */
  .woocommerce ul.products li.product .woocommerce-loop-product__title,
  .woocommerce ul.products li.product .price { padding-left: 12px; padding-right: 12px; }
  .woocommerce ul.products li.product .star-rating,
  .woocommerce ul.products li.product .et-rating-placeholder { margin-left: 12px; margin-right: 12px; }
  .woocommerce ul.products li.product .button,
  .woocommerce ul.products li.product .added_to_cart { margin-left: 12px; margin-right: 12px; }
}


/* Darmowa dostawa: notka i pasek postępu */
.et-freeship-note {
  display: flex; align-items: center; gap: 8px;
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--fg-muted);
}
.et-freeship-note::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 999px;
  background: var(--color-brand-orange);
  flex: 0 0 auto;
}
.et-freeship-bar {
  margin: 0 0 22px;
  padding: 14px 18px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.et-freeship-msg { margin: 0 0 10px; font-size: 14px; color: var(--fg-default); }
.et-freeship-msg .woocommerce-Price-amount,
.et-freeship-msg .et-freeship-amt { color: var(--color-brand-orange); font-weight: 600; }
.et-freeship-track {
  height: 5px;
  background: var(--color-ink-4);
  border-radius: 999px;
  overflow: hidden;
}
.et-freeship-fill {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--color-brand-orange-deep), var(--color-brand-orange));
  border-radius: 999px;
  transition: width .4s var(--ease);
}
.et-freeship-bar.is-complete { border-color: rgba(246,149,0,.45); }
.et-freeship-bar.is-complete .et-freeship-msg { color: var(--color-brand-orange); }


/* Sekcja O firmie: mały napis wyrównany z nagłówkiem */
.about-eyebrow {
  text-align: left !important;
  justify-content: flex-start !important;
  margin-left: 0 !important;
}


/* Stopka: kolumna kontaktu zamiast logo */
.footer-brand--contact {
  align-items: flex-start;
  width: auto;
}
.footer-brand--contact h4 {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-bone-0);
  margin: 0 0 14px;
}
.footer-brand--contact .footer-social { margin: 0 0 22px; justify-content: flex-start; gap: 12px; }
.footer-brand--contact .footer-social .icon-btn { width: 46px; height: 46px; }
.footer-brand--contact .footer-mail-label { margin-bottom: 8px; }
.footer-brand--contact p { text-align: left; margin: 0; }
.footer-brand--contact .footer-mail { font-size: 15px; }
@media (max-width: 768px) {
  .footer-brand--contact { align-items: center; }
  .footer-brand--contact p { text-align: center; }
  .footer-brand--contact .footer-social { justify-content: center; }
}




/* Konfigurator — zakładki */
.et-builder-tabs { display: flex; gap: 10px; flex-wrap: wrap; margin: 6px 0 22px; }
.et-builder-tab {
  background: var(--bg-surface);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-pill);
  color: var(--fg-muted);
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 11px 18px;
  min-height: 44px; /* zmierzone 41 px */
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-builder-tab:hover { color: var(--fg-default); border-color: var(--border-strong); }
}
.et-builder-tab.is-active {
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
  color: var(--color-ink-1);
}
.et-builder-pane { display: none; }
.et-builder-pane.is-active { display: block; }

/* Pudełko: 2 sloty i paleta po 2 kolory w wierszu */
#pane-box .et-builder-slots { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
#pane-box .et-slot { padding: 18px 8px 16px; }
#pane-box .et-slot .et-slot-dot { width: 46px; height: 46px; }
#pane-box .et-builder-palette { grid-template-columns: repeat(2, minmax(0, 1fr)); }
#pane-box .et-box3d { display: block; margin: 0; }
#pane-box .et-box3d-canvas { min-height: 320px; }
/* Pola napisu stoją w kolumnie grafiki, która na telefonie środkuje tekst
   (`.et-builder-media`). Notki o druku 3D z kreską po lewej wychodziły
   wyśrodkowane - kreska przy lewej krawędzi, tekst na środku - a na karcie
   pudełka te same notki stoją do lewej (audyt iOS 2026-09-26). */
#pane-box .et-box3d-fields { margin-top: 14px; text-align: start; }
/* Napis na pudełku - zły znak widać od razu pod polem (audyt D9) */
.et-box3d-error { margin: 6px 0 0; color: var(--color-danger); font-size: 0.85rem; line-height: 1.4; }
.et-box3d-fields input[aria-invalid="true"] { border-color: var(--color-danger); }


/* Konfigurator — opis zakładki */
.et-builder-desc {
  color: var(--fg-muted);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 18px;
  padding-left: 14px;
  border-left: 2px solid var(--color-brand-orange);
}


/* Brak poziomego przewijania na telefonie */
html, body { max-width: 100%; overflow-x: hidden; }
.et-banners, .hero, .container, .et-builder, .et-box3d-section { max-width: 100%; }
iframe, video, .wp-block-embed__wrapper iframe { max-width: 100%; }
.et-box3d-canvas canvas { max-width: 100%; }

/* Hamburger jako ostatni przycisk w prawym rogu */
.header-actions .et-nav-toggle { order: 99; }


/* Konfigurator — licznik, aktywny slot, zaznaczone kolory */
.et-builder-counter {
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 12px;
}
.et-builder-counter .et-counter-now { color: var(--color-brand-orange); font-size: 15px; }
.et-slot.is-active {
  border-style: solid;
  border-color: var(--color-brand-orange);
  box-shadow: 0 0 0 3px rgba(246,149,0,.16);
}
.et-palette-color { position: relative; }
.et-palette-color.is-picked { border-color: var(--color-brand-orange); }

/* Mobilny pasek zakupu */
.et-builder-sticky {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: none;
  flex-direction: column; align-items: stretch; gap: 6px;
  padding: 9px 14px calc(9px + env(safe-area-inset-bottom));
  background: rgba(11,11,11,.94);
  border-top: 1px solid var(--border-default);
  /*
   * Bez `backdrop-filter`. Tło paska jest ostatecznie 97% kryjące (reguła
   * niżej z `!important`), więc rozmycie wnosiło ~3% obrazu — praktycznie
   * niewidoczne — a zmuszało przeglądarkę do odczytywania tła pod paskiem
   * w każdej klatce przewijania. To typowe źródło migotania elementów
   * `position: fixed` na telefonach.
   *
   * Własna warstwa kompozycji zamiast tego: pasek nie jest przerysowywany
   * razem z przewijaną treścią.
   */
  transform: translateZ(0);
  will-change: transform;
}
.et-builder-sticky.is-visible { display: flex; }
.et-sticky-price {
  font-family: var(--font-heading);
  font-size: 19px; font-weight: 600;
  line-height: 1.1;
  color: var(--color-brand-orange);
  white-space: nowrap;
}
.et-sticky-btn {
  flex: 0 1 auto;               /* przycisk nie rozpycha paska */
  max-width: 56%;
  font-size: 12px;
  padding: 12px 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 380px) {
  .et-sticky-price { font-size: 17px; }
  .et-sticky-ship  { font-size: 11px; }
  .et-sticky-btn   { max-width: 52%; padding: 11px 12px; }
}
.et-sticky-btn[disabled] { background: var(--color-ink-4); color: var(--fg-faint); }
/* KARTA PRODUKTU: WYŁĄCZONY PRZYCISK W PASKU NIE MOŻE WYGLĄDAĆ NA AWARIĘ
   (zgłoszenie #7, 2026-09-26: „DODAJ DO KOSZYKA" szare na szarym).

   Wyłączenie jest zamierzone: przy produkcie z wyborem kolorów (Rodzanice -
   Miks kolorów) `egotape-builder.js` wyłącza prawdziwy przycisk, dopóki nie
   ma czterech kolorów, a pasek kopiuje ten stan (`etCreateStickyBar`). Pasek
   stoi jednak nad opiniami i polecanymi, daleko od wyboru, i pełny szary
   prostokąt z bladym napisem (3,7:1) czytał się tam jak zepsuty przycisk.

   Przerywana ramka to w tym motywie „jeszcze niepełne": tak rysowane są
   puste sloty rolek w tym samym wyborze kolorów. Przycisk mówi więc „zestaw
   nie jest jeszcze skompletowany", a nie „coś nie działa". Tylko na karcie
   produktu - pasek konfiguratora na stronie głównej zostaje bez zmian. */
.single-product .et-sticky-btn[disabled] {
  background: transparent;
  border: 1px dashed var(--border-input);
  color: var(--fg-faint);
  cursor: not-allowed;
}
@media (min-width: 861px) { .et-builder-sticky { display: none !important; } }

/* Link edukacyjny w hero */
.hero-link {
  display: inline-flex; align-items: center;
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--fg-muted);
  padding: 12px 4px;
}
@media (hover: hover) and (pointer: fine) {
  .hero-link:hover { color: var(--color-brand-orange); }
}


/* Atrybut hidden ma pierwszeństwo nad układem flex */
.et-palette-count[hidden] { display: none !important; }


/* Wybrany kolor: wyraźna ramka jako główny sygnał wyboru */
.et-palette-color.is-picked {
  border-color: var(--color-brand-orange);
  box-shadow: 0 0 0 2px rgba(246,149,0,.22);
}


/* Sticky pasek zawsze na wierzchu — sekcje z .et-grain tworzą własny kontekst warstw */
.et-builder-sticky {
  z-index: 2147483000 !important;
  isolation: isolate;
  background: rgba(11,11,11,.97) !important;
  box-shadow: 0 -12px 30px rgba(0,0,0,.55);
}
/* nie pozwól sekcjom przykryć paska */
.about, .et-builder, .et-box3d-section, .products-section, .feature-section { z-index: auto; }


/* Jeden kontener dla całej treści — szerokość i marginesy z Personalizacji */
.hero,
.woocommerce .products-header,
.wp-block-woocommerce-cart,
.wp-block-woocommerce-checkout,
.wc-block-checkout,
.et-payments-inner {
  width: min(100% - (var(--et-gutter, 24px) * 2), var(--et-container, 1320px)) !important;
  max-width: none !important;
  margin-inline: auto !important;
}
.hero { padding-left: 0; padding-right: 0; }

/* ...ALE NIE DWA RAZY POD RZĄD.

   Reguła wyżej nadaje szerokość kontenera pięciu elementom naraz. Dla
   `.hero` i `.et-payments-inner` jest to słuszne - stoją bezpośrednio
   w treści strony. Bloki koszyka i kasy stoją INACZEJ: siedzą wewnątrz
   `main.site-main.container`, który tę samą formułę już zastosował. Odstęp
   od krawędzi odejmował się więc dwukrotnie.

   Zmierzone na ekranie 390 px: treść strony 334 px, blok koszyka 278 px.
   Czternaście procent szerokości oddane na nic - i to na stronie, gdzie
   liczy się każde pole formularza. Na komputerze ta sama różnica ustawiała
   kasę o 28 px na prawo od własnego nagłówka i okruszków nad nim.

   Element w kontenerze ma brać całą jego szerokość; odstęp od krawędzi
   ekranu jest zadaniem kontenera i tylko jego. Wyższa specyficzność
   (dwie klasy zamiast jednej) załatwia to bez kolejnego `!important`
   ponad ten, który już tam stoi. */
.container .wp-block-woocommerce-cart,
.container .wp-block-woocommerce-checkout,
.container .wc-block-checkout {
  width: 100% !important;
}

/* Telefon: węższy margines boczny */
@media (max-width: 640px) {
  :root { --et-gutter: var(--et-gutter-mobile, 18px); }
}


/* Hero: treść wyrównana do tej samej pionowej linii co reszta strony */
.hero {
  padding-left: 0 !important;
  padding-right: 0 !important;
}
@media (min-width: 861px) {
  .hero-eyebrow,
  .hero-title,
  .hero-sub,
  .hero-ctas { margin-left: 0 !important; }
  .hero-logo { margin-left: -8px; }  /* ogon przekreślenia lekko wychodzi poza linię */
}


/* Opis zależny od zakładki */
.et-builder-intro.is-hidden { display: none; }

/* Przełącznik: wizualizacja 3D / zdjęcia */
.et-media-switch { display: flex; gap: 8px; margin-bottom: 12px; }
.et-media-tab {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  color: var(--fg-muted);
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 9px 14px;
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .et-media-tab:hover { color: var(--fg-default); border-color: var(--border-strong); }
}
.et-media-tab.is-active {
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
  color: var(--color-ink-1);
}
.et-photo-main img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
}
.et-photo-thumbs { display: flex; gap: 8px; margin-top: 10px; }
.et-photo-thumb {
  width: 68px; height: 68px;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden;
  background: var(--bg-surface);
  cursor: pointer;
}
.et-photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.et-photo-thumb.is-active { border-color: var(--color-brand-orange); }


/* Pozycje menu z kotwicą: podświetlane dopiero przy przewinięciu do sekcji.

   Kolor jak każda inna pozycja - przygaszenie wyglądało jak pozycja wyłączona
   albo „bieżąca" (zgłoszenie właściciela 2026-09-23: „Stwórz zestaw ma ten sam
   kolor co pozostałe"). Wyróżnienie zostaje samemu przewijaniu: dopiero gdy
   sekcja wejdzie na ekran, skrypt dokłada `.is-current`. Klasy `current-menu-item`
   te pozycje i tak nie dostają - zdejmuje ją filtr w `functions.php`. */
.header-nav .et-anchor-item > a { color: var(--fg-default); }
.header-nav .et-anchor-item > a::after { opacity: 0; }
.header-nav a.is-current { color: var(--color-brand-orange); }
.header-nav a.is-current::after { opacity: 1; }


/* =========================================================================
   Konfigurator — animowany stos rolek
   ========================================================================= */
.et-builder-media { position: relative; }
.et-builder-media img { transition: opacity .45s var(--ease); }

.et-stack {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end;
  padding-bottom: 14%;
  pointer-events: none;
}
.et-stack-rolls {
  display: flex;
  flex-direction: column-reverse;   /* nowe rolki lądują na wierzchu stosu */
  align-items: center;
  gap: 0;
}
.et-stack-shadow {
  width: 46%;
  height: 16px;
  margin-top: 10px;
  background: radial-gradient(ellipse at center, rgba(0,0,0,.65) 0%, rgba(0,0,0,0) 70%);
  opacity: 0;
  transition: opacity .4s var(--ease);
}
.et-stack.has-rolls .et-stack-shadow { opacity: 1; }

/* pojedyncza rolka: bok + wierzch + otwór */
.et-roll {
  position: relative;
  width: var(--et-roll-w, 260px);
  height: calc(var(--et-roll-w, 260px) * 0.274);
  margin-top: calc(var(--et-roll-w, 260px) * -0.036 - var(--et-roll-gap, 0px));
  animation: et-roll-drop .5s cubic-bezier(.18,.9,.28,1.3) both;
  filter: drop-shadow(0 6px 12px rgba(0,0,0,.45));
}
.et-roll-side {
  position: absolute; left: 0; right: 0; top: 26%; bottom: 0;
  border-radius: 0 0 50% 50% / 0 0 40% 40%;
  background-color: var(--roll, #8a8a8a);          /* pełne krycie */
  background-image: linear-gradient(90deg,
    rgba(0,0,0,.55) 0%,
    rgba(0,0,0,.15) 22%,
    rgba(255,255,255,.22) 50%,
    rgba(0,0,0,.15) 78%,
    rgba(0,0,0,.55) 100%);
}
.et-roll-top {
  position: absolute; left: 0; right: 0; top: 0; height: 56%;
  border-radius: 50%;
  background-color: var(--roll, #8a8a8a);
  background-image: linear-gradient(160deg, rgba(255,255,255,.30), rgba(255,255,255,0) 45%, rgba(0,0,0,.22));
  box-shadow: inset 0 -2px 6px rgba(0,0,0,.35);
}
.et-roll-hole {
  position: absolute; left: 50%; top: 13%;
  width: 34%; height: 32%;
  transform: translateX(-50%);
  border-radius: 50%;
  background-color: var(--color-ink-1);
  background-image: radial-gradient(ellipse at 50% 35%, rgba(0,0,0,1) 55%, rgba(255,255,255,.10) 100%);
  box-shadow: inset 0 2px 5px rgba(0,0,0,.9);
}
.et-roll.is-leaving { animation: et-roll-out .25s ease-in forwards; }

@keyframes et-roll-drop {
  0%   { opacity: 0; transform: translateY(-90px) scaleY(.86) rotate(-3deg); }
  70%  { opacity: 1; transform: translateY(4px) scaleY(1.04) rotate(.5deg); }
  100% { opacity: 1; transform: translateY(0) scaleY(1) rotate(0); }
}
@keyframes et-roll-out {
  to { opacity: 0; transform: translateY(-40px) scale(.9); }
}
@media (prefers-reduced-motion: reduce) {
  .et-roll { animation: none; }
}
@media (max-width: 860px) {
  /*
   * Zmienna MUSI siedzieć na wspólnym przodku stosu i znacznika, nie na
   * samym `.et-stack`. Oba liczą z niej wzajemne rezerwacje miejsca
   * (stos 0.85, znacznik 0.70) — gdy stos widział 190px, a znacznik
   * dziedziczone z `:root` 260px, rezerwacje przestawały się zgadzać
   * i cała kompozycja uciekała w prawo.
   */
  .et-builder-media { --et-roll-w: var(--et-roll-w-mobile, 190px); }
}


/* Stos rolek zawsze przed grafiką */
.et-stack { z-index: 3; }
.et-builder-media img { position: relative; z-index: 1; }

/* --- Stos rolek na karcie produktu ---------------------------------------
 * Nakładka doklejana z JS do zewnętrznego kontenera galerii (patrz komentarz
 * w egotape.js — wnętrze galerii przejmuje flexslider).
 */
.woocommerce-product-gallery.et-has-stack {
  position: relative;
  /*
   * Rozmiar dobrany tak, żeby kompozycja (rolki + plus + pudełko = 1.55 × ta
   * wartość) wypełniała ~68% szerokości kadru — tyle, ile na stronie głównej.
   *
   * Wcześniejsze `clamp(180px, 22vw, 300px)` dawało 78–80% i wszystko
   * wyglądało na wciśnięte: pudełko na za duże, a plus wchodził na taśmy.
   * Proporcje między elementami były poprawne — za duża była cała grupa
   * względem ramy.
   */
  --et-roll-w: clamp(150px, 18vw, 260px);
}

/* Przygaszenie grafiki pod stosem rolek — wartość trzymamy w CSS, bo to
 * decyzja wizualna, a nie logika (JS tylko przełącza klasę `.is-dimmed`).
 * Konfigurator na stronie głównej zostawia grafikę ledwie widoczną. */
.et-builder-media img.is-dimmed,
.et-media-art img.is-dimmed { opacity: .18; }

/* Karta produktu idzie dalej: zdjęcie znika całkowicie. Przezroczystość na
 * `__wrapper`, a nie na samym <img>, zabiera też biały kafel galerii
 * (`background: #FFFFFF` wyżej w pliku) — bez tego zostawałby jasny
 * prostokąt, na którym rolki się gubiły. */
.et-has-stack .woocommerce-product-gallery__wrapper { transition: opacity .4s var(--ease); }
.et-has-stack .woocommerce-product-gallery__wrapper.is-dimmed { opacity: 0; }

/* Lupka PhotoSwipe (dorzucana przez WooCommerce z JS) nie ma po co zostawać
 * nad niewidocznym zdjęciem. */
.et-has-stack .woocommerce-product-gallery__trigger { display: none; }

/* =========================================================================
 * Kompozycja „taśmy + pudełko"
 *
 * Wspólna dla konfiguratora na stronie głównej i dla karty produktu:
 * taśmy z lewej, bursztynowy plus na środku, pudełko z prawej.
 *
 * Selektory są zgrupowane celowo. Oba miejsca mają inne klasy
 * (`.et-builder-media`/`.et-stack`/`.et-addon-tin` kontra
 * `.et-has-stack`/`.et-pdp-stack`/`.et-pdp-tin`), ale ta sama kompozycja
 * ma jedno źródło — inaczej każda korekta proporcji wymagałaby pamiętania
 * o dwóch miejscach.
 * ====================================================================== */

/*
 * Dlaczego nie dzielimy kadru na pół.
 *
 * Wcześniej stos zajmował lewą połowę, a znaczek prawą. Przy takim podziale
 * grupa NIE MOŻE być wyśrodkowana względem grafiki: rolki (0.70 × szerokość
 * rolki) są węższe niż plus z pudełkiem po drugiej stronie, więc całość
 * uciekała w prawo o kilkanaście pikseli. Przesuwanie osi podziału „na oko"
 * rozjeżdżałoby się przy każdej korekcie skali.
 *
 * Teraz oba elementy zajmują CAŁY kadr i wzajemnie rezerwują sobie miejsce
 * paddingiem: stos odsuwa się od prawej o szerokość znacznika, a znacznik od
 * lewej o szerokość rolek. Każdy centruje swoją treść w tym, co zostało —
 * a że rezerwacje są policzone z tych samych wartości, treści stykają się
 * dokładnie tam, gdzie trzeba, i cała grupa wychodzi na środku kadru
 * niezależnie od proporcji.
 *
 * Wszystkie szerokości pochodzą z `--et-roll-w`, więc zależność się trzyma
 * przy dowolnym rozmiarze:
 *   rolki      0.70   |  plus 0.12 + 2 × 0.09 marginesu  |  pudełko 0.55
 *   znacznik = 0.09 + 0.12 + 0.09 + 0.55 = 0.85
 */
.et-has-stack .et-pdp-stack,
.et-builder-media .et-stack {
  transition: padding .35s var(--ease);
}
.et-has-stack .et-pdp-stack { padding-bottom: 8%; }

/* Skala na samych rolkach, nie na stosie: stos rozciąga się teraz na cały
 * kadr, więc skalowanie go zmniejszałoby też rezerwacje paddingiem i psuło
 * wyśrodkowanie. Skalowanie nie zmienia rozmiaru w układzie, ale centrowanie
 * i tak liczy się od środka, więc obraz się zgadza. */
.et-stack-rolls {
  transform-origin: center;
  transition: transform .35s var(--ease);
}

.et-has-stack.has-addon .et-pdp-stack,
.et-builder-media.has-addon .et-stack {
  justify-content: center;
  padding-bottom: 0;
  padding-right: calc(var(--et-roll-w, 260px) * (0.30 + var(--et-tin-scale, .42)));
}
.et-has-stack.has-addon .et-stack-rolls,
.et-builder-media.has-addon .et-stack-rolls { transform: scale(.70); }
/* Cień jest rodzeństwem rolek, więc skala go nie obejmuje — szerokość
 * z tej samej zmiennej, żeby nie został szerszy od zmniejszonych rolek. */
.et-has-stack.has-addon .et-stack-shadow,
.et-builder-media.has-addon .et-stack-shadow { width: calc(var(--et-roll-w, 260px) * 0.5); }

/* Znaczek zajmuje prawą część kadru: plus jako pierwszy w rzędzie wypada
 * mniej więcej na środku, pudełko zaraz za nim. */
.et-has-stack .et-pdp-tin,
.et-builder-media .et-addon-tin {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  /* Odstępy robią marginesy plusa, nie `gap` — dzięki temu są równe po obu
   * jego stronach z konstrukcji, a nie z dobranych wartości. */
  gap: 0;
  padding-top: 0;
  /* Rezerwacja miejsca na rolki po lewej. Zjeżdża do zera, gdy rolek nie ma,
   * i wtedy pudełko samo wchodzi na środek kadru — stąd animacja na
   * paddingu. Pop przy pojawieniu się działa na `transform`, więc nie kolidują. */
  padding-left: calc(var(--et-roll-w, 260px) * 0.70);
  transition: padding-left .35s var(--ease);
}
/* Pudełko ma własny mnożnik, niezależny od skali rolek — dzięki temu można
 * dostroić jedno bez ruszania drugiego ani rozmiaru plusa (ten liczy się
 * z `--et-roll-w`, więc zmiennej celowo nie zmieniamy). */
/*
 * Selektor z `div.product div.images` NIE jest ozdobnikiem — bez niego
 * wygrywa reguła WooCommerce:
 *   .woocommerce div.product div.images img { width:100%; height:auto }
 * (3 klasy + 3 typy). Na karcie produktu rozciągała ona grafikę pudełka na
 * całą szerokość i żadna ustawiona tu skala nie miała znaczenia — dlatego
 * pudełko wyglądało tak samo mimo zmian wartości. Na stronie głównej problem
 * nie występował, bo tam nie ma przodka `div.images`.
 */
.woocommerce div.product div.images .et-pdp-tin img,
.et-has-stack .et-pdp-tin img,
.et-builder-media .et-addon-tin img {
  /* Wielkość z Personalizacji („Metalowe pudełko — wielkość"), bo to ocena
   * wizualna. Domyślnie 42% szerokości rolki — pudełko ma być dodatkiem
   * obok taśm, nie drugim bohaterem kadru. */
  width: calc(var(--et-roll-w, 260px) * var(--et-tin-scale, .42));
  transition: width .35s var(--ease);
}

/* Plus w równej odległości od taśm i od pudełka.
 *
 * Lewy margines odsuwa go od prawej krawędzi rolek (ta stoi dokładnie na
 * środku kadru), prawy — od pudełka. Ta sama wartość po obu stronach, więc
 * symetria wynika z układu i nie trzeba jej pilnować przy zmianach skali.
 * Procent liczy się od szerokości znacznika, czyli połowy kadru. */
.et-has-stack .et-pdp-tin .et-addon-plus,
.et-builder-media .et-addon-tin .et-addon-plus {
  /* Stała szerokość pudełka plusa, żeby rezerwacja miejsca (0.85) była
   * policzalna — inaczej zależałaby od szerokości glifu w danym kroju. */
  flex: 0 0 auto;
  width: calc(var(--et-roll-w, 260px) * 0.12);
  margin: 0 calc(var(--et-roll-w, 260px) * 0.09);
  text-align: center;
}

/* Samo pudełko, bez rolek: wraca na środek kadru i bez plusa — plus ma sens
 * dopiero jako złączenie taśm z pudełkiem. Gdy wjadą rolki, reguły wyżej
 * przesuwają pudełko w prawo i plus się pojawia. */
.et-has-stack.has-addon:not(.has-rolls) .et-pdp-tin,
.et-builder-media.has-addon:not(.has-rolls) .et-addon-tin { padding-left: 0; }
.et-has-stack.has-addon:not(.has-rolls) .et-addon-plus,
.et-builder-media.has-addon:not(.has-rolls) .et-addon-plus { display: none; }
/* Samo w kadrze pudełko potrzebuje innej skali niż w układzie z rolkami:
 * 0.55 było za duże, 0.44 za małe — stanęło na 0.49. Po wjeździe rolek
 * wraca do pełnego rozmiaru. */
.woocommerce div.product div.images .et-has-stack.has-addon:not(.has-rolls) .et-pdp-tin img,
.et-has-stack.has-addon:not(.has-rolls) .et-pdp-tin img,
.et-builder-media.has-addon:not(.has-rolls) .et-addon-tin img { width: calc(var(--et-roll-w, 260px) * var(--et-tin-scale, .42) * 0.9); }

@media (max-width: 860px) {
  /* Jedno źródło dla stosu i znacznika — oba są dziećmi galerii.
   * (Wcześniej trzeba tu było jeszcze zbijać regułę `.et-stack`
   * z konfiguratora; ta ustawia zmienną na wspólnym przodku, więc
   * neutralizacja przestała być potrzebna.) */
  /* Na mobile kadr to prawie cała szerokość ekranu, więc mnożnik jest inny,
   * ale cel ten sam: ~68% wypełnienia. Poprzednie 52vw dawało 90%. */
  .woocommerce-product-gallery.et-has-stack { --et-roll-w: clamp(120px, 40vw, 280px); }
}


/* --- Metalowe pudełko: rolki chowają się do środka ------------------------ */

/* Znaczek metalowego pudełka: pod grafiką, w osi kolumny */
.et-media-art { position: relative; }
.et-addon-tin {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding-top: 14px;
  animation: et-tin-pop .4s cubic-bezier(.2,.9,.3,1.3) both;
}
.et-addon-tin[hidden] { display: none !important; }
.et-addon-plus {
  font-family: var(--font-heading);
  font-size: clamp(26px, calc(var(--et-roll-w, 260px) * 0.13), 40px);
  font-weight: 700;
  color: var(--color-brand-orange);
  text-shadow: 0 2px 10px rgba(0,0,0,.6);
  line-height: 1;
}
/* Szerokość ustawia blok kompozycji wyżej (zależy od tego, czy w kadrze są
 * rolki). Tu zostaje tylko wygląd samego obrazka — inaczej ta reguła, jako
 * późniejsza przy równej sile selektora, nadpisywałaby tamtą. */
.et-builder-media .et-addon-tin img,
.et-addon-tin img {
  height: auto;
  background: transparent !important;  /* zbija .et-builder-media img { background:#fff } */
  border-radius: 0 !important;
  filter: drop-shadow(0 10px 16px rgba(0,0,0,.55));
}
@keyframes et-tin-pop {
  0%   { opacity: 0; transform: translateY(12px) scale(.88); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .et-addon-tin { animation: none; } }




/* Margines rezerwujący miejsce POD grafiką był potrzebny, gdy znaczek
 * pudełka wypadał poniżej kadru (`top: 100%`). Od czasu przeniesienia
 * kompozycji na układ poziomy znaczek mieści się w kadrze, więc rezerwacja
 * zostawiałaby tylko pustą dziurę pod konfiguratorem. */


/* Miniatura zestawu w koszyku */
.et-mini-stack {
  display: inline-flex;
  flex-direction: column-reverse;
  align-items: center;
  justify-content: center;
  width: 64px;
  padding: 4px 0;
}
.et-mini-roll {
  width: 52px; height: 13px;
  margin-top: -3px;
  border-radius: 50%;
  background-color: var(--roll, #8a8a8a);
  background-image: linear-gradient(90deg, rgba(0,0,0,.5), rgba(255,255,255,.22) 50%, rgba(0,0,0,.5));
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
}

/* Linia zapewnień nad przyciskiem */
.et-reassurance {
  /* Dol 11 px pilnowany tutaj: w Personalizacji stoi 9 px (audyt D3) -
     wlasciciel powinien podniesc to ustawienie, ale nawet gdy nie, napis
     „4 rolki · 8mm×10m" nie zejdzie ponizej czytelnosci. */
  font-size: max(11px, var(--et-reassure-size, 12px));
  letter-spacing: .02em;
  color: var(--fg-faint);
  margin: 0 0 10px;
}

/* Sticky: cena + informacja o darmowej dostawie */
.et-sticky-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;                 /* pozwala tekstowi się zwężać zamiast wychodzić pod przycisk */
}
.et-sticky-ship {
  font-size: 11px;
  line-height: 1.3;
  color: var(--fg-faint);
  white-space: normal;          /* zawija zamiast uciekać w bok */
  overflow-wrap: anywhere;
}
.et-sticky-ship.is-done { color: var(--color-brand-orange); }


/* Miniatura stosu w blokowym koszyku i podsumowaniu */
.wc-block-cart-items__row .et-mini-stack,
.wc-block-components-order-summary-item .et-mini-stack {
  width: 100%;
  min-width: 52px;
  padding: 6px 0;
}
.wc-block-components-order-summary-item .et-mini-roll { width: 42px; height: 11px; }


/* Sticky: notka o dostawie w osobnym wierszu nad ceną i przyciskiem */
.et-builder-sticky .et-sticky-ship {
  display: block;
  width: 100%;
  font-size: 11px;
  line-height: 1.25;
  color: var(--fg-faint);
  text-align: center;
}
.et-builder-sticky .et-sticky-ship:empty { display: none; }
.et-sticky-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
}
.et-builder-sticky .et-sticky-price { flex: 0 0 auto; font-size: 20px; }
.et-builder-sticky .et-sticky-btn {
  flex: 1 1 auto;
  max-width: none;
  font-size: 13px;
  padding: 12px 18px;
  overflow: visible;
  text-overflow: clip;
}


/* Koszyk/checkout (bloki): cechy pozycji jedna pod drugą, bez separatorów „/” */
.wc-block-components-product-details,
.wc-block-components-product-details__description {
  display: block !important;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
.wc-block-components-product-details__item,
li.wc-block-components-product-details__item {
  display: block !important;
  margin: 0 0 2px;
  padding: 0;
  line-height: 1.45;
}
/* separatory bloków (ukośniki / przecinki dorysowywane w CSS) */
.wc-block-components-product-details__item::after,
.wc-block-components-product-details__item::before,
.wc-block-components-product-details li::after,
.wc-block-components-product-details li::before {
  content: none !important;
}
.wc-block-components-product-details__name {
  color: var(--fg-faint);
  font-weight: 400;
}
.wc-block-components-product-details__value { color: var(--fg-default); }


/* Bloki: lista cech pozycji — selektory strukturalne (klasy li są generowane z nazw cech) */
.wc-block-components-product-details,
ul.wc-block-components-product-details {
  display: block !important;
  margin: 6px 0 0 !important;
  padding: 0 !important;
  list-style: none !important;
}
.wc-block-components-product-details > li {
  display: block !important;
  margin: 0 0 2px !important;
  padding: 0 !important;
  line-height: 1.45;
}
.wc-block-components-product-details > li::after,
.wc-block-components-product-details > li::before {
  content: none !important;
  display: none !important;
}
.wc-block-components-product-details > li > span { display: inline; }


/* Kolory jako jedna cecha: etykieta nad wartością, wartość w kolumnie */
.wc-block-components-product-details > li { white-space: normal; }
.wc-block-components-product-details__name { display: block; margin-bottom: 1px; }
.wc-block-components-product-details__value { display: block; }


/* Wartość cechy pozycji: zachowaj łamanie wierszy z PHP */
.wc-block-components-product-details__value,
.wc-block-components-product-details > li {
  white-space: pre-line;
}
.wc-block-components-product-details__name { white-space: normal; }


/* Kupon w checkoucie: panel musi być klikalny (blokada dotyczy tylko podsumowania) */
.wp-block-woocommerce-checkout-order-summary-coupon-form-block,
.wc-block-components-totals-coupon,
.wc-block-components-totals-coupon .wc-block-components-panel__button,
.wc-block-components-totals-coupon__form,
.wc-block-components-totals-coupon__input,
.wc-block-components-totals-coupon__button {
  pointer-events: auto !important;
  cursor: pointer !important;
}
.wc-block-components-totals-coupon .wc-block-components-panel__button svg,
.wc-block-components-totals-coupon .wc-block-components-panel__button-icon {
  display: inline-block !important;   /* strzałka rozwijania wraca */
  opacity: 1 !important;
}
.wc-block-components-totals-coupon__input input { cursor: text !important; }
.wc-block-components-totals-coupon__form { margin-top: 10px; }


/* Baner zgód (cookies) + Consent Mode V2 */
.egotape-consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  background: var(--bg-surface);
  border-top: 1px solid var(--border-default);
  box-shadow: var(--shadow-2);
  padding: 18px var(--et-gutter, 28px);
}
.egotape-consent-banner--hidden { display: none; }
.egotape-consent-banner__inner {
  max-width: var(--et-container, 1320px);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}
.egotape-consent-banner__body { flex: 1 1 380px; }
.egotape-consent-banner__title {
  margin: 0 0 6px;
  font-family: var(--font-heading);
  font-size: 16px;
  letter-spacing: .02em;
  color: var(--fg-default);
}
.egotape-consent-banner__text {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-muted);
}
.egotape-consent-banner__text:last-child { margin-bottom: 0; }

/* Reszta wyjaśnienia pod rozwinięciem. Zmierzone: baner zajmował 66%
   ekranu telefonu i był `fixed`, więc zasłaniał cenę i „Dodaj do koszyka".
   Na desktopie miejsca nie brakuje, więc tam zostaje otwarte. */
.egotape-consent-banner__wiecej { margin: 0; }
.egotape-consent-banner__wiecej > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--color-brand-orange);
  padding: 6px 0;
  min-height: 44px; /* cel dotyku (D5) */
  display: inline-flex; align-items: center;
  list-style: none;
}
/* Rząd „Więcej" + „Dostosuj": pełna szerokość pod treścią i przyciskami. */
.egotape-consent-banner__more {
  flex: 1 1 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.egotape-consent-banner__more .egotape-consent-banner__wiecej { flex: 1 1 auto; min-width: 0; }
.egotape-consent-banner__more .egotape-consent-banner__btn--link { flex: 0 0 auto; padding-left: 0; padding-right: 0; }
.egotape-consent-banner__wiecej > summary::-webkit-details-marker { display: none; }
.egotape-consent-banner__wiecej > summary::after { content: " ▾"; }
.egotape-consent-banner__wiecej[open] > summary::after { content: " ▴"; }
.egotape-consent-banner__wiecej .egotape-consent-banner__text { margin-top: 8px; }

/* TAK SAMO NA KAŻDEJ SZEROKOŚCI. Kusiło, żeby na desktopie pokazać całość
   od razu - ale zamknięte `<details>` chowa treść przez styl przeglądarki,
   a nie przez `display`, i odkrycie jej regułą CSS działa różnie
   w różnych wersjach. Reguła, która czasem działa, jest gorsza od jednego
   zachowania wszędzie. */
.egotape-consent-banner__text a { color: var(--color-brand-orange); text-decoration: underline; }
.egotape-consent-banner__actions {
  display: flex;
  gap: 12px;
  flex: 0 0 auto;
  flex-wrap: wrap;
}

/* NA TELEFONIE: dwa przyciski decyzji w jednym rzędzie, „dostosuj" pod
   nimi jako odnośnik. Trzy przyciski pełnej szerokości pod sobą zabierały
   160 px z 844 - a to jest ekran, na którym ma się zmieścić produkt. */
@media (max-width: 640px) {
  .egotape-consent-banner { padding: 12px var(--et-gutter, 18px) 8px; }
  .egotape-consent-banner__inner { gap: 8px; }
  .egotape-consent-banner__title { font-size: 15px; margin-bottom: 4px; }
  .egotape-consent-banner__text { font-size: 13px; line-height: 1.4; margin-bottom: 0; }
  .egotape-consent-banner__actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    width: 100%;
  }
  /* Dwie decyzje w jednej linii tekstu: przy 13 px „Zaakceptuj wszystkie"
     łamało się na dwa wiersze i przycisk miał 62 px zamiast 44. */
  .egotape-consent-banner__actions .egotape-consent-banner__btn { padding: 12px 6px; min-height: 44px; font-size: 12px; letter-spacing: .02em; }
  /* „Więcej" i „Dostosuj" w jednym rzędzie, zwarto (audyt U4: 300 px -> ok. 200 px). */
  .egotape-consent-banner__more { gap: 12px; align-items: center; }
  .egotape-consent-banner__more .egotape-consent-banner__btn--link { min-height: 44px; padding: 8px 0; font-size: 12px; }
  .egotape-consent-banner__wiecej > summary { font-size: 12px; padding: 0; }
}
.egotape-consent-banner__btn {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-size: 13px;
  padding: 10px 22px;
  border-radius: var(--radius-3);
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--fg-default);
  cursor: pointer;
  transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.egotape-consent-banner__btn--accept {
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
  color: var(--color-ink-1);
}
@media (hover: hover) and (pointer: fine) {
  .egotape-consent-banner__btn--accept:hover { background: var(--color-brand-orange-bright); border-color: var(--color-brand-orange-bright); }
  .egotape-consent-banner__btn--reject:hover { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
}
.egotape-consent-banner__btn--link {
  border-color: transparent;
  background: transparent;
  text-decoration: underline;
  text-underline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
  .egotape-consent-banner__btn--link:hover { color: var(--color-brand-orange); }
}
@media (max-width: 640px) {
  .egotape-consent-banner__inner { flex-direction: column; align-items: stretch; }
  /* `flex: 1 1 380px` przy kolumnie znaczy 380 px WYSOKOSCI, a nie
     szerokosci - i to bylo prawdziwe zrodlo banera zajmujacego 66% ekranu
     telefonu. Trzy linijki tekstu wygladaly na osiem, bo pod nimi stalo
     260 px pustego miejsca wymuszonego przez baze elastyczna. */
  .egotape-consent-banner__body { flex: 0 1 auto; }

  /* PASEK "DODAJ DO KOSZYKA" USTEPUJE BANEROWI ZGOD.
     Pasek ma `z-index: 2147483000` i zaslanial dolne 78 px banera - czyli
     przycisk "Dostosuj zgody", ktory jest jedna z trzech rownorzednych
     odpowiedzi na pytanie o zgode. Podbijanie z-indeksu banera byloby
     wyscigiem; chowamy pasek, bo dopoki pytanie stoi, kupowanie i tak
     jest zaslonione.
     `:has()` obsluguja wszystkie dzisiejsze przegladarki, a tam, gdzie nie -
     zostaje dzisiejsze zachowanie, czyli nic sie nie pogarsza. */
  /* Zgoda z poprzedniej wizyty chowa baner klasa na <html> (inc/analytics.php),
     a nie klasa `--hidden` - bez tego warunku pasek znikal u KAZDEGO, kto
     juz odpowiedzial na pytanie o cookies (zgloszenie wlasciciela 2026-09-06). */
  html:not(.et-zgoda-podjeta) body:has(.egotape-consent-banner:not(.egotape-consent-banner--hidden)) .et-builder-sticky {
    display: none;
  }
  .egotape-consent-banner__actions { justify-content: stretch; }
  .egotape-consent-banner__btn { flex: 1 1 0; }
}

.egotape-consent-reopen {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--fg-muted);
  text-decoration: underline;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .egotape-consent-reopen:hover { color: var(--color-brand-orange); }
}

/* Panel szczegółowy zgód (kategorie) */
.egotape-consent-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, .6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.egotape-consent-overlay--hidden { display: none; }
.egotape-consent-panel {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-2);
  max-width: 640px;
  width: 100%;
  /* `dvh`: na iPhonie `vh` liczy się od okna bez pasków Safari, więc przy
     widocznym pasku adresu panel wychodził poza ekran górą i dołem
     (wyśrodkowany). `vh` zostaje dla przeglądarek sprzed `dvh`. */
  max-height: 86vh;
  max-height: 86dvh;
  overflow-y: auto;
  padding: 28px;
}
.egotape-consent-panel__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}
.egotape-consent-panel__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 22px;
  letter-spacing: .02em;
  color: var(--fg-default);
}
.egotape-consent-panel__close {
  background: none;
  border: none;
  font-size: 26px;
  line-height: 1;
  color: var(--fg-muted);
  cursor: pointer;
  padding: 0 4px;
  /* Cel dotyku 44x44 zamiast 30x26 (audyt iOS 2026-09-26). Ujemne marginesy
     trzymają krzyżyk i miejsce w układzie tam, gdzie były (30x26) - rośnie
     pole dotyku, a tytuł obok nie traci ani piksela. */
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
  margin: -9px -7px;
}
@media (hover: hover) and (pointer: fine) {
  .egotape-consent-panel__close:hover { color: var(--color-brand-orange); }
}
.egotape-consent-panel__intro {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-muted);
}
.egotape-consent-select-all {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--fg-default);
  padding: 10px 0;
  border-top: 1px solid var(--border-default);
  border-bottom: 1px solid var(--border-default);
  margin-bottom: 8px;
  cursor: pointer;
}
.egotape-consent-categories {
  display: flex;
  flex-direction: column;
}
.egotape-consent-category {
  padding: 14px 0;
  border-bottom: 1px solid var(--border-default);
}
.egotape-consent-category:last-child { border-bottom: none; }
.egotape-consent-category__head { display: flex; }
.egotape-consent-category__toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
.egotape-consent-category__toggle input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--color-brand-orange);
  cursor: pointer;
  flex: 0 0 auto;
}
.egotape-consent-category__toggle input[type="checkbox"]:disabled { cursor: not-allowed; opacity: .7; }
.egotape-consent-category__title {
  font-family: var(--font-heading);
  font-size: 15px;
  letter-spacing: .01em;
  color: var(--fg-default);
}
.egotape-consent-category__desc {
  margin: 8px 0 0 28px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-muted);
}
.egotape-consent-panel__actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  margin-top: 20px;
  flex-wrap: wrap;
}
@media (max-width: 640px) {
  .egotape-consent-panel { padding: 20px; }
  .egotape-consent-category__desc { margin-left: 0; }
  .egotape-consent-panel__actions .egotape-consent-banner__btn { flex: 1 1 0; }
}

/* Powiadomienie „Wróć gdy dostępne" na stronie wyprzedanego produktu */
.et-stock-notify {
  margin: 18px 0;
  padding: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.et-stock-notify__label {
  margin: 0 0 10px;
  font-size: 14px;
  color: var(--fg-default);
}
.et-stock-notify__row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.et-stock-notify__input {
  flex: 1 1 220px;
  padding: 10px 14px;
  border-radius: var(--radius-3);
  border: 1px solid var(--border-input);
  background: var(--bg-input);
  color: var(--fg-default);
  font-size: 16px;
}
.et-stock-notify__input:disabled { opacity: .6; }
.et-stock-notify__submit { flex: 0 0 auto; }
.et-stock-notify__msg {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--fg-muted);
}
@media (max-width: 480px) {
  .et-stock-notify__row { flex-direction: column; align-items: stretch; }
}

/* Komunikat stanu magazynowego WooCommerce (np. „Pozostało tylko: X") */
p.stock {
  margin: 10px 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .02em;
}
p.stock.in-stock { color: var(--color-brand-orange); }
p.stock.out-of-stock { color: var(--fg-muted); font-weight: 400; }


/* =========================================================================
 * Przełącznik języka (flagi)
 * Renderuje się tylko przy włączonej dwujęzyczności — patrz inc/i18n.php.
 * ====================================================================== */
.et-lang { display: inline-flex; align-items: center; gap: 4px; margin-right: 4px; }
.et-lang-item {
  display: inline-flex; align-items: center; justify-content: center;
  /* 44px celu dotykowego — ten sam standard co reszta ikon w nagłówku. */
  min-width: 44px; min-height: 44px;
  border-radius: var(--radius-2);
  opacity: .45;
  transition: opacity .2s var(--ease), background .2s var(--ease);
}
.et-lang-item:focus-visible { opacity: 1; background: var(--bg-surface); }
@media (hover: hover) and (pointer: fine) {
  .et-lang-item:hover { opacity: 1; background: var(--bg-surface); }
}
.et-lang-item.is-active { opacity: 1; }
.et-flag { display: block; border-radius: 2px; }
@media (max-width: 560px) {
  /* Na wąskim ekranie pokazujemy tylko flagę nieaktywnego języka — sam
   * przełącznik, bez pary. Aktywna flaga nic nie wnosi, a zabiera miejsce
   * w i tak ciasnym rzędzie ikon. */
  .et-lang-item.is-active { display: none; }
}


/* =========================================================================
 * Rangi klientów (pasy)
 * ====================================================================== */
.et-rank-box {
  margin: 0 0 24px;
  padding: 18px 20px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.et-rank-box h3 {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
}
.et-rank { display: inline-flex; align-items: center; gap: 12px; }
/* ZNACZNIK KOLORU RANGI - SCHOWANY RAZEM Z ODSTĘPEM (zgłoszenie #6).

   Od 2026-07-30 (be09c032, rozdzielenie pasa i rangi) znacznik nazywa się
   `.et-rank-mark`, a jego styl został pod starą nazwą `.et-rank-belt`.
   Pusty `span` miał więc 0 × 0 px i nikt go nie widział, ale `gap: 12px`
   rodzica dalej odsuwał nazwę: „Wędrowiec” stał 12 px na prawo od „Cześć,
   …” w nagłówku konta, a tak samo w obu kaflach rangi w kokpicie.
   Po dwóch miesiącach bez znacznika nie przywracamy go po cichu - to
   decyzja o wyglądzie, nie naprawa. Chowamy go, a z nim znika odstęp. */
.et-rank-mark { display: none; }
.et-rank-label {
  font-family: var(--font-heading);
  font-size: 20px; font-weight: 600;
  letter-spacing: .04em;
  color: var(--fg-default);
}
.et-rank-next {
  display: block;
  margin-top: 10px;
  font-size: 14px;
  color: var(--fg-muted);
}
.et-rank-next.is-max { color: var(--color-brand-orange); }


/* =========================================================================
 * Karta produktu na siatce — odświeżenie
 *
 * Problem wyjściowy: zdjęcia produktowe mają lite białe tło, więc każdy kafel
 * był identycznym białym kwadratem na ciemnej karcie. Tożsamość bóstwa niósł
 * wyłącznie medalion na hover, a ten jest wyłączony na dotyku — czyli na
 * telefonie marka nie pokazywała się wcale.
 *
 * Nie da się tego naprawić samym CSS-em tła (biel jest w plikach zdjęć),
 * więc kolor bóstwa wchodzi tam, gdzie mamy nad nim kontrolę: w poświatę
 * pod zdjęciem, w krążek ze znakiem i w podświetlenie karty przy najechaniu.
 * ====================================================================== */

/* Poświata koloru bóstwa u dołu kadru — pod zdjęciem, nad białym tłem.
 * Delikatna, bo ma sugerować światło sceny, a nie kolorować produkt. */
.et-product-well.has-talisman::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 42%;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--et-talisman) 42%, transparent) 0%,
    transparent 100%);
  pointer-events: none;
  z-index: 1;
}

/* Krążek ze znakiem bóstwa — widoczny zawsze, też na telefonie.
 * Wchodzi na krawędź kadru, żeby czytał się i na zdjęciu, i na karcie. */
/* Opakowanie kadru — pozycjonuje znaczek i NIE przycina zawartości,
 * w odróżnieniu od samego kadru. */
.et-well-wrap { position: relative; }

.et-talisman-badge {
  position: absolute;
  left: 18px;
  /*
   * Na zdjęciu, w jego lewym dolnym rogu — ale w CAŁOŚCI wewnątrz kadru.
   *
   * Wcześniejsza wersja przecinała dolną krawędź i wyglądała na płasko
   * ściętą (zrzuty 18 i 19 w `audyt_screeny/`); następna wypadła w całości
   * pod zdjęciem i zostawiała pas pustki. Tu nie ma granicy do przecięcia:
   * krążek siedzi nad zdjęciem, z marginesem od brzegów.
   *
   * Pozycjonujemy względem `.et-well-wrap`, nie `.et-product-well` — ten
   * drugi ma `overflow: hidden` (konieczne przy powiększeniu zdjęcia na
   * hover) i przyciąłby cień krążka.
   */
  bottom: 14px;
  top: auto;
  z-index: 3;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--et-talisman, var(--color-brand-orange));
  /* Pierścień ratuje skrajne kolory: Białobóg (#DCDBD6) na jasnym zdjęciu
   * i Czarnobóg (#262730) na ciemnej karcie. */
  box-shadow: 0 0 0 2px rgba(255,255,255,.22), 0 6px 16px rgba(0,0,0,.45);
  /* Zabezpieczenie: cokolwiek by się nie policzyło, nic nie wyjdzie poza okrąg. */
  overflow: hidden;
  /* Pierścień w kolorze karty jest teraz zbędny (krążek leży na jednolitym
   * tle), ale jasna obwódka zostaje — ratuje Czarnobóg (#262730), który bez
   * niej zlewałby się z ciemną kartą. */
  transition: transform .35s var(--ease);
}
/*
 * 64%, a nie „na oko".
 *
 * Medaliony są kwadratowe (1:1), a kwadrat wpisany w koło może mieć bok
 * najwyżej d/√2 ≈ 70,7% średnicy — powyżej tego rogi grafiki wychodzą poza
 * okrąg. Pierwsza wersja miała 76% i medalion wystawał u góry, gdzie rysunek
 * jest najgęstszy. 64% zostawia jeszcze ~2 px marginesu na cień.
 */
/*
 * Selektor MUSI być mocniejszy niż reguła WooCommerce:
 *   .woocommerce ul.products li.product a img { width:100%; height:auto; margin:0 0 1em }
 * (3 klasy — bije samo `.et-talisman-badge img`, które ma jedną).
 *
 * Najgroźniejszy jest tam `margin: 0 0 1em`: w kontenerze centrującym flexem
 * dolny margines wypycha grafikę do GÓRY, przez co talizman siadał przy
 * górnej krawędzi krążka. Dopóki znaczek leżał w kadrze, chroniła go reguła
 * motywu o czterech klasach (zerowała margines); po przeniesieniu poza kadr
 * ta ochrona zniknęła i reguła WooCommerce zaczęła wygrywać.
 */
.woocommerce ul.products li.product .et-talisman-badge img,
.et-talisman-badge img {
  /*
   * 95% — praktyczne maksimum, wyliczone, nie dobrane.
   *
   * Wcześniejsze limity (70,7%, potem 85,4%) opierały się na przekątnej
   * PROSTOKĄTA otaczającego rysunek. To było za ostrożne: medaliony są
   * kształtem zbliżonym do koła, więc rogi tego prostokąta są przezroczyste
   * i nie mają czego wystawiać poza okrąg.
   *
   * Właściwa miara to maksymalny promień nieprzezroczystego piksela od
   * środka kanwy. Zmierzony GD-em dla wszystkich ośmiu medalionów wynosi
   * 0,394–0,505 ramki. Ogranicza nas Perun (0,505), czyli ramka może sięgnąć
   * 99,1% średnicy krążka, zanim cokolwiek widocznego wyjdzie poza okrąg.
   *
   * Skala jest PER MEDALION, podawana z PHP w `--et-medallion-scale`.
   * Każdy ma inny margines przezroczystości wokół rysunku (promień treści
   * 0,394–0,505 ramki), więc jedna wspólna wartość albo zostawiała jedne
   * za małe, albo wypychała inne poza okrąg. Przy swojej wartości każdy
   * rysunek dotyka krawędzi.
   *
   * Wartości > 100% są normalne: ramka jest wtedy większa od krążka, ale
   * wystają z niej wyłącznie przezroczyste rogi, które i tak przycina
   * `overflow: hidden`.
   */
  flex: 0 0 auto;
  width: var(--et-medallion-scale, 99%);
  height: var(--et-medallion-scale, 99%);
  /*
   * KONIECZNE: globalne `img { max-width: 100% }` (początek pliku) ucinało
   * każdą skalę powyżej 100%, przez co wartości 116%, 127% i 130% dawały
   * dokładnie ten sam obraz. Bez tego ekran „Talizmany" wygląda na zepsuty.
   */
  max-width: none;
  max-height: none;
  margin: 0;
  display: block;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.45));
}
/* Tylko pod kursorem - na iPhonie krążek zostawał powiększony po dotknięciu. */
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product:hover .et-talisman-badge { transform: scale(1.08); }
}

/* Miękka krawędź białego kadru — bez tego zdjęcie kończy się twardą linią
 * bieli na ciemnej karcie.
 *
 * WZMOCNIONE 2026-08-13 po przeglądzie mobilnym: „zdjęcia produktów na
 * białym tle świecą w ciemnym UI, duże białe prostokąty rozbijają mrok
 * brandu. Idealnie: packshoty na ciemnym tle albo chociaż tło #171717
 * + winieta".
 *
 * Pierwsza część tego zdania jest poza zasięgiem arkusza stylów - biel
 * siedzi w plikach zdjęć i zdejmie ją dopiero nowa sesja zdjęciowa. Druga
 * część to jest dokładnie ta warstwa: cień od środka był wyłącznie przy
 * DOLNEJ krawędzi (`inset 0 -24px`), więc trzy pozostałe boki nadal kończyły
 * się ostrą linią bieli, a najbardziej świecił róg między dwiema kartami.
 *
 * Teraz winieta obchodzi cały kadr. Środek zostaje przezroczysty - tam leży
 * produkt i to on ma być widoczny; ciemnieją same krawędzie, mocniej
 * w rogach niż w połowie boku.
 *
 * Poświata koloru bóstwa siedzi PIĘTRO NIŻEJ (`::after`, `z-index: 1`),
 * więc winieta ją przygasza. Stąd przezroczysty pas u dołu w drugim
 * gradiencie: bez niego kolor bóstwa - jedyny nośnik tożsamości produktu
 * na telefonie - zniknąłby pod czernią. */
.et-product-well::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  box-shadow: inset 0 -24px 40px -24px rgba(0,0,0,.35);
  background:
    radial-gradient(118% 118% at 50% 46%, transparent 40%, rgba(11, 11, 11, .34) 76%, rgba(11, 11, 11, .74) 100%),
    linear-gradient(to bottom, rgba(11, 11, 11, .30) 0%, transparent 18%);
}

/* Podświetlenie karty przy najechaniu — bursztyn, ten sam co przy pasku
 * subskrypcji, żeby reakcja na kursor była w całym sklepie jedna.
 *
 * Wcześniej stało tu `color-mix(… var(--et-talisman) …)`, co dawało BIAŁY
 * kontur: `--et-talisman` jest ustawiane dopiero na `.et-product-well`
 * wewnątrz karty, a nie na samym `li`. Nierozwiązana zmienna czyni
 * `color-mix()` nieprawidłowym, a nieprawidłowy `border-color` spada do
 * `currentColor` — czyli do jasnego koloru tekstu karty. Kolor bóstwa nigdy
 * się tam nie pojawiał, choć taki był zamysł.
 *
 * Tylko pod kursorem: na iPhonie dotknięcie „Dodaj do koszyka" zostawiało
 * pomarańczową ramkę na całej karcie (zrzut #4, 2026-09-26). */
@media (hover: hover) and (pointer: fine) {
  .woocommerce ul.products li.product:hover {
    border-color: var(--color-brand-orange);
  }
}

/* Hierarchia: nazwa bóstwa jest tym, co klient rozpoznaje — niech będzie
 * mocniejsza od ceny, a nie odwrotnie. */
.woocommerce ul.products li.product .woocommerce-loop-product__title { font-size: 17px; line-height: 1.25; }

@media (max-width: 560px) {
  .et-talisman-badge { width: 36px; height: 36px; left: 11px; bottom: 11px; }
  .woocommerce ul.products li.product .woocommerce-loop-product__title { font-size: 15px; }
}


/* =========================================================================
 * Karta produktu — tożsamość bóstwa i sygnały zaufania
 * ====================================================================== */

/* Medalion nad tytułem. Klient przychodzi z siatki, na której każdy produkt
 * ma kolorowy znak — karta bez niego wyglądała jak sklep bez marki. */
/*
 * Krążek po lewej od nazwy produktu, nie nad nią.
 *
 * Jako osobny blok nad tytułem zostawiał pas pustej przestrzeni w kolumnie
 * zakupowej. Float wpuszcza tytuł obok, więc oba elementy dzielą jedną
 * wysokość zamiast układać się jeden pod drugim.
 *
 * `overflow: hidden` na tytule tworzy własny kontekst formatowania — dzięki
 * temu tytuł staje OBOK krążka zamiast go oblewać, co przy dwuwierszowej
 * nazwie wyglądałoby przypadkowo.
 * `clear: left` na cenie zamyka float, żeby nie wpływał na resztę kolumny.
 */
.et-pdp-talisman { float: left; margin: 4px 18px 10px 0; }

/*
 * Tytuł i cena stają OBOK krążka, jeden pod drugim — cena należy do nazwy,
 * nie do ikony. `overflow: hidden` daje obu własny kontekst formatowania,
 * więc ustawiają się przy floacie zamiast go oblewać (przy dwuwierszowej
 * nazwie oblewanie wygląda przypadkowo).
 */
.woocommerce div.product .summary .product_title,
.woocommerce div.product .summary .price { overflow: hidden; }
/* Ocena między nazwą a ceną potrzebuje tego samego (audyt iOS 2026-09-26):
   bez własnego kontekstu oblewała krążek i przy 320 px „(4 opinie" stało
   obok krążka, a „klienta)" pod nim, od lewej krawędzi kolumny.
   `flow-root` zamiast `overflow: hidden` - nie przycina obwódki fokusu. */
.woocommerce div.product .summary .woocommerce-product-rating { display: flow-root; }

/* Float zamykamy dopiero pod ceną — dalsza część kolumny wraca na pełną szerokość. */
.woocommerce div.product .summary .woocommerce-product-details__short-description,
.woocommerce div.product .summary form.cart { clear: left; }
.et-pdp-talisman-disc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /*
   * Średnica = wysokość nazwy + wiersz ceny, a nie dobrana liczba.
   * Tytuł ma `clamp(2rem, 4vw, 3rem)`, cena 26px — krążek skaluje się razem
   * z tytułem, więc proporcja trzyma się na każdej szerokości ekranu.
   */
  --et-pdp-title: clamp(2rem, 4vw, 3rem);
  border-radius: 999px;
  background: var(--et-talisman, var(--color-brand-orange));
  /* Jasna obwódka ratuje skrajne kolory: Czarnobóg (#262730) zlałby się
   * z ciemnym tłem, Białobóg (#DCDBD6) potrzebuje odcięcia od jasnych zdjęć. */
  box-shadow: 0 0 0 2px rgba(255,255,255,.22), 0 8px 20px rgba(0,0,0,.5);
}
/* Ta sama pułapka co na siatce: WooCommerce ustawia obrazkom w karcie
 * `width:100%; height:auto; margin:0 0 1em`, a dolny margines wypycha
 * zawartość do góry we flexie. Stąd jawne wyzerowanie. */
.et-pdp-talisman-disc img {
  /* Skala per medalion — patrz komentarz przy znaczku na siatce.
   * `max-width/height: none` z tego samego powodu: globalne `img
   * { max-width: 100% }` ucinałoby skale powyżej 100%. */
  flex: 0 0 auto;
  width: var(--et-medallion-scale, 99%);
  height: var(--et-medallion-scale, 99%);
  max-width: none;
  max-height: none;
  margin: 0;
  display: block;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.45));
}

/* Sygnały zaufania pod przyciskiem „Do koszyka" — odpowiedzi na wątpliwości
 * dokładnie tam, gdzie zapada decyzja, zamiast na osobnych podstronach. */
.et-pdp-trust {
  list-style: none;
  margin: 16px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--border-default);
  display: grid;
  gap: 9px;
}
.et-pdp-trust li {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 14px;
  color: var(--fg-muted);
}
.et-pdp-trust svg {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  color: var(--color-brand-orange);
}
@media (min-width: 561px) {
  /* Dwie kolumny na szerszym ekranie — cztery pozycje w pionie robiły
   * niepotrzebnie długą kolumnę i odpychały opis produktu. */
  .et-pdp-trust { grid-template-columns: 1fr 1fr; gap: 9px 18px; }
}

/* Dostępność pod ceną na karcie produktu. */
.et-pdp-stock {
  clear: left;
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-success);
}
.et-pdp-stock::before { content: "● "; }
/* Niski stan wyróżniony, ale bez krzyku — to informacja, nie alarm. */
.et-pdp-stock.is-low { color: var(--color-brand-orange); }

/* --- Kolumna zakupowa: nazwa, cena i dostępność jako jeden blok ----------
 *
 * Domyślnie tytuł miał `margin-bottom: .5em` (przy 48px to 24px), a cena
 * marginesy akapitu — razem robiło się kilkadziesiąt pikseli pustki między
 * trzema informacjami, które należą do siebie. Nazwa, cena i dostępność mają
 * czytać się jako jedna grupa, a dopiero potem zaczyna się opis.
 */
.woocommerce div.product .summary .product_title { margin-bottom: 8px; }
.woocommerce div.product .summary p.price { margin: 0 0 6px; }
.et-pdp-stock { margin: 0 0 18px; }

/* Krążek dobrany do wysokości całej grupy (nazwa + odstęp + cena), a nie
 * samej nazwy — po ściśnięciu marginesów grupa jest niższa niż wcześniej. */
.et-pdp-talisman-disc {
  width: calc(var(--et-pdp-title) + 40px);
  height: calc(var(--et-pdp-title) + 40px);
}

/* --- Karta produktu: dodatek a akcja zakupu ------------------------------
 *
 * DECYZJA PROJEKTOWA: dodatek NIE stoi w jednym rzędzie z ilością
 * i przyciskiem. Próbowaliśmy tak i to nie był dobry układ:
 *
 * 1. Checkbox w ramce obok przycisku czyta się jak drugi przycisk. Dodatek
 *    jest WYBOREM, a nie akcją — postawiony w rzędzie akcji zaciera hierarchię
 *    i konkuruje z „Dodaj do koszyka".
 * 2. Etykieta „METALOWE PUDEŁKO (+10,00 zł)" potrzebuje ~236px. W kolumnie
 *    zakupowej (~500px) po odjęciu ilości, przycisku i odstępów tyle nie
 *    zostaje, więc `flex-shrink` ją ściskał, a `overflow` ucinał — po cichu.
 * 3. Wyrównanie w pionie checkboxa z tekstem względem przycisku jest z natury
 *    kruche: każda zmiana kroju, paddingu czy długości etykiety je psuje.
 *    Właśnie to wracało przy kolejnych poprawkach.
 *
 * Dlatego dodatek dostaje własny, pełnej szerokości wiersz NAD akcją — jako
 * opcja produktu, obok koloru i ilości. Przycisk zakupu zostaje sam w swoim
 * rzędzie i dominuje, tak jak powinien.
 */
.woocommerce div.product form.cart {
  --et-cart-control-h: 52px;   /* 52px, nie 46px — wygodny cel dotykowy */
  align-items: center;
}

/* Dodatek jako opcja: pełna szerokość, tekst się mieści, nic nie jest ucinane. */
.woocommerce div.product form.cart .egotape-addons {
  flex-basis: 100%;
  margin: 0 0 14px;
}
.woocommerce div.product form.cart .egotape-box-addon label {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  min-height: var(--et-cart-control-h);
  padding: 10px 16px;
  white-space: normal;
  cursor: pointer;
}

/* Stan zaznaczenia. Wcześniej jedynym potwierdzeniem wyboru był natywny
 * checkbox — łatwy do przeoczenia przy dopłacie, która zmienia cenę. */
.woocommerce div.product form.cart .egotape-box-addon label:has(input:checked) {
  border-color: var(--color-brand-orange);
  background: color-mix(in srgb, var(--color-brand-orange) 12%, var(--bg-surface));
}

/* Wiersz akcji: ilość wąska, przycisk wypełnia resztę i dominuje. */
.woocommerce div.product form.cart div.quantity .qty { height: var(--et-cart-control-h); }
.woocommerce div.product form.cart .single_add_to_cart_button {
  height: var(--et-cart-control-h);
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Przy 320 px przycisk (napis 128 px + 2x24 px) nie mieścił się obok pola
   ilości o 2 px i spadał do osobnego wiersza - pole ilości stało samo
   (audyt iOS 2026-09-26). Węższe wypełnienie trzyma jeden wiersz. */
@media (max-width: 360px) {
  .woocommerce div.product form.cart .single_add_to_cart_button { padding-left: 16px; padding-right: 16px; }
}

/* --- „−” I „+” PRZY ILOŚCI (2026-09-26) --------------------------------
   Właściciel: na telefonie ilość dało się tylko wpisać z klawiatury.
   Przyciski dokłada `inc/woocommerce.php` (tylko przy polu, które da się
   zmienić), zachowanie - `egotape.js`. Jedna ramka na całość, jak wybór
   ilości w koszyku (#5): przyciski 48 x 52 px, liczba na środku, 18 px
   (iPhone przybliża stronę przy polu poniżej 16 px).

   Jeden wiersz z przyciskiem zakupu, dopóki się mieści; ciaśniej - dwa
   wiersze, oba na całą szerokość. Bez zapytania o szerokość ekranu:
   `flex-grow` 1 przy ilości i 999 przy przycisku daje w jednym wierszu
   prawie całe wolne miejsce przyciskowi, a gdy przycisk spadnie niżej,
   każdy z nich wypełnia swój wiersz sam. */
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn) {
  display: flex; align-items: stretch;
  flex: 1 0 auto;
  margin: 0;
  height: var(--et-cart-control-h);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-3);
  background: var(--bg-input);
  overflow: hidden;
}
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn) .qty {
  flex: 1 1 auto;
  width: 48px; min-width: 48px; height: 100%;
  margin: 0; padding: 0;
  border: 0; border-radius: 0; background: transparent;
  text-align: center;
  font-size: 18px;
  -moz-appearance: textfield; appearance: textfield;
}
/* Strzałki pola liczby z komputerowych przeglądarek - obok są już przyciski. */
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn) .qty::-webkit-outer-spin-button,
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn) .qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn) .qty:focus { outline: none; }
.woocommerce div.product form.cart div.quantity:has(.et-qty-btn):focus-within { border-color: var(--color-brand-orange); }
.woocommerce div.product form.cart:has(.et-qty-btn) .single_add_to_cart_button { flex: 999 1 auto; }
.et-qty-btn {
  flex: 0 0 48px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 100%; min-height: 44px;
  margin: 0; padding: 0;
  border: 0; border-radius: 0;
  background: transparent;
  color: var(--fg-default);
  cursor: pointer;
  /* Szybkie „+ + +” palcem: bez tego iPhone bierze drugie dotknięcie za
     przybliżenie strony. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.et-qty-btn svg { display: block; }
.et-qty-btn:active:not(:disabled) { background: var(--color-ink-3); color: var(--color-brand-orange); }
.et-qty-btn:disabled { color: var(--fg-faint); cursor: default; }
.et-qty-btn:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) {
  .et-qty-btn:hover:not(:disabled) { color: var(--color-brand-orange); }
}

/* --- Przycisk InPost Pay na karcie produktu -------------------------------
   Wtyczka wstawia go hakiem `woocommerce_after_add_to_cart_button`, czyli do
   środka `form.cart`, który jest u nas rzędem flex z zawijaniem. Bez tych
   reguł przycisk dostawał resztkę miejsca obok listy zalet: 104 px
   szerokości, napis pod nim łamany co słowo i ucięty („Karta/Apple/Go",
   2026-09-26).

   Pełny wiersz i miejsce tuż pod „Dodaj do koszyka": wszystko, co stoi po
   przycisku zakupu (lista zalet, notka o darmowej wysyłce, pasek pudełka),
   dostaje `order: 1` i przesuwa się za InPost, zachowując swoją kolejność.
   `::after` to clearfix WooCommerce - w rzędzie flex jest zwykłym elementem
   i bez `order` stawał przed listą zalet, spychając ją o odstęp (12 px).
   Margines 10 px, który element InPostu ma z siebie, zerujemy - odstępy
   w formularzu robi `gap`, więc bez tego InPost stał 22 px pod przyciskiem
   zamiast 12 jak reszta wierszy. */
.woocommerce div.product form.cart > .izi-widget-placeholder { flex: 1 1 100%; min-width: 0; }
.woocommerce div.product form.cart > .izi-widget-placeholder inpost-izi-button { margin: 0; }
.woocommerce div.product form.cart > .single_add_to_cart_button ~ :not(.izi-widget-placeholder),
.woocommerce div.product form.cart::after { order: 1; }


/* =========================================================================
 * Pomocnik FAQ — dostawa, zwroty, dobór taśmy
 * ====================================================================== */
.et-faq {
  position: fixed; right: 18px; bottom: 18px; z-index: 70;
  transition: transform .24s var(--ease, ease), opacity .18s var(--ease, ease);
}
/* Klasę nadaje `egotape.js` przy przewijaniu w dół - powód tam, przy kodzie.
   Zjazd W DÓŁ, a nie samo zniknięcie: element, który odjeżdża w tę stronę,
   z której przyszedł, czyta się jako schowany, a nie jako zgaszony. */
.et-faq.is-hidden {
  transform: translateY(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}
/* Kto prosi o mniej ruchu, dostaje samo znikanie, bez jazdy. */
@media (prefers-reduced-motion: reduce) {
  .et-faq { transition: opacity .18s linear; }
  .et-faq.is-hidden { transform: none; }
}
/*
 * Domyślnie sam znak zapytania — okrągły, 52px, czyli wygodny cel dotykowy.
 * Pełna etykieta rozwija się dopiero przy najechaniu i tylko tam, gdzie
 * kursor istnieje (`@media (hover: hover)`); na dotyku nie ma czym najechać,
 * więc przycisk zostaje ikoną i nie zabiera miejsca na ekranie.
 */
.et-faq-toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: 0;
  width: 52px; height: 52px;
  padding: 0;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  border: none; border-radius: var(--radius-pill);
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 10px 26px rgba(0,0,0,.5);
  transition: width .28s var(--ease), padding .28s var(--ease), gap .28s var(--ease), transform .2s var(--ease);
}
.et-faq-toggle svg { width: 22px; height: 22px; flex: 0 0 auto; }
/* Etykieta zwinięta do zera, ale wciąż w drzewie — czytniki ekranu ją widzą. */
.et-faq-toggle > span {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-width .28s var(--ease), opacity .2s var(--ease);
}
/* =========================================================================
   ETYKIETA WYJEZDZA OBOK PRZYCISKU, A NIE Z NIEGO

   Wczesniej najechanie zmienialo szerokosc samego przycisku (52 px -> auto).
   `width` nie da sie plynnie animowac do `auto`, wiec pudelko skakalo,
   a poniewaz przycisk jest przyklejony do PRAWEJ krawedzi, jego lewy bok
   odjezdzal w prawo - spod kursora. Zmierzone: kursor na srodku (x=1396),
   po najechaniu przycisk 24 px szeroki w zakresie 1398..1422, czyli juz nie
   pod kursorem. Efekt: najezdzasz, przycisk ucieka, klikniecie ladzie w tlo
   i pomocnik wyglada na zepsuty. Znalezione audytem interakcji.

   Teraz przycisk ma STALE 52 px i nie rusza sie ani o piksel, a napis
   pojawia sie obok niego jako osobna plakietka. `pointer-events: none` na
   niej, zeby sama nie przejmowala klikniec.
   ====================================================================== */
@media (hover: hover) {
  .et-faq-toggle { position: relative; }
  .et-faq-toggle > span {
    position: absolute;
    right: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    max-width: none;
    padding: 9px 14px;
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
    border-radius: var(--radius-pill);
    box-shadow: 0 10px 26px rgba(0,0,0,.5);
    pointer-events: none;
    opacity: 0;
    transition: opacity .18s var(--ease);
  }
  .et-faq-toggle:hover > span,
  .et-faq-toggle:focus-visible > span,
  .et-faq-toggle[aria-expanded="true"] > span { opacity: 1; }
  .et-faq-toggle:hover,
  .et-faq-toggle:focus-visible { transform: translateY(-2px); }
}

/* =========================================================================
   NA TELEFONIE: MNIEJSZA I CIEMNA - zgłoszenie z przeglądu mobilnego
   (2026-08-13): „floating help (?) nakłada się na karty i kradnie pomarańcz.
   Zmniejsz, przenieś do stopki/menu albo zrób ciemny wariant".

   Wybrany ciemny wariant, a nie przeniesienie do stopki. Pomoc pod ręką ma
   sens dokładnie tam, gdzie człowiek się waha - czyli przy produkcie,
   w połowie strony. Zepchnięta do stopki przestaje być pomocą i robi się
   pozycją w spisie treści, do której nikt nie schodzi.

   Zostaje więc na miejscu i przestaje krzyczeć: ciemne koło z pomarańczową
   OBWÓDKĄ zamiast pomarańczowej plamy. Ten sam cel dotykowy (44 px to dolna
   granica, poniżej palec chybia), ta sama pozycja, ale w hierarchii koloru
   schodzi z pierwszego planu na trzeci - a pomarańcz na stronie zostaje
   jeden: główne CTA i ceny.

   Niżej też: 12 px zamiast 18 od dołu i od prawej odsuwa przycisk od rogu
   karty, na którą zachodził. */
/* NEUTRALNA TAKŻE NA PULPICIE - audyt pulpitu: „floating »Szybka pomoc«
   jest pomarańczowy i KONKURUJE Z CTA, zmień na neutralny (surface +
   border)".

   Zdjęte z telefonu tego samego dnia i argument jest ten sam, tyle że na
   pulpicie mocniejszy: przycisk wisi nad treścią przez cały czas wizyty,
   więc jest jedynym pomarańczem, który NIGDY nie schodzi z ekranu. Główne
   CTA przewija się i wraca; ten nie. Pomoc jest narzędziem obsługi, a nie
   ofertą - nie ma po co brać koloru zarezerwowanego dla rzeczy, które się
   kupuje. */
.et-faq-toggle {
  background: var(--bg-surface);
  color: var(--color-bone-2);
  border: 1px solid var(--border-input);
}
/* Najechanie i otwarty panel WOLNO podświetlić: wtedy kolor mówi o tym, co
   się właśnie dzieje, a nie zabiega o uwagę z góry. */
@media (hover: hover) {
  .et-faq-toggle:hover,
  .et-faq-toggle:focus-visible {
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
    border-color: var(--color-brand-orange);
  }
}

@media (max-width: 768px) {
  .et-faq { right: 12px; bottom: 12px; }
  .et-faq-toggle {
    width: 44px; height: 44px;
    background: rgba(23, 23, 23, .92);
    /* KOŚĆ, NIE POMARAŃCZ - zgłoszenie mówiło wprost „kradnie pomarańcz".
       Pomarańczowa obwódka była półśrodkiem: mniej koloru niż wypełnienie,
       ale wciąż ten sam kolor w tej samej grupie co ceny obok. Pomoc jest
       narzędziem obsługi, a nie ofertą, więc nie ma po co brać koloru
       zarezerwowanego dla rzeczy, które się kupuje. */
    color: var(--color-bone-3);
    border: 1px solid var(--border-input);
    /* Cień lżejszy razem z przyciskiem - ten sam co przy 52 px robił wokół
       małego koła ciemną aureolę większą niż samo koło. */
    box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  }
  .et-faq-toggle svg { width: 20px; height: 20px; }
  /* Po otwarciu panelu przycisk zamienia się miejscami z tłem: to jest
     stan włączony i ma być widać, że to on ten panel trzyma. */
  .et-faq-toggle[aria-expanded="true"] {
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
  }
}

.et-faq-panel {
  position: absolute; right: 0; bottom: calc(100% + 12px);
  width: min(360px, calc(100vw - 36px));
  /* `dvh` = widoczne okno; na iPhonie `vh` liczy się bez pasków Safari. */
  max-height: min(70vh, 560px);
  max-height: min(70dvh, 560px);
  overflow-y: auto;
  padding: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
}
.et-faq-panel[hidden] { display: none; }
.et-faq-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.et-faq-head strong {
  font-family: var(--font-heading); font-size: 14px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-bone-0);
}
.et-faq-close {
  background: none; border: none; cursor: pointer;
  font-size: 24px; line-height: 1; color: var(--fg-muted); padding: 0 4px;
  /* Cel dotyku 44x44 zamiast 28x24 (audyt iOS 2026-09-26); ujemne
     marginesy trzymają znak i miejsce w nagłówku panelu bez zmian. */
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
  margin: -10px -8px;
}
@media (hover: hover) and (pointer: fine) {
  .et-faq-close:hover { color: var(--color-brand-orange); }
}
.et-faq-intro { margin: 0 0 12px; font-size: 13px; color: var(--fg-muted); }

.et-faq-list { list-style: none; margin: 0; padding: 0; }
.et-faq-list li { border-top: 1px solid var(--border-default); }
.et-faq-q {
  width: 100%;
  /* 44px celu dotykowego — ten sam standard co reszta interfejsu. */
  min-height: 44px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 0;
  background: none; border: none; cursor: pointer;
  text-align: left;
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600; color: var(--fg-default);
}
.et-faq-q::after { content: "+"; color: var(--color-brand-orange); font-size: 18px; line-height: 1; }
.et-faq-q[aria-expanded="true"]::after { content: "–"; }
@media (hover: hover) and (pointer: fine) {
  .et-faq-q:hover { color: var(--color-brand-orange); }
}
.et-faq-a { padding: 0 0 12px; font-size: 14px; color: var(--fg-muted); }
.et-faq-a[hidden] { display: none; }
.et-faq-a p { margin: 0 0 8px; }
.et-faq-a p:last-child { margin: 0; }

@media (max-width: 560px) {
  .et-faq { right: 12px; bottom: 12px; }
  /* 44 px, nie 48: przycisk mieszka teraz w pasku dolnym (patrz blok paska
     nizej w pliku) i 48 px nie miescilo sie w jego 56 px z odstepem. */
  .et-faq-toggle { width: 44px; height: 44px; }
}
/* Pasek „Do koszyka" na karcie produktu jest przyklejony do dołu — pomocnik
 * musi mu ustąpić, żeby nie zasłaniał przycisku zakupu. */
@media (max-width: 860px) {
  body:has(.et-builder-sticky.is-visible) .et-faq { bottom: 92px; }
}


/* =========================================================================
 * Pas BJJ — odznaka, avatar, opinie
 *
 * Wygląd wg projektu: taśma w kolorze pasa, ciemna belka (u czarnego pasa
 * czerwona) i 0–4 białe belki stopni. Rysowane CSS-em, bez grafik — skaluje
 * się do każdego rozmiaru i nie dokłada żądań.
 * ====================================================================== */
/* Taśma pasa — prostokąt bez zaokrągleń, z podświetleniem górnej i cieniem
 * dolnej krawędzi. To ten światłocień daje wrażenie grubego splotu; wcześniejsza
 * wersja z zaokrągleniem i przeszyciem w kolorze pasa wyglądała jak pigułka. */
.et-belt {
  display: inline-block;
  position: relative;
  width: 36px;
  height: 8px;
  background: var(--belt, #DCDBD6);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18),
              inset 0 -1px 0 rgba(0,0,0,.35);
}
.et-belt-bar {
  position: absolute;
  right: 4px; top: 0; bottom: 0;
  width: 11px;
  display: flex; align-items: center; justify-content: center; gap: 1px;
  background: var(--belt-bar, #111114);
}
.et-belt-bar i {
  width: 1px; height: 100%;
  background: var(--color-bone-1, #F5F1EA);
}

/* Odznaka = pigułka: taśma + nazwa stopnia. */
.et-belt-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px;
  background: var(--color-ink-1, #0B0B0B);
  border: 1px solid var(--border-default, #2A2A2A);
  border-radius: 999px;
}
.et-belt-label {
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-muted, #B8AE9E);
  white-space: nowrap;
}

/*
 * Avatar — ciemna kwadratowa kafla z pasem gi u dołu.
 *
 * Bez znaku marki: wersja ze znakiem bursztynowym rozbijała ciemny motyw,
 * a znak powtórzony przy każdej opinii i tak przestawał cokolwiek znaczyć.
 * Kafla niesie jedną informację — stopień.
 *
 * Wszystko liczone w `em`, a rozmiar wchodzi jako `font-size` (inline z PHP),
 * więc jeden zestaw reguł obsługuje każdy rozmiar bez breakpointów.
 */
.et-avatar {
  position: relative;
  display: inline-block;
  width: 1em; height: 1em;
  flex: none;
  vertical-align: middle;
}
.et-avatar-tile {
  position: absolute; inset: 0;
  border-radius: .125em;
  overflow: hidden;
  background: var(--color-ink-3, #1F1F1F);
  /* Ziarno — cztery drobne punkty w kolorze przybrudzonego bursztynu, żeby
   * płaskie tło nie wyglądało jak dziura w layoucie. */
  background-image:
    radial-gradient(circle at 26% 22%, #3A2C14 .5px, transparent 1.6px),
    radial-gradient(circle at 68% 38%, #3A2C14 .5px, transparent 1.6px),
    radial-gradient(circle at 44% 60%, #3A2C14 .5px, transparent 1.6px);
  background-size: .34em .34em, .26em .26em, .42em .42em;
  box-shadow: inset 0 0 0 .018em rgba(255,255,255,.10);
}
.et-avatar-belt {
  position: absolute;
  left: 0; right: 0; bottom: .08em;
  height: .18em;
  background: var(--belt, #DCDBD6);
  box-shadow: inset 0 .016em 0 rgba(255,255,255,.18),
              inset 0 -.016em 0 rgba(0,0,0,.35);
}
.et-avatar-stitch {
  position: absolute;
  top: .034em; bottom: .034em; left: .04em; right: .04em;
  border-top: .012em dashed var(--belt-stitch, rgba(0,0,0,.3));
  border-bottom: .012em dashed var(--belt-stitch, rgba(0,0,0,.3));
}
.et-avatar-bar {
  position: absolute;
  right: .10em; top: 0; bottom: 0;
  width: .26em;
  display: flex; align-items: center; justify-content: center; gap: .03em;
  background: var(--belt-bar, #111114);
}
.et-avatar-bar i {
  width: .03em; height: 100%;
  background: var(--color-bone-1, #F5F1EA);
}

/* Przy autorze opinii.
 *
 * Odznaka wypada NAD nazwą autora, bo `woocommerce_review_meta` odpala się
 * przed szablonem z nazwą, a wejście między nazwę a datę wymagałoby
 * nadpisania szablonu WooCommerce — czego motyw świadomie nie robi.
 * Stąd odstęp od dołu zamiast od lewej. */
.et-comment-belt { display: inline-flex; vertical-align: middle; margin: 0 0 6px; }

/* OPINIE: JEDNA KARTA Z AWATAREM W ŚRODKU (zgłoszenie #9; tak samo na pulpicie).

   Awatar pasa to `<span>` z `pre_get_avatar` (wyżej), a nie `<img>` -
   reguła WooCommerce dla `img.avatar` (pozycja absolutna w rogu, obok
   ramki) go nie łapie. Stał więc w osobnym wierszu NAD ramką opinii,
   a ramka `.comment-text` (`margin-left: 50px` z woocommerce.css plus
   40 px wcięcia listy `ol`) zaczynała się 90 px od krawędzi treści.
   Zmierzone na 393 px: w ramce zostawało 213 px, odznaka i gwiazdki
   (float z prawej) stały 3,4 px od siebie, a data łamała się na dywizie
   („2025-10-” / „04”). Ramka była biała (#e4e1e4), a autor i data szare
   #767676 - kolory WooCommerce spod jasnego motywu.

   Teraz kartą jest `.comment_container`: awatar z lewej, obok niego jedna
   kolumna - odznaka i gwiazdki (12 px odstępu; gdy się nie mieszczą,
   gwiazdki schodzą pod odznakę), autor z datą i treść. Selektory z tym
   samym przedrostkiem co w woocommerce.css (dwa identyfikatory), żeby
   wygrywać kolejnością, bez `!important`. */
.woocommerce #reviews #comments ol.commentlist { padding: 0; }
.woocommerce #reviews #comments ol.commentlist li { margin: 0 0 12px; }
.woocommerce #reviews #comments ol.commentlist li .comment_container {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
}
.woocommerce #reviews #comments ol.commentlist li .comment_container > .avatar { flex: none; margin: 0; }
/* Klient bez pasa dostaje zwykły Gravatar `<img>` - ten WooCommerce
   przypina absolutnie do rogu `li`, czyli na kartę. */
.woocommerce #reviews #comments ol.commentlist li .comment_container > img.avatar {
  position: static;
  width: 60px;
  height: 60px;
  padding: 0;
  border: 0;
  background: none;
}
.woocommerce #reviews #comments ol.commentlist li .comment-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
}
/* Clearfix WooCommerce (`display: table`) w układzie flex byłby pustym
   elementem - i dokładałby 12 px odstępu przed odznaką. */
.woocommerce #reviews #comments ol.commentlist li .comment-text::before,
.woocommerce #reviews #comments ol.commentlist li .comment-text::after { content: none; }
.woocommerce #reviews #comments ol.commentlist li .comment-text > * { flex: 1 1 100%; }
/* W znaczniku gwiazdki stoją PRZED odznaką; w karcie odznaka idzie pierwsza. */
.woocommerce #reviews #comments ol.commentlist li .comment-text > .et-comment-belt { flex: 0 0 auto; order: -2; margin: 0; }
.woocommerce #reviews #comments ol.commentlist li .comment-text > .star-rating { flex: none; order: -1; float: none; margin: 0; }
.woocommerce #reviews #comments ol.commentlist li .comment-text p.meta {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-faint);
}
.woocommerce #reviews #comments ol.commentlist li .comment-text .woocommerce-review__author { color: var(--fg-default); font-weight: 600; }
/* Data w całości - iPhone łamał ją na dywizie. */
.woocommerce #reviews #comments ol.commentlist li .woocommerce-review__published-date { white-space: nowrap; }
.woocommerce #reviews #comments ol.commentlist li .comment-text .description { margin: 2px 0 0; }
.woocommerce #reviews #comments ol.commentlist li .comment-text .description p { margin: 0 0 .5em; }
.woocommerce #reviews #comments ol.commentlist li .comment-text .description p:last-child { margin-bottom: 0; }
/* Odpowiedź sklepu pod opinią: 50 px wcięcia z WooCommerce zjadało na
   telefonie jedną siódmą szerokości. */
.woocommerce #reviews #comments ol.commentlist ul.children { margin: 12px 0 0 16px; padding: 0; }

/* Telefon: odznaka, gwiazdki i autor obok awatara, treść opinii pod nim na
   całą szerokość karty. W kolumnie obok awatara na treść zostawało 150 px
   przy 320 px ekranu („Świetna jakość i” / „kolor”). `display: contents`
   na `.comment-text` (zwykły `div`, bez znaczenia dla czytnika) wpuszcza
   jego dzieci do siatki karty. */
@media (max-width: 480px) {
  .woocommerce #reviews #comments ol.commentlist li .comment_container {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 6px 14px;
  }
  .woocommerce #reviews #comments ol.commentlist li .comment_container > .avatar { grid-column: 1; grid-row: 1 / span 3; align-self: start; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text { display: contents; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text > * { grid-column: 1 / -1; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text > .et-comment-belt { grid-column: 2; grid-row: 1; justify-self: start; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text > .star-rating { grid-column: 2; grid-row: 2; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text > p.meta { grid-column: 2; grid-row: 3; }
  .woocommerce #reviews #comments ol.commentlist li .comment-text .description { margin-top: 6px; }
}

/* Formularz opinii pod listą (to samo zgłoszenie - ten sam ekran). */
/* „Dodaj opinię” to nagłówek (`role="heading"`), a WooCommerce zostawia go
   gołym napisem 16 px, zlewającym się ze zdaniem pod spodem. */
.woocommerce #reviews #review_form .comment-reply-title {
  display: block;
  margin: 28px 0 6px;
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-bone-0);
}
.woocommerce #reviews #review_form .comment-notes { font-size: 14px; }
/* Gwiazdki oceny: w WooCommerce pola 24 × 24 px z przerwą 4,5 px - na
   iPhonie łatwo trafić sąsiednią i ocenić o gwiazdkę za nisko. Pole
   44 × 44, ta sama 24-pikselowa gwiazdka pośrodku; ujemny margines trzyma
   pierwszą gwiazdkę w linii z podpisem „Twoja ocena”. */
.woocommerce #reviews #review_form p.stars { margin: 0 0 8px -10px; }
.woocommerce #reviews #review_form p.stars a { width: 44px; height: 44px; vertical-align: top; }
.woocommerce #reviews #review_form p.stars a::before { top: 10px; left: 10px; }
/* „Zapamiętaj moje dane”: kwadracik stał sam w wierszu, a zdanie pod nim
   (etykieta `display: block` z reguły formularza komentarzy). */
.woocommerce #reviews #review_form .comment-form-cookies-consent { display: flex; align-items: flex-start; gap: 10px; }
.woocommerce #reviews #review_form .comment-form-cookies-consent input {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 3px 0 0;
  accent-color: var(--color-brand-orange);
}
.woocommerce #reviews #review_form .comment-form-cookies-consent label { margin: 0; }

/* Pole wyboru pasa przy rejestracji i w koncie. */
.et-optional { color: var(--fg-faint); font-weight: 400; text-transform: none; letter-spacing: 0; }
.et-field-help { display: block; margin-top: 6px; font-size: 12px; color: var(--fg-faint); }

/* Pas przy REJESTRACJI - wydzielony, żeby lista rozwijana wciśnięta między
   hasło a zgody nie wyglądała na pole wymagane. Pytanie stoi nad nią wprost;
   belki ustawia się dopiero w danych konta, gdzie stoją obok pasa i widać,
   czego dotyczą. */
.et-rejestracja-pas {
  margin: 18px 0 4px;
  padding: 14px 16px 4px;
  /* Tokeny motywu, nie wartosci pod jasne tlo: sklep jest ciemny, wiec
     `rgba(0,0,0,.12)` daje ramke, ktorej nie widac wcale. */
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--color-brand-orange);
  border-radius: 0 var(--radius-3) var(--radius-3) 0;
  background: var(--bg-surface);
}
.et-rejestracja-pas-pytanie {
  margin: 0 0 10px;
  font-size: 14px;
  line-height: 1.5;
  font-weight: 600;
}
.et-rejestracja-pas .form-row { margin-bottom: 10px; }


/* =========================================================================
 * Zdjęcia od klientów — avatar profilowy, zdjęcia w opiniach, lightbox
 * ====================================================================== */

/* Własne zdjęcie wchodzi w tę samą kwadratową kaflę co pas, więc wszystkie
 * avatary przy opiniach czytają się jako jeden rodzaj elementu. Pas zostaje
 * na dole i nadal niesie stopień. */
.et-avatar-photo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* WooCommerce ustawia obrazkom w opiniach własne marginesy i szerokości —
   * bez tego zdjęcie wypadałoby z kafli. */
  max-width: none; max-height: none; margin: 0;
  border-radius: inherit;
}

/* --- Pole zdjęcia w „Dane konta" --- */
.et-avatar-field { border: 0; padding: 0; margin: 0 0 24px; }
.et-avatar-field legend {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-bone-1);
  padding: 0;
}
.et-avatar-current { display: flex; align-items: center; gap: 16px; margin-top: 12px; flex-wrap: wrap; }
.et-avatar-controls { display: flex; flex-direction: column; gap: 8px; }
.et-checkbox-inline { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg-muted); }

/* Przycisk „wybierz plik": natywny input jest brzydki i nie da się go
 * ostylować, więc chowamy go wewnątrz etykiety. Etykieta pozostaje
 * klikalna i czytana przez czytniki ekranu, więc nic nie tracimy. */
.et-file-button {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 10px 18px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--color-bone-1);
  font-family: var(--font-heading);
  font-size: 12px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
/* Najechanie tylko pod myszą: na iPhonie `:hover` zostaje po dotknięciu,
   a ten przycisk otwiera wybór pliku i strona zostaje - obwódka świeciłaby
   na pomarańczowo aż do dotknięcia czegoś innego. Na dotyk `:active`. */
@media (hover: hover) and (pointer: fine) {
  .et-file-button:hover { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
}
.et-file-button:active { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
.et-file-button input[type="file"] {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.et-file-button:focus-within { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; }

/* --- Wybór zdjęć w formularzu opinii --- */
.et-review-photos { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.et-review-photos.is-busy { opacity: .6; pointer-events: none; }
.et-review-photos-list { display: flex; flex-wrap: wrap; gap: 10px; }

.et-review-thumb {
  position: relative;
  width: 72px; height: 72px;
  border-radius: var(--radius-3);
  overflow: hidden;
  background: var(--bg-input);
}
.et-review-thumb img { width: 100%; height: 100%; object-fit: cover; margin: 0; }
.et-review-thumb-remove {
  position: absolute; top: 2px; right: 2px;
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: rgba(0,0,0,.72);
  color: #fff; font-size: 16px; line-height: 1;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-review-thumb-remove:hover { background: var(--color-brand-orange); }
}

.et-review-photos-error { display: none; font-size: 13px; color: var(--color-danger); }
.et-review-photos-error.is-shown { display: block; }

/* --- Miniatury pod opinią --- */
.et-review-gallery { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.et-review-photo {
  width: 96px; height: 96px;
  padding: 0; border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden; background: none; cursor: zoom-in;
  transition: border-color .15s ease, transform .15s ease;
}
/* Jak wyżej: miniatura otwiera podgląd na tej samej stronie, więc po
   zamknięciu podglądu „przyklejony” `:hover` zostawiałby ją uniesioną. */
@media (hover: hover) and (pointer: fine) {
  .et-review-photo:hover { border-color: var(--color-brand-orange); transform: translateY(-2px); }
}
.et-review-photo:active { border-color: var(--color-brand-orange); }
.et-review-photo img { width: 100%; height: 100%; object-fit: cover; margin: 0; display: block; }

/* --- Lightbox --- */
body.et-lb-open { overflow: hidden; }

.et-lightbox {
  position: fixed; inset: 0;
  z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(6,6,8,.94);
  padding: 24px;
}
.et-lightbox[hidden] { display: none; }

.et-lb-stage {
  margin: 0;
  max-width: 100%; max-height: 100%;
  display: flex; align-items: center; justify-content: center;
}
.et-lb-stage img {
  max-width: 100%;
  /* Wysokość liczona z okna minus pas na licznik i marginesy, żeby zdjęcie
   * nigdy nie chowało się pod krawędzią ekranu na niskich oknach. */
  max-height: calc(100vh - 120px);
  width: auto; height: auto;
  object-fit: contain;
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-2);
}

.et-lb-close,
.et-lb-nav {
  position: absolute;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-default);
  background: rgba(0,0,0,.55);
  color: var(--color-bone-1);
  cursor: pointer;
  line-height: 1;
  transition: border-color .15s ease, color .15s ease;
}
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-lb-close:hover,
  .et-lb-nav:hover { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
}
.et-lb-close:focus-visible,
.et-lb-nav:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; }

.et-lb-close {
  top: 16px; right: 16px;
  width: 44px; height: 44px;
  border-radius: 50%; font-size: 24px;
}
.et-lb-nav {
  top: 50%; transform: translateY(-50%);
  width: 48px; height: 64px;
  border-radius: var(--radius-3);
  font-size: 32px;
}
.et-lb-nav[hidden] { display: none; }
.et-lb-prev { left: 16px; }
.et-lb-next { right: 16px; }

.et-lb-counter {
  position: absolute; bottom: 20px; left: 0; right: 0;
  margin: 0; text-align: center;
  font-family: var(--font-heading);
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-muted);
}
.et-lb-counter[hidden] { display: none; }

/* Na wąskim ekranie strzałki po bokach zjadałyby zdjęcie — schodzą na dół,
 * gdzie i tak wygodniej ich dosięgnąć kciukiem. Przesuwanie palcem działa
 * niezależnie od nich. */
@media (max-width: 600px) {
  .et-lightbox { padding: 12px; }
  .et-lb-nav { top: auto; bottom: 16px; transform: none; width: 56px; height: 44px; }
  .et-lb-prev { left: 20%; }
  .et-lb-next { right: 20%; }
  .et-lb-counter { bottom: 72px; }
  .et-lb-stage img { max-height: calc(100vh - 160px); }
  .et-review-photo { width: 76px; height: 76px; }
}


/* =========================================================================
 * Newsletter i zakładka bezpieczeństwa produktu
 * ====================================================================== */
/* Zapis na newsletter - poziomy pas, nie kafel.
 *
 * Pierwsza wersja była wyśrodkowaną kolumną 560 px: nagłówek, tekst, pole,
 * przycisk i zgoda jedno pod drugim. Pięć rzędów nad stopką zajmowało tyle
 * miejsca, że sekcja wyglądała na ważniejszą niż jest.
 *
 * Teraz tekst siedzi po lewej, formularz po prawej, zgoda w jednym wierszu
 * pod spodem - z pięciu rzędów robią się dwa. Tło zniknęło na rzecz samej
 * ramki, żeby pas nie konkurował ze stopką i produktami. */
.et-newsletter {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: 10px 28px;
  /* Szerokość jak `.container` (ten sam margines boczny co reszta strony),
     najwyżej 860 px. Samo `max-width` dawało na telefonie całą szerokość
     okna: ramka z zaokrąglonymi rogami przy samej krawędzi ekranu i treść
     16 px od brzegu, gdy wszystko nad nią ma 28 px (zgłoszenia #6 i #7). */
  width: min(100% - (var(--et-gutter, 24px) * 2), 860px);
  margin: 0 auto var(--et-space-desktop, 96px);
  padding: 16px 20px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  text-align: left;
}

.et-newsletter-copy { min-width: 0; }

.et-newsletter-title {
  margin: 0 0 2px;
  font-family: var(--font-heading);
  font-size: 15px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-bone-0);
}
.et-newsletter-intro {
  margin: 0;
  font-size: 12.5px; line-height: 1.45;
  color: var(--fg-muted);
}

.et-newsletter-row { display: flex; gap: 8px; min-width: 0; }
.et-newsletter-row input[type="email"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 14px;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-pill);
  color: var(--color-bone-1);
  font-size: 16px; /* bylo 14 - zoom na iOS */
  min-height: 44px;
}
.et-newsletter-row button {
  flex: 0 0 auto;
  padding: 10px 20px;
  min-height: 44px; display: inline-flex; align-items: center; /* zmierzone 39 px */
  border: 0; border-radius: var(--radius-pill);
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-weight: 700; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase;
  cursor: pointer;
}
.et-newsletter-row button:disabled { opacity: .6; cursor: default; }

/* Zgoda i komunikat pod spodem, przez całą szerokość - nie rozpychają
 * kolumn i nie dokładają rzędu do właściwej treści. */
.et-newsletter-consent {
  grid-column: 1 / -1;
  display: flex; align-items: flex-start; gap: 7px;
  margin: 0;
  font-size: 12px; line-height: 1.4; color: var(--fg-faint); /* zdanie, nie podpis: 12 px */
}
.et-newsletter-consent input { margin-top: 1px; width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--color-brand-orange); }

/* Pułapka na boty: musi zniknąć z widoku, ale zostać w drzewie i być
 * „wypełnialna" - dlatego przesunięcie poza ekran, a nie `display:none`,
 * którego część botów nie wypełnia. */
.et-newsletter-hp {
  position: absolute !important;
  left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

.et-newsletter-msg {
  grid-column: 1 / -1;
  margin: 0; font-size: 12px; min-height: 0;
}
.et-newsletter-msg:empty { display: none; }
.et-newsletter-msg.is-ok  { color: var(--color-bone-3); }
.et-newsletter-msg.is-err { color: var(--color-danger); }

@media (max-width: 720px) {
  .et-newsletter { grid-template-columns: 1fr; gap: 12px; padding: 16px; }
  .et-newsletter-row { flex-wrap: wrap; }
  .et-newsletter-row input[type="email"] { flex: 1 1 100%; }
  .et-newsletter-row button { flex: 1 1 100%; }
}

/* Zakładka „Bezpieczeństwo produktu" (GPSR). */
.et-gpsr h3 {
  margin: 20px 0 6px;
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
}
.et-gpsr p { margin: 0 0 8px; }
.et-gpsr code { background: var(--bg-input); padding: 2px 6px; border-radius: 3px; }

/* Pasek informujący, że rabat z linku polecającego czeka na koszyk. */
.et-ref-bar {
  padding: 10px 16px;
  text-align: center;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .04em;
}


/* =========================================================================
 * Polecane produkty w koszyku („Zobacz inne równie interesujące")
 *
 * Sekcję renderuje blok `woocommerce/product-collection`, którego motyw
 * wcześniej nie dotykał wcale - leciała więc na domyślnych stylach
 * WooCommerce Blocks. Efekt: drobna czcionka (cena miała klasę
 * `has-small-font-size`), obce przyciski i karty niepodobne do niczego
 * innego w sklepie.
 *
 * Selektory wzięte z realnego HTML-a, nie z dokumentacji: pierwsza wersja
 * celowała w `.wc-block-cart__cross-sells`, której na stronie nie ma wcale.
 * Struktura to:
 *   div.wp-block-woocommerce-product-collection
 *     > h2.wp-block-heading                  <- nagłówek sekcji
 *     > ul.wc-block-product-template
 *         > li.wc-block-product              <- karta
 *             h2.wp-block-post-title
 *             div.wp-block-woocommerce-product-price
 *             a.wp-block-button__link
 * ====================================================================== */

/* Nagłówek sekcji. Zawężony do koszyka i do bezpośredniego dziecka bloku,
 * bo tytuły produktów w środku to również `h2` - szersza reguła zmieniłaby
 * je razem z nagłówkiem. */
.woocommerce-cart .wp-block-woocommerce-product-collection > h2.wp-block-heading {
  font-family: var(--font-display);
  font-size: clamp(22px, 3.4vw, 32px);
  font-weight: 400;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-bone-0);
  margin: clamp(28px, 5vw, 56px) 0 18px;
}

/* Siatka ustawiona wprost, żeby układ nie zależał od tego, którą wersję
 * własnych stylów akurat wyśle WooCommerce. */
.woocommerce-cart ul.wc-block-product-template {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin: 0; padding: 0; list-style: none;
}
@media (max-width: 780px) {
  .woocommerce-cart ul.wc-block-product-template { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .woocommerce-cart ul.wc-block-product-template { grid-template-columns: 1fr; }
}

/* --- karta --- */
.woocommerce-cart li.wc-block-product {
  display: flex;
  flex-direction: column;
  padding: 14px;
  margin: 0;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  transition: border-color .18s ease, transform .18s ease;
}
/* Uniesienie i ramka tylko pod kursorem - na iPhonie karta zostawała
   uniesiona i obramowana po dotknięciu (przyklejony `:hover`). */
@media (hover: hover) and (pointer: fine) {
  .woocommerce-cart li.wc-block-product:hover {
    border-color: var(--color-brand-orange);
    transform: translateY(-3px);
  }
}

.woocommerce-cart li.wc-block-product .wc-block-components-product-image {
  margin: 0 0 12px;
  border-radius: calc(var(--radius-3) - 4px);
  overflow: hidden;
  background: var(--bg-input);
}
.woocommerce-cart li.wc-block-product .wc-block-components-product-image img {
  width: 100%; height: auto; display: block; margin: 0;
}

/* Nazwa produktu. */
.woocommerce-cart li.wc-block-product .wp-block-post-title {
  font-family: var(--font-heading);
  font-size: 15px !important;
  font-weight: 600;
  letter-spacing: .03em;
  line-height: 1.3;
  text-transform: uppercase;
  text-align: left !important;
  margin: 0 0 6px !important;
}
.woocommerce-cart li.wc-block-product .wp-block-post-title a {
  color: var(--color-bone-0);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce-cart li.wc-block-product .wp-block-post-title a:hover { color: var(--color-brand-orange); }
}

/* Cena. `has-small-font-size` to źródło wrażenia, że wszystko jest drobne -
 * cena nie jest przypisem, więc nadpisujemy z `!important`.
 *
 * `auto` u góry: cena schodzi na dół razem z przyciskiem, tak jak w kartach
 * sklepu (2026-09-26). Przy dwóch kolumnach (421-780 px) nazwa w jednym
 * i w dwóch wierszach stawiała ceny na różnych wysokościach. */
.woocommerce-cart li.wc-block-product .wp-block-woocommerce-product-price {
  font-size: 17px !important;
  font-weight: 700;
  text-align: left !important;
  color: var(--color-brand-orange);
  margin: auto 0 12px !important;
}
/* NAPRAWDĘ 17 px I DO LEWEJ (2026-09-26). Reguła wyżej trafia w opakowanie,
 * a liczbę rysuje element w środku, który WooCommerce oznacza klasami
 * `has-small-font-size` (13 px z `!important` z rdzenia WordPressa)
 * i `has-text-align-center`, a motyw daje mu wcięcie `.wc-block-grid__product-
 * price` (12 px). Zmierzone: cena 13 px, wyśrodkowana, 12 px od tytułu. */
.woocommerce-cart li.wc-block-product .wp-block-woocommerce-product-price .wc-block-components-product-price {
  font-size: 17px !important;
  text-align: left;
  padding: 0;
}
.woocommerce-cart li.wc-block-product .wp-block-woocommerce-product-price del { opacity: .55; font-weight: 400; }
.woocommerce-cart li.wc-block-product .wp-block-woocommerce-product-price ins { text-decoration: none; }

/* --- przycisk --- */
.woocommerce-cart li.wc-block-product .wp-block-button,
.woocommerce-cart li.wc-block-product > .et-configure-btn,
.woocommerce-cart li.wc-block-product > .button {
  margin-top: 0;      /* równą linię przycisków mimo różnej długości nazw
                         trzyma teraz cena nad nimi (`margin-top: auto`);
                         drugie `auto` tutaj dzieliłoby wolne miejsce na pół.
                         Produkt konfigurowalny ma przycisk motywu wprost
                         w karcie, bez `.wp-block-button` (zrzut 2026-09-06) */
  width: 100%;
}
.woocommerce-cart li.wc-block-product .wp-block-button__link {
  display: inline-flex;
  align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  /* Ten sam kształt co `.button` (i „Skomponuj zestaw" obok): w jednym
     rzędzie kart była pigułka 12 px i prostokąt 14 px (zrzut właściciela
     2026-09-06). Wartości skopiowane z reguły bazowej `.button`. */
  padding: 13px 24px;
  min-height: 44px;
  line-height: 1;
  border: 1px solid transparent; border-radius: var(--radius-3);
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  /* `!important`, bo blok dokłada przyciskowi klasę `has-small-font-size`,
     a rdzeń WordPressa ustawia dla niej 13 px z `!important`. */
  font-size: 14px !important; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: filter .15s ease, transform .12s ease;
}
/* WĄSKA KARTA W KOSZYKU - ta sama zasada co w kartach sklepu („WĄSKA KARTA"
   przy celach dotyku). Dwie kolumny od 421 px: przy 430 px karta ma 150 px
   wnętrza, a „SKOMPONUJ ZESTAW" przy 14 px i rozstrzeleniu .08em - 132 px
   na 102 px miejsca. Łamał się na dwa wiersze wyrównane do lewej, przycisk
   rósł do 56 px i cena w tej karcie stała 12 px wyżej niż obok (zmierzone
   2026-09-26). W wąskiej karcie: 13 px, ciaśniej, miejsce na dwa wiersze
   w każdym przycisku - „Skomponuj zestaw" (114 px) mieści się w jednym. */
.woocommerce-cart li.wc-block-product { container: et-karta / inline-size; }
.woocommerce-cart li.wc-block-product .wp-block-button__link,
.woocommerce-cart li.wc-block-product > .et-configure-btn,
.woocommerce-cart li.wc-block-product > .button {
  text-align: center;
  text-wrap: balance;
}
@container et-karta (max-width: 199.9px) {
  .woocommerce-cart li.wc-block-product .wp-block-button__link,
  .woocommerce-cart li.wc-block-product > .et-configure-btn,
  .woocommerce-cart li.wc-block-product > .button {
    min-height: 48px;
    padding: 8px 10px;
    font-size: 13px !important; /* przebija 14 px z `!important` wyżej */
    letter-spacing: .04em;
    line-height: 1.15;
  }
}
@media (hover: hover) and (pointer: fine) {
  .woocommerce-cart li.wc-block-product .wp-block-button__link:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
    color: var(--color-ink-1);
  }
}
.woocommerce-cart li.wc-block-product .wp-block-button__link:focus-visible {
  outline: 2px solid var(--color-bone-0); outline-offset: 2px;
}

/* Stany po kliknięciu. Przycisk NIE robi się szary - klient ma zobaczyć
 * potwierdzenie, nie wrażenie awarii. */
.woocommerce-cart li.wc-block-product .wp-block-button__link.is-adding {
  pointer-events: none;
  filter: brightness(.9);
}
.woocommerce-cart li.wc-block-product .wp-block-button__link.is-added {
  pointer-events: none;
  /* Ten sam token zieleni co wszedzie; ciemny tekst, bo bialy na #4CAE6B
     mialby 2,8:1 (audyt D9). */
  background: var(--color-success);
  color: var(--color-ink-1);
}
.woocommerce-cart li.wc-block-product .wp-block-button__link.is-adding::before {
  content: "";
  width: 13px; height: 13px;
  border: 2px solid rgba(0,0,0,.25);
  border-top-color: var(--color-ink-1);
  border-radius: 50%;
  animation: et-spin .6s linear infinite;
}
@keyframes et-spin { to { transform: rotate(360deg); } }

/* WooCommerce dokleja własne „dodano do koszyka" obok przycisku - tutaj
 * tylko rozbijałoby karty, bo potwierdzenie jest na samym przycisku. */
.woocommerce-cart li.wc-block-product .added_to_cart { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  .woocommerce-cart li.wc-block-product:hover { transform: none; }
  .woocommerce-cart li.wc-block-product .wp-block-button__link.is-adding::before { animation: none; }
}


/* =========================================================================
 * Strona „Dla klubów i eventów"
 * ====================================================================== */
.et-ev { max-width: 980px; margin: 0 auto; }

/* Tytuł strony renderuje `page.php`, więc centrujemy go z poziomu body -
 * inaczej trzeba by dokładać osobny szablon dla jednej strony. Okruszki
 * zostają po lewej, bo wyśrodkowana nawigacja czyta się gorzej. */
.et-ev-page .entry-title {
  text-align: center;
  margin-bottom: 4px;
}
.et-ev-page .entry-content { margin-top: 0; }

.et-ev-hero { text-align: center; margin-bottom: clamp(28px, 5vw, 48px); }
/* Podtytuł, nie nagłówek strony: jedyny <h1> to tytuł z `page.php`. */
.et-ev-sub {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.4vw, 40px);
  font-weight: 400;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-brand-orange);
  margin: 0 0 10px;
}
.et-ev-lead {
  max-width: 620px; margin: 0 auto;
  font-size: 16px; line-height: 1.55; color: var(--fg-muted);
}

.et-ev-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.et-ev-card {
  padding: 20px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.et-ev-card h2 {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-brand-orange);
  margin: 0 0 10px;
}
.et-ev-card ul, .et-ev-card ol { margin: 0; padding-left: 18px; }
.et-ev-card li { font-size: 13.5px; line-height: 1.5; color: var(--fg-muted); margin-bottom: 6px; }

/* Pasek z konkretami. Czas realizacji i minimalna ilość odsiewają zapytania,
 * na które i tak padłaby odmowa - dlatego stoją wysoko, a nie w drobnym
 * druku pod formularzem. */
/* Kreski rysowane cieniem komórek, nie odstępem siatki.
 *
 * Pierwsza wersja robiła je przez `gap: 1px` na kolorowym tle - i to zależy
 * od tego, jak siatka się zawinie: przy czterech pozycjach w jednym rzędzie
 * jednej kreski brakowało. `box-shadow` rysuje się poza obrysem komórki
 * i jest przycinany przez `overflow: hidden` rodzica, więc skrajne linie
 * znikają same, a wewnętrzne są zawsze - niezależnie od liczby pozycji
 * i liczby rzędów. */
.et-ev-facts {
  display: grid;
  /* auto-fit, bo pozycji bywa trzy albo cztery - minimalna ilość pokazuje
   * się tylko wtedy, gdy właściciel ją ustawił. */
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 0;
  margin-bottom: clamp(28px, 5vw, 48px);
  background: var(--bg-page);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden;
}
.et-ev-facts > div {
  padding: 16px 18px;
  box-shadow: -1px 0 0 var(--border-default),
               0 -1px 0 var(--border-default);
}
.et-ev-fact-label {
  display: block;
  font-family: var(--font-heading);
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 4px;
}
.et-ev-facts strong { font-size: 14px; color: var(--color-bone-0); font-weight: 600; }

.et-ev-form-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 3.4vw, 30px);
  text-align: center;
  margin: 0 0 20px;
}
.et-ev-form {
  padding: clamp(18px, 3vw, 28px);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}

.et-ev-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.et-ev-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.et-ev-field--wide { grid-column: 1 / -1; }
.et-ev-field > span {
  font-family: var(--font-heading);
  font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-muted);
}
.et-ev-field em { color: var(--color-brand-orange); font-style: normal; }
.et-ev-field input,
.et-ev-field select,
.et-ev-field textarea {
  width: 100%;
  padding: 10px 13px;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: 8px;
  color: var(--color-bone-1);
  font-size: 16px;
  font-family: inherit;
}
.et-ev-field textarea { resize: vertical; }
/* LISTA I DATA PO IOS-OWEMU (audyt iOS 2026-09-26).
   Lista „Kto pyta" miała wygląd systemowy: na iPhonie własną strzałkę
   i inną wysokość niż pola obok (52 px przy 42 px pól). Ta sama strzałka
   co w formularzach WooCommerce, więc wygląda tak samo wszędzie.
   Pole daty na iPhonie ma wartość wyśrodkowaną i puste potrafi się
   spłaszczyć - stąd dosunięcie do lewej jak w pozostałych polach
   i najmniejsza wysokość równa celowi dotyku. */
.et-ev-field select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23B8AE9E' stroke-width='2'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.et-ev-field input[type="date"] { min-height: 44px; text-align: left; }
.et-ev-field input[type="date"]::-webkit-date-and-time-value { text-align: left; }
.et-ev-field input:focus, .et-ev-field select:focus, .et-ev-field textarea:focus {
  border-color: var(--color-brand-orange); /* pierscien fokusu z `:focus-visible` zostaje (audyt D15) */
}

.et-ev-consent {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 16px 0 0;
  font-size: 12px; line-height: 1.45; color: var(--fg-faint);
}
.et-ev-consent input { margin-top: 2px; width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--color-brand-orange); }

.et-ev-hp { position: absolute !important; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.et-ev-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 18px; }
.et-ev-msg { margin: 0; font-size: 13px; }
.et-ev-msg:empty { display: none; }
.et-ev-msg.is-ok  { color: var(--color-bone-3); }
.et-ev-msg.is-err { color: var(--color-danger); }

/* Zaproszenie na karcie pudełka personalizowanego. */
.et-ev-hint {
  margin: 12px 0 0;
  font-size: 13px; color: var(--fg-muted);
}
.et-ev-hint a { color: var(--color-brand-orange); }

@media (max-width: 860px) {
  .et-ev-cards { grid-template-columns: 1fr; }
  .et-ev-grid { grid-template-columns: 1fr; }
}

/* =========================================================================
   Subskrypcja taśm - konfigurator planu na stronie produktu
   ========================================================================= */

.et-sub {
  margin: 0 0 24px;
  display: grid;
  gap: 22px;
}

.et-sub-step { display: grid; gap: 10px; }

.et-sub-legend {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-sub-num {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-ink-4);
  color: var(--fg-default);
  font-size: 11px;
  letter-spacing: 0;
}

/* --- segmentowane przełączniki ------------------------------------------- */

.et-sub-seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }

.et-sub-opt { position: relative; display: block; cursor: pointer; }

/* Input zostaje w drzewie dostępności i obsłudze klawiatury - chowamy go
   wizualnie, a stan zaznaczenia rysuje sąsiadujący kafelek. */
.et-sub-opt input {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.et-sub-opt-in {
  position: relative;
  display: grid;
  gap: 1px;
  padding: 14px 8px 12px;
  min-height: 100%;
  text-align: center;
  align-content: center;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}

.et-sub-opt-in strong {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  color: var(--fg-default);
  /* Bebas Neue jest tylko w grubości 400; `strong` prosił o 700 i Safari
     dorabiał pogrubienie sam - obrys rozmyty (audyt iOS 2026-09-26). */
  font-weight: 400;
}

.et-sub-opt-freq {
  font-family: var(--font-heading) !important;
  font-size: 14px !important;
  line-height: 1.25 !important;
}

.et-sub-opt-lbl {
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-sub-opt-in small {
  margin-top: 5px;
  font-size: 12px;
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

@media (hover: hover) and (pointer: fine) {
  .et-sub-opt:hover .et-sub-opt-in { border-color: var(--border-strong); }
}

.et-sub-opt input:checked + .et-sub-opt-in {
  border-color: var(--color-brand-orange);
  background: var(--color-brand-amber-grain);
}

.et-sub-opt input:checked + .et-sub-opt-in small { color: var(--color-brand-orange-bright); }

.et-sub-opt input:focus-visible + .et-sub-opt-in {
  outline: 2px solid var(--color-brand-orange-bright);
  outline-offset: 2px;
}

.et-sub-opt input:active + .et-sub-opt-in { transform: scale(.98); }

.et-sub-flag {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: .07em;
  text-transform: uppercase;
}

/* --- próbki kolorów ------------------------------------------------------ */

.et-sub-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.et-sub-sw {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 5px;
  width: 58px;
  cursor: pointer;
}

.et-sub-sw input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.et-sub-sw-in {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--sw, #8A8A8A);
  box-shadow: 0 0 0 1px var(--border-strong);
  transition: box-shadow .18s ease, transform .18s ease;
}

/* Mix dostaje kołowy gradient z prawdziwych barw taśm - czytelniej niż napis. */
.et-sub-sw-mix .et-sub-sw-in {
  background: conic-gradient(
    #1F1F23 0 12.5%, #F2EFE9 0 25%, #B3202C 0 37.5%, #5A3B84 0 50%,
    #5A6136 0 62.5%, #33517E 0 75%, #D6497C 0 87.5%, #E89A3C 0
  );
}

.et-sub-sw-lbl {
  font-size: 11px;
  line-height: 1.2;
  text-align: center;
  color: var(--fg-muted);
}

@media (hover: hover) and (pointer: fine) {
  .et-sub-sw:hover .et-sub-sw-in { transform: scale(1.08); }
}

.et-sub-sw input:checked + .et-sub-sw-in {
  box-shadow: 0 0 0 2px var(--bg-page), 0 0 0 4px var(--color-brand-orange);
  transform: scale(1.08);
}

.et-sub-sw input:checked ~ .et-sub-sw-lbl { color: var(--fg-default); }

.et-sub-sw input:focus-visible + .et-sub-sw-in {
  outline: 2px solid var(--color-brand-orange-bright);
  outline-offset: 3px;
}

.et-sub-hint { margin: 2px 0 0; font-size: 12.5px; color: var(--fg-faint); }

/* --- podsumowanie planu -------------------------------------------------- */

.et-sub-plan {
  display: grid;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: linear-gradient(180deg, var(--color-ink-2), var(--color-ink-3));
}

/* Oś czasu: kropki na wspólnej linii, podpisane realnymi miesiącami. */
.et-sub-timeline {
  position: relative;
  display: flex;
  justify-content: space-between;
  gap: 4px;
  margin: 4px 0 2px;
  padding: 0;
  list-style: none;
}

.et-sub-timeline::before {
  content: "";
  position: absolute;
  left: 6px;
  right: 6px;
  top: 5px;
  height: 2px;
  background: var(--color-ink-4);
}

.et-sub-dot {
  position: relative;
  flex: 1;
  padding-top: 18px;
  text-align: center;
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-sub-dot::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-brand-orange);
  box-shadow: 0 0 0 3px var(--color-ink-2);
}

.et-sub-dot[data-year]::after {
  content: "’" attr(data-year);
  margin-left: 2px;
  color: var(--fg-faint);
}

.et-sub-dot-gap { color: var(--fg-faint); }
.et-sub-dot-gap::before { display: none; }

.et-sub-lines {
  display: grid;
  gap: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border-default);
}

.et-sub-line { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; }
.et-sub-line-k { color: var(--fg-muted); }
.et-sub-line-v { color: var(--fg-default); font-variant-numeric: tabular-nums; }
.et-sub-line-v.is-free { color: var(--color-success); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }

.et-sub-sum {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-default);
}

.et-sub-sum-k {
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-sub-total {
  font-family: var(--font-display);
  font-size: 34px;
  line-height: 1;
  color: var(--color-brand-orange);
  font-variant-numeric: tabular-nums;
  font-weight: 400; /* jw. - Bebas bez sztucznego pogrubienia */
}

.et-sub-save {
  margin: 0;
  padding: 8px 12px;
  border-radius: var(--radius-3);
  background: rgba(76, 174, 107, .12);
  color: var(--color-success);
  font-size: 13px;
  font-weight: 600;
}

@media (max-width: 560px) {
  .et-sub-seg { grid-template-columns: repeat(2, 1fr); }
  /* Ostatnia opcja bez pary na całą szerokość - przy trzech opcjach
     w dwóch kolumnach stała sama, z pustym miejscem obok (2026-09-24). */
  .et-sub-seg > .et-sub-opt:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .et-sub-total { font-size: 30px; }
  .et-sub-sw { width: 52px; }
}

@media (prefers-reduced-motion: reduce) {
  .et-sub-opt-in, .et-sub-sw-in { transition: none; }
  .et-sub-sw:hover .et-sub-sw-in { transform: none; }
}

/* --- Subskrypcja: pasek zachęty na stronie głównej ------------------------ */

/* Celowo wąski pasek, nie sekcja: strona główna ma już kreator zestawu,
   a drugi duży blok tej samej rangi rozmyłby oba. */
.et-subcta { padding: 0 0 var(--et-space-desktop, 64px); }

.et-subcta-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 22px;
  text-decoration: none;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background:
    radial-gradient(120% 180% at 100% 50%, rgba(246, 149, 0, .10), transparent 62%),
    var(--color-ink-2);
  transition: border-color .18s ease, background .18s ease;
}

@media (hover: hover) and (pointer: fine) {
  .et-subcta-bar:hover { border-color: var(--color-brand-orange); }
}

.et-subcta-text { display: grid; gap: 3px; min-width: 0; }

.et-subcta-text strong {
  font-family: var(--font-heading);
  font-size: 17px;
  letter-spacing: .02em;
  color: var(--fg-default);
}

/* Zdanie obok przycisku łamie się na dwa równe wiersze zamiast zostawiać
   ogon w drugim: przed zmianą było „...często - płacisz raz," / „resztę
   pilnujemy my.", po zmianie „Ustal, ile taśm i jak często -" / „płacisz raz,
   resztę pilnujemy my." (zmierzone na 360, 390, 412 i 430 px). Samotne „my"
   na końcu pilnuje dodatkowo twarda spacja z `egotape_bez_sieroty()` - dla
   przeglądarek, które nie znają jeszcze `text-wrap`. */
.et-subcta-text span { font-size: 14px; color: var(--fg-muted); text-wrap: balance; }

.et-subcta-end { display: flex; align-items: center; gap: 18px; flex-shrink: 0; }

.et-subcta-from { font-size: 13.5px; color: var(--fg-muted); white-space: nowrap; }
.et-subcta-from .amount { color: var(--fg-default); font-weight: 600; }

/* Cały pasek jest linkiem, więc „przycisk" to tylko wygląd - nie zagnieżdżamy
   drugiego elementu klikalnego w klikalnym. */
.et-subcta-btn { pointer-events: none; }

@media (max-width: 720px) {
  .et-subcta-bar { flex-direction: column; align-items: flex-start; gap: 14px; }
  .et-subcta-end { width: 100%; justify-content: space-between; }
}

/* DÓŁ KARTY NA TELEFONIE: CENA NAD PRZYCISKIEM, PRZYCISK NA CAŁĄ SZEROKOŚĆ.

   Cena („od 39,99 zł za dostawę", 152 px) i przycisk („Zamów subskrypcję",
   168 px z wypełnieniem) potrzebują razem 338 px, a karta daje 288 px na
   ekranie 390 px. Obok siebie mieszczą się dopiero od ok. 560 px szerokości
   okna - niżej napis na przycisku łamał się na dwa wiersze, rząd rósł do
   56 px i cena wisiała wyśrodkowana w pustce obok (zgłoszenie właściciela
   2026-09-23). Pionowo: cena w swoim wierszu, przycisk pełnej szerokości. */
@media (max-width: 560px) {
  .et-subcta-end {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .et-subcta-btn { width: 100%; }

  /* Ciaśniejsze wypełnienie karty: przy marginesie strony 28 px i wypełnieniu
     22 px tekst zaczynał się 50 px od krawędzi ekranu, a to właśnie te piksele
     decydują, czy zdanie zmieści się w jednym wierszu. */
  .et-subcta-bar { padding: 16px; }

  /* Zdanie ma zostać w JEDNYM wierszu (prośba właściciela). Przy stałych 14 px
     mieści się od 390 px szerokości okna, ale już nie na 360 px, gdzie kolumna
     ma 272 px - stąd człon `vw`, który schodzi do 12,5 px na najwęższych
     ekranach i wraca do 14 px, gdy tylko jest miejsce. */
  .et-subcta-text span { font-size: clamp(12.5px, 3.7vw, 14px); }
}

/* Napis na przycisku zostaje w jednym wierszu - na telefonie przycisk ma całą
   szerokość karty, a szerzej i tak się mieści. */
.et-subcta-btn { white-space: nowrap; }

/* --- Subskrypcja: panel klienta w „Moje konto" ---------------------------- */

.et-acc-sub {
  margin: 0 0 26px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  overflow: hidden;
}

.et-acc-head {
  padding: 16px 18px;
  border-bottom: 1px solid var(--border-default);
}

.et-acc-head h3 { margin: 0; font-family: var(--font-heading); font-size: 17px; }
.et-acc-meta { margin: 4px 0 0; font-size: 13px; color: var(--fg-muted); }

.et-acc-list { margin: 0; padding: 0; list-style: none; }

.et-acc-item {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 16px;
  padding: 14px 18px;
  border-top: 1px solid var(--color-ink-3);
}

.et-acc-item:first-child { border-top: 0; }
.et-acc-item.is-locked { opacity: .62; }

.et-acc-when { display: grid; gap: 2px; align-content: start; }
.et-acc-when strong { font-size: 14.5px; color: var(--fg-default); }
.et-acc-when span { font-size: 12px; color: var(--fg-faint); }

.et-acc-now { display: flex; flex-wrap: wrap; gap: 8px; }

.et-acc-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 10px 4px 6px;
  border-radius: var(--radius-pill);
  background: var(--color-ink-3);
  font-size: 12.5px;
  color: var(--fg-default);
}

.et-acc-chip i,
.et-acc-color i {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--sw, #8A8A8A);
  box-shadow: 0 0 0 1px var(--border-strong);
  flex-shrink: 0;
}

.et-acc-lock { margin: 8px 0 0; font-size: 12.5px; color: var(--fg-faint); }

/* --- rezygnacja z subskrypcji ------------------------------------------
   Celowo najcichszy element na ekranie: odsuniety kreska, drobnym pismem,
   w kolorze przygaszonym zamiast pomaranczowego akcentu, ktory w tym
   motywie znaczy „kliknij tutaj". Ma byc do znalezienia, gdy ktos go
   szuka, i niewidoczny, gdy nie szuka.
   Rozwiniety wyglada juz normalnie - skoro ktos tu doszedl, ma prawo
   przeczytac rachunek bez mruzenia oczu. */
.et-acc-quit { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border-default); }
/* Karta subskrypcji nie ma własnego wypełnienia (mają je nagłówek, adres
   i paczki: 18 px z boków). Rezygnacja go nie miała, więc tekst stał przy
   samej ramce, a kwota „1 619,60 zł” dotykała prawej krawędzi karty
   (atrapa, 393 px). */
.et-acc-sub > .et-acc-quit { padding: 14px 18px 18px; }

.et-acc-quit > summary {
  cursor: pointer;
  width: fit-content;
  font-size: 12.5px;
  color: var(--fg-faint);
}
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-acc-quit > summary:hover { color: var(--fg-muted); }
}

.et-acc-quit-body { margin-top: 12px; max-width: 46ch; font-size: 14px; color: var(--fg-muted); }

.et-acc-quit-calc { width: 100%; margin: 12px 0; border-collapse: collapse; }
.et-acc-quit-calc th,
.et-acc-quit-calc td { padding: 6px 0; text-align: left; font-weight: 400; }
.et-acc-quit-calc td { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.et-acc-quit-sum th,
.et-acc-quit-sum td {
  border-top: 1px solid var(--border-default);
  padding-top: 10px;
  color: var(--fg-default);
  font-weight: 700;
}

.et-acc-quit-ok { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 12px; font-size: 13px; }
.et-acc-quit-ok input { margin-top: 2px; flex: 0 0 auto; }
/* To zdanie, nie podpis pola - reguła etykiet formularzy konta pisała je
   wersalikami 12 px. */
.et-account .et-acc-quit-ok { font-size: 13px; letter-spacing: normal; text-transform: none; }

/* Przycisk wtorny, nie akcja glowna - obrys zamiast wypelnienia.
   Selektor z `.et-account .button`: sama klasa przegrywała z pomarańczowym
   wypełnieniem `.et-account .button` (dwie klasy, dalej w pliku) i przycisk
   rezygnacji wyglądał jak główna akcja ekranu. */
.et-account .button.et-acc-quit-btn {
  background: transparent;
  border: 1px solid var(--border-input);
  color: var(--fg-muted);
}
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-account .button.et-acc-quit-btn:hover { border-color: var(--color-danger); color: var(--color-danger); background: transparent; }
}

.et-acc-quit-note { margin: 14px 0 0; font-size: 12.5px; color: var(--fg-faint); }

.et-acc-edit { margin-top: 10px; }

.et-acc-edit summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--color-brand-orange);
  width: fit-content;
}
/* „Zmień kolory”, „Zmień paczkomat lub kontakt” i „Rezygnacja…” mają
   13 px pisma i ok. 20 px wysokości. Na dotyk niewidoczne pole 44 px
   (warstwa `::after`), bez przesuwania czegokolwiek w karcie. */
@media (pointer: coarse) {
  .et-acc-edit > summary,
  .et-acc-quit > summary { position: relative; }
  .et-acc-edit > summary::after,
  .et-acc-quit > summary::after { content: ""; position: absolute; inset: -12px -8px; }
}

.et-acc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 8px;
  margin: 12px 0;
}

.et-acc-color {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--color-ink-3);
}

.et-acc-name { flex: 1; font-size: 13px; color: var(--fg-default); min-width: 0; }
/* Kafel koloru to `label` - reguła etykiet formularzy konta dawała mu
   wersaliki („CZARNY”), a obok, w podsumowaniu paczki, ten sam kolor stoi
   zwykłym pismem („4 × Czarny”). */
.et-account .et-acc-color { letter-spacing: normal; text-transform: none; }

.et-acc-color input {
  width: 58px;
  padding: 5px 6px;
  text-align: center;
  background: var(--bg-input);
  color: var(--fg-default);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  font-variant-numeric: tabular-nums;
}

.et-acc-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.et-acc-total { margin: 0; font-size: 13px; color: var(--fg-muted); }
.et-acc-form.is-invalid .et-acc-total { color: var(--color-danger); }
.et-acc-form button[disabled] { opacity: .5; cursor: not-allowed; }

@media (max-width: 600px) {
  .et-acc-item { grid-template-columns: 1fr; gap: 8px; }
}

/* --- Subskrypcja: grafika bez białej ramki -------------------------------- */

/* Zdjęcia produktów to wycinanki na przezroczystym tle, więc galeria daje im
   białą podkładkę z marginesem. Grafika subskrypcji jest ciemna i wypełnia
   cały kadr - ta sama podkładka robi z niej białą ramkę. */
/* UWAGA na selektor: klasa `woocommerce` siedzi na <body>, czyli na TYM SAMYM
   elemencie co `et-subscription-product`. Zapis z odstępem
   (`.et-subscription-product .woocommerce`) wymagałby dwóch różnych elementów
   i nigdy nie trafiał - biała podkładka zostawała mimo poprawki. Muszą być
   zapisane razem, bez odstępu. */
.et-subscription-product.woocommerce div.product div.images .woocommerce-product-gallery__wrapper {
  background: transparent;
  padding: 0;
}

.et-subscription-product.woocommerce div.product div.images img {
  border-radius: var(--radius-3);
  filter: none;
}

/* W kaflu listy (kategoria, wyszukiwarka) ta sama zasada: tło pod grafiką
   w jej własnej czerni, a nie w bieli przewidzianej dla wycinanek. */
li.product.et-sub-tile .et-product-well { background: var(--color-ink-1); }

/* Grafika ma wypełnić kadr co do piksela. Selektor musi być mocniejszy niż
   reguła WooCommerce `.woocommerce ul.products li.product a img`
   (`width:100%;height:auto;margin:0 0 1em`) - to ona zostawiała pasek tła
   pod obrazkiem, widoczny jako biała ramka. */
.woocommerce ul.products li.product.et-sub-tile .et-product-well img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  margin: 0;
}

/* Na karcie produktu grafika idzie na całą szerokość kolumny. */
.et-subscription-product.woocommerce div.product div.images .woocommerce-product-gallery__wrapper img {
  width: 100%;
  height: auto;
  display: block;
  margin: 0;
}

/* --- Subskrypcja: rozpis kolorów na poszczególne dostawy ------------------ */

.et-sub-split { margin-top: 12px; }

.et-sub-split > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--color-brand-orange);
  width: fit-content;
}

.et-sub-split-rows { display: grid; gap: 10px; margin-top: 12px; }

.et-sub-split-row {
  padding: 10px 12px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--color-ink-3);
}

.et-sub-split-row.is-bad { border-color: var(--color-danger); }

.et-sub-split-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}

.et-sub-split-head strong {
  font-family: var(--font-heading);
  font-size: 13px;
  color: var(--fg-default);
}

.et-sub-split-head span { font-size: 12px; color: var(--fg-faint); text-transform: uppercase; }

.et-sub-split-sum {
  margin-left: auto;
  font-style: normal;
  font-size: 12px;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}

.et-sub-split-row.is-bad .et-sub-split-sum { color: var(--color-danger); font-weight: 600; }

.et-sub-split-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
  gap: 6px;
}

.et-sub-split-color {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 6px;
  background: var(--bg-surface);
}

.et-sub-split-color i {
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--sw, #8A8A8A);
  box-shadow: 0 0 0 1px var(--border-strong);
  flex-shrink: 0;
}

.et-sub-split-color span { flex: 1; font-size: 12.5px; color: var(--fg-muted); min-width: 0; }

.et-sub-split-color input {
  width: 48px;
  padding: 4px 5px;
  text-align: center;
  background: var(--bg-input);
  color: var(--fg-default);
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  font-variant-numeric: tabular-nums;
}
/* Dwie kolumny po 153 px na telefonie (393 px): na nazwę zostawało 60 px,
   a „Bursztynowy" ma przy 12,5 px 77 px - końcówka chowała się pod polem
   liczby („Bursztynow"), „Purpurowy" i „Granatowy" dotykały pola (audyt iOS
   2026-09-26). Telefon nie rysuje strzałek w polu liczby, więc pole może
   być węższe; pismo 11,5 px to wciąż ponad dołem skali motywu. */
@media (max-width: 420px) {
  .et-sub-split-color { gap: 6px; }
  .et-sub-split-color span { font-size: 11.5px; }
  .et-sub-split-color input { width: 40px; }
}

/* --- Subskrypcja: dane dostawy w koncie klienta --------------------------- */

.et-acc-dest {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-default);
  background: var(--color-ink-3);
}

.et-acc-dest-now { display: grid; gap: 2px; }

.et-acc-dest-k {
  font-family: var(--font-heading);
  font-size: 11.5px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-acc-dest-now strong { font-size: 14.5px; color: var(--fg-default); }
.et-acc-dest-c { font-size: 12.5px; color: var(--fg-faint); }

.et-acc-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  margin: 12px 0;
}

.et-acc-fields label { display: grid; gap: 4px; min-width: 0; }
.et-acc-fields .et-acc-wide { grid-column: 1 / -1; }

.et-acc-fields span {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-acc-fields input {
  padding: 9px 10px;
  background: var(--bg-input);
  color: var(--fg-default);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: 14.5px;
}

.et-acc-fields input:focus-visible {
  outline: 2px solid var(--color-brand-orange);
  outline-offset: 1px;
}

.et-acc-destform .et-acc-hint { margin: 0 0 12px; font-size: 12.5px; color: var(--fg-faint); }

/* =========================================================================
   Moje konto — układ, nawigacja, kokpit
   =========================================================================
   WooCommerce daje tu gołą listę linków i dwa akapity tekstu. Na ciemnym
   motywie wyglądało to jak strona bez stylów, a zamówienia i subskrypcje
   niczym nie wyróżniały się z listy. */

/* Strony konta idą przez page.php, gdzie `.entry` ma 760 px szerokości do
   czytania artykułów. Dla panelu z nawigacją i tabelami to o wiele za mało -
   nawigacja ściskała się do „Kok", a tabele zamówień i adresów rozjeżdżały. */
.et-account .entry { max-width: none; }
.et-account .entry-content { color: var(--fg-default); }

.et-account .woocommerce {
  display: grid;
  /* Stała szerokość, nie `minmax(0, 250px)`: przy minimum 0 kolumna kurczy
     się razem z treścią i etykiety zakładek się ucinają. */
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 22px 30px;
  align-items: start;
}

/* Cokolwiek jeszcze WooCommerce tu wstawi (powiadomienia) - na całą szerokość. */
.et-account .woocommerce > * { grid-column: 1 / -1; min-width: 0; }
.et-account .woocommerce-MyAccount-navigation { grid-column: 1; }
.et-account .woocommerce-MyAccount-content { grid-column: 2; }

/* WooCommerce układa te dwa bloki floatami: nawigacja 30%, treść 68%.
   W siatce float nic nie robi, ale PROCENTY owszem - i liczą się od kolumny
   siatki, nie od strony. Nawigacja dostawała 30% z 250 px, czyli 75 px,
   przez co „Kokpit" ucinał się do „Kok". */
.et-account .woocommerce-MyAccount-navigation,
.et-account .woocommerce-MyAccount-content {
  float: none;
  width: auto;
}

/* --- nagłówek konta ------------------------------------------------------- */

.et-acch {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 22px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background:
    radial-gradient(120% 200% at 0% 50%, rgba(246, 149, 0, .10), transparent 58%),
    linear-gradient(180deg, var(--color-ink-2), var(--color-ink-3));
}

.et-acch-av { flex-shrink: 0; line-height: 0; }
.et-acch-txt { flex: 1; min-width: 0; display: grid; gap: 5px; }

.et-acch-hi {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  line-height: 1;
  letter-spacing: .03em;
  color: var(--fg-default);
}

.et-acch-rank { display: flex; }

.et-acch-out {
  flex-shrink: 0;
  padding: 8px 16px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  font-family: var(--font-heading);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  text-decoration: none;
  transition: border-color .18s ease, color .18s ease;
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-acch-out:hover { border-color: var(--color-brand-orange); color: var(--fg-default); }
}

/* --- nawigacja ------------------------------------------------------------ */

.et-account .woocommerce-MyAccount-navigation {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  overflow: hidden;
  position: sticky;
  top: 92px;
}

.et-account .woocommerce-MyAccount-navigation ul { margin: 0; padding: 6px; list-style: none; }
.et-account .woocommerce-MyAccount-navigation li { margin: 0; }

.et-account .woocommerce-MyAccount-navigation a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  border-radius: 7px;
  font-size: 14.5px;
  color: var(--fg-muted);
  text-decoration: none;
  transition: background .16s ease, color .16s ease;
}

/* Ikona rysowana maską na klasie, którą WooCommerce sam nadaje pozycji -
   dzięki temu nie trzeba podmieniać szablonu nawigacji. */
.et-account .woocommerce-MyAccount-navigation a::before {
  content: "";
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
  opacity: .85;
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-account .woocommerce-MyAccount-navigation a:hover { background: var(--color-ink-3); color: var(--fg-default); }
}

.et-account .woocommerce-MyAccount-navigation li.is-active a {
  background: var(--color-brand-amber-grain);
  color: var(--color-brand-orange-bright);
  font-weight: 600;
}

.et-account .woocommerce-MyAccount-navigation li.is-active a::before { opacity: 1; }

.woocommerce-MyAccount-navigation-link--dashboard      { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9'%3E%3Crect x='3' y='3' width='7' height='7'/%3E%3Crect x='14' y='3' width='7' height='7'/%3E%3Crect x='3' y='14' width='7' height='7'/%3E%3Crect x='14' y='14' width='7' height='7'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--orders         { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linejoin='round'%3E%3Cpath d='M3 7l9-4 9 4v10l-9 4-9-4z'/%3E%3Cpath d='M3 7l9 4 9-4M12 11v10'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--subskrypcje    { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9a8 8 0 0113.6-4.6L21 8'/%3E%3Cpath d='M21 3v5h-5'/%3E%3Cpath d='M20 15a8 8 0 01-13.6 4.6L3 16'/%3E%3Cpath d='M3 21v-5h5'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--downloads      { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='M7 11l5 5 5-5'/%3E%3Cpath d='M4 21h16'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--edit-address   { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linejoin='round'%3E%3Cpath d='M12 21s7-6 7-11a7 7 0 10-14 0c0 5 7 11 7 11z'/%3E%3Ccircle cx='12' cy='10' r='2.5'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--edit-account   { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0116 0'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--p24-one-click  { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9'%3E%3Crect x='2.5' y='5' width='19' height='14' rx='2'/%3E%3Cpath d='M2.5 10h19'/%3E%3C/svg%3E"); }
.woocommerce-MyAccount-navigation-link--customer-logout{ --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4'/%3E%3Cpath d='M16 17l5-5-5-5M21 12H9'/%3E%3C/svg%3E"); }

/* Wylogowanie odsuwamy od reszty - to nie jest kolejna zakładka konta. */
.woocommerce-MyAccount-navigation-link--customer-logout {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--color-ink-3);
}

/* --- treść ---------------------------------------------------------------- */

.et-account .woocommerce-MyAccount-content { color: var(--fg-default); }

/* Domyślne akapity kokpitu - patrz komentarz w inc/account.php. */
.et-account-dashboard .woocommerce-MyAccount-content > p { display: none; }

/* --- kafle kokpitu -------------------------------------------------------- */

.et-dash {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}

.et-card {
  display: grid;
  align-content: start;
  gap: 6px;
  padding: 18px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  text-decoration: none;
  transition: border-color .18s ease, transform .18s ease;
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  a.et-card:hover { border-color: var(--color-brand-orange); transform: translateY(-2px); }
}
a.et-card:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; }

.et-card-eyebrow {
  font-family: var(--font-heading);
  font-size: 11.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-card-num {
  font-family: var(--font-display);
  font-size: 44px;
  line-height: .95;
  color: var(--color-brand-orange);
  font-variant-numeric: tabular-nums;
}

.et-card-lead {
  font-family: var(--font-heading);
  font-size: 19px;
  line-height: 1.2;
  color: var(--fg-default);
}

.et-card-sub { font-size: 13px; color: var(--fg-muted); }

.et-card-go {
  margin-top: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-brand-orange);
}

.et-card-go::after { content: " ›"; } /* dywiz i „›" zamiast strzalki - czytnik nie mowi „strzalka w prawo" (audyt D13) */

.et-card-quiet { background: var(--color-ink-3); }

.et-card-invite {
  background:
    radial-gradient(130% 160% at 100% 0%, rgba(246, 149, 0, .12), transparent 60%),
    var(--bg-surface);
}

/* Najbliższa paczka: data i kolory rolek, które w niej pojadą. */
.et-card-next { display: grid; gap: 4px; margin-top: 4px; }
.et-card-next-k { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-faint); }
.et-card-next strong { font-size: 16px; color: var(--fg-default); }

.et-card-rolls { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }

.et-card-rolls i {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--sw, #8A8A8A);
  box-shadow: 0 0 0 1px var(--border-strong);
}

.et-card-progress {
  margin-top: 10px;
  height: 4px;
  border-radius: 2px;
  background: var(--color-ink-4);
  overflow: hidden;
}

.et-card-progress span { display: block; height: 100%; background: var(--color-brand-orange); }

.et-dash-links { display: flex; flex-wrap: wrap; gap: 10px; }

.et-dash-links a {
  padding: 9px 15px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  font-size: 13.5px;
  color: var(--fg-muted);
  text-decoration: none;
  transition: border-color .18s ease, color .18s ease;
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-dash-links a:hover { border-color: var(--border-strong); color: var(--fg-default); }
}

/* Na dotyk 44 px zamiast zmierzonych 38 - to jedyne skróty do adresów
   i hasła w kokpicie. Mysz zostaje przy dawnym rozmiarze. */
@media (pointer: coarse) {
  .et-dash-links a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* --- tabele i formularze w koncie ----------------------------------------- */

.et-account .woocommerce-orders-table,
.et-account .shop_table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  overflow: hidden;
  background: var(--bg-surface);
}

.et-account .shop_table th {
  padding: 12px 14px;
  text-align: left;
  font-family: var(--font-heading);
  font-size: 11.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  background: var(--color-ink-3);
  border-bottom: 1px solid var(--border-default);
}

.et-account .shop_table td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--color-ink-3);
  font-size: 14px;
  color: var(--fg-default);
}

.et-account .shop_table tr:last-child td { border-bottom: 0; }

.et-account .woocommerce-button,
.et-account .button {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; /* pigulka miala ok. 34 px (audyt D5) */
  padding: 9px 16px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  font-family: var(--font-heading);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: filter .15s ease;
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-account .woocommerce-button:hover,
  .et-account .button:hover { filter: brightness(1.08); }
}

/* Śledzenie przesyłki nad „Szczegółami zamówienia” w Moim koncie (2026-09-27,
   `woocommerce_view_order` w inc/woocommerce.php). Karta jak podsumowania
   w koncie; numer tabelaryczny, przycisk to zwykły `.et-account .button`.
   Na wąskim ekranie przycisk schodzi pod numer na całą szerokość. */
.et-account .et-tracking {
  margin: 0 0 24px;
  padding: 16px 18px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
}
.et-account .et-tracking-title {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-size: 17px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.et-account .et-tracking-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 14px; }
.et-account .et-tracking-item {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 16px;
}
.et-account .et-tracking-info { display: grid; gap: 2px; min-width: 0; }
.et-account .et-tracking-carrier { font-size: 13px; color: var(--fg-muted); }
/* Numer InPost ma 24 cyfry: na 320 px przy 16 px łamał się w środku
   (trudno przeczytać i przepisać) - czcionka maleje z ekranem do 14 px. */
.et-account .et-tracking-number {
  font-size: clamp(14px, 4.2vw, 16px); font-weight: 600; color: var(--fg-default);
  font-variant-numeric: tabular-nums; letter-spacing: .02em; overflow-wrap: anywhere;
}
@media (max-width: 400px) {
  .et-account .et-tracking-number { letter-spacing: 0; }
}
.et-account .button.et-tracking-btn { margin: 0; }
@media (max-width: 480px) {
  .et-account .button.et-tracking-btn { width: 100%; }
}

.et-account .woocommerce-Address {
  padding: 16px 18px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  margin-bottom: 16px;
}

/* `flex-wrap`: tytuł („Adres rozliczeniowy”) i odnośnik („Edytuj Adres
   rozliczeniowy”) razem mają ok. 320 px, a karta na 393 px ma 299 px
   w środku - bez zawijania tytuł łamał się na dwa wiersze. Teraz odnośnik
   schodzi pod tytuł. */
.et-account .woocommerce-Address-title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px; }
/* Clearfix z woocommerce-layout.css (`::before`/`::after`, `display: table`)
   w układzie flex był pustym elementem: odstęp 12 px wcinał tytuł, a przy
   zawijaniu spychał go na prawy brzeg. Selektor 0,3,1 - tyle co
   `.woocommerce-account .addresses .title::before` z WooCommerce. */
.et-account .addresses .woocommerce-Address-title::before,
.et-account .addresses .woocommerce-Address-title::after { content: none; }
.et-account .woocommerce-Address address { font-style: normal; color: var(--fg-muted); line-height: 1.7; }

/* FORMULARZE KONTA - TYLKO W TREŚCI KONTA.

   `:where(.woocommerce)` zawęża reguły do formularzy WooCommerce (dane,
   adresy, logowanie, subskrypcja) i NIE zmienia ich szczegółowości.
   Bez tego `.et-account form label` łapało każdy formularz na stronach
   konta, także zapis na newsletter nad stopką: zgoda szła wersalikami,
   a pole e-mail traciło kształt pigułki (7 px zaokrąglenia zamiast
   `--radius-pill`) - tylko na stronach konta. */
/* `padding: 0`: WooCommerce daje wierszom formularza 3 px wypełnienia, więc
   etykiety i pola stały 3 px na prawo od tytułów sekcji, przycisków
   i akapitów tego samego formularza. */
.et-account :where(.woocommerce) form .form-row { display: grid; gap: 5px; margin-bottom: 14px; padding: 0; }

.et-account :where(.woocommerce) form label {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.et-account :where(.woocommerce) form .input-text,
.et-account :where(.woocommerce) form input[type="text"],
.et-account :where(.woocommerce) form input[type="email"],
.et-account :where(.woocommerce) form input[type="tel"],
.et-account :where(.woocommerce) form input[type="password"],
.et-account :where(.woocommerce) form select {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  color: var(--fg-default);
  border: 1px solid var(--border-input);
  border-radius: 7px;
  font-family: var(--font-body);
  font-size: 16px; /* bylo 15 - zoom na iOS */
}

.et-account :where(.woocommerce) form .input-text:focus-visible,
.et-account :where(.woocommerce) form select:focus-visible {
  outline: 2px solid var(--color-brand-orange);
  outline-offset: 1px;
}

/*
 * WooCommerce wstawia ikonę komunikatu przez `::before` pozycjonowane
 * ABSOLUTNIE (top: 1em, left: 1.5em) i robi jej miejsce lewym wcięciem
 * `padding-left: 3.5em`. Nadpisanie samego `padding` kasowało to miejsce,
 * ale nie ruszało ikony - zielony ptaszek lądował na tekście i całość
 * była nieczytelna. Zmieniamy oba naraz: wcięcie i pozycję ikony.
 */
.et-account .woocommerce-info,
.et-account .woocommerce-message {
  border-left: 3px solid var(--color-brand-orange);
  /* GÓRNA KRESKA ZDJĘTA - to ona wyglądała jak ucięta ramka.

     WooCommerce daje każdemu powiadomieniu `border-top: 3px solid`, a reguła
     wyżej dokłada tu akcent po lewej. Razem dawało to pomarańczową literę L:
     kreska u góry i przy lewej krawędzi, a prawa i dolna bez niczego. Oko
     czyta taki kształt jako ramkę, której zabrakło dwóch boków - zwłaszcza
     że prawe rogi są zaokrąglone, a lewe nie.

     Zamierzony był sam pasek z lewej: `border-radius: 0 R R 0` mówi wprost
     „płasko przy lewej, zaokrąglone po prawej", czyli kształt zakładki
     doklejonej do krawędzi. Kreska u góry była niedopatrzeniem, nie
     decyzją. */
  border-top: 0;
  background: var(--color-ink-3);
  color: var(--fg-default);
  padding: 13px 16px 13px 44px;
  border-radius: 0 var(--radius-3) var(--radius-3) 0;
}
.et-account .woocommerce-info::before,
.et-account .woocommerce-message::before {
  top: 13px;
  left: 16px;
}

/* KOMUNIKAT PRZELEWY24 W „PŁATNOŚCI ONE CLICK” (zgłoszenie #6).

   Wtyczka (`templates/account/one-click-tab.php`) wypisuje „Brak zapisanej
   płatności/zakupu one click.” znacznikiem komunikatu z WooCommerce Blocks
   (`.wc-block-components-notice-banner`), a style tego znacznika siedzą
   w arkuszach koszyka i kasy - na stronie konta ich nie ma. Zostawał goły
   `div`: ikona (i) sama w pierwszym wierszu, tekst bez odstępu od ramki.
   Tu dostaje wygląd komunikatów konta (pasek z lewej, ciemne tło, ikona
   obok tekstu). Selektor z `.woocommerce-MyAccount-content` (trzy klasy),
   żeby wygrał z arkuszem Blocks także tam, gdzie ten jednak się załaduje. */
.et-account .woocommerce-MyAccount-content .wc-block-components-notice-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 16px;
  padding: 13px 16px;
  border: 0;
  border-left: 3px solid var(--color-brand-orange);
  border-radius: 0 var(--radius-3) var(--radius-3) 0;
  background: var(--color-ink-3);
  color: var(--fg-default);
  font-size: 16px;
  line-height: 1.6;
}
.et-account .woocommerce-MyAccount-content .wc-block-components-notice-banner > svg {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 3px;
  padding: 0;
  border-radius: 0;
  background: none;
  fill: var(--color-info);
}
.et-account .woocommerce-MyAccount-content .wc-block-components-notice-banner > .wc-block-components-notice-banner__content {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
}

/* Pierścień fokusu na komunikacie. WooCommerce (woocommerce.js,
   `focus_populate_live_region`) po 500 ms ustawia fokus na pierwszym
   komunikacie z `role="alert"` (tabindex -1), żeby czytnik ekranu go
   przeczytał. Fokus ze skryptu zaraz po wejściu na stronę dostaje
   `:focus-visible`, więc komunikat obrysowywał się pierścieniem motywu:
   2 px + 2 px odsunięcia, ramka o 4 px szersza od kolumny treści (zrzut #6:
   58-866 zamiast 67-857). Komunikat nie jest sterowaniem - Tab go omija,
   a czytnik fokus dostaje i bez pierścienia. */
.et-account :is(.woocommerce-message, .woocommerce-error, .woocommerce-info, .wc-block-components-notice-banner)[tabindex="-1"]:focus { outline: none; }

/* --- telefon -------------------------------------------------------------- */

@media (max-width: 900px) {
  .et-account .woocommerce { grid-template-columns: 1fr; }
  .et-account .woocommerce-MyAccount-navigation,
  .et-account .woocommerce-MyAccount-content { grid-column: 1; }

  /* ZAKŁADKI W RÓWNEJ SIATCE, NIE PRZEWIJANE.

     Wcześniej był tu poziomy przewijak, żeby zaoszczędzić miejsce w pionie -
     i to była zła zamiana. Zmierzone na 390 px: pasek miał 848 px treści
     w oknie 332 px, więc TRZY z sześciu pozycji były poza ekranem, w tym
     „Szczegóły konta" i „Wyloguj się". Do tego ostatnia widoczna pozycja
     urywała się w połowie słowa, co czyta się jak usterka, a nie jak
     zaproszenie do przewinięcia. Nic nie sygnalizowało, że da się przesunąć.

     Po nim było zawijanie jak tekst - i też źle (zgłoszenie #6, iPhone
     393 px): pozycje miały różne szerokości, więc kolumny nie trzymały
     linii („Zamówienia” i „Szczegóły konta” 6 px od siebie), aktywna
     „Płatności One click” stała sama w rzędzie, a „Wyloguj się” w osobnym,
     z pustą przerwą i pionową kreską (`border-left` ze starej wersji).

     Teraz dwie równe kolumny: wszystko widać od razu, rzędy i kolumny
     trzymają linię, za długa etykieta łamie się na dwa wyważone wiersze
     w swojej komórce. Wylogowanie jest zwykłą komórką - przy nieparzystej
     liczbie pozycji (np. z „Subskrypcjami”) bierze cały ostatni rząd, więc
     nigdzie nie zostaje dziura. */
  .et-account .woocommerce-MyAccount-navigation {
    position: static;
    overflow: visible;
  }
  .et-account .woocommerce-MyAccount-navigation ul {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 4px;
  }
  .et-account .woocommerce-MyAccount-navigation li { display: flex; }
  .et-account .woocommerce-MyAccount-navigation li:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .et-account .woocommerce-MyAccount-navigation a {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    gap: 9px;
    padding: 10px;
    font-size: 14px;
    line-height: 1.3;
    text-wrap: balance;
  }
  .woocommerce-MyAccount-navigation-link--customer-logout {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }

  .et-acch { flex-wrap: wrap; }
  .et-acch-txt { flex-basis: 100%; order: 3; }
  /* Wyloguj na prawy brzeg pierwszego rzędu, naprzeciw awatara - stał
     przyklejony do awatara (16 px), jakby był jego podpisem. I 44 px na
     dotyk zamiast 37. */
  .et-acch-out { margin-left: auto; min-height: 44px; display: inline-flex; align-items: center; }
}

/* Tabele na telefonie: tylko „responsywne” (lista zamówień, karty P24) -
   te woocommerce-smallscreen.css i tak przestawia na karty z linijkami
   „etykieta: wartość”. Reguły celowały wcześniej w KAŻDĄ `.shop_table`,
   więc łapały też tabelę szczegółów jednego zamówienia (bez `_responsive`)
   i ją rozbijały: nazwa produktu, „× 1” i opcje w trzech kolumnach obok
   siebie, „Razem: 89,98 zł (zawiera … VAT)” w dwóch (atrapa zamówienia,
   393 px). Tę tabelę układa na telefonie osobny blok niżej („SZCZEGÓŁY
   ZAMÓWIENIA”), wspólny ze stroną „dziękujemy”. */
@media (max-width: 560px) {
  .et-account .shop_table_responsive thead { display: none; }
  .et-account .shop_table_responsive tr { display: grid; gap: 2px; padding: 12px 14px; border-bottom: 1px solid var(--color-ink-3); }
  .et-account .shop_table_responsive td { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; border: 0; }
  .et-account .shop_table_responsive td::before { content: attr(data-title); color: var(--fg-muted); font-size: 12.5px; }
}

/* Przyciski działań przy zamówieniu stały na pulpicie kant w kant
   (0 px odstępu między „Zapłać”, „Zobacz” i „Anuluj”). */
.et-account table.my_account_orders td.woocommerce-orders-table__cell-order-actions .button { margin: 3px 6px 3px 0; }

@media (max-width: 768px) {
  /* NUMER ZAMÓWIENIA. WooCommerce 11 wypisuje go w wierszu jako
     `th scope="row"`, a woocommerce-smallscreen.css (do 768 px) chowa każdy
     `tbody th` - karta zamówienia na telefonie miała datę, status i kwotę,
     ale nie numer, którym klient posługuje się w mailach i przy zwrotach.
     Wraca jako pierwsza linijka karty, tak jak pozostałe. */
  .et-account table.shop_table_responsive tbody th {
    display: block;
    padding: 9px 12px;
    border: 0;
    background: none;
    text-align: right;
    font-family: var(--font-body);
    font-size: 14px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg-default);
  }
  .et-account table.shop_table_responsive tbody th::before {
    content: attr(data-title) ": ";
    float: left;
    font-weight: 700;
    color: var(--fg-muted);
    font-size: 12.5px;
  }
  /* Przyciski działań w jednym rzędzie na całą szerokość karty, bez
     podpisu „Działania:” - trzy („Zapłać / Zobacz / Anuluj”) stały do
     prawej w dwóch nierównych rzędach. */
  .et-account table.my_account_orders td.woocommerce-orders-table__cell-order-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .et-account table.my_account_orders td.woocommerce-orders-table__cell-order-actions::before { display: none; }
  .et-account table.my_account_orders td.woocommerce-orders-table__cell-order-actions .button { flex: 1 1 auto; margin: 0; }
}

/* =========================================================================
   SZCZEGÓŁY ZAMÓWIENIA: „Moje konto -> zamówienie” i strona „dziękujemy”

   Jeden szablon WooCommerce (`order/order-details.php`, potem
   `order-details-customer.php`) w dwóch miejscach, więc jeden zestaw reguł:
   `:is(.et-account, .woocommerce-order-received)` ma szczegółowość jednej
   klasy. Zgłoszenie #8 („dziękujemy”) i atrapa zamówienia w koncie.
   ========================================================================= */

/* Dodatki pozycji („Kolor 1: Biały”) z `wc_display_item_meta()`: lista
   miała 40 px wcięcia, etykieta `float: left`, a wartość to akapit z 16 px
   marginesu - na 393 px każda para zajmowała dwie linijki z przerwą,
   cztery kolory 264 px wysokości. Jedna linijka na parę. */
:is(.et-account, .woocommerce-order-received) .woocommerce-table--order-details td.product-name .wc-item-meta {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-muted);
}
:is(.et-account, .woocommerce-order-received) .woocommerce-table--order-details td.product-name .wc-item-meta li { display: flex; flex-wrap: wrap; column-gap: .3em; margin: 0; }
:is(.et-account, .woocommerce-order-received) .woocommerce-table--order-details td.product-name .wc-item-meta .wc-item-meta-label { float: none; clear: none; margin: 0; font-weight: 500; color: inherit; }
:is(.et-account, .woocommerce-order-received) .woocommerce-table--order-details td.product-name .wc-item-meta p { margin: 0; color: var(--fg-default); }

@media (max-width: 600px) {
  /* TABELA JAKO LISTA. W układzie tabeli kolumnę „Łącznie” rozpychała
     stopka (paczkomat z adresem, „Przelewy24 - PKO BP”, „(zawiera 16,83 zł
     VAT)”): na 393 px nazwa dostawała 158 px, kwota 177 px, „Rodzanice -
     Miks kolorów × 1” łamało się na 2-3 wiersze obok pustego pola, a w koncie
     napis przycisku „Śledź przesyłkę” łamał się w środku. Teraz każdy wiersz
     to pasek: nazwa na całą szerokość minus kwota, w stopce etykieta z lewej
     i wartość z prawej - a gdy wartość się nie mieści, schodzi pod etykietę,
     nadal do prawej. Nagłówek „Produkt / Łącznie” znika jak w liście
     zamówień: na wąskim ekranie nic nie dodaje. */
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details,
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details :is(tbody, tfoot) { display: block; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details { margin-right: 0; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details thead { display: none; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tr {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    border-top: 1px solid var(--border-default);
  }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tbody tr:first-child { border-top: 0; }
  /* 0,2,3 - tyle co stopka WooCommerce (`.woocommerce table.shop_table tfoot
     td`); słabsze `border: 0` zostawiało jej kreskę nad etykietą i nad
     wartością. */
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details :is(tbody, tfoot) :is(th, td) {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    font-size: 14px;
    line-height: 1.5;
  }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details td.product-name { flex: 1 1 auto; min-width: 0; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details td.product-total { flex: none; white-space: nowrap; text-align: right; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details td[colspan] { flex: 1 1 100%; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tfoot tr { flex-wrap: wrap; row-gap: 4px; }
  /* Etykiety stopki jednym krojem w obu miejscach (w koncie miały pasek tła
     nagłówka tabeli - w wierszu flex kawałek tła pod samym słowem). */
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tfoot th {
    flex: none;
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--fg-muted);
  }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tfoot td { flex: 0 1 auto; min-width: 0; margin-left: auto; text-align: right; }
  :is(.et-account, .woocommerce-order-received) table.woocommerce-table--order-details tfoot .button { white-space: nowrap; }
}

/* Adresy pod tabelą. W koncie siatka jak w „Adresach”, na „dziękujemy”
   stare floaty WooCommerce - na telefonie tytuł drugiego adresu przyklejony
   do pierwszego. Obramowanie WooCommerce `rgba(0,0,0,.1)` na ciemnym tle
   znikało, a 12 px wypełnienia odsuwało adres od tytułu bez żadnej ramki. */
.woocommerce-order-received .woocommerce-customer-details .col2-set {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  width: auto;
}
.woocommerce-order-received .woocommerce-customer-details .col2-set::before,
.woocommerce-order-received .woocommerce-customer-details .col2-set::after { content: none; }
.woocommerce-order-received .woocommerce-customer-details .col2-set .col-1,
.woocommerce-order-received .woocommerce-customer-details .col2-set .col-2 { float: none; width: auto; margin: 0; }
:is(.et-account, .woocommerce-order-received) .woocommerce-customer-details address {
  padding: 14px 16px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  color: var(--fg-muted);
  line-height: 1.7;
}

/* „Aktualizacje zamówienia” (notatki sklepu dla klienta) - tylko w koncie.
   Lista `ol` z numeracją „1.” i 40 px wcięcia; karta jak reszta konta.
   Selektor meta 0,5,3 - tyle co `.woocommerce ol.commentlist.notes li.note
   p.meta` z woocommerce.css (pogrubienie). */
.et-account ol.woocommerce-OrderUpdates { margin: 0 0 24px; padding: 0; list-style: none; }
.et-account ol.woocommerce-OrderUpdates li.woocommerce-OrderUpdate {
  margin: 0 0 8px;
  padding: 12px 14px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
}
.et-account ol.commentlist.notes li.note p.woocommerce-OrderUpdate-meta { margin: 0 0 4px; font-size: 12.5px; font-weight: 400; color: var(--fg-faint); }
.et-account .woocommerce-OrderUpdate-description p { margin: 0; }


/* --- Moje konto: kolumny WooCommerce (adresy, formularze) ------------------ */

/* WooCommerce układa te bloki starymi floatami na ~48% szerokości. W siatce
   panelu daje to rozjechane, nierówne kolumny - zastępujemy je gridem. */
.et-account .col2-set,
.et-account .u-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  width: auto;
}

.et-account .col2-set::before,
.et-account .col2-set::after,
.et-account .u-columns::before,
.et-account .u-columns::after { content: none; }

.et-account .col2-set .col-1,
.et-account .col2-set .col-2,
.et-account .u-columns .u-column1,
.et-account .u-columns .u-column2 {
  float: none;
  width: auto;
  margin: 0;
}

.et-account .woocommerce-Address { margin: 0; height: 100%; }

.et-account .woocommerce-Address-title h2 {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 15px;
  letter-spacing: .02em;
  color: var(--fg-default);
}

.et-account .woocommerce-Address-title .edit {
  font-size: 12.5px;
  color: var(--color-brand-orange);
  text-decoration: none;
  white-space: nowrap;
}
/* Odnośnik ma 20 px wysokości; na dotyk pole rośnie do 44 px, a ujemny
   margines trzyma układ karty bez zmian. */
@media (pointer: coarse) {
  .et-account .woocommerce-Address-title .edit { display: inline-block; padding: 12px 0; margin: -12px 0; }
}

@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .et-account .woocommerce-Address-title .edit:hover { text-decoration: underline; }
}

/* Formularz adresu: dwie kolumny na desktopie, pola pełnej szerokości tam,
   gdzie ich treść tego wymaga (ulica, firma). */
.et-account form.edit-account,
.et-account form.woocommerce-address-fields,
.et-account .woocommerce-address-fields__field-wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0 16px;
}

.et-account form.edit-account > *,
.et-account form.woocommerce-address-fields > *,
.et-account .woocommerce-address-fields__field-wrapper > * { min-width: 0; }

.et-account .form-row-wide,
.et-account form.edit-account fieldset,
.et-account form.edit-account p:not(.form-row),
.et-account form.woocommerce-address-fields p:not(.form-row),
.et-account .woocommerce-address-fields__field-wrapper > .form-row-wide { grid-column: 1 / -1; }

.et-account :where(.woocommerce) form .form-row-first,
.et-account :where(.woocommerce) form .form-row-last { width: auto; float: none; margin-right: 0; }

.et-account :where(.woocommerce) form .woocommerce-Button,
.et-account :where(.woocommerce) form button[type="submit"] { justify-self: start; grid-column: 1 / -1; }

.et-account fieldset legend {
  padding: 0;
  margin: 8px 0 12px;
  font-family: var(--font-heading);
  font-size: 14px;
  color: var(--fg-default);
}
/* „Zmiana hasła” w „Szczegółach konta”: fieldset miał ramkę przeglądarki
   (2 px, jasna, „groove”) - jedyna biała ramka na ciemnej stronie, z tytułem
   wciśniętym w górną krawędź i polami wciętymi o 14 px względem pól nad
   nią. Tytuł zostaje nagłówkiem sekcji, pola w tej samej linii co reszta. */
.et-account form.edit-account fieldset:not(.et-avatar-field) {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
/* Tytuł sekcji tym samym krojem co „Zdjęcie profilowe” niżej w formularzu. */
.et-account form.edit-account fieldset:not(.et-avatar-field) legend {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-bone-1);
}

.et-account .woocommerce-MyAccount-content > p { color: var(--fg-muted); }
.et-account .woocommerce-MyAccount-content h2 { margin-top: 0; }

/* Select2 (kraj/województwo) na ciemnym tle - domyślnie jest biały. */
.et-account .select2-container--default .select2-selection--single {
  height: auto;
  padding: 8px 10px;
  background: var(--bg-input);
  border: 1px solid var(--border-strong);
  border-radius: 7px;
}

.et-account .select2-container--default .select2-selection--single .select2-selection__rendered {
  color: var(--fg-default);
  line-height: 1.4;
  padding: 0;
}

.et-account .select2-container--default .select2-selection--single .select2-selection__arrow { top: 50%; transform: translateY(-50%); }


/* =========================================================================
   Konfigurator: stała wysokość elementów, które zmienia klikanie palety

   Zgłoszenie: na telefonie ekran przesuwał się przy KAŻDEJ dokładanej rolce,
   więc po nietrafionym kliknięciu trzeba było celować od nowa.

   Przewijanie nie było wołane z kodu - to przeglądarka kompensowała zmiany
   wysokości układu (zakotwiczenie przewijania). Kliknięcie palety zmieniało
   wysokość w dwóch miejscach:

     1. nazwa w slocie - „Rolka 1" mieści się w jednym wierszu, „Zieleń
        militarna" w dwóch, więc cały rząd slotów rósł, a paleta pod nim
        zjeżdżała w dół;
     2. podsumowanie pod paletą - lista wybranych kolorów przechodzi
        z jednego wiersza do dwóch mniej więcej przy trzeciej rolce.

   Oba miejsca mają teraz wysokość niezależną od treści (dwa wiersze,
   nadmiar ucinany), więc nie ma czego kompensować i ekran stoi.
   ========================================================================= */
.et-slot .et-slot-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  /* Jednowyrazowe nazwy („Bursztynowy") wychodziły poza wąski slot -
     tu wolno je złamać w środku, byle zmieściły się w kafelku. */
  overflow-wrap: anywhere;
  text-align: center;
  line-height: 1.25;
  min-height: 2.5em;          /* dokładnie dwa wiersze, zawsze */
}
@media (max-width: 860px) {
  /* Slot ma na telefonie ~65 px w środku. 9 px było nieczytelne (audyt D3:
     ok. 2 mm wersalika); 11 px to dół skali motywu, a rozstrzelenie idzie
     do zera, żeby „ROLKA 1" (ok. 46 px) na pewno się zmieściło. Nazwy palety
     („MILITARNA") nie stoją w slocie, więc nie muszą się tu mieścić. */
  .et-slot .et-slot-name { font-size: 11px; letter-spacing: 0; }
}

.et-builder-summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  line-height: 1.4;
  min-height: 2.8em;          /* dwa wiersze; pełny zestaw czterech nazw się mieści */
}


/* =========================================================================
   Stos rolek wyśrodkowany na grafice (konfigurator, stan bez pudełka)

   Pełny zestaw czterech rolek ma stać dokładnie na środku kadru z Rodzanicami.
   Wcześniej dno stosu było odsunięte od dołu o `14%`, a procent w `padding`
   liczy się od SZEROKOŚCI kadru, nie od wysokości - więc wyśrodkowanie
   zależało od proporcji grafiki i rozjeżdżało się przy każdej zmianie
   szerokości kolumny. Przy domyślnych ustawieniach stos stał ~48 px za nisko.

   `bottom` liczy procent od wysokości, więc dno stosu ustawiamy wprost:
   środek kadru minus połowa pełnego stosu minus cień pod nim. Cztery rolki
   wypadają w pionowym środku przy dowolnej szerokości kolumny i dowolnym
   `--et-roll-w`.

   Skąd 0.494: rolka ma wysokość 0.274w i wchodzi na poprzednią o 0.036w
   (plus `--et-roll-gap`), więc pełny stos to 0.988w - 4 × gap, a połowa
   0.494w - 2 × gap. Cień to 10 px marginesu + 16 px wysokości.

   Sama grafika ma treść wyśrodkowaną w pliku (widoczny rysunek wypada na
   0.495 wysokości), więc środek kadru jest tu równy środkowi rysunku.

   Stan z metalowym pudełkiem ma własne wyśrodkowanie (`.has-addon` wyżej)
   i celowo go nie ruszamy - stąd `:not(.has-addon)`.
   ========================================================================= */
.et-builder-media:not(.has-addon) .et-stack {
  padding-bottom: 0;
  bottom: calc(50% - var(--et-roll-w, 260px) * 0.494 + var(--et-roll-gap, 0px) * 2 - 26px);
  transition: padding .35s var(--ease), bottom .35s var(--ease);
}


/* =========================================================================
   Stos rolek nie może być kotwicą przewijania

   To była prawdziwa przyczyna skakania ekranu w konfiguratorze - poprzednie
   dwie próby leczyły objawy w treści strony, a treść strony była niewinna.

   Pomiar z telefonu (`?etdiag=1`) pokazał zestaw liczb, który wygląda na
   sprzeczny: wysokości bloków bez zmian (sloty 102>102, podsumowanie
   39>39), wysokość dokumentu bez zmian (6146>6146), wysokość okna bez
   zmian (1012>1012) - a mimo to przewijanie przeskakiwało po każdym
   kliknięciu o 45-46 px.

   45 px to nie przypadek: rolka ma wysokość 0.274 szerokości i wchodzi na
   poprzednią o 0.036, więc każda dokładana rolka podnosi stos o 0.238 ×
   190 px = 45,2 px przy ustawieniu mobilnym. Stos jest pozycjonowany
   absolutnie, więc nie rusza układu strony - ale Chrome wybierał element
   w nim na KOTWICĘ PRZEWIJANIA i po każdej zmianie przewijał okno tak, żeby
   kotwica została w tym samym miejscu. Mechanizm, który ma zapobiegać
   skakaniu treści, sam je wywoływał, bo uczepił się dekoracji.

   Zdejmowanie rolek było gorsze niż dokładanie, bo odlatująca rolka znika
   z DOM dopiero po animacji - przeskok wypadał ~260 ms po puszczeniu palca,
   czyli w momencie, którego nikt nie łączy z własnym kliknięciem.

   `overflow-anchor: none` wyklucza ten fragment z wyboru kotwicy. Treść
   w normalnym układzie (sloty, paleta, podsumowanie) zostaje kandydatem
   na kotwicę i dalej korzysta z tego mechanizmu tak, jak powinna.
   ========================================================================= */
.et-stack,
.et-stack-rolls,
.et-stack-shadow,
.et-roll { overflow-anchor: none; }


/* --- CELE DOTYKU W SIATCE PRODUKTÓW -----------------------------------------
   Zmierzone na telefonie: „Dodaj do koszyka" na kaflu miało 37 px wysokości,
   „Personalizuj" tyle samo. Próg to 44 px (Apple) / 48 px (Google) - a to
   jest jedyny przycisk w tej siatce, który bezpośrednio zarabia. */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart,
.et-personalizuj,
.woocommerce ul.products li.product a.button.add_to_cart_button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Napis złamany na dwa wiersze stoi na środku, nie przy lewej krawędzi. */
  text-align: center;
}

/* WĄSKA KARTA: PRZYCISKI W RZĘDZIE MAJĄ JEDNĄ WYSOKOŚĆ (2026-09-26, #4).

   Napis, który się nie mieści, łamie się na dwa wiersze (reguła przy
   „Karty produktów na telefonie"). W wąskiej karcie spotyka to „Dodaj do
   koszyka" (102 px) i „Skomponuj zestaw" (105 px), ale już nie
   „Personalizuj" (76 px) - w jednym rzędzie stałyby więc przyciski 44
   i 52 px wysokie, a ceny nad nimi na dwóch wysokościach. W wąskiej karcie
   każdy przycisk ma od razu miejsce na dwa wiersze (48 px) i węższe
   wypełnienie boczne; napis w jednym wierszu stoi po prostu na środku.

   Próg: wnętrze karty 150 px - 24 px marginesów - 2 px ramki - 16 px
   wypełnienia = 108 px na napis, czyli najdłuższy z nich (105 px) plus
   zapas. Pytamy o szerokość KARTY, nie ekranu: ta zależy od Personalizacji
   (liczba kart, podgląd, margines) i od miejsca (suwak, siatka, polecane).
   Przy 393 px w wąskim trybie są karty suwaka (148 px), a karty siatki
   sklepu (161 px) już nie. */
.woocommerce ul.products li.product { container: et-karta / inline-size; }
@container et-karta (max-width: 149.9px) {
  .woocommerce ul.products li.product .button,
  .woocommerce ul.products li.product a.button.add_to_cart_button,
  .woocommerce ul.products li.product .added_to_cart {
    min-height: 48px;
    padding: 6px 4px;
    line-height: 1.15;
  }
}

/* --- Moje konto na telefonie: zakładki logowania i rejestracji ------------ */

/*
 * Pasek zakładek buduje `egotape.js`. Na pulpicie jest niewidoczny, bo tam
 * obie kolumny stoją obok siebie i wybieranie między nimi nic nie daje.
 */
.et-konto-taby { display: none; }

@media (max-width: 768px) {
  .et-konto-taby {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin: 0 0 18px;
  }
  .et-konto-tab {
    appearance: none;
    -webkit-appearance: none;
    border: 1px solid var(--border-default);
    background: transparent;
    color: var(--fg-muted);
    font-family: var(--font-heading);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    /* 44 px wysokości to nie zaokrąglenie w górę, tylko najmniejszy palec,
       w jaki da się trafić bez chybiania. */
    min-height: 44px;
    padding: 10px 8px;
    border-radius: var(--radius-2, 10px);
    cursor: pointer;
  }
  .et-konto-tab.is-active {
    background: var(--color-brand-orange);
    border-color: var(--color-brand-orange);
    color: #0B0B0B;
  }
  .et-konto-tab:focus-visible { outline: 2px solid var(--color-brand-orange-bright); outline-offset: 2px; }

  /*
   * Ukrywanie nieaktywnej kolumny siedzi WYŁĄCZNIE w tym zapytaniu o media.
   * Gdyby stało poza nim, a klasa `is-active` została po zmianie szerokości
   * okna, pulpit pokazałby jeden formularz zamiast dwóch. Tak jest to
   * niemożliwe: powyżej 768 px reguła w ogóle nie istnieje.
   */
  .et-konto-taby-on > .u-column1,
  .et-konto-taby-on > .u-column2 { display: none; }
  .et-konto-taby-on > .u-column1.is-active,
  .et-konto-taby-on > .u-column2.is-active { display: block; }
  /* Nagłówek kolumny powtarzałby napis z zakładki. */
  .et-konto-taby-on > .u-column1 > h2,
  .et-konto-taby-on > .u-column2 > h2 { display: none; }

  /* Pusty pojemnik na komunikaty WooCommerce zostawiał odstęp nad paskiem
     zakładek, choć nie było w nim nic do pokazania. Gdy komunikat jest -
     a to właśnie wtedy, gdy logowanie się nie udało - pojemnik wraca. */
  .woocommerce .woocommerce-notices-wrapper:empty { display: none; }

  /* ODZYSKANE MIEJSCE. Zmierzone przed zmianą: 105 px pustki między
     „Moje konto" a „Logowanie", z czego 43 px to margines nagłówka kolumny
     (zbędny, bo nagłówek znika), a reszta to marginesy formularza. */
  .woocommerce-account .entry-title { margin-bottom: 12px; }
  .woocommerce .u-columns.col2-set { margin-top: 0; }
  .woocommerce form.login,
  .woocommerce form.register { margin: 0 0 24px; padding: 16px; }
}

/* --- „Dodaj do koszyka": animacja ---------------------------------------- */

/*
 * Trzy warstwy, każda robi coś innego:
 *
 *   1. Odwrócenie kolorów - bursztyn zamienia się z czernią w 0,25 s.
 *      To jest cała animacja tego przycisku.
 *   2. Uniesienie z cieniem - mówi „to się klika", zanim ktokolwiek
 *      kliknie.
 *   3. Wciśnięcie przy `:active` - jedyne, co działa na dotyk, i jedyne,
 *      co odpowiada na sam gest.
 *
 * BYŁ TU JESZCZE PRZESUWAJĄCY SIĘ POŁYSK - biały pasek przelatujący przez
 * przycisk przy najechaniu. Zdjęty 2026-08-12 na prośbę właściciela jako
 * zbyt agresywny. Gdyby ktoś chciał wrócić do czegoś w tym duchu: łagodniej
 * wypada wypełnienie WJEŻDŻAJĄCE Z BOKU zamiast błysku przelatującego
 * w poprzek - ruch idzie wtedy w jedną stronę i kończy się na spoczynku,
 * a nie przelatuje przez pole widzenia.
 *
 * `overflow: hidden` zostaje jako zabezpieczenie zaokrąglonego rogu.
 */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product a.button.add_to_cart_button {
  position: relative;
  overflow: hidden;
  /* Przezroczysta ramka JUŻ W STANIE SPOCZYNKU. Przy najechaniu pojawia się
     bursztynowa obwódka, a gdyby ramki nie było tu od początku, przycisk
     urósłby w tej chwili o dwa piksele i napis by podskoczył. Reszta
     układu ma `box-sizing: border-box`, więc sama ramka nie zmienia
     wysokości pudełka. */
  border: 1px solid transparent;
  transition:
    transform .18s var(--ease),
    box-shadow .18s var(--ease),
    background-color .25s var(--ease),
    border-color .25s var(--ease),
    color .25s var(--ease);
}


@media (hover: hover) and (pointer: fine) {
  /* ODWRÓCENIE KOLORÓW przy najechaniu: z bursztynowego wypełnienia na
     czerń z bursztynową obwódką i bursztynowym napisem.

     Czas 0,25 s jest wzięty z odniesienia, które podał właściciel - tam
     przejście tła i koloru trwa tyle samo. Krócej wygląda jak przeskok,
     dłużej jak ospałość.

     Kolory idą ze zmiennych motywu, nie z zapisu szesnastkowego: gdy
     kiedyś zmieni się barwa marki, ten przycisk zmieni się razem z nią. */
  .woocommerce ul.products li.product .button:hover,
  .woocommerce ul.products li.product a.button.add_to_cart_button:hover {
    background-color: var(--color-ink-1);
    border-color: var(--color-brand-orange);
    color: var(--color-brand-orange);
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(246, 149, 0, .28);
  }
}

/* To samo odwrócenie kolorów dla nawigacji klawiaturą - inaczej podpowiedź
   „to jest teraz zaznaczone" byłaby słabsza niż dla myszy. */
.woocommerce ul.products li.product .button:focus-visible {
  background-color: var(--color-ink-1);
  border-color: var(--color-brand-orange);
  color: var(--color-brand-orange);
}

.woocommerce ul.products li.product .button:active {
  transform: translateY(0) scale(.97);
  box-shadow: none;
}

/* Tu stała osierocona klamra `}` (od 2026-08-12). Parser brał ją za początek
   selektora następnej reguły i wyrzucał cały blok „Ograniczony ruch" niżej -
   uniesienie przycisku zostawało też u tych, którzy prosili o mniej ruchu. */

/*
 * Ograniczony ruch: zostaje samo wciśnięcie, bo to nie ozdoba, tylko
 * potwierdzenie, że dotyk został przyjęty. Połysk i unoszenie znikają.
 */
@media (prefers-reduced-motion: reduce) {
  /* Znika ruch, nie informacja: uniesienie i połysk wyłączone, ale
     odwrócenie kolorów zostaje - to ono mówi „najechałeś na przycisk". */
  .woocommerce ul.products li.product .button:hover { transform: none; box-shadow: none; }
  .woocommerce ul.products li.product .button {
    transition: background-color .18s linear, border-color .18s linear, color .18s linear;
  }
}

/* Tytuł produktu na kafelku: jedna linia, zawsze.
   `nowrap` wymusza jedną linię, `overflow: hidden` jest ostatnim
   zabezpieczeniem - gdyby JS nie zadziałał albo nazwa przekroczyła próg
   czytelności, napis zostanie przycięty zamiast rozepchać kafelek. */
.woocommerce ul.products li.product .woocommerce-loop-product__title {
  white-space: nowrap;
  overflow: hidden;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title .et-tytul-fit {
  display: inline-block;
}
/* Nazwa, która nie mieści się w jednej linii nawet przy progu czytelności -
   patrz „zejście awaryjne" w `egotape.js`. Dwie linie są tu mniejszym złem
   niż ucięta nazwa produktu. */
.woocommerce ul.products li.product .woocommerce-loop-product__title.et-tytul-lamany {
  white-space: normal;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title.et-tytul-lamany .et-tytul-fit {
  display: inline;
}

/* Pusty wiersz w miejscu oceny na kafelkach bez opinii - patrz
   `inc/woocommerce.php`. Wysokość i margines MUSZĄ zgadzać się z
   `.star-rating` co do piksela, inaczej wyrównanie przycisków rozjedzie
   się o tę różnicę.

   I ROZJECHAŁO SIĘ - 2026-08-13, zgłoszone w audycie pulpitu: „gwiazdki
   tylko przy Nawii spychają cenę niżej niż u sąsiadów".

   Wpisane tu 12 px brało się z `font-size: 12px` gwiazdek. Ale wysokość
   `.star-rating` nie równa się wielkości pisma: WooCommerce liczy ją
   z `line-height` znaków gwiazdek i wychodzi 16 px. Cztery piksele różnicy
   na każdej karcie z opinią - dokładnie ten uskok, który widać w rzędzie.

   Obie liczby idą teraz z JEDNEJ zmiennej i obie są narzucone wprost.
   Komentarz wyżej mówił „muszą się zgadzać co do piksela" i miał rację;
   brakowało tylko tego, żeby dało się je rozjechać wyłącznie w jednym
   miejscu, a nie w dwóch niezależnych regułach. */
:root { --et-rating-h: 16px; }
.woocommerce ul.products li.product .star-rating,
.woocommerce ul.products li.product .et-rating-placeholder {
  height: var(--et-rating-h);
  line-height: var(--et-rating-h);
  margin: 6px 18px 0;
  overflow: hidden;
}

/* --- Karta produktu: „Dodaj do koszyka" z odwróceniem kolorów ------------- */

/*
 * To samo zachowanie co na kafelkach w siatce: bursztyn zamienia się
 * z czernią, zostaje bursztynowa obwódka i napis.
 *
 * ZAKRES JEST WĄSKI CELOWO. Reguła obok (`.button.alt`) obejmuje jednym
 * selektorem także „Kupuję i płacę" w kasie i przyciski koszyka blokowego.
 * Właściciel prosił o przycisk na KARCIE PRODUKTU, a kasa to miejsce, gdzie
 * nie zmienia się wyglądu przy okazji - dlatego tu stoi osobny, węższy
 * selektor zamiast dopisania koloru do tamtej grupy.
 *
 * `!important` nie z wygody: reguła podstawowa dla `.button.alt` używa go
 * przy tle i kolorze, więc bez tego zmiana nie miałaby żadnego skutku.
 * Ramka `!important` nie potrzebuje, bo tam jej nie ma.
 *
 * SELEKTOR WYMIENIA WSZYSTKIE TRZY KLASY (`single_add_to_cart_button`,
 * `button`, `alt`) i to nie jest ozdoba. Ten przycisk nosi je wszystkie,
 * a reguła obok trafia w niego przez `.woocommerce button.button.alt:hover`
 * - selektor BARDZIEJ szczegółowy niż sama nazwa przycisku. Pierwsza wersja
 * tej poprawki miała tylko `.single_add_to_cart_button:hover` i przegrywała:
 * ramka zmieniała kolor (bo tamta reguła ramki nie ustawia), a tło zostawało
 * bursztynowe. Wyglądało to jak działający `!important`, który nie działa.
 */
.woocommerce button.single_add_to_cart_button {
  transition:
    transform .18s var(--ease),
    box-shadow .18s var(--ease),
    background-color .25s var(--ease),
    border-color .25s var(--ease),
    color .25s var(--ease);
}

/* `:not(:disabled)`: wyłączony przycisk (produkt z wyborem kolorów przed
   kompletem) pod kursorem czerniał, dostawał bursztynowy napis i podnosił
   się - udawał gotowy do kliknięcia (audyt 2026-09-26, pulpit). */
@media (hover: hover) and (pointer: fine) {
  .woocommerce button.single_add_to_cart_button.button.alt:hover:not(:disabled) {
    background: var(--color-ink-1) !important;
    color: var(--color-brand-orange) !important;
    border-color: var(--color-brand-orange);
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(246, 149, 0, .28);
  }
}

/* Klawiatura widzi to samo co mysz. */
.woocommerce button.single_add_to_cart_button.button.alt:focus-visible {
  background: var(--color-ink-1) !important;
  color: var(--color-brand-orange) !important;
  border-color: var(--color-brand-orange);
}

.woocommerce button.single_add_to_cart_button:active {
  transform: translateY(0) scale(.99);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  /* Ruch znika, informacja zostaje - dokładnie jak na kafelkach. */
  .woocommerce button.single_add_to_cart_button:hover { transform: none; box-shadow: none; }
  .woocommerce button.single_add_to_cart_button {
    transition: background-color .18s linear, border-color .18s linear, color .18s linear;
  }
}

/* --- Sklep na telefonie: odstęp siatki i rząd kategorii ------------------
 *
 * OBA TE BLOKI MUSZĄ STAĆ NA KOŃCU PLIKU i to nie jest kwestia porządku.
 *
 * Zapytanie o media NIE podnosi specyficzności. Odstęp siatki ustawia
 * `.woocommerce .products-header + ul.products` (bez żadnego zapytania),
 * a zawijanie pigułek `.et-cat-chips` - obie reguły stoją wyżej w pliku niż
 * blok telefonu, więc wersje pisane wewnątrz `@media` przegrywały mimo
 * poprawnej treści. Widać było to po tym, że część deklaracji z tego samego
 * bloku wchodziła (`overflow-x`), a część nie (`flex-wrap`).
 *
 * To czwarty raz w tym pliku, gdy ta sama pułapka kosztowała jedno podejście.
 */
@media (max-width: 560px) {
  /* 28 px między kafelkami to przy dwóch kolumnach ponad 8% szerokości
     ekranu oddane pustce. */
  .woocommerce .products-header + ul.products,
  .woocommerce ul.products { gap: 12px; }
}

/*
 * Kategorie na telefonie: jeden rząd do przewijania w bok.
 *
 * Cztery pigułki łamały się na trzy wiersze i zajmowały 180 px NAD pierwszym
 * produktem - czyli jedną piątą ekranu na nawigację, zanim widać cokolwiek
 * do kupienia. W jednym rzędzie zajmują 44 px, a pozostałe kategorie są
 * o jeden ruch kciuka w bok.
 *
 * Pasek przewijania jest schowany celowo: na telefonie i tak go nie widać
 * podczas przewijania palcem, a zajmowałby miejsce pod pigułkami.
 */
@media (max-width: 640px) {
  nav.et-cat-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    margin-bottom: 16px;
    /* Wcięcie po bokach równe marginesowi strony, a sam pojemnik szerszy
       o te marginesy - dzięki temu ostatnia pigułka może dojechać do
       krawędzi ekranu i widać, że rząd się przewija. */
    margin-left: calc(var(--et-gutter, 18px) * -1);
    margin-right: calc(var(--et-gutter, 18px) * -1);
    padding-left: var(--et-gutter, 18px);
    padding-right: var(--et-gutter, 18px);
    /* Bez tego przyciąganie (`scroll-snap-align: start`) dosuwało pierwszą
       pigułkę do samej krawędzi ekranu i zjadało wcięcie: po wczytaniu rząd
       stał przewinięty o 28 px, „Wszystkie" na x=0 zamiast na linii treści
       (zmierzone na 393 px w WebKit, audyt iOS 2026-09-26). */
    scroll-padding-inline: var(--et-gutter, 18px);
  }
  nav.et-cat-chips::-webkit-scrollbar { display: none; }
  nav.et-cat-chips .et-chip {
    flex: 0 0 auto;
    scroll-snap-align: start;
    white-space: nowrap;
  }
}

/*
 * Przycisk zawsze przy dnie kafelka.
 *
 * Kafelki w rzędzie mają wspólną wysokość, a treść nad przyciskiem bywa
 * różna: nazwa, która nie mieści się w jednej linii, robi kartę o 20 px
 * wyższą i jej przycisk zjeżdżał niżej niż u sąsiada. Zmierzone na stronie
 * sklepu: 315 px kontra 294 px w tym samym rzędzie.
 *
 * `margin-top: auto` zjada całą wolną przestrzeń NAD przyciskiem, więc
 * przyciski stają w jednej linii niezależnie od tego, co jest wyżej.
 *
 * Skutek uboczny, przyjęty świadomie: na kafelku z krótszą nazwą przerwa
 * między ceną a przyciskiem robi się większa niż zadane 8 px. Wybór jest
 * między „równe przyciski, nierówne przerwy" a „równe przerwy, nierówne
 * przyciski" - a to przycisk jest tym, w co się celuje kciukiem i to jego
 * położenie widać przy porównywaniu dwóch produktów obok siebie.
 *
 * OD 2026-09-26 WOLNE MIEJSCE BIERZE CENA, NIE PRZYCISK (zgłoszenia #4, #7).
 * Odnośnik produktu wypełnia kartę, a cena ma w nim `margin-top: auto`
 * (reguła przy „PRZYCISKI RÓWNO U DOŁU"), więc przyciski dalej stoją
 * w jednej linii, a ceny razem z nimi. Tutaj zostaje stałe 8 px - `auto`
 * nie dostałoby już żadnego miejsca i przycisk dotknąłby ceny.
 */
.woocommerce ul.products li.product .button { margin-top: 8px; }

/* --- Sklep na telefonie: cztery kafelki na pierwszym ekranie --------------
 *
 * CEL POSTAWIONY WPROST: dwa rzędy kafelków RAZEM Z PRZYCISKAMI mają się
 * zmieścić w jednym ekranie. Zmierzone przed zmianą na 390x844: dolna
 * krawędź przycisków drugiego rzędu wypadała na 927 px, czyli 83 px poza
 * ekranem. Widać było półtora rzędu.
 *
 * Skąd biorę te 83 px (wszystko zmierzone, nie zgadywane):
 *   40 -> 12 px  wypełnienie nad okruszkiem            = 28 px
 *   32 -> 10 px  odstęp okruszek -> nagłówek           = 22 px
 *   38,4 -> 30 px nagłówek „SKLEP" plus mniejszy odstęp = ~17 px
 *   16 -> 12 px  odstęp pod kategoriami                =  4 px
 *   wnętrze kafelka, dwa rzędy                         = ~24 px
 *
 * Nagłówek „SKLEP" schodzi z 38,4 do 30 px i to jest jedyna zmiana, która
 * dotyka typografii. Na telefonie ten napis powtarza informację, którą
 * czytelnik ma już w okruszku nad nim i w zakładce - nie musi być
 * największym elementem ekranu.
 */
@media (max-width: 640px) {
  .woocommerce .woo-main,
  .woo-main { padding-top: 12px; }

  .woocommerce .woocommerce-breadcrumb { margin-bottom: 10px; }

  .woocommerce-page h1.page-title,
  .woocommerce h1.page-title,
  .woo-main h1 {
    font-size: 30px;
    margin-bottom: 10px;
  }

  nav.et-cat-chips { margin-bottom: 12px; }

  /* Wnętrze kafelka: te same odstępy, tylko ciaśniej. Zdjęcie i przycisk
     zostają nietknięte - to one są celem kciuka. */
  .woocommerce ul.products li.product .woocommerce-loop-product__title { padding-top: 8px; }
  .woocommerce ul.products li.product .price { padding-top: 2px; }
  .woocommerce ul.products li.product .button,
  .woocommerce ul.products li.product .added_to_cart { margin-bottom: 10px; }
}


/* =========================================================================
   Kasa: wysyłka, paczkomat, płatność - czytelność
   =========================================================================

   Wtyczka InPost (`inpost-for-woocommerce`) dokłada do blokowej kasy własne
   okna i przyciski ze STAŁYMI, jasnymi tłami - są pisane pod motyw na białym
   tle. Ten motyw jest ciemny, więc jego globalny kolor tekstu (`--fg-default`,
   kość) dziedziczy się do tych białych okien i tekst znika: biały na białym.

   Zmierzone na żywej stronie przed poprawką:
     - tytuł mapy paczkomatów „Wybierz paczkomat": #F5F1EA na #FAFAFA = 1,03:1;
     - komunikat „Musisz wybrać paczkomat." w okienku walidacji: to samo, czyli
       klient po kliknięciu „Zapłać" widział pusty biały prostokąt z przyciskiem
       „Ok" i nie wiedział, czego od niego chcą - zamówienie stało w miejscu bez
       ŻADNEGO czytelnego komunikatu. To jest najkrótsza droga do porzucenia
       koszyka, jaką ta kasa miała.

   Dlatego nie „poprawiamy koloru tekstu", tylko przenosimy te okna do ciemnej
   palety motywu - wtedy odziedziczony kolor jest tym właściwym, a nie tym,
   który trzeba nadpisywać w kółko przy każdej aktualizacji wtyczki.
   ---------------------------------------------------------------------- */

/* Czerwień komunikatów o błędzie. WooCommerce daje #CC1818, co na tle strony
   (#0B0B0B) wychodzi 3,48:1 - poniżej progu 4,5:1 dla zwykłego tekstu. A to są
   akurat te napisy, które MUSZĄ być czytelne, bo bez nich klient nie wie, czego
   poprawić. Jaśniejszy odcień daje 7,8:1. */
:root { --et-kasa-blad: var(--color-danger); } /* ten sam token co w calym motywie */

.wc-block-components-validation-error,
.wc-block-components-validation-error p,
.wc-block-components-checkbox.has-error .wc-block-components-checkbox__label,
.wc-block-components-checkbox.has-error a {
  color: var(--et-kasa-blad) !important;
}
/* Pole z błędem ma się różnić też ramką, nie tylko napisem pod spodem -
   sam czerwony tekst 50 px niżej ginie na długim formularzu. */
.wc-block-components-text-input.has-error input,
.wc-block-components-combobox.has-error input,
.wc-block-components-address-form .has-error input {
  border-color: var(--et-kasa-blad) !important;
}

/* --- Okienko walidacji wtyczki InPost („Musisz wybrać paczkomat.") --------
   Wtyczka buduje je w JS ze stylami wpisanymi wprost w element (`style="..."`),
   więc tło i kolor przycisku trzeba przebić `!important`. Kolor samego
   komunikatu nie jest wpisany w element - tam wystarczy zwykła reguła. */
#inpost_pl_checkout_validation_modal > div {
  background-color: var(--bg-surface) !important;
  border: 1px solid var(--color-brand-orange);
  border-radius: var(--radius-3) !important;
  box-shadow: var(--shadow-2) !important;
  max-width: 360px !important;
  padding: 28px 24px 24px !important;
  color: var(--fg-default);
  font-family: var(--font-body);
}
#inpost_pl_checkout_validation_modal > div > div {
  color: var(--fg-default);
  font-size: 16px !important;
  line-height: 1.5;
}
#inp_pl_close_modal_cross { color: var(--fg-muted); }
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  #inp_pl_close_modal_cross:hover { color: var(--fg-default); }
}
#inp_pl_close_modal_button {
  background-color: var(--color-brand-orange) !important;
  /* ciemny tekst na pomarańczu, nie biały: biały daje 2,3:1, ciemny 8,6:1 */
  color: var(--color-ink-1) !important;
  font-family: var(--font-heading) !important;
  font-size: 13px !important;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: var(--radius-3) !important;
  padding: 13px 28px !important;
}

/* --- Modal mapy paczkomatów (jBox) --------------------------------------
   Sama mapa jest w iframie InPostu i zostaje biała - tego nie zmienimy.
   Ale ramka okna jest w naszym DOM-ie, więc pasek tytułu i krzyżyk mogą być
   czytelne i w palecie sklepu. */
.jBox-Modal .jBox-container { background: var(--bg-surface) !important; }
.jBox-Modal .jBox-title {
  background: var(--bg-surface) !important;
  color: var(--fg-default) !important;
  font-family: var(--font-display) !important;
  font-size: 20px !important;
  letter-spacing: .04em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--border-default) !important;
}
.jBox-Modal .jBox-content { background: var(--bg-surface) !important; padding: 0 !important; }
.jBox-Modal.jBox-closeButton-title .jBox-closeButton {
  border-color: var(--border-strong) !important;
}
/* Krzyżyk to kółko 32 x 32 px (`front.css` wtyczki). Wygląd zostaje, pole
   dotyku rośnie do 44 x 44 - pseudo-element jest częścią przycisku, więc
   dotknięcie obok kółka też zamyka okno (iPhone, 2026-09-26). -8 px, bo
   `inset` liczy się od wnętrza 2-pikselowego obramowania: 28 + 16 = 44. */
.jBox-Modal.jBox-closeButton-title .jBox-closeButton::after { content: ""; position: absolute; inset: -8px; }
.jBox-Modal .jBox-closeButton svg { fill: var(--fg-default) !important; }
@media (hover: hover) and (pointer: fine) {
  /* Najechanie tylko pod kursorem - na iPhonie przyklejało się po dotknięciu (audyt iOS 2026-09-26). */
  .jBox-Modal .jBox-closeButton:hover { border-color: var(--color-brand-orange) !important; }
}
.jBox-overlay { background: rgba(0,0,0,.72) !important; }

/* --- Potwierdzenie wybranego paczkomatu ----------------------------------
   Wtyczka renderuje je jako biały prostokąt (`background:#fff` w jej CSS),
   więc bez tej reguły klient po wybraniu punktu dostaje biały tekst na białym
   tle i nie widzi, KTÓRY paczkomat wybrał.

   Apaczka (Orlen Paczka i reszta punktów z jej mapy) ma ten sam problem:
   `#apaczka_selected_point_data` z `apaczka-points-map.css` to biała ramka
   z zieloną obwódką, a w środku nasz jasny tekst („tło z paczkomatu jest
   białe i słabo widoczne", 2026-09-26). Numer i opis punktu Apaczka wstawia
   w te same `#selected-parcel-machine-id` / `-desc` co InPost, więc po
   dopisaniu ramki tutaj oba potwierdzenia wyglądają jednakowo. */
#easypack_selected_point_data,
.easypack_selected_point_data,
#apaczka_selected_point_data {
  background: var(--bg-input) !important;
  border: 1px solid var(--color-brand-orange) !important;
  border-radius: var(--radius-3) !important;
  padding: 14px 16px !important;
  color: var(--fg-default) !important;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
}
#selected-parcel-machine-id {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-brand-orange);
  margin-bottom: 4px;
}
#selected-parcel-machine-desc,
#selected-parcel-machine-desc1 { color: var(--fg-muted); }
#inpost_pl_selected_point_data_wrap { margin-top: 12px; }

/* --- Przycisk wyboru paczkomatu ------------------------------------------
   Przed poprawką: biały napis na pomarańczowym tle (2,28:1 - nieczytelny),
   19 px, szerokość 200 px, wyśrodkowany POD kartą opcji wysyłki. Wyglądał
   dokładnie tak jak przycisk „Zapłać" na dole strony, więc konkurował z nim
   o uwagę, a jednocześnie był gorzej czytelny niż on.

   Po poprawce jest to przycisk drugoplanowy: pomarańczowa ramka i pomarańczowy
   napis na ciemnym tle (7,1:1). Nadal rzuca się w oczy - bo to krok obowiązkowy
   - ale nie udaje przycisku kończącego zamówienie. Pełna szerokość, żeby na
   telefonie był łatwy do trafienia palcem.

   SELEKTOR JEST CELOWO MOCNY - i to jest tu cała trudność.
   Ten przycisk ma przeciwko sobie DWA źródła, które ładują się PO motywie:
     1. `front.css` wtyczki InPost - `border: 0 !important`, `font-size: 19px
        !important`;
     2. `<style>` wstawiany przez wtyczkę w `wp_head` z priorytetem 100
        (EasyPack_Helper::include_inline_css) - `background: #f69500 !important`,
        wzięte z ustawienia `easypack_custom_button_css` w panelu InPostu.
   Przy równym `!important` wygrywa arkusz późniejszy, więc sam
   `.easypack_show_geowidget` (0,1,0) przegrywał z obydwoma - pierwsza wersja
   tej poprawki wyglądała w pliku dobrze i na stronie nie działała wcale
   (zmierzone: pomarańczowy tekst na pomarańczowym tle). Selektor po ID
   (1,0,0) wygrywa niezależnie od kolejności arkuszy, a wariant `button.klasa`
   (0,1,1) łapie klasyczną kasę, gdzie tego ID nie ma. */
#easypack_block_type_geowidget,
button.easypack_show_geowidget,
#easypack_show_geowidget.easypack_show_geowidget {
  display: block !important;
  width: 100% !important;
  max-width: none !important;
  margin: 0 0 4px !important;
  padding: 15px 18px !important;
  background: transparent !important;
  border: 2px solid var(--color-brand-orange) !important;
  border-radius: var(--radius-3) !important;
  box-shadow: none !important;
  color: var(--color-brand-orange) !important;
  font-family: var(--font-heading) !important;
  font-size: 13px !important;
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.25 !important;
  text-transform: uppercase;
  transition: background .2s var(--ease), color .2s var(--ease);
}
/* Wypełnienie tylko pod kursorem i klawiaturą: na iPhonie `:hover` zostaje po
   dotknięciu, więc po zamknięciu mapy przycisk stał wypełniony pomarańczem -
   jak „Kupuję i płacę", od którego ten przycisk ma się właśnie odróżniać. */
@media (hover: hover) and (pointer: fine) {
  #easypack_block_type_geowidget:hover,
  button.easypack_show_geowidget:hover {
    background: var(--color-brand-orange) !important;
    color: var(--color-ink-1) !important;
  }
}
#easypack_block_type_geowidget:focus-visible,
button.easypack_show_geowidget:focus-visible {
  background: var(--color-brand-orange) !important;
  color: var(--color-ink-1) !important;
}

/* Zdanie wyjaśniające, że wybór punktu jest obowiązkowy. Tekst przychodzi
   z Personalizacji przez zmienną `--et-paczkomat-hint` (inc/woocommerce.php).
   Wstawiony przez `::after` kontenera z listą metod, czyli dokładnie między
   kartą opcji a przyciskiem; `:has()` zawęża to do przypadku, gdy przycisk
   InPostu w ogóle jest na stronie - przy wysyłce kurierem do UE hasła o
   paczkomacie być nie może. */
.wc-block-components-checkout-step__content:has(.easypack_show_geowidget)
  .wc-block-components-shipping-rates-control::after {
  content: var(--et-paczkomat-hint, "");
  display: block;
  margin: 14px 0 10px;
  color: var(--fg-muted);
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
}

/* --- Karta metody wysyłki: napis „do 2 dni roboczych" ---------------------
   Wtyczka daje mu `font-size: 0.7em` i `border: 3px dotted #3c3b35`. Na naszej
   typografii wychodziło z tego 9,1 px w kropkowanej ramce - wyglądało jak
   niedokończony element interfejsu, a nie jak termin dostawy, i było poniżej
   granicy czytelności. Zwykły, spokojny podpis mówi to samo. */
#inpost_pl_block_delivery_terms,
#inpost_pl_delivery_terms {
  font-size: 12px !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  color: var(--fg-muted) !important;
  line-height: 1.4 !important;
}
/* Logo InPostu i termin dostawy siedzą WEWNĄTRZ etykiety pola radio, przez co
   nazwa metody łamała się na dwie linie przy pustym miejscu obok. Układ
   poziomy z odstępem porządkuje wiersz. */
.inpost_pl-block-shipping-method-meta-wrap {
  display: flex !important;
  flex-direction: row !important;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}
.inpost_pl_method_logo img { height: 22px !important; }

/* --- Karty opcji wysyłki i płatności -------------------------------------
   Przed poprawką każda opcja była przezroczysta i bez ramki (zmierzone:
   `background: rgba(0,0,0,0)`, `border: 0px none`), więc lista metod płatności
   wyglądała jak luźny tekst z kropką z boku. Klient nie widział, że to są
   klikalne kafle ani która pozycja jest wybrana - poza samą kropką radio.
   Teraz każda opcja to kafel, a wybrany ma pomarańczową ramkę i lekki odcień. */
.wc-block-components-radio-control__option {
  background: var(--bg-input) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-3) !important;
  margin-bottom: 10px !important;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.wc-block-components-radio-control__option:last-child { margin-bottom: 0 !important; }
/* `:hover` ma wagę 0,2,0 i przy `!important` przebijał pomarańczową ramkę wybranej
   opcji (0,1,0): na iPhonie `:hover` zostaje po dotknięciu, więc właśnie wybrana
   wysyłka czy płatność miała szarą ramkę zamiast pomarańczowej. */
@media (hover: hover) and (pointer: fine) {
  .wc-block-components-radio-control__option:not(.wc-block-components-radio-control__option-checked):hover { border-color: var(--border-strong) !important; }
}
.wc-block-components-radio-control__option-checked,
.wc-block-components-radio-control__option--checked-option-highlighted {
  background: var(--color-brand-amber-grain) !important;
  border-color: var(--color-brand-orange) !important;
}
/* Grupa nie rysuje już własnej ramki - inaczej mamy ramkę w ramce. */
.wc-block-components-radio-control--highlight-checked::before,
.wc-block-components-radio-control--highlight-checked::after,
.wc-block-components-radio-control-accordion-option::before {
  display: none !important;
}
.wc-block-components-radio-control__label {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--fg-default) !important;
}
.wc-block-components-radio-control__secondary-label,
.wc-block-components-radio-control__description {
  color: var(--fg-muted) !important;
}
.wc-block-components-radio-control__option-checked .wc-block-components-radio-control__secondary-label {
  color: var(--color-brand-orange) !important;
}
/* Cena opcji: Blocks rezerwuje jej pół kafla (`flex: 0 0 50%`), więc nazwie
   z logo InPostu i terminem zostawało 136 px z 271: „do 2 dni / roboczych"
   w dwóch wierszach obok pustego pola (393 px), a na 320 px także
   „Orlen / Paczka" i „InPost Paczkomat / 24/7". Cena bierze tyle, ile
   potrzebuje („15,00 zł" = 46 px), odstęp trzyma ją z dala od nazwy. */
.wc-block-components-radio-control__label-group { column-gap: 12px; }
.wc-block-components-radio-control__label-group .wc-block-components-radio-control__secondary-label { flex: 0 0 auto; }
/* Treść rozwinięta pod wybraną płatnością siedzi w tym samym kaflu. */
.wc-block-components-radio-control-accordion-content {
  background: transparent !important;
  border: none !important;
  color: var(--fg-muted);
}

/* --- Pole „Kraj / region" ------------------------------------------------
   Jedyne pole w całym formularzu bez tła i bez ramki (zmierzone: tło
   przezroczyste, `border-width: 0px`, podczas gdy każde inne pole ma #1F1F1F
   i ramkę #2A2A2A). Wyglądało jak napis, nie jak pole do zmiany. */
.wc-block-components-combobox .wc-block-components-combobox-control input,
.wc-block-components-country-input input,
.wc-block-components-state-input input,
#shipping-country, #billing-country, #shipping-state, #billing-state {
  background: var(--bg-input) !important;
  border: 1px solid var(--border-input) !important;
  border-radius: var(--radius-3) !important;
  color: var(--fg-default) !important;
}

/* --- Kasa bez wyjść bocznych ---------------------------------------------
   Pod przyciskiem „Zapłać" stał zapis na newsletter z WŁASNYM pomarańczowym
   przyciskiem (drugi taki sam przycisk 120 px niżej) i pełna stopka z dziesięcioma
   linkami wyprowadzającymi ze sklepu. Zmierzone na telefonie: 1650 z 4001 px
   strony zamówienia to było to, co jest POD przyciskiem kończącym zakup.
   Na stronie zamówienia zostaje to, co buduje zaufanie - logotypy płatności,
   nota prawna i stopka - a znika to, co odciąga. */
.woocommerce-checkout .et-newsletter,
.woocommerce-checkout .footer-top { display: none !important; }

/* --- Płatności: kafel i jego rozwinięty opis to jedno ---------------------
   WooCommerce rysuje wybraną płatność jako „accordion": osobno kafel z nazwą,
   osobno panel z opisem pod spodem. Po nadaniu kafelkom ramek wychodziły z
   tego dwa stykające się pudełka dla JEDNEJ wybranej metody. Ramkę bierze więc
   na siebie kontener accordionu, a kafel w środku jest przezroczysty. */
.wc-block-components-radio-control-accordion-option {
  background: var(--bg-input) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-3) !important;
  margin-bottom: 10px !important;
  overflow: hidden;
}
.wc-block-components-radio-control-accordion-option:has(.wc-block-components-radio-control__option-checked) {
  background: var(--color-brand-amber-grain) !important;
  border-color: var(--color-brand-orange) !important;
}
.wc-block-components-radio-control-accordion-option .wc-block-components-radio-control__option {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  margin-bottom: 0 !important;
}


/* =============================================================================
   KASA NA TELEFONIE: DROGA DO PIERWSZEGO POLA

   Zmierzone na 390x844: pierwsze pole formularza zaczynało się na 923 px,
   czyli CAŁY pierwszy ekran nie zawierał niczego do wypełnienia. Klient widzi
   pasek promocyjny, nagłówek, okruszki, pasek darmowej dostawy i podsumowanie
   - i musi się domyślić, że formularz jest gdzieś niżej.

   Czego tu NIE ROBIMY i dlaczego: nie przenosimy podsumowania pod formularz,
   choć to jedna linijka (`order`). Wylądowałoby wtedy POD przyciskiem
   „Kupuję", czyli klient zatwierdzałby płatność, nie mając nad nią kwoty.
   Nie chowamy też pozycji zamówienia - klient ma prawo widzieć, za co płaci,
   zanim kliknie.

   Zostaje więc odchudzenie tego, co nie niesie treści: okruszki (na kasie
   nikt nie nawiguje wstecz po drzewie kategorii) i nagłówek podsumowania,
   który zajmował 76 px na samo jedno słowo.
   ========================================================================= */
@media (max-width: 782px) {
  .woocommerce-checkout .breadcrumb,
  .woocommerce-checkout .woocommerce-breadcrumb { display: none; }

  .woocommerce-checkout .wc-block-components-checkout-order-summary__title {
    min-height: 0;
    padding-top: 8px; padding-bottom: 8px;
    margin-top: 4px;
  }
}

/* Cele dotykowe, których nie dało się załatwić przy stopce.

   Reguły bazowe tych dwóch elementów stoją w pliku DALEJ niż blok
   `pointer: coarse` przy stopce, a przy równej szczegółowości wygrywa
   późniejsza - więc tamten blok ich nie przebijał. Zmierzone: przycisk
   newslettera miał 32 px, odnośnik do ustawień zgód 21 px. */
@media (pointer: coarse) {
  .et-newsletter-row button { padding: 16px 20px; }
  .egotape-consent-reopen { display: inline-block; padding: 12px 0; }
}
/* Przycisk „Zaloguj się przez Google".

   KSZTALT JEST NASZ, ZNAK JEST ICH.

   Pierwsza wersja była białą pigułką z wytycznych Google i odcinała się od
   sklepu jak wklejka z innej strony: 999 px zaokrąglenia przy naszych 8,
   bez wersalików, biel na ciemnym. Google przewiduje wariant CIEMNY właśnie
   po to - i ten pasuje tu bez naginania czegokolwiek.

   Zmierzone z „Zaloguj się" tego samego formularza i przepisane: zaokrąglenie
   `--radius-3`, krój nagłówkowy 14/600, wersaliki, odstęp liter .08em,
   wyściółka 13/24. Różnica jest jedna i celowa: 44 px wysokości zamiast 42,
   bo to jest próg dotykowy, do którego reszta sklepu została doprowadzona.

   Nietknięty zostaje ZNAK Google - czterokolorowe „G" w oryginalnych
   proporcjach. To jedyne, czego wytyczne naprawdę pilnują, i jedyne, po czym
   człowiek rozpoznaje, dokąd go ten przycisk zabierze.

   Szerokość pełna, bo to nie jest drugi przycisk wysyłający ten sam
   formularz, tylko osobna droga do tego samego celu. */
a.et-google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  min-height: 44px;
  margin-top: 16px;
  padding: 13px 24px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-3);
  background: var(--bg-surface);
  color: var(--fg-default);
  font-family: var(--font-heading);
  font-size: 14px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none;
  transition: border-color .15s ease, background-color .15s ease;
}
/* Podswietlenie tylko tam, gdzie jest czym najechac.

   Zmierzone: przegladarka na telefonie melduje `(hover: hover)` jako falsz,
   ale i tak zostawia stan `:hover` po dotknieciu - przycisk zostawalby
   z bursztynowa obwodka az do przewiniecia strony, wygladajac na wybrany.
   `:focus-visible` zostaje POZA warunkiem, bo obramowanie przy nawigacji
   klawiatura jest potrzebne wszedzie. */
@media (hover: hover) {
  a.et-google-btn:hover {
    background: var(--bg-elev-1, var(--bg-surface));
    border-color: var(--color-brand-orange);
  }
}
a.et-google-btn:focus-visible {
  border-color: var(--color-brand-orange);
  color: var(--fg-default);
}
/* Napis dziedziczy kolor z przycisku, a nie z reguły dla linków - inaczej
   `.entry-content a` maluje go kolorem marki. Zmierzone, nie przewidziane. */
.et-google-btn span { color: inherit; }

/* Znak Google siedzi na własnym białym krążku, bo jego kolory są robione pod
   jasne tło - postawiony wprost na ciemnym gubi niebieskie i czerwone pole. */
.et-google-btn__znak {
  flex: 0 0 auto;
  box-sizing: content-box;
  padding: 3px;
  background: #fff;
  border-radius: 50%;
}


/* Na telefonie glowny przycisk logowania idzie na pelna szerokosc.

   Zmierzone na 390 px: „Zaloguj sie" mialo 132 px, a stojacy pod nim
   „Zaloguj sie przez Google" - 300. Wiekszy element czyta sie jako
   wazniejszy, wiec hierarchia wychodzila odwrotnie do zamiaru: droga
   poboczna wygladala na glowna.

   Na pulpicie zostaje szerokosc dopasowana do tresci - tam formularz jest
   waski wzgledem strony i rozciagniety przycisk wygladalby na pasek. */
@media (max-width: 640px) {
  .woocommerce form.woocommerce-form-login button.woocommerce-form-login__submit,
  .woocommerce form.woocommerce-form-register button.woocommerce-form-register__submit {
    display: block;
    width: 100%;
    min-height: 48px;
  }

  .woocommerce form.woocommerce-form-login a.et-google-btn,
  .woocommerce form.woocommerce-form-register a.et-google-btn {
    min-height: 48px;
    padding-top: 11px;
    padding-bottom: 11px;
  }
}

/* Rowna krawedz z polami formularza - na KAZDEJ szerokosci.

   WooCommerce trzyma pola w `p.form-row` z 3 px wysciolki po bokach,
   a przycisk Google jest doklejany wprost do formularza - wychodzil wiec
   szerszy o te 6 px i wystawal o 3 px w lewo poza pola nad soba. Na telefonie
   bylo to widac od razu, na pulpicie dopiero po zmierzeniu (81 px wobec 84).

   Latwiej dolozyc to samo wciecie, niz zabierac je wierszom formularza:
   tamto odsuniecie robi miejsce na obramowanie pola przy nawigacji
   klawiatura i zabranie go obcieloby ramke. */
.woocommerce form.woocommerce-form-login a.et-google-btn,
.woocommerce form.woocommerce-form-register a.et-google-btn {
  width: calc(100% - 6px);
  margin-left: 3px;
}
/* =============================================================================
   PASEK NAWIGACJI NA DOLE EKRANU (telefon)

   Wzorem jest timer i stary sklep: cztery pozycje, ikona nad podpisem,
   kciuk siega bez zmiany chwytu telefonu. Uzasadnienie, KIEDY ten pasek
   ustepuje, siedzi w `inc/nav-mobilna.php` - tu jest tylko wykonanie.

   Wysokosc: 56 px tresci plus bezpieczny margines iPhone'a. Bez
   `env(safe-area-inset-bottom)` podpisy wchodza pod kreske gestu i sa
   nieklikalne na kazdym telefonie z tej polowy dekady.
   ========================================================================== */
:root { --et-pasek-dolny: 56px; }

.et-mobile-bar { display: none; }

@media (max-width: 640px) {
  .et-mobile-bar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;                      /* nad trescia, pod banerem zgod (9999) */
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    height: calc(var(--et-pasek-dolny) + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: rgba(11, 11, 11, .94);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--border-default);
    transition: transform .2s ease;
  }
  .et-mobile-bar__item {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px;
    background: none; border: 0; cursor: pointer;
    color: var(--fg-muted);
    font-family: var(--font-heading);
    font-size: 11px; font-weight: 600; /* dol skali motywu (audyt D3) */
    letter-spacing: .06em; text-transform: uppercase;
    text-decoration: none;
    /* Caly slupek jest celem dotykowym: 97 px szerokosci na 56 wysokosci,
       czyli grubo powyzej progu - o to wlasnie chodzi w pasku na dole. */
    min-height: var(--et-pasek-dolny);
  }
  .et-mobile-bar__item svg { width: 22px; height: 22px; }
  .et-mobile-bar__item[aria-expanded="true"],
  .et-mobile-bar__item:focus-visible { color: var(--color-brand-orange); }

  /* Licznik przy koszyku - ten sam kawalek HTML, ktory odswieza WooCommerce. */
  .et-mobile-bar__ikona { position: relative; display: inline-flex; }
  .et-mobile-bar__ikona .et-cart-count {
    position: absolute; top: -6px; right: -10px;
    min-width: 16px; height: 16px; padding: 0 4px;
    border-radius: 999px;
    background: var(--color-brand-orange);
    color: var(--color-ink-1);
    font-size: 11px; line-height: 16px; text-align: center;
  }

  /* MIEJSCE NA PASEK NA DOLE STRONY.

     Sama wysciolka na `body` NIE WYSTARCZA i to jest zmierzone, nie
     teoretyczne: `overflow-x: hidden` jest ustawione zarowno na `html`, jak
     i na `body`, przez co oba staja sie kontenerami przewijania i koniec
     dokumentu wypada nizej, niz wynikaloby z wysciolki. Ostatni wiersz
     stopki - z przyciskiem „Ustawienia plikow cookies" - lezal wtedy POD
     paskiem nawigacji i nie dalo sie w niego trafic (zmierzone: przycisk
     814-859, pasek od 788).

     Dlatego zapas dostaje takze sam wiersz stopki. Nie ruszam przy tym
     globalnych regul przewijania: `overflow-x: hidden` chroni przed
     poziomym przesuwaniem strony i jego zdjecie odbiloby sie wszedzie. */
  body { padding-bottom: calc(var(--et-pasek-dolny) + env(safe-area-inset-bottom, 0px)); }
  .footer-bottom { padding-bottom: calc(var(--et-pasek-dolny) + env(safe-area-inset-bottom, 0px) + 20px); }

  /* Plywajace „?" wisi w prawym dolnym rogu i wchodzilo na napis „Ustawienia
     plikow cookies" (zmierzone: napis 198-362, przycisk 330-378). Odsuwamy
     ostatni wiersz stopki o szerokosc tego przycisku z zapasem - to jedyny
     wiersz, ktory z nim sasiaduje. */
  .footer-bottom { padding-right: 60px; }

  /* PASEK USTEPUJE AKCJI.
     Na karcie produktu dol ekranu nalezy do „Dodaj do koszyka", a w koszyku
     do „Przejdz do kasy". Dwa paski jeden nad drugim zjadlyby jedna czwarta
     ekranu i kazaly wybierac miedzy nawigacja a zakupem. */
  body:has(.et-builder-sticky.is-visible) .et-mobile-bar { transform: translateY(100%); }
  body.woocommerce-cart .et-mobile-bar,
  body.woocommerce-checkout .et-mobile-bar { display: none; }
  body.woocommerce-cart,
  body.woocommerce-checkout { padding-bottom: 0; }

  /* „?" WCHODZI DO PASKA, A NIE NAD NIEGO (audyt D2/U12, 2026-09-06).

     Nad paskiem przycisk wisial na prawej kolumnie kafli (zmierzone na 390 px:
     przycisk 330-378, kafel do 374) i zbieral dotkniecia przeznaczone dla
     produktu, a na karcie zachodzil na „Dodaj do koszyka". Pasek ma juz
     zarezerwowane 56 px u dolu strony (`padding-bottom` na body), wiec
     odstepujemy w nim pas 62 px po prawej i tam stawiamy przycisk: nie lezy
     na tresci nigdy, bo pod nim nic nie ma. Cztery pozycje paska zwezaja sie
     do ok. 82 px - wciaz ponad progiem 44 px. */
  .et-mobile-bar { padding-right: 62px; }
  .et-faq { right: 9px; bottom: calc(env(safe-area-inset-bottom, 0px) + 6px); }
  /* Bez paska (koszyk, kasa) przycisk wraca do rogu. */
  body.woocommerce-cart .et-faq,
  body.woocommerce-checkout .et-faq { right: 12px; bottom: 12px; }
  /* Pasek „Dodaj do koszyka" zjezdza na miejsce paska nawigacji - pomoc
     ustepuje razem z nim, zamiast wisiec nad przyciskiem zakupu. */
  body:has(.et-builder-sticky.is-visible) .et-faq { transform: translateY(150%); opacity: 0; pointer-events: none; }

  /* =========================================================================
     BANER ZGOD ZASLANIA DOL EKRANU - WIEC DOL EKRANU USTEPUJE

     Zgloszenie wlasciciela: „przycisk MENU oraz znaczek SZYBKA POMOC oba nie
     dzialaja". Odtworzone: baner zgod ma 300 px wysokosci i z-index 9999,
     wiec lezy DOKLADNIE na pasku nawigacji i na plywajacym „?".
     `elementFromPoint` nad oboma zwracal przycisk banera - dotkniecie
     trafialo w baner, nie w nie.

     Przyciski byly sprawne przez caly czas i to jest tu najgorsze: widoczny
     przycisk, ktory nie reaguje, czyta sie jako zepsuta strona. Niewidoczny
     przycisk nie obiecuje niczego.

     Dlatego oba schodza z drogi, dopoki pytanie o zgode stoi - to ta sama
     zasada, ktora motyw stosuje juz do paska „Dodaj do koszyka". Po
     odpowiedzi baner dostaje klase `--hidden` i wszystko wraca.
     ====================================================================== */
  html:not(.et-zgoda-podjeta) body:has(.egotape-consent-banner:not(.egotape-consent-banner--hidden)) .et-mobile-bar,
  html:not(.et-zgoda-podjeta) body:has(.egotape-consent-banner:not(.egotape-consent-banner--hidden)) .et-faq {
    display: none;
  }

  /* PODPOWIEDZI WYSZUKIWARKI I POPUP PROMOCJI - TA SAMA ZASADA
     (audyt iOS 2026-09-26).
     Lista podpowiedzi sięga do dołu ekranu, a ostatnia pozycja, „Zobacz
     wszystkie wyniki", leżała pod paskiem (393x659: lista do 635, pasek
     od 603) - widoczna przez 94% czerni, ale nie do trafienia. Popup
     promocji zajmuje cały ekran, a pod przyciemnieniem prześwitywały
     podpisy paska: „Nie teraz" stało dokładnie na nich (320 px: na SZUKAJ,
     ZALOGUJ SIĘ i KOSZYK). Dopóki warstwa stoi, pasek i „?" schodzą. */
  body:has(#et-search-suggestions:not([hidden])) .et-mobile-bar,
  html.et-promo-lock .et-mobile-bar { transform: translateY(100%); }
  body:has(#et-search-suggestions:not([hidden])) .et-faq,
  html.et-promo-lock .et-faq { transform: translateY(150%); opacity: 0; pointer-events: none; }

  /* Nagłówek oddaje paskowi TE CZTERY ikony, ktore sie dubluja.

     Pierwsza wersja chowala `.icon-btn` hurtem i zabrala przy okazji przycisk
     narzedzi - czyli jedyne przejscie do timera dla zalogowanego klienta,
     ktorego w dolnym pasku nie ma. Stad wyliczenie po klasach, nie po
     `aria-label`: etykiety sa tlumaczone i wersja angielska przestalaby
     pasowac do selektora. */
  .header .header-actions .et-search-toggle,
  .header .header-actions .et-nav-toggle,
  .header .header-actions .et-header-konto,
  .header .header-actions .et-header-koszyk { display: none; }
}

/* Narzedzia: na telefonie zostaje sam wpis w szufladzie menu.

   Pozycje "Narzedzia" byly w szufladzie OD DAWNA (`.et-tools-mobile`,
   pokazywana tylko na waskich ekranach) - dopisanie ich drugi raz wlasnym
   filtrem dalo podwojne "Timer rund" i "Dziennik treningowy" u zalogowanych.
   Filtr usuniety; tu zostaje wylacznie schowanie PRZYCISKU z naglowka, zeby
   logo moglo stanac na srodku samo. */
@media (max-width: 640px) {
  .header .et-tools-toggle,
  .header .et-tools-bar { display: none; }

  /* LOGO NA SRODKU.
     `.header-actions` idzie poza uklad (pozycjonowanie bezwzgledne), bo tylko
     wtedy logo srodkuje sie wzgledem CALEJ szerokosci naglowka, a nie wzgledem
     tego, co zostalo po prawej. Przy pustej grupie akcji roznica wynosila
     21 px - dosc, zeby bylo widac, ze cos jest krzywo. */
  /* Naglowek na telefonie dostaje wezszy margines boczny niz reszta strony.

     Znak jest szeroki i niski: przy 60 px wysokosci ma 292 px szerokosci,
     czyli przy marginesie 28 px zostawaloby po 21 px z kazdej strony i nie
     dalo sie go powiekszyc ani o piksel. Logo jest wysrodkowane, wiec nie
     musi trzymac linii z trescia ponizej - a to jedyny powod, dla ktorego
     naglowek dzielil margines z reszta strony. */
  .header-inner {
    position: relative;
    justify-content: center;
    gap: 0;
    width: calc(100% - 32px);
  }
  .header-logo { margin: 0; max-width: 100%; }
  /* SZEROKOSC EKRANU JEST TWARDA GRANICA WYSOKOSCI LOGO.

     Znak jest szeroki i niski (proporcja blisko 5:1), wiec rosnie glownie
     w bok: przy 68 px ma juz 331 px szerokosci na 358 dostepnych. Przy
     wpisanych 100 px chcialby 487 px i wychodzil poza ekran - zmierzone,
     lewa krawedz na -49.

     `max-width` zatrzymuje go na szerokosci naglowka, a `object-fit`
     dopasowuje obrazek proporcjonalnie zamiast go rozciagac. Efekt: powyzej
     okolo 73 px na ekranie 390 px logo po prostu przestaje rosnac. To jest
     ograniczenie fizyczne, nie ustawienie - zeby przekroczyc te granice,
     trzeba zabrac naglowkowi margines boczny. */
  .header-logo img {
    /* Wysokosc to MNIEJSZA z dwoch: zadana w Personalizacji i ta, ktora
       jeszcze miesci sie w szerokosci ekranu. Druga liczba bierze sie
       z proporcji samego pliku logo (`--et-logo-proporcje`, wyliczane
       w PHP), wiec podmiana znaku na inny nie wymaga tu zadnej zmiany. */
    height: min(var(--et-logo-mobile, 36px), calc((100vw - 32px) / var(--et-logo-proporcje, 4.87)));
    max-width: 100%;
    object-fit: contain;
  }
  .header-actions {
    position: absolute; right: 0; top: 50%;
    transform: translateY(-50%);
    margin-left: 0;
  }
}


/* Zgoda zapisana w przegladarce - pytanie znika, zanim strona sie pokaze.

   Klase ustawia krotki skrypt w naglowku (patrz inc/analytics.php). Powod:
   strony dla niezalogowanych leza w pamieci podrecznej BEZ rozroznienia
   ciasteczka zgody, wiec sam PHP nie moze o tym decydowac. */
html.et-zgoda-podjeta .egotape-consent-banner { display: none; }

/* Lupa na zdjeciu produktu nie moze zjadac klikniec.

   WooCommerce nakłada na zdjecie warstwe powiekszenia (`img.zoomImg`, wtyczka
   jquery-zoom) i wstawia ja OBOK linku, nie w srodku. Powiekszenie po
   klknieciu (PhotoSwipe) jest tymczasem podpiete pod klikniecia w LINK - wiec
   zdarzenie zatrzymywalo sie na warstwie lupy i nie docieralo nigdzie dalej.

   Objaw: klikniecie w zdjecie produktu na pulpicie nie robilo NIC. Zlapane
   audytem interakcji 2026-08-19 (test trafienia w elementy klikalne), bo
   zadne sprawdzenie wygladu nie ma jak tego zobaczyc.

   `pointer-events: none` przepuszcza klikniecie do linku pod spodem.
   Samo powiekszenie przy najechaniu dziala dalej: jquery-zoom sledzi ruch
   myszy na KONTENERZE, a nie na tej warstwie. */
.woocommerce div.product .woocommerce-product-gallery__image img.zoomImg {
  pointer-events: none;
}

/* =============================================================================
   PRZYCISK WYBORU PUNKTU ODBIORU (Apaczka, mapa punktow)

   Wtyczka rysuje go we wlasnych kolorach: jaskrawa zielen (41,187,21) na bieli,
   napis 19 px. Na ciemnej, bursztynowej kasie wyglada jak wklejka z innej
   strony - a stoi w miejscu, ktore MUSI wygladac na czesc zamowienia, bo bez
   wybrania punktu przesylki nie da sie nadac.

   Uwaga na strukture: `#apaczka_mp_geowidget_show_map` to SAM przycisk, a nie
   pojemnik z przyciskiem w srodku. Pierwsza wersja tych regul celowala
   w potomka i dlatego zmienila tylko rozmiar, zostawiajac zielen.
   ========================================================================== */
#apaczka_mp_geowidget_show_map.button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  margin: 12px 0 4px;
  padding: 12px 20px;
  box-sizing: border-box;
  background: var(--color-brand-orange);
  color: var(--color-ink-1);
  border: 1px solid transparent;
  border-radius: var(--radius-3);
  font-family: var(--font-heading);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.2;
  cursor: pointer;
}
@media (hover: hover) {
  #apaczka_mp_geowidget_show_map.button:hover {
    background: var(--color-brand-orange-bright, var(--color-brand-orange));
  }
}
/* Wybrany punkt - potwierdzenie pod przyciskiem, czytelne na ciemnym tle.
   Sama ramka z danymi punktu (`#apaczka_selected_point_data`) jest przy
   potwierdzeniu paczkomatu InPost - wyglądają tak samo. */
#apaczka_selected_point_data_wrap {
  margin-top: 10px;
  color: var(--fg-default);
  font-size: 14px;
}

/* Ikona rodzaju dostawy przy opcji wysylki.

   Wstawia ja `egotape.js` (kasa jest na Reakcie i przerysowuje liste, wiec
   nie da sie tego zrobic samym PHP). Kolor bierze sie z tekstu opcji, dzieki
   czemu zaznaczona opcja podswietla ikone razem z napisem. */
.et-ikona-wysylki {
  display: inline-flex;
  align-items: center;
  vertical-align: -6px;
  margin-right: 10px;
  color: var(--fg-muted);
}
.wc-block-components-radio-control__option-checked .et-ikona-wysylki { color: var(--color-brand-orange); }
.et-ikona-wysylki svg { width: 24px; height: 24px; }

/* =========================================================================
   TAŚMY Z HASŁAMI W HERO (wariant 3a na telefonie, 5b na komputerze)

   PO CO NA TELEFONIE: cena i trzy zdania opisu zajmowały pięć wierszy
   i spychały nagłówek „Taśmy treningowe" oraz ceny na kartach pod pasek
   dolny. W tym miejscu leży teraz pasek, na którym po kolei nakleja się
   i odrywa jedno krótkie hasło.

   PO CO NA KOMPUTERZE: hero było dwiema kolumnami - tekst z lewej, zdjęcie
   z prawej. Projekt „plakat na zdjęciu" (2026-09-23) stawia zdjęcie pod
   całym hero, a treść na środku: duży tytuł z ostatnim słowem na taśmie,
   pod nim ten sam rotator co na telefonie, tylko większy.

   DLACZEGO TEN BLOK JEST NA KOŃCU PLIKU: reguły hero dla telefonu żyją
   w `@media (max-width: 768px)`, a dla komputera wyżej w pliku. Blok
   postawiony wcześniej przegrywałby z nimi przy równej szczegółowości,
   a podbijanie selektorów `!important` byłoby gorsze niż kolejność.

   ZAKRES: rotator działa poniżej 600 px i od 1024 px. Pomiędzy (tablet)
   zostaje pełny opis, bo tam mieści się w całości.

   BEZ JAVASCRIPTU taśmy w ogóle się nie pokazują, a na ekranie zostaje
   zwykły opis - dokładnie taki, jaki był przed zmianą.
   ====================================================================== */

.hero-rotator { display: contents; }
.hero-dots { display: none; }
.hero-tapes { display: none; }

/* Krótsza nazwa przycisku pokazuje się dopiero tam, gdzie dwa przyciski stoją
   obok siebie - czyli na telefonie z włączonym rotatorem. Wszędzie indziej
   widać napis z Personalizacji, bez zmian. */
.tylko-telefon { display: none; }

/* Naklejanie: pasek odsłania się od lewej. */
@keyframes etApply {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
/* Zrywanie: pasek podnosi się w prawo i znika. Odległości są zmiennymi, bo
   na komputerze taśma jest większa i musi odjechać dalej. */
@keyframes etPeel {
  from { transform: translateY(-50%) rotate(var(--r)); opacity: 1; }
  to   {
    transform:
      translateY(calc(-50% - var(--zryw-y, 18px)))
      translateX(var(--zryw-x, 12px))
      rotate(calc(var(--r) - var(--zryw-obrot, 6deg)));
    opacity: 0;
  }
}

/* --- Rotator: wspólny dla telefonu i komputera --------------------------- */

@media (max-width: 600px), (min-width: 1024px) {
  html.js .hero .hero-rotator {
    display: block;
    position: relative;
    height: var(--pasmo-h, 46px);
    /* `visible`, nie `hidden`: zrywany pasek wychodzi lekko poza pasmo. */
    overflow: visible;
  }

  /* Treść niosą taśmy, więc cena i opis schodzą z ekranu. W kodzie strony
     zostają - czyta je wyszukiwarka. */
  html.js .hero .hero-rotator .hero-price,
  html.js .hero .hero-rotator .hero-sub { display: none; }
  html.js .hero .hero-tapes { display: block; }

  html.js .hero .tape {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    display: none;
    justify-content: center;
    transform: translateY(-50%) rotate(var(--r));
    transform-origin: center;
    /* Cień jako filtr, bo `clip-path` ucina `box-shadow` razem z rogami. */
    filter: drop-shadow(var(--cien, 0 3px 6px rgba(0, 0, 0, .55)));
    --r: -1.5deg;
  }
  html.js .hero .tape:nth-child(even) { --r: 1.2deg; }

  /* Widoczne są tylko dwie: ta wchodząca i ta, która właśnie się zrywa. */
  html.js .hero .tape.is-in,
  html.js .hero .tape.is-out { display: flex; }

  html.js .hero .tape__reveal { display: block; }
  html.js .hero .tape.is-in .tape__reveal { animation: etApply 450ms cubic-bezier(.2, .7, .2, 1) 140ms both; }
  html.js .hero .tape.is-out { animation: etPeel 380ms cubic-bezier(.4, 0, 1, 1) forwards; }

  html.js .hero .tape__strip {
    height: var(--tasma-h, 30px);
    padding: var(--tasma-pad, 0 16px);
    display: flex;
    align-items: center;
    white-space: nowrap;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: var(--tasma-fs, 14px);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--color-ink-1, #0B0B0B);
    /* Delikatne prążki: taśma bawełniana, nie kartka papieru. */
    background:
      repeating-linear-gradient(90deg, rgba(0, 0, 0, .05) 0 1px, transparent 1px 3px),
      var(--color-bone-0, #F5F1EA);
    clip-path: polygon(
      0 0, 100% 0,
      calc(100% - var(--zab, 4px)) 12.5%, 100% 25%,
      calc(100% - var(--zab, 4px)) 37.5%, 100% 50%,
      calc(100% - var(--zab, 4px)) 62.5%, 100% 75%,
      calc(100% - var(--zab, 4px)) 87.5%, 100% 100%,
      0 100%,
      var(--zab, 4px) 87.5%, 0 75%,
      var(--zab, 4px) 62.5%, 0 50%,
      var(--zab, 4px) 37.5%, 0 25%,
      var(--zab, 4px) 12.5%
    );
  }
  html.js .hero .tape--cena .tape__strip {
    background:
      repeating-linear-gradient(90deg, rgba(0, 0, 0, .05) 0 1px, transparent 1px 3px),
      var(--color-brand-orange, #F69500);
  }

  /* Kreski: pole dotyku wyższe niż sama kreska - palec trafia w cały
     prostokąt, a oko widzi tylko kreskę. */
  html.js .hero-dots { display: flex; gap: 6px; align-items: center; }
  .hero-dot {
    width: var(--kreska-w, 18px);
    height: 14px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    display: flex;
    align-items: center;
  }
  .hero-dot::before {
    content: "";
    display: block;
    width: 100%;
    height: 3px;
    border-radius: 2px;
    background: var(--border-strong, #3A3A3A);
    transition: background .2s ease;
  }
  .hero-dot.is-active::before { background: var(--color-bone-0); }
  .hero-dot:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; }
  /* Pole dotyku 24x44 zamiast 18x14 (audyt iOS 2026-09-26) - niewidoczne,
     układ się nie zmienia. W bok tylko 3 px, połowa odstępu między
     kreskami, żeby sąsiednie pola na siebie nie zachodziły; w pionie
     mieści się w wierszu z odnośnikiem i w odstępie nad przyciskami. */
  .hero-dot { position: relative; }
  .hero-dot::after { content: ""; position: absolute; inset: -15px -3px; }
}

/* --- Telefon: układ przycisków pod rotatorem ----------------------------- */

@media (max-width: 600px) {
  /* Najdłuższe hasła nie mieszczą się w jednym wierszu na najwęższych
     ekranach - schodzimy z krojem i wypełnieniem, zamiast pozwolić taśmie
     wyjść poza ekran. */
  @media (max-width: 380px) {
    html.js .hero .tape__strip { --tasma-fs: 13px; --tasma-pad: 0 12px; }
  }
  /* 320 px (audyt iOS 2026-09-26): najdłuższa taśma, z ceną, miała przy
     13 px 338 px i wychodziła 9 px za każdą krawędź ekranu - postrzępione
     końce ucinała krawędź strony. 12 px daje ok. 310 px, czyli 5 px zapasu
     z każdej strony. */
  @media (max-width: 340px) {
    html.js .hero .tape__strip { --tasma-fs: 12px; --tasma-pad: 0 10px; }
  }

  /* Kreski i odnośnik w jednym wierszu, przyciski obok siebie w drugim.
     Siatka zamiast kolumny flex, bo tylko ona ustawia dwa wiersze o różnym
     podziale bez dokładania pojemników do szablonu. */
  html.js .hero .hero-ctas {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    grid-template-areas:
      "kreski odnosnik"
      "cta1   cta2";
    gap: 10px;
    /* `center` zostawiało przyciski różnej wysokości na różnych osiach -
       `stretch` równa je do wiersza, a wiersz do najwyższego z nich. */
    align-items: stretch;
    margin-top: 2px;
  }
  html.js .hero .hero-ctas > .hero-dots,
  html.js .hero .hero-ctas > .hero-link { align-self: center; }
  html.js .hero .hero-ctas .hero-dots { grid-area: kreski; justify-self: start; }
  html.js .hero .hero-ctas .hero-link {
    grid-area: odnosnik;
    justify-self: end;
    align-self: center;
    min-height: 0;
    text-align: right;
  }
  html.js .hero .hero-ctas .btn .tylko-pulpit { display: none; }
  html.js .hero .hero-ctas .btn .tylko-telefon { display: inline; }
  html.js .hero .hero-ctas .btn-primary { grid-area: cta1; }
  html.js .hero .hero-ctas .btn-secondary { grid-area: cta2; }
  /* Oba przyciski w jednym wierszu tekstu i tej samej wysokości. Dłuższa
     nazwa wpisana w Personalizacji najpierw zmniejszy krój, a gdy i to nie
     starczy - zawinie się. Celowo BEZ `nowrap`: tekst wychodzący poza
     pomarańczowy prostokąt wygląda na usterkę. */
  html.js .hero .hero-ctas .btn {
    width: 100%;
    min-height: 48px;
    padding-left: 8px;
    padding-right: 8px;
    font-size: clamp(12px, 3.4vw, 14px);
  }
}

/* --- Komputer: tekst po lewej, zdjęcie do prawej krawędzi (7b) ----------- */

/* Zdjęcie po prawej istnieje tylko na komputerze. Poniżej 1024 px zostaje
   karuzela z `.hero-right` - telefon i tablet bez zmian. */
.hero-photo-wrap { display: none; }

@media (min-width: 1024px) {
  /* HERO NA CAŁĄ SZEROKOŚĆ OKNA - tylko tutaj.

     Reguła z `!important` wyżej w pliku trzyma hero w szerokości strony,
     a hero ma `overflow: hidden` - zdjęcie ucięłoby się więc na krawędzi
     kontenera, a nie okna. Hero dostaje pełną szerokość, a w szerokości
     strony (tej samej co siatka produktów niżej) zostaje sama treść
     w `.hero-left`. `body .hero` ma większą wagę niż `.hero`, więc
     wygrywa także przy `!important`. */
  body .hero {
    width: 100% !important;
    display: flex;
    flex-direction: column;
    position: relative;
    height: clamp(520px, 62vh, 620px);
    min-height: 0;
    overflow: hidden;
    padding-bottom: 0;
  }

  /* Karuzela z telefonu schodzi z układu. Tła elementów wewnątrz `display:
     none` przeglądarka nie pobiera, więc te zdjęcia nie idą na komputerze
     przez sieć. */
  .hero .hero-right,
  .hero .hero-right.has-image { display: none; }

  /* Treść: lewa krawędź dokładnie tam, gdzie lewa krawędź „Taśm
     treningowych" - ten sam wzór szerokości co kontener strony. */
  .hero .hero-left {
    position: relative;
    z-index: 2;
    flex: 1 1 auto;
    width: min(100% - (var(--et-gutter, 24px) * 2), var(--et-container, 1320px));
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    text-align: left;
    gap: 0;
    padding-bottom: 40px;
  }
  .hero .hero-left > * { max-width: 640px; }

  /* ZDJĘCIE. Stoi przy prawej krawędzi okna i wtapia się w tło z trzech
     stron: lewej, prawej i od dołu (góra zostaje ostra - tam stoi ciemny
     nagłówek). Poszarpany brzeg z projektu 7b właściciel odrzucił
     2026-09-23: „to powinno się zlewać, jak wcześniej".

     Maska, nie nakładka w kolorze tła: zdjęcie naprawdę znika, więc pod
     spodem widać ziarno i tło strony, a nie namalowany na nim czarny pas.
     Lewy zanik jest szerszy, bo tam zdjęcie spotyka tekst - i dlatego samo
     zdjęcie sięga dalej w lewo niż w projekcie: zanik zjada jego brzeg.
     `--foto-zanik` czyta też `egotape.js`, pilnując odstępu tytułu.

     `.et-grain > *` daje dzieciom hero `position: relative` - dwie klasy
     w selektorze to przebijają. */
  .hero .hero-photo-wrap {
    --foto-zanik: 240px;
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 0;
    width: clamp(640px, 54vw, 1100px);
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--foto-zanik)),
      linear-gradient(270deg, transparent 0, #000 140px),
      linear-gradient(0deg, transparent 0, #000 140px);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--foto-zanik)),
      linear-gradient(270deg, transparent 0, #000 140px),
      linear-gradient(0deg, transparent 0, #000 140px);
    mask-composite: intersect;
  }
  .hero .hero-photo-wrap picture { display: block; width: 100%; height: 100%; }
  .hero .hero-photo {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 40%;
  }
  /* TYTUŁ: dwa wiersze tej samej szerokości, od lewej.

     Równe szerokości robi `egotape.js` (krótszy wiersz rośnie do dłuższego),
     i on też pilnuje 40 px odstępu od zdjęcia: gdy miejsca brakuje, maleje
     tytuł, a zdjęcie zostaje. Bez JavaScriptu `<br>` zostaje widoczny
     i tytuł łamie się jak dawniej. */
  .hero .hero-title {
    margin: 0;
    font-family: var(--font-display);
    /* Mnożnik z Personalizacji („Hero - wielkość napisu na komputerze"). */
    font-size: calc(clamp(88px, 6.25vw, 120px) * var(--et-hero-claim-pc, 1));
    line-height: .9;
    letter-spacing: .02em;
    text-align: left;
  }
  .hero .hero-title .hero-title-line { display: block; white-space: nowrap; }
  .hero .hero-title .hero-title-fit > br { display: none; }

  /* ROTATOR WYŚRODKOWANY POD TYTUŁEM (prośba właściciela 2026-09-23).

     Oś to środek tytułu, nie środek hero: `egotape.js` po dopasowaniu
     tytułu wpisuje w `--et-kolumna` szerokość bloku tekstu (tytuł albo
     rząd przycisków, co szersze). Pasmo taśm i wiersz z kreskami mają
     tę szerokość i środkują swoją treść. Taśma dłuższa niż pasmo dostaje
     mniejszy krój (`is-ciasno`, patrz `egotape-hero.js`). */
  html.js .hero .hero-rotator {
    --pasmo-h: 60px;
    width: var(--et-kolumna, 100%);
    max-width: 600px;
    margin-top: 22px;
  }
  html.js .hero .tape {
    justify-content: center;
    transform-origin: center;
    --tasma-h: 42px;
    --tasma-pad: 0 22px;
    --tasma-fs: 19px;
    --zab: 5px;
    --cien: 0 4px 8px rgba(0, 0, 0, .55);
    --zryw-y: 22px;
    --zryw-x: 14px;
    --zryw-obrot: 5deg;
  }
  /* Hasło dłuższe niż pasmo (sprawdza `egotape-hero.js`) - krój o 2 px
     mniejszy, zamiast taśmy wychodzącej na zdjęcie. */
  html.js .hero .hero-rotator.is-ciasno .tape { --tasma-fs: 17px; }

  /* Kreski i odnośnik w pierwszym wierszu - na środku, pod taśmą;
     przyciski w drugim - od lewej, w linii z tytułem. Flex z łamaniem
     zamiast siatki, bo w siatce odnośnik stałby na krawędzi kolumny
     wyznaczonej przez szerszy przycisk, a ma stać 20 px za kreskami.
     Pseudo-element o pełnej szerokości łamie wiersz, a automatyczne
     marginesy po obu stronach pierwszego wiersza go środkują. */
  html.js .hero .hero-ctas {
    width: var(--et-kolumna, auto);
    max-width: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 0;
    margin-top: 12px;
  }
  html.js .hero .hero-ctas::before {
    content: "";
    order: 3;
    flex-basis: 100%;
    height: 0;
  }
  html.js .hero .hero-ctas .hero-dots { order: 1; --kreska-w: 22px; margin-left: auto; }
  html.js .hero .hero-ctas .hero-link { order: 2; margin-left: 20px; margin-right: auto; }
  html.js .hero .hero-ctas .btn-primary { order: 4; margin-top: 30px; }
  html.js .hero .hero-ctas .btn-secondary { order: 5; margin-top: 30px; margin-left: 12px; }
  /* Kreski na ciemnym tle: nieaktywne przygaszoną bielą, aktywna w kolorze
     tekstu (`--color-bone-0` to czysta biel). */
  .hero .hero-dot::before { background: rgba(245, 241, 234, .35); }
  .hero .hero-dot.is-active::before { background: var(--fg-default, #F5F1EA); }
  html.js .hero .hero-ctas .btn {
    height: 56px;
    min-height: 56px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 16px;
    text-transform: uppercase;
  }
  html.js .hero .hero-ctas .btn-primary { padding: 0 32px; background: var(--color-brand-orange, #F69500); }
  html.js .hero .hero-ctas .btn-secondary { padding: 0 28px; border: 1px solid #444; }

  /* „Taśmy treningowe" tuż pod hero. */
  .hero + .products-section { padding-top: 24px; }
}

/* 1024-1279: węższe zdjęcie i mniejsze taśmy. Minimum 640 px z szerszych
   ekranów tu nie obowiązuje - przy 1024 px zjadłoby miejsce na przyciski. */
@media (min-width: 1024px) and (max-width: 1279px) {
  .hero .hero-photo-wrap { width: 50vw; }
  .hero .hero-title { font-size: calc(88px * var(--et-hero-claim-pc, 1)); }
  html.js .hero .hero-rotator { max-width: 480px; }
  html.js .hero .tape { --tasma-fs: 16px; }
  html.js .hero .hero-rotator.is-ciasno .tape { --tasma-fs: 14px; }
}

/* „Ogranicz ruch" w ustawieniach systemu: taśma po prostu jest, bez
   naklejania i zrywania. Kreskami dalej można przełączać hasła. */
@media (prefers-reduced-motion: reduce) {
  html.js .hero .tape.is-in .tape__reveal,
  html.js .hero .tape.is-out { animation: none; }
  html.js .hero .tape.is-out { display: none; }
}

/* =========================================================================
   POPUPY PROMOCYJNE (2026-09-23)

   Logika i rejestr szablonów: inc/promo-popups.php, panel:
   inc/admin-promo-popups.php, znaczniki: template-parts/promo/, skrypt:
   assets/js/promo-popup.js. Tu wygląd wspólnej obudowy i trzech szablonów.
   Wszystko to siedzi w `<template>`, dopóki skrypt tego nie wstawi, więc
   reguły niżej nie dotykają strony, na której promocji nie ma.
   ========================================================================= */

/* --- Kupon 14a: kartka z czterema taśmami ---------------------------------

   Wymiary bazowe z projektu (kartka 256 px) mnożone przez `--coupon-scale` -
   JEDNA liczba skaluje całość, z taśmami i cieniem. Popup ustawia ją
   skryptem (1,25 na komputerze, mniej na telefonie), kupon w hero ma 1.
   Kolory wpisane wprost, a nie tokenami motywu: kartka ma wyglądać tak samo,
   nawet gdyby paleta strony kiedyś się zmieniła - to jest przedmiot. */
.et-coupon {
  --s: var(--coupon-scale, 1);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(12px * var(--s));
  box-sizing: border-box;
  width: calc(256px * var(--s));
  margin: 0;
  padding: calc(30px * var(--s)) calc(20px * var(--s)) calc(24px * var(--s));
  border: 0;
  border-radius: 0;
  background: #F5F1EA;
  color: #0B0B0B;
  font: inherit;
  font-family: var(--font-body);
  line-height: 1.2;
  letter-spacing: normal;
  text-align: center;
  text-transform: none;
  cursor: pointer;
  transform: rotate(-3deg);
  filter: drop-shadow(0 calc(18px * var(--s)) calc(30px * var(--s)) rgba(0, 0, 0, .6));
  -webkit-tap-highlight-color: transparent;
}
.et-coupon:focus-visible {
  outline: 3px solid var(--color-brand-orange);
  outline-offset: 6px;
  box-shadow: none;
}
.et-coupon__kicker {
  display: inline-flex;
  align-items: center;
  gap: calc(7px * var(--s));
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(12px * var(--s));
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.et-coupon__flag {
  flex: none;
  display: inline-block;
  box-sizing: border-box;
  width: calc(20px * var(--s));
  height: calc(13px * var(--s));
  border: 1px solid #0B0B0B;
  background: linear-gradient(180deg, #FFF 0 50%, #DC143C 50% 100%);
}
.et-coupon__headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(34px * var(--s));
  line-height: .95;
  text-transform: uppercase;
}
.et-coupon__percent {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(96px * var(--s));
  line-height: .85;
}
.et-coupon__code {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: calc(52px * var(--s));
  border: calc(2px * var(--s)) dashed #0B0B0B;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(26px * var(--s));
  letter-spacing: .08em;
  white-space: nowrap;
}
/* Odstęp liter dokłada miejsce także ZA ostatnią literą - bez tej wyściółki
   kod stałby o ułamek piksela na lewo od środka ramki. */
.et-coupon__code-text { padding-left: .08em; }
/* Etykieta stanu stoi OBOK podpowiedzi, nie w polu kodu: dłuższe
   „SKOPIOWANO" nie może zmieniać wysokości kartki. Wiersz się nie łamie,
   a kartka ma stałą szerokość, więc zmiana napisu nie rusza jej wymiarów.

   Bez dodatkowego odstępu - tylko `space-between`, jak w projekcie. Zmierzone
   przy skali 1: wiersz 216,6 px, „Wpisz kod w koszyku." 139 px,
   „SKOPIOWANO" 77,6 px - każdy dodatkowy piksel odstępu obcinał podpowiedź. */
.et-coupon__row {
  align-self: stretch;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  white-space: nowrap;
}
.et-coupon__hint {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-body);
  font-size: calc(13px * var(--s));
  line-height: 1.3;
}
/* Etykieta rośnie w lewo (wiersz dosuwa ją do prawej). Podpowiedź może się
   skrócić wielokropkiem tylko wtedy, gdy właściciel wpisze dłuższy tekst
   - rezerwowanie miejsca na „SKOPIOWANO" obcinałoby ją na stałe.
   Ujemny margines zdejmuje odstęp liter ZA ostatnią literą: bez niego prawa
   krawędź napisu nie trzyma linii z ramką kodu, a wiersz traci 1,2 px. */
.et-coupon__state {
  flex: none;
  margin-right: -.1em;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(12px * var(--s, 1));
  letter-spacing: .1em;
  text-transform: uppercase;
}
.et-coupon__state-done { display: none; }
.is-copied .et-coupon__state-idle { display: none; }
.is-copied .et-coupon__state-done { display: inline; }

/* Taśmy w rogach. Cień na opakowaniu, bo `clip-path` na samej taśmie ucina
   `box-shadow`; obrót na taśmie, żeby cień padał w dół, a nie „za" obrotem. */
.et-coupon__tape {
  position: absolute;
  width: calc(84px * var(--s));
  height: calc(24px * var(--s));
  pointer-events: none;
  filter: drop-shadow(0 calc(2px * var(--s)) calc(4px * var(--s)) rgba(0, 0, 0, .4));
}
.et-coupon__tape-strip,
.et-sheet__tape-strip {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .06) 0 calc(1px * var(--s, 1)), transparent calc(1px * var(--s, 1)) calc(3px * var(--s, 1))),
    #F69500;
  clip-path: polygon(0 0, 100% 0, calc(100% - 4px * var(--s, 1)) 12.5%, 100% 25%, calc(100% - 4px * var(--s, 1)) 37.5%, 100% 50%, calc(100% - 4px * var(--s, 1)) 62.5%, 100% 75%, calc(100% - 4px * var(--s, 1)) 87.5%, 100% 100%, 0 100%, calc(4px * var(--s, 1)) 87.5%, 0 75%, calc(4px * var(--s, 1)) 62.5%, 0 50%, calc(4px * var(--s, 1)) 37.5%, 0 25%, calc(4px * var(--s, 1)) 12.5%);
  transform: rotate(var(--tape-rot, 0deg));
}
.et-coupon__tape--tl { left: calc(-20px * var(--s)); top: calc(-6px * var(--s)); --tape-rot: -38deg; }
.et-coupon__tape--tr { right: calc(-20px * var(--s)); top: calc(-6px * var(--s)); --tape-rot: 38deg; }
.et-coupon__tape--bl { left: calc(-20px * var(--s)); bottom: calc(-6px * var(--s)); --tape-rot: 38deg; }
.et-coupon__tape--br { right: calc(-20px * var(--s)); bottom: calc(-6px * var(--s)); --tape-rot: -38deg; }

/* --- Obudowa popupu (natywny <dialog>) ------------------------------------ */
dialog.et-promo {
  box-sizing: border-box;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--fg-default);
}
dialog.et-promo:not([open]) { display: none; }

.et-promo--modal {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  overscroll-behavior: contain;
}
/* Samo przyciemnienie, BEZ rozmycia - decyzja z projektu 14a. */
.et-promo--modal::backdrop { background: rgba(0, 0, 0, .72); }

.et-promo__stage {
  box-sizing: border-box;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  /* U góry miejsce na przycisk zamknięcia - kupon z taśmami na nim nie siądzie. */
  padding: 60px 12px 16px;
}
@media (min-width: 768px) {
  .et-promo__stage { padding: 32px 24px 24px; }
}

.et-promo__close {
  position: fixed;
  top: 8px;
  right: 8px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(245, 241, 234, .28);
  border-radius: 0;
  background: rgba(11, 11, 11, .6);
  color: #F5F1EA;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .et-promo__close:hover { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
}

/* Przyciski pod kuponem - poza obrotem kartki, w szerokości kartki. */
.et-promo__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  width: calc(256px * var(--coupon-scale, 1));
  max-width: 100%;
}
.et-promo__actions .btn { width: 100%; min-height: 48px; }
.et-promo__primary { font-size: 15px; }
.et-promo__actions .btn-secondary { color: #F5F1EA; }
.et-promo__later {
  align-self: center;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  background: none;
  color: #F5F1EA;
  font-family: var(--font-body);
  font-size: 15px;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .et-promo__later:hover { color: var(--color-brand-orange); }
}

/* Animacja: nakładka 200 ms, kupon „nakleja się" 250 ms, wyjście 150 ms. */
@keyframes et-promo-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes et-promo-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes et-promo-stick {
  from { transform: scale(.96) rotate(-6deg); }
  to   { transform: scale(1) rotate(-3deg); }
}
@keyframes et-promo-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
.et-promo--modal.is-open::backdrop { animation: et-promo-fade-in .2s ease-out both; }
.et-promo--modal.is-open .et-promo__stage,
.et-promo--modal.is-open .et-promo__close { animation: et-promo-fade-in .2s ease-out both; }
.et-promo.is-open .et-promo__stage .et-coupon { animation: et-promo-stick .25s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.et-promo--sheet.is-open .et-sheet { animation: et-promo-rise .25s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.et-promo.is-closing,
.et-promo.is-closing::backdrop { animation: et-promo-fade-out .15s ease-in both; }
/* „Ogranicz ruch": tylko przenikanie, bez obrotu i jazdy. */
@media (prefers-reduced-motion: reduce) {
  .et-promo.is-open .et-promo__stage .et-coupon { animation: none; }
  .et-promo--sheet.is-open .et-sheet { animation: et-promo-fade-in .2s ease-out both; }
}

/* Otwarte okno = strona pod spodem stoi. Wyściółkę za pasek przewijania
   dokłada skrypt, żeby treść pod nakładką nie skakała w bok. */
html.et-promo-lock,
html.et-promo-lock body { overflow: hidden; }

/* --- Kupon w lewym marginesie hero (szerokie ekrany) ---------------------

   Czy się mieści, mierzy skrypt (taśmy + 16 px zapasu do lewej krawędzi
   treści) - szerokość treści ustawia Personalizacja, więc stały próg w CSS
   kłamałby po każdej zmianie. Poniżej 1440 px nie ma go w ogóle. */
.et-promo-hero { display: none; }
@media (min-width: 1440px) {
  .hero .et-promo-hero:not([hidden]) {
    --coupon-scale: 1;
    display: block;
    position: absolute;
    left: 46px;
    top: 110px;
    z-index: 3;
    width: 256px;
    animation: et-promo-fade-in .2s ease-out both;
  }
}
/* KOD W PASKU PROMO JEST ZAWSZE - także obok kuponu w hero.

   Zgłoszenie właściciela 2026-09-23: „nie widzę, by »Tekst w pasku promo«
   dodawał się do paska”. Stała tu reguła, która chowała pozycję z kodem,
   gdy obok tytułu stał kupon w hero (ta sama informacja dwa razy). Kupon
   w hero mieści się jednak na każdym monitorze szerszym niż ok. 2000 px
   (pomiar: 1920 nie, 2048 tak), a kto raz zamknął popup, dostaje go od razu
   - więc na szerokim ekranie pozycji z pola nie było nigdy, choć panel
   obiecuje ją wprost. (Klasa `et-promo-hero-on`, która to sterowała, zniknęła
   ze skryptu 2026-09-26 - nic jej już nie czytało.) */
/* Kod w pasku promo: jaśniej i grubiej od reszty, ale bez pomarańczu -
   w tym pasku akcentem są tylko kropki (patrz `.promo-item`). */
.promo-item--code { color: var(--color-bone-0); font-weight: 600; }

/* KOD NA STARCIE PĘTLI STOI W POLU WIDZENIA (ekrany do 1439 px).

   Pasek rusza od zera, a kod jest pierwszą pozycją każdej kopii - w chwili
   wczytania stał więc przy lewej krawędzi, pod maską zanikania, i od razu
   z niej wyjeżdżał. Pomiar 2026-09-23 (kopia ok. 1230 px, obieg 30 s): cały
   napis czytelny dopiero po ok. 26 s na telefonie (360-412 px), 19 s przy
   768 px, 8 s przy 1280 px, 4,5 s przy 1440 px. Od ok. 1680 px kod drugiej
   kopii jest czytelny od razu - tam start zostaje bez zmian.

   Ta sama pętla co `promo-scroll` (dokładnie jedna kopia w 30 s), inny jest
   tylko punkt startu: kod DRUGIEJ kopii zaczyna na 30vw. Na telefonie jego
   prawy brzeg wypada tuż przed maską prawej krawędzi, więc przejeżdża cały
   ekran; po lewej stoi koniec pierwszej kopii, więc nic nie jest puste.

   Warunek, żeby pod koniec obiegu nie zabrakło toru przy prawej krawędzi:
   kopia >= 0,56 x szerokość ekranu (przy 1439 px: 806 px). Dzisiejsze
   pozycje z Personalizacji dają ok. 1230 px - brakowałoby dopiero przy
   dwóch-trzech krótkich pozycjach, i to pod maską prawej krawędzi.

   `:has()`: bez aktywnej promocji (albo gdy skrypt zdejmie kod po jej końcu)
   pasek chodzi dokładnie jak dawniej. Przy „mniej ruchu” pasek stoi
   (`animation: none` wyżej) - stąd warunek w zapytaniu. */
@media (max-width: 1439px) and (prefers-reduced-motion: no-preference) {
  .promo-track:has(> .promo-item--code) { animation-name: promo-scroll-lead; }
}
@keyframes promo-scroll-lead {
  from { transform: translateX(calc(-100% / 3 + 30vw)); }
  to   { transform: translateX(calc(-200% / 3 + 30vw)); }
}

/* --- Szablon: karta na dole ekranu ---------------------------------------- */
.et-promo--sheet {
  position: fixed;
  z-index: 90; /* nad paskiem nawigacji (60) i „?" (70), pod banerem zgód (9999) */
  inset: auto 12px 12px 12px;
  width: auto;
  max-width: 420px;
}
@media (max-width: 640px) {
  /* Nad dolnym paskiem nawigacji, a gdy jego miejsce zajmuje „Dodaj do
     koszyka" - nad tym paskiem (zmierzone 2026-09-23: 83 px, więc 83 + 12
     odstępu + 1 na zaokrąglenie). */
  .et-promo--sheet { bottom: calc(var(--et-pasek-dolny, 56px) + env(safe-area-inset-bottom, 0px) + 12px); }
  body:has(.et-builder-sticky.is-visible) .et-promo--sheet { bottom: calc(env(safe-area-inset-bottom, 0px) + 96px); }
}
@media (min-width: 641px) {
  /* Lewy dolny róg - prawy należy do przycisku pomocy „?". */
  .et-promo--sheet { inset: auto auto 24px 24px; width: 380px; }
}
.et-sheet {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0 16px;
  padding: 18px 44px 12px 18px;
  background: #F5F1EA;
  color: #0B0B0B;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .55);
}
.et-sheet__tape {
  position: absolute;
  left: -12px;
  top: -8px;
  width: 64px;
  height: 20px;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .4));
  --tape-rot: -24deg;
}
.et-sheet__percent {
  margin: 0;
  font-family: var(--font-display);
  font-size: 58px;
  line-height: .85;
}
.et-sheet__kicker {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.et-sheet__headline {
  margin: 2px 0 8px;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1;
  letter-spacing: .02em;
  text-transform: uppercase;
}
.et-sheet__code {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  box-sizing: border-box;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0 12px;
  border: 2px dashed #0B0B0B;
  border-radius: 0;
  background: transparent;
  color: #0B0B0B;
  cursor: pointer;
}
.et-sheet__code:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 3px; box-shadow: none; }
.et-sheet__code-text {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 20px;
  letter-spacing: .08em;
  white-space: nowrap;
}
.et-sheet__code .et-coupon__state { font-size: 11px; }
.et-sheet__hint { margin: 6px 0 0; font-size: 12px; line-height: 1.35; }
.et-sheet__links { display: flex; flex-wrap: wrap; gap: 0 16px; margin: 2px 0 0; }
.et-sheet__link {
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: #0B0B0B;
  font-family: var(--font-body);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.et-sheet__link--apply { font-weight: 700; }
.et-sheet__close {
  position: absolute;
  top: 2px;
  right: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: #0B0B0B;
  cursor: pointer;
}
.et-sheet__close:focus-visible,
.et-sheet__link:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; box-shadow: none; }

/* --- Szablon: ogłoszenie bez kodu ----------------------------------------- */
.et-announce {
  position: relative;
  box-sizing: border-box;
  width: min(420px, 100%);
  padding: 40px 28px 20px;
  background: var(--color-ink-1);
  border: 1px solid var(--border-strong);
  color: #F5F1EA;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .6);
}
.et-announce__tape {
  position: absolute;
  top: -15px;
  left: 22px;
  margin: 0;
  transform: rotate(-3deg);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .45));
}
.et-announce__tape-strip {
  display: inline-block;
  padding: 7px 20px;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .06) 0 1px, transparent 1px 3px),
    #F69500;
  color: #0B0B0B;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  clip-path: polygon(0 0, 100% 0, calc(100% - 4px) 12.5%, 100% 25%, calc(100% - 4px) 37.5%, 100% 50%, calc(100% - 4px) 62.5%, 100% 75%, calc(100% - 4px) 87.5%, 100% 100%, 0 100%, 4px 87.5%, 0 75%, 4px 62.5%, 0 50%, 4px 37.5%, 0 25%, 4px 12.5%);
}
.et-announce__headline {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: clamp(38px, 11vw, 52px);
  font-weight: 400;
  line-height: .95;
  letter-spacing: .02em;
  color: #F5F1EA;
}
.et-announce__body { margin: 0 0 22px; color: var(--fg-muted); font-size: 15px; line-height: 1.55; }
.et-announce .et-promo__actions { width: 100%; }

@media print {
  .et-promo,
  .et-promo-hero { display: none !important; }
}

/* --- Szablon 17d: naklejka z logo (2026-09-23, kampania NOWASTRONA) -------

   Znacznik: template-parts/promo/coupon-sticker.php. Wymiary bazowe z projektu
   (szerokość 280 px) mnożone przez `--coupon-scale`, jak w 14a: popup ustawia
   skalę skryptem (1,25 na komputerze, 1,15 na telefonie, mniej na niskich
   ekranach), kupon w hero ma 1.

   Naklejka nie ma własnego tła - leży na ciemnej nakładce albo na hero, stąd
   jasny tekst wiersza pod kodem. Nigdzie po drodze nie ma `overflow: hidden`:
   taśmy wystają poza 280 px. */
.et-sticker {
  --s: var(--coupon-scale, 1);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-sizing: border-box;
  width: calc(280px * var(--s));
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: #0B0B0B;
  font: inherit;
  line-height: 1.2;
  letter-spacing: normal;
  text-align: center;
  text-transform: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.et-sticker:focus-visible {
  outline: 3px solid var(--color-brand-orange);
  outline-offset: 6px;
  box-shadow: none;
}
.et-sticker__art {
  position: relative;
  display: block;
  width: calc(280px * var(--s));
  height: calc(244px * var(--s));
}
/* Znak marki: animowany wrapper bez własnego obrotu (skala 1,3 → 1 rośnie
   wtedy równo), obrót -5° i cień na samym obrazku. */
.et-sticker__mark-wrap {
  position: absolute;
  left: calc(35px * var(--s));
  top: calc(14px * var(--s));
  display: block;
  width: calc(210px * var(--s));
  height: calc(210px * var(--s));
}
/* Ciemne koło pod znakiem: wycięcia w białym krążku pokazują to, co pod
   spodem, a naklejka ma wyglądać tak samo na każdym tle. */
.et-sticker__disc {
  position: absolute;
  left: calc(2px * var(--s));
  top: calc(2px * var(--s));
  width: calc(206px * var(--s));
  height: calc(206px * var(--s));
  border-radius: 50%;
  background: #0B0B0B;
}
.et-sticker__mark {
  position: relative;
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  transform: rotate(-5deg);
  filter: drop-shadow(0 calc(12px * var(--s)) calc(22px * var(--s)) rgba(0, 0, 0, .6));
}
/* Taśma = trzy poziomy: tu obrót i cień (cień na elemencie z `clip-path`
   byłby ucięty), `__peel` tylko się odkleja, `__strip` ma zęby i tło. */
.et-sticker__tape {
  position: absolute;
  z-index: 2;
  display: block;
  filter: drop-shadow(0 calc(4px * var(--s)) calc(8px * var(--s)) rgba(0, 0, 0, .55));
}
.et-sticker__tape--line { left: 0; top: calc(22px * var(--s)); transform: rotate(-18deg); }
.et-sticker__tape--percent { right: calc(-8px * var(--s)); top: calc(156px * var(--s)); transform: rotate(-14deg); }
.et-sticker__peel { display: block; }
/* Postrzępione końce: 8 zębów na krótszym boku, głębokość `--t`. */
.et-sticker__strip {
  --t: 5px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  white-space: nowrap;
  color: #0B0B0B;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .05) 0 calc(1px * var(--s)), transparent calc(1px * var(--s)) calc(3px * var(--s))),
    #F5F1EA;
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--t) * var(--s)) 12.5%, 100% 25%, calc(100% - var(--t) * var(--s)) 37.5%, 100% 50%, calc(100% - var(--t) * var(--s)) 62.5%, 100% 75%, calc(100% - var(--t) * var(--s)) 87.5%, 100% 100%, 0 100%, calc(var(--t) * var(--s)) 87.5%, 0 75%, calc(var(--t) * var(--s)) 62.5%, 0 50%, calc(var(--t) * var(--s)) 37.5%, 0 25%, calc(var(--t) * var(--s)) 12.5%);
}
.et-sticker__tape--line .et-sticker__strip {
  height: calc(40px * var(--s));
  padding: 0 calc(16px * var(--s));
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(16px * var(--s));
  letter-spacing: .08em;
  text-transform: uppercase;
}
.et-sticker__tape--percent .et-sticker__strip {
  --t: 7px;
  height: calc(74px * var(--s));
  padding: calc(4px * var(--s)) calc(22px * var(--s)) 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(80px * var(--s));
  line-height: .9;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .06) 0 calc(1px * var(--s)), transparent calc(1px * var(--s)) calc(3px * var(--s))),
    #F69500;
}
.et-sticker__codebar {
  position: relative;
  display: block;
  margin-top: calc(8px * var(--s));
  transform: rotate(1deg);
  filter: drop-shadow(0 calc(4px * var(--s)) calc(8px * var(--s)) rgba(0, 0, 0, .55));
}
.et-sticker__codebar .et-sticker__strip {
  height: calc(54px * var(--s));
  padding: 0 calc(24px * var(--s));
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(26px * var(--s));
  letter-spacing: .1em;
}
.et-sticker__row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: calc(14px * var(--s));
  margin-top: calc(12px * var(--s));
  white-space: nowrap;
}
.et-sticker__hint {
  font-family: var(--font-body);
  font-size: calc(13px * var(--s));
  line-height: 1.3;
  color: #D6CEC0;
}
/* Stała szerokość etykiety: 84 px mieści „SKOPIOWANO", więc przełączenie
   napisu niczego w wierszu nie przesuwa. */
.et-sticker__state {
  min-width: calc(84px * var(--s));
  text-align: left;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc(12px * var(--s));
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #F69500;
}

/* Wejście 17d: znak rośnie, taśmy odklejają się po kolei (380, 550, 720 ms),
   potem wiersz i przyciski. `backwards` = przed startem element stoi
   w pierwszej klatce (taśma schowana), więc nic nie mignie; po końcu
   animacja znika i zostaje zwykły wygląd, bez resztek `clip-path`. */
@keyframes et-sticker-mark {
  from { opacity: 0; transform: scale(1.3); }
  to   { opacity: 1; transform: none; }
}
@keyframes et-sticker-peel {
  from { clip-path: inset(-40% 100% -40% 0); }
  to   { clip-path: inset(-40% 0 -40% 0); }
}
@keyframes et-sticker-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.et-promo--sticker.is-open .et-sticker__mark-wrap { animation: et-sticker-mark .3s cubic-bezier(0.2, 0.7, 0.2, 1) .1s backwards; }
.et-promo--sticker.is-open .et-sticker__peel { animation: et-sticker-peel .24s cubic-bezier(0.2, 0.7, 0.2, 1) .38s backwards; }
.et-promo--sticker.is-open .et-sticker__tape--percent .et-sticker__peel { animation-delay: .55s; }
.et-promo--sticker.is-open .et-sticker__codebar .et-sticker__peel { animation-delay: .72s; }
.et-promo--sticker.is-open .et-sticker__row { animation: et-promo-fade-in .2s cubic-bezier(0.2, 0.7, 0.2, 1) .95s backwards; }
.et-promo--sticker.is-open .et-promo__actions { animation: et-sticker-rise .22s cubic-bezier(0.2, 0.7, 0.2, 1) 1.05s backwards; }
/* „Ogranicz ruch": tylko przenikanie całości (nakładka i scena, wyżej). */
@media (prefers-reduced-motion: reduce) {
  .et-promo--sticker.is-open .et-sticker__mark-wrap,
  .et-promo--sticker.is-open .et-sticker__peel,
  .et-promo--sticker.is-open .et-sticker__row,
  .et-promo--sticker.is-open .et-promo__actions { animation: none; }
}

/* Miejsce naklejki w marginesie hero; czy się mieści, mierzy skrypt. */
@media (min-width: 1440px) {
  .hero .et-promo-hero--sticker:not([hidden]) { left: 22px; top: 168px; width: 280px; }
}
/* Poniżej 2048 px naklejka o 12% mniejsza i 4 px bliżej krawędzi.
   Pełnej wielkości z taśmami potrzebuje ok. 330 px marginesu, a przy
   najpopularniejszym 1920 px tytuł zaczyna się na 300 px - skrypt ją chował
   i właściciel na swoim monitorze w ogóle jej nie widział („czemu obrazka
   z kodem nie widać", 2026-09-27). Przy 88% zostaje ok. 24 px odstępu
   od tytułu. Od 2048 px bez zmian. */
@media (min-width: 1440px) and (max-width: 2047px) {
  .hero .et-promo-hero--sticker:not([hidden]) { --coupon-scale: .88; left: 18px; width: calc(280px * .88); }
}
/* W trakcie lotu z popupu (skrypt, 480 ms) bez zwykłego przenikania. */
.hero .et-promo-hero.is-landing { animation: none; }


/* =========================================================================
   DOSTĘPNOŚĆ - audyt testowy 2026-09-27 (D16, D18)
   ========================================================================= */

/* Linki w treści różniły się od tekstu wyłącznie kolorem (WCAG 1.4.1):
   regulamin i polityka w zgodach kasy, okruszki, linki w tekście stron.
   Tylko linki bez klasy w akapitach i tabelach treści - przyciski,
   kafelki i nawigacja konta zostają bez podkreślenia. */
.entry-content p a:not([class]),
.entry-content td a:not([class]),
.wc-block-checkout__terms a,
.wc-block-components-checkbox__label a,
.woocommerce-privacy-policy-text a,
.breadcrumb a,
.woocommerce .woocommerce-breadcrumb a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}

/* Orlen Paczka (Apaczka): po wyborze punktu przycisk mówi „Zmień punkt
   dostawy” - tekst z `data-et-zmien` (egotape.js), bo swój tekst przycisku
   trzyma React wtyczki. */
#apaczka_mp_geowidget_show_map[data-et-zmien] { font-size: 0; }
#apaczka_mp_geowidget_show_map[data-et-zmien]::after {
  content: attr(data-et-zmien);
  font-size: 1rem;
}
#apaczka_mp_geowidget_show_map:focus-visible,
#apaczka_mp_geowidget_modal_cross:focus-visible {
  outline: 2px solid var(--color-brand-orange);
  outline-offset: 2px;
}
/* Krzyżyk mapy: był mały i blady (19 px, szary na szarym). `body` z przodu,
   bo arkusz wtyczki ładuje się PO motywie z tym samym selektorem. */
body #apaczka_mp_geowidget_modal_cross {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  line-height: 1;
  color: #111;
  background: #fff;
  border: 2px solid #111;
  /* Ponad warstwami mapy: Leaflet w tym samym kontekście ma z-index
     400-1000 i zasłaniał górną połowę krzyżyka. */
  z-index: 2000;
}
/* Małe telefony (iPhone SE): mapa na cały ekran zamiast ramki 90%x80%
   z 5% marginesu - tyle zostawało, że mapy prawie nie było widać. */
@media (max-width: 420px) {
  body .apaczka_mp_geowidget_modal .apaczka_mp_geowidget_modal_inner {
    width: 100%;
    height: 100%;
    margin-top: 0;
    padding: 12px;
    border-radius: 0;
  }
  body #apaczka_mp_geowidget_modal_cross { top: 8px; right: 8px; }
}


/* InPost Pay przed zgodą (audyt D6): w miejscu przycisku zastępczy przycisk
   „Pokaż przycisk InPost Pay”. Znika, gdy skrypty InPost się wczytają. */
.et-izi-fasada {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  min-height: 48px;
  padding: 10px 16px;
  border: 1px solid var(--border-strong, #3A3A3A);
  border-radius: var(--radius, 8px);
  background: var(--bg-surface, #171717);
  color: var(--fg-default, #F5F1EA);
  font: inherit;
  cursor: pointer;
}
.et-izi-fasada:hover { border-color: var(--color-brand-orange); }
.et-izi-fasada:focus-visible { outline: 2px solid var(--color-brand-orange); outline-offset: 2px; }
.et-izi-fasada[disabled] { cursor: progress; opacity: .8; }
.et-izi-fasada__nazwa { font-weight: 600; }
.et-izi-fasada__opis { font-size: .8rem; color: var(--fg-muted, #B8AE9E); }
.et-izi-wczytany .et-izi-fasada { display: none; }
