/* ==========================================================================
   KANCELARIA RADCY PRAWNEGO MACIEJA PENCZERZYŃSKIEGO
   Design system · tokens.css
   --------------------------------------------------------------------------
   Jedno źródło prawdy dla nowej strony. Fonty: Schibsted Grotesk (całość)
   + IBM Plex Mono (etykiety, meta). W produkcji fonty self-host (woff2).
   Kierunek: redakcyjna dyscyplina (Masiota) + marka osobista (Dziuba).
   Zasady twarde: radius 0, brak cieni, brak gradientów, jeden akcent.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENY
   -------------------------------------------------------------------------- */
:root {
  /* Kolor · papier i atrament */
  --paper:      #F6F6F4;  /* tło strony, chłodna złamana biel */
  --surface:    #FCFCFB;  /* powierzchnie uniesione (karty, formularz) */
  --ink:        #171A1F;  /* tekst główny, złamana czerń */
  --ink-2:      #565C66;  /* tekst drugorzędny */
  --ink-3:      #8A9099;  /* tekst pomocniczy, placeholdery */
  --hairline:   #E3E3E0;  /* linie włosowe, obramowania */

  /* Kolor · akcent (granat żabotu radcy prawnego) */
  --accent:      #1E3A5F; /* przyciski, linki aktywne, detale */
  --accent-deep: #152B49; /* hover / stan aktywny */
  --accent-wash: #EBF0F5; /* delikatne tło wyróżnienia, tinta granatu */

  /* Kolor · sekcje ciemne (stopka, pasy) */
  --ink-bg:     #14171C;  /* tło ciemnej sekcji */
  --paper-on-ink: #E9EAE7;/* tekst na ciemnym */
  --ink-2-on-ink: #9BA1A9;/* tekst drugorzędny na ciemnym */
  --accent-lite:  #9DB8D6;/* akcent czytelny na ciemnym (granat rozjaśniony) */
  --hairline-on-ink: rgb(255 255 255 / 0.09); /* linia włosowa na ciemnym */

  /* Kolor · stany formularza */
  --error:      #A83232;

  /* Typografia · rodziny */
  --font-sans: "Schibsted Grotesk", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", "Consolas", monospace;

  /* Typografia · skala (płynna) */
  --text-display: clamp(2.75rem, 6.5vw + 1rem, 5.75rem);  /* H1 / hero */
  --text-h2:      clamp(1.9rem, 3vw + 0.6rem, 3.25rem);   /* nagłówki sekcji */
  --text-h3:      clamp(1.25rem, 1vw + 1rem, 1.5rem);     /* nagłówki kart */
  --text-lead:    clamp(1.2rem, 1.2vw + 0.9rem, 1.625rem);/* akapit wprowadzający */
  --text-body:    1.0625rem;                               /* tekst podstawowy */
  --text-small:   0.9375rem;                               /* podpisy, stopka */
  --text-mono:    0.8125rem;                               /* etykiety mono */

  /* Typografia · rytm */
  --leading-tight: 1.04;   /* display */
  --leading-head:  1.12;   /* h2, h3 */
  --leading-body:  1.65;   /* akapity */
  --tracking-tight: -0.02em;
  --tracking-mono:  0.14em;

  /* Layout */
  --container: 1360px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section: clamp(5rem, 11vw, 8.5rem);   /* pion między sekcjami */
  --section-sm: clamp(3rem, 6vw, 5rem);
  /* Wysokość kadru mapy. W tokenach, bo tę samą wartość musi znać nota
     bramy zgód (sekcja 18) — inaczej włączenie mapy przesuwałoby stronę. */
  --map-h: clamp(420px, 68svh, 820px);

  /* Odstępy (baza 4 px) */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-6: 1.5rem;
  --s-8: 2rem;
  --s-10: 2.5rem;
  --s-12: 3rem;
  --s-16: 4rem;

  /* Kształt i ruch */
  --radius: 0;                                   /* system ostry, bez zaokrągleń */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 0.6s;      /* wejścia sekcji */
  --dur-fast: 0.22s;/* hovery, przyciski */

  /* Warstwy */
  --z-nav: 100;
  --z-overlay: 200;
}

/* --------------------------------------------------------------------------
   2. BAZA
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }

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

a { color: inherit; }

::selection {
  background: var(--accent);
  color: #fff;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   3. TYPOGRAFIA · klasy
   -------------------------------------------------------------------------- */
.t-display {
  font-size: var(--text-display);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  font-weight: 500;
}

.t-h2 {
  font-size: var(--text-h2);
  line-height: var(--leading-head);
  letter-spacing: var(--tracking-tight);
  font-weight: 500;
}

/* Nagłówki sekcji na bardzo wąskim ekranie.

   `--text-h2` to `clamp(1.9rem, 3vw + 0.6rem, 3.25rem)`. Poniżej ~430 px
   człon zależny od szerokości spada pod minimum i nagłówek PRZESTAJE maleć
   razem z ekranem — zostaje na sztywnych 1.9rem. Tymczasem reguła „bez sierot"
   skleja w tych tytułach po dwa–trzy wyrazy twardą spacją, a sklejony blok
   nie ma się gdzie złamać. Efekt: „Częste pytania w sprawach spadkowych"
   wychodziło poza kolumnę o 27 px przy 360 px, „Jak odzyskuję należności"
   o 15 px przy 320 px, i tak dalej — na prawie spadkowym rozpychało to CAŁĄ
   stronę w poziomie.

   Poniżej progu skalujemy więc nagłówek za szerokością ekranu, dokładnie tak,
   jak od początku robią to H1 hero na podstronach. Twarde spacje zostają na
   miejscu: alternatywą było ich rozrywanie, czyli złamanie reguły „bez sierot”.

   7.6vw jest dobrane tak, żeby przy 400 px dać dokładnie tyle, co dotychczasowe
   minimum (30.4 px) — przejście przez próg jest niewidoczne — a przy 320 px
   zostawić jeszcze zapas na najdłuższy sklejony blok w serwisie. */
@media (max-width: 400px) {
  .t-h2 { font-size: 7.6vw; }
}

.t-h3 {
  font-size: var(--text-h3);
  line-height: var(--leading-head);
  font-weight: 500;
}

.t-lead {
  font-size: var(--text-lead);
  line-height: 1.45;
  letter-spacing: -0.01em;
  font-weight: 400;
  max-width: 34ch;
}

.t-body { font-size: var(--text-body); }

.t-small {
  font-size: var(--text-small);
  color: var(--ink-2);
}

.t-muted { color: var(--ink-2); }

/* Etykieta mono (odpowiednik „WYBRANE SPECJALIZACJE" u Masioty).
   Dyscyplina: maksymalnie jedna etykieta na trzy sekcje strony. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}

/* Ograniczenie szerokości akapitu */
.measure { max-width: 62ch; }

/* Uwaga na marginesie — zdanie, które komentuje sekcję, ale nie należy do
   jej toku: „zasady, które obowiązują zawsze", „tabela nie zastąpi rozmowy".
   Wspólna jest sama kreska w akcencie; odstęp, miara i kolor zależą od
   miejsca, więc zostają po stronie strony. */
.side-note {
  border-left: 2px solid var(--accent);
  padding-left: var(--s-8);
}

/* Cytat wiodący — pojedyncze zdanie w skali między akapitem a nagłówkiem.
   Otwiera kolumnę tekstu („O mnie" na stronie głównej) albo niesie pasek
   osobisty na podstronie. Kolor słów prowadzi GSAP przy scrollu, bez
   `transition` — kłóciłoby się z klatkami scruba; `.is-lit` zostaje dla
   ścieżki bez animacji. Bez skryptu słowa nie są rozbijane na `.w`
   i zdanie renderuje się normalnym atramentem. */
.pull-line {
  font-size: clamp(1.5rem, 2.2vw + 0.5rem, 2.4rem);
  line-height: 1.28;
  letter-spacing: -0.01em;
  font-weight: 500;
  max-width: 26ch;
}
.pull-line .w { color: var(--ink-3); }
.pull-line .w.is-lit { color: var(--ink); }

/* ---------- Sieroty i wdowy ----------
   Dwie warstwy ochrony, bo żadna nie wystarcza sama:
   1) `text-wrap` — przeglądarka równoważy linie nagłówków i pilnuje,
      żeby w ostatniej linii akapitu nie zostało pojedyncze słowo;
   2) twarde spacje (&nbsp;) w treści — spinają dwa ostatnie wyrazy oraz
      jednoliterowe spójniki, i działają też tam, gdzie (1) nie jest
      wspierane. Przy zmianie copy trzeba je dopisać ręcznie. */
h1, h2, h3,
.t-lead, .pull-line, .svc__title, .why-item__title, .faq summary,
.trust-wall__pre, .trust-wall__name, .stat__label, .stat__value,
.about-v2__caption, .contact__val, .field__label,
/* `.stage__title` bywa `<h3>` (tor etapów), a bywa `<p>` (pasek dat, gdzie
   nagłówek byłby przeskokiem poziomu) — klasa bije wtedy regułę `p` niżej. */
.stage__title { text-wrap: balance; }
p, li, figcaption, .svc__lead, .faq__answer { text-wrap: pretty; }

/* --------------------------------------------------------------------------
   4. LAYOUT
   -------------------------------------------------------------------------- */
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Odstęp między sekcjami niesie sam `.section` — dołem jedna, górą druga.
   Dlatego druga z rzędu sekcja NA PAPIERZE zdejmuje sobie górny padding
   (`style="padding-top: 0"` w pliku strony), inaczej światło byłoby podwójne.
   Zdejmuje go TYLKO wtedy. Po pasie pełnej szerokości (`.cta`, `.facts-v2`,
   `.hero-*`, `.page-hero`) górny padding musi zostać: pas ma własne wypełnienie
   wewnątrz, ale nic pod sobą, więc bez niego nagłówek następnej sekcji przykleja
   się do granatu. */
.section { padding-block: var(--section); }
.section--sm { padding-block: var(--section-sm); }

/* Nawigacja jest fixed (96 px) — kotwice muszą się zatrzymać pod nią. */
section[id] { scroll-margin-top: 120px; }

/* Linia włosowa */
.rule {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 0;
}

/* Sekcja ciemna (stopka, pas zaufania) */
.on-ink {
  background: var(--ink-bg);
  color: var(--paper-on-ink);
}
.on-ink .t-muted,
.on-ink .t-small,
.on-ink .eyebrow { color: var(--ink-2-on-ink); }
.on-ink .rule { border-color: rgb(255 255 255 / 0.12); }

/* --------------------------------------------------------------------------
   5. PRZYCISKI I LINKI
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.95rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: scale(0.98); }

.btn--primary {
  background: var(--accent);
  color: #fff;
}
.btn--primary:hover { background: var(--accent-deep); }

.btn--ghost {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}
.btn--ghost:hover {
  background: var(--ink);
  color: var(--paper);
}
.on-ink .btn--ghost {
  border-color: var(--paper-on-ink);
  color: var(--paper-on-ink);
}
.on-ink .btn--ghost:hover {
  background: var(--paper-on-ink);
  color: var(--ink);
}

/* Link mono z podkreśleniem (odpowiednik „ZOBACZ WIĘCEJ") */
.link-mono {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
  transition: color var(--dur-fast) var(--ease);
}
.link-mono:hover { color: var(--accent); }

/* Link w środku zdania. `.link-mono` stoi w osobnym wierszu i woła o uwagę;
   ten ma nie rozbijać akapitu, więc niesie go samo podkreślenie w akcencie. */
.link-inline {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--dur-fast) var(--ease);
}
.link-inline:hover { color: var(--accent-deep); }

/* Strzałka w przyciskach i wierszach index-listy */
.arrow {
  display: inline-block;
  transition: transform var(--dur-fast) var(--ease);
}

/* --------------------------------------------------------------------------
   6. NAWIGACJA
   -------------------------------------------------------------------------- */
.site-nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--hairline);
}
/* Trzy sloty w jednym wierszu: marka, menu, znak KIRP. Skrajne kolumny mają
   po `1fr`, więc menu stoi w OSI STRONY, a nie w połowie odległości między
   marką a znakiem — te dwa mają różne szerokości i przy `space-between`
   menu uciekałoby w prawo. Kolumny nie zjadą poniżej `min-content`, więc
   przy wąskim oknie pasek najpierw traci światło (media niżej), a menu
   znika dopiero razem z całą nawigacją. */
.site-nav__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-8);
  height: 96px;
}
/* Lockup marki: nazwisko, a pod nim rola — mono, wersalikami, z szerokim
   trackingiem. Ta sama gramatyka co `.eyebrow`, więc para czyta się jak
   znak firmowy, a nie jak początek zdania. Kropka rozdzielająca zniknęła
   razem z jednym wierszem.
   Rozmiar jest dobrany do 80-pikselowego logo KIRP po drugiej stronie paska
   (powiększony 17.09.2026: nazwisko 24 px, rola 13 px). Szerokość lockupu
   wyznacza wiersz roli, nie nazwisko — przy 13 px ma 260 px i menu stoi
   w osi strony od ok. 1030 px w górę. Niżej schodzi tylko nazwisko, a rola
   zostaje przy 11 px (sekcja 15): szersza zepchnęłaby menu z osi przy
   769 px i nie zmieściłaby się obok logo na telefonie. */
.site-nav__brand {
  display: grid;
  gap: 0.25rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.15;
  text-decoration: none;
}
.site-nav__brand span {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.site-nav__links {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Znak KIRP po prawej — pełne logo w wersji tonalnej (`logo-kirp-tonalne.jpg`):
   srebrny znak z podpisem na granatowym prostokącie. Względem pliku od klienta
   granatowe marginesy są o połowę węższe (60 px z ok. 110 px w oryginale,
   równo z każdej strony), żeby przy tej samej wysokości znak był większy.
   Podpis ma w pasku litery poniżej 4 px i jest nieczytelny, ale stoi cały
   plik, a nie wycięty z niego sam sygnet — to świadoma decyzja (17.09.2026).
   80 px w 96-pikselowym pasku zostawia po 8 px światła u góry i u dołu —
   pasek urósł z 72 px właśnie po to, żeby logo było większe (17.09.2026).
   Nie jest linkiem: to znak przynależności do samorządu, a nie zaproszenie
   do wyjścia ze strony w pasku nawigacji.
   `max-width: none` znosi globalne `img { max-width: 100% }`: z nim obrazek
   w kolumnie `auto` jest „ściśliwy” i na wąskim telefonie siatka zgniatała
   logo w pionowy pasek, zamiast oddać miejsce z kolumny marki. */
.site-nav__seal {
  justify-self: end;
  display: block;
  height: 80px;
  width: auto;
  max-width: none;
}

.site-nav__links a {
  text-decoration: none;
  font-size: var(--text-small);
  color: var(--ink-2);
  transition: color var(--dur-fast) var(--ease);
}
.site-nav__links a:hover,
.site-nav__links a[aria-current="page"] { color: var(--ink); }

/* ---------- Podmenu (rozwijana lista usług) ----------
   Sterowanie samym CSS-em: `:hover` dla myszy, `:focus-within` dla
   klawiatury — link otwierający siedzi w tym samym `li`, więc tabulacja
   na niego odsłania panel, zanim fokus wejdzie do środka.
   Panel jest zawsze papierowy, także nad ciemnym hero: system nie ma
   cieni, więc odcina go krawędź, nie rozmycie. */

/* Pozycje ciągną się na całą wysokość paska, żeby panel otwierał się
   dokładnie pod jego krawędzią (`top: 100%`) i żeby kursor nie gubił
   hoveru po drodze. Wysokość trzeba przeprowadzić przez cały łańcuch:
   `nav` jest elementem flex paska i domyślnie tylko się centruje, więc
   bez `stretch` `li` miałoby wysokość samego tekstu. */
.site-nav__inner > nav { align-self: stretch; justify-self: center; }
.site-nav__links { height: 100%; }
.site-nav__links > li { align-self: stretch; display: flex; align-items: center; }

.site-nav__item--has-sub { position: relative; }
.site-nav__item--has-sub > a { display: inline-flex; align-items: center; }

.site-nav__caret {
  width: 6px;
  height: 6px;
  margin-left: 0.5em;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--dur-fast) var(--ease);
}

.site-nav__sub {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 264px;
  margin: 0;
  padding: var(--s-2) 0;
  list-style: none;
  background: var(--paper);
  border: 1px solid var(--hairline);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              visibility var(--dur-fast) var(--ease);
}
.site-nav__sub a {
  display: block;
  padding: 0.5rem var(--s-6);
  white-space: nowrap;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.site-nav__sub a:hover { background: var(--accent-wash); }

.site-nav__item--has-sub:hover .site-nav__sub,
.site-nav__item--has-sub:focus-within .site-nav__sub {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.site-nav__item--has-sub:hover .site-nav__caret,
.site-nav__item--has-sub:focus-within .site-nav__caret {
  transform: translateY(1px) rotate(225deg);
}

/* --------------------------------------------------------------------------
   7. LISTA INDEKSOWA (specjalizacje · wzorzec Masioty)
   -------------------------------------------------------------------------- */
.index-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--hairline);
}
.index-list__item { border-bottom: 1px solid var(--hairline); }
.index-list__link {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-8);
  padding: clamp(1.4rem, 3vw, 2.1rem) 0;
  text-decoration: none;
  transition: padding-left var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.index-list__title {
  font-size: clamp(1.25rem, 2vw, 1.75rem);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.index-list__desc {
  color: var(--ink-2);
  font-size: var(--text-small);
  max-width: 44ch;
}
.index-list__link:hover { padding-left: var(--s-3); color: var(--accent); }
.index-list__link:hover .arrow { transform: translateX(6px); }

/* --------------------------------------------------------------------------
   8. KARTY WPISÓW (aktualności / porady prawne)
   -------------------------------------------------------------------------- */
.note-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  text-decoration: none;
  color: inherit;
}
.note-card__media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--hairline);
}
.note-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transition: transform var(--dur) var(--ease);
}
.note-card:hover .note-card__media img { transform: scale(1.03); }
.note-card__meta {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}
.note-card__title {
  font-size: var(--text-h3);
  line-height: var(--leading-head);
  font-weight: 500;
}
.note-card:hover .note-card__title { color: var(--accent); }

/* --------------------------------------------------------------------------
   9. LICZBY (pas zaufania)
   -------------------------------------------------------------------------- */
.stat {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.stat__value {
  font-size: clamp(2.5rem, 4vw, 3.75rem);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  line-height: 1;
}
.stat__label { color: var(--ink-2); font-size: var(--text-small); }

/* --------------------------------------------------------------------------
   10. CYTAT / REFERENCJA
   -------------------------------------------------------------------------- */
.quote {
  border-left: 2px solid var(--accent);
  padding-left: var(--s-8);
  max-width: 46ch;
}
.quote__text {
  font-size: var(--text-lead);
  line-height: 1.45;
  letter-spacing: -0.01em;
}
.quote__author {
  margin-top: var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}

/* --------------------------------------------------------------------------
   11. FORMULARZ
   -------------------------------------------------------------------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.field__label {
  font-size: var(--text-small);
  font-weight: 500;
}
.field__input {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  transition: border-color var(--dur-fast) var(--ease);
  /* ⚠️ TE DWIE LINIE TRZYMAJĄ CAŁY UKŁAD NA WĄSKIM EKRANIE.
     `<input>` i `<textarea>` mają wbudowaną szerokość domyślną (atrybut
     `size`/`cols`, około 20 znaków ≈ 240 px + wyściółka). To nie jest
     sugestia — to PODŁOGA, poniżej której pole nie zejdzie samo z siebie.
     Formularz jest kolumną flex, więc ta podłoga stawała się szerokością
     minimalną całego formularza (330 px). Przy oknie 320 px strona nie
     miała jak się zmieścić i dziewięć podstron dostawało poziomy pasek
     przewijania. `min-width: 0` zdejmuje podłogę, `width: 100%` domyka
     pole do szerokości kolumny. */
  width: 100%;
  min-width: 0;
}
.field__input::placeholder { color: var(--ink-3); }
.field__input:hover { border-color: var(--ink-3); }
.field__input:focus {
  outline: none;
  border-color: var(--accent);
}
.field__help { font-size: var(--text-small); color: var(--ink-2); }
.field--error .field__input { border-color: var(--error); }
.field__error {
  font-size: var(--text-small);
  color: var(--error);
}
textarea.field__input { min-height: 9rem; resize: vertical; }

/* --------------------------------------------------------------------------
   12. FOTOGRAFIA
   -------------------------------------------------------------------------- */
/* Cała fotografia serwisu jest czarno-biała. */
.ph-bw { filter: grayscale(1); }
.ph-frame {
  overflow: hidden;
  background: var(--hairline);
}

/* --------------------------------------------------------------------------
   13. RUCH (wejścia sekcji)
   --------------------------------------------------------------------------
   Użycie: element z klasą .reveal dostaje .is-visible przez
   IntersectionObserver (raz, przy ~20% widoczności). Stagger przez
   --reveal-delay na kolejnych elementach (wielokrotność 70 ms).
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease);
  transition-delay: var(--reveal-delay, 0s);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* Rozświetlanie słowo po słowie jest animacją — bez niej cytat od razu
     stoi pełnym atramentem, także gdyby skrypt zdążył rozbić go na `.w`. */
  .pull-line .w { color: var(--ink); }
  .btn, .index-list__link, .note-card__media img, .arrow,
  .site-nav__sub, .site-nav__caret,
  .acc summary, .acc summary::after { transition: none; }
}

/* --------------------------------------------------------------------------
   14. STOPKA
   -------------------------------------------------------------------------- */
.site-footer { padding-block: var(--section-sm); }
.site-footer__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: var(--s-12);
}
.site-footer__meta {
  margin-top: var(--s-16);
  padding-top: var(--s-6);
  border-top: 1px solid rgb(255 255 255 / 0.12);
  display: flex;
  justify-content: space-between;
  gap: var(--s-8);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: 0.06em;
  color: var(--ink-2-on-ink);
}
.site-footer a { text-decoration: none; }
.site-footer a:hover { color: #fff; }

/* --------------------------------------------------------------------------
   15. RESPONSYWNOŚĆ
   -------------------------------------------------------------------------- */
/* Pasek trzyma trzy sloty w jednym wierszu do samego progu 768 px. Zanim
   zabraknie miejsca, oddaje światło między nimi — to tańsze niż łamanie
   układu, a marka i znak zostają na swoich krańcach. */
@media (max-width: 1024px) {
  .site-nav__inner { gap: var(--s-6); }
  .site-nav__links { gap: var(--s-6); }
  .site-nav__brand { font-size: 1.25rem; }
  .site-nav__brand span { font-size: 0.6875rem; }
  .site-nav__seal { height: 76px; }
}
@media (max-width: 900px) {
  .site-footer__grid { grid-template-columns: 1fr; gap: var(--s-8); }
}
/* ⚠️ TEN BLOK MUSI STAĆ PO DEFINICJI `.btn` (sekcja 6), a nie przy typografii.
   Selektor ma tę samą specyficzność co reguła bazowa, więc rozstrzyga
   kolejność w pliku — postawiony wyżej, przegrywał z `white-space: nowrap`
   i poprawka nie działała wcale.

   Sam `nowrap` chroni przycisk przed brzydkim łamaniem etykiety i ma sens
   wszędzie POZA najwęższymi ekranami. Tam przestaje być ochroną, a staje się
   szerokością nie do zbicia: najdłuższa etykieta w serwisie („Wyślij sprawę
   do oceny") ma 262 px i wymuszała tyle samo na całym formularzu, a przez
   niego na całej stronie — windykacja przewijała się w poziomie przy 320 px.
   Pod tym progiem etykieta ma prawo złamać się na dwie linie; `line-height`
   i wyśrodkowanie sprawiają, że wygląda to jak decyzja, a nie jak awaria. */
@media (max-width: 400px) {
  .btn {
    white-space: normal;
    line-height: 1.25;
    text-align: center;
  }
}

@media (max-width: 768px) {
  .site-nav__links { display: none; } /* na mobile: hamburger (do implementacji) */
  /* Bez menu środkowa kolumna byłaby pustym słupkiem z własnym gapem —
     pasek wraca do dwóch slotów: marka i znak KIRP. */
  .site-nav__inner > nav { display: none; }
  .site-nav__inner { grid-template-columns: 1fr auto; }
  .index-list__desc { display: none; }
  .index-list__link { grid-template-columns: minmax(0, 1fr) auto; }
  .site-footer__meta { flex-direction: column; gap: var(--s-3); }
}
/* Telefon: marka i logo dzielą jeden wiersz, a rola (220 px przy 11 px) nie
   ma już skąd oddać miejsca. Mniejsze jest więc logo, a poniżej 360 px — przy
   320 px zostaje 280 px na oba sloty — schodzi o stopień także rola. */
@media (max-width: 480px) {
  .site-nav__brand { font-size: 1.125rem; }
  .site-nav__seal { height: 60px; }
}
@media (max-width: 359px) {
  .site-nav__brand span { font-size: 0.625rem; }
  .site-nav__seal { height: 52px; }
}

/* --------------------------------------------------------------------------
   16. KOMPONENTY WSPÓŁDZIELONE PRZEZ STRONY
   --------------------------------------------------------------------------
   Wydzielone z index.html w momencie, gdy powstała druga strona (kontakt).
   Blok stoi na końcu pliku celowo: warianty (.site-nav--v2, .btn--paper)
   mają tę samą specyficzność co bazy z sekcji 5–6 i muszą je nadpisać.
   -------------------------------------------------------------------------- */

/* 16.1 · Nawigacja: przezroczysta nad hero, papierowa po scrollu.
          Klasę `is-scrolled` przełącza skrypt strony (ScrollTrigger albo
          IntersectionObserver na ścieżce bez GSAP).
          Kolory pisma są te same w obu stanach — hero jest jasne, więc pasek
          nie musi przechodzić z bieli na atrament. Po scrollu dochodzi mu
          tylko tło i krawędź, i to jedyne, co się animuje. */
.site-nav--v2 {
  position: fixed;
  inset-inline: 0;
  top: 0;
  background: transparent;
  border-bottom: 1px solid transparent;
  backdrop-filter: none;
  transition: background-color .35s var(--ease), border-color .35s var(--ease);
}
.site-nav--v2 .site-nav__brand,
.site-nav--v2 .site-nav__links a { color: var(--ink); }
.site-nav--v2 .site-nav__brand span { color: var(--ink-2); }
.site-nav--v2.is-scrolled {
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  border-color: var(--hairline);
  backdrop-filter: blur(8px);
}
.site-nav--v2 .site-nav__links a:hover { color: var(--accent); }
/* Aktywna zakładka: sam kolor za słabo odróżnia się od hoveru, stąd kreska. */
.site-nav--v2 .site-nav__links a[aria-current="page"] {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-thickness: 1px;
}

/* Podmenu jest osobnym panelem, nie częścią paska: aktywna pozycja nie
   dostaje w nim kreski, bo panel i tak pokazuje tylko jedną gałąź serwisu.
   Reguły wyżej mają tę samą specyficzność, więc wygrywa kolejność w pliku. */
.site-nav--v2 .site-nav__sub a { color: var(--ink-2); }
.site-nav--v2 .site-nav__sub a:hover { color: var(--accent); }
.site-nav--v2 .site-nav__sub a[aria-current="page"] {
  color: var(--accent);
  text-decoration: none;
}

/* 16.2 · Przycisk papierowy — CTA na ciemnym tle */
.btn--paper {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
}
.btn--paper:hover { background: #fff; }

/* 16.3 · Ruch: stan początkowy .reveal ustawia GSAP, więc przejścia CSS
          muszą zamilknąć — inaczej dwie warstwy animowałyby tę samą
          przezroczystość. Bez skryptu elementy zostają widoczne. */
html.has-js .reveal { transition: none; }
html:not(.has-js) .reveal { opacity: 1; transform: none; }
/* Tryb QA (?static) — zrzuty pełnej strony bez animacji. */
html.qa-static .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }

/* 16.4 · Hero podstrony — jasne, kompaktowe. Ta sama gramatyka co hero
          strony głównej (tinta granatu `--accent-wash`, rozświetlenie
          w prawym górnym rogu, pociemnienie przy dolnej krawędzi, siatka
          linii i znak §), tylko w mniejszej skali: podstrona ma zapowiadać
          treść, nie konkurować z nią.
          Ten sam kolor niesie blok kontaktowy na dole każdej strony
          (`.contact-band`), więc podstrona otwiera się i zamyka tym samym
          walorem, a treść w środku zostaje papierowa. */
.page-hero {
  position: relative;
  background:
    radial-gradient(120% 120% at 85% -30%, rgb(255 255 255 / 0.9), transparent 62%),
    linear-gradient(180deg, transparent 45%, rgb(30 58 95 / 0.07)),
    var(--accent-wash);
  color: var(--ink);
  overflow: hidden;
}
/* Górny padding wymija nawigację (fixed, 96 px). */
.page-hero__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(10rem, 15vh + 1.5rem, 12.5rem) clamp(3.5rem, 8vh, 5.5rem);
}
.page-hero .eyebrow { color: var(--accent); }
.page-hero__title {
  font-size: clamp(2.6rem, 4.4vw + 0.5rem, 4.5rem);
  line-height: 1.06;
  letter-spacing: var(--tracking-tight);
  font-weight: 500;
  margin-top: var(--s-8);
}
.page-hero__title .line { display: block; overflow: hidden; }
.page-hero__title .line > span { display: inline-block; will-change: transform; }
.page-hero__sub {
  margin-top: var(--s-8);
  max-width: 52ch;
  font-size: var(--text-lead);
  line-height: 1.5;
  color: var(--ink-2);
}
/* Siatka i znak § w tincie granatu, nie w `--hairline` — szara linia
   włosowa jest zestrojona z papierem i na niebieskawym tle ciągnie w zieleń. */
.page-hero__grid {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.page-hero__grid span { border-left: 1px solid rgb(30 58 95 / 0.10); }
.page-hero__mark {
  position: absolute;
  z-index: 1;
  right: -0.04em;
  bottom: -0.3em;
  font-size: clamp(11rem, 26vw, 22rem);
  line-height: 1;
  font-weight: 500;
  color: transparent;
  -webkit-text-stroke: 1px rgb(30 58 95 / 0.18);
  pointer-events: none;
  user-select: none;
}

/* 16.5 · Blok kontaktowy (dane + formularz obok siebie) */
.contact-band { background: var(--accent-wash); }
.contact {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}
.contact__intro { margin-top: var(--s-8); color: var(--ink-2); max-width: 46ch; }
.contact__list { list-style: none; margin: var(--s-10) 0 0; padding: 0; }
.contact__list li {
  display: flex; flex-direction: column; gap: var(--s-1);
  padding: var(--s-6) 0;
  border-top: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
.contact__list li:last-child { border-bottom: 1px solid color-mix(in srgb, var(--accent) 18%, transparent); }
.contact__key {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}
.contact__val { font-size: var(--text-h3); font-weight: 500; text-decoration: none; }
a.contact__val:hover { color: var(--accent); }
/* Dopisek pod wartością (np. „bez konieczności przyjazdu") — mniejszy,
   żeby nie rywalizował z numerem telefonu. */
.contact__note { font-size: var(--text-small); color: var(--ink-2); margin-top: var(--s-1); }
.contact__form {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-top: 2px solid var(--accent);
  padding: clamp(1.75rem, 4vw, 3rem);
  display: flex; flex-direction: column; gap: var(--s-6);
}
.contact__promise { font-size: var(--text-small); color: var(--ink-2); }
.contact__rodo { font-size: 0.8125rem; color: var(--ink-3); max-width: 52ch; }

/* 16.6 · Mapa — pas pełnej szerokości, wstawiany bez kontenera i bez
          paddingu sekcji, więc styka się z sąsiadami krawędź w krawędź.
          Iframe jest tu jednocześnie kadrem: żadnego `aspect-ratio` ani
          pozycjonowania absolutnego, bo mapa musi znać swój docelowy
          rozmiar już w chwili wczytania — inaczej renderuje kafle pod
          poprzedni wymiar i zostawia pusty pas z boku.
          Skala szarości trzyma ją w regule „fotografia serwisu jest
          czarno-biała"; kolor wraca przy interakcji, żeby mapa czytelnie
          sygnalizowała, że da się nią sterować. */
.map__frame {
  display: block;
  width: 100%;
  height: var(--map-h);
  border: 0;
  background: var(--hairline);
  filter: grayscale(1) contrast(1.04);
  transition: filter var(--dur) var(--ease);
}
.map__frame:hover,
.map__frame:focus { filter: none; }

/* 16.7 · Akordeon — baza wspólna. Na stronie głównej niesie listę usług
          (wariant `.svc`, tam też mieszka), na podstronach FAQ.
          Wysokość animuje GSAP (0 <-> auto), stąd sam `overflow` na
          `.acc__body`, bez sztuczki z `grid-template-rows`. Bez skryptu
          `details` otwiera się natywnie, skokowo — i to jest w porządku. */
.acc details { border-bottom: 1px solid var(--hairline); }
.acc details:first-of-type { border-top: 1px solid var(--hairline); }
.acc summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  align-items: baseline;
  gap: var(--s-6);
  padding: clamp(1.25rem, 2.5vw, 1.85rem) 0;
  transition: color var(--dur-fast) var(--ease);
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after {
  content: "+";
  flex: none;
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1;
  color: var(--ink-3);
  transition: transform .3s var(--ease), color .3s var(--ease);
}
.acc summary:hover { color: var(--accent); }
.acc details[open] summary { color: var(--accent); }
.acc details[open] summary::after { transform: rotate(45deg); color: var(--accent); }
.acc__body { overflow: hidden; }

/* FAQ — wariant bez numeracji, w węższej kolumnie niż siatka strony:
   pytanie i odpowiedź mają się czytać jednym rzutem oka. */
.faq { max-width: 880px; }
.faq summary {
  grid-template-columns: minmax(0, 1fr) auto;
  font-size: clamp(1.125rem, 1.5vw, 1.375rem);
  font-weight: 500;
}
.faq__answer {
  padding-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
  color: var(--ink-2);
  max-width: 62ch;
}

/* (reguła nagłówków na wąskim ekranie przeniesiona do sekcji 3 · TYPOGRAFIA —
   dotyczy wszystkich `.t-h2`, nie tylko tych w FAQ) */

/* 16.8 · Stopka. Stał tu wielki wyciągnięty napis „PENCZERZYŃSKI" — zdjęty
          29.07.2026. Stopka kończy się teraz wierszem meta i własnym
          dolnym paddingiem `.site-footer`, bez dodatkowej kompensacji:
          cała pionowa przestrzeń pod spodem należała do tamtego napisu. */
.footer-v2__legal { margin-top: var(--s-3); color: var(--ink-2-on-ink); font-size: var(--text-small); }

/* 16.9 · Ściana zaufania — lockupy nazw firm w siatce z linii włosowych.
           Docelowo w tych polach logotypy (SVG, monochrom). Stoi na stronie
           głównej i na podstronie prawa gospodarczego, stąd tutaj. */
.trust-wall {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.trust-wall__item {
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  min-height: 148px;
  padding: var(--s-8) var(--s-6);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  text-align: center;
  transition: background-color var(--dur-fast) var(--ease);
}
.trust-wall__item:hover { background: var(--accent-wash); }
.trust-wall__pre {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-3);
  /* DWIE linie zarezerwowane na stałe, na każdej szerokości. Najdłuższy
     nadpis („Przedsiębiorstwo Usług Komunalnych") zawija się na dwie linie
     już przy 768 px, a rezerwacja jednej linii dawała wtedy 14 px rozjazdu
     w rzędzie. Rezerwa musi odpowiadać najgorszemu przypadkowi, nie
     typowemu — inaczej wystarczy jedna dłuższa nazwa firmy, żeby rząd
     znowu zaczął zygzakować. */
  min-height: 2lh;
}

/* Wspólna linia nazw w rzędzie.

   Komórka jest wyśrodkowana w pionie, więc jej zawartość zaczyna się tym
   wyżej, im mniej ma wierszy. „POLBET" i „Sunrise System" nie mają nadpisu
   i przez to stały o 15 px wyżej niż „CORIMP" czy „OSOWA", a poniżej 390 px
   dochodziło do tego zawinięcie najdłuższego nadpisu na dwie linie i różnica
   rosła do 25 px. Rząd nazw czytał się jak zygzak.

   Zamiast zmieniać markup, komórkom bez nadpisu dokładamy pustą atrapę tej
   samej wysokości. `1lh` liczy się od WŁASNEGO kroju atrapy, dlatego dostaje
   ona metryki nadpisu (mono), a nie nazwy — inaczej rezerwacja nie zgadzałaby
   się co do piksela. */
.trust-wall__name:first-child::before {
  content: "";
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  /* ⚠️ INTERLINIA MUSI BYĆ TA SAMA CO W NADPISIE. `lh` liczy się od
     line-height ELEMENTU, a atrapa siedzi w `.trust-wall__name`, które ma
     `--leading-head` (1.12). Nadpis dziedziczy interlinię akapitową (1.65),
     więc bez tej linijki rezerwacja była o 4 px za niska i rząd nadal
     nie trzymał wspólnej linii. */
  line-height: var(--leading-body);
  min-height: 2lh;
  margin-bottom: var(--s-2);
}
.trust-wall__name {
  font-size: clamp(1.0625rem, 1.4vw, 1.375rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: var(--leading-head);
}

/* 16.10 · Tor etapów — rząd kolumn, w którym kolejność jest treścią:
           wezwanie jest tańsze od pozwu (windykacja), dział spadku nie ma
           sensu przed stwierdzeniem nabycia (spadki), a rok wpisu na listę
           radców poprzedza otwarcie kancelarii („O mnie", pasek dat).
           Stąd `<ol>` i stąd ten komponent stoi w sekcji 16, nie 17:
           niesie tor postępowania na podstronach usługowych i kalendarium
           poza nimi.
           `auto-fit` zamiast sztywnej liczby kolumn, bo tor ma dwa etapy,
           trzy albo cztery — puste ścieżki się zwijają, a `1fr` rozdziela
           całą szerokość między te, które zostały.
           Każdy etap otwiera pełnej mocy kreska w atramencie (zwykły
           `--hairline` byłby za cichy na tor) z krótkim odcinkiem
           w akcencie na starcie. Numer etapu jest w akcencie, nie
           w `--ink-3` jak numery w `.cases` — tam numerujemy przykłady,
           tu odmierzamy drogę.
           To `<ol>`, więc reset listy musi być jawny: baza (sekcja 2)
           zeruje `<ul>/<ol>` tylko `margin`.
           `.stage__text` jest opcjonalny — pasek dat kończy się na tytule.
           Wyjątek od `<ol>`, świadomy: sekcja „otoczenie sprawy" na stronie
           głównej wymienia role wokół sprawy (notariusz, komornik, syndyk,
           mediator) i żadna z nich nie jest pierwsza, więc idzie tam `<ul>`.
           Reguły są klasowe, działają na obu listach bez zmian. */
.stages {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem);
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding: 0;
  list-style: none;
}
.stage {
  position: relative;
  border-top: 1px solid var(--ink);
  padding-top: var(--s-6);
}
/* Element absolutny liczy się od pudełka wewnętrznego, czyli spod
   obramowania — stąd `top: -1px`, żeby pasek nakrył kreskę, a nie zawisł
   nad nią. Wystaje o 1 px w dół i to jest cały efekt: przez pierwsze
   40 px kreska jest grubsza i granatowa. */
.stage::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 40px;
  height: 2px;
  background: var(--accent);
}
.stage__num {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--accent);
}
.stage__title {
  margin-top: var(--s-2);
  font-size: clamp(1.15rem, 1.6vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: var(--leading-head);
}
.stage__text { margin-top: var(--s-3); color: var(--ink-2); }

/* 16.11 · Blok „o mnie" — portret w lewej kolumnie, proza w prawej.
           Zdjęcie jest lepkie, więc twarz zostaje w kadrze przez cały
           czas czytania; to ten sam chwyt co lepki nagłówek w `.editorial`
           (17.3), tylko nośnikiem jest fotografia.
           Stoi na stronie głównej (zapowiedź) i na podstronie „O mnie"
           (pełna wersja), stąd tutaj.
           Kadr `__crop` przycina zdjęcie, żeby parallaks nie odsłonił tła.
           Ramka offsetowa (`__frame::after`) siedzi poza kadrem — inaczej
           przycięłaby się razem ze zdjęciem. */
.about-v2 {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
}
.about-v2__media { position: sticky; top: 128px; }
.about-v2__frame { position: relative; }
.about-v2__crop { position: relative; z-index: 1; overflow: hidden; }
.about-v2__frame img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; display: block; }
.about-v2__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(14px, 14px);
  border: 1px solid var(--accent);
  z-index: 0;
}
.about-v2__caption {
  margin-top: var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}
.about-v2__text p + p { margin-top: var(--s-6); }
/* Wyższa specyficzność niż `.about-v2__text p + p`, inaczej podpis
   dostaje odstęp akapitowy zamiast własnego. */
.about-v2__text .about-v2__sign { margin-top: var(--s-10); }
.about-v2__sign { font-weight: 500; }
.about-v2__sign span { display: block; font-weight: 400; color: var(--ink-2); font-size: var(--text-small); margin-top: var(--s-1); }

/* 16.12 · Siatka zasad — cztery pola 2×2 na liniach włosowych.
           Nie karty: pola nie mają tła ani obramowania dookoła, rozdziela
           je sama siatka, więc blok czyta się jak spis, a nie jak kafelki.
           Numeracja mono w `--ink-3`, jak w `.cases` — to są przykłady
           tej samej rzeczy, nie kolejne kroki (od tego jest `.stages`).
           Stoi na stronie głównej („Na czym polega współpraca") i na
           podstronie „O mnie" („Cztery zasady, których się trzymam").
           Zaprojektowana pod cztery pola: przy nieparzystej liczbie
           ostatni wiersz zostaje z pustą kolumną po prawej. */
.why-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--hairline);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.why-item {
  padding: clamp(2rem, 3.5vw, 3rem) clamp(1.5rem, 4vw, 4rem) clamp(2rem, 3.5vw, 3rem) 0;
  border-bottom: 1px solid var(--hairline);
}
.why-item:nth-child(even) {
  border-left: 1px solid var(--hairline);
  padding-right: 0;
  padding-left: clamp(1.5rem, 4vw, 4rem);
}
.why-item__num {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--ink-3);
}
.why-item__title { margin-top: var(--s-4); font-size: var(--text-h3); font-weight: 500; line-height: var(--leading-head); }
.why-item__text { margin-top: var(--s-3); color: var(--ink-2); max-width: 46ch; }

/* 16.13 · Lista definicyjna — termin po lewej, jego rozwinięcie po prawej.
           `<dl>` mówi dokładnie to, co niesie treść, więc nie karty i nie
           wiersze `.cases`. Świadomie bez numeracji: numery sugerowałyby
           kolejność albo ranking, a tu żadna pozycja nie jest „pierwsza".
           Wiersze wyrównuje siatka, więc kreska pod obiema kolumnami stoi
           na tej samej wysokości niezależnie od długości opisu.
           Nazwa wzięła się z pierwszego użycia (porównanie form prawnych
           na podstronie spółek), ale komponent jest ogólny — na „O mnie"
           niesie listę tego, co potwierdza pracę radcy. */
.compare {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  border-top: 1px solid var(--hairline);
}
.compare dt,
.compare dd {
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--hairline);
}
.compare dt {
  font-size: clamp(1.15rem, 1.6vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: var(--leading-head);
  padding-right: clamp(1.5rem, 4vw, 3rem);
}
.compare dd {
  margin: 0;
  color: var(--ink-2);
  padding-left: clamp(1.5rem, 4vw, 3rem);
  border-left: 1px solid var(--hairline);
}

/* 16.14 · Responsywność i ruch ograniczony dla bloków współdzielonych */
@media (max-width: 900px) {
  .contact { grid-template-columns: 1fr; }
  .page-hero__mark { font-size: 13rem; right: -0.08em; }
  .trust-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Tor schodzi do jednej kolumny dopiero tutaj: wąskie kolumny prozy są
     jeszcze czytelne na tablecie, a rozbicie ich wcześniej zabiera sekcji
     sens „idziemy krok po kroku". */
  .stages { grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 2.5rem); }
  .about-v2 { grid-template-columns: 1fr; }
  /* Bez lepkości i w mniejszym kadrze: na jednej kolumnie zdjęcie na całą
     szerokość zepchnęłoby tekst poniżej ekranu. */
  .about-v2__media { position: static; max-width: 420px; }
  .why-grid { grid-template-columns: 1fr; }
  .why-item, .why-item:nth-child(even) { border-left: 0; padding-inline: 0; }
}
/* Lista definicyjna schodzi do jednej kolumny wcześniej niż reszta: dwa
   bloki prozy obok siebie robią się nieczytelne, zanim zabraknie miejsca
   na samą siatkę. Rozwinięcie zostaje wtedy tuż pod terminem, więc kreska
   i pionowa linia byłyby już tylko szumem. */
@media (max-width: 820px) {
  .compare { grid-template-columns: 1fr; }
  .compare dt { border-bottom: 0; padding-bottom: 0; padding-right: 0; }
  .compare dd {
    padding-left: 0;
    padding-top: var(--s-3);
    border-left: 0;
  }
}
@media (max-width: 640px) {
  .trust-wall { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .map__frame { transition: none; }
  .trust-wall__item { transition: none; }
}

/* --------------------------------------------------------------------------
   17. PODSTRONY USŁUGOWE
   --------------------------------------------------------------------------
   Gramatyka wspólna dla podstron dziedzin prawa (prawo cywilne, prawo
   gospodarcze, kolejne). Wydzielone z prawo-cywilne.html, gdy powstała
   druga taka podstrona i te same układy pojawiły się drugi raz.
   Reszta — pasy, listy i panele występujące na jednej stronie — zostaje
   w pliku tej strony.
   -------------------------------------------------------------------------- */

/* 17.1 · Okruszek w nadtytule hero. Podstrona usługowa potrzebuje drogi
          powrotnej do listy usług, a copy hero jest bez przycisków — więc
          nawigację niesie sam nadtytuł. */
.page-hero .eyebrow a {
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
/* Hero jest jasne, więc okruszek nie może rozjaśniać się na hover — idzie
   w drugą stronę, do atramentu, jak każdy link na papierze. */
.page-hero .eyebrow a:hover { color: var(--ink); }

/* 17.2 · Lista sytuacji („z czym zgłaszają się klienci").
          Świadomie nie akordeon: to sedno podstrony i musi dać się
          przeczytać bez klikania. Wiersz zamiast kafla, bo opisy są za
          długie na kartę, a linia włosowa trzyma rytm strony głównej.
          Numeracja mono — jak `.svc__num` i `.why-item__num`. */
.cases {
  border-top: 1px solid var(--hairline);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.case {
  display: grid;
  grid-template-columns: auto minmax(0, 4fr) minmax(0, 7fr);
  align-items: baseline;
  gap: var(--s-4) clamp(2rem, 5vw, 4.5rem);
  padding: clamp(1.75rem, 3.5vw, 2.75rem) 0;
  border-bottom: 1px solid var(--hairline);
}
.case__num {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  color: var(--ink-3);
}
.case__title {
  font-size: clamp(1.2rem, 1.9vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: var(--leading-head);
}
.case__text { color: var(--ink-2); }
.cases-note {
  margin-top: clamp(2rem, 4vw, 3rem);
  max-width: 72ch;
  color: var(--ink-2);
}

/* 17.3 · Układ redakcyjny: nagłówek zostaje w kadrze, kiedy tekst
          przewija się obok — ten sam chwyt co zdjęcie w „O mnie". */
.editorial {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}
.editorial__head { position: sticky; top: 128px; }
.editorial__body p + p { margin-top: var(--s-6); }

/* 17.4 · Cichy blok pod kreską: etykieta mono, nagłówek i akapit.
          Domyka sekcję albo stoi jako osobny przystanek. Nazwa wzięła się
          z pierwszego użycia („czego się spodziewać po kontakcie"), ale
          komponent jest ogólny — na windykacji niesie sytuację szczególną
          („jeśli mają Państwo już wyrok"). Odstęp od góry zależy od
          kontekstu, więc zostaje po stronie strony. */
.expect {
  padding-top: clamp(1.75rem, 3.5vw, 2.5rem);
  border-top: 1px solid var(--hairline);
}
.expect__title {
  margin-top: var(--s-3);
  font-size: var(--text-h3);
  font-weight: 500;
  line-height: var(--leading-head);
}
.expect__text { margin-top: var(--s-4); color: var(--ink-2); }
/* Wariant zagnieżdżony: blok domyka kolumnę tekstu układu redakcyjnego
   (prawo cywilne, prawo rodzinne) i potrzebuje wtedy odstępu od akapitów
   wyżej. Stojąc samodzielnie w sekcji (prawo gospodarcze) nie potrzebuje. */
.editorial__body .expect { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

/* 17.5 · Wyróżniona linijka o sprawach pilnych, nad formularzem.
          Odpowiednik granatowego pasa, ale w skali jednej linijki — dla
          podstron, gdzie copy stawia telefon przy formularzu, a nie
          w osobnej sekcji. Numer dziedziczy skalę po `.contact__val`,
          żeby czytał się jak dane kontaktowe na pozostałych stronach. */
.urgent-line {
  margin-top: var(--s-10);
  border-left: 2px solid var(--accent);
  padding-left: var(--s-8);
  max-width: 44ch;
}
.urgent-line__label { font-weight: 500; }
.urgent-line .contact__val { display: inline-block; margin-top: var(--s-2); }

/* 17.6 · Granatowy pas z wezwaniem do kontaktu, mniej więcej w połowie
          podstrony. Każda podstrona usługowa ma dokładnie jeden, dobrany
          do tematu: termin na odpowiedź (prawo cywilne), przedawnienie
          roszczenia (windykacja), termin na odrzucenie spadku (spadki),
          umowa do podpisania na wczoraj (prawo gospodarcze), pierwsza
          rozmowa (prawo rodzinne), wybór ścieżki (spółki).
          Rola jest jedna: dać czytelnikowi wyjście do kontaktu w środku
          czytania, zamiast kazać mu scrollować do formularza na dole.
          Ta sama gramatyka co pas wiarygodności na stronie głównej:
          granat plus siatka linii, żeby pas czytał się jako element tego
          samego systemu.
          Prawa kolumna kończy się akcją — telefonem (`__key` + `__phone`)
          tam, gdzie liczy się czas, albo przyciskiem `.btn--paper` tam,
          gdzie copy prosi o opisanie sprawy. Nigdy oboma naraz. */
.cta {
  position: relative;
  overflow: hidden;
  background: var(--accent);
  color: #fff;
}
.cta__grid {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.cta__grid span { border-left: 1px solid rgb(255 255 255 / 0.14); }
/* Podział kolumn wynika z siatki `.cta__grid`, nie z proporcji 5/7.
   Kontener jest wyśrodkowany, więc jego oś to oś sekcji — środkowa linia
   siatki pada dokładnie w 50% kontenera. Przy 5/7 prawa kolumna startowała
   ok. 45%, czyli linia wchodziła w pierwsze znaki akapitu i czytała się jak
   błąd druku (i to przy każdej szerokości okna, bo obie wartości są
   procentowe). Teraz linia leży w osi rynny: obie kolumny odsuwają się od
   niej o `--gutter`, czyli o to samo wcięcie, które kontener daje nagłówkowi
   po lewej. Ta sama zasada co w `.why-grid`, `.compare` i `.trust-wall`:
   treść nie siada na kresce, tylko zaczyna się za nią.
   Rynna jest związana z `--gutter`, nie z własnym clamp-em — inaczej przy
   jednej szerokości linia stałaby w osi, a przy innej obok niej. */
.cta__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: calc(50% - var(--gutter)) minmax(0, 1fr);
  column-gap: calc(var(--gutter) * 2);
  row-gap: clamp(2rem, 5vw, 5rem);
  padding-block: clamp(3rem, 6vw, 5rem);
}
.cta .eyebrow { color: var(--accent-lite); }
.cta__title {
  margin-top: var(--s-4);
  font-size: clamp(1.6rem, 2.2vw + 0.6rem, 2.5rem);
  font-weight: 500;
  line-height: var(--leading-head);
  letter-spacing: var(--tracking-tight);
}
/* Ta sama wartość co etykiety pasa wiarygodności na stronie głównej:
   --ink-2-on-ink jest zestrojony z czernią, nie z granatem. */
.cta__text { color: #C9D5E2; max-width: 58ch; }
.cta__key {
  display: block;
  margin-top: var(--s-10);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--accent-lite);
}
.cta__phone {
  display: inline-block;
  margin-top: var(--s-3);
  padding-bottom: var(--s-2);
  font-size: clamp(1.6rem, 2.6vw, 2.25rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-decoration: none;
  border-bottom: 1px solid rgb(255 255 255 / 0.35);
  transition: border-color var(--dur-fast) var(--ease);
}
.cta__phone:hover { border-color: #fff; }
/* Wariant z przyciskiem zamiast telefonu — ten sam odstęp od akapitu,
   co etykieta nad numerem, żeby oba warianty siadały w tym samym rytmie. */
.cta .btn { margin-top: var(--s-10); }

/* Ostrzeżenie dodatkowe w lewej kolumnie, pod tytułem: drugie zagrożenie,
   którego nie da się zmieścić w jednym zdaniu tytułu (pułapka z dziećmi
   przy odrzuceniu spadku). Kreska w `--accent-lite`, nie w akcencie —
   na granacie sam granat byłby niewidoczny. */
.cta__note {
  margin-top: var(--s-8);
  border-left: 2px solid var(--accent-lite);
  padding-left: var(--s-6);
  font-size: var(--text-small);
  color: #C9D5E2;
  max-width: 46ch;
}
.cta__note strong { color: #fff; font-weight: 500; }

/* 17.7 · Lista „co warto przygotować" w kolumnie obok formularza.
          Linie w kolorze rozcieńczonego granatu — jak `.contact__list`,
          bo obie listy stoją w tej samej kolumnie, na tym samym tle.
          Nagłówek listy jest zwykłym tekstem, nie etykietą mono: całe
          zdanie wersalikami z trackingiem by krzyczało. */
.prep { margin-top: var(--s-10); }
.prep__title {
  font-size: var(--text-body);
  font-weight: 500;
  line-height: var(--leading-body);
}
.prep__list {
  list-style: none;
  margin: var(--s-6) 0 0;
  padding: 0;
}
.prep__list li {
  display: flex;
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-top: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
.prep__list li:last-child { border-bottom: 1px solid color-mix(in srgb, var(--accent) 18%, transparent); }
.prep__list li::before {
  content: "§";
  flex: none;
  color: var(--accent);
  font-size: 0.875rem;
  line-height: 1.7;
}
.prep__note {
  margin-top: var(--s-6);
  font-size: var(--text-small);
  color: var(--ink-2);
  max-width: 52ch;
}

/* 17.8 · Responsywność podstron usługowych */
@media (max-width: 900px) {
  .editorial { grid-template-columns: 1fr; }
  .editorial__head { position: static; }
  /* Numer zostaje przy tytule, opis schodzi pod niego, wciąż z wcięciem. */
  .case { grid-template-columns: auto minmax(0, 1fr); }
  .case__text { grid-column: 2 / -1; }
  .cta__inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   18. ZGODY · baner cookies i brama treści zewnętrznych
   --------------------------------------------------------------------------
   Logika siedzi w `js/consent.js` — tam też lista kategorii i cała treść.
   Tutaj jest sam wygląd.
   Pasek stoi na dole okna. Bez cienia (reguła systemu), więc od strony
   odcina go kreska w akcencie — 2 px, ta sama gramatyka co `.side-note`
   i `.urgent-line`. Sama linia włosowa byłaby tu za cicha: pasek stoi raz
   nad papierem, raz nad ciemną stopką i w obu sytuacjach musi się odciąć.
   -------------------------------------------------------------------------- */
.consent {
  position: fixed;
  inset: auto 0 0 0;
  z-index: var(--z-overlay);
  background: var(--surface);
  border-top: 2px solid var(--accent);
  /* Rozwinięte ustawienia na niskim ekranie muszą dać się doscrollować. */
  max-height: 100svh;
  overflow-y: auto;
  transform: translateY(100%);
  transition: transform 0.5s var(--ease);
}
.consent.is-open { transform: translateY(0); }

.consent__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: end;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
}
.consent__text {
  margin-top: var(--s-3);
  max-width: 68ch;
  font-size: var(--text-small);
  color: var(--ink-2);
}

/* Przyciski w skali paska użytkowego, nie sekcji strony — te same warianty
   `.btn`, tylko ciaśniejsze. „Tylko niezbędne" i „Akceptuję wszystkie" mają
   celowo identyczny rozmiar: odmowa nie może być trudniejsza od zgody. */
.consent__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-6);
}
.consent .btn {
  padding: 0.8rem 1.35rem;
  font-size: var(--text-small);
}

@media (min-width: 901px) {
  /* Na szerokim ekranie przyciski stoją w jednym rzędzie i domyślnie mają
     szerokość swojej etykiety — „Akceptuję wszystkie" wychodziło przez to
     o 31 px szersze od „Tylko niezbędne". Wspólna szerokość minimalna zrównuje
     obie decyzje, tak jak zapowiada komentarz przy `.consent__actions`.
     Węższe ekrany mają własny mechanizm (siatka równych kolumn niżej), więc
     ta reguła jest CELOWO ograniczona do desktopu — na 360 px 12.5rem
     rozepchnęłoby pas poza ekran. */
  .consent__actions .btn {
    min-width: 12.5rem;
    justify-content: center;
  }
}
.consent__more {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* Odpowiedź formularza — potwierdzenie albo powód, dla którego się nie udało.
   Kreska w kolorze zamiast tła i ikony: system nie ma „boksów alertów”, a ten
   sam idiom (kreska + tekst) niesie już `.side-note` i `.urgent-line`. */
.form-status {
  margin-top: var(--s-6);
  padding-left: var(--s-4);
  border-left: 2px solid var(--accent);
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--ink-2);
}
.form-status.is-ok { border-left-color: var(--accent); color: var(--ink); }
/* Błąd nie dostaje czerwieni — paleta serwisu jej nie ma, a komunikat i tak
   mówi wprost, co poprawić. Odróżnia go grubsza kreska w atramencie. */
.form-status.is-blad { border-left-color: var(--ink); color: var(--ink); }

/* „Ustawienia cookies" w stopce — dopisywane przez `js/consent.js`.

   Był to `<a href="#">`, czyli link, który nigdzie nie prowadzi: kliknięcie
   obsługiwał JavaScript, a `href` służył tylko za pretekst do wyglądu linku.
   Element, który wykonuje akcję na stronie, jest przyciskiem — i dlatego jest
   nim teraz naprawdę. Ta klasa zdejmuje wygląd kontrolki systemowej, żeby
   przycisk niczym nie różnił się od sąsiednich linków stopki. */
.footer-link-btn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  /* Bez podkreślenia i z tym samym hoverem co `.site-footer a` — sąsiednie
     linki stopki też są bez dekoracji, więc przycisk ma być nieodróżnialny. */
  text-decoration: none;
  cursor: pointer;
}
.site-footer .footer-link-btn:hover { color: #fff; }

/* Ustawienia — wiersze rozdzielone kreskami, jak `.contact__list`.
   Przełącznik po prawej, żeby wzrok szedł najpierw po nazwach kategorii. */
.consent__panel {
  grid-column: 1 / -1;
  margin-top: var(--s-8);
}
.consent__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-6);
  align-items: start;
  padding: var(--s-6) 0;
  border-top: 1px solid var(--hairline);
}
.consent__row:last-of-type { border-bottom: 1px solid var(--hairline); }
.consent__row-title { font-weight: 500; }
.consent__row-desc {
  margin-top: var(--s-2);
  font-size: var(--text-small);
  color: var(--ink-2);
  max-width: 62ch;
}
.consent__save { margin-top: var(--s-6); }

/* Kwadrat, nie pigułka — radius 0 obowiązuje też kontrolki. Kategoria
   niezbędna jest zaznaczona i zablokowana, więc dostaje szarość zamiast
   akcentu: ma czytać się jako stan rzeczy, a nie jako Państwa wybór. */
.consent__switch {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
  margin: 0;
  border: 1px solid var(--ink-3);
  border-radius: var(--radius);
  background: transparent;
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.consent__switch:hover { border-color: var(--accent); }
.consent__switch:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.consent__switch:checked::after {
  content: "";
  width: 0.5rem;
  height: 0.28rem;
  border-left: 1.5px solid #fff;
  border-bottom: 1.5px solid #fff;
  transform: rotate(-45deg) translate(1px, -1px);
}
.consent__switch:disabled {
  cursor: default;
  background: var(--ink-3);
  border-color: var(--ink-3);
}
.consent__switch:disabled:hover { border-color: var(--ink-3); }

/* --------------------------------------------------------------------------
   Brama treści zewnętrznych — kadr w miejscu osadzonego elementu, dopóki
   nie ma zgody. Nota i element leżą w tej samej komórce siatki, więc kadr
   ma dokładnie ten sam rozmiar przed zgodą i po niej: włączenie mapy nie
   przesuwa strony. Bez skryptu widać samą notę — i to jest właściwe
   zachowanie: brak JS nie może oznaczać cichego wpuszczenia Google.
   -------------------------------------------------------------------------- */
.consent-gate { display: grid; }
.consent-gate > * { grid-area: 1 / 1; }
.consent-gate.is-unlocked .consent-gate__note { display: none; }
/* `hidden` na osadzeniu musi wygrać z jego własnym `display` (np. `.map__frame`
   ma `display: block`). Reguła autorska bije regułę przeglądarki niezależnie
   od specyficzności, więc atrybut sam z siebie by nie wystarczył. */
.consent-gate [hidden] { display: none; }

.consent-gate__note {
  min-height: var(--map-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
  padding: var(--s-12) var(--gutter);
  text-align: center;
  background: var(--surface);
  border-block: 1px solid var(--hairline);
}
.consent-gate__note p { max-width: 56ch; color: var(--ink-2); }
.consent-gate__note .btn { margin-top: var(--s-4); }
.consent-gate__note .t-small { margin-top: var(--s-2); }

@media (max-width: 900px) {
  .consent__inner { grid-template-columns: 1fr; align-items: start; }

  /* ⚠️ ODMOWA MUSI BYĆ TAK SAMO ŁATWA JAK ZGODA — to nie jest kwestia gustu.

     Poprzednio stało tu `flex: 1 1 auto`, przez co przyciski rosły
     proporcjonalnie do DŁUGOŚCI SWOJEJ ETYKIETY. Przy 360 px „Tylko
     niezbędne" mieściło się obok „Ustawień" i miało 200 px, a dłuższe
     „Akceptuję wszystkie" spadało do własnego wiersza na całą szerokość
     (320 px) — wypełnione granatem, więc jeszcze mocniejsze wizualnie.
     Zgoda była o 60% większa od odmowy, wbrew temu, co deklaruje komentarz
     przy `.consent__actions` wyżej.

     Siatka o równych kolumnach wiąże obie decyzje tą samą szerokością
     niezależnie od długości napisu. „Ustawienia" to nie decyzja, tylko
     wejście w szczegóły — idą do osobnego wiersza nad przyciskami. */
  .consent__actions {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-4);
  }
  .consent__more { grid-column: 1 / -1; justify-self: start; }
  .consent .btn { width: 100%; justify-content: center; }
}

@media (max-width: 560px) {
  /* Dwie równe kolumny zostają aż do najwęższych ekranów. Ustawienie
     przycisków jeden pod drugim też dawałoby równość, ale kosztowało trzeci
     wiersz — a pas zgód i tak zabiera pół ekranu. Etykiety mają prawo złamać
     się na dwie linie (patrz `.btn` w sekcji 15) i to jest tańsze niż kolejny
     wiersz. Równość jest zachowana: obie kolumny mają tę samą szerokość,
     a `align-items: stretch` domyka je do tej samej wysokości. */
  .consent__actions { align-items: stretch; }

  /* Pas zajmował 52% wysokości ekranu przy 360×780. Ciaśniejsze marginesy
     i twardy limit zostawiają widoczny kawałek strony pod spodem, żeby było
     wiadomo, co się właściwie akceptuje. Przy dłuższej treści pas ma
     własne przewijanie (`overflow-y: auto` w `.consent`). */
  .consent { max-height: 80svh; }
  .consent__inner { padding-block: var(--s-6); gap: var(--s-6); }
  .consent__text { line-height: 1.5; }
}
@media (prefers-reduced-motion: reduce) {
  .consent { transition: none; }
  .consent__switch { transition: none; }
}

/* --------------------------------------------------------------------------
   19. TELEFON POD RĘKĄ
   --------------------------------------------------------------------------
   Jeden element, dwa zachowania — markup wstrzykuje js/site.js, więc numer
   jest w serwisie w jednym miejscu.
   Na desktopie kwadrat w prawym dolnym rogu: sama słuchawka, numer wysuwa
   się dopiero po najechaniu albo tabulacji. Z komputera prawie nikt nie
   dzwoni, więc numer ma być do odczytania i zapamiętania, nie do klikania.
   Poniżej 768 px — czyli dokładnie tam, gdzie znika pasek nawigacji — ten
   sam element rozkłada się w belkę na całą szerokość z numerem widocznym
   od razu. Na telefonie to jest realny przycisk „zadzwoń" i jedyne stałe
   wezwanie na ekranie.
   Warstwa `--z-nav`, nie `--z-overlay`: dopóki ktoś nie rozstrzygnie zgód,
   baner cookies ma prawo przykryć telefon. Zgoda idzie pierwsza.
   -------------------------------------------------------------------------- */
.call {
  position: fixed;
  right: clamp(1rem, 2.5vw, 2rem);
  bottom: clamp(1rem, 2.5vw, 2rem);
  z-index: var(--z-nav);
  display: inline-flex;
  align-items: center;
  padding: 0.9rem;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  font-size: var(--text-body);
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1;
  transition: background-color var(--dur-fast) var(--ease);
}
.call:hover { background: var(--accent-deep); }
.call__icon { flex: none; display: block; width: 1.25rem; height: 1.25rem; }

/* Numer wjeżdża szerokością ścieżki siatki: 0fr -> 1fr daje dokładnie tyle
   miejsca, ile zajmuje tekst, bez zgadywania `max-width` (a przy zmianie
   numeru — bez przeliczania go od nowa). Odstęp od ikony siedzi w środku
   ścieżki, nie w `gap` — inaczej zwinięty kwadrat miałby po prawej
   kilkanaście pikseli pustego marginesu i przestałby być kwadratem. */
.call__label {
  display: grid;
  grid-template-columns: 0fr;
  /* Świadomie między tokenami: `--dur-fast` (0.22 s) to tempo zmiany koloru
     i na przejechanie stu pikseli jest szarpnięciem, a `--dur` (0.6 s) to
     tempo wchodzenia sekcji i przy hoverze się wlecze. */
  transition: grid-template-columns 0.32s var(--ease);
}
.call__label > span {
  overflow: hidden;
  white-space: nowrap;
  padding-left: var(--s-3);
}
.call:hover .call__label,
.call:focus-visible .call__label { grid-template-columns: 1fr; }

@media (max-width: 768px) {
  .call {
    right: 0;
    left: 0;
    bottom: 0;
    justify-content: center;
    padding: 1rem var(--gutter);
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid rgb(255 255 255 / 0.14);
  }
  .call__label { grid-template-columns: 1fr; }
  /* Belka przykrywa dół stopki, więc stopka musi jej oddać tyle miejsca,
     ile sama zajmuje. Padding idzie na stopkę, nie na `body`: inaczej pod
     ciemnym blokiem pokazałby się pasek papieru. */
  .site-footer {
    padding-bottom: calc(var(--section-sm) + 3.25rem + env(safe-area-inset-bottom, 0px));
  }
}
@media (prefers-reduced-motion: reduce) {
  .call,
  .call__label { transition: none; }
}
