/* ==========================================================================
   TOMOŃ – sztuka masażu
   Design tokens, reset, bazowa typografia (mobile-first)
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonty — self-hosted (Fraunces + Outfit)
   Pliki źródłowe wgraj do /fonts. Format docelowy: WOFF2.
   -------------------------------------------------------------------------- */
/* Fraunces występuje wyłącznie w wadze 600 (h1–h4 i wszystkie miejsca
   z --font-heading ustawiają font-weight: 600), więc plik regular/400 nie ma
   odbiorcy — nie deklarujemy go wcale. */
@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/fraunces-semibold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Outfit';
  src: url('/fonts/outfit-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Outfit';
  src: url('/fonts/outfit-medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Kolory */
  --color-bg: #F7F3EC;
  --color-green: #7C8B6F;
  --color-terracotta: #C1704A;
  --color-text: #26332A;

  --color-bg-alt: #EFE9DD;
  --color-white: #FFFFFF;
  --color-terracotta-dark: #A85C3B;
  --color-green-dark: #66735A;
  --color-text-muted: #5B6B5C;

  /* Terakota do TEKSTU (linki, ceny). Bazowa --color-terracotta daje na
     jasnych tłach tylko 3.06–3.69:1, a --color-terracotta-dark 4.08–4.46:1 —
     oba poniżej progu WCAG AA 4.5:1 dla tekstu poniżej 18.66px. Ten odcień
     trzyma 5.46:1 na #FFFFFF, 4.94:1 na #F7F3EC i 4.52:1 na #EFE9DD, czyli
     przechodzi na każdym tle występującym w serwisie. Tła przycisków zostają
     na --color-terracotta — tam kolor niesie markę, nie treść. */
  --color-terracotta-text: #99593B;

  /* Fonty */
  --font-heading: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* Spacing scale */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.5rem;
  --space-xl: 4rem;
  --space-2xl: 6rem;
  --space-3xl: 9rem;

  /* Border-radius scale */
  --radius-sm: 0.5rem;
  --radius-md: 1.25rem;
  --radius-lg: 2.5rem;
  --radius-full: 999px;

  /* Layout */
  --container-max: 72rem;
  --transition-base: 0.3s ease;
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* UWAGA: musi być `clip`, nie `hidden`. Przy `overflow-x: hidden` druga oś
     wylicza się na `overflow-y: auto`, co czyni z <html> kontener przewijania —
     ze wszystkimi tego skutkami dla pozycjonowania i płynności scrolla.
     `clip` obcina tak samo, ale NIE tworzy kontenera przewijania. */
  overflow-x: clip;
}

body {
  min-height: 100vh;
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  position: relative;
  /* jw. — `clip` zamiast `hidden`, żeby <body> też nie stał się kontenerem
     przewijania. */
  overflow-x: clip;
}

/* Uwaga na przyszłość: notch / Dynamic Island nie jest tu obsługiwany żadnym
   CSS-em i tak ma zostać. <meta name="viewport"> celowo NIE ma `viewport-fit=cover`,
   więc Safari na iOS sam trzyma treść w obszarze bezpiecznym, a pas przy wyspie
   maluje tłem strony. Header nigdzie nie jest sticky ani fixed (poza stanem
   z otwartym menu), więc nie ma czego kompensować — dodanie `viewport-fit=cover`
   bez jednoczesnego paddingu wpuściłoby logo i hamburger pod wyspę. */

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

table {
  border-collapse: collapse;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   Skip link — pierwszy fokusowalny element w <body> na każdej podstronie.
   Pozwala pominąć 9-pozycyjną nawigację i przejść wprost do treści.

   Element jest wypchnięty ponad górną krawędź, a NIE ukryty przez
   `display: none` / `visibility: hidden` — te wyjęłyby go z kolejności Tab,
   czyli uniemożliwiły jakiekolwiek sfokusowanie. `position: absolute` sprawia,
   że nieaktywny link nie zajmuje miejsca w layoucie (kotwicą jest <body>,
   które ma `position: relative`).

   z-index ponad .site-header (220), bo header jest sticky i przykryłby link
   w widocznej pozycji. Kolory z tokenów: #F7F3EC na #26332A = 11.95:1,
   czyli z zapasem ponad AA (4.5:1), a nawet ponad AAA (7:1).
   -------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  top: var(--space-sm);
  left: var(--space-sm);
  z-index: 400;
  transform: translateY(calc(-100% - var(--space-lg)));
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-full);
  background-color: var(--color-text);
  color: var(--color-bg);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  transition: transform var(--transition-base);
}

.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--color-terracotta-text);
  outline-offset: 2px;
}

/* Cel skip-linka. `tabindex="-1"` w HTML sprawia, że po skoku focus faktycznie
   ląduje na <main> (bez tego przeglądarki przesuwają tylko scroll, a Tab wraca
   na początek strony). Pierścienia focusu tu nie pokazujemy — sygnałem dla
   użytkownika jest sam skok, a obrys całej sekcji byłby mylący.
   Bez scroll-margin-top: header nie jest sticky, więc nie ma czego omijać —
   skok ma wylądować na samej górze treści. */
#main-content:focus,
#main-content:focus-visible {
  outline: none;
}

/* --------------------------------------------------------------------------
   Grain texture overlay
   Subtelny szum na tle całej strony, nie blokuje interakcji.
   -------------------------------------------------------------------------- */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.03;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* --------------------------------------------------------------------------
   Typografia bazowa (mobile-first)
   -------------------------------------------------------------------------- */
h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.15;
}

h1 {
  font-size: clamp(2.25rem, 6vw, 3.5rem);
}

h2 {
  font-size: clamp(1.75rem, 4.5vw, 2.5rem);
}

h3 {
  font-size: clamp(1.375rem, 3vw, 1.75rem);
}

h4 {
  font-size: 1.125rem;
}

p {
  font-size: 1rem;
}

.lead {
  font-size: 1.125rem;
  color: var(--color-text-muted);
}

small {
  font-size: 0.875rem;
}

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-md);
  overflow-x: hidden;
}

/* --------------------------------------------------------------------------
   Breakpoints — mobile-first (min-width)
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
  .container {
    padding-inline: var(--space-lg);
  }

  p {
    font-size: 1.0625rem;
  }
}

@media (min-width: 1024px) {
  .container {
    padding-inline: var(--space-xl);
  }
}

@media (min-width: 1440px) {
  .container {
    padding-inline: 0;
  }
}

/* ==========================================================================
   CTA button (wariant terakota)
   ========================================================================== */
.cta-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-md);
  background-color: var(--color-terracotta);
  color: var(--color-white);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  border-radius: var(--radius-full);
  white-space: nowrap;
  transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.cta-button:hover,
.cta-button:focus-visible {
  background-color: var(--color-terracotta-dark);
  transform: translateY(-2px);
  box-shadow: 0 0.75rem 1.5rem rgba(193, 112, 74, 0.35);
}

/* ==========================================================================
   Site header
   ========================================================================== */
.site-header {
  /* Header NIE jest przyklejany na żadnej z 12 stron: siedzi w normalnym
     przepływie na górze dokumentu i przewija się razem z treścią. `relative`,
     a nie `static`, wyłącznie po to, żeby działał z-index niżej — element
     `static` go ignoruje. Bez `top`: żadnego offsetu.
     Jedyny wyjątek to stan z otwartym menu (`body.nav-open .site-header`),
     gdzie header musi być `fixed`, inaczej przycisk „X" uciekłby nad ekran. */
  position: relative;
  /* Wyżej niż #mobile-nav (200), bo header i menu są rodzeństwem (menu celowo
     NIE jest w headerze — patrz komentarz przy #mobile-nav). Dzięki temu
     przycisk zamykania (hamburger → X, z-index: 210 wewnątrz headera) zostaje
     klikalny nad otwartym pełnoekranowym panelem. Sticky CTA (150)
     i back-to-top (140) zostają pod panelem. Na index trzyma też logo
     i nawigację nad .hero-bg-video, które hero podciąga pod header. */
  z-index: 220;
  background-color: rgba(247, 243, 236, 0);
  /* Przezroczysty 1px — wchodzi w wysokość pudełka, na której opiera się
     ujemny margin-top w .hero (73px / 99px). Nie usuwać bez korekty tam. */
  border-bottom: 1px solid transparent;
}

/* Header nachodzi na hero (patrz ujemny margin-top niżej) tylko na
   index.html — oznaczonej jawnie klasą .site-header--hero w HTML (zamiast
   wykrywania sąsiedztwa #hero selektorem :has()). Dopóki nie doszło do
   scrolla, tło jest przezroczyste i pokazuje ciemne wideo/zdjęcie hero,
   więc tekst nawigacji musi przejść na biel z delikatnym cieniem dla
   czytelności. Na pozostałych 11 stronach (bez klasy --hero) nic się tu nie
   uruchamia — tam tekst zostaje w domyślnym ciemnym kolorze.
   Biel obowiązuje bezwarunkowo: header jest w normalnym przepływie, więc przez
   cały czas, gdy jest widoczny, leży na ciemnym kadrze.
   Scoped do .nav (pozioma nawigacja desktopowa) — celowo NIE do
   #mobile-nav, który jest osobnym pełnoekranowym panelem z własnym,
   kryjącym tłem (--color-bg) i musi zachować normalny ciemny kolor tekstu
   niezależnie od stanu headera. */
.site-header--hero .nav .nav-link {
  color: var(--color-white);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 8px rgba(0, 0, 0, 0.25);
}

.site-header--hero .hamburger-line {
  background-color: var(--color-white);
}

/* Na mobile index.html nav bar jest bez logo — hero ma być czystym kadrem
   wideo z samym hasłem. Bez logo w rzędzie zostaje tylko hamburger (.nav
   i CTA są już ukryte poniżej 1100px); margin-left: auto przesuwa go w
   prawy róg, żeby "justify-content: space-between" na jednym elemencie
   nie wypchnął go w lewo, zostawiając pusty header. Od 768px logo wraca
   do nav bara bez zmian — reguła jest scoped do max-width: 767px. */
@media (max-width: 767px) {
  .site-header--hero .site-logo {
    display: none;
  }

  .site-header--hero .header-actions {
    margin-left: auto;
  }
}

/* Logo nad hero — WYŁĄCZNIE mobile na index.html. Nav bar zostaje bez logo
   (sam hamburger, patrz reguła wyżej); to osobny element w lewym górnym rogu
   kadru wideo, odwzorowanie pozycji, w której dawniej siedziało logo
   z przezroczystego headera, zanim ukryto je na mobile. Od 768px logo wraca
   do nav bara, więc tutaj znika. Używa wariantu z białym „SZTUKA MASAŻU"
   (LogoNoBackground-index.png) dla czytelności na wideo. */
.hero-logo {
  display: none;
}

@media (max-width: 767px) {
  .hero-logo {
    display: block;
    position: absolute;
    /* 16px — ta sama linia co padding-block headera, więc logo trafia dokładnie
       w rząd z hamburgerem. Bez env(): hero zaczyna się już pod wyspą (padding
       na <body> plus ujemny margin-top hero), więc inset doliczyłby się drugi raz. */
    top: var(--space-sm);
    left: var(--space-md);  /* 24px — jak padding-inline .container na mobile */
    z-index: 2;             /* nad .hero-overlay (1); sticky header (220) i tak jest po prawej */
  }

  .hero-logo img {
    display: block;
    height: 45px;           /* jak logo w nav barze na mobile (pozostałe podstrony) */
    width: auto;
  }
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  /* Oddech nad/pod logo (16px). Wysokość nav bara = wysokość logo
     (najwyższy element) + 2 × ten padding. Jednolity dla wszystkich stanów
     headera i wszystkich breakpointów. */
  padding-block: var(--space-sm);
}

.site-logo img {
  display: block;
  /* Plik logo jest przycięty do bboxu grafiki (1267×564) — brak przezroczystych
     pasów, które wcześniej sztucznie podbijały wysokość headera. Poniższe
     wartości = dotychczasowa WIDOCZNA wysokość logo (stary height × 564/1024),
     więc logo wygląda identycznie, a nav bar jest o te wycięte pasy niższy. */
  height: 45px;
  width: auto;
  transition: height 0.3s ease;
}

@media (min-width: 768px) {
  .site-logo img {
    height: 66px;
  }
}

/* Nawigacja desktopowa — ukryta na mobile */
.nav {
  display: none;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.nav-link {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text);
  position: relative;
  padding-block: var(--space-3xs);
  transition: color var(--transition-base);
}

.nav-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 2px;
  background-color: var(--color-terracotta);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition-base);
}

.nav-link:hover,
.nav-link:focus-visible,
.nav-link.is-active {
  color: var(--color-terracotta-text);
}

.nav-link:hover::after,
.nav-link:focus-visible::after,
.nav-link.is-active::after {
  transform: scaleX(1);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.header-actions .cta-button {
  display: none;
}

/* Hamburger — widoczny tylko na mobile */
.hamburger {
  position: relative;
  z-index: 210;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hamburger-box {
  position: relative;
  width: 1.5rem;
  height: 1rem;
}

.hamburger-line {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: var(--radius-full);
  background-color: var(--color-text);
  transition: transform var(--transition-base), opacity var(--transition-base), top var(--transition-base);
}

.hamburger-line:nth-child(1) {
  top: 0;
}

.hamburger-line:nth-child(2) {
  top: 50%;
  transform: translateY(-50%);
}

.hamburger-line:nth-child(3) {
  top: 100%;
  transform: translateY(-100%);
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(1) {
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(2) {
  opacity: 0;
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(3) {
  top: 50%;
  transform: translateY(-50%) rotate(-45deg);
}

/* Otwarte menu: panel #mobile-nav ma jasne tło (--color-bg), więc biały X
   z reguły .site-header--hero .hamburger-line (index.html) byłby na nim
   niewidoczny. Terakota — ten sam kolor co przyciski CTA — daje
   kontrast 3.36:1 na #F7F3EC (próg WCAG 1.4.11 dla elementów graficznych to
   3:1) i spójność kolorystyczną. Selektor jest o jedną klasę bardziej
   szczegółowy niż reguła z białym kolorem, więc wygrywa niezależnie od
   kolejności w pliku. */
.site-header .hamburger[aria-expanded="true"] .hamburger-line {
  background-color: var(--color-terracotta);
}

/* ==========================================================================
   Mobile nav — pełnoekranowy overlay z animacją wysuwania

   UWAGA: ten <nav> musi być bezpośrednim dzieckiem <body>, a NIE dzieckiem
   .site-header. Powód: .site-header ma z-index: 220 i tworzy kontekst stosu,
   w którym z-index: 200 menu byłoby uwięzione poniżej .sticky-cta (150)
   i .back-to-top (140). Dodatkowo przy otwartym menu header jest `fixed`,
   więc zagnieżdżone menu liczyłoby `inset: 0` względem paska headera (~72 px),
   a nie viewportu — otwierałoby się jako niewidoczny pasek.
   Nie przenosić z powrotem do <header>.
   ========================================================================== */
#mobile-nav {
  position: fixed;
  /* inset: 0 zostaje jako fallback; 100dvh nadpisuje wysokość w
     przeglądarkach mobilnych, gdzie pasek adresu zmienia viewport. */
  inset: 0;
  height: 100dvh;
  z-index: 200;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-lg);
  padding: var(--space-2xl) var(--space-lg);
  background-color: var(--color-bg);
  transform: translateX(100%);
  /* `visibility: hidden` wyjmuje zamknięty panel z drzewa dostępności i z
     kolejności Tab. Sam `transform` tego NIE robi — bez tego na mobile Tab
     przechodził przez 9 niewidocznych linków + CTA, zanim dotarł do treści.
     Visibility animuje się skokowo, więc w transition trzyma stan `visible`
     przez cały czas wysuwania i przełącza się na `hidden` dopiero na końcu
     chowania — animacja wygląda identycznie jak wcześniej. */
  visibility: hidden;
  transition: transform 0.4s ease, visibility 0.4s ease;
  overflow-y: auto;
  /* Scroll wewnątrz menu nie przenosi się na stronę pod spodem. */
  overscroll-behavior: contain;
}

#mobile-nav.is-open {
  transform: translateX(0);
  visibility: visible;
}

#mobile-nav .nav-list {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
}

#mobile-nav .nav-link {
  font-family: var(--font-heading);
  font-size: 1.75rem;
  font-weight: 600;
}

#mobile-nav .cta-button {
  margin-top: var(--space-sm);
}

/* Header rysuje się nad otwartym panelem (żeby X był klikalny), więc jego
   „przescrollowana" oprawa — półprzezroczyste tło, blur i cień — tworzyłaby
   widoczny pasek na górze menu. Przy otwartym menu zdejmujemy ją; zostaje
   sam X na jednolitym tle panelu (logo chowamy — patrz reguła
   `body.nav-open .site-logo` niżej, żeby nie zachodziło na nazwy linków). */
/* JEDYNE miejsce w projekcie, gdzie header jest wyjęty z przepływu — i musi
   takie zostać. Header siedzi normalnie na górze dokumentu, więc po przewinięciu
   strony jest już dawno poza ekranem; gdyby menu otwarte np. z 2000 px zostawiło
   go w przepływie, przycisk „X" byłby poza widokiem i menu nie dałoby się zamknąć.
   Przy otwartym menu <body> dostaje `position: fixed` (blokada scrolla), więc
   header przypinamy jawnie do góry viewportu. Dotyczy wyłącznie stanu nav-open. */
body.nav-open .site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

/* Logo w headerze żyje w kontekście stosu .site-header (z-index: 220), a logo
   nad hero na index.html w .hero — oba PONAD pełnoekranowym #mobile-nav
   (z-index: 200), więc przy otwartym menu prześwitywały nad nazwami linków.
   Samego .site-header nie da się obniżyć bez utraty klikalnego „X"
   (.hamburger, z-index: 210), więc na czas otwartego menu chowamy oba loga.
   `body.nav-open` to ta sama klasa, którą script.js ustawia przy otwarciu menu.
   Transition (na bazowych selektorach) trzyma płynne wygaszenie i powrót —
   `prefers-reduced-motion` sam skraca je do zera, jak przy #mobile-nav. */
.site-logo,
.hero-logo {
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

body.nav-open .site-logo,
body.nav-open .hero-logo {
  opacity: 0;
  visibility: hidden;
}

/* Blokada scrolla tła przy otwartym menu.
   Samo `overflow: hidden` na <body> nie wystarcza — na iOS Safari elementem
   przewijanym jest <html>, więc tło dalej się przesuwa. Wyjęcie <body>
   z przepływu (`position: fixed`) blokuje scroll w każdej przeglądarce.
   Ujemny `top` (ustawiany z JS na aktualne scrollY) trzyma stronę wizualnie
   w tym samym miejscu, a closeMenu() przywraca pozycję — dzięki temu
   otwarcie menu NIE powoduje skoku strony na górę.
   `overflow: clip` na <html> byłby prostszy, ale kasuje offset scrolla,
   przez co strona wracałaby na górę. */
body.nav-open {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  #mobile-nav {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Desktop: pokaż nav poziomą i CTA w headerze, ukryj hamburger + mobile nav.
   Próg podniesiony z 1024 do 1100 px — pozioma nawigacja (duże logo + 8 linków
   + CTA) mieści się w jednej linii dopiero od ~1060 px; poniżej zostaje
   kompaktowe menu hamburger.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
  /* Mniej rozciągnięty nav bar na dużych ekranach: logo zostaje przy lewej
     krawędzi, a nawigacja + CTA są zgrupowane razem przy prawej (margin-left:
     auto na .nav pochłania wolną przestrzeń zamiast rozpychać elementy
     space-between na całą szerokość). Węższy padding boczny i ciaśniejsze
     odstępy między linkami, żeby cała nawigacja mieściła się w jednej linii
     bez zawijania. Zmiany nie dotyczą mobile (tam działa hamburger). */
  .site-header .container {
    padding-inline: var(--space-md);
    gap: var(--space-sm);
  }

  .nav {
    display: block;
    margin-left: auto;
  }

  .nav .nav-list {
    gap: var(--space-xs);
  }

  .header-actions .cta-button {
    display: inline-flex;
  }

  .hamburger {
    display: none;
  }

  #mobile-nav {
    display: none;
  }
}

/* ==========================================================================
   Site footer
   ========================================================================== */
/* Tło stopki na --color-green-dark, nie --color-green. Na #7C8B6F kontrast AA
   jest nieosiągalny dla JAKIEGOKOLWIEK jasnego tekstu — nawet czysta biel daje
   tam 3.63:1. Ciemniejszy wariant (już obecny w palecie) podnosi tekst #F7F3EC
   do 4.56:1. Z tego samego powodu teksty w stopce idą pełnym kryciem —
   hierarchię niosą rozmiary czcionek, nie przezroczystość. */
.site-footer {
  background-color: var(--color-green-dark);
  color: var(--color-bg);
  margin-top: var(--space-2xl);
}

.site-footer .container {
  padding-block: var(--space-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.footer-brand {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.375rem;
}

.footer-tagline {
  color: var(--color-bg);
  margin-top: var(--space-3xs);
}

.footer-contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.footer-contact a {
  transition: color var(--transition-base);
}

.footer-contact a:hover,
.footer-contact a:focus-visible {
  color: var(--color-bg);
  text-decoration: underline;
}

.footer-copy {
  font-size: 0.8125rem;
  color: var(--color-bg);
}

.footer-heading {
  display: none;
}

.footer-credit {
  margin-top: var(--space-2xs);
  font-size: 0.75rem;
  color: var(--color-bg);
}

.footer-credit a {
  color: inherit;
}

.footer-credit a:hover,
.footer-credit a:focus-visible {
  text-decoration: underline;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xs) var(--space-md);
  font-size: 0.875rem;
}

.footer-links a {
  color: var(--color-bg);
  transition: color var(--transition-base);
}

.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--color-white);
  text-decoration: underline;
}

.footer-social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-md);
}

.footer-social a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-bg);
  transition: color var(--transition-base);
}

.footer-social a:hover,
.footer-social a:focus-visible {
  color: var(--color-white);
  text-decoration: underline;
}

.footer-social svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.footer-social svg.icon-fill {
  fill: currentColor;
  stroke: none;
}

@media (max-width: 1023px) {
  .site-footer .container {
    align-items: center;
    text-align: center;
  }

  /* Kolejność sekcji na mobile/tablet: marka → kontakt → social → copyright → credit */
  .site-footer .container > div:first-child {
    order: 1;
  }

  .footer-contact {
    order: 2;
    align-items: center;
  }

  .footer-social {
    order: 3;
    gap: var(--space-sm);
  }

  .footer-social a {
    min-height: 2.75rem;
  }

  .footer-copy {
    order: 4;
  }

  .footer-credit {
    order: 5;
  }

  /* Wrapper wprowadzony dla layoutu desktopowego (patrz min-width: 1024px) —
     na mobile "znika" z drzewa layoutu, żeby .footer-copy i .footer-credit
     nadal działały jako bezpośrednie flex-items z powyższymi order: 4/5. */
  .footer-bottom {
    display: contents;
  }
}

@media (min-width: 1024px) {
  .site-footer .container {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    column-gap: var(--space-lg);
    row-gap: var(--space-lg);
    align-items: start;
  }

  .footer-links,
  .footer-social {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--space-2xs);
  }

  .footer-heading {
    display: block;
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-bg);
    margin-bottom: var(--space-sm);
  }

  .footer-bottom {
    grid-column: 1 / -1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-md);
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid rgba(247, 243, 236, 0.15);
  }

  .footer-credit {
    margin-top: 0;
  }
}

/* ==========================================================================
   Sticky CTA — mobile: fixed bottom, desktop: floating
   ========================================================================== */
.sticky-cta {
  position: fixed;
  z-index: 150;
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.5rem);
  transition: opacity var(--transition-base), transform var(--transition-base);
}

.sticky-cta.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

/* Mobile: pełna szerokość, przyklejony do dołu */
.sticky-cta {
  left: var(--space-sm);
  right: var(--space-sm);
  bottom: var(--space-sm);
  justify-content: center;
  padding-block: var(--space-sm);
  box-shadow: 0 0.5rem 1.5rem rgba(38, 51, 42, 0.2);
}

/* Desktop: floating w prawym dolnym rogu, mniejszy */
@media (min-width: 1024px) {
  .sticky-cta {
    left: auto;
    right: var(--space-lg);
    bottom: var(--space-lg);
    padding: var(--space-xs) var(--space-lg);
  }
}

/* Mobile (≤767px): wyśrodkowanie odporne na rozszerzenie layout viewportu */
@media (max-width: 767px) {
  .sticky-cta {
    left: 50%;
    right: auto;
    width: calc(100% - (var(--space-sm) * 2));
    max-width: calc(100vw - (var(--space-sm) * 2));
    transform: translate(-50%, 0.5rem);
  }

  .sticky-cta.is-visible {
    transform: translate(-50%, 0);
  }
}

@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .sticky-cta,
  .sticky-cta.is-visible {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sticky-cta {
    transition: opacity 0.01ms;
  }
}

/* ==========================================================================
   Back to top
   ========================================================================== */
.back-to-top {
  position: fixed;
  z-index: 140;
  right: var(--space-sm);
  bottom: calc(var(--space-sm) + 3.5rem + var(--space-sm));
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-full);
  background-color: var(--color-green);
  color: var(--color-white);
  box-shadow: 0 0.25rem 1rem rgba(38, 51, 42, 0.2);
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.5rem);
  transition: opacity var(--transition-base), transform var(--transition-base), background-color var(--transition-base);
}

.back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.back-to-top:hover,
.back-to-top:focus-visible {
  background-color: var(--color-green-dark);
}

.back-to-top svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (min-width: 1024px) {
  .back-to-top {
    left: var(--space-lg);
    right: auto;
    bottom: var(--space-lg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .back-to-top {
    transition: opacity 0.01ms;
  }
}

/* ==========================================================================
   Reveal on scroll (Intersection Observer)
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   Hero — pełny ekran
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  color: var(--color-white);
  background-color: var(--color-green-dark);
  /* Wciąga kadr pod przezroczysty header (patrz .site-header--hero wyżej), żeby
     header realnie nachodził na wideo zamiast siedzieć nad nim na osobnym pasku.
     Wartość = pełna wysokość pudełka headera w stanie nieprzewiniętym: na mobile
     logo jest ukryte, zostaje sam hamburger 40px + 2×16px padding-block
     (.site-header .container) + 1px border-bottom (przezroczysty, ale zajmuje
     miejsce) = 73px. Pominięcie tego 1px zostawiało szczelinę, przez którą nad
     kadrem prześwitywało kremowe tło strony. Bez env() — header i hero są oba
     wewnątrz <body> odsuniętego już o safe-area, więc offset to czysta wysokość
     headera. */
  margin-top: -73px;
}

@media (min-width: 768px) {
  .hero {
    /* Od 768px logo wraca do nav bara: 66px + 2×16px + 1px border = 99px
       (patrz .site-logo img). */
    margin-top: -99px;
  }
}

.hero-bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}

/* iOS Safari rysuje natywny przycisk ▶ na wstrzymanym wideo inline nawet bez
   atrybutu controls. Gdy autoplay jest zablokowany (Low Power Mode) albo
   celowo pominięty (prefers-reduced-motion), hero ma wyglądać jak zwykłe,
   celowe zdjęcie — nie jak wideo, które się nie załadowało.
   -webkit-appearance: none jest tu konieczne: na iOS samo display: none bywa
   ignorowane dla start-playback-button. */
.hero-bg-video::-webkit-media-controls,
.hero-bg-video::-webkit-media-controls-panel,
.hero-bg-video::-webkit-media-controls-start-playback-button,
.hero-bg-video::-webkit-media-controls-play-button,
.hero-bg-video::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
  opacity: 0;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Podbita siła nakładki pod wideo (ruch odciąga wzrok od tekstu bardziej
     niż statyczne zdjęcie) — zmierzone Pillow na najjaśniejszej klatce
     pętli (odblask świecy), symulacja object-fit:cover dla 375/414/768/1440px:
     ~5.95:1 kontrastu na każdej z nich, z zapasem ponad próg AA 4.5:1. */
  background: linear-gradient(
    180deg,
    rgba(38, 51, 42, 0.5) 0%,
    rgba(38, 51, 42, 0.75) 30%,
    rgba(38, 51, 42, 0.88) 100%
  );
}

.hero-content {
  position: relative;
  z-index: 2;
  max-width: 40rem;
  padding-block: var(--space-2xl);
}

.hero-title {
  color: var(--color-white);
}

.hero-subtitle {
  margin-top: var(--space-sm);
  font-size: 1.125rem;
  color: rgba(255, 255, 255, 0.9);
}

.cta-button--large {
  margin-top: var(--space-lg);
  padding: var(--space-sm) var(--space-xl);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Mobile: mocniej wyeksponowany nagłówek hero, cały blok tekstu wyżej.
   Scoped do max-width: 767px — desktop bez zmian. */
@media (max-width: 767px) {
  /* 2.5rem (40px) zamiast 2.25rem (36px) z clamp() dla h1 — +11%.
     Górna granica jest osiągana od ~374px w górę, więc na 375/390/414/430px
     nagłówek ma równe 40px. Poniżej tej szerokości rozmiar łagodnie schodzi
     do dotychczasowych 36px: przy 320px najdłuższa linia ("przyjeżdża do")
     zostawia już tylko ~9px zapasu, a zejście do 4 linii wyglądałoby gorzej
     niż nieco mniejszy nagłówek. */
  .hero-title {
    font-size: clamp(2.25rem, 10.7vw, 2.5rem);
  }

  .hero-content {
    /* .hero centruje ten blok pionowo (align-items: center), więc dolny
       margines przesuwa go w górę o POŁOWĘ swojej wartości: 6rem → 48px,
       czyli mniej więcej wysokość jednej linii nagłówka (40px × 1.15 = 46px).
       Górny padding-block (6rem) zostaje jako zapas przed hamburgerem/notchem. */
    margin-bottom: var(--space-2xl);
  }
}

/* ==========================================================================
   Sekcja intro
   ========================================================================== */
.section-intro {
  padding-block: var(--space-2xl);
  text-align: center;
}

.section-intro p {
  max-width: 42rem;
  margin-inline: auto;
  font-size: 1.125rem;
  color: var(--color-text-muted);
}

/* ==========================================================================
   Sekcje ogólne (nagłówki)
   ========================================================================== */
.section {
  padding-block: var(--space-2xl);
}

.section-heading {
  margin-bottom: var(--space-lg);
  text-align: center;
}

.section-link {
  display: inline-block;
  margin-top: var(--space-md);
  font-weight: 500;
  color: var(--color-terracotta-text);
}

.section-link:hover,
.section-link:focus-visible {
  text-decoration: underline;
}

/* ==========================================================================
   Teaser usług — karty
   ========================================================================== */
.services-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.service-card {
  padding: var(--space-lg);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.service-card:hover {
  transform: translateY(-0.25rem);
  box-shadow: 0 1rem 2rem rgba(38, 51, 42, 0.1);
}

.service-card h3 {
  margin-bottom: var(--space-sm);
}

.service-card p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.service-card a {
  display: inline-block;
  margin-top: var(--space-sm);
  padding-block: 0.75rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-terracotta-text);
}

.services-grid.reveal .service-card {
  transition-delay: 0s;
}

.services-grid.is-visible .service-card:nth-child(2) {
  transition-delay: 0.1s;
}

.services-grid.is-visible .service-card:nth-child(3) {
  transition-delay: 0.2s;
}

.services-grid.is-visible .service-card:nth-child(4) {
  transition-delay: 0.3s;
}

/* ==========================================================================
   Dlaczego ja — lista punktów
   ========================================================================== */
.why-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  max-width: 48rem;
  margin-inline: auto;
}

.why-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
}

.why-item-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  background-color: var(--color-green);
  color: var(--color-white);
  font-size: 0.875rem;
}

.why-item p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

/* ==========================================================================
   Mini sekcja stref dojazdu
   ========================================================================== */
.zones-teaser {
  background-color: var(--color-bg-alt);
  border-radius: var(--radius-lg);
  padding: var(--space-xl) var(--space-lg);
  text-align: center;
}

.zones-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-md);
  margin-top: var(--space-md);
}

.zone-pill {
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-full);
  background-color: var(--color-white);
  font-size: 0.875rem;
  font-weight: 500;
}

/* ==========================================================================
   Teaser opinii
   ========================================================================== */
.reviews-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.review-card {
  padding: var(--space-lg);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--color-terracotta);
  cursor: pointer;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.review-card:hover,
.review-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 0.5rem 1.5rem rgba(38, 51, 42, 0.12);
}

.review-card p {
  font-style: italic;
  color: var(--color-text);
}

.review-stars {
  display: block;
  margin-bottom: var(--space-2xs);
  color: var(--color-terracotta);
  font-size: 0.875rem;
  letter-spacing: 0.1em;
}

.review-author {
  display: block;
  margin-top: var(--space-sm);
  padding-top: var(--space-2xs);
  border-top: 1px solid rgba(38, 51, 42, 0.1);
  font-style: normal;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

.reviews-toggle {
  display: none;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-terracotta-text);
}

.reviews-toggle:hover,
.reviews-toggle:focus-visible {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   Breakpointy — grid layouts
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
  .services-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .reviews-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Liczba kolumn wynika z tego, ile miejsca realnie potrzebuje karta, a nie
   z okrągłego breakpointu. Najdłuższy nagłówek („Masaż relaksacyjno-
   -regeneracyjny") łamie się na dywizie na segmenty ~190 px, do tego 2 × 40 px
   paddingu karty — czyli minimum ~270 px na kolumnę.
     • 1024–1439 px: kontener ma 896–1072 px, więc 4 kolumny dałyby 206–238 px
       i karty były ucinane przez `overflow-x` kontenera. 3 kolumny dają 283+ px
       i przy okazji równo dzielą 6-kartowe siatki na stronach miejskich.
     • od 1440 px: kontener osiąga swoje max 1152 px, 4 kolumny = 270 px — mieści
       się, więc wracamy do docelowego układu 4-kolumnowego.
   minmax(0, …) zamiast gołego 1fr, bo domyślnym minimum ścieżki `1fr` jest
   min-content — to ono pozwalało kolumnom rozepchać siatkę ponad kontener. */
@media (min-width: 1024px) {
  .services-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1440px) {
  .services-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Modyfikator: siatka 3-kolumnowa (np. "większe miasta w regionie" na
   dojazd.html) — nadpisuje repeat(4, 1fr) i repeat(2, 1fr) powyżej, żeby
   3 karty nie zostawiały pustej kolumny i nie ciążyły w lewo. */
.services-grid--3 {
  margin-top: var(--space-md);
}

@media (min-width: 768px) {
  .services-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: var(--space-lg);
  }
}

/* ==========================================================================
   O mnie — zdjęcie + tekst
   ========================================================================== */
.about-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  padding-block: var(--space-2xl);
  align-items: center;
}

.about-photo {
  aspect-ratio: 4 / 5;
  background-color: var(--color-green);
  border-radius: 63% 37% 54% 46% / 43% 37% 63% 57%;
  width: 100%;
  max-width: 24rem;
  margin-inline: auto;
  object-fit: cover;
  object-position: 50% 22%;
}

.about-text h1 {
  margin-bottom: var(--space-md);
}

.about-text p + p {
  margin-top: var(--space-sm);
}

.about-text p {
  color: var(--color-text-muted);
}

@media (min-width: 1024px) {
  .about-hero {
    grid-template-columns: minmax(20rem, 30rem) 1fr;
    gap: var(--space-2xl);
  }

  .about-photo {
    max-width: none;
  }
}

/* ==========================================================================
   Karty kwalifikacji (wariant .service-card z ikoną)
   ========================================================================== */
.qualifications-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.qualification-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--space-sm);
  color: var(--color-green);
}

.qualification-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (min-width: 768px) {
  .qualifications-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 1023px) {
  .qualification-icon {
    width: 4rem;
    height: 4rem;
    max-width: 4rem;
    max-height: 4rem;
  }
}

/* ==========================================================================
   Karty certyfikatów
   ========================================================================== */
.certificates-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

.certificate-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: center;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.certificate-card:hover,
.certificate-card:focus-visible {
  transform: translateY(-0.25rem);
  box-shadow: 0 1rem 2rem rgba(38, 51, 42, 0.1);
}

.certificate-card img {
  width: 100%;
  max-width: 8rem;
  height: auto;
  aspect-ratio: 891 / 1600;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.certificate-name {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text);
}

@media (min-width: 768px) {
  .certificates-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.certificates-extra {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  margin-top: 0;
  pointer-events: none;
  transition: max-height 0.5s ease, opacity 0.5s ease, margin-top 0.5s ease;
}

.certificates-extra.is-open {
  max-height: 80rem;
  opacity: 1;
  margin-top: var(--space-md);
  pointer-events: auto;
}

@media (min-width: 768px) {
  .certificates-extra {
    grid-template-columns: repeat(4, 1fr);
  }
}

.certificates-toggle-wrap {
  display: flex;
  justify-content: center;
  margin-top: var(--space-md);
}

.certificates-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: var(--space-xs) var(--space-lg);
  border: 1.5px solid var(--color-green);
  border-radius: var(--radius-full);
  background-color: transparent;
  color: var(--color-green-dark);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  transition: background-color var(--transition-base), color var(--transition-base), transform var(--transition-base);
}

.certificates-toggle.has-extra {
  display: inline-flex;
}

.certificates-toggle:hover,
.certificates-toggle:focus-visible {
  background-color: var(--color-green);
  color: var(--color-white);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .certificates-extra {
    transition-duration: 0.01ms;
  }
}

/* ==========================================================================
   Sekcja zamykająca z CTA
   ========================================================================== */
.closing-cta {
  text-align: center;
  padding-block: var(--space-2xl);
}

.closing-cta p {
  max-width: 32rem;
  margin: 0 auto var(--space-sm);
  color: var(--color-text-muted);
}

/* ==========================================================================
   Oferta — spis treści (jump links)
   ========================================================================== */
.toc {
  margin-block: var(--space-lg);
  padding: var(--space-md);
  background-color: var(--color-bg-alt);
  border-radius: var(--radius-md);
}

.toc-title {
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}

.toc-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2xs) var(--space-md);
}

.toc-list a {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text);
  transition: color var(--transition-base);
}

.toc-list a:hover,
.toc-list a:focus-visible {
  color: var(--color-terracotta-text);
  text-decoration: underline;
}

@media (min-width: 768px) {
  .toc-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .toc-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ==========================================================================
   Oferta — szczegóły usługi
   ========================================================================== */
.service-detail {
  padding-block: var(--space-2xl);
  scroll-margin-top: var(--space-lg);
}

.service-detail:nth-of-type(even) {
  background-color: var(--color-bg-alt);
}

.service-detail .container {
  max-width: 48rem;
}

.service-duration {
  display: inline-block;
  margin-block: var(--space-2xs) var(--space-md);
  padding: var(--space-3xs) var(--space-sm);
  border-radius: var(--radius-full);
  background-color: var(--color-green-dark);
  color: var(--color-white);
  font-size: 0.8125rem;
  font-weight: 500;
}

.service-detail p:not(.service-duration) {
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}

.service-detail .cta-button {
  margin-top: var(--space-sm);
}

/* ==========================================================================
   Cennik — statystyki z animowanym licznikiem
   ========================================================================== */
.stats {
  padding-block: var(--space-2xl);
  text-align: center;
}

.stats-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  max-width: 36rem;
  margin-inline: auto;
}

.stat-value {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(2.5rem, 8vw, 3.5rem);
  color: var(--color-terracotta);
  line-height: 1;
}

.stat-label {
  margin-top: var(--space-2xs);
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

@media (min-width: 768px) {
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ==========================================================================
   Cennik — karty
   ========================================================================== */
.pricing-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.pricing-card {
  padding: var(--space-lg);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
}

.pricing-card h3 {
  margin-bottom: var(--space-sm);
}

.pricing-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-bottom: var(--space-sm);
}

.pricing-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding-block: var(--space-2xs);
  border-bottom: 1px dashed rgba(38, 51, 42, 0.15);
  font-size: 0.9375rem;
}

.pricing-list li:last-child {
  border-bottom: none;
}

.pricing-list .price {
  font-weight: 600;
  color: var(--color-terracotta-text);
}

.pricing-card a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-terracotta-text);
}

.pricing-card a:hover,
.pricing-card a:focus-visible {
  text-decoration: underline;
}

@media (min-width: 768px) {
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .pricing-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.price--na {
  color: var(--color-text-muted);
  font-weight: 500;
}

/* ==========================================================================
   Cennik — pierwsza wizyta + pakiety
   ========================================================================== */
.first-visit {
  text-align: center;
  background-color: var(--color-green);
  color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: var(--space-xl) var(--space-lg);
}

.first-visit h2 {
  color: var(--color-white);
  margin-bottom: var(--space-sm);
}

.first-visit-offer {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
}

.packages-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.package-card {
  padding: var(--space-lg);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  text-align: center;
}

.package-discount {
  font-family: var(--font-heading);
  font-size: 2rem;
  font-weight: 600;
  color: var(--color-terracotta);
  margin-bottom: var(--space-2xs);
}

.package-card h3 {
  margin-bottom: var(--space-2xs);
}

.package-card p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

.packages-note {
  margin-top: var(--space-md);
  text-align: center;
  color: var(--color-text-muted);
}

@media (min-width: 768px) {
  .packages-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ==========================================================================
   Dojazd — mapa stref (SVG koncentryczne okręgi)
   ========================================================================== */
.zones-map {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  align-items: center;
  padding-block: var(--space-2xl);
}

.zones-map-svg {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}

.zone-circle {
  fill: none;
  stroke-width: 2;
  transition: stroke-dashoffset 1.2s ease;
}

.zone-circle--1 {
  stroke: var(--color-green);
}

.zone-circle--2 {
  stroke: var(--color-terracotta);
}

.zone-circle--3 {
  stroke: var(--color-text-muted);
}

.zone-center-dot {
  fill: var(--color-terracotta);
}

.zone-center-label {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.75rem;
  fill: var(--color-text);
  text-anchor: middle;
}

.zone-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.zone-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-md);
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--color-green);
  opacity: 0;
  transform: translateX(1rem);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.zone-card.is-visible {
  opacity: 1;
  transform: translateX(0);
}

.zone-card--2 {
  border-left-color: var(--color-terracotta);
}

.zone-card--3 {
  border-left-color: var(--color-text-muted);
}

.zone-card h3 {
  margin-bottom: var(--space-3xs);
}

.zone-card p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

@media (prefers-reduced-motion: reduce) {
  .zone-circle,
  .zone-card {
    transition-duration: 0.01ms;
  }
}

@media (min-width: 1024px) {
  .zones-map {
    grid-template-columns: 1fr 1fr;
  }
}

/* ==========================================================================
   Dojazd — miejscowości w zasięgu
   ========================================================================== */
.towns-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

.town-chip {
  padding: var(--space-2xs) var(--space-md);
  border-radius: var(--radius-full);
  background-color: rgba(124, 139, 111, 0.15);
  /* #66735A dawało na tej pigułce 3.92:1 — o włos za mało. */
  color: #5E6953;
  font-size: 0.875rem;
  font-weight: 500;
}

.zone-group {
  margin-bottom: var(--space-lg);
  text-align: center;
}

.zone-group:last-child {
  margin-bottom: 0;
}

.zone-group h3 {
  margin-bottom: var(--space-sm);
}

.zone-group--1 h3 {
  color: var(--color-green);
}

.zone-group--2 h3 {
  color: var(--color-terracotta);
}

.zone-group--3 h3 {
  color: var(--color-text-muted);
}

/* ==========================================================================
   Jak wygląda wizyta — pionowy timeline
   ========================================================================== */
.timeline {
  position: relative;
  max-width: 40rem;
  margin-inline: auto;
  padding-block: var(--space-xl);
}

.timeline::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 1.25rem;
  width: 2px;
  background-color: rgba(38, 51, 42, 0.15);
}

.timeline-item {
  position: relative;
  display: flex;
  gap: var(--space-md);
  padding-bottom: var(--space-lg);
}

.timeline-item:last-child {
  padding-bottom: 0;
}

.timeline-number {
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-terracotta);
  color: var(--color-white);
  font-family: var(--font-heading);
  font-weight: 600;
}

.timeline-content h3 {
  margin-bottom: var(--space-3xs);
}

.timeline-content p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

.timeline-item.reveal:nth-child(1) { transition-delay: 0ms; }
.timeline-item.reveal:nth-child(2) { transition-delay: 100ms; }
.timeline-item.reveal:nth-child(3) { transition-delay: 200ms; }
.timeline-item.reveal:nth-child(4) { transition-delay: 300ms; }
.timeline-item.reveal:nth-child(5) { transition-delay: 400ms; }
.timeline-item.reveal:nth-child(6) { transition-delay: 500ms; }

/* ==========================================================================
   Opinie — marquee (desktop) / stack (mobile)
   ========================================================================== */
.reviews-marquee {
  padding-block: var(--space-lg);
}

.reviews-track {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.reviews-track .review-card {
  width: 100%;
}

@media (min-width: 768px) {
  .reviews-marquee {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
    mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
  }

  .reviews-track {
    flex-direction: row;
    width: max-content;
    animation: marquee-scroll 30s linear infinite;
  }

  .reviews-track:hover {
    animation-play-state: paused;
  }

  .reviews-track .review-card {
    width: 20rem;
    flex-shrink: 0;
  }
}

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

@media (prefers-reduced-motion: reduce) {
  .reviews-track {
    animation: none;
  }
}

/* ==========================================================================
   FAQ — akordeon
   ========================================================================== */
.accordion {
  max-width: 44rem;
  margin-inline: auto;
  padding-block: var(--space-lg);
}

.accordion-item {
  border-bottom: 1px solid rgba(38, 51, 42, 0.15);
}

.accordion-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  width: 100%;
  padding-block: var(--space-md);
  text-align: left;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--color-text);
}

.accordion-icon {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  color: var(--color-terracotta);
  transition: transform var(--transition-base);
}

.accordion-trigger[aria-expanded="true"] .accordion-icon {
  transform: rotate(180deg);
}

.accordion-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s ease;
}

.accordion-panel.is-open {
  grid-template-rows: 1fr;
}

/* `grid-template-rows: 0fr` + `overflow: hidden` chowa panel wizualnie, ale
   jego zawartość zostaje w drzewie dostępności — linki w zwiniętych panelach
   (np. 3 linki do stron miejskich w ostatnim pytaniu) łapały Tab. `visibility`
   je z tej kolejności wyjmuje, a transition trzyma stan `visible` przez czas
   zwijania, więc animacja nie zmienia się o klatkę. */
.accordion-panel-inner {
  overflow: hidden;
  visibility: hidden;
  transition: visibility 0.35s ease;
}

.accordion-panel.is-open .accordion-panel-inner {
  visibility: visible;
}

.accordion-panel p {
  padding-bottom: var(--space-md);
  color: var(--color-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .accordion-panel,
  .accordion-icon {
    transition-duration: 0.01ms;
  }
}

/* ==========================================================================
   Kontakt — layout formularz + dane
   ========================================================================== */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* minmax(0, …) zamiast gołych jednostek fr — inaczej minimum ścieżki wynosi
   min-content, a <select id="usluga"> z długimi nazwami zabiegów („Masaż
   relaksacyjny z aromaterapią") rozpychał kolumnę: na 320 px formularz
   wychodził 9 px poza kadr i był ucinany. */
.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
  padding-block: var(--space-2xl);
}

@media (min-width: 1024px) {
  .contact-layout {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    align-items: start;
  }
}

/* --------------------------------------------------------------------------
   Formularz
   -------------------------------------------------------------------------- */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.form-field label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text);
}

.form-field input,
.form-field select,
.form-field textarea {
  /* Pola formularza nie mogą wymuszać szerokości rodzica własnym min-content
     (dotyczy zwłaszcza <select>, którego minimum liczy się z najdłuższej opcji). */
  min-width: 0;
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid rgba(38, 51, 42, 0.2);
  border-radius: var(--radius-sm);
  background-color: var(--color-white);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 1rem;
  transition: border-color var(--transition-base);
}

.form-field textarea {
  min-height: 8rem;
  resize: vertical;
}

/* Wcześniej `outline: none` zostawiał jako jedyny sygnał focusu zmianę koloru
   ramki 1 px — za słabe wobec WCAG 2.4.11. Własny outline zamiast natywnego
   trzyma spójność z paletą i jest widoczny wyłącznie w stanie focus. */
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: 2px solid var(--color-terracotta-text);
  outline-offset: 1px;
  border-color: var(--color-terracotta-text);
}

.contact-form .cta-button {
  align-self: flex-start;
}

#form-status {
  font-size: 0.9375rem;
  font-weight: 500;
}

#form-status.is-success {
  color: var(--color-green-dark);
}

#form-status.is-error {
  color: var(--color-terracotta-dark);
}

/* --------------------------------------------------------------------------
   Dane kontaktowe
   -------------------------------------------------------------------------- */
.contact-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: var(--space-lg);
  background-color: var(--color-bg-alt);
  border-radius: var(--radius-md);
}

.contact-info-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.contact-info-group h3 {
  font-size: 1rem;
}

.contact-info-group a {
  font-weight: 500;
  color: var(--color-terracotta-text);
}

.contact-info-group a:hover,
.contact-info-group a:focus-visible {
  text-decoration: underline;
}

.contact-social {
  display: flex;
  gap: var(--space-sm);
}

.contact-social a {
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-full);
  background-color: var(--color-white);
  font-size: 0.875rem;
  font-weight: 500;
}

.contact-social a:hover,
.contact-social a:focus-visible {
  background-color: var(--color-green);
  color: var(--color-white);
}

/* ==========================================================================
   Modal opinii (lightbox)
   ========================================================================== */
[hidden] {
  display: none !important;
}

.review-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background-color: rgba(38, 51, 42, 0.7);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.review-modal-overlay.is-open {
  opacity: 1;
}

.review-modal {
  position: relative;
  width: 100%;
  max-width: 32rem;
  max-height: 85vh;
  overflow-y: auto;
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  padding: var(--space-2xl) var(--space-lg);
  transform: scale(0.95);
  transition: transform 0.3s ease;
}

.review-modal-overlay.is-open .review-modal {
  transform: scale(1);
}

.review-modal-close {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  color: var(--color-text);
  transition: background-color var(--transition-base);
}

.review-modal-close:hover,
.review-modal-close:focus-visible {
  background-color: var(--color-bg-alt);
}

.review-modal-close svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.review-modal-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-full);
  background-color: var(--color-bg-alt);
  color: var(--color-text);
  transition: background-color var(--transition-base);
}

.review-modal-arrow:hover,
.review-modal-arrow:focus-visible {
  background-color: var(--color-green);
  color: var(--color-white);
}

.review-modal-arrow--prev {
  left: var(--space-xs);
}

.review-modal-arrow--next {
  right: var(--space-xs);
}

.review-modal-arrow svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.review-modal-content {
  text-align: center;
  opacity: 1;
  transition: opacity 0.2s ease;
}

.review-modal-content.is-switching {
  opacity: 0;
}

.review-modal-content .review-stars {
  font-size: 1rem;
}

#review-modal-text {
  font-size: 1.125rem;
  font-style: italic;
  color: var(--color-text);
}

body.modal-open {
  overflow: hidden;
}

@media (max-width: 767px) {
  .review-modal {
    max-width: calc(100% - 2 * var(--space-md));
    padding: var(--space-xl) var(--space-md);
  }
}

@media (prefers-reduced-motion: reduce) {
  .review-modal-overlay,
  .review-modal,
  .review-modal-content {
    transition-duration: 0.01ms;
  }
}

/* ==========================================================================
   Modal certyfikatu (lightbox)
   ========================================================================== */
.certificate-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background-color: rgba(38, 51, 42, 0.7);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.certificate-modal-overlay.is-open {
  opacity: 1;
}

.certificate-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 90vw;
  max-height: 85vh;
  overflow-y: auto;
  background-color: var(--color-white);
  border-radius: var(--radius-md);
  padding: var(--space-xl) var(--space-lg);
  transform: scale(0.95);
  transition: transform 0.3s ease;
}

.certificate-modal-overlay.is-open .certificate-modal {
  transform: scale(1);
}

.certificate-modal-close {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-bg-alt);
  color: var(--color-text);
  transition: background-color var(--transition-base);
}

.certificate-modal-close:hover,
.certificate-modal-close:focus-visible {
  background-color: var(--color-green);
  color: var(--color-white);
}

.certificate-modal-close svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.certificate-modal-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  min-height: 0;
}

#certificate-modal-image {
  max-width: 90vw;
  max-height: 65vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius-sm);
}

.certificate-modal-name {
  font-weight: 500;
  color: var(--color-text);
  text-align: center;
}

@media (max-width: 767px) {
  .certificate-modal {
    padding: var(--space-lg) var(--space-md);
  }

  #certificate-modal-image {
    max-height: 60vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .certificate-modal-overlay,
  .certificate-modal {
    transition-duration: 0.01ms;
  }
}

/* ==========================================================================
   Audyt responsywności — poprawki mobile/tablet (max-width: 767px)
   ========================================================================== */
@media (max-width: 767px) {
  /* 1. Przyciski CTA — nie mogą wypychać layoutu poza viewport */
  .cta-button {
    max-width: 100%;
    white-space: normal;
    text-align: center;
    word-break: break-word;
  }

  .cta-button--large {
    padding-inline: var(--space-lg);
  }

  /* 2. Lista miejscowości (dojazd.html) */
  .towns-list {
    flex-direction: column;
    align-items: center;
  }

  /* 3. Opinie — ukrycie duplikatów marquee i kompaktowe karty */
  .reviews-track > [aria-hidden="true"] {
    display: none;
  }

  .reviews-track .review-card {
    padding: var(--space-md);
    box-shadow: 0 0.25rem 1rem rgba(38, 51, 42, 0.08);
  }

  .reviews-extra {
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height 0.5s ease, opacity 0.5s ease;
  }

  .reviews-extra.is-open {
    max-height: 100rem;
    opacity: 1;
  }

  .reviews-toggle {
    display: none;
    margin: var(--space-md) auto 0;
  }

  .reviews-toggle.has-extra {
    display: inline-flex;
  }

  /* 4. Ogólny audyt — spójne, mniejsze odstępy między sekcjami */
  .section,
  .section-intro,
  .closing-cta {
    padding-block: var(--space-xl);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reviews-extra {
    transition-duration: 0.01ms;
  }
}
