/* =============================================
   SERVICES SECTION
   Used on: hero.html, oferta-okna.html
   ============================================= */
.services {
  background-color: var(--white);
  padding: 100px 24px;
  position: relative;
  overflow: hidden;

  /* Tokeny kaskady wejscia (ta sama zasada co `.why-us`, why-us.css v60):
     krok MUSI byc dluzszy niz czas trwania ruchu, inaczej elementy nakladaja
     sie i sekcja czyta sie jako jedna fala. Globalne `--reveal-duration`
     (0.9s) jest dobrane pod pojedyncze wejscie sekcji i do kaskady sie nie
     nadaje. Strojenie tempa = zmiana TYLKO tych dwoch wartosci.
     Definiowane na `.services` (nie na `.reveal-services`), bo `.services__card`
     odwoluje sie do nich w swoim bazowym `transition` na WSZYSTKICH 20
     stronach z ta sekcja — brak wartosci uniewaznilby cala deklaracje. */
  --services-reveal-dur: 0.5s;
  --services-step: 0.25s;

  /* Karty maja WLASNY czas i krzywa, bo nie sa czescia kaskady naglowka —
     odslania je trigger per rzad, wiec nic ich nie ogranicza od gory.
     Wartosci sa przepisane 1:1 z wejscia hero na stronie glownej
     (`fadeInLeft 0.7s ease-out` + 30px, hero.css) — klient wskazal je jako
     wzorzec predkosci i charakteru ruchu. NIE podmieniaj tego na
     `--reveal-ease`: to expo-out, ktory przy 0.5s robi ~90% drogi w ~120ms
     i na elemencie wielkosci karty czyta sie jak wystrzal.
     Musza byc na `.services` (nie na `.reveal-services`) — patrz komentarz
     przy tokenach wyzej. */
  --services-card-dur: 0.7s;
  --services-card-ease: ease-out;
}


.services__container {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 80px;
  align-items: start;
}

.services__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;
  grid-column: 1;
  justify-self: start;
}

.services__label::before { content: "// "; }
.services__label { text-transform: capitalize; }

.services__heading {
  font-size: var(--heading-size);
  font-weight: var(--heading-weight);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 0;
  color: var(--dark-gray);
  grid-column: 1;
}

.services__heading span {
  color: inherit;
}

.services__subheading {
  font-size: 18px;
  font-weight: 400;
  line-height: 1.7;
  color: var(--gray-500);
  max-width: 380px;
  margin: 0;
  grid-column: 2;
  justify-self: end;
  align-self: start;
}

.services__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  max-width: var(--max-width-wide);
  margin: 56px auto 0;
  grid-column: 1 / -1;
}

.services__card {
  background: var(--white);
  border: none;
  border-radius: 10px;
  padding: 0;
  text-align: left;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  /* opacity + translate obsluguja wejscie karty (patrz "Scroll reveal" nizej).
     Musza byc TU, w regule bazowej: gdyby reguła revealu podala wlasny
     `transition`, shorthand skasowalby hover na box-shadow i transform. */
  transition: box-shadow 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              opacity var(--services-card-dur) var(--services-card-ease),
              translate var(--services-card-dur) var(--services-card-ease);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}

.services__card:hover,
.services__card.touch-hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
}

.services__card:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 4px;
}

/* Card image — top half */
.services__card-image {
  width: 100%;
  height: 384px;
  overflow: hidden;
  position: relative;
}

.services__card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Ogrodzenia: zrodlo jest PIONOWE (967x1200), a kadr karty poziomy, wiec
   `cover` przycina tylko w pionie. Przy domyslnym `center` (50%) kadr zaczyna
   sie ~168px ponizej gory zrodla, a gorna krawedz ogrodzenia lezy na y~142 —
   czyli konce slupkow byly ucinane i nie bylo widac, gdzie ogrodzenie sie
   konczy. 12% stawia kadr na y~44 (desktop) / ~47 (mobile), wiec nad
   ogrodzeniem zostaje ~12% wysokosci kadru zapasu na kazdej szerokosci
   (kadr jest inny na 1440 / 1100 / 390, ale ta jedna wartosc obsluguje
   wszystkie — patrz services.css v40). Pozostale 5 kart ma zdjecia, ktorych
   srodek jest poprawnym kadrem, wiec regula jest CELOWO zawezona do jednej. */
.services__card[href="/oferta/ogrodzenia"] .services__card-image img {
  object-position: center 12%;
}

.services__card:hover .services__card-image img,
.services__card.touch-hover .services__card-image img {
  transform: scale(1.06);
}

/* Dark overlay on hover */
.services__card-image::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  transition: background 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 1;
  pointer-events: none;
}

.services__card:hover .services__card-image::after,
.services__card.touch-hover .services__card-image::after {
  background: rgba(0, 0, 0, 0.35);
}

/* "Otwórz" pill on hover */
.services__card-image::before {
  content: 'Otwórz';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.85);
  z-index: 2;
  background: var(--white);
  color: var(--dark-gray);
  font-family: var(--font-family);
  font-size: 15px;
  font-weight: 600;
  padding: 14px 32px;
  border-radius: 7px;
  opacity: 0;
  transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1), transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.services__card:hover .services__card-image::before,
.services__card.touch-hover .services__card-image::before {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* Card body — bottom half.
   flex-grow so the white body fills the leftover height when the grid stretches
   a short card to match a taller sibling — otherwise the card's own cream
   var(--white) background shows through as a strip under the body. */
.services__card-body {
  padding: 24px 28px 28px;
  background: #ffffff;
  flex-grow: 1;
}

.services__card-title {
  font-size: 22px;
  font-weight: 600;
  color: var(--dark-gray);
  letter-spacing: -0.01em;
  margin-bottom: 8px;
  line-height: 1.3;
}

.services__card-subtitle {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  color: var(--gray-500);
}

/* ---- Scroll reveal — sekwencyjny, element po elemencie ----
   Kolejnosc: label → (heading + subheading RAZEM, bo stoja obok siebie w
   tym samym rzedzie gridu) → 1. rzad kart → 2. rzad kart.
   Karty grupuja sie PER RZAD, wiec podzial zalezy od liczby kolumn i jest
   powtorzony w blokach responsywnych nizej (3 kol → 2 rzedy, 2 kol → 3,
   1 kol → 6). Renderuje to tylko hero.html — pozostale 19 stron ma sekcje
   `.services--product` bez klasy `.reveal-services`. */
.services__container.reveal-services .services__label,
.services__container.reveal-services .services__heading,
.services__container.reveal-services .services__subheading {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--services-reveal-dur) var(--reveal-ease),
              transform var(--services-reveal-dur) var(--reveal-ease);
}

/* Karta wjezdza na `translate`, NIE na `transform` — hover-lift
   (`.services__card:hover { transform: translateY(-4px) }`) ma nizsza
   specyficznosc (0,2,0) niz ta kaskada (0,3,0), wiec transform w regule
   revealu zablokowalby unoszenie sie karty po odslonieciu. `translate` to
   osobna wlasciwosc, wiec oba ruchy wspolistnieja. Transition siedzi w
   bazowej regule `.services__card`. */
.services__container.reveal-services .services__card {
  opacity: 0;
  /* 30px = dystans wejscia hero (`fadeInLeft` w base.css), zeby ruch mial
     ten sam zasieg co wzorzec, nie tylko ten sam czas i krzywa. */
  translate: 0 30px;
}

.services__container.reveal-services.visible .services__label,
.services__container.reveal-services.visible .services__heading,
.services__container.reveal-services.visible .services__subheading {
  opacity: 1;
  transform: translateY(0);
}

/* Karty NIE sa czescia czasowej kaskady naglowka — kazdy RZAD ma wlasny
   trigger (`.is-revealed` dodaje modul "Services Rows Reveal" w main.js, gdy
   rzad wjedzie w widok). Powod: kaskada startuje, gdy w widok wchodzi label,
   a karty sa wtedy jeszcze daleko pod ekranem (zmierzone @1440: 1. rzad 120px,
   2. rzad 668px ponizej krawedzi okna) — czasowe opoznienia wypalaly sie na
   niewidocznych elementach i uzytkownik zastawal oba rzedy juz odsloniete.
   Grupowanie po rzedach robi JS z `offsetTop`, wiec dziala dla 3/2/1 kolumn
   bez powielania regul w media queries. */
.services__container.reveal-services .services__card.is-revealed {
  opacity: 1;
  translate: none;
}

.services__container.reveal-services.visible .services__label { transition-delay: 0s; }
.services__container.reveal-services.visible .services__heading,
.services__container.reveal-services.visible .services__subheading { transition-delay: var(--services-step); }

/* Karty nie maja tu zadnych `transition-delay` — o momencie ich wejscia
   decyduje trigger per rzad w main.js, a nie pozycja w kaskadzie naglowka. */

/* =============================================
   RESPONSIVE — SERVICES
   ============================================= */
/* === Tablet (≤1024px) === */
@media (max-width: 1024px) {
  .services__container {
    grid-template-columns: 1fr;
    gap: 16px;
    text-align: center;
  }

  .services__label {
    grid-column: 1;
    justify-self: center;
  }

  .services__heading {
    font-size: 36px;
    grid-column: 1;
    margin: 0 auto 12px;
  }

  .services__subheading {
    grid-column: 1;
    max-width: 580px;
    margin: 0 auto;
    justify-self: center;
  }

  .services__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
  }

  .services__card:last-child:nth-child(odd) {
    grid-column: span 2;
  }

  .services__card-body {
    padding: 22px 24px 24px;
  }

  /* Tablet: 2 kolumny → 3 rzedy. Grupowanie robi JS z `offsetTop`, wiec ten
     blok nie potrzebuje juz zadnych regul kaskady. */
}

/* === Mobile (≤768px) === */
@media (max-width: 768px) {
  .services__container {
    text-align: left;
  }

  .services__label {
    justify-self: start;
  }

  .services__heading {
    font-size: 32px;
    margin-left: 0;
    margin-right: 0;
  }

  .services__subheading {
    margin-left: 0;
    margin-right: 0;
    justify-self: start;
  }

  /* Single-column stack — one card per row, full width.
     grid-auto-rows: 1fr keeps every card the same height as the tallest, so the
     stack stays uniform; .services__card-body flex-grow fills the slack in white. */
  .services__grid {
    grid-template-columns: 1fr;
    grid-auto-rows: 1fr;
    gap: 16px;
    max-width: 480px;
    margin: 40px auto 0;
  }

  .services__card {
    text-align: left;
  }

  .services__card-image {
    height: auto;
    aspect-ratio: 6 / 5;
  }

  .services__card-body {
    padding: 20px 22px 24px;
  }

  .services__card-title {
    font-size: 20px;
    margin-bottom: 6px;
  }

  .services__card-subtitle {
    font-size: 14.5px;
    line-height: 1.6;
  }

  /* Neutralise :hover / .touch-hover on mobile. Touch browsers latch :hover
     onto the last tapped element ("sticky hover"), which would leave that card
     revealed forever. On mobile ONLY .services__card--open may reveal. */
  .services__card:hover,
  .services__card.touch-hover {
    transform: none;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  }

  .services__card:hover .services__card-image img,
  .services__card.touch-hover .services__card-image img {
    transform: none;
  }

  .services__card:hover .services__card-image::after,
  .services__card.touch-hover .services__card-image::after {
    background: rgba(0, 0, 0, 0);
  }

  .services__card:hover .services__card-image::before,
  .services__card.touch-hover .services__card-image::before {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.85);
  }

  /* Two-tap reveal — first tap opens (JS adds .services__card--open),
     second tap on the card navigates. Doubled class matches the specificity
     of the :hover rules above and wins by coming later in source order. */
  .services__card--open.services__card .services__card-image img {
    transform: scale(1.06);
  }

  .services__card--open.services__card .services__card-image::after {
    background: rgba(0, 0, 0, 0.35);
  }

  .services__card--open.services__card .services__card-image::before {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }

  /* Mobile: 1 kolumna → kazda karta to osobny rzad. Wczesniej mialy tu wlasne
     `transition-delay`, ale karty 4–6 byly wtedy 1500px pod ekranem i caly
     krok wypalal sie w niewidocznym miejscu — teraz odsłania je trigger
     per rzad w main.js, wiec ten blok nie potrzebuje zadnych regul. */
}

/* === Small mobile (≤600px) === */
@media (max-width: 600px) {
  .services {
    padding: 72px 20px;
  }

  .services__subheading {
    font-size: 16px;
  }

  .services__card-title {
    font-size: 19px;
  }

  .services__card-subtitle {
    font-size: 14px;
  }
}

/* Reduced motion — zostaje sam fade, bez ruchu i bez kaskady
   (ta sama zasada co globalny blok w base.css v131–132). */
@media (prefers-reduced-motion: reduce) {
  .services__container.reveal-services .services__label,
  .services__container.reveal-services .services__heading,
  .services__container.reveal-services .services__subheading,
  .services__container.reveal-services .services__card,
  .services__container.reveal-services.visible .services__label,
  .services__container.reveal-services.visible .services__heading,
  .services__container.reveal-services.visible .services__subheading,
  .services__container.reveal-services .services__card.is-revealed {
    transform: none;
    translate: none;
    transition-delay: 0s;
  }
}

/* ---- TELEFON: etykieta + naglowek wjezdzaja Z LEWEJ ----
   Wspolna regula calego serwisu (2026-08-03, base.css v142): naglowek sekcji
   wchodzi Z BOKU, tresc (karty) Z DOLU — klient poprosil, zeby ruch byl
   „i lewo/prawo, i z dolu". Podtytul ZOSTAJE z dolu: na telefonie stoi pod
   naglowkiem w tej samej kolumnie, wiec wjazd z boku rozjechalby go z labelem.
   Dystans wpisany LICZBA, bo ta sekcja jako jedyna nie ma tokenu `--*-shift`
   (jej wejscie powstalo przed ujednoliceniem) — 44px to ta sama wartosc, ktora
   base.css v142 ustawia pozostalym sekcjom na telefonie.
   Selektor jest kopia stanu ukrytego (0,3,0), wiec wygrywa kolejnoscia w
   zrodle; reguly z `.visible` (0,4,0) dalej przebijaja obie.
   `no-preference` jest konieczne — blok reduced-motion lezy wyzej w pliku. */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .services__container.reveal-services .services__label,
  .services__container.reveal-services .services__heading {
    transform: translateX(-44px);
  }

  /* Podtytul: 28px → 44px — jednakowy dystans wjazdu w calym serwisie. */
  .services__container.reveal-services .services__subheading {
    transform: translateY(44px);
  }

  /* Karty: 30px → 44px, zeby wjazd z dolu byl rownie czytelny co ruch boczny
     naglowka. `translate`, NIE `transform` — hover-lift karty siedzi na
     `transform` (patrz komentarz przy stanie ukrytym wyzej). */
  .services__container.reveal-services .services__card {
    translate: 0 44px;
  }
}
