/* HUTNIK etap 3 „Heron" — GRAYBOX (bez polishu; szlif = T4)
   Paleta: docs/PROJEKT.md + granat zmierzony z logo (#163379) */
:root{
  --paper:#ffffff;
  --fog:#f5f5f5;
  --carbon:#0f0f0f;
  --navy:#163379;
  --navy-soft:rgba(22,51,121,.55);
  --lime:#a5c200;  /* ciemniejsza limonka dla lepszego kontrastu */
  --orange:#e67e22;      /* 1 element na stronę — nitka w calloucie MATERIAŁ */
  --red:#b3261e;         /* tylko logo / mikro */
  --ink:#211b14;
  --ink-2:rgba(33,27,20,.72);
  --grid:rgba(22,51,121,.07);
  --frame:rgba(22,51,121,.55);
  --font-h:"Staatliches","Archivo","Space Grotesk","Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-b:"Inter","IBM Plex Mono",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-m:"IBM Plex Mono","JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --maxw:1280px;
  --pad:clamp(20px,4vw,64px);
  --mx:50vw; --my:40vh;   /* pozycja kursora (JS) */
  --lens-r:260px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;overflow-x:clip}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
html.is-preloading{overflow:hidden;scroll-behavior:auto}   /* scroll zablokowany na czas intra */
body{margin:0;font-family:var(--font-b);color:var(--ink);background:var(--fog);line-height:1.5;overflow-x:clip;scrollbar-gutter:stable}
img{display:block;max-width:100%;height:auto}
a{color:inherit}
h1,h2,h3,h4{font-family:var(--font-h);letter-spacing:-.01em;line-height:1.05;margin:0}
/* TYTUŁY SEKCJI = ta sama czcionka co hero h1 (user 2026-10-04):
   font-h, waga 900, wersaliki, duży stopień pisma, DWUKOLOR (czerwone .brand).
   Rozmiar nieco mniejszy niż hero (hasło ma być największe na stronie). */
h2{font-size:clamp(44px,5.2vw,84px);font-weight:900;line-height:.95;
  letter-spacing:-.03em;text-transform:uppercase;margin-bottom:.5em}
/* Polityka prywatności ma h1 (jedyne w zestawie — dokument, nie sekcja).
   Musi dostać identyczne formatowanie co h2, inaczej tytuł skurczy się
   do rozmiaru body i strona zyska drugi wygląd.
   Kolor #fff jest WYMAGANY: .page-polityka ma tło --carbon (#0f0f0f),
   a bazowy var(--ink) to granat — na tym tle byłby nieczytelny.
   (onas.css:48 daje biały dla .onas-hero h1; polityka używa .onas-hist,
    więc tej reguły nie łapie.) */
.onas-hist h1{font-size:clamp(44px,5.2vw,84px);font-weight:900;line-height:.95;
  letter-spacing:-.03em;text-transform:uppercase;margin-bottom:.5em;
  color:#fff;-webkit-text-stroke:0}
@media (max-width:767px){
  .onas-hist h1{font-size:clamp(34px,8.6vw,48px);letter-spacing:-.02em}
}
.sec h2 .brand{color:var(--red)}
h3{font-size:clamp(18px,1.6vw,22px);margin:.4em 0 .3em}
p{margin:0 0 1em}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- TŁO z mechaniką kursora ---------- */
.bg{position:fixed;inset:0;z-index:-1;pointer-events:none;background:#f5f5f5}
/* tło: WebP (890 KB PNG → 167 KB, ta sama rozdzielczość 1024²) */
.bg__base,.bg__lens{position:absolute;inset:0;background:url("assets/tlo/tlo-papier-czerpany-wykroj.webp") center/cover no-repeat}
.bg__base{opacity:.42}                         /* ściszony szkic */
.bg__lens{opacity:.95;                          /* pełny szkic tylko wokół kursora */
  -webkit-mask-image:radial-gradient(circle var(--lens-r) at var(--mx) var(--my),#000 0%,rgba(0,0,0,.55) 45%,transparent 100%);
          mask-image:radial-gradient(circle var(--lens-r) at var(--mx) var(--my),#000 0%,rgba(0,0,0,.55) 45%,transparent 100%)}
@media (prefers-reduced-motion:reduce),(pointer:coarse){
  .bg__lens{display:none}
  .bg__base{opacity:.5}                         /* statyczny, stały poziom */
}

/* ═══════════════════════════════════════════════════════════
   NEWS BAR — inspirowany Aura
   Czarny pas gruby idzie w prawo, czerwony cieńszy w lewo
   ═══════════════════════════════════════════════════════════ */
/* Ciasno pomiędzy sekcje: nad paskiem 40 px własnego marginesu, pod nim
   40 px — ale .sec zjada 94 px paddingu na górze, więc dolny margines jest
   ujemny i równa różnicę. Stąd niezgodna suma. */
.infinity-bar{position:relative;z-index:10;display:block;width:100vw;margin:40px 0 calc(40px - clamp(48px,6.5vw,96px));margin-left:calc(50% - 50vw);overflow:hidden;font-family:"Oswald","Arial Narrow",sans-serif;white-space:nowrap}
.infinity-bar__track{display:flex;flex-direction:row;flex-wrap:nowrap;width:max-content;overflow:visible}
.infinity-bar__content{display:flex;align-items:center;gap:16px;flex-shrink:0;padding:10px 0;font-size:16px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
.infinity-bar__item{flex-shrink:0}
.infinity-bar__track--black{background:#000;color:#fff;position:relative}
.infinity-bar__track--black::before{content:'';position:absolute;top:0;left:0;right:0;height:1.8px;background:var(--red)}
.infinity-bar__track--black .infinity-bar__item{color:#fff}
.infinity-bar__track--red .infinity-bar__content{padding:8.4px 0;font-size:12.6px}
.infinity-bar__track--red{background:var(--red);color:#fff}
.infinity-bar__track--black .infinity-bar__content{animation:infinity-black 20s linear infinite}
.infinity-bar__track--red .infinity-bar__content{animation:infinity-red 25s linear infinite}
.infinity-bar__dot{color:var(--red);font-size:10px}
.infinity-bar__sep{color:rgba(255,255,255,.7)}
/* Seamless loop: dwie identyczne grupy, kazda jedzie o (-100% - gap).
   Reset = start kopii, wiec nie widac przeskoku (wzorzec: ryanmulligan.dev/css-marquee). */
.infinity-bar__track{gap:16px}
.infinity-bar__group{display:flex;align-items:center;gap:16px;flex-shrink:0;animation-timing-function:linear;animation-iteration-count:infinite}
.infinity-bar__track--black .infinity-bar__group{animation-duration:20s}
.infinity-bar__track--red .infinity-bar__group{animation-duration:25s}
.infinity-bar__track--black .infinity-bar__group{animation-name:infinity-left}
.infinity-bar__track--red .infinity-bar__group{animation-name:infinity-right}
@keyframes infinity-left{from{transform:translateX(0)}to{transform:translateX(calc(-100% - 16px))}}
@keyframes infinity-right{from{transform:translateX(calc(-100% - 16px))}to{transform:translateX(0)}}
/* stare reguly content-animacji wylaczone */
.infinity-bar__track--black .infinity-bar__content,.infinity-bar__track--red .infinity-bar__content{animation:none}
@media(prefers-reduced-motion:reduce){.infinity-bar__group{animation:none}}
@media(prefers-reduced-motion:reduce){.infinity-bar__track--black,.infinity-bar__track--red{animation:none}}
/* KONFLIKT z-indexów rozstrzygnięty na korzyść kurtyny: .nav ma 2400,
   panele kurtyny 2500, .curtain-logo 2600 (dalej leci nad wszystkim).
   Powód: przy rozsuwaniu tkanina musi zasłaniać belkę — inaczej pasek
   z nawigacją wyłaniał się spod tkaniny w miejscu, gdzie powinna być kurtyna.

   UWAGA na klikalność: panele kurtyny mają pointer-events:auto i zasłaniają
   ekran. Belka jest niżej, więc w fazie ZAMKNIĘTEJ (przed rozsuwaniem) linki
   nieklikalne — .left/.right przechwytują eventy. To świadomy kompromis:
   w fazie zamkniętej kurtyna ma zakrywać belkę, więc linki odsłaniają się
   dopiero po rozsuwaniu. Nie podnosić .nav z powrotem nad 2500 bez
   jednoczesnego wyłączenia pointer-events na panelach. */
/* ══════════════════════════════════════════════════════════════
   GÓRNA BELKA — STAŁA PIGUŁKA (2026-10-05, przebudowa)
   ══════════════════════════════════════════════════════════════
   PRZED (burdel zgłoszony przez usera): belka BEZ tła + ::before scrim
   (jasny, gaśnie nad hero) + ::after płyta (TYLKO .nav-dark:hover) +
   logo w 3 wariantach (dark/light/hero) przełączanych klasą .nav-dark
   w JS → trzy stany wizualne w zależności od scrolla; logo nachodziło
   na hasło hero, limonkowy pasek wjeżdżał w logo.

   TERAZ: JEDNA forma, zero stanów.
   - ciemna pigułka #0c0f14, radius 14px, pośrodku, max-width = treść
   - padding 8px → wysokość ~54px zamiast ~150px starej belki
   - logo STAŁE jasne (.nav__logo-mark), bez przełączania
   - linki STAŁE jasne; aktywna = limonka, hover = limonka
   - bez JS, bez ::before/::after
   Referencja formy: TinyKPI nav (kage.design) — pigułka jako osobny
   obiekt unoszący się nad treścią, nie belka-pasek przez całą szerokość.
   ────────────────────────────────────────────────────────────── */
.nav{position:fixed;top:14px;left:50%;transform:translateX(-50%);
  z-index:2400;
  display:flex;align-items:center;gap:22px;
  max-width:calc(100vw - 2 * var(--pad));
  padding:6px 22px;
  background:#0c0f14;
  border:1px solid rgba(255,255,255,.10);
  border-radius:14px;
  box-shadow:0 10px 30px rgba(0,0,0,.30),0 2px 8px rgba(0,0,0,.20);
  --nav-fg:#f5f2ed; --nav-h:54px}
.nav__logo{display:block;line-height:0;flex:0 0 auto}
.nav__logo-mark{height:46px;width:auto;max-width:none;display:block}
/* linki — STAŁE jasne, bez glow zależnego od podłoża */
.nav__menu{display:flex;align-items:center;gap:28px;margin-left:auto}
.nav__links{display:flex;gap:24px;margin-left:0;
  font-family:"Oswald","Arial Narrow",sans-serif;font-weight:600;
  font-size:14px;letter-spacing:.09em;text-transform:uppercase}
.nav__links a{position:relative;text-decoration:none;color:#b9bfc7;
  padding:6px 0;transition:color .25s ease}
.nav__links a:hover,.nav__links a:focus-visible{color:var(--lime)}
.nav__links a.is-active{color:var(--lime)}
.nav__links a[aria-current="page"]{color:var(--lime)}
.nav__links a:focus-visible{outline:2px solid var(--lime);outline-offset:4px;
  border-radius:2px}
.nav__burger{display:none}
@media (max-width:1023px){
  .nav{gap:14px;padding:8px 16px}
  .nav__links{display:none}
  .nav__burger{display:flex;flex-direction:column;justify-content:center;gap:5px;
    flex:0 0 auto;margin-left:auto;
    background:none;border:0;padding:10px 6px;cursor:pointer}
  .nav__burger span{display:block;width:24px;height:2px;background:#f5f2ed;transition:background .3s}
  .nav--open{flex-wrap:wrap;border-radius:14px}
  .nav--open .nav__menu{display:flex;flex-direction:column;gap:16px;align-items:flex-start;
    width:100%;padding-top:14px;border-top:1px solid rgba(255,255,255,.12)}
  .nav--open .nav__links{display:flex;flex-direction:column;gap:14px;align-items:flex-start;font-size:16px}
  .nav--open .nav__burger span{background:#f5f2ed}
  .nav--open .nav__burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .nav--open .nav__burger span:nth-child(2){opacity:0}
  .nav--open .nav__burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}
.btn{display:inline-block;background:var(--lime);color:var(--carbon);font-weight:700;text-decoration:none;
  padding:14px 24px;border-radius:4px;font-size:16px;border:1px solid rgba(33,27,20,.15)}
.btn:hover{filter:brightness(.96)}
.btn--sm{padding:9px 16px;font-size:14px}
.link-arrow{text-decoration:none;font-weight:600;color:var(--navy);border-bottom:1px solid var(--navy-soft);padding-bottom:2px}
.link-arrow::after{content:" →"}
.link-arrow--light{color:var(--lime);border-color:rgba(196,230,0,.5)}

/* ---------- CTA w sekcji kontakt: dwa bliźniacze przyciski, CZERWONE ----------
   „Wyślij maila" (adres jako treść) → mailto = domyślny klient poczty usera.
   „Zadzwoń" (nr jako treść) → tel, widoczny tylko na mobile (<900px).
   Czerwień marki (--red) na czarnym tle kontaktu; hover rozjaśnia, nie ściemnia
   (na ciemnym tle brightness(.96) gasi przycisk). */
.btn--mail{background:var(--red);color:#fff;border-color:rgba(255,255,255,.18);
  font-family:var(--font-m);font-weight:600;letter-spacing:.02em}
.btn--mail:hover{background:#cf2f26;filter:none}
.btn--mail:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* Telefon: WIDOCZNY na PC i mobile. Czerwona obwódka + czerwony tekst na
   przezroczystym tle — odróżnia go od wypełnionego maila (bliźniaczy, nie taki sam).
   Wcześniej był display:none na PC — błędne odczytanie polecenia. */
.btn--tel{background:transparent;color:var(--red);border:2px solid var(--red)}
.btn--tel:hover{background:rgba(179,38,30,.14);color:#fff;border-color:#fff}

/* ---------- Wspólny kontener sekcji ---------- */
.sec{max-width:var(--maxw);margin:0 auto;padding:clamp(48px,6.5vw,96px) var(--pad)}
.sec__note{color:var(--ink-2);max-width:60ch;margin-top:-.4em;margin-bottom:2em}

/* ---------- ARKUSZ — jednolity filtr dla każdej grafiki ---------- */
.arkusz{position:relative;margin:0;padding:24px 18px 16px;
  background:
    repeating-linear-gradient(0deg,var(--grid) 0 1px,transparent 1px 24px),
    repeating-linear-gradient(90deg,var(--grid) 0 1px,transparent 1px 24px),
    rgba(255,255,255,.96);
  border:1px solid var(--frame);}
/* narożniki techniczne */
.arkusz::before,.arkusz::after{content:"";position:absolute;width:10px;height:10px;border:1px solid var(--navy);pointer-events:none}
.arkusz::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.arkusz::after{bottom:-1px;right:-1px;border-left:0;border-top:0}
.arkusz__nr{position:absolute;top:6px;left:10px;font:11px/1 var(--font-m);letter-spacing:.12em;text-transform:uppercase;color:var(--navy)}
.arkusz img{width:100%;filter:saturate(.55) contrast(.96);mix-blend-mode:multiply}
.arkusz__cap{margin-top:12px;font:13px/1.3 var(--font-m);letter-spacing:.06em;text-transform:uppercase;color:var(--ink);opacity:.85}
/* film w arkuszu — jak .hurtownia__foto: bez paddingu, pełna szerokość, bez filtra multiply */
.onas__film{padding:0;overflow:hidden}
.onas__film video{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;filter:none;mix-blend-mode:normal}
/* grafika bez ramki — pełna szerokość sekcji, na samym dole.
   .onas jest gridem 7fr/5fr — pasek musi wyjść poza kolumny (grid-column:1/-1). */
.onas__pasek{grid-column:1/-1;margin:32px 0 0;padding:0;width:100%;justify-self:stretch}
.onas__pasek img{display:block;width:100%;height:auto;aspect-ratio:1376/397;object-fit:cover;filter:none;mix-blend-mode:normal;border:0}
/* kafel — stały format */
.arkusz--tile img{aspect-ratio:4/3;object-fit:cover}
/* placeholder — wyraźny, jednolity */
.arkusz--ph img{aspect-ratio:3/2;object-fit:cover}
.arkusz__ph{display:none}
.arkusz--ph.is-missing img{display:none}
.arkusz--ph.is-missing .arkusz__ph{display:flex;align-items:center;justify-content:center;text-align:center;aspect-ratio:3/2;
  border:2px dashed var(--navy);font:15px/1.5 var(--font-m);letter-spacing:.08em;text-transform:uppercase;color:var(--navy);
  background:repeating-linear-gradient(135deg,rgba(22,51,121,.05) 0 8px,transparent 8px 16px)}
.arkusz__ph small{text-transform:none;letter-spacing:0;opacity:.8}

/* ---------- HERO ---------- */
.hero{position:relative;isolation:isolate;overflow:hidden;
  /* STAŁA SZEROKOŚĆ — .opening-scene .middle animuje width:0→100% na scrollu
     (view-timeline --curtain). Bez tego .hero dostawał width rosnącego tracku,
     a jego kolumny 1fr przeliczały się co klatkę: GIF (Rys. 01) i tekst opisowy
     wędrowały i rozszerzały się razem z kurtyną. Ustalona szerokość = zawartość
     stoi nieruchomo, a kurtyna odsłania ją (overflow:clip na .middle). */
  /* PEŁNA SZEROKOŚĆ (2026-10-03): film ma być full-bleed jak w referencji.
     Treść trzyma szerokość przez padding = max(gutter, (100% − maxw)/2),
     więc hasło/deska stoją w kolumnie 1280, a tło idzie od krawędzi do krawędzi. */
  width:100%;max-width:none;
  margin:0 auto;padding:24px max(var(--pad),calc(50% - var(--maxw)/2)) 48px;
  display:grid;grid-template-columns:repeat(12,1fr);column-gap:24px;align-items:center;
  min-height:100svh;
  padding-top:clamp(120px,15vh,190px)   /* nav fixed (bez tła) — hasło startuje pod belką */
  }
/* FILM jako tło — 1:1 z nagłówkiem „O nas" (.onas-hero__bg w onas.css):
   video na pełny kadr + mgła gradientem (tekst po lewej, kadr widoczny po prawej). */
.hero__bg{position:absolute;inset:0;z-index:-1;background:var(--carbon);overflow:hidden}
.hero__bg video{width:100%;height:100%;object-fit:cover;display:block}
.hero__bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(6,10,20,.88) 0%,rgba(6,10,20,.74) 42%,rgba(6,10,20,.38) 100%)}
/* UKŁAD HERO (user 2026-10-04): LEAD po lewej na całą wysokość sekcji,
   HASŁO po prawej. Zero kolumn w środku — film (kadr telefonu/wybroju)
   gra w pustej przestrzeni. */
.hero__lead{grid-column:1/6;grid-row:1;position:relative;z-index:2;
  align-self:stretch;margin:0;display:flex;flex-direction:column;justify-content:center;
  /* USER 2026-10-04: „powiększ tekst hero o 100%" → ×2 względem poprzedniego
   układu (było clamp(19px,1.55vw,27px)). */
  font-size:clamp(24px,2.35vw,40px);font-weight:500;line-height:1.42;
  color:rgba(255,255,255,.94);max-width:100%;
  padding-left:22px;
  text-shadow:0 2px 16px rgba(6,10,20,.75)}
/* LIMONKOWA LINIA LEADU — zamiast `border-left` (który się ciął twardo na
   dole sekcji). Teraz to pseudo-element z gradientem: pełna limonka u góry,
   wygaszanie do zera na 120 px nad dołem. Powód: hero i hurtownia mają ten
   sam kolor tła (#0f0f0f), więc jedynym sygnałem końca sekcji było ucięcie
   tej linii. Znikający koniec = miękkie wyjście zamiast cięcia (user 10.05). */
.hero__lead::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:linear-gradient(180deg,
    var(--lime) 0%,
    var(--lime) calc(100% - 140px),
    rgba(165,194,0,0) 100%)}
.hero__copy{grid-column:8/13;grid-row:1;position:relative;z-index:2;justify-self:end;text-align:right}
/* Arkusz krojowni (rysunek + hotspoty + callouty) wraca do swojego slotu 6/13 —
   film jest teraz tłem, nie zawartością kolumny. */
.arkusz--hero{grid-column:6/13;position:relative;z-index:2;will-change:transform,opacity}
.hero h1{font-size:clamp(64px,8.6vw,120px);font-weight:900;line-height:.92;letter-spacing:-.03em;margin-bottom:.2em;text-transform:uppercase}
/* Na filmowym tle litery są jasne (jak w .onas-hero); czerwień .brand z
   czarną obwódką — bez niej gubi się na jasnych fragmentach kadru. */
.hero h1{color:#fff;text-shadow:0 2px 18px rgba(6,10,20,.55)}
.hero h1 .brand{color:var(--red);-webkit-text-stroke:1px #000;paint-order:stroke fill}
/* sekcje na jasnym tle — bez czarnego obrysu (obrys tylko na filmowym hero) */
.sec h2 .brand{color:var(--red);-webkit-text-stroke:0}
/* cienka czarna obwódka odcina czerwone litery od jasnego tła (fallback dla przeglądarek bez text-stroke) */
@supports not (-webkit-text-stroke:1px #000){
  .hero h1 .brand{text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}
}
/* USZYJEMY — SVG path drawing (hero h1). inline-block + height .82em = mieści się w line-height .92 */
.hero__copy h1 .drawing-text{display:inline-block;vertical-align:baseline;width:auto;height:.8em;overflow:visible}
.hero__copy h1 .drawing-text .line{stroke:var(--red)}
/* Tekst opisowy — styl zdefiniowany wyżej w bloku UKŁAD HERO (lead po lewej). */
.hero__cta{display:flex;align-items:center;gap:24px;flex-wrap:wrap;margin:28px 0 22px}
.hero__fact{font:13px/1.4 var(--font-m);letter-spacing:.04em;color:var(--ink);opacity:.85;margin:0}
.hero__list{grid-column:6/13;display:none;margin:20px 0 24px;padding:0 0 0 0;list-style:none}
.hero__list li{padding:12px 0 12px 40px;border-top:1px solid rgba(22,51,121,.18);font-size:15px;position:relative;counter-increment:hl}
.hero__list li::before{content:counter(hl);position:absolute;left:0;top:12px;width:24px;height:24px;border-radius:50%;background:var(--lime);border:1px solid var(--carbon);font:700 12px/22px var(--font-m);text-align:center;color:var(--carbon)}
.hero__list{counter-reset:hl}
.hero__list::before{content:"Rys. 01 — objaśnienia punktów";display:block;font:11px/1 var(--font-m);letter-spacing:.12em;text-transform:uppercase;color:var(--navy);margin-bottom:10px}
.hero__list li .co__label{display:block;margin-bottom:4px}
html:not(.js) .hero__list{display:block}      /* bez JS lista zawsze */

/* deska: raster + overlay */
.deska{position:relative}
.deska__img{width:100%}
.deska__svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.lead{stroke:var(--navy);stroke-width:1.2;fill:none;opacity:0;  /* dasharray/offset = długość w px (JS; viewBox = px) */
  transition:stroke-dashoffset 250ms ease-out,opacity 120ms}
.lead.is-on{stroke-dashoffset:0;opacity:1}
.lead.is-off{transition:opacity 400ms;opacity:0}

.hotspots{list-style:none;margin:0;padding:0;position:absolute;inset:0;pointer-events:none}
.hs{pointer-events:auto;position:absolute;left:var(--x);top:var(--y);transform:translate(-50%,-50%);
  width:44px;height:44px;border:0;background:transparent;padding:0;cursor:pointer;border-radius:50%;display:grid;place-items:center}
.hs::before{content:"";width:12px;height:12px;border-radius:50%;background:var(--lime);border:1px solid var(--carbon);
  transition:width 160ms,height 160ms;box-shadow:0 0 0 1px rgba(255,255,255,.8)}
.hs::after{content:"";position:absolute;width:12px;height:12px;border-radius:50%;border:1px solid var(--navy);
  animation:pulse 1.8s ease-out infinite}
.deska.interacted .hs::after,.hs.is-on::after{animation:none;opacity:0}   /* pulsowanie tylko do 1. interakcji */
.hs.near::before,.hs:hover::before,.hs:focus-visible::before{width:16px;height:16px}
.hs.is-on::before{width:16px;height:16px;box-shadow:0 0 0 3px rgba(196,230,0,.35),0 0 0 1px rgba(255,255,255,.8)}
.hs.is-pinned::before{background:var(--carbon);border-color:var(--lime)}
.hs:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.hs__n{display:none;font:700 11px/1 var(--font-m);color:var(--carbon)}
@keyframes pulse{0%{transform:scale(1);opacity:.9}100%{transform:scale(3.2);opacity:0}}
@media (prefers-reduced-motion:reduce){.hs::after{animation:none;opacity:0}.lead{transition:none}.co{transition:none!important}}

.callouts{position:absolute;inset:0;pointer-events:none}
.co{position:absolute;width:15rem;max-width:44%;background:var(--paper);border:1px solid var(--navy);padding:10px 12px 8px;
  box-shadow:0 8px 24px rgba(22,51,121,.10);opacity:0;transform:translateY(8px);pointer-events:none;
  transition:opacity 250ms ease-out,transform 250ms ease-out;font-size:14px;line-height:1.4}
.co.is-on{opacity:1;transform:none}
.co.is-pinned{pointer-events:auto}
.co.is-off{transition:opacity 400ms,transform 400ms}
.co p{margin:0}
.co__label{display:inline-block;font:600 11px/1 var(--font-m);letter-spacing:.14em;text-transform:uppercase;color:var(--navy);
  margin-bottom:8px;padding:3px 6px;border:1px solid var(--navy-soft)}
.co.is-pinned .co__label{background:var(--lime);border-color:var(--lime);color:var(--carbon)}
.co[data-id="3"] .co__label{border-left:3px solid var(--orange)} /* jedyny akcent pomarańczowy — „nitka" */

/* ---------- O NAS ---------- */
.onas{display:grid;grid-template-columns:7fr 5fr;gap:48px;align-items:start}
/* Akapity „O nas" — formatowanie 1:1 z .hero__lead (wzorzec: user, 2026-09-28).
   Przejete z hero: rozmiar plynny, waga 500, interlinia 1.45, szerokosc 38ch,
   granatowa linia 2px nad tekstem + 14px odstepu od linii do tekstu.
   Kroj: Inter — tak jak w hero (decyzja usera, 2026-09-28). */
.onas__text p{font-family:"Inter","IBM Plex Mono",system-ui,sans-serif;font-weight:500;font-size:clamp(17px,1.3vw,21px);line-height:1.45;max-width:38ch;color:var(--ink);border-top:2px solid var(--navy);padding-top:14px}

/* ---------- ETAPY — jedyna sekcja na fog, ostry brzeg ---------- */
.etapy{max-width:none;background:var(--fog);border-top:1px solid var(--grid);border-bottom:1px solid var(--grid)}
.etapy>*{max-width:var(--maxw);margin-left:auto;margin-right:auto}
.etapy__list{list-style:none;padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
.etap{position:relative;padding-top:8px}
.etap .arkusz{margin:0;padding:0;overflow:hidden}
.etap .arkusz img{display:block;width:100%;height:100%;aspect-ratio:3/2;object-fit:cover;filter:none;mix-blend-mode:normal}
.etap__nr{display:block;font:12px/1 var(--font-m);letter-spacing:.14em;color:var(--navy);margin-bottom:6px}
.etap p{font-size:14px;color:var(--ink-2)}
.etap--0{display:none;}display:grid;grid-template-columns:auto 1fr;column-gap:28px;align-items:baseline}
.etap--0 .etap__nr{grid-row:1/3;font-size:28px;align-self:start;margin-top:6px}
.etap--0 p{grid-column:2;max-width:70ch;margin:0}
.etap--0 h3{color:var(--navy)}

/* ---------- HURTOWNIA BHP — przebudowa 2026-10-04 ----------
   DECYZJA: sekcja JAŚNA (jak reszta strony), BEZ kartki w kratkę.
   Kratka .arkusz = język szkicownika krawieckiego (szycie); Hurtownia to
   handel/asortyment i ten klimat jej nie przystawał.
   h2 bierze sizę z globalnej reguły h2 (jak menu i pozostałe sekcje).
   Zdjęcie lady 1376×768 (16:9) idzie POZIOMO, full-bleed pod treścią —
   poprzedni slot 656×1087 ciął je do pionowej belki (cover). */
/* TŁO SEKCJI (2026-10-04): .bg jest fixed, a jego .bg__lens ma opacity .95
   wokół kursora — szkic wykroju pojawiał się dokładnie pod tekstem i zjadał
   czytelność (potwierdzone renderem).
   Sekcja bierze TEN SAM papier, ale:
     1) pełnoszerokościowo i z własnym centrowaniem (papier w .bg jest
        position:fixed/inset:0 — w skali sekcji wyglądałby jak wklejona plama
        z twardymi krawędziami bocznymi),
     2) mocno wyciszony (krycie .10 zamiast .42+.95) = ledwo widoczny znak wodny,
     3) z miękką bielą pod tekstem (radial-gradient) dla kontrastu. */
/* FULL-BLEED: .sec ma max-width:1280 + margin:auto (pomiar: left=640 przy
   oknie 2560) — tło sekcji zawsze było wąskim pasem z twardymi krawędziami
   bocznymi, czyli „wklejona plama". Sekcja idzie do krawędzi okna, a treść
   trzyma szerokość przez padding = max(--pad, (100% − maxw)/2). */
/* ===== SEKCJA CIEMNA (2026-10-04, wariant A wybrany przez usera) =====
   Powód: w wariancie jasnym lada przy opacity .42 dawała YAVG 219/255 —
   ledwo widoczny szum, a sekcja czytała się jak pusta kartka A4.
   Teraz: granat carbon jako baza, lada jako PEŁNOPRAWNE tło (krycie .62),
   tekst biały. Kontrast biały/granat = ~11:1.
   Priorytet w tle: czytelny tekst > ostrość zdjęcia. Dlatego gradient boczny. */
.hurtownia{position:relative;isolation:isolate;max-width:none;margin:0;
  background:var(--carbon);
  padding-left:max(var(--pad),calc(50% - var(--maxw)/2));
  padding-right:max(var(--pad),calc(50% - var(--maxw)/2))}
/* PRZERWA MIĘDZY HERO A HURTOWNIĄ (user 2026-10-05). Rozsuwamy sekcje
   marginesem, żeby w luce było TŁO STRONY (papier czerpany .bg), a nie nowy
   pas granatu. Dwa błędy z drogi, nie powtarzać:
   1) padding-top na .hurtownia — przerwa dostała carbon, a strona ma własne
      tło; wyszła ciemna bandka. Ten sam efekt dawał margines na .hero.
   2) lada ::before z inset:0 — wypełniała przerwę zdjęciem, granica znikała.
      Poprawnie: margines NAD sekcją (tło strony) + lada wraca do inset:0. */
.hurtownia .sec__inner{max-width:none;margin:0}
/* TYTUŁ DWUBARWNY: `HURTOWNIA` biała, tylko `BHP` limonkowa (user: „tylko BHP
   z napisu ma być limonkowe"). W HTML `span.brand` przeniesiony na słowo BHP —
   globalne `.sec h2 .brand` daje mu wtedy kolor `--red`, który na granacie
   miał 3.1:1, więc nadpisujemy na `--lime` (9.6:1).
   UWAGA: te dwie reguły muszą być w tej kolejności — `.brand` musi wygrywać. */
.hurtownia h2{color:#fff}
.hurtownia h2 .brand{color:var(--lime)}
.hero{margin-bottom:96px}
/* lada jako tło — krycie podniesione .42 → .62, kąt z prawej */
.hurtownia::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("assets/hurtownia/lada-hurtownia.jpg") 78% 50%/cover no-repeat;
  opacity:.82}
.hurtownia::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(90deg,rgba(12,20,44,.80) 0%,rgba(12,20,44,.62) 45%,
      rgba(12,20,44,.40) 70%,rgba(12,20,44,.12) 88%,rgba(12,20,44,0) 100%),
    linear-gradient(180deg,rgba(12,20,44,.32) 0%,rgba(12,20,44,0) 34%,
      rgba(12,20,44,.32) 100%)}
.hurtownia>*{position:relative;z-index:1}

/* hasło „Nie tylko szyjemy" — osobna linia POD tytułem sekcji, monospacem
   w nawiasie, żeby było hasłem a nie konkurencyjnym nagłówkiem */
.hurtownia__haslo{margin:-.6em 0 1.8em;font-family:var(--font-m);font-weight:600;
  font-size:clamp(15px,1.2vw,19px);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.72)}

.hurtownia__lead{max-width:min(62ch,var(--maxw));margin:-.2em 0 2.4em}
.hurtownia__lead p{font-size:clamp(17px,1.35vw,21px);color:rgba(255,255,255,.88);margin:0}

/* CIEMNE TŁO (2026-10-04): nagłówki kategorii białe — na granacie granatowy
   nagłówek znikł (kontrast 1.4:1). Accent = limonkowy --lime. */
.hurtownia__h{font-family:var(--font-m);font-size:14px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:#fff;margin:0 0 .5em}

/* lista kategorii — belka górna zamiast ramki */
/* TREŚĆ MAKS. DO 1280px (padding sekcji = 640 przy oknie 2560) — dzięki temu
   trzecia kolumna kończy się na ~75% szerokości, a zdjęcie lada wchodzi
   dopiero na prawym pasie. Bez tego tekst siadał na jasnym dębie. */
.hurtownia__grid{list-style:none;padding:0;margin:0 0 0;max-width:var(--maxw);
  display:grid;grid-template-columns:repeat(3,1fr);
  /* KAFLE ZAMKNIĘTE (user 2026-10-05: „za bardzo ściana tekstu, tytuły kafli
     zlewają się z treścią"). Pomiar: tło kafla rgba(9,15,34,.48) na tle sekcji
     rgb(15,15,15) — granice boczne i dolne NIEWIDOCZNE, kafel czytał się jako
     wiszący tekst z kreską u góry. Teraz: pełne obramowanie, mocniejsze tło,
     limonkowa belka tylko górna, nagłówek własnym blokiem z oddechem. */
  gap:clamp(18px,2vw,28px) clamp(14px,1.6vw,26px)}
.hurtownia__grid > li{padding:clamp(22px,2.2vw,32px) clamp(18px,1.8vw,28px);
  border:1px solid rgba(255,255,255,.26);
  border-top:3px solid var(--lime);
  background:rgba(9,15,34,.82);
  box-shadow:0 1px 0 rgba(255,255,255,.12) inset,0 10px 26px rgba(4,8,20,.55)}
/* nagłówek kafla = osobny blok, wyraźny odstęp od treści pod nim */
.hurtownia__grid .hurtownia__h{font-size:15px;margin:0 0 .85em;
  padding-bottom:.7em;border-bottom:1px solid rgba(255,255,255,.16);
  line-height:1.35}
.hurtownia__grid p{margin:0;font-size:15.5px;line-height:1.62;color:rgba(255,255,255,.9);
  /* podbicie cieniem pod tekstem — vision zgłosił słaby kontrast drobnego druku
     w 2. i 3. kolumnie, gdzie przez gradient przechodzi rozbłysk lampy */
  text-shadow:0 1px 3px rgba(6,12,30,.9),0 0 8px rgba(6,12,30,.7)}

/* trzy fakty: PFRON wyróżniony wagą (liczba), nie kolorem belki */
/* TRZY POWODY, RÓWNA WAGA (2026-10-04, user: „procent nie wyraża o co chodzi,
   trzy sekcje gubią się w wyrazie"). Bez wyróżnionej kolumny 1.3fr i bez
   blokowej liczby — trzy karty tej samej wagi, każda z limonkową belką.
   Waga PFRON-a jest oddana TREŚCIĄ pytania w nagłówku, nie rozmiarem kolumny. */
.hurtownia__fakty{display:grid;grid-template-columns:repeat(3,1fr);max-width:var(--maxw);
  gap:clamp(20px,2.4vw,36px);margin-top:clamp(48px,6vw,88px)}
/* PANEL POD TREŚĆ, nie ciemny gradient (2026-10-04): gradient przyciemniający
   gasił ladę, a po jego rozluźnieniu kolumny 2 i 3 wpadały na jasny dąb
   (vision: „najgorzej czytają się 2 i 3"). Rozwiązanie: każdy powód dostaje
   własne półprzezroczyste tło. Zdjęcie zostaje odsłonięte dookoła. */
.hurtownia__fakt{padding:clamp(24px,2.4vw,34px) clamp(20px,2vw,28px);
  border:1px solid rgba(255,255,255,.26);
  border-top:3px solid var(--lime);
  background:rgba(9,15,34,.82);
  box-shadow:0 1px 0 rgba(255,255,255,.12) inset,0 10px 26px rgba(4,8,20,.55)}
.hurtownia__fakt p{margin:0;font-size:15.5px;line-height:1.62;color:rgba(255,255,255,.9);
}
/* nagłówek powodu = pytanie do kupującego, biały i większy niż belka kategorii */
.hurtownia__fakt .hurtownia__h{font-size:clamp(17px,1.5vw,21px);font-weight:700;
  letter-spacing:0;text-transform:none;line-height:1.28;margin-bottom:.7em}
.hurtownia__fakt p b{color:var(--lime);font-weight:700}

.hurtownia__cta{justify-self:start;display:inline-flex;align-items:center;gap:14px;
  margin-top:clamp(36px,4vw,56px);font-family:var(--font-m);font-weight:600;font-size:13px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--carbon);background:var(--lime);
  padding:18px 26px;text-decoration:none;transition:filter 160ms ease}
.hurtownia__cta:hover{filter:brightness(1.1)}
.hurtownia__cta span{color:var(--carbon);opacity:.7}
.hurtownia__cta:focus-visible{outline:2px solid var(--lime);outline-offset:3px}

/* zdjęcie lady — POZIOME, full-bleed (ujemny margin == --pad), ratio z pliku */
/* zdjęcie lady — USUNIĘTE 2026-10-04 (lada jest teraz tłem sekcji, patrz .hurtownia::before) — reguła wyłączona full-bleed na całą szerokość okna. Ujemny margin musi
   kasować własny padding sekcji (= max(--pad,(50%−maxw/2)=640px), sam --pad
   nie wystarczał — zdjęcie zostało w kontenerze 1280). */
/* UWAGA: clamp() z JEDNYM argumentem nie jest poprawnym clamp — przeglądarka
   traktuje go jako min(max(v),val), przez co margin wyszedł -64px zamiast -640px.
   Tu jawny max() bez clamp. */
.hurtownia__foto{margin-top:clamp(48px,6vw,88px);
  /* UWAGA: procentowy margin liczy się od szerokości CONTENT BOX rodzica
     (tutaj 1280, bo sekcja ma padding 640), więc `50%` dawało 640, nie 1280.
     Dlatego `margin:-max(pad, 50%−maxw/2)` dawał −64 zamiast −640.
     Pewna metoda: 100vw + przesunięcie o 50% własnej szerokości. */
  width:100vw;max-width:100vw;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
  margin-bottom:0;position:relative;overflow:hidden;background:var(--carbon)}
.hurtownia__foto img{display:block;width:100%;height:auto;aspect-ratio:1376/768;
  object-fit:cover;object-position:center;filter:none;mix-blend-mode:normal}

@media (max-width:900px){
  .hurtownia__grid{grid-template-columns:repeat(2,1fr)}
  .hurtownia__fakty{grid-template-columns:1fr}
}

/* ---------- ZASTOSOWANIA / ODZIEŻ ---------- */
/* ZASTOSOWANIA = pozioma karuzela (peel effect).
   Mechanika: natywny scroll + scroll-snap. Mobile = natywny swipe (touch),
   desktop = drag myszą + trackpad poziomy. Zero bibliotek.
   Efekt: aktywny kafel duży i jasny, sąsiedzi mniejsi i przygaszeni
   (skala/opacity/filter liczy app.js --railState), podpis wjeżdża u dołu,
   obraz ma wewnętrzny parallax (przesuwa się wolniej niż kafel).
   Pasek wychodzi poza padding .sec — kafel przy krawędzi nie ucina się. */
.branze__head{display:flex;align-items:flex-end;justify-content:space-between;
  gap:24px;flex-wrap:wrap;margin-bottom:34px}
.branze__head h2{margin:0}
.branze__meta{display:flex;align-items:baseline;gap:18px;flex:0 0 auto}
.branze__count{font-family:var(--font-m);font-size:13px;letter-spacing:.06em;color:var(--ink-2)}
.branze__count b{font-size:22px;font-weight:700;color:var(--navy)}
.branze__count i{margin:0 4px;font-style:normal;opacity:.5}
.branze__hint{font-family:var(--font-m);font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-2);display:flex;align-items:center;gap:8px}
/* strzałka-hint: dwie równoległe linie sygnalizujące ruch (czysty CSS) */
.branze__hint::after{content:"";width:26px;height:8px;
  background:linear-gradient(var(--ink-2),var(--ink-2)) left center/100% 1px no-repeat,
             linear-gradient(var(--ink-2),var(--ink-2)) left center/100% 1px no-repeat;
  background-position:0 2px,0 5px;opacity:.7}

/* Padding brzegowy ustawia app.js w px = (pasek − kafel)/2. CSS-owy %
   liczyłby się względem RODZICA (.sec), a nie pasa (który jest szerszy o ujemny
   margin) — kafel nie trafiał w środek. Bez tego paddingu pierwszy i ostatni
   kafel przyklejają się do krawędzi zamiast wyśrodkować (snap-align:center).
   Fallback: --pad, żeby przed pomiarem nie było kafla pod krawędzią. */
.branze__rail{list-style:none;
  margin:0 calc(var(--pad) * -1);
  padding:0 var(--pad) 8px;
  display:flex;gap:20px;align-items:center;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  scroll-behavior:smooth;
  scrollbar-width:thin;scrollbar-color:var(--grid) transparent}
.branze__rail:focus-visible{outline:2px solid var(--navy);outline-offset:-2px}
/* kursor chwytania na desktopie ustawia app.js (nie na touch) */
.branze__rail::-webkit-scrollbar{height:6px}
.branze__rail::-webkit-scrollbar-track{background:transparent}
.branze__rail::-webkit-scrollbar-thumb{background:var(--grid);border-radius:3px}
.branze__rail::-webkit-scrollbar-thumb:hover{background:var(--navy)}

.branze__rail > li{flex:0 0 auto;scroll-snap-align:center;
  /* sąsiedzi startują mniejsi i przygaszeni — JS nadpisuje skalę/opacity co klatkę.
     :not(.branze__spacer) — bez tego skalowane są też spacery brzegowe
     (360px → 324px) i ostatni kafel przestaje trafiać w środek ekranu. */
  transform:scale(.9);transform-origin:center center;
  transition:none;will-change:transform,opacity}
.branze__rail > li.branze__spacer{transform:none;will-change:auto}
/* DUŻY slot aktywnego kafla + kawałki sąsiadów po obu stronach (peek).
   ~38vw: na 1280 px widać ~2.7 kafla, więc „tu są jeszcze kolejne" jest czytelne. */
.branze__rail .arkusz--tile{width:clamp(360px,38vw,560px)}
.branze__rail .arkusz--tile img{aspect-ratio:3/2;object-fit:cover;display:block}
/* parallax obrazu: klipujemy ramkę, obraz przesuwa się w poziomie (JS ustawia) */
.branze__rail .arkusz--tile .arkusz__frame{overflow:hidden;position:relative;display:block}
.branze__rail .arkusz--tile img{width:112%;max-width:none;margin-left:-6%;will-change:transform}
/* podpis: wjeżdża u dołu przy aktywacji (JS dodaje .is-on) */
.branze__rail .arkusz--tile .arkusz__cap{
  transform:translateY(8px);opacity:.55;
  transition:transform .45s cubic-bezier(.2,.7,.2,1),opacity .45s ease}
.branze__rail .arkusz--tile.is-on .arkusz__cap{transform:none;opacity:1}
/* numeracja Rys. NN: mniejsza i gaszona na nieaktywnych */
.branze__rail .arkusz--tile .arkusz__nr{transition:opacity .45s ease;opacity:.6}
.branze__rail .arkusz--tile.is-on .arkusz__nr{opacity:1}
/* cienka ramka wokół aktywnego — sygnał pozycji bez strzałek */
.branze__rail .arkusz--tile::after{content:"";position:absolute;inset:-6px;
  border:2px solid var(--navy);opacity:0;transition:opacity .45s ease;pointer-events:none}
.branze__rail .arkusz--tile.is-on::after{opacity:.28}

/* Pasek postępu pod pasem */
.branze__progress{position:relative;height:2px;margin-top:34px;
  background:var(--grid);overflow:hidden}
.branze__progress span{position:absolute;inset:0 auto 0 0;width:0;
  background:var(--navy);transition:width .12s linear}

/* Galeria przewijana kółkiem myszy — brak dragu i brak kliknięć */
.branze__rail{cursor:default}

/* ---------- GALERIA — pas zdjęć, rozsuwany hoverem ----------
   Referencja: codepen.io/stefcharle/pen/Gydvbx (.item{flex:1} → :hover{flex:7},
   transition .8s). Bez ramek .arkusz: same zdjęcia, object-fit:cover.
   Full-bleed: ujemne marginy == --pad, żeby pas szedł do krawędzi okna. */
/* TYTUŁ NA GALERII — user 2026-10-05: „w prawym DOLNYM rogu, na samej
   galerii, dodaj literom obwódkę". Zamiast h2 nad pasem zdjęć (zjadł 96 px
   odstępu i pchał sekcję w dół) tytuł wchodzi DO .gal jako position:absolute.
   .gal jest pasem pełnoekranowym, więc prawy dolny róg = prawy dolny róg
   zdjęcia. Kotwica `top:14px;right:...` zamieniona na `bottom:14px`. */
.gal__label{position:absolute;bottom:14px;right:calc(var(--pad) + 2px);margin:0;z-index:2;
  /* TEN SAM rozmiar co h2 sekcji (style.css:35) — user 2026-10-05: „nie
     zmieniać wielkości czcionki i być duży". Nie clamp 13-17px tylko
     `font:inherit` + jawne wartości, bo h2 globalnie ma własny font-size. */
  font-family:inherit;font-size:clamp(44px,5.2vw,84px);font-weight:900;line-height:.95;
  letter-spacing:-.03em;text-transform:uppercase;color:#fff;
  -webkit-text-stroke:2px rgba(12,20,44,.9);
  paint-order:stroke fill;
  text-shadow:0 2px 0 rgba(12,20,44,.9),0 0 30px rgba(12,20,44,.8);
  pointer-events:none}
.odziez{position:relative;
  /* padding-top zmniejszony z clamp(48px,6.5vw,96px) na 24 px — user 2026-10-05:
     „ma za dużą przerwę do poprzedniej". Zmierzone: od dołu sekcji Branże do
     góry galerii było 85 px. Samo .sec (style.css:183) zostaje nietknięte —
     skrócona jest wyłącznie górna odstęp sekcji Galeria. */
  padding-top:24px}
/* Tytuł Galeria jest teraz na zdjęciach (.gal__label). h2 zostaje w DOM dla
   czytników i kotwic — .u-sr = wizualnie ukryty, nie display:none, bo ten
   display:none na .odziez h2 wyłączałby go też z drzewa dostępności. */
.u-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* position:relative KONIECZNE: .gal__label jest position:absolute i bez tego
   kotwiczy się do .odziez (position:relative), przez co lądował 67 px NAD
   pasem zdjęć (zmierzone: label.top 2621 vs gal.top 2688). */
.gal{list-style:none;padding:0;margin:0 calc(var(--pad) * -1);position:relative;
  display:flex;align-items:stretch;height:clamp(280px,52vh,520px);gap:0}
.gal__item{flex:1 1 0;min-width:0;overflow:hidden;transition:flex .8s ease}
.gal__item:hover,.gal__item:focus-within{flex:7 1 0}
.gal__item img{width:100%;height:100%;object-fit:cover;object-position:center;
  filter:none;mix-blend-mode:normal}
/* mobile: bez hovera — poziomy scroll natywny */
@media (max-width:760px){
  .gal{height:62vh;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none}
  .gal::-webkit-scrollbar{display:none}
  .gal__item{flex:0 0 62vw;scroll-snap-align:center}
  .gal__item:hover{flex:0 0 62vw}
}

/* ---------- KONTAKT — jedyna ciemna ---------- */
.kontakt{max-width:none;background:var(--carbon);color:#f5f5f5}
.kontakt{display:block}
.kontakt__text{max-width:none}
.kontakt h2{color:#fff}
/* na ciemnym tle --red (#b3261e) ginie — akcentem jest tu limonka (jak CTA) */
.kontakt h2 .brand{color:var(--lime)}
.kontakt p{color:rgba(244,242,238,.8)}
.kontakt__cta{display:flex;gap:24px;align-items:center;flex-wrap:wrap;margin-top:28px}
@media (min-width:900px){.kontakt{padding-left:calc((100vw - var(--maxw))/2 + var(--pad));padding-right:calc((100vw - var(--maxw))/2 + var(--pad))}}

/* ---------- STOPKA ---------- */
.foot{max-width:none;background:var(--carbon);margin:0 auto;padding:56px var(--pad) 40px;display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px;font-size:14px;color:rgba(244,242,238,.85)}
.foot>*{max-width:var(--maxw);width:100%;margin-left:auto;margin-right:auto}
.foot h4{font:600 12px/1 var(--font-m);letter-spacing:.14em;text-transform:uppercase;color:var(--lime);margin-bottom:14px}
.foot a{text-decoration:none;color:#fff}
.foot a:hover{color:var(--lime)}
/* Logo wyrównane z kaflem maila (.kontakt .btn--mail) w PRAWE OKNO przeglądarki
   (1455px). Pomiar pikselami z rzeczywistego zrzutu: kafel x=195, litera "H" w logo
   x=168 → różnica 27px. Po korekcie do 107px zmierzone w oknie Brave 1455px:
   kafel x=195, litera "H" x=189 → zostało 6px. Dociskam o 6 → 113px. */
.foot__brand{display:flex;align-items:flex-start;justify-content:flex-start;
  margin-left:113px}
.foot__brand img{width:180px;height:auto;margin-bottom:12px}
.foot p{font:14px/1.7 var(--font-m);color:rgba(244,242,238,.85);line-height:1.8}

/* .foot__ids usunięte razem z NIP/REGON ze stopki (01.10) */

/* ---------- RESPONSYWNOŚĆ ---------- */
/* ---------- MOBILE: hero (<=899px) — film jest TŁEM sekcji (jak „O nas"),
   więc na mobile nie ma już osobnego slotu na film; plansza krojowni zostaje
   w kolejności dokumentu (po haśle). ---------- */
@media (max-width:899px){
  /* plansza krojowni (rysunek + hotspoty) */
  .arkusz--hero{order:0;max-height:none;overflow:visible}
  .hero__list{order:3}
  /* Film jako tło: na wąskim ekranie mgła pionowa, żeby hasło było czytelne
     na górze kadru (1:1 z .onas-hero__bg w onas.css). */
  .hero__bg::after{background:linear-gradient(180deg,
    rgba(6,10,20,.62) 0%,rgba(6,10,20,.72) 45%,rgba(6,10,20,.88) 100%)}
  /* HERO pełny ekran na mobile (user 2026-10-05): film jest tłem sekcji, więc
     musi objąć CAŁĄ sekcję, a treść stać w jej dolnej połowie — inaczej blok
     tekstu wchodzi pod belkę i wychodzi poza kadr filmu.
     .hero{min-height:0} z ≤1023px zabijało 100svh z desktopu → film dostawał
     317 px zamiast 844. Przywracamy min-height i odsuwamy treść spod belki
     (nav zmierzone: 76 px) z bezpiecznym marginesem. */
}

@media (max-width:1023px){
  .hero{grid-template-columns:1fr;min-height:0;padding-top:28px;align-items:start}
  /* jedna kolumna: hasło najpierw, lead pod nim (kolejność w DOM: lead, copy) */
  .hero__lead,.hero__copy,.arkusz--hero,.hero__list{grid-column:1;grid-row:auto}
  .hero__lead{max-width:none;border-left:0;border-top:2px solid var(--lime);
    padding-left:0;padding-top:14px;font-size:clamp(17px,2.4vw,21px)}
  /* pionowa linia z desktopu nie ma tu sensu — układ jednokolumnowy, lead ma
     górną krawędź. Gradientowy pseudo-element wyłączamy. */
  .hero__lead::before{display:none}
  .hero__copy{margin-top:20px;text-align:left}
  .onas,.kontakt{grid-template-columns:1fr}
  .etapy__list{grid-template-columns:repeat(2,1fr)}
  .etap--0{grid-template-columns:1fr}
  .etap--0 .etap__nr{grid-row:auto}
  .etap--0 p{grid-column:1}
  .odziez__grid{grid-template-columns:repeat(3,1fr)}
  .nav__links{display:none}
  .callouts{display:none}
  .hero__list{display:block}
  /* Mobile: przyciski CTA w stosie symetrycznie — oba na pełną szerokość,
     równy rozstaw. Telefon jest teraz widoczny też na PC (patrz .btn--tel). */
  .kontakt__cta{flex-direction:column;align-items:stretch;gap:12px}
  .kontakt__cta .btn{display:block;text-align:center}
}
/* HERO — kolejność u góry pod belką (user 2026-10-05): TEKST → zielona linia →
   tytuł (hasło). Wcześniej `align-content:end` kładło blok na dole, a
   zielona linia była NAD tekstem (`border-top` na .hero__lead). Teraz:
   lead → `border-bottom` jako separator → hasło, całość pod belką.
   Film nadal objąca całą sekcję (`min-height:100svh`, tło `.hero__bg` inset:0).
   Reguła MUSI być po bloku ≤1023px, inaczej kaskada ją nadpisuje.
   Nav zmierzony na 390 px = 76 px. */
@media (max-width:1023px){
  .hero{min-height:100svh;align-content:start;
    padding-top:calc(76px + 20px);padding-bottom:clamp(28px,7vh,56px)}
  .hero__lead{border-top:0;border-bottom:2px solid var(--lime);
    padding-top:0;padding-bottom:18px;margin-bottom:22px}
}
/* GALERIA — mobile (user 2026-10-05): kafle były 62vw × 62vh z cover, więc na
   390 px widać było obcięty środek jednej fotografii, a poziomy scroll nie
   dawał „wysunięcia na pierwszy plan" (desktop ma je przez hover `flex:7`,
   mobile nie ma). Teraz: kafel szeroki, wysokość = propor fotografii (zmierzone
   800×597), `object-fit:contain` → CAŁA fotografia w kadrze, snap co kafel.
   Wysokość musi być `auto` — inaczej 62vh kontenera zostawiałby litry pustki. */
@media (max-width:760px){
  .gal{height:auto;align-items:stretch}
  .gal__item{flex:0 0 88vw}
  .gal__item:hover,.gal__item:focus-within{flex:0 0 88vw}
  .gal__item img{height:auto;aspect-ratio:800/597;object-fit:contain}
}
@media (max-width:599px){
  /* MOBILE: rysunek statyczny, bez interakcji i bez listy 01-04 (decyzja usera 2026-09-16) */
  .arkusz--hero{order:0;max-height:none;overflow:visible}
  .hero__list{display:none!important}
  .callouts,.deska__svg,.hotspots{display:none!important}
  .hero__list::before{content:none}
  .arkusz--hero .arkusz__nr,.arkusz--hero .arkusz__cap{display:none}
  .hero h1{font-size:clamp(44px,13vw,60px);letter-spacing:-.02em}
  h2{font-size:clamp(34px,8.6vw,48px);letter-spacing:-.02em}
  .hero__lead{font-size:clamp(16px,4.6vw,20px)}
  .hero__fact{font-size:14px;letter-spacing:.02em}
  .odziez__grid,.etapy__list{grid-template-columns:1fr 1fr}
  /* HURTOWNIA — mobile */
  .hurtownia__grid{grid-template-columns:1fr}
  .hurtownia__fakty{grid-template-columns:1fr}
  .hurtownia__cta{width:100%;justify-content:center}
  /* Pasek branżowy na mobile: kafel ~78vw, snap co kafel = klasyczny swipe */
  .branze__rail{gap:16px;scroll-padding-left:var(--pad)}
  .branze__rail .arkusz--tile{width:78vw;max-width:340px}
  .branze__rail .arkusz--tile img{aspect-ratio:3/4}  /* pionowe kadry czytelniejsze na telefonie */
  .sec__hint{margin-bottom:14px}
  /* STOPKA mobile (user 2026-10-05): `1fr 1fr` z biurka zostawiało logo
     wciśnięte w kolumnę 128 px OBOK kolumny „Kontakt" — logo i tekst nachodziły
     na siebie i nie było na swoim miejscu. Na telefonie: jedna kolumna,
     logo pełną szerokością u góry (szerokość z aspect-ratio z HTML: 2531×1250),
     potem kolumny treści pod nim, wszystko do lewej. */
  .foot{grid-template-columns:1fr;gap:28px;padding:44px var(--pad) 36px}
  /* `.foot>*{margin-left:auto;margin-right:auto}` z desktopu centruje kolumny,
     ale sam logo (flex) wychodził na left:133 przy kolumnach na left:20 —
     nierówna lewa krawędź. Mobile: wszystko do lewej, jeden flush. */
  .foot>*{margin-left:0;margin-right:0}
  .foot__brand{justify-content:flex-start;margin-bottom:4px}
  .foot__brand img{width:min(100%,220px);height:auto;margin-bottom:0}
  .nav{gap:12px}
  .nav__logo img{height:52px;width:auto}
}
@media (max-width:420px){.odziez__grid,.etapy__list{grid-template-columns:1fr}}

/* ═══════════════════════════════════════════════════════════
   OPENING SCENE — kurtyna otwierająca stronę (CodePen WbpOOBZ)
   Mechanika 1:1 z pena: scena 200dvh + sticky #grid 100dvh,
   grid-template-columns 1fr 0fr 1fr → 0fr 1fr 0fr sterowane
   scrollem. Zero JS. W .middle tylko nav+hero; reszta strony
   płynie po scenie (jak .spacer w źródle).
   Timeline: named view-timeline sceny, zakres contain = dokładnie
   runway 100dvh (scena-height − viewport-height), niezależnie od
   długości strony (scroll() root padałby na długiej stronie).
   Panele = granat marki (--navy, zmierzony z logo).
   Bez wsparcia animation-timeline (Firefox): animation biegnie na
   zegarze (1 ms) i kończy się na stanie otwartym — treść dostępna.
   ═══════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════
   HERO — dawna scena otwarcia (kurtyna scroll-driven, view-timeline
   --curtain, sticky #grid, panele Verlet) USUNIĘTA 2026-10-03.
   Otwarcie robi teraz PRELOADER (czasowy, na load) — patrz .preloader.
   Ta sekcja to zwykły, pełnoekranowy hero: film tło + hasło + deska.
   Bez sticky i bez pointer-events:none — nic już nie zasłania treści.
   ═══════════════════════════════════════════════════════════ */
.opening-scene{position:relative;width:100%}
#grid{position:relative;display:block;width:100%}
/* KURTYNA SCROLLOWA — USUNIĘTA 2026-10-03 (Voytek, zielone światło).
   W tym pliku nie szukaj już: .opening-scene .left/.right, @keyframes
   panels/open/lampBreath/logoMove/logoOut, .lamp-beam, .curtain-logo.
   Mechanika (panele + view-timeline --curtain + sticky #grid) odeszła na
   rzecz CZASOWEGO preloadera (.preloader). Pomiar przed usunięciem: panele
   i .curtain-logo = 0 w DOM, #grid position:relative (nie sticky),
   view-timeline-name:none, animation-timeline:auto → bramka w app.js nigdy
   nie włączyła gateOn(). Nic nie było żywe — usunięcie bez zmian wizualnych.
   .opening-scene i #grid ZOSTAJĄ jako kontener hero (hero w #grid > .middle).
   USUNIĘTE z #grid: `overflow:hidden` — wstawione było, „żeby hero wystawał
   zza kurtyny" (komentarz przy linii 302). Kurtyny nie ma, więc cięcie było
   reliktem; po zdjęciu brak zmian wizualnych (pomiar + akceptacja Voytka
   na 8661). Przywrócenie: dopisz `overflow:hidden` do #grid niżej. */



/* ============================================================
   STRONA „SZYJEMY" (src/szyjemy.html) — sekcja w budowie.
   Docelowo: panel kont klienta + baza wzorów. Na razie strona
   informacyjna z wezwaniem do kontaktu.
   ============================================================ */
.budowa{max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
/* Belka jest position:fixed (83px desktop / 65px mobile), więc treść musi
   mieć padding, inaczej chowa się pod nią. Definicja jak w onas.css. */
.page-szyjemy{--nav-h:83px}
.budowa-hero{padding:calc(var(--nav-h) + 72px) 0 64px;text-align:left}
.budowa-hero__eyebrow{font:600 13px/1 var(--font-m);letter-spacing:.16em;
  text-transform:uppercase;color:var(--lime);margin-bottom:20px}
.budowa-hero h1{font:var(--font-d);font-size:clamp(38px,5.4vw,76px);line-height:1.02;
  letter-spacing:-.015em;margin:0 0 24px}
.budowa-hero h1 .brand{color:var(--red)}
.budowa-hero__lead{font:400 clamp(17px,1.35vw,21px)/1.62 var(--font-m);
  color:var(--ink-2);max-width:52ch;margin:0}
.budowa-sec{padding:72px 0}
.budowa-sec h2{font:var(--font-d);font-size:clamp(28px,3.1vw,42px);line-height:1.08;
  margin:0 0 44px}
.budowa-sec h2 .brand{color:var(--red)}
.budowa__grid{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
.budowa__karta{border-top:2px solid var(--carbon);padding-top:18px}
.budowa__karta h3{font:600 15px/1.25 var(--font-m);letter-spacing:.04em;
  text-transform:uppercase;margin:0 0 10px}
.budowa__karta p{font:400 15px/1.66 var(--font-m);color:var(--ink-2);margin:0}
@media (max-width:899px){
  .budowa__grid{grid-template-columns:repeat(2,1fr)}
  .page-szyjemy{--nav-h:65px}
  .budowa-hero{padding-top:calc(var(--nav-h) + 48px)}
}
@media (max-width:599px){
  .budowa__grid{grid-template-columns:1fr}
  .budowa-sec{padding:56px 0}
}

/* ============================================================
   T4 POLISH — pojawianie się tekstu „słowo po słowie" + rozmycie
   Mechanika przeniesiona z aura-ai-landing-29.aura.build (szlif, nie paleta).
   Spec: docs/etap3/AURA-SZLIF-SPEC.md §1.
   Klasę .w-anim dodaje WYŁĄCZNIE JS — bez JS tekst zostaje normalnie widoczny
   (żadnego ukrytego nagłówka przy awarii skryptu).
   ============================================================ */
.w-anim{display:inline-block;opacity:0;filter:blur(8px);transform:translateY(16px);
  animation:wordIn .8s cubic-bezier(.22,1,.36,1) forwards}
@keyframes wordIn{to{opacity:1;filter:blur(0);transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){
  .w-anim{animation:none;opacity:1;filter:none;transform:none}
}

/* ═══════════════════════════════════════════════════════════
   PRELOADER / APERTURA (decyzja usera 2026-10-03, ref. voyeurverite.com)
   Czasowy, na load (nie scroll-driven). Sekwencja:
     1) ukośny czerwony panel + szczelina 212×16 z paskiem + licznik 001→100
     2) panel rozstępuje się (blinds góra/dół) → odsłania GRAFIKĘ (igła i nitka)
     3) grafika kolapsuje do linii → odsłania HERO
   JS: app.js (blok PRELOADER). Klasy: .is-open / .is-revealing / .is-done.
   z-index 3000 — nad belką (2400): w trakcie ładowania kurtyna zasłania belkę.
   ═══════════════════════════════════════════════════════════ */
.preloader{position:fixed;inset:0;z-index:3000;pointer-events:none}
.preloader.is-done{display:none}
.preloader__graphic{position:absolute;inset:0;
  width:100%;height:100%;object-fit:contain;background:#0b0b0c;
  clip-path:inset(0 0 0 0);opacity:1;
  transition:clip-path .95s cubic-bezier(.77,0,.175,1),opacity .95s cubic-bezier(.77,0,.175,1)}
.preloader.is-revealing .preloader__graphic{clip-path:inset(50% 0 50% 0);opacity:0}
.preloader__curtain{position:absolute;inset:0;transform:rotate(-10deg) scale(1.55);transform-origin:50% 50%}
.preloader__top,.preloader__bot{position:absolute;left:0;width:100%;height:50%;
  background:linear-gradient(120deg,#c40016 0%,var(--red) 55%,#5e0009 100%);
  transition:transform 1s cubic-bezier(.77,0,.175,1)}
.preloader__top{top:0}
.preloader__bot{bottom:0}
.preloader.is-open .preloader__top{transform:translateY(-101%)}
.preloader.is-open .preloader__bot{transform:translateY(101%)}
.preloader__slit{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:212px;height:16px;background:#2a0004;overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.35),0 0 34px 10px rgba(0,0,0,.35);
  transition:opacity .3s linear}
.preloader.is-open .preloader__slit{opacity:0}
.preloader__slit span{position:absolute;inset:0;display:block;width:0%;background:#efeae3}
.preloader__meta{position:absolute;left:50%;top:50%;transform:translate(-50%,calc(-50% + 40px));
  display:flex;gap:1rem;font-family:var(--font-m);font-size:12px;letter-spacing:.2em;
  text-transform:uppercase;color:#f0d7d9;transition:opacity .3s linear}
.preloader.is-open .preloader__meta{opacity:0}
@media (prefers-reduced-motion:reduce){ .preloader{display:none} }
