/* ============================================================
   RADICALFANS · Editorial Paper — system wspólny
   Wszystko, co powtarza się na każdej stronie: zmienne, nagłówek,
   przyciski, nagłówek podstrony, ciemna „tylna okładka" (brief +
   stopka). Rzeczy występujące raz (hero, karuzela logotypów, siatka
   realizacji, lista asortymentu) zostają w <style> swojej strony.

   Zasada kompozycji: kremowa „kartka" + ciemne bloki jako świadomy
   rytm, nie przypadek. Czerwień = jedyny akcent.
   ============================================================ */
:root{
  --bg:#F1EDE5;        /* kremowe tło — „papier" */
  --bg-2:#E7E2D8;      /* sekcje wyróżnione */
  --ink:#15130F;       /* czerń druku — tekst i ciemne bloki */
  --ink-2:#221F19;     /* hover / pola formularza na ciemnym */
  --line:#D6CFC1;      /* hairline na papierze */
  --line-2:#B7AE9C;    /* mocniejsza linia */
  --muted:#5E5850;     /* tekst drugorzędny (kontrast 5.2:1) */
  --onink:#F1EDE5;     /* tekst na ciemnym */
  --onink-mut:#A39C90; /* drugorzędny na ciemnym */
  --red:#C4141B;
  --red-deep:#9C0F14;

  --cut:polygon(9px 0,100% 0,100% calc(100% - 9px),calc(100% - 9px) 100%,0 100%,0 9px);
  --btn-fill:var(--bg);   /* tlo pod przyciskami ramkowymi */

  /* Anton wystepuje tylko w wadze 400 — trzymamy naturalna wage kroju,
     bez syntetycznego pogrubienia (zlewalo wiersze przy duzym stopniu). */
  --display:'Anton',sans-serif;
  --ui:'Oswald',sans-serif;
  --body:'Archivo',sans-serif;
  /* Warstwa mikrotypografii: etykiety, okruszki, liczniki, podpisy. Do 15.09
     stal tu Space Mono pod nazwa --mono. Rozstrzygnal precedens z arkuszy
     rozmiarowek: w zadnym <svg> nie ma monospace'u ani razu — nadtytul
     (.t-kick) i KOLUMNY LICZB (.num) stoja na Archivo 600, choc to jedyne
     miejsce w projekcie, gdzie rowna szerokosc cyfry ma funkcje. Nazwa
     --meta zamiast --mono, zeby zmienna nie klamala o kroju.
     To ta sama rodzina co --body; osobna zmienna zostaje, bo role sa rozne
     i rozjazd (inny krój dla etykiet) ma byc mozliwy jedna linia. */
  --meta:'Archivo',sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--ink);font-family:var(--body);line-height:1.55;-webkit-font-smoothing:antialiased}

/* faktura papieru — na jasnym multiply, nie overlay */
body:before{content:"";position:fixed;inset:0;pointer-events:none;z-index:60;opacity:.04;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

.wrap{max-width:1240px;margin:0 auto;padding:0 32px}
.label{font-family:var(--meta);font-weight:600;text-transform:uppercase;letter-spacing:.18em;font-size:12px;color:var(--muted)}
.accent{color:var(--red)}
a{color:inherit}
img{display:block;max-width:100%}

/* ---------- header — przezroczysty nad hero, kremowy po scrollu ---------- */
header{position:fixed;top:0;left:0;right:0;background:transparent;border-bottom:1px solid transparent;z-index:40;
  transition:background .25s,border-color .25s,backdrop-filter .25s}
header.stuck{background:rgba(241,237,229,.92);backdrop-filter:blur(10px);border-bottom-color:var(--line)}
/* Podstrony nie maja hero ze zdjeciem, wiec nagłówek nie ma nad czym byc
   przezroczysty — stoi kremowy od pierwszej klatki, bez czekania na scroll. */
body.sub header{background:rgba(241,237,229,.92);backdrop-filter:blur(10px);border-bottom-color:var(--line)}
.hd{display:flex;align-items:center;justify-content:space-between;height:76px}
/* Logo jest linkiem na strone glowna na kazdej podstronie, ale nie dawalo
   na to zadnego znaku: 35x44 px monogramu bez stanu :hover. Stad wrazenie,
   ze powrotu na glowna nie ma. Przygaszenie zamiast czerwieni — logo jest
   znakiem firmowym, nie pozycja menu, wiec nie powinno sie przebarwiac. */
.logo-link{display:inline-flex;align-items:center;transition:opacity .15s}
.logo-link:hover,.logo-link:focus-visible{opacity:.55}
.logo-img{height:44px;width:auto;filter:brightness(0)}
nav.main{display:flex;gap:30px;align-items:center}
nav.main a{font-family:var(--ui);font-weight:600;font-size:14px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink);text-decoration:none;transition:.15s;position:relative}
nav.main a:not(.btn):after{content:"";position:absolute;left:0;right:100%;bottom:-6px;height:2px;background:var(--red);transition:right .2s}
nav.main a:not(.btn):hover:after{right:0}
nav.main a.btn-primary,nav.main a.btn-primary:hover{color:#fff}
/* „Strona glowna" istnieje w znacznikach zawsze, ale na desktopie stoi
   schowana. Powod jest zmierzony: szosta pozycja kosztuje 136,4 px, a przy
   901 px — najciasniejszym desktopie, bo burger wchodzi od 900 — zbija
   przeswit miedzy logo a menu ze 116,7 px do ZERA i sciska menu z 757,8
   do 738,9. Na desktopie droga na glowna jest w logo i w okruchach.
   Pod trzema kreskami menu jest kolumna, wiec pozycja nic nie kosztuje —
   a okruchy sa tam najdrobniejsze. Zapalenie w @media(max-width:900px). */
nav.main a.home{display:none}
/* strona, na ktorej wlasnie jestesmy — kreska zapalona na stale.
   Dwie wartosci, bo dwie sytuacje: `page` tam, gdzie pozycja menu prowadzi
   dokladnie do biezacej strony (hub, zdobienia), `true` tam, gdzie oznacza
   sekcje, a nie strone — na podstronie kategorii „Produkty” prowadzi do huba,
   wiec `page` byloby nieprawda dla czytnika ekranu. */
nav.main a[aria-current]:not(.btn):after{right:0}

/* Przyciski: dwie warstwy zamiast border+clip-path.
   Tlo elementu = kolor obrysu, pseudo-element (inset 1px) = wypelnienie.
   Dzieki temu linia biegnie takze po sciecu i rog jest domkniety. */
.btn{position:relative;isolation:isolate;display:inline-flex;align-items:center;gap:9px;
  font-family:var(--ui);font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:14px;
  padding:13px 25px;text-decoration:none;border:0;cursor:pointer;transition:color .15s,background .15s;
  clip-path:var(--cut);background:var(--btn-line)}
.btn:before{content:"";position:absolute;inset:1px;z-index:-1;clip-path:var(--cut);background:var(--btn-face);transition:background .15s}
.btn-primary{--btn-line:var(--red);--btn-face:var(--red);color:#fff}
.btn-primary:hover{--btn-line:var(--red-deep);--btn-face:var(--red-deep)}
.btn-ghost{--btn-line:var(--line-2);--btn-face:var(--btn-fill);color:var(--ink)}
.btn-ghost:hover{--btn-line:var(--ink);--btn-face:var(--ink);color:var(--bg)}
.btn-onink{--btn-line:rgba(241,237,229,.45);--btn-face:var(--ink);color:var(--onink)}
.btn-onink:hover{--btn-line:var(--onink);--btn-face:var(--onink);color:var(--ink)}
/* wypelnienie przyciskow ramkowych dopasowane do tla, na ktorym leza */
.dark{--btn-fill:var(--ink)}
.dark .btn-ghost{--btn-line:rgba(241,237,229,.45);color:var(--onink)}
.dark .btn-ghost:hover{--btn-line:var(--onink);--btn-face:var(--onink);color:var(--ink)}

/* ---------- burger + mobilne CTA ---------- */
.burger{display:none;flex-direction:column;justify-content:center;gap:6px;width:44px;height:44px;
  background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
.burger span{display:block;width:26px;height:2px;background:var(--ink);margin:0 auto;
  transition:transform .28s,opacity .2s}
.burger.on span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.burger.on span:nth-child(2){opacity:0}
.burger.on span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}

/* pasek CTA przyklejony do dolnej krawedzi — dwa pelne przyciski, zawsze jedna linia.
   z-index 35 = PONIZEJ naglowka (40), zeby rozwiniete menu mobilne bylo nad paskiem. */
.mcta{display:none;position:fixed;left:0;right:0;bottom:0;z-index:35;
  box-shadow:0 -8px 26px rgba(21,19,15,.16);padding-bottom:env(safe-area-inset-bottom);
  transition:transform .35s ease-out}
/* Progressive enhancement: bez JS pasek jest widoczny od razu.
   Stan ukryty istnieje WYLACZNIE pod html.js — nigdy odwrotnie. */
html.js .mcta[data-reveal]{transform:translateY(100%);visibility:hidden}
html.js .mcta[data-reveal].is-shown{transform:none;visibility:visible}
@media(prefers-reduced-motion:reduce){.mcta{transition:none}}
.mcta a{flex:1 1 50%;min-width:0;display:flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--ui);font-weight:700;text-transform:uppercase;letter-spacing:.05em;font-size:13px;
  line-height:1;padding:18px 8px;text-decoration:none;white-space:nowrap}
.mcta .a1{background:var(--red);color:#fff}
.mcta .a2{background:var(--ink);color:var(--onink)}
@media(max-width:360px){.mcta a{font-size:12px;letter-spacing:.03em;padding:17px 6px}}

/* ---------- sekcje ---------- */
section{padding:clamp(60px,9vw,112px) 0;border-bottom:1px solid var(--line);position:relative;scroll-margin-top:78px}
.sh{margin-bottom:16px}
.sh .num{display:block;font-family:var(--meta);font-weight:600;color:var(--red);font-size:13px;letter-spacing:.1em;margin-bottom:10px}
.sh h2{font-family:var(--display);font-weight:400;text-transform:uppercase;font-size:clamp(34px,5.8vw,76px);line-height:.88}
.ssub{color:var(--muted);max-width:640px;margin-bottom:50px;font-size:16px}
.more{margin-top:34px;display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.more .hint{font-family:var(--meta);font-size:13px;color:var(--muted)}

/* ---------- nagłówek podstrony ----------
   Bez zdjecia na cala wysokosc — hero z fotografia zostaje wyroznikiem
   strony glownej. Tu kremowy blok domkniety hairlinem. Gorny padding
   musi przepuscic nagłówek (fixed, 76px). */
.phead{padding:calc(76px + clamp(46px,7vw,86px)) 0 clamp(46px,7vw,86px);border-bottom:1px solid var(--line);background:var(--bg-2)}
.crumbs{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:26px}
.crumbs a{text-decoration:none;transition:color .15s}
.crumbs a:hover{color:var(--red)}
.crumbs .sep{margin:0 8px;color:var(--line-2)}
/* Kreska zamiast nadtytulu. Podtytul zniknal z .phead, bo powielal okruchy:
   ta sama rodzina, ten sam stopien, ten sam kolor i w obu ukosnik — czytalo
   sie to jak jedna lamana linia. Numer „01 /” byl numerem sekcji strony
   glownej (.sh .num) i na podstronie nie oznaczal niczego, a do tego stal
   wyszarzony zamiast na czerwono, wiec nie wygladal nawet na ten cytat,
   ktorym byl. Zostaje sam gest domykajacy tytul.
   Proporcje wprost z arkusza rozmiarowki (.t-rule): przy tytule 48 kreska
   ma 52 szerokosci i 2 grubosci, 16 pod linia pisma. Stad 1.083em szerokosci
   i 0.042em grubosci — w em, nie w px, bo h1 chodzi po clampie 44–104.
   Odsadzka policzona od DOLU pola wiersza, nie od linii pisma: przy
   line-height .88 Anton siedzi w polu wyzszym niz wiersz, wiec wartosc jest
   zmierzona w przegladarce, nie przeliczona z 0.333em. */
.phead h1::after{content:"";display:block;background:var(--red);
  width:1.083em;height:0.042em;margin-top:0.309em}
.phead h1{font-family:var(--display);font-weight:400;text-transform:uppercase;font-size:clamp(44px,8.4vw,104px);line-height:.88;
  margin-bottom:max(26px,0.46em)}
.phead h1 .accent{color:var(--red)}
/* Odstep pod tytulem siedzi na h1, nie na leadzie — bo ma byc liczony w em
   TYTULU (clamp 44–104), a em leadu to 17px. Warunek: swiatlo POD kreska
   wieksze niz NAD nia, inaczej kreska przykleja sie do akapitu i domyka
   nie to, co trzeba. Nad kreska jest 0.309em, pod nia 0.46em — stosunek
   1:1,49 na obu krancach clampa. Podloga 26px trzyma stary odstep na
   waskim ekranie, gdzie 0.46em zeszloby do 20px. */
.phead .lead{color:var(--muted);max-width:600px;font-size:17px;margin-top:0}
/* Rzad przyciskow pod leadem naglowka podstrony. Na waskim ekranie schodza
   na pelna szerokosc — dwa przyciski obok siebie ponizej 560px nie miescza
   sie w jednej linii bez lamania etykiety. */
.phead .pacts{display:flex;flex-wrap:wrap;gap:14px;margin-top:34px}
@media(max-width:560px){
  .phead .pacts{gap:10px}
  .phead .pacts .btn{width:100%;justify-content:center}
}

/* ---------- pas CTA na ciemnym (powtarza sie na podstronach) ---------- */
.band{padding:clamp(52px,7vw,86px) 0}
.band .in{display:grid;grid-template-columns:1fr auto;align-items:center;gap:28px 48px}
.band h2{font-family:var(--display);font-weight:400;text-transform:uppercase;font-size:clamp(28px,4.2vw,52px);line-height:.9}
.band h2 .accent{color:var(--red)}
.band p{color:var(--onink-mut);margin-top:14px;max-width:520px;font-size:15px}

/* ---------- brief + stopka: ciemna „tylna okładka" ---------- */
.dark{background:var(--ink);color:var(--onink)}
.brief{padding:clamp(60px,9vw,112px) 0;border-bottom:1px solid rgba(241,237,229,.12)}
.brief .in{display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:center}
.brief h2{font-family:var(--display);font-weight:400;text-transform:uppercase;font-size:clamp(36px,5.4vw,68px);line-height:.9}
.brief h2 .accent{color:var(--red)}
.brief .lead{color:var(--onink-mut);margin:20px 0 28px;max-width:440px}
.ph-row{display:flex;gap:26px;flex-wrap:wrap}
.ph-row a{font-family:var(--ui);font-weight:600;font-size:17px;text-decoration:none;transition:.15s}
.ph-row a:hover{color:var(--red)}
.ph-row .lab{display:block;font-family:var(--meta);font-weight:600;font-size:11px;color:var(--onink-mut);letter-spacing:.1em}
.form{background:var(--ink-2);border:1px solid rgba(241,237,229,.14);padding:30px}
.form .row{margin-bottom:16px}
.form label{font-family:var(--ui);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--onink-mut);display:block;margin-bottom:7px}
.form input,.form textarea,.form select{width:100%;background:var(--ink);border:1px solid rgba(241,237,229,.18);color:var(--onink);padding:12px 14px;font-family:var(--body);font-size:14px}
/* 04.10: ponizej 16px Safari na iPhonie powieksza strone po dotknieciu pola i zostawia
   ja powiekszona (przesuwanie na boki). Na telefonach 16px, na komputerze 14px jak bylo. */
@media(max-width:900px){.form input,.form textarea,.form select{font-size:16px}}
.form input::placeholder,.form textarea::placeholder{color:#6f695f}
.form input:focus,.form textarea:focus,.form select:focus{outline:none;border-color:var(--red)}
.form .two{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.form .up{border:1px dashed rgba(241,237,229,.28);padding:16px;text-align:center;font-family:var(--meta);font-size:12px;color:var(--onink-mut)}
/* pole plików: prawdziwy input schowany, klikalny jest label .up (P2) */
.form .up-input{position:absolute;width:1px;height:1px;padding:0;border:0;opacity:0;overflow:hidden}
.form label.up{display:block;margin-bottom:0;cursor:pointer;text-transform:none;letter-spacing:0;
  font-family:var(--meta);font-weight:400;font-size:12px;color:var(--onink-mut)}
.form .up-input:focus-visible+.up{outline:2px solid var(--onink);outline-offset:2px}
.form .up-lista{list-style:none;margin:8px 0 0;padding:0;font-family:var(--meta);font-size:12px;color:var(--onink-mut)}
.form .up-lista li.zle{color:#ff8a7a}
.form .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form .form-status{min-height:1.4em;margin:0 0 12px;font-size:14px;color:var(--onink)}
.form .form-status.zle{color:#ff8a7a}
.form.wyslany .row,.form.wyslany .rodo,.form.wyslany button{display:none}
/* Drobny druk nad przyciskiem wysylki — kolejnosc DOM, zeby czytnik ekranu
   dostal go PRZED wyslaniem, a nie po. Akapit informacyjny (art. 13 RODO),
   nie checkbox — podstawa przetwarzania to dzialania na zadanie osoby przed
   zawarciem umowy, a nie zgoda. Kontrast --onink-mut na --ink-2 = 6,1:1,
   wiec 11px jest bezpieczne. */
.form .rodo{margin:4px 0 18px;font-family:var(--meta);font-size:11px;line-height:1.65;color:var(--onink-mut)}
.form .rodo a{color:var(--onink);text-decoration:underline;text-underline-offset:2px}
.form .rodo a:hover{color:var(--red)}
/* zaslepki tresci do uzupelnienia — czerwone, zeby nie przeszly niezauwazone
   do publikacji. Poza .rodo stoja tez przy limicie rozmiaru zalacznika. */
.form .todo{color:var(--red)}

footer{padding:70px 0 40px}
.fgrid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;margin-bottom:50px}
footer h5{font-family:var(--meta);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--onink-mut);margin-bottom:16px}
footer ul{list-style:none}
footer li{margin-bottom:9px;font-size:14px}
footer li a{text-decoration:none;transition:.15s}
footer li a:hover{color:var(--red)}
footer .logo-img{filter:brightness(0) invert(1)}
.fbottom{border-top:1px solid rgba(241,237,229,.14);padding-top:24px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-family:var(--meta);font-weight:600;font-size:11px;color:var(--onink-mut);text-transform:uppercase;letter-spacing:.1em}

@media(max-width:900px){
  .fgrid{grid-template-columns:1fr 1fr}
  .brief .in{grid-template-columns:1fr;gap:40px}
  .band .in{grid-template-columns:1fr}

  /* menu chowa sie pod trzy kreski */
  .burger{display:flex}
  header.menu-open{background:var(--bg);border-bottom-color:var(--line)}
  nav.main{position:fixed;top:76px;left:0;right:0;flex-direction:column;align-items:stretch;gap:0;
    background:var(--bg);border-bottom:1px solid var(--line);padding:4px 32px 22px;
    transform:translateY(-135%);transition:transform .3s ease;box-shadow:0 22px 44px rgba(21,19,15,.10)}
  nav.main.open{transform:none}
  nav.main a{padding:16px 0;border-bottom:1px solid var(--line);font-size:16px}
  /* Kreska znika pod OSTATNIA WIDOCZNA pozycja. `:last-of-type` trafia
     w `a.btn`, ktore w tym samym media query ma `display:none` — zerowanie
     szlo wiec w element, ktorego nie widac, a „Kontakt" zostawal z kreska
     wiszaca nad dolna krawedzia menu. Regula `:has(+ a.btn)` mowi wprost:
     link stojacy PRZED przyciskiem CTA. Druga zostaje na wypadek nawigacji
     bez CTA (wtedy ostatni link jest naprawde ostatni). */
  nav.main a:has(+ a.btn){border-bottom:0}
  nav.main a:last-of-type{border-bottom:0}
  nav.main a:not(.btn):after{display:none}
  nav.main a.home{display:block}
  nav.main a.btn{display:none}          /* CTA znika — zastepuja je plywajace przyciski */

  /* plywajace CTA na dole ekranu.
     UWAGA: 900px MUSI byc identyczne z breakpointem, przy ktorym naglowek chowa
     swoje CTA (nav.main a.btn powyzej, ten sam media query). Rozjazd tych liczb
     = zakres szerokosci bez ZADNEGO CTA na ekranie. Trzymac razem. */
  .mcta{display:flex}
  body{padding-bottom:56px}
}
@media(max-width:560px){
  .fgrid,.form .two{grid-template-columns:1fr}
}


/* ============================================================
   STRONA KATEGORII (kat-)
   Powtarza sie 18 razy, wiec caly system siedzi tutaj, a plik
   kategorii zostaje sama trescia. Hub uzywa prefiksu p-, wiec
   kolizji nazw nie ma.
   ============================================================ */

/* ---------- modele: sekcje jedna pod druga, naprzemiennie ---------- */

/* Grupa modeli (np. meskie / damskie). Kategorie bez podzialu po prostu
   nie owijaja modeli w .kat-group — reszta dziala tak samo, bo :first-of-type
   i :nth-of-type licza rodzenstwo, wiec same przeskaluja sie do kontenera. */
.kat-group{margin-top:clamp(50px,6vw,84px)}
.kat-group:first-of-type{margin-top:0}
.kat-group > h3{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink);padding-bottom:14px;border-bottom:1px solid var(--line-2);
  margin-bottom:clamp(30px,3.6vw,50px)}

.kat-model{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,64px);align-items:center;
  padding:clamp(36px,4.6vw,60px) 0;border-top:1px solid var(--line)}
.kat-model:first-of-type{border-top:0;padding-top:0}
/* Naprzemiennosc TYLKO na desktopie. Kolejnosc DOM zawsze zdjecie -> tresc,
   wiec czytnik ekranu dostaje sensowna sekwencje niezaleznie od tego,
   po ktorej stronie kadr wypadl wizualnie. Liczona w obrebie grupy, wiec
   kazda grupa zaczyna sie tak samo. */
.kat-model:nth-of-type(even) .kat-fig{order:2}

/* Sufit 420 px zamiast pelnej polowy kolumny (588 px). Kadr 4:5 na polowie
   siatki miat 735 px wysokosci przy 218 px tekstu obok — 71% wiersza bylo
   pustka. Ponizej: wiersz ~590 px zamiast 759 px. Kadr dosuwa sie do zewnetrznej
   krawedzi, wiec tekst zawsze startuje od osi srodkowej. */
.kat-fig{margin:0;position:relative;aspect-ratio:4/5;max-width:420px;width:100%;
  background:var(--bg-2);border:1px solid var(--line);overflow:hidden}
.kat-model:nth-of-type(odd) .kat-fig{justify-self:start}
.kat-model:nth-of-type(even) .kat-fig{justify-self:end}
.kat-fig img{width:100%;height:100%;object-fit:cover}

/* Zaslepka kadru. Wyglad dziedziczy po .p-thumb.empty z huba — kremowe tlo,
   hairline, przekatna z gradientu — zeby brak zdjecia mowil tym samym jezykiem
   na calym serwisie. Podmiana na zdjecie = zamiana tego <span> na <img>. */
.kat-ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:18px;text-align:center;
  background-image:
    linear-gradient(135deg,transparent calc(50% - .5px),var(--line) 50%,transparent calc(50% + .5px)),
    linear-gradient(45deg,transparent calc(50% - .5px),var(--line) 50%,transparent calc(50% + .5px))}
.kat-ph span{background:var(--bg-2);padding:7px 11px;font-family:var(--meta);font-weight:600;font-size:10px;
  letter-spacing:.14em;line-height:1.7;color:var(--muted)}

.kat-body h4{font-family:var(--display);font-weight:400;text-transform:uppercase;
  font-size:clamp(28px,3.6vw,46px);line-height:.95}
.kat-body p{color:var(--muted);margin-top:16px;font-size:16px;max-width:46ch}

/* Pigulki: jedyne miejsce na liczby. Kolejnosc stala w obrebie kategorii,
   zeby dawaly sie porownywac wzrokiem miedzy modelami:
   gramatura - sklad - sylwetka - liczba kolorow.

   Ramka odpadla 2026-08-31: obrys + uppercase + mono to sygnatura przycisku,
   wiec parametry wygladaly na klikalne i nieaktywne zarazem. Zostaje sam tekst
   z czerwonym ukosnikiem — ten sam znak, ktory numeruje sekcje i metody. */
.kat-pills{display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:26px;list-style:none}
.kat-pills li{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted)}
.kat-pills li::before{content:"/";color:var(--red);margin-right:8px}

@media(max-width:900px){
  /* Jedna kolumna: naprzemiennosc znika, bo na waskim ekranie nie da sie jej
     odczytac. Kadr dostaje sufit szerokosci — pelna szerokosc przy 4:5 zajmowalaby
     caly ekran w pionie. */
  .kat-model{grid-template-columns:1fr;gap:26px}
  .kat-model:nth-of-type(even) .kat-fig{order:0}
  .kat-model:nth-of-type(odd) .kat-fig,
  .kat-model:nth-of-type(even) .kat-fig{justify-self:start}
  .kat-fig{max-width:440px}
}

/* ---------- modele: wariant SIATKA, dla kategorii z duza liczba fasonow ---------- */
/* Doszedl 22.09 przy czapkach zimowych. Spec §3 konczy tabele zachowan zdaniem
   "powyzej 8 modeli wracamy do rozmowy" — czapek jest 12, czyli prawie dwa razy
   tyle co bluz. Rytm naprzemienny dalby strone dwa razy dluzsza od wszystkiego,
   co dotad zbudowalismy, a opisy fasonow sa tu krotkie: modele roznia sie splotem
   i konstrukcja, nie krojem, wiec kazdy kolejny akapit powtarzalby sasiada.
   Siatka pokazuje je tak, jak sie je oglada — obok siebie, do porownania.

   To WARIANT, nie drugi uklad: kadr, typografia, pigulki i zaslepka zostaja te same,
   zmienia sie wylacznie sposob ulozenia kart. Kategoria wchodzi w niego przez
   dodanie klasy .siatka na sekcji i owiniecie modeli w .kat-grid. Wroci przy
   czapkach z daszkiem i skarpetkach. */
.kat-models.siatka .kat-grid{display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(34px,4vw,60px) clamp(28px,4vw,64px)}
/* Karta nie jest juz siatka dwukolumnowa, tylko blokiem: zdjecie, pod nim tresc.
   display:block wylacza przy okazji order i justify-self z ukladu naprzemiennego —
   obie wlasciwosci dzialaja tylko na dziecku kontenera flex/grid, wiec reguly
   :nth-of-type wyzej zostaja bez skutku i nie trzeba ich nadpisywac. */
.kat-models.siatka .kat-model{display:block;padding:0;border-top:0}
.kat-models.siatka .kat-fig{max-width:none}
.kat-models.siatka .kat-body{margin-top:20px}
/* Typografia karty jest BAZOWA — stopien nazwy, wielkosc i miara akapitu zostaja
   takie same jak w ukladzie naprzemiennym. Pierwsza wersja zmniejszala nazwe do 34 px
   i zwezala akapit do 38ch "bo to karta"; zmierzone: przy kolumnie 556 px akapit
   konczyl sie na 326 px, czyli na 59% szerokosci kadru nad nim, i prawa krawedz
   czytala sie jak przypadek. Kolumna w siatce ma DOKLADNIE TYLE SAMO szerokosci
   co kolumna tekstu w ukladzie naprzemiennym (556 px), wiec nie bylo czego zwezac —
   te same 46ch daja te sama dlugosc wiersza na wszystkich trzech kategoriach. */
.kat-models.siatka .kat-pills{margin-top:16px}

@media(max-width:900px){
  /* Jedna kolumna — tak samo jak uklad naprzemienny, z tym samym sufitem kadru.
     Ponizej tego progu oba warianty wygladaja identycznie i to jest zamierzone:
     na telefonie roznica miedzy nimi nie istnieje. */
  .kat-models.siatka .kat-grid{grid-template-columns:1fr;gap:44px}
  .kat-models.siatka .kat-fig{max-width:440px}
}

/* ---------- zdobienia: rozwijane wiersze, dobor per kategoria ---------- */
/* Kafle zamienione na wiersze 28.08. Powod: sekcja zajmowala 1005 px na telefonie
   (9,7% strony), a nie ma w niej czego pokazywac — to sam tekst i drogowskaz do
   zdobienia.html. Zwiniecie niczego nie chowa przed okiem, bo nie ma zdjec.
   Na <details>, wiec dziala bez JS i obsluguje sie klawiatura bez naszego kodu. */
.kat-tech{background:var(--bg-2);--btn-fill:var(--bg-2)}
.kat-tech .lista{border-top:1px solid var(--line-2)}
.kat-tech .z{border-bottom:1px solid var(--line-2)}
.kat-tech .z[hidden]{display:none}

.kat-tech summary{list-style:none;cursor:pointer;position:relative;
  display:flex;align-items:baseline;gap:14px;padding:20px 40px 20px 0}
.kat-tech summary::-webkit-details-marker{display:none}
.kat-tech summary h3{font-family:var(--ui);font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;font-size:16px;transition:color .15s}
.kat-tech summary .qual{font-family:var(--meta);font-weight:600;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
/* strzalka z dwoch krawedzi — bez ikony i bez dodatkowego pliku */
.kat-tech summary::after{content:"";position:absolute;right:6px;top:50%;
  width:9px;height:9px;margin-top:-8px;transform:rotate(45deg);
  border-right:2px solid var(--line-2);border-bottom:2px solid var(--line-2);
  transition:transform .2s,border-color .15s}
.kat-tech .z[open] summary::after{transform:rotate(-135deg);margin-top:-2px}
.kat-tech summary:focus-visible{outline:2px solid var(--red);outline-offset:-3px}

.kat-tech .panel{padding:0 40px 24px 0}
.kat-tech .panel p{color:var(--muted);font-size:15px;max-width:62ch}
.kat-tech .panel .go{display:inline-block;margin-top:16px;font-family:var(--meta);font-weight:600;
  font-size:11px;letter-spacing:.1em;color:var(--red);text-decoration:none}

@media (hover:hover) and (pointer:fine){
  .kat-tech summary:hover h3{color:var(--red)}
  .kat-tech summary:hover::after{border-color:var(--red)}
  .kat-tech .panel .go:hover{text-decoration:underline}
}
@media(max-width:560px){
  .kat-tech summary{flex-direction:column;align-items:flex-start;gap:5px;padding-right:34px}
}
@media(prefers-reduced-motion:reduce){
  .kat-tech summary::after{transition:none}
}

/* ---------- najczestsze pytania: rozwijane odpowiedzi ---------- */
/* Ten sam mechanizm co .kat-tech (<details>, strzalka z dwoch krawedzi), ale osobny
   komponent: pytanie to zdanie, nie nazwa techniki — wersaliki Oswalda 16 px
   czytalyby sie przy 60 znakach jak krzyk. Stad Archivo i zwykla wielkosc liter.
   Domyslnie wszystko zwiniete: 23 otwarte odpowiedzi to sciana tekstu, a pytania
   maja sie dac przeskanowac wzrokiem. */
.faq .lista{border-top:1px solid var(--line-2);max-width:860px}
.faq .q{border-bottom:1px solid var(--line-2)}
.faq summary{list-style:none;cursor:pointer;position:relative;
  display:flex;align-items:baseline;flex-wrap:wrap;gap:6px 14px;padding:20px 40px 20px 0}
.faq summary::-webkit-details-marker{display:none}
.faq summary h3{font-family:var(--body);font-weight:600;font-size:18px;line-height:1.35;
  transition:color .15s}
.faq summary::after{content:"";position:absolute;right:6px;top:50%;
  width:9px;height:9px;margin-top:-8px;transform:rotate(45deg);
  border-right:2px solid var(--line-2);border-bottom:2px solid var(--line-2);
  transition:transform .2s,border-color .15s}
.faq .q[open] summary::after{transform:rotate(-135deg);margin-top:-2px}
.faq summary:focus-visible{outline:2px solid var(--red);outline-offset:-3px}
.faq .panel{padding:0 40px 24px 0}
.faq .panel p{color:var(--muted);font-size:16px;max-width:64ch}
.faq .panel p+p,.faq .panel p+ul,.faq .panel ul+p{margin-top:10px}
.faq .panel ul{color:var(--muted);font-size:16px;padding-left:20px;max-width:64ch}
.faq .panel a{color:var(--ink);text-decoration-color:var(--red);text-underline-offset:3px}

/* ROBOCZE — odpowiedz albo jej fragment czeka na potwierdzenie klienta (PROGRESS §6).
   Etykieta w <summary>, fragment w tekscie na czerwono. Po potwierdzeniu zdejmuje
   sie klase .robocze z <details> i <span class="todo"> z tekstu — nic wiecej. */
.faq .robocze summary .qual{font-family:var(--meta);font-weight:600;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--red)}
.faq .todo{color:var(--red)}

@media (hover:hover) and (pointer:fine){
  .faq summary:hover h3{color:var(--red)}
  .faq summary:hover::after{border-color:var(--red)}
}
@media(max-width:560px){
  .faq summary{padding-right:34px}
  .faq summary h3{font-size:17px}
  .faq .panel{padding-right:0}
}
@media(prefers-reduced-motion:reduce){
  .faq summary::after{transition:none}
}

/* ---------- karuzela pozioma (realizacje, szyny detali) ---------- */
/* Prefiks .kat-real zdjety 2026-09-02: te same klasy obsluguja szesc szyn na
   stronie zdobien. Klasy .rail, .rail-wrap, .r i .rn nie wystepuja nigdzie
   indziej w serwisie — sprawdzone w trzech plikach HTML przed zmiana. */
/* Bez biblioteki. Przewijalny rzad + scroll-snap; strzalki tylko dodaja
   wygode. Bez JS zostaje zwykly przewijalny rzad — dziala palcem i gladzikiem,
   znika jedynie sterowanie przyciskami. */
.rail-wrap{position:relative}
.rail{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  /* Pasek przewijania chowamy — afordancje niesie teraz wystajacy skrawek
     nastepnego kadru i strzalki na zdjeciu. */
  scrollbar-width:none;-ms-overflow-style:none}
.rail::-webkit-scrollbar{display:none}
.rail:focus-visible{outline:2px solid var(--red);outline-offset:4px}
.r{flex:0 0 calc((100% - 28px)/3);scroll-snap-align:start;
  position:relative;aspect-ratio:4/5;background:var(--bg-2);
  border:1px solid var(--line);overflow:hidden}
.r img{width:100%;height:100%;object-fit:cover}

/* Strzalki NA kadrze, przy krawedziach — od razu mowia, ze przewija sie
   wlasnie ten rzad zdjec. Pojawiaja sie dopiero z JS, bo bez niego nic by
   nie robily. Przyciemniona plamka pod znakiem, zeby jasny szewron trzymal
   sie i na bialej koszulce, i na czarnej. */
.rn{position:absolute;top:calc(50% - 1px);transform:translateY(-50%);z-index:2;
  width:46px;height:46px;display:none;align-items:center;justify-content:center;
  padding:0;cursor:pointer;color:var(--onink);
  background:rgba(21,19,15,.55);border:1px solid rgba(241,237,229,.5);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  transition:background .15s,border-color .15s,opacity .2s,visibility .2s}
html.js .rn{display:flex}
.rn.prev{left:12px}
.rn.next{right:12px}
/* Hover TYLKO tam, gdzie istnieje kursor.
   Na dotyku :hover przykleja sie po tapnieciu i strzalka zostaje czerwona,
   a zapowiedziana transformacja na obrazku potrafi zepchnac go na osobna
   warstwe GPU, gdzie pomniejszenie 2x liczone jest tanszym filtrem — stad
   miekkie kadry przed dotknieciem. Poza kursorem nie ma ani jednego, ani
   drugiego. */
@media (hover:hover) and (pointer:fine){
  .rn:hover:not(:disabled){background:var(--red);border-color:var(--red)}
  .r img{transition:transform .4s}
  .r:hover img{transform:scale(1.05)}
}
.rn:focus-visible{outline:2px solid var(--red);outline-offset:3px}
/* na krancu strzalka znika calkiem — wyszarzona nad zdjeciem robilaby brud */
.rn:disabled{opacity:0;visibility:hidden;pointer-events:none}

/* Licznik pod kadrem. Strzalki mowia "da sie przewinac", ale nie mowia,
   ile jeszcze zostalo — a przy schowanym pasku przewijania nie mowi tego nic.
   Liczba wiodaca to pierwszy widoczny kadr, wiec na szerokim ekranie skacze
   o trzy. Bez JS licznik sie nie pokazuje: sam by nie nadazal za rzedem. */
.rail-count{display:none;margin-top:14px;text-align:right;
  font-family:var(--meta);font-weight:600;font-variant-numeric:tabular-nums;font-size:12px;letter-spacing:.1em;color:var(--muted)}
html.js .rail-count{display:block}
.rail-count .now{color:var(--ink)}

@media(max-width:900px){
  /* Kafel wezszy niz polowa, wiec zza krawedzi wystaje skrawek nastepnego
     zdjecia. To czytelniejsza podpowiedz niz sama strzalka. */
  .r{flex-basis:44%}
}
@media(max-width:560px){
  .r{flex-basis:84%}
  .rn{width:40px;height:40px}
  .rn.prev{left:8px}
  .rn.next{right:8px}
}
@media(prefers-reduced-motion:reduce){
  .rail{scroll-behavior:auto}
  .r img{transition:none}
  .r:hover img{transform:none}
  .rn{transition:none}
}

/* ---------- naglowek kategorii: trzy fakty pod przyciskami ----------
   Naklad, termin i co przyslac. Tresc pochodzi z sekcji 04 "Jak zamowic"
   (usunieta 31.08); tego samego dnia stala pod haslem briefu, a 2026-08-31
   przeniesiona do naglowka: to pierwszy ekran kategorii, a nie 75% strony.
   Jezyk wizualny wspolny z pigulkami przy modelach — ten sam ukosnik. */
.phead .fakty{list-style:none;display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:26px}
.phead .fakty li{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.phead .fakty li::before{content:"/";color:var(--red);margin-right:8px}

/* ---------- zdobienia: strona ---------- */
/* Szesc blokow, w kazdym wlasna szyna detali.
   Kadr 4:5 — ten sam co w szynie realizacji. Kwadrat 1:1 z §10 specu odpadl 02.09
   po ocenie klienta: czesc materialu to cale sztuki w pionie, a kwadrat scinal im
   naglowki nadruku. Makro na 4:5 nie traci nic.
   Ramka i tlo schodza z .r na obrazek, bo .r jest tu <figure> i musi wypuscic
   podpis pod kadrem zamiast go przyciac. */

/* Pasek skokow. Do 02.09 byl zawijanym ciagiem wewnatrz naglowka strony i przy
   390 px rozsypywal sie na trzy rzedy drobnego tekstu. Od 03.09 stoi w osobnym
   pasku POZA .phead — inaczej position:sticky trzymaloby sie tylko dopoki naglowek
   strony jest widoczny, czyli przez dwa ekrany z dwunastu.
   Na szerokim ekranie ten sam kolor tla co .phead, wiec czyta sie dalej jako jego
   czesc; .phead oddaje wtedy swoja kreske paskowi. */
.zd-navbar{background:var(--bg-2);border-bottom:1px solid var(--line)}
.phead-bez-kreski{border-bottom:0}
.zd-nav{display:flex;flex-wrap:wrap;gap:10px 22px;padding:16px 0}
.zd-nav a{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);text-decoration:none;transition:color .15s}
.zd-nav a::before{content:"/";color:var(--red);margin-right:8px}
.zd-nav a:hover{color:var(--ink)}
.zd-nav a:focus-visible{outline:2px solid var(--red);outline-offset:3px}
/* Sekcja, ktora akurat jest na ekranie. Ustawiane w rf.js; bez JS zaden link
   nie jest wyrozniony i pasek dziala jak zwykla lista skrotow. */
.zd-nav a[aria-current="true"]{color:var(--red)}
.zd-nav-kr{display:none}

.zd-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 18px;margin-bottom:18px}
.zd-head .num{font-family:var(--meta);font-weight:600;color:var(--red);font-size:13px;letter-spacing:.1em}
.zd-head h2{font-family:var(--display);font-weight:400;text-transform:uppercase;
  font-size:clamp(34px,5.8vw,76px);line-height:.88}
/* Kwalifikator ("Wieksze naklady") na tej stronie NIE wystepuje — decyzja klienta
   02.09. Zostaje na kategorii, gdzie stoi tuz przy nazwie wiersza i czyta sie jako
   etykieta; przy naglowku wielkosci 76 px wisial przy prawej krawedzi bez zaczepienia.
   Tresc i tak niesie pierwszy akapit bloku. */

.zd-txt{max-width:640px;color:var(--muted);font-size:16px}
.zd-txt p + p{margin-top:16px}

/* Mikrolista wariantow. <dl> z para <dt>/<dd> w <div> — HTML5 na to pozwala,
   a bez opakowania siatka rozjezdza nazwe z korzyscia. */
.zd-var{display:grid;grid-template-columns:1fr 1fr;gap:24px 34px;
  max-width:900px;margin:38px 0 44px}
.zd-var>div{border-top:1px solid var(--line-2);padding-top:12px}
.zd-var dt{font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink)}
.zd-var dd{margin-top:8px;color:var(--muted);font-size:15px;line-height:1.65}

/* Blok bez mikrolisty wariantow (sublimacja): szyna szlaby wprost pod akapitem,
   bez odstepu. Odtwarzamy ten sam prześwit, ktory daje dolny margines .zd-var,
   zeby wysokosc bloku czytala sie tak samo w calej szostce. */
.zd-txt + .rail-wrap{margin-top:44px}

.zd .r{aspect-ratio:auto;background:none;border:0;overflow:visible}
.zd .r img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  background:var(--bg-2);border:1px solid var(--line)}
/* Zaslepka: ten sam jezyk co .kat-ph na kategorii. */
.zd .r .ph{position:relative;display:block;aspect-ratio:4/5;
  background:var(--bg-2);border:1px solid var(--line)}
/* Blok 06 na wyroznionym tle — rekomendacja redakcji z 02.09: wykonczenia
   krawieckie to nie kolejna metoda znakowania, tylko dowod, ze produkt powstaje
   od podstaw. Ten sam odcien, co .phead i sekcja 02 na kategorii, wiec strona
   nie dostaje nowego koloru, tylko uzywa istniejacego. */
.zd-wyroznik{background:var(--bg-2)}
/* Zaslepka i kadr musza wtedy siedziec na kremie, inaczej znikaja w tle. */
.zd-wyroznik .r .ph,
.zd-wyroznik .r img{background:var(--bg)}
.zd-wyroznik .kat-ph span{background:var(--bg)}

.zd-cap{margin-top:10px;font-family:var(--meta);font-weight:600;font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);line-height:1.6}

@media (hover:hover) and (pointer:fine){
  /* Bez powiekszenia na hover: kadr wypuszcza podpis, wiec nie ma overflow,
     w ktorym transformacja mialaby sie schowac. Makro i tak jest zblizeniem. */
  .zd .r:hover img{transform:none}
}
@media(max-width:900px){
  .zd-var{grid-template-columns:1fr;gap:20px}

  /* Jeden rzad, przewijany palcem. Powyzej 900 px szesc pelnych nazw miesci sie
     w linii (zmierzone: 789 px potrzebne, 885 px dostepne), wiec przewijanie
     wlacza sie dokladnie tam, gdzie zaczyna byc potrzebne. */
  .zd-navbar{position:sticky;top:77px;z-index:30}
  .zd-nav{flex-wrap:nowrap;overflow-x:auto;gap:22px;
    /* Pasek wychodzi na krawedzie ekranu, zeby skrawek nastepnej pozycji byl
       widoczny zamiast urywac sie rowno z marginesem tekstu. */
    margin:0 -32px;padding:14px 32px;
    scroll-padding-left:32px;
    scrollbar-width:none;-ms-overflow-style:none;
    overscroll-behavior-x:contain}
  .zd-nav::-webkit-scrollbar{display:none}
  .zd-nav a{white-space:nowrap}
  .zd-nav a[aria-current="true"]{text-decoration:underline;text-decoration-color:var(--red);
    text-decoration-thickness:2px;text-underline-offset:6px}
  /* Ukosnik NIE nalezy do podkreslenia. Dekoracja tekstu propaguje sie na
     potomkow, w tym na `::before`, wiec kreska biegla takze pod „/" i pod
     odstepem za nim — czytalo sie to jak podkreslenie dwoch rzeczy naraz.
     `inline-block` robi z pseudoelementu atomowy inline, a do jego wnetrza
     dekoracja rodzica juz nie wchodzi. Geometria bez zmian: szerokosc znaku
     i margines 8 px zostaja te same (sprawdzone na stronie kontrolnej). */
  .zd-nav a[aria-current="true"]::before{display:inline-block}
  .zd-nav-dl{display:none}
  .zd-nav-kr{display:inline}
  /* Kotwica musi zejsc spod naglowka I spod przyklejonego paska. */
  /* 77 px naglowka + 48 px paska = 125 (zmierzone 03.09) */
  section{scroll-margin-top:125px}
}
@media(prefers-reduced-motion:reduce){
  .zd-nav{scroll-behavior:auto}
}

/* ---------- kafel realizacji: zdjecie + podpis ---------- */
/* Przeniesiony 02.10 bez zmian ze <style> strony glownej (sekcja 03), bo uzywa go
   tez realizacje.html. Uklad mozaiki (.gal, .s4/.s6/.s8, .tall) zostal na glownej;
   tu jest tylko sam kafel. rf.js czyta .pn i .pt do podpisu lightboxa. */
.g{position:relative;overflow:hidden;border:1px solid var(--line)}
.g .ph{position:relative;height:100%;min-height:230px;background:var(--bg-2)}
.g .ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .45s}
.g:hover .ph img{transform:scale(1.04)}
.g .cap{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:16px;color:#F4F1EA;
  background:linear-gradient(0deg,rgba(10,9,7,.9),transparent);transform:translateY(8px);opacity:.9;transition:.2s}
.g:hover .cap{transform:none;opacity:1}
.g .cap .pn{font-family:var(--ui);font-weight:700;text-transform:uppercase;font-size:14px;letter-spacing:.04em}
/* Wersaliki, nie kapitaliki: Archivo nie ma cechy `smcp` — zmierzone,
   font-feature-settings:"smcp" nie zmienia szerokosci ani o piksel, wiec
   font-variant-caps:small-caps kazaloby przegladarce je PODROBIC przez
   zmniejszenie wersalikow. Kreska wychodzi wtedy cienka i przy 11px na
   bieli 68% krycia gubi sie na zdjeciu.
   Wartosci sa wprost z .lb-cap (600 / .06em / wersaliki) i to jest powod
   wazniejszy niz wyglad: rf.js czyta .pn i .pt z kafla i wstawia je do
   podpisu lightboxa, wiec DO TEJ PORY ten sam ciag zmienial wielkosc liter
   po kliknieciu. Teraz nie zmienia. Ta sama regula co .zd-cap i
   .rz figcaption — cala rodzina podpisow stoi na jednym zapisie. */
.g .cap .pt{font-family:var(--meta);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:11px;color:rgba(255,255,255,.68)}

/* ---------- realizacje.html: kolaz ---------- */
/* Siatka 4 kolumn, wszystkie zrodla sa pionowe, wiec podstawa to kafel 4:5.
   Warianty: .rl-duzy (2x2, tez 4:5) i .rl-poziom (2 kolumny, 8:5 — tylko kadry
   przyciete pod ten ksztalt w narzedzia/kadry-realizacje.py).
   Kolejnosc kafli w HTML ukladana pasmami przez narzedzia/realizacje-strona.py,
   tak zeby kazde pasmo 4 x 2 domykalo sie bez dziur — takze na 2 kolumnach.
   align-self:stretch wprost, bo element z aspect-ratio przy domyslnym `normal`
   wyrownuje sie do poczatku i zostawia szpare w rzedzie z wyzszym sasiadem.
   justify-self:stretch z tego samego powodu w poziomie: bez niego kafel w rzedzie
   wyzszym niz on sam (obok .rl-poziom) bral szerokosc z proporcji i wystawal
   o ok. 4 px poza kolumne (zmierzone 02.10). Oba wprost = oba wymiary z siatki. */
.rl-gal{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.rl-gal>.g{align-self:stretch;justify-self:stretch;aspect-ratio:4/5}
.rl-gal>.g .ph{min-height:0}
.rl-gal>.g.rl-duzy{grid-column:span 2;grid-row:span 2}
.rl-gal>.g.rl-poziom{grid-column:span 2;aspect-ratio:8/5}
@media(max-width:900px){.rl-gal{grid-template-columns:repeat(2,1fr);gap:8px}}
/* Waski ekran: maly kafel ma ok. 160 px, podpis nakladany na zdjecie lamal sie
   na 3-4 linie i zaslanial polowe kadru. Pisma nie zmniejszamy — podpis schodzi
   POD zdjecie, na ciemny pasek w kolorze nakladki. Proporcja przechodzi z kafla
   na .ph, bo wysokosc kafla zalezy teraz od dlugosci podpisu; rzad wyrownuje
   align-self:stretch, a .cap rosnie (flex:1), wiec paski w rzedzie koncza sie rowno. */
@media(max-width:560px){
  /* .rl-poziom wprost: regula 8:5 wyzej ma wyzsza specyficznosc niz samo .g */
  .rl-gal>.g,.rl-gal>.g.rl-poziom{aspect-ratio:auto;display:flex;flex-direction:column;background:var(--ink)}
  .rl-gal>.g .ph{aspect-ratio:4/5;height:auto}
  .rl-gal>.g.rl-poziom .ph{aspect-ratio:8/5}
  .rl-gal>.g .cap{position:static;flex:1;transform:none;opacity:1;background:none;padding:10px 10px 12px}
}

/* ---------- lightbox: powiekszony podglad kadru ---------- */
/* Jeden mechanizm dla trzech roznych struktur: szyn zdobien (figure.r),
   szyny realizacji na kategorii (div.r) i mozaiki na stronie glownej (div.g).
   Sterowany atrybutem data-lb na KONTENERZE, nie selektorem .rail — inaczej
   odcialby mozaike i przyszle realizacje.html.

   Wszystko ponizej wchodzi tylko pod html.js, tak samo jak strzalki szyny:
   bez JS zaden kafel nie udaje przycisku i nie ma martwej klikalnosci. */

/* Kafel jako wejscie do podgladu. Kursor lupy, a nie lapka — mowi, co sie
   stanie, nie tylko ze cos sie stanie. */
html.js .lb-kafel{cursor:zoom-in}
html.js .lb-kafel:focus-visible{outline:2px solid var(--red);outline-offset:3px}
/* Kontener jest JEDNYM przystankiem Tab; kafle maja tabindex="-1" i chodzi sie
   po nich strzalkami. Stad wyroznienie takze wtedy, gdy fokus stoi na szynie,
   a nie na kaflu — inaczej po wejsciu Tabem nie widac, gdzie sie jest. */
html.js [data-lb]:focus-visible{outline:2px solid var(--red);outline-offset:4px}

/* Okno. display ustawiany TYLKO pod [open] — regula bez tego warunku
   nadpisalaby UA-owe display:none i zamkniety dialog zostalby na ekranie. */
.lb{padding:0;border:0;margin:0;width:100%;max-width:none;height:100%;max-height:none;
  background:rgba(21,19,15,.975);color:var(--onink);overflow:hidden}
.lb[open]{display:flex;align-items:center;justify-content:center}
/* Prawdziwy <figure> z <figcaption>, nie dwa luzne bloki: powiekszenie i jego
   podpis maja byc dla czytnika ekranu jedna calascia. */
.lb-fig{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:18px;max-width:100%;max-height:100%;min-height:0}
/* Kolor wpisany liczba, nie var(--ink): ::backdrop dziedziczy zmienne dopiero
   w nowszych przegladarkach, a to jedyne tlo w starszych. */
.lb::backdrop{background:rgba(21,19,15,.975)}
.lb[open]{animation:lb-wejscie .18s ease-out}
@keyframes lb-wejscie{from{opacity:0}to{opacity:1}}

/* Blokada przewijania tla. showModal() sam tego nie gwarantuje w kazdej
   przegladarce, a przewijajaca sie strona pod otwartym podgladem dezorientuje. */
html.lb-open{overflow:hidden}

.lb-stage{position:relative;display:flex;align-items:center;justify-content:center;
  max-width:100%;min-height:0}
/* 100dvh, nie 100vh — na telefonie pasek adresu chowa sie i chowa, a vh
   liczy ekran bez tego ruchu, przez co dol kadru wchodzil pod pasek. */
.lb-img{display:block;width:auto;height:auto;
  max-width:calc(100vw - 32px);max-height:calc(100dvh - 150px);object-fit:contain}

/* Strzalki NA kadrze, przy krawedziach — ta sama zasada, co w szynie (.rn). */
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:46px;height:46px;display:flex;align-items:center;justify-content:center;
  padding:0;cursor:pointer;color:var(--onink);
  background:rgba(21,19,15,.55);border:1px solid rgba(241,237,229,.5);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  transition:background .15s,border-color .15s,opacity .2s,visibility .2s}
.lb-nav.prev{left:12px}
.lb-nav.next{right:12px}
@media (hover:hover) and (pointer:fine){
  .lb-nav:hover:not(:disabled){background:var(--red);border-color:var(--red)}
  .lb-x:hover{background:var(--red);border-color:var(--red)}
}
.lb-nav:focus-visible,.lb-x:focus-visible{outline:2px solid var(--red);outline-offset:3px}
/* Na krancu strzalka znika calkiem, jak w szynie — wyszarzona robilaby brud.
   Zapetlenia nie ma: grupa ma poczatek i koniec. */
.lb-nav:disabled{opacity:0;visibility:hidden;pointer-events:none}

.lb-x{position:absolute;top:14px;right:14px;z-index:3;
  width:46px;height:46px;display:flex;align-items:center;justify-content:center;
  padding:0;cursor:pointer;color:var(--onink);
  background:rgba(21,19,15,.55);border:1px solid rgba(241,237,229,.5);
  transition:background .15s,border-color .15s}

/* Pasek pod kadrem: podpis z lewej, licznik z prawej. Gdy kafel nie ma podpisu
   (realizacje na kategorii), zostaje sam licznik — wariant A z §10. */
/* Szerokosc paska bierze sie ze zdjecia, nie z ekranu: to .lb-fig dopasowuje
   sie do kadru, a pasek rozpina sie na 100% jego szerokosci. Inaczej podpis
   i licznik odjezdzaja na krawedzie ekranu i przestaja nalezec do zdjecia. */
.lb-bar{display:flex;align-items:baseline;justify-content:space-between;gap:24px;
  width:100%;padding:0 2px}
.lb-cap{font-family:var(--meta);font-weight:600;font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--onink-mut);line-height:1.6}
.lb-cap .lb-cap-1{color:var(--onink)}
.lb-cap .lb-cap-2{display:block}
.lb-count{margin-left:auto;white-space:nowrap;
  font-family:var(--meta);font-weight:600;font-variant-numeric:tabular-nums;font-size:12px;letter-spacing:.1em;color:var(--onink-mut)}
.lb-count .now{color:var(--onink)}

@media(max-width:560px){
  .lb-fig{gap:12px}
  .lb-nav{width:40px;height:40px}
  .lb-nav.prev{left:8px}
  .lb-nav.next{right:8px}
  .lb-x{top:8px;right:8px;width:40px;height:40px}
  .lb-img{max-width:100vw;max-height:calc(100dvh - 132px)}
  .lb-bar{padding:0 16px}
}
@media(prefers-reduced-motion:reduce){
  .lb[open]{animation:none}
  .lb-nav,.lb-x{transition:none}
}

/* ---------- rz- : tabele rozmiarow ---------- */
/* Siatka arkuszy. Kafel jest LINKIEM do pliku z arkuszem, a nie przyciskiem —
   powod i przelaczanie zachowania opisane przy data-lb-prog w rf.js.
   Dzieki temu caly blok dziala bez JS: klikniecie otwiera arkusz.

   Jeden prog: 900 px. Ten sam, na ktorym pasek skokow robi sie przyklejony,
   i ten sam, ktory rf.js bierze z data-lb-prog. Dwie kolumny ponizej niego
   daja kafel ~400 px, czyli tytul arkusza na granicy czytelnosci — a to
   jedyne, co miniatura ma przekazac. */
.rz-siatka{display:grid;gap:34px 32px}

.rz{margin:0}
.rz > a{display:block;border:1px solid var(--line);background:var(--bg-2);
  text-decoration:none;transition:border-color .15s}
.rz > a:focus-visible{outline:2px solid var(--red);outline-offset:3px}
.rz img{width:100%;height:auto}

/* Podpis nie powtarza tytulu z arkusza — dokłada zakres rozmiarow, ktorego
   z miniatury nie widac, i daje stronie tekst. Bez niego czternascie obrazkow
   to podstrona bez tresci: nie do znalezienia ani przez Ctrl+F, ani w Google. */
.rz figcaption{display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;gap:6px 18px;margin-top:12px;
  font-family:var(--meta);font-weight:600;font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;line-height:1.5}
/* margin-left:auto, a nie samo space-between: gdy dluga nazwa zawija podpis
   do drugiej linii, zakres zostaje sam w wierszu i space-between zepchnaloby
   go do LEWEJ — czytaloby sie jak druga linia nazwy. */
.rz-zakres{margin-left:auto;color:var(--muted);white-space:nowrap}

/* Kotwica musi zejsc spod naglowka I spod przyklejonego paska — te same
   liczby, co przy `section` (zmierzone 03.09), i pod tym samym warunkiem.
   Warunek MUSI byc `max-width:900px`, a nie `min-width` z odwrotna wartoscia:
   przy dokladnie 900 px pasek jest juz przyklejony, wiec kotwica liczaca 78 px
   ladowalaby 47 px za wysoko — pod paskiem (zmierzone na granicy). */
.rz{scroll-margin-top:78px}

.rz-brak{color:var(--muted);font-size:16px;max-width:640px;margin-top:8px}

@media(min-width:900px){
  .rz-siatka{grid-template-columns:1fr 1fr}
}
@media(max-width:900px){
  .rz{scroll-margin-top:125px}
}
@media (hover:hover) and (pointer:fine){
  .rz > a:hover{border-color:var(--red)}
}

/* ---------- pasek liczb (trust bar) — strona główna i O nas ----------
   Przeniesiony 03.10 ze <style> index.html, gdy pojawił się drugi raz. */
.strip{border-bottom:1px solid var(--line);background:var(--bg-2)}
.strip .in{display:grid;grid-template-columns:repeat(4,1fr)}
.strip .it{padding:34px 24px;border-right:1px solid var(--line)}
.strip .it:last-child{border-right:none}
.strip .n{font-family:var(--display);font-weight:400;font-size:46px;line-height:1}
.strip .n .accent{color:var(--red)}
.strip .t{font-family:var(--meta);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);margin-top:6px}
@media(max-width:900px){
  .strip .in{grid-template-columns:1fr 1fr}
  /* uklad 2x2: kreska pionowa tylko w srodku, nie na krawedzi paska */
  .strip .it:nth-child(2n){border-right:none}
  .strip .it:nth-child(-n+2){border-bottom:1px solid var(--line)}
}
@media(max-width:560px){
  /* trust bar zostaje 2x2; liczba (~75px) i etykieta (~80px) mieszcza sie
     w polowie szerokosci nawet przy 320px — schodzi tylko padding komorki */
  .strip .it{padding:26px 16px}
}
/* 04.10: przy 320px pasek wystawal o 11px. Zmierzone min-content: „DOSWIADCZENIA”
   125px (kolumna z „12 lat”), „100%” 109px; przy wrap 32 + padding 4x16 zostawalo
   256px na 298px. Ponizej 361px: wrap 24, komorki bez zewnetrznego paddingu, 12px
   miedzy kolumnami (zapas 14px przy 320). Stopien liczb i etykiet bez zmian.
   Komentarz wyzej mowil, ze „miesci sie przy 320px” — pomiar 04.10 temu przeczyl. */
@media(max-width:360px){
  .strip .wrap{padding:0 24px}
  .strip .it{padding:26px 12px 26px 0}
  .strip .it:nth-child(2n){padding:26px 0 26px 12px}
}

/* ---------- pasy pracowni: cztery pionowe zdjecia schodkiem ----------
   Strona glowna (sekcja 05) i o-nas.html (etap „Dzis”), 04.10. Kolejnosc procesu:
   tkaniny, wykroje, krojenie, szycie. Bez ramek, cieni i podpisow na ekranie. */
.pasy{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;align-items:start;width:min(586px,100%)}
.pasy picture{display:block}
.pasy img{display:block;width:100%;height:auto;aspect-ratio:136/460;object-fit:cover}
.pasy picture:nth-child(2){margin-top:48px}
.pasy picture:nth-child(3){margin-top:18px}
.pasy picture:nth-child(4){margin-top:64px}
.pasy .tkaniny{object-position:55% 50%}
/* 30%: kadr konczy sie na ~61% szerokosci, zielona plama na pierwszym planie zaczyna sie od ~63% */
.pasy .wykroje{object-position:30% 45%}
.pasy .krojenie{object-position:38% 50%}
.pasy .szycie{object-position:55% 55%}
@media(max-width:900px){
  .pasy{width:100%}
  .pasy picture:nth-child(2){margin-top:24px}
  .pasy picture:nth-child(3){margin-top:9px}
  .pasy picture:nth-child(4){margin-top:32px}
}
@media(max-width:560px){
  .pasy{gap:8px}
  .pasy img{aspect-ratio:1/2.4}
  .pasy picture:nth-child(2){margin-top:16px}
  .pasy picture:nth-child(3){margin-top:6px}
  .pasy picture:nth-child(4){margin-top:22px}
  /* szerszy kadr (1:2,4) przy 30% wpuszczal zielona plame — od lewej krawedzi */
  .pasy .wykroje{object-position:0% 45%}
}

/* ---------- tekst ciagly (polityka prywatnosci) ----------
   Dlugi tekst do czytania: wezsza kolumna, wieksza interlinia, srodtytuly
   w kroju UI (nie Anton — to nie sa naglowki sekcji z numeracja). */
.prose{max-width:720px}
.prose h2{font-family:var(--ui);font-weight:600;font-size:20px;line-height:1.25;text-transform:uppercase;letter-spacing:.04em;margin:48px 0 14px}
.prose h2:first-child{margin-top:0}
.prose p,.prose li{font-size:16px;line-height:1.65}
.prose p + p,.prose p + ul,.prose ul + p{margin-top:12px}
.prose ul{padding-left:20px}
.prose li + li{margin-top:6px}
.prose .dop{color:var(--muted);font-size:15px}            /* dopiski: podstawa prawna, okres */
.prose .dop + .dop{margin-top:4px}
.prose .dop + ul{margin-top:4px;color:var(--muted);font-size:15px}
.prose .dop + ul li{font-size:15px}
.prose .skrot{background:var(--bg-2);border-left:3px solid var(--red);padding:22px 26px 22px 44px}  /* blok „W skrócie” */
.prose a{text-decoration:underline;text-underline-offset:2px}
@media(max-width:560px){
  .prose .skrot{padding:18px 16px 18px 34px}
}
