/* =============================================
   PROCESS / COLLABORATION SECTION
   Used on: hero.html, oferta-okna.html
   ============================================= */
.process {
  background-color: var(--white);
  padding: 100px 24px;
  position: relative;
  overflow: hidden;
}

.process::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 60%;
  height: 100%;
  background: radial-gradient(ellipse at 80% 50%, rgba(var(--orange-rgb), 0.05) 0%, rgba(var(--orange-rgb), 0.02) 40%, transparent 70%);
  filter: blur(40px);
  pointer-events: none;
  z-index: 0;
  will-change: transform;
}

.process__container {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 6fr 5fr;
  gap: 64px;
  align-items: center;
  position: relative;
  z-index: 1;
}

/* Content first (left), timeline second (right) */
.process__content { order: -1; }

/* ---- Right: Timeline panel ---- */
/* Matches .showroom__image-wrapper dimensions (4:5 ratio) */
.process__timeline-wrapper {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  background: #ffffff;
  border: 1.5px solid #ffffff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

/* Subtle orange glow at top */
.process__timeline-wrapper::after {
  content: '';
  position: absolute;
  top: -60px;
  left: 50%;
  transform: translateX(-50%);
  width: 250px;
  height: 250px;
  background: radial-gradient(circle, rgba(var(--orange-rgb), 0.06) 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

/* Aspect ratio enforced via padding-bottom (Safari-safe) — matches showroom 4:5 */
.process__timeline-inner {
  position: relative;
  width: 100%;
  padding-bottom: 125%;
}

.process__timeline {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  z-index: 1;
  padding: 56px 32px 0;
}


/* Individual step — flex:1 ensures equal icon-to-icon spacing */
.process__step {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  flex: 1;
}


/* Step icon — matches showroom__feature-icon style */
.process__step-icon {
  position: relative;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  background: linear-gradient(135deg, rgba(var(--orange-rgb), 0.4), rgba(var(--orange-end-rgb), 0.4));
  color: var(--orange);
  transition: background 0.35s ease-in, color 0.35s ease-in, box-shadow 0.35s ease-in;
  will-change: transform;
}

.process__step.highlight .process__step-icon {
  transition: background 0.5s cubic-bezier(0.22, 1, 0.36, 1), color 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.process__step-icon svg {
  width: 24px;
  height: 24px;
}

/* Numbered badge on icon */
.process__step-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--orange-gradient);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  box-shadow: 0 2px 6px rgba(var(--orange-rgb), 0.3);
}

.process__step-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.process__step-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--dark-gray);
  line-height: 1.3;
  transition: color 0.35s ease-in;
}

.process__step.highlight .process__step-title {
  transition: color 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Sequential highlight state — triggered by JS */
.process__step.highlight .process__step-icon {
  background: var(--orange-gradient);
  color: var(--white);
}

/* Glow on pseudo-element — disabled */
.process__step-icon::after {
  display: none;
}

.process__step.highlight .process__step-title {
  color: var(--orange);
}


.process__step-desc {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--gray-500);
}

/* ---- Right: Text content ---- */
.process__content {
  display: flex;
  flex-direction: column;
}

.process__label {
  display: inline-block;
  padding: 0;
  background: transparent;
  color: var(--dark-gray);
  border: none;
  font-size: 15px;
  font-weight: 500;
  border-radius: 0;
  letter-spacing: 0.02em;
  margin-bottom: 20px;
  align-self: flex-start;
}

.process__heading {
  font-size: var(--heading-size);
  font-weight: var(--heading-weight);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--dark-gray);
  margin-bottom: 20px;
}

.process__subheading {
  font-size: 17px;
  font-weight: 400;
  line-height: 1.7;
  color: var(--gray-500);
  margin-bottom: 44px;
  max-width: 520px;
}

/* Value points list */
.process__values {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-bottom: 44px;
}

.process__value {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 16px;
  font-weight: 500;
  color: var(--dark-gray);
  line-height: 1.4;
}

.process__value-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  background: rgba(var(--orange-rgb), 0.12);
  color: var(--orange);
}

.process__value-icon svg {
  width: 16px;
  height: 16px;
}

/* CTA button uses existing .ihb pattern */
.ihb--process {
  font-size: 17px;
  padding: 16px 40px;
  align-self: flex-start;
}


/* =============================================
   STACKED PROCESS VARIANT (hero.html only)
   ============================================= */
.process--stack { overflow: visible; padding-bottom: 0; }
.process--stack::before { display: none; }

.process-stack__container {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(auto, 600px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  position: relative;
  z-index: 1;
}

.process-stack__content {
  display: flex;
  flex-direction: column;
  position: sticky;
  top: calc(var(--navbar-height) + 32px);
  align-self: start;
}

.process-stack__heading {
  font-size: var(--heading-size);
  font-weight: var(--heading-weight);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--dark-gray);
  margin: 0 0 24px;
}

.process-stack__subheading {
  /* 18px — wspolny rozmiar subheadingu sekcji na desktopie (>1200px, czyli tam
     gdzie dziala sticky stack). ≤1200 zostaje na 17px, ≤768 na 16px. */
  font-size: 18px;
  font-weight: 400;
  line-height: 1.7;
  color: var(--gray-500);
  margin: 0 0 40px;
  max-width: 420px;
}

.process-stack__values {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 0 0 44px;
  padding: 0;
}

.process-stack__cards {
  display: flex;
  flex-direction: column;
  gap: 48px;
}

/* Spacer sized so at card 5 dock, the testimonials badge + heading + subheading
   are visible at the bottom of the viewport (subheading bottom + ~48px breathing
   room). Subtract 679px from 100vh to lift testimonials 48px higher than the
   minimum-fit value (631px). */
.process-stack__cards::after {
  content: '';
  display: block;
  flex: none;
  height: calc(100vh - 744px);
}

.process-card {
  /* min(), nie sztywne 767px: kolumna kart (1fr) przy 1201–1439px jest wezsza
     niz 767, a sztywna szerokosc + `overflow-x: clip` na body ucinaly prawa
     krawedz kart (zmierzone do 151px @1280 — tytuly typu „03. Finalna Oferta
     i Zamówie…" konczyly sie za ekranem). Od 1440px min() zwraca projektowe 767. */
  width: min(767px, 100%);
  margin-left: auto;
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 36px;
  align-items: start;
  padding: 20px 32px 20px 20px;
  background: #ffffff;
  border-radius: 24px;
  box-shadow: 0 10px 30px -18px rgba(21, 21, 21, 0.18);
  position: sticky;
  top: calc(var(--navbar-height) + 32px + var(--stack-offset, 0px));
}

.process-card__body { padding-top: 48px; }

/* Progressive dock offset + z-index. Works for both the 5-card hero stack and the
   7-card oferta stack: nth-child sets the ascending offset + rising z-index, and
   :last-child (later in source, equal specificity) forces the TOP card's offset
   back to 0 while keeping its highest z-index — so whichever card is last docks flush. */
.process-card:nth-child(1) { --stack-offset: 0px;  z-index: 1; }
.process-card:nth-child(2) { --stack-offset: 14px; z-index: 2; }
.process-card:nth-child(3) { --stack-offset: 28px; z-index: 3; }
.process-card:nth-child(4) { --stack-offset: 42px; z-index: 4; }
.process-card:nth-child(5) { --stack-offset: 56px; z-index: 5; }
.process-card:nth-child(6) { --stack-offset: 70px; z-index: 6; }
.process-card:nth-child(7) { --stack-offset: 84px; z-index: 7; }
.process-card:last-child   { --stack-offset: 0px; }

/* 1201–1439px: wezszy lewy tor (520 zamiast 600), zeby kolumna kart oddala
   kartom jak najwiecej z projektowych 767px (przy 600 karta mialaby ledwie
   ~537–616px). Tekst lewej kolumny i tak sklada sie wezej (subheading ma
   max-width 420); punkty listy moga zlamac sie na dwie linie — zamierzone. */
@media (min-width: 1201px) and (max-width: 1439px) {
  .process-stack__container {
    grid-template-columns: minmax(auto, 520px) minmax(0, 1fr);
  }
}

/* Kill sticky on small viewports (already handled by 1-column layout) */
@media (max-width: 1200px) {
  .process-card { position: static; top: auto; }
  .process-stack__content { position: static; top: auto; }
}

/* Respect user motion preference */
@media (prefers-reduced-motion: reduce) {
  .process-card { position: static; top: auto; }
  .process-stack__content { position: static; top: auto; }
}

.process-card__media {
  aspect-ratio: 1 / 1;
  border-radius: 16px;
  background: #DDD6CC;
  overflow: hidden;
}

.process-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Gray photo placeholder (oferta-* stack — until real images are added) */
.process-card__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #E4E2DD;
  color: #A9A49B;
}
.process-card__placeholder svg {
  width: 42px;
  height: 42px;
}

.process-card__body {
  min-width: 0;
}

.process-card__title {
  font-size: 27px;
  font-weight: 600;
  color: var(--dark-gray);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
}

.process-card__number {
  margin-right: 4px;
}

.process-card__desc {
  font-size: 15px;
  line-height: 1.6;
  color: var(--gray-500);
  margin: 0;
  max-width: 56ch;
}

/* =============================================
   REVEAL — kaskada wejscia sekcji (.process--stack, 9 stron)
   Kolejnosc z zyczenia klienta: label → heading + karty RAZEM → subheading →
   3 punkty z ptaszkiem (wlatuja Z BOKU, jeden po drugim) → przycisk CTA.

   Ruch hero: 0.7s ease-out, 30px — te same tokeny co why-us v63, services v37,
   showroom v63, montage v52, realizacje v28. NIE wracaj tu do `--reveal-ease`
   (expo-out, ~90% drogi w ~20% czasu, czyta sie jak szarpniecie).
   Pion zawsze Z DOLU — zasada klienta „nic z gory".
   ============================================= */
.process--stack {
  --ps-reveal-dur: 0.7s;
  --ps-ease: ease-out;
  --ps-step: 0.25s;
  --ps-shift: 30px;
}

/* `.section-fade` zostaje na sekcji WYLACZNIE jako trigger dla `.visible`
   z common.js — wlasny fade calej sekcji jest wygaszony, bo animuja sie
   pojedyncze elementy. To NIE jest kosmetyka: `transform` na sekcji tworzy
   nowy uklad odniesienia, a ta sekcja stoi na `position: sticky` (kolumna
   tekstu + karty) i na ScrollTriggerze mierzacym pozycje dokowania kart. */
.process--stack.section-fade {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ---- Na kaskadzie CZASOWEJ tylko label i heading ----
   Zmierzone w chwili startu kaskady @1440×900: label i 1. karta maja `top` 705,
   czyli sa w kadrze; subheading, punkty i CTA sa juz PONIZEJ krawedzi okna
   (CTA az o 256px), wiec ich opoznienia wypalilyby sie poza kadrem — maja
   trigger pozycyjny, patrz nizej. */
.process--stack.section-fade .process__label,
.process--stack.section-fade .process-stack__heading {
  opacity: 0;
  transform: translateY(var(--ps-shift));
  transition: opacity var(--ps-reveal-dur) var(--ps-ease),
              transform var(--ps-reveal-dur) var(--ps-ease);
}

.process--stack.section-fade.visible .process__label,
.process--stack.section-fade.visible .process-stack__heading {
  opacity: 1;
  transform: translateY(0);
}

.process--stack.section-fade.visible .process__label { transition-delay: 0s; }
.process--stack.section-fade.visible .process-stack__heading { transition-delay: var(--ps-step); }

/* ---- Karty („okienka") — wchodza RAZEM z naglowkiem, SAMYM fadem ----
   **Karty nie moga miec ruchu i to jest ograniczenie techniczne, nie wybor
   estetyczny.** `transform` na karcie nalezy do GSAP-a (drabinka `scale(...)`
   stosu, skrypt inline w hero.html i na 8 stronach oferty), a sztuczka „uzyj
   `translate`, bo to osobna wlasciwosc" — ktora dziala przeciwko animacjom CSS
   (patrz `why-us-float`) — przeciwko GSAP-owi NIE dziala: CSSPlugin wchlania
   niezalezne `translate`/`rotate`/`scale` do swojej macierzy i zeruje je inline.
   Zmierzone: przy `translate: 0 30px` karta dostawala `transform:
   matrix(1,0,0,1,0,30)` i `translate: none`, czyli zostawala przesunieta o 30px
   NA STALE, takze po zakonczeniu revealu. Sam fade jest tu bezpieczny, bo
   `opacity` nie jest czescia macierzy transformacji.
   Karty 2+ sa w chwili startu pod ekranem i to jest OK: to jedno wejscie calej
   kolumny razem z naglowkiem, a nie osobne wejscia kart. */
.process--stack.section-fade .process-card {
  opacity: 0;
  transition: opacity var(--ps-reveal-dur) var(--ps-ease);
}

.process--stack.section-fade.visible .process-card {
  opacity: 1;
  transition-delay: var(--ps-step);
}

/* ---- Trigger POZYCYJNY: subheading → 3 punkty → CTA ----
   `.is-revealed` dodaje modul „Process Stack Reveal" w common.js, kazdemu
   elementowi osobno, gdy sam wjedzie w widok. Modul trzyma wspolna os czasu,
   wiec kolejnosc jest zachowana takze wtedy, gdy kilka elementow wpadnie w
   widok w jednej klatce (niskie okno, szybkie przewijanie).
   Stan ukryty jest zagniezdzony pod `.process--js-reveal` (klasa dodawana przez
   ten sam modul) — bramka bezpieczenstwa: nowy CSS ze starym, zbuforowanym
   common.js zostawilby te elementy na `opacity: 0` na zawsze (zdarzylo sie
   realnie, patrz partners.css v32). Brak modulu = tresc widoczna, bez animacji. */
.process--js-reveal .process-stack__subheading,
.process--js-reveal .process-stack__values .process__value {
  opacity: 0;
  transform: translateY(var(--ps-shift));
  transition: opacity var(--ps-reveal-dur) var(--ps-ease),
              transform var(--ps-reveal-dur) var(--ps-ease);
}

/* Przycisk CTA — stan ukryty revealu, ale `background-position` MUSI zostac
   w liscie `transition`, inaczej wlasny `transition` skasowalby przejazd
   gradientu z `.ihb` (navbar.css) i kolor na hoverze przeskakiwalby bez plynnosci. */
.process--js-reveal .ihb--process {
  opacity: 0;
  transform: translateY(var(--ps-shift));
  transition: opacity var(--ps-reveal-dur) var(--ps-ease),
              transform var(--ps-reveal-dur) var(--ps-ease),
              background-position 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Punkty wlatuja Z BOKU (zyczenie klienta) — z lewej, jak punkty w „Dlaczego my". */
.process--js-reveal .process-stack__values .process__value {
  transform: translateX(calc(-1 * var(--ps-shift)));
}

/* `.process--stack` ma `overflow: visible` i NIE wolno tego zmieniac (oba
   `position: sticky` w tej sekcji przestalyby dzialac), a przy 1440px kolumna
   tekstu zaczyna sie 24px od krawedzi okna — poziomy wjazd o 30px zrobilby
   wiec realne przepelnienie strony. Dlatego klip trzyma sama lista.

   **Klip jest odsuniety o DOKLADNIE dystans ruchu** (`padding-left` = `--ps-shift`,
   cofniete tym samym ujemnym `margin-left`, wiec uklad w spoczynku sie nie zmienia).
   Bez tego odsuniecia linia ciecia lezala na krawedzi tekstu i punkt byl w trakcie
   wjazdu ROZKROJONY w powietrzu — zmierzone: do 30px lewej strony pozycji zniknietej,
   czyli praktycznie cala plakietka z ptaszkiem (22px). Teraz punkt w chwili startu
   stoi rowno na krawedzi klipu, wiec przez caly ruch jest widoczny w calosci.
   Ujemny margines NIE robi poziomego przewijania: tresc wychodzaca poza LEWA krawedz
   bloku poczatkowego nie tworzy obszaru przewijania w ukladzie LTR. */
.process--js-reveal .process-stack__values {
  overflow: hidden;
  padding-left: var(--ps-shift);
  margin-left: calc(-1 * var(--ps-shift));
}

.process--js-reveal .process-stack__subheading.is-revealed,
.process--js-reveal .process-stack__values .process__value.is-revealed,
.process--js-reveal .ihb--process.is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .process--stack.section-fade .process__label,
  .process--stack.section-fade .process-stack__heading,
  .process--js-reveal .process-stack__subheading,
  .process--js-reveal .ihb--process,
  /* Podbite do (0,3,0), zeby przebic regule kierunkowa punktow — ma tyle samo,
     wiec bez tego punkty zachowalyby wjazd z boku mimo reduced motion. */
  .process--js-reveal .process-stack__values .process__value {
    transform: none;
    transition-delay: 0s;
  }

  /* Karty i tak jada samym fadem — zostaje tylko zdjecie opoznienia. */
  .process--stack.section-fade .process-card {
    transition-delay: 0s;
  }
}

/* =============================================
   KARTY PROCESU — WJAZD Z BOKU, TYLKO ≤1200px

   Do 2026-08-03 karty byly JEDYNYMI elementami w serwisie bez zadnego ruchu
   (sam fade) i do tego szly kaskada CZASOWA naglowka — zmierzone @390x844:
   fade konczyl sie, gdy karta byla jeszcze **2373px (home) / 3013px (oferta)
   PONIZEJ dolnej krawedzi ekranu**, wiec uzytkownik nigdy nie widzial wejscia,
   tylko gotowa karte. Klient: „niektore elementy maja dosłownie animacje
   natychmiastowego pojawiania sie".

   **Dlaczego dopiero teraz i dlaczego tylko ≤1200px:** komentarz przy regule
   bazowej („karty nie moga miec ruchu") dotyczy DESKTOPU i nadal obowiazuje —
   tam `transform` karty nalezy do GSAP-a (drabinka `scale` stosu), a CSSPlugin
   wchlania niezalezne `translate` i zeruje je inline. Ale caly ten silnik jest
   uzbrojony przez `gsap.matchMedia('(min-width: 1201px) …')` (patrz process.css
   v79), wiec **ponizej 1201px GSAP nie dotyka kart w ogole** — `transform` jest
   wolny, a `position: sticky` jest tam i tak wylaczone. Nie przenos tego bloku
   powyzej 1200px.

   Kierunek: karty NIEPARZYSTE z lewej, PARZYSTE z prawej — naprzemienny rytm,
   ktory na waskim ekranie czyta sie wyraznie i jest spojny z punktami tej samej
   sekcji (te wjezdzaja z lewej).

   Klip: `.process--stack` ma na desktopie `overflow: visible` i NIE wolno tego
   ruszac (sticky), ale tutaj sticky nie ma, wiec sekcja moze przyciac sama —
   `overflow-x: clip` (NIE `hidden`: `hidden` zrobiloby z sekcji kontener
   przewijania). Linia ciecia lezy wtedy na KRAWEDZI EKRANU, wiec karta
   wjezdza spoza kadru i nie trzeba kompensacji `padding`/`margin` jak przy
   `.process-stack__values` (patrz gotcha o rozkrojonych wjazdach).

   Kaskada czasowa naglowka jest dla kart WYGASZONA (regula (0,5,0) ponizej) —
   zamiast niej kazda karta czeka na `.is-revealed` z modulu „Process Stack
   Reveal" w common.js v66. Blok jest pod `prefers-reduced-motion: no-preference`,
   wiec przy ograniczonym ruchu zostaje dotychczasowe zachowanie (sam fade).
   ============================================= */
@media (max-width: 1200px) and (prefers-reduced-motion: no-preference) {
  .process--stack {
    overflow-x: clip;
  }

  /* Dystans WIEKSZY niz `--ps-shift` (30px) i to jest celowe: karta zajmuje
     cala szerokosc kolumny, wiec 30px czyta sie na niej jak drgniecie, a nie
     jak wjazd. 56px = ~14% szerokosci ekranu 390px. Sekcja przycina przy
     krawedzi okna, wiec nie ma ryzyka poziomego przepelnienia. */
  .process--js-reveal .process-card {
    --ps-card-shift: 56px;
    transform: translateX(var(--ps-card-x, 0px));
    transition: opacity var(--ps-reveal-dur) var(--ps-ease),
                transform var(--ps-reveal-dur) var(--ps-ease);
  }

  .process--js-reveal .process-card:nth-child(odd) { --ps-card-x: calc(-1 * var(--ps-card-shift)); }
  .process--js-reveal .process-card:nth-child(even) { --ps-card-x: var(--ps-card-shift); }

  /* (0,5,0) — przebija `.process--stack.section-fade.visible .process-card`
     (0,4,0), czyli wyjmuje karty z kaskady czasowej naglowka. */
  .process--stack.process--js-reveal.section-fade.visible .process-card {
    opacity: 0;
    transition-delay: 0s;
  }

  /* Oba selektory sa potrzebne: (0,6,0) na wypadek obecnosci `.visible`
     (regula wyzej) i (0,3,0) dla stanu bez niej — ten drugi bije bazowy stan
     ukryty (0,3,0) kolejnoscia w zrodle. */
  .process--stack.process--js-reveal.section-fade.visible .process-card.is-revealed,
  .process--js-reveal .process-card.is-revealed {
    opacity: 1;
    transform: none;
  }
}

/* === Tablet/mobile stacked variant === */
@media (max-width: 1200px) {
  .process-stack__container {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .process-stack__heading { font-size: 36px; }
  /* Trzyma tablet na dotychczasowych 17px (baza urosla do 18px na desktopie). */
  .process-stack__subheading { max-width: 100%; font-size: 17px; }
  .process-card {
    width: 100%;               /* reset the 767px desktop width so cards fit the single-column track */
    grid-template-columns: 160px minmax(0, 1fr);
    gap: 24px;
    padding: 24px;
  }
  .process-card__title { font-size: 23px; }
  /* The spacer only exists to time the last card's dock against the testimonials
     section while sticky is running. Sticky is off at this width, so it is just
     dead scroll — 172px of blank at 916px tall, and more on taller phones. */
  .process-stack__cards::after { display: none; }
}

@media (max-width: 768px) {
  /* 32px / 16px, not the 36px / 17px inherited from the ≤1200px block.
     Every other section heading on mobile (why-us, services, showroom,
     realizacje, testimonials, montage, faq, about-*) is 32px over a 15–16px
     subheading, so 36/17 made this one section read as a level above its peers
     without being one. It also wrapped to 4 lines at 360px; 32px holds 3. */
  .process-stack__heading { font-size: 32px; }
  .process-stack__subheading { font-size: 16px; }

  /* KARTY MAJA NATURALNA WYSOKOSC — i to jest swiadomy wybor, nie przeoczenie.
     Ta sekcja ma trzy wykluczajace sie wymagania: rowne zdjecia, rowne karty
     i rowny odstep do dolnej krawedzi. Zmierzone @390: tekst karty (tytul+opis)
     ma 172 / 148 / 124 / 98 / 74 px, bo opisy licza 5/4/3/3/2 linie, a tytuly
     2/2/2/1/1. Roznica 98px MUSI gdzies byc — i kazde z trzech miejsc bylo juz
     odrzucone przez klienta: pod opisem (v86 → „inna odleglosc do krawedzi"),
     w zdjeciu (v89, `grid-auto-rows: 1fr` + `1fr auto` + `stretch` → „zdjecia
     maja rozne rozmiary", kadry 233..331px), a wczesniej w wysokosci kart.
     Wybrany kompromis (decyzja klienta): nadmiar idzie w WYSOKOSC KARTY, bo
     karty stoja jedna pod druga z odstepem 48px i przy oknie 844px widac jedna
     na ekran — roznicy nie widac, a wszystko WEWNATRZ karty jest identyczne.
     Dlatego NIE MA tu `grid-auto-rows: 1fr` (kontener zostaje bazowym
     flex-column) ani `grid-template-rows`/`align-items` na karcie: wysokosc
     kadru bierze sie WYLACZNIE z `aspect-ratio` nizej, a bazowe
     `align-items: start` nie pozwala zdjeciu rozciagnac sie do wysokosci karty.
     **Nie przywracaj rownej wysokosci kart bez decyzji klienta** — wraca wtedy
     jeden z dwoch odrzuconych objawow. Jedyne wyjscie z tego trojkata to
     wyrownanie DLUGOSCI opisow (i tytulow) — zmiana tresci na 9 stronach. */
  .process-card {
    grid-template-columns: 1fr;
    gap: 20px;
    padding: 20px;
  }
  /* Single column here, so the image spans the card as a banner. The base
     260px square was left-aligned in a ~372px card, leaving a dead right gutter.
     Kadr 16/10 byl za plaski przy rownej wysokosci kart (zdjecie 194px przy
     karcie ~440px) — 4/3 daje 232px, czyli +20%, i zdjecie niesie karte zamiast
     byc paskiem nad tekstem. Proporcja jest JEDNA dla wszystkich kart i taka ma
     zostac: gdyby zdjecie rozciagalo sie do wysokosci karty, kadry roznilyby sie
     miedzy kartami i wrocilby ten sam efekt „kazde inne", tyle ze na zdjeciach. */
  .process-card__media {
    width: 100%;
    max-width: none;
    aspect-ratio: 4 / 3;
  }
  /* padding-top on __body only exists to drop the title into the image's upper
     third in the 2-col desktop/tablet grid. Stacked here it is dead space on top
     of the 20px grid gap. */
  .process-card__body { padding-top: 0; }
  .process-card__title { font-size: 21px; }
}

/* =============================================
   RESPONSIVE — PROCESS
   ============================================= */
/* === Wide desktop (≤1200px) === */
@media (max-width: 1200px) {
  .process__heading {
    font-size: 44px;
  }
}

/* === Tablet (≤1024px) === */
@media (max-width: 1024px) {
  .process__container {
    grid-template-columns: 1fr;
    gap: 0;
  }

  /* Break content wrapper so children participate in grid */
  .process__content {
    display: contents;
  }

  /* Order: label → heading → subheading → values → timeline → button */
  .process__label { order: 1; justify-self: start; margin-bottom: 20px; }
  .process__heading { order: 2; margin-bottom: 20px; font-size: 36px; text-align: left; }
  .process__subheading { order: 3; margin-bottom: 32px; text-align: left; max-width: 100%; }
  .process__values { order: 4; margin-bottom: 36px; }
  .process__timeline-wrapper {
    order: 5;
    width: 100%;
    margin-bottom: 40px;
  }
  .ihb--process {
    order: 6;
    justify-self: center;
  }

  .process__timeline-inner {
    padding-bottom: 0;
  }

  .process__timeline {
    position: relative;
    padding: 24px 20px;
    gap: 28px;
    justify-content: flex-start;
  }

  .process__step {
    flex: none;
  }
}

/* === Mobile (≤768px) === */
@media (max-width: 768px) {
  .process {
    padding: 72px 20px;
  }

  .process__container {
    gap: 0;
  }

  /* Break content wrapper so children participate in grid */
  .process__content {
    display: contents;
  }

  /* Order: label → heading → subheading → values → timeline → button */
  .process__label { order: 1; justify-self: start; margin-bottom: 20px; }
  .process__heading { order: 2; margin-bottom: 20px; font-size: 32px; text-align: left; }
  .process__subheading { order: 3; margin-bottom: 32px; font-size: 15px; text-align: left; }
  .process__values { order: 4; margin-bottom: 36px; }
  .process__timeline-wrapper {
    order: 5;
    max-width: none;
    width: 100%;
    margin-bottom: 40px;
  }
  .ihb--process {
    order: 6;
    justify-self: center;
    font-size: 16px;
    padding: 14px 36px;
  }
}

/* ---- FIX: legacy `order` z ukladu `.process__content` przeciekal do stosu ----
   Bloki `≤1024px` i `≤768px` wyzej ustawiaja `order` na `.process__label` (1) i
   `.ihb--process` (6), zeby poukladac STARY, gridowy uklad `.process__content`
   (tam `display: contents` wypuszcza dzieci do gridu sekcji). Selektory nie sa
   jednak niczym zawezone, wiec trafialy tez w `.process-stack__content`, ktory
   jest zwyklym flex-column — a tam heading/subheading/values maja domyslne
   `order: 0`. Efekt na telefonie: label „// Proces Wspolpracy" ladowal MIEDZY
   lista z ptaszkami a przyciskiem, zamiast na gorze sekcji (zmierzone @390:
   heading top 113, values 328, label 531, CTA 570).
   Zerowanie wraca do kolejnosci z DOM. Specyficznosc (0,2,0) bije oba bloki
   (0,1,0) niezaleznie od kolejnosci w zrodle, a jedna regula w `≤1024px`
   pokrywa takze `≤768px`. Stary uklad `.process__content` jest nietkniety. */
@media (max-width: 1024px) {
  .process-stack__content .process__label,
  .process-stack__content .ihb--process {
    order: 0;
  }
}

/* Section badge prefix "// " */
.process__label::before { content: "// "; }
.process__label { text-transform: capitalize; }

/* ---- TELEFON: etykieta + naglowek wjezdzaja Z LEWEJ ----
   Wspolna regula calego serwisu (2026-08-03, base.css v142): na telefonie
   NAGLOWEK sekcji wchodzi Z BOKU, a TRESC (karty, zdjecia, listy) Z DOLU.
   Mieszanka jest zamierzona — klient poprosil, zeby ruch byl „i lewo/prawo,
   i z dolu", zamiast dotychczasowego przypadkowego rozklad kierunkow.
   Selektor jest KOPIA stanu ukrytego wyzej, wiec ma te sama specyficznosc i
   wygrywa kolejnoscia w zrodle; reguly odslaniajace maja o klase wiecej
   (`.visible` / `.is-revealed`), wiec dalej przebijaja obie.
   Warunek `no-preference` jest KONIECZNY: blok `prefers-reduced-motion` w tym
   pliku lezy WYZEJ, wiec bez niego ta regula by go przebila.
   Dystans idzie z tokenu sekcji (na telefonie 44px — base.css v142), a sekcja
   przycina poziomo, wiec wjazd nie robi przewijania w bok. */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .process--stack.section-fade .process__label,
  .process--stack.section-fade .process-stack__heading {
    transform: translateX(calc(-1 * var(--ps-shift)));
  }
}
