/* ═══════════════════════════════════════════════════════════════════════════
   PTS - style wzorców blokowych

   `components.css` obsługuje elementy układu przeniesione z wersji B:
   nawigację, stopkę, nagłówki podstron. Ich HTML pisał generator, więc
   selektory zakładają dokładną strukturę.

   Bloki Gutenberga generuje WordPress i ta struktura wygląda inaczej.
   Zamiast naginać tamte selektory, wzorce dostają własny arkusz. Dzięki
   temu zmiana w bloku nie psuje nawigacji i odwrotnie.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Hero ─────────────────────────────────────────────────────────────────
   Zbudowany na core/cover, bo redakcja ma móc wymienić zdjęcie tła bez
   dotykania kodu. Wersja B miała tu canvas ze smugami i animację liter;
   nie przenoszę ich, bo wiazaly sie z konkretnym HTML generatora, a efekt
   dawaly kosztem tego, ze tresci nie dalo sie edytowac. */

.hero-blok.wp-block-cover {
  min-height: clamp(32rem, 26rem + 26vh, 46rem);
  padding-block: var(--section-y);
  align-items: flex-end;

  /* Podkład na wypadek braku zdjęcia. Tekst hero jest biały, więc bez tego
     świeżo wstawiona sekcja to biały napis na białym tle i wygląda na
     zepsutą, zanim redakcja zdąży wybrać zdjęcie. */
  background-color: var(--navy-ink);
}

.hero-blok .wp-block-cover__inner-container {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
}

/* Hero wychodzi poza kolumnę treści na pełną szerokość okna. Pas przerwany
   białymi marginesami czyta się jak baner wklejony w stronę, a nie jak
   otwarcie serwisu. */
.hero-blok.wp-block-cover.alignfull {
  width: calc(100vw - var(--pasek, 0px));
  max-width: calc(100vw - var(--pasek, 0px));
  margin-left: calc(50% - (100vw - var(--pasek, 0px)) / 2);
  margin-right: calc(50% - (100vw - var(--pasek, 0px)) / 2);
}

/* Filtr „Deep Blue" z księgi (s. 15). Zdjęcia hali bywają jasne i szare,
   a tekst musi się na nich obronić bez przyciemniania całości na czarno.
   Gradient idzie na własnym pseudoelemencie, a nie na warstwie WordPressa:
   przy `dimRatio: 0` rdzeń nadaje jej `opacity: 0` i cokolwiek by tam nie
   wpisać, pozostaje niewidoczne. */
.hero-blok::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Krycie jest dobrane pod ciemną skórę strony: zdjęcie ma być widoczne,
     a gradient tylko dowozi kontrast pod tekst przy dolnej i lewej
     krawędzi. Poprzednie wartości (0.92 przy dole) zjadały cały kadr
     i hero wyglądało jak jednolity granat. */
  background:
    linear-gradient(
      to top,
      rgba(19, 16, 59, 0.88) 0%,
      rgba(20, 17, 59, 0.42) 34%,
      rgba(29, 40, 122, 0.16) 68%,
      rgba(29, 40, 122, 0.30) 100%
    ),
    linear-gradient(
      to right,
      rgba(19, 16, 59, 0.86) 0%,
      rgba(20, 17, 59, 0.62) 34%,
      rgba(20, 17, 59, 0.18) 62%,
      transparent 100%
    );
}

.hero-blok .wp-block-cover__inner-container {
  position: relative;
  z-index: 2;
}

/* Zdjęcie hero zostaje bez `z-index` i bez `will-change`. Dodałem je pod
   parallax, którego tu nie ma, a oba tworzą własny kontekst stackingu
   i wpychają zdjęcie pod gradient, przez co hero pokazywało sam podkład.
   Kolejność warstw wystarczy tu ta domyślna. */
.hero-blok .wp-block-cover__image-background {
  object-fit: cover;
}

/* ── Hero z pierwszym planem ─────────────────────────────────────
   Ten sam kadr lezy w hero dwa razy: raz caly, jako tlo, i drugi raz
   przepuszczony przez maske pierwszego planu - nad naglowkiem. Napis wchodzi
   przez to ZA pojazd, zamiast lezec na zdjeciu. Maske liczy
   `narzedzia/wytnij-przod.py` z mapy glebi, a `inc/ruch.php` dokladna warstwe
   tylko wtedy, gdy maska dla wybranego zdjecia istnieje.

   Obie warstwy musza kadrowac identycznie, inaczej pierwszy plan przesuwa sie
   wzgledem wlasnego tla i zostaje po nim podwojny obrys. Stad `cover`
   i srodek po obu stronach, i stad ten sam plik zdjecia w obu miejscach -
   przegladarka pobiera go raz.                                              */
.hero-blok__przod {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background-image: var(--przod-foto);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  -webkit-mask-image: var(--przod-maska);
          mask-image: var(--przod-maska);
  -webkit-mask-size: cover;
          mask-size: cover;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Kompozycja tego kadru ma os: dwa czola pojazdow zbiegaja sie do jasnego
   srodka. Naglowek dosuniety do lewej krawedzi wchodzilby za pojazd
   poczatkami wierszy, czyli dokladnie tam, gdzie oko zaczyna czytac. Hero
   z pierwszym planem jest wiec jedynym miejscem na stronie, gdzie tresc
   stoi w osi - reszta zostaje przy lewej krawedzi kolumny. */
.hero-blok.ma-przod.wp-block-cover {
  align-items: center;
  /* Wyspy nawigacji nie zaslaniaja tresci soba, wiec pierwszy wiersz
     naglowka musi zaczynac sie ponizej nich. Ich wysokosc jest stala:
     bierze sie z wymaganych 200 px szerokosci znaku. */
  padding-top: max(var(--section-y), min(9.5rem, 17vh));
}

.hero-blok.ma-przod .wp-block-cover__inner-container { text-align: center; }
/* Naglowek sklada sie w najwyzej trzy wiersze (Iwona, 2026-08-31:
   „rozszerzyc tak, zeby zmiescil sie max w 3 wierszach"). Kolumna jest
   szersza niz dawne 16ch, ale nie idzie na cala powloke: warstwa przodu
   (czola pojazdow) lezy NAD trescia i przykrywa poczatki wierszy, ktore
   pod nia wejda - kolumna musi zostac w jasnym srodku kadru. Granica
   w `em`, nie w `ch` i nie w px: skaluje sie ze stopniem, wiec podzial
   na wiersze nie zalezy od szerokosci okna. Zdanie glownej sklada sie
   w te 16 em w trzy wiersze przy kazdym stopniu; `balance` wyrownuje
   ich dlugosci, zeby ostatni nie zostal jednym slowem. Na telefonie
   kolumne przycina kontener i wierszy jest wiecej - trzy wymagalyby
   stopnia ponizej czytelnosci. */
.hero-blok.ma-przod h1 {
  max-width: 16em;
  margin-inline: auto;
  font-size: clamp(1.5rem, 0.3rem + 4vw, 3.6rem);
  text-wrap: balance;
}
.hero-blok.ma-przod .hero-blok__sub { max-width: 44ch; margin-inline: auto; }
.hero-blok.ma-przod .wp-block-buttons { justify-content: center; }
.hero-blok.ma-przod .eyebrow { justify-content: center; }

/* Srodek kadru jest jasny (hala za pojazdami), wiec bialy napis potrzebuje
   tam wlasnego przyciemnienia. Gradient boczny z wersji dosunietej do lewej
   nie ma tu czego przyciemniac i tylko zabiera kadr. */
.hero-blok.ma-przod::before {
  background:
    radial-gradient(
      64% 54% at 50% 46%,
      rgba(7, 6, 26, 0.80) 0%,
      rgba(9, 8, 32, 0.52) 52%,
      rgba(19, 16, 59, 0.12) 100%
    ),
    linear-gradient(
      to top,
      rgba(19, 16, 59, 0.86) 0%,
      rgba(20, 17, 59, 0.34) 38%,
      rgba(29, 40, 122, 0.14) 72%,
      rgba(29, 40, 122, 0.28) 100%
    );
}

/* ── Warstwa ruchu hero ───────────────────────────────────────────────────
   Markup dokłada filtr z `inc/ruch.php`, nie wzorzec, więc redakcja nie ma
   tu czego zepsuć ani czego zgubić przy wstawianiu sekcji od nowa. */

/* Smugi pochylone jak w znaku PTS. Leżą nad gradientem, bo pod nim gasną:
   filtr Deep Blue ma przy dolnej krawędzi 0,92 krycia i zjada wszystko,
   co jest pod nim. Krycie samego canvasu trzyma je w tle, żeby nie
   konkurowały z typografią. */
.hero-blok__smugi {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  opacity: 0.5;
  pointer-events: none;
}

/* Zapas skali musi pokryć przesunięcie parallaxu, inaczej spod zdjęcia
   wyjrzy granatowy podkład bloku. Przy współczynniku 0,07 z filtru
   przesunięcie nie przekracza kilkudziesięciu pikseli, a 18% wysokości
   hero to zapas ponad dwukrotny. */
.hero-blok .wp-block-cover__image-background[data-parallax] {
  z-index: 0;
  transform: scale(1.18);
  will-change: transform;
}

/* ── Głębia ze zdjęcia ────────────────────────────────────────────────────
   Canvas WebGL zamiast płaskiego zdjęcia, gdy obok pliku zdjęcia leży mapa
   głębi (`inc/ruch.php` dokłada wtedy `data-glebia`). Zdjęcie gaśnie
   dopiero po klasie `ma-glebie`, czyli po załadowaniu obu tekstur - żaden
   błąd po drodze nie zostawia hero bez tła. */
.hero-blok__glebia {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  pointer-events: none;
}

.hero-blok.ma-glebie .hero-blok__glebia { opacity: 1; }

.hero-blok.ma-glebie .wp-block-cover__image-background {
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  animation: none;
}

/* Kaskada słów w nagłówku. Wersja B animowała całe wiersze, ale wiersze
   trzeba było wpisać w markup jako `<span class="ln">`. Tu tekst pisze
   redakcja i żaden podział na wiersze nie przetrwa zmiany treści ani
   szerokości okna, więc maska idzie na słowo: `app.js` owija słowa sam,
   a efekt jest ten sam, tylko odporny na dowolny tekst. */
.hero-blok h1 .wd {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;

  /* Nagłówek hero ma interlinię 1.03, czyli pole wiersza jest NIŻSZE niż
     litery, które się w nim mieszczą. Maska bez zapasu obcina wtedy nie
     ogonki, ale połowę wysokości liter - „doświadczenie" traciło dolną
     część każdego znaku. Zapas idzie z obu stron, a ujemne marginesy
     zdejmują go z układu, więc odstępy między wierszami zostają takie,
     jakie zaprojektował arkusz. */
  padding-block: 0.2em;
  margin-block: -0.2em;
}

.hero-blok h1 .wd > span {
  display: inline-block;
  will-change: transform;
}

.js-motion .hero-blok h1 .wd > span {
  transform: translateY(108%);
}

/* Kursywa w nagłówku hero wychodzi pomarańczem, nie pochyleniem. Redakcja
   ma w edytorze zwykły przycisk kursywy i tym samym dostęp do akcentu
   z księgi, bez wpisywania klas. */
.hero-blok h1 em {
  font-style: normal;
  color: var(--orange);
}

/* Wskaźnik przewijania. Przy wąskim ekranie schodzi: hero jest tam niskie,
   a pionowy napis przy krawędzi wchodzi w treść. */
.hero-blok__scroll {
  position: absolute;
  right: calc(var(--gutter) - 0.5rem);
  bottom: clamp(2.5rem, 6vw, 5rem);
  z-index: 2;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  font-size: 0.64rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  /* Kadr hero bywa jasny w tym rogu, a wskaźnik stoi na zdjęciu, nie na
     płycie. Cień jest pewniejszy od mocniejszego koloru: kolor musiałby
     wygrać z każdym zdjęciem, jakie redakcja tam wstawi. */
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 14px rgba(6, 5, 22, 0.65);
  writing-mode: vertical-rl;
}

.hero-blok__scroll i {
  display: block;
  width: 1px;
  height: 54px;
  background: linear-gradient(to bottom, var(--orange), transparent);
  transform-origin: top;
  animation: pts-scroll-hint 2.4s var(--ease-out) infinite;
}

@keyframes pts-scroll-hint {
  0%        { transform: scaleY(0.2); opacity: 0; }
  30%       { opacity: 1; }
  60%, 100% { transform: scaleY(1); opacity: 0; }
}

@media (max-width: 900px) {
  .hero-blok__scroll { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-blok__scroll i { animation: none; }
  .hero-blok .wp-block-cover__image-background[data-parallax] { transform: none; }
}

.hero-blok .eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  font-weight: 700;
}

.hero-blok .eyebrow::before {
  content: "";
  width: 2.4rem;
  height: 2px;
  background: var(--orange);
  flex: none;
}

.hero-blok h1 {
  max-width: 16ch;
  margin-block: var(--s-5) var(--s-4);
}

.hero-blok .hero-blok__sub {
  max-width: 52ch;
}

/* ── Pas z faktami ────────────────────────────────────────────────────────
   UWAGA na nazwy klas. `components.css` z wersji B definiuje wlasne `.facts`
   jako siatke czterokolumnowa i celuje w `.facts > div`. Uzyta na bloku
   przechwytywala kontener kolumn i sciskala je do jednej czwartej szerokosci,
   az tekst lamal sie litera po literze. Wzorce blokowe uzywaja wiec wlasnych
   nazw wszedzie tam, gdzie stary arkusz steruje ukladem, a nie samym wygladem.
   Klasy `.card` i `.ph` zostaja swiadomie: tam kolizja daje dokladnie ten
   efekt, ktorego chcemy, lacznie z filtrem Deep Blue z ksiegi. */

/* Pas idzie przez cala szerokosc okna, tak jak hero nad nim. Sekcja
   urwana weziej niz ta powyzej lamie rytm strony w miejscu, w ktorym
   oko akurat go szuka. */
/* Zasada ukladu: tlo sekcji idzie przez cala szerokosc okna, tresc zostaje
   w kolumnie o szerokosci `--shell`. Kolorowy prostokat urwany na 1280 px
   czyta sie jak wklejony w strone banner, a nie jak jej czesc.

   Wyrownanie robi padding kontenera, a nie `max-width` na dzieciach.
   Przy dzieciach kazde z nich centruje sie osobno i elementy o wlasnych
   marginesach, jak nadtytul z kreska, wychodza z linii reszty sekcji. */
.pas-faktow.alignfull,
.cta.alignfull,
.obszary.alignfull,
.tor-jazda.alignfull,
.wp-block-group.alignfull.section {
  width: calc(100vw - var(--pasek, 0px));
  max-width: calc(100vw - var(--pasek, 0px));
  margin-left: calc(50% - (100vw - var(--pasek, 0px)) / 2);
  margin-right: calc(50% - (100vw - var(--pasek, 0px)) / 2);
  padding-inline: max(var(--gutter), calc((100vw - var(--pasek, 0px) - var(--shell)) / 2));
}

/* Kolumny wewnatrz takiej sekcji maja juz wyrownanie z paddingu rodzica,
   wiec `alignwide` nie moze dokladac wlasnych marginesow ujemnych. */
.pas-faktow.alignfull .wp-block-columns.alignwide,
.wp-block-group.alignfull.section .wp-block-columns.alignwide {
  max-width: 100%;
  margin-inline: 0;
}

/* To samo dotyczy tresci, ktora WordPress zwezilby do kolumny `content`
   i wysrodkowal marginesem: naglowek, akapit, lista i rejestr maja stac
   na jednej linii, bo inaczej kazda sekcja zaczyna sie gdzie indziej. */
.wp-block-group.alignfull.section > :is(h2, h3, p, ul, ol, .rejestr, .tor, .wp-block-buttons) {
  max-width: none;
  margin-inline: 0;
}

/* Kreska przy kolumnie jest pseudoelementem, a nie obramowaniem, bo ma się
   rysować od góry przy wejściu sekcji, w rytmie kaskady kolumn. Obramowania
   nie da się animować skalą, a animowanie samej szerokości szarpie układ.
   Bez `js-motion` - czyli przy prośbie o ograniczenie ruchu - kreska stoi
   od razu pełnej wysokości, więc niczego nie brakuje. */
.pas-faktow .wp-block-column {
  position: relative;
  padding-left: var(--s-4);
}

.pas-faktow .wp-block-column::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--orange);
  transform-origin: top;
  transition: transform 0.8s var(--ease-out) var(--anim-delay, 0s);
}

.js-motion .pas-faktow .wp-block-column::before { transform: scaleY(0); }
.pas-faktow .wp-block-column.is-in::before { transform: scaleY(1); }

.pas-faktow__liczba {
  line-height: var(--lh-tight);
  margin-bottom: var(--s-1);
}

/* Hasła z arkusza PTS to pełne zdania, nie liczby z podpisem, więc kolumna
   niesie jeden akapit; wyróżnikiem zostaje pomarańczowa kreska kolumny. */
.pas-faktow__haslo {
  margin: 0;
  max-width: 26ch;
  text-wrap: balance;
}

/* ── Pas z siecią w tle ───────────────────────────────────────────────────
   Wariant pasa faktów dla sekcji o nadzorze nad siecią pojazdu. Rysunek jest
   ozdobą generowaną losowo, nie schematem: powód i zakaz dopisywania podpisów
   siedzą w nagłówku wzorca `patterns/siec-w-tle.php`. */

.pas-sieci {
  position: relative;
  overflow: hidden;
}

.pas-sieci__plotno {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Treść musi zostać nad płótnem, inaczej impulsy przechodzą po literach. */
.pas-sieci > .wp-block-columns {
  position: relative;
  z-index: 1;
}

/* Scena cyber: landing podstrony Cyberbezpieczeństwo (Oliver, 2026-09-04).
   Wysoka sekcja z samą siecią i przyciskiem na stronę produktu - sieć jest
   tu tłem głównym, nie ozdobą pasa, więc dostaje pełny oddech. */
.cyber-scena {
  display: grid;
  align-content: center;
  min-height: min(62svh, 36rem);
}

.cyber-scena > .wp-block-buttons {
  position: relative;
  z-index: 1;
}

/* ── Karty ────────────────────────────────────────────────────────────────
   Wyrównanie wysokości idzie z siatki, nie z ustawionej ręcznie wysokości.
   Redakcja wpisuje różnej długości opisy i karty muszą to znieść. */

.wp-block-column > .card {
  height: 100%;
  border-radius: var(--r-lg);
  border: var(--hair);
  transition: box-shadow var(--t) var(--ease), transform var(--t) var(--ease);
}

.wp-block-column > .card:hover {
  box-shadow: var(--lift-1);
  transform: translateY(-2px);
}

.wp-block-column > .card h3 {
  margin-bottom: var(--s-3);
}

/* ── Sekcje ───────────────────────────────────────────────────────────── */

.section .eyebrow,
.section--mist .eyebrow {
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: var(--s-3);
}

.cta {
  border-radius: 0;
  text-align: center;
}

/* Stopień i jedna linia nagłówka pasa wezwania są w `wizual.css` - tam
   siedzi reguła nagłówków sekcji, którą trzeba nadpisać po niej. */

.cta .wp-block-buttons {
  justify-content: center;
}

/* ── Przyciski blokowe ────────────────────────────────────────────────────
   Rdzeń WordPressa daje im kolor i zaokrąglenie z `theme.json`, ale nie daje
   żadnej reakcji na kursor. Przycisk, który nie odpowiada na najechanie,
   czyta się jak makieta, a nie jak działający serwis - i to jest pierwsza
   rzecz, którą widać na stronie firmy remontującej tabor. */

/* Stopien etykiety przycisku (1.18rem, waga 700 z `theme.json`) nie jest
   estetyka, tylko warunkiem dostepnosci: biel na pomaranczu z ksiegi daje
   3.17:1, co WCAG AA dopuszcza dopiero powyzej 18.66 px przy wadze 700.
   Zmniejszenie tej wartosci wypuszcza glowne wezwanie do dzialania ponizej
   progu czytelnosci; przyciemnienie pomaranczu zlamaloby palete. */
.wp-block-button__link {
  position: relative;
  transition:
    background-color var(--t) var(--ease),
    border-color var(--t) var(--ease),
    color var(--t) var(--ease),
    box-shadow var(--t) var(--ease),
    transform var(--t) var(--ease);
}

.wp-block-button:not(.is-style-outline) > .wp-block-button__link:hover {
  background-color: var(--orange-deep);
  box-shadow: var(--lift-1);
  transform: translateY(-2px);
}

.wp-block-button > .wp-block-button__link:active {
  transform: translateY(0);
}

/* Przyciski bez strzałek (Iwona, 2026-09-07). Strzałka szła dotąd
   pseudoelementem na każdy przycisk blokowy; teraz kierunek pokazuje
   tylko powrót „← Oferta" w sekcji rodzeństwa, gdzie niesie treść. */

/* Obrys widoczny przy nawigacji klawiaturą. Bez tego przycisk blokowy
   gubi ognisko na ciemnym tle i strona przestaje być obsługiwalna
   bez myszy. */
.wp-block-button__link:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

/* Przycisk obrysowany na ciemnym tle: wariant WordPressa dziedziczy kolor
   tekstu, który na granacie i na zdjęciu hero znika. */
.cta .is-style-outline .wp-block-button__link,
.hero-blok .is-style-outline .wp-block-button__link,
.phead__akcje .is-style-outline .wp-block-button__link {
  color: var(--on-navy);
  border-color: rgba(255, 255, 255, 0.4);
}

/* Nagłówek składa przyciski w szablonie, nie w treści, a rdzeń WordPressa
   drukuje CSS wariantu „outline" tylko wtedy, gdy blok z tym stylem stoi
   w treści strony - markup z szablonu zostawał pełnym pomarańczem.
   Obrys trzeba więc dać wprost. */
.phead__akcje .is-style-outline .wp-block-button__link {
  background: transparent;
  border: 2px solid rgba(255, 255, 255, 0.4);
}

.cta .is-style-outline .wp-block-button__link:hover,
.hero-blok .is-style-outline .wp-block-button__link:hover,
.phead__akcje .is-style-outline .wp-block-button__link:hover {
  border-color: var(--orange);
  color: var(--orange);
}

/* ── Zdjęcia w blokach ────────────────────────────────────────────────── */

.wp-block-image.ph img,
.wp-block-gallery.ph-siatka img {
  border-radius: var(--r-lg);
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.wp-block-video.film video {
  border-radius: var(--r-lg);
  width: 100%;
}

/* ── Zawężenie treści wpisywanej swobodnie ────────────────────────────────
   Akapit rozciągnięty na 1280 px jest nieczytelny. Bloki treści trzymają
   szerokość tekstową, a pełną szerokość dostają tylko te, które o nią proszą. */

.wp-block-post-content > p,
.wp-block-post-content > h2,
.wp-block-post-content > h3,
.wp-block-post-content > ul,
.wp-block-post-content > ol {
  max-width: var(--shell-narrow);
  margin-inline: auto;
}

/* ── Lista realizacji ─────────────────────────────────────────────────────
   Siatka dopasowuje liczbę kolumn do szerokości, bez progów wpisanych
   ręcznie. Realizacji przybywa i nikt nie będzie poprawiał breakpointów
   przy trzynastej. */

.lista-realizacji {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: var(--s-5);
  margin-top: var(--s-6);
}

.karta-realizacji .ph {
  display: block;
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  aspect-ratio: 3 / 2;
}

.karta-realizacji img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease-out);
}

.karta-realizacji .ph:hover img {
  transform: scale(1.04);
}

/* Podpis leży na zdjęciu, więc potrzebuje własnego podkładu. Zdjęcia hali
   bywają jasne u dołu i sam biały tekst na nich ginie. */
.karta-realizacji__tytul {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-6) var(--s-4) var(--s-4);
  color: var(--on-navy);
  font-weight: 700;
  background: linear-gradient(to top, rgba(20, 17, 59, 0.88), transparent);
}

.prev-next {
  /* Trzy stale kolumny: Poprzednia | powrot na strone zbiorcza | Nastepna
     (Iwona, 2026-09-08). Siatka zamiast flexa, zeby brak ktorejs strzalki
     nie przesuwal pozostalych - „Nastepna" stala po lewej, gdy wpis byl
     ostatni w kolejce. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-7);
  border-top: var(--hair);
}

.prev-next__slot--dalej { text-align: right; }

.prev-next__powrot {
  font-weight: 700;
  color: var(--on-navy-2);
}

.prev-next__powrot:hover,
.prev-next__powrot:focus-visible { color: var(--orange); }

/* ── Formularz kontaktowy ─────────────────────────────────────────────── */

/* Gniazdo eRecruitera zamiast formularza: tekst i przycisk mają stać
   w tej samej kolumnie co nagłówek sekcji, a nie w środku układu
   „constrained" (WordPress centruje marginesem auto z !important
   każdy blok węższy od kolumny - stąd wcięcie, Oliver 2026-09-07). */
article .section .form-cv--erecruiter {
  max-width: 60ch;
  margin-inline: 0 !important;
}

.form-kontakt .field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
}

.form-kontakt label {
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--ink-2);
}

.form-kontakt input[type="text"],
.form-kontakt input[type="email"],
.form-kontakt input[type="tel"],
.form-kontakt textarea {
  font: inherit;
  color: var(--ink);
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--white);
  transition: border-color var(--t-fast) var(--ease);
}

.form-kontakt input:focus-visible,
.form-kontakt textarea:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 1px;
  border-color: var(--orange);
}

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

.field--zgoda label {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink-2);
  cursor: pointer;
}

.field--zgoda input {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.2rem;
  flex: none;
  accent-color: var(--orange);
}

.form-note {
  font-size: var(--fs-micro);
  color: var(--ink-3);
  max-width: 60ch;
  margin-bottom: var(--s-5);

  /* `components.css` robi z tej klasy pojemnik flex dla wersji B. Tutaj
     w środku jest zdanie z odnośnikiem, a flex ustawiał tekst i odnośnik
     w dwóch ciasnych kolumnach. */
  display: block;
}

/* Pole pułapka na roboty. `display: none` bywa przez nie wykrywane, więc
   pole zostaje w układzie, tylko poza widocznym obszarem. */
.pole-pulapka {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-komunikat {
  padding: var(--s-4);
  border-radius: var(--r);
  border: 1px solid;
  margin-bottom: var(--s-5);
}

.form-komunikat--ok {
  background: var(--navy-wash);
  border-color: var(--navy);
}

.form-komunikat--blad {
  background: var(--orange-wash);
  border-color: var(--orange-ink);
  color: var(--orange-ink);
}

/* ── Opowieść na przewijaniu ──────────────────────────────────────────────
   Zdjęcie przypięte po lewej, kroki przewijają się po prawej; aktywny krok
   wybiera kadr. Cała mechanika siedzi w klasach `js-motion` i `jest`,
   więc bez JavaScriptu (i przy prośbie o ograniczenie ruchu) sekcja jest
   zwykłą kolumną zdjęć i tekstu - nic nie znika.                          */

.opowiesc__uklad.wp-block-columns {
  display: grid !important;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 5rem);
  align-items: start;
  margin-top: clamp(1.5rem, 3vw, 3rem);
}

.opowiesc__media { position: relative; }

.opowiesc__kadr { margin: 0 0 var(--s-4); border-radius: var(--r-lg); overflow: hidden; }
.opowiesc__kadr img { width: 100%; height: 100%; object-fit: cover; }

/* Z warstwą ruchu: kolumna zdjęć przykleja się pod paskiem nawigacji,
   kadry leżą na sobie i przechodzą jeden w drugi. */
.js-motion .opowiesc__media {
  position: sticky;
  top: clamp(6rem, 9rem, 12vh);
  height: min(68vh, 38rem);
}

.js-motion .opowiesc__kadr {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  transform: scale(1.045);
  transition: opacity 0.7s var(--ease), transform 1.4s var(--ease-out);
}

.js-motion .opowiesc__kadr.jest {
  opacity: 1;
  transform: none;
}

.opowiesc__krok {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: var(--s-5);
  padding-left: clamp(1.2rem, 2vw, 2rem);
  border-left: 2px solid var(--line);
}

/* Wysokość kroków nadaje rytm przewijaniu tylko wtedy, gdy działa warstwa
   ruchu. Bez niej (wyłączony JavaScript, prośba o ograniczenie ruchu)
   rozciągnięte kroki zostawiałyby długie puste pasy między akapitami. */
/* 40vh zamiast 52: krok dalej trzyma rytm wymiany kadrow, ale opowiesc
   przestaje kosztowac dwa pelne ekrany przewijania (Iwona, 2026-08-31). */
.js-motion .opowiesc__krok { min-height: 40vh; }

.opowiesc__krok::before {
  content: "";
  position: absolute;
  left: -2px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--orange);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.7s var(--ease-out);
}

.js-motion .opowiesc__krok {
  opacity: 0.32;
  transition: opacity 0.5s var(--ease);
}

.js-motion .opowiesc__krok.jest { opacity: 1; }
.opowiesc__krok.jest::before { transform: scaleY(1); }

.opowiesc__krok h3 { margin-bottom: var(--s-3); }

@media (max-width: 880px) {
  .opowiesc__uklad.wp-block-columns { grid-template-columns: minmax(0, 1fr); }

  /* Na telefonie kadr zostaje przypięty u góry, a kroki przechodzą pod
     nim - obraz zmienia się w rytmie czytania, tak samo jak na szerokim
     ekranie, tylko nad tekstem zamiast obok. */
  .js-motion .opowiesc__media {
    top: 5.2rem;
    height: 38vh;
    z-index: 2;
  }

  .js-motion .opowiesc__krok { min-height: 36vh; }
}


/* ═══ REJESTR ════════════════════════════════════════════════════════════
   Wiersze zamiast rzędu jednakowych kart. Karta o stałej wysokości zrównuje
   wszystko ze wszystkim: usługa opisana trzema zdaniami wygląda tak samo
   ważnie jak ta opisana jednym, a czytelnik dostaje spis treści zamiast
   oferty. Wiersz pozwala nazwie być dużą, opisowi tak długiemu, jak wymaga
   rzecz, a oku zjechać po lewej krawędzi.                                  */

.rejestr { --rejestr-linia: var(--line); }

.rejestr .rejestr__poz {
  display: grid;
  /* Kolumna w `rem`, nie w `ch`: `ch` liczy sie od kroju wiersza, wiec
     nazwa i opis dawaly inna szerokosc kolumny w kazdym wierszu i lewa
     krawedz opisow falowala. */
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  justify-items: start;
  gap: var(--s-4) var(--s-7);
  align-items: baseline;
  padding: var(--s-5) 0;
  border-top: 1px solid var(--rejestr-linia);
  position: relative;
}

.rejestr .rejestr__poz:last-child { border-bottom: 1px solid var(--rejestr-linia); }

/* Podbicie wjeżdża od lewej wzdłuż linii wiersza: gest z toru, nie z karty.
   Bez zmiany wysokości, więc nic pod spodem nie drga.                      */
.rejestr .rejestr__poz::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t) var(--ease-out);
}

.rejestr .rejestr__poz:hover::before,
.rejestr .rejestr__poz:focus-within::before { transform: scaleX(1); }

/* Wiersz z odnośnikiem ma już własny wskaźnik - kreskę pod nazwą. Podbicie
   górnej linii dawało wtedy dwie pomarańczowe kreski naraz i przy dwóch
   sąsiednich wierszach robił się z tego płot (Iwona, 2026-09-08:
   „za dużo tych linii pomarańczowych"). */
.rejestr .rejestr__poz:has(.rejestr__nazwa a)::before { content: none; }

.rejestr .rejestr__nazwa {
  margin: 0;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
  text-wrap: balance;
}

.rejestr .rejestr__nazwa a {
  color: inherit;
  text-decoration: none;
  /* inline-block: tlo z kreska rysuje sie pod calym blokiem nazwy,
     wiec dwu- i czterowierszowe nazwy certyfikatow dostaja jedno
     podkreslenie na dole zamiast kreski pod kazda linia
     (Iwona, 2026-09-07). */
  display: inline-block;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size var(--t) var(--ease-out);
}

.rejestr .rejestr__nazwa a:hover,
.rejestr .rejestr__nazwa a:focus-visible { background-size: 100% 2px; }

/* Akcent redakcji w nazwie pozycji: kursywa wychodzi pomarańczem, jak
   w nagłówkach - Iwona (2026-09-06) chce nim wyróżnić „Ludzie",
   „Doświadczenie" i „Elastyczność" w wartościach firmy. */
.rejestr .rejestr__nazwa em {
  font-style: normal;
  color: var(--orange);
}

/* Cała pozycja z odnośnikiem jest celem kliknięcia (Iwona, 2026-09-06:
   certyfikat pobiera się kliknięciem w całe okienko) - ten sam gest co
   w indeksie obszarów. */
.rejestr .rejestr__poz:has(.rejestr__nazwa a) .rejestr__nazwa a::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* Strzałka mówi, że wiersz gdzieś prowadzi. Rysuje ją znak z kroju pisma
   dopisany po nazwie, więc czytnik ekranu czyta samą nazwę odnośnika.      */
.rejestr .rejestr__poz:has(.rejestr__nazwa a) { padding-right: 3rem; }

.rejestr .rejestr__poz:has(.rejestr__nazwa a)::after {
  content: "";
  position: absolute;
  top: calc(var(--s-5) + 0.55em);
  right: 0.6rem;
  width: 0.6rem;
  height: 0.6rem;
  border-top: 2px solid var(--orange);
  border-right: 2px solid var(--orange);
  transform: rotate(45deg);
  transition: transform var(--t) var(--ease-out);
}

.rejestr .rejestr__poz:hover::after,
.rejestr .rejestr__poz:focus-within::after { transform: rotate(45deg) translate(0.2rem, -0.2rem); }

.rejestr .rejestr__opis {
  margin: 0;
  max-width: 62ch;
  color: var(--ink-2);
}

/* Przycisk w pozycji (usługi cyber odsyłają do railguardsentinel.eu):
   staje pod opisem, w jego kolumnie - nie pod nazwą. */
.rejestr .rejestr__poz > .wp-block-buttons {
  grid-column: 2;
  margin-top: var(--s-2);
}

@media (max-width: 780px) {
  .rejestr .rejestr__poz > .wp-block-buttons { grid-column: 1; }
}

.section--navy .rejestr { --rejestr-linia: rgba(255, 255, 255, 0.16); }
.section--navy .rejestr .rejestr__opis { color: var(--on-navy-2); }

@media (max-width: 780px) {
  .rejestr .rejestr__poz {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-3);
    padding: var(--s-4) 0;
  }
}

/* ═══ OBSZARY: indeks ofert na wejsciu Oferty ════════════════════════════
   Piec obszarow jako pelnoekranowy spis zaraz pod naglowkiem strony
   (Iwona, 2026-09-04): pozycje odslaniaja sie w rytmie przewijania
   (warstwa wejsc w animacje.css lapie `.obszary__poz`), najechanie albo
   fokus wywoluje kadr obszaru w tle calej sekcji, klikniecie przenosi na
   podstrone. Bez `:has()` i bez ruchu zostaje czytelny spis odnosnikow.  */

.obszary {
  position: relative;
  overflow: hidden;
  display: grid;
  align-content: center;
  min-height: min(92svh, 58rem);
  padding-block: var(--s-7);
}

.obszary__tla { position: absolute; inset: 0; }

.obszary__tlo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.05);
  transition: opacity 0.5s var(--ease), transform 5s var(--ease-out);
}

/* Woal nad kadrem: tekst ma wygrywac z kazdym zdjeciem. */
.obszary__tla::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Lzejszy woal (Iwona, 2026-09-07: „zeby bylo widac zdjecie"): ciemniej
     zostaje tylko lewa polowa, pod nazwami obszarow, prawa odslania kadr.
     Czytelnosc nazw asekuruje cien tekstu nizej. */
  background: linear-gradient(90deg, rgba(19, 16, 59, 0.86), rgba(19, 16, 59, 0.55) 55%, rgba(19, 16, 59, 0.34));
}

.obszary__nazwa a,
.obszary__opis {
  text-shadow: 0 1px 14px rgba(6, 5, 22, 0.55);
}

.obszary:has(.obszary__poz:nth-child(1):is(:hover, :focus-within)) .obszary__tlo:nth-child(1),
.obszary:has(.obszary__poz:nth-child(2):is(:hover, :focus-within)) .obszary__tlo:nth-child(2),
.obszary:has(.obszary__poz:nth-child(3):is(:hover, :focus-within)) .obszary__tlo:nth-child(3),
.obszary:has(.obszary__poz:nth-child(4):is(:hover, :focus-within)) .obszary__tlo:nth-child(4),
.obszary:has(.obszary__poz:nth-child(5):is(:hover, :focus-within)) .obszary__tlo:nth-child(5) {
  opacity: 1;
  transform: scale(1);
}

/* Kadr spoczynkowy (Oliver, 2026-09-04: sekcja stała na gołym granacie).
   Zdjęcie hali czeka pod woalem, dopóki czytelnik nie wskaże obszaru;
   wskazanie dowolnej pozycji wygasza kadr spoczynkowy na rzecz kadru
   obszaru. Idzie ostatnim dzieckiem `obszary__tla`, żeby nie przesuwać
   numeracji `nth-child` dopasowującej kadry do pozycji. */
.obszary__tlo--staly { opacity: 1; transform: scale(1); }

.obszary:has(.obszary__poz:is(:hover, :focus-within)) .obszary__tlo--staly { opacity: 0; }

/* Nagłówek nad spisem (O PTS): indeks obszarów na Ofercie nagłówka nie ma,
   spis „Zobacz też" musi go mieć, bo jest sekcją w środku strony. Nagłówek
   stoi w zestawie OBOK listy, nie w niej - pozycje listy muszą zostać jej
   jedynymi dziećmi, bo dopasowanie kadru do pozycji liczy `nth-child`. */
/* Kontener `.obszary` sam wyrównuje treść do krawędzi sekcji (formuła
   alignfull wyżej), więc wewnętrzny `.shell` nie może dokładać drugiego
   wcięcia - nazwy stałyby o gutter na prawo od tytułu strony
   (Iwona, 2026-09-08: jedna lewa krawędź). */
.obszary .shell { padding-inline: 0; }

.obszary__zestaw { position: relative; }
.obszary__zestaw > h2 { margin-bottom: var(--s-6); }

/* Wariant krótszy dla spisów mniejszych niż pięć ofert (podstrony O PTS):
   pełne 92svh przy czterech pozycjach zostawiało pustkę pod spisem. */
.obszary--krotki { min-height: min(72svh, 46rem); }

/* Wariant pełnoekranowy (/oferta): kadry indeksu wypełniają cały pierwszy
   widok, a tytuł strony leży na zdjęciu - nagłówek zwarty wychodzi
   z przepływu w `components.css`. Górny padding robi miejsce na tytuł
   (ścieżka + h1 pod wyspami nawigacji), świadomie z zapasem: nachodzenie
   tytułu na pierwszą pozycję byłoby gorsze niż oddech. */
/* Podwójna klasa świadomie: reguła telefonu niżej zeruje `min-height`
   wszystkim indeksom, a pełny ekran ma obowiązywać także tam. */
.obszary.obszary--ekran {
  min-height: 100svh;
  padding-top: clamp(21.5rem, 16rem + 11svh, 26rem);
  padding-bottom: clamp(2.5rem, 6svh, 4rem);
}

.obszary__lista {
  position: relative;
  width: 100%;
  counter-reset: obszar;
}

.obszary__poz {
  counter-increment: obszar;
  position: relative;
  display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr);
  grid-template-areas: "nr nazwa" "nr opis";
  align-items: baseline;
  column-gap: var(--s-4);
  padding: clamp(1.1rem, 2.2vh, 1.8rem) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}
.obszary__poz:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.16); }

/* Cały wiersz jest celem kliknięcia, nie sama nazwa: odnośnik nazwy
   rozciąga się na pozycję niewidoczną warstwą. Strona to landing-spis,
   więc pozycja ma działać jak kafel. */
.obszary__nazwa a::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* Numer porzadkowy liczy CSS, wiec nie wchodzi do drzewa dostepnosci. */
.obszary__poz::before {
  content: counter(obszar, decimal-leading-zero);
  grid-area: nr;
  align-self: start;
  color: var(--orange);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.14em;
}

/* Stopień niższy (Iwona, 2026-09-06): najdłuższa nazwa obszaru ma mieścić
   się w jednym wierszu - „Naprawa, modernizacja i utrzymanie taboru
   szynowego" przy 1.9rem wchodzi w kolumnę powłoki bez łamania.
   Selektor z dwiema klasami, bo nazwy bywają h2 i regułę biłby stopień
   nagłówków sekcji z `wizual.css` (`.section h2`). */
.obszary .obszary__nazwa {
  grid-area: nazwa;
  margin: 0;
  font-size: clamp(1.25rem, 0.85rem + 1.2vw, 1.9rem);
  font-weight: 900;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
  text-wrap: balance;
}

.obszary__nazwa a {
  color: #fff;
  text-decoration: none;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 3px;
  transition: background-size var(--t) var(--ease-out), color var(--t-fast) var(--ease);
}

.obszary__poz:is(:hover, :focus-within) .obszary__nazwa a { background-size: 100% 3px; }

.obszary__opis {
  grid-area: opis;
  margin: 0.35rem 0 0;
  max-width: 62ch;
  color: var(--on-navy-2);
  opacity: 0.85;
  transition: opacity var(--t-fast) var(--ease);
}

.obszary__poz:is(:hover, :focus-within) .obszary__opis { opacity: 1; }

@media (max-width: 780px) {
  .obszary { min-height: 0; }
  .obszary__poz {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "nr" "nazwa" "opis";
  }
  .obszary__poz::before { margin-bottom: 0.2rem; }
}

/* ═══ TOR ════════════════════════════════════════════════════════════════
   Kolejne daty ułożone wzdłuż linii. Rysunek jest z toru kolejowego, a nie
   z ogólnej osi czasu: podkład, na nim przystanki. Struktura treści prosi
   o ten układ dwa razy - przy historii spółki i przy krokach jakości.      */

.tor {
  --tor-linia: var(--line);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-6) var(--s-5);
}

.tor .tor__przystanek {
  position: relative;
  padding-top: var(--s-5);
  border-top: 2px solid var(--tor-linia);
}

/* Węzeł siedzi na linii, nie pod nią: przecięcie toru z przystankiem. */
.tor .tor__przystanek::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 0;
  width: 10px;
  height: 10px;
  background: var(--orange);
  border-radius: 50%;
}

.tor .tor__rok {
  margin: 0 0 var(--s-2);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: var(--orange-ink);
}

.tor .tor__nazwa {
  margin: 0 0 var(--s-3);
  font-size: var(--fs-h4);
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
}

.tor .tor__przystanek p:last-child {
  margin-bottom: 0;
  color: var(--ink-2);
  max-width: 40ch;
}

.section--navy .tor,
.pas-faktow .tor { --tor-linia: rgba(255, 255, 255, 0.2); }
.section--navy .tor .tor__rok { color: var(--orange); }
.section--navy .tor .tor__przystanek p:last-child { color: var(--on-navy-2); }

/* ── Tor przypięty (historia firmy) ────────────────────────────────────
   Wariant „tor-jazda": sekcja przypina się na ekran, przystanki stoją
   w jednej linii na ciągłej szynie, a taśma przejeżdża pod nieruchomym
   pociągiem w rytmie przewijania (Oliver, 2026-09-04: „wyrównać w jednej
   linii" + animacja). Mechanika jak w pasie slajdów: przypięcie i jazdę
   dokłada `interakcje.css` tam, gdzie przeglądarka zna oś przewijania.
   Stanem spoczynku - i zapasem dla telefonu, Firefoksa i ograniczonego
   ruchu - jest dotychczasowa siatka `tor`; pociąg i pasek postępu
   istnieją tylko w trybie przypiętym. Pion sekcji siedzi tu, a nie
   w stylu wpisanym w treść: tryb przypięty musi go umieć wyzerować. */
.tor-jazda { padding-block: var(--wp--preset--spacing--70); }

.tor-jazda__pociag,
.tor-jazda__postep,
.tor-jazda__kroki { display: none; }

/* ═══ ZAKRES PRAC ════════════════════════════════════════════════════════
   Dziewięć pozycji jedną listą czytało się jak spis treści - to jest uwaga
   PTS do obecnej strony. Grupy nie dokładają treści, tylko pozwalają
   czytelnikowi znaleźć swoją sprawę bez czytania całości.                  */

.zakres .zakres__grupa {
  margin: 0 0 var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 2px solid var(--orange);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.zakres .zakres__lista {
  margin: 0;
  padding: 0;
  list-style: none;
}

.zakres .zakres__lista li {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
}

.zakres .zakres__lista li::marker { content: none; }

.section--navy .zakres .zakres__lista li {
  border-bottom-color: rgba(255, 255, 255, 0.14);
  color: var(--on-navy-2);
}

/* ═══ RAMY PRAWNE ════════════════════════════════════════════════════════
   Cztery dokumenty, które wyznaczają zakres obowiązku, na stronie głównej.
   Nazwy same w sobie są treścią: dyrektor techniczny przewoźnika rozpoznaje
   je od razu i to one mówią, że nie chodzi o marketing.                    */

.ramy {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s-3);
}

.ramy li {
  position: relative;
  padding: var(--s-3) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  font-size: var(--fs-lead);
  font-weight: 900;
  letter-spacing: var(--ls-head);
  color: #fff;
}

.ramy li::marker { content: none; }

/* Kreska pod nazwa dojezdza pomaranczem w rytmie impulsow w tle: dokument
   jest wymagany, wiec ma sie dopisywac do listy, a nie stac na niej. */
.ramy li::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 1px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-slow) var(--ease-out);
}

.pas-sieci:hover .ramy li::after,
.ramy li:hover::after { transform: scaleX(1); }

.ramy li:nth-child(2)::after { transition-delay: 0.08s; }
.ramy li:nth-child(3)::after { transition-delay: 0.16s; }
.ramy li:nth-child(4)::after { transition-delay: 0.24s; }

/* ═══ LISTY W TREŚCI ═════════════════════════════════════════════════════
   `base.css` zdejmuje punktory ze wszystkich list, bo używa ich też do
   nawigacji i pasków. Lista w treści bez żadnego znacznika czyta się jak
   zbitka zdań, więc dostaje własny: kreskę w kolorze akcentu, ten sam gest
   co w rejestrze i w torze.                                               */

article .wp-block-list:not(.ramy):not(.zakres__lista) {
  display: grid;
  gap: var(--s-2);
  max-width: 72ch;

  /* Uklad „constrained" WordPressa centruje marginesem `auto` z `!important`
     kazdy blok wezszy od kolumny. Bez tego lista odjezdza na srodek sekcji,
     a naglowek nad nia zostaje przy lewej krawedzi. */
  margin-inline: 0 !important;
}

article .wp-block-list:not(.ramy):not(.zakres__lista) > li {
  position: relative;
  padding-left: 1.3rem;
}

/* Kreska punktora krótka (Iwona, 2026-09-06): długi myślnik przy każdej
   pozycji zakresu usług czytał się jak drugi separator. */
article .wp-block-list:not(.ramy):not(.zakres__lista) > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 0.55rem;
  height: 2px;
  background: var(--orange);
}

/* Lista numerowana (regulamin) zostaje numerowana: numer punktu jest tam
   treścią, bo kontrahent powołuje się na niego w korespondencji.
   Selektor musi powtórzyć klamrę `:not()` reguły wyżej - inaczej ta wygrywa
   specyficznością i punkty regulaminu dostają kreskę zamiast numeru
   (widoczne od skrócenia kreski punktora 2026-09-06). */
article ol.wp-block-list {
  counter-reset: punkt;
}

/* Wcięcie liczone pod dwie cyfry: regulamin ma 22 punkty, a przy wcięciu
   spod kreski numer 10 nachodził na pierwsze słowo. */
article ol.wp-block-list:not(.ramy):not(.zakres__lista) > li {
  padding-left: 2.1rem;
}

article ol.wp-block-list:not(.ramy):not(.zakres__lista) > li::before {
  counter-increment: punkt;
  content: counter(punkt) ".";
  width: auto;
  height: auto;
  top: 0;
  background: none;
  color: var(--orange-ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ═══ RYTM PIONOWY ═══════════════════════════════════════════════════════
   Nad nagłówkiem więcej miejsca niż pod nim: to odstęp mówi, że zaczyna się
   nowa rzecz. Drugi nagłówek w jednej sekcji („Wymagania", zaraz po nim
   „Dodatkowym atutem będą") sklejał się z listą nad sobą.               */

article .section h2 + *,
article .section--mist h2 + * { margin-top: var(--s-4); }

article .section *:not(h2) + h2,
article .section--mist *:not(h2) + h2 { margin-top: var(--s-9); }

/* ═══ PAS SLAJDÓW ════════════════════════════════════════════════════════
   Pozycje sekcji na taśmie. Stan spoczynku - i zarazem zapas dla telefonu,
   Firefoksa i ograniczonego ruchu - to zwykła kolumna: nic tu nie wymaga
   JavaScriptu ani osi przewijania. Jazdę w poziomie z przypięciem sekcji
   dokłada `interakcje.css` tam, gdzie przeglądarka zna oś przewijania.
   Numer slajdu liczy arkusz, więc nie wchodzi do drzewa dostępności.      */

.pas-slajdow__okno { position: relative; }

.pas-slajdow__tasma {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  margin-top: var(--s-7);
  counter-reset: slajd;
}

.pas-slajdow__slajd {
  position: relative;
  counter-increment: slajd;
  padding: var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--navy-wash);
}

/* Numer porządkowy konturem - ten sam gest co w rejestrze. */
.pas-slajdow__slajd::before {
  content: counter(slajd, decimal-leading-zero);
  display: block;
  margin-bottom: var(--s-5);
  font-size: clamp(2.2rem, 1.6rem + 2vw, 3.4rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.02em;
  color: transparent;
  -webkit-text-stroke: 1px var(--orange);
}

.pas-slajdow__tytul {
  margin: 0 0 var(--s-4);
  font-size: var(--fs-h3, clamp(1.3rem, 1.12rem + 0.85vw, 1.86rem));
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
}

.pas-slajdow__tytul a {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size var(--t) var(--ease);
}

.pas-slajdow__tytul a:hover,
.pas-slajdow__tytul a:focus-visible { background-size: 100% 2px; }

/* Slajd z odnosnikiem w tytule jest klikalny w calosci: odnosnik
   rozciaga sie na karte, a strzalka w rogu zapowiada przejscie do
   podstrony obszaru (Iwona, 2026-08-31). Pusty tekst alternatywny
   zdejmuje strzalke z drzewa dostepnosci - nazwa odnosnika to tytul.
   Bez `:has` (starsze przegladarki) klikalny zostaje sam tytul. */
.pas-slajdow__tytul a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.pas-slajdow__slajd:has(.pas-slajdow__tytul a:hover),
.pas-slajdow__slajd:has(.pas-slajdow__tytul a:focus-visible) {
  border-color: var(--orange);
}

.pas-slajdow__opis { margin: 0; color: var(--ink-2); }

/* Pasek postępu jazdy istnieje tylko w trybie przypiętym. */
.pas-slajdow__postep { display: none; }

/* ═══ KADR NA CAŁY EKRAN ═════════════════════════════════════════════════
   Pełnoekranowy przerywnik ze zdjęciem i krótkim podpisem - oddech między
   sekcjami tekstu. Zdjęcie dryfuje wolniej niż strona (`interakcje.css`);
   bez osi przewijania zostaje nieruchomy kadr i nic nie ginie.            */

.wp-block-group.alignfull.kadr-pelny {
  width: calc(100vw - var(--pasek, 0px));
  max-width: calc(100vw - var(--pasek, 0px));
  margin-left: calc(50% - (100vw - var(--pasek, 0px)) / 2);
  margin-right: calc(50% - (100vw - var(--pasek, 0px)) / 2);
}

.kadr-pelny {
  position: relative;
  /* Kadr zszedl z niemal calego ekranu: krotsze strony (Iwona, 2026-08-31). */
  height: min(64svh, 42rem);
  overflow: clip;
  background: var(--navy-ink);
}

.kadr-pelny .kadr-pelny__foto {
  position: absolute;
  inset: 0;
  margin: 0;
}

.kadr-pelny .kadr-pelny__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Podkład pod podpis: zdjęcie bywa jasne przy dolnej krawędzi. */
.kadr-pelny::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(19, 16, 59, 0.72), transparent 38%);
}

.kadr-pelny__podpis {
  position: absolute;
  z-index: 1;
  left: max(var(--gutter), calc((100% - var(--shell)) / 2));
  bottom: clamp(1.6rem, 4svh, 3rem);
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.85);
}

.kadr-pelny__podpis::before {
  content: "";
  flex: none;
  width: 2.4rem;
  height: 2px;
  background: var(--orange);
}


/* ── Ikony grup taboru ────────────────────────────────────────────
   Rząd czterech piktogramów na podstronach obszarów oferty - arkusz
   struktury (2026-09-03) prosi o nie przy naprawie taboru i naprawie
   podzespołów. Kafelek granatowy pod białą sylwetką powtarza zasadę
   pociągu z paska: znak zawsze stoi na swoim tle, więc rząd wygląda
   tak samo na ciemnej i jasnej skórze. */
.tabor-ikony {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin-top: var(--wp--preset--spacing--50);
  /* Oddech między rzędem ikon a nagłówkiem „Zakres usług" pod nim
     (Oliver, 2026-09-04): rząd kafelków i tytuł sklejały się w jedno. */
  margin-bottom: var(--wp--preset--spacing--60);
}

.tabor-ikony figure {
  margin: 0;
  padding: 1.4rem 1.2rem 1.1rem;
  background: var(--navy-ink);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  text-align: center;
}

.tabor-ikony img {
  display: block;
  width: min(100%, 10.5rem);
  height: auto;
  margin-inline: auto;
}

/* Podpisy wrocily, ale subtelne (Iwona, 2026-09-07): maly stopien,
   zwykla waga i przygaszona biel zamiast pelnej - ikona ma prowadzic,
   podpis tylko nazywa. */
.tabor-ikony figcaption {
  margin-top: 0.7rem;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.3;
  color: var(--on-navy-3);
}

@media (max-width: 880px) {
  .tabor-ikony { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Rodzeństwo podstrony ─────────────────────────────────────────
   Sekcja „Pozostałe obszary" doklejana szablonem pod treścią każdej
   strony potomnej: czytelnik przechodzi między obszarami bez wracania
   na Ofertę i szukania indeksu od nowa. Pozycje są kafelkami ze
   zdjęciem (Oliver, 2026-09-04) - ten sam język co indeks obszarów na
   /oferta: kadr pod granatowym woalem, biała nazwa, strzałka. */
.kafle {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--s-4);
}

.kafle__poz {
  position: relative;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  min-height: 13rem;
  padding: var(--s-4);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r);
  /* Granat zamiast dziury, gdy strona nie ma zdjęcia wyróżniającego. */
  background: linear-gradient(160deg, var(--navy-soft), var(--navy-ink) 70%);
  text-decoration: none;
  isolation: isolate;
}

.kafle__tlo {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.03);
  transition: transform var(--t-slow) var(--ease-out);
}

/* Woal nad kadrem: nazwa ma wygrywać z każdym zdjęciem. */
.kafle__poz::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(19, 16, 59, 0.9), rgba(19, 16, 59, 0.35) 55%, rgba(19, 16, 59, 0.2));
  transition: background-color var(--t) var(--ease);
}

.kafle__nazwa {
  max-width: calc(100% - 2.4rem);
  color: #fff;
  font-size: clamp(1.15rem, 1rem + 0.6vw, 1.5rem);
  font-weight: 800;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
  text-wrap: balance;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 3px;
  transition: background-size var(--t) var(--ease-out);
}

/* Reakcja na kursor tylko na kaflu-odnośniku: kafel pokazowy (np.
   „Przykłady realizacji" na dostawie pojazdów) jest divem i ma stać
   nieruchomo - ruch sugerowałby, że da się w niego kliknąć (Iwona,
   2026-09-06). */
a.kafle__poz:is(:hover, :focus-visible) .kafle__tlo { transform: scale(1.08); }
a.kafle__poz:is(:hover, :focus-visible) .kafle__nazwa { background-size: 100% 3px; }

div.kafle__poz .kafle__tlo { transform: none; }

/* ── Pojazdy z oknem parametrów ───────────────────────────────────
   Kafle pojazdów na dostawie pojazdów szynowych (Oliver, 2026-09-07):
   najechanie na kafel otwiera pod rzędem okno z parametrami pojazdu,
   zejście kursorem poza kafel i okno zamyka je. Dotyk i klawiatura
   przełączają kliknięciem (klasa `otwarte` z `app.js`). Bez
   JavaScriptu okna stoją w treści jak zwykłe sekcje - nic nie ginie. */
.pojazdy {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--s-4);
}

/* Sekcje mają własne konteksty warstw (isolation przy poświacie), więc
   bez podbicia okno wjeżdżałoby POD następną sekcję - i pod jej kafle,
   które przechwytywałyby wtedy kursor. */
article .section--pojazdy {
  position: relative;
  z-index: 4;
}

.pojazdy__kafel {
  position: relative;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  width: 100%;
  min-height: 13rem;
  padding: var(--s-4);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r);
  background: linear-gradient(160deg, var(--navy-soft), var(--navy-ink) 70%);
  font: inherit;
  text-align: left;
  cursor: pointer;
  isolation: isolate;
}

.pojazdy__tlo {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.03);
  transition: transform var(--t-slow) var(--ease-out);
}

/* Kafel bez zdjęcia (wagony piętrowe - PTS nie dostarczył kadru):
   piktogram w języku marki na granatowym gradiencie. */
.pojazdy__piktogram {
  position: absolute;
  top: calc(50% - 1rem);
  left: 50%;
  z-index: -2;
  width: min(60%, 10rem);
  height: auto;
  transform: translate(-50%, -50%);
  opacity: 0.85;
}

/* Woal nad kadrem: nazwa ma wygrywać z każdym zdjęciem. */
.pojazdy__kafel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(19, 16, 59, 0.9), rgba(19, 16, 59, 0.35) 55%, rgba(19, 16, 59, 0.2));
}

.pojazdy__nazwa {
  max-width: calc(100% - 2.4rem);
  color: #fff;
  font-size: clamp(1.15rem, 1rem + 0.6vw, 1.5rem);
  font-weight: 800;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
  text-wrap: balance;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 3px;
  transition: background-size var(--t) var(--ease-out);
}

/* Znak „+" w rogu mówi, że kafel się otwiera; otwarty obraca się w „×". */
.pojazdy__plus {
  position: absolute;
  right: var(--s-4);
  bottom: var(--s-4);
  color: var(--orange);
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1;
  transition: transform var(--t) var(--ease-out);
}

.pojazdy__poz:is(:hover, :focus-within, .otwarte) .pojazdy__tlo { transform: scale(1.08); }
.pojazdy__poz:is(:hover, :focus-within, .otwarte) .pojazdy__nazwa { background-size: 100% 3px; }
.pojazdy__poz:is(:hover, :focus-within, .otwarte) .pojazdy__plus { transform: rotate(45deg); }

.pojazdy__kafel:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* Okno parametrów. Z JavaScriptem (`js-pojazdy`) jest wysuwaną kartą
   pod całym rzędem kafli; górny padding okna to niewidzialny mostek,
   po którym kursor schodzi z kafla do treści bez gubienia :hover
   (okno jest dzieckiem pozycji w drzewie, choć wisi pod rzędem). */
.js-pojazdy .pojazdy__okno {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  z-index: 6;
  display: none;
  padding-top: var(--s-3);
}

@media (hover: hover) {
  .js-pojazdy .pojazdy__poz:hover .pojazdy__okno { display: block; }
}

.js-pojazdy .pojazdy__poz.otwarte .pojazdy__okno { display: block; }

.pojazdy__karta {
  padding: var(--s-5) var(--s-5) var(--s-4);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--r);
  background: var(--navy-ink);
  box-shadow: 0 22px 48px rgba(6, 5, 22, 0.55);
}

.pojazdy__karta h3 {
  margin: 0 0 var(--s-4);
  color: #fff;
}

.pojazdy__karta .wp-block-list { color: var(--on-navy-2); }

/* Na telefonie okno otwiera się pod swoim kaflem jak akordeon - karta
   pod całym rzędem lądowałaby ekran niżej niż dotknięty kafel. */
@media (max-width: 720px) {
  .js-pojazdy .pojazdy__okno {
    position: static;
    display: none;
  }
}

/* ── Kafelki zawodów (Kariera) ────────────────────────────────────
   „Aktualnie poszukujemy" jako rząd kafelków zamiast listy (Oliver,
   2026-09-07: „w jakichś kafelkach, żeby to nie było wszystko
   tekstem"). Kafelki pokazowe - nie są odnośnikami, więc stoją
   nieruchomo, jak kafle pokazowe na dostawie pojazdów. */
.zawody {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: var(--s-3);
  max-width: 64rem;
  margin-inline: 0 !important;
}

.zawody__poz {
  display: grid;
  place-items: center;
  min-height: 5.4rem;
  padding: var(--s-3);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r);
  background: linear-gradient(160deg, var(--navy-soft), var(--navy-ink) 75%);
  color: #fff;
  font-weight: 700;
  font-size: 1.06rem;
  text-align: center;
  text-wrap: balance;
}

/* Kariera: „Co zapewniamy?" jako karty zamiast listy punktow (Oliver,
   2026-09-07: „forma bardziej zjadliwa, wieksze przerwy"). Tresc slowo
   w slowo z arkusza; zmienia sie wylacznie uklad. Karty stoja na jasnej
   sekcji, wiec kolor pisma bierze sie z niej, nie z ciemnej skory.      */
.zapewniamy {
  display: grid;
  /* 21rem daje trzy kolumny na szerokim ekranie, wiec szesc pozycji
     z arkusza uklada sie w dwa rowne rzedy, a nie 4 + 2.               */
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  gap: var(--s-4);
  margin-top: var(--wp--preset--spacing--50);
  margin-inline: 0 !important;
}

.zapewniamy__poz {
  position: relative;
  padding: var(--s-4) var(--s-4) var(--s-4) calc(var(--s-4) + 1.4rem);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: rgba(255, 255, 255, 0.55);
  font-size: 1.06rem;
  line-height: 1.5;
}

/* Znacznik pozycji: ta sama pomaranczowa kreska co przy punktach list
   w tresci, zeby karta czytala sie dalej jak pozycja wyliczenia.        */
.zapewniamy__poz::before {
  content: "";
  position: absolute;
  top: calc(var(--s-4) + 0.62em);
  left: var(--s-4);
  width: 0.55rem;
  height: 2px;
  background: var(--orange);
}

/* Zdanie zamykajace lead: oddech nad soba i stopien wyzszy od akapitu,
   zeby nie sklejalo sie z naglowkiem nastepnej sekcji.                  */
.kariera-haslo {
  margin-top: var(--wp--preset--spacing--50);
  font-size: 1.18rem;
}

.kariera-hr { margin-top: var(--wp--preset--spacing--50); }

.rodzenstwo .rodzenstwo__powrot {
  display: inline-block;
  margin-top: var(--wp--preset--spacing--50);
  font-weight: 700;
}

/* Naglowek sekcji zszedl (Iwona, 2026-09-07), wiec kafle podchodza pod
   przyciski konczace tresc - bez tego zostawala przerwa na wysokosc
   dwoch odstepow sekcji plus naglowka. */
.rodzenstwo.section { padding-top: 0; }

/* Jasna sekcja tuz przed kaflami rodzenstwa oddaje wiekszosc dolnego
   marginesu (Oliver, 2026-09-07): 54 px bieli pod ostatnim wierszem
   rejestru robilo pas pustego tla miedzy trescia a kaflami. Kafle i tak
   podchodza pod krawedz, wiec zostaje tyle, ile potrzeba, zeby ostatni
   wiersz nie dotykal granicy sekcji. */
article:has(+ .rodzenstwo) > .section--mist:last-child {
  /* `!important`, bo padding sekcji jest wpisany inline przez edytor bloków
     i bez tego wygrywa ze stylem motywu. */
  padding-bottom: var(--s-4) !important;
}

/* ...a kafle schodzą spod jej krawędzi, żeby między białym tłem
   certyfikatów a kaflami wszedł pas granatu (Oliver, 2026-09-07).
   Domyślnie kafle podchodzą pod treść bez odstępu i tak zostaje tam,
   gdzie sekcja nad nimi jest ciemna - granat na granacie niczego nie
   rozdziela, a odstęp tylko wydłużałby stronę. */
article:has(> .section--mist:last-child) + .rodzenstwo.section {
  padding-top: var(--wp--preset--spacing--50);
}

/* ── Cyberbezpieczenstwo: oferta i partner naukowy ───────────────────────
   Tresc jest w calosci z arkusza 2.0 (Iwona), zmienia sie wylacznie forma
   (Oliver, 2026-09-07: „ubierz to w ladniejsza forme"). Cztery pozycje
   wyliczenia staja sie kartami, zdanie o wspolnym projekcie dostaje znak
   uczelni.                                                               */
.oferta-cyber {
  display: grid;
  /* 28rem daje dwie kolumny na szerokim ekranie, wiec cztery pozycje
     z arkusza stoja 2x2, a nie 3 + 1. */
  grid-template-columns: repeat(auto-fit, minmax(min(28rem, 100%), 1fr));
  gap: var(--s-4);
  margin-top: var(--wp--preset--spacing--50);
  margin-inline: 0 !important;
}

.oferta-cyber__poz {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-4);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r);
  background: linear-gradient(160deg, var(--navy-soft), var(--navy-ink) 78%);
  overflow: hidden;
}

/* Kreska natarcia u gory karty - ten sam gest co obrys kafli obszarow.
   Rosnie przy najechaniu, wiec karta reaguje bez ruszania ukladu.        */
.oferta-cyber__poz::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--orange), rgba(241, 101, 33, 0));
  transform: scaleX(0.28);
  transform-origin: left;
  transition: transform 0.5s var(--ease-out);
}

.oferta-cyber__poz:hover::before { transform: scaleX(1); }

/* Numer porzadkowy liczy CSS, wiec nie wchodzi do drzewa dostepnosci
   ani do tresci w edytorze - redakcja edytuje same nazwy uslug.          */
.oferta-cyber { counter-reset: cyber; }

.oferta-cyber__poz::after {
  counter-increment: cyber;
  content: "0" counter(cyber);
  order: -1;
  flex: 0 0 auto;
  font-size: 1.5rem;
  font-weight: 900;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(241, 101, 33, 0.85);
}

.oferta-cyber__tekst {
  font-size: 1.12rem;
  line-height: 1.45;
  text-wrap: pretty;
}

/* Partner naukowy: znak PK i Wydzialu stoi na jasnej wyspie, bo ksiega PK
   zabrania zmiany kolorow znaku, a granat #003571 na granacie strony jest
   nieczytelny. Ta sama zasada co przy znakach jednostek certyfikujacych.
   JEDEN ZNAK, NIE DWA - umowa z Wydzialem zobowiazuje do logo
   asymetrycznego (ksiega PK 2026, str. 30).                              */
.partner-nauka {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  flex-wrap: wrap;
}

.partner-nauka__tekst { flex: 1 1 26rem; margin: 0; }

.partner-nauka__znak {
  flex: 0 0 auto;
  display: block;
  /* Sygnet PK ma miec 64 px wysokosci (ksiega, str. 7), a w pliku zajmuje
     302 z 425 px - reszta to wbudowane pole ochronne. Caly znak potrzebuje
     wiec 90 px; 6.5rem daje sygnetowi 74 px z zapasem.                   */
  height: auto;
  width: auto;
  max-height: 6.5rem;
  /* Szerokosc kolumny wygrywa z wysokoscia: przy 390 px znak w 5rem mial
     360 px i wypychal strone w bok. Ponizej ~370 px sygnet schodzi wtedy
     pod minimum z ksiegi, ale rozjechana strona jest gorsza od mniejszego
     znaku, a proporcje zostaja nietkniete.                                */
  max-width: 100%;
}


/* Szerokość sekcji rodzeństwa (Iwona, 2026-09-06): kafle zaczynają się
   tam, gdzie kreski punktorów treści (lewa krawędź kolumny wide),
   a kończą przy prawej krawędzi wyspy językowej - czyli o `--gutter`
   głębiej niż kolumna wide. Na wąskim oknie obie strony wracają do
   zwykłego marginesu. */
.rodzenstwo .shell {
  max-width: none;
  padding-left: max(var(--gutter), calc((100vw - var(--pasek, 0px) - var(--shell)) / 2));
  padding-right: max(var(--gutter), calc((100vw - var(--pasek, 0px) - var(--shell)) / 2 + var(--gutter)));
}

/* ═══ TABLICA INFORMACYJNA (dofinansowanie) ═══════════════════════════════
   Urzędowa tablica o dofinansowaniu z Funduszu Ubezpieczeń Społecznych
   (materiał od PTS, 2026-09-04). Celowo biała plansza z godłem na ciemnej
   stronie: to reprodukcja tablicy urzędowej, a nie sekcja serwisu, więc
   nie przejmuje skóry deep blue. Treść jest w blokach strony - redakcja
   poprawi kwotę czy datę bez dotykania kodu.                              */

.tablica-bhp {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-6);
  align-items: start;
  max-width: 60rem;
  padding: clamp(1.75rem, 4vw, 3rem);
  background: #fff;
  color: #1a1a1a;
  border-radius: var(--r-lg);
}

.tablica-bhp .tablica-bhp__godlo {
  margin: 0;
  width: clamp(4.5rem, 9vw, 6.5rem);
}

.tablica-bhp .tablica-bhp__godlo img { width: 100%; height: auto; }

/* Nagłówek tablicy bywa h2 (podstrona Dofinansowania) albo h3 (wariant
   w treści) - bez wspólnej reguły h2 dziedziczy biel ciemnej skóry
   i znika na białej planszy. */
.tablica-bhp :is(h2, h3) {
  margin: 0 0 var(--s-4);
  color: #1a1a1a;
  font-size: clamp(1.1rem, 1rem + 0.6vw, 1.5rem);
  font-weight: 900;
  line-height: var(--lh-head);
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.tablica-bhp p {
  margin: 0 0 var(--s-3);
  color: #333;
}

.tablica-bhp .tablica-bhp__projekt {
  font-weight: 700;
  color: #1a1a1a;
}

.tablica-bhp .tablica-bhp__kwoty {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 2px solid var(--orange);
  font-weight: 700;
  color: #1a1a1a;
}

@media (max-width: 640px) {
  .tablica-bhp { grid-template-columns: 1fr; }
}

/* Tablica pod przyciskiem (Oliver, 2026-09-05). Prawnie wolno: przy
   dofinansowaniu rownym 50 000 zl obowiazek informacyjny nie powstaje
   (prog „przekracza", rozporzadzenie Dz.U. 2021 poz. 953 § 3 ust. 1),
   a gdyby powstal, przepis i tak zada osobnej zakladki/podstrony
   (§ 7 ust. 2), nie planszy wprost. Natywny <details>: dziala bez
   JavaScriptu i z klawiatury, wydruk strony pokazuje calosc. */
.tablica-fus > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.95em 1.7em;
  border: 1px solid rgba(255, 255, 255, 0.38);
  border-radius: var(--r-sm);
  color: #fff;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  list-style: none;
  transition: border-color var(--t) var(--ease), background var(--t) var(--ease);
}
.tablica-fus > summary::-webkit-details-marker { display: none; }

.tablica-fus > summary::after {
  content: "";
  width: 0.45em;
  height: 0.45em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.1em, -0.1em);
  transition: transform var(--t) var(--ease);
}

.tablica-fus > summary:hover,
.tablica-fus > summary:focus-visible {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

.tablica-fus[open] > summary { margin-bottom: var(--s-5); }
.tablica-fus[open] > summary::after { transform: rotate(225deg) translate(-0.05em, -0.05em); }

/* ── Karta danych na Kontakcie ────────────────────────────────────────── */

/* Separator nad "Siedziba i zakład produkcyjny" z większym oddechem
   (uwaga Olivera 2026-09-06). */
.kontakt-dane .wp-block-separator {
  margin-top: 2.4rem;
  margin-bottom: 2.4rem;
}

/* ── Rejestr z logami (certyfikaty) ───────────────────────────────────── */

/* Iwona 2026-09-07: każdy certyfikat z logo jednostki, sekcja na jasnym
   tle, bo znaki IMQ, IRIS i IQNet są projektowane na biel. */
.rejestr--loga .rejestr__poz {
  grid-template-columns: minmax(0, 7.5rem) minmax(0, 16rem) minmax(0, 1fr);
  align-items: center;
}

.rejestr--loga .rejestr__logo {
  margin: 0;
  justify-self: start;
}

.rejestr--loga .rejestr__logo img {
  display: block;
  max-height: 5.75rem;
  width: auto;
  max-width: 100%;
}

@media (max-width: 780px) {
  .rejestr--loga .rejestr__poz { grid-template-columns: minmax(0, 1fr); }
  .rejestr--loga .rejestr__logo img { max-height: 4.5rem; }
}
