﻿/*
 * Warstwa korekt nakładana NA oryginalny CSS z Oxygena.
 * Ładowana jako ostatnia, więc wygrywa bez `!important` tam, gdzie się da.
 *
 * Zasada: minimalny zestaw regułek naprawiających konkretne, zmierzone problemy.
 * Nie przepisujemy tu wyglądu — od tego będzie refaktor na komponenty.
 */

:root {
  --brand-mint: #2f8a77;
  --brand-cyan: #00728a;
  --brand-coral-text: #b4442f;
}

/* Kontrastu NIE poprawiamy tutaj — Oxygen ustawia kolory selektorami po ID,
   których nie da się przebić z zewnętrznego arkusza. Podmiana barw dzieje się
   wprost w arkuszach, w scripts/enhance.mjs (COLOR_MAP). */

/* --- 1. Pola dotykowe: zmierzone 37–41 px, norma to 44 px --- */
.ct-link-button,
.oxy-nav-menu a,
.facetwp-dropdown,
.facetwp-autocomplete,
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="submit"],
select,
button {
  min-height: 44px;
}

.ct-link-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* --- 4. Czytelność długich bloków tekstu ---
   Klasę .txt-left nadaje enhance.mjs tylko blokom dłuższym niż 25 słów,
   żeby nie ruszać krótkich, celowo wyśrodkowanych podpisów. */
.txt-left {
  text-align: left !important;
  /* !important, bo Oxygen ustawia max-width:100% selektorem po ID.
     68ch ≈ 630 px przy 16 px — mieści się w zalecanych 60–75 znaków w linii. */
  max-width: 68ch !important;
}

/* Bloku tekstu NIE centrujemy: kontenery Oxygena to kolumny flex z własnym
   `align-items`, więc `margin-inline:auto` odrywało akapit od krawędzi, przy
   której stoi jego nagłówek (widoczne w panelach usług). Niech decyduje rodzic. */

/* --- 4b. Cztery karty „dlaczego Properton?" na wspólnych liniach ---
   Karta niesie trzy rzeczy jedna pod drugą: tytuł, opis, kolorowy pasek.
   Dopóki rząd był flexem, każda karta układała je u siebie w środku, więc
   tytuł zawijający się do dwóch linii spychał swój opis niżej niż sąsiedzi
   (mierzone na /sprzedaj: opisy startowały na 4904 i 4928 px). Wyrównanie
   samych pasków `margin-top:auto` łatało tylko dolną krawędź.

   Rząd jest teraz gridem, a karta — subgridem tych samych trzech wierszy.
   Wysokość wiersza wyznacza najwyższa karta, więc tytuły, opisy i paski
   stoją na wspólnych liniach niezależnie od tego, na ile linii zawinie się
   tekst przy danej szerokości okna. To samo działa na /kup, /wynajmij
   i na stronie głównej — sekcja jest w czterech zrzutach tą samą sekcją
   o tych samych identyfikatorach.

   Poniżej 991 px Oxygen ustawia karty jedna pod drugą; grid schodzi wtedy
   do jednej kolumny, a wyrównanie przestaje mieć znaczenie i nie przeszkadza. */
#div_block-54-14 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto auto auto;
  align-items: start;
}

#div_block-55-14,
#div_block-63-14,
#div_block-67-14,
#div_block-71-14 {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  justify-items: center;
  /* Oxygen daje karcie `align-items:center`; w gridzie znaczy to centrowanie
     w wierszu, więc krótszy opis odpływał od wspólnej górnej linii. */
  align-items: start;
  width: auto;
}

@media (max-width: 991px) {
  #div_block-54-14 {
    grid-template-columns: 1fr;
  }
}

/* Opis karty: jedna szerokość dla całej czwórki. Oxygen daje wszystkim
   `max-width:249px`, ale enhance.mjs bywa nadaje pojedynczej karcie klasę
   .txt-left (blok dłuższy niż 25 słów), a ta niesie własne `68ch !important`
   i wyrównanie do lewej — czwarta karta robiła się szersza od rodzeństwa.
   Tu wygrywa rola: ta sama rola, ta sama miara. */
#text_block-60-14,
#text_block-65-14,
#text_block-69-14,
#text_block-73-14 {
  max-width: 249px !important;
  text-align: center !important;
  margin-bottom: 0;
}

/* Pasek stoi we własnym wierszu subgridu, więc odstęp nad nim jest jego
   własnym marginesem — bez rozpychania `margin-top:auto`. */
#div_block-62-14,
#div_block-66-14,
#div_block-70-14,
#div_block-74-14 {
  margin-top: 45px;
  flex-shrink: 0;
}

/* --- 4b3. Nagłówki kroków procesu w mierze akapitu ---
   Akapit kroku urywa się na 68ch (`.txt-left`, ok. 631 px), a nagłówek nad nim
   nie miał żadnego ograniczenia i przy dłuższym tytule ciągnął się do 771 px.
   Prawa krawędź nagłówka mijała się wtedy z prawą krawędzią tekstu — widać to
   było mocniej po skróceniu opisów, bo w kolumnie zostało więcej powietrza.
   Jedna miara dla nagłówka i akapitu domyka krok wspólną krawędzią. */
#section-21-16 h3.ct-headline,
#section-65-18 h3.ct-headline,
#section-17-20 h3.ct-headline {
  /* Ta sama miara co `.txt-left` (68ch akapitu przy 16 px). W px, bo `ch`
     liczy się od fontu własnego elementu, a nagłówek jest większy — 68ch
     dawałoby mu 1420 px, czyli żadnego ograniczenia. */
  max-width: 631px;
}

/* --- 4c. Punkty w panelach usług ---
   Panele niosły po dwa akapity (559 słów łącznie = 6,4 ekrana na telefonie),
   powtarzające treść z /sprzedaj/, /kup/ i /wynajmij/. Zostaje jedno zdanie
   wprowadzające i trzy konkrety — resztę czyta się na stronie docelowej. */
.us-punkty {
  list-style: none;
  margin: 1em 0 0;
  padding: 0;
  max-width: 68ch;
}

.us-punkty li {
  position: relative;
  padding-left: 1.5em;
  margin-bottom: 0.5em;
  text-align: left;
}

.us-punkty li::before {
  content: "";
  position: absolute;
  left: 0;
  /* 0.65em ≈ środek pierwszego wiersza przy line-height 1,3 */
  top: 0.65em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.45;
}

/* Dawna korekta 4d (nagłówek „zapraszamy do kontaktu" na koralowym panelu)
   oraz awaryjny stan karuzeli opinii zniknęły razem z oxygenową sekcją, której
   dotyczyły. Zastąpił ją komponent `KontaktCTA.astro` — sam pilnuje kontrastu,
   a opinie klientów mają w serwisie jedno miejsce: panel opinii Google. */

/* --- 4e. Miara wiersza w pytaniach i odpowiedziach ---
   Odpowiedzi szły przez całą szerokość sekcji (~130 znaków w wierszu).
   Ta sama miara co reszta tekstu na stronie. */
#div_block-172-14 {
  max-width: 72ch;
  margin-inline: auto;
}

/* --- 4f. FAQ jako accordion ---
   Trzy rozwinięte odpowiedzi to 1,4 ekrana ściany tekstu na telefonie, a pyta
   się zwykle o jedną rzecz. Treść zostaje w DOM (details tylko ją zwija, Google
   ją indeksuje), a blok JSON-LD FAQPage jest nietknięty. */
.faq-item {
  border-bottom: 1px solid rgb(0 0 0 / 0.12);
}

.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  cursor: pointer;
  /* 44 px celu dotykowego */
  padding: 0.9em 0;
  list-style: none;
}

/* Safari rysuje własny trójkąt mimo list-style:none */
.faq-q::-webkit-details-marker {
  display: none;
}

/* h3 zostaje dla SEO i czytnika, ale nie może rozpychać wiersza na blok */
.faq-q h3 {
  margin: 0;
  text-align: left;
}

.faq-q::after {
  content: "";
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform 0.2s ease;
}

.faq-item[open] .faq-q::after {
  transform: rotate(-135deg);
}

.faq-a {
  margin: 0 0 1.2em;
  text-align: left;
}

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

/* --- 5. Widoczny focus (Oxygen go gasi) --- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
[role="button"]:focus-visible {
  outline: 3px solid var(--brand-cyan);
  outline-offset: 2px;
}

/* --- 6. Pasek kontaktowy i link pomijający nawigację --- */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 10000;
}

.skip-link:focus {
  left: 1rem;
  top: 1rem;
  padding: 0.75rem 1.25rem;
  background: #fff;
  color: #16211e;
  border-radius: 4px;
  box-shadow: 0 4px 16px rgb(0 0 0 / 0.25);
}

.header-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0 1.25rem;
  border-radius: 999px;
  background: var(--brand-coral-text);
  color: #fff;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.5px;
  text-decoration: none;
  white-space: nowrap;
}

.header-phone:hover,
.header-phone:focus {
  background: #963a28;
  color: #fff;
}

/* --- 7. Hero „tryptyk usług" (wariant zaakceptowany w trybie live, 2026-08-10) ---
   Zastępuje dawne hero zdjęcie+kartonik: trzy klikalne panele usług w kolorach
   funkcyjnych (koral/mięta/cyjan) na prawdziwych zdjęciach + pasek wyszukiwarki. */
.hv1-hero {
  display: block;
}

/* H1 przejęty po usuniętej sekcji „witamy w Properton”: hero jest tryptykiem
   zdjęć i nie ma gdzie postawić nagłówka, ale strona musi go mieć — dla
   czytników ekranu i wyszukiwarek. */
.hv1-h1 {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hv1-panels {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  min-height: 66vh;
}

.hv1-panel {
  position: relative;
  display: flex;
  align-items: flex-end;
  padding: 40px;
  text-decoration: none;
  background-size: cover;
  background-position: center;
}

.hv1-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.82;
  /* zejście z najazdu szybsze niż wejście — pole koloru wraca bez ociągania */
  transition: opacity 0.25s ease-out;
}

.hv1-panel:hover::before,
.hv1-panel:focus-visible::before {
  opacity: 0.57;
  transition: opacity 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Przyciemnienie przy dolnej krawędzi — warunek czytelności podpisu (16px) na
   zdjęciu: bez niego biały tekst schodzi do 3,6:1 na jasnych kadrach.
   To chrome funkcyjne, nie ozdoba. */
.hv1-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(0 0 0 / 0.4), transparent 42%);
  pointer-events: none;
}

/* Cyjanowy obrys focusu ginie na cyjanowym panelu — na zdjęciach biały. */
.hv1-panel:focus-visible {
  outline: 3px solid #fff;
  outline-offset: -6px;
}

.hv1-sprzedaj {
  background-image: url(/assets/hero/sprzedaj-uscisk-dloni-kamienica.webp);
}

.hv1-sprzedaj::before {
  background: var(--brand-coral-text);
}

.hv1-kup {
  background-image: url(/assets/hero/kup-para-w-pustym-mieszkaniu.webp);
}

.hv1-kup::before {
  background: #2a7d6b;
}

.hv1-wynajmij {
  background-image: url(/assets/hero/wynajmij-klucze-w-drzwiach.webp);
}

.hv1-wynajmij::before {
  background: var(--brand-cyan);
}

.hv1-label {
  position: relative;
  z-index: 1;
  color: #fff;
  font-family: Lato, sans-serif;
  line-height: 1;
}

.hv1-word {
  display: block;
  font-size: 56px;
  font-weight: 800;
}

.hv1-sub {
  display: block;
  margin-top: 10px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.55px;
  transition: transform 0.25s ease-out;
}

/* Najazd: podpis dosuwa się do słowa usługi — przesunięcie, nie krycie;
   w spoczynku podpis jest w pełni widoczny (dotyk nie ma hovera). */
.hv1-panel:hover .hv1-sub,
.hv1-panel:focus-visible .hv1-sub {
  transform: translateY(-4px);
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

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

  .hv1-panel:hover .hv1-sub,
  .hv1-panel:focus-visible .hv1-sub {
    transform: none;
  }
  /* odsłona zdjęcia (opacity ::before) zostaje — to feedback stanu, nie ozdoba */
}

.hv1-search {
  background: #fff;
}

.hv1-search-inner {
  max-width: 1360px;
  margin: 0 auto;
  display: flex;
  gap: 20px;
  padding: 24px 20px;
  align-items: stretch;
}

.hv1-field {
  flex: 1 1 0;
  min-height: 55px;
  border: 0;
  border-radius: 0;
  background: #f2f2f2;
  color: #2a2a2a;
  font-family: Lato, sans-serif;
  font-weight: 600;
  font-size: 14px;
  padding: 0 16px;
}

.hv1-field::placeholder {
  color: #374047;
}

.hv1-submit {
  flex: 0 0 180px;
  min-height: 55px;
  border: 0;
  border-radius: 0;
  background: var(--brand-coral-text);
  color: #fff;
  font-family: Lato, sans-serif;
  font-weight: 700;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease-out;
}

.hv1-submit:hover {
  background: var(--brand-cyan);
}

@media (max-width: 991px) {
  .hv1-panels {
    grid-template-columns: 1fr;
    min-height: 0;
  }

  .hv1-panel {
    min-height: 190px;
    padding: 24px 20px;
  }

  .hv1-word {
    font-size: 40px;
  }

  .hv1-search-inner {
    flex-direction: column;
  }

  .hv1-submit {
    flex-basis: auto;
  }
}

/* --- 9. Rytm długiego tekstu ---
   Panele usług niosą po ~850 znaków w jednym bloku rozdzielonym <br><br>.
   Oko nie miało gdzie wejść: nagłówek, a potem jednolita plama. Teraz trzy
   stopnie — nagłówek, zdanie prowadzące (18px), tekst podstawowy — i prawdziwy
   odstęp między akapitami zamiast pustego wiersza. Panele mają ~250px zapasu
   w pionie (wysokość dyktuje zdjęcie), więc większy lead nie wydłuża strony. */
.ct-text-block p {
  margin: 0 0 20px;
}

.ct-text-block p:last-child {
  margin-bottom: 0;
}

.ct-text-block .us-lead {
  font-size: 18px;
  line-height: 1.5;
  margin-bottom: 24px;
}

/* Jedna miara dla czterech paneli: było 464 px i 525 px, czyli cztery takty
   o różnej szerokości. !important, bo .txt-left narzuca 68ch. */
#text_block-27-14,
#text_block-20-14,
#text_block-133-14,
#text_block-148-14 {
  max-width: 54ch !important;
}

/* Na szerokościach pośrednich (tablet, wąski laptop) 80-pikselowe wcięcia
   zaprojektowane pod szeroki układ zjadały miarę: 42 i 48 znaków w wierszu,
   różnica 16% między panelami. Poniżej 1320px wcięcia są symetryczne i mniejsze,
   więc cztery takty mają tę samą szerokość. */
@media (max-width: 1320px) and (min-width: 992px) {
  #div_block-120-14,
  #div_block-125-14,
  #div_block-131-14,
  #div_block-146-14 {
    padding-left: 24px;
    padding-right: 24px;
  }

  #div_block-16-14,
  #div_block-145-14 {
    padding-left: 24px;
  }
}

/* --- 10. Pytania i odpowiedzi: łączenie w pary ---
   Odstępy były równe, więc pytanie kleiło się do cudzej odpowiedzi tak samo
   mocno jak do swojej. Blisko wewnątrz pary, luźno między parami.
   (Puste <h3></h3>, których Oxygen używał jako odstępu, usunięte ze źródła.) */
#_rich_text-190-14 h3 {
  font-size: 24px;
  line-height: 1.25;
  margin: 52px 0 10px;
}

#_rich_text-190-14 h3:first-of-type {
  margin-top: 0;
}

#_rich_text-190-14 .faq-a {
  margin: 0;
}

/* Pasek mobilny — telefon był dotąd tylko w stopce, 8 sekcji od góry. */
.contact-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 9999;
  display: none;
  border-top: 1px solid rgb(0 0 0 / 0.08);
  background: #fff;
  box-shadow: 0 -4px 20px rgb(0 0 0 / 0.12);
  padding-bottom: env(safe-area-inset-bottom);
}

.contact-bar a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 56px;
  font-weight: 700;
  font-size: 16px;
  text-decoration: none;
}

.contact-bar .cb-call {
  background: var(--brand-coral-text);
  color: #fff;
}

.contact-bar .cb-mail {
  background: #fff;
  color: #16211e;
}

@media (max-width: 991px) {
  .contact-bar {
    display: flex;
  }

  /* miejsce na pasek, żeby nie zasłaniał stopki */
  body {
    padding-bottom: 56px;
  }

  .header-phone {
    display: none;
  }
}

/* --- 11. Nagłówek „zwarty pasek" ---
   PRZENIESIONE 2026-08-15 do `src/components/Header.astro`.

   Style jechały tutaj, bo nagłówek istniał tylko na stronach ze zrzutu,
   obok CSS-u z Oxygena. Gdy nagłówek stał się jednym komponentem dla całego
   serwisu, okazało się, że `Base.astro` (strony ofert) w ogóle nie ładuje
   tego pliku — nagłówek leciał tam bez stylu: 346 px zamiast 79, bez
   przyklejenia, logo 302 px. Style mieszkają teraz przy markupie i jadą
   razem z nim wszędzie. Oxygen nie zna klas `.naglowek__*`, więc nie ma
   już czego przebijać kolejnością ładowania. */

/* --- Podstrony usługowe: jeden układ, dwa kolory (2026-08-14) ---
   /sprzedaj i /kup to ta sama strona z inną usługą: hero ze zdjęciem pod
   filtrem koloru i formularzem, sekcja wprowadzająca z gniazdem na materiał,
   proces w policzalnych krokach, „dlaczego my", sekcja zamykająca. Poprawki
   12–16 opisują ten układ raz, a listy identyfikatorów niosą oba warianty.

   Dlaczego nadal po ID, a nie po klasach: Oxygen nazwał te same bloki inaczej
   na każdej stronie (`-16` i `-18`) i stylował je selektorami po ID. Reguła
   po klasie ma niższą swoistość i przegrałaby z arkuszem Oxygena — musiałaby
   nadrabiać lawiną `!important`. Dopisanie identyfikatora do listy jest
   uczciwsze niż udawanie, że zrzut ma warstwę komponentów.

   Kolor usługi wchodzi tu zmienną, nie kopią reguł: koral na /sprzedaj,
   mięta na /kup. Zasada trzech kolorów mówi, że kolor jednej usługi nie ma
   prawa pojawić się na stronie drugiej — także w narożniku pustego gniazda
   i w kratce zgody, dlatego zmienna siedzi na `<body>`, a nie na sekcji. */
.page-id-16 {
  --usluga: #b4442f;
}

.page-id-18 {
  --usluga: #2a7d6b;
}

.page-id-20 {
  --usluga: #00728a;
}

/* --- 12. Proces usługi na /sprzedaj i /kup: ostre krawędzie zamiast kół ---
   Sekcja niosła sześć zdjęć 353×353 w kołach i sześć numerów w koralowych
   kółkach — jedyne koła w serwisie poza pigułką telefonu, a DESIGN.md stawia
   sprawę wprost: ostre krawędzie wszędzie, wyjątkiem jest pigułka. Nowe
   komponenty (Doradcy, KontaktCTA) zerują zaokrąglenia Oxygena tak samo;
   ta sekcja została pominięta, bo siedzi w zrzucie.

   Uwaga na przyszłość: okrągłość NIE była w CSS — same pliki były wykadrowane
   do koła z przezroczystym tłem. Dlatego razem z tą korektą podmienione zostały
   zdjęcia w zrzucie na prostokątne (DANE ZASTĘPCZE, do dobrania tematycznie).

   Numery były pozycjonowane na oko pod okrąg — cztery różne warianty
   (right/bottom, top/left, left/bottom, top/right) na sześć kroków. Teraz
   jeden róg dla wszystkich: numeracja czyta się z góry, jak sekwencja.

   Odstępy między krokami szły na przemian 87 px i 120 px, bez powodu.
   Jeden takt dla całej sekcji. */
#div_block-26-16,
#div_block-56-69,
#div_block-63-69,
#div_block-70-69,
#div_block-77-69,
#div_block-84-69,
#div_block-69-18,
#div_block-84-18,
#div_block-90-18,
#div_block-105-18,
#div_block-111-18,
#div_block-21-20,
#div_block-36-20,
#div_block-42-20,
#div_block-57-20,
#div_block-63-20,
#div_block-78-20 {
  border-radius: 0;
  background-color: transparent;
  overflow: hidden;
}

/* wewnętrzne przesunięcia z Oxygena robiły miejsce na koralowy pierścień */
#div_block-26-16 > div,
#div_block-56-69 > div,
#div_block-63-69 > div,
#div_block-70-69 > div,
#div_block-77-69 > div,
#div_block-84-69 > div,
#div_block-69-18 > div,
#div_block-84-18 > div,
#div_block-90-18 > div,
#div_block-105-18 > div,
#div_block-111-18 > div,
#div_block-21-20 > div,
#div_block-36-20 > div,
#div_block-42-20 > div,
#div_block-57-20 > div,
#div_block-63-20 > div,
#div_block-78-20 > div {
  margin: 0;
}

/* Sekcja procesu stoi na szarości #f2f2f2, a pusty stan gniazda ma domyślnie
   dokładnie taką samą szarość — pole robiło się niewidzialne i zostawały same
   koralowe narożniki wiszące w powietrzu. Na tej sekcji pole jest białe;
   to ta sama zamiana ról, którą robią karty ofert na szarym tle. */
#div_block-26-16 figure,
#div_block-56-69 figure,
#div_block-63-69 figure,
#div_block-70-69 figure,
#div_block-77-69 figure,
#div_block-84-69 figure,
#div_block-69-18 figure,
#div_block-84-18 figure,
#div_block-90-18 figure,
#div_block-105-18 figure,
#div_block-111-18 figure,
#div_block-21-20 figure,
#div_block-36-20 figure,
#div_block-42-20 figure,
#div_block-57-20 figure,
#div_block-63-20 figure,
#div_block-78-20 figure {
  --gm-tlo: #fff;
}

/* Kadr kroku ma stały rozmiar niezależnie od tego, czy stoi w nim zdjęcie,
   czy gniazdo czekające na materiał — po podmianie nic się nie przesuwa. */
#div_block-26-16 img,
#div_block-56-69 img,
#div_block-63-69 img,
#div_block-70-69 img,
#div_block-77-69 img,
#div_block-84-69 img,
#div_block-26-16 figure,
#div_block-56-69 figure,
#div_block-63-69 figure,
#div_block-70-69 figure,
#div_block-77-69 figure,
#div_block-84-69 figure,
#div_block-69-18 img,
#div_block-84-18 img,
#div_block-90-18 img,
#div_block-105-18 img,
#div_block-111-18 img,
#div_block-69-18 figure,
#div_block-84-18 figure,
#div_block-90-18 figure,
#div_block-105-18 figure,
#div_block-111-18 figure,
#div_block-21-20 img,
#div_block-36-20 img,
#div_block-42-20 img,
#div_block-57-20 img,
#div_block-63-20 img,
#div_block-78-20 img,
#div_block-21-20 figure,
#div_block-36-20 figure,
#div_block-42-20 figure,
#div_block-57-20 figure,
#div_block-63-20 figure,
#div_block-78-20 figure {
  display: block;
  width: 353px;
  height: 353px;
  object-fit: cover;
  border-radius: 0;
}

/* Na ≤479 px Oxygen zwęża kadr kroku do 300×300, a sztywna figura 353
   wystawała z niego po 26 px z każdej strony. Overflow:hidden kadru ucinał
   wystającą część razem z pastylką licznika, która kotwiczy się do lewej
   krawędzi wrappera figury - z "1/6" zostawało "/6" (zgłoszenie właściciela,
   2026-08-27). Figura idzie za kadrem. */
@media (max-width: 479px) {
  :is(
      #div_block-26-16,
      #div_block-56-69,
      #div_block-63-69,
      #div_block-70-69,
      #div_block-77-69,
      #div_block-84-69,
      #div_block-69-18,
      #div_block-84-18,
      #div_block-90-18,
      #div_block-105-18,
      #div_block-111-18,
      #div_block-21-20,
      #div_block-36-20,
      #div_block-42-20,
      #div_block-57-20,
      #div_block-63-20,
      #div_block-78-20
    )
    :is(img, figure) {
    width: 300px;
    height: 300px;
  }
}

#div_block-53-69,
#div_block-59-69,
#div_block-66-69,
#div_block-73-69,
#div_block-80-69,
#div_block-87-69,
#div_block-72-18,
#div_block-87-18,
#div_block-93-18,
#div_block-108-18,
#div_block-114-18,
#div_block-24-20,
#div_block-39-20,
#div_block-45-20,
#div_block-60-20,
#div_block-66-20,
#div_block-81-20 {
  border-radius: 0;
  inset: 0 auto auto 0;
}

#div_block-36-16,
#div_block-58-16,
#div_block-78-16,
#div_block-78-18,
#div_block-99-18,
#div_block-30-20,
#div_block-51-20,
#div_block-72-20 {
  margin-top: 87px;
}

/* --- 13. Hero /sprzedaj: panel usługi zamiast wyszukiwarki cudzych ofert ---
   Ekran otwierający stronę sprzedaży nie dawał właścicielowi nic do zrobienia:
   jedynym elementem interaktywnym była wyszukiwarka bazy nieruchomości, czyli
   narzędzie kupującego. Nagłówek „sprzedaj z nami" stał zepchnięty na bok,
   koralowy na jasnym zdjęciu, bez akcji.

   Ten sam język, co hero strony głównej (poprawka 7): prawdziwe zdjęcie pod
   filtrem w kolorze usługi, gradient przy dolnej krawędzi dla czytelności,
   nagłówek małą literą przy dole. Tam trzy panele usług, tu jeden — bo strona
   dotyczy jednej usługi. Wyszukiwarka zostaje na stronie głównej, gdzie stoi
   pod tryptykiem i ma sens. */
#section-2-16,
#section-2-18,
#section-2-20 {
  position: relative;
  background-position: center;
}

#section-2-16::before,
#section-2-18::before,
#section-2-20::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--usluga);
  opacity: 0.82;
}

/* warunek czytelności białego tekstu na jasnym kadrze — chrome funkcyjne */
#section-2-16::after,
#section-2-18::after,
#section-2-20::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(0 0 0 / 0.4), transparent 42%);
  pointer-events: none;
}

/* Wysokość i wyrównanie jak w panelach tryptyku: treść siedzi przy dolnej
   krawędzi, nad nią pracuje zdjęcie. Bez tego sekcja spłaszczała się do paska,
   bo padding 296px z Oxygena robił miejsce pod kartonik wyszukiwarki. */
#section-2-16 > .ct-section-inner-wrap,
#section-2-18 > .ct-section-inner-wrap,
#section-2-20 > .ct-section-inner-wrap {
  position: relative;
  z-index: 1;
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: 80px;
  padding-bottom: 64px;
}

/* tekst schodzi z prawej krawędzi do lewej, jak w panelach na stronie głównej */
#div_block-3-16,
#div_block-4-16,
#div_block-3-18,
#div_block-4-18,
#div_block-3-20,
#div_block-4-20 {
  align-items: flex-start;
  text-align: left;
}

/* `padding-inline`, a nie sama prawa strona: Oxygen odsuwał nagłówek od środka
   strony, ale na /sprzedaj zrobił to paddingiem z prawej, a na /kup z lewej —
   ta sama intencja, dwa różne zapisy. Zerujemy obie krawędzie. */
#div_block-4-16,
#div_block-4-18,
#div_block-4-20 {
  width: 100%;
  padding-inline: 0;
}

#headline-5-16,
#text_block-7-16,
#headline-5-18,
#text_block-6-18,
#headline-5-20,
#text_block-6-20 {
  color: #fff;
}

/* Wyszukiwarka (#div_block-141-16) nie jest tu chowana CSS-em, tylko wycięta
   ze zrzutu — jej miejsce zajmuje szew <!--hero-zgloszenie-->, patrz poprawka 16. */

.hero-usluga__akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 28px;
  margin-top: 32px;
}

/* `.hero-usluga__cta` (biały przycisk prowadzący do formularza na dole strony)
   zniknął razem z poprawką 16 — formularz stoi teraz w hero, więc odnośnik do
   samego siebie nie miał już do czego prowadzić. */

.hero-usluga__tel {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: #fff;
  /* stopień `headline` z DESIGN.md — telefon jest tu drugą akcją, nie podpisem */
  font-size: 24px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-decoration: none;
  border-bottom: 2px solid rgb(255 255 255 / 0.6);
}

.hero-usluga__tel:hover,
.hero-usluga__tel:focus-visible {
  border-bottom-color: #fff;
}

/* biały obrys focusu — cyjanowy ginie na koralowym polu */
#section-2-16 a:focus-visible,
#section-2-18 a:focus-visible,
#section-2-20 a:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}

@media (max-width: 767px) {
  #section-2-16 > .ct-section-inner-wrap,
  #section-2-18 > .ct-section-inner-wrap,
  #section-2-20 > .ct-section-inner-wrap {
    padding-top: 80px;
    padding-bottom: 60px;
  }
}

/* --- 14. Sekcja wprowadzająca /sprzedaj: koniec ze ścianą i pustką ---
   Sekcja łamała trzy zasady systemu naraz. Nagłówek szedł wielką literą
   i w całości koralem, choć DESIGN.md mówi: małą literą, jedno słowo
   w kolorze usługi (sąsiednia sekcja „jak wygląda u nas proces sprzedaży"
   robi to poprawnie). Zdjęcie to był stockowy uścisk dłoni nad modelem
   domku, przy zasadzie „zdjęcia prawdziwe, nigdy stockowe" — usunięte
   ze zrzutu. Tekst stał w połowie szerokości, druga połowa świeciła pustką,
   a pod spodem szło 1372 znaki w jednej kolumnie.

   Najpierw (2026-08-13) treść poszła w dwa łamy przy tej samej liczbie słów.
   To leczyło kształt, nie chorobę: pięć akapitów w kółko powtarzało, że jesteśmy
   sprawdzonym biurem, więc dwa łamy dawały tylko dwie ściany zamiast jednej.

   Teraz (2026-08-14) tekst schodzi z pięciu akapitów do trzech, w jednej
   kolumnie z normalną miarą wiersza, a zwolnioną połowę zajmuje gniazdo
   na zdjęcie. Frazy, na które strona jest pozycjonowana, zostały co do słowa
   razem z pełną listą miejscowości — skrócone są powtórzenia, nie SEO. */
#headline-14-16,
#headline-13-18,
#headline-13-20 {
  color: var(--ink, #2a2a2a);
  max-width: 24ch;
}

#div_block-12-16,
#div_block-12-18,
#div_block-12-20 {
  width: 100%;
  padding-left: 0;
}

/* Tekst w kolumnie pierwszej (dwa wiersze: nagłówek z leadem, potem miasta),
   zdjęcie w drugiej — przez oba wiersze, więc kadr jest wysoki. */
#section-9-16 > .ct-section-inner-wrap,
#section-8-18 > .ct-section-inner-wrap,
#section-8-20 > .ct-section-inner-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 400px;
  /* odstęp wiersza jak między akapitami, nie jak między blokami — akapit
     z miejscowościami jest dalszym ciągiem tekstu, a nie osobną sekcją */
  gap: 24px 64px;
  align-items: start;
}

#div_block-10-16,
#div_block-9-18,
#div_block-9-20 {
  grid-column: 1;
  grid-row: 1;
}

/* Akapit z miejscowościami jest dalszym ciągiem tekstu, nie osobnym blokiem —
   odstęp robi margines akapitu, a nie odstęp siatki i padding z Oxygena. */
#div_block-18-16,
#div_block-15-18,
#div_block-15-20 {
  grid-column: 1;
  grid-row: 2;
  margin-top: 0;
  padding-top: 0;
}

#section-9-16 > .ct-section-inner-wrap > figure,
#section-8-18 > .ct-section-inner-wrap > figure,
#section-8-20 > .ct-section-inner-wrap > figure {
  grid-column: 2;
  grid-row: 1 / span 2;
}

/* Dwadzieścia osiem nazw miejscowości pogrubionych w jednym ciągu czyta się
   jak upychanie fraz, a nie jak zdanie. Pogrubienie zostaje przy nazwie
   głównego biura, lista wraca do zwykłego tekstu — treść i frazy bez zmian. */
.lista-miast {
  font-weight: 400;
}

@media (max-width: 991px) {
  #section-9-16 > .ct-section-inner-wrap,
  #section-8-18 > .ct-section-inner-wrap,
  #section-8-20 > .ct-section-inner-wrap {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  /* zdjęcie schodzi pod tekst; kolumna jedna, więc wiersze ustawiają się same */
  #section-9-16 > .ct-section-inner-wrap > figure,
  #section-8-18 > .ct-section-inner-wrap > figure,
  #section-8-20 > .ct-section-inner-wrap > figure {
    grid-column: 1;
    grid-row: auto;
  }
}

/* --- 15. Proces jako droga policzalna ---
   Sprzedajacy nie boi sie ceny, boi sie procesu: ile to potrwa i ile jeszcze
   przede mna. Numery krokow byly ozdoba — teraz sa licznikiem. „1" mowi,
   gdzie jestes; „/6" mowi, ile calosc ma w ogole krokow, wiec juz przy
   pierwszym zdjeciu wiadomo, ze droga sie konczy.

   Zadnej dekoracji: ten sam prostokat w kolorze uslugi, ta sama biel, tylko
   drugi stopien wielkosci (15px, `label-pill` z DESIGN.md). Bez przezroczystosci
   — biel z alfa zeszlaby ponizej AA na koralu. Czytnik ekranu przeczyta „1/6",
   czyli dokladnie to, co widzi wzrok.

   Mianownik stoi w tresci strony (`<span class="krok-licznik__z">`), a nie
   w `content` reguly ::after. Wczesniej byla to wartosc wpisana w CSS, wiec
   /kup — proces o pieciu krokach, nie szesciu — musialby dostac wlasna regule
   z innym napisem. Liczba krokow jest faktem o stronie, a fakty mieszkaja
   w tresci; CSS nadaje im tylko stopien wielkosci. */
.krok-licznik__z {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#div_block-53-69,
#div_block-59-69,
#div_block-66-69,
#div_block-73-69,
#div_block-80-69,
#div_block-87-69,
#div_block-72-18,
#div_block-87-18,
#div_block-93-18,
#div_block-108-18,
#div_block-114-18,
#div_block-24-20,
#div_block-39-20,
#div_block-45-20,
#div_block-60-20,
#div_block-66-20,
#div_block-81-20 {
  width: auto;
  min-width: 53px;
  padding-inline: 10px;
}

/* Sekcja szla od naglowka wprost w krok 1 i urywala sie po ostatnim kroku.
   Zdanie wprowadzajace nazywa cala droge, domkniecie ja zamyka i przekazuje
   do formularza — pierwszy krok jest jeden klik stad. */
.proces-wstep {
  max-width: 46ch;
  margin: 20px auto 0;
  font-size: 18px;
  line-height: 1.5;
}

.proces-domkniecie {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  /* rodzic z Oxygena to kolumna z `align-items:flex-start`, więc bez pełnej
     szerokości blok kleiłby się do lewej krawędzi mimo wyśrodkowanej treści */
  width: 100%;
  margin-top: 87px;
  text-align: center;
}

.proces-domkniecie p {
  max-width: 40ch;
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.6px;
}

.proces-domkniecie__cta {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 25px 10px;
  background: var(--usluga);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-decoration: none;
}

/* cyjan jako uniwersalny hover — tak samo jak przyciski uslug na glownej */
.proces-domkniecie__cta:hover,
.proces-domkniecie__cta:focus-visible {
  background: var(--brand-cyan);
  color: #fff;
}

@media (max-width: 767px) {
  .proces-domkniecie {
    margin-top: 60px;
  }

  .proces-domkniecie p {
    font-size: 18px;
  }
}

@media (max-width: 991px) {
  #headline-14-16,
  #headline-13-18,
  #headline-13-20 {
    max-width: none;
  }
}

/* Oxygen trzymał tu na wąskich ekranach `padding-top: 350px` — rezerwę pod
   kartonik wyszukiwarki, który zwisał z hero (`#div_block-141-16`,
   `bottom: -450px`). Wyszukiwarki nie ma od poprawki 16, więc został pas
   pustej bieli na trzysta pikseli. Takt jak w progu 991 px. */
@media (max-width: 767px) {
  #section-9-16 > .ct-section-inner-wrap,
  #section-8-18 > .ct-section-inner-wrap,
  #section-8-20 > .ct-section-inner-wrap {
    padding-top: 50px;
  }
}

/* --- 16. Hero /sprzedaj: formularz zgłoszenia w pierwszym ekranie (2026-08-14) ---
   Poprawka 13 zdjęła z hero wyszukiwarkę cudzych ofert i zostawiła nagłówek
   z telefonem — ekran otwierający stronę wciąż nie miał niczego, co sprzedający
   mógłby wypełnić. Teraz hero jest dwukolumnowe: po lewej zdjęcie pod koralem
   niesie „sprzedaj z nami" i numer, po prawej stoi biała płyta formularza
   (komponent HeroZgloszenie.astro, szew hero-zgloszenie).

   Dwie drogi kontaktu zostają równorzędne — tak jak w sekcji zamykającej —
   tylko obie awansują do pierwszego ekranu. Dlatego odnośnik „zgłoś
   nieruchomość" zniknął z lewej kolumny: prowadził do formularza na dole
   strony, a ten stoi teraz obok. */
#div_block-3-16,
#div_block-3-18,
#div_block-3-20 {
  display: grid;
  /* stała kolumna formularza: pola nie mają powodu rosnąć z szerokością ekranu,
     a nagłówek ma */
  grid-template-columns: minmax(0, 1fr) 420px;
  gap: 64px;
  align-items: end;
  width: 100%;
}

/* O wysokości sekcji decyduje sam formularz — i to jest zamierzone (prośba
   właściciela 2026-08-15: hero na desktopie niższe). Wcześniejsze 76vh
   dorzucało pustego kadru na wysokich ekranach; teraz płyta z zagęszczonymi
   odstępami (media ≥992px w HeroZgloszenie.astro) wyznacza pion, a zerowanie
   poniżej wyłącza też 60vh z poprawki 13. */
#section-2-16 > .ct-section-inner-wrap,
#section-2-18 > .ct-section-inner-wrap,
#section-2-20 > .ct-section-inner-wrap {
  min-height: 0;
}

@media (max-width: 1120px) {
  #div_block-3-16,
  #div_block-3-18,
  #div_block-3-20 {
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 40px;
  }
}

/* Poniżej 992 px kolumny stają w słupek — tak samo jak w sekcji zamykającej.
   Nagłówek zostaje pierwszy: obietnica przed formularzem, nie odwrotnie. */
@media (max-width: 991px) {
  #div_block-3-16,
  #div_block-3-18,
  #div_block-3-20 {
    grid-template-columns: 1fr;
    gap: 32px;
    align-items: stretch;
  }

  #section-2-16 > .ct-section-inner-wrap,
  #section-2-18 > .ct-section-inner-wrap,
  #section-2-20 > .ct-section-inner-wrap {
    min-height: 0;
  }
}

/* --- 17. Reszta bagażu Oxygena na /kup (2026-08-14) ---
   Trzy rzeczy, których poprawki 12–16 nie łapią, bo na /sprzedaj nie istniały.

   1. Kadry kroków na /kup miały pod spodem miętowe koło (`background-color`
      + `border-radius:50%`) i wewnętrzne przesunięcia pod koralowy pierścień;
      zdejmuje je poprawka 12. Zostaje jednak `@media (max-width:479px)`, gdzie
      Oxygen zbija kadr do 300 px, a licznik przesuwa `right`/`left` pod okrąg.
      Przy `inset: 0 auto auto 0` z poprawki 12 obie krawędzie byłyby ustawione
      naraz i prostokąt licznika rozciągnąłby się na całą szerokość kadru.
   2. Kadr trzymał sztywne 353 px także wtedy, gdy rodzic schodził do 300 px —
      różnicę zjadał `overflow:hidden`, czyli brief w gnieździe był przycinany
      na najwęższych telefonach. Kadr bierze teraz szerokość rodzica.
   3. Sekcja pod hero miała na wąskich ekranach `padding-top: 350px` rezerwy
      pod kartonik wyszukiwarki (`#div_block-147-18`, `bottom: -450px`).
      Wyszukiwarki nie ma — to ta sama korekta, co przy poprawce 15. */
@media (max-width: 479px) {
  #div_block-72-18,
  #div_block-87-18,
  #div_block-93-18,
  #div_block-108-18,
  #div_block-114-18,
  #div_block-24-20,
  #div_block-39-20,
  #div_block-45-20,
  #div_block-60-20,
  #div_block-66-20,
  #div_block-81-20 {
    inset: 0 auto auto 0;
  }
}

#div_block-26-16 figure,
#div_block-56-69 figure,
#div_block-63-69 figure,
#div_block-70-69 figure,
#div_block-77-69 figure,
#div_block-84-69 figure,
#div_block-69-18 figure,
#div_block-84-18 figure,
#div_block-90-18 figure,
#div_block-105-18 figure,
#div_block-111-18 figure,
#div_block-21-20 figure,
#div_block-36-20 figure,
#div_block-42-20 figure,
#div_block-57-20 figure,
#div_block-63-20 figure,
#div_block-78-20 figure {
  width: 100%;
  height: auto;
}

/* --- 18. Trzecia podstrona usługowa: /wynajmij (2026-08-15) ---
   Poprawki 12–17 opisują układ podstrony usługowej raz, a listy identyfikatorów
   niosą warianty: `-16` /sprzedaj, `-18` /kup, `-20` /wynajmij. Trzy rzeczy
   zostają poza tymi listami, bo dotyczą wyłącznie cyjanu.

   1. Zdjęcie hero. Oxygen dał /wynajmij dokładnie ten sam plik, co /sprzedaj
      (`sprzedaz-mieszkania-przez-agencje-properton-3.webp`). Pod filtrem koloru
      różnica koral/cyjan maskuje to na pierwszy rzut oka, ale obie strony
      otwiera ten sam kadr — a przy przejściu między nimi widać, że to jedno
      zdjęcie przemalowane. Wynajem dostaje własny: salon gotowy na najemcę,
      czyli dokładnie to, co ta usługa oddaje w ręce klienta.
   2. Hover domknięcia procesu. `.proces-domkniecie__cta:hover` idzie w cyjan
      jako uniwersalny hover — ale tutaj przycisk JEST cyjanowy, więc najazd
      nie robiłby nic. Ciemniejszy odcień tej samej barwy, ta sama para co
      koral → ciemny koral i ta sama, której używa panel w hero. */
#section-2-20 {
  background-image: url(/assets/hero/wynajmij-hero-salon.webp);
}

.page-id-20 .proces-domkniecie__cta:hover,
.page-id-20 .proces-domkniecie__cta:focus-visible {
  background: #005a6d;
}

/* --- 19. Hero usługowe na desktopie: zdjęcie zamiast pustego pola koloru (2026-08-15) ---
   Na szerokich ekranach lewa kolumna hero niosła tylko dwuwierszowy nagłówek
   i telefon w dolnym rogu — nad nimi stało ~600px płaszczyzny koloru, bo filtr
   0.82 (wartość z paneli tryptyku) gasi zdjęcie niemal do jednolitej barwy.
   Na telefonie ta sama sekcja jest zwarta i niczego jej nie brakuje.

   Trzy ruchy, wszystkie tylko od 992px w górę:
   1. Filtr luzuje do 0.66 — pusta przestrzeń staje się kadrem, który ma tam
      pracować. To nie nowy stan idiomu „zdjęcie pod kolorem": tryptyk już
      odsłania zdjęcie do 0.57 na hoverze, tu odsłona jest spoczynkowa, bo
      panel jest jeden i nie ma z kim konkurować.
   2. Słowo usługi idzie na pełną siłę pisma display: 96px (pułap 6rem),
      z systemową linią akcentu na polu koloru (biel 6px o kryciu 40% —
      ten sam zapis, co akcentowane słowa nagłówków na /kariera). Na tej
      stronie h1 JEST słowem usługi, więc linia podkreśla cały nagłówek,
      nie fragment. 60px z Oxygena było stopniem nagłówka sekcji, a to
      jest znak firmowy całej podstrony — jedyny element, który ma prawo
      krzyczeć, i dlatego wszystko wokół zostaje ciche.
   3. Pod nagłówkiem staje jednozdaniowy lead (Body-large 18px, biały) —
      obietnica strony jej własnymi słowami, wzięta ze wstępu, nie dopisana.
      Poniżej 992px lead znika: kolumny stoją w słupku, a wstęp z tą samą
      treścią zaczyna się ekran niżej — dwa razy tego samego nie czytamy.

   Gradient sięga wyżej niż dolne 42% z poprawki 13, bo stustopniowy nagłówek
   wchodzi tekstem w środek kadru: przy dole 0.5, w połowie ~0.2, gaśnie przy
   70% wysokości. To warunek czytelności (chrome funkcyjne), nie dekoracja. */
.hero-usluga__lead {
  display: none;
}

@media (min-width: 992px) {
  .hero-usluga__lead {
    display: block;
    margin: 28px 0 0;
    max-width: 44ch;
    color: #fff;
    font-family: Lato, sans-serif;
    font-size: 18px;
    font-weight: 400;
    line-height: 1.6;
  }

  #headline-5-16,
  #headline-5-18,
  #headline-5-20 {
    width: fit-content;
    padding-bottom: 12px;
    border-bottom: 6px solid rgb(255 255 255 / 0.4);
    font-size: 96px;
    line-height: 1;
    letter-spacing: 2px;
  }

  #text_block-7-16,
  #text_block-6-18,
  #text_block-6-20 {
    margin-top: 16px;
  }

  #section-2-16::before,
  #section-2-18::before,
  #section-2-20::before {
    opacity: 0.66;
  }

  #section-2-16::after,
  #section-2-18::after,
  #section-2-20::after {
    background: linear-gradient(
      to top,
      rgb(0 0 0 / 0.5),
      rgb(0 0 0 / 0.2) 48%,
      transparent 70%
    );
  }

  /* niższe hero (prośba właściciela): 80/64 z poprawki 13 zostaje dla widoków
     w słupku, desktop dostaje ciaśniejszą ramę wokół płyty */
  #section-2-16 > .ct-section-inner-wrap,
  #section-2-18 > .ct-section-inner-wrap,
  #section-2-20 > .ct-section-inner-wrap {
    padding-top: 56px;
    padding-bottom: 48px;
  }
}

/* Formularze kontaktowe: honeypot niewidoczny dla ludzi, czytelny status wysyłki. */
.contact-honeypot {
  position: absolute !important;
  left: -10000px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}

.wpcf7-response-output:not(:empty) {
  display: block;
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  border: 2px solid currentColor;
  background: #fff;
  color: #16211e;
}

.wpcf7-response-output.contact-status--success {
  color: #176647;
}

.wpcf7-response-output.contact-status--error {
  color: #9b2c20;
}

.wpcf7-submit:disabled {
  cursor: wait;
  opacity: 0.7;
}

/* --- 20. Ruch wejścia sekcji: kolor dojeżdża razem z sekcją (2026-08-19) ---
   Stany startowe (.ruch-czeka) nadają skrypty stron - /ruch-glowna.js na
   głównej, /ruch-uslugi.js na /sprzedaj, /kup i /wynajmij - i tylko sekcjom stojącym
   pod dolną krawędzią okna - bez JS i przy prefers-reduced-motion strona stoi
   widoczna od pierwszej klatki. IntersectionObserver + przejścia CSS, bo
   właściciel ogląda stronę w Firefoksie, gdzie scroll-driven CSS nie istnieje.

   Reguły celowo bez prefiksu strony (wcześniej `.home`): klasy .ruch-* istnieją
   wyłącznie tam, gdzie nadał je skrypt danej strony, więc selektor strony
   niczego nie zawężał, a blokował współdzielenie słownika między podstronami.

   Przejścia siedzą wyłącznie pod .ruch-wszedl: nadanie .ruch-czeka niczego nie
   animuje (element skacze do stanu startowego poza ekranem), a zdjęcie klasy
   odpala dojście. Jedna teza, kilka odmian:
   - atuty ("witamy" na głównej, "dlaczego Properton" na /sprzedaj) wchodzą
     jako lista ze schodkiem, kreska koloru dorysowuje się na końcu (scaleX);
   - w panelach usług pas 30px rozlewa się z góry (scaleY), zdjęcie odsłania
     się od strony pasa (clip-path), tekst dochodzi przesunięciem;
   - karty ofert wchodzą jako lista ze schodkiem.
   Nagłówki sekcji stoją nieruchomo - ruch niesie kolor i treść, nie wszystko. */

.ruch-czeka .ruch-atut {
  transform: translateY(26px);
  opacity: 0;
}

.ruch-wszedl .ruch-atut {
  transition:
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 140ms),
    opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 140ms);
}

/* Kreska koloru atutu (ostatnie dziecko kolumny) rysuje się po dojściu tekstu. */
.ruch-atut > div:last-child {
  transform-origin: left center;
}

.ruch-czeka .ruch-atut > div:last-child {
  transform: scaleX(0);
}

.ruch-wszedl .ruch-atut > div:last-child {
  transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1)
    calc(var(--ruch-krok, 0) * 140ms + 450ms);
}

/* Panel usługi: pas koloru rozlewa się z góry w dół. */
.ruch-pas {
  transform-origin: center top;
}

.ruch-czeka .ruch-pas {
  transform: scaleY(0);
}

.ruch-wszedl .ruch-pas {
  transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Zdjęcie panelu odsłania się od strony pasa - kolor "podaje" kadr dalej.
   Na /sprzedaj odsłona idzie od strony tekstu: treść "podaje" kadr. */
.ruch-czeka .ruch-zdjecie--od-lewej {
  clip-path: inset(0 100% 0 0);
}

.ruch-czeka .ruch-zdjecie--od-prawej {
  clip-path: inset(0 0 0 100%);
}

.ruch-wszedl .ruch-zdjecie {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s;
}

/* Tekst panelu dochodzi przesunięciem, chwilę po starcie pasa. Schodek
   (--ruch-krok) domyślnie zerowy - główna używa pojedynczych tekstów,
   /sprzedaj układa z nich krótkie listy. */
.ruch-czeka .ruch-tekst {
  transform: translateY(30px);
  opacity: 0;
}

.ruch-wszedl .ruch-tekst {
  transition:
    transform 1s cubic-bezier(0.16, 1, 0.3, 1) calc(0.15s + var(--ruch-krok, 0) * 140ms),
    opacity 1s cubic-bezier(0.16, 1, 0.3, 1) calc(0.15s + var(--ruch-krok, 0) * 140ms);
}

/* Karty najnowszych ofert: lista wchodzi jak lista. */
.ruch-czeka .ruch-karta {
  transform: translateY(34px);
  opacity: 0;
}

.ruch-wszedl .ruch-karta {
  transition:
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 170ms),
    opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 170ms);
}

/* --- 21. Ruch podstron usługowych: wejście z głównej i kadry procesu (2026-08-27) ---
   Na /sprzedaj, /kup i /wynajmij wchodzi się niemal zawsze z głównej, więc
   podstrona dostaje moment autorski na starcie: hero nie stoi gotowy, tylko
   "dojeżdża" w tej samej gramatyce, co sekcje głównej. Zdjęcie tła stoi od
   pierwszej klatki (żadnego białego błysku), "sprzedaj"/"kup"/"wynajmij"
   i "z nami" wjeżdżają razem jednym dojściem (odsłona clip-pathem odrzucona
   przez właściciela - "robi się brzydko"), potem lead, na końcu unosi się
   biały panel zgłoszenia.

   Klasy .ruch-hero i .ruch-hero-fraza nadaje /ruch-uslugi.js (defer, przed
   pierwszym malowaniem); bez JS i przy prefers-reduced-motion hero stoi
   widoczny od razu. Keyframes z `both`, żeby stan startowy trzymał się
   także przez czas opóźnienia. */

@keyframes ruch-dojscie {
  from {
    transform: translateY(28px);
    opacity: 0;
  }
}

/* Nagłówek usługi i "z nami" to jedna fraza - wjeżdżają jednym taktem. */
.ruch-hero .ruch-hero-fraza {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
}

.ruch-hero .hero-usluga__lead {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.55s both;
}

.ruch-hero .hz {
  animation: ruch-dojscie 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.8s both;
}

/* Krok procesu: koralowe koło rośnie ze środka (kolor dojeżdża pierwszy),
   licznik 1/6 wskakuje na gotowe koło, tekst kroku dochodzi przesunięciem.
   Licznik jest dzieckiem koła, więc transformacje się składają - stan
   startowy scale(0) liczy się od już przeskalowanego rodzica i niczego
   nie rozjeżdża. */
.ruch-czeka .ruch-kolo {
  transform: scale(0.55);
  opacity: 0;
}

.ruch-wszedl .ruch-kolo {
  transition:
    transform 1.5s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

.ruch-czeka .ruch-licznik {
  transform: scale(0);
}

.ruch-wszedl .ruch-licznik {
  transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1) 0.6s;
}

/* Tempo podstron usługowych: właściciel poprosił o wolniejszy ruch
   (2026-08-27, przy /sprzedaj). Zwolnienie siedzi w nadpisaniach
   zakresowanych do stron usługowych, a nie w regułach wspólnych —
   tempo głównej jest zaakceptowane i zostaje. */
:is(.page-id-16, .page-id-18, .page-id-20) .ruch-wszedl .ruch-tekst {
  transition:
    transform 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms),
    opacity 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms);
}

:is(.page-id-16, .page-id-18, .page-id-20) .ruch-wszedl .ruch-zdjecie {
  transition: clip-path 1.9s cubic-bezier(0.16, 1, 0.3, 1) 0.3s;
}

:is(.page-id-16, .page-id-18, .page-id-20) .ruch-wszedl .ruch-atut {
  transition:
    transform 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 220ms),
    opacity 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 220ms);
}

:is(.page-id-16, .page-id-18, .page-id-20) .ruch-wszedl .ruch-atut > div:last-child {
  transition: transform 1.1s cubic-bezier(0.16, 1, 0.3, 1)
    calc(var(--ruch-krok, 0) * 220ms + 650ms);
}

:is(.page-id-16, .page-id-18, .page-id-20) .ruch-wszedl .ruch-karta {
  transition:
    transform 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 240ms),
    opacity 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(var(--ruch-krok, 0) * 240ms);
}

/* --- 22. Ruch /kariera: ta sama gramatyka, co podstrony usługowe (2026-09-25) ---
   Klasy nadaje /ruch-kariera.js (defer, przed pierwszym malowaniem); bez JS
   i przy prefers-reduced-motion strona stoi widoczna od razu. Hero wchodzi
   jak na /sprzedaj: nagłówek, lead, warunki, na końcu przycisk. Reszta
   strony przy scrollu: portret odsłania się od strony wyimka, głos
   dochodzi schodkiem, punkty wsparcia i formularz wchodzą jak lista.
   Tempo = tempo podstron usługowych (właściciel: „za szybkie - zwolnij"). */

.ruch-hero .ka-h1 {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
}

.ruch-hero .ka-lead {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.55s both;
}

.ruch-hero .ka-warunki {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.75s both;
}

.ruch-hero .ka-cta {
  animation: ruch-dojscie 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.95s both;
}

/* Odsłona portretu: okno kadru (figura) wjeżdża od strony wyimka, a zdjęcie
   w środku jedzie tyle samo w przeciwną stronę - portret stoi w miejscu,
   rośnie tylko widoczny pas, jak przy clip-path. Ale transform liczy
   kompozytor, a clip-path przemalowywał zdjęcie w każdej klatce i na
   słabszych telefonach klatkował (2026-09-29). Przycina okno, nie kadr -
   inaczej przeciw-przesunięte zdjęcie wraca na miejsce całe. */
.ka-odslona > .gm {
  overflow: hidden;
}

.ruch-czeka .ka-odslona--od-prawej > .gm,
.ruch-czeka .ka-odslona--od-lewej > .gm > * {
  transform: translateX(100%);
}

.ruch-czeka .ka-odslona--od-lewej > .gm,
.ruch-czeka .ka-odslona--od-prawej > .gm > * {
  transform: translateX(-100%);
}

.ka .ruch-wszedl .ka-odslona > .gm,
.ka .ruch-wszedl .ka-odslona > .gm > * {
  transition: transform 1.9s cubic-bezier(0.16, 1, 0.3, 1) 0.3s;
}

/* Rozkładówka widoczna od startu zamyka wejście hero: portret odsłania się
   od strony wyimka, głos dochodzi schodkiem - ta sama choreografia, co przy
   scrollu, tylko w keyframes, zaraz po przycisku hero. */
@keyframes ka-z-prawej {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}

@keyframes ka-z-lewej {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}

.ka-roz.ruch-hero .ka-odslona--od-prawej > .gm,
.ka-roz.ruch-hero .ka-odslona--od-lewej > .gm > * {
  animation: ka-z-prawej 1.9s cubic-bezier(0.16, 1, 0.3, 1) 1.1s both;
}

.ka-roz.ruch-hero .ka-odslona--od-lewej > .gm,
.ka-roz.ruch-hero .ka-odslona--od-prawej > .gm > * {
  animation: ka-z-lewej 1.9s cubic-bezier(0.16, 1, 0.3, 1) 1.1s both;
}

.ka-roz.ruch-hero .ka-roz-krok {
  animation: ruch-dojscie 1.5s cubic-bezier(0.16, 1, 0.3, 1)
    calc(1.35s + var(--ruch-krok, 0) * 200ms) both;
}

/* Portret jeszcze się nie zdekodował: cała rozkładówka stoi w stanie
   startowym (both trzyma go przez opóźnienie), żeby odsłona nie pokazała
   pustego pola. Klasę zdejmuje /ruch-kariera.js. */
.ka-roz--czeka-na-zdjecie * {
  animation-play-state: paused !important;
}

.ka .ruch-wszedl .ruch-tekst {
  transition:
    transform 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms),
    opacity 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms);
}

.ka .ruch-wszedl .ruch-karta {
  transition:
    transform 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms),
    opacity 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms);
}

/* --- 23. Ruch /kontakt: ta sama gramatyka, co /kariera i podstrony usługowe (2026-09-25) ---
   Klasy nadaje /ruch-kontakt.js (defer, przed pierwszym malowaniem); bez JS
   i przy prefers-reduced-motion strona stoi widoczna od razu. Hero wchodzi
   jak na /sprzedaj: nagłówek, lead, potem cztery fakty schodkiem, na końcu
   cichszy rząd danych rejestrowych. Przy scrollu pas doradców i sekcja
   „porozmawiajmy o" (tu treść główna) dochodzą, formularz wchodzi ostatni.
   Tempo = tempo podstron usługowych (właściciel: „za szybkie - zwolnij"). */

.ruch-hero .kt-tytul {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
}

.ruch-hero .kt-lead {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.55s both;
}

.ruch-hero .kt-pozycja {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1)
    calc(0.8s + var(--ruch-krok, 0) * 220ms) both;
}

.ruch-hero .kt-rejestr {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 1.55s both;
}

/* Pas doradców widoczny od startu (szeroki ekran) zamyka wejście hero. */
.ruch-hero .kt-h2 {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 1.7s both;
}

.ruch-hero .kt-doradcy-tekst {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 1.9s both;
}

.ruch-hero .kt-doradcy-akcja {
  animation: ruch-dojscie 1.4s cubic-bezier(0.16, 1, 0.3, 1) 2.1s both;
}

:is(.kt, .kc) .ruch-wszedl .ruch-tekst {
  transition:
    transform 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms),
    opacity 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms);
}

:is(.kt, .kc) .ruch-wszedl .ruch-karta {
  transition:
    transform 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms),
    opacity 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms);
}

/* --- 24. Ruch /o-nas: ta sama gramatyka, co /kariera, /kontakt i podstrony usługowe (2026-09-28) ---
   Klasy nadaje /ruch-o-nas.js (defer, przed pierwszym malowaniem); bez JS
   i przy prefers-reduced-motion strona stoi widoczna od razu. Hero wchodzi
   jak na /sprzedaj: etykieta z nagłówkiem, lead, na końcu przycisk; zdjęcie
   stoi. Pasek liczb widoczny od startu domyka wejście hero schodkiem. Przy
   scrollu panele jak panele usług na głównej (pas, zdjęcie od strony pasa,
   tekst), wartości, doradcy i opinie dochodzą, karty wchodzą jako lista.
   Tempo = tempo podstron usługowych (właściciel: „za szybkie - zwolnij"). */

.ruch-hero .oa-etykieta,
.ruch-hero .oa-tytul {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
}

.ruch-hero .oa-lead {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.55s both;
}

.ruch-hero .oa-przycisk {
  animation: ruch-dojscie 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.8s both;
}

.oa-liczby.ruch-hero .oa-liczby-lista > li {
  animation: ruch-dojscie 1.3s cubic-bezier(0.16, 1, 0.3, 1)
    calc(1.1s + var(--ruch-krok, 0) * 220ms) both;
}

.oa .ruch-wszedl .ruch-pas {
  transition: transform 1.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.oa .ruch-wszedl .ruch-zdjecie {
  transition: clip-path 1.9s cubic-bezier(0.16, 1, 0.3, 1) 0.3s;
}

.oa .ruch-wszedl .ruch-tekst {
  transition:
    transform 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms),
    opacity 1.5s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 200ms);
}

.oa .ruch-wszedl .ruch-karta {
  transition:
    transform 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms),
    opacity 1.3s cubic-bezier(0.16, 1, 0.3, 1) calc(0.25s + var(--ruch-krok, 0) * 240ms);
}
