/* ==========================================================================
   Cennik /oferta. HTML generowany przez cennik.py z copy/oferta.md.
   Nie ma odpowiednika w bibliotece komponentow (wiki/komponenty/index.md
   nie ma cennika/tabeli cen), zbudowany od zera na tokenach.

   D37, 29.08.2026: uklad PASMOWY 1:1 z makieta Karola, nie plaska kolumna
   na kategorie. Kategoria z podgrupami (twarz) to kilka pasm, po jednym na
   podgrupe, naprzemiennie jasne/ciemne, kazde ze zdjeciem po prawej.
   Kategorie bez podgrup (cialo, usta, zmiany-skorne) to jedno pasmo z
   uslugami w siatce 2 kolumny. Zdjecie domyslnie po prawej: uproszczenie
   wobec makiety, ktora miesza strony miedzy pasmami, koszt odwzorowania
   tego 1:1 (strona zdjecia per pasmo) nieproporcjonalny do efektu.

   D115, 03.09.2026: wyjatek od powyzszego uproszczenia, zrobiony punktowo
   po zgloszeniu Jakuba. Wstep kategorii "twarz" (eyebrow+H2+lead) dostal
   WLASNE pasmo (osobne od pierwszej podgrupy, wczesniej sklejone razem),
   a pierwsza podgrupa dostala zdjecie PO LEWEJ plus pionowa kreske przy
   liscie, 1:1 z makieta (raw/.../Oferta/02-twarz-oczyszczanie...). Modyfikator
   `.cennik-pasmo__grid--lewo` odwraca kolumny i strone bleedu, generowany
   przez cennik.py (parametr `strona` w html_pasmo()), nie recznie w HTML.

   D122, 03.09.2026: ten sam wstep (eyebrow+H2+lead+zdjecie, klasa
   `.cennik-pasmo--wstep`) dobudowany do cialo/usta/zmiany-skorne, zgloszenie
   Jakuba "ten sam pasek co na makiecie, a ponizej sa juz wymienione ceny".
   Kazda z tych trzech kategorii ma tylko JEDNO zdjecie w `ZDJECIA` (cennik.py),
   ktore teraz idzie do wstepu, wiec sekcja z cenami PONIZEJ nie ma juz wlasnej
   kolumny zdjecia: `.cennik-pasmo--pelny` (nizej w tym pliku), kontener na
   pelnej szerokosci, bez gridu tresc/zdjecie. Zastepuje wczesniejszy uklad,
   w ktorym #cialo mialo osobna restrukturyzacje CSS na grid-areas (audyt
   31.08.2026, usunieta razem z tym ruchem, patrz historia w decyzje.md D122).

   D125, 03.09.2026: wstep PRZEBUDOWANY W CALOSCI, D122 nieaktualne. Jakub,
   po zobaczeniu D122 na zywo: "dużo wolnej przestrzeni po lewej... nie
   chodzi o zachowanie tego samego układu, tylko przebudować w pełni, żeby
   była spójna, ale wyglądała dobrze... zupełnie inna forma." Wstep nie jest
   juz `.cennik-pasmo` z klasa `.cennik-pasmo--wstep` (D122) tylko osobna
   rodzina `.cennik-wstep`, generowana przez `html_wstep()` w cennik.py.
   Trzy warianty strukturalne (D baner, E naklada, F sam tekst) stanely obok
   siebie na przelaczniku, Jakub wybral **D globalnie**, na wszystkie cztery
   kategorie naraz ("idziemy w D globalnie"). E, F i mechanizm przelacznika
   usuniete z kodu w calosci. Historia wyzej (D37/D115/D122) zostaje jako
   zapis jak dotarlismy do tego punktu, ale opisany tam uklad
   (`.cennik-pasmo__grid` dla wstepu, klasa `.cennik-pasmo--wstep`) juz nie
   istnieje w kodzie.

   D33, 28.08.2026: przycisk "Rezerwuj" stoi w KAZDYM wierszu wariantu,
   podniesiony do progu dotyku 44px (D4). ID Booksy jest per usluga, nie
   per wariant, wiec wszystkie wiersze jednej uslugi prowadza pod ten sam
   adres, swiadomie przyjety koszt. Potwierdzone zgodne z makieta 29.08.
   ========================================================================== */

.cennik-pasmo {
  position: relative;
/* D168, 03.09.2026: wartosc ustawiona przez Jakuba w konfiguratorze i
   przeniesiona TUTAJ, do pliku wlasciciela, na jego polecenie ("idzie do
   plikow sekcji bo to sa poprawki sekcji"). Konfigurator.css skasowany,
   zeby ten sam odstep nie zyl w dwoch miejscach naraz. */
  padding-block: var(--space-6);
  scroll-margin-top: var(--space-12);
}

.cennik-pasmo__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 42%);
  gap: var(--space-9);
  align-items: start;
}

/* D114, 03.09.2026: proba bleedu zdjec cennika do krawedzi okna (zgodnie
   z makieta Karola), COFNIETA w D118. Zdjecie ze `position:sticky` (D117)
   plus ujemny margines dawaly u Jakuba realny scroll poziomy strony,
   niereprodukowalny w tym srodowisku (Playwright/Chromium czysty na
   1024-2560px), najpewniej rozjazd silnika w kombinacji sticky+ujemny
   margines. Jakub zaproponowal prosciej: "zdjecie zaokraglone... zeby nie
   bawic sie w pelna szerokosc". Zdjecie zostaje wewnatrz `.container`,
   zaokraglone, bez bleedu. */
/* D162, 03.09.2026: --radius-md -> ksztalt liscia, zgloszenie Jakuba "te
   zdjecia w ofercie przy obszarach mialy byc zrobione w ksztalcie liscia, tak
   samo jak na home". Wariant liscia idzie za strona, po ktorej stoi zdjecie:
   ostry czubek wskazuje kolumne z tekstem, tak jak w pasmach oferty na home.
   Domyslnie zdjecie jest w drugiej kolumnie (po prawej), wiec --lisc-odbity. */
.cennik-pasmo__zdjecie {
  border-radius: var(--lisc-odbity);
  overflow: hidden;
  aspect-ratio: 4 / 5;
}
.cennik-pasmo__zdjecie img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* D139, 03.09.2026: `.cennik-pasmo--pelny` (pasmo bez zdjecia dla cialo/usta/
   zmiany-skorne, D122) nie istnieje juz w cennik.py. Zgloszenie Jakuba:
   "ta struktura się psuje... musimy ją zrobić taką, jak jest wyżej [Twarz]".
   Cennik tych trzech kategorii dostaje ten sam uklad grid/42% ze zdjeciem
   co podgrupy Twarzy, patrz historia D115/D122 wyzej w tym pliku. */

/* D115: wariant "zdjecie po lewej". Kolumny odwrocone (zdjecie 42% pierwsze,
   tresc 1fr drugie, zgodnie z kolejnoscia w DOM ktora generuje cennik.py). */
.cennik-pasmo__grid--lewo {
  grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
}
/* D162: zdjecie po lewej, wiec czubek liscia obraca sie na prawo, w strone tekstu. */
.cennik-pasmo__grid--lewo .cennik-pasmo__zdjecie { border-radius: var(--lisc); }

/* D115: pionowa kreska ("lista wszystkich zabiegow z kreska po stronie
   zdjecia, pelna do konca"), 1:1 z makieta. border-inline siega calej
   wysokosci bloku tresci, wiec "pelna do konca" jest darmowe, nie trzeba
   liczyc wysokosci recznie.
   D141, 03.09.2026: do D139 kreska stala wylacznie na pierwszej podgrupie
   Twarzy (jedynej "lewo" w tamtym momencie), zawsze border-inline-start.
   Zgloszenie Jakuba: kreska ma byc na KAZDYM pasmie, zawsze PO STRONIE
   ZDJECIA, nie tylko po lewej. Domyslnie (strona=prawo, tresc pierwsza w
   DOM, zdjecie drugie) linia siedzi na inline-end tresci, bo tam wlasnie
   zaczyna sie zdjecie. Modyfikator `--lewo` (ten sam, ktory odwraca kolumny
   gridu) odwraca kreske na inline-start. */
.cennik-pasmo__tresc--kreska {
  border-inline-end: var(--border-width) solid var(--line-ctx-soft);
  padding-inline-end: var(--space-6);
}
.cennik-pasmo__grid--lewo .cennik-pasmo__tresc--kreska {
  border-inline-end: 0;
  padding-inline-end: 0;
  border-inline-start: var(--border-width) solid var(--line-ctx-soft);
  padding-inline-start: var(--space-6);
}

/* D117, 03.09.2026: zdjecie zostaje w miejscu przy scrollu, przewija sie
   tylko tresc obok. Zgloszenie Jakuba, wprost "tylko na komputerze".
   Mechanizm: .cennik-pasmo__grid ma juz align-items:start (linia wyzej w
   pliku), wiec zdjecie NIE rozciaga sie do wysokosci tresci, kolumna
   zdjecia zostaje wlasnej wysokosci (aspect-ratio 4/5), a caly wiersz
   gridu jest tak wysoki jak dluzsza tresc. To jest dokladnie warunek
   potrzebny position:sticky: element sticky "odklei sie" dopiero gdy
   dojdzie do dolu WLASNEGO wiersza gridu, czyli razem z koncem tresci,
   a do tego momentu zostaje przypiety do --header-rest-h + oddech, pod
   naglowkiem (z-index nizszy niz --z-header, zeby kapsula zawsze wygrywala
   przy zakladce). Prog 901px, ten sam co reszta ukladu pasmowego (ponizej
   tego progu grid schodzi do jednej kolumny, sticky by nie mial sensu).

   D122: wylaczenie dla #cialo usuniete. Do tej daty #cialo trzymalo zdjecie
   w mniejszym, wlasnym boksie obok tytulu (osobna restrukturyzacja CSS),
   gdzie sticky nie mialby efektu. Ten uklad zniknal razem z restrukturyzacja:
   #cialo ma dzis ten sam wstep pelnowysokosciowy co reszta kategorii, wiec
   sticky dziala tak samo wszedzie. */
@media (min-width: 901px) {
  .cennik-pasmo__zdjecie {
    position: sticky;
    top: calc(var(--header-rest-h, 0px) + var(--space-3));
    z-index: var(--z-sticky);
  }
}

/* ==========================================================================
   D125, 03.09.2026: pasek tytulowy kategorii. Baner: zdjecie umiarkowanej
   wysokosci (nie wysoki portret jak w D37/D115/D122), tresc wysrodkowana w
   pionie wzgledem niego, wiec nie zostaje pusta przestrzen pod krotkim
   tekstem. Wybrany przez Jakuba sposrod trzech wariantow strukturalnych na
   przelaczniku (D/E/F), globalnie na wszystkie cztery kategorie.
   ========================================================================== */
/* D129, 03.09.2026: padding-block zmieniony z var(--space-8) (48px, stale) na
   var(--space-section) (rytm kazdej innej sekcji na stronie, plynny
   clamp). Zgloszenie Jakuba na mobile: "odstepy gora-dol, zeby byly
   spojne". Diagnoza: `.cennik-wstep` nie ma klasy `.section`, wiec nie
   dziedziczyl globalnego rytmu jak `.cennik-pasmo` (ktory ma "section
   cennik-pasmo"), zostal na sztywnym --space-8 z pierwszej wersji D125.
   Skutek zmierzony na 390px: odstep wstep→pierwsza podgrupa byl 48+72=120px,
   odstep miedzy kolejnymi podgrupami 72+72=144px, czyli dwa rozne rytmy w
   jednym ciagu sekcji. Po zmianie oba 144px, spojne w calej kategorii. */
/* D168, 03.09.2026: wartosc ustawiona przez Jakuba w konfiguratorze i
   przeniesiona TUTAJ, do pliku wlasciciela, na jego polecenie ("idzie do
   plikow sekcji bo to sa poprawki sekcji"). Konfigurator.css skasowany,
   zeby ten sam odstep nie zyl w dwoch miejscach naraz. */
.cennik-wstep { padding-block: var(--space-8) var(--space-7); scroll-margin-top: var(--space-12); }
/* D165, 03.09.2026: kolumna zdjecia 42% -> 36%. Naglowek kategorii lamal sie
   na trzy wiersze zamiast dwoch z copy: najdluzszy ("Zabiegi na twarz, szyje
   i dekolt") potrzebuje 744px przy 1440, a kolumna tekstu dawala 704px, wiec
   pierwszy segment sam sie lamal, zanim doszlo do zamierzonego <br> przed
   "Ostrów Mazowiecka". Zmiana liczona z najdluzszego naglowka na pieciu
   szerokosciach, nie z jednej. */
.cennik-wstep__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 36%);
  gap: var(--space-8);
  align-items: center;
}
/* D162, 03.09.2026: ksztalt liscia zamiast zaokraglonego prostokata, patrz
   nota przy .cennik-pasmo__zdjecie. Zdjecie wstepu stoi zawsze w drugiej
   kolumnie, po prawej, wiec zawsze --lisc-odbity. */
.cennik-wstep__zdjecie {
  border-radius: var(--lisc-odbity);
  overflow: hidden;
  aspect-ratio: 3 / 2;
}
.cennik-wstep__zdjecie img { inline-size: 100%; block-size: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .cennik-wstep__grid { grid-template-columns: 1fr; }
  /* D166, 03.09.2026: na telefonie ksztalt liscia (D162) schodzi, zostaje
     zaokraglony prostokat, decyzja Jakuba. Ta sama zasada co przy zdjeciu
     "o mnie" na home (D93/D148): lisc jest ksztaltem dla ukladu dwukolumnowego,
     na pelnej szerokosci telefonu czyta sie jako uciety kadr, nie jako ksztalt. */
  .cennik-wstep__zdjecie { aspect-ratio: 16 / 10; border-radius: var(--radius-md); }
  /* D135, 03.09.2026: zgloszenie Jakuba ze zrzutu, "rozjazdy miedzy
     elementami" - odstep zdjecie->naglowek podgrupy (144px, D129: oba po
     72px z --space-section) rzucal sie w oczy obok znacznie ciasniejszego
     rytmu naglowek/podtytul/wiersze ponizej (D132-134). --space-8 (48px)
     zamiast --space-section na OBU stronach granicy (wstep i pasmo,
     symetrycznie, ten sam token na obu, zasada z D129 zostaje: gora=dol),
     tylko na mobile. Odstep spada z 144px na 96px, reszta rytmu (miedzy
     kolejnymi podgrupami Twarzy, w tym Lifting/Zabiegi iglowe) bez zmian,
     bo tam miedzy sekcjami stoi pelna lista cen, nie pusta przestrzen. */
  /* D168: mobilny override zdjety. Baza ma teraz te sama wartosc na kazdej
     szerokosci, zgodnie z ustawieniem z konfiguratora. */
}

/* 01.09.2026 (D50): font-size na --fs-display-3, razem z H1 hero (byl
   dziedziczony z domyslnego h2, czyli --fs-display-2, 84px). Hero schodzi
   na display-3 (67px), wiec H2 kategorii cennika schodza razem z nim,
   inaczej hierarchia nagłowkow byłaby odwrocona (H2 wiekszy niz H1). */
/* D165: `max-width: 20ch` zdjety. Przycinal naglowek do 683px, czyli ponizej
   744px, ktorych potrzebuje najdluzszy z czterech. Szerokosc trzyma teraz sama
   kolumna gridu, jedno ograniczenie zamiast dwoch. */
/* 14.09.2026, zgloszenie Jakuba na zywo: "wielkosc czcionek... w porownaniu
   do CTA albo nawigacji w headerze wydaja sie duze", potem doprecyzowane
   "H1 hero jest taki sam jak H2 w ofercie". Zmierzone: --fs-display-3 dawal
   H1 i H2 kategorii IDENTYCZNY rozmiar co do piksela (66.672px na 1440px),
   3-4x wiekszy niz CTA headera (16px) i nawigacja (20px). Zalozenie D50
   ("H2 rowny hero") mialo sens, dopoki H2 bylo krotka etykieta ("Usta",
   "Modelowanie sylwetki"). Od 13-14.09 H2 to pelne zdanie z korzyscia
   ("Zabiegi oczyszczaja i ujedrniaja skore..."), wiec ten sam rozmiar
   renderuje cale zdanie jako drugie hero na stronie, nie podsekcje pod nim.
   Nowy token schodzi PONIZEJ H1 (67px) i ZOSTAJE POWYZEJ H3 podgrupy
   (--fs-display-4, 49px na 1440px), zeby hierarchia H1>H2>H3 sie nie
   odwrocila. Lokalny, nie globalny --fs-*, bo to jedyne miejsce w projekcie,
   gdzie naglowek tego poziomu musi uniesc pelne zdanie zamiast etykiety. */
.cennik__tytul { font-size: clamp(32px, 4vw, 58px); margin: 0 0 var(--space-6); }

/* Plaski, wysrodkowany blok jak w makiecie (08B), nie kartka z lewym
   akcentem. Kolory na sztywno, NIE z kontekstu .on-dark/.on-light: kategoria
   "zmiany skorne" moze wypasc na ciemnym tle w alternacji, a --surface-sand
   jest stalym jasnym hexem niezaleznym od kontekstu, wiec kremowy tekst na
   ciemnym kontekscie na kremowym pasku byl nieczytelny (znalezione 28.08). */
/* D157, 03.09.2026: zgloszenie Jakuba na zywo (desktop), "ten box mielismy
   wywalic". D148 chowala to pudelko wylacznie na mobile, zalozenie ze na
   desktopie ma prawo do wlasnego miejsca bylo moje, nie jego. Wywalone
   wszedzie, tekst zostaje w copy/oferta.md (kanon copy nietykalne), to
   decyzja PREZENTACJI, nie tresci. */
.cennik__zastrzezenie {
  display: none;
  margin: 0 0 var(--space-7);
  padding: var(--space-5) var(--space-6);
  background: var(--surface-cream-hi);
  color: var(--text-on-light);
  text-align: center;
  font-size: var(--fs-small);
  line-height: 1.6;
}

.cennik__intro { max-width: 62ch; margin: 0 0 var(--space-8); color: var(--fg-muted); line-height: 1.6; }

/* D132, 03.09.2026: hierarchia obu naglowkow cennika podniesiona do poziomu
   z makiety, zgloszenie Jakuba ze zrzutu: "wieksza, innym kolorem, tym
   brazowym" dla podgrupy, i to samo wyroznienie dla tytulu uslugi ponizej.
   Przed ta zmiana oba naglowki byly niemal tej samej wielkosci (--fs-card
   19-24px vs --fs-body-lg 17-21px), za blisko siebie i za blisko zwyklego
   tekstu, zeby czytac sie jako hierarchia. Podgrupa dostaje --fs-display-4
   (istniejacy token "naglowek pomocniczy", nie nowa wartosc) i --accent-deep
   (ten sam braz co eyebrow/nadtytuly w calym projekcie). Tytul uslugi
   zostaje wizualnie NIZEJ podgrupy (mniejszy, bez koloru), ale wyrazniej
   nad zwyklym tekstem niz przedtem: --fs-card zamiast --fs-body-lg. */
.cennik__podgrupa {
  margin: 0 0 var(--space-5);
  font-family: var(--font-display);
  font-size: var(--fs-display-4);
  color: var(--accent-deep);
}
/* D136, 03.09.2026: zgloszenie Jakuba ze zrzutu "Lifting i ujedrnianie"
   (podgrupa na tle .on-dark): braz --accent-deep (dobry na jasnym) ginie
   na ciemnym tle, maly kontrast. Na ciemnym: kremowa biel zamiast brazu.
   "Pogrubiony" NIE jest doslownym font-weight: Bellefair ma jedna wage
   (400), font-weight:600+ daje fake bold przegladarki, ten sam problem co
   .cennik__usluga-tytul opisuje w komentarzu nizej (audyt 31.08.2026).
   Wyroznienie przez letter-spacing (--ls-caps), tym samym mechanizmem co
   tam, nie przez zlamanie fonta. */
.on-dark .cennik__podgrupa {
  color: var(--text-on-dark);
  letter-spacing: var(--ls-caps);
}

.cennik__usluga { margin-block-end: var(--space-7); }
/* D150, 03.09.2026: zgloszenie Jakuba, odstep koniec cennika->konsultacja
   dalej za duzy mimo D149 (zero na .cennik-pasmo, padding-block-end).
   Przyczyna: `.cennik__usluga` to grid item (`.cennik-pasmo__tresc` jest
   dzieckiem `.cennik-pasmo__grid`, display:grid), margines dziecka w gridzie
   NIGDY sie nie zwija (CSS Grid nie kolapsuje marginesow w ogole, w
   przeciwienstwie do zwyklego block flow), wiec margin-block-end OSTATNIEGO
   `.cennik__usluga` w kazdym pasmie/wstepie renderowal sie w pelni, dodajac
   40px POZA zerowanym paddingiem sekcji. Zero na ostatnim dziecku usuwa ta
   ukryta warstwe, tak samo w kazdym miejscu gdzie usluga jest ostatnia
   trescia przed koncem pasma/wstepu. */
.cennik-pasmo__tresc > .cennik__usluga:last-child,
.cennik-wstep__cennik > .cennik__usluga:last-child {
  margin-block-end: 0;
}
/* Audyt 31.08.2026: font-weight:var(--fw-semibold) na Bellefair (jedna waga,
   400) dawal fake bold przegladarki, litery grubsze i znieksztalcone wobec
   .cennik__podgrupa obok. Bellefair nigdy nie jest pogrubiana (tokens.css
   linia 143). Wyroznienie przeniesione na letter-spacing, jak w podgrupie. */
.cennik__usluga-tytul { margin: 0 0 var(--space-2); font-size: var(--fs-card); font-weight: var(--fw-display); letter-spacing: var(--ls-caps); }
.cennik__opis { margin: 0 0 var(--space-3); max-width: 62ch; color: var(--fg-muted); line-height: 1.6; }

/* Przycisk Szczegoly, 13.09.2026 (popup z przebiegiem i zaleceniami po
   zabiegu, opis w cenniku zostaje krotki, R10/R11 w rzemioslo-copy.md).
   Ghost, bez tla i ramki (tokens.css :591-592), zeby nie konkurowal z
   przyciskiem Rezerwuj w tym samym wierszu usluglugi. Strzalka to ten sam
   .btn__arrow co front-page.php:176 (jedyne inne uzycie w motywie). */
.cennik__szczegoly {
  margin: 0 0 var(--space-4);
  padding-inline: 0;
  display: inline-flex;
}

/* --- popup Szczegoly -------------------------------------------------- */

.cennik-dialog {
  /* Popup jest zawsze jasny, niezaleznie od tego, czy stoi w DOM wewnatrz
     sekcji .on-dark (np. kategoria "Modelowanie sylwetki"). <dialog>
     otwarty przez showModal() renderuje sie w top layer, ale w drzewie DOM
     zostaje na miejscu, wiec zmienne kontekstu (--fg-muted, --focus-ctx)
     nadal spadaja z .on-dark rodzica i nadpisuja te tutaj. Bez tego resetu
     .cennik-dialog__tresc p i .cennik-dialog__zamknij dziedziczyly jasny
     tekst na jasnym tle popupu, prawie niewidoczny (znalezione 14.09.2026,
     Jakub na zywo, kategoria Karboksyterapia). */
  --fg: var(--text-on-light);
  --fg-muted: var(--text-on-light-muted);
  --focus-ctx: var(--focus-on-light);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  max-inline-size: 560px;
  inline-size: min(560px, calc(100vw - var(--space-8)));
  max-block-size: min(80vh, 640px);
  background: var(--surface-cream-hi);
  color: var(--text-on-light);
  box-shadow: var(--shadow-kapsula);
}
/* :not([open]) zamiast [hidden]: <dialog> zamkniety przez showModal()/close()
   dostaje display:none z przegladarki automatycznie, ta regula jest tu na
   wypadek stanu przejsciowego, ten sam wzorzec ostroznosci co .menu-mobilne
   w header.css. */
.cennik-dialog:not([open]) { display: none; }
.cennik-dialog::backdrop {
  background: color-mix(in srgb, var(--surface-dark) 50%, transparent);
}

.cennik-dialog__tresc {
  padding: var(--space-8);
  overflow-y: auto;
  max-block-size: min(80vh, 640px);
}
.cennik-dialog__tytul {
  margin: 0 0 var(--space-5);
  font-size: var(--fs-card);
  font-weight: var(--fw-display);
}
.cennik-dialog__tresc p { margin: 0 0 var(--space-4); line-height: 1.6; color: var(--fg-muted); }
.cennik-dialog__tresc p:last-child { margin-block-end: 0; }
.cennik-dialog__tresc p strong { color: var(--fg); font-weight: var(--fw-semibold); }

.cennik-dialog__zamknij {
  position: absolute;
  inset-block-start: var(--space-5);
  inset-inline-end: var(--space-5);
  inline-size: 32px;
  block-size: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--fg-muted);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.cennik-dialog__zamknij:hover { background: var(--surface-sand); color: var(--fg); }
.cennik-dialog__zamknij:focus-visible {
  outline: var(--focus-width) solid var(--focus-ctx, var(--accent));
  outline-offset: var(--focus-offset);
}
.cennik-dialog__zamknij svg { inline-size: 16px; block-size: 16px; }

/* 14.09.2026: wariant "arkusz od dolu, pelna szerokosc" ponizej 700px
   COFNIETY na wyrazna prosbe Jakuba ("daj na srodek i zmniejsz szerokosc
   prawo lewo, zeby to byl taki box na srodku"). Mial krotkie zycie (13-14.09):
   najpierw prawidlowy `inset-block-end` mial bug (przyklejal sie do gory,
   naprawiony wyzej tego samego dnia), a zaraz po naprawie Jakub i tak
   zdecydowal, ze woli wersje wyśrodkowana. Popup ponizej 700px dziedziczy
   teraz DOKLADNIE te sama regule `.cennik-dialog` co desktop: wyśrodkowany
   przez domyslne centrowanie <dialog>, szerokosc `min(560px, 100vw - 48px)`
   daje 24px marginesu z kazdej strony na waskim ekranie, zaokraglenie na
   wszystkich czterech rogach (zero osobnych regol dla mobile). Historia
   obu wersji (arkusz i jego bug) zostaje w wiki/log.md, 14.09.2026, na
   wypadek gdyby ktos wrocil do tego pomyslu. */

@media (prefers-reduced-motion: reduce) {
  .cennik-dialog { transition: none; }
}

.cennik__lista { list-style: none; margin: 0; padding: 0; border-block-start: var(--border-width) solid var(--line-ctx-soft); }

.cennik__wiersz {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-3);
  border-block-end: var(--border-width) solid var(--line-ctx-soft);
}

/* D172, 03.09.2026: `overflow-wrap` dolozone po audycie. Kolumna wariantu jest
   `minmax(0, 1fr)` obok dwoch sztywnych (54 i 108 px, D149), wiec przy 375 px
   okna zostaje jej 109 px. Najdluzsze slowo cennika ("przebarwieniami") jest
   od tego szersze i bez tej reguly wystawalo poza wiersz o 8 px. `break-word`,
   nie `anywhere`: lamie wylacznie slowo, ktore samo nie miesci sie w kolumnie,
   reszta zawija sie normalnie po spacjach. */
.cennik__wariant { font-size: var(--fs-body); overflow-wrap: break-word; }
.cennik__czas { font-size: var(--fs-small); color: var(--fg-muted); white-space: nowrap; }
.cennik__cena { font-size: var(--fs-body); font-weight: var(--fw-semibold); white-space: nowrap; text-align: end; min-width: 9ch; }

/* Przycisk podniesiony do progu dotyku 44px (D33/D4). Rozmiar --btn-h-sm
   (42px, tokens.css) nie wystarcza, wiec wiersz cennika ma wlasny minimalny
   wymiar zamiast kolejnego stopnia w globalnej skali przyciskow. */
.cennik__rezerwuj {
  min-height: 44px;
  padding-inline: var(--space-5);
  white-space: nowrap;
}
/* D140, 03.09.2026: `.cennik__cta`/`.cennik__podpis` (pasek "Umów bezpłatną
   konsultację" miedzy kategoriami) usuniete z HTML w calosci (cennik.py nie
   generuje juz tej sekcji), regula tu razem z nim. Zgloszenie Jakuba
   "wywalamy w ogole ten pasek", zgodne z ustalona wczesniej zasada zero CTA
   miedzy kategoriami (D116/D138, jedyne CTA na koncu strony). */

/* D140: cennik dolaczony wprost do wstepu ("usta" ma tylko 2 uslugi, osobne
   pasmo bylo za rozbudowane). Odstep od zdania wprowadzajacego, ten sam
   token co reszta pionowego rytmu wewnatrz karty uslugi. */
.cennik-wstep__cennik { margin-block-start: var(--space-7); }

/* D143, 03.09.2026: kreska (D115/D141) tez na "usta", zgloszenie Jakuba
   "do ust tez dodaj kreskę". Zdjecie wstepu jest zawsze PO PRAWEJ (zero
   wariantu --lewo w tym komponencie), wiec jeden kierunek wystarcza:
   border-inline-end dotyka zdjecia, tak jak `.cennik-pasmo__tresc--kreska`
   w domyslnym (prawo) wariancie. */
.cennik-wstep__tresc--kreska {
  border-inline-end: var(--border-width) solid var(--line-ctx-soft);
  padding-inline-end: var(--space-6);
}

@media (max-width: 900px) {
  /* D143: kreska schodzi na mobile, ten sam powod co D128 na .cennik-pasmo
     (makieta mobile jej nie ma, sekcja przechodzi na 1 kolumne). */
  .cennik-wstep__tresc--kreska {
    border-inline-end: 0;
    padding-inline-end: 0;
  }
}

/* ==========================================================================
   D157, 03.09.2026: zgloszenie Jakuba na zywo, DESKTOP ("odstęp między
   Twarzą a sylwetką... teraz dużo przestrzeni to zajmuje", "obszar Ciało...
   strasznie wielkie odstępy", "Zmiany skórne... ogromne odstępy między
   sekcją tytułową a cennikiem"). D148-D151 rozwiazaly dokladnie ten sam
   mechanizm (dwa paddingi po tej samej wartosci na granicy bez szwu koloru
   czytaja sie jako jeden, podwojony odstep) ale WYLACZNIE na mobile (ponizej
   900px). Na desktopie oba paddingi licza sie z `--space-section` (clamp do
   120px), wiec podwojenie jest tam nawet wieksze niz na mobile bylo. Cztery
   reguly ponizej to te same z D148-D151, przeniesione z bloku @media na
   caly zakres szerokosci: dotycza teraz kazdej granicy, nie tylko mobile.
   ========================================================================== */
/* D168: zero u gory pasma bez zdjecia (D148) WYCOFANE. Sterowanie grupowe
   w konfiguratorze splaszczylo ten wyjatek do wspolnych 32px i Jakub przyjal
   ten stan. Gdyby odstep nad pierwsza podgrupa znowu wygladal za duzo, to
   jest miejsce do przywrocenia (pulapka 37). */
.cennik__intro:has(+ .cennik__zastrzezenie) { margin-block-end: 0; }
/* D168: zero na granicy zmiany-skorne do CTA (D149) WYCOFANE, ten sam powod
   co wyzej. */
/* D168: zero na granicy Twarz do Cialo (D150) WYCOFANE, ten sam powod. */
/* D157, dopisek: samo zerowanie jednej strony nie wystarczylo na desktopie,
   bo druga strona (.cennik-wstep, padding-block-end domyslnie
   --space-section, clamp do 120px) zostawala nieruszona i dalej dawala
   odstep az do 120px, wiekszy niz referencyjny gap gora (48px, staly
   --space-8 gap w .cennik-wstep__grid). Kazdy wstep (#twarz/#cialo/
   #zmiany-skorne) ma po ID skrocony wlasny dol do tego samego tokenu,
   razem z zerowaniem wyzej daje dokladnie 48px, rowne gorze. #cialo
   dodatkowo ma skrocona GORE (Twarz->Ciało, ten sam mechanizm co
   #zmiany-skorne+.cennik-pasmo wyzej, ale na wstepie po ID zamiast na
   poprzednim pasmie przez :has()). */
/* D168: wlasny dol wstepow po ID (D157) WYCOFANY. Baza daje teraz 40px na
   kazdej szerokosci, wiec regula po ID tylko by ja cicho przebijala. */
/* D168: wlasna gora #cialo (D157) WYCOFANA, baza daje te sama wartosc. */

@media (max-width: 900px) {
  .cennik-pasmo__grid { grid-template-columns: 1fr; }
  /* D166: to samo co przy zdjeciu wstepu wyzej. Selektor musi powtorzyc
     modyfikator `--lewo`, inaczej regula wariantu (0,0,2,0) wygrywa waga z ta
     (0,0,1,0) mimo pozniejszego polozenia w pliku, PRZEKAZANIE.md pulapka 28. */
  .cennik-pasmo__zdjecie,
  .cennik-pasmo__grid--lewo .cennik-pasmo__zdjecie { border-radius: var(--radius-md); }
  .cennik-pasmo__zdjecie { aspect-ratio: 16 / 10; order: -1; }
  /* D135, ten sam token co .cennik-wstep wyzej w tym pliku (48px zamiast
     72px), zeby gora i dol granicy wstep<->pasmo zostaly rowne (zasada
     z D129). Skutek uboczny, przyjety swiadomie: rytm miedzy WSZYSTKIMI
     pasmami cennika na mobile (Oczyszczanie<->Lifting<->Zabiegi iglowe,
     wstep<->pelny na Ciele/Ustach/Zmianach skornych) tez sie sciesnia,
     bo `.cennik-pasmo` jest jedna, wspoldzielona klasa. Nie tylko punkt
     zgloszony na zrzucie, ale ta sama zasada zastosowana jednolicie. */
  /* D168: mobilny override zdjety, patrz nota przy .cennik-wstep wyzej. */
  /* D126, 03.09.2026: zgloszenie Jakuba "usuwamy zarowno jedno jak i
     drugie" (oba zdjecia w gornej czesci "Twarz" na telefonie). D127
     (ten sam dzien, po zobaczeniu mobile makiety) przywrocil zdjecie
     wstepu (`.cennik-wstep__zdjecie`, wyzej w tym pliku), ale TO zdjecie
     (pierwsza podgrupa "Oczyszczanie i pielegnacja") zostaje ukryte:
     "jedno zdjecie moze zostac".
     D139, 03.09.2026: selektor przepiety z `.cennik-pasmo__grid--lewo` na
     dedykowana klase `.cennik-pasmo--mobile-bez-zdjecia` (cennik.py,
     parametr mobile_bez_zdjecia w html_pasmo()). Powod: po D139 wiecej niz
     jedno pasmo ma zdjecie po lewej (Twarz podgrupa 3 "Zabiegi igłowe",
     plus caly cennik cialo/usta/zmiany-skorne), a chowanie na mobile mialo
     zostac wylacznie na tej jednej, pierwotnej pozycji z D126/D127, zeby
     ogolny selektor `--lewo` nie schowal tez zdjec, ktore Jakub chce miec
     widoczne.
     D148, 03.09.2026: druga pozycja dolaczona, zgloszenie Jakuba "cialo i
     zmiany skorne pokazuja 2 zdjecia na mobile [wstep + pasmo, dublowane
     D139], jedno usuwamy". `mobile_bez_zdjecia=True` teraz tez na pasmie
     cen cialo/zmiany-skorne (cennik.py), Twarz podgrupa 3 i usta (bez
     osobnego pasma od D140) nie sa ruszone. */
  .cennik-pasmo--mobile-bez-zdjecia .cennik-pasmo__zdjecie { display: none; }
  /* D148: zdjecie "usta" na mobile ladowalo sie na samym dole, PO liscie
     dwoch uslug (DOM: tresc pierwsza, zdjecie druga w html_wstep(), patrz
     cennik.py) - zgloszenie Jakuba "powinno być pomiędzy... [ale] tam, na
     dole, usuwamy". Jedyna kategoria bez osobnego pasma cen (D140), wiec
     nie ma gdzie mechanizmu mobile_bez_zdjecia z html_pasmo(), selektor po
     ID zamiast. */
  #usta .cennik-wstep__zdjecie { display: none; }
  /* D128, 03.09.2026: zgloszenie Jakuba, ten sam mobile przeglad. Kreska
     (D115) i jej padding-inline-start istnialy po to, zeby oddzielic tresc
     od zdjecia PO LEWEJ w dwoch kolumnach na desktopie. Zdjecie zniknelo z
     mobile w D126, wiec kreska zostala bez powodu i tylko zabierala
     szerokosc: "kreska po lewej... zabiegi bardziej sciesniete... na
     makiecie jest prawie pelna szerokosc sekcji". Makieta mobile
     (raw/.../Oferta/02, kolumna MOBILE 390) nie ma kreski, cennik zaczyna
     sie od zwyklego marginesu kontenera. Nadal aktualne po D141: kreska
     zostaje wylaczona na mobile wszedzie, nie tylko przy pierwszej podgrupie,
     ten sam powod (makieta) dotyczy kazdego pasma jednakowo. Zerowanie OBU
     stron (nie tylko inline-start), bo D141 dala kresce strone zalezna od
     zdjecia, wiec na roznych pasmach aktywna strona jest rozna.
     Selektor `.cennik-pasmo__grid--lewo .cennik-pasmo__tresc--kreska`
     (D141, wyzej w pliku) ma specyficznosc dwoch klas i wygrywa z gola
     `.cennik-pasmo__tresc--kreska` niezaleznie od kolejnosci w pliku
     (PRZEKAZANIE.md pulapka 28), wiec reset na mobile musi powtorzyc te
     sama pare klas, nie tylko baze. */
  .cennik-pasmo__tresc--kreska,
  .cennik-pasmo__grid--lewo .cennik-pasmo__tresc--kreska {
    border-inline-start: 0;
    border-inline-end: 0;
    padding-inline-start: 0;
    padding-inline-end: 0;
  }
}

/* D139, 03.09.2026: dawny fallback `#cialo/#usta/#zmiany-skorne .cennik__siatka`
   na 1100px (D103/D122) usuniety razem z `.cennik__siatka` w calosci: siatka
   2-kolumnowa nie istnieje juz w kodzie, cialo/usta/zmiany-skorne dostaly
   pojedyncza kolumne uslug jak podgrupy Twarzy (patrz komentarz przy
   `.cennik-pasmo--pelny` wyzej), wiec problem "za waska kolumna na 1024px"
   nie ma juz gdzie wystapic w tej formie. */

/* Historia ukladu wiersza cennika na mobile (03.09.2026, jeden dzien, cztery
   proby): D127 wprowadzilo "wariant / czas+cena+rezerwuj", oparte na
   zanizonej rozdzielczosci crop makiety (mylnie wygladalo na dwie linie).
   D130 cofnelo to po zoomie 1:1 na oryginal, ktory pokazal JEDNA linie
   (wariant+czas+cena+Rezerwuj obok siebie), ale sam tekst "Rezerwuj" nie
   zostawial miejsca na dluzsze nazwy wariantow. D131 probowalo ikony
   kalendarza zamiast tekstu przycisku, Jakub odrzucil ("nie taka ikonke").
   D132 dalo przyciskowi wlasna, PELNA szerokosc linii pod czasem/cena -
   dzialalo, ale przycisk na pelnej szerokosci wygladal "ogromny".

   D133: DWIE KOLUMNY, nie trzy wiersze na pelnej szerokosci. Wariant PO
   LEWEJ (wlasna kolumna, moze zawijac sie swobodnie, nie zderza sie z
   niczym), po PRAWEJ czas+cena w jednej linii, a POD nimi, na ICH
   szerokosci (nie na pelnej szerokosci wiersza), przycisk Rezerwuj -
   dokladnie wedlug opisu Jakuba. `grid-template-areas` z "wariant" w OBU
   wierszach prawej-lewej kolumny scala sie automatycznie w jeden prostokat
   (CSS Grid), wiec wariant zajmuje cala wysokosc bez dodatkowego kodu. */
@media (max-width: 700px) {
  /* D149, 03.09.2026: zgloszenie Jakuba, przycisk Rezerwuj rozjezdza sie
     szerokoscia miedzy wierszami. Kolumny czas/cena byly `auto` (D133),
     czyli kazdy WIERSZ to WLASNY grid (`.cennik__wiersz` jest gridem samo
     w sobie, nie dzieli kolumn z sasiednimi wierszami jak tabela), wiec
     szerokosc auto-track liczyla sie z tresci TEGO jednego wiersza. Przy
     opisowej cenie ("cena ustalana na konsultacji", D139) kolumna cena
     rosla, przycisk (span czas+cena, D133) rosl razem z nia, a kolumna
     wariant (1fr, reszta miejsca) traciła szerokosc i tekst lamal sie na 4
     linie ("wiotkość wybranej części ciała", "brzuch, boczki, uda, kolana",
     Cialo; "duży obszar", Zmiany skorne, wszystkie trzy z ta sama opisowa
     cena). Naprawa: czas i cena na STALE px zamiast auto, wiec przycisk ma
     jedna, stala szerokosc na kazdym wierszu kazdej kategorii, a wariant
     (1fr) dostaje reszte konsekwentnie. */
  .cennik__wiersz {
    grid-template-columns: minmax(0, 1fr) 54px 108px;
    grid-template-areas:
      "wariant czas cena"
      "wariant rezerwuj rezerwuj";
    column-gap: var(--space-3);
    row-gap: var(--space-2);
    align-items: start;
  }
  .cennik__wariant { grid-area: wariant; align-self: center; }
  .cennik__czas { grid-area: czas; }
  /* D139, 03.09.2026: white-space:normal dodane przy sprzataniu `.cennik__siatka`
     (dawny nosiciel tej reguly, tylko dla cialo/usta/zmiany-skorne, D112).
     Bez niej "cena ustalana na konsultacji" (zmiany-skorne) w kolumnie `auto`
     tego gridu nie zawija sie, auto-track rosnie do szerokosci tekstu i caly
     wiersz przepelnia sie o 23px na 390px (zmierzone). Krotkie ceny liczbowe
     zawijania nie potrzebuja, regula nie zmienia ich wygladu. */
  .cennik__cena { grid-area: cena; white-space: normal; }
  /* inline-size:100% wypelnia dokladnie szerokosc wlasnej kolumny (auto,
     wyznaczonej przez szerszy z czas/cena w wierszu wyzej), nie calego
     wiersza jak w D132: to jest "na ich szerokosci przycisk rezerwacji"
     z opisu Jakuba. Wysokosc 44px (D33/D4, prog dotyku) zostaje bez zmian
     swiadomie, nawet w D134 (mniejszy przycisk): to prog dostepnosci, nie
     estetyki, wiec "mniejszy" idzie w padding i czcionke, nie w wysokosc. */
  .cennik__rezerwuj {
    grid-area: rezerwuj;
    inline-size: 100%;
    padding-inline: var(--space-3);
    font-size: var(--fs-fine);
  }
}

/* D170, 03.09.2026: wartosci dobrane przez Jakuba w konfiguratorze, zakres
   telefon (max-width: 700px, pulapka 38). Zapisane w pliku wlasciciela, nie w
   konfigurator.css, zgodnie z rozstrzygnieciem z D168: konfigurator sluzy do
   DOBRANIA wartosci, nie do jej przechowywania. */
@media (max-width: 700px) {
  /* Wstepy kategorii po ID, bo kazdy dostal wlasna wartosc. Selektor po ID
     (1,0,0) wygrywa z baza `.cennik-wstep` niezaleznie od kolejnosci w pliku.
     Trzy zera na dole i pelny odstep po obu stronach Ust to wybor Jakuba
     zrobiony okiem na zywej stronie, nie wyliczenie: zapisuje wartosci, nie
     dorabiam do nich mechanizmu. Rodzina zer wyglada jak D149/D150 (dwa
     paddingi bez szwu koloru czytaja sie jako jeden, pulapka 36), ale tego
     nie zmierzylem, wiec nie podaje tego jako przyczyny. */
  #twarz { padding-block: var(--space-6) 0; }
  #cialo { padding-block: var(--space-6) 0; }
  #usta { padding-block: var(--space-5); }
  #zmiany-skorne { padding-block: var(--space-6) 0; }
}
