/* ─ Ł&I Przyczepy Kempingowe ──────────────────────────────────────────
   Motyw: JASNY papier na całej stronie (theme lock, bez sekcji-wyjątków).
   Akcent: granat #1b3a6b (odświeżenie 09.10.2026, wcześniej zieleń #1e4a30) - jeden kolor, wszędzie. Dobrany pod tusz
   ilustracji (próbka z rysunków: rgb 0-16 / 16-40 / 0-16), żeby rysunki
   i interfejs były tym samym atramentem.
   Typografia: Kalam (nagłówki, odręczna) + Patrick Hand (tekst).
   Kształty: jeden system - "maźnięcie pędzlem" (nieregularny border-radius)
   na przyciskach i podkreśleniach, 14px na kartach i mediach.
   ⭐ Zdjęcia: od 28.09 BEZ białych ramek i bez obrotu (Łukasz wybrał wariant C
      z trzech lokalnych) - zaokrąglone 20px, chłodny cień, a na kartach ofert
      nazwa + rok/DMC + cena leżą NA zdjęciu, na ciemnym gradiencie u dołu.
      Stare ramki (polaroid z obrotem) są w historii: `_backup_front_20260928-*`.
   ------------------------------------------------------------------ */

/* Kalam - nagłówki. 1 = latin-ext (polskie znaki), 2 = latin. */
@font-face{font-family:Kalam;font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/kalam-400-1.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:Kalam;font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/kalam-400-2.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:Kalam;font-style:normal;font-weight:700;font-display:swap;
  src:url(fonts/kalam-700-1.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:Kalam;font-style:normal;font-weight:700;font-display:swap;
  src:url(fonts/kalam-700-2.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

/* Patrick Hand - tekst czytany. */
@font-face{font-family:'Patrick Hand';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/hand-1.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Patrick Hand';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/hand-2.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

:root{
  /* ⭐ 28.09: chłodny błękit zamiast beżu (Łukasz: beż „za bardzo jak u tego
     z Rudy Śląskiej”). Stary beż: #f2e9d8 / #fffdf6 / #e9dec7 / #d9cdb4,
     tusz #2e2418 / #6b5d48. Cienie w rgba(27,37,45,…) = kolor --tusz. */
  --papier:#e9eff2;        /* tło strony */
  --papier-jasny:#ffffff;  /* karta, ramka zdjęcia */
  --papier-cien:#dbe4ea;   /* wypełnienia, kafle */
  --linia:#c6d2da;         /* obramowania i separatory */
  --tusz:#1b252d;          /* tekst główny */
  --tusz-mut:#51606b;      /* tekst drugorzędny */
  --zielen:#1b3a6b;        /* AKCENT - jedyny */
  --zielen-jas:#2a5294;    /* hover akcentu */
  --e:cubic-bezier(.16,1,.3,1);
  --wrap:1240px;
  --r:14px;
  /* maźnięcie pędzlem - ten sam kształt na przyciskach i podkreśleniach */
  --pedzel:255px 14px 225px 14px/14px 225px 14px 255px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--papier);color:var(--tusz);
  font-family:'Patrick Hand',ui-rounded,'Segoe UI',sans-serif;
  font-size:19px;line-height:1.62;-webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit}

/* Ziarno papieru. Osobna warstwa, fixed + pointer-events:none, żeby GPU nie
   przemalowywało jej przy każdym przewinięciu (to zabija FPS na telefonie). */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E");
}
body>*{position:relative;z-index:1}

.wrap{width:min(100% - 40px,var(--wrap));margin-inline:auto}
.mut{color:var(--tusz-mut)}
.sr{max-width:56ch}

.skip{position:absolute;left:-9999px;top:0;z-index:60;background:var(--zielen);
  color:#fff;padding:10px 18px;border-radius:var(--pedzel);text-decoration:none}
.skip:focus{left:16px;top:12px}
:focus-visible{outline:2px solid var(--zielen);outline-offset:3px;border-radius:4px}

/* ── nagłówki ─────────────────────────────────────────────────────── */
h1,h2,h3{font-family:Kalam,cursive;font-weight:700;line-height:1.18;
  letter-spacing:.01em;margin:0}

/* ⛔ `display:table` (nie block, nie inline-block): pudełko kurczy się do
   szerokości tekstu ORAZ daje się wyśrodkować przez margin-inline:auto.
   Przy `display:block` podkreślenie liczyło środek od całego kontenera,
   nie od napisu, i uciekało w lewo. Złapane 28.09.2026. */
.sek__tyt{font-size:clamp(1.85rem,3.6vw,2.75rem);margin:0 0 16px;position:relative;
  display:table;padding-bottom:.26em}
/* Pędzlowe podkreślenie - to samo maźnięcie co na przyciskach.
   ⛔ STAŁA szerokość, nie procent nagłówka. Przy 46% każdy tytuł dostawał inny
   pasek, a przy sześciu językach różnice robiły się drastyczne ("Køb uden
   overraskelser" vs "Kupujesz bez niespodzianek") i wyglądało to na przypadek.
   Stała długość czyta się jako celowy znak. Zgłoszone przez Łukasza 28.09. */
.sek__tyt::after{content:"";position:absolute;left:0;bottom:0;width:132px;
  height:6px;background:var(--zielen);opacity:.85;border-radius:var(--pedzel)}
.sek__tyt--c{margin-inline:auto;text-align:center}
.sek__tyt--c::after{left:50%;transform:translateX(-50%)}

.brew{font-family:Kalam,cursive;font-weight:700;font-size:13px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--tusz-mut);margin:0 0 6px}

.lead{color:var(--tusz-mut);max-width:58ch;margin:0 0 22px;font-size:1.06rem}

/* ── przyciski ────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:Kalam,cursive;font-weight:700;font-size:1.02rem;letter-spacing:.02em;
  padding:13px 30px;border-radius:var(--pedzel);text-decoration:none;
  border:2px solid transparent;cursor:pointer;white-space:nowrap;
  transition:transform .18s var(--e),background .2s,border-color .2s,color .2s}
.btn--gl{background:var(--zielen);color:#fff}
.btn--gl:hover{background:var(--zielen-jas)}
.btn--duch{background:transparent;color:var(--zielen);border-color:var(--zielen)}
.btn--duch:hover{background:var(--zielen);color:#fff}
.btn--sm{padding:9px 20px;font-size:.94rem;background:var(--zielen);color:#fff}
.btn--blok{display:flex;width:100%;margin-bottom:10px}
/* Oba numery w jednym przycisku, jeden pod drugim (Łukasz 28.09: „wszędzie po
   dwa numery"). Szerokość jak przy jednym numerze - mieści się w nagłówku
   i na pasku oferty na telefonie. Każdy numer osobnym linkiem, min. 24 px
   wysokości (cel dotykowy WCAG 2.5.8). */
.tel2{display:inline-flex;flex-direction:column;flex:0 0 auto;padding:3px 16px;
  background:var(--zielen);border-radius:var(--pedzel)}
.tel2 a{display:block;padding:2px 0;color:#fff;text-decoration:none;text-align:center;
  font-family:Kalam,cursive;font-weight:700;font-size:.9rem;line-height:1.45;
  letter-spacing:.02em;white-space:nowrap}
.tel2 a+a{border-top:1px solid rgba(255,255,255,.28)}
.tel2 a:hover{text-decoration:underline}
.btn:active{transform:translateY(1px) scale(.99)}

/* ── nawigacja ────────────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:40;background:rgba(233,239,242,.9);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--linia)}
.nav__in{display:flex;align-items:center;gap:22px;height:70px}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none;margin-right:auto}
/* Znak firmowy = SAM NAPIS, bez ikony (decyzja Łukasza 28.09).
   ⛔ Nie wracać do wciskania „Ł&I" w rysunek przyczepy - trzy podejścia,
   za każdym razem napis wychodził krzywo przy zmianie skali. */
.brand__txt{display:flex;flex-direction:column;line-height:1.1}
.brand__txt b{font-family:Kalam,cursive;font-weight:700;font-size:1.42rem;
  color:var(--zielen);letter-spacing:.02em}
.brand__txt>span{font-family:Kalam,cursive;font-weight:700;font-size:.84rem;
  letter-spacing:.11em;text-transform:uppercase;color:var(--tusz)}
.brand__txt em{font-style:normal;font-size:.76rem;color:var(--tusz-mut);
  letter-spacing:.04em}
.brand__txt{display:flex;flex-direction:column;font-family:Kalam,cursive;
  font-weight:700;font-size:1rem;line-height:1.15}
.brand__txt em{font-style:normal;font-weight:400;font-size:.8rem;color:var(--tusz-mut)}
/* ── przełącznik języka ───────────────────────────────────────────────
   Flagi są samodzielnie hostowane (assets/flagi), nie emoji: emoji flag
   nie renderuje się na Windowsie w ogóle. Kod kraju obok flagi, bo sama
   flaga to kiepski wskaźnik języka dla kogoś, kto jej nie zna. */
.jez{display:flex;align-items:center;gap:2px}
.jez__p{display:flex;align-items:center;gap:5px;padding:5px 7px;border-radius:8px;
  text-decoration:none;opacity:.5;transition:opacity .2s,background .2s}
.jez__p img{width:22px;height:15px;object-fit:cover;border-radius:2px;
  box-shadow:0 0 0 1px rgba(27,37,45,.18)}
.jez__p span{font-family:Kalam,cursive;font-weight:700;font-size:.78rem;
  letter-spacing:.04em;color:var(--tusz-mut)}
.jez__p:hover{opacity:.9;background:rgba(27,37,45,.06)}
.jez__p.jest{opacity:1}
.jez__p.jest span{color:var(--zielen)}

/* ── menu na telefon ──────────────────────────────────────────────────
   Przycisk to same trzy kreski, które po otwarciu składają się w krzyżyk,
   a pozycje menu wjeżdżają kaskadą. Zero biblioteki, ~15 linii JS.
   ⛔ BEZ przyczepki w przycisku - Łukasz 28.09: „bez sensu to wygląda".
   ⛔ Zwinięty panel ma `visibility:hidden` - bez tego linki zostają w kolejce
      tabulatora i klawiatura wpada w niewidoczne menu. */
.hb{display:none;align-items:center;justify-content:center;width:42px;height:40px;
  padding:0;margin-left:2px;flex:0 0 auto;
  background:none;border:1px solid var(--linia);border-radius:10px;
  color:var(--zielen);cursor:pointer}
.hb__kr{display:grid;gap:3.5px}
.hb__kr i{display:block;width:19px;height:2px;background:currentColor;border-radius:2px;
  transition:transform .35s var(--e),opacity .25s}
.nav.otw .hb__kr i:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.nav.otw .hb__kr i:nth-child(2){opacity:0}
.nav.otw .hb__kr i:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}

.mmenu{display:none;overflow:hidden;visibility:hidden;
  border-top:1px solid var(--linia);background:var(--papier-jasny);
  grid-template-rows:0fr;transition:grid-template-rows .42s var(--e),visibility 0s .42s}
.nav.otw .mmenu{grid-template-rows:1fr;visibility:visible;transition-delay:0s}
.mmenu__in{min-height:0;display:flex;flex-direction:column}
.mmenu a{padding:15px 0;text-decoration:none;font-family:Kalam,cursive;
  font-weight:700;font-size:1.18rem;color:var(--tusz);
  border-bottom:1px solid var(--linia);
  opacity:0;transform:translateX(-14px);
  transition:opacity .4s var(--e),transform .4s var(--e)}
.mmenu a:last-child{border-bottom:0}
.nav.otw .mmenu a{opacity:1;transform:none;
  transition-delay:calc(90ms + var(--i) * 70ms)}

.nav__links{display:flex;gap:26px}
.nav__links a{color:var(--tusz-mut);text-decoration:none;font-size:1.02rem;
  transition:color .2s}
.nav__links a:hover{color:var(--zielen)}

/* ── znak „Ł&I → Łukasz & Iwona" ──────────────────────────────────────
   ⛔⛔ NIE ZMIENIAĆ: .marka MUSI mieć width:fit-content, bo kreska pod
   spodem (::after, scaleX) rozciąga się dokładnie do szerokości tekstu.
   Przy width:100% kreska jedzie przez pół ekranu i efekt się rozpada.
   ⛔ Litery mają CIĄGŁY indeks --i 0-8 przez oba imiona - stagger nie
   restartuje się na „Iwona".                                          */
.marka{position:relative;display:flex;width:fit-content;align-items:baseline;
  gap:.3em;margin:0 0 24px;font-family:Kalam,cursive;
  font-size:clamp(1.45rem,3.6vw,2.15rem);font-weight:700;letter-spacing:0;
  color:var(--zielen);animation:markaIn .62s var(--e) both}
@keyframes markaIn{from{opacity:0;transform:translateY(10px)}}
.marka::after{content:"";position:absolute;left:0;right:0;bottom:-.18em;height:3px;
  background:currentColor;opacity:.3;border-radius:var(--pedzel);
  transform:scaleX(0);transform-origin:left;
  animation:kreskaIn .7s var(--e) .38s both}
@keyframes kreskaIn{to{transform:scaleX(1)}}
.marka__cz{display:inline-flex;align-items:baseline}
.marka__amp{opacity:.4;transition:opacity .55s var(--e)}
.marka.jest .marka__amp{opacity:.85;transition-delay:.25s}
/* ⛔⛔ `white-space:nowrap` JEST OBOWIĄZKOWE. Przy `max-width:0` litery imienia
   łamią się każda do osobnej linii wewnątrz zerowej szerokości - `overflow:hidden`
   je ukrywa, ale pudełko rośnie w pionie i cały znak rozjeżdża się na 279px
   zamiast 56px. Widać to dopiero przy POWTÓRCE (najechanie/klik), bo wtedy klasa
   `jest` jest zdejmowana na 380ms. Zmierzone 28.09.2026. */
.roz{display:inline-block;max-width:0;overflow:hidden;font-style:normal;
  white-space:nowrap;vertical-align:bottom;
  transition:max-width .5s var(--e)}
.marka.jest .roz{max-width:7ch;transition-duration:.9s}
.marka.jest .roz--2{transition-delay:.14s}
.roz>span{display:inline-block;opacity:0;transform:translateX(.4em);filter:blur(5px);
  transition:opacity .46s var(--e),transform .52s var(--e),filter .46s var(--e);
  transition-delay:calc(var(--i) * 44ms)}
.marka.jest .roz>span{opacity:1;transform:none;filter:blur(0)}
/* Przyczepka dojeżdża na końcu, już po rozwinięciu imion (ostatnia litera
   kończy się ok. 44ms×8 + 0,46s). Wpięta w tę samą klasę `jest`, więc
   powtórka po najechaniu/kliknięciu działa razem z resztą. */
.marka__woz{flex:0 0 auto;align-self:center;width:clamp(34px,5.4vw,50px);height:auto;
  margin-left:.18em;opacity:0;transform:translateX(-85%);
  transition:opacity .5s var(--e) .62s,transform .78s var(--e) .62s}
.marka.jest .marka__woz{opacity:.92;transform:translateX(0)}

/* ── intro: zasłona przy wejściu na główną ────────────────────────────
   Łukasz 28.09: jasne tło zasłania stronę, przejeżdża ZDJĘCIOWY zestaw
   auto + przyczepa, za nim pojawia się napis, potem zasłona znika i rusza hero.
   ⭐ Napis odsłania KURTYNA (.intro__jazda::before) przyczepiona do tyłu
      zestawu - jedzie razem z nim, więc napis wyłania się dokładnie za
      przyczepą, bez synchronizowania czasów. Kurtyna ma kolor zasłony, więc
      zasłona MUSI być jednolita (bez ziarna) - inaczej widać krawędź kurtyny.
   ⛔ Bez JS znika sama (animacja CSS). Z JS: przy każdym wejściu (poza
      kotwicą #...), klik pomija,
      `html.intro-gra` wstrzymuje animacje hero do końca intra.
   ⛔ Czas `introZnika` (3,6 s) = CZAS_INTRO w app.js. Przejazd 3,1 s (Łukasz 28.09:
      „trochę wolniej” - było 2,2 s). */
.intro{position:fixed;inset:0;z-index:100;display:grid;place-items:center;
  overflow:hidden;background:var(--papier-jasny);cursor:pointer;
  animation:introZnika .6s var(--e) 3.6s forwards}
.intro.pomin{animation:introPomin .35s var(--e) forwards}
@keyframes introZnika{to{opacity:0;visibility:hidden}}
@keyframes introPomin{to{opacity:0;visibility:hidden}}
html.bez-intro .intro{display:none}
html.intro-gra{overflow:hidden}
html.intro-gra .hero *{animation-play-state:paused}
.intro__napis{position:relative;z-index:1;display:flex;flex-direction:column;
  align-items:center;padding:0 16px;text-align:center;color:var(--zielen)}
.intro__napis b{font-family:Kalam,cursive;font-weight:700;line-height:1.15;
  font-size:clamp(3.4rem,11vw,7rem)}
.intro__napis span{font-family:Kalam,cursive;font-weight:700;text-transform:uppercase;
  letter-spacing:.2em;line-height:1.3;font-size:clamp(.95rem,2.6vw,1.6rem);color:var(--tusz)}
.intro__napis em{font-style:normal;margin-top:.3em;font-size:clamp(1rem,2.2vw,1.35rem);
  color:var(--tusz-mut)}
.intro__jazda{position:absolute;left:0;top:50%;z-index:2;
  width:clamp(300px,64vw,900px);transform:translate(-100%,-50%);
  animation:introJazda 3.1s cubic-bezier(.33,.08,.4,.95) .1s forwards}
.intro__jazda img{position:relative;z-index:1;display:block;width:100%;height:auto;
  animation:introBuja .2s ease-in-out infinite alternate}
.intro__jazda::before{content:"";position:absolute;z-index:0;left:6%;top:-100vh;
  bottom:-100vh;width:220vw;background:var(--papier-jasny)}
@keyframes introJazda{to{transform:translate(100vw,-50%)}}
@keyframes introBuja{to{transform:translateY(-1.5px)}}

/* ── hero ─────────────────────────────────────────────────────────── */
.hero{position:relative;padding:64px 0 52px;overflow:hidden}
/* rysunek poziomicowy pod hero - wyblakły, wygaszony ku dołowi maską,
   żeby nie ciął się twardą krawędzią o następną sekcję */
.hero::before{content:"";position:absolute;inset:-40px 0 0;z-index:0;
  background:url(tlo/mapa.webp) center top/cover no-repeat;opacity:.34;
  -webkit-mask-image:linear-gradient(180deg,#000 45%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 45%,transparent 100%);pointer-events:none}
.hero__in{position:relative;z-index:1;display:grid;grid-template-columns:1.02fr .98fr;
  gap:52px;align-items:center}
.hero__tyt{font-size:clamp(2.2rem,4.4vw,3.5rem);margin:0 0 18px}
/* maski wjazdu linii nagłówka. ⛔ Kalam ma długie zejścia (ł, y, j) -
   line-height poniżej 1.14 je obcina o overflow:hidden. */
.lin{display:block;overflow:hidden;line-height:1.16}
.lin>span{display:block;padding-bottom:.06em;
  animation:linIn .74s var(--e) both}
.lin:nth-child(1)>span{animation-delay:.45s}
.lin:nth-child(2)>span{animation-delay:.56s}
@keyframes linIn{from{transform:translateY(105%)}}
.hero__pod{color:var(--tusz-mut);max-width:46ch;font-size:1.1rem;margin:0 0 26px;
  animation:wejdz .7s var(--e) .78s both}
.hero__akcje{display:flex;gap:14px;flex-wrap:wrap;
  animation:wejdz .7s var(--e) .92s both}
@keyframes wejdz{from{opacity:0;transform:translateY(12px)}}
.hero__foto{margin:0;border-radius:20px;overflow:hidden;
  box-shadow:0 22px 44px rgba(27,37,45,.2);
  animation:wejdz .8s var(--e) .3s both}
.hero__foto img{aspect-ratio:4/3;object-fit:cover;width:100%;
  background:var(--papier-cien)}

/* ── sekcje ───────────────────────────────────────────────────────── */
.sek{padding:84px 0;position:relative}
.sek--jak{background:var(--papier-cien);border-block:1px solid var(--linia)}

/* ── siatka ofert ─────────────────────────────────────────────────── */
.siatka{display:grid;grid-template-columns:repeat(6,1fr);gap:30px;margin-top:34px}
/* Karta = zdjęcie, a opis (nazwa, rok/DMC, cena) leży NA nim, na ciemnym
   gradiencie u dołu. `.karta` ma wysokość zdjęcia, bo opis jest absolutny. */
.karta{grid-column:span 2;text-decoration:none;color:inherit;display:block;
  position:relative;transition:transform .3s var(--e)}
.karta--duza{grid-column:span 3}
.karta__foto{position:relative;overflow:hidden;border-radius:20px;
  box-shadow:0 14px 30px rgba(27,37,45,.18);
  transition:transform .3s var(--e),box-shadow .3s var(--e)}
.karta__foto>img{width:100%;aspect-ratio:4/3;object-fit:cover;
  background:var(--papier-cien);transition:transform .6s var(--e)}
.karta--duza .karta__foto>img{aspect-ratio:3/2}
.karta:hover .karta__foto{transform:translateY(-4px);
  box-shadow:0 24px 42px rgba(27,37,45,.24)}
.karta:hover .karta__foto>img{transform:scale(1.045)}
.karta__opis{position:absolute;left:0;right:0;bottom:0;z-index:1;
  padding:70px 22px 18px;border-radius:0 0 20px 20px;pointer-events:none;
  background:linear-gradient(to top,rgba(8,14,18,.86) 0%,rgba(8,14,18,.55) 55%,rgba(8,14,18,0) 100%);
  transition:transform .3s var(--e)}
.karta:hover .karta__opis{transform:translateY(-4px)}
.karta__opis h3{font-size:1.35rem;margin:0 0 2px;color:#fff}
.karta__meta{color:rgba(255,255,255,.88);font-size:.98rem;margin:0 0 4px}
.karta__cena{display:inline-block;margin:4px 0 0;padding:3px 14px;color:#fff;
  background:var(--zielen);border-radius:var(--pedzel);
  font-family:Kalam,cursive;font-weight:700;font-size:1.24rem}
/* liczba zdjęć - PRAWDZIWA z oferty; ikona zamiast słowa, więc bez tłumaczeń */
.karta__ile{position:absolute;right:12px;top:14px;z-index:2;display:inline-flex;
  align-items:center;gap:6px;padding:3px 11px 3px 9px;border-radius:999px;
  background:rgba(15,22,28,.68);color:#fff;font-size:.9rem;line-height:1.5;
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}

/* ── nasz plac ────────────────────────────────────────────────────────
   Rysunek placu Z ULICY, oddalony (Łukasz 28.09): płot z płyt po lewej,
   brama PRZESUWNA odsunięta w lewo (dorysowana programowo - D:/ai/dorysuj_brame.py,
   bo Qwen rysował ją zamkniętą ze skrzydłem),
   dom tuż za sztachetami, baner na sztachetach.
   Źródło: plac_qwen/plac_final5.webp z plac_final4c.png (przyczepa PRZED domem, nie za; bez ludzi i
   kwiatów - Łukasz 28.09; brama PRZED płotem, od ulicy, CAŁKIEM otwarta -
   przy odsunięciu 2/3 wyglądała na przymkniętą). Za tylnym murem NIE MA drzew -
   wyższy biały mur i niebo (Łukasz 28.09, zdjęcie Street View), mur obniżony
   programowo, niebo przezroczyste, reszta KRYJĄCA (D:/ai/plac_mur_niebo.py).
   Niebo przezroczyste, reszta kryjąca (plac_mur_niebo.py, nie --kolor). */
.plac{text-align:center}
.plac__txt{margin:0 auto 26px}
.plac__rys{margin:0;position:relative;max-width:1000px;margin-inline:auto;
  container-type:inline-size}
/* Ulica, płot i brama dochodzą do krawędzi kadru - wygaszamy lewy bok i dół.
   ⛔ Prawy bok tylko od 99%: baner kończy się na 98,8% szerokości. */
.plac__rys img{width:100%;height:auto;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 99%,transparent),linear-gradient(0deg,transparent,#000 13%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 99%,transparent),linear-gradient(0deg,transparent,#000 13%);
  mask-composite:intersect}
/* Napis na banerze (Łukasz 28.09: „Przyczepy kempingowe Ł & I").
   ⛔ Pudełko = WNĘTRZE banera, bez czerwonej ramki: x 1084..1368, y 400..446
   w kadrze 1392x752, po przycięciu (2,33,1390,750) - liczy to D:/ai/plac_mur_niebo.py. Poprzednio pudełko było
   całym banerem z ramką i napis wyjeżdżał poza białe pole.
   Rozmiary w `cqw` (rosną razem z rysunkiem): wnętrze ma 20,6cqw x 3,4cqw,
   obrys czcionki Kalam (1,29 em na wiersz) obu wierszy ~86% wysokości,
   napis ~53% szerokości - zmierzone Range.getBoundingClientRect, zapas na zejścia
   liter Kalam (p, y). Przy podmianie rysunku przelicz od nowa. */
.plac__baner{position:absolute;left:78%;top:51.2%;width:20.5%;height:6.4%;margin:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;line-height:1.3;color:#a3242a;white-space:nowrap}
.plac__baner b{font-family:Kalam,cursive;font-weight:700;font-size:1.0cqw}
.plac__baner span{font-family:Kalam,cursive;font-weight:700;font-size:1.12cqw;color:var(--zielen)}
/* Kalam osadza litery wysoko w linii - bez przesunięcia napis dotykał górnej
   krawędzi pola (375 px: 0 px od góry, 9 px od dołu). Zmierzone na pikselach. */
.plac__baner b,.plac__baner span{position:relative;top:.2cqw}

/* ── „jak kupujemy" ───────────────────────────────────────────────── */
.jak{display:grid;grid-template-columns:1.05fr .95fr;gap:52px;align-items:center}
.lista{list-style:none;margin:0;padding:0;display:grid;gap:16px}
.lista li{position:relative;padding-left:34px;color:var(--tusz-mut)}
.lista li b{color:var(--tusz);font-weight:400;font-family:Kalam,cursive}
/* odręczny „ptaszek" zamiast kropki listy */
.lista li::before{content:"";position:absolute;left:2px;top:.42em;width:15px;height:9px;
  border-left:2.5px solid var(--zielen);border-bottom:2.5px solid var(--zielen);
  transform:rotate(-45deg)}
.jak__foto{margin:0;border-radius:20px;overflow:hidden;
  box-shadow:0 22px 44px rgba(27,37,45,.2)}
.jak__foto img{width:100%;aspect-ratio:4/3;object-fit:cover}

/* ── sprzedane (marquee) ──────────────────────────────────────────── */
.sek--hist{text-align:center;overflow:hidden}
.pasek{margin-top:34px;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.pasek__tor{display:flex;gap:20px;width:max-content;animation:jedz 48s linear infinite}
@keyframes jedz{to{transform:translateX(-50%)}}
.pasek img{width:190px;height:132px;object-fit:cover;background:var(--papier-cien);
  border-radius:12px;box-shadow:0 7px 13px rgba(27,37,45,.14);
  opacity:.62;filter:grayscale(.6)}

/* ── gdzie nas znajdziecie ────────────────────────────────────────────
   Drogowskaz z adresem na deskach (Łukasz 28.09: wrócić do drogowskazu,
   mapa miasta odrzucona). Adres leży NA deskach jako tekst HTML, nie jest
   wpalony w obrazek - generator psuje litery, a tekst z HTML jest ostry,
   zaznaczalny i czyta go wyszukiwarka.
   ⭐ Pozycje desek ZMIERZONE z pliku Z3_drogowskaz_jasny (1216x832): deski
   y 198-320 / 341-463 / 482-605, płaska część x 300-650. Po przycięciu
   ramką (2,8,947,830) środki wypadają na x 50,4%, y 30,5 / 47,9 / 65,1%.
   Przy podmianie rysunku przelicz od nowa.
   Rozmiar w `cqw` - napis rośnie i maleje razem z rysunkiem, więc na
   każdej szerokości mieści się na desce (płaska część = 35% szerokości). */
.sek--gdzie{background:var(--papier-cien);border-top:1px solid var(--linia)}
.gdzie{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:center}
.gdzie__znak{position:relative;margin:0;container-type:inline-size}
/* Drzewa i trawa dochodzą do lewej i dolnej krawędzi kadru generatora -
   bez wygaszenia widać tam prostą, uciętą linię. */
.gdzie__znak img{width:100%;height:auto;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 14%),linear-gradient(0deg,transparent,#000 12%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 14%),linear-gradient(0deg,transparent,#000 12%);
  mask-composite:intersect}
.gdzie__deski{position:absolute;inset:0;margin:0}
.deska{position:absolute;left:50.4%;transform:translate(-50%,-50%) rotate(-1.2deg);
  font-family:Kalam,cursive;font-weight:700;line-height:1.2;white-space:nowrap;
  font-size:1.1rem;font-size:3.9cqw;color:#4a3521;
  text-shadow:0 1px 0 rgba(255,245,225,.45)}
.deska--1{top:30.5%}
.deska--2{top:47.9%}
.deska--3{top:65.1%}

/* ── kontakt ──────────────────────────────────────────────────────── */
.sek--kontakt{position:relative;overflow:hidden;
  background:var(--papier-cien);border-top:1px solid var(--linia)}
/* obozowisko nad jeziorem - wyblakłe, po prawej, nie wchodzi pod tekst */
.sek--kontakt::before{content:"";position:absolute;right:-6%;bottom:-8%;
  width:min(56%,720px);aspect-ratio:1400/958;z-index:0;
  background:url(tlo/obozowisko.webp) right bottom/contain no-repeat;opacity:.3;
  pointer-events:none}
.kontakt{position:relative;z-index:1;text-align:center}
.kontakt .lead{margin-inline:auto}
.kontakt__tel{display:flex;gap:20px;justify-content:center;flex-wrap:wrap;
  margin:30px 0 20px}
.tel{display:flex;flex-direction:column;gap:2px;min-width:230px;padding:20px 28px;
  background:var(--papier-jasny);border:1px solid var(--linia);border-radius:var(--r);
  text-decoration:none;box-shadow:0 8px 16px rgba(27,37,45,.1);
  transition:transform .22s var(--e),box-shadow .22s var(--e)}
.tel:hover{transform:translateY(-3px);box-shadow:0 14px 24px rgba(27,37,45,.15)}
.tel span{font-size:.92rem}
.tel b{font-family:Kalam,cursive;font-size:1.5rem;color:var(--zielen)}
.adres{color:var(--tusz-mut);margin:0}

/* ── stopka ───────────────────────────────────────────────────────── */
.stopka{position:relative;padding:150px 0 24px;background:var(--papier-cien);
  border-top:1px solid var(--linia)}
/* Pas lasu wrastający w stopkę. ⛔ Rysunek ma jaśniejsze tło niż stopka, więc
   maska musi wygaszać go NA OBIE strony (góra i dół), inaczej widać krawędź. */
.stopka::before{content:"";position:absolute;left:0;right:0;top:0;height:150px;
  background:url(tlo/las.webp) center bottom/cover no-repeat;opacity:.4;
  -webkit-mask-image:linear-gradient(180deg,transparent 4%,#000 55%,transparent 97%);
  mask-image:linear-gradient(180deg,transparent 4%,#000 55%,transparent 97%);
  pointer-events:none}

.stopka__in{position:relative;display:grid;
  grid-template-columns:1.4fr .8fr .9fr;gap:40px;
  padding-bottom:26px;border-bottom:1px solid var(--linia)}
.stopka__kol{min-width:0}
.stopka__znak{display:flex;align-items:center;gap:11px;text-decoration:none;
  margin-bottom:10px}
.stopka__nazwa{font-family:Kalam,cursive;font-weight:700;font-size:1.16rem;
  line-height:1.2}
.stopka__opis{margin:0;font-size:.97rem;max-width:34ch}

.stopka__lab{font-family:Kalam,cursive;font-weight:700;font-size:12.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--tusz-mut);
  margin:0 0 12px}
.stopka__lista{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.stopka__lista a{color:var(--tusz-mut);text-decoration:none;transition:color .2s}
.stopka__lista a:hover{color:var(--zielen)}
.stopka__adres{margin:0 0 12px;font-size:.97rem;line-height:1.5}
/* ⛔ nowrap: numer nigdy nie łamie się w środku (Łukasz 28.09: „przechodzą do nowej linii") */
.stopka__tel{display:block;color:var(--zielen);text-decoration:none;white-space:nowrap;
  font-family:Kalam,cursive;font-weight:700;font-size:1.14rem;line-height:1.5}
.stopka__fb{display:inline-flex;align-items:center;gap:8px;margin-top:12px;
  color:var(--zielen);text-decoration:none;font-weight:600;font-size:.97rem;transition:color .2s}
.stopka__fb svg{flex:none}
.stopka__fb:hover{color:var(--zielen-jas)}

.stopka__dol{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  padding-top:16px}
.stopka__dol p{margin:0;font-size:.93rem}

/* ── strona oferty ────────────────────────────────────────────────── */
.oferta__gora{padding:24px 0 6px}
.wroc{color:var(--tusz-mut);text-decoration:none;font-size:1rem}
.wroc::before{content:"← "}
.wroc:hover{color:var(--zielen)}
.oferta__in{display:grid;grid-template-columns:1.55fr .85fr;gap:38px;
  align-items:start;padding-bottom:10px}
/* ⛔⛔ BEZ TEGO GALERIA ROZPYCHA KOLUMNĘ. Element siatki ma domyślnie
   `min-width:auto`, czyli nie zwęzi się poniżej szerokości zawartości -
   a w środku jest `.kar__tor` z N slajdami po 100%. Efekt: zdjęcie na całą
   szerokość ekranu i panel z ceną wypchnięty poza widok. Złapane 28.09.2026. */
.oferta__in>*{min-width:0}
.galeria,.kar,.kar__tor{min-width:0}

.kar{position:relative;border-radius:20px;overflow:hidden;
  box-shadow:0 18px 40px rgba(27,37,45,.18)}
.kar__tor{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none}
.kar__tor::-webkit-scrollbar{display:none}
.kar__sl{flex:0 0 100%;scroll-snap-align:center}
.kar__sl img{width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--papier-cien)}
.kar__strz{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;
  display:grid;place-items:center;border:1px solid var(--linia);
  background:rgba(255,255,255,.94);color:var(--tusz);border-radius:50%;font-size:26px;
  line-height:1;cursor:pointer;box-shadow:0 6px 14px rgba(27,37,45,.18)}
.kar__strz--l{left:16px}
.kar__strz--p{right:16px}
.kar__strz:hover{background:var(--zielen);color:#fff;border-color:var(--zielen)}
.kar__licz{position:absolute;right:16px;bottom:16px;margin:0;padding:5px 13px;
  background:rgba(27,37,45,.74);color:#fff;border-radius:999px;font-size:.9rem}
.galeria__mini{display:flex;gap:10px;overflow-x:auto;padding:14px 2px 4px;
  scrollbar-width:thin}
.mini{flex:0 0 auto;width:92px;padding:0;background:none;
  border:2px solid transparent;border-radius:12px;overflow:hidden;cursor:pointer;opacity:.62;
  transition:opacity .2s,border-color .2s,transform .2s var(--e)}
.mini img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:10px}
.mini:hover{opacity:.9}
.mini.jest{opacity:1;border-color:var(--zielen);transform:translateY(-2px)}

.panel{position:sticky;top:94px;background:var(--papier-jasny);
  border:1px solid var(--linia);border-radius:var(--r);padding:28px;
  box-shadow:0 12px 26px rgba(27,37,45,.12)}
.panel h1{font-size:1.95rem;margin:0 0 6px}
.panel__cena{font-family:Kalam,cursive;font-weight:700;font-size:1.95rem;
  color:var(--zielen);margin:0 0 20px}
.dane{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:22px}
.dana{background:var(--papier-cien);border-radius:10px;padding:11px 14px;
  display:flex;flex-direction:column;gap:1px}
.dana span{font-size:.88rem}
.dana b{font-family:Kalam,cursive;font-size:1.06rem;font-weight:700}
.panel__adres{margin:14px 0 0;font-size:.96rem}

.oferta__cechy{padding:66px 20px 10px}
.cechy{list-style:none;margin:22px 0 0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.cechy li{position:relative;padding:13px 16px 13px 44px;background:var(--papier-jasny);
  border:1px solid var(--linia);border-radius:12px}
.cechy li::before{content:"";position:absolute;left:17px;top:1.15em;width:13px;height:8px;
  border-left:2.5px solid var(--zielen);border-bottom:2.5px solid var(--zielen);
  transform:rotate(-45deg)}
.siatka--3 .karta{grid-column:span 2}

/* mobilna belka z ceną i telefonem */
.belka{display:none;position:fixed;left:0;right:0;bottom:0;z-index:45;
  align-items:center;justify-content:space-between;gap:14px;padding:11px 18px;
  background:rgba(255,255,255,.97);border-top:1px solid var(--linia);
  box-shadow:0 -6px 18px rgba(27,37,45,.14)}
.belka b{font-family:Kalam,cursive;font-size:1.28rem;color:var(--zielen)}

/* ── reveal przy scrollu ──────────────────────────────────────────── */
[data-reveal]{opacity:0;transform:translateY(18px);
  transition:opacity .6s var(--e),transform .6s var(--e)}
[data-reveal].wid{opacity:1;transform:none}

/* ── responsywność ────────────────────────────────────────────────── */
/* Nawigacja chudnie stopniowo, żeby ani razu nie przelać się poza ekran.
   Progi dobrane pomiarem `scrollWidth - clientWidth`, nie na oko. */
@media (max-width:1000px){
  .jez__p span{display:none}
  .jez__p{gap:0;padding:5px 4px}
}
@media (max-width:860px){
  .nav__links{display:none}
  .hb{display:flex}
  .mmenu{display:grid}
}

@media (max-width:960px){
  .hero__in,.jak,.oferta__in,.gdzie{grid-template-columns:1fr;gap:34px}
  .gdzie__znak{width:100%;max-width:560px;margin-inline:auto}
  .hero{padding:44px 0 36px}
  .hero__foto{order:-1}
  .panel{position:static}
  .siatka{grid-template-columns:repeat(4,1fr)}
  .karta,.karta--duza,.siatka--3 .karta{grid-column:span 2}
  .sek{padding:62px 0}
  .sek--kontakt::before{width:70%;opacity:.2}
}
@media (max-width:720px){
  body{font-size:18px}
  .nav__in{height:62px;gap:8px}
  .nav__links{display:none}
  /* Na telefonie zostają same flagi bez kodów - sześć par flaga+kod nie
     mieści się obok marki i przycisku z telefonem. */
  .jez{gap:0}
  /* 5px pionowo, nie 4px: 14px flagi + 2×5 = 24px, czyli minimalny cel
     dotykowy z WCAG 2.5.8. Przy 4px wychodziły 22px. */
  .jez__p{padding:5px 3px;gap:0}
  .jez__p span{display:none}
  .jez__p img{width:20px;height:14px}
  /* ⛔⛔ NIE UKRYWAĆ `.brand__txt` - od 28.09 to JEST znak firmowy (nie ma już
     ikony), więc ukrycie zostawia nagłówek bez nazwy firmy. Zamiast chować,
     zmniejszamy: sam „Ł & I" plus miasto, bez linijki „PRZYCZEPY KEMPINGOWE",
     która nie mieści się obok flag i przycisku z telefonem. */
  .brand__txt b{font-size:1.16rem}
  .brand__txt>span{display:none}
  .brand__txt em{font-size:.7rem}
  .jez{flex:0 0 auto}
  .siatka{grid-template-columns:1fr;gap:26px}
  .karta,.karta--duza,.siatka--3 .karta{grid-column:span 1}
  /* ⛔ węższy nagłówek, żeby „Sprawdzone przyczepy" nie obcinało się
     o overflow:hidden masek .lin na telefonach 360px */
  .hero__tyt{font-size:clamp(1.95rem,7.4vw,2.7rem)}
  .hero__akcje .btn{width:100%}
  .kar__strz{display:none}
  .belka{display:flex}
  .oferta{padding-bottom:96px}  /* pasek z dwoma numerami jest wyższy */
  .mini{width:76px}
  .pasek img{width:152px;height:106px}
  .dane{grid-template-columns:1fr}
  .stopka{padding-top:92px}
  /* Trzy kolumny na telefonie dawały kontaktowi 74px (320px: 58px) i numery
     łamały się na 2-3 linie. Marka idzie na całą szerokość, pod nią dwie kolumny. */
  .stopka__in{grid-template-columns:1fr 1fr;gap:30px 24px}
  .stopka__kol--marka{grid-column:1/-1}
}

/* ⛔ Poniżej 480px marka, sześć flag i przycisk z telefonem nie mieszczą się
   w jednym pasku (zmierzone: nadmiar 12px przy 360, 52px przy 320). Ściśnięte
   flagi schodziły do 22px wysokości, czyli poniżej progu wygodnego kliknięcia
   (WCAG 2.5.8 wymaga 24px). Dlatego dostają własny rząd pod paskiem.
   ⚠️ Ten blok MUSI stać po bloku 720px, inaczej `height:62px` stamtąd wygrywa
   kolejnością i flagi zostają wciśnięte w pasek. */
@media (max-width:480px){
  .nav__in{flex-wrap:wrap;height:auto;padding-top:9px}
  .jez{order:3;width:100%;justify-content:center;gap:2px;
    margin-top:8px;padding:6px 0;border-top:1px solid var(--linia)}
  .jez__p{padding:6px 8px}
  .jez__p img{width:24px;height:16px}
}

/* Na dotyku nie ma :hover - bez tego efekt najechania zostaje zapalony
   po tapnięciu, aż użytkownik kliknie gdzie indziej. */
@media (hover:none){
  .karta:hover .karta__foto{transform:none;box-shadow:0 14px 30px rgba(27,37,45,.18)}
  .karta:hover .karta__foto>img,.karta:hover .karta__opis{transform:none}
  .tel:hover{transform:none}
  .karta:active{transform:scale(.988)}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .lin>span,.hero__pod,.hero__akcje,.hero__foto,.marka{opacity:1;transform:none}
  .roz{max-width:7ch}
  .roz>span{opacity:1;transform:none;filter:none}
  .marka__woz{opacity:.92;transform:none}
  [data-reveal]{opacity:1;transform:none}
  .pasek__tor{animation:none}
  .intro{display:none}
}
