/* ============================================================
   Schody Jagodzinski - jeden arkusz systemu
   ------------------------------------------------------------
   1. BAZA DOKUMENTU  - zastepuje hello-elementor/assets/css/reset.css
   2. SYSTEM .jag     - wlasciwy design system
   3. POPUP           - szablon "Zamow pomiar" na tokenach systemu

   Do 27.07.2026 witryna ladowala cztery obce arkusze:
     hello/reset.css          154 selektory, ZERO klas trafiajacych w markup
     hello/theme.css           41 klas, trafiala 1
     hello/header-footer.css   29 klas, trafialo 0
     majewski-child/style.css  86 klas, trafialo 21 - i to one kolidowaly
   Razem 33 kB, z czego uzyteczne byly wylacznie style popupu i garstka
   bazowych regul dokumentu. Reszta albo nic nie robila, albo szkodzila:
   to stad bral sie magentowy #c36 pod kazdym golym przyciskiem i to stad
   .hero-sheet svg{position:absolute} wysadzilo kiedys rysunek w hero.
   ============================================================ */

/* --- 1. BAZA DOKUMENTU --------------------------------------
   Tylko to, bez czego przegladarka zle zlozy strone. Zadnych kolorow
   marki, zadnych rozmiarow przyciskow, zadnych ramek pol formularza -
   to nalezy do systemu nizej, nie do resetu. */
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{margin:0; background:#ffffff; color:#241e1c;
  font-family:"Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size:1rem; line-height:1.5;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;}
img{max-width:100%; height:auto; border-style:none;}
[hidden],template{display:none;}
details{display:block;} summary{display:list-item;}
a{color:inherit; text-decoration:none; background-color:transparent;}
b,strong{font-weight:600;}
h1,h2,h3,h4,h5,h6{margin:0; color:inherit; font-weight:600; line-height:1.15; letter-spacing:-.02em;}
h1{font-size:2.25rem;} h2{font-size:1.75rem;} h3{font-size:1.375rem;}
h4{font-size:1.125rem;} h5,h6{font-size:1rem;}
p,ul,ol,li,dl,dt,dd,figure,blockquote{margin:0;}
button,input,optgroup,select,textarea{font-family:inherit; font-size:1rem; line-height:1.5; margin:0;}
button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button;}
/* Kluczowe: reset motywu nadrzednego nadawal tu tlo #c36 i ramke marki obcej. */
button,[type="button"],[type="submit"]{background:none; border:0; color:inherit; cursor:pointer;}
textarea{overflow:auto; resize:vertical;}

/* Tokeny sa deklarowane rowniez na :root, zeby popup i inne szablony
   Elementora, ktore nie siedza wewnatrz .jag, siegaly po ten sam system.
   Blok .jag nizej powtarza je celowo - dzieki temu nic wewnatrz systemu
   nie zmienia sie o jotę przy tej przeprowadzce. */
:root{
  --bg:#ffffff; --surface:#f8f5f4; --surface-2:#f1ece8; --ink:#241e1c; --ink-soft:#3e3633;
  --muted:#6e6765; --hairline:#e7e2df; --hairline-strong:#d8d1cd;
  --brand:#dd4300; --brand-strong:#b62000; --brand-hover:#9c1c00; --brand-soft:#ffece3;
  --r:3px; --r-lg:5px; --container:1320px; --ease:cubic-bezier(.16,1,.3,1);
}

/* --- 2. SYSTEM .jag ----------------------------------------- */
/* ===== Schody Jagodziński - wspólny design system (cała witryna) ===== */
.jag{
  --bg:#ffffff; --surface:#f8f5f4; --surface-2:#f1ece8; --ink:#241e1c; --ink-soft:#3e3633;
  --muted:#6e6765; --hairline:#e7e2df; --hairline-strong:#d8d1cd;
  --brand:#dd4300; --brand-strong:#b62000; --brand-hover:#9c1c00; --brand-soft:#ffece3;
  --oak:#c98a45; --walnut:#7c4a2d; --pine:#e6cfa3; --ash:#dcc9ad;
  --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px; --sp-9:96px;
  --r:3px; --r-lg:5px; --container:1320px; --ease:cubic-bezier(.16,1,.3,1);
  --z-sticky:100; --z-menu:200; --z-lightbox:300;
  font-family:"Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  color:var(--ink); background:var(--bg); font-size:17px; line-height:1.6;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; font-kerning:normal;
}
.jag *{box-sizing:border-box;}
.jag :where(h1,h2,h3,h4,p,ul,ol,li,figure,blockquote,form){margin:0;}
.jag img{display:block; max-width:100%; height:auto;}
.jag a{color:inherit; text-decoration:none;}
.jag button{font:inherit; color:inherit; cursor:pointer;}
.jag ::selection{background:var(--brand-soft); color:var(--brand-strong);}
.jag :focus-visible{outline:2.5px solid var(--brand-strong); outline-offset:3px; border-radius:2px;}
html{scroll-behavior:smooth; scroll-padding-top:84px;}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto;}}

/* layout */
.jag .wrap{width:100%; max-width:var(--container); margin-inline:auto; padding-inline:clamp(20px,5vw,48px);}
.jag .section{padding-block:clamp(64px,10vw,128px);}
.jag .section--tight{padding-block:clamp(48px,7vw,88px);}
.jag .lead{font-size:clamp(1.05rem,1.5vw,1.28rem); line-height:1.5; color:var(--ink-soft); max-width:60ch;}
.jag p.body{color:var(--ink-soft); max-width:64ch;}
.jag p.body + p.body{margin-top:1em;}
.jag h2.h-sec{font-size:clamp(1.85rem,3.6vw,2.9rem); font-weight:600; line-height:1.05; letter-spacing:-.025em; text-wrap:balance; max-width:20ch;}
.jag .sec-head{max-width:760px; margin-bottom:clamp(32px,5vw,56px);}
.jag .sec-head .lead{margin-top:18px;}
.jag .kicker{display:inline-flex; align-items:center; gap:10px; font-size:.82rem; font-weight:600; color:var(--brand-strong);}
.jag .kicker::before{content:""; width:26px; height:2px; background:var(--brand);}
.jag .center{text-align:center; margin-inline:auto;}
/* wezszy wariant kontenera: byl wpisywany inline jako max-width:760px na .wrap,
   czyli jednorazowa wartosc nadpisujaca kontener systemowy. Teraz ma nazwe. */
.jag .wrap--narrow{max-width:min(var(--container),880px);}
/* lista cech: ten sam uklad byl budowany inline pietnascie razy na czterech
   podstronach. Znacznik dostaje stala szerokosc, wiec tekst rownia sie w kolumne. */
.jag .jag-list{list-style:none; margin-top:18px; display:flex; flex-direction:column; gap:10px;}
.jag .jag-list li{display:flex; gap:12px; color:var(--ink-soft);}
.jag .jag-list li>span:first-child{flex:none; width:12px; color:var(--brand-strong); font-weight:700;}

/* buttons */
.jag .btn{display:inline-flex; align-items:center; justify-content:center; gap:8px; background:var(--brand-strong); color:#fff; font-weight:600; font-size:.98rem; padding:13px 22px; border-radius:var(--r); border:0; white-space:nowrap; transition:background .2s, transform .2s var(--ease), box-shadow .25s; box-shadow:0 1px 2px rgba(182,32,0,.18);}
.jag .btn:hover{background:var(--brand-hover); transform:translateY(-1px); box-shadow:0 6px 18px rgba(182,32,0,.22);}
.jag .btn:active{transform:translateY(0);}
.jag .btn--ghost{background:transparent; color:var(--ink); border:1px solid var(--hairline-strong); box-shadow:none;}
.jag .btn--ghost:hover{background:var(--surface); border-color:var(--ink); color:var(--ink); box-shadow:none;}
.jag .btn--lg{padding:16px 28px; font-size:1.05rem;}
.jag .btn--light{background:#fff; color:var(--brand-strong);} .jag .btn--light:hover{background:#fff;color:var(--brand-hover);}
/* Cel dotykowy: sam tekst dawal ~27 px wysokosci, a to element sciezki
   zakupowej - odsylacz z kafla oferty na strone produktowa. Padding
   podnosi go do ~49 px, ujemny margines oddaje sasiadom to, co zabral,
   wiec uklad nie drgnie. */
.jag .textlink{color:var(--brand-strong); font-weight:600; display:inline-flex; align-items:center; gap:7px; padding-block:11px; margin-block:-11px;}
.jag .textlink svg{width:16px;height:16px; transition:transform .25s var(--ease);}
.jag .textlink:hover svg{transform:translateX(3px);}

/* header */
.jag-bar{position:fixed; top:0; left:0; right:0; z-index:var(--z-sticky); background:rgba(255,255,255,.82); backdrop-filter:saturate(1.4) blur(14px); border-bottom:1px solid transparent; transition:border-color .3s, box-shadow .3s;}
.jag-bar.scrolled{border-bottom-color:var(--hairline); box-shadow:0 1px 0 rgba(36,30,28,.03);}
/* Pasek na pelna szerokosc okna. Kontener tresci stoi na 1320 px, wiec
   powyzej 1416 px szerokosci okna pasek dostawal te same 1224 px na menu,
   telefon, przycisk i logotyp, mimo ze miejsca obok bylo w nadmiarze.
   Zdejmujemy tylko ograniczenie szerokosci - margines boczny zostaje ten
   sam co w tresci, wiec logotyp trzyma linie z krawedzia okna.
   Ponizej progu nawigacji nic sie nie zmienia, bo tam kontener i tak nie
   dochodzil do swojego maksimum. */
@media (min-width:1081px){.jag-bar .wrap{max-width:none;}}
.jag-bar .bar-in{display:flex; align-items:center; justify-content:space-between; gap:24px; height:72px;}
/* Logotyp jako plik SVG zamiast dwuwierszowego ukladu tekstowego.
   Wysokosc jest plynna, bo znak ma proporcje 12,2:1 - przy stalej wysokosci
   zajmowalby w pasku od 208 do 318 px w zaleznosci od widoku i wypychalby
   nawigacje. Gorna granica 26 px odpowiada wysokosci starego napisu. */
.jag-logo{display:flex; align-items:center;}
.jag-logo img{display:block; width:auto; height:clamp(17px,2.4vw,26px);}
/* Powyzej progu nawigacji pasek dzieli szerokosc z menu, telefonem i
   przyciskiem, wiec znak dostaje wezszy zakres. Gorna granica jest stala,
   bo kontener zatrzymuje sie na 1320 px - dalszy wzrost logotypu zjadalby
   miejsce, ktorego juz nie przybywa. */
@media (min-width:1081px){.jag-bar .jag-logo img{height:clamp(17px,1.6vw,26px);}}
.jag-nav{display:flex; align-items:center; gap:28px;}
.jag-nav > a, .jag-nav .has-sub > button{font-size:.98rem; font-weight:500; color:var(--ink-soft); background:none; border:0; padding:6px 0; position:relative; display:inline-flex; align-items:center; gap:5px; transition:color .2s;}
.jag-nav a[aria-current="page"]{color:var(--ink);}
.jag-nav > a::after{content:""; position:absolute; left:0; right:100%; bottom:0; height:2px; background:var(--brand); transition:right .3s var(--ease);}
.jag-nav > a:hover{color:var(--ink);} .jag-nav > a:hover::after{right:0;}
.jag-nav .has-sub{position:relative;}
.jag-nav .has-sub > button svg{width:13px;height:13px;transition:transform .25s;}
.jag-nav .has-sub:hover > button{color:var(--ink);} .jag-nav .has-sub:hover > button svg{transform:rotate(180deg);}
.jag-sub{position:absolute; top:100%; left:-16px; min-width:260px; background:#fff; border:1px solid var(--hairline); border-radius:var(--r-lg); box-shadow:0 18px 40px rgba(36,30,28,.12); padding:8px; opacity:0; visibility:hidden; transform:translateY(6px); transition:.25s var(--ease);}
.jag-nav .has-sub:hover .jag-sub, .jag-nav .has-sub:focus-within .jag-sub{opacity:1; visibility:visible; transform:translateY(0);}
.jag-sub a{display:flex; flex-direction:column; gap:2px; padding:10px 14px; border-radius:var(--r); transition:background .18s;}
.jag-sub a:hover{background:var(--surface);}
.jag-sub a b{font-size:.95rem; font-weight:600; color:var(--ink);}
.jag-sub a small{font-size:.8rem; color:var(--muted);}
.jag-cta{display:flex; align-items:center; gap:18px;}
.jag-tel{font-weight:600; font-size:1rem; white-space:nowrap; display:flex; align-items:center; gap:7px;}
.jag-tel svg{width:16px; height:16px; color:var(--brand-strong);}
.jag-burger{display:none; width:44px; height:44px; align-items:center; justify-content:center; background:transparent; border:0;}
.jag-burger span,.jag-burger span::before,.jag-burger span::after{display:block; width:24px; height:2px; background:var(--ink); transition:.3s var(--ease);}
.jag-burger span{position:relative;} .jag-burger span::before,.jag-burger span::after{content:""; position:absolute; left:0;} .jag-burger span::before{top:-7px;} .jag-burger span::after{top:7px;}
/* Prog zwijania nawigacji do hamburgera. Byl na 860 px, ale szesc pozycji
   menu plus telefon plus przycisk nie miescily sie w pasku juz ponizej
   okolo 1050 px - pozycje zachodzily na siebie, zanim doszedl tu logotyp.
   Prog idzie na 1080 px, powyzej zmierzonej granicy. Reszta ukladu
   mobilnego zostaje na 860 px, bo tam zmienia sie tresc, nie pasek. */
@media (max-width:1080px){
  .jag-nav,.jag-cta .jag-tel,.jag-cta .btn{display:none;}
  .jag-burger{display:flex;}
}
/* Pas posredni: nawigacja juz sie miesci, ale nie razem z numerem telefonu.
   Numer schodzi pierwszy, bo przycisk prowadzi do tej samej rozmowy, a na
   dotykowych szerokosciach telefon i tak jest w dolnym pasku. */
@media (min-width:1081px) and (max-width:1360px){
  .jag-bar .jag-cta .jag-tel{display:none;}
  .jag-bar .jag-nav{gap:20px;}
}

.jag-mobile{position:fixed; inset:0; z-index:var(--z-menu); background:var(--bg); display:flex; flex-direction:column; padding:0 clamp(20px,6vw,40px) 40px; transform:translateY(-100%); transition:transform .4s var(--ease), visibility 0s .4s; visibility:hidden; overflow-y:auto;}
.jag-mobile.open{transform:translateY(0); visibility:visible; transition:transform .4s var(--ease), visibility 0s;}
/* panel przyjezdza, potem tresc siada - inaczej caly ekran zmienia sie naraz */
.jag.js .jag-mobile nav a{opacity:0; transform:translateY(10px);}
.jag.js .jag-mobile.open nav a{opacity:1; transform:none; transition:opacity .3s var(--ease), transform .3s var(--ease);}
.jag.js .jag-mobile.open nav a:nth-child(1){transition-delay:.14s;}
.jag.js .jag-mobile.open nav a:nth-child(2){transition-delay:.17s;}
.jag.js .jag-mobile.open nav a:nth-child(3){transition-delay:.2s;}
.jag.js .jag-mobile.open nav a:nth-child(4){transition-delay:.23s;}
.jag.js .jag-mobile.open nav a:nth-child(5){transition-delay:.26s;}
.jag.js .jag-mobile.open nav a:nth-child(6){transition-delay:.29s;}
.jag.js .jag-mobile.open nav a:nth-child(7){transition-delay:.32s;}
.jag.js .jag-mobile.open nav a:nth-child(n+8){transition-delay:.35s;}
.jag.js .jag-mobile-foot{opacity:0; transform:translateY(10px);}
.jag.js .jag-mobile.open .jag-mobile-foot{opacity:1; transform:none; transition:opacity .3s var(--ease) .38s, transform .3s var(--ease) .38s;}
/* flex:none jest tu istotne. Panel to kolumna flex z przewijaniem, wiec przy
   dluzszym menu przegladarka sciskala ten pasek z 72 px do 44 px wysokosci
   contentu - logo skakalo o kilkanascie pikseli w gore w momencie otwarcia
   menu. Teraz pasek trzyma te sama wysokosc co .bar-in w naglowku strony. */
.jag-mobile-top{display:flex; align-items:center; justify-content:space-between; height:72px; flex:none;}
.jag-mobile-close{width:44px;height:44px;background:transparent;border:0;font-size:0;position:relative;}
.jag-mobile-close::before,.jag-mobile-close::after{content:"";position:absolute;left:10px;top:21px;width:24px;height:2px;background:var(--ink);}
.jag-mobile-close::before{transform:rotate(45deg);} .jag-mobile-close::after{transform:rotate(-45deg);}
.jag-mobile nav{display:flex; flex-direction:column; gap:2px; margin-top:16px;}
.jag-mobile nav a{font-size:1.5rem; font-weight:600; letter-spacing:-.02em; padding:12px 0; border-bottom:1px solid var(--hairline);}
.jag-mobile nav a.sub{font-size:1.05rem; font-weight:500; color:var(--ink-soft); padding:9px 0 9px 16px; border-bottom:0;}
.jag-mobile-foot{margin-top:auto; padding-top:24px; display:flex; flex-direction:column; gap:14px;}
.jag-mobile-foot .jag-tel{font-size:1.3rem;}

/* page hero (podstrony) */
.jag-phero{padding-top:clamp(116px,14vw,168px); padding-bottom:clamp(40px,6vw,72px); border-bottom:1px solid var(--hairline);}
.jag-crumbs{display:flex; gap:8px; align-items:center; font-size:.85rem; color:var(--muted); margin-bottom:11px; flex-wrap:wrap;}
/* okruszki: ~23 px tekstu -> ~45 px celu dotykowego */
.jag-crumbs a{display:inline-flex; align-items:center; padding-block:11px;}
.jag-crumbs a:hover{color:var(--brand-strong);} .jag-crumbs span{color:var(--hairline-strong);}
.jag-phero h1{font-size:clamp(2.2rem,5vw,3.6rem); font-weight:700; line-height:1.03; letter-spacing:-.03em; text-wrap:balance; max-width:18ch;}
.jag-phero .lead{margin-top:22px;}
.jag-phero .phero-grid{display:grid; grid-template-columns:1.1fr .9fr; gap:clamp(28px,4vw,64px); align-items:center;}
/* Naglowek bez zdjecia. Bez tego kolumna po zdjeciu zostaje pusta, a tekst
   siedzi sciesniony w polowie szerokosci. Jedna kolumna, ale z ograniczona
   miara - inaczej wiersz leci przez cale 1224 px i robi sie nieczytelny. */
.jag-phero .phero-grid:not(:has(.phero-media)){grid-template-columns:minmax(0,1fr); max-width:42rem;}
.jag-phero .phero-media{border-radius:var(--r-lg); overflow:hidden; aspect-ratio:4/3; background:var(--surface);}
.jag-phero .phero-media img{width:100%;height:100%;object-fit:cover;object-position:50% 0;}
.jag-phero .phero-actions{display:flex; flex-wrap:wrap; gap:12px; margin-top:30px;}

/* hero (strona główna) */
.jag-hero{padding-top:clamp(112px,14vw,168px); padding-bottom:clamp(48px,7vw,96px);}
/* Kolumna tekstu odzyskuje szerokosc (.86 -> .96fr), bo to ona dusila
   naglowek. Rysunek i tak zostaje wiekszy niz przed zmiana: caly zysk
   pochodzi ze zdjetej ramki i paddingu, nie z zabierania miejsca tekstowi.
   Przy oknie 1200 px arkusz ma ~541 px wobec ~521 px w stanie wyjsciowym,
   a kolumna tekstu ~499 px wobec ~471 px. Obie strony wychodza do przodu. */
.jag-hero-grid{display:grid; grid-template-columns:.96fr 1.04fr; gap:clamp(28px,4vw,64px); align-items:center;}
/* Winowajca lamania po jednym slowie byl czlon vw, nie sufit. Przy oknie
   1200 px 6.2vw = 74 px, a kolumna tekstu miala wtedy ~447 px - dwa slowa
   "Schody, ktore" zajmowaly ~460 px, wiec nie miescil sie ani jeden
   sensowny wiersz. Sufit 4.7rem w ogole sie nie wlaczal, bo vw byl nizej.
   Tniemy oba: 6.2 -> 4.2vw i 4.7 -> 3.6rem. Przy 1200 px daje to 50 px
   zamiast 74, przy 1440 px 57.6 px. */
.jag-hero h1{font-size:clamp(2.2rem,4.2vw,3.6rem); font-weight:700; line-height:1.02; letter-spacing:-.032em; text-wrap:balance;}
.jag-hero h1 em{font-style:normal; color:var(--brand-strong);}
.jag-hero .lead{margin-top:26px;}
.jag-hero-actions{display:flex; flex-wrap:wrap; gap:14px; margin-top:34px;}
.jag-hero-facts{display:flex; gap:clamp(20px,3vw,44px); margin-top:44px; padding-top:30px; border-top:1px solid var(--hairline); flex-wrap:wrap;}
.jag-fact b{display:block; font-size:clamp(1.5rem,2.4vw,2.1rem); font-weight:700; letter-spacing:-.02em; line-height:1;}
.jag-fact span{display:block; font-size:.82rem; font-weight:500; color:var(--muted); margin-top:8px;}
.jag-hero-media{position:relative;}
.jag-hero-media .frame{position:relative; border-radius:var(--r-lg); overflow:hidden; background:var(--surface); aspect-ratio:1024/1400;}
.jag-hero-media img{width:100%; height:100%; object-fit:cover;}
.jag-cap{position:absolute; left:16px; bottom:16px; background:rgba(255,255,255,.94); padding:9px 14px; border-radius:var(--r); font-size:.8rem; font-weight:600; color:var(--ink); box-shadow:0 4px 16px rgba(36,30,28,.14); display:flex; align-items:center; gap:8px;}
.jag-cap::before{content:""; width:8px; height:8px; border-radius:50%; background:var(--brand);}

/* offer cards */
/* jawne trzy kolumny zamiast auto-fit: przy 1320 px auto-fit miescil cztery,
   wiec szesc kafli na stronie glownej wychodzilo 4+2 z dwiema pustymi komorkami.
   Trzy kolumny domykaja szesc na dwa rowne wiersze. */
.jag-offers{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(16px,2vw,24px);}
/* dwa kafle w siatce na trzy zostawialyby pusta trzecia kolumne,
   wiec pary maja wlasny wariant zamiast sierotki */
.jag-offers--pair{grid-template-columns:repeat(2,1fr);}
/* Dwie siatki jedna pod druga czytaja sie jak jedna, o ile odstep miedzy nimi
   jest taki sam jak odstep wewnatrz. Sluzy to przypadkowi, gdy kart jest piec:
   trzy w rzedzie, a pod nimi para szerszych, zamiast rzedu z dziura. */
.jag-offers + .jag-offers{margin-top:clamp(16px,2vw,24px);}
@media (max-width:1024px){.jag-offers{grid-template-columns:repeat(2,1fr);}}
@media (max-width:640px){.jag-offers,.jag-offers--pair{grid-template-columns:1fr;}}
.jag-offer{position:relative; display:flex; flex-direction:column; background:var(--bg); border:1px solid var(--hairline); border-radius:var(--r-lg); overflow:hidden; transition:transform .3s var(--ease), box-shadow .3s, border-color .3s;}
.jag-offer:hover{transform:translateY(-4px); box-shadow:0 18px 40px rgba(36,30,28,.10); border-color:var(--hairline-strong);}
.jag-offer .media{aspect-ratio:16/11; background:var(--surface); overflow:hidden;}
.jag-offer .media img{width:100%;height:100%;object-fit:cover; transition:transform .7s var(--ease);}
.jag-offer:hover .media img{transform:scale(1.05);}
.jag-offer .body{padding:22px 24px 26px; display:flex; flex-direction:column; flex:1;}
.jag-offer :is(h2,h3){font-size:1.3rem; font-weight:600; letter-spacing:-.01em;}
.jag-offer p{margin-top:10px; color:var(--ink-soft); font-size:.97rem; flex:1;}
.jag-offer .textlink{margin-top:18px;}
.jag-offer.featured{grid-column:span 2;}
.jag-offer.featured .media{aspect-ratio:auto;}
@media (max-width:720px){.jag-offer.featured{grid-column:span 1;}}

/* feature rows */
.jag-rows{display:flex; flex-direction:column; gap:clamp(40px,6vw,80px);}
.jag-row{display:grid; grid-template-columns:1fr 1fr; gap:clamp(28px,4vw,64px); align-items:center;}
.jag-row:nth-child(even) .row-media{order:2;}
.jag-row .row-media{border-radius:var(--r-lg); overflow:hidden; background:var(--surface); aspect-ratio:4/3;}
.jag-row .row-media img{width:100%;height:100%;object-fit:cover; transition:transform .8s var(--ease);}
.jag-row:hover .row-media img{transform:scale(1.03);}
.jag-row h3{font-size:clamp(1.4rem,2.4vw,1.95rem); font-weight:600; letter-spacing:-.02em; line-height:1.1;}
.jag-row p{margin-top:16px; color:var(--ink-soft); max-width:48ch;}
/* rzad tagów: byl scharakteryzowany tylko wewnatrz .jag-row, wiec kazde
   uzycie poza wierszem konczylo sie powtarzaniem tych samych regul inline */
/* .mini i .jag-tag usuniete razem z plakietkami z naglowkow podstron oferty -
   po ich skasowaniu w tresci nie zostalo zadnego elementu, ktory by ich uzywal. */
.jag-row .textlink{margin-top:22px;}

/* wood swatches */
.jag-woods{display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(14px,2vw,26px);}
.jag-wood{background:var(--bg); border:1px solid var(--hairline); border-radius:var(--r-lg); overflow:hidden; transition:transform .3s var(--ease), box-shadow .3s;}
.jag-wood:hover{transform:translateY(-4px); box-shadow:0 14px 34px rgba(36,30,28,.09);}
.jag-swatch{height:120px; position:relative;}
.jag-swatch::after{content:""; position:absolute; inset:0; background-image:repeating-linear-gradient(92deg, rgba(60,40,20,.10) 0 1px, transparent 1px 7px); mix-blend-mode:multiply;}
.jag-swatch.sosna{background:linear-gradient(160deg,#efd9b4,#e6cfa3);}
.jag-swatch.buk{background:linear-gradient(160deg,#f0d8bf,#e3bfa0);}
.jag-swatch.dab{background:linear-gradient(160deg,#d59f5f,#c07f38);}
.jag-swatch.jesion{background:linear-gradient(160deg,#ecdcc0,#ddc7a2);}
.jag-wood .wb{padding:18px 20px 22px;}
.jag-wood h3{font-size:1.2rem; font-weight:600;}
.jag-wood .meta{margin-top:10px; display:flex; flex-direction:column; gap:5px;}
.jag-wood .meta div{display:flex; justify-content:space-between; font-size:.86rem; color:var(--muted);}
.jag-wood .meta b{color:var(--ink); font-weight:600;}
.jag-wood .track{height:5px; background:var(--surface); border-radius:100px; overflow:hidden; margin-top:14px;}
.jag-wood .fill{height:100%; background:var(--brand); border-radius:100px;}

/* steps */
.jag-steps{display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(20px,3vw,36px); counter-reset:step;}
/* Numer szedl absolutnie na top:18px przy .jag-step{padding-top:30px}. Przy
   0,85 rem jego linia konczyla sie okolo 34 px, czyli nizej niz zaczynal sie
   tytul - stad wrazenie, ze cyfra jest wcisnieta w naglowek. Numer wraca do
   normalnego przeplywu, wiec odstep jest policzony, a nie zgadniety:
   kreska, 26 px, numer, 18 px, tytul. */
.jag-step{position:relative; padding-top:26px; border-top:2px solid var(--ink);}
.jag-step::before{counter-increment:step; content:"0" counter(step); display:block; margin-bottom:18px; font-size:1.05rem; font-weight:700; line-height:1; letter-spacing:.01em; color:var(--brand-strong);}
.jag-step :is(h2,h3){font-size:1.22rem; font-weight:600; margin-bottom:12px;}
.jag-step p{font-size:.96rem; color:var(--ink-soft);}

/* gallery + lightbox */
.jag-gallery{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px;}
.jag-gallery:has(>.jag-gitem:last-child:nth-child(1)){grid-template-columns:minmax(0,420px);}
.jag-gallery:has(>.jag-gitem:last-child:nth-child(2)){grid-template-columns:repeat(2,minmax(0,1fr)); max-width:820px;}
/* Rytm galerii. Rowna siatka 3 kolumn czytala sie jak arkusz kontaktowy -
   osiem zdjec tej samej wielkosci, zadnej hierarchii. Od piatego zdjecia
   wchodzi wiec uklad 4-kolumnowy, w ktorym co piate zdjecie zajmuje pole
   2x2, a przeplyw dense domyka luki mniejszymi kaflami.
   Wyjatek na koncu: jesli duzy kafel wypadlby wsrod czterech ostatnich
   zdjec, wraca do 1x1. Bez tego galeria konczy sie dziura wielkosci
   czterech pol, bo nie ma juz czym jej wypelnic. */
/* Wysokosci: siatka ma drobna jednostke wiersza (~74 px), a kafle zajmuja
   4, 5 lub 6 takich jednostek. Dzieki temu sasiednie kolumny nie konczy sie
   w tej samej linii i zdjecia przeplataja sie jak w masonry - ale szerokosc
   kolumny zostaje stala, wiec nic sie nie kurczy. */
@media (min-width:1000px){
.jag-gallery:has(>.jag-gitem:nth-child(5)){grid-template-columns:repeat(4,minmax(0,1fr)); grid-auto-flow:dense; grid-auto-rows:clamp(46px,4.8vw,74px);}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem{aspect-ratio:auto; grid-row:span 5;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem:nth-child(5n+3),
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem:nth-child(5n+4){grid-row:span 6;}
/* Duze zdjecie zmienia strone co blok: pierwszy ma je z lewej, drugi z prawej.
   Kolumna jest podana wprost (1/span 2 albo 3/span 2), bo samo span 2 przy
   przeplywie dense zawsze laduje w pierwszej wolnej kolumnie, czyli z lewej. */
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem:nth-child(10n+1){grid-column:1/span 2; grid-row:span 11;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem:nth-child(10n+6){grid-column:3/span 2; grid-row:span 11;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem:nth-child(5n+1):nth-last-child(-n+4){grid-column:auto; grid-row:span 5;}
/* Ogon galerii - klasy nadaje JS po policzeniu, ile zdjec jest widocznych.
   Uklad chodzi blokami po piec, wiec przy 8 czy 24 widocznych ostatni blok
   jest niepelny. Bez tego duzy kafel na 11 wierszy stal obok dwoch krotszych
   i zostawial pod nimi ok. 500 px pustki, a ostatni rzad nie domykal kolumn.
   is-flat  - duzy kafel wraca do rozmiaru 1x1, bo nie ma go czym obstawic,
   is-tail  - wyrownana wysokosc, zeby dol galerii byl prosty,
   is-tail2 - kafel na dwie kolumny (przy dwoch lub trzech zdjeciach w ogonie),
   is-tail4 - kafel na cala szerokosc (gdy w ogonie zostaje jedno zdjecie). */
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-flat.is-flat{grid-column:auto;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-tail.is-tail{grid-row:span 5;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-tail2.is-tail2{grid-column:span 2;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-tail3.is-tail3{grid-column:span 3;}
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-tail4.is-tail4{grid-column:1/-1; grid-row:span 6;}
/* Poziome zdjecia: po dwie kolumny, wiec staja obok siebie i razem domykaja
   rzad. Dziala to tylko dlatego, ze w kolejnosci galerii ida zaraz po pelnym
   bloku - siatka jest wtedy rowna i pierwszy z nich laduje w kolumnie 1.
   Wczesniej, wstawione w srodek niepelnego rzedu, dense przesuwal je o jedna
   kolumne i pod spodem zostawaly schodki pustych pol. */
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-wide.is-wide{grid-column:span 2; grid-row:span 3;}
/* Kadr poziomy w ogonie dostaje te sama wysokosc co reszta ogona. Bez tego
   w jednym rzedzie stal kafel na 3 wiersze obok kafla na 5 i pod nizszym
   zostawala dziura - ogon domyka kolumny tylko wtedy, gdy jest rowny. */
.jag-gallery:has(>.jag-gitem:nth-child(5)) .jag-gitem.is-wide.is-tail.is-tail{grid-row:span 5;}
}
.jag-gitem{border-radius:var(--r-lg); overflow:hidden; background:var(--surface); cursor:zoom-in; position:relative; display:block; width:100%; border:0; padding:0; aspect-ratio:3/4;}
.jag-gitem img{width:100%; height:100%; object-fit:cover; display:block; transition:transform .7s var(--ease);}
/* Zdjecia poziome. W kaflu 3:4 zostawaly z nich same srodki - kadr poziomy
   przycinany do pionu traci to, co go tworzy. Dostaja wiec wlasny format. */
.jag-gitem.is-wide{aspect-ratio:3/2;}
/* Ponizej ukladu 4-kolumnowego kadr poziomy w polowie szerokosci robi sie
   znaczkiem - na waskim ekranie bierze caly rzad. */
/* margin-top na kadrze poziomym to nie odstep dla ozdoby: kafel z prawej
   kolumny jest zsuniety transformem, wiec wystaje o te sama wartosc poza
   swoj wiersz i bez tego marginesu wchodzil na pas poziomy o 10 px. */
@media (max-width:999px){.jag-gallery:has(>.jag-gitem.is-wide){grid-auto-flow:dense;} .jag-gallery .jag-gitem.is-wide{grid-column:1/-1; margin-top:clamp(18px,5vw,32px);}}
/* Telefon: dwie rowne kolumny czytaly sie jak tabelka - kazde zdjecie
   zaczynalo sie i konczylo w tej samej linii co sasiad. Prawa kolumna jest
   wiec zsunieta w dol, przez co lewa wydaje sie wyzsza i galeria dostaje
   rytm. Przesuniecie robi transform, wiec nie rusza siatki - stad padding
   na dole, ktory oddaje wysunietemu kaflowi miejsce. Kadry poziome biora
   caly rzad, wiec ich to nie dotyczy. */
@media (max-width:999px){
  .jag-gallery{padding-bottom:clamp(18px,5vw,32px);}
  .jag-gallery>.jag-gitem:nth-child(even):not(.is-wide){transform:translateY(clamp(18px,5vw,32px));}
}
/* Wczytaj wiecej. Ukryte kafle maja loading=lazy, wiec dopoki nie zostana
   pokazane, przegladarka nie pobiera ich plikow - button faktycznie wczytuje
   zdjecia, a nie tylko odslania juz sciagniete.
   Gdy zdjec jest osiem lub mniej, button znika sam - nie ma czego wczytywac. */
.jag-gallery.is-collapsed>.jag-gitem:nth-child(n+9){display:none;}
/* Realizacje startuja od szesnastu. Regula jest w CSS, a nie tylko w JS,
   zeby przed uruchomieniem skryptu nie mrugnelo osiem kafli zamiast szesnastu. */
.jag-gallery.is-collapsed[data-start="16"]>.jag-gitem:nth-child(n+9){display:block;}
.jag-gallery.is-collapsed[data-start="16"]>.jag-gitem:nth-child(n+17){display:none;}
.jag-gitem[hidden]{display:none;}
.jag-gallery-more{display:flex; justify-content:center; margin-top:clamp(22px,3vw,34px);}
.jag-gallery-more[hidden]{display:none;}
.jag-gallery:not(:has(>.jag-gitem:nth-child(9))) + .jag-gallery-more{display:none;}
.jag-gitem::after{content:""; position:absolute; inset:0; background:linear-gradient(to top, rgba(36,30,28,.28), transparent 42%); opacity:0; transition:opacity .35s;}
.jag-gitem:hover img{transform:scale(1.045);} .jag-gitem:hover::after{opacity:1;}
/* visibility zamiast display: dzieki temu zamkniecie tez ma przebieg,
   a nie znika w jednej klatce w polowie wygaszania tla */
.jag-lb{position:fixed; inset:0; z-index:var(--z-lightbox); background:rgba(24,20,18,.94); display:flex; align-items:center; justify-content:center; opacity:0; visibility:hidden; transition:opacity .3s var(--ease), visibility 0s .3s;}
.jag-lb.open{opacity:1; visibility:visible; transition:opacity .3s var(--ease), visibility 0s;}
.jag-lb img{max-width:min(92vw,1100px); max-height:86vh; width:auto; height:auto; border-radius:var(--r); box-shadow:0 30px 80px rgba(0,0,0,.5); transform:scale(.955); transition:transform .4s var(--ease), opacity .16s linear;}
.jag-lb.open img{transform:none;}
.jag-lb.swap img{opacity:0; transition:opacity .12s linear;}
.jag-lb-btn{position:absolute; background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.22); color:#fff; width:52px; height:52px; border-radius:50%; display:flex; align-items:center; justify-content:center; transition:background .2s;}
.jag-lb-btn:hover{background:rgba(255,255,255,.22);} .jag-lb-btn svg{width:22px;height:22px;}
.jag-lb-close{top:22px; right:22px;} .jag-lb-prev{left:20px; top:50%; transform:translateY(-50%);} .jag-lb-next{right:20px; top:50%; transform:translateY(-50%);}
.jag-lb-count{position:absolute; bottom:24px; left:50%; transform:translateX(-50%); color:rgba(255,255,255,.8); font-size:.9rem;}

/* proby drewna
   Podpis siedzi POD zdjeciem, nie pojawia sie na najechanie: dziala na
   dotyku, czyta go czytnik ekranu i widac go bez zadnej interakcji.
   Nazwa gatunku to tutaj tresc, a nie ozdoba - chowanie jej za hoverem
   znaczyloby, ze na telefonie ta sekcja jest zbiorem nieopisanych kwadratow.
   auto-fit zwija puste sciezki, wiec cztery, piec albo szesc probek zawsze
   tworzy jeden rowny rzad bez sierotki. */
.jag-samples{display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:clamp(14px,1.8vw,22px);}
.jag-sample{display:flex; flex-direction:column; gap:12px; width:100%; padding:0; border:0; background:none; text-align:left; cursor:zoom-in;}
.jag-sample .shot{border:1px solid var(--hairline); border-radius:var(--r-lg); overflow:hidden; background:var(--surface); aspect-ratio:3/4; transition:border-color .3s;}
.jag-sample .shot img{width:100%; height:100%; object-fit:cover; display:block; transition:transform .7s var(--ease);}
.jag-sample:hover .shot{border-color:var(--hairline-strong);}
.jag-sample:hover .shot img{transform:scale(1.04);}
.jag-sample b{font-size:.97rem; font-weight:600; color:var(--ink); line-height:1.25;}
.jag-sample small{display:block; font-size:.82rem; color:var(--muted); margin-top:3px;}
@media (max-width:1024px){.jag-samples{grid-template-columns:repeat(2,1fr);}}

/* trust */
/* auto-fit zamiast sztywnych dwoch kolumn: trzy pozycje tworzyly 2+1
   i zostawialy dziure w prawym dolnym rogu na dwoch stronach */
.jag-trust{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:clamp(28px,4vw,56px) clamp(40px,6vw,80px);}
.jag-trust-item{display:grid; grid-template-columns:auto 1fr; gap:18px; align-items:start;}
.jag-trust-item .ic{width:38px; height:38px; flex:none; color:var(--brand-strong);}
.jag-trust-item h3{font-size:1.22rem; font-weight:600; margin-bottom:8px;}
.jag-trust-item p{color:var(--ink-soft); font-size:.98rem; max-width:44ch;}

/* spec list */
/* Kreski rysuja teraz cienie komorek, a nie gap:1px na tle --hairline.
   Przy szesciu pozycjach w siatce mieszczacej piec resztka wiersza
   pokazywala sie jako szary prostokat. Teraz pusta reszta to po prostu tlo,
   niezaleznie od liczby pozycji. */
/* Liczba kolumn nie moze byc dobierana automatycznie. auto-fit dawal przy
   1224 px cztery kolumny, a pozycji jest szesc - ostatni rzad konczyl sie
   w polowie, kreska pozioma urywala sie w powietrzu i po prawej zostawalo
   puste pole w ramce. Kolumny sa teraz dobrane do liczby pozycji, wiec
   kazdy rzad jest pelny: szesc idzie 3x2, cztery jednym rzedem. */
.jag-specs{display:grid; grid-template-columns:repeat(3,1fr); background:var(--bg); border:1px solid var(--hairline); border-radius:var(--r-lg); overflow:hidden;}
.jag-specs:has(>.jag-spec:nth-child(4):last-child){grid-template-columns:repeat(4,1fr);}
@media (max-width:980px){
  .jag-specs,.jag-specs:has(>.jag-spec:nth-child(4):last-child){grid-template-columns:repeat(2,1fr);}
}
@media (max-width:560px){
  .jag-specs,.jag-specs:has(>.jag-spec:nth-child(4):last-child){grid-template-columns:1fr;}
}
.jag-spec{background:var(--bg); padding:22px 24px; box-shadow:-1px 0 0 var(--hairline), 0 -1px 0 var(--hairline);}
.jag-spec dt{font-size:.82rem; font-weight:600; color:var(--muted); margin-bottom:8px;}
.jag-spec dd{font-size:1.05rem; color:var(--ink);}

/* FAQ */
.jag-faq{max-width:820px;}
.jag-faq-cta{max-width:820px; margin-top:28px; display:flex;}
@media (max-width:560px){.jag-faq-cta .btn{width:100%; justify-content:center;}}
.jag-q{border-bottom:1px solid var(--hairline);}
.jag-q button{width:100%; display:flex; align-items:center; justify-content:space-between; gap:20px; text-align:left; padding:22px 0; background:none; border:0; font-size:1.12rem; font-weight:600; color:var(--ink);}
.jag-q .ic{width:22px; height:22px; flex:none; color:var(--brand-strong); transition:transform .3s var(--ease);}
.jag-q[open] .ic, .jag-q.open .ic{transform:rotate(45deg);}
/* grid-template-rows zamiast max-height: nie trzeba zgadywac wysokosci,
   wiec odpowiedz otwiera sie tym samym tempem niezaleznie od dlugosci */
/* Zwiniety stan przeciekal: min-height:0 zeruje tylko pudelko tresci, a
   marginesy i padding elementu i tak licza sie do minimalnego wkladu do
   wiersza siatki. Akapit odpowiedzi mial padding-bottom 24 px i marginesy,
   wiec sciezka 0fr konczyla sie na kilkudziesieciu pikselach zamiast na
   zerze i pierwsza linia odpowiedzi byla widoczna przed rozwinieciem.
   Element siatki nie ma teraz wlasnych marginesow ani paddingu, a odstep
   pod odpowiedzia pojawia sie razem z nia. Do tego visibility:hidden w
   stanie zwinietym, zeby tresc nie byla czytana przez czytniki ekranu
   i zeby linki w odpowiedzi nie lapaly fokusu. */
.jag-q .ans{display:grid; grid-template-rows:0fr; overflow:hidden; visibility:hidden; transition:grid-template-rows .34s var(--ease), visibility 0s linear .34s;}
.jag-q.open .ans,.jag-q[open] .ans{grid-template-rows:1fr; visibility:visible; transition:grid-template-rows .34s var(--ease), visibility 0s;}
.jag-q .ans>*{overflow:hidden; min-height:0; margin:0; padding:0;}
.jag-q .ans p{color:var(--ink-soft); max-width:70ch;}
.jag-q.open .ans p,.jag-q[open] .ans p{padding-bottom:24px;}

/* CTA band (na każdej stronie) */
.jag-cta-band{background:var(--ink); color:#fff;}
.jag-cta-band .in{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:28px;}
.jag-cta-band h2{font-size:clamp(1.6rem,3vw,2.4rem); font-weight:600; letter-spacing:-.02em; line-height:1.1; max-width:20ch; text-wrap:balance;}
.jag-cta-band p{margin-top:12px; color:rgba(255,255,255,.7); max-width:44ch;}
.jag-cta-band .acts{display:flex; flex-wrap:wrap; gap:14px; align-items:center;}
.jag-cta-band .tel-lg{color:#fff; font-size:1.3rem; font-weight:700; display:flex; align-items:center; gap:10px;}
/* Pasmo koncowe niesie teraz formularz, wiec przechodzi na te sama siatke co
   sekcja kontaktu: tekst z numerem po lewej, kreator po prawej. Reuzywamy
   .jag-k-grid, bo ma juz przetestowane zwijanie do jednej kolumny na 860 px.
   Numer zostaje w lewej kolumnie, zeby nie znikl z hierarchii. */
.jag-cta-band .jag-k-grid .tel-lg{width:fit-content; margin-top:26px;}
.jag-cta-band .jag-k-grid .jag-proof{margin-top:22px;}
/* Pasmo ma wlasna regule dla kazdego <p>, pisana pod bialy tekst na ciemnym
   tle. Formularz jest w tym pasmie bialym kartonikiem, wiec ta regula trafiala
   takze w pytania kreatora i w notke pod przyciskiem: bialy tekst na bialym
   tle, czyli trzy niewidoczne akapity. Zdejmujemy ja w obrebie formularza.
   Regula na element (0-1-1) przegrywa z ta na dwie klasy plus element. */
.jag-cta-band .jag-form p{margin-top:0; max-width:none; color:var(--ink);}
.jag-cta-band .jag-form .jag-form-note{color:var(--muted);}
.jag-cta-band .jag-form .jag-wiz-call small{color:rgba(255,255,255,.78);}
.jag-cta-band .tel-lg svg{width:22px;height:22px;color:#ff7a4d;}

/* contact / form */
.jag-kontakt{background:var(--ink); color:#fff;}
.jag-k-grid{display:grid; grid-template-columns:1.1fr .9fr; gap:clamp(36px,6vw,88px); align-items:start;}
.jag-kontakt h2{font-size:clamp(1.9rem,3.6vw,3rem); font-weight:600; line-height:1.05; letter-spacing:-.025em; text-wrap:balance; max-width:16ch;}
.jag-kontakt .sub{margin-top:20px; color:rgba(255,255,255,.72); max-width:44ch;}
.jag-k-contact{margin-top:34px; display:flex; flex-direction:column; gap:20px;}
.jag-k-line{display:flex; align-items:center; gap:14px;}
.jag-k-line .ic{width:22px; height:22px; color:#ff7a4d; flex:none;}
.jag-k-line b{font-size:1.5rem; font-weight:700;}
.jag-k-line small{display:block; color:rgba(255,255,255,.6); font-size:.85rem; margin-top:2px;}
.jag-form{background:var(--bg); color:var(--ink); border-radius:var(--r-lg); padding:clamp(24px,3vw,38px);}
.jag-field{margin-bottom:18px;}
.jag-field label{display:block; font-size:.9rem; font-weight:600; margin-bottom:8px;}
.jag-field input,.jag-field textarea{width:100%; font:inherit; font-size:1rem; color:var(--ink); background:var(--surface); border:1px solid var(--hairline-strong); border-radius:var(--r); padding:13px 15px; transition:border-color .2s, box-shadow .2s;}
.jag-field textarea{resize:vertical; min-height:104px;}
.jag-field input::placeholder,.jag-field textarea::placeholder{color:#9a938f;}
.jag-field input:focus,.jag-field textarea:focus{outline:0; border-color:var(--brand-strong); box-shadow:0 0 0 3px var(--brand-soft);}
.jag-field.invalid input,.jag-field.invalid textarea{border-color:#c0261a; box-shadow:0 0 0 3px #f7dcd8; animation:jag-nudge .32s var(--ease);}
@keyframes jag-nudge{0%{transform:translateX(0);} 28%{transform:translateX(-4px);} 62%{transform:translateX(3px);} 100%{transform:translateX(0);}}
.jag-field .err{display:none; color:#a51f14; font-size:.84rem; font-weight:500; margin-top:7px;}
.jag-field.invalid .err{display:block;}
.jag-form .btn{width:100%; margin-top:6px;}
.jag-form-note{margin-top:14px; font-size:.82rem; color:var(--muted); text-align:center;}

/* Zgoda na kontakt. Wlasny kwadrat zamiast systemowego, zeby dal sie zrobic
   na 24 px i w kolorze marki, ale klikalny obszar to caly wiersz z trescia,
   wiec cel dotykowy ma pelna szerokosc pola i nie schodzi ponizej 44 px. */
.jag-consent{margin-bottom:20px;}
/* Selektor musi byc scharakteryzowany mocniej niz .jag-field label (0-1-1),
   ktore ustawia display:block. Przy 0-1-0 etykieta zostawala blokiem, span
   byl elementem liniowym i ignorowal wymiary, wiec kwadrat mial 2 x 18 px
   i praktycznie nie bylo go widac. Tu jest 0-2-1. */
.jag-field .jag-check{display:flex; align-items:flex-start; gap:12px; padding:6px 0; margin-bottom:0; font-size:1rem; font-weight:500; cursor:pointer;}
.jag-check input{position:absolute; width:1px; height:1px; margin:0; padding:0; opacity:0; pointer-events:none;}
.jag-check>span{flex:none; width:24px; height:24px; margin-top:1px; background:var(--surface); border:1px solid var(--hairline-strong); border-radius:var(--r); position:relative; transition:background .18s, border-color .18s;}
.jag-check>span::after{content:""; position:absolute; left:7px; top:3px; width:8px; height:14px; border-right:2.5px solid #fff; border-bottom:2.5px solid #fff; transform:rotate(40deg) scale(.6); opacity:0; transition:opacity .18s, transform .18s var(--ease);}
.jag-check input:checked+span{background:var(--brand-strong); border-color:var(--brand-strong);}
.jag-check input:checked+span::after{opacity:1; transform:rotate(40deg) scale(1);}
.jag-check input:focus-visible+span{outline:2.5px solid var(--brand-strong); outline-offset:3px;}
.jag-check small{font-size:.86rem; font-weight:400; line-height:1.45; color:var(--ink-soft);}
.jag-check a{color:var(--brand-strong); font-weight:600; text-decoration:underline; text-underline-offset:2px;}
.jag-field.invalid .jag-check>span{border-color:#c0261a; box-shadow:0 0 0 3px #f7dcd8;}

/* ===== okno zgody na ciasteczka =====
   Banner wtyczki siedzi w shadow DOM, wiec z zewnatrz da sie ruszyc tylko
   hosta (#wpconsent-container w zwyklym DOM) i te elementy, ktore wtyczka
   wystawia przez atrybut part. Nazwy partow sprawdzone w wygenerowanym HTML.
   Uklad "modal" ustawiony w opcjach wtyczki dodaje klase, ale jej frontowy
   arkusz nie ma dla niej ani jednej reguly, wiec cale pozycjonowanie jest tu.
   Deklaracje z zewnetrznego drzewa wygrywaja z regulami wewnatrz shadow root,
   dlatego nie ma tu ani jednego !important.

   Okno nie blokuje strony: zadnego przygaszonego tla, zadnej blokady
   przewijania. Mozna czytac i klikac dalej, a wybor zrobic pozniej.

   Telefon: szuflada przyklejona do dolu, na pelna szerokosc, zaokraglona tylko
   u gory. Desktop od 861 px: pudelko w prawym dolnym rogu. */
#wpconsent-container{--wpconsent-min-width:0px; --wpconsent-border-radius:var(--r-lg); --wpconsent-padding:clamp(20px,4vw,26px);}
/* Wtyczka trzyma --wpconsent-min-width na 526 px i uzywa tej liczby dwa razy:
   jako min-width calego okna i jako STALA szerokosc tresci (width, nie
   max-width). Przy wezszym oknie tresc wychodzila za krawedz, a na telefonie
   min-width lamalby strone w poprzek. Zerujemy zrodlo, a nie skutki. Zmienne
   dziedzicza sie przez granice shadow root, wiec wystarcza na hoscie. */

/* Okno bylo siatka z jednym wierszem minmax(0,1fr). Do tego wtyczka
   pozycjonuje je przez right:10px i bottom:10px, wiec kazda krawedz, ktorej
   nie chcemy, trzeba wygasic jawnie - inaczej przy height:auto i podanych obu
   krawedziach pudelko rozciaga sie miedzy nimi, a wiersz 1fr zjada nadwyzke
   jako pusta przestrzen miedzy tekstem i przyciskami. */
#wpconsent-container::part(wpconsent-banner){display:flex; flex-direction:column; gap:20px; grid-template-rows:none; position:fixed; top:auto; left:0; right:0; bottom:0; transform:none; width:auto; min-width:0; max-width:none; height:auto; max-height:calc(100vh - 24px); overflow:auto; margin:0; padding:clamp(20px,4vw,26px) clamp(18px,4vw,24px); border-radius:var(--r-lg) var(--r-lg) 0 0; box-shadow:0 -18px 50px rgba(0,0,0,.35);}
@media (min-width:861px){
  #wpconsent-container::part(wpconsent-banner){left:auto; right:24px; bottom:24px; width:420px; padding:clamp(22px,3vw,30px); border-radius:var(--r-lg); box-shadow:0 24px 60px rgba(0,0,0,.4); max-height:calc(100vh - 48px);}
}
/* Na telefonie u dolu siedzi juz pasek szybkiego kontaktu z numerem, wiec
   szuflada podnosi sie o jego wysokosc, zeby go nie zakrywac. Warunek na .up,
   bo pasek wyjezdza dopiero po zjechaniu ponizej hero - inaczej na gorze
   strony pod szuflada wisialaby pusta przerwa. Pasek i kontener wtyczki nie sa
   rodzenstwem, wiec przez ~ tego nie da sie zlapac i stad :has() na body.
   Bez wsparcia dla :has() szuflada po prostu zakrywa pasek, czyli tyle, ile
   robila wczesniej. */
@media (max-width:860px){
  body:has(.jag-callbar.up) #wpconsent-container::part(wpconsent-banner){bottom:52px;}
}
#wpconsent-container::part(wpconsent-banner-body){width:auto; max-width:none; max-height:none; margin:0; padding:0; text-align:left;}
/* Szerokosc, nie wysokosc, jest tu wielkoscia prowadzaca, bo przy sterowaniu
   wysokoscia i clampowaniu max-width znak splaszczylby sie w poprzek.
   Druga wartosc to vw, nie procent: procent liczy sie od kontenera, a ten
   siedzi w naglowku o siatce 100px 1fr 100px, wiec logo dostawaloby 100 px.
   Jednostka vw nie zalezy od rodzica, wiec rozmiar jest poprawny nawet gdy
   arkusz wstrzykiwany do shadow root nie dojdzie. */
#wpconsent-container::part(wpconsent-banner-logo){display:block; height:auto; width:min(340px,72vw); margin-inline:auto;}
#wpconsent-container::part(wpconsent-banner-footer){display:flex; flex-wrap:wrap; gap:10px; margin:0;}
/* Akceptacja i odrzucenie dziela rzad po rowno, wiec zaden z nich nie jest
   trudniejszy do trafienia. Ustawienia schodza pod nie na pelna szerokosc.
   Wtyczka dawala przyciskom 30 px wysokosci, czyli ponizej progu dotykowego. */
#wpconsent-container::part(wpconsent-button-accept),
#wpconsent-container::part(wpconsent-button-cancel){flex:1 1 46%; min-height:48px; border:0; border-radius:var(--r); font-weight:600;}
#wpconsent-container::part(wpconsent-button-preferences){flex:1 1 100%; order:3; min-height:44px; border:0; border-radius:var(--r); font-weight:600;}
#wpconsent-container::part(wpconsent-preferences-content){border-radius:var(--r-lg);}
/* Szuflada wjezdza z dolu, pudelko w narozniku tylko sie wylania. Rozne stany
   docelowe transformu, wiec kazdy wariant ma wlasna klatkowke. */
@media (prefers-reduced-motion:no-preference){
  #wpconsent-container::part(wpconsent-banner){animation:jag-consent-sheet .38s cubic-bezier(.16,1,.3,1) both;}
}
@media (prefers-reduced-motion:no-preference) and (min-width:861px){
  #wpconsent-container::part(wpconsent-banner){animation-name:jag-consent-corner;}
}
@keyframes jag-consent-sheet{from{opacity:0; transform:translateY(100%);} to{opacity:1; transform:none;}}
@keyframes jag-consent-corner{from{opacity:0; transform:translateY(10px);} to{opacity:1; transform:none;}}
/* ===== mapa dojazdu =====
   Osadzenie Google ustawia wlasne ciasteczka, wiec nie wczytujemy go, dopoki
   ktos sam o to nie poprosi. Dzieki temu mapa nie wpada pod zgode i widzi ja
   kazdy, a przy samym wejsciu na strone do Google nie leci zadne zapytanie.
   aspect-ratio trzyma wysokosc pudelka z gory, wiec podmiana zaslepki na ramke
   nie przesuwa niczego pod spodem. */
.jag-map{position:relative; aspect-ratio:16/7; border:1px solid var(--hairline-strong); border-radius:var(--r-lg); overflow:hidden; background:var(--bg);}
.jag-map-ph{position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; padding:24px; text-align:center;}
.jag-map-ph .ic{width:30px; height:30px; color:var(--brand-strong);}
.jag-map-ph b{font-size:clamp(1.05rem,1.8vw,1.3rem); font-weight:600; letter-spacing:-.01em; color:var(--ink);}
.jag-map-ph small{max-width:46ch; font-size:.88rem; line-height:1.45; color:var(--muted);}
.jag-map-acts{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:10px 20px; margin-top:6px;}
.jag-map iframe{display:block; width:100%; height:100%; border:0;}
.jag-map-under{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 24px; margin-top:16px;}
.jag-map-under b{font-size:1.02rem; font-weight:600; color:var(--ink);}
@media (max-width:700px){
  .jag-map{aspect-ratio:4/3;}
  .jag-map-acts{flex-direction:column; gap:12px;}
  .jag-map-acts .btn{width:100%;}
}

/* ===== 404 =====
   Celem nie jest przepraszanie, a zatrzymanie kogos na stronie. Dlatego pod
   komunikatem stoi cala oferta jako lista wyborów, a nie sam link do strony
   glownej. Liczba 404 jest cicha: informuje, ale nie jest bohaterem. */
.jag-404{padding-block:clamp(52px,8vw,96px);}
.jag-404 .wrap{max-width:900px;}
.jag-404-code{display:block; font-size:.86rem; font-weight:700; letter-spacing:.14em; color:var(--muted);}
.jag-404-h{margin-top:12px; font-size:clamp(1.9rem,4.4vw,2.9rem); font-weight:600; letter-spacing:-.03em; line-height:1.05;}
.jag-404-lead{margin-top:14px; max-width:56ch; font-size:clamp(1.02rem,1.5vw,1.15rem); color:var(--ink-soft);}
.jag-404-path{margin-top:14px; font-size:.9rem; color:var(--muted);}
.jag-404-path code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; color:var(--ink); font-weight:600; word-break:break-all;}
.jag-404-path[hidden]{display:none;}
.jag-404-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-top:clamp(30px,4vw,42px);}
.jag .jag-404-card{display:block; min-height:74px; padding:15px 17px; background:var(--surface); border:1px solid var(--hairline-strong); border-radius:var(--r); transition:border-color .2s, background .2s, transform .2s var(--ease);}
.jag .jag-404-card:hover{border-color:var(--ink); background:var(--bg); transform:translateY(-2px);}
.jag-404-card b{display:block; font-size:1rem; font-weight:600; color:var(--ink);}
.jag-404-card small{display:block; margin-top:3px; font-size:.86rem; color:var(--muted);}
.jag-404-more{display:flex; flex-wrap:wrap; gap:8px 22px; margin-top:26px;}
.jag .jag-404-more a{font-size:.94rem; font-weight:600; color:var(--brand-strong); text-decoration:underline; text-underline-offset:3px;}
.jag .jag-404-more a:hover{color:var(--ink);}
.jag-404-acts{display:flex; flex-wrap:wrap; align-items:center; gap:16px; margin-top:clamp(30px,4vw,40px); padding-top:clamp(26px,3.5vw,34px); border-top:1px solid var(--hairline);}
.jag .jag-404-tel{display:flex; align-items:center; gap:11px; color:var(--ink);}
.jag-404-tel svg{width:21px; height:21px; flex:none; color:var(--brand-strong);}
.jag-404-tel b{display:block; font-size:1.2rem; font-weight:700; line-height:1.1;}
.jag-404-tel small{display:block; margin-top:2px; font-size:.82rem; color:var(--muted);}
@media (max-width:640px){
  .jag-404-grid{grid-template-columns:1fr;}
  .jag-404-acts{flex-direction:column; align-items:stretch;}
  .jag-404-acts .btn{width:100%;}
  .jag .jag-404-tel{justify-content:center;}
}

/* ===== strona po wysłaniu formularza =====
   Ciemne tlo, bo to ma byc moment, a nie kolejna podstrona z trescią. Trzy
   rzeczy robia tu robote: znak potwierdzenia, ktory sam sie rysuje, pierwszy
   krok od razu odhaczony, zeby widac bylo postep, a nie slepy zaulek, oraz
   konkretne terminy zamiast ogolnikow. Pod spodem zawsze jest nastepny ruch:
   telefon dla niecierpliwych i realizacje do ogladania. */
.jag-ok{background:var(--ink); color:#fff; padding-block:clamp(56px,9vw,110px);}
.jag-ok .wrap{max-width:720px; text-align:center;}
.jag-ok-mark{display:block; width:clamp(56px,8vw,72px); margin:0 auto clamp(22px,3vw,30px); color:#6bd08a;}
.jag-ok-mark svg{width:100%; height:auto; display:block;}
.jag-ok-h{font-size:clamp(1.9rem,4.6vw,3rem); font-weight:600; letter-spacing:-.03em; line-height:1.05;}
.jag-ok-lead{margin-top:14px; font-size:clamp(1.02rem,1.6vw,1.2rem); color:rgba(255,255,255,.74); text-wrap:pretty;}
.jag-ok-echo{display:inline-block; margin-top:18px; padding:9px 16px; background:rgba(255,255,255,.08); border-radius:100px; font-size:.92rem; font-weight:600; color:#fff;}
.jag-ok-echo[hidden]{display:none;}
/* Kroki: lista z cienkim lacznikiem, zeby czytalo sie jako droga, a nie zbior
   punktow. Lacznik ma 1 px, wiec nie robi z tego kolorowej ramki. */
.jag-ok-steps{list-style:none; margin:clamp(34px,5vw,52px) 0 0; padding:0; text-align:left; display:grid; gap:0;}
.jag-ok-steps li{position:relative; display:flex; align-items:flex-start; gap:16px; padding:0 0 22px 0;}
.jag-ok-steps li:last-child{padding-bottom:0;}
.jag-ok-steps li::before{content:""; position:absolute; left:17px; top:36px; bottom:0; width:1px; background:rgba(255,255,255,.16);}
.jag-ok-steps li:last-child::before{display:none;}
.jag-ok-steps .n{flex:none; width:35px; height:35px; border-radius:50%; display:grid; place-items:center; font-size:.92rem; font-weight:700; color:rgba(255,255,255,.62); background:rgba(255,255,255,.08); position:relative; z-index:1;}
.jag-ok-steps .is-done .n{background:#6bd08a; color:#10331c; font-size:1.05rem;}
.jag-ok-steps b{display:block; font-size:1.05rem; font-weight:600; color:#fff;}
.jag-ok-steps .is-done b{color:#6bd08a;}
.jag-ok-steps small{display:block; margin-top:3px; font-size:.92rem; line-height:1.45; color:rgba(255,255,255,.62);}
.jag-ok-acts{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:16px; margin-top:clamp(32px,4.5vw,46px);}
.jag .jag-ok-tel{display:flex; align-items:center; gap:12px; text-align:left; padding:12px 20px 12px 16px; border:1px solid rgba(255,255,255,.22); border-radius:var(--r); color:#fff; transition:border-color .2s, background .2s;}
.jag .jag-ok-tel:hover{border-color:#fff; background:rgba(255,255,255,.06); color:#fff;}
.jag-ok-tel svg{width:22px; height:22px; flex:none; color:#ff7a4d;}
.jag-ok-tel b{display:block; font-size:1.25rem; font-weight:700; line-height:1.1;}
.jag-ok-tel small{display:block; margin-top:2px; font-size:.82rem; color:rgba(255,255,255,.6);}
/* Prawdziwe probki drewna, te same, ktore klient i tak wybiera przy zamowieniu.
   To jest ten moment: czekanie na telefon dostaje sens, bo jest w nim konkretna
   rzecz do zrobienia, a nie ozdoba. Materiał nalezy do tego produktu i zadna
   inna witryna nie mogłaby tego użyć bez zmian. */
.jag .jag-ok-wood{display:block; margin-top:clamp(30px,4vw,42px); padding:18px; text-align:left; background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.12); border-radius:var(--r-lg); color:#fff; transition:background .25s, border-color .25s;}
.jag .jag-ok-wood:hover{background:rgba(255,255,255,.09); border-color:rgba(255,255,255,.26); color:#fff;}
.jag-ok-wood-strip{display:flex; gap:6px; margin-bottom:16px;}
/* Kadrowanie probek. Pliki to renderingi 600x800 na bialym tle: drewno zajmuje
   poziomo od 14 do 87 procent szerokosci, w najwezszym przypadku od 16 do 86.
   Bez kadrowania kazdy kafel mial biala obwodke i strip czytal sie jak zepsuta
   siatka, a nie jak wzornik. Powiekszenie 1,5 wynika z 1/0,70 plus zapas.
   Wartosci zmierzone na wszystkich szesciu plikach, nie przyjete na oko. */
.jag-ok-wood-strip .sw{flex:1 1 0; min-width:0; height:clamp(46px,7vw,62px); border-radius:2px; overflow:hidden; display:block;
  transition:transform .4s var(--ease); transition-delay:calc(var(--i) * 22ms);}
.jag-ok-wood-strip .sw img{width:100%; height:100%; object-fit:cover; display:block; transform:scale(1.5);}
/* Probki podnosza sie po kolei, jak wachlarz wzornika w rece. Ruch jest
   odpowiedzia na najechanie, nie kolejnym wejsciem sekcji. Podnosi sie
   opakowanie, bo transform obrazka trzyma powiekszenie. */
.jag .jag-ok-wood:hover .jag-ok-wood-strip .sw,
.jag .jag-ok-wood:focus-visible .jag-ok-wood-strip .sw{transform:translateY(-4px);}
.jag-ok-wood-txt b{display:flex; align-items:center; gap:8px; font-size:1.05rem; font-weight:600;}
.jag-ok-wood-txt b svg{width:17px; height:17px; flex:none; transition:transform .25s var(--ease);}
.jag .jag-ok-wood:hover .jag-ok-wood-txt b svg{transform:translateX(4px);}
.jag-ok-wood-txt small{display:block; margin-top:5px; font-size:.9rem; line-height:1.45; color:rgba(255,255,255,.64);}
.jag .jag-ok-link{display:inline-flex; align-items:center; gap:7px; font-weight:600; color:rgba(255,255,255,.78); text-decoration:underline; text-underline-offset:3px; transition:color .2s;}
.jag .jag-ok-link:hover{color:#fff;}
.jag-ok-link svg{width:15px; height:15px; transition:transform .25s var(--ease);}
.jag .jag-ok-link:hover svg{transform:translateX(3px);}
.jag-ok-foot{margin-top:clamp(28px,4vw,40px); font-size:.88rem; color:rgba(255,255,255,.58);}
.jag-ok-foot a{color:rgba(255,255,255,.8); text-decoration:underline; text-underline-offset:2px;}
/* Znak rysuje sie sam: najpierw okrag, potem ptaszek. Przy wylaczonych
   animacjach po prostu jest od razu narysowany. */
@media (prefers-reduced-motion:no-preference){
  .jag-ok-mark svg .c{stroke-dasharray:150; stroke-dashoffset:150; animation:jag-ok-circle .5s var(--ease) .05s forwards;}
  .jag-ok-mark svg .t{stroke-dasharray:40; stroke-dashoffset:40; animation:jag-ok-tick .38s var(--ease) .42s forwards;}
  .jag-ok-mark{animation:jag-ok-pop .5s var(--ease) both;}
}
@keyframes jag-ok-circle{to{stroke-dashoffset:0;}}
@keyframes jag-ok-tick{to{stroke-dashoffset:0;}}
@keyframes jag-ok-pop{from{opacity:0; transform:scale(.84);} to{opacity:1; transform:none;}}
@media (max-width:560px){
  .jag-ok-acts{flex-direction:column; align-items:stretch;}
  .jag-ok-acts .btn{width:100%;}
  .jag .jag-ok-tel{justify-content:center;}
}

/* ===== podstrony prawne =====
   Miara 72ch, szersza niz 64ch dla tekstu marketingowego, bo tu czyta sie
   punkt po punkcie, a nie ciagiem. Tabela ciasteczek ma trzy kolumny zamiast
   czterech: dostawca siedzi w naglowku sekcji, wiec na 375 px nie trzeba
   niczego zwezac ani przewijac w poprzek. */
.jag-legal{max-width:72ch;}
.jag-legal h2{font-size:clamp(1.3rem,2.1vw,1.65rem); font-weight:600; letter-spacing:-.02em; line-height:1.2; margin:clamp(30px,3.4vw,44px) 0 12px;}
.jag-legal h2:first-child{margin-top:0;}
.jag-legal p{color:var(--ink-soft); margin:0 0 1em;}
.jag-legal ul{list-style:none; display:grid; gap:9px; margin:0 0 1.2em; padding:0;}
.jag-legal li{display:flex; gap:12px; color:var(--ink-soft);}
.jag-legal li::before{content:"-"; flex:none; color:var(--brand-strong); font-weight:700;}
.jag-legal a{color:var(--brand-strong); font-weight:600; text-decoration:underline; text-underline-offset:2px;}
.jag-table{width:100%; border-collapse:collapse; margin:0 0 1.4em; font-size:.92rem;}
.jag-table th,.jag-table td{text-align:left; padding:11px 12px 11px 0; border-bottom:1px solid var(--hairline); vertical-align:top; color:var(--ink-soft);}
.jag-table th{font-size:.78rem; font-weight:600; color:var(--muted); border-bottom-color:var(--hairline-strong);}
.jag-table code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.9em; color:var(--ink); font-weight:600;}
@media (max-width:560px){
  .jag-table{font-size:.86rem;}
  .jag-table th,.jag-table td{padding:9px 8px 9px 0;}
}

/* ===== kreator kontaktu =====
   Telefon jest celem numer jeden, wiec na trzecim kroku polaczenie dostaje
   blok na pelna szerokosc w kolorze marki, a formularz schodzi do przycisku
   obrysowanego pod nim. Dwa pierwsze kroki to same dotkniecia, zero pisania,
   bo to one decyduja, czy ktos w ogole dojdzie do kontaktu. Bez JS wszystkie
   kroki sa widoczne naraz i calosc dziala jak jeden dluzszy formularz. */
/* Szerokosci wpisane jawnie, a nie zdane na rozciaganie przez rodzica.
   Kreator stoi teraz w dwoch roznych miejscach: w sekcji kontaktu i w pasmie
   koncowym, ktore jest kontenerem Elementora z --display:flex. W kontekscie
   flexowym dzieci moga byc zwezane do tresci zamiast rozciagane, a wtedy
   opcje schodza do dlugosci najdluzszej linii i pasek postepu z flex:1 bez
   wlasnej tresci kurczy sie do zera, czyli znika. Deklaracja width:100% jest
   nieszkodliwa tam, gdzie uklad i tak byl poprawny. */
.jag-form .jag-wiz-head,
.jag-form .jag-wiz-step,
.jag-form .jag-wiz-opts,
.jag-form .jag-wiz-opt,
.jag-form .jag-field,
.jag-form .jag-wiz-call,
.jag-form .jag-form-status{width:100%;}
.jag-form{align-self:stretch;}
.jag-wiz-head{display:flex; align-items:center; gap:16px; margin-bottom:20px;}
.jag-wiz-count{flex:none; font-size:.82rem; font-weight:600; color:var(--muted);}
/* min-width chroni pasek przed zapadnieciem sie do zera, gdyby rzad kiedykolwiek
   liczyl szerokosc z tresci: pasek nie ma zadnej wlasnej tresci. */
.jag-wiz-bar{flex:1 1 auto; min-width:80px; height:3px; background:var(--hairline); border-radius:100px; overflow:hidden;}
.jag-wiz-bar span{display:block; height:100%; width:33.3%; background:var(--brand-strong); transition:width .4s var(--ease);}
.jag-wiz-step{border:0; padding:0; margin:0; min-width:0;}
.jag-wiz-step[hidden]{display:none;}
/* display:flex z reguly wyzej bije domyslne [hidden]{display:none} przegladarki,
   wiec licznik trzeba schowac jawnie. */
.jag-wiz-head[hidden]{display:none;}
.jag-wiz-q{display:block; padding:0; margin:0 0 16px; font-size:1.25rem; font-weight:600; line-height:1.2; letter-spacing:-.015em; color:var(--ink);}
.jag-wiz-opts{display:grid; gap:10px;}
/* Pole radio lezy na calej karcie, wiec cel dotykowy to cala karta, a nie
   krazek 20 px. Minimalna wysokosc 60 px trzyma go nad progiem 44 px. */
.jag-wiz-opt{position:relative; display:block; cursor:pointer;}
.jag-wiz-opt input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer;}
.jag-wiz-opt>span{display:block; min-height:60px; padding:14px 16px; background:var(--surface); border:1px solid var(--hairline-strong); border-radius:var(--r); transition:border-color .2s, background .2s;}
.jag-wiz-opt b{display:block; font-size:1rem; font-weight:600; color:var(--ink);}
.jag-wiz-opt small{display:block; margin-top:3px; font-size:.86rem; color:var(--muted);}
.jag-wiz-opt input:hover+span,.jag-wiz-opt input:focus-visible+span{border-color:var(--ink);}
.jag-wiz-opt input:checked+span{border-color:var(--brand-strong); background:var(--brand-soft);}
/* Czwarta opcja to zbiorcza reszta oferty, wiec dostaje lekka przerwe nad
   soba. Odstep w siatce to 10 px, tu wychodzi 16 px i to wystarcza, zeby
   czytalo sie jako "albo cos innego", bez rysowania kreski. */
.jag-wiz-opt--other{margin-top:6px;}
/* Polaczenie: jedyny element w tym kroku w kolorze marki i najwieksza
   typografia w calym formularzu. */
.jag .jag-wiz-call{display:flex; align-items:center; gap:14px; padding:18px 20px; background:var(--brand-strong); color:#fff; border-radius:var(--r); box-shadow:0 1px 2px rgba(182,32,0,.18); transition:background .2s, transform .2s var(--ease);}
.jag .jag-wiz-call:hover{background:var(--brand-hover); color:#fff; transform:translateY(-1px);}
.jag-wiz-call .ic{flex:none; width:26px; height:26px;}
.jag-wiz-call .ic svg{width:100%; height:100%;}
.jag-wiz-call b{display:block; font-size:1.35rem; font-weight:700; line-height:1.1; letter-spacing:-.01em;}
.jag-wiz-call small{display:block; margin-top:4px; font-size:.86rem; color:rgba(255,255,255,.78);}
/* 0-3-0 bije neutralizator resetu motywu na koncu arkusza (0-2-1). */
.jag .jag-wiz-alt{display:block; width:100%; margin-top:12px; min-height:48px; padding:13px 18px; background:transparent; border:1px solid var(--hairline-strong); border-radius:var(--r); font-size:.98rem; font-weight:600; color:var(--ink); text-align:center; transition:background .2s, border-color .2s;}
.jag .jag-wiz-alt:hover{background:var(--surface); border-color:var(--ink); color:var(--ink);}
.jag .jag-wiz-back{align-self:flex-start; margin-top:16px; padding:11px 0; background:none; border:0; font-size:.9rem; font-weight:600; color:var(--muted); transition:color .2s;}
.jag .jag-wiz-back:hover{color:var(--brand-strong); background:transparent;}
.jag-wiz-back[hidden]{display:none;}
/* Numer w kolumnie obok formularza: cel numer jeden, wiec dostaje najwieksza
   liczbe na tej sekcji. */
.jag-k-line b.tel-xl{font-size:clamp(1.8rem,4.4vw,2.4rem); line-height:1.05; letter-spacing:-.02em;}
.jag-form-status{margin-top:16px; padding:14px 16px; border-radius:var(--r); font-size:.94rem; font-weight:500; display:none;}
.jag-form-status.ok{display:block; background:#e8f5ec; color:#1c6b3a; border:1px solid #bfe4cc;}
.jag-form-status.fail{display:block; background:#fcebe8; color:#a51f14; border:1px solid #f2c9c1;}
/* najwazniejsza zmiana stanu na calej witrynie: zapytanie poszlo.
   Do tej pory wskakiwala twardym display:block, bez zadnego przebiegu. */
.jag-form-status.ok,.jag-form-status.fail{animation:jag-status-in .44s var(--ease) both;}
@keyframes jag-status-in{from{opacity:0; transform:translateY(-8px);} to{opacity:1; transform:none;}}

/* stan wysylki: przycisk pokazuje, ze cos trwa, zamiast tylko zmieniac napis */
.jag .btn[aria-busy="true"]{pointer-events:none; position:relative; overflow:hidden;}
.jag .btn[aria-busy="true"]::after{content:""; position:absolute; inset:0; background:linear-gradient(90deg,transparent,rgba(255,255,255,.3),transparent); transform:translateX(-100%); animation:jag-sweep 1.1s linear infinite;}
@keyframes jag-sweep{to{transform:translateX(100%);}}

/* footer */
.jag-foot{padding-block:clamp(40px,6vw,64px); border-top:1px solid var(--hairline);}
.jag-foot-in{display:flex; flex-wrap:wrap; gap:28px 48px; justify-content:space-between; align-items:flex-start;}
.jag-foot .jag-logo img{height:clamp(20px,2.2vw,28px);}
.jag-foot-cols{display:flex; flex-wrap:wrap; gap:40px 64px;}
.jag-foot-col h2{font-size:.82rem; font-weight:600; color:var(--muted); margin-bottom:14px;}
.jag-foot-col p{display:block; font-size:.96rem; color:var(--ink-soft); margin-bottom:9px;}
/* stopka: ~26 px -> ~44 px. Padding zastepuje margines, wiec odstepy
   miedzy pozycjami zostaja takie same, rosnie tylko obszar dotyku. */
.jag-foot-col a{display:block; font-size:.96rem; color:var(--ink-soft); padding-block:9px; margin-bottom:0;}
.jag-foot-col a:hover{color:var(--brand-strong);}
.jag-foot-bottom{margin-top:36px; padding-top:22px; border-top:1px solid var(--hairline); display:flex; flex-wrap:wrap; gap:12px 24px; justify-content:space-between; font-size:.84rem; color:var(--muted);}
/* Podpis wykonawcy zostaje w tonie stopki: podkreslenie na --hairline-strong
   zaznacza, ze to odsylacz, ale nie podnosi go do rangi pozycji menu. */
.jag-foot-bottom a{color:var(--muted); text-decoration:underline; text-decoration-color:var(--hairline-strong); text-underline-offset:3px; padding-block:5px; margin-block:-5px;}
.jag-foot-bottom a:hover{color:var(--brand-strong); text-decoration-color:currentColor;}

/* ===== pasek szybkiego kontaktu (tylko mobile) =====
   Ponizej 860 px naglowek chowa telefon i przycisk CTA, zostawiajac logo
   i hamburger. Glowna akcja lezala wiec w gornej czesci ekranu i jeszcze
   za jednym dotknieciem. Pasek przenosi ja do dolnej jednej trzeciej,
   czyli w naturalny zasieg kciuka, i pokazuje sie dopiero po zjechaniu
   ponizej hero - zeby nie zaslanial pierwszego ekranu. */
.jag-callbar{display:none;}
@media (max-width:860px){
  .jag-callbar{position:fixed; left:0; right:0; bottom:0; z-index:var(--z-sticky);
    display:flex; gap:10px; align-items:stretch;
    padding:10px 14px; padding-bottom:calc(10px + env(safe-area-inset-bottom,0px));
    background:rgba(255,255,255,.95); backdrop-filter:saturate(1.4) blur(14px);
    border-top:1px solid var(--hairline); box-shadow:0 -2px 18px rgba(36,30,28,.07);
    transform:translateY(105%); visibility:hidden;
    transition:transform .32s var(--ease), visibility 0s .32s;}
  .jag-callbar.up{transform:none; visibility:visible; transition:transform .32s var(--ease), visibility 0s;}
  .jag-callbar>*{flex:1 1 0; min-height:52px; font-size:1rem;}
  .jag-callbar .jag-callbar-tel{display:inline-flex; align-items:center; justify-content:center; gap:9px;
    font-weight:700; color:var(--ink); background:var(--bg);
    border:1px solid var(--hairline-strong); border-radius:var(--r);}
  .jag-callbar .jag-callbar-tel svg{width:19px; height:19px; color:var(--brand-strong);}
  /* stopka oddaje miejsce paskowi, zeby nie przykrywal ostatnich linkow */
  .jag-foot{padding-bottom:calc(clamp(40px,6vw,64px) + 74px);}
}

/* ===== pasek realizacji komercyjnych =====
   Nazwy marek jako typografia, nie jako logotypy. Trzy powody:
   1. Logotypy Volvo i Kia to znaki towarowe - ich uzycie sugeruje relacje
      z producentem, a pracownia robila prace w salonach, czyli najpewniej
      dla dealera. Nazwa opisana slowem jest prawdziwa przy kazdej wersji.
   2. Dwa obce logotypy obok siebie to dwa obce jezyki wizualne w srodku
      systemu, ktory ma jeden krój i jedna palete.
   3. Nie mam plikow logo, a sciaganie ich z sieci to zla droga.
   Struktura skaluje sie na kolejne pozycje bez zmiany CSS. */
.jag-clients-band{border-block:1px solid var(--hairline); background:var(--surface); padding-block:clamp(20px,2.6vw,30px);}
.jag-clients{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:14px clamp(20px,3vw,40px);}
/* 0,82rem to bylo 13,1 px - za malo na etykiete, ktora ma nazwac caly pasek.
   1,05rem = 16,8 px, czyli +28%, i nadal ponizej stopnia tekstu podstawowego. */
.jag-clients-label{font-size:1.05rem; font-weight:600; color:var(--muted); flex:none;}
/* Logotypy.
   Oba pliki sa jednobarwne (#000, jedna sciezka), wiec grayscale bylby
   pusta operacja - zamiast tego wyciszamy je sama nieprzezroczystoscia.
   Czern na 62% wobec --surface czyta sie jak spokojna szarosc i nie wpuszcza
   do systemu obcej palety.

   Wysokosc ustawiona per marka, bo pliki maja rozne wypelnienie ramki:
   Volvo zajmuje ~94% wysokosci swojego viewBox, Kia ~63% (reszta to pusty
   margines w pliku). Przy jednakowej wysokosci CSS Kia bylaby o polowe
   mniejsza optycznie. Stosunek 1,45 wyrownuje wysokosc SAMEGO znaku.
   To sa dwie liczby do ewentualnego dostrojenia okiem. */
.jag-logos{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:clamp(20px,3vw,44px); list-style:none; margin:0; padding:0; flex:1 1 auto;}
.jag-logos li{display:flex; align-items:center;}
/* Jedna wysokosc dla obu znakow - i tym razem naprawde rowna.

   Zrodlo problemu bylo w plikach, nie w CSS. Oba SVG mialy ogromny pusty
   margines w viewBox: znak Volvo zajmowal 13,2% wysokosci pliku, Kia 23,5%.
   Przy jednakowej wysokosci CSS glif Kii wychodzil 1,79x wyzszy od Volvo
   i zadna korekta wspolczynnikiem tego nie naprawiala - przesuwala tylko
   blad. Oba viewBox sa teraz przyciete do rzeczywistego obrysu sciezki
   (policzonego biblioteka, nie na oko), wiec wypelniaja 100% wysokosci
   i rowna wysokosc CSS znaczy rowna wysokosc znaku.

   Wartosc spadla z 92 na 34 px, bo teraz opisuje sam znak, a nie ramke
   pliku, w ktorej znak siedzial. Volvo uroslo w praktyce blisko trzykrotnie. */
/* Nieprzezroczystosc 0,55: czern na tle --surface daje #706e6e, a systemowy
   --muted to #6e6765. Roznica jest niewidoczna, wiec logotypy trafiaja
   dokladnie w ton, ktorym ta strona mowi „drugorzedne” - zamiast w wartosc
   dobrana na oko. Wysokosc ścieta o 20% wzgledem 22/34 px. */
.jag-logos img{display:block; width:auto; max-width:none; opacity:.62; filter:grayscale(1); transition:opacity .25s var(--ease), filter .25s var(--ease); height:clamp(18px,2.1vw,27px);}
.jag-logos li:hover img{opacity:.9; filter:grayscale(0);}
/* Wysokosci dobrane per logotyp - te znaki maja rozne proporcje (Volvo 12,9:1,
   Teatr Wielki 2,6:1), wiec jedna wysokosc CSS dawalaby wstege, w ktorej
   Volvo jest trzy razy szersze od reszty. Wyrownujemy mase optyczna, nie liczbe. */
.jag-logos .l-volvo{gap:clamp(9px,1vw,13px);}
.jag-logos .l-volvo img{height:clamp(10px,1.05vw,13px);}
.jag-logos .l-volvo .l-name{padding-left:clamp(9px,1vw,13px); border-left:1px solid currentColor; font-size:clamp(12px,1.25vw,16px); font-weight:500; letter-spacing:.1em; line-height:1.35; color:var(--ink); opacity:.62;}
.jag-logos li:hover .l-name{opacity:.9;}
.jag-logos .l-kia img{height:clamp(13px,1.4vw,18px);}
.jag-logos .l-promet img{height:clamp(19px,2.05vw,26px);}
.jag-logos .l-klimeko img{height:clamp(14px,1.5vw,19px);}
.jag-logos .l-opera img{height:clamp(26px,2.85vw,36px);}

/* ===== opinie =====
   Trzy rowne karty. Poprzedni uklad rozdzielal glosy na wiodacy i chor:
   cytat wiodacy dostawal miare 26ch w wierszu na pelna szerokosc, wiec prawa
   polowa sekcji stala pusta, a podpisy dwoch pozostalych kart siadaly na
   roznych wysokosciach, bo kazda konczyla sie tam, gdzie konczyl sie jej
   tekst. Rowny rzad zdejmuje oba te problemy naraz.

   Karta to obiekt, ktory ten system juz ma w .jag-offer i .jag-wood: 1 px
   --hairline i promien --r-lg, zero nowych prymitywow. Wypelnienie idzie na
   --surface, bo sekcja stoi teraz na bialym tle i biala karta na bialym nie
   czytalaby sie jako karta. Bez unoszenia na hover - te karty nigdzie nie
   prowadza, wiec nie moga udawac klikalnych. */
.jag-reviews{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(14px,1.5vw,22px); align-items:stretch;}
.jag-review{display:flex; flex-direction:column; margin:0; background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-lg); padding:clamp(22px,2.1vw,30px);}
.jag-review blockquote{margin:15px 0 0; font-size:1.02rem; line-height:1.55; color:var(--ink-soft);}
/* margin-top:auto sciaga podpisy wszystkich kart do wspolnej linii przy dole,
   niezaleznie od tego, ile wierszy ma cytat. Kreska nad podpisem biegnie
   wtedy przez trzy karty na tej samej wysokosci.

   Kolumna, nie wiersz: przy nazwisku i zrodle w jednej linii "Tomasz
   Karczewski" lamal sie na dwa wiersze przy okolo 1000 px, przez co jego
   kreska szla 18 px wyzej niz w dwoch pozostalych kartach. Staly uklad
   dwuwierszowy trzyma je na jednej wysokosci na kazdej szerokosci. */
.jag-review figcaption{margin-top:auto; padding-top:20px; border-top:1px solid var(--hairline-strong); display:flex; flex-direction:column; align-items:flex-start; gap:3px;}
.jag-review figcaption b{font-size:1rem; font-weight:600; color:var(--ink);}
.jag-review figcaption span{font-size:.86rem; color:var(--muted);}
.jag-stars{display:inline-flex; gap:3px; color:var(--brand-strong);}
.jag-stars svg{width:16px; height:16px; fill:currentColor;}
.jag-reviews + .body{margin-top:clamp(26px,3vw,40px);}

@media (max-width:900px){
  .jag-reviews{grid-template-columns:1fr; gap:14px;}
}
/* Telefon: space-between rozklada logotypy po dwa na wiersz z dziura posrodku,
   a ostatni wiersz rozjezdza sie na cala szerokosc. Na waskim ekranie pasek
   ma byc zwykla, rowno odstepowana lista - stad flex-start i etykieta nad nia. */
@media (max-width:760px){
  .jag .jag-clients-band .wrap{max-width:none; padding-inline:12px;}
  .jag-clients{flex-direction:column; align-items:center; justify-content:flex-start; gap:16px;}
  .jag-clients-label{text-align:center;}
  .jag-logos{justify-content:space-evenly; gap:18px; flex:0 1 auto; width:100%;}
  .jag-logos .l-volvo img{height:10px;}
  .jag-logos .l-volvo .l-name{font-size:12px; padding-left:10px;}
  .jag-logos .l-kia img{height:14px;}
  .jag-logos .l-promet img{height:19px;}
  .jag-logos .l-klimeko img{height:14px;}
  .jag-logos .l-opera img{height:24px;}
}
/* Ponizej 560 px caly komplet nie miesci sie w jednym wierszu, a zawijanie
   flexem dawalo raz 3+2, raz 2+3 - uklad zmienial sie co kilkanascie pikseli
   szerokosci. Siatka szesciu kolumn ustawia podzial na sztywno: Volvo i Kia
   w pierwszym wierszu, pozostale trzy w drugim. Pozycje sa wpisane recznie,
   wiec nowy logotyp wymaga dopisania mu kolumn. */
@media (max-width:560px){
  .jag-logos{display:grid; grid-template-columns:repeat(6,1fr); gap:18px 8px; width:100%;}
  .jag-logos li{justify-self:center;}
  .jag-logos .l-volvo{grid-column:1/5;}
  .jag-logos .l-kia{grid-column:5/7;}
  .jag-logos .l-promet{grid-column:1/3;}
  .jag-logos .l-klimeko{grid-column:3/5;}
  .jag-logos .l-opera{grid-column:5/7;}
}

/* ===== pasek faktow przy punktach konwersji =====
   Wylacznie fakty juz zatwierdzone przez klienta i obecne na witrynie.
   To redukcja ryzyka i wiarygodnosc, a NIE dowod spoleczny - opinii,
   nazwisk ani zdjec klientow tu nie ma i nie da sie ich wymyslic. */
.jag-proof{display:flex; flex-wrap:wrap; gap:10px 26px; margin-top:22px;}
.jag-proof span{display:inline-flex; align-items:center; gap:9px; font-size:.9rem; font-weight:500; color:var(--ink-soft);}
.jag-proof span::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--brand-strong); flex:none;}
.jag-cta-band .jag-proof span{color:rgba(255,255,255,.78);}
.jag-cta-band .jag-proof span::before{background:#ff7a4d;}
.jag-kontakt .jag-proof span{color:rgba(255,255,255,.78);}
.jag-kontakt .jag-proof span::before{background:#ff7a4d;}

/* ===== ruch =====
   Jeden moment autorski: rysunek techniczny w hero kresli sie sam.
   Wszystko inne trwa krocej niz pol sekundy i istnieje wylacznie po to,
   zeby tlumaczyc stan albo potwierdzac akcje. Zadna sekcja nie dostaje
   wejscia tylko dlatego, ze jest sekcja. */

/* wejscie tresci: krotko i blisko, bez ceremonii */
.jag .reveal{opacity:1; transform:none;}
.jag.js .reveal{opacity:0; transform:translateY(26px); transition:opacity .58s var(--ease), transform .58s var(--ease);}
.jag.js .reveal.in{opacity:1; transform:none;}

/* lista wchodzi jako jedna lista, nie jako szesc niezaleznych zdarzen */
.jag.js .stagger>*{opacity:0; transform:translateY(30px); transition:opacity .62s var(--ease), transform .62s var(--ease);}
.jag.js .stagger.in>*{opacity:1; transform:none;}
.jag.js .stagger.in>*:nth-child(2){transition-delay:.08s;}
.jag.js .stagger.in>*:nth-child(3){transition-delay:.16s;}
.jag.js .stagger.in>*:nth-child(4){transition-delay:.24s;}
.jag.js .stagger.in>*:nth-child(5){transition-delay:.32s;}
.jag.js .stagger.in>*:nth-child(6){transition-delay:.4s;}
.jag.js .stagger.in>*:nth-child(7){transition-delay:.46s;}
.jag.js .stagger.in>*:nth-child(n+8){transition-delay:.5s;}

/* material zdjeciowy odslania sie od dolu do gory, jak budowany bieg.
   Inny material niz tekst, wiec czyta sie jako inna warstwa hierarchii,
   a nie jako ten sam efekt powtorzony po raz dwudziesty. */
.jag.js .reveal-media .row-media,
.jag.js .reveal-media>.media{clip-path:inset(0 0 100% 0 round var(--r-lg)); transition:clip-path .82s var(--ease);}
.jag.js .reveal-media.in .row-media,
.jag.js .reveal-media.in>.media{clip-path:inset(0 0 0 0 round var(--r-lg));}
/* drugi wymiar: kadr osiada w trakcie odslaniania. Sama maska przy duzym
   zdjeciu czyta sie slabo, bo krawedz jedzie szybko i nie ma czego sledzic. */
.jag.js .reveal-media .row-media img,
.jag.js .reveal-media>.media img,
.jag.js .wipe img{transform:scale(1.07); transition:transform 1.1s var(--ease);}
.jag.js .reveal-media.in .row-media img,
.jag.js .reveal-media.in>.media img,
.jag.js .wipe.in img{transform:none;}
/* Powiekszenie przy najechaniu siedzi na tym samym img co skala odslaniania,
   a regula odslaniania ma wyzsza specyficznosc - bez tego hover w wierszach
   umarlby na stale po pierwszym przewinieciu. 0-6-1 bije 0-5-1. */
.jag.js .jag-row.reveal-media.in:hover .row-media img{transform:scale(1.03);}
.jag.js .reveal-media>:not(.row-media):not(.media){opacity:0; transform:translateY(22px); transition:opacity .56s var(--ease) .14s, transform .56s var(--ease) .14s;}
.jag.js .reveal-media.in>:not(.row-media):not(.media){opacity:1; transform:none;}
/* ten sam gest na samym elemencie, nie na jego rodzicu - dla hero podstron */
.jag.js .wipe{clip-path:inset(0 0 100% 0 round var(--r-lg)); transition:clip-path .82s var(--ease);}
.jag.js .wipe.in{clip-path:inset(0 0 0 0 round var(--r-lg));}

/* hero: kolumna tekstu ustawia sie szybko i schodzi z drogi, zeby
   rysunek mial scene dla siebie. Arkusz nie ma zadnego wejscia -
   jego wejsciem jest to, ze sie kresli. */
.jag.js .jag-hero-grid>div>.reveal{transition-duration:.66s;}
.jag.js .jag-hero-grid>div>.reveal.in:nth-child(2){transition-delay:.09s;}
.jag.js .jag-hero-grid>div>.reveal.in:nth-child(3){transition-delay:.18s;}
.jag.js .jag-hero-grid>div>.reveal.in:nth-child(4){transition-delay:.27s;}
.jag.js .jag-hero-facts.stagger.in>*{transition-delay:.36s;}
.jag.js .jag-hero-facts.stagger.in>*:nth-child(2){transition-delay:.44s;}
.jag.js .jag-hero-facts.stagger.in>*:nth-child(3){transition-delay:.52s;}

/* paski gatunkow: wartosc rysuje sie od zera, wiec liczba znaczy cos,
   czego statyczny pasek nie przekazuje */
.jag.js .jag-woods .fill{transform:scaleX(0); transform-origin:left center; transition:transform .9s var(--ease);}
.jag.js .jag-woods.in .fill{transform:none;}
.jag.js .jag-woods.in .jag-wood:nth-child(2) .fill{transition-delay:.08s;}
.jag.js .jag-woods.in .jag-wood:nth-child(3) .fill{transition-delay:.16s;}
.jag.js .jag-woods.in .jag-wood:nth-child(4) .fill{transition-delay:.24s;}

@media (prefers-reduced-motion:reduce){
  .jag.js .reveal,.jag.js .stagger>*,.jag.js .reveal-media>*,.jag.js .jag-mobile nav a{opacity:1!important; transform:none!important; transition:none!important;}
  .jag.js .reveal-media .row-media,.jag.js .reveal-media>.media,.jag.js .wipe{clip-path:none!important;}
  /* skala kadru siedzi na wnuku, wiec regula na dzieciach jej nie lapie */
  .jag.js .reveal-media img,.jag.js .wipe img{transform:none!important; transition:none!important;}
  .jag.js .jag-woods .fill{transform:none!important;}
  .jag .btn[aria-busy="true"]::after{animation:none!important; display:none!important;}
  .jag *{transition-duration:.01ms!important; animation-duration:.01ms!important;}
}

/* responsive */
@media (max-width:1024px){.jag-woods{grid-template-columns:repeat(2,1fr);} .jag-steps{grid-template-columns:repeat(2,1fr); gap:36px 28px;} .jag-gallery{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (max-width:860px){
  .jag-hero-grid,.jag-phero .phero-grid{grid-template-columns:1fr; gap:36px;}
  .jag-hero-media{max-width:600px;}
  .jag-row{grid-template-columns:1fr; gap:22px;} .jag-row:nth-child(even) .row-media{order:0;} .jag-row .row-media{aspect-ratio:16/10;}
  .jag-k-grid{grid-template-columns:1fr; gap:36px;} .jag-trust{grid-template-columns:1fr; gap:30px;}
  .jag-cta-band .in{flex-direction:column; align-items:flex-start;}
}
@media (max-width:560px){.jag{font-size:16px;} .jag-woods{grid-template-columns:1fr 1fr; gap:12px;} .jag-steps{grid-template-columns:1fr;} .jag-gallery{grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px;} .jag-hero-facts{gap:20px 28px;} .jag-foot-in{flex-direction:column;}}


/* ===== Hero: rysunek techniczny zamiast zdjecia ===== */
/* Arkusz hu\u015bta si\u0119 na w\u0142asnej wysoko\u015bci, a siatka hero (align-items:center)
   ustawia go w pionie na r\u00f3wni z kolumn\u0105 tekstu. \u017badnych wysoko\u015bci procentowych
   ani flexa wok\u00f3\u0142 SVG \u2014 svg ma width:100% liczone wzgl\u0119dem .hero-sheet, wi\u0119c ten
   div musi mie\u0107 jawn\u0105 szeroko\u015b\u0107 blokow\u0105, inaczej sizing robi si\u0119 cykliczny. */
.jag .jag-hero-media{align-self:center; display:block;}
/* Optyczny \u015brodek le\u017cy ni\u017cej ni\u017c geometryczny: kolumna tekstu ma ci\u0119\u017car u do\u0142u
   (liczby, przyciski), wi\u0119c czysto matematyczne wy\u015brodkowanie czyta si\u0119 jako
   'za wysoko'. UWAGA: przy align-self:center siatka centruje margin box, wi\u0119c
   margin-top przesuwa arkusz o PO\u0141OW\u0118 swojej warto\u015bci. 52px = ~26px w d\u00f3\u0142. */
@media (min-width:861px){
  .jag .jag-hero-media{margin-top:0;}
}
/* Bez ramki i bez paddingu: arkusz kreslarski nie potrzebuje pudelka,
   zeby czytac sie jako rysunek. Zdjecie obwodki oddaje te 20-32 px
   samemu rysunkowi, wiec robi sie wiekszy bez ruszania siatki. */
.jag .jag-dwg{position:relative; display:block; height:auto; border:0; background:none; padding:0;}
.jag .jag-dwg .hero-sheet{position:static; inset:auto; display:block; width:100%;}
/* position:static bylo kiedys obrona przed regula .hero-sheet svg{position:absolute}
   z arkusza motywu potomnego. Arkusz zszedl z frontu 27.07.2026, wiec kolizji
   juz nie ma - zostawiamy jawna deklaracje jako asekuracje, gdyby ktos kiedys
   przywrocil tamten plik. aspect-ratio domyka wyliczanie wysokosci. */
.jag .jag-dwg .drawing{position:static; inset:auto; display:block; width:100%; height:auto; aspect-ratio:720/660;}
.jag .jag-dwg .ink{stroke:var(--ink); stroke-width:1.6; fill:none; stroke-linejoin:miter;}
.jag .jag-dwg .hair{stroke:var(--hairline-strong); stroke-width:1; fill:none;}
.jag .jag-dwg .dim{stroke:var(--brand-strong); stroke-width:1; fill:none;}
.jag .jag-dwg .dimtext{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; fill:var(--brand-strong); letter-spacing:.04em;}
.jag .jag-dwg .lbl{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; fill:var(--muted); letter-spacing:.04em;}
.jag .jag-dwg .tlab{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:9px; fill:var(--muted); letter-spacing:.09em;}
.jag .jag-dwg .tval{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; fill:var(--ink); letter-spacing:.01em;}
.jag .jag-dwg .grid-bg{stroke:var(--hairline); stroke-width:.5;}


/* ===== neutralizacja resetu motywu nadrzednego =====
   hello-elementor/assets/css/reset.css (laduje sie jako pierwszy arkusz na
   stronie) zawiera:
     button:focus, button:hover { background-color:#c36; color:#fff }
   Specyficznosc 0-1-1, wiec bije kazda regule klasowa tego systemu. Skutek:
   KAZDY goly przycisk swiecil magenta przy najechaniu i przy fokusie z
   klawiatury - kafle probek, miniatury galerii, naglowki FAQ, hamburger,
   krzyzyk menu i strzalki lightboxa. Na /realizacje/ to 32 elementy.
   Rownowazymy to na 0-1-1; jag.css laduje sie pozniej, wiec wygrywa
   kolejnoscia. Nizej odzyskuja swoje tlo te przyciski, ktore je maja miec. */
.jag button:hover, .jag button:focus,
.jag [type="button"]:hover, .jag [type="button"]:focus,
.jag [type="submit"]:hover, .jag [type="submit"]:focus{background-color:transparent; color:inherit;}

/* 0-2-1, wiec bije regule powyzej. Bez tego strzalki lightboxa dziedziczylyby
   ciemny --ink na ciemnym tle i znikaly przy najechaniu. */
.jag .jag-lb-btn:hover, .jag .jag-lb-btn:focus{background:rgba(255,255,255,.22); color:#fff;}
.jag .btn:hover{background:var(--brand-hover); color:#fff;}
.jag .btn--ghost:hover{background:var(--surface); color:var(--ink);}
.jag .btn--light:hover{background:#fff; color:var(--brand-hover);}


/* --- 3. POPUP "Zamow pomiar" --------------------------------
   Szablon Elementora ID 19, wstrzykiwany na cala witryne. Nie siedzi
   wewnatrz .jag, wiec korzysta z tokenow z :root. Wczesniej wisial na
   --pencil, --line-2 i --sans z arkusza motywu potomnego, czyli na innej
   palecie i innym kroju niz reszta strony. Teraz to ten sam system. */
.maj-popup{color:var(--ink); font-family:"Schibsted Grotesk", system-ui, sans-serif;}
.maj-popup .titleblock{display:flex; align-items:baseline; gap:20px; margin-bottom:20px;}
.maj-popup .titleblock h2{font-size:1.6rem; font-weight:600; letter-spacing:-.025em; line-height:1.1;}
.maj-popup .titleblock .rule{flex:1; height:1px; background:var(--hairline-strong); align-self:center;}
.maj-popup .lede{color:var(--ink-soft); line-height:1.5;}

.maj-form .elementor-field-group{margin-bottom:18px;}
.maj-form .elementor-field-label{display:block; font-size:.9rem; font-weight:600; color:var(--ink); margin-bottom:8px;}
.maj-form input[type="text"],.maj-form input[type="tel"],.maj-form input[type="email"],.maj-form textarea{
  width:100%; font:inherit; font-size:1rem; color:var(--ink); background:var(--surface);
  border:1px solid var(--hairline-strong); border-radius:var(--r); padding:13px 15px;
  transition:border-color .2s, box-shadow .2s;}
.maj-form input:focus,.maj-form textarea:focus{outline:0; border-color:var(--brand-strong); box-shadow:0 0 0 3px var(--brand-soft);}
.maj-form textarea{resize:vertical; min-height:104px;}
.maj-form ::placeholder{color:#9a938f; opacity:1;}
.maj-form button[type="submit"],.maj-form .elementor-button,
.maj-btn .elementor-button{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  background:var(--brand-strong); color:#fff; font-weight:600; font-size:.98rem;
  padding:13px 22px; border:0; border-radius:var(--r); cursor:pointer; white-space:nowrap;
  box-shadow:0 1px 2px rgba(182,32,0,.18);
  transition:background .2s, transform .2s var(--ease), box-shadow .25s;}
.maj-form button[type="submit"]:hover,.maj-form .elementor-button:hover,
.maj-btn .elementor-button:hover{background:var(--brand-hover); color:#fff; transform:translateY(-1px); box-shadow:0 6px 18px rgba(182,32,0,.22);}
.maj-btn-ghost .elementor-button{background:transparent; color:var(--ink); border:1px solid var(--hairline-strong); box-shadow:none; border-radius:var(--r); padding:13px 22px; font-weight:600;}
.maj-btn-ghost .elementor-button:hover{background:var(--surface); border-color:var(--ink); color:var(--ink);}
.maj-btn .elementor-button-content-wrapper,.maj-btn-ghost .elementor-button-content-wrapper{display:contents;}
@media (prefers-reduced-motion:reduce){
  .maj-form button[type="submit"],.maj-form .elementor-button,.maj-btn .elementor-button{transition:none;}
}