/* ===================================================================
   FitPage — style.css
   Mobile-first. Breakpointy: 480px / 700px / 900px.
   Sekcje: zmienne, podstawy, layout, komponenty, animacje, media queries.
   =================================================================== */

/* ----------------------------- Zmienne ----------------------------- */
:root {
  /* `only` (nie samo `light`) mówi przeglądarce wprost: nie odwracaj/nie
     przemalowuj tej strony pod wymuszony tryb ciemny systemu, nawet jeśli
     użytkownik ma go włączony (np. "wymuszony tryb ciemny dla stron" w
     Chrome/Samsung Internet na Androidzie) — bez tego niektóre przeglądarki
     mobilne same odwracały kolory całej strony, logo włącznie, bo strona
     nigdzie wprost nie deklarowała, że nie obsługuje ciemnego motywu.
     `:root` ma wyższą specyficzność niż selektor `html` niżej (który wciąż
     ma samo `color-scheme: light` — zostaje, bo i tak przegrywa z tą
     regułą), więc to ta wartość obowiązuje. Uzupełnione przez
     `<meta name="color-scheme" content="light">` w `<head>` każdej strony —
     ta sama deklaracja w dwóch miejscach z tego samego powodu, jak zaleca
     specyfikacja. Zgodne z "Don't introduce or assume a dark theme"
     (DESIGN.md) — to świadomie jedyny, jasny motyw. */
  color-scheme: only light;

  /* tło całej strony — jasny, kremowy canvas. Świadomy wybór jasnego
     motywu (patrz DESIGN.md), nie gradient — jedna płaska płaszczyzna,
     na której siedzi cała treść. */
  --canvas: #F7F3EA;

  /* akcent — głęboka zieleń butelkowa (zastępuje Stadium Amber) */
  --accent:        #1F3D2B;
  --accent-strong: #2C6B47;   /* hover/active — jaśniejsza, bardziej nasycona zieleń */
  --on-accent:     #FBF8F0;   /* tekst/znaki NA wypełnieniu akcentu (przyciski, plakietki, haczyk checkboxa) —
                                  akcent jest teraz ciemny, więc to co dawniej robił --ink (ciemny tekst na
                                  jasnym akcencie) musi się odwrócić na jasny tekst na ciemnym akcencie */

  /* tekst (ciemny — motyw jasny) */
  --text:  #202821;   /* główny tekst/nagłówki — ciemna, lekko zielonkawa czerń */
  --muted: #52594F;   /* tekst pomocniczy */
  --error: #A13333;   /* pogłębione względem starego #d64545 — na jasnym tle płytszy czerwony spadał poniżej 4.5:1 */

  /* powierzchnie — lekko przyciemnione zielenią zamiast rozjaśnione bielą */
  --bg:     rgba(31, 61, 43, 0.05); /* karty (portfolio, kroki, FAQ, pola formularza) */
  --bg-alt: rgba(31, 61, 43, 0.05);
  --border: rgba(31, 61, 43, 0.16);

  --maxw: 1080px;
  --radius: 14px;
  --shadow: 0 14px 40px rgba(31, 45, 36, 0.16); /* miękki, zazieleniony — czarny 45% byłby na jasnym tle zbyt ciężki */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Typografia — webfonty z Google Fonts (podłączone przez <link> w <head>
     każdej strony, nie @import w CSS — @import blokuje równoległe pobieranie
     i opóźnia pierwsze wymalowanie tekstu). Fraunces (600/700) na nagłówki —
     serif o wyraźnym charakterze, kontrastuje z neutralnym Inter (400/500)
     na treść. Oba mają `&display=swap` w URL-u zapytania, więc przeglądarka
     pokazuje fallback natychmiast i podmienia na webfont dopiero po
     doładowaniu (bez niewidocznego tekstu na starcie — FOIT). Fallbacki w
     stosie to poprzedni systemowy stos, nie generyczne serif/sans-serif —
     stos systemowy jest bliższy proporcjom Fraunces/Inter niż domyślny
     serif przeglądarki, więc swap jest mniej zauważalny. */
  --font-heading: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ----------------------------- Podstawy ----------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; background: var(--canvas); color-scheme: light; }

/* min-height:100vh samo w sobie NIE przykleja stopki do dołu — rozciąga
   tylko sam element body, a footer i tak kończy się tam, gdzie kończy się
   treść. Na krótkich stronach (np. artykuly.html na wysokim ekranie)
   zostawiało to puste, kremowe pole pod ciemną stopką zamiast stopki na
   samym dole. Flex column + main jako jedyny rosnący element to
   standardowy wzorzec "sticky footer": main wypełnia całą wolną
   przestrzeń, stopka zostaje dosunięta do dołu niezależnie od tego, ile
   treści jest w main. .splash (position:fixed) i tak jest poza normalnym
   flow, więc flex go nie dotyczy. */
body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--text);
  background: var(--canvas);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
main { flex: 1 0 auto; }

/* h4-h6 nieużywane nigdzie na stronie dziś, ale reguła obejmuje cały
   zakres h1-h6 na wypadek przyszłej treści — waga 600 dla mniejszych
   poziomów (700 zostaje dla h1-h3, już przetestowane wizualnie). */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  line-height: 1.2;
  margin: 0 0 0.5em;
  letter-spacing: -0.01em; /* Fraunces ma już własny, wyraźniejszy rytm liter niż stos systemowy —
                               poprzedni -0.02em (dobrany pod system-ui) na serifie ściska litery
                               odrobinę za mocno, stąd o 0.01em luźniej */
}
h1, h2, h3 { font-weight: 700; }
h4, h5, h6 { font-weight: 600; }
/* subtelna, neutralna poświata pod nagłówkami H1/H2 (nie H3 — tytuły
   komponentów typu .card__title zostają płaskie). Zazieleniona jak reszta
   cieni w systemie (spójna z --shadow), nie kolor akcentu — to głębia,
   nie ozdoba. */
.hero__title,
.section__title,
.brief-success__title {
  text-shadow: 0 1px 3px rgba(31, 45, 36, 0.14);
}
p { margin: 0 0 1em; }
img { max-width: 100%; display: block; }
a { color: inherit; }

/* Pierścień focusa — dotąd zdefiniowany tylko przy polach formularza i przy
   custom checkboxie zgody (patrz sekcja .form). Linki (nav, stopka,
   portfolio), przyciski .btn, .nav__toggle i <summary> (FAQ, Proces, RODO)
   polegały na domyślnym obramowaniu przeglądarki, które przy resetach
   (border:0, list-style:none na <summary> itp.) bywa niewidoczne. Jeden
   globalny token pokrywa resztę zamiast dopisywać go po komponencie. */
a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Skip-link (WCAG 2.4.1) — pierwszy fokusowalny element w każdym <body>
   (patrz każda strona, tuż po <body>), niewidoczny do czasu focusu, żeby
   użytkownik klawiatury/czytnika ekranu nie musiał przetabowywać całego
   nav na każdej podstronie. Styl pełnej pigułki jak .btn/.nav__cta — ten
   sam, ugruntowany wzorzec "widocznej akcji" na stronie, nie nowy,
   niedokumentowany kształt. z-index wyżej niż .splash (999), bo użytkownik
   klawiatury może dotrzeć tu focusem, zanim nakładka zdąży zniknąć. */
.skip-link {
  position: absolute;
  top: -100px;
  left: 16px;
  z-index: 1000;
  padding: 12px 20px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.2s var(--ease);
}
.skip-link:focus {
  top: 16px;
}
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: 20px;
}

/* ----------------------------- Sekcje ----------------------------- */
/* Bez paneli — treść siedzi bezpośrednio na canvasie. Odstęp między
   sekcjami idzie wyłącznie przez padding/margin (--section + wewnętrzny
   padding kontenera), nie przez wizualne pudełka. Wartości obniżone
   (z 52/88px i 40/44px) po zgłoszeniu, że kolejne sekcje na index.html
   (O nas / Portfolio / Artykuły) wyglądają na zbyt puste — dwie warstwy
   paddingu (sekcja + kontener) sumowały się do ~260-284px pustej
   przestrzeni między treścią jednej sekcji a nagłówkiem następnej na
   desktopie, zmierzone w przeglądarce. Nowe wartości dają ~148px na
   desktopie / ~116px na mobile, ok. 45%/38% mniej — nadal wyraźny
   odstęp, bez wrażenia pustki. Zmiana dotyczy `.section` globalnie
   (współdzielone przez wszystkie strony), nie tylko trójki wskazanej
   przez klienta — te same dwie warstwy paddingu były identyczne
   wszędzie, więc zawężenie tylko do index.html wprowadziłoby
   niespójny rytm między stronami. */
.section { padding: 40px 0; }
.section > .container {
  padding-top: 16px;
  padding-bottom: 20px;
}
.section__title { font-size: 1.6rem; margin-bottom: 1rem; }

/* żeby sticky nav nie zasłaniał nagłówka po kliknięciu w link kotwicy */
[id] { scroll-margin-top: 84px; }

/* ----------------------------- Przyciski ----------------------------- */
.btn {
  display: inline-block;
  padding: 14px 28px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.18s var(--ease),
              box-shadow 0.18s var(--ease),
              background-color 0.18s var(--ease);
}
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--accent-strong);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(31, 61, 43, 0.28);
}
.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none; /* blokuje :hover, żeby przycisk nie "ożywał" wizualnie podczas wysyłki */
}

/* Pulsująca obwódka — WYŁĄCZNIE na CTA "Umów konsultację" w hero, trzy
   razy po wejściu, potem spokój (13.10.2026, /impeccable quieter: dwa
   nieskończone pulsy naraz, w nav i w hero, przestały wskazywać jedną
   akcję). .nav__cta i CTA domykające już nie pulsują. Świadomy wyjątek od The Lift-Means-
   Interactive Rule (DESIGN.md) — na wyraźne, szczegółowe życzenie
   (kolor, timing i krzywa podane wprost), nie odruchowy wybór. Reszta
   przycisków/linków (patrz niżej) dostaje tylko reakcję na hover/focus,
   zero ruchu w spoczynku — pulsowanie zostaje zarezerwowane dla tych
   trzech miejsc, żeby nie rozmyć akcentu na całą stronę. Animacja żyje
   wyłącznie pod prefers-reduced-motion: no-preference, więc z włączonym
   ograniczeniem ruchu systemowego przycisk jest w pełni statyczny — nie
   trzeba tego osobno wyłączać. animation-play-state: paused na hover/focus,
   żeby istniejący, celowy efekt uniesienia (.btn--primary:hover, cień
   0 12px 28px) mógł się pokazać bez konkurowania z pulsującym box-shadow
   (animacja CSS nadpisywałaby go co klatkę). */
@keyframes cta-pulse {
  0% { box-shadow: 0 0 0 0 rgba(31, 61, 43, 0.35); }
  100% { box-shadow: 0 0 0 10px rgba(31, 61, 43, 0); }
}
@media (prefers-reduced-motion: no-preference) {
  .btn--pulse {
    animation: cta-pulse 2s ease-in-out 1.2s 3;
  }
  .btn--pulse:hover,
  .btn--pulse:focus-visible {
    animation-play-state: paused;
  }
}

/* ============================== INTRO (strona główna) ============================== */
/* Raz na sesję, tylko index.html: dwa koła z ikonami wjeżdżają z boków,
   część wspólna się rozjaśnia, pojawia się logo, nakładka znika (1,8 s).
   Nakładka trafia do DOM tylko wtedy, gdy intro ma się odtworzyć
   (<template> + krótki skrypt na początku <body>). */
.intro {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--accent);
  color: var(--canvas);
  cursor: pointer;
  animation: intro-znika 0.5s var(--ease) 1.3s forwards;
}
.intro--koniec { animation: intro-znika 0.15s ease forwards; }
.intro__scena {
  --w: min(760px, 92vw);
  position: relative;
  width: var(--w);
}
.intro__svg { display: block; width: 100%; height: auto; overflow: visible; }
.intro__kolo--l { animation: intro-z-lewej 0.65s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.intro__kolo--p { animation: intro-z-prawej 0.65s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.intro__soczewka { opacity: 0; animation: intro-pojawia 0.35s ease 0.55s forwards; }
.intro__srodek {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--w) * 0.016);
  opacity: 0;
  transform: translate(-50%, -50%);
  animation: intro-logo 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) 0.65s forwards;
}
.intro__srodek img {
  display: block;
  width: calc(var(--w) * 0.084);
  height: auto;
  opacity: 0.8;
}
.intro__srodek span {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: calc(var(--w) * 0.053);
  line-height: 1;
  letter-spacing: -0.02em;
}
@keyframes intro-z-lewej { from { opacity: 0; transform: translateX(-640px); } to { opacity: 1; transform: none; } }
@keyframes intro-z-prawej { from { opacity: 0; transform: translateX(640px); } to { opacity: 1; transform: none; } }
@keyframes intro-pojawia { to { opacity: 1; } }
@keyframes intro-logo {
  from { opacity: 0; transform: translate(-50%, -44%) scale(0.94); }
  to { opacity: 1; transform: translate(-50%, -50%); }
}
@keyframes intro-znika { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .intro { display: none !important; }
}

/* ============================== SPLASH ============================== */
/* Pełnoekranowa nakładka na wejściu — dwa warianty na każdej stronie,
   .splash--new i .splash--old, oba w DOM naraz, tylko jeden naraz widoczny
   (display, patrz "Przełącznik nowy/stary" niżej). Pierwsze wejście w
   sesji (sessionStorage, inline <script> w <head>, sprawdzane przed
   pierwszym renderem) pokazuje nowy, rozbudowany wariant — każde kolejne
   wejście na jakąkolwiek stronę w tej samej sesji pokazuje z powrotem
   wariant sprzed przebudowy 30.09.2026 (prostsze logo na kremowym tle,
   1.44s) zamiast w ogóle nic nie pokazywać — to świadoma decyzja klienta:
   nowy splash jako "powitanie" przy pierwszym wejściu, stary jako lżejszy,
   już wcześniej sprawdzony akcent przy każdym kolejnym wejściu na stronę.

   .splash (baza, wspólna dla obu wariantów) niesie tylko pozycjonowanie —
   kolor tła i animacja należą do każdego wariantu osobno. */
.splash {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---- Wariant nowy (.splash--new) — pierwsze wejście w sesji ----
   Tło idzie zieleń (--accent) → kremowy (--canvas), na środku ikona +
   napis "FitPage" wchodzą osobno (ikona pierwsza, napis zaraz po niej),
   potem oba przechodzą z kremowego na zielony w tym samym momencie, co tło
   robi odwrotnie — nakładka znika dopiero, gdy ten kolorowy crossfade jest
   już prawie domknięty, żeby nic nie "skakało" w momencie zniknięcia. Cały
   timing: czyste CSS @keyframes z animation-fill-mode: forwards (skrót
   `forwards` w `animation`) na KAŻDYM elemencie z osobna — zero JS
   potrzebne, żeby cokolwiek z tego ruszyło albo się zakończyło. JS
   (script.js) dokłada wyłącznie pomijanie klikiem/klawiszem, patrz niżej.

   Technika "dwa nałożone elementy + crossfade opacity" (zamiast animowania
   `color` wprost, czego nie ma na liście dozwolonych właściwości: transform,
   opacity, background-color) — ikona to dwa obrazy (`images/logo-fitpage-
   cream.png`, wygenerowany z oryginału przez Pillow z tej samej maski alfa,
   i oryginalny zielony `logo-fitpage.png`), napis to dwa identyczne <span>
   w różnych kolorach. Oba zestawy nakładają się idealnie (position:
   absolute na drugiej warstwie), więc crossfade opacity wygląda jak zmiana
   koloru, mimo że `color`/żaden kolor obrazu nigdy nie jest animowany. */
.splash--new {
  background-color: var(--accent);
  animation: splash-bg 1s var(--ease) forwards,
             splash-hide-new 1s var(--ease) forwards;
}
.splash__inner {
  display: flex;
  align-items: center;
  gap: 14px;
}

.splash__icon-stack {
  position: relative;
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  animation: splash-icon-scale 1s var(--ease) forwards;
}
.splash__icon {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.splash__icon--cream { animation: splash-icon-cream 1s var(--ease) forwards; }
.splash__icon--green { animation: splash-icon-green 1s var(--ease) forwards; }

.splash__text-stack {
  position: relative;
  display: inline-block;
}
.splash__text {
  display: block;
  font-family: var(--font-heading);
  font-size: clamp(1.8rem, 6vw, 2.4rem);
  font-weight: 700;
  white-space: nowrap;
}
.splash__text--cream {
  color: var(--canvas);
  animation: splash-text-cream 1s var(--ease) forwards;
}
.splash__text--green {
  position: absolute;
  inset: 0;
  color: var(--accent);
  animation: splash-text-green 1s var(--ease) forwards;
}

/* Procenty poniżej odpowiadają konkretnym milisekundom na osi 1.6s:
   6%=100ms (start wejścia ikony), 28%=450ms (koniec wejścia ikony),
   24%=380ms (start wejścia napisu, lekko na zakładkę z ikoną — "zaraz
   po niej"), 46%=730ms (koniec wejścia napisu), 64%=1020ms (koniec
   przystanku, start przejścia kolorów), 89%=1420ms (koniec przejścia
   kolorów), 81%=1300ms (start zanikania całej nakładki, nachodzi na
   koniec przejścia kolorów, więc do zniknięcia dochodzi, gdy kolory są
   już prawie na miejscu — bez tego nachodzenia zanikanie zaczynałoby się
   dopiero po twardej przerwie, co czuć jako zacięcie).

   Segment przejścia kolorów (64%-89%) ma własny `animation-timing-function:
   linear`, inny niż `var(--ease)` odziedziczony z `animation` na elemencie.
   Powód: `var(--ease)` to agresywna krzywa ease-out, która przy wejściu
   ikony/napisu daje pożądany, żwawy "doskok" na miejsce, ale na crossfadzie
   kolorów (opacity dwóch warstw + background-color razem) ściskała niemal
   całą widoczną zmianę w pierwszą jedną trzecią segmentu, zostawiając długi,
   wizualnie "martwy" ogon - zmierzone przez scrubowanie animacji (Web
   Animations API, currentTime) co kilka punktów procentowych: przy 72%
   (niecałe 1/3 drogi przez segment) opacity było już na 0.146 z 1, czyli
   85% zmiany już za sobą. Linear rozkłada to równo na całej długości
   segmentu, więc kolory realnie "płyną" przez cały czas trwania przejścia,
   zamiast skoczyć na początku i stać w miejscu do końca. */
@keyframes splash-icon-scale {
  0%, 6%    { transform: scale(0.82); }
  28%, 100% { transform: scale(1); }
}
@keyframes splash-icon-cream {
  0%, 6%    { opacity: 0; }
  28%       { opacity: 1; }
  64%       { opacity: 1; animation-timing-function: linear; }
  89%, 100% { opacity: 0; }
}
@keyframes splash-icon-green {
  0%, 89%   { opacity: 0; animation-timing-function: linear; }
  100%      { opacity: 1; }
}
@keyframes splash-text-cream {
  0%, 24%   { opacity: 0; transform: translateY(8px); }
  46%       { opacity: 1; transform: translateY(0); }
  64%       { opacity: 1; transform: translateY(0); animation-timing-function: linear; }
  89%, 100% { opacity: 0; transform: translateY(0); }
}
@keyframes splash-text-green {
  0%, 89%   { opacity: 0; animation-timing-function: linear; }
  100%      { opacity: 1; }
}
@keyframes splash-bg {
  0%, 64%   { background-color: var(--accent); animation-timing-function: linear; }
  89%, 100% { background-color: var(--canvas); }
}
@keyframes splash-hide-new {
  0%, 81%  { opacity: 1; visibility: visible; pointer-events: auto; }
  100%     { opacity: 0; visibility: hidden; pointer-events: none; }
}

/* ---- Wariant stary (.splash--old) — drugie i kolejne wejście w sesji ----
   Dokładnie ta sama implementacja, która działała na stronie przed
   przebudową 30.09.2026 (logo na stałym kremowym tle, bez przejścia
   kolorów) — przywrócona tu pod osobnymi nazwami klas/keyframes, żeby nie
   kolidowała z wariantem nowym. Domyślnie ukryty (display: none);
   przełącznik "nowy/stary" niżej odwraca to w zależności od tego, czy
   .splash-repeat jest na <html>. */
.splash--old {
  display: none;
  background-color: var(--canvas);
  animation: splash-hide-old 0.6s var(--ease) forwards;
}
.splash__logo-old {
  width: 125px; /* 96px + 30% */
  height: auto;
  animation: splash-logo-old 0.6s var(--ease) forwards; /* skrócone z 1.44s 13.10.2026 */
}
@keyframes splash-logo-old {
  0%   { opacity: 0; transform: scale(0.6); }
  30%  { opacity: 1; transform: scale(1); }
  70%  { opacity: 1; transform: scale(1.15); }
  100% { opacity: 0; transform: scale(1.4); }
}
@keyframes splash-hide-old {
  0%, 85% { opacity: 1; visibility: visible; pointer-events: auto; }
  100%    { opacity: 0; visibility: hidden; pointer-events: none; }
}

/* Pomijanie klikiem/klawiszem (script.js dodaje tę klasę raz, przy
   pierwszym kliku albo klawiszu, na OBA warianty naraz — tylko widoczny
   ma znaczenie, ale to tańsze niż sprawdzać który to). Nie usuwa animacji
   (co cofnęłoby wszystko do stanu 0% i dałoby widoczny skok) — zamiast
   tego ściska KAŻDĄ trwającą animację do prawie zera, więc każda
   dokańcza swoją własną krzywą i ląduje dokładnie na zdefiniowanym
   stanie końcowym. Ten sam, dobrze znany trik co globalne wyłączanie
   animacji pod prefers-reduced-motion, tu użyty punktowo na nakładkę. */
.splash--skip,
.splash--skip * {
  animation-duration: 0.01ms !important;
  animation-delay: 0s !important;
}

/* !important celowe: .splash-repeat .splash--old (niżej) ma wyższą
   swoistość (dwie klasy) niż ta reguła media (jedna klasa) i bez
   !important by ją przebił, pokazując stary splash nawet pod
   prefers-reduced-motion. Dostępność wygrywa zawsze, niezależnie od
   swoistości reszty reguł. */
@media (prefers-reduced-motion: reduce) {
  .splash { display: none !important; }
}

/* Przełącznik nowy/stary — klasa .splash-repeat na <html> (inline <script>
   w <head>, sprawdza sessionStorage przed pierwszym renderem) oznacza, że
   to NIE jest pierwsze wejście w tej sesji: chowa wariant nowy, pokazuje
   stary. Bez tej klasy (pierwsze wejście) domyślny stan obu wariantów
   (.splash--new widoczny przez bazowe display:flex z .splash, .splash--old
   ukryty) już jest tym, co ma się pokazać — nic dodatkowego nie trzeba
   pisać dla tego przypadku. */
.splash-repeat .splash--new { display: none; }
.splash-repeat .splash--old { display: flex; }

/* ============================== NAV ============================== */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(247, 243, 234, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(31, 61, 43, 0.10);
  color: var(--text);
}
.nav__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 64px;
}
.nav__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}
.nav__logo-img {
  display: block;
  /* Wymiary jawne + flex-shrink: 0, nie "height: 44px; width: auto".
     .nav__logo to kontener flex, a przy width: auto obrazek jest elementem
     flex, który może się kurczyć — na telefonach węższych niż ~385px
     (360px: 19x44, 375px: 34x44, 320px: 0x44 — zmierzone) logo było
     ściskane wszerz i wyglądało na rozciągnięte pionowo. Ikona jest
     kwadratowa (596x596), więc 44x44 to jej realne proporcje. */
  width: 44px;
  height: 44px; /* dopasowane do wysokości .nav__cta (~43px) */
  flex-shrink: 0;
  object-fit: contain;
}
.nav__logo-text {
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: -0.03em;
  color: var(--text);
}

/* .nav__right grupuje linki + CTA + hamburger, żeby .nav__inner mogło
   trzymać tylko dwa elementy (logo | reszta) w space-between — tak samo
   na każdej szerokości. Pod 700px chowają się same linki tekstowe
   (.nav__links); CTA zostaje widoczne w pasku nav (który i tak jest
   position: sticky) zamiast znikać do hamburgera — odwiedzający z telefonu
   (większość ruchu wg PRODUCT.md) ma "Umów konsultację" w zasięgu zawsze,
   bez dodatkowego dotknięcia. Odstęp 20px (obniżony z 26px po dodaniu
   6. linku "Opinie") — przy 26px pełny rząd (6 linków + CTA) potrzebował
   ~710px, co przy progu 700px dawało realny poziomy overflow ~5-10px w
   wąskim oknie 700-709px (zmierzone empirycznie w iframe). Przy 20px
   potrzebne ~680px, zapas ~20px pod progiem. */
.nav__right {
  display: flex;
  align-items: center;
  gap: 20px;
}
.nav__links {
  display: flex;
  align-items: center;
  gap: 20px;
}
.nav__links a {
  font-size: 0.95rem;
  text-decoration: none;
  color: var(--text);
  opacity: 0.85;
  border-radius: 6px;
  transition: opacity 0.15s, transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.nav__links a:hover,
.nav__links a:focus-visible {
  opacity: 1;
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.nav__cta {
  padding: 9px 18px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent) !important;
  font-weight: 600;
  opacity: 1 !important;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 0.18s var(--ease),
              box-shadow 0.18s var(--ease),
              background-color 0.18s var(--ease);
}
/* Ten sam lift co .btn--primary:hover (identyczny przycisk "Umów
   konsultację", inna klasa z powodów layoutu w nav) — dotąd nav__cta nie
   miał żadnej reakcji na hover w ogóle; bez tego, po wstrzymaniu pulsu na
   hover (patrz cta-pulse wyżej), przycisk stawałby się nagle całkiem
   statyczny. */
.nav__cta:hover,
.nav__cta:focus-visible {
  background: var(--accent-strong);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(31, 61, 43, 0.28);
}

.nav__toggle {
  display: none;              /* widoczny tylko na mobile (media query) */
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;                /* WCAG 2.5.5/2.5.8 — minimalny touch target 44×44px */
  height: 44px;
  padding: 11px;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.nav__toggle span {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
}

/* ============================== HERO ============================== */
/* Bez własnego tła — ten sam kremowy canvas co reszta strony. */
.hero {
  background: transparent;
  color: var(--text);
  text-align: center;
  padding: 96px 20px 48px;
}
.hero__inner { max-width: 760px; margin-inline: auto; }
.hero__makieta { max-width: 240px; margin: 40px auto 0; }
.hero__makieta img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 22px 30px rgba(31, 45, 36, 0.18));
}
.hero__notka { margin: 16px 0 0; font-size: 0.9375rem; line-height: 1.5; color: var(--muted); }
.hero__nadtytul {
  margin: 0 0 14px;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--accent-strong);
}
p.hero__title {
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.hero__title {
  font-size: clamp(1.9rem, 6vw, 3.1rem);
  margin-bottom: 0.4em;
}
.hero__subtitle {
  font-size: clamp(1rem, 2.4vw, 1.2rem);
  color: var(--muted);
  margin-bottom: 2em;
}

/* wariant kompaktowy — nagłówek podstrony (np. kontakt.html) */
.hero--compact { padding: 72px 20px 60px; }
.hero--compact .hero__subtitle { margin-bottom: 0; }

/* wariant ze zdjęciem w tle — dla artykułów z dedykowaną grafiką nagłówka.
   Samo zdjęcie ustawiane jest per-strona inline (style="background-image"),
   bo to treść konkretnego artykułu, nie decyzja stylistyczna — reszta
   (przyciemnienie, wysokość, kolor tekstu) żyje tutaj, żeby dało się użyć
   dla kolejnych artykułów bez powtarzania CSS. background-size: cover +
   background-position: center gwarantują, że zdjęcie wypełnia cały obszar
   nagłówka na każdej szerokości ekranu — bez pustych pasów po bokach. */
.hero--cover {
  position: relative;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  min-height: 260px;
}
.hero--cover::before {
  /* przyciemnienie w kolorze Pine Black (ten sam ciemny akcent co stopka) —
     0.65 dobrane tak, żeby jasny tekst trzymał WCAG AA (4.5:1) nawet na
     najjaśniejszych fragmentach tego konkretnego zdjęcia (żółta ściana,
     białe koszulki) — sprawdzone liczbowo, nie na oko. */
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(22, 33, 27, 0.65);
}
.hero--cover .hero__inner { position: relative; z-index: 1; }
.hero--cover .artykul__meta,
.hero--cover .hero__title {
  color: var(--on-accent);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35); /* dodatkowa czytelność na ruchliwym zdjęciu */
}

/* ============================== TRENINGI (pasek) ============================== */
/* Poziomy, zapętlony pasek nad "O nas" — dwie identyczne kopie listy obok
   siebie, animacja przesuwa cały tor o -50% jego własnej szerokości, czyli
   dokładnie o szerokość jednej kopii -> pętla bez szwu. Druga kopia ma
   aria-hidden, żeby czytnik ekranu nie usłyszał każdej nazwy dwa razy.
   Ikony neutralne (--text); zieleń akcentowa tylko jako kropka-separator
   między pozycjami — zgodnie z The One Mark Rule (akcent rzadko, nie jako
   wypełnienie całego paska). */
.trainings {
  position: relative;
  overflow: hidden;
  padding: 28px 0;
}
.trainings:hover .trainings__track,
.trainings:focus-within .trainings__track,
.trainings--stop .trainings__track { animation-play-state: paused; }
.trainings__pauza {
  position: absolute;
  top: 50%;
  right: 12px;
  z-index: 1;
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--canvas);
  color: var(--text);
  transform: translateY(-50%);
  cursor: pointer;
}
.trainings__pauza:hover { border-color: var(--accent-strong); color: var(--accent-strong); }
.trainings__ikona-start,
.trainings--stop .trainings__ikona-pauza { display: none; }
.trainings--stop .trainings__ikona-start { display: block; }
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.trainings__track {
  display: flex;
  width: max-content;
  /* Jedna kopia listy = 3 przebiegi 8 dyscyplin, zmierzone 3568px (szersza
     niż ekran 2560px, więc pętla nigdy nie odsłania pustego pasa). Tempo
     bez zmian względem starej, 8-elementowej kopii (~1189px w 32s, czyli
     ~37px/s): 3568 / 37,2 ≈ 96s. Przy zmianie listy przelicz tak samo. */
  animation: trainings-scroll 108s linear infinite;
}
.trainings__list {
  display: flex;
  align-items: center;
  gap: 28px;
  list-style: none;
  margin: 0;
  padding: 0 14px;
  flex-shrink: 0;
}
.trainings__item {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.95rem;
}
.trainings__item svg {
  width: 22px;
  height: 22px;
  color: var(--text);
  flex-shrink: 0;
}
.trainings__item::after {
  content: "";
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  margin-left: 14px;
  border-radius: 50%;
  background: var(--accent);
}

@keyframes trainings-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  /* Pasek stoi: bez animacji, bez kopii do pętli i bez powtórzeń, tylko
     8 dyscyplin raz, zawijanych i wyśrodkowanych na każdej szerokości. */
  .trainings__track { animation: none; width: auto; justify-content: center; }
  .trainings__pauza { display: none; }
  .trainings__list { flex-wrap: wrap; justify-content: center; row-gap: 14px; }
  .trainings__list[aria-hidden="true"],
  .trainings__item[aria-hidden="true"] { display: none; }
}

/* ============================== CTA (domykające) ============================== */
/* Ostatnia sekcja przed stopką — Atuty (najsilniejszy blok zaufania na
   stronie) dotąd wpadały prosto w ciemną stopkę bez żadnego wezwania do
   działania (złapane przez /impeccable critique: naruszenie peak-end rule
   dokładnie w momencie najwyższego zbudowanego zainteresowania). Ten sam
   wizualny język co hero (wyśrodkowany tekst, ten sam .btn.btn--primary,
   bez panelu/tła — zgodnie z Flat Canvas Rule) — świadomie bez nowych
   efektów ozdobnych, żeby to był spokojny, czytelny blok, nie kolejny
   element przyciągający uwagę. */
.cta-closing { text-align: center; }
.cta-closing__inner { max-width: 560px; margin-inline: auto; }
.cta-closing .section__title { margin-bottom: 0.5em; }
.cta-closing__text {
  max-width: 48ch;
  margin-inline: auto;
  margin-bottom: 1.75em;
  color: var(--muted);
  text-wrap: pretty;
}
.cta-closing__podpis { margin: 20px 0 0; font-size: 0.9375rem; color: var(--muted); }
.cta-closing__podpis a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent-strong);
  font-weight: 600;
}

/* ============================== DLA KOGO ============================== */
.dla-kogo__lista { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.dla-kogo__lista li { border-bottom: 1px solid var(--border); }
.dla-kogo__link {
  position: relative;
  display: grid;
  gap: 4px;
  padding: 20px 48px 20px 16px;
  color: var(--text);
  text-decoration: none;
  transition: background-color 0.18s var(--ease);
}
.dla-kogo__link::after {
  content: "\2192";
  position: absolute;
  top: 50%;
  right: 16px;
  font-size: 1.25rem;
  color: var(--accent-strong);
  transform: translateY(-50%);
  transition: transform 0.18s var(--ease);
}
.dla-kogo__nazwa { font-family: var(--font-heading); font-size: 1.2rem; font-weight: 700; line-height: 1.25; }
.dla-kogo__opis { color: var(--muted); }
.dla-kogo__link:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; }
@media (hover: hover) {
  .dla-kogo__link:hover { background: var(--bg); }
  .dla-kogo__link:hover .dla-kogo__nazwa { color: var(--accent-strong); }
  .dla-kogo__link:hover::after { transform: translate(4px, -50%); }
}
@media (min-width: 900px) {
  .dla-kogo__lista { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 40px; }
  .dla-kogo__lista li:first-child { border-bottom: 1px solid var(--border); }
}
@media (prefers-reduced-motion: reduce) {
  .dla-kogo__link, .dla-kogo__link::after { transition: none; }
}

/* ============================== PODSTRONY OFERTOWE ============================== */
.oferta__dopisek { margin: 12px 0 0; color: var(--muted); font-size: 0.9375rem; }
.oferta__dopisek a,
.oferta-pakiet__inne a { color: var(--accent-strong); font-weight: 600; }
.oferta-pakiet__grid { display: grid; gap: 24px; }
.oferta-pakiet__cena { margin: 0; font-family: var(--font-heading); font-size: 2rem; font-weight: 700; color: var(--accent); }
.oferta-pakiet__cena span { font-family: var(--font-body); font-size: 0.95rem; font-weight: 600; color: var(--muted); }
.oferta-pakiet__cena { white-space: nowrap; }
.oferta-pakiet__czas { margin: 8px 0 0; color: var(--muted); }
.oferta-pakiet__inne { margin: 20px 0 0; color: var(--muted); max-width: 60ch; }
@media (min-width: 900px) {
  .oferta-pakiet__grid { grid-template-columns: minmax(0, 0.7fr) minmax(0, 2fr); gap: 56px; align-items: start; }
}
.style-pasek__lista.style-pasek__lista--dwa { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 720px; }
@media (max-width: 768px) {
  .style-pasek__lista.style-pasek__lista--dwa li { flex-basis: 47%; }
}
.hero--oferta .hero__akcje { margin-top: 28px; }
.oferta-pakiet__nazwa { margin: 0 0 4px; font-weight: 600; color: var(--muted); }

/* ============================== CO DOSTAJESZ ============================== */
/* Makieta telefonu (projekt pokazowy, podpisany jako taki) obok listy
   tego, co trener dostaje. Lista to <dl> z hairline'ami, nie siatka kart
   z ikonami. Mobile: makieta nad listą, od 900px obok siebie. */
.co-dostajesz__grid { display: grid; gap: 24px; }
.co-dostajesz__lista { margin: 0; }
.co-dostajesz__punkt {
  padding: 18px 0;
  border-top: 1px solid var(--border);
}
.co-dostajesz__punkt:last-child { border-bottom: 1px solid var(--border); }
.co-dostajesz__punkt dt {
  font-family: var(--font-heading);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--text);
}
.co-dostajesz__punkt dd {
  margin: 6px 0 0;
  max-width: 52ch;
  color: var(--muted);
}

/* ============================== O NAS ============================== */
.o-nas p {
  max-width: 680px;
  color: var(--muted);
}
.o-nas strong { color: var(--text); }
.o-nas__kto { font-size: 1.05rem; color: var(--text); }
.o-nas__portret { margin: 0 0 24px; max-width: 220px; }
.o-nas__portret img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--radius); }
.o-nas__text p:last-child { margin-bottom: 0; }

/* Pasek procesu: 6 etapów z proces.html w jednym rzędzie (desktop) albo
   w dwóch kolumnach (telefon). Numer niesie kolejność, więc zostaje. */
.proces-pasek__tytul {
  margin: 48px 0 18px;
  font-size: 1.15rem;
}
.proces-pasek {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.proces-pasek li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-weight: 600;
  color: var(--text);
  transition: border-color 0.18s var(--ease), background-color 0.18s var(--ease);
}
.proces-pasek a { color: inherit; text-decoration: none; }
.proces-pasek a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.proces-pasek a:focus-visible { outline: none; }
.proces-pasek li:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .proces-pasek li:hover { border-color: var(--accent-strong); background: var(--bg); }
  .proces-pasek li:hover a { color: var(--accent-strong); }
}
.proces-pasek__nr {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.8rem;
  font-weight: 700;
}
.o-nas__wiecej { margin: 20px 0 0; }
.o-nas__wiecej a {
  display: inline-block;
  padding: 10px 0;
  color: var(--accent-strong);
  font-weight: 600;
  text-decoration: none;
  text-underline-offset: 3px;
}
.o-nas__wiecej a:hover,
.o-nas__wiecej a:focus-visible { text-decoration: underline; }

/* ============================== PORTFOLIO ============================== */
/* auto-fit (nie auto-fill) + justify-content: center — z jedną kartą
   auto-fill wciąż rezerwuje tyle kolumn 280-400px, ile zmieściłoby się w
   .container, więc karta zostaje przyklejona do lewej krawędzi z dużą,
   niewidzialną pustką po prawej (złapane przez /impeccable critique: karta
   "floats in dead space" tuż przy sekcji budującej zaufanie). auto-fit
   zwija nieużywane tory do 0px, więc jedyna realna karta jest wyśrodkowana
   w sekcji zamiast wyglądać na przypadkowo osierocony fragment siatki;
   przy kolejnych realizacjach karty i tak ułożą się w rząd od lewej, jak
   dotąd — zmiana wpływa tylko na wygląd przy 1-2 kartach. */
.portfolio__grid {
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 400px));
  justify-content: center;
}
.card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card__body { padding: 24px; }
.card__title { font-size: 1.15rem; margin-bottom: 0.4em; }
.card__text { color: var(--muted); font-size: 0.95rem; }
.card__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  text-decoration: none;
  color: var(--accent-strong);
  border-radius: 6px;
  transition: gap 0.18s var(--ease), transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.card__link:hover,
.card__link:focus-visible {
  gap: 12px;
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.card__link svg { width: 16px; height: 16px; }

/* ============================== ARTYKUŁY ============================== */
/* Karta z dużym kwadratowym obrazkiem na górze, pod nim tytuł i data z
   czasem czytania. Bez tła/obramowania karty: obrazek sam wyznacza jej
   kształt, a tekst siedzi wprost na canvasie. Cień pojawia się tylko na
   obrazku i tylko na hover/focus (DESIGN.md, "The Lift-Means-Interactive
   Rule"). Siatka: 1 kolumna na telefonie, 2 od 700px. */
.artykuly__intro { max-width: 62ch; }
.artykuly__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 36px;
}
.artykul-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.artykul-card__media {
  position: relative;
  margin-bottom: 10px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
  transition: box-shadow 0.25s var(--ease), transform 0.25s var(--ease);
}
.artykul-card__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}
.artykul-card:hover .artykul-card__media,
.artykul-card:focus-within .artykul-card__media {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.artykul-card:hover .artykul-card__img,
.artykul-card:focus-within .artykul-card__img { transform: scale(1.03); }

/* pigułki kategorii w lewym górnym rogu obrazka: ciemna zieleń z kremowym
   tekstem, bo okładki mają jasne, kremowe tło */
.artykul-card__tags {
  position: absolute;
  top: 14px;
  left: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.artykul-card__tags li {
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  padding: 7px 12px;
  border-radius: 999px;
}

.artykul-card__title { font-size: 1.15rem; line-height: 1.3; margin: 0; }
.artykul-card__title a {
  text-decoration: none;
  color: var(--text);
  transition: color 0.15s;
}
.artykul-card:hover .artykul-card__title a { color: var(--accent-strong); }
.artykul-card__title a::after {
  /* powiększa klikalny obszar do całej karty bez zagnieżdżania linków */
  content: "";
  position: absolute;
  inset: 0;
}

@media (min-width: 700px) {
  .artykuly__grid { grid-template-columns: repeat(2, 1fr); gap: 48px 32px; }
  .artykul-card__title { font-size: 1.35rem; }
}
/* od 1024px trzy kolumny i niższe okładki 4:3; na głównej jeden pełny
   rząd, czyli 3 najnowsze (jak na telefonie) */
@media (min-width: 1024px) {
  .artykuly__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 44px 28px; }
  .artykul-card__img { aspect-ratio: 4 / 3; }
  .artykul-card__title { font-size: 1.2rem; }
  #artykuly .artykuly__grid .artykul-card:nth-child(n+4) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .artykul-card__media,
  .artykul-card__img { transition: none; }
  .artykul-card:hover .artykul-card__media,
  .artykul-card:focus-within .artykul-card__media,
  .artykul-card:hover .artykul-card__img,
  .artykul-card:focus-within .artykul-card__img { transform: none; }
}

/* metadata (data publikacji) — współdzielona przez kartę na liście i
   nagłówek pojedynczego artykułu */
.artykul__meta { color: var(--muted); font-size: 0.8rem; margin: 0; }

/* podstrona pojedynczego artykułu — typografia jak .polityka (tryb "Read"):
   tekst ograniczony do ~65ch, żeby nie powtórzyć problemu z długością linii */
/* Cała treść artykułu (nagłówek h2/h3, akapity, CTA, link powrotny) w jednej
   wyśrodkowanej kolumnie czytelniczej — .container ma 1080px, a sam tekst
   ograniczony do ~65ch (żeby linia nie była za długa) zostawiał dotąd puste
   miejsce WYŁĄCZNIE po prawej stronie, bo kolumna była przyklejona do
   lewej krawędzi kontenera zamiast wyśrodkowana. */
.artykul { max-width: 65ch; margin-inline: auto; }
/* okładka artykułu (1200x630) nad treścią, zaokrąglona jak reszta strony */
.artykul__cover { margin: 0; }
.artykul__cover-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}
.artykul__body { margin-top: 32px; }
.artykul__body p,
.artykul__body ul,
.artykul__body ol {
  color: var(--muted);
}
.artykul__body h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; }
.artykul__body h2:first-child { margin-top: 0; }
.artykul__body h3 { font-size: 1.1rem; margin: 1.3em 0 0.4em; }
.artykul__body strong { color: var(--text); }
/* Linki wewnątrz treści (linkowanie międzyartykułowe) — kolor akcentu,
   bez podkreślenia w spoczynku, podkreślenie tylko na hover/focus. Zwykły
   tekstowy link w zdaniu, nie link-przycisk — bez lift/shadow, które mają
   .brief__back/.artykul__back/.card__link (to inna kategoria, patrz
   CLAUDE.md "Popraw animacje interakcji"), bo uniesienie pojedynczego
   słowa w środku płynącego akapitu wyglądałoby na złamane, nie subtelne. */
.artykul__body a { color: var(--accent-strong); text-decoration: none; }
.artykul__body a:hover,
.artykul__body a:focus-visible { text-decoration: underline; }
.artykul__body ul,
.artykul__body ol { margin-bottom: 1em; padding-left: 1.25em; }
.artykul__body li { margin-bottom: 0.4em; }

/* Tabela porównawcza w treści artykułu (pierwsza: strona-czy-booksy).
   Płaska, tylko hairline między wierszami (Flat Canvas Rule), bez tła.
   Wrapper przewija się poziomo, gdyby trzy kolumny nie zmieściły się
   na wąskim telefonie, zamiast rozpychać całą stronę. */
.artykul__table-wrap {
  overflow-x: auto;
  margin: 0 0 1em;
}
.artykul__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  line-height: 1.45;
}
.artykul__table caption {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.artykul__table th,
.artykul__table td {
  padding: 10px 12px 10px 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}
.artykul__table thead th {
  font-weight: 600;
  color: var(--text);
  border-bottom-color: var(--text);
}
.artykul__table tbody th {
  font-weight: 600;
  color: var(--text);
  min-width: 8.5em;
}
.artykul__table td { color: var(--muted); min-width: 10em; }

/* Wąski telefon: trzy kolumny się nie mieszczą (zmierzone przy 375px:
   433px treści na 335px miejsca, trzecia kolumna ucięta za krawędzią).
   Każdy wiersz staje się blokiem: nagłówek wiersza na całą szerokość,
   pod nim dwie komórki obok siebie z etykietą z data-label. */
@media (max-width: 560px) {
  .artykul__table thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .artykul__table tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
  }
  .artykul__table th,
  .artykul__table td {
    min-width: 0;
    padding: 0;
    border-bottom: 0;
  }
  .artykul__table tbody th {
    grid-column: 1 / -1;
    margin-bottom: 6px;
  }
  .artykul__table td::before {
    content: attr(data-label);
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text);
  }
}

/* FAQ na końcu artykułu: ten sam akordeon co faq.html, tylko w kolumnie
   czytelniczej artykułu. */
.artykul__faq { margin-bottom: 1em; }

/* "Zobacz też" — link do jednego powiązanego artykułu, przed CTA.
   Hairline border u góry jako jedyny separator (bez panelu/tła, zgodnie z
   Flat Canvas Rule) — ten sam wzorzec co linia nad .footer__links. */
.artykul__related {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
.artykul__related p {
  margin: 0 0 4px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
}
.artykul__related a { color: var(--accent-strong); text-decoration: none; }
.artykul__related a:hover,
.artykul__related a:focus-visible { text-decoration: underline; }

.artykul__cta { margin-top: 32px; }
.artykul__cta p { margin-bottom: 12px; color: var(--muted); }
.artykul__back { margin-top: 28px; font-size: 0.9rem; }
.artykul__back a {
  display: inline-block;
  color: var(--accent-strong);
  text-decoration: none;
  border-radius: 6px;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.artykul__back a:hover,
.artykul__back a:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

/* ============================== OPINIE (opinie klientów) ============================== */
/* Ta sama siatka co .artykuly__grid — auto-fit + 1fr, żeby puste tory
   kolumn zapadały się zamiast zostawiać widoczną dziurę, kiedy opinii
   jest mniej niż mieściłoby się w pełnym rzędzie. Karta płaska w
   spoczynku, cień tylko na hover — jak .artykul-card/.krok, zgodnie
   z "The Lift-Means-Interactive Rule" (cień w spoczynku zastrzeżony dla
   portfolio). Gwiazdki jako własne SVG (nie znaki Unicode ★, zakazane
   przez craft-floor jako namiastka systemu ikon), w kolorze akcentu —
   pojedyncza dopuszczalna kolorystyczna powtarzalność, bo to rozpoznawalny,
   wymagający jednolitości wzorzec oceny, nie ozdoba sparowana z resztą UI. */
.opinie__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 28px;
  color: var(--muted);
  font-size: 0.95rem;
}
.opinie__score { font-weight: 700; color: var(--text); }
.opinie__stars {
  display: inline-flex;
  gap: 2px;
  color: var(--accent);
}
.opinie__stars svg { width: 20px; height: 20px; }
.opinie__count { font-weight: 600; }

.opinie__grid {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.opinia-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  transition: transform 0.18s var(--ease),
              box-shadow 0.18s var(--ease),
              border-color 0.18s var(--ease);
}
.opinia-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
  border-color: var(--accent);
}
.opinia-card__stars {
  display: inline-flex;
  gap: 2px;
  color: var(--accent);
  margin-bottom: 12px;
}
.opinia-card__stars svg { width: 18px; height: 18px; }
.opinia-card__text {
  color: var(--muted);
  margin: 0 0 16px;
}
.opinia-card__author {
  margin: 0;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
}
.opinia-card__role {
  font-weight: 400;
  color: var(--muted);
}

/* ============================== PROCES (proces.html) ============================== */
/* Nagłówek: rozmyty kolaż miniatur szablonów pod zieloną warstwą marki
   (0.78 daje min. 5.7:1 dla jasnego tekstu). */
.hero--proces {
  background-image: url("images/proces-hero-800.jpg");
  background-image: image-set(url("images/proces-hero-800.webp") type("image/webp"), url("images/proces-hero-800.jpg") type("image/jpeg"));
}
@media (min-width: 800px) {
  .hero--proces {
    background-image: url("images/proces-hero.jpg");
    background-image: image-set(url("images/proces-hero.webp") type("image/webp"), url("images/proces-hero.jpg") type("image/jpeg"));
  }
}
.hero--proces::before { background: rgba(31, 61, 43, 0.78); }
.hero--proces .hero__subtitle { color: var(--on-accent); text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35); }
@media (min-width: 900px) { .hero--proces { padding-block: 112px 96px; } }

/* Oś czasu: telefon pionowa z linią po lewej, od 900px linia na środku
   i etapy naprzemiennie po obu stronach */
.os {
  --nr: 40px;
  --os-gap: 36px;
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: var(--os-gap);
}
/* linia tylko między kolejnymi numerami, kończy się na ostatnim etapie */
.etap:not(:last-child)::after {
  content: "";
  position: absolute;
  top: var(--nr);
  bottom: calc(-1 * var(--os-gap));
  left: calc(var(--nr) / 2 - 1px);
  width: 2px;
  background: var(--border);
}
.etap {
  position: relative;
  display: grid;
  grid-template-columns: var(--nr) minmax(0, 1fr);
  gap: 18px;
}
.etap__nr {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--nr);
  height: var(--nr);
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  box-shadow: 0 0 0 6px var(--canvas);
}
.etap__czas {
  margin: 0 0 4px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--accent-strong);
}
.etap__nazwa { margin: 0 0 12px; font-size: 1.3rem; }
.etap__role { margin: 0; display: grid; gap: 10px; }
.etap__role div { display: grid; gap: 2px; }
.etap__role dt { font-size: 0.875rem; font-weight: 600; color: var(--text); }
.etap__role dd { margin: 0; color: var(--muted); }
@media (min-width: 900px) {
  .os { --os-gap: 8px; max-width: 980px; margin-inline: auto; }
  .etap:not(:last-child)::after { left: calc(50% - 1px); }
  .etap {
    grid-template-columns: minmax(0, 1fr) var(--nr) minmax(0, 1fr);
    gap: 40px;
    align-items: start;
  }
  .etap__nr { grid-column: 2; grid-row: 1; }
  .etap__tresc { grid-row: 1; padding-top: 6px; }
  .etap:nth-child(odd) .etap__tresc { grid-column: 1; text-align: right; }
  .etap:nth-child(even) .etap__tresc { grid-column: 3; }
  .etap:nth-child(odd) .etap__role div { justify-items: end; }
}

/* Co przygotować */
.przygotuj__grid { display: grid; gap: 24px; }
.przygotuj__lead { margin: 0; color: var(--muted); max-width: 40ch; }
.przygotuj__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}
.przygotuj__lista li {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}
.przygotuj__lista li::before {
  content: "";
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-strong);
}
@media (min-width: 900px) {
  .przygotuj__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 64px; align-items: start; }
}

/* CTA z dwoma przyciskami */
.cta-closing__akcje { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 8px; }
.cta-closing__akcje .btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; }
@media (max-width: 480px) {
  .cta-closing__akcje .btn { flex: 1 1 100%; }
}

/* ============================== FORMULARZ ============================== */
.form { max-width: 560px; }
.form__row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 18px;
}
.form__row label { font-weight: 600; font-size: 0.9rem; }
.form input,
.form textarea,
.form select {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.form input:focus,
.form textarea:focus,
.form select:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: transparent;
}
.form textarea { resize: vertical; }

/* Błąd pola: obramowanie zmienia kolor, ale to nie jedyny sygnał (WCAG
   1.4.1/3.3.1) — dokłada się ikonka (koło z wykrzyknikiem, kolor --error
   wpisany na sztywno w SVG, tak jak ptaszek w .form__consent-box), plus
   tekst w .form__error obok/pod polem. */
.form input:not([type="checkbox"]).is-touched:invalid,
.form textarea.is-touched:invalid {
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='%23A13333'/%3E%3Crect x='11' y='6' width='2' height='8' rx='1' fill='%23FBF8F0'/%3E%3Crect x='11' y='16' width='2' height='2' rx='1' fill='%23FBF8F0'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 18px 18px;
}
.form input:not([type="checkbox"]).is-touched:invalid { background-position: right 12px center; }
.form textarea.is-touched:invalid { background-position: top 12px right 12px; }
/* autouzupełnianie w Chrome nie wymusza własnego (żółtawego) tła w jasnym motywie */
.form input:-webkit-autofill,
.form input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px #F1EEE2 inset;
  caret-color: var(--text);
}

.form__rodo {
  margin-bottom: 16px;
  padding: 12px 14px;
  font-size: 0.85rem;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.form__rodo summary { cursor: pointer; font-weight: 600; color: var(--text); }
.form__rodo p { margin: 10px 0 0; }

/* --- Sekcja zgód (RODO) --- */
.form__consents {
  margin: 0 0 22px;
  padding: 0;
  border: 0;
}
.form__consents legend {
  padding: 0;
  margin-bottom: 12px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
}

.form__consent {
  position: relative;
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 12px;
  align-items: start;
  margin: 0 0 14px;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted);
  cursor: pointer;
}

/* natywny checkbox — niewidoczny, ale klikalny i dostępny z klawiatury */
.form__consent > input {
  position: absolute;
  top: 2px;
  left: 0;
  width: 22px;
  height: 22px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

/* rysowany kwadracik */
.form__consent-box {
  grid-column: 1;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  border: 2px solid var(--border);
  border-radius: 6px;
  background-color: rgba(31, 61, 43, 0.04);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FBF8F0' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0 0;
  transition: background-color 0.18s var(--ease),
              border-color 0.18s var(--ease),
              background-size 0.2s var(--ease);
}
.form__consent-text { grid-column: 2; }

.form__consent:hover .form__consent-box { border-color: var(--accent); }
.form__consent > input:focus-visible ~ .form__consent-box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* stan zaznaczony + animacja „pop” przy kliknięciu */
.form__consent > input:checked ~ .form__consent-box {
  background-color: var(--accent);
  border-color: var(--accent);
  background-size: 14px 14px;
  animation: consent-pop 0.28s var(--ease);
}
.form__consent:has(> input:checked) .form__consent-text { color: var(--text); }

/* nie zaznaczona zgoda wymagana po próbie wysłania — border sam w sobie to
   tylko kolor (WCAG 1.4.1/3.3.1), więc dokłada się ta sama ikonka błędu co
   przy polach tekstowych zamiast pustego kwadracika */
.form__consent > input.is-touched:invalid ~ .form__consent-box {
  border-color: var(--error);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='%23A13333'/%3E%3Crect x='11' y='6' width='2' height='8' rx='1' fill='%23FBF8F0'/%3E%3Crect x='11' y='16' width='2' height='2' rx='1' fill='%23FBF8F0'/%3E%3C/svg%3E");
  background-size: 14px 14px;
}

@keyframes consent-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.22); }
  70%  { transform: scale(0.94); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .form__consent-box { transition: none; }
  .form__consent > input:checked ~ .form__consent-box { animation: none; }
}

/* --- Ocena w gwiazdkach (formularz opinii, opinie-dodaj.html) ---
   Klasyczna czysto-CSS-owa sztuczka z radio-buttonami: kolejność w DOM jest
   odwrócona (5,4,3,2,1), a flex-direction: row-reverse przywraca właściwy
   wizualny porządek 1→5 — dzięki temu ogólny selektor rodzeństwa (~) od
   zaznaczonej/najechanej gwiazdki trafia dokładnie w te "niższe" wizualnie
   (czyli fizycznie kolejne w DOM), które mają się też zapalić. */
.form__rating-group { margin: 0 0 18px; padding: 0; border: 0; }
.form__rating-group legend {
  padding: 0;
  margin-bottom: 10px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
}
.form__rating {
  position: relative;
  display: inline-flex;
  flex-direction: row-reverse;
  gap: 4px;
}
/* natywne radio — niewidoczne, ale klikalne i dostępne z klawiatury (ten sam
   wzorzec „visually hidden” co .form__consent > input) */
.form__rating input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* 44×44px cel dotyku (WCAG 2.5.5/2.5.8, ten sam próg co .nav__toggle) —
   ikona w środku mniejsza, żeby 5 gwiazdek nie rozjeżdżało się na wąskim ekranie */
.form__rating label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--border);
  cursor: pointer;
  transition: color 0.15s var(--ease);
}
.form__rating label svg { width: 26px; height: 26px; }
.form__rating label:hover,
.form__rating label:hover ~ label,
.form__rating input:checked ~ label {
  color: var(--accent);
}
.form__rating input:focus-visible + label {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}
@media (prefers-reduced-motion: reduce) {
  .form__rating label { transition: none; }
}

/* --- Grupa radio prostych wyborów tekstowych (nie ocena gwiazdkowa) ---
   "Ceny na stronie" / "Styl strony" na kontakt.html — oba opcjonalne, więc
   bez ikonki błędu / required. Ta sama animacja zaznaczenia co .form__consent
   (rysowany znacznik + consent-pop) — świadomie ten sam, współdzielony
   keyframe, nie osobna kopia — tylko okrąg zamiast kwadratu, bo to radio,
   nie checkbox, i wypełniona kropka zamiast ptaszka. min-height: 44px na
   <label> (nie na samym 22px kółku) zostaje z poprzedniej wersji — klik
   gdziekolwiek w etykiecie zaznacza input, więc to wystarcza na WCAG
   2.5.5/2.5.8 bez rozciągania samego kółka. */
.form__radio-group { margin: 0 0 18px; padding: 0; border: 0; }
.form__radio-group legend {
  padding: 0;
  margin-bottom: 10px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
}
.form__radio-option {
  position: relative;
  display: grid;
  grid-template-columns: 22px 1fr;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  font-size: 0.95rem;
  color: var(--muted);
  cursor: pointer;
}

/* natywny radio — niewidoczny, ale klikalny i dostępny z klawiatury (ten
   sam wzorzec co .form__consent > input) */
.form__radio-option > input {
  position: absolute;
  top: 50%;
  left: 0;
  width: 22px;
  height: 22px;
  margin: 0;
  transform: translateY(-50%);
  opacity: 0;
  cursor: pointer;
}

/* rysowane kółko — ten sam border/tło/transition co .form__consent-box,
   tylko border-radius: 50% i wypełniona kropka zamiast ptaszka */
.form__radio-dot {
  grid-column: 1;
  width: 22px;
  height: 22px;
  border: 2px solid var(--border);
  border-radius: 50%;
  background-color: rgba(31, 61, 43, 0.04);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='7' fill='%23FBF8F0'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0 0;
  transition: background-color 0.18s var(--ease),
              border-color 0.18s var(--ease),
              background-size 0.2s var(--ease);
}
.form__radio-text { grid-column: 2; }

.form__radio-option:hover .form__radio-dot { border-color: var(--accent); }
.form__radio-option > input:focus-visible ~ .form__radio-dot {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* stan zaznaczony + ta sama animacja „pop” co przy zgodach */
.form__radio-option > input:checked ~ .form__radio-dot {
  background-color: var(--accent);
  border-color: var(--accent);
  background-size: 12px 12px;
  animation: consent-pop 0.28s var(--ease);
}
.form__radio-option:has(> input:checked) .form__radio-text { color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .form__radio-dot { transition: none; }
  .form__radio-option > input:checked ~ .form__radio-dot { animation: none; }
}

/* --- Checkboxy w grupach wyboru (brief): ten sam układ co radio, kwadrat z ptaszkiem --- */
.form__check-box {
  grid-column: 1;
  width: 22px;
  height: 22px;
  border: 2px solid var(--border);
  border-radius: 6px;
  background-color: rgba(31, 61, 43, 0.04);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FBF8F0' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0 0;
  transition: background-color 0.18s var(--ease),
              border-color 0.18s var(--ease),
              background-size 0.2s var(--ease);
}
.form__radio-option:hover .form__check-box { border-color: var(--accent); }
.form__radio-option > input:focus-visible ~ .form__check-box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.form__radio-option > input:checked ~ .form__check-box {
  background-color: var(--accent);
  border-color: var(--accent);
  background-size: 14px 14px;
  animation: consent-pop 0.28s var(--ease);
}
.form__radio-group > .form__hint { display: block; margin: -4px 0 4px; }
.form__radio-group.is-invalid .form__radio-dot,
.form__radio-group.is-invalid .form__check-box { border-color: var(--error); }
@media (prefers-reduced-motion: reduce) {
  .form__check-box { transition: none; }
  .form__radio-option > input:checked ~ .form__check-box { animation: none; }
}

/* --- Formularz krokowy (brief). Bez JS kroki stoją jeden pod drugim. --- */
.form [hidden] { display: none !important; }
.brief__intro {
  max-width: 560px;
  margin: 0 0 24px;
  color: var(--muted);
}
.form__step {
  min-width: 0;
  margin: 0 0 36px;
  padding: 0;
  border: 0;
}
.form__step-title {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 18px;
  font-family: var(--font-heading);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--text);
}
.form__step-title:focus { outline: none; }
.form__step-count {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}
.form.is-stepped .form__step { margin-bottom: 0; }
.form.is-stepped .form__step:not(.is-active) { display: none; }
.form.is-stepped .form__step-count { display: none; }

.form__progress { margin-bottom: 24px; scroll-margin-top: 96px; }
.form__progress-label {
  margin: 0 0 8px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
}
.form__progress-track {
  height: 6px;
  border-radius: 999px;
  background: var(--bg);
  overflow: hidden;
}
.form__progress-fill {
  display: block;
  width: 25%;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 0.3s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .form__progress-fill { transition: none; }
}

.form__step-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}
.form__step-nav [data-step-next],
.form.is-stepped .form__step-nav [type="submit"] { margin-left: auto; }

.btn--secondary {
  background: transparent;
  color: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--border);
}
.btn--secondary:hover,
.btn--secondary:focus-visible {
  background: var(--bg);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.req { color: var(--accent); font-weight: 700; }
.form__optional { color: var(--muted); font-weight: 400; font-size: 0.85em; }

.form__status {
  min-height: 1.2em;
  margin: 12px 0 0;
  font-size: 0.9rem;
  font-weight: 600;
}
.form__status.is-ok  { color: var(--accent-strong); }
.form .is-touched:invalid { border-color: var(--error); }

/* Błąd wysyłki, podbity wizualnie (04.10.2026) — sama kolorowa linia
   tekstu była za łatwa do przeoczenia po nieudanej wysyłce. Ten sam
   wzorzec ikony błędu (koło z wykrzyknikiem) co przy polach i checkboxie
   zgody wyżej, tu jako tło ::before zamiast inline w polu. */
.form__status.is-err {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: rgba(161, 51, 51, 0.08);
  border: 1px solid rgba(161, 51, 51, 0.28);
  border-radius: 10px;
  color: var(--error);
}
.form__status.is-err::before {
  content: '';
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='%23A13333'/%3E%3Crect x='11' y='6' width='2' height='8' rx='1' fill='%23FBF8F0'/%3E%3Crect x='11' y='16' width='2' height='2' rx='1' fill='%23FBF8F0'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 18px 18px;
}

/* --- Spinner na przycisku wysyłki (stan "Wysyłanie…", 04.10.2026) ---
   .btn__spinner jest w DOM zawsze (wewnątrz przycisku), ale ukryty
   (display:none) — JS dokłada .is-loading na .btn, nie na sam spinner,
   żeby ta sama klasa mogła w przyszłości sterować też innymi stanami
   przycisku (np. tekstem), nie tylko widocznością kółka. */
.btn__spinner {
  display: none;
  width: 15px;
  height: 15px;
  margin-right: 8px;
  vertical-align: -2px;
  border: 2px solid rgba(251, 248, 240, 0.35);
  border-top-color: var(--on-accent);
  border-radius: 50%;
}
.btn.is-loading .btn__spinner {
  display: inline-block;
  animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .btn.is-loading .btn__spinner { animation: none; }
}

/* --- Panel sukcesu briefu (04.10.2026) — zastępuje cały formularz po
   udanej wysyłce, patrz kontakt.html/script.js. .brief.is-submitted to
   klasa na <section class="section brief">, dodawana przez JS po
   potwierdzeniu od Formspree; bez niej panel zostaje display:none, a
   formularz/link powrotny widoczne jak dotąd (to NIE jest stan domyślny
   strony, tylko stan po wysyłce). */
.brief-success {
  display: none;
  max-width: 480px;
  margin: 0 auto;
  padding: 48px 24px;
  text-align: center;
}
.brief.is-submitted .form,
.brief.is-submitted .brief__back { display: none; }
.brief.is-submitted .brief-success { display: block; }

/* Focus ring własny, nie poleganie na globalnej regule a/button/summary
   wyżej (ta nie obejmuje zwykłego diva) — panel dostaje focus programowo
   (script.js, po scrollIntoView), więc musi mieć widoczny, spójny z resztą
   strony pierścień, nie domyślny obrys przeglądarki. */
.brief-success:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
  border-radius: 8px;
}

/* Ikona potwierdzenia — jedyny akcent zieleni w tym widoku (The One Mark
   Rule, DESIGN.md): kontur koła + znacznik rysują się przez
   stroke-dasharray/dashoffset, klasyczny trik SVG "drawing-on" zamiast
   zwykłego fade-in, bo to właśnie ma czytać się jak odhaczenie, nie jak
   zwykłe pojawienie się elementu. Koło najpierw (0-0.5s), znacznik zaraz
   po (0.35-0.7s, lekko nachodzi na koniec koła) - żadna z dwóch animacji
   nie jest przypięta do stanu początkowego innej właściwości niż
   stroke-dashoffset, więc nic nie "skacze" na starcie. dasharray obu
   kształtów jest świadomie trochę większy niż realna długość konturu
   (176 dla koła r=28, 2*pi*28≈175.9; 40 dla znacznika, realnie ~35) —
   bezpieczny margines, nie wymaga liczenia promienia/długości co do piksela. */
.brief-success__icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 20px;
}
.brief-success__icon-circle,
.brief-success__icon-check {
  stroke: var(--accent);
  fill: none;
}
.brief-success__icon-circle {
  stroke-dasharray: 176;
  stroke-dashoffset: 176;
  animation: brief-success-draw 0.5s var(--ease) forwards;
}
.brief-success__icon-check {
  stroke-dasharray: 40;
  stroke-dashoffset: 40;
  animation: brief-success-draw 0.35s var(--ease) 0.35s forwards;
}
@keyframes brief-success-draw {
  to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .brief-success__icon-circle,
  .brief-success__icon-check {
    animation: none;
    stroke-dashoffset: 0;
  }
}

.brief-success__title {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  color: var(--text);
}
.brief-success__text {
  margin: 0 0 28px;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--muted);
}

.form__hint {
  font-size: 0.8rem;
  color: var(--muted);
}
.form__error {
  display: block;
  margin-top: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--error);
}
.form__error:empty { display: none; }

.form__required-note {
  margin: 4px 0 0;
  font-size: 0.8rem;
  color: var(--muted);
}

/* honeypot antyspam — wizualnie i w drzewie A11y niewidoczny (aria-hidden na <p>),
   bez left:-9999px, żeby nie poszerzać obszaru przewijania strony */
.form__honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* podstrona briefu */
.brief__back { margin-top: 28px; font-size: 0.9rem; }
.brief__back a {
  display: inline-block;
  color: var(--accent-strong);
  text-decoration: none;
  border-radius: 6px;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.brief__back a:hover,
.brief__back a:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

/* ============================== POLITYKA PRYWATNOŚCI ============================== */
/* Tryb "Read" — sekwencyjne nagłówki numerowane w warstwie "Title" (jak
   .krok__title/.card__title), nie pełne .section__title dla każdej z 6
   sekcji naraz. Tekst ograniczony do ~68ch, żeby nie powtórzyć problemu
   z długością linii, który audyt zgłosił gdzie indziej na stronie. */
.polityka p,
.polityka ul {
  max-width: 60ch;
  color: var(--muted);
}
.polityka h2 {
  font-size: 1.15rem;
  margin: 2em 0 0.5em;
}
.polityka h2:first-child { margin-top: 0; }
.polityka strong { color: var(--text); }
.polityka ul { margin-bottom: 1em; padding-left: 1.25em; }
.polityka li { margin-bottom: 0.4em; }

/* ============================== CENNIK ============================== */
/* Pakiety na cennik.html i skrót na index.html (15.10.2026). Karty z
   hairline'em jak .faq__item, bez cieni. Wyróżniony pakiet (Trener) dostaje
   obwódkę w akcencie i plakietkę; tylko on ma wypełniony przycisk, reszta
   .btn--secondary, żeby nie było trzech zielonych przycisków obok siebie.
   Mobile: jedna kolumna, od 900px trzy obok siebie. */
.cennik__lead {
  max-width: 62ch;
  color: var(--muted);
}
.cennik__pakiety {
  display: grid;
  gap: 16px;
  margin-top: 28px; /* miejsce na plakietkę "Najczęściej wybierany" nad kartą */
  align-items: stretch;
}
.pakiet {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 24px 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.pakiet--wyrozniony {
  border: 2px solid var(--accent);
  padding: 23px 21px; /* -1px za grubszą obwódkę, żeby treść nie skakała */
}
/* plakietka siedzi na górnej krawędzi karty, żeby nie spychała nazwy
   i ceny niżej niż w sąsiednich kartach (ceny stoją w jednej linii) */
.pakiet__plakietka {
  position: absolute;
  top: 0;
  left: 21px;
  transform: translateY(-50%);
  margin: 0;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.8rem;
  font-weight: 600;
}
.pakiet__nazwa {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.3rem;
  line-height: 1.2;
}
.pakiet__cena {
  margin: 6px 0 12px;
  font-family: var(--font-heading);
  font-size: 2.1rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--accent);
}
.pakiet__cena span {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--muted);
}
.pakiet__opis {
  margin: 0 0 12px;
  color: var(--muted);
}
.pakiet__lista {
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
}
.pakiet__lista li {
  position: relative;
  padding: 7px 0 7px 26px;
  border-top: 1px solid var(--border);
}
.pakiet__lista li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0.95em;
  width: 10px;
  height: 6px;
  border-left: 2px solid var(--accent-strong);
  border-bottom: 2px solid var(--accent-strong);
  transform: translateY(-50%) rotate(-45deg);
}
.pakiet__czas {
  margin: auto 0 0; /* dociska do dołu karty, żeby terminy stały w jednej linii */
  padding-top: 4px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}
.pakiet__btn {
  margin-top: 18px;
  text-align: center;
}
/* Cała karta pakietu/opieki jest klikalna: ::after przycisku "Wybieram ..."
   rozciąga się na kartę (bez zagnieżdżania linków), a karta reaguje na
   hover/focus uniesieniem i obwódką, jak karty artykułów. */
.pakiet,
.opieka {
  transition: transform 0.18s var(--ease),
              box-shadow 0.18s var(--ease),
              border-color 0.18s var(--ease);
}
.pakiet__btn::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}
.pakiet:hover,
.pakiet:focus-within,
.opieka:hover,
.opieka:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
  border-color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .pakiet,
  .opieka { transition: none; }
  .pakiet:hover,
  .pakiet:focus-within,
  .opieka:hover,
  .opieka:focus-within { transform: none; }
}
.cennik__wiecej { margin: 28px 0 0; }
/* notka nad briefem, gdy ktoś przyszedł z przycisku w cenniku */
.brief__pakiet {
  margin: 0 0 20px;
  padding: 12px 16px;
  border-left: 3px solid var(--accent);
  background: var(--bg);
  border-radius: 0 10px 10px 0;
  font-weight: 600;
  color: var(--text);
}

.cennik__opieka-tytul { margin-top: 56px; }
.cennik__opieka {
  display: grid;
  gap: 16px;
}
.opieka {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.opieka .pakiet__lista { margin-bottom: 18px; }
.opieka .pakiet__btn { margin-top: auto; } /* przycisk na dole, równo w obu kartach */
.opieka__glowa {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.opieka__cena {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}
.opieka__cena span {
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--muted);
}
@media (min-width: 700px) {
  .cennik__opieka { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .cennik__pakiety { grid-template-columns: repeat(3, 1fr); }
}

/* ============================== FAQ ============================== */
/* Jeden komponent na faq.html, cennik.html i w artykułach: lista bez tła,
   pytania rozdzielone hairline'ami, natywne <details name="..."> (jedno
   otwarte naraz w obrębie listy). */
.faq__list {
  max-width: 760px;
  border-top: 1px solid var(--border);
}
.faq__item {
  position: relative;
  border-bottom: 1px solid var(--border);
}
.faq__item::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: var(--accent-strong);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.2s var(--ease);
}
.faq__item[open]::before { transform: scaleY(1); }
.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 56px;
  padding: 20px 16px;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "";
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
  color: var(--accent-strong);
  transition: transform 0.2s var(--ease);
}
.faq__item[open] > summary { color: var(--accent-strong); }
.faq__item[open] > summary::after { transform: rotate(45deg); }
.faq__item summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: 4px;
}
@media (hover: hover) {
  .faq__item summary:hover { background: var(--bg); }
}
.faq__item > :not(summary) {
  max-width: 65ch;
  margin: 0;
  padding: 0 16px 20px;
  color: var(--muted);
  font-size: 0.95rem;
}
/* płynne rozwijanie tam, gdzie przeglądarka umie animować do "auto";
   gdzie indziej odpowiedź po prostu się pokazuje */
@supports (interpolate-size: allow-keywords) {
  .faq__item { interpolate-size: allow-keywords; }
  .faq__item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size 0.2s var(--ease), content-visibility 0.2s allow-discrete;
  }
  .faq__item[open]::details-content { block-size: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .faq__item::before,
  .faq__item summary,
  .faq__item summary::after,
  .faq__item::details-content { transition: none; }
}
.faq__cta { margin-top: 32px; }
.faq__cta p { margin-bottom: 12px; color: var(--muted); }

/* ============================== FOOTER ============================== */
/* Jedyna świadomie ciemna powierzchnia w jasnym motywie — ten sam
   strukturalny "kotwiczący" akcent, co czarna stopka w starym motywie,
   tylko przełożony na rodzinę nowej palety (bardzo ciemna, stonowana
   zieleń, nie sam akcent — akcent ma zostawać rzadki, nie zalewać dużej
   powierzchni). Linki na stopce dostają jasny --on-accent, bo
   --accent-strong (średnia zieleń) na tak ciemnym tle traci kontrast. */
.footer {
  padding: 32px 0;
  font-size: 0.9rem;
  color: rgba(251, 248, 240, 0.72);
  background: #16211B;
  border-top: 1px solid rgba(251, 248, 240, 0.10);
}
.footer__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}
.footer__logo { font-weight: 800; letter-spacing: -0.03em; color: var(--on-accent); }
.footer p { margin: 0; }
.footer__razem { white-space: nowrap; }
@media (max-width: 899px) {
  .footer__razem { display: block; }
  .footer__kropka { display: none; }
}
@media (min-width: 900px) {
  .footer__inner { flex-direction: row; justify-content: space-between; text-align: left; }
  .footer__inner p:not(:first-of-type) { white-space: nowrap; }
}
/* linki w wierszach stopki: większy obszar dotyku */
.footer p a { display: inline-block; padding: 8px 0; }

/* rząd skrótów (O nas / Proces / FAQ / Kontakt) — na samym dole strony */
.footer__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 24px;
  margin: 0 auto 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(251, 248, 240, 0.14);
  font-weight: 600;
}
.footer__links a {
  display: inline-block;
  padding: 9px 0; /* cel dotyku ~44px wysokości */
  color: var(--on-accent);
  text-decoration: none;
  transition: transform 0.18s var(--ease);
}
/* Bez box-shadow tutaj (inaczej niż pozostałe linki-przyciski) — tło
   stopki jest już prawie czarne (Pine Black, #16211B), więc ten sam
   zazieleniony token --shadow po prostu zlewa się z tłem i nic by nie
   było widać. Uniesienie translateY + podkreślenie na hover/focus
   wystarcza jako reakcja, bez wymyślania nowego, jaśniejszego cienia
   tylko dla tego jednego, ciemnego kontekstu. */
.footer__links a:hover,
.footer__links a:focus-visible {
  text-decoration: underline;
  transform: translateY(-2px);
}

/* ===================================================================
   ANIMACJE PRZY SCROLLU — scaffolding pod przyszłą rozbudowę
   Zasada: CSS mówi JAK, JS mówi KIEDY (dodaje klasę .widoczna).
   Aby animować kolejny element — dodaj mu w HTML klasę .reveal.
   Kaskada (stagger) dla rodzeństwa .reveal liczona jest w script.js.
   Bez JS elementy są normalnie widoczne (gate przez klasę .js).
   =================================================================== */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
  will-change: opacity, transform;
}
.js .reveal.widoczna {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* will-change: auto tutaj też (nie tylko opacity/transform/transition) —
     bez transition, script.js nigdy nie dostanie "transitionend", którego
     używa do sprzątania will-change po normalnym przejściu (patrz
     releaseWillChangeAfterReveal w script.js), więc pod reduced-motion
     zostałby zapalony na >100 elementach .reveal na stałe, mimo że żadna
     animacja się tu w ogóle nie odbywa — zero uzasadnienia dla warstwy
     kompozytora. Naprawione przy okazji /impeccable optimize 22.09.2026. */
  .js .reveal { opacity: 1; transform: none; transition: none; will-change: auto; }
  .btn { transition: none; }
}

/* ===================================================================
   MEDIA QUERIES
   =================================================================== */

/* --- >= 480px --- */
@media (min-width: 480px) {


  .artykul__meta { font-size: 0.9rem; }
}

/* --- < 700px : menu mobilne --- */
@media (max-width: 699px) {
  .nav__toggle { display: flex; }
  .nav__right { gap: 10px; }
  .nav__links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 20px 16px;
    background: var(--canvas);
    box-shadow: 0 14px 24px rgba(31, 45, 36, 0.10);
  }
  .nav.is-open .nav__links { display: flex; }
  .nav__links a {
    padding: 12px 0;
    opacity: 1;
    border-bottom: 1px solid rgba(31, 61, 43, 0.12);
  }
  /* CTA zostaje w pasku nav (nie w rozwijanym menu) — trochę bardziej
     zwarte niż na desktopie, żeby zmieściło się obok hamburgera bez
     zawijania tekstu (white-space: nowrap wyżej). Pionowy padding 11px
     (zamiast 10px) domyka wysokość do pełnych 44px (WCAG 2.5.5/2.5.8,
     ten sam próg co .nav__toggle) — poziomy padding/font-size bez zmian,
     więc szerokość (zmierzona wcześniej: 148px, z zapasem ~15px pod
     progiem 700px) jest nietknięta. */
  .nav__cta { padding: 11px 14px; font-size: 0.85rem; }
}

/* --- <= 385px : wąskie telefony (iPhone SE/mini 375, popularne Androidy 360, 320) ---
   Pełny pasek nav (logo 44 + napis 72 + CTA 149 + hamburger 44 + odstępy +
   padding kontenera) potrzebuje ~385px; węższy ekran nie mieścił go bez
   ściskania logo lub poziomego przewijania. Zamiast zmniejszać cele dotyku
   (CTA i hamburger zostają 44px wysokości), oszczędzamy na odstępach,
   paddingu i kroju napisu. */
@media (max-width: 385px) {
  .nav__inner { gap: 8px; }
  .nav__inner.container { padding-inline: 16px; }
  .nav__logo { gap: 8px; }
  .nav__logo-text { font-size: 1.1rem; }
  .nav__right { gap: 4px; }
  .nav__cta { padding: 11px 10px; font-size: 0.875rem; } /* 11px pion przy 0.875rem daje pełne 44px */
}

/* --- <= 349px : najwęższe telefony (320-349px) ---
   Nawet po powyższym napis "FitPage" obok ikony się nie mieści. Ikona
   zostaje, napis jest tylko ukryty wizualnie (technika visually-hidden, nie
   display:none) — dzięki temu link do strony głównej zachowuje nazwę
   dostępności (img ma alt="", więc to napis jest jego nazwą). */
@media (max-width: 349px) {
  .nav__logo-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* --- >= 700px --- */
@media (min-width: 700px) {
  .section { padding: 56px 0; }
  .section__title { font-size: 2rem; }
}

/* --- >= 900px --- */
@media (min-width: 900px) {
  .hero:not(.hero--compact) { padding: 120px 20px 64px; }
  .hero--compact { padding: 96px 20px 76px; }

  /* Co dostajesz: tytuł z lewej, cztery punkty 2x2 */
  .co-dostajesz__text { display: grid; grid-template-columns: minmax(0, 0.7fr) minmax(0, 2fr); gap: 56px; align-items: start; }
  .co-dostajesz__text .section__title { margin: 0; }
  .co-dostajesz__lista { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 40px; }
  .co-dostajesz__punkt:nth-last-child(-n+2) { border-bottom: 1px solid var(--border); }

  /* Hero: tekst z lewej, makieta strony trenera z prawej */
  .hero--podzielony .hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    align-items: center;
    gap: 64px;
    max-width: var(--maxw);
    text-align: left;
  }
  .hero--podzielony .hero__akcje { justify-content: flex-start; }
  .hero--podzielony .hero__makieta { max-width: 300px; margin: 0; justify-self: center; }
  .proces-pasek { grid-template-columns: repeat(5, 1fr); }
  .proces-pasek li {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding: 16px;
  }
}

/* 5 etapów w 2 kolumnach: ostatni na całą szerokość, bez dziury obok */
@media (max-width: 899px) {
  .proces-pasek li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (max-width: 359px) {
  .proces-pasek li { flex-direction: column; align-items: flex-start; gap: 8px; padding: 12px; }
}

/* ===================================================================
   TELEFON (do 768px): krótsza strona, kompaktowe artykuły, cennik
   w poziomym pasku, zwijane "O mnie", szybsze odsłanianie.
   Desktop bez zmian, poza dopiskiem o VAT pod cennikiem.
   =================================================================== */

/* dopisek o VAT pod cenami (telefon i desktop) */
.cennik__vat {
  margin: 16px 0 0;
  font-size: 0.875rem;
  color: var(--muted);
}

/* elementy tylko na telefon */
.hero__cennik,
.artykuly__wszystkie,
.o-nas__czytaj,
.cennik__kropki,
.style-pasek__kropki { display: none; }

@media (max-width: 768px) {
  /* 1. odstępy: ok. 56px między treścią kolejnych sekcji */
  .section { padding: 12px 0; }
  .section > .container { padding-top: 16px; padding-bottom: 16px; }
  .hero { padding: 48px 20px 32px; }
  .hero__makieta { max-width: 190px; margin-top: 28px; }
  .proces-pasek__tytul { margin-top: 32px; }

  /* 9. hero: dwa przyciski na pełną szerokość, jeden pod drugim */
  .hero__akcje { display: flex; flex-direction: column; gap: 12px; }
  .hero__akcje .btn { display: block; width: 100%; text-align: center; }
  .hero__cennik {
    display: inline-flex;
    align-self: center;
    align-items: center;
    min-height: 44px;
    color: var(--accent-strong);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 4px;
  }

  /* 4. O mnie: 2 akapity + "Czytaj dalej" */
  .o-nas__tekst-zwiniety .o-nas__reszta { display: none; }
  .o-nas__czytaj {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-top: 8px;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-weight: 600;
    color: var(--accent-strong);
    text-decoration: underline;
    text-underline-offset: 4px;
    cursor: pointer;
  }
  .o-nas__text p:last-of-type { margin-bottom: 0; }

  /* 3. cennik: poziomy pasek ze scroll-snap, karta ok. 85% */
  .cennik__pakiety--skrot {
    position: relative;
    display: flex;
    gap: 12px;
    margin: 20px -20px 0;
    padding: 16px 7.5% 4px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .cennik__pakiety--skrot::-webkit-scrollbar { display: none; }
  /* boczny padding 7.5% + karta na całą szerokość pola = ok. 85% ekranu */
  .cennik__pakiety--skrot .pakiet {
    flex: 0 0 100%;
    scroll-snap-align: center;
  }
  /* karty poza ekranem w poziomie nie mogą czekać na odsłonięcie */
  .js .cennik__pakiety--skrot .reveal { opacity: 1; transform: none; transition: none; }
  .cennik__pakiety--skrot .pakiet:hover,
  .cennik__pakiety--skrot .pakiet:focus-within { transform: none; }
  .cennik__kropki,
  .style-pasek__kropki {
    display: flex;
    justify-content: center;
    margin-top: 4px;
  }
  .cennik__kropki button,
  .style-pasek__kropki button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .cennik__kropki button::before,
  .style-pasek__kropki button::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--border);
    transition: background-color 0.2s, transform 0.2s;
  }
  .cennik__kropki button[aria-current="true"]::before,
  .style-pasek__kropki button[aria-current="true"]::before {
    background: var(--accent);
    transform: scale(1.25);
  }
  .cennik__vat { text-align: center; }
  .cennik__wiecej { margin-top: 16px; text-align: center; }

  /* 2. artykuły: kompaktowa lista; na stronie głównej tylko 3 najnowsze
     (#artykuly to sekcja tylko na index.html, artykuly.html pokazuje wszystkie) */
  .artykuly__grid { grid-template-columns: 1fr; gap: 16px; }
  #artykuly .artykuly__grid .artykul-card:nth-child(n+4) { display: none; }
  .artykul-card {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: 14px;
    row-gap: 4px;
    align-items: start;
  }
  .artykul-card__media { display: contents; }
  .artykul-card__img {
    grid-column: 1;
    grid-row: 1 / span 3;
    width: 96px;
    height: 96px;
    margin: 0;
    border-radius: 10px;
  }
  .artykul-card:hover .artykul-card__img,
  .artykul-card:focus-within .artykul-card__img { transform: none; }
  .artykul-card__tags {
    position: static;
    grid-column: 2;
    grid-row: 1;
  }
  .artykul-card__tags li { font-size: 0.875rem; padding: 6px 10px; background: transparent; color: var(--accent-strong); box-shadow: inset 0 0 0 1px var(--border); }
  .artykul-card__title {
    grid-column: 2;
    grid-row: 2;
    font-size: 1rem;
    line-height: 1.3;
  }
  .artykul-card .artykul__meta { grid-column: 2; grid-row: 3; }
  .artykuly__link { display: none; }
  .artykuly__wszystkie { display: block; margin: 20px 0 0; }
  .artykuly__wszystkie .btn { display: block; text-align: center; }

  /* 7. czytelność: nic poniżej 14px */
  .artykul__meta { font-size: 0.875rem; }
  .pakiet__plakietka { font-size: 0.875rem; padding: 6px 12px; }
  .nav__cta { font-size: 0.875rem; }

  /* 8. cele dotyku min. 44px */
  .brief__back a,
  .o-nas__wiecej a,
  .footer__links a,
  .footer p a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .footer p a { padding-block: 0; }

}

/* 5. odsłanianie na telefonie: krótko (200ms), bez kaskady */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .js .reveal {
    transform: translateY(12px);
    transition-duration: 0.2s;
  }
}

/* ============================== SZABLONY ============================== */
.szablony__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 40px;
}
@media (min-width: 700px) {
  .szablony__lista { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 56px 32px; }
}
.szablon { display: flex; flex-direction: column; }
.szablon__miniatura {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.szablon__miniatura img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.szablon__nazwa { margin: 20px 0 6px; font-size: 1.4rem; }
.szablon__opis { margin: 0 0 20px; color: var(--muted); max-width: 48ch; }
.szablon__akcje { display: flex; flex-wrap: wrap; gap: 12px; margin-top: auto; }
.szablon__akcje .btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; }
.szablony .faq__cta { margin-top: 64px; }
@media (max-width: 480px) {
  .szablon__akcje .btn { flex: 1 1 auto; }
}

/* Podgląd szablonu w oknie */
html:has(.podglad[open]) { overflow: hidden; }
.podglad {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--canvas);
  color: var(--text);
}
.podglad[open] { display: flex; flex-direction: column; }
.podglad::backdrop { background: rgba(22, 33, 27, 0.6); }
.podglad__pasek {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 12px 10px 20px;
  border-bottom: 1px solid var(--border);
}
.podglad__tytul { order: 1; flex: 1 1 auto; margin: 0; font-size: 1.15rem; }
.podglad__zamknij {
  order: 2;
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
.podglad__zamknij:hover { background: var(--border); }
.podglad__widok {
  order: 3;
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
}
.podglad__przelacznik {
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.podglad__przelacznik[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.podglad__wybierz {
  order: 4;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-left: auto;
  padding: 10px 18px;
  font-size: 0.9rem;
}
.podglad__scena {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  justify-content: center;
  overflow: hidden;
  background: rgba(31, 61, 43, 0.08);
}
.podglad__ramka { position: relative; flex: none; overflow: hidden; background: #FFFFFF; }
.podglad__straznik { position: absolute; width: 1px; height: 1px; overflow: hidden; }
.podglad__iframe { position: absolute; top: 0; left: 0; display: block; border: 0; transform-origin: 0 0; }
@media (max-width: 699px) {
  .podglad__pasek { padding: 8px 12px 10px 16px; }
  .podglad__przelacznik { padding: 0 12px; }
  .podglad__wybierz { padding: 10px 14px; }
}
@media (min-width: 700px) {
  .podglad__scena { padding: 20px; }
  .podglad__ramka { border-radius: 12px; box-shadow: var(--shadow); }
  .podglad--telefon .podglad__ramka { border-radius: 28px; }
}
@media (min-width: 900px) {
  .podglad {
    width: calc(100% - 48px);
    height: calc(100% - 48px);
    margin: auto;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
  }
  .podglad__tytul { order: 1; }
  .podglad__widok { order: 2; }
  .podglad__wybierz { order: 3; margin-left: 0; }
  .podglad__zamknij { order: 4; }
}

/* Pasek ze stylami na stronie głównej */
.style-pasek__glowa {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 16px;
}
.style-pasek__glowa .section__title { margin-bottom: 0; }
.style-pasek__link,
.cennik__style a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent-strong);
  font-weight: 600;
  text-decoration: none;
}
.style-pasek__link:hover,
.style-pasek__link:focus-visible,
.cennik__style a:hover,
.cennik__style a:focus-visible { text-decoration: underline; text-underline-offset: 4px; }
.cennik__style { margin: 12px 0 0; }
.style-pasek__lista {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
}
.style-pasek__lista a { display: block; color: var(--text); font-weight: 600; text-decoration: none; }
.style-pasek__lista img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top;
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.style-pasek__lista a:hover img,
.style-pasek__lista a:focus-visible img { transform: translateY(-3px); box-shadow: var(--shadow); }
.style-pasek__lista span { display: flex; align-items: center; min-height: 44px; }
@media (max-width: 768px) {
  .style-pasek__lista {
    display: flex;
    gap: 12px;
    margin: 8px -20px 0;
    padding: 0 20px 4px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 20px;
    scrollbar-width: none;
  }
  .style-pasek__lista::-webkit-scrollbar { display: none; }
  .style-pasek__lista li { flex: 0 0 44%; scroll-snap-align: start; }
}
@media (prefers-reduced-motion: reduce) {
  .style-pasek__lista img { transition: none; }
  .style-pasek__lista a:hover img,
  .style-pasek__lista a:focus-visible img { transform: none; }
}

/* Pole wyboru w briefie */
.form select {
  appearance: none;
  -webkit-appearance: none;
  min-height: 48px;
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23202821' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 12px 8px;
  cursor: pointer;
}
.form__hint a { display: inline-flex; align-items: center; min-height: 44px; color: var(--accent-strong); font-weight: 600; }

/* ============================== PODSTRONY OFERTOWE: ilustracje ============================== */
/* Strona dla trenera i strona dla dietetyka (20.10.2026). Ilustracje w stylu
   okładek artykułów (images/artykuly): telefon z przykładową stroną klienta,
   karty UI, talerz. Wyłącznie HTML/CSS/SVG inline, bez zdjęć, więc hero nie
   pobiera nic ciężkiego. Całe sceny mają aria-hidden: treść niesie tekst
   obok, makiety to przykład marki fikcyjnej. Dwie ciemnozielone sekcje
   (oś czasu, CTA) to świadomy wyjątek od The Flat Canvas Rule na tych
   dwóch podstronach, na życzenie klienta. */
:root {
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --karta: #FFFDF8;
  --piasek: #F1E7D2;
  --talerz-zielen: #7FA87A;
  --talerz-zolty: #E8C77A;
  --talerz-pomarancz: #E08C4E;
  --telefon-ramka: #18211B;
  --pasek-przegladarki: #EFE8D8;
  --gwiazdki: #B8872A;
  --zielen-na-ciemnym: #A8CDB4; /* tekst pomocniczy na --accent, ok. 6.9:1 */
}

/* ---- Hero: tekst + scena ---- */
.scena { margin: 40px auto 0; width: min(100%, 440px); text-align: left; }
.scena__plotno { position: relative; aspect-ratio: 44 / 50; }

/* Telefon: wnętrze skaluje się jednostkami cqi (szerokość telefonu), więc
   ta sama makieta działa w 190px na telefonie i w 240px na desktopie. */
.telefon {
  container-type: inline-size;
  position: absolute;
  top: 2%;
  left: 24%;
  width: 54%;
  aspect-ratio: 9 / 18;
  padding: 3.4%;
  border-radius: 15% / 7.5%;
  background: var(--telefon-ramka);
  box-shadow: 0 30px 60px rgba(31, 45, 36, 0.22), 0 6px 14px rgba(31, 45, 36, 0.12);
  transform: rotate(4deg);
}
.telefon__ekran {
  display: flex;
  flex-direction: column;
  gap: 5.5cqi;
  height: 100%;
  overflow: hidden;
  padding: 5cqi 7cqi 7cqi;
  border-radius: 11cqi;
  background: var(--on-accent);
  color: var(--accent);
}
.telefon__ekran > * { margin: 0; }
/* pasek adresu: makieta to przykładowa strona, nie opinie o FitPage */
.telefon__adres {
  align-self: center;
  max-width: 100%;
  padding: 1.6cqi 4.5cqi;
  border-radius: 999px;
  background: rgba(31, 61, 43, 0.07);
  font-family: var(--font-mono);
  font-size: 3.6cqi;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.telefon__pasek {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3cqi;
  font-family: var(--font-mono);
  font-size: 4.4cqi;
  color: var(--text);
  white-space: nowrap;
}
.telefon__menu {
  flex-shrink: 0;
  width: 7cqi;
  height: 5cqi;
  background:
    linear-gradient(currentColor 0 0) top / 100% 0.9cqi no-repeat,
    linear-gradient(currentColor 0 0) center / 100% 0.9cqi no-repeat,
    linear-gradient(currentColor 0 0) bottom / 100% 0.9cqi no-repeat;
}
.telefon__etykieta {
  margin-top: 3cqi;
  font-family: var(--font-mono);
  font-size: 3.7cqi;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.telefon__haslo {
  font-family: var(--font-heading);
  font-size: 11.5cqi;
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.01em;
  text-shadow: none;
}
.telefon__foto {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  aspect-ratio: 3 / 2;
  border-radius: 5cqi;
  background: linear-gradient(135deg, var(--accent-strong), var(--accent));
  color: var(--on-accent);
}
.telefon__foto svg { width: 34cqi; height: auto; }
.telefon__cena { font-size: 5cqi; font-weight: 600; color: var(--text); }
.telefon__cena b { font-family: var(--font-heading); font-size: 8cqi; color: var(--accent); }
.telefon__btn {
  display: block;
  padding: 4.2cqi;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 5cqi;
  font-weight: 600;
  text-align: center;
}
.telefon__linie { display: grid; gap: 2.6cqi; margin-top: auto; }
.telefon__linie i { display: block; height: 2.4cqi; border-radius: 2cqi; background: rgba(31, 61, 43, 0.1); }
.telefon__linie i:last-child { width: 64%; }
.telefon__o-mnie { display: flex; align-items: center; gap: 4cqi; padding: 4cqi; border-radius: 5cqi; background: rgba(31, 61, 43, 0.06); }
.telefon__o-mnie > i { flex-shrink: 0; width: 15cqi; height: 15cqi; border-radius: 50%; background: var(--talerz-zielen); }
.telefon__o-mnie > span { flex: 1; display: grid; gap: 2.4cqi; }
.telefon__o-mnie > span i { display: block; height: 2.4cqi; border-radius: 2cqi; background: rgba(31, 61, 43, 0.14); }
.telefon__o-mnie > span i:last-child { width: 60%; }

/* Pływające karty wokół telefonu */
.karta-ui {
  position: absolute;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--karta);
  box-shadow: 0 14px 30px rgba(31, 45, 36, 0.14);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  white-space: nowrap;
}
.karta-ui--mono { font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500; }
/* gwiazdki rysowane maską SVG, liczba w --n */
.karta-ui__gwiazdki {
  flex-shrink: 0;
  width: calc(var(--n, 1) * 15px);
  height: 14px;
  background: var(--gwiazdki);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.5l2.9 6.1 6.6.8-4.9 4.6 1.3 6.6L12 17.3l-5.9 3.3 1.3-6.6-4.9-4.6 6.6-.8z'/%3E%3C/svg%3E") left / 15px 14px repeat-x;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.5l2.9 6.1 6.6.8-4.9 4.6 1.3 6.6L12 17.3l-5.9 3.3 1.3-6.6-4.9-4.6 6.6-.8z'/%3E%3C/svg%3E") left / 15px 14px repeat-x;
}
.karta-ui__kropka { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-strong); box-shadow: 0 0 0 4px rgba(44, 107, 71, 0.15); }
.karta-ui__kroki { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 0.75rem; font-weight: 500; }
.karta-ui__kroki span { padding: 4px 8px; border: 1px solid var(--border); border-radius: 999px; }
.karta-ui__kroki span:first-child { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.karta-ui--opinia { display: grid; gap: 2px; white-space: normal; width: 210px; font-weight: 500; }
.karta-ui--opinia { justify-items: start; gap: 6px; }

.scena--trener .karta-ui--1 { top: 9%; left: -3%; rotate: -4deg; }
.scena--trener .karta-ui--2 { top: 31%; right: -6%; rotate: 3deg; }
.scena--trener .karta-ui--3 { bottom: 7%; left: 0; rotate: -2deg; }

/* Dietetyk: talerz z okładki artykułu za telefonem */
.scena__talerz {
  position: absolute;
  top: 20%;
  left: -6%;
  width: 62%;
  height: auto;
  filter: drop-shadow(0 18px 30px rgba(31, 45, 36, 0.14));
}
.scena--dietetyk .telefon { left: 40%; width: 52%; }
.scena--dietetyk .karta-ui--1 { top: 6%; left: 0; rotate: -3deg; }
.scena--dietetyk .karta-ui--2 { bottom: 5%; left: -4%; rotate: 2deg; }
.scena--dietetyk .karta-ui--3 { top: 66%; right: -8%; rotate: 3deg; }

/* Jedno uniesienie i powrót po wejściu (2 przebiegi alternate = koniec
   w pozycji wyjściowej), całość do 5 s, potem spokój. Bez pętli bez końca:
   ruch dłuższy niż 5 s wymagałby pauzy (WCAG 2.2.2), jak pasek dyscyplin
   na głównej. */
@media (prefers-reduced-motion: no-preference) {
  .karta-ui { animation: karta-unosi 2s ease-in-out 0.4s 2 alternate both; }
  .karta-ui--2 { animation-duration: 2.2s; }
  .karta-ui--3 { animation-duration: 2.3s; }
}
/* translate (osobna właściwość), nie transform — żeby nie gryzło się z obrotem */
@keyframes karta-unosi { from { translate: 0 0; } to { translate: 0 -10px; } }

@media (min-width: 900px) {
  .hero--oferta .hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    align-items: center;
    gap: 48px;
    max-width: var(--maxw);
    text-align: left;
  }
  .hero--oferta .scena { margin: 0; justify-self: end; }
  .hero--oferta { padding-block: 72px 64px; }
}

/* Telefon: makieta pod tekstem, mniejsza, prosto, z jedną kartą */
@media (max-width: 560px) {
  .scena { margin-top: 32px; }
  .scena__plotno { aspect-ratio: auto; display: flex; justify-content: center; }
  .telefon { position: relative; top: auto; left: auto; width: 188px; transform: none; }
  .scena--dietetyk .telefon { left: 34px; width: 188px; }
  .karta-ui--2,
  .scena--trener .karta-ui--3,
  .scena--dietetyk .karta-ui--1 { display: none; }
  .scena--trener .karta-ui--1 { top: auto; bottom: 7%; left: calc(50% - 168px); rotate: -3deg; }
  .scena--dietetyk .karta-ui--3 { top: auto; bottom: 10%; left: calc(50% - 172px); right: auto; width: 178px; rotate: -2deg; }
  .scena__talerz { top: 12%; left: calc(50% - 178px); width: 170px; }
}

/* ---- Czego potrzebuje strona: punkty z ilustracjami UI ---- */
.potrzeby__glowa { max-width: 62ch; margin-bottom: 28px; }
.potrzeby__glowa .section__title { margin-bottom: 0; }
.potrzeby__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.potrzeba {
  display: grid;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--bg);
}
.potrzeba--piasek { background: var(--piasek); }
.potrzeba__ilustracja {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-height: 200px;
  padding: 28px 20px;
}
.potrzeba__tekst { padding: 4px 24px 26px; }
.potrzeba__tekst h3 { margin: 0 0 6px; font-size: 1.2rem; line-height: 1.25; }
.potrzeba__tekst p { margin: 0; max-width: 52ch; color: var(--muted); }
@media (min-width: 900px) {
  .potrzeby__glowa { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); gap: 48px; align-items: end; max-width: none; margin-bottom: 36px; }
  .potrzeby__glowa .oferta__dopisek { margin: 0; }
  .potrzeby__lista { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
  .potrzeba__ilustracja { min-height: 250px; padding: 36px 28px; }
  .potrzeba__tekst { padding: 4px 32px 32px; }
  .potrzeba--szeroka { grid-column: 1 / -1; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: center; }
  .potrzeba--szeroka .potrzeba__tekst { padding: 32px 48px 32px 8px; }
  .potrzeba--odwrocona .potrzeba__ilustracja { order: 2; }
  .potrzeba--odwrocona .potrzeba__tekst { padding: 32px 8px 32px 48px; }
}

/* Mini komponenty UI w ilustracjach */
.ui {
  width: min(100%, 290px);
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--karta);
  box-shadow: 0 10px 24px rgba(31, 45, 36, 0.1);
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--text);
  text-align: left;
}
.ui--waska { width: auto; }
.ui__mono {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.ui__tytul {
  display: block;
  margin: 6px 0 12px;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--accent);
}
.ui__chipy { display: flex; flex-wrap: wrap; gap: 6px; }
.ui__chip {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--karta);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}
.ui__chip--on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.ui__chip--skresl { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1.5px; background: transparent; }
.ui__strzalka { font-size: 1.1rem; color: var(--accent-strong); }
.ui__wiersz {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--border);
}
.ui__wiersz:last-child { border-bottom: 0; padding-bottom: 0; }
.ui__wiersz span { flex: 1; }
.ui__wiersz b { font-family: var(--font-heading); font-size: 0.95rem; color: var(--accent); white-space: nowrap; }
.ui__wiersz small { font-size: 0.7rem; color: var(--muted); }
.ui__btn {
  position: relative;
  display: inline-flex;
  padding: 11px 20px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.875rem;
  font-weight: 600;
  box-shadow: 0 10px 22px rgba(31, 61, 43, 0.25);
}
.ui__kursor { position: absolute; right: -10px; bottom: -16px; width: 22px; height: auto; }
.ui__sloty { display: grid; grid-template-columns: repeat(3, auto); gap: 6px; margin-top: 8px; }
.ui__slot {
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-align: center;
  color: var(--muted);
}
.ui__slot--zajety { text-decoration: line-through; opacity: 0.6; }
.ui__slot--on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.ui__pinezka { display: flex; align-items: center; gap: 10px; }
.ui__pinezka svg { flex-shrink: 0; width: 26px; height: auto; color: var(--accent-strong); }
.ui__pinezka b { display: block; font-size: 0.8125rem; }
.ui__pinezka small { display: block; font-size: 0.72rem; color: var(--muted); }
.ui__znaczek {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(44, 107, 71, 0.12);
  color: var(--accent-strong);
  font-size: 0.72rem;
  font-weight: 600;
}
.ui__znaczek::before {
  content: "";
  width: 11px;
  height: 11px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3L13 4.5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3L13 4.5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.ui__pole {
  display: block;
  margin-top: 7px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  font-size: 0.75rem;
  color: var(--muted);
}
.ui__pole--skresl { border-style: dashed; background: transparent; text-decoration: line-through; opacity: 0.7; }
.ui__awatar {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--talerz-zielen);
  color: var(--on-accent);
  font-family: var(--font-heading);
  font-weight: 700;
}
.ui__profil { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.ui__profil b { display: block; font-size: 0.875rem; }
.ui__profil small { display: block; font-size: 0.72rem; color: var(--muted); }
.ui__plik {
  position: relative;
  display: grid;
  place-items: center;
  width: 54px;
  height: 66px;
  border: 1.5px solid var(--border);
  border-radius: 6px 16px 6px 6px;
  background: var(--karta);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  rotate: -6deg;
}
.ui__plik::after {
  content: "";
  position: absolute;
  inset: 50% -8px auto;
  height: 2px;
  background: var(--error);
  rotate: -35deg;
}
/* przed / po: suwak porównania */
.ui-pp { display: grid; grid-template-columns: 1fr 1fr; overflow: hidden; height: 130px; margin-bottom: 10px; border-radius: 8px; position: relative; }
.ui-pp span { display: flex; align-items: flex-end; padding: 8px; font-family: var(--font-mono); font-size: 0.7rem; }
.ui-pp span:first-child { background: linear-gradient(160deg, #E4D9C2, #CDBF9F); color: var(--text); }
.ui-pp span:last-child { justify-content: flex-end; background: linear-gradient(160deg, var(--talerz-zielen), var(--accent-strong)); color: var(--on-accent); }
.ui-pp::after {
  content: "\2039\00a0\203A";
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--karta);
  color: var(--accent);
  font-weight: 700;
  font-size: 0.8rem;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 0 3px rgba(251, 248, 240, 0.5);
}
.ui-pp::before { content: ""; position: absolute; inset: 0 auto 0 calc(50% - 1px); width: 2px; background: var(--karta); }
.ui-stos { display: grid; gap: 12px; justify-items: center; }
@media (max-width: 480px) {
  .ui { width: 100%; }
  .ui--waska { width: auto; }
  .ui__plik { position: absolute; top: 12px; right: 12px; width: 44px; height: 54px; }
}

/* ---- Ciemnozielone sekcje z łukiem ---- */
.sekcja-ciemna {
  position: relative;
  margin-block: 32px;
  padding-block: 96px;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: 50% / 56px;
}
.sekcja-ciemna--do-stopki { margin-bottom: 0; border-radius: 50% 50% 0 0 / 56px 56px 0 0; }
.sekcja-ciemna .section__title { color: var(--on-accent); text-shadow: none; }
.sekcja-ciemna a:focus-visible { outline-color: var(--on-accent); }
@media (max-width: 768px) {
  .sekcja-ciemna { margin-block: 24px; padding-block: 64px; border-radius: 50% / 28px; }
  .sekcja-ciemna--do-stopki { margin-bottom: 0; border-radius: 50% 50% 0 0 / 28px 28px 0 0; }
}

/* Oś czasu z proces.html na ciemnym tle: tylko termin i nazwa etapu */
.oferta-proces .section__title { text-align: center; margin-bottom: 40px; }
.oferta-proces .o-nas__wiecej { margin-top: 36px; text-align: center; }
.oferta-proces .o-nas__wiecej a { color: var(--on-accent); text-decoration: underline; text-decoration-color: rgba(251, 248, 240, 0.4); }
.sekcja-ciemna .etap__nr { background: var(--on-accent); color: var(--accent); box-shadow: 0 0 0 6px var(--accent); }
.sekcja-ciemna .etap:not(:last-child)::after { background: rgba(251, 248, 240, 0.28); }
.sekcja-ciemna .etap__czas { color: var(--zielen-na-ciemnym); }
.sekcja-ciemna .etap__nazwa { margin: 0; }
.sekcja-ciemna .etap__nazwa a { color: var(--on-accent); text-decoration: none; text-underline-offset: 4px; }
/* cały blok etapu (termin + nazwa) jest celem kliknięcia, min. 44px wysokości */
.oferta-proces .etap__tresc { position: relative; min-height: 44px; }
.oferta-proces .etap__nazwa a::after { content: ""; position: absolute; inset: -6px -12px; border-radius: 10px; }
.oferta-proces .etap__nazwa a:focus-visible { outline: none; }
@media (hover: hover) {
  .oferta-proces .etap__tresc:hover .etap__nazwa a { text-decoration: underline; }
}
.oferta-proces .etap__nazwa a:focus-visible::after { outline: 2px solid var(--on-accent); outline-offset: 0; }
.sekcja-ciemna .etap__nazwa a:hover,
.sekcja-ciemna .etap__nazwa a:focus-visible { text-decoration: underline; }

/* ---- Style: miniatury w ramce przeglądarki ---- */
.oferta-style { list-style: none; margin: 20px 0 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }
.oferta-style a { display: block; color: var(--text); text-decoration: none; }
.przegladarka {
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--karta);
  box-shadow: 0 10px 26px rgba(31, 45, 36, 0.08);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.przegladarka__pasek {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--pasek-przegladarki);
}
.przegladarka__pasek i { width: 9px; height: 9px; border-radius: 50%; background: rgba(31, 61, 43, 0.22); }
.przegladarka__adres {
  flex: 0 1 auto;
  min-width: 0;
  margin-left: 10px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--canvas);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.przegladarka picture { display: block; }
.przegladarka img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top;
  transition: transform 0.5s var(--ease);
}
.oferta-style__nazwa { display: flex; align-items: center; justify-content: space-between; min-height: 48px; margin-top: 8px; font-weight: 600; }
.oferta-style__nazwa span:last-child { color: var(--accent-strong); transition: transform 0.18s var(--ease); }
.oferta-style a:focus-visible { outline: none; }
.oferta-style a:focus-visible .przegladarka { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (hover: hover) {
  .oferta-style a:hover .przegladarka { transform: translateY(-4px); box-shadow: var(--shadow); }
  .oferta-style a:hover img { transform: scale(1.03); }
  .oferta-style a:hover .oferta-style__nazwa span:last-child { transform: translateX(4px); }
}
@media (min-width: 700px) {
  .oferta-style { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  .przegladarka, .przegladarka img, .oferta-style__nazwa span:last-child { transition: none; }
}

/* ---- CTA: dwa nachodzące koła, przycisk w części wspólnej ---- */
.cta-venn .cta-closing__inner { max-width: 680px; }
.cta-venn .cta-closing__text { color: rgba(251, 248, 240, 0.84); }
.cta-venn .cta-closing__podpis { color: rgba(251, 248, 240, 0.8); }
.cta-venn .cta-closing__podpis a { color: var(--on-accent); }
.cta-venn .btn--secondary { color: var(--on-accent); box-shadow: inset 0 0 0 1.5px rgba(251, 248, 240, 0.4); }
.cta-venn .btn--secondary:hover,
.cta-venn .btn--secondary:focus-visible { background: rgba(251, 248, 240, 0.1); box-shadow: inset 0 0 0 1.5px var(--on-accent); }
.cta-venn .cta-closing__akcje { margin-top: 4px; }
.venn { position: relative; max-width: 620px; margin: 0 auto 20px; color: var(--on-accent); }
.venn__svg { display: block; width: 100%; height: auto; overflow: visible; }
.btn.venn__btn {
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--on-accent);
  color: var(--accent);
  white-space: nowrap;
  transform: translate(-50%, -50%);
}
.btn.venn__btn:hover,
.btn.venn__btn:focus-visible {
  background: #fff;
  transform: translate(-50%, calc(-50% - 2px));
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
}
@media (prefers-reduced-motion: no-preference) {
  .js .venn .venn__kolo { transition: transform 0.9s var(--ease) 0.1s; }
  .js .venn .venn__soczewka { transition: opacity 0.6s ease 0.6s; }
  .js .venn:not(.widoczna) .venn__kolo--l { transform: translateX(-40px); }
  .js .venn:not(.widoczna) .venn__kolo--p { transform: translateX(40px); }
  .js .venn:not(.widoczna) .venn__soczewka { opacity: 0; }
}
@media (max-width: 560px) {
  .venn { margin-inline: -12px; }
  .btn.venn__btn { padding: 12px 18px; font-size: 0.9375rem; }
}
