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

html,
body {
  margin: 0;
  padding: 0;
}

/* ==========================================================================
   Motyw — zmienne
   ========================================================================== */

:root {
  /* Border-radius — skala tokenów zamiast magicznych liczb, tak by promienie
     zagnieżdżonych elementów pozostawały koncentryczne (promień = promień dziecka + padding
     rodzica) niezależnie od tego, gdzie w layoucie są użyte. */
  --radius-pill: 999px;
  --radius-round: 50%;
  --radius-item: 16px;
  /* Przyciski CTA/ghost — świadomie mniej okrągłe niż --radius-pill (nav-link,
     kafelki nawigacji), żeby nie wyglądały jak w pełni zaokrąglona pigułka. */
  --radius-button: 14px;
  /* Duże powierzchnie dostają promień rosnący razem z nimi — stała wartość
     wygląda na zbyt ostrą na szerokim ekranie i zbyt obłą na wąskim.
     Karta zagnieżdżona w kafelku: promień = --radius-tile − padding kafelka. */
  --radius-tile: clamp(22px, 2.4vw, 42px);

  --nav-height: 69px;
  --gutter: clamp(14px, 1.8vw, 24px);

  /* Akcent — pomarańcz, stały w obu motywach (nie zależy od jasny/ciemny) */
  --accent-1: #ffb84d;
  --accent-2: #ff9500;
  --accent-3: #ff7a00;
  --accent-soft: rgba(255, 149, 0, 0.35);
  --accent-soft-strong: rgba(255, 149, 0, 0.48);
  --accent-text: #ffffff;

  --bg-color: #ffffff;
  --bg-gradient: none;
  --bg-glow: none;
  --bg-noise: none;
  --text: #1d1d1f;
  --text-muted: rgba(29, 29, 31, 0.65);

  --nav-hover-bg: rgba(0, 0, 0, 0.06);
  --nav-active-bg: rgba(0, 0, 0, 0.1);

  --nav-bg: #ffffff;
  --nav-border: rgba(0, 0, 0, 0.08);

  --tile-bg: #f4f4f6;
  --tile-border: rgba(0, 0, 0, 0.06);

  /* Wyróżnienie w nagłówku — do czasu ustalenia koloru akcentu identyczne
     z resztą tekstu; wtedy wystarczy podmienić tę jedną wartość. */
  --heading-accent: currentColor;

  --cta-bg-1: #1d1d1f;
  --cta-bg-2: #000000;
  --cta-text: #ffffff;
  --cta-glow: rgba(0, 0, 0, 0.2);
  --cta-glow-hover: rgba(0, 0, 0, 0.28);

  --toggle-bg: rgba(0, 0, 0, 0.05);
  --toggle-bg-hover: rgba(0, 0, 0, 0.1);

  --mobile-link-hover-bg: rgba(0, 0, 0, 0.05);

  --focus-ring: rgba(0, 0, 0, 0.6);
}

html {
  background: var(--bg-color);
}

body {
  min-height: 100vh;
  width: 100%;
  background-color: var(--bg-color);
  background-image: var(--bg-noise), var(--bg-glow), var(--bg-gradient);
  background-repeat: repeat, no-repeat, no-repeat;
  background-size: 180px 180px, 100% 100%, 100% 100%;
  background-blend-mode: overlay, normal, normal;
  color: var(--text);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 400ms ease, color 400ms ease;
}

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

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: inherit;
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero__tile {
  /* Karta obejmuje teraz i pasek nawigacji (.site-header__tile), i treść
     hero (.hero__body) — jedno wspólne zdjęcie w tle, bez szwu między nimi.
     Nawigacja trzyma naturalną wysokość u góry, reszta miejsca centruje
     treść hero (patrz .hero__body). */
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--gutter) * 2);
  margin: var(--gutter);
  border-radius: var(--radius-tile);
  /* Kolor jako awaryjne tło pod zdjęciem (zanim się wczyta / gdyby nie doszło) */
  background-color: var(--tile-bg);
  /* Winieta na górze i dole chroni czytelność tytułu i przycisków — środek
     zdjęcia zostaje odsłonięty, bo sam w sobie ma wystarczający kontrast. */
  background-image: linear-gradient(
      180deg,
      rgba(3, 8, 6, 0.4) 0%,
      rgba(3, 8, 6, 0.12) 32%,
      rgba(3, 8, 6, 0.12) 68%,
      rgba(3, 8, 6, 0.45) 100%
    ),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px var(--tile-border);
  /* Zdjęcie nie przemalowuje się wraz z motywem — tekst i przyciski w tej
     karcie dostają więc własny, stały jasny kolor zamiast --text/--text-muted. */
  color: #f3f5f2;
  transition: box-shadow 400ms ease;
}

/* Pasek nawigacji zagnieżdżony w karcie hero — bez własnego tła (przezroczysty,
   widać przez niego zdjęcie karty), stąd jasny wariant kolorów zamiast
   --text/--text-muted (te są dobrane pod białe tło). */
.hero__tile .site-header__tile {
  background: transparent;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.hero__tile .brand {
  color: #f3f5f2;
}

.hero__tile .nav-link {
  color: rgba(243, 245, 242, 0.75);
}

.hero__tile .nav-link:hover {
  color: #f3f5f2;
  background: rgba(255, 255, 255, 0.12);
}

.hero__tile .nav-link:active {
  background: rgba(255, 255, 255, 0.18);
}

.hero__tile .menu-toggle {
  background: rgba(255, 255, 255, 0.12);
  color: #f3f5f2;
}

.hero__tile .menu-toggle:hover {
  background: rgba(255, 255, 255, 0.18);
}

.hero__tile .menu-toggle span {
  background: #f3f5f2;
}

/* Przycisk w prawym górnym rogu (nawigacja) — biały, tak samo i z tego samego
   powodu co główne CTA w .hero__actions: zdjęcie w tle nie przemalowuje się
   z motywem, więc ciemny wariant nie miałby z czym kontrastować. */
.btn-cta.desktop-cta {
  color: #0a0a0a;
  background: linear-gradient(180deg, #ffffff, rgba(255, 255, 255, 0.86));
  box-shadow: 0 10px 24px -8px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.btn-cta.desktop-cta:hover {
  box-shadow: 0 12px 28px -8px rgba(255, 255, 255, 0.45), 0 3px 10px rgba(0, 0, 0, 0.35);
}

.hero__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(28px, 5vw, 80px);
}

.hero__title {
  margin: 0;
  /* width (nie tylko max-width) — bez tego h1 jako wyśrodkowane dziecko flexa
     dopasowuje szerokość do najszerszej AKTUALNIE wyrenderowanej linii, czyli
     też do rotującej frazy. Przy krótszej frazie box się zwężał, co przesuwało
     też poziomo (i delikatnie zmieniało zawijanie) stałego prefiksu nad nim. */
  width: 100%;
  max-width: 18ch;
  font-size: clamp(2.4rem, 6.4vw, 5rem);
  font-weight: 600;
  /* duży stopień pisma wymaga ciaśniejszej interlinii i ujemnego trackingu,
     inaczej litery czytają się jak rozstrzelone */
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

/* Prefiks i rotator jako osobne bloki — każdy dostaje własny, niezależny
   kontekst zawijania (text-wrap: balance liczy złamania linii tylko w obrębie
   swojego bloku). Gdyby oba zostały w jednym ciągu inline, dłuższa/krótsza
   rotująca fraza zmieniałaby całkowitą liczbę linii akapitu, a balance
   przeliczałby wtedy też złamania w stałym prefiksie — stąd "przeskakiwanie". */
.hero__prefix {
  display: block;
}

.hero__rotator {
  display: block;
}

.hero__accent {
  color: var(--heading-accent);
}

/* Wyskakiwanie litera po literze, od lewej do prawej: każdy .split-char
   dostaje własne opóźnienie (ustawiane z JS jako transition-delay), więc
   kolejne litery wjeżdżają jedna za drugą zamiast całego słowa naraz.
   .split-word owija każde słowo w inline-block, żeby zawijanie linii wciąż
   łamało się na spacjach, a nie w środku wyrazu. */
.split-word {
  display: inline-block;
}

.split-char {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.35em);
  transition: opacity 420ms cubic-bezier(0.16, 1, 0.3, 1), transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
}

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

.hero__lead {
  margin: clamp(10px, 1.1vw, 14px) 0 0;
  max-width: 56ch;
  font-size: clamp(1rem, 1.35vw, 1.2rem);
  line-height: 1.55;
  color: rgba(243, 245, 242, 0.82);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: clamp(26px, 3vw, 40px);
}

/* przyciski nawigacji są celowo drobne — w hero muszą utrzymać proporcję
   do nagłówka, który jest kilkukrotnie większy */
.hero__actions .btn-cta,
.hero__actions .btn-ghost {
  padding: clamp(12px, 1.1vw, 15px) clamp(22px, 2vw, 30px);
  font-size: clamp(14px, 1.05vw, 16px);
}

/* Zdjęcie w tle nie przemalowuje się wraz z motywem, więc główny przycisk
   zostaje na stałe biały zamiast odwracać się w czarny razem z resztą
   strony — tak samo jak tekst i .btn-ghost w tej sekcji. */
.hero__actions .btn-cta {
  color: #0a0a0a;
  background: linear-gradient(180deg, #ffffff, rgba(255, 255, 255, 0.86));
  box-shadow: 0 10px 24px -8px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.hero__actions .btn-cta:hover {
  box-shadow: 0 12px 28px -8px rgba(255, 255, 255, 0.45), 0 3px 10px rgba(0, 0, 0, 0.35);
}

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  padding: 10px 20px;
  border-radius: var(--radius-button);
  font-size: 14px;
  font-weight: 600;
  /* dziedziczy stały jasny kolor z .hero__tile — jedyna dotychczasowa
     powierzchnia tego przycisku to zdjęcie, nie tło strony */
  color: inherit;
  box-shadow: inset 0 0 0 1px rgba(243, 245, 242, 0.4);
  transition: background-color 200ms ease, transform 100ms ease-out;
}

.btn-ghost:hover {
  background: rgba(243, 245, 242, 0.12);
}

.btn-ghost:active {
  transform: scale(0.96);
}

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

  .btn-ghost {
    transition: none;
  }
}

/* ==========================================================================
   Jak zaczynamy współpracę — pozioma oś czasu z 4 etapami. Sekcja celowo
   bez kafelkowych teł (samo tło strony) — inaczej niż .service-card, żeby
   nie powielać tego samego wzorca dwa razy pod rząd.
   ========================================================================== */

.steps {
  padding: clamp(56px, 8vw, 96px) var(--gutter);
}

.steps__inner {
  max-width: 1280px;
  margin: 0 auto;
}

.steps__header {
  max-width: 640px;
  margin-bottom: clamp(40px, 6vw, 72px);
}

.steps__eyebrow {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.steps__title {
  margin: 0;
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}

.steps__lead {
  margin: 14px 0 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.steps__grid {
  display: flex;
  flex-direction: column;
}

/* Każdy etap "przykleja się" do góry i stoi w miejscu, dopóki kolejny —
   również przyklejony, ale z wyższym z-index i pełnym tłem — nie nadjedzie
   od dołu i go nie przykryje. Stąd min-height (odległość przewijania
   potrzebna, żeby dany etap "puścił") i jednolite tło zamiast przezroczystego. */
.step {
  position: sticky;
  top: calc(clamp(16px, 4vh, 48px) + (var(--step-index, 1) - 1) * clamp(14px, 2vh, 24px));
  z-index: calc(var(--step-index, 1));
  display: grid;
  grid-template-columns: auto 1fr minmax(280px, 420px);
  align-items: center;
  gap: clamp(24px, 4vw, 48px);
  min-height: 54vh;
  padding: clamp(32px, 5vw, 52px) clamp(28px, 4vw, 56px);
  background: var(--tile-bg);
  border-radius: var(--radius-tile);
  overflow: hidden;
  box-shadow: 0 -24px 48px -32px rgba(0, 0, 0, 0.14);
}

.step:nth-of-type(1) { --step-index: 1; }
.step:nth-of-type(2) { --step-index: 2; }
.step:nth-of-type(3) { --step-index: 3; }
.step:nth-of-type(4) { --step-index: 4; }

/* Tylko desktop: nagłówek sekcji też się przykleja (nad kafelkami, więc
   zostaje widoczny podczas przewijania kaskady), a kafelki dostają
   margines u góry, żeby nie wjeżdżały pod niego.

   .steps__sticky-wrap dostaje jawną, dużą wysokość (nagłówek + 3 kafelki)
   — to właśnie ten "zapas" w bezpośrednim rodzicu daje nagłówkowi
   (position: sticky w środku) czas na bycie przyklejonym. Bez tego zapasu
   sticky nie miałoby się gdzie "trzymać" (uwaga: position: absolute na
   wrapperze nie działa — sticky wewnątrz position: absolute w ogóle się
   nie przykleja w tej przeglądarce; musi to być position: relative).

   Żeby ten duży wrapper nie odsunął .steps__grid o całą swoją wysokość w
   dół, .steps__grid dostaje ujemny margin-top równy dokładnie tej
   "nadwyżce" (3 kafelki) — kafelki renderują się więc dokładnie tam, gdzie
   bez tego zapasu, nachodząc na pustą (bez tła) resztę wrappera, co nie
   ma żadnego efektu wizualnego.

   Wysokość wrappera sięga dokładnie do miejsca, w którym czwarty (ostatni)
   kafelek dojeżdża na swoje miejsce — po tym momencie kończy się też
   "zapas" nagłówka, więc odkleja się on w sposób całkowicie naturalny
   (bez skoku) i jedzie dalej razem ze stroną, zamiast zostawać przyklejony
   przez cały czas postoju ostatniego kafelka. */
@media (min-width: 901px) {
  .steps {
    padding-top: clamp(24px, 3vh, 40px);
    --steps-header-space: clamp(196px, 24vh, 226px);
  }

  .steps__sticky-wrap {
    position: relative;
    height: calc(var(--steps-header-space) + 3 * 54vh);
  }

  .steps__header {
    position: sticky;
    top: clamp(16px, 3vh, 32px);
    /* Niżej niż kafelki (z-index 1-4) — na samym końcu kaskady, gdy
       ostatni kafelek "wyjeżdża" i przechodzi przez okolice nagłówka,
       to on ma być na wierzchu (tak jak każdy kolejny kafelek przykrywa
       poprzedni), a nie odwrotnie. */
    z-index: 0;
    background: var(--bg-color);
  }

  .steps__grid {
    margin-top: calc(-3 * 54vh);
  }

  .step {
    top: calc(var(--steps-header-space) + (var(--step-index, 1) - 1) * clamp(14px, 2vh, 24px));
  }
}

/* Cyfra w stylu "wyciętej" z tła hero — to samo zdjęcie co w .hero__tile,
   maskowane kształtem tekstu (background-clip: text), więc numer etapu
   niesie dokładnie ten sam odcień zieleni co reszta marki. */
.step__number {
  font-size: clamp(4rem, 8vw, 7rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  background: url("/images/hero-background.webp") center/cover no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.step__title {
  margin: 0;
  font-size: clamp(1.25rem, 1.8vw, 1.5rem);
  font-weight: 600;
  color: var(--text);
}

.step__desc {
  max-width: 480px;
  margin: 10px 0 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.step__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 16px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}

.step__cta span {
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}

.step__cta:hover span {
  transform: translateX(3px);
}

.step__media {
  aspect-ratio: 4 / 3;
  margin-inline: 16px;
  border-radius: var(--radius-item);
  background: var(--bg-color);
  box-shadow: inset 0 0 0 1px var(--tile-border);
  overflow: hidden;
  transform: rotate(var(--tilt, 0deg));
  animation: step-media-float 6s ease-in-out infinite;
}

/* Naprzemienny przechył + lewitacja — margin-inline daje miejsce na obrót
   i bujanie bez ucinania przez overflow: hidden na .step. */
.step:nth-of-type(1) .step__media { --tilt: -4deg; animation-delay: 0s; }
.step:nth-of-type(2) .step__media { --tilt: 3deg; animation-delay: -1.5s; }
.step:nth-of-type(3) .step__media { --tilt: -3deg; animation-delay: -3s; }
.step:nth-of-type(4) .step__media { --tilt: 4deg; animation-delay: -4.5s; }

@keyframes step-media-float {
  0%, 100% {
    transform: rotate(var(--tilt, 0deg)) translateY(0);
  }
  50% {
    transform: rotate(var(--tilt, 0deg)) translateY(var(--float-y, -14px));
  }
}

/* Abstrakcyjne makiety w kafelkach zdjęć — bez prawdziwych zrzutów/tekstu,
   każdy etap dostaje inny, tematycznie dopasowany "żywy" placeholder. */
.step__mock {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.step__mock-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding: 10px 12px;
  border-bottom: 1px solid var(--tile-border);
}

.step__mock-bar span {
  width: 7px;
  height: 7px;
  border-radius: var(--radius-round);
  background: var(--text-muted);
  opacity: 0.35;
}

.step__mock-body {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
  gap: 10px;
  padding: 16px 18px;
}

.step__mock-body > * {
  opacity: 0;
}

.step__mock-body > *:nth-child(1) { animation: mock-reveal-1 9s ease-in-out infinite; }
.step__mock-body > *:nth-child(2) { animation: mock-reveal-2 9s ease-in-out infinite; }
.step__mock-body > *:nth-child(3) { animation: mock-reveal-3 9s ease-in-out infinite; }
.step__mock-body > *:nth-child(4) { animation: mock-reveal-4 9s ease-in-out infinite; }

@keyframes mock-reveal-1 {
  0%, 4% { opacity: 0; transform: translateY(6px); }
  10%, 88% { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; }
}
@keyframes mock-reveal-2 {
  0%, 26% { opacity: 0; transform: translateY(6px); }
  32%, 88% { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; }
}
@keyframes mock-reveal-3 {
  0%, 48% { opacity: 0; transform: translateY(6px); }
  54%, 88% { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; }
}
@keyframes mock-reveal-4 {
  0%, 70% { opacity: 0; transform: translateY(6px); }
  76%, 88% { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; }
}

/* Etap 1 — okno rozmowy, dymki na przemian z lewej/prawej.
   Szerokość (--w) siedzi na .chat-bubble, bo przy align-self inne niż
   stretch dziecko-procent nie ma względem czego się policzyć (auto/auto). */
.chat-bubble {
  display: flex;
  width: var(--w, 60%);
}

.chat-bubble--in { align-self: flex-start; }
.chat-bubble--out { align-self: flex-end; }

.chat-bubble__line {
  width: 100%;
  height: 18px;
  border-radius: var(--radius-pill);
}

.chat-bubble--in .chat-bubble__line { background: var(--tile-border); }
.chat-bubble--out .chat-bubble__line { background: var(--text); opacity: 0.85; }

/* Etap 2 — tabelka wyceny, pozycje + wiersz sumy */
.quote-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.quote-row__label,
.quote-row__value {
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--tile-border);
}

.quote-row__label { width: 58%; }
.quote-row__value { width: 18%; }

.quote-row--total {
  padding-top: 10px;
  border-top: 1px solid var(--tile-border);
}

.quote-row--total .quote-row__label,
.quote-row--total .quote-row__value {
  height: 12px;
  background: var(--text);
  opacity: 0.85;
}

/* Etap 3 — okno przeglądarki, wireframe przenikający w gotowy layout */
.step__mock-browser-body {
  position: relative;
  flex: 1;
}

.browser-frame {
  position: absolute;
  inset: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.browser-frame--wire { animation: browser-crossfade-wire 9s ease-in-out infinite; }
.browser-frame--final { animation: browser-crossfade-final 9s ease-in-out infinite; }

@keyframes browser-crossfade-wire {
  0%, 42% { opacity: 1; }
  50%, 92% { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes browser-crossfade-final {
  0%, 42% { opacity: 0; }
  50%, 92% { opacity: 1; }
  100% { opacity: 0; }
}

.bf-block {
  border-radius: 4px;
  background: var(--tile-border);
}

.bf-block--header { height: 12%; width: 40%; }
.bf-block--hero { height: 42%; width: 100%; }
.bf-block--line { height: 8%; width: 90%; }
.bf-block--line.short { width: 55%; }
.bf-block--cta { height: 14%; width: 30%; margin-top: auto; }

.browser-frame--final .bf-block--header,
.browser-frame--final .bf-block--cta {
  background: var(--text);
  opacity: 0.85;
}

.browser-frame--final .bf-block--hero {
  box-shadow: inset 0 0 0 1px var(--text-muted);
}

/* Etap 4 — rosnący wykres słupkowy, bez ramki okna (karta statystyk) */
.step__mock-growth-body {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  height: 100%;
  padding: 20px 18px;
}

.growth-bar {
  flex: 1;
  height: var(--bar-h, 40%);
  border-radius: 4px 4px 0 0;
  background: var(--tile-border);
  transform: scaleY(0);
  transform-origin: bottom;
  animation: growth-bar-rise 6s ease-in-out infinite;
  animation-delay: var(--row-delay, 0s);
}

.growth-bar:last-child {
  background: var(--text);
  opacity: 0.85;
}

@keyframes growth-bar-rise {
  0%, 6% { transform: scaleY(0); }
  35%, 85% { transform: scaleY(1); }
  95%, 100% { transform: scaleY(0); }
}

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

  .step__mock-body > * {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .browser-frame--wire,
  .browser-frame--final {
    animation: none;
  }

  .browser-frame--wire { opacity: 1; }
  .browser-frame--final { opacity: 0; }

  .growth-bar {
    animation: none;
    transform: scaleY(1);
  }
}

@media (max-width: 900px) {
  .step {
    grid-template-columns: 1fr;
    gap: 36px;
    padding: clamp(28px, 6vw, 40px) 24px;
  }

  .step__media {
    aspect-ratio: 16 / 9;
    order: 2;
    --float-y: -8px;
  }
}

/* ==========================================================================
   Opinie klientów — w tle wolno przewijający się, ogromny napis "Grow with
   Us" wycięty z naszego zielonego zdjęcia (background-clip: text), a nad
   nim druga, niezależna karuzela z kafelkami opinii (odwrotny kierunek —
   efekt lekkiego paralaksu).
   ========================================================================== */

.testimonials {
  padding: clamp(56px, 8vw, 96px) 0;
  overflow: hidden;
}

.testimonials__header {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.testimonials__eyebrow {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.testimonials__title {
  margin: 0;
  max-width: 640px;
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}

.testimonials__lead {
  margin: 14px 0 0;
  max-width: 640px;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.testimonials__stack {
  position: relative;
  margin-top: clamp(40px, 6vw, 64px);
  min-height: clamp(420px, 48vw, 560px);
  display: flex;
  align-items: center;
}

.testimonials__bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  /* Podbite w górę względem kafelków (które zostają wyśrodkowane w
     .testimonials__stack) — dzięki temu napis wyraźniej "wystaje" zza
     kafelków u góry, zamiast równo po obu stronach. */
  transform: translateY(clamp(-110px, -8vw, -56px));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

/* Mocniejsze podbicie tylko na desktopie — mobile zostaje przy wartości
   bazowej powyżej. */
@media (min-width: 900px) {
  .testimonials__bg {
    transform: translateY(clamp(-190px, -12vw, -140px));
  }
}

.testimonials__bg-track {
  display: flex;
  align-items: center;
  width: max-content;
  gap: clamp(24px, 4vw, 56px);
  animation: testimonials-scroll-left var(--testimonials-bg-duration, 60s) linear infinite;
}

.testimonials__bg-track span {
  font-size: clamp(7rem, 19vw, 17rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  background-image: linear-gradient(180deg, rgba(3, 8, 6, 0.15) 0%, rgba(3, 8, 6, 0.55) 100%),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.testimonials__bg-sep {
  font-size: clamp(1.6rem, 4vw, 3rem);
  color: rgba(15, 28, 21, 0.4);
}

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

.testimonials__marquee {
  position: relative;
  z-index: 1;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.testimonials__track {
  display: flex;
  width: max-content;
  gap: clamp(16px, 2vw, 24px);
  padding: 0 var(--gutter);
  animation: testimonials-scroll-right var(--testimonials-duration, 50s) linear infinite;
}

.testimonials__track:has(.testimonial-card:hover),
.testimonials__track:has(.testimonial-card:focus-within) {
  animation-play-state: paused;
}

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

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

.testimonial-card {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: clamp(280px, 30vw, 360px);
  padding: clamp(24px, 2.4vw, 32px);
  border-radius: var(--radius-item);
  background: var(--tile-bg);
  box-shadow: inset 0 0 0 1px var(--tile-border), 0 16px 32px -20px rgba(0, 0, 0, 0.25);
}

.testimonial-card__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-round);
  background: rgba(0, 0, 0, 0.06);
  color: var(--text-muted);
}

.testimonial-card__avatar svg {
  width: 24px;
  height: 24px;
}

.testimonial-card__person {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.testimonial-card__name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text);
}

.testimonial-card__role {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.testimonial-card__quote {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text);
}

@media (max-width: 700px) {
  .testimonials__stack {
    min-height: clamp(360px, 90vw, 440px);
  }

  .testimonials__bg {
    transform: translateY(clamp(-230px, -40vw, -155px));
  }

  .testimonials__bg-track span {
    font-size: clamp(6rem, 34vw, 9rem);
  }

  .testimonials__bg-sep {
    font-size: clamp(1.4rem, 8vw, 2.4rem);
  }

  .testimonial-card {
    width: clamp(240px, 78vw, 300px);
  }
}

/* ==========================================================================
   Usługi — filary po lewej (rozwijane kafelki), promo-kafelek ze zdjęciem
   z hero po prawej
   ========================================================================== */

.services {
  padding: clamp(56px, 8vw, 96px) var(--gutter);
}

.services__layout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  align-items: stretch;
  gap: 24px;
  max-width: 1280px;
  margin: 0 auto;
}

.services__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Promo-kafelek — to samo zdjęcie i ta sama winieta co .hero__tile, dla
   spójności z hero; celowo osobna reguła zamiast współdzielenia klasy, bo
   .hero__tile niesie ze sobą też reguły specyficzne dla nawigacji w środku. */
.services__promo {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  border-radius: var(--radius-tile);
  padding: clamp(28px, 3vw, 44px);
  background-color: var(--tile-bg);
  background-image: linear-gradient(
      180deg,
      rgba(3, 8, 6, 0.15) 0%,
      rgba(3, 8, 6, 0.12) 40%,
      rgba(3, 8, 6, 0.55) 100%
    ),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px var(--tile-border);
  color: #f3f5f2;
  min-height: 420px;
}

.services__promo-title {
  margin: 0;
  font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.services__promo-desc {
  margin: 14px 0 0;
  font-size: 0.98rem;
  line-height: 1.6;
  color: rgba(243, 245, 242, 0.82);
}

.service-card {
  border-radius: var(--radius-item);
  background: var(--tile-bg);
  box-shadow: inset 0 0 0 1px var(--tile-border);
  overflow: hidden;
  transition: box-shadow 200ms ease;
}

.service-card__toggle {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 28px 26px 10px;
  border: 0;
  background: none;
  text-align: left;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
  transition: transform 120ms ease-out;
}

.service-card__toggle:active {
  transform: scale(0.98);
}

.service-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  color: var(--text);
}

.service-card__icon svg {
  width: 100%;
  height: 100%;
}

.service-card__title {
  flex: 1;
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.3;
}

.service-card__desc {
  margin: 0;
  padding: 0 26px 24px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text-muted);
}

.service-card__toggle-icon {
  position: relative;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.service-card__toggle-icon span {
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--text);
  border-radius: 2px;
  transition: transform 250ms cubic-bezier(0.22, 1, 0.36, 1), opacity 200ms ease;
}

.service-card__toggle-icon span:first-child {
  width: 100%;
  height: 1.5px;
}

.service-card__toggle-icon span:last-child {
  width: 1.5px;
  height: 100%;
}

.service-card.is-open .service-card__toggle-icon span:last-child {
  transform: rotate(90deg);
  opacity: 0;
}

/* Rozwijanie na grid-template-rows (0fr → 1fr) zamiast max-height — animuje
   się do rzeczywistej wysokości treści bez zgadywania wartości w px, a przy
   1fr nie ucina zawartości, jeśli tekst się kiedyś rozrośnie. */
.service-card__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms cubic-bezier(0.22, 1, 0.36, 1);
}

.service-card.is-open .service-card__panel {
  grid-template-rows: 1fr;
}

.service-card__panel-inner {
  overflow: hidden;
}

.service-card__items {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 26px 26px;
  border-top: 1px solid var(--tile-border);
}

/* Podpunkty jako osobne, klikalne kafelki (linkują do oferty) zamiast
   statycznej listy + jednego zbiorczego CTA. */
.service-card__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 16px;
  border-radius: var(--radius-button);
  background: #ffffff;
  color: inherit;
  text-decoration: none;
  box-shadow: inset 0 0 0 1px var(--tile-border);
  transition: box-shadow 180ms ease, transform 120ms ease-out;
}

.service-card__item:focus-visible {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
  transform: translateY(-1px);
}

/* :active zamiast tylko :hover — na dotyku (bez myszy) :hover nie daje
   żadnego potwierdzenia tapnięcia przed przejściem na inną stronę. */
.service-card__item:active {
  transform: scale(0.98);
}

@media (hover: hover) and (pointer: fine) {
  .service-card__item:hover {
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
    transform: translateY(-1px);
  }
}

.service-card__item-title {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text);
}

.service-card__item-desc {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--text-muted);
}

/* Kaskadowe wjechanie kart usług / pytań FAQ przy pierwszym wejściu w sekcję —
   .reveal-headings.js robi to samo dla samych nagłówków (litera po literze),
   to jest ten sam moment, tylko dla treści pod spodem, żeby nie wskakiwała płasko.
   Opóźnienie ustawia js/reveal-lists.js. */
.reveal-item {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 300ms cubic-bezier(0.22, 1, 0.36, 1), transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}

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

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

  /* Na mobile promo-kafelek z hero ma iść NAD listę rozwijanych filarów —
     order zamiast zmiany kolejności w HTML, żeby na desktopie (dwie
     kolumny obok siebie) kolejność w DOM i tab-order zostały bez zmian. */
  .services__promo {
    order: -1;
    min-height: 320px;
  }
}

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

  .service-card__toggle-icon span {
    transition: none;
  }
}

/* ==========================================================================
   Realizacje — nagłówek + samoprzewijająca się karuzela (jednakowe kafelki).
   Pasek zdublowany w JS (portfolio.js) i animowany czystym CSS keyframe —
   prędkość (px/s) stała, czas trwania dopasowywany do realnej szerokości
   treści, żeby pętla była płynna niezależnie od liczby/rozmiaru zdjęć.
   ========================================================================== */

.portfolio {
  padding: clamp(56px, 8vw, 96px) 0;
  overflow: hidden;
}

.portfolio__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.portfolio__eyebrow {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.portfolio__title {
  margin: 0;
  max-width: 640px;
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}

.portfolio__lead {
  margin: 14px 0 0;
  max-width: 640px;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.portfolio__marquee {
  margin-top: clamp(32px, 5vw, 56px);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

/* Klasyczna karuzela — czysty CSS keyframe (jak .testimonials__track), bez
   własnego sterowania: brak przeciągania i kółka myszy, tylko auto-scroll
   z pauzą po najechaniu na kafelek. Czas trwania liczony z realnej
   szerokości treści w js/portfolio.js (--portfolio-duration), żeby prędkość
   (px/s) była stała niezależnie od liczby/rozmiaru zdjęć. */
.portfolio__track {
  display: flex;
  width: max-content;
  gap: clamp(16px, 2vw, 24px);
  padding: 0 var(--gutter);
  animation: portfolio-scroll var(--portfolio-duration, 50s) linear infinite;
}

.portfolio__track:has(.portfolio__item:hover),
.portfolio__track:has(.portfolio__item:focus-within) {
  animation-play-state: paused;
}

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

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

.portfolio__item {
  position: relative;
  flex: 0 0 auto;
  width: clamp(280px, 28vw, 380px);
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-item);
  overflow: hidden;
  background: var(--tile-bg);
  box-shadow: inset 0 0 0 1px var(--tile-border);
}

/* Nazwa strony i krótki opis branży — ukryte domyślnie, wjeżdżają po
   najechaniu na kafelek (albo po jego wyfokusowaniu, dla klawiatury). */
.portfolio__item-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(16px, 2.2vw, 24px);
  background: linear-gradient(180deg, rgba(3, 8, 6, 0) 45%, rgba(3, 8, 6, 0.82) 100%);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 220ms ease, transform 220ms ease;
  pointer-events: none;
}

.portfolio__item:hover .portfolio__item-overlay,
.portfolio__item:focus-within .portfolio__item-overlay {
  opacity: 1;
  transform: translateY(0);
}

.portfolio__item-title {
  font-size: 0.98rem;
  font-weight: 600;
  color: #f3f5f2;
}

.portfolio__item-desc {
  margin-top: 3px;
  font-size: 0.82rem;
  color: rgba(243, 245, 242, 0.78);
}

.portfolio__item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms cubic-bezier(0.22, 1, 0.36, 1);
}

.portfolio__item:hover img,
.portfolio__item:focus-within img {
  transform: scale(1.06);
}

/* Miejsce zarezerwowane pod przyszłe mockupy — na razie puste, tego samego
   rozmiaru co reszta kafelków, żeby karuzela nie "skakała" po podmianie. */
.portfolio__item--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}

.portfolio__item--empty svg {
  width: 32px;
  height: 32px;
}


/* ==========================================================================
   FAQ — pytania jako osobne, rozwijane "applelowskie" kafelki. Ta sama
   mechanika co .service-card (grid-template-rows 0fr → 1fr, plus/minus
   z dwóch belek), tylko bez ikony i bez zawsze-widocznego opisu —
   odpowiedź jest w całości schowana, dopóki pytanie nie zostanie otwarte.
   ========================================================================== */

.faq {
  padding: clamp(24px, 3vw, 40px) var(--gutter) clamp(56px, 8vw, 96px);
}

.faq__inner {
  max-width: 1280px;
  margin: 0 auto;
}

.faq__layout {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  align-items: stretch;
  gap: 24px;
}

.faq__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Ten sam wzorzec co .services__promo — zdjęcie hero w tle, nagłówek
   i opis w jasnym kolorze, przypięte do dołu kafelka. Tu dodatkowo CTA
   do kontaktu, którego promo-kafelek w Usługach nie miał. */
.faq__promo {
  order: -1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  border-radius: var(--radius-tile);
  padding: clamp(28px, 3vw, 44px);
  background-color: var(--tile-bg);
  background-image: linear-gradient(
      180deg,
      rgba(3, 8, 6, 0.15) 0%,
      rgba(3, 8, 6, 0.12) 40%,
      rgba(3, 8, 6, 0.55) 100%
    ),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px var(--tile-border);
  color: #f3f5f2;
  min-height: 420px;
}

.faq__eyebrow {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(243, 245, 242, 0.75);
}

.faq__title {
  margin: 0;
  font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: #f3f5f2;
}

.faq__lead {
  margin: 14px 0 0;
  font-size: 0.98rem;
  line-height: 1.6;
  color: rgba(243, 245, 242, 0.82);
}

.faq__promo-cta {
  margin-top: 22px;
}

/* Selektor złożony (.btn-cta.faq__promo-cta), bo .btn-cta jest zdefiniowany
   niżej w pliku — przy takiej samej specyficzności (jedna klasa) wygrałby
   z samym .faq__promo-cta niezależnie od kolejności reguł tutaj. */
.btn-cta.faq__promo-cta {
  color: #0a0a0a;
  background: linear-gradient(180deg, #ffffff, rgba(255, 255, 255, 0.86));
  box-shadow: 0 10px 24px -8px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.btn-cta.faq__promo-cta:hover {
  box-shadow: 0 12px 28px -8px rgba(255, 255, 255, 0.45), 0 3px 10px rgba(0, 0, 0, 0.35);
}

.faq-item {
  border-radius: var(--radius-item);
  background: var(--tile-bg);
  box-shadow: inset 0 0 0 1px var(--tile-border);
  overflow: hidden;
  transition: box-shadow 200ms ease;
}

.faq-item__toggle {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 24px 26px;
  border: 0;
  background: none;
  text-align: left;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
  transition: transform 120ms ease-out;
}

.faq-item__toggle:active {
  transform: scale(0.98);
}

.faq-item__question {
  flex: 1;
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.4;
}

.faq-item__toggle-icon {
  position: relative;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.faq-item__toggle-icon span {
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--text);
  border-radius: 2px;
  transition: transform 250ms cubic-bezier(0.22, 1, 0.36, 1), opacity 200ms ease;
}

.faq-item__toggle-icon span:first-child {
  width: 100%;
  height: 1.5px;
}

.faq-item__toggle-icon span:last-child {
  width: 1.5px;
  height: 100%;
}

.faq-item.is-open .faq-item__toggle-icon span:last-child {
  transform: rotate(90deg);
  opacity: 0;
}

.faq-item__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms cubic-bezier(0.22, 1, 0.36, 1);
}

.faq-item.is-open .faq-item__panel {
  grid-template-rows: 1fr;
}

.faq-item__panel-inner {
  overflow: hidden;
}

.faq-item__answer {
  margin: 0;
  padding: 0 26px 24px;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-muted);
}

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

  .faq__promo {
    min-height: 320px;
  }

  .faq__promo-cta {
    align-self: center;
  }
}

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

  .faq-item__toggle-icon span {
    transition: none;
  }
}

/* ==========================================================================
   Nawigacja
   ========================================================================== */

.site-header__tile {
  width: 100%;
  /* Grid, nie flex + space-between: z trzema elementami o różnej szerokości
     (logo vs. CTA+przełącznik) space-between centruje nav-links w luce MIĘDZY
     nimi, nie na środku paska — stąd widoczne przesunięcie w lewo. Symetryczne
     skrajne kolumny (minmax(0, 1fr)) gwarantują środkowej kolumnie prawdziwy
     środek paska, niezależnie od tego, ile waży logo czy prawa strona. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 20px;
  padding: 14px 24px;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
  transition: background-color 400ms ease, border-color 400ms ease;
}

.brand {
  /* Jawna kolumna — bez tego .main-nav z display:none (mobile) wypada z
     automatycznego rozmieszczania siatki, a .header-actions "zjeżdża" do
     środkowej kolumny zamiast zostać w trzeciej, przy prawej krawędzi. */
  grid-column: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-self: start;
  color: var(--text);
  transition: color 400ms ease;
}

.brand svg {
  height: 18px;
  width: auto;
  display: block;
}

.main-nav {
  grid-column: 2;
  position: relative;
  display: flex;
  align-items: center;
  justify-self: center;
  gap: 2px;
}

.nav-link {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  padding: 9px 16px;
  border-radius: var(--radius-pill);
  transition: color 200ms ease, background-color 200ms ease, transform 100ms ease-out;
}

.nav-link:hover {
  color: var(--text);
  background: var(--nav-hover-bg);
}

.nav-link:active {
  transform: scale(0.96);
  background: var(--nav-active-bg);
}

/* Rozwijane menu pod "Oferta" — czysto CSS-owe (hover + focus-within), bez
   JS: :focus-within trzyma panel otwarty też podczas tabowania przez linki
   w środku, więc zamyka się dopiero, gdy fokus faktycznie wyjdzie poza cały
   .nav-item. */
.nav-item {
  position: relative;
}

.nav-item__trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  font-family: inherit;
  cursor: pointer;
}

.nav-item__chevron {
  width: 10px;
  height: 10px;
  transition: transform 200ms ease;
}

.nav-item:hover .nav-item__chevron,
.nav-item:focus-within .nav-item__chevron {
  transform: rotate(180deg);
}

/* Rozwijanie od góry do dołu na max-height (nie grid-template-rows: fr-owe
   wartości nie mają stałego punktu odniesienia dla auto-wysokiego kontenera,
   więc przy zwijaniu przeglądarka non-stop przelicza "dostępną przestrzeń"
   od nowa i animacja się zacina; stałe piksele w max-height animują się
   liniowo w obie strony bez tego problemu). Padding też jedzie w transition,
   inaczej przy max-height:0 nadal byłby widoczny jako góra/dół paddingu.
   visibility chowa panel dopiero PO zakończeniu zwijania, więc po drodze nie
   widać spłaszczonego cienia przy wysokości bliskiej zeru. */
.nav-dropdown {
  position: absolute;
  top: calc(100% + 24px);
  left: 50%;
  z-index: 20;
  width: min(640px, calc(100vw - 2 * var(--gutter)));
  transform: translateX(-50%);
  visibility: hidden;
  transition: visibility 340ms;
}

.nav-item:hover .nav-dropdown,
.nav-item:focus-within .nav-dropdown {
  visibility: visible;
}

.nav-dropdown__inner {
  overflow: hidden;
  max-height: 0;
  padding: 0 20px;
  border-radius: var(--radius-item);
  background: #ffffff;
  box-shadow: 0 20px 48px -16px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: max-height 340ms cubic-bezier(0.22, 1, 0.36, 1), padding 340ms cubic-bezier(0.22, 1, 0.36, 1);
}

.nav-item:hover .nav-dropdown__inner,
.nav-item:focus-within .nav-dropdown__inner {
  max-height: 480px;
  padding: 20px;
}

.nav-dropdown__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 20px;
}

.nav-dropdown__pillar {
  padding: 12px 0;
}

.nav-dropdown__pillar + .nav-dropdown__pillar {
  border-top: 1px solid var(--tile-border);
}

.nav-dropdown__grid .nav-dropdown__pillar:nth-child(2) {
  border-top: 0;
}

.nav-dropdown__pillar-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.nav-dropdown__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--text);
}

.nav-dropdown__icon svg {
  width: 100%;
  height: 100%;
}

.nav-dropdown__pillar-title {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
}

.nav-dropdown__services {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: 32px;
}

.nav-dropdown__service {
  padding: 6px 10px;
  margin-left: -10px;
  border-radius: var(--radius-button);
  font-size: 0.86rem;
  color: var(--text-muted);
  transition: background-color 150ms ease, color 150ms ease, transform 120ms ease-out;
}

.nav-dropdown__service:focus-visible {
  background: var(--tile-bg);
  color: var(--text);
}

.nav-dropdown__service:active {
  background: var(--tile-bg);
  color: var(--text);
  transform: scale(0.98);
}

@media (hover: hover) and (pointer: fine) {
  .nav-dropdown__service:hover {
    background: var(--tile-bg);
    color: var(--text);
  }
}

.nav-dropdown__promo {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 12px;
  padding: 16px 20px;
  border-radius: var(--radius-item);
  background: var(--tile-bg);
  text-align: center;
}

.nav-dropdown__promo-text {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--text);
}

.nav-dropdown__promo-cta {
  padding: 9px 20px;
  font-size: 13px;
}

@media (max-width: 560px) {
  .nav-dropdown__grid {
    grid-template-columns: 1fr;
  }

  .nav-dropdown__grid .nav-dropdown__pillar:nth-child(n) {
    border-top: 1px solid var(--tile-border);
  }

  .nav-dropdown__grid .nav-dropdown__pillar:first-child {
    border-top: 0;
    padding-top: 0;
  }
}

.header-actions {
  grid-column: 3;
  position: relative;
  display: flex;
  align-items: center;
  justify-self: end;
  gap: 8px;
}

.btn-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  padding: 10px 20px;
  border-radius: var(--radius-button);
  font-size: 14px;
  font-weight: 600;
  color: var(--cta-text);
  background: linear-gradient(180deg, var(--cta-bg-1), var(--cta-bg-2));
  box-shadow: 0 10px 24px -8px var(--cta-glow), 0 2px 8px rgba(0, 0, 0, 0.3);
  transition: transform 100ms ease-out, box-shadow 200ms ease, background 400ms ease, color 400ms ease;
}

.btn-cta:hover {
  box-shadow: 0 12px 28px -8px var(--cta-glow-hover), 0 3px 10px rgba(0, 0, 0, 0.35);
}

.btn-cta:active {
  transform: scale(0.96);
}

.menu-toggle {
  display: flex;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--radius-round);
  background: var(--toggle-bg);
  color: var(--text);
  cursor: pointer;
  transition: background-color 200ms ease, color 400ms ease, transform 100ms ease-out;
}

.menu-toggle:hover {
  background: var(--toggle-bg-hover);
}

.menu-toggle:active {
  transform: scale(0.94);
}

.menu-toggle {
  display: none;
  flex-direction: column;
  gap: 4px;
}

.menu-toggle span {
  display: block;
  width: 16px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--text);
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1), opacity 150ms ease, background-color 400ms ease;
}

.menu-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}

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

.menu-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

.mobile-menu {
  position: fixed;
  top: var(--nav-height);
  left: 0;
  right: 0;
  z-index: 49;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
  transform-origin: top center;
  opacity: 0;
  transform: translateY(-8px);
  transition:
    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
    background-color 400ms ease,
    border-color 400ms ease;
}

.mobile-menu[hidden] {
  display: none;
}

.mobile-menu.is-open {
  opacity: 1;
  transform: translateY(0);
}

.mobile-link {
  font-size: 16px;
  font-weight: 500;
  color: var(--text-muted);
  padding: 13px 14px;
  border-radius: var(--radius-item);
  transition: background-color 200ms ease, color 200ms ease, transform 100ms ease-out;
}

.mobile-link:hover {
  background: var(--mobile-link-hover-bg);
  color: var(--text);
}

.mobile-link:active {
  transform: scale(0.98);
}

.mobile-cta {
  margin-top: 8px;
  justify-content: center;
}

/* Rozwijane "Oferta" w menu mobilnym — ten sam schemat grid-template-rows
   0fr → 1fr co .service-card__panel na stronie głównej. */
.mobile-menu__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform 120ms ease-out;
}

.mobile-menu__trigger:active {
  transform: scale(0.98);
}

.mobile-menu__chevron {
  position: relative;
  width: 10px;
  height: 10px;
  flex-shrink: 0;
}

.mobile-menu__chevron span {
  position: absolute;
  inset: 0;
  margin: auto;
  background: currentColor;
  border-radius: 1px;
  transition: transform 250ms cubic-bezier(0.22, 1, 0.36, 1), opacity 200ms ease;
}

.mobile-menu__chevron span:first-child {
  width: 100%;
  height: 1.5px;
}

.mobile-menu__chevron span:last-child {
  width: 1.5px;
  height: 100%;
}

.mobile-menu__trigger[aria-expanded="true"] .mobile-menu__chevron span:last-child {
  transform: rotate(90deg);
  opacity: 0;
}

.mobile-menu__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms cubic-bezier(0.22, 1, 0.36, 1);
}

.mobile-menu__trigger[aria-expanded="true"] + .mobile-menu__panel {
  grid-template-rows: 1fr;
}

.mobile-menu__panel-inner {
  overflow: hidden;
}

.mobile-menu__pillar {
  display: flex;
  flex-direction: column;
  padding: 10px 14px 16px;
}

.mobile-menu__pillar-title {
  margin-bottom: 4px;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.mobile-menu__service {
  padding: 10px 8px;
  border-radius: var(--radius-button);
  font-size: 15px;
  color: var(--text-muted);
  transition: background-color 150ms ease, color 150ms ease, transform 120ms ease-out;
}

.mobile-menu__service:active {
  background: var(--mobile-link-hover-bg);
  color: var(--text);
  transform: scale(0.98);
}

@media (hover: hover) and (pointer: fine) {
  .mobile-menu__service:hover {
    background: var(--mobile-link-hover-bg);
    color: var(--text);
  }
}

@media (max-width: 860px) {
  .main-nav,
  .desktop-cta {
    display: none;
  }

  .menu-toggle {
    display: flex;
  }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-menu {
    transition: opacity 200ms ease, background-color 400ms ease;
    transform: none !important;
  }

  .nav-link,
  .btn-cta,
  .menu-toggle span,
  .menu-toggle,
  .nav-dropdown,
  .nav-dropdown__inner,
  .nav-item__chevron,
  .mobile-menu__panel,
  .mobile-menu__chevron span {
    transition: none;
  }
}

/* ==========================================================================
   Stopka — "wysuwa się" spod strony. Stopka stoi position: fixed na dole
   ekranu przez cały czas, pod resztą strony (z-index niżej). .page-wrap
   (wszystko poza stopką) dostaje margines dolny równy wysokości stopki
   (mierzone w js/footer-reveal.js) — to on tworzy dodatkowy odcinek
   przewijania, w trakcie którego reszta strony zjeżdża w górę i odsłania
   to, co czekało pod spodem od samego początku. Treść tymczasowa/placeholder.
   ========================================================================== */

.page-wrap {
  position: relative;
  z-index: 1;
  background: var(--bg-color);
  border-radius: 0 0 var(--radius-tile) var(--radius-tile);
}

.site-footer {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(24px, 4vw, 40px);
  min-height: clamp(460px, 48vw, 640px);
  /* Górny padding ma dodatkowe --footer-top-buffer — to samo tło stopki
     (cover, center bottom) po prostu "rozciąga się" o ten kawałek wyżej,
     więc nad treścią stopki jest zapas już ugruntowanej zieleni, zanim
     zacznie się właściwa treść (logo itd). Dzięki temu zaokrąglone dolne
     rogi .page-wrap zawsze lądują na tym samym, ciągłym tle — bez osobnego
     elementu i bez ręcznego przeliczania kadru zdjęcia. footer-reveal.js
     odejmuje dokładnie tyle samo od marginesu odsłaniania, więc ten zapas
     zostaje na stałe schowany za ostatnią sekcją, a reszta treści stopki
     (łącznie z logo) i tak w pełni się odsłania. */
  padding: calc(clamp(32px, 5vw, 56px) + var(--footer-top-buffer, 80px)) 0 clamp(32px, 5vw, 56px);
  background-image: linear-gradient(
      180deg,
      rgba(3, 8, 6, 0.45) 0%,
      rgba(3, 8, 6, 0.3) 35%,
      rgba(3, 8, 6, 0.65) 100%
    ),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center bottom;
  background-repeat: no-repeat;
  color: #f3f5f2;
}

.site-footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: clamp(32px, 6vw, 80px);
  max-width: 1280px;
  margin: 0 auto;
  width: 100%;
  padding: 0 var(--gutter);
}

.site-footer__col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.site-footer__col--brand {
  max-width: 420px;
}

.site-footer__brand svg {
  height: 26px;
  width: auto;
  color: #f3f5f2;
}

.site-footer__heading {
  margin: 0;
  font-size: clamp(1.3rem, 2vw, 1.6rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: #f3f5f2;
}

.site-footer__tagline {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.6;
  color: rgba(243, 245, 242, 0.82);
}

/* Selektor złożony (.btn-cta.site-footer__cta) — patrz uwaga przy
   .btn-cta.faq__promo-cta o kolejności reguł i specyficzności. */
.btn-cta.site-footer__cta {
  margin-top: 6px;
  color: #0a0a0a;
  background: linear-gradient(180deg, #ffffff, rgba(255, 255, 255, 0.86));
  box-shadow: 0 10px 24px -8px rgba(255, 255, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.btn-cta.site-footer__cta:hover {
  box-shadow: 0 12px 28px -8px rgba(255, 255, 255, 0.45), 0 3px 10px rgba(0, 0, 0, 0.35);
}

.site-footer__col--contact {
  align-items: flex-end;
  text-align: right;
  padding-top: 2px;
}

.site-footer__contact-title {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(243, 245, 242, 0.6);
}

.site-footer__contact-item {
  font-size: 1rem;
  font-weight: 600;
  color: #f3f5f2;
}

.site-footer__contact-item:hover {
  opacity: 0.8;
}

.site-footer__marquee {
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.site-footer__marquee-track {
  display: flex;
  align-items: center;
  width: max-content;
  gap: clamp(20px, 3vw, 40px);
  padding: 0 var(--gutter);
  animation: footer-marquee-scroll var(--footer-marquee-duration, 30s) linear infinite;
}

.site-footer__marquee-item {
  font-size: clamp(3.4rem, 10vw, 8.5rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: #f3f5f2;
  white-space: nowrap;
}

.site-footer__marquee-sep {
  font-size: clamp(1.2rem, 2.4vw, 1.8rem);
  color: rgba(243, 245, 242, 0.5);
}

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

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

.site-footer__copy {
  margin: 0 auto 0;
  max-width: 1280px;
  width: 100%;
  padding: 0 var(--gutter);
  font-size: 0.8rem;
  color: rgba(243, 245, 242, 0.6);
}

@media (max-width: 700px) {
  .site-footer__inner {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 32px;
  }

  .site-footer__col,
  .site-footer__col--brand,
  .site-footer__col--contact {
    align-items: center;
    text-align: center;
    max-width: 100%;
  }

  .site-footer__copy {
    text-align: center;
  }
}

/* ==========================================================================
   Nakładka "wkrótce" — pełnoekranowa, ponad wszystkim, blokuje dostęp do
   reszty strony wizualnie (position:fixed + wysoki z-index) i dla
   asystujących technologii (inert na .page-wrap/.site-footer w HTML, patrz
   index.html). Czysty HTML/CSS bez JS, żeby działała nawet gdy JS się
   nie wykona — to jedyny sposób, żeby faktycznie zawsze zasłaniała treść.
   ========================================================================== */

html:has(.site-lock),
body:has(.site-lock) {
  overflow: hidden;
}

.site-lock {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(32px, 7vw, 72px) clamp(24px, 6vw, 64px) clamp(24px, 4vw, 40px);
  text-align: center;
  background-image: linear-gradient(180deg, rgba(3, 8, 6, 0.35) 0%, rgba(3, 8, 6, 0.6) 100%),
    url("/images/hero-background.webp");
  background-size: cover;
  background-position: center;
  color: #f3f5f2;
}

/* flex: 1 — zajmuje całą wysokość ponad .site-lock__bottom (który zostaje
   przy dole na margin-top: auto), a justify-content: center centruje
   logo+opis w TEJ przestrzeni, więc nie ląduje ani przy samej górze, ani
   zbyt blisko karuzeli na dole. */
.site-lock__top {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 2.5vw, 24px);
}

.site-lock__logo svg {
  width: clamp(200px, 30vw, 380px);
  height: auto;
  display: block;
  color: #f3f5f2;
}

.site-lock__text {
  margin: 0;
  font-size: clamp(1.1rem, 2.4vw, 1.5rem);
  font-weight: 500;
  color: rgba(243, 245, 242, 0.88);
}

/* margin-top: auto pcha ten blok na sam dół kolumny, niezależnie od tego,
   ile miejsca zajmuje .site-lock__top u góry — reszta wysokości między nimi
   zostaje po prostu pusta. */
.site-lock__bottom {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(16px, 3vw, 28px);
  width: 100%;
}

.site-lock__contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 24px;
  padding: 0 24px;
}

/* Przygaszone, "brudne" szare — dane kontaktowe są tu tylko na wszelki
   wypadek, nie mają konkurować wizualnie z logo/napisem u góry. */
.site-lock__contact-item {
  font-size: 0.85rem;
  font-weight: 500;
  color: rgba(180, 182, 176, 0.5);
}

.site-lock__contact a {
  color: inherit;
  font-weight: 600;
  transition: color 150ms ease;
}

.site-lock__contact a:hover {
  color: #f3f5f2;
}

/* Widoczny tylko dla zalogowanego administratora, gdy .site-lock jest
   pominięte (patrz warunek PHP w index.php) — jedyny sposób, żeby się
   wylogować i wrócić do zwykłego widoku odwiedzającego. */
.admin-badge {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 10000;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  background: rgba(29, 29, 31, 0.92);
  color: #ffffff;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 6px 16px -6px rgba(0, 0, 0, 0.4);
  transition: opacity 150ms ease;
}

.admin-badge:hover {
  opacity: 0.82;
}
