/* Sekcje strony głównej, Salon Masażu Magnolia. Kolejność zgodna z page-briefs/home.md. */

/* ==========================================================================
   Wrapper strony. D-PLASKIE-SEKCJE, 06.09.2026: zero padding/gap, sekcje
   ida pelna szerokoscia tego kontenera, bez szwu miedzy nimi (decyzja
   Jakuba w nocy 06.09, cofa sygnature "karty na krem" z 26.08.2026).
   Jedyny wyjatek: hero home, ktory sam sobie dokleja wciecie boczne,
   patrz .sekcja--hero.panel nizej.
   ========================================================================== */
.strona {
  /* D-KONTENER-FLUID, 04.09: powiazane z --container zamiast wlasnej stalej,
     zeby "ramka" (dawniej 1512-1200=312px) skalowala sie proporcjonalnie
     zamiast zamrazac panele na 1512px. Przy --container=1200 (viewport<=1440)
     daje dokladnie 1512, jak dotad. */
  max-width: calc(var(--container) + 312px);
  margin-inline: auto;
}

/* .panel niesie wylacznie kolor od 06.09.2026 (D-PLASKIE-SEKCJE). Radius i
   overflow zostaja tylko na hero home (.sekcja--hero.panel, sekcja 1). */
.panel--jasny { background: var(--surface-cream); }
.panel--ciemny { background: var(--surface-dark); color: var(--text-on-dark); }
.panel--ciemny-2 { background: var(--clr-dark-2); color: var(--text-on-dark); }

/* h1-h3 mają kolor zapisany wprost w base.css (--text-on-light), więc na ciemnym
   panelu trzeba go świadomie nadpisać, inaczej nagłówek ginie na ciemnym tle. */
.panel--ciemny h1, .panel--ciemny h2, .panel--ciemny h3,
.panel--ciemny-2 h1, .panel--ciemny-2 h2, .panel--ciemny-2 h3 {
  color: var(--text-on-dark);
}

.sekcja { padding-block: var(--space-section); position: relative; }
@media (max-width: 767px) { .sekcja { padding-block: var(--sekcja-y-mobile); } }

/* Od D-PLASKIE-SEKCJE (06.09.2026) rownowazne .panel.panel--jasny: oba
   tla tresci ujednolicone na --surface-cream, --clr-cream-wash zostaje
   wylacznie dla headera. Klasa zostaje z uzycia historycznego
   (D-HOME-POPRAWKI, 04.09.2026), nie usuwana zeby nie ruszac markupu bez
   potrzeby. */
.sekcja--flush { background: var(--surface-cream); }
/* Feedback Jakuba 06.09.2026 (przegląd desktop): sekcja "kategorie" na Home
   ma odcinać się subtelnie od "o mnie" pod nią, ten sam ton co header
   (--clr-cream-wash) zamiast --surface-cream reszty treści. Modyfikator
   scoped tylko do kategorie.php, .sekcja--flush sama zostaje na cream. */
.sekcja--flush-wash { background: var(--clr-cream-wash); }
/* 08.09.2026 (hub /masaze, Jakub): dwie sekcje flush-wash pod rząd, ten sam
   kolor, więc padding-top drugiej dokładał się do padding-bottom pierwszej
   i dawał podwójny, zbyt wysoki odstęp między kategoriami a boxem "nie
   wiesz co wybrać". Odstęp niesie już padding-bottom pierwszej sekcji. */
.sekcja--flush-wash + .sekcja--flush-wash { padding-top: 0; }
/* Ciemny odpowiednik wyzej (24.09.2026): FAQ i opinie na stronach kategorii
   ida jedna po drugiej, oba domyslnie panel--ciemny-2, bez tej reguly ich
   padding-bottom+padding-top sumuja sie w tym samym kolorze na 144px i
   wygladaja jak jedna przewymiarowana przerwa (Jakub, zrzut lecznicze).
   Scoped do tej jednej pary klas, nie dotyka panel--ciemny (inny odcien). */
.sekcja.panel--ciemny-2 + .sekcja.panel--ciemny-2 { padding-top: 0; }
/* Jasny odpowiednik (24.09.2026, ten sam wieczor): Home, O mnie (.sekcja--flush,
   surface-cream) i Pakiety/voucher (.panel--jasny, tez surface-cream) ida jedna
   po drugiej, ten sam efekt sumowania 72+72=144px w tym samym kolorze (Jakub,
   zrzut "Wybierz voucher lub pakiet"). .sekcja--flush istnieje tylko w
   o-mnie.php w calym motywie, wiec ten selektor jest bezpiecznie scoped do
   dokladnie tej jednej sekwencji na Home. */
.sekcja--flush + .panel--jasny.sekcja { padding-top: 0; }
/* Trzeci jasny przypadek (24.09.2026): /pakiety, tabela-porownanie.php i
   faq-akordeon.php (tlo=jasny) renderuja identyczna klase .panel.panel--jasny.sekcja
   jedna po drugiej, ten sam efekt sumowania 72+72=144px (Jakub: odstep pod
   "Policz sama" wiekszy niz gdzie indziej na stronie). Selektor ogolny
   (nie doklejony do jednego komponentu), bo obie sekcje juz dzis dziela
   dokladnie te sama pare klas, kolejny komponent .panel--jasny dostawiony
   po ktoryms z nich zlapie ta sama regule automatycznie. */
.panel--jasny.sekcja + .panel--jasny.sekcja { padding-top: 0; }
/* Sama para na /pakiety, tylko z pustym kotwicowym div#zapytaj-pakiet miedzy
   sekcjami (page-pakiety.php), ktory przerywa bezposrednie rodzenstwo "+" mimo
   ze wizualnie div jest bez wysokosci i niewidoczny. pakiet-karta.php ->
   #zapytaj-pakiet -> formularz-kontakt.php, oba panel--jasny, ten sam efekt
   sumowania 72+72px. */
.panel--jasny.sekcja + #zapytaj-pakiet + .panel--jasny.sekcja { padding-top: 0; }
.sekcja--split { padding-block: var(--sekcja-y-split); }

/* ==========================================================================
   0a. Pasek kontaktowy (topbar). Ukryty pod 768.
   Zrosniety z .naglowek w jeden plaski blok, flush pod krawedzia .strona.
   Od D-PLASKIE-SEKCJE (06.09.2026) .strona juz nie ma padding/gap, wiec
   flush jest domyslnym stanem kazdego dziecka blokowego, bez potrzeby
   ujemnego marginesu ktory dawniej znosil ten padding (D-NAGLOWEK-MANDALA,
   04.09.2026, teraz nieaktualny komentarz usuniety). */
/* Topbar ciemny, naglowek jasny: dwa rozne tony zamiast jednego (D-KOLORY-NAGLOWEK,
   04.09.2026, wzorzec Mandali). --accent na ciemnym tle ma kontrast 2.8:1
   (patrz design-system.md, tabela kontrastu), wiec ikony i tekst ida na
   warianty "soft" zrobione pod ciemne tlo, nie na zwykly --accent/--text-on-light-muted. */
.topbar {
  background: var(--surface-dark);
  border-radius: 0;
}
.topbar__wnetrze {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 28px;
  align-items: center;
  padding: 12px var(--kontener-x);
  font-size: 13px;
  color: var(--text-on-dark-muted);
}
.topbar__wnetrze a { text-decoration: none; }
.topbar__wnetrze a:hover { color: var(--text-on-dark); }
.topbar__prawa { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 28px; }
.topbar__item { display: inline-flex; align-items: center; gap: 8px; }
.topbar__item svg { width: 14px; height: 14px; color: var(--accent-ctx); flex: none; }
/* A9, sesja poprawkowa 10.09.2026: link telefonu w topbarze mial 22px
   wysokosci. Padding plus rownowazny ujemny margines: pasek zostaje tej
   samej wysokosci (12px padding-block .topbar__wnetrze), obszar klikalny
   linku rosnie do 40px. */
.topbar__item--telefon { padding-block: 9px; margin-block: -9px; }
/* Na mobile zostaje sam telefon, adres i godziny nie mieszcza sie bez
   ucinania tresci (D-NAGLOWEK-FIX, 04.09.2026). Telefon w topbarze jest
   informacyjny, przycisk w headerze obok jest juz samo "Zadzwon". */
@media (max-width: 767px) {
  .topbar__item--adres, .topbar__item--godziny { display: none; }
  .topbar__wnetrze { justify-content: center; padding-block: 10px; }
}

/* ==========================================================================
   0b. Header sticky
   Zrosniety z .topbar, zero przerwy (oba flush, .strona bez gap od
   06.09.2026). Radius 0 zamiast pigulki (D-NAGLOWEK-MANDALA). Sticky
   top:0, bo naturalna pozycja jest juz na krawedzi.
   ========================================================================== */
.naglowek {
  background: var(--clr-cream-wash);
  border-radius: 0;
  position: sticky;
  top: 0;
  z-index: 50;
}
/* Grid, nie flex: 1fr/auto/1fr garantuje ze srodkowa kolumna (menu) stoi
   dokladnie na srodku calego paska, niezaleznie od tego czy logo i prawa
   grupa (social+akcje) maja rowna szerokosc (D-HEADER-STRUKTURA, 04.09.2026).
   Flex z justify-content:space-between tego nie daje, bo wtedy menu stoi
   na srodku PRZESTRZENI MIEDZY logo a prawa grupa, nie na srodku paska. */
/* Header/topbar na standardowym .kontener (08.09.2026, Jakub: "hero, header
   i topbar szersze niż reszta sekcji"). Poprzednia wersja (D-HEADER-STRUKTURA,
   04.09.2026) zdejmowała max-width z .kontener i liczyła własny padding, żeby
   ręcznie dopasować logo do lewej krawędzi hero -- działało tylko przy jednym
   zmierzonym viewporcie, bo --container jest fluid (clamp), a formuła
   nagłówka była stałą liczbą pikseli. Przy szerszych ekranach --container
   rósł, formuła nie, więc header realnie się rozjeżdżał z resztą strony.
   Teraz header/topbar używają tego samego var(--container) co każda inna
   sekcja, a hero (patrz .hero__wnetrze niżej) dostał to samo -- oba
   wyrównują się do tej samej osi automatycznie, bez ręcznej formuły. */
.naglowek__wnetrze {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 20px;
  padding-block: 14px;
  min-height: 56px;
}
/* Kolumny jawne, nie auto-placement: gdy nav dostaje display:none na
   mobile, auto-placement pomija go calkowicie i wciska .naglowek__prawa
   w srodkowa kolumne zamiast trzeciej, psujac wyrownanie do prawej
   krawedzi. Jawny numer kolumny trzyma pozycje niezaleznie od tego,
   ktory element jest akurat ukryty. */
.naglowek__logo { grid-column: 1; }
.naglowek__nawigacja { grid-column: 2; justify-self: center; }
.naglowek__prawa { grid-column: 3; display: flex; align-items: center; gap: 20px; justify-self: end; }
.naglowek__logo {
  text-decoration: none;
  color: var(--text-on-light);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.1;
  flex: none;
}
.naglowek__logo small {
  font-size: 9px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}
.naglowek__logo strong {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: .01em;
}
.naglowek__logo em {
  font-style: normal;
  font-size: 9px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent);
}

.naglowek__nawigacja ul {
  list-style: none;
  display: flex;
  gap: 28px;
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}
.naglowek__nawigacja a {
  text-decoration: none;
  font-size: var(--fs-body);
  color: var(--text-on-light);
}
.naglowek__nawigacja a:hover { color: var(--accent); }

/* Dropdown "Masaże", D-TRZY-WARSTWY (04.09.2026, S1). Jeden poziom, pięć
   kategorii, zero flyoutu: Lumira miała dwa poziomy i trzy nakładające się
   bloki CSS łatające gubiony hover, świadomie tego nie powtarzamy. Czysty
   CSS, hover + focus-within (klawiatura), zero JS. WordPress dokłada klasę
   menu-item-has-children i owija dzieci w <ul class="sub-menu"> sam, gdy
   pozycja menu ma potomków (wp_nav_menu depth=>2 w header.php już to woła). */
.naglowek__nawigacja li { position: relative; }
.naglowek__nawigacja li.menu-item-has-children > a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  /* D-CHEVRON-BLEED (06.09.2026): rotate(45deg) na kwadracie 6x6 rozciąga
     bounding box do ok. 8,49px, co dodaje realny scrollWidth +2px na tym
     linku globalnym (potwierdzone dom.py). Wizualnie nic się nie zmienia
     (dokument scrollW==clientW, brak scrolla), ale rozjazd wychodzi jako
     P0 w spojnosc.py na każdej podstronie. Zamiast wpisywać wyjątek
     (selektor to goły "a", zbyt szeroki, wyłączyłby bramkę wszędzie),
     naprawione u źródła: 2px rezerwy po prawej wchłania nadmiar. */
  padding-right: 2px;
}
.naglowek__nawigacja li.menu-item-has-children > a::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.naglowek__nawigacja li.menu-item-has-children:hover > a::after,
.naglowek__nawigacja li.menu-item-has-children:focus-within > a::after {
  transform: translateY(1px) rotate(225deg);
}
.naglowek__nawigacja .sub-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  min-width: 240px;
  margin: 0;
  padding: 10px;
  background: var(--surface-cream);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-karta);
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%) translateY(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur) var(--ease);
  z-index: 60;
}
.naglowek__nawigacja li:hover > .sub-menu,
.naglowek__nawigacja li:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(6px);
}
.naglowek__nawigacja .sub-menu a {
  display: block;
  padding: 10px 14px;
  border-radius: calc(var(--radius-md) - 10px);
  white-space: nowrap;
}
.naglowek__nawigacja .sub-menu a:hover { background: var(--clr-cream-wash); }

.naglowek__social { display: flex; align-items: center; gap: 14px; flex: none; }
.naglowek__social-ikona { display: flex; color: var(--text-on-light-muted); }
.naglowek__social-ikona svg { width: 18px; height: 18px; }

/* Koszyk, G1 06.09.2026 (D-WOOCOMMERCE-SAMOOBSLUGA, D-KOSZYK-MOBILE).
   Poza .naglowek__social celowo: ten wrapper ma aria-hidden dzielony z FB/IG
   (adresow profili nie mamy), a koszyk od teraz jest realnym, klikalnym
   elementem funkcjonalnym, nie dekoracja. */
.naglowek__koszyk {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-on-light-muted);
  text-decoration: none;
  flex: none;
}
.naglowek__koszyk:hover { color: var(--accent); }
.naglowek__koszyk svg { width: 19px; height: 19px; }
.naglowek__koszyk-licznik {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--text-on-dark);
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  position: absolute;
  top: -6px;
  right: -8px;
}
.naglowek__koszyk[data-jdb-koszyk-puste="0"] .naglowek__koszyk-licznik { display: flex; }
.naglowek__koszyk-tekst { display: none; }

/* J0, 11.09.2026: ikona wieksza (19px -> 24px) i obszar klikalny 44x44
   (wzorzec A9, .naglowek__cta-tel nizej), tylko instancja w naglowku
   desktop -- `.naglowek__prawa >` jest tym samym selektorem co reguła
   chowajaca ta instancje na mobile kilka linii nizej, wiec instancja
   off-canvas (pelny wiersz z tekstem) zostaje nietknieta. */
.naglowek__prawa > .naglowek__koszyk {
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -13px;
}
.naglowek__prawa > .naglowek__koszyk svg { width: 24px; height: 24px; }
/* Licznik byl pozycjonowany wzgledem ikony 19px bez wlasnego pudelka
   (top:-6px/right:-8px). Pudelko 44x44 z ikona 24px wysrodkowana zostawia
   10px marginesu z kazdej strony ikony -- odjete od starych offsetow,
   zeby plakietka zostala wizualnie w tym samym miejscu wzgledem ikony. */
.naglowek__prawa > .naglowek__koszyk .naglowek__koszyk-licznik { top: 4px; right: 2px; }


.naglowek__akcje { display: flex; align-items: center; gap: 12px; flex: none; }
/* A9, sesja poprawkowa 10.09.2026: przyciski w .naglowek__akcje maja box 44x44,
   ikona/kreski w srodku bez zmiany wygladu, ujemny margines kompensuje
   dodatkowa szerokosc w rzedzie. Ikona telefonu (.naglowek__cta-tel) zdjeta
   11.09.2026 w rundzie mobile. */

.naglowek__hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  margin: -6px -10px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
}
.naglowek__hamburger span { width: 26px; height: 2px; background: var(--text-on-light); border-radius: 2px; }

/* Runda mobile 11.09.2026 (decyzja Jakuba): na <=900 srodkowa kolumna gridu
   niesie przycisk "Kup voucher", po prawej koszyk (44x44, ta sama instancja
   co na desktopie) i hamburger. Ikona telefonu zdjeta z paska, telefon zostaje
   w szufladzie ("Zadzwon") i w stopce. */
.naglowek__voucher { display: none; grid-column: 2; justify-self: center; }
@media (max-width: 900px) {
  .naglowek__nawigacja { display: none; }
  .naglowek__social { display: none; }
  .naglowek__wnetrze { gap: 12px; }
  .naglowek__voucher {
    display: inline-flex;
    padding: 10px 16px;
    font-size: 14px;
    white-space: nowrap;
  }
  .naglowek__prawa { gap: 0; }
  .naglowek__akcje { gap: 6px; }
  .naglowek__akcje .btn--primary.btn--full-label { display: none; }
  .naglowek__prawa > .naglowek__koszyk { margin: -6px 0; }
  .naglowek__hamburger { display: flex; margin: -6px -10px -6px 0; }
  .naglowek__logo strong { font-size: 20px; }
}
@media (max-width: 380px) {
  .naglowek__voucher { padding: 9px 12px; font-size: 13px; }
  .naglowek__logo strong { font-size: 18px; }
}

/* Off-canvas menu mobilne */
.off-canvas {
  position: fixed;
  inset: 0;
  z-index: 100;
  visibility: hidden;
  overflow: hidden;
  /* Runda mobile 11.09.2026: visibility przelaczalo sie natychmiast, wiec
     zamkniecie skakalo (panel znikal w polowie drogi). Opoznienie rowne
     czasowi przejazdu panelu przy zamykaniu, zero przy otwieraniu. */
  transition: visibility 0s linear var(--dur);
}
.off-canvas[data-otwarte="true"] { visibility: visible; transition-delay: 0s; }
.off-canvas__tlo {
  position: absolute; inset: 0;
  background: rgba(27,23,19,.5);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.off-canvas__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(84vw, 360px);
  background: var(--surface-cream);
  padding: 28px 24px;
  transform: translateX(100%);
  transition: transform var(--dur) var(--ease);
  overflow-y: auto;
}
.off-canvas[data-otwarte="true"] .off-canvas__tlo { opacity: 1; }
.off-canvas[data-otwarte="true"] .off-canvas__panel { transform: translateX(0); }
/* Stager pozycji (11.09.2026) zdjety 12.09.2026 na feedback Jakuba ("animacja
   dziwna"), bo pozycje jechaly translateY W TRAKCIE gdy caly panel jeszcze
   jechal translateX -- dwa jednoczesne ruchy w roznych osiach wygladaly na
   szarpanie, nie na animacje. Przywrocone tego samego dnia na wyrazne
   zyczenie: tym razem sama OPACJA (zero transform, zero drugiego kierunku
   ruchu) i dopiero PO tym jak panel dojedzie (--dur=500ms), zeby oba ruchy
   nigdy sie nie nakladaly. Patrz li.nth-child nizej. */
.off-canvas__zamknij {
  background: none; border: 0; cursor: pointer; margin-left: auto; display: block;
  font-size: 28px; line-height: 1; color: var(--text-on-light); padding: 4px 8px;
}
.off-canvas__nawigacja { list-style: none; margin: 24px 0; padding: 0; }
.off-canvas__nawigacja li + li { margin-top: 4px; }
/* Stager wejscia pozycji glownych (nie submenu, stad ">"), tylko opacja,
   opoznienie startuje po dojezdzie panelu (--dur). Zamkniecie bez opoznienia:
   selektor wymaga data-otwarte="true", wiec przy zamykaniu wraca do bazowej
   200ms bez delay i znika, zanim panel skonczy zjezdzac. */
/* 25.09.2026: staggered fade-in (opacity:0 -> 1, opoznienia 500-660ms per
   pozycja) usuniety na zyczenie Jakuba -- panel wjezdzal juz "pusty", biale
   tlo bez tekstu, dopiero po pol sekundy zaczynaly pojawiac sie linki jeden
   po drugim. Pozycje menu widoczne od razu, jak tylko panel wjezdza. */
.off-canvas__nawigacja > li { opacity: 1; }
.off-canvas__nawigacja a {
  display: block; padding: 12px 4px; text-decoration: none; font-size: 18px;
  font-family: var(--font-display); color: var(--text-on-light); border-bottom: 1px solid var(--line-on-light);
}
/* Submenu w szufladzie (12.09.2026, feedback Jakuba: brakowalo dropdownu
   "Masaze"). wp_nav_menu depth 2 daje li.menu-item-has-children > a + ul.sub-menu,
   JS dokleja przycisk .off-canvas__rozwin obok linku (link dalej prowadzi do
   hubu, chevron rozwija liste). Rodzic biezacej podstrony startuje rozwiniety. */
.off-canvas__nawigacja li.menu-item-has-children { display: flex; flex-wrap: wrap; align-items: stretch; }
.off-canvas__nawigacja li.menu-item-has-children > a { flex: 1 1 0; min-width: 0; }
.off-canvas__rozwin {
  flex: none; width: 48px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-bottom: 1px solid var(--line-on-light); cursor: pointer; padding: 0;
  color: var(--text-on-light);
}
.off-canvas__rozwin::before {
  content: ""; width: 8px; height: 8px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 240ms var(--ease);
}
.off-canvas__rozwin[aria-expanded="true"]::before { transform: translateY(2px) rotate(225deg); }
.off-canvas__nawigacja .sub-menu {
  flex: 1 1 100%; list-style: none; margin: 0; padding: 4px 0 4px 16px;
  display: none;
}
.off-canvas__nawigacja li[data-rozwiniete="true"] > .sub-menu { display: block; }
.off-canvas__nawigacja .sub-menu li + li { margin-top: 0; }
.off-canvas__nawigacja .sub-menu a { font-size: 16px; padding: 10px 4px; border-bottom-color: transparent; color: var(--text-on-light-muted); }
.off-canvas__nawigacja .sub-menu li.current-menu-item > a { color: var(--accent); }

/* Mini-koszyk w szufladzie (J0, 11.09.2026). Mechanizm 1:1 z .off-canvas
   wyzej (data-otwarte, tlo+panel, fixed inset:0), panel ciemny zamiast
   jasnego i wjazd szybszy (240ms, spec wizualny Lumira/Mandala zamiast
   --dur=500ms uzywanego przez menu). Tresc to woocommerce_mini_cart(),
   stylowana tu klasami rdzenia WooCommerce (.woocommerce-mini-cart*,
   .button.wc-forward/.checkout), zero nadpisania PHP szablonu potrzebne. */
.koszyk-szuflada {
  position: fixed;
  inset: 0;
  z-index: 100;
  visibility: hidden;
  overflow: hidden;
  transition: visibility 0s linear 240ms;
}
.koszyk-szuflada[data-otwarte="true"] { visibility: visible; transition-delay: 0s; }
.koszyk-szuflada__tlo {
  position: absolute; inset: 0;
  background: rgba(27,23,19,.5);
  opacity: 0;
  transition: opacity 240ms var(--ease);
}
.koszyk-szuflada__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(420px, 100vw);
  background: var(--surface-dark);
  color: var(--text-on-dark);
  padding: 28px 24px;
  transform: translateX(100%);
  transition: transform 240ms var(--ease);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.koszyk-szuflada[data-otwarte="true"] .koszyk-szuflada__tlo { opacity: 1; }
.koszyk-szuflada[data-otwarte="true"] .koszyk-szuflada__panel { transform: translateX(0); }

.koszyk-szuflada__naglowek {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 20px; flex: none;
}
.koszyk-szuflada__naglowek h2 {
  font-family: var(--font-display); font-size: var(--fs-display-4); color: var(--text-on-dark); margin: 0;
}
.koszyk-szuflada__zamknij {
  background: none; border: 0; cursor: pointer;
  font-size: 28px; line-height: 1; color: var(--text-on-dark); padding: 4px 8px;
}

.widget_shopping_cart_content { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.koszyk-szuflada .woocommerce-mini-cart { list-style: none; margin: 0 0 20px; padding: 0; }
.koszyk-szuflada .woocommerce-mini-cart-item {
  /* NIE flex na <li>: obrazek+nazwa siedzą w jednym wspólnym <a> (rdzeń
     WooCommerce konkatenuje $thumbnail.$product_name), a dl.variation i
     .quantity są SIOSTRAMI tego <a>, nie jego dziećmi. Flex na <li> ustawiłby
     wszystkie cztery elementy w jednym rzędzie (metadane obok tytułu zamiast
     pod nim) -- <li> zostaje blokiem, kolumnę robi sam <a> niżej, reszta
     wyrównana wcięciem 76px (64px obrazka + 12px odstępu). */
  padding: 16px 0;
  border-bottom: 1px solid rgba(255,255,255,.2);
  position: relative;
}
.koszyk-szuflada .woocommerce-mini-cart-item:first-child { padding-top: 0; }
.koszyk-szuflada .woocommerce-mini-cart-item img {
  width: 64px; height: 64px; object-fit: cover; border-radius: var(--radius-md); flex: none;
  border: 1px solid var(--line-on-dark);
}
/* Placeholder WooCommerce (produkt bez zdjęcia): zamiast tonować kwadrat,
   chowamy go całkiem (decyzja Jakuba 12.09.2026) i zerujemy wcięcie 76px u
   rodzeństwa <a> (:has, wsparcie powszechne), żeby tytuł i metadane zaczynały
   się od lewej krawędzi zamiast zostawiać sierocy pas pustego miejsca.
   Docelowo produkty maja miec realne zdjecia (braki-materialy.md). */
.koszyk-szuflada .woocommerce-mini-cart-item img.woocommerce-placeholder {
  display: none;
}
.koszyk-szuflada .woocommerce-mini-cart-item:has(img.woocommerce-placeholder) .quantity,
.koszyk-szuflada .woocommerce-mini-cart-item:has(img.woocommerce-placeholder) dl.variation {
  margin-left: 0;
}
.koszyk-szuflada .woocommerce-mini-cart-item a {
  display: flex; align-items: flex-start; gap: 12px;
  color: var(--accent-ctx); text-decoration: none; font-family: var(--font-display); font-size: 18px;
  padding-right: 20px;
}
.koszyk-szuflada .woocommerce-mini-cart-item .quantity {
  display: block; margin: 4px 0 0 76px; font-size: var(--fs-small); color: var(--text-on-dark-muted);
}
.koszyk-szuflada .woocommerce-mini-cart-item dl.variation {
  margin: 4px 0 0 76px; font-size: var(--fs-small); color: var(--text-on-dark-muted); display: flex; flex-wrap: wrap; gap: 4px;
}
.koszyk-szuflada .woocommerce-mini-cart-item dl.variation dt,
.koszyk-szuflada .woocommerce-mini-cart-item dl.variation dd { margin: 0; font-weight: 400; }
/* Rdzen WooCommerce (cart-item-data.php) dokleja ":" do <dt> juz sam,
   dublowanie go tu dawalo "Dla::". <dd> jest przez wpautop() zawsze
   zawinieta w <p>, block-level -- resetowane do inline zeby nie lamalo
   ukladu flex rodzica. */
.koszyk-szuflada .woocommerce-mini-cart-item dl.variation dd p { margin: 0; display: inline; }
.koszyk-szuflada .remove_from_cart_button {
  position: absolute; top: 16px; right: 0;
  color: var(--text-on-dark-muted); text-decoration: none; font-size: 20px; line-height: 1;
}
.koszyk-szuflada .remove_from_cart_button:hover { color: var(--accent-ctx); }

.koszyk-szuflada .woocommerce-mini-cart__total {
  /* Bez border-top: ostatnia pozycja listy ma juz border-bottom, dwie linie
     tuz obok siebie wygladaly na blad renderowania (zrzut Jakuba 12.09.2026). */
  margin: 0 0 16px; padding-top: 16px;
  font-family: var(--font-display); font-size: var(--fs-display-4); color: var(--text-on-dark);
  display: flex; justify-content: space-between; flex: none;
}
.koszyk-szuflada .woocommerce-mini-cart__total strong { font-weight: 500; }

.koszyk-szuflada .woocommerce-mini-cart__buttons {
  display: flex; flex-direction: column; gap: 10px; margin: auto 0 0; flex: none;
  padding-top: 20px; border-top: 1px solid var(--line-on-dark);
}
.koszyk-szuflada .woocommerce-mini-cart__buttons .button {
  display: block; text-align: center; text-decoration: none;
  border-radius: var(--radius-pill); padding: 14px 20px; font-family: var(--font-text); font-size: var(--fs-body);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.koszyk-szuflada .woocommerce-mini-cart__buttons .button.wc-forward:not(.checkout) {
  background: transparent; color: var(--text-on-dark); border: 1px solid var(--line-on-dark);
}
.koszyk-szuflada .woocommerce-mini-cart__buttons .button.wc-forward:not(.checkout):hover {
  background: var(--text-on-dark); color: var(--text-on-light); border-color: var(--text-on-dark);
}
.koszyk-szuflada .woocommerce-mini-cart__buttons .button.checkout {
  background: var(--accent); color: var(--text-on-dark); border: 1px solid var(--accent);
}
.koszyk-szuflada .woocommerce-mini-cart__buttons .button.checkout:hover {
  background: transparent; color: var(--accent-ctx); border-color: var(--accent-ctx);
}

.koszyk-szuflada__pusty-tekst,
.koszyk-szuflada .woocommerce-mini-cart__empty-message {
  color: var(--text-on-dark-muted); margin: 0 0 20px;
}

/* ==========================================================================
   1. Hero
   ========================================================================== */
/* Hero mieści się w jednym ekranie. Wczesniej stalo tu min-height: 620px,
   ktore nigdy nie wiazalo: .hero__foto nie ma zadeklarowanej wysokosci, wiec
   height:100% na obrazku degradowalo do auto i wiersz gridu bral wysokosc
   z proporcji zdjecia, 985,7 px przy kolumnie 700,5 px. Naprawa jest w dwoch
   miejscach naraz, tu i w .hero__foto img nizej. Jedno bez drugiego nie dziala.
   dvh obok vh jest konieczne: na iOS 100vh liczy sie przy ZWINIETYM pasku
   adresu, a przy wejsciu na strone pasek jest rozwiniety. */
/* Jedyny zaokraglony panel sekcyjny na stronie (D-PLASKIE-SEKCJE, 06.09.2026,
   decyzja nocna). Wciecie TYLKO boczne (margin-inline), gora i dol flush
   z headerem/kolejna sekcja, bo .strona juz nie ma gap. max-width wlasny,
   bo hero nie moze polegac na wrapperze ktory stracil padding. */
/* Jedyny zaokraglony panel sekcyjny na stronie (D-PLASKIE-SEKCJE, 06.09.2026,
   decyzja nocna). Wciecie TYLKO boczne (margin-inline), gora i dol flush
   z headerem/kolejna sekcja, bo .strona juz nie ma gap. max-width wlasny,
   bo hero nie moze polegac na wrapperze ktory stracil padding.
   08.09.2026: proba zwezenia do var(--container) COFNIETA tego samego dnia
   (Jakub: "bardzo zbita ta tresc") -- hero z natury jest szerszy/mocniejszy
   niz zwykle sekcje, to celowy wzorzec (Lumira/Mandala), nie wada. Zostaje
   TYLKO poprawka headera/topbara nizej (.hero__wnetrze), to byl realny bug. */
.sekcja--hero.panel {
  margin-inline: var(--strona-pad);
  max-width: calc(var(--container) + 312px - 2 * var(--strona-pad));
  border-radius: var(--radius-panel);
  overflow: hidden;
}
.hero__wnetrze {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: 0;
  align-items: stretch;
  min-height: calc(100vh  - var(--chrome-h));
  min-height: calc(100dvh - var(--chrome-h));
}
/* Padding sekcji dokladalby 144 px do wyliczonego pudelka. */
.sekcja--hero { padding-block: 0; }
/* PROBA Z 04.09.2026 (D-NAGLOWEK-FIX) COFNIETA TEGO SAMEGO DNIA.
   Doklejenie hero flush do headera bylo bledna interpretacja "hero na
   szerokosc headera": prawdziwy wzorzec Mandali ma header flush, ale
   hero POD nim wciety i zaokraglony, z widocznym jasnym marginesem po
   bokach, nie flush. Ciemny topbar + jasna nawigacja + od razu ciemne
   hero bez odstepu (D-KOLORY-NAGLOWEK) dawalo ostry, brzydki pasek.
   06.09.2026: wciecie zostaje wylacznie boczne (patrz .sekcja--hero.panel
   wyzej), gora/dol flush, bo caly wrapper stracil gap miedzy sekcjami. */
.hero__tresc {
  /* 11.09.2026, feedback Jakuba: odstęp od lewej wyglądał ciasny wobec
     odstępu góra/dół. Pierwsza poprawka (padding: var(--space-7) na
     wszystkie strony, 40px) okazała się niewidoczna: padding-top nie jest
     tym, co realnie widać jako "odstęp od góry" -- justify-content:center
     w wysokiej kolumnie flex wypycha H1 daleko od górnej krawędzi (zmierzone
     202px do H1 przy 768px wysokości sekcji), padding-left tymczasem JEST
     realnym odstępem od lewej (40px). Naprawa dotyczy więc lewej/prawej
     wprost, nie porównania z padding-top: rośnie z tokenem do wartości
     skalowanej z szerokością viewportu (nie sztywny px, żeby nie wyglądało
     przesadnie na węższych desktopach). max-width rośnie razem z paddingiem
     (box-sizing: border-box, base.css), żeby szerokość SAMEGO tekstu i
     rząd dwóch przycisków CTA zostały jak przed zmianą (~520px), zamiast
     się ścieśniać i łamać przyciski do dwóch wierszy. */
  padding: var(--space-7) clamp(64px, 8vw, 120px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: calc(520px + 2 * clamp(64px, 8vw, 120px));
}
.hero__tresc h1 { margin-bottom: var(--space-5); }
.hero__lead { font-size: var(--fs-lead); color: var(--text-on-dark-muted); max-width: 46ch; margin-bottom: var(--space-7); }
.hero__cta { display: flex; gap: 14px; flex-wrap: wrap; }

.hero__foto {
  position: relative;
  overflow: hidden;
  clip-path: ellipse(78% 62% at 78% 50%);
}
/* Obraz wychodzi z przeplywu, zeby nie dyktowal wysokosci wiersza gridu.
   Rodzic ma juz position:relative i overflow:hidden. */
.hero__foto img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 20%; }

@media (max-width: 900px) {
  .hero__wnetrze { grid-template-columns: 1fr; min-height: 0; }
  .hero__foto { clip-path: none; order: -1; aspect-ratio: auto; height: 25vh; height: 25dvh; }
  .hero__tresc { max-width: none; padding: 36px 20px 40px; }
  .hero__cta { flex-direction: column; }
  .hero__cta .btn { width: 100%; }
}

/* "Nie wiesz co wybrać", box ciemny (hub /masaze, 06.09.2026). Poprawka
   Jakuba po pierwszym podejściu: nie bleed na szerokość hero home (to była
   pomyłka, wzięta z .sekcja--hero.panel), tylko zwykła szerokość .kontener,
   ta sama co hero-podstrony.php na tej stronie i co reszta tekstu. Kolor
   dokładnie --surface-dark, ten sam co stopka (patrz tokens.css, komentarz
   "karta ciemna: hero, cta koncowe, stopka"). Odstęp góra/dół to zwykły
   padding-block sekcji (ten sam co nad slajderem popularnych i przed
   stopką), bez własnego marginesu -- stąd "taki sam odstęp z obu stron".
   Zdjęcie małe, w stałej kolumnie (nie 50/50 jak hero), referencja
   Jakuba: karta vouchera z ciemnym tłem, mockup po prawej wyraźnie mniejszy
   niż tekst. */
.zaproszenie-box {
  border-radius: var(--radius-panel);
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,300px);
  align-items: stretch;
  gap: var(--space-9);
}
.zaproszenie__tresc { padding: var(--space-9) var(--space-7); }
.zaproszenie-box .zaproszenie__tresc h2 { margin-bottom: var(--space-5); }
.zaproszenie-box .zaproszenie__tresc p { color: var(--text-on-dark-muted); max-width: 46ch; margin-bottom: var(--space-7); }
/* Kadr: elipsa jak .hero__foto (hero home), rozciągnięta na pełną wysokość
   i doklejona do prawej krawędzi boxa (bez paddingu, tak jak zdjęcie hero
   dochodzi do krawędzi swojego panelu) -- feedback Jakuba po trzecim
   przeglądzie, wcześniej zdjęcie stało wysrodkowane z odstępem dookoła. */
.zaproszenie__foto {
  position: relative;
  overflow: hidden;
  clip-path: ellipse(78% 62% at 78% 50%);
}
.zaproszenie__foto img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .zaproszenie-box { grid-template-columns: 1fr; gap: 0; }
  .zaproszenie__foto { clip-path: none; aspect-ratio: 4/5; order: -1; }
  .zaproszenie__tresc { padding: 36px 20px 40px; }
}

/* Zabieg-wyróżnienie (16.09.2026, świecowanie uszu): box jednokolumnowy,
   bez zdjęcia (brak materiału, zero placeholdera). Sam panel--ciemny +
   nagłówek/tekst dziedziczą kolor z reguły linii 27-28 wyżej. */
/* 26.09.2026, redesign dwukolumnowy (Etap 6): tresc po lewej, pigulki
   czas/cena + dwa przyciski po prawej, wyrownane pionowo do srodka.
   border-left w --accent-ctx odroznia ten jeden box od zwyklych kart
   panel--ciemny (pakiety, koszyk), zero nowego koloru. */
.wyroznienie-zabieg {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-7);
  border-radius: var(--radius-panel);
  border-left: 4px solid var(--accent-ctx);
  padding: var(--space-9) var(--space-7);
}
.wyroznienie-zabieg__tresc p { color: var(--text-on-dark-muted); max-width: 52ch; margin: 0; }
.wyroznienie-zabieg__akcja { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); }
.wyroznienie-zabieg__pigulki { display: flex; flex-wrap: wrap; gap: 8px; }
.wyroznienie-zabieg__pigulka {
  display: inline-block;
  font-size: var(--fs-small);
  color: var(--accent-ctx);
  border: 1px solid var(--accent-ctx);
  border-radius: var(--radius-pill);
  padding: 4px 12px;
}
.wyroznienie-zabieg__btny { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.wyroznienie-zabieg__btny .btn { justify-content: center; }

@media (max-width: 600px) {
  .wyroznienie-zabieg {
    grid-template-columns: 1fr;
    border-left: none;
    border-top: 4px solid var(--accent-ctx);
    padding: 32px 20px;
  }
  .wyroznienie-zabieg__akcja { align-items: stretch; margin-top: var(--space-5); }
}

/* ==========================================================================
   2. Pięć kategorii zabiegów
   ========================================================================== */
.oferta__intro { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.oferta__intro .lead { font-size: var(--fs-lead); }

.kafle {
  display: grid;
  grid-template-columns: repeat(3, minmax(0,1fr));
  gap: 24px;
  position: relative;
  z-index: 1;
}
.kafel-zabieg { display: flex; flex-direction: column; }
.kafel-zabieg__foto {
  border-radius: var(--radius-lg) var(--radius-lg) 50% 50% / var(--radius-lg) var(--radius-lg) 46% 46%;
  overflow: hidden;
  aspect-ratio: 4/3;
  margin-bottom: var(--space-5);
  background: var(--clr-cream-wash);
}
.kafel-zabieg__foto img { width: 100%; height: 100%; object-fit: cover; }
.kafel-zabieg--plaski .kafel-zabieg__foto { border-radius: var(--radius-lg); aspect-ratio: 16/6; }

.kafel-zabieg h3 { margin-bottom: 6px; }
.kafel-zabieg__cena {
  color: var(--accent);
  font-weight: 500;
  font-size: 14px;
  margin-bottom: 10px;
}
.kafel-zabieg p.opis { font-size: 14px; margin-bottom: 14px; }

.kafle-rzad2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0,1fr));
  gap: 24px;
  margin-top: 24px;
  position: relative;
  z-index: 1;
}

@media (max-width: 900px) {
  .kafle, .kafle-rzad2 { grid-template-columns: 1fr; }
  /* Runda mobile 11.09.2026 (decyzja Jakuba): w jednej kolumnie wszystkie
     kafle maja jeden ksztalt, luk 4:3 jak rzad pierwszy i jak na home.
     Zrodlo obrazka dla plaskiego kafla przelacza <picture> w kategorie.php. */
  .kafel-zabieg--plaski .kafel-zabieg__foto {
    border-radius: var(--radius-lg) var(--radius-lg) 50% 50% / var(--radius-lg) var(--radius-lg) 46% 46%;
    aspect-ratio: 4/3;
  }
}

/* ==========================================================================
   3. O mnie + pas dowodu
   ========================================================================== */
.omnie__grid {
  display: grid;
  grid-template-columns: minmax(0,1.15fr) minmax(0,0.85fr);
  gap: var(--space-9);
  /* D-PLASKIE-SEKCJE 06.09 (decyzja 7): "end" z 04.09.2026 maskowalo objaw
     (portret 617px vs tekst 405px) zamiast go leczyc. Naprawione u zrodla:
     .omnie__foto traci wlasny aspect-ratio, "stretch" (domyslne dla grid)
     rozciaga PUDELKO zdjecia do wysokosci kolumny tekstu, a object-fit:cover
     przycina fotke do tej wysokosci bez rozciagania samego obrazu. */
  align-items: stretch;
  position: relative;
  z-index: 1;
}
.omnie__tekst p { font-size: 15px; }
/* Naprawa 06.09.2026 (feedback Jakuba: pusta przestrzeń pod tekstem):
   img z height:100% w kolumnie bez wlasnej wysokosci "auto" spada na
   INTRINSIC proporcje pliku (660x890), wiec to zdjecie dyktowalo wiersz
   gridu (813px), a krotszy tekst byl tylko rozciagany do tej wysokosci -
   pusto pod linkiem. Ten sam blad i ta sama lata co .hero__foto wyzej:
   img wychodzi z przeplywu (position:absolute), kontener traci wlasna
   intrinsic wysokosc, wiec align-items:stretch dopasowuje go NAPRAWDE do
   wysokosci tekstu, nie odwrotnie. */
/* J4, sesja poprawkowa 10.09.2026: stretch-do-tekstu (06.09) dawal wysoki
   wiersz tylko gdy tekst byl dlugi. Krotki tekst (jak dzis, brak
   .przewagi bo pole "advantages" puste) dawal wiersz ~260px, a portret
   660x890 wciecie w tak plaski box zeby "cover" go wypelnil, wygladal na
   uciety (widac ledwie gorna krawedz zdjecia). min-height daje zdjeciu
   sensowna podloge niezaleznie od dlugosci tekstu, stretch na gridzie
   nadal pozwala mu urosnac wyzej gdy tekst jest dluzszy niz ta podloga. */
.omnie__foto {
  position: relative;
  min-height: clamp(440px, 34vw, 620px);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.omnie__foto img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }

/* Przeniesione 06.09.2026 do wnetrza .omnie__tekst (feedback Jakuba, patrz
   komentarz nad partialem PHP): z pelnoszerokosciowego rzedu 3 kart na
   kompaktowa liste ikona+tekst, ktora miesci sie w lewej kolumnie pod
   przyciskiem. Zero bialych boxow - to byly osobne karty na pelna
   szerokosc strony, w waskiej kolumnie wygladalyby ciasno. */
.przewagi {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: var(--space-7);
  position: relative; z-index: 1;
}
.przewaga {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 14px;
}
.przewaga svg {
  width: 40px; height: 40px; padding: 10px; box-sizing: border-box;
  color: var(--accent);
  background: var(--clr-cream-wash);
  border-radius: 50%;
  flex: none;
}
.przewaga p { font-size: 14.5px; margin: 0; color: var(--text-on-light); }

/* .pas-dowodu usunieta z uzycia 06.09.2026 (feedback Jakuba: box z numerem
   certyfikatu wyleciał z Home). Zero innych wywolan w motywie, CSS skasowany
   razem z markupem zamiast zostawiac martwa regule. */

@media (max-width: 900px) {
  .omnie__grid { grid-template-columns: 1fr; gap: var(--space-7); }
  .omnie__foto { order: -1; aspect-ratio: 4/5; min-height: 0; }
}

/* Podstrona /o-mnie, sekcja 2 "founder story" (S6, 04.09.2026), o-mnie-historia.php.
   Sama forma co .omnie__grid (tekst/zdjecie, 50/50, aspect-ratio 3/4, radius-foto).
   Zdjecie po LEWEJ na desktopie (11.09.2026, na zyczenie Jakuba): DOM zostaje
   w kolejnosci zrodlowej (tekst, potem foto, PHP nietkniety), wizualny
   reorder robi "order:-1" na .historia__foto plus zamienione proporcje
   kolumn (0.85fr/1.15fr zamiast 1.15fr/0.85fr) zeby tekst zostal SZERSZA
   kolumna mimo ze teraz jest druga. BEZ reorderu mobile: page-brief chce
   zdjecie POD tekstem na 375, nie NAD nim jak na Home, wiec "order" wraca
   do 0 (kolejnosc zrodlowa: tekst, potem foto) w media query ponizej. Brak
   listy przewag/pasa dowodu w tej sekcji (maja wlasna sekcje 4), wiec nie ma
   odpowiednikow .przewagi/.pas-dowodu tutaj. */
.historia__grid {
  display: grid;
  grid-template-columns: minmax(0,0.85fr) minmax(0,1.15fr);
  gap: var(--space-9);
  align-items: center;
  position: relative;
  z-index: 1;
}
.historia__tekst p { font-size: 15px; }
.historia__tekst .btn { margin-top: var(--space-5); }
.historia__foto {
  order: -1;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 3/4;
}
.historia__foto img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }

@media (max-width: 900px) {
  .historia__grid { grid-template-columns: 1fr; gap: var(--space-7); }
  .historia__foto { order: 0; }
}

/* ==========================================================================
   4. Pakiety i voucher
   ========================================================================== */
.pakiety__intro { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.pakiety__duet { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; position: relative; z-index: 1; }
/* D-PLASKIE-SEKCJE 06.09: panel wraca jasny, eyebrow/lead uzywaja juz
   swoich zwyklych domyslnych kolorow (--accent, --text-on-light-muted z
   body), wiec override na .panel--ciemny z 04.09 nie jest juz potrzebny
   tutaj (zostaje uzywany gdzie indziej, np. kroki-wizyty jesli wroci
   ciemny wariant). */

/* Redesign 06.09.2026 (feedback Jakuba: "mało czytelne"): zdjęcie w tle
   zdjęte, zamiast tego miękka plama koloru jako dekoracja. Zdjęcie WRACA
   08.09.2026, druga decyzja Jakuba ("nałóż zdjęcia stockowe, ściemnij żeby
   tekst był czytelny") -- tym razem z jawnym ciemnym overlayem na
   .karta-produkt__bg zamiast gołego zdjęcia, dokładnie to, czego brakowało
   za pierwszym razem. Fallback bez zdjęcia (pole ACF puste) zostaje: flat
   --surface-dark/--surface-white plus plama, jak przed tą zmianą. */
.karta-produkt {
  border-radius: var(--radius-md);
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 360px;
  padding: 44px 40px;
}
.karta-produkt__bg { position: absolute; inset: 0; z-index: 0; }
.karta-produkt__bg img { width: 100%; height: 100%; object-fit: cover; }
.karta-produkt__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, rgba(27,23,19,.72) 0%, rgba(27,23,19,.5) 55%, rgba(27,23,19,.68) 100%);
}

.karta-produkt--voucher { background: var(--surface-dark); color: var(--text-on-dark); }
.karta-produkt--voucher h3 { color: var(--text-on-dark); }

.pakiety__duet .karta-produkt--pakiet { background: var(--surface-white); color: var(--text-on-light-muted); }
.pakiety__duet .karta-produkt--pakiet h3 { color: var(--text-on-light); }

/* Zdjęcie + overlay obecne -> tekst zawsze na jasnych tokenach "on-dark",
   niezależnie od tego, czy karta domyślnie jest ciemna (voucher) czy biała
   (pakiet). Klasa dopisywana w PHP tylko gdy pole obrazu jest wypełnione.
   Prefiks .pakiety__duet powtórzony celowo (08.09.2026, naprawa buga): bez
   niego selektor miał niższą specyficzność niż ".pakiety__duet
   .karta-produkt--pakiet h3" wyżej i przegrywał, więc tekst na karcie
   pakietu zostawał ciemny na ciemnym zdjęciu, nieczytelny. */
.pakiety__duet .karta-produkt--ma-zdjecie,
.pakiety__duet .karta-produkt--ma-zdjecie h3 { color: var(--text-on-dark); }
.pakiety__duet .karta-produkt--ma-zdjecie p.opis { color: var(--text-on-dark-muted); }
.karta-produkt--ma-zdjecie::before { display: none; }

/* Przycisk na zdjęciu (11.09.2026, feedback Jakuba: "mało widoczny").
   .btn--secondary sam w sobie liczy na ciemne, ALE jednolite tło (obrys
   rgba(...,.35) + brak wypełnienia). Na zdjęciu z overlayem ten sam obrys
   ginie w fakturze fotografii. Tu dostaje pełny, kontrastowy obrys plus
   lekkie wypełnienie, żeby czytał się jak przycisk niezależnie od tego,
   co akurat jest pod spodem na zdjęciu. */
.karta-produkt--ma-zdjecie .btn--secondary {
  background: rgba(247,238,227,.12);
  border-color: var(--text-on-dark);
}
.karta-produkt--ma-zdjecie .btn--secondary:hover {
  background: var(--text-on-dark);
  color: var(--text-on-light);
  border-color: var(--text-on-dark);
}

.karta-produkt__tresc { position: relative; z-index: 1; }
.karta-produkt__plakietka {
  display: inline-block;
  border: 1px solid var(--accent-ctx);
  color: var(--accent-ctx);
  border-radius: var(--radius-pill);
  padding: 4px 14px;
  font-size: 12.5px;
  margin-bottom: 16px;
}
.karta-produkt--pakiet .karta-produkt__plakietka { color: var(--accent); border-color: var(--accent); }
.karta-produkt--pakiet .karta-produkt__konkret { color: var(--accent); font-weight: 500; margin-bottom: 10px; font-size: 15px; }
.karta-produkt h3 { font-size: var(--fs-display-3); margin-bottom: 12px; }
.karta-produkt p.opis { font-size: 15px; margin-bottom: 24px; max-width: 38ch; }

@media (max-width: 900px) {
  .pakiety__duet { grid-template-columns: 1fr; }
  .karta-produkt { min-height: 0; padding: 36px 28px; }
}

/* ==========================================================================
   5. Trzy kroki wizyty
   ========================================================================== */
.kroki__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.kroki {
  display: grid;
  grid-template-columns: repeat(3, minmax(0,1fr));
  gap: var(--space-7);
  position: relative;
  margin-bottom: var(--space-7);
  z-index: 1;
}
/* 24.09.2026, zgloszenie Jakuba (zrzut, /pakiety): odstep pod ostatnim
   krokiem wiekszy niz nad naglowkiem. Przyczyna potwierdzona computed
   stylem na zywo: margin-bottom powyzej istnieje zeby zrobic odstep przed
   opcjonalnym .kroki__cta (przycisk pod krokami, kroki_cta_label/url w
   ACF) -- gdy CTA nie ustawione (jak dzis na /pakiety), .kroki jest
   OSTATNIM dzieckiem .kontener i ten margines dokleja sie do pelnego
   padding-bottom sekcji (72px + 40px = 112px), podczas gdy padding-top nad
   naglowkiem to samo 72px bez dodatku. Kiedy .kroki__cta JEST obecne,
   margines zostaje potrzebny (:last-child wtedy nie pasuje). */
.kroki:last-child { margin-bottom: 0; }
.krok { text-align: center; display: flex; flex-direction: column; align-items: center; }
.krok__ikona {
  width: 74px; height: 74px;
  border-radius: 50%;
  border: 1px solid var(--accent-ctx);
  display: grid; place-items: center;
  margin-bottom: 18px;
  background: var(--surface-white);
}
.krok__ikona svg { width: 28px; height: 28px; color: var(--accent); }
.krok p { font-size: 14.5px; max-width: 26ch; }
/* Wariant "numery" (08.09.2026, wzorzec Mandali, /pakiety), cyfra zdjeta
   10.09.2026 (AI-slop audyt): tytul nad opisem, bez zadnego znacznika kolejnosci.
   11.09.2026 (feedback Jakuba): pogrubiony naglowek (700 zamiast domyslnych
   500 z base.css h3) -- bez tego "numer" wygladal tak samo jak zwykly opis,
   nic nie wyrozizniajac kroku ponad tekstem pod nim. */
.krok--numer h3 { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.krok--numer p { max-width: 28ch; }
/* D-HOME-POPRAWKI 04.09: przycisk pod krokami byl zwyklym elementem
   inline-flex bez rodzica centrujacego, wiec lgnal do lewej krawedzi
   kontenera zamiast siedziec pod wysrodkowana siatka ikon nad nim. */
.kroki__cta { text-align: center; }
/* Wariant ciemny (Home, D-HOME-POPRAWKI 04.09): domyslny .eyebrow (--accent)
   ma na --surface-dark tylko 2.8:1 (design-system.md, "NIE UZYWAC"), wiec na ciemnym
   panelu przechodzi na --accent-ctx. Domyslny kolor <p> dziedziczy z body
   (--text-on-light-muted, ciemny), na ciemnym panelu trzeba go jawnie podmienic. */
.panel--ciemny .kroki__head .eyebrow { color: var(--accent-ctx); }
.panel--ciemny .krok p { color: var(--text-on-dark-muted); }

@media (max-width: 900px) {
  .kroki { grid-template-columns: 1fr; gap: var(--space-7); text-align: left; }
  .krok { flex-direction: row; align-items: flex-start; gap: 16px; text-align: left; }
  .krok__ikona { margin-bottom: 0; flex: none; }
  /* Runda mobile 11.09.2026: wariant z naglowkiem (/pakiety) w rzedzie flex
     sciskal h3 do waskiej kolumny miedzy ikona a opisem (4 linie po jednym
     slowie). Grid: ikona w pierwszej kolumnie na dwa wiersze, naglowek nad
     opisem w drugiej. Home (bez h3) zostaje flexem, tam nic sie nie zmienia. */
  .krok--numer { display: grid; grid-template-columns: auto minmax(0,1fr); column-gap: 16px; align-items: start; }
  .krok--numer .krok__ikona { grid-row: 1 / 3; width: 56px; height: 56px; }
  .krok--numer .krok__ikona svg { width: 22px; height: 22px; }
  .krok--numer h3 { grid-column: 2; margin-top: 4px; }
  .krok--numer p { grid-column: 2; max-width: none; }
}

/* Cztery wartości, pasek ikon (06.09.2026, wzorzec Lumiry). Sam wzorzec
   ikona-w-kółku co .krok wyżej (kroki-wizyty.php), cztery kolumny zamiast
   trzech, panel ciemny zamiast zmiennego tla. Globalny komponent, dane z
   Ustawień strony (cechy-cztery.php). */
.cechy-cztery {
  display: grid;
  grid-template-columns: repeat(4, minmax(0,1fr));
  gap: var(--space-7);
}
.cechy-cztery__pozycja { text-align: center; display: flex; flex-direction: column; align-items: center; }
.cechy-cztery__ikona {
  width: 64px; height: 64px;
  border-radius: 50%;
  border: 1px solid var(--line-on-dark);
  display: grid; place-items: center;
  margin-bottom: 16px;
}
.cechy-cztery__ikona svg { width: 26px; height: 26px; color: var(--accent-ctx); }
.cechy-cztery__pozycja h3 { font-size: 17px; margin-bottom: 6px; }
.cechy-cztery__pozycja p { font-size: 14px; color: var(--text-on-dark-muted); max-width: 26ch; }

@media (max-width: 900px) {
  .cechy-cztery { grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--space-5) var(--space-4); }
}
@media (max-width: 480px) {
  .cechy-cztery { grid-template-columns: 1fr; }
}

/* ==========================================================================
   6. Opinie
   ========================================================================== */
/* Odstep pod naglowkiem zmniejszony z --space-9 na --space-7 (24.09.2026),
   zeby pasowal do .opinie__stopka margin-top nizej -- gora sekcji wygladala
   na cieższa niz dol przy tej samej sekcji, ten sam problem na mobile bo
   --space-9/--space-7 nie maja osobnej wartosci pod 767px. */
.opinie__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
/* D-HOME-POPRAWKI 04.09: slider poziomy zamiast asymetrycznej siatki
   (jedna karta na dwa rzedy plus dwie stackowane), na zyczenie Jakuba -
   "przerzucamy cały czas takie trzy bloki w bok". Scroll-snap zamiast
   biblioteki: zero zaleznosci, dziala tez bez JS (przewijanie palcem/
   trackpadem), JS (main.js) dokleja tylko strzalki i wygladzone przewijanie
   o jedna karte. */
.opinie__slider { position: relative; z-index: 1; }
.opinie__track {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.opinie__track::-webkit-scrollbar { display: none; }
.opinia {
  border: 1px solid var(--line-on-dark);
  border-radius: var(--radius-md);
  padding: 28px 26px;
  flex: 0 0 clamp(260px, 34vw, 420px);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
}
/* Runda mobile 11.09.2026: podstrona z jedna opinia (np. Kobido) pokazywala
   karte 260px z pustym pasem po prawej. Jedyna karta bierze cala szerokosc. */
.opinie__track .opinia:only-child { flex-basis: 100%; }
/* Kolko z inicjalem zdjete (AI-slop audyt 10.09.2026), zostaje samo nazwisko. */
.opinia__autor { margin-bottom: 18px; }
.opinia__nazwisko { font-family: var(--font-display); font-size: 16px; border-bottom: 1px solid var(--line-on-dark); padding-bottom: 2px; }
.opinia__cytat { font-size: 14.5px; color: var(--text-on-dark-muted); position: relative; }
.opinie__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--clr-dark-2);
  border: 1px solid var(--line-on-dark);
  display: grid; place-items: center;
  color: var(--text-on-dark);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* [hidden] sam nie wygrywa z .opinie__nav{display:grid} (ta sama
   specyficznosc, arkusz autora bije UA), wiec dopisane jawnie - JS
   (main.js, "przelicz") chowa strzalki/kropki gdy wszystkie karty
   mieszcza sie na raz (06.09.2026). */
.opinie__nav[hidden], .opinie__kropki[hidden] { display: none; }
.opinie__nav:hover { background: var(--surface-dark); border-color: var(--accent-ctx); }
.opinie__nav svg { width: 18px; height: 18px; }
/* Feedback Jakuba 06.09.2026: strzałki na left:0/right:0 siedziały NA
   pierwszej/ostatniej karcie, nie obok niej. Przesunięte w gutter kontenera
   (połowa własnej szerokości na zewnątrz krawędzi toru), sekcja jest ciemna
   dookoła więc nie wystaje na jasne tło. */
.opinie__nav--prev { left: -22px; }
.opinie__nav--prev svg { transform: scaleX(-1); }
.opinie__nav--next { right: -22px; }
.opinie__stopka { margin-top: var(--space-7); position: relative; z-index: 1; }

/* Kropki, D-OPINIE-MANDALA (06.09.2026): wzorzec Studio Mandala mial
   strzalki+kropki na kazdej szerokosci (tylko zmniejszone na 375), Magnolia
   mialo same strzalki i gubila je ponizej 900px, czyli mobile zostawal bez
   zadnego widocznego afordansu ze to karuzela. Kropki dzialaja na wszystkich
   szerokosciach, strzalki teraz tez, tylko mniejsze ponizej 900px zamiast
   znikac (patrz media query nizej). */
.opinie__kropki {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: var(--space-5);
  position: relative;
  z-index: 1;
}
/* A9, sesja poprawkowa 10.09.2026: kropka-przycisk miala obszar klikalny
   rowny widocznej kropce (8px), daleko ponizej progu 40px. ::after
   niewidoczny (bez tla) rozszerza hitbox do 40x40 wzgledem samego
   przycisku, position:absolute wiec nie wchodzi do layoutu, gap i
   wyglad kropek zostaja dokladnie takie same jak dzis. */
.opinie__kropka {
  position: relative;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--line-on-dark);
  border: 0; padding: 0; cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.opinie__kropka::after { content: ""; position: absolute; inset: -16px; }
.opinie__kropka:hover { background: var(--accent-ctx); }
.opinie__kropka[aria-current="true"] { background: var(--accent-ctx); transform: scale(1.35); }

@media (max-width: 900px) {
  .opinie__nav { width: 36px; height: 36px; }
  .opinie__nav svg { width: 15px; height: 15px; }
  .opinie__nav--prev { left: -14px; }
  .opinie__nav--next { right: -14px; }
}

/* ==========================================================================
   7. CTA końcowe
   ========================================================================== */
/* overflow:hidden wlasny od 06.09.2026 (D-PLASKIE-SEKCJE): dawniej dawal go
   .panel, ktory po tej zmianie juz go nie niesie. */
.cta-koncowe { position: relative; overflow: hidden; min-height: 420px; display: flex; align-items: center; }
.cta-koncowe__bg { position: absolute; inset: 0; z-index: 0; }
.cta-koncowe__bg img { width: 100%; height: 100%; object-fit: cover; }
.cta-koncowe__bg::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(27,23,19,.92) 0%, rgba(27,23,19,.72) 42%, rgba(27,23,19,.15) 78%);
}
/* Wyśrodkowane w boxie (08.09.2026, Jakub): blok byl przypiety do lewej
   krawedzi kontenera, cala reszta bleed-zdjecia pusta po prawej. */
.cta-koncowe__tresc { position: relative; z-index: 1; max-width: 480px; padding-block: 56px; margin-inline: auto; text-align: center; }
.cta-koncowe__tresc .divider { margin-inline: auto; }
.cta-koncowe__mikro { font-size: 13.5px; color: var(--text-on-dark-muted); margin-top: var(--space-5); }
/* Telefon jako drugorzedny link pod glownym CTA (08.09.2026, D-SKLEP-WG-MANDALI).
   --accent-ctx, nie --accent: goly --accent na --surface-dark ma tylko 2.8:1
   kontrastu (design-system.md, "NIE UZYWAC"), ta sama zasada co eyebrow na
   panel--ciemny gdzie indziej w tym pliku. */
.cta-koncowe__drugi {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-5);
  color: var(--accent-ctx);
  font-size: 14px;
  font-weight: 500;
}
.cta-koncowe__drugi svg { width: 15px; height: 15px; }
.cta-koncowe__drugi:hover { color: var(--text-on-dark); }

@media (max-width: 900px) {
  .cta-koncowe { min-height: 360px; }
  .cta-koncowe__bg::after { background: linear-gradient(180deg, rgba(27,23,19,.55) 0%, rgba(27,23,19,.92) 65%); }
  .cta-koncowe__tresc { max-width: none; }
  .cta-koncowe .btn { width: 100%; }
}

/* ==========================================================================
   8. Stopka
   ========================================================================== */
.stopka__wnetrze {
  display: grid;
  /* 11.09.2026, feedback Jakuba: "Popularne zabiegi" obok "Kategorie", nie
     pod spodem w tej samej kolumnie. Cztery kolumny zamiast trzech (marka
     dalej szersza, pozostałe trzy węższe niż wcześniej, bo dzielą miejsce
     dawnej pojedynczej kolumny środkowej). */
  grid-template-columns: 1.3fr 0.9fr 0.9fr 0.8fr;
  gap: var(--space-9) var(--space-7);
  padding-block: var(--space-section);
}
.stopka h3 {
  font-family: var(--font-text);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-ctx);
  font-weight: 500;
  margin-bottom: var(--space-5);
}
.stopka__marka { display: flex; flex-direction: column; gap: 14px; }
.stopka__marka p { font-size: 14px; color: var(--text-on-dark-muted); }
.stopka__social { display: flex; gap: 14px; }
.stopka__social-ikona { display: flex; color: var(--text-on-dark-muted); padding-block: 10px; margin-block: -10px; }
.stopka__social-ikona svg { width: 18px; height: 18px; }
.stopka__social-ikona:hover { color: var(--accent-ctx); }
.stopka address { font-style: normal; font-size: 14px; display: flex; flex-direction: column; gap: 8px; }
.stopka address a { text-decoration: underline; text-decoration-color: var(--line-on-dark); }
.stopka ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 14px; }
/* A9, sesja poprawkowa 10.09.2026: link 14px/20px wysokosci byl ponizej progu
   40px dotykowego. Padding plus rownowazny ujemny margines rozszerza obszar
   klikalny bez ruszania odstepu miedzy wierszami listy (gap liczy sie od
   krawedzi <li>, nie <a>, wiec kompensacja zostaje wewnatrz <a>). */
.stopka ul a { display: inline-flex; align-items: center; text-decoration: none; padding-block: 10px; margin-block: -10px; }
.stopka ul a:hover { color: var(--accent-ctx); }
.stopka__prawne a { display: inline-flex; align-items: center; padding-block: 10px; margin-block: -10px; }

/* J6/J7, sesja poprawkowa 10.09.2026: kolumna "Prawne" zdjeta z siatki
   powyzej (4 -> 3 kolumny), ten sam link teraz stoi w dolnym pasku bez
   wlasnego naglowka, obok copyright (lewo) i credit+IG Jakuba (prawo).
   Grid zamiast flex space-between, zeby srodkowa kolumna byla realnie
   wysrodkowana niezaleznie od szerokosci lewej/prawej tresci. */
.stopka__dol {
  border-top: 1px solid var(--line-on-dark);
  padding-block: 22px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  font-size: 13px;
  color: var(--text-on-dark-muted);
}
.stopka__dol a { text-decoration: none; }
.stopka__dol a:hover { color: var(--accent-ctx); }
.stopka__copyright { margin: 0; }
/* 11.09.2026, feedback Jakuba: Regulamin/Polityka miały stać w jednej linii,
   ale renderowały się jedno pod drugim mimo display:flex tutaj. Przyczyna:
   ".stopka ul" (linia wyżej w pliku, specyficzność klasa+element) ustawia
   flex-direction: column i wygrywa z samym ".stopka__prawne" (specyficzność
   jedna klasa), niezależnie od kolejności w pliku. ".stopka__dol" w
   selektorze podbija specyficzność do dwóch klas, wygrywa. */
.stopka__dol .stopka__prawne { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: row; gap: 20px; justify-self: center; }
.stopka__credit { margin: 0; display: flex; align-items: center; gap: 14px; justify-self: end; }
.stopka__ig { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; margin: -13px -13px -13px 0; color: inherit; }
.stopka__ig svg { width: 18px; height: 18px; }
.stopka__ig:hover { color: var(--accent-ctx); }

@media (max-width: 900px) {
  /* Tablet 768-900: dwie kolumny, marka na cala szerokosc (wzorzec Dominiki Tyl). */
  .stopka__wnetrze { grid-template-columns: 1.15fr 1fr; gap: var(--space-7) var(--space-5); }
  .stopka__marka { grid-column: 1 / -1; }

  .stopka__dol { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 14px; }
  .stopka__prawne, .stopka__credit { justify-self: center; }
}
@media (max-width: 767px) {
  /* Runda mobile 11.09.2026, decyzja Jakuba: telefon = jedna kolumna, trzy
     listy (Kategorie, Popularne zabiegi, Strony) jedna pod druga, kazda ze
     swoim naglowkiem. Wczesniejszy argument "poltora ekranu linkow" znany
     i swiadomie odrzucony. */
  .stopka__wnetrze { grid-template-columns: 1fr; gap: var(--space-7); }
  .stopka__marka { grid-column: auto; }
  .stopka__kolumna { grid-column: auto; }
}

/* 9. Sticky pasek telefonu (.pasek-telefon-mobile) zdjety 11.09.2026 w rundzie
   mobile na decyzje Jakuba; CTA zyje w szufladzie menu i w sekcjach. */

/* ==========================================================================
   PODSTRONY KATEGORII (wzorzec dla wszystkich pięciu kategorii masaży).
   Zbudowane pierwszy raz na /masaze/lecznicze, 03.09.2026.
   ========================================================================== */

/* Breadcrumb + numer kategorii, góra hero podstrony */
.podstrona-breadcrumb {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: var(--space-9);
  position: relative;
  z-index: 1;
}
.podstrona-breadcrumb__sciezka { font-size: 13.5px; color: var(--text-on-light-muted); white-space: nowrap; }
.podstrona-breadcrumb__sciezka a { text-decoration: none; }
.podstrona-breadcrumb__sciezka a:hover { color: var(--accent); }
.podstrona-breadcrumb__sciezka span[aria-current] { color: var(--text-on-light); }
@media (max-width: 767px) {
  .podstrona-breadcrumb { flex-wrap: wrap; gap: 10px; margin-bottom: var(--space-7); }
  .podstrona-breadcrumb__sciezka { white-space: normal; }
}

/* Hero podstrony: split 50/50, tekst + zdjęcie w jednym rzędzie (Blok F5,
   06.09.2026, decyzja 8 planu nocnego). Wartość 0.85fr zamiast 1fr na
   drugiej kolumnie: wzorzec IKHAKIMA (1fr 1.05fr) i Dominika Tyl (1fr 0.7fr)
   dają zdjęciu mniej niż połowę, tu pośrodku między nimi. */
.hero-podstrony__wnetrze {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,0.85fr);
  gap: var(--space-9);
  align-items: center;
  position: relative;
  z-index: 1;
}
.hero-podstrony__tresc { display: flex; flex-direction: column; justify-content: center; }
.hero-podstrony__tresc .lead { font-size: var(--fs-lead); max-width: 46ch; margin-bottom: var(--space-7); }
.hero-podstrony__cta-grupa { display: flex; gap: 14px; flex-wrap: wrap; }

/* Trzy krótkie korzyści pod CTA (06.09.2026, wzorzec Lumiry, tylko zabieg). */
.hero-podstrony__korzysci {
  display: flex;
  gap: var(--space-7);
  margin-top: var(--space-7);
  flex-wrap: wrap;
}
.hero-podstrony__korzysc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  max-width: 15ch;
  font-size: 13.5px;
  color: var(--text-on-light-muted);
}

/* Wariant bez zdjęcia (podstrony bez hero_image: dziś żadna, zostaje jako
   siatka bezpieczeństwa). Bez tego druga kolumna zostawiałaby pustą
   szczelinę po prawej. */
.hero-podstrony__wnetrze--pelna { grid-template-columns: 1fr; }
.hero-podstrony__wnetrze--pelna .hero-podstrony__tresc { max-width: 640px; }

/* Wariant "sklep" (08.09.2026, wzorzec Mandali, /pakiety i /vouchery,
   D-SKLEP-WG-MANDALI): jedna kolumna wyśrodkowana, nie lewa jak --pelna.
   Panel ciemny wymuszony w PHP (klasa_panel), tu tylko układ tekstu. */
.hero-podstrony__wnetrze--sklep {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
}
.hero-podstrony__wnetrze--sklep .hero-podstrony__tresc {
  max-width: 720px;
  align-items: center;
}
.hero-podstrony__wnetrze--sklep .hero-podstrony__tresc .lead { margin-inline: auto; }
/* Breadcrumb jest rodzeństwem .wnetrze (poza gridem), zostaje lewy jak na
   pozostałych 15 stronach -- "breadcrumb zostaje" w planie znaczy bez
   zmiany, nie wymuszone centrowanie. */

.hero-podstrony__foto {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4/5;
  position: relative;
  z-index: 1;
}
.hero-podstrony__foto img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  /* Jedna kolumna, zdjęcie POD tekstem: kolejność naturalna DOM (tekst
     pierwszy w markupie), żeby H1 był pierwszą rzeczą na ekranie. IKHAKIMA
     stawia zdjęcie nad tekstem, ale tam hero nie ma okruszków nad H1. */
  .hero-podstrony__wnetrze { grid-template-columns: 1fr; }
  .hero-podstrony__foto { margin-top: var(--space-7); aspect-ratio: 4/3; }
}

/* Hero "bleed" (06.09.2026, wzorzec Lumiry; rozszerzony 08.09.2026 na
   podstrony kategorii, wzorzec Mandala mandala-warszawa.pl/oferta-twarz,
   decyzja Jakuba): zdjęcie na całą szerokość jako tło, treść na wierzchu.
   Wcięty i zaokrąglony jak hero home (.sekcja--hero.panel), drugi i
   ostatni świadomy wyjątek od D-PLASKIE-SEKCJE. min-height obniżony z
   pierwotnych 620/520 -- referencja Mandali trzyma box wyraźnie płaski
   względem szerokości, nie pełnoekranowy. */
.sekcja--hero-bleed {
  position: relative;
  overflow: hidden;
  padding-block: 0;
  min-height: 400px;
  display: flex;
  /* 11.09.2026, feedback Jakuba: flex-end przyklejał .kontener (breadcrumb +
     wiersz tekst/karta) do DOŁU panelu. Panel ma min-height 400px, więc gdy
     treść jest krótsza niż 400px, CAŁY nadmiar lądował nad treścią (odstęp
     od góry), a pod spodem zostawał tylko stały padding-bottom .kontener
     (32px) -- zmierzone: 87-102px góra vs 32px dół, ten sam wzorzec na
     wszystkich stronach z tym panelem (kategorie, zabiegi, sklep). center
     dzieli nadmiar po równo góra/dół niezależnie od wysokości treści. */
  align-items: center;
  margin-inline: var(--kontener-x);
  max-width: calc(var(--container) + 312px - 2 * var(--kontener-x));
  border-radius: var(--radius-panel);
}
.hero-bleed__bg { position: absolute; inset: 0; z-index: 0; }
.hero-bleed__bg img { width: 100%; height: 100%; object-fit: cover; }
.hero-bleed__nakladka {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(27,23,19,.4) 0%, rgba(27,23,19,.9) 100%);
}
.sekcja--hero-bleed .kontener { position: relative; z-index: 1; width: 100%; padding-block: var(--space-7) 32px; }
.sekcja--hero-bleed .podstrona-breadcrumb { margin-bottom: var(--space-5); }

/* Tekst na ciemnym zdjęciu: te same tokeny "on-dark" co reszta serwisu,
   po prostu żaden inny hero dotąd nie potrzebował ich na breadcrumbie/lead/
   korzyściach jednocześnie. Selektory scoped pod .panel--ciemny, więc nie
   dotykają jasnego wariantu hero na pozostałych 15 podstronach. */
.panel--ciemny .podstrona-breadcrumb__sciezka { color: var(--text-on-dark-muted); }
.panel--ciemny .podstrona-breadcrumb__sciezka a:hover { color: var(--accent-ctx); }
.panel--ciemny .podstrona-breadcrumb__sciezka span[aria-current] { color: var(--text-on-dark); }
.panel--ciemny .hero-podstrony__tresc .eyebrow { color: var(--accent-ctx); }
.panel--ciemny .hero-podstrony__tresc .lead { color: var(--text-on-dark-muted); }
.panel--ciemny .hero-podstrony__korzysc { color: var(--text-on-dark-muted); }

@media (max-width: 767px) {
  .sekcja--hero-bleed { min-height: 340px; margin-inline: var(--kontener-x); }
  .sekcja--hero-bleed .kontener { padding-block: 24px 24px; }
}

/* Kiedy warto przyjść: panel ciemny, lista ponumerowana + domknięcie w bloku akcentowym */
.sytuacje__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-9);
  justify-content: space-between;
  padding-bottom: var(--space-7);
  margin-bottom: var(--space-7);
  border-bottom: 1px solid var(--line-on-dark);
  position: relative; z-index: 1;
}
.sytuacje__head h2 { max-width: 14ch; margin-bottom: 0; }
.sytuacje__head-lead { max-width: 34ch; font-size: 15px; color: var(--text-on-dark-muted); align-self: center; }

.sytuacje__grid {
  display: grid;
  grid-template-columns: minmax(0,1fr) 300px;
  gap: var(--space-9);
  align-items: stretch;
  position: relative; z-index: 1;
}
.sytuacje__lista { display: flex; flex-direction: column; }
.sytuacja-item {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 20px 0;
  border-top: 1px solid var(--line-on-dark);
}
.sytuacja-item:first-child { border-top: 0; padding-top: 4px; }
.sytuacja-item p { margin: 0; font-size: 15.5px; color: var(--text-on-dark); }

.sytuacje__domkniecie {
  background: var(--accent);
  border-radius: var(--radius-md);
  padding: 30px 28px;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
  justify-content: center;
}
.sytuacje__domkniecie p { margin: 0; font-size: 15px; color: var(--text-on-dark); line-height: 1.6; }
/* S6, 04.09.2026: CTA opcjonalny (sytuacje_cta_label/url). Blok tla ma juz
   kolor --accent, wiec domyslny obrys .btn--secondary (rgba w tonie
   terakoty, myslany pod ciemny panel) ginie na tym samym tonie. Nadpisujemy
   sam obrys tokenem kremowym, reszta wariantu (tlo, kolor tekstu) zostaje. */
.sytuacje__domkniecie .btn { flex: none; }
.sytuacje__domkniecie .btn--secondary { border-color: var(--text-on-dark); }

@media (max-width: 900px) {
  .sytuacje__head { flex-direction: column; gap: var(--space-4); border-bottom: 0; padding-bottom: 0; }
  .sytuacje__grid { grid-template-columns: 1fr; }
}

/* Dyplom, wcześnie: panel jasny, kompaktowy pas dowodu */
.dyplom-pas {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-9);
  position: relative; z-index: 1;
}
.dyplom-pas__tekst { max-width: 56ch; }
.dyplom-pas__tekst p { font-size: 15px; margin-bottom: var(--space-5); }
.dyplom-pas__foto {
  flex: none;
  width: 180px;
  aspect-ratio: 4/3;
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-karta);
}
.dyplom-pas__foto img { width: 100%; height: 100%; object-fit: cover; }

/* Wariant ciemny (G2, 06.09.2026, feature-bar $args['tlo']). H2/p dziedzicza
   var(--text-on-dark) z .panel--ciemny, ale .eyebrow i .link-strzalka maja
   wlasny color:var(--accent) niezalezny od kontekstu, wiec potrzebuja
   nadpisania na --accent-ctx, ten sam wzorzec co .panel--ciemny .kroki__head
   .eyebrow nizej. */
.panel--ciemny .dyplom-pas .eyebrow,
.panel--ciemny .dyplom-pas .link-strzalka { color: var(--accent-ctx); }

@media (max-width: 900px) {
  .dyplom-pas { flex-direction: column; align-items: flex-start; gap: var(--space-7); }
  .dyplom-pas__foto { width: 100%; max-width: 260px; }
}

/* Listing zabiegów tej kategorii (D-TRZY-WARSTWY, 04.09.2026). Zastępuje
   dwa osobne bloki sprzed replanu: .cennik (rail + tabela wariantów) i
   .tech-wiersz (foto + tekst, bez ceny). Jeden wiersz robi teraz obie role:
   foto, tytuł, meta czas+cena od, opis, opcjonalny link. */
.listing-zabiegow__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.listing-zabiegow__lista { position: relative; z-index: 1; }
/* Wiersz, przebudowany 06.09.2026 na wzorzec Lumiry: trzy kolumny (foto,
   treść, akcja) zamiast dwóch, cena/czas/przycisk przeniesione z góry
   treści do osobnej kolumny po prawej. */
.listing-wiersz {
  display: grid;
  grid-template-columns: 220px minmax(0,1fr) 180px;
  gap: var(--space-7);
  align-items: center;
  padding: var(--space-7) 0;
  border-top: 1px solid var(--line-on-light);
}
.listing-wiersz:first-child { border-top: 0; padding-top: 0; }
.listing-wiersz:last-child { padding-bottom: 0; }
.listing-wiersz__foto { border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 4/3; }
.listing-wiersz__foto img { width: 100%; height: 100%; object-fit: cover; }
/* Wiersz bez zdjecia (AI-slop audyt 10.09.2026: ikona magnolii jako placeholder
   zdjeta) renderuje sie bez kolumny foto, tresc i akcja dostaja wiecej miejsca. */
.listing-wiersz--bez-foto { grid-template-columns: minmax(0,1fr) 180px; }
.listing-wiersz__plakietka {
  display: inline-block;
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 3px 10px;
  margin-bottom: 8px;
}
.listing-wiersz__tresc h3 { margin-bottom: 6px; }
.listing-wiersz__tresc p { font-size: 14.5px; max-width: 62ch; margin-bottom: 10px; }
.listing-wiersz__akcja {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  text-align: right;
}
/* 08.09.2026 (Jakub): cena i czas obok siebie, nie jedno pod drugim. */
.listing-wiersz__cena-czas { display: flex; align-items: baseline; gap: 12px; }
.listing-wiersz__cena { font-family: var(--font-display); font-size: 21px; color: var(--accent); white-space: nowrap; }
.listing-wiersz__czas {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-on-light-muted);
  white-space: nowrap;
}
.listing-wiersz__czas svg { width: 14px; height: 14px; flex: none; }
.listing-wiersz__akcja .btn { white-space: nowrap; }

@media (max-width: 900px) {
  /* 25.09.2026: gap: var(--space-7) (40px) mial sens jako odstep MIEDZY
     KOLUMNAMI foto|tresc|akcja w ukladzie 3-kolumnowym desktopu. Po zwinieciu
     do grid-template-columns:1fr ten sam gap staje sie pionowym odstepem
     MIEDZY KAZDA SEKCJA z osobna (foto->tresc, tresc->akcja), wygladajac jak
     pusta dziura miedzy "Szczegoly" a cena/przyciskiem Zadzwon. Zwezone do
     --space-4 tylko na tym zwinietym ukladzie, desktop bez zmian. */
  .listing-wiersz { grid-template-columns: 1fr; gap: var(--space-4); }
  .listing-wiersz__akcja { align-items: flex-start; text-align: left; flex-direction: row; flex-wrap: wrap; }
}
@media (max-width: 600px) {
  .listing-wiersz__foto { aspect-ratio: 16/9; }
}

/* Karta cenowa, pojedynczy zabieg. Przebudowana 08.09.2026 (zgłoszenie
   Jakuba): z poziomej belki pod hero na pionową kartę w prawej kolumnie
   hero-bleed (hero-podstrony.php, modyfikator --karta). Stare klasy
   .karta-cenowa-sekcja i pozioma odmiana .karta-cenowa__item/lista/akcje
   skasowane calkowicie razem z markupem, ktory je uzywal (jedyny konsument
   tego komponentu to page-zabieg.php). */
/* 11.09.2026, feedback Jakuba: tekst (H1+lead, krótki) i karta (cennik albo
   CTA, zawsze wyższa) startowały od tej samej górnej krawędzi
   (align-items: start), więc kolumna tekstu zostawiała pusty pas pod sobą,
   zanim karta się kończyła. Pierwsza próba (align-items: center tylko dla
   trybu CTA) naprawiła pas, ale rozjechała górne krawędzie kolumn (tekst
   wjeżdżał w dół o połowę różnicy wysokości, karta zostawała u góry) --
   drugi problem, zgłoszony zaraz potem. align-items: stretch naprawia oba
   naraz: obie kolumny dostają pełną wysokość wiersza (górne krawędzie
   zawsze równe, niezależnie od tego, o ile karta jest wyższa), a
   .hero-podstrony__tresc ma już justify-content: center (linia niżej w
   pliku), więc krótszy tekst sam się centruje w tej wysokości zamiast
   zostawiać pas WYŁĄCZNIE pod sobą. Jeden mechanizm dla obu trybów karty
   (cennik i CTA), modyfikator --karta-cta niepotrzebny, usunięty. */
.hero-podstrony__wnetrze--karta {
  grid-template-columns: minmax(0,1fr) minmax(300px, 360px);
  align-items: stretch;
  /* J10, 11.09.2026: position:static nadpisuje relative z bazowej klasy
     .hero-podstrony__wnetrze -- inaczej TO jest containing blockiem dla
     .hero-podstrony__karta absolute (patrz niżej), a nie .kontener, i karta
     centruje się w wierszu (który jest już prawie symetryczny), a nie w
     panelu. Bez straty stackingu: .kontener ma już własny z-index:1 w tym
     kontekście (scoped .sekcja--hero-bleed .kontener), więc treść nadal
     stoi nad tłem hero-bleed bez własnej stacking context wiersza. */
  position: static;
}
.hero-podstrony__karta { position: relative; z-index: 1; }
/* minmax(300px,...) na drugiej kolumnie ma tę samą specyficzność (jedna
   klasa) co ".hero-podstrony__wnetrze{grid-template-columns:1fr}" w media
   query wcześniej w pliku (linia ok. 1057): przy równej specyficzności
   wygrywa kolejność w źródle, a ta reguła stoi PO tamtej, więc bez tego
   override 300px+ kolumna przetrwałaby na 375px i wypychała przewijanie
   w bok. Własna media query, nie poleganie na przypadkowej kolejności. */
@media (max-width: 900px) {
  /* Runda mobile 11.09.2026: lead (margin-bottom 40) plus gap siatki (64)
     dawaly 104px pustego tla miedzy tekstem a karta. Gap 24, razem 64. */
  .hero-podstrony__wnetrze--karta { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* J10, 11.09.2026: karta miała nierówny odstęp od góry/dołu PANELU
   (.sekcja--hero-bleed), nie od wiersza siatki -- winny jest .kontener,
   którego góra niesie padding-top + breadcrumb (~100px), a dół tylko
   padding-bottom (32px), więc karta wewnątrz wiersza siadała asymetrycznie
   mimo że sam wiersz jest dobrze wycentrowany w kolumnie tekstu. Jakub nie
   chce ruszać tych paddingów ani breadcrumba (są tam z innego powodu, patrz
   .sekcja--hero-bleed .kontener wyżej). Naprawa: karta wychodzi z wiersza
   gridu i centruje się PIONOWO niezależnie, względem .kontener -- co jest
   równoważne centrowaniu względem całego panelu, bo panel centruje
   .kontener flexem jako jedną całość (align-items:center na
   .sekcja--hero-bleed), więc środek .kontener i środek panelu to ten sam
   punkt. Kolumna karty w gridzie zostaje pusta (grid-template-columns
   niezmienione), tylko rezerwuje miejsce, żeby kolumna tekstu się nie
   rozjechała. Tylko desktop: na mobile (media query wyżej, 1fr) karta
   wraca do zwykłego przepływu pod tekstem. */
@media (min-width: 901px) {
  .hero-podstrony__wnetrze--karta .hero-podstrony__karta {
    position: absolute;
    top: 50%;
    right: 0;
    width: 360px;
    transform: translateY(-50%);
  }
}

.karta-cenowa--hero {
  background: var(--surface-cream);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-karta);
  padding: 28px 30px;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.karta-cenowa--hero .karta-cenowa__label { font-size: var(--fs-small); color: var(--text-on-light-muted); text-transform: uppercase; letter-spacing: .08em; }
/* J9, 11.09.2026: tryb CTA (podstrony kategorii, bez cennika). Ten sam
   jasny background karty co reszta, tylko nagłówek+zdanie zamiast listy. */
.karta-cenowa--hero .karta-cenowa__heading { font-family: var(--font-display); font-size: var(--fs-display-4); color: var(--text-on-light); margin: 0; }
.karta-cenowa--hero .karta-cenowa__text { font-size: var(--fs-body); color: var(--text-on-light-muted); margin: 0; }
.karta-cenowa--hero .karta-cenowa__lista { display: flex; flex-direction: column; gap: 4px; }
.karta-cenowa--hero .karta-cenowa__item {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-top: 12px;
  text-align: left;
}
.karta-cenowa--hero .karta-cenowa__item:first-child { padding-top: 0; }
.karta-cenowa--hero .karta-cenowa__item + .karta-cenowa__item { border-top: 1px solid var(--line-on-light); }
.karta-cenowa--hero .karta-cenowa__item-info { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.karta-cenowa--hero .karta-cenowa__plakietka {
  position: static;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--surface-white);
  background: var(--accent);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.karta-cenowa--hero .karta-cenowa__wariant-etykieta { font-size: 13.5px; color: var(--text-on-light); }
.karta-cenowa--hero .karta-cenowa__czas { font-size: 13px; color: var(--text-on-light-muted); }
.karta-cenowa--hero .karta-cenowa__cena { font-family: var(--font-display); font-size: 24px; color: var(--accent); flex: none; }
.karta-cenowa--hero .karta-cenowa__akcje { display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--line-on-light); padding-top: var(--space-5); }
.karta-cenowa--hero .karta-cenowa__akcje .btn { width: 100%; justify-content: center; }

@media (max-width: 900px) {
  .karta-cenowa--hero { margin-top: var(--space-7); }
}

/* FAQ, akordeon natywny <details> */
.faq__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.faq-lista { position: relative; z-index: 1; }
.faq-item { border-bottom: 1px solid var(--line-on-dark); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 2px;
  font-family: var(--font-display);
  font-size: 19px;
  color: var(--text-on-dark);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::marker { content: ""; }
/* Ikonka +/- rysowana jako dwie belki wyśrodkowane bezwzględnie (position:50%/50%
   + translate(-50%,-50%)), nie jako glif fontu w ::before. Glif "+" ma własne
   metryki (optyczny środek wyżej niż geometryczny), więc grid place-items:center
   nigdy nie centrował go idealnie względem kółka. Belki są prostokątami bez
   metryk fontu, więc centrują się dokładnie. Zgłoszone 08.09.2026. */
.faq-item__toggle {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid var(--accent-ctx);
  position: relative;
  color: var(--accent-ctx);
}
.faq-item__toggle::before,
.faq-item__toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
}
.faq-item__toggle::before { width: 10px; height: 1.5px; }
.faq-item__toggle::after { width: 1.5px; height: 10px; }
.faq-item[open] .faq-item__toggle { background: var(--accent); border-color: var(--accent); color: var(--text-on-dark); }
.faq-item[open] .faq-item__toggle::after { display: none; }
.faq-item__odpowiedz { padding: 0 2px var(--space-7); font-size: 14.5px; color: var(--text-on-dark-muted); max-width: 72ch; }

/* Wariant "jasny" (08.09.2026, wzorzec Mandali, /pakiety i /vouchery,
   D-SKLEP-WG-MANDALI): białe karty na kremowym tle zamiast linii na
   ciemnym. Kolory tekstu jawnie nadpisane (K1, lekcje-techniczne): base
   .faq-item summary/__odpowiedz i .faq-item__toggle mają twarde kolory
   dopasowane do panel--ciemny-2, na panel--jasny bez override tekst
   zostałby jasny na jasnym. */
.faq-lista--jasny { display: flex; flex-direction: column; gap: 10px; }
.faq-item--karta {
  border-bottom: 0;
  background: var(--surface-white);
  border-radius: var(--radius-md);
}
.faq-item--karta summary { color: var(--text-on-light); padding-inline: 22px; }
.faq-item--karta .faq-item__odpowiedz { color: var(--text-on-light-muted); padding-inline: 22px; }
.faq-item--karta .faq-item__toggle { border-color: var(--accent); color: var(--accent); }
.faq-item--karta[open] .faq-item__toggle { background: var(--accent); border-color: var(--accent); color: var(--text-on-dark); }

@media (max-width: 767px) {
  .faq-item summary { font-size: 17px; }
}

/* ==========================================================================
   BLOK D, komponenty bez gustu (04.09.2026): karty-grid, blok-tekst,
   voucher-karta, siatka-certyfikatow. hero-podstrony i feature-bar reużywają
   klasy już zdefiniowane wyżej, bez zmiany.
   ========================================================================== */

/* Karty grid, uniwersalny. Karta sama w sobie to .kafel-zabieg, już zmierzony
   na Home, celowo bez zmiany. Tu tylko wrapper i modyfikatory kolumn. */
.karty-grid__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.karty-grid__head .lead { font-size: var(--fs-lead); }

.karty-grid {
  display: grid;
  gap: 24px;
  position: relative;
  z-index: 1;
}
.karty-grid--2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.karty-grid--3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.karty-grid--4 { grid-template-columns: repeat(4, minmax(0,1fr)); }

@media (max-width: 900px) {
  .karty-grid--2, .karty-grid--3, .karty-grid--4 { grid-template-columns: 1fr; }
}

/* Popularne zabiegi, slider poziomy (hub /masaze, 06.09.2026, zyczenie
   Jakuba). Ten sam silnik co .opinie__slider (scroll-snap + strzalki +
   kropki, main.js jdbKaruzela()), ale sekcja stoi na panel--jasny wiec
   nav/kropki dostaja jasny wariant kolorow zamiast --line-on-dark/
   --text-on-dark. Karta zostaje .kafel-zabieg bez zmian (ten sam wyglad
   co kafle kategorii i karty-grid), tylko flex-basis zamiast szerokosci
   z grida. */
.popularne-slider { position: relative; z-index: 1; }
.popularne-slider__track {
  display: flex;
  gap: 24px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.popularne-slider__track::-webkit-scrollbar { display: none; }
.popularne-slider__track .kafel-zabieg {
  flex: 0 0 clamp(260px, 30vw, 360px);
  scroll-snap-align: start;
}
.popularne-slider__nav {
  position: absolute;
  top: 35%;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--surface-cream);
  border: 1px solid var(--line-on-light);
  display: grid; place-items: center;
  color: var(--text-on-light);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.popularne-slider__nav[hidden], .popularne-slider__kropki[hidden] { display: none; }
.popularne-slider__nav:hover { background: var(--clr-cream-wash); border-color: var(--accent); }
.popularne-slider__nav svg { width: 18px; height: 18px; }
.popularne-slider__nav--prev { left: -22px; }
.popularne-slider__nav--prev svg { transform: scaleX(-1); }
.popularne-slider__nav--next { right: -22px; }
.popularne-slider__kropki {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: var(--space-5);
  position: relative;
  z-index: 1;
}
/* A9, ten sam wzorzec co .opinie__kropka wyzej: ::after niewidoczny
   rozszerza hitbox do 40x40 bez zmiany layoutu ani wygladu. */
.popularne-slider__kropka {
  position: relative;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--line-on-light);
  border: 0; padding: 0; cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.popularne-slider__kropka::after { content: ""; position: absolute; inset: -16px; }
.popularne-slider__kropka:hover { background: var(--accent); }
.popularne-slider__kropka[aria-current="true"] { background: var(--accent); transform: scale(1.35); }

@media (max-width: 900px) {
  .popularne-slider__nav { width: 36px; height: 36px; }
  .popularne-slider__nav svg { width: 15px; height: 15px; }
  .popularne-slider__nav--prev { left: -14px; }
  .popularne-slider__nav--next { right: -14px; }
}

/* Blok tekstu, prosty: eyebrow + H2 opcjonalny + akapity. */
.blok-tekst { max-width: 72ch; position: relative; z-index: 1; }
.blok-tekst__tresc p { font-size: 15px; }

/* "Jak wygląda" + "Korzyści", dwie kolumny (06.09.2026, wzorzec Lumiry,
   zabieg-korzysci.php). Lewa jasna (.blok-tekst reużyty bez zmian), prawa
   karta ciemna z listą i opcjonalnym zdjęciem na dole. */
.zabieg-korzysci {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,0.9fr);
  gap: var(--space-9);
  align-items: start;
}
.zabieg-korzysci--jedna { grid-template-columns: 1fr; max-width: 640px; }
.zabieg-korzysci__karta {
  border-radius: var(--radius-panel);
  padding: var(--space-7);
}
.zabieg-korzysci__karta h3 { text-align: center; margin-bottom: var(--space-5); }
.zabieg-korzysci__lead { text-align: center; color: var(--text-on-dark-muted); font-size: 14.5px; margin-bottom: var(--space-5); }
/* Ptaszki zdjete (AI-slop audyt 10.09.2026): kreska zamiast ikony checka w kolku. */
.zabieg-korzysci__lista { list-style: none; margin: 0 0 var(--space-5); padding: 0; display: flex; flex-direction: column; gap: 14px; }
.zabieg-korzysci__lista li { position: relative; padding-left: 22px; font-size: 14.5px; }
.zabieg-korzysci__lista li::before { content: "\2022"; position: absolute; left: 0; color: var(--accent-ctx); }
.zabieg-korzysci__domkniecie { font-size: 14.5px; color: var(--text-on-dark-muted); border-top: 1px solid var(--line-on-dark); padding-top: var(--space-5); margin-bottom: 0; }
.zabieg-korzysci__foto { border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 4/3; margin-top: var(--space-5); }
.zabieg-korzysci__foto img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .zabieg-korzysci { grid-template-columns: 1fr; }
}

/* Opis zabiegu w trzech elementach: dla kogo / cel zabiegu / właściwości
   (D16/D23, 21.09.2026, zabieg-opis.php). Zastępuje w renderze
   .zabieg-korzysci wyżej (CSS tamtej sekcji zostaje, pola ACF mają
   historyczne dane, budowa-strony.md "Copy, które nie pasuje do
   komponentu").

   22.09.2026 (E.4, plan-runda-poprawek-2026-09-22-wieczor.md, Jakub po
   obejrzeniu stagingu): trzy równe kolumny WYCOFANE, wchodzą dwie. Lewa to
   proza na jasnym tle (dla kogo + cel jedno pod drugim), prawa to wyróżniony
   box na ciemnym tle (właściwości). Proporcja kolumn i gap 1:1 z
   .zabieg-korzysci wyżej, kształt boxu 1:1 z .wyroznienie-zabieg (ten sam
   --radius-panel, ten sam padding), żeby nie powstał trzeci wariant ciemnej
   karty w motywie. Zero nowego koloru: box bierze .panel--ciemny, czyli
   --surface-dark, tak samo jak zabieg-wyroznienie.php.

   Sekcja dostaje własny modyfikator na pionowy oddech zamiast domyślnego
   --space-section ("ma być bardziej rozciągnięta", Jakub). Selektor jest
   złożony (.sekcja.sekcja--zabieg-opis), bo .sekcja sama ma regułę mobilną
   niżej w tym pliku i przy jednej klasie wygrałaby kolejnością źródła. */
.zabieg-opis__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }

/* Tło sekcji, 24.09.2026 (Jakub): --clr-cream-wash zamiast dziedziczonego
   --surface-cream z .panel--jasny, zeby ta sekcja odcinala sie wizualnie
   od sasiadow na tym samym tle. Selektor .sekcja.sekcja--zabieg-opis ma
   wyzsza specyficznosc niz .panel--jasny, wiec nadpisuje bez !important. */
.sekcja.sekcja--zabieg-opis {
  background: var(--clr-cream-wash);
  padding-block: calc((var(--space-section) + var(--space-7)) / 2);
}

.zabieg-opis {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,0.9fr);
  gap: var(--space-9);
  align-items: start;
  position: relative;
  z-index: 1;
}
/* Jedna z dwóch kolumn pusta w danych (K9): siatka schodzi do jednej kolumny
   i zwęża się do szerokości czytelnej prozy, zamiast rozciągać jedną kolumnę
   na cały kontener. Ten sam zabieg co .zabieg-korzysci--jedna. */
.zabieg-opis--jedna { grid-template-columns: minmax(0,1fr); max-width: 640px; }

.zabieg-opis__lewa { display: flex; flex-direction: column; gap: var(--space-7); }
.zabieg-opis__item h3,
.zabieg-opis__box h3 {
  font-size: 23px;
  font-weight: 600;
  margin-bottom: 6px;
  padding-bottom: 12px;
  position: relative;
}
/* Wariant B, 24.09.2026 (Jakub, artefakt zabieg-opis-warianty): etykiety
   za male (17px) i zlewaly sie z proza pod nimi. Kreska pod naglowkiem jako
   fizyczny odstepnik, kolor rozny per kontekst tla (jasna lewa kolumna vs
   ciemny box). */
.zabieg-opis__item h3::after,
.zabieg-opis__box h3::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 32px;
  height: 2px;
  background: var(--accent);
}
.zabieg-opis__box h3::after { background: var(--accent-ctx); }
.zabieg-opis__item p { font-size: 14.5px; color: var(--text-on-light-muted); margin: 0; }

.zabieg-opis__box { border-radius: var(--radius-panel); padding: var(--space-9) var(--space-7); }
/* Body na ciemnym tle ma własny ton (--text-on-dark-muted), inaczej
   odziedziczyłby --text-on-light-muted z reguły .zabieg-opis__item p. */
.zabieg-opis__box p { font-size: 14.5px; color: var(--text-on-dark-muted); margin: 0; }

@media (max-width: 900px) {
  .zabieg-opis { grid-template-columns: minmax(0,1fr); gap: var(--space-5); }
  .zabieg-opis__lewa { gap: var(--space-5); }
}

@media (max-width: 767px) {
  .sekcja.sekcja--zabieg-opis { padding-block: calc((var(--sekcja-y-mobile) + var(--space-5)) / 2); }
}

@media (max-width: 600px) {
  .zabieg-opis__box { padding: 32px 20px; }
}

/* Voucher, karta samodzielna: sama .karta-produkt--voucher (Home), w ramce
   o szerokości połowy kontenera, bo to jej naturalny rozmiar zmierzony w duet. */
.voucher-karta__wrap { max-width: 560px; position: relative; z-index: 1; }

@media (max-width: 900px) {
  .voucher-karta__wrap { max-width: none; }
}

/* Lista certyfikatów: tekst, bez ikon i bez kart-w-siatce (AI-slop audyt 10.09.2026, zastapilo grid z ikona dokumentu w kolku i platyt-sume). */
.certyfikaty__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.certyfikaty__head .lead { font-size: var(--fs-lead); }

.certyfikaty-lista {
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
}
.certyfikat-wiersz {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding: 14px 0;
  border-bottom: 1px solid var(--line-on-light);
}
.certyfikat-wiersz:first-child { padding-top: 0; }
.certyfikat-wiersz__foto {
  width: 64px;
  aspect-ratio: 4/3;
  border-radius: var(--radius-md);
  overflow: hidden;
  flex-shrink: 0;
}
.certyfikat-wiersz__foto img { width: 100%; height: 100%; object-fit: cover; }
.certyfikat-wiersz__tytul { font-size: 15px; font-weight: 500; color: var(--text-on-light); margin: 0; }
.certyfikat-wiersz__data { font-size: 13px; color: var(--text-on-light-muted); margin: 0; white-space: nowrap; }

/* ==========================================================================
   Podstrona /kontakt (S7, 05.09.2026). Cztery sekcje nowe: telefon, NAP+mapa,
   formularz, tabela godzin. Sekcje "jak dojechać" (feature-bar) i CTA końcowe
   są reuse bez zmian CSS. */

/* --- Sekcja 02, duzy numer telefonu --------------------------------------- */
.kontakt-telefon__wnetrze {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-5);
  max-width: 640px;
  margin-inline: auto;
  position: relative;
  z-index: 1;
}
.kontakt-telefon__numer {
  font-family: var(--font-display);
  font-size: clamp(38px, 6.5vw, 72px);
  line-height: 1.05;
  color: var(--text-on-dark);
  text-decoration: none;
}
.kontakt-telefon__numer:hover { color: var(--accent-ctx); }
.kontakt-telefon__zdanie { margin: 0; font-size: var(--fs-lead); color: var(--text-on-dark-muted); }
.kontakt-telefon__godziny { margin: 0; font-size: 13.5px; color: var(--text-on-dark-muted); }

/* --- Sekcja 03, NAP z ikonami + mapa --------------------------------------- */
/* 25.09.2026: godziny wydzielone z .kontakt-nap__dane na wlasny grid-item
   (.kontakt-nap__godziny), zeby na mobile mozna bylo ustawic kolejnosc
   dane->mapa->godziny (Jakub: mapa ma isc zaraz po telefonie, godziny pod
   mapa) bez zmianyukladu desktopu (dane+godziny nadal w jednej kolumnie
   obok mapy). */
.kontakt-nap__grid {
  display: grid;
  grid-template-columns: 320px 1fr;
  grid-template-areas: "dane mapa" "godziny mapa";
  gap: var(--space-9) var(--space-9);
  row-gap: var(--space-5);
  align-items: start;
  position: relative;
  z-index: 1;
}
.kontakt-nap__dane { grid-area: dane; }
.kontakt-nap__mapa { grid-area: mapa; }
.kontakt-nap__godziny { grid-area: godziny; }
/* h1 zamiast h2 od 10.09.2026 (hero zdjęte z /kontakt), rozmiar wizualny
   zablokowany na dawnej wartości h2, żeby zmiana tagu nie zmieniła wyglądu. */
.kontakt-nap__dane h1 { font-size: var(--fs-display-3); font-weight: 500; margin-bottom: var(--space-7); }

.dane { list-style: none; margin: 0 0 var(--space-7); padding: 0; }
.dane__pozycja {
  display: grid;
  grid-template-columns: 32px 1fr;
  align-items: center;
  gap: var(--space-4);
  padding-block: 14px;
  border-bottom: 1px solid var(--line-on-light);
  font-size: 15px;
}
.dane__pozycja:first-child { padding-top: 0; }
.dane__pozycja address { font-style: normal; }
.dane__pozycja a { text-decoration: none; }
.dane__pozycja a:hover { color: var(--accent); }
.dane__ikona { display: flex; width: 22px; height: 22px; color: var(--accent); flex: none; }
.dane__ikona svg { width: 100%; height: 100%; }

.kontakt-nap__mapa-ramka {
  aspect-ratio: 4/3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
  background: var(--clr-cream-wash);
}
.kontakt-nap__mapa-ramka iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

@media (max-width: 900px) {
  .kontakt-nap__grid { grid-template-columns: 1fr; grid-template-areas: "dane" "mapa" "godziny"; }
  .kontakt-nap__mapa-ramka { aspect-ratio: 16/10; }
}

/* --- Tabela godzin, reuzyta w sekcji 03 (kompakt) i 06 (pelna) ------------- */
.tabela-godzin { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.tabela-godzin td { padding: 11px 0; border-bottom: 1px solid var(--line-on-light); color: var(--text-on-light-muted); }
.tabela-godzin tr:last-child td { border-bottom: 0; }
.tabela-godzin td:first-child { color: var(--text-on-light); }
.tabela-godzin td:last-child { text-align: right; }
.tabela-godzin--kompakt td { padding: 9px 0; }

/* --- Sekcja 05, formularz --------------------------------------------------- */
/* Uklad (11.09.2026, na zyczenie Jakuba): zdjecie opcjonalne
   (`formularz_image`, ACF), gdy jest -- dwie kolumny, zdjecie po lewej,
   formularz po prawej w kolumnie, ten sam wzorzec gridu co
   .hero-podstrony__wnetrze. Bez zdjecia (--pelna) uklad zostaje dokladnie
   taki jak przed ta zmiana: jedna kolumna, .formularz-kontakt__wrap
   wysrodkowany. */
.formularz-kontakt__uklad {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,0.85fr);
  gap: var(--space-9);
  align-items: center;
}
.formularz-kontakt__uklad--pelna { display: block; }

.formularz-kontakt__foto {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4/5;
  position: relative;
  z-index: 1;
}
.formularz-kontakt__foto img { width: 100%; height: 100%; object-fit: cover; }

.formularz-kontakt__wrap {
  max-width: 560px;
  margin-inline: auto;
  text-align: center;
  position: relative;
  z-index: 1;
}
.formularz-kontakt__wrap > .lead { max-width: 44ch; margin-inline: auto var(--space-9); margin-block-end: var(--space-9); font-size: var(--fs-lead); }

/* Wariant obok zdjecia: lewo wyrownany zamiast wysrodkowanego, na pelna
   szerokosc kolumny zamiast wlasnego max-width -- ten sam wzorzec co
   .formularz-kontakt__wrap na mobile ponizej (text-align:left). */
.formularz-kontakt__wrap--kolumna {
  max-width: none;
  margin-inline: 0;
  text-align: left;
}
.formularz-kontakt__wrap--kolumna > .lead { margin-inline: 0 var(--space-9); }

/* Wariant "karta" (24.09.2026, /pakiety, formularz "Zapytaj o pakiet
   dowolny"): sam formularz i handler beze zmian, tylko oprawa -- kremowa
   karta plywajaca na tle sekcji, ten sam jezyk co inne karty tego motywu
   (surface-cream + radius-md + shadow-karta), zeby NIE wygladalo na
   wklejone 1:1 z plaskiego, wysrodkowanego bloku tekstu na /kontakt. */
.formularz-kontakt__wrap--karta {
  background: var(--surface-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-karta);
  padding: var(--space-9) var(--space-7);
}

/* FAQ + formularz "Zapytaj o pakiet dowolny" obok siebie (24.09.2026,
   specyfikacja Jakuba, TYLKO /pakiety), zamiast dwoch osobnych
   pelnoszerokosciowych sekcji. Oba partiale wolane z polaczony=>true,
   wspolny wrapper .kontener dostarcza page-pakiety.php. */
.pakiety-faq-formularz__uklad {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: var(--space-9, 48px);
  align-items: start;
}
@media (max-width: 900px) {
  .pakiety-faq-formularz__uklad { grid-template-columns: 1fr; gap: var(--space-7, 32px); }
}
.pakiety-faq-formularz__form .formularz-kontakt__wrap--karta { margin-inline: 0; }

/* 26.09.2026, Etap 7: kafelki FAQ na /pakiety byly biale na kremowym tle
   obok bialej karty formularza -- zero kontrastu miedzy sekcjami, FAQ
   wtapialo sie w tlo. Nadpisane TYLKO w tym ukladzie (selektor scopowany
   przez rodzica .pakiety-faq-formularz__uklad), zero wplywu na
   .faq-item--karta uzywane gdzie indziej (np. /vouchery, jesli kiedys
   przelaczy sie na wariant jasny). */
.pakiety-faq-formularz__uklad .faq-item--karta { background: var(--surface-dark); }
.pakiety-faq-formularz__uklad .faq-item--karta summary { color: var(--text-on-dark); }
.pakiety-faq-formularz__uklad .faq-item--karta .faq-item__odpowiedz { color: var(--text-on-dark-muted); }
.pakiety-faq-formularz__uklad .faq-item--karta .faq-item__toggle { border-color: var(--accent-ctx); color: var(--accent-ctx); }
.pakiety-faq-formularz__uklad .faq-item--karta[open] .faq-item__toggle { background: var(--accent-ctx); border-color: var(--accent-ctx); color: var(--text-on-dark); }

@media (max-width: 900px) {
  /* Jedna kolumna, zdjecie NAD formularzem: ten sam wzorzec co
     .hero-podstrony__wnetrze -- na wąskim ekranie kolejność DOM (zdjęcie
     pierwsze w markupie tej sekcji) staje się kolejnością wizualną.
     Tekst zostaje lewo wyrownany (baza --kolumna), zgodnie z regulą
     .formularz-kontakt__wrap na @767px nizej, ktora i tak wymusza to samo
     na wariancie bez zdjecia -- jeden kierunek na obu wariantach. */
  .formularz-kontakt__uklad { grid-template-columns: 1fr; }
  .formularz-kontakt__foto { aspect-ratio: 4/3; margin-bottom: var(--space-7); }
}

.formularz {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.formularz__pole { display: flex; flex-direction: column; gap: 8px; }
.formularz__pole label {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
}
.formularz__pole input,
.formularz__pole textarea {
  font-family: var(--font-text);
  font-size: 15px;
  color: var(--text-on-light);
  padding: 13px 16px;
  border: 1px solid var(--line-on-light);
  border-radius: var(--radius-md);
  background: var(--surface-white);
}
.formularz__pole textarea { resize: vertical; min-height: 130px; }
.formularz__pole input:focus,
.formularz__pole textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.formularz__zgoda {
  display: grid;
  grid-template-columns: 20px 1fr;
  align-items: start;
  gap: 10px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-on-light-muted);
}
.formularz__zgoda input { margin-top: 3px; }
.formularz__zgoda a { color: var(--accent); text-decoration: underline; }

.formularz__blad {
  margin: 0 0 var(--space-5);
  padding: 13px 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  background: rgba(140, 81, 41, 0.08);
  color: var(--accent);
  font-size: 14px;
  text-align: left;
}

/* Sukces formularza kontaktowego, inline na /kontakt zamiast osobnej strony
   /dziekujemy (skasowana, decyzja Jakuba 24.09.2026). Ten sam kolor co
   .formularz__blad, wzorzec już ustalony gdzie indziej w tym pliku: jeden
   akcentowy box na oba komunikaty formularza, nie osobna paleta sukcesu. */
.formularz__sukces {
  margin: 0;
  padding: 13px 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  background: rgba(140, 81, 41, 0.08);
  color: var(--accent);
  font-size: 14px;
  text-align: left;
}
.formularz__sukces p { margin: 0; }

.formularz button[type="submit"] { align-self: flex-start; }

/* Konfigurator voucherów, dwie karty (06.09.2026, wzorzec Mandali).
   Restyling formularza natywnego WooCommerce (table.variations, .jdbv-pola
   z wtyczki magnolia-vouchery, quantity, single_add_to_cart_button) na
   tokeny motywu -- domyślny markup Woo nie ma żadnego swojego stylu poza
   przeglądarkowym. Reguły scoped pod .voucher-konfigurator, nie dotykają
   realnej strony produktu (tam WooCommerce renderuje to samo bez tego CSS,
   ale ta strona nigdy nie jest pokazywana klientce, patrz komentarz w
   voucher-konfigurator.php). */
.voucher-konfigurator {
  display: grid;
  grid-template-columns: repeat(2, minmax(0,1fr));
  gap: var(--space-9);
  align-items: start;
}
.voucher-konfigurator__karta {
  background: var(--surface-white);
  border-radius: var(--radius-panel);
  padding: var(--space-9) var(--space-7);
  position: relative;
}
/* .voucher-konfigurator__head i __plakietka skasowane 08.09.2026 (Sesja 2):
   zero eyebrow/plakietka nad H2, markup w voucher-konfigurator.php już ich
   nie renderuje. Nagłówek to teraz zwykłe h2.voucher-konfigurator__tytul. */
.voucher-konfigurator__tytul { margin: 0 0 var(--space-7); }

/* Formularz Woo: table.variations reflow na pionowy stos pól, ten sam
   wzorzec wizualny co .formularz__pole (formularz-kontakt.php). */
.voucher-konfigurator table.variations,
.voucher-konfigurator table.variations tbody,
.voucher-konfigurator table.variations tr,
.voucher-konfigurator table.variations th,
.voucher-konfigurator table.variations td { display: block; width: 100%; padding: 0; border: 0; text-align: left; }
.voucher-konfigurator table.variations tr { margin-bottom: var(--space-5); }
.voucher-konfigurator table.variations th label {
  display: block;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
  margin-bottom: 8px;
  font-weight: 400;
}
.voucher-konfigurator table.variations select {
  width: 100%;
  font-family: var(--font-text);
  font-size: 15px;
  color: var(--text-on-light);
  padding: 13px 40px 13px 16px;
  border: 1px solid var(--line-on-light);
  border-radius: var(--radius-md);
  background-color: var(--surface-white);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238C5129' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px;
  appearance: none;
}
.voucher-konfigurator table.variations select:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.voucher-konfigurator .reset_variations { display: none; }

/* J10, sesja poprawkowa 10.09.2026: `hidden` chowa wiersze <tr> pastylkowane
   przez JS (main.js, wierszWariant/wierszNominal) i pole "Twoja kwota"
   (magnolia-vouchery.php), ale reguly wyzej ("display: block"/"display:
   flex" na tych samych selektorach) mialy wyzsza specyficznosc niz atrybut
   przegladarki i bily go -- efekt: podwojny naglowek "Wariant" (oryginalny
   <th> obok wlasnej etykiety pastylek) i pole kwoty widoczne od startu
   zamiast dopiero po kliknieciu "Dowolna kwota". Regula wylaczajaca musi
   wygrac z KAZDA regula wlaczajaca ten sam element (lekcje-techniczne.md). */
.voucher-konfigurator [hidden] { display: none !important; }

/* Pastylki (08.09.2026, Sesja 2, D-SKLEP-WG-MANDALI): zastępują <select>
   atrybutu "Wariant" (produkt 69, filtrowane JS-em wg Zabiegu) i cały
   atrybut "Nominał" (produkt 64). Sam <select> zostaje w DOM ukryty
   (wiersz .hidden przez JS), pastylka tylko ustawia jego .value.
   role="radio"/"radiogroup" zgodnie z WAI-ARIA (main.js: klik albo
   strzałki, aria-checked, tabindex="0" tylko na zaznaczonym elemencie). */
.jdbv-pastylki-blok { margin-bottom: var(--space-5); }
.jdbv-pastylki-etykieta {
  display: block;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
  margin-bottom: 8px;
}
.jdbv-pastylki { display: flex; flex-wrap: wrap; gap: 10px; }
.jdbv-pastylka {
  font-family: var(--font-text);
  font-size: 14px;
  color: var(--text-on-light);
  padding: 10px 18px;
  border: 1px solid var(--line-on-light);
  border-radius: var(--radius-pill);
  background: var(--surface-white);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.jdbv-pastylka[aria-checked="true"] { background: var(--accent); border-color: var(--accent); color: var(--text-on-dark); }
.jdbv-pastylka:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Nasze pola dla/od/dedykacja (plugin magnolia-vouchery), sam wzorzec co
   .formularz__pole. */
.voucher-konfigurator .jdbv-pola { display: flex; flex-direction: column; gap: var(--space-5); margin-top: var(--space-5); }
.voucher-konfigurator .jdbv-pole { display: flex; flex-direction: column; gap: 8px; margin: 0; }
.voucher-konfigurator .jdbv-pole label {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
}
.voucher-konfigurator .jdbv-pole input,
.voucher-konfigurator .jdbv-pole textarea {
  font-family: var(--font-text);
  font-size: 15px;
  color: var(--text-on-light);
  padding: 13px 16px;
  border: 1px solid var(--line-on-light);
  border-radius: var(--radius-md);
  background: var(--surface-white);
}
.voucher-konfigurator .jdbv-pole textarea { resize: vertical; min-height: 90px; }
.voucher-konfigurator .jdbv-pole input:focus,
.voucher-konfigurator .jdbv-pole textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* Cena i dostępność wariantu, pojawia się dopiero po wyborze (JS Woo). */
.voucher-konfigurator .woocommerce-variation-price { margin: var(--space-5) 0; font-size: 21px; font-family: var(--font-display); color: var(--accent); }
.voucher-konfigurator .woocommerce-variation-description { font-size: 14px; color: var(--text-on-light-muted); margin-bottom: var(--space-5); }
.voucher-konfigurator .woocommerce-variation-availability { font-size: 13px; }

/* Ilość ukryta: kupno wielokrotności tego samego vouchera na raz to brzeg,
   nie flow, którego chcemy uczyć klientkę (wzorzec Mandali, brak pola
   ilości). Input zostaje w DOM (POST-uje domyślne "1"), tylko schowany. */
.voucher-konfigurator .quantity { display: none; }

.voucher-konfigurator .single_add_to_cart_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: var(--space-5);
  padding: 15px 26px;
  border-radius: var(--radius-pill);
  font-family: var(--font-text);
  font-size: 15px;
  font-weight: 500;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--text-on-dark);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
/* Ten sam wzorzec co .btn--primary (08.09.2026): wypelniony -> na hover traci tlo. */
.voucher-konfigurator .single_add_to_cart_button:hover { background: transparent; color: var(--accent); border-color: var(--accent); }
.voucher-konfigurator .single_add_to_cart_button.disabled { opacity: .5; cursor: not-allowed; }

/* Komunikat po dodaniu do koszyka (main.js, "Konfigurator voucherów").
   Ten sam kolor dla sukcesu i błędu co .formularz__blad -- paleta Magnolii
   nie ma osobnego czerwonego tonu na błędy, --accent niesie obie role. */
.jdbv-komunikat { margin: var(--space-5) 0 0; font-size: 14px; text-align: center; color: var(--accent); }

@media (max-width: 900px) {
  .voucher-konfigurator { grid-template-columns: 1fr; }
  .voucher-konfigurator__karta { padding: 32px 24px; }
}

@media (max-width: 767px) {
  .formularz-kontakt__wrap { text-align: left; }
  .formularz-kontakt__wrap h2,
  .formularz-kontakt__wrap > .lead { text-align: left; margin-inline: 0; }
  .formularz button[type="submit"] { align-self: stretch; }
}

/* --- Sekcja 06, tabela godzin cały tydzień --------------------------------- */
.godziny-tydzien__wrap {
  max-width: 460px;
  margin-inline: auto;
  position: relative;
  z-index: 1;
}
.godziny-tydzien__wrap h2 { text-align: center; margin-bottom: var(--space-7); }

/* ==========================================================================
   Podstrona /pakiety. Przepisane 08.09.2026, wzorzec Mandali
   (D-SKLEP-WG-MANDALI): sześć kart pakietów (pakiet-karta.php v2), zero
   eyebrow, jedna karta może być wyróżniona (ciemna). Zastępuje wersję S8a
   (05.09.2026, dwa przyciski poziomo, plakietka "W cenie" osobno). */
/* Karta flagowa (24.09.2026): pasmo na pelna szerokosc NAD siatka, jeden
   pakiet oznaczony pak_wyrozniony (dzis Pakiet dowolny). Ten sam jezyk co
   .pakiet-karta--wyrozniona wczesniej (surface-dark + accent-ctx), teraz
   jako wlasny, wiekszy komponent zamiast karty tej samej wielkosci co
   reszta w siatce. */
/* Uklad 24.09.2026 wieczor, specyfikacja Jakuba (nadpisuje wczesniejsza
   wersje "karta flagowa nad siatka" z tej samej nocy, usunieta -- patrz
   pakiet-karta.php). Jeden grid 3-kolumnowy na wszystkie piec kart. Rzad 1:
   trzy rowne (Kobido/twarzy/plecow). Rzad 2: .pakiet-karta--wyrozniona
   (dzis Pakiet dowolny) dostaje span 2, Cale cialo zostaje 1 kolumna --
   wychodzi samo z naturalnego porzadku repeatera w gridzie, zero PHP do
   recznego ukladania. */
.pakiety-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0,1fr));
  gap: 24px;
  position: relative;
  z-index: 1;
  align-items: stretch;
}
/* 25.09.2026: span domyslny (desktop) zyje TUTAJ, przed media queries, zeby
   kaskada zawsze wygrywala w strone waszego breakpointu (kolejnosc zrodla
   bije specificity przy remisie). Druga, bezwarunkowa deklaracja tej samej
   wlasciwosci nizej w pliku (przy tle .pakiet-karta--wyrozniona) psula
   mobile: mimo ze stala PRZED tym blokiem w kaskadzie logicznie, w pliku
   stala FIZYCZNIE PO @media(560px), wiec zawsze wygrywala i span 2 zostawal
   na telefonie -- 3 z 5 kart renderowaly sie z szerokoscia 0px. Naprawa:
   ta deklaracja span 2 zostaje jedynym zrodlem dla desktopu, tamta dalej w
   pliku juz go nie ustawia. */
.pakiet-karta--wyrozniona { grid-column: span 2; }
@media (max-width: 900px) {
  .pakiety-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .pakiet-karta--wyrozniona { grid-column: span 2; }
}
@media (max-width: 560px) {
  .pakiety-grid { grid-template-columns: 1fr; }
  .pakiet-karta--wyrozniona { grid-column: span 1; }
}
.pakiet-karta {
  position: relative;
  background: var(--surface-white);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.pakiet-karta__plakietka {
  position: absolute;
  top: 18px;
  right: 18px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--surface-white);
  background: var(--accent);
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  z-index: 1;
}
.pakiet-karta__foto { aspect-ratio: 4/3; }
.pakiet-karta__foto img { width: 100%; height: 100%; object-fit: cover; }
.pakiet-karta__tresc {
  padding: 28px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.pakiet-karta__tresc h3 { margin-bottom: 0; }
.pakiet-karta__cena { font-family: var(--font-display); font-size: 28px; color: var(--accent); margin: 0; }
.pakiet-karta__zdanie { font-size: 14px; color: var(--text-on-light-muted); margin: 0; }
.pakiet-karta__lista {
  list-style: none;
  margin: 4px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--line-on-light);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 14px;
  color: var(--text-on-light-muted);
}
.pakiet-karta__lista strong { color: var(--text-on-light); font-weight: 500; }
.pakiet-karta__akcje { display: flex; flex-direction: column; gap: 10px; margin-top: auto; padding-top: 18px; }
.pakiet-karta__akcje .btn { width: 100%; justify-content: center; }
.pakiet-karta__tel {
  align-self: center;
  font-size: 13.5px;
  color: var(--text-on-light-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.pakiet-karta__tel:hover { color: var(--accent); }

/* Karta wyróżniona: ciemna, kolor tekstu JAWNY na każdym elemencie (K1,
   lekcje-techniczne, 04.09.2026: komponent z niezależnym tłem dziedziczy
   kolor po rodzicu, tu rodzicem jest .panel--jasny więc bez override
   tekst zostałby ciemny na ciemnym). */
.pakiet-karta--wyrozniona { background: var(--surface-dark); }
.pakiet-karta--wyrozniona .pakiet-karta__tresc h3,
.pakiet-karta--wyrozniona .pakiet-karta__cena { color: var(--text-on-dark); }
.pakiet-karta--wyrozniona .pakiet-karta__cena { color: var(--accent-ctx); }

/* Konfigurator pakietow 3/6/9 (24.09.2026, noc). Kopia scopowana pod
   .pakiet-karta__konfigurator z bloku .voucher-konfigurator wyzej w tym
   pliku -- ten sam formularz natywny WooCommerce (table.variations,
   single_add_to_cart_button, woocommerce-variation-price), inny kontener
   wizualny (karta pakietu, nie osobna sekcja z dwoma kolumnami), wiec
   osobny blok zamiast doklejania drugiego znaczenia do selektora vouchera.
   .jdbv-pastylki/.jdbv-pastylka/.jdbv-komunikat NIE sa tu powtorzone,
   nie sa scopowane pod .voucher-konfigurator wiec dzialaja tu bez zmian. */
.pakiet-karta__konfigurator table.variations,
.pakiet-karta__konfigurator table.variations tbody,
.pakiet-karta__konfigurator table.variations tr,
.pakiet-karta__konfigurator table.variations th,
.pakiet-karta__konfigurator table.variations td { display: block; width: 100%; padding: 0; border: 0; text-align: left; }
.pakiet-karta__konfigurator table.variations tr { margin-bottom: var(--space-5); }
.pakiet-karta__konfigurator table.variations th label {
  display: block;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
  margin-bottom: 8px;
  font-weight: 400;
}
.pakiet-karta__konfigurator [hidden] { display: none !important; }
.pakiet-karta__konfigurator .reset_variations { display: none; }
.pakiet-karta__konfigurator .quantity { display: none; }
.pakiet-karta__konfigurator .woocommerce-variation-price { margin: var(--space-5) 0 0; font-size: 22px; font-family: var(--font-display); color: var(--accent); }
.pakiet-karta__konfigurator .woocommerce-variation-description { font-size: 13px; color: var(--text-on-light-muted); margin: 4px 0 0; }
.pakiet-karta__konfigurator .woocommerce-variation-availability { font-size: 12px; }
.pakiet-karta--wyrozniona .pakiet-karta__konfigurator .woocommerce-variation-price { color: var(--accent-ctx); }
.pakiet-karta__konfigurator .single_add_to_cart_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: var(--space-5);
  padding: 15px 26px;
  border-radius: var(--radius-pill);
  font-family: var(--font-text);
  font-size: 15px;
  font-weight: 500;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--text-on-dark);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pakiet-karta__konfigurator .single_add_to_cart_button:hover { background: transparent; color: var(--accent); border-color: var(--accent); }
.pakiet-karta__konfigurator .single_add_to_cart_button.disabled { opacity: .5; cursor: not-allowed; }
.pakiet-karta--wyrozniona .pakiet-karta__konfigurator .single_add_to_cart_button { border-color: var(--accent-ctx); background: var(--accent-ctx); }
.pakiet-karta--wyrozniona .pakiet-karta__konfigurator .single_add_to_cart_button:hover { background: transparent; color: var(--accent-ctx); border-color: var(--accent-ctx); }
.pakiet-karta--wyrozniona .pakiet-karta__zdanie,
.pakiet-karta--wyrozniona .pakiet-karta__lista { color: var(--text-on-dark-muted); }
.pakiet-karta--wyrozniona .pakiet-karta__lista strong { color: var(--text-on-dark); }
.pakiet-karta--wyrozniona .pakiet-karta__lista { border-top-color: var(--line-on-dark); }
.pakiet-karta--wyrozniona .pakiet-karta__tel { color: var(--text-on-dark-muted); }
.pakiet-karta--wyrozniona .pakiet-karta__tel:hover { color: var(--accent-ctx); }
.pakiet-karta--wyrozniona .pakiet-karta__plakietka { background: var(--accent-ctx); color: var(--text-on-dark); }

/* Stary @media (max-width:900px) .pakiety-grid {1fr} usuniety 24.09.2026 --
   zastapiony tiered wersja (900px->2col, 560px->1col) zdefiniowana wyzej,
   przy samej deklaracji .pakiety-grid. Ten sam selektor dwa razy w pliku
   psulby sie kolejnoscia kaskady, nie oczywista, wiec zostaje jeden. */

/* ==========================================================================
   Tabela porównawcza pakietów, nowy komponent 08.09.2026, wzorzec Mandali
   (BEZ kolumny oszczędności, tabela-porownanie.php). */
.tabela-porownanie__head { max-width: 640px; margin-bottom: var(--space-7); position: relative; z-index: 1; }
.tabela-porownanie__scroll { overflow-x: auto; position: relative; z-index: 1; }
.tabela-porownanie { width: 100%; border-collapse: collapse; font-size: 14.5px; min-width: 640px; }
.tabela-porownanie th {
  text-align: left;
  font-family: var(--font-text);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
  font-weight: 500;
  padding: 0 16px 14px 0;
  border-bottom: 1px solid var(--line-on-light);
}
.tabela-porownanie td {
  padding: 16px 16px 16px 0;
  border-bottom: 1px solid var(--line-on-light);
  color: var(--text-on-light-muted);
  vertical-align: top;
}
.tabela-porownanie tr:last-child td { border-bottom: 0; }
.tabela-porownanie td:first-child { color: var(--text-on-light); font-weight: 500; }
.tabela-porownanie td:nth-child(3) { font-family: var(--font-display); font-size: 19px; color: var(--accent); }
.tabela-porownanie__link { margin-top: var(--space-7); }
.tabela-porownanie__hint { display: none; }

@media (max-width: 767px) {
  .tabela-porownanie { min-width: 600px; font-size: 13.5px; }
  /* Runda mobile 11.09.2026: naglowki lamaly sie w srodku slowa ("POJEDYN /
     ZABIEGU"), cena w dwoch liniach ("1 500 / zl"), a przewijalna tabela nie
     dawala zadnego sygnalu, ze cos jest dalej w prawo. */
  .tabela-porownanie th { white-space: nowrap; }
  .tabela-porownanie td:nth-child(3) { white-space: nowrap; }
  .tabela-porownanie__scroll { -webkit-overflow-scrolling: touch; }
  .tabela-porownanie__scroll::after {
    content: "";
    position: absolute; top: 0; right: 0; bottom: 0; width: 40px;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(243,236,229,0), var(--surface-cream, #f3ece5));
  }
  .tabela-porownanie__scroll { padding-right: 0; }
  .tabela-porownanie__hint { display: block; font-size: 12.5px; color: var(--text-on-light-muted); margin-bottom: 10px; }
}

/* Strony /koszyk/ i /zamowienie/ (WooCommerce Blocks, React): produkt bez
   zdjecia dostaje ten sam traktament co szuflada koszyka. Tu <img> renderowany
   przez blok NIE niesie klasy "woocommerce-placeholder" (to atrybut tylko
   klasycznego mini-koszyka) -- dopasowanie po fragmencie sciezki pliku,
   stabilnym nazewnictwie WooCommerce. .wc-block-cart-item__image to <td>
   tabeli, wiec display:none usuwa cala kolumne bez pustej dziury.
   Decyzja Jakuba 12.09.2026. */
.wc-block-cart-item__image:has(img[src*="/placeholder.webp"]),
.wc-block-components-order-summary-item__image:has(img[src*="/placeholder.webp"]) {
  display: none;
}

/* 02.10.2026: box z zdjeciem (zabieg-wyroznienie.php). Tresc po lewej
   (naglowek, opis, pigulki, "Szczegoly" + jeden przycisk w jednym rzedzie),
   zdjecie po prawej, wypelnia cala wysokosc boxu, bez nakladki. */
.wyroznienie-zabieg__tresc { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); }
.wyroznienie-zabieg__btny { flex-direction: row; align-items: center; flex-wrap: wrap; gap: var(--space-5); width: auto; margin-top: var(--space-3); }
.panel--ciemny .wyroznienie-zabieg__btny .link-strzalka { color: var(--accent-ctx); }
.wyroznienie-zabieg--foto {
  display: block;
  position: relative;
  padding: 0;
  overflow: hidden;
  min-height: 440px;
}
.wyroznienie-zabieg--foto .wyroznienie-zabieg__tresc {
  position: relative;
  z-index: 2;
  max-width: 46%;
  min-height: 440px;
  padding: var(--space-9) var(--space-7);
  justify-content: center;
}
.wyroznienie-zabieg__foto { position: absolute; top: 0; right: 0; bottom: 0; width: 66%; z-index: 0; }
.wyroznienie-zabieg__foto::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--surface-dark, #1b1511) 0%, rgba(27,21,17,.55) 22%, rgba(27,21,17,0) 48%);
}
.wyroznienie-zabieg__foto .wyroznienie-zabieg__img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 32%; display: block; }
@media (max-width: 600px) {
  .wyroznienie-zabieg--foto { min-height: 0; border-top: none; }
  .wyroznienie-zabieg--foto .wyroznienie-zabieg__tresc { max-width: none; min-height: 0; padding: 28px 20px; }
  .wyroznienie-zabieg__foto { position: relative; inset: auto; width: 100%; height: 220px; }
  .wyroznienie-zabieg__foto::after { display: none; }
  .wyroznienie-zabieg__foto .wyroznienie-zabieg__img { object-position: 50% 25%; }
  .wyroznienie-zabieg--foto { display: flex; flex-direction: column-reverse; }
}
/* 02.10.2026: sekcja O mnie na Home, opcjonalne drugie zdjecie nalozone na
   pierwsze (pole about_image_2). .omnie__media to element gridu (wysokosc z
   rozciagniecia jak dawniej .omnie__foto), w srodku glowne zdjecie wypelnia
   caly box, a drugie, mniejsze, wystaje z dolnego lewego rogu. Bez drugiego
   zdjecia wyglad jak przed zmiana. */
.omnie__media { position: relative; min-height: clamp(440px, 34vw, 620px); }
.omnie__media > .omnie__foto { position: absolute; inset: 0; min-height: 0; }
.omnie__foto2 {
  position: absolute;
  left: -14%;
  bottom: -7%;
  width: 56%;
  aspect-ratio: 4 / 5;
  border: 6px solid var(--clr-cream-wash, #f3ebe3);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 14px 34px rgba(27, 21, 17, .22);
  z-index: 2;
}
.omnie__foto2 img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
@media (max-width: 900px) {
  /* 04.10.2026: iOS Safari zwijal wysokosc, gdy box mial tylko aspect-ratio, a dzieci absolutne. Wysokosc z elementu w przeplywie (padding-top 125% = 4/5). */
  .omnie__media { order: -1; aspect-ratio: auto; min-height: 0; }
  .omnie__media::before { content: ''; display: block; padding-top: 125%; }
  .omnie__media--duo { margin-bottom: 44px; }
  .omnie__foto2 { left: 5%; bottom: -36px; width: 48%; border-width: 4px; }
}
/* 02.10.2026 (Jakub, mobile): pojedyncze podstrony zabiegow i kategorie masazy, odstep miedzy
   leadem a karta ceny i czasu rowny odstepowi miedzy H1 a leadem (16px).
   Wczesniej lead margin-bottom 40 + gap siatki 24 + margin-top karty 40 = 104px. */
@media (max-width: 900px) {
  .hero-podstrony__wnetrze--karta { gap: 0; }
  .hero-podstrony__wnetrze--karta .hero-podstrony__tresc .lead { margin-bottom: 0; }
  .hero-podstrony__wnetrze--karta .karta-cenowa--hero { margin-top: 16px; }
}
/* 02.10.2026: konfigurator Pakietu dowolnego na 500 zl (pakiet-dowolny.php,
   assets/js/pakiet-dowolny.js). Lista zabiegow w przewijanym boxie, licznik
   sumy i reszty nad nim, przycisk zakupu pod spodem. */
.pakiet-dowolny { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-5); text-align: left; }
.pakiet-dowolny__intro { margin: 0; color: var(--text-on-dark-muted); font-size: var(--fs-small); }
.pakiet-dowolny__licznik {
  display: flex;
  justify-content: space-between;
  gap: var(--space-5);
  padding: 12px 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .07);
  border: 1px solid var(--line-on-dark);
  font-size: var(--fs-small);
}
.pakiet-dowolny__licznik strong { font-family: var(--font-display); font-size: 18px; color: var(--accent-ctx); }
.pakiet-dowolny__lista { max-height: 380px; overflow-y: auto; border: 1px solid var(--line-on-dark); border-radius: var(--radius-md); padding: 0 16px 8px; }
.pakiet-dowolny__grupa h4 { margin: 16px 0 4px; font-family: var(--font-display); font-size: 19px; color: var(--text-on-dark); }
.pakiet-dowolny__wiersz { display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line-on-dark); }
.pakiet-dowolny__wiersz--wybrany .pakiet-dowolny__nazwa { font-weight: 600; }
.pakiet-dowolny__nazwa { font-size: 14px; color: var(--text-on-dark); }
.pakiet-dowolny__cena { font-family: var(--font-display); font-size: 18px; color: var(--accent-ctx); white-space: nowrap; }
.pakiet-dowolny__licznik-sztuk { display: inline-flex; align-items: center; gap: 8px; }
.pakiet-dowolny__btn { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--accent-ctx); background: transparent; color: var(--accent-ctx); cursor: pointer; font-size: 18px; line-height: 1; padding: 0; }
.pakiet-dowolny__btn:disabled { opacity: .35; cursor: not-allowed; }
.pakiet-dowolny__ilosc { min-width: 1.3em; text-align: center; font-size: 15px; }
.pakiet-dowolny__komunikat { margin: 0; min-height: 1.4em; font-size: var(--fs-small); color: var(--text-on-dark-muted); }
.pakiet-dowolny__komunikat--blad { color: #ff9b8a; }
.pakiet-dowolny__komunikat a { color: var(--accent-ctx); text-decoration: underline; }
.pakiet-dowolny__kup { align-self: flex-start; }
@media (max-width: 600px) {
  .pakiet-dowolny__wiersz { grid-template-columns: 1fr auto; row-gap: 6px; }
  .pakiet-dowolny__licznik-sztuk { grid-column: 1 / -1; justify-self: end; }
  .pakiet-dowolny__kup { align-self: stretch; justify-content: center; }
}
.pakiet-dowolny__podpowiedz { margin: 0; font-size: var(--fs-small); color: var(--accent-ctx); }
.pakiet-dowolny__kup:disabled { opacity: .45; cursor: not-allowed; }

/* Fluent Forms w stylu Magnolii (06.10.2026). Te same tokeny co natywny .formularz powyzej,
   zeby przelaczenie formularza nie zmienilo wygladu. */
.formularz-kontakt__wrap .fluentform { text-align: left; }
.formularz-kontakt__wrap .fluentform .ff-el-group { margin-bottom: var(--space-5); }
.formularz-kontakt__wrap .fluentform .ff-el-input--label label {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--text-on-light-muted);
  font-weight: 400;
}
.formularz-kontakt__wrap .fluentform .ff-el-input--label.ff-el-is-required label::after { color: var(--accent); }
.formularz-kontakt__wrap .fluentform .ff-el-form-control {
  font-family: var(--font-text);
  font-size: 15px;
  color: var(--text-on-light);
  padding: 13px 16px;
  border: 1px solid var(--line-on-light);
  border-radius: var(--radius-md);
  background: var(--surface-white);
  box-shadow: none;
}
.formularz-kontakt__wrap .fluentform textarea.ff-el-form-control { resize: vertical; min-height: 130px; }
.formularz-kontakt__wrap .fluentform .ff-el-form-control:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
  background: var(--surface-white);
  color: var(--text-on-light);
}
.formularz-kontakt__wrap .fluentform .ff_t_c,
.formularz-kontakt__wrap .fluentform .ff-el-tc label,
.formularz-kontakt__wrap .fluentform .ff_tc_label {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-on-light-muted);
}
.formularz-kontakt__wrap .fluentform .ff_t_c a { color: var(--accent); text-decoration: underline; }
.formularz-kontakt__wrap .fluentform .text-danger,
.formularz-kontakt__wrap .fluentform .error {
  color: var(--accent);
  font-size: 13px;
}
.formularz-kontakt__wrap .fluentform .ff-el-is-error .ff-el-form-control { border-color: var(--accent); }
.formularz-kontakt__wrap .fluentform .ff-btn-submit.btn {
  display: inline-flex;
  padding: 15px 26px;
  border-radius: var(--radius-pill);
  font-family: var(--font-text);
  font-size: 15px;
  font-weight: 500;
  background: var(--accent);
  color: var(--text-on-dark);
  border: 1px solid var(--accent);
  box-shadow: none;
  opacity: 1;
}
.formularz-kontakt__wrap .fluentform .ff-btn-submit.btn:hover { background: transparent; color: var(--accent); border-color: var(--accent); }
.formularz-kontakt__wrap .ff-message-success,
.formularz-kontakt__wrap .fluentform .ff-message-success {
  margin: 0;
  padding: 13px 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  background: rgba(140, 81, 41, 0.08);
  color: var(--accent);
  font-size: 14px;
  text-align: left;
  box-shadow: none;
}
@media (max-width: 767px) { .formularz-kontakt__wrap .fluentform .ff-btn-submit.btn { width: 100%; } }
