/* Fonty hostowane lokalnie (wczesniej Google Fonts): Sora i JetBrains Mono,
   pliki zmiennej grubosci, podzbiory latin i latin-ext jak w Google Fonts.
   Dwa pliki Sory sa preloadowane w <head> kazdej strony. */
@font-face{font-family:'Sora';font-style:normal;font-weight:100 800;font-display:swap;src:url(/assets/fonts/sora-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Sora';font-style:normal;font-weight:100 800;font-display:swap;src:url(/assets/fonts/sora-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:100 800;font-display:swap;src:url(/assets/fonts/jetbrains-mono-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:100 800;font-display:swap;src:url(/assets/fonts/jetbrains-mono-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/* ═══════════════ ZORNA × ONE — jedno ujecie ═══════════════
   Osobny arkusz tylko dla tej podstrony (nie dolacza css/style.css ani
   css/podstrona.css - uklad "sceny" jest na tyle wlasny, ze wspolne klasy
   (np. .media, .hero-word) mogłyby kolidowac z nazwami tutaj). Tokeny
   kolorow sa skopiowane 1:1 z css/style.css, zeby paleta zostala identyczna.

   Bez JS / z prefers-reduced-motion strona jest zwyklym, czytelnym dokumentem
   w normalnym przeplywie (patrz komentarz przy html.is-motion nizej) - caly
   uklad "warstwy absolutne + przypiecia" wlacza sie WYLACZNIE pod ta klasa,
   ktora js/one.js dokleja tylko gdy GSAP + ScrollTrigger sa zaladowane i nie
   ma reduced-motion. */

:root{
  --bg:#050607;
  --ink:#eef0f2;
  --mut:#9aa0a6;
  --dim:#7c8288;
  --faint:#565f66;
  --line:rgba(255,255,255,.08);
  --line2:rgba(255,255,255,.16);
  --rec:#e5484d;
  --ease:cubic-bezier(.2,.8,.2,1);
  --font:'Sora',sans-serif;
  --mono:'JetBrains Mono',monospace;
  --kadr-w:36vw;
  --montaz-head:140px;
}
@media (max-width:768px){ :root{ --kadr-w:72vw; --montaz-head:56px; --mob-ws:88vw; } }

*,*::before,*::after{box-sizing:border-box}
html{scrollbar-width:thin;scrollbar-color:#2a2e32 var(--bg)}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-stopped{overflow:hidden}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font);font-weight:300;overflow-x:clip;min-height:100dvh;
}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4,h5,p{margin:0}
button{font-family:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
::selection{background:var(--ink);color:var(--bg)}
img,video{max-width:100%;display:block}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
html.on-light :focus-visible{outline-color:#050607}

.sec-label{font:400 11px var(--mono);letter-spacing:.22em;text-transform:uppercase;color:var(--dim)}
#stykowka .sec-label{color:#5a6168}

.pill{
  display:inline-flex;align-items:center;gap:6px;
  font:400 12px var(--mono);letter-spacing:.16em;text-transform:uppercase;
  padding:14px 28px;border-radius:999px;transition:translate .3s var(--ease),box-shadow .3s,background .3s;
}
.pill-light{color:#050607;background:var(--ink)}
.pill-light:hover{translate:0 -3px;box-shadow:0 14px 40px -14px rgba(255,255,255,.3)}
.pill-outline{box-shadow:inset 0 0 0 1px rgba(255,255,255,.32)}
.pill-outline:hover{box-shadow:inset 0 0 0 1px #fff;background:rgba(255,255,255,.06)}

/* ═══════════════ ZIARNO ═══════════════ */
#grain{
  position:fixed;inset:0;z-index:850;pointer-events:none;
  opacity:.07;mix-blend-mode:overlay;
  background-repeat:repeat;background-size:180px 180px;
}
html.on-light #grain{opacity:.05}

/* ═══════════════ KURSOR AUTOFOKUS ═══════════════
   cursor:none tylko na glownych kontenerach strony (main, header, footer),
   NIGDY na body/*: gdyby objal caly dokument, przykrylby tez host widgetu
   asystenta (wstrzykiwany osobnym skryptem poza ta strona) i ukrylby jego
   systemowy kursor tam, gdzie nasz wlasny kursor juz nie siega (np. wewnatrz
   iframe widgetu, ktorego DOM nie jest nasz). */
html.has-cursor main,html.has-cursor #site-header,html.has-cursor footer{cursor:none!important}
/* Centrowanie WYLACZNIE przez GSAP xPercent:-50/yPercent:-50 (ustawione raz
   w js/one.js), nie przez ujemne marginesy: przy zmianie width/height (najazd
   na link, wejscie w lupe) procentowe centrowanie samo przelicza sie
   poprawnie, a stale marginesy trzeba by osobno przeliczac dla kazdego
   rozmiaru. */
#af-cursor{
  position:fixed;top:0;left:0;z-index:950;pointer-events:none;
  width:26px;height:26px;
  mix-blend-mode:difference;opacity:0;transition:opacity .25s,width .35s var(--ease),height .35s var(--ease);
  will-change:transform;
}
html.has-cursor #af-cursor{opacity:1}
#af-cursor i{position:absolute;width:8px;height:8px;border:1.5px solid var(--ink)}
#af-cursor i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
#af-cursor i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
#af-cursor i:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
#af-cursor i:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}
#af-cursor .af-tag{
  position:absolute;top:-16px;left:0;font:400 9px var(--mono);letter-spacing:.12em;
  color:var(--ink);opacity:0;
}
#af-cursor.is-target .af-tag{opacity:1}
#af-cursor.is-loupe{width:180px;height:180px;mix-blend-mode:normal;border-radius:50%;background:#0b0d0f;box-shadow:0 0 0 2px var(--ink),0 20px 50px -20px rgba(0,0,0,.6);background-size:cover;background-repeat:no-repeat}
#af-cursor.is-loupe i{display:none}
#af-cursor .loupe-tag{position:absolute;inset:0;display:none;align-items:center;justify-content:center;font:400 11px var(--mono);letter-spacing:.2em;color:var(--dim)}
#af-cursor.is-loupe .loupe-tag.is-empty{display:flex}

/* ═══════════════ HUD ═══════════════
   Bez GSAP/z reduced-motion (html.reduced, patrz initReducedFallback w
   js/one.js) HUD i blysk klapsa nie maja sensu bez sterujacej ich osi scrolla
   - zostalyby jako statyczny, nigdy-nie-aktualizowany STBY. */
html.reduced #hud,html.reduced .blysk{display:none}
#hud{position:fixed;inset:0;z-index:820;pointer-events:none}
/* Kazdy naroznik rysowany dwoma paskami POZYCJONOWANYMI wprost (top/left/
   right/bottom), bez transform:scaleX(-1)/scale(-1,-1) do "lustrzanego
   odbicia" - inaczej GSAP-owy tween "scale" (wejscie HUD w initHeroIntro)
   nadpisuje CALY transform i gubi to odbicie (patrz poprawka #18). */
.hud-corner{position:absolute;width:28px;height:28px;opacity:.7}
.hud-corner i{position:absolute;background:var(--ink)}
.hud-corner.tl{left:18px;top:18px}
.hud-corner.tl i:first-child{top:0;left:0;width:100%;height:1.5px}
.hud-corner.tl i:last-child{top:0;left:0;width:1.5px;height:100%}
.hud-corner.tr{right:18px;top:18px}
.hud-corner.tr i:first-child{top:0;right:0;width:100%;height:1.5px}
.hud-corner.tr i:last-child{top:0;right:0;width:1.5px;height:100%}
.hud-corner.bl{left:18px;bottom:18px}
.hud-corner.bl i:first-child{bottom:0;left:0;width:100%;height:1.5px}
.hud-corner.bl i:last-child{bottom:0;left:0;width:1.5px;height:100%}
.hud-corner.br{right:18px;bottom:18px}
.hud-corner.br i:first-child{bottom:0;right:0;width:100%;height:1.5px}
.hud-corner.br i:last-child{bottom:0;right:0;width:1.5px;height:100%}
html.on-light .hud-corner i{background:#050607}

.hud-status{
  position:absolute;left:18px;bottom:22px;display:flex;align-items:center;gap:8px;
  font:400 11px var(--mono);letter-spacing:.14em;color:var(--mut);
}
html.on-light .hud-status{color:#5a6168}
.status-dot{width:7px;height:7px;border-radius:50%;box-shadow:inset 0 0 0 1.3px var(--mut);flex:none}
.hud-status.is-rec .status-dot{background:var(--rec);box-shadow:none;animation:hudRec 1.1s ease-in-out infinite}
.hud-status.is-standby .status-tc{animation:hudStandby 1.6s ease-in-out infinite}
.hud-status.is-cut .status-dot{background:var(--faint);box-shadow:none}
.status-tc{font-variant-numeric:tabular-nums}
@keyframes hudRec{0%,100%{opacity:1}50%{opacity:.25}}
@keyframes hudStandby{0%,100%{opacity:1}50%{opacity:.35}}

.hud-scene{
  position:absolute;left:50%;bottom:22px;transform:translateX(-50%);
  font:400 11px var(--mono);letter-spacing:.14em;color:var(--dim);white-space:nowrap;
}
html.on-light .hud-scene{color:#5a6168}
.hud-progress{position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--line2)}
html.on-light .hud-progress{background:rgba(5,6,7,.16)}
.hud-tick{position:absolute;top:-2px;width:1px;height:5px;background:var(--line2)}
.hud-playhead{position:absolute;top:-4px;width:2px;height:9px;background:var(--rec);transform:translateX(-1px)}
.hud-reticle{
  position:absolute;top:50%;left:50%;width:22px;height:22px;margin:-11px 0 0 -11px;opacity:0;
}
.hud-reticle i{position:absolute;background:rgba(238,240,242,.6)}
.hud-reticle i:first-child{left:50%;top:0;width:1px;height:100%;margin-left:-.5px}
.hud-reticle i:last-child{top:50%;left:0;height:1px;width:100%;margin-top:-.5px}

@media (max-width:768px){
  .hud-corner{width:18px;height:18px}
  .hud-corner.tr,.hud-corner.tl{top:10px}
  .hud-corner.bl,.hud-corner.br{bottom:10px}
  .hud-corner.tl,.hud-corner.bl{left:10px}
  .hud-corner.tr,.hud-corner.br{right:10px}
  .hud-status{left:10px;bottom:16px}
  .hud-scene{display:none}
  .hud-reticle{display:none}
}

/* ═══════════════ NAGLOWEK ═══════════════ */
#site-header{
  position:fixed;top:0;left:0;right:0;z-index:800;
  display:flex;align-items:center;justify-content:space-between;
  padding:18px 40px;background:linear-gradient(rgba(5,6,7,.85),rgba(5,6,7,0));
  will-change:transform;
}
.site-lockup{display:flex;align-items:center;gap:10px}
.site-lockup img{width:30px;height:30px;object-fit:contain;filter:drop-shadow(0 0 8px rgba(255,255,255,.16))}
.site-lockup .lk-zorna{font:400 18px var(--font)}
.site-lockup .lk-x{font:400 13px var(--mono);color:var(--dim)}
.site-lockup .lk-one-glyph{width:12px;height:auto;color:var(--ink)}
.site-lockup .lk-one{font:600 18px var(--font);letter-spacing:.04em}
.site-nav{display:flex;align-items:center;gap:26px}
.site-nav a:not(.pill){font:400 12px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--mut);transition:color .25s}
.site-nav a:not(.pill):hover{color:var(--ink)}
.cta-short{display:none}
@media (max-width:768px){
  #site-header{padding:14px 18px}
  .site-nav .site-link{display:none}
  .cta-full{display:none}
  .cta-short{display:inline}
  .site-lockup .lk-zorna,.site-lockup .lk-one{font-size:15px}
}

/* ═══════════════ PRELOADER (LEADER) ═══════════════ */
#preloader{
  position:fixed;inset:0;z-index:1000;background:#050607;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;
}
.leader-circle{position:relative;width:220px;height:220px;flex:none}
.leader-ring{position:absolute;inset:0;border-radius:50%;border:1px solid var(--line2)}
.leader-ring.is-inner{inset:14px}
.leader-cross i{position:absolute;background:var(--line2)}
.leader-cross i:first-child{left:50%;top:0;width:1px;height:100%;margin-left:-.5px}
.leader-cross i:last-child{top:50%;left:0;height:1px;width:100%;margin-top:-.5px}
@property --zang{syntax:'<angle>';inherits:false;initial-value:0deg}
.leader-sweep{
  position:absolute;inset:0;border-radius:50%;background:rgba(238,240,242,.08);
  -webkit-mask:conic-gradient(from -90deg,#000 var(--zang),transparent 0);
  mask:conic-gradient(from -90deg,#000 var(--zang),transparent 0);
}
.leader-num,.leader-glyph{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font:200 120px var(--font);color:var(--ink);opacity:0;
}
.leader-glyph svg{height:110px;width:auto;color:var(--ink)}
/* Pozycja (translateX) liczona i animowana w js/one.js (positionLeaderLockup)
   razem z przesunieciem .leader-circle w prawo - poprawka #3, runda 3: caly
   lockup (logo + x + kolo) ma sie wysrodkowac jako JEDNA calosc, wiec samo
   umieszczenie reveal wzgledem NIERUCHOMEGO kola juz nie wystarcza (logo
   nachodzilo na krawedz kola). top:50% zostaje w CSS, left tez - x dochodzi
   z GSAP. */
.leader-reveal{
  position:absolute;left:50%;top:50%;
  display:flex;align-items:center;gap:20px;opacity:0;
  transform:translateY(-50%);
}
.leader-reveal img{width:64px;height:64px;object-fit:contain}
.leader-reveal .lr-x{font:400 20px var(--mono);color:var(--dim)}
.leader-caption{font:400 11px var(--mono);letter-spacing:.16em;color:var(--dim);opacity:0}
.leader-skip{position:absolute;bottom:26px;font:400 10px var(--mono);letter-spacing:.14em;color:var(--dim);padding:0 20px;text-align:center}

@media (max-width:400px){
  .leader-circle{width:170px;height:170px}
  .leader-num,.leader-glyph{font-size:86px}
  .leader-glyph svg{height:78px}
  .leader-reveal{gap:12px}
  .leader-reveal img{width:40px;height:40px}
  .leader-reveal .lr-x{font-size:15px}
}

/* ═══════════════ ZAKRES SCENY (poza html.is-motion: dokument normalny) ═══════════════ */
main{padding-top:78px}
#scena{position:relative;display:flex;flex-direction:column;gap:0}
.scena-fade{display:none}

/* -- hero-tekst: PIERWSZY w DOM (przed .oglos), zeby poza is-motion H1 szedl
   przed H2 ogloszenia; pozycjonowanie pod is-motion i tak jest absolutne. -- */
.hero-tekst{
  position:relative;padding:64px 6vw 48px;display:flex;flex-direction:column;gap:22px;
  max-width:920px;
}
/* .hero-intro: wrapper (wystepuje 2x w DOM, ta sama klasa) wokol
   hero-eyebrow oraz hero-lead/hero-cta-row/hero-hint - WYLACZNIE ten
   wrapper dotyka initHeroIntro (wejscie na starcie), scrub (initScena)
   animuje bezposrednio elementy w srodku. Dwa rozlaczne cele tweenow na
   dwoch rozlacznych elementach, zeby WebKit nie mogl po powrocie do u=0
   przypadkiem odczytac/przywrocic stanu poczatkowego intro (poprawka
   WebKit, iPhone 13). display:flex + ten sam gap co .hero-tekst, zeby
   wstawienie wrappera nie zmienilo odstepow wizualnie. */
.hero-intro{display:flex;flex-direction:column;align-items:flex-start;gap:22px}
.hero-eyebrow{font:400 11px var(--mono);letter-spacing:.22em;text-transform:uppercase;color:var(--dim)}
.hero-h1{
  font:200 clamp(64px,12.2vw,190px)/.92 var(--font);letter-spacing:-.04em;
  mix-blend-mode:difference;color:var(--ink);
}
.h1-line{display:block;overflow:hidden}
.ch-mask{display:inline-block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em;vertical-align:top}
.ch{display:inline-block;will-change:transform}
.hero-lead{font:300 clamp(15px,1.6vw,19px)/1.6 var(--font);color:var(--mut);max-width:56ch;text-shadow:0 1px 14px rgba(0,0,0,.6)}
/* przyciemnienie miedzy tasma (kadr 01 pod spodem) a tekstem hero - bez tego
   lead ginal na jasnych fragmentach wideo (poprawka #4, runda 2). Poza
   is-motion nie wystepuje (dokument plynie normalnie, tekst nie stoi na
   wideo). z-index:2 siedzi miedzy .tasma (auto) a .hero-tekst (5). */
.hero-scrim{display:none}
.hero-cta-row{display:flex;flex-wrap:wrap;gap:16px;margin-top:6px}
.hero-hint{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:20px;color:var(--dim)}
.hero-hint>span:first-child{font:400 10px var(--mono);letter-spacing:.2em;text-transform:uppercase}
.hero-hint-line{width:1px;height:30px;background:var(--line2);overflow:hidden;position:relative}
.hero-hint-line span{position:absolute;left:0;top:0;width:1px;height:12px;background:var(--ink);animation:hintPulse 2s ease-in-out infinite}
@keyframes hintPulse{0%{transform:translateY(-14px)}70%,100%{transform:translateY(36px)}}
@media (max-width:768px){
  /* runda MOBILE #4: mix-blend-mode:difference kosztuje wiecej na slabszym
     GPU telefonow i jest mniej widoczne na malym ekranie - zwykly kolor. */
  .hero-h1{font-size:16vw;mix-blend-mode:normal}
}
@media (max-width:400px){
  .hero-tekst{gap:14px;padding:56px 5vw 32px}
  .hero-intro{gap:14px}
  .hero-lead{font-size:14.5px}
  .hero-cta-row{gap:10px}
  .pill{padding:12px 20px;font-size:11px}
  .hero-hint{margin-top:10px}
}

/* -- tasma: bez JS/motion to poziomy przewijalny pasek -- */
.tasma{position:relative;padding:20px 0;background:#101316;overflow-x:auto;-webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
/* position:relative jest tu celowe (nie tylko kosmetyczne): dzieki temu
   .tasma-row jest prawidlowym offsetParent-em w lancuchu od .kadr w gore
   (przez pozycjonowane .tasma-frames), wiec js/one.js moze policzyc pozycje
   kadru WZGLEDEM WLASNEGO pudelka rzedu (offsetLeft/offsetTop), zamiast
   przypadkowo trafiac na dalszego przodka. Patrz geometriaTasmy() w js/one.js. */
.tasma-row{position:relative;display:flex;flex-direction:column;width:max-content;margin:0 auto}
.tasma-perf{height:8px;background:repeating-linear-gradient(90deg,rgba(238,240,242,.85) 0 6px,transparent 6px 20px)}
.tasma-frames{position:relative;display:flex;align-items:flex-start;gap:14px;padding:14px 24px}
.kadr-wrap{flex:none;width:var(--kadr-w);display:flex;flex-direction:column;gap:6px;scroll-snap-align:center}
.kadr{position:relative;width:100%;aspect-ratio:16/9;border-radius:4px;overflow:hidden;background:#14171a}
.kadr img,.kadr video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Runda MOBILE 2, punkt 3: przyciemnianie kadru na telefonie NIE przez
   filter:brightness() (kosztowne, przemalowuje cala warstwe co klatke), tylko
   przez taka nakladke z opacity (--kadr-dim ustawiane w js/one.js,
   tasmaTickMobile) - tansze, w pelni kompozytowane przez GPU. Regula
   scelowo TYLKO pod (max-width:768px): desktop dalej uzywa filter (bez
   zmian) i nie zalezy od tej wlasciwosci calkiem, nawet gdyby jej wartosc
   zostala przypadkiem gdzies ustawiona (np. przy live-resize przez breakpoint). */
@media (max-width:768px){
  html.is-motion .kadr::after{
    content:'';position:absolute;inset:0;background:#000;pointer-events:none;
    opacity:var(--kadr-dim,0);
  }
}
.kadr-meta{position:relative;display:flex;flex-direction:column;gap:2px;text-align:center}
.kadr-code,.kadr-caption{font:400 10px var(--mono);letter-spacing:.06em;color:rgba(238,240,242,.5)}
.kadr-caption{color:var(--mut)}
@media (max-width:768px){
  /* Runda MOBILE 2, punkt 1: "podpis biezacego kadru" przenosi sie do
     wspolnej strefy podpisu (.mob-caption); kod krawedziowy (ONE 25P ▸ 01)
     zostaje NA tasmie, w normalnym rozmiarze - patrz FIXES-M2. Runda M3,
     punkt 7 (dostepnosc): NIE display:none (usuwaloby tresc z drzewa
     dostepnosci - czytnik ekranu nigdy nie przeczytalby podpisu kadru),
     tylko ukrycie WIZUALNE (1x1px, przyciete) - .kadr-meta dostal wyzej
     position:relative, zeby position:absolute tutaj bylo kontenerowane
     lokalnie, a nie gdzies w gorze drzewa (.tasma-frames). */
  html.is-motion .kadr-caption{
    position:absolute!important;width:1px!important;height:1px!important;
    overflow:hidden!important;clip-path:inset(50%)!important;white-space:nowrap!important;
    margin:0!important;
  }
  html.is-motion .kadr-code{ font-size:9px; }
}

/* -- klaps: statyczny, zamkniety, poza is-motion -- */
.klaps{
  position:relative;width:min(560px,88vw);margin:0 auto 40px;background:#0b0d0f;border-radius:6px;
  box-shadow:0 30px 70px -30px rgba(0,0,0,.7);overflow:hidden;
}
/* Runda MOBILE, punkt 2: szerokosc naturalna wprost z zadania (min(86vw,360px)),
   zeby js/one.js (mierzKlaps) mial stabilny, przewidywalny klapsNaturalW do
   liczenia skali - dziala w obu trybach (is-motion i fallback). */
@media (max-width:768px){
  .klaps{width:min(86vw,360px)}
}
.klaps-pasy-top{height:34px;border-radius:6px 6px 0 0;overflow:hidden;background:repeating-linear-gradient(62deg,#0b0d0f 0 34px,#eef0f2 34px 68px)}
.klaps-ramie{height:34px;transform-origin:left center}
.klaps-ramie-visual{width:100%;height:100%;transform-origin:left center;background:repeating-linear-gradient(118deg,#0b0d0f 0 34px,#eef0f2 34px 68px)}
.klaps-fields{padding:22px 24px 26px;display:flex;flex-direction:column;gap:16px}
.klaps-field{display:flex;flex-direction:column;gap:4px}
.klaps-field-big .klaps-value{font:300 clamp(28px,4vw,50px) var(--font)}
.klaps-row{display:flex;gap:26px;flex-wrap:wrap}
.klaps-row .klaps-field{flex:1;min-width:110px}
.klaps-label{font:400 10px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--mut)}
.klaps-value{font:300 22px var(--font);color:var(--ink)}
.klaps-value-glyph svg{height:18px;width:auto;color:var(--ink)}
.klaps-sync{padding:0 24px 20px;font:400 11px var(--mono);letter-spacing:.1em;color:var(--dim)}

/* -- oglos -- */
.oglos{position:relative;padding:0 6vw 56px;display:flex;flex-direction:column;gap:18px;max-width:640px;margin:0 auto}
.oglos h2{font:300 clamp(34px,4.6vw,58px)/1.06 var(--font);letter-spacing:-.01em;transform-origin:top left}
/* maska dla splitWords() w js/one.js (odslanianie H2 slowo po slowie) */
.oglos h2 .word{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.1em;margin-bottom:-.1em}
.oglos h2 .word>span{display:inline-block;will-change:transform}
.oglos p{font:300 16px/1.65 var(--font);color:var(--mut)}
/* Na desktopie zachowuje sie jak gdyby wrappera nie bylo (oba akapity leca w
   normalnym przeplywie .oglos, jeden pod drugim). Na mobile (poprawka #2,
   runda 2) oba akapity naklada sie w JEDNYM miejscu (ta sama komorka grida),
   zeby js/one.js mogl je zamieniac crossfade'em zamiast pokazywac oba
   naraz na calym ekranie. */
.oglos-akapit-slot{display:contents}
/* TYLKO pod is-motion (poprawka #5, runda 3): bez tej klasy js/one.js nigdy
   nie robi crossfade'u (splitLines-style JS nie dziala), wiec oba akapity
   normalnie plyna jeden pod drugim - z ta regula bezwarunkowa na mobile
   naklada się rowniez w reduced-motion/bez-GSAP, dajac nieczytelna
   mieszanine dwoch tekstow w jednym miejscu na zawsze widocznych. */
@media (max-width:768px){
  html.is-motion .oglos-akapit-slot{display:grid}
  html.is-motion .oglos-akapit-slot p{grid-area:1/1}
}
.oglos-podpis{display:flex;align-items:center;gap:14px;margin-top:8px}
/* Uwaga: ten blok "oglos-podpis{display:none}" zniknal (runda M3, punkt 7) -
   caly .oglos jest juz ukryty WIZUALNIE (nie display:none) na kazdej
   wysokosci mobile (patrz regula .oglos nizej), wiec ukrywanie samego
   podpisu osobno tylko usuwaloby go z drzewa dostepnosci niezaleznie od
   reszty ogloszenia - sprzecznie z celem tamtej poprawki. */
.podpis-logos{display:flex;align-items:center;gap:8px}
.podpis-logo{width:26px;height:26px;object-fit:contain}
.podpis-glyph{width:12px;height:auto;color:var(--ink)}
.podpis-lines{display:flex;flex-direction:column;gap:2px;font:400 11px var(--mono);letter-spacing:.05em;color:var(--dim)}

/* -- bramka: dekoracyjna, poza is-motion nieobecna -- */
.bramka{display:none}

/* -- rozdzial-tytul -- */
.rozdzial-tytul{padding:56px 6vw;max-width:720px;margin:0 auto;display:flex;flex-direction:column;gap:16px}
.rozdzial-tytul h2{font:300 clamp(26px,3.4vw,42px)/1.08 var(--font);letter-spacing:-.01em}
.rozdzial-tytul p{font:300 15px/1.6 var(--font);color:var(--mut);max-width:52ch}
.tytul-tags{display:flex;flex-wrap:wrap;gap:8px;font:400 11px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
.tytul-tags span:not(:first-child)::before{content:'· ';color:var(--faint)}

/* -- przegladarka: rozmiar CALKOWICIE w CSS (JS czyta offsetWidth/offsetHeight,
   nigdy nie ustawia width/height sam - patrz B11 w liscie poprawek: cala
   animacja to transform:scale/x/y, zeby tekst w srodku skalowal sie plynnie
   zamiast lamac uklad przy zmianie realnej szerokosci/wysokosci). -- */
.przegladarka{width:min(1000px,92vw);margin:0 auto 40px;border-radius:12px;overflow:hidden;box-shadow:0 40px 90px -40px rgba(0,0,0,.7)}
.przegladarka-topbar{height:44px;background:#eef0f2;display:flex;align-items:center;gap:16px;padding:0 16px;transform-origin:top;overflow:hidden}
.pb-dot{width:9px;height:9px;border-radius:50%;background:#c3c8cd;flex:none}
.pb-address{flex:1;height:26px;border-radius:6px;background:#dfe2e5;display:flex;align-items:center;gap:6px;padding:0 12px;color:#5a6168;min-width:0}
.pb-address svg{width:11px;height:11px;flex:none}
.pb-url{font:400 12px var(--mono);color:#3a4046;white-space:nowrap;overflow:hidden}
.przegladarka-viewport{position:relative;aspect-ratio:16/9;background:#0b0d0f;overflow:hidden}
.przegladarka-viewport canvas{position:absolute;inset:0;width:100%;height:100%}
.pb-fallback-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pb-overlay{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:space-between;padding:20px 26px;pointer-events:none}
.pb-nav{display:flex;justify-content:space-between;align-items:center;color:#fff}
.pb-brand{font:600 12px var(--font);letter-spacing:.26em}
.pb-links{font:400 11px var(--mono);letter-spacing:.1em;color:rgba(255,255,255,.75)}
.pb-hero{padding-bottom:6px}
.pb-hero h3{font:300 clamp(22px,3vw,44px)/1.1 var(--font);color:#fff;text-shadow:0 4px 30px rgba(0,0,0,.6);margin-bottom:14px}
.pb-pill{display:inline-flex;font:400 12px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:#050607;background:#fff;padding:12px 22px;border-radius:999px}
@media (max-width:768px){
  /* fonty dopasowane do szerokosci Ws (runda MOBILE 2, punkt "8.8 do 11.2") */
  .pb-hero h3{font-size:20px;margin-bottom:10px}
  .pb-pill{padding:7px 16px;font-size:10.5px}
}
.pb-scrub{position:absolute;right:16px;top:70px;bottom:70px;display:flex;flex-direction:column;align-items:center;gap:8px;color:#fff}
.pb-scrub-track{position:relative;flex:1;width:2px;background:rgba(255,255,255,.25)}
.pb-scrub-fill{position:absolute;left:0;top:0;width:100%;background:#fff;height:0%}
.pb-scrub-count{font:400 9.5px var(--mono);letter-spacing:.08em;writing-mode:vertical-rl}
@media (max-width:768px){ .przegladarka{width:var(--mob-ws,88vw)} }

/* -- fakty: jeden slot, crossfade w js/one.js (opacity), pozycja liczona w JS
   (left/top ustawiane wprost, wyrownane do lewej krawedzi przegladarki) -- */
.fakty{position:fixed;width:min(300px,80vw);margin:0}
.fakt{position:absolute;inset:0 auto auto 0;width:100%;opacity:0;padding-top:18px;border-top:1px solid var(--line2);display:flex;flex-direction:column;gap:8px}
.fakt-num{font:400 11px var(--mono);letter-spacing:.14em;color:var(--dim)}
.fakt h4{font:400 18px var(--font)}
.fakt p{font:300 13.5px/1.6 var(--font);color:var(--mut)}
.fakt-arrow{margin-top:4px;color:var(--dim)}
.fakt-arrow svg{width:20px;height:26px}

/* -- montaz -- */
.montaz{width:min(1180px,92vw);margin:0 auto 80px;display:flex;flex-direction:column;gap:26px}
.montaz-tytul{display:flex;flex-direction:column;gap:14px;max-width:640px}
.montaz-tytul h2{font:300 clamp(28px,3.6vw,44px)/1.15 var(--font)}
.montaz-tytul p{font:300 15px/1.6 var(--font);color:var(--mut)}
/* Runda MOBILE 2: #tytul03 i .montaz-tytul (a wiec i ich akapity) sa juz
   calkowicie ukryte na kazdym telefonie (patrz regoly .rozdzial-tytul i
   .montaz-tytul wyzej) - zastapione wspolna strefa .mob-title/.mob-caption -
   wiec nie trzeba juz osobno chowac samych akapitow na niskich ekranach. */
.montaz-panel{position:relative;background:#0b0d0f;border:1px solid var(--line2);border-radius:16px;padding:20px 22px 26px;overflow:hidden}
.montaz-topbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;gap:12px}
.montaz-seq{font:400 11px var(--mono);letter-spacing:.1em;color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.montaz-transport{display:flex;gap:10px;color:var(--dim);flex:none}
.montaz-transport svg{width:14px;height:14px}
.montaz-tc{font:400 11px var(--mono);letter-spacing:.08em;color:var(--mut);font-variant-numeric:tabular-nums;flex:none}
.montaz-ruler{position:relative;height:26px;margin:0 0 6px var(--montaz-head);background:repeating-linear-gradient(90deg,var(--line) 0 1px,transparent 1px 40px)}
.ruler-step{position:absolute;top:6px;font:400 9px var(--mono);letter-spacing:.08em;color:var(--dim);white-space:nowrap}
.ruler-step .rn{font-weight:400}
.montaz-tracks{display:flex;flex-direction:column;gap:6px;position:relative}
.track{display:flex;align-items:stretch;gap:10px}
.track-head{flex:0 0 var(--montaz-head);display:flex;flex-direction:column;justify-content:center;gap:2px;min-width:0}
.track-id{font:400 10px var(--mono);letter-spacing:.12em;color:var(--dim)}
.track-name{font:400 11px var(--font);color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.track-lane{position:relative;flex:1;height:52px;background:rgba(255,255,255,.02);border-radius:6px;min-width:0}
.clip{position:absolute;top:4px;bottom:4px;border-radius:5px;overflow:hidden;border:1px dashed rgba(255,255,255,.25);display:flex;flex-direction:column;justify-content:center;padding:4px 10px}
.clip-fill{position:absolute;inset:0;transform-origin:left center;z-index:0}
html.is-motion .clip-fill{transform:scaleX(0)}
.clip-dark .clip-fill{background:#1d2226;box-shadow:inset 0 0 0 1px rgba(255,255,255,.16)}
.clip-light .clip-fill{background:#eef0f2}
.clip-audio .clip-fill{background:#14171a;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
.clip-social .clip-fill{background:#9aa0a6}
.clip-tag,.clip-name{position:relative;z-index:1}
.clip-tag{font:400 9.5px var(--mono);letter-spacing:.1em;white-space:nowrap}
.clip-name{font:400 13px var(--font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.clip-dark .clip-tag,.clip-dark .clip-name,.clip-audio .clip-tag,.clip-audio .clip-name{color:var(--ink)}
.clip-light .clip-tag,.clip-light .clip-name,.clip-social .clip-tag,.clip-social .clip-name{color:#050607}
.clip-thumb{position:absolute;inset:0;background-size:cover;background-position:center;filter:brightness(.5);opacity:0;z-index:0}
.clip.is-flash{box-shadow:0 0 0 2px var(--rec),0 0 24px 2px var(--rec)}
.waveform{position:absolute;left:10px;right:10px;bottom:6px;display:flex;align-items:flex-end;gap:1.5px;height:16px;opacity:.7;z-index:1}
.waveform span{flex:1;background:currentColor;min-width:1px;transform-origin:bottom}
/* left liczony przez calc() tak, by 0-100% (--phead, ustawiane w js/one.js)
   odpowiadalo dokladnie szerokosci PASA KLIPOW (bez kolumny naglowka
   sciezki), zeby glowica pokrywala sie z frontem wypelniania klipow -
   poprawka B16. */
.montaz-playhead{
  position:absolute;top:34px;bottom:12px;width:2px;background:var(--rec);pointer-events:none;
  left:calc(var(--montaz-head) + (100% - var(--montaz-head)) * var(--phead,0));
}
.montaz-steps{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
.krok{display:flex;flex-direction:column;gap:8px;transition:opacity .3s}
.krok-num{font:400 11px var(--mono);color:var(--dim)}
.krok h5{font:400 15px var(--font)}
.krok p{font:300 13px/1.55 var(--font);color:var(--mut)}
@media (max-width:768px){
  .montaz-seq{max-width:120px}
  .track-name{display:none}
  /* poprawka #5, runda 2: etykiety linijki zlewaly sie ("01 Brief02 Plan...")
     - na mobile pokazujemy tylko numery. Nazwy klipow byly obcinane
     wielokropkiem - na mobile pokazujemy krotka wersje z data-short (bez
     etykiety ZORNA/ONE/RAZEM, tez zbyt ciasnej). */
  .ruler-step .rt{display:none}
  html.is-motion .clip-tag{display:none}
  html.is-motion .clip-name{font-size:0}
  html.is-motion .clip-name::before{content:attr(data-short);font-size:8.5px;font-family:var(--font);}
  .montaz-steps{display:block;position:relative;min-height:96px}
  .montaz-steps .krok{position:absolute;inset:0;opacity:0}
}

/* Poprawka koordynatora (runda MOBILE 2): na niskich telefonach (iPhone SE)
   panel montazu MA ZAWSZE szerokosc Ws - .is-compact (przelaczana w
   js/one.js, mierzMontazScale) NIE skaluje calego bloku, tylko zmniejsza
   WYSOKOSCI jego elementow (pasek, linijka, sciezki, nazwy klipow), zeby
   panel+tytul+podpis kroku (ten ostatni juz we wspolnej strefie .mob-caption)
   zmiescily sie w ekranie bez zwezania panelu. */
@media (max-width:768px){
  html.is-motion .montaz-panel.is-compact{padding:10px 12px 12px}
  html.is-motion .montaz-panel.is-compact .montaz-topbar{margin-bottom:6px}
  html.is-motion .montaz-panel.is-compact .montaz-seq,
  html.is-motion .montaz-panel.is-compact .montaz-tc{font-size:9px}
  html.is-motion .montaz-panel.is-compact .montaz-transport svg{width:11px;height:11px}
  html.is-motion .montaz-panel.is-compact .montaz-ruler{height:20px;margin-bottom:4px}
  html.is-motion .montaz-panel.is-compact .ruler-step{top:4px;font-size:8px}
  html.is-motion .montaz-panel.is-compact .montaz-tracks{gap:4px}
  html.is-motion .montaz-panel.is-compact .track-lane{height:34px}
  html.is-motion .montaz-panel.is-compact .clip-name::before{font-size:8px}
  html.is-motion .montaz-panel.is-compact .montaz-playhead{top:22px;bottom:8px}
  html.is-motion .montaz-panel.is-compact .waveform{height:11px}
}

/* -- blysk -- */
.blysk{position:fixed;inset:0;background:#fff;opacity:0;pointer-events:none;z-index:900}

/* ═══════════════ NAPISY KONCOWE ═══════════════ */
#obsada{position:relative;background:#050607;padding:100px 6vw}
.napisy-wrap{max-width:760px;margin:0 auto;display:flex;flex-direction:column;gap:70px;text-align:center}
.napisy-crawl h2{font:200 clamp(56px,8vw,110px) var(--font);margin:14px 0 40px}
.napisy-row{display:grid;grid-template-columns:1fr 1fr;gap:26px;align-items:baseline;padding:10px 0}
.napisy-row .rola{text-align:right;font:400 12px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}
.napisy-row .nazwa{text-align:left;font:300 26px var(--font)}
.napisy-gap{height:26px}
.napisy-final{display:flex;flex-direction:column;gap:10px}
.final-label{font:400 12px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.final-brand{font:200 clamp(48px,8vw,110px) var(--font);position:relative;display:inline-block;background-image:linear-gradient(100deg,var(--ink) 40%,#fff 50%,var(--ink) 60%);background-size:260% 100%;-webkit-background-clip:text;background-clip:text;color:transparent}
@media (max-width:600px){
  .napisy-row{grid-template-columns:1fr;gap:4px;text-align:center;justify-items:center}
  .napisy-row .rola,.napisy-row .nazwa{text-align:center}
}

/* ═══════════════ STYKOWKA (jasna) ═══════════════ */
#stykowka{background:#eef0f2;color:#050607;padding:110px 6vw}
.styk-head{max-width:760px;margin:0 auto 50px;display:flex;flex-direction:column;gap:14px}
.styk-head h2{font:300 clamp(32px,4.4vw,54px)/1.08 var(--font);letter-spacing:-.01em}
.styk-head p{font:300 16px/1.6 var(--font);color:#353a3f;max-width:56ch}
/* Szerokosc arkusza wprost wg specyfikacji rundy 2: min(1280px, 100vw - 2*80px). */
.styk-arkusz{width:min(1280px,calc(100vw - 160px));margin:0 auto 90px;background:#0b0d0f;border-radius:8px;padding:40px;perspective:1400px}
/* Dwie wersje tresci (desktop: 2 paski x 3 kadry / mobile: 3 paski x 2 kadry) -
   przelaczane display:none, zeby kazdy pasek mial WLASNA perforacje gora+dol,
   niezaleznie od tego, ile kadrow miesci sie w rzedzie na danej szerokosci
   (poprawka #6, runda 2: plaska siatka flex-wrap nie dawala prawdziwych
   "paskow tasmy" z perforacja przy kazdym rzedzie). display:none usuwa
   nieaktywna wersje tez z drzewa dostepnosci, wiec czytnik ekranu nie czyta
   tych samych podpisow dwa razy. */
.styk-set{display:flex;flex-direction:column;gap:12px}
.styk-set-mobile{display:none}
.styk-pasek{display:flex;flex-direction:column;gap:0}
.styk-perf{height:8px;background:repeating-linear-gradient(90deg,rgba(238,240,242,.85) 0 6px,transparent 6px 20px)}
.styk-kadry{display:flex;gap:16px;padding:12px 6px}
/* min-width:0 jest kluczowe: bez niego domyslne min-width:auto flex-itema
   liczy sie z tresci (obrazu), wiec przy 2 kadrach w waskim mobilnym pasku
   flex:1 nie mogl ich rownomiernie rozciagnac na cala szerokosc - zostawaly
   scisniete do ulamka dostepnego miejsca (poprawka #2, runda 4). */
/* <figure> ma domyslny margines przegladarki (ok. 1em 40px) - to on realnie
   zjadal 80px szerokosci na kadr, nie flex/min-width (poprawka #2, runda 5). */
.styk-kadr{position:relative;flex:1 1 0;min-width:0;width:auto;margin:0;display:flex;flex-direction:column;gap:6px}
.styk-kadr img{width:100%;aspect-ratio:3/2;object-fit:cover;border-radius:3px}
.styk-kadr figcaption{font:400 9.5px var(--mono);letter-spacing:.06em;color:rgba(238,240,242,.55);text-align:center}
.styk-petla{position:absolute;inset:-10% -10% -10% -18%;pointer-events:none;color:var(--rec);overflow:visible}
.styk-petla path{fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round}
.styk-check{position:absolute;bottom:6px;right:2px;width:20px;height:20px;color:var(--rec)}
.styk-klient{width:min(1080px,94vw);margin:96px auto 0;display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:center}
.styk-klient-tekst{display:flex;flex-direction:column;gap:16px}
.styk-klient-tekst h3{font:300 38px/1.15 var(--font)}
.styk-klient-tekst p{font:300 15.5px/1.65 var(--font);color:#353a3f;max-width:48ch}
.styk-klient-tekst a{font:400 13px var(--mono);letter-spacing:.1em;color:#050607;border-bottom:1px solid #050607;width:fit-content;padding-bottom:2px}
.styk-klient-okno{border-radius:10px;overflow:hidden;box-shadow:0 40px 90px -40px rgba(0,0,0,.35);perspective:1400px}
.okno-bar{height:34px;background:#0b0d0f;display:flex;align-items:center;gap:8px;padding:0 14px}
.okno-bar span{width:8px;height:8px;border-radius:50%;background:#3a4046}
.okno-addr-chip{margin-left:10px;height:20px;padding:0 10px;border-radius:4px;background:#1a1e22;display:flex;align-items:center}
.okno-addr{font:400 11px var(--mono);color:#9aa0a6}
.styk-klient-okno img{width:100%;display:block}

@media (max-width:900px){
  .styk-klient{grid-template-columns:1fr;gap:34px}
}
@media (max-width:768px){
  /* poprawka #1, runda 3: min(1280px, 100vw-160px) na waskich ekranach dawal
     ok. 230px (100vw-160px), za malo na 2 zdjecia w rzedzie - stad "ikonki". */
  .styk-arkusz{width:calc(100vw - 48px);padding:14px}
  .styk-set-desktop{display:none}
  .styk-set-mobile{display:flex}
}

/* ═══════════════ AKCJA ═══════════════ */
#akcja{position:relative;background:#050607;padding:0 0 90px;overflow:hidden}
.akcja-pasy{height:26px;background:repeating-linear-gradient(118deg,#eef0f2 0 30px,#050607 30px 60px)}
.akcja-inner{max-width:900px;margin:0 auto;padding:64px 6vw 0;display:flex;flex-direction:column;align-items:center;text-align:center;gap:22px}
.akcja-meta{display:flex;gap:10px;font:400 11px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.akcja-meta span:not(:first-child)::before{content:'· ';color:var(--faint)}
.akcja-rec{display:inline-flex;align-items:center;gap:6px}
.rec-dot{width:7px;height:7px;border-radius:50%;background:var(--rec);animation:hudRec 1.1s ease-in-out infinite}
/* white-space:nowrap + clamp dopasowany tak, zeby "Akcja" nigdy nie zawijalo
   sie w kontenerze .akcja-inner (max-width:900px) - przy starym
   clamp(72px,22vw,330px) litery przy duzym 22vw byly szersze niz kontener i
   lamaly sie na "Akcj"/"a" (poprawka #7). */
.akcja-h2{
  display:flex;align-items:baseline;gap:0;white-space:nowrap;
  font:200 clamp(96px,21vw,320px)/.86 var(--font);letter-spacing:-.05em;
}
/* Kropka stoi dokladnie tam, gdzie balaby kropka po "a" (bez odstepu -
   przez to "Akcja" + kropka czyta sie jak "Akcja.") */
.akcja-dot{width:.14em;height:.14em;border-radius:50%;background:var(--rec);margin-left:.03em;transform:translateY(-.06em);animation:hudRec 1.1s ease-in-out infinite}
html.is-motion .akcja-dot{opacity:0}
.akcja-p{font:300 17px/1.6 var(--font);color:var(--mut);max-width:56ch;margin:0 auto}
.akcja-karty{display:flex;gap:20px;flex-wrap:wrap;margin-top:30px;width:100%}
.karta{
  flex:1;min-width:240px;display:flex;flex-direction:column;gap:10px;
  padding:26px;border:1px solid var(--line2);border-radius:18px;transition:border-color .3s;
}
.karta:hover{border-color:rgba(255,255,255,.5)}
.karta-logo{width:44px;height:44px;display:flex;align-items:center;justify-content:center}
.karta-logo img{width:100%;height:100%;object-fit:contain}
.karta-logo-one svg{width:18px;height:auto;color:var(--ink)}
.karta-nazwa{font:400 17px var(--font)}
.karta-tagi{font:400 11px var(--mono);letter-spacing:.08em;color:var(--dim)}
.karta a{font:300 14px var(--font);color:var(--mut);transition:color .25s}
.karta a:hover{color:var(--ink)}

footer{
  display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:16px;
  padding:28px 6vw 132px;border-top:1px solid var(--line);max-width:1180px;margin:0 auto;
}
.foot-copy{font:400 11px var(--mono);color:var(--dim)}
.foot-links{display:flex;flex-wrap:wrap;gap:22px}
.foot-links a{font:400 11px var(--mono);letter-spacing:.04em;color:var(--dim);transition:color .25s}
.foot-links a:hover{color:var(--ink)}

@media (max-width:768px){
  .akcja-karty{flex-direction:column}
}

/* Runda MOBILE 2, punkt 4: sekcje po scenie (Obsada/Stykowka/Akcja) dostaja
   te same 20px marginesy boczne co strefa tytulu na mobile - etykieta+H2
   juz uzywaja tych samych klas (.sec-label, h2), wiec spojnosc typografii
   jest zachowana automatycznie; tu wyrownujemy tylko odstepy. */
@media (max-width:768px){
  #obsada,#stykowka{padding-left:20px;padding-right:20px}
  .akcja-inner{padding-left:20px;padding-right:20px}
}

/* ═══════════════════════════════════════════════════════════════════
   html.is-motion: uklad "jednego ujecia" — warstwy absolutne, przypiecia.
   Wlacza sie tylko gdy js/one.js potwierdzil GSAP + ScrollTrigger i brak
   prefers-reduced-motion. Bez tej klasy wszystko powyzej zostaje normalnym
   dokumentem w przeplywie strony. ═══════════════════════════════════════ */
html.is-motion main{padding-top:0}
html.is-motion #preloader{display:flex}
html.pre-skip #preloader{display:none}

html.is-motion #scena{
  height:100vh;height:100svh;overflow:hidden;background:#050607;
}
/* Tylko position: BEZ inset:0 i BEZ pointer-events:auto domyslnie. inset:0
   dawal kazdej warstwie ukryte right:0/bottom:0, ktore psuly wszystkie
   warstwy nadpisujace tylko left/top (patrz uzasadnienie przy .klaps/.oglos/
   .fakty/.montaz nizej: left+right+auto-width/height = przegladarka sama
   liczy wysokosc jako "kontener - top - bottom", scisksjac tresc). Kazda
   warstwa, ktora ma wypelniac cala scene, dostaje inset:0 JAWNIE ponizej. */
html.is-motion #scena>*{position:absolute;pointer-events:none}
html.is-motion #scena>.tasma,
html.is-motion #scena>.hero-tekst,
html.is-motion #scena>.hero-scrim,
html.is-motion #scena>.scena-fade{inset:0}
html.is-motion #scena>.hero-tekst .hero-cta-row a{pointer-events:auto}
/* z-index JAWNY, najwyzszy w scenie (ale pod HUD:820/naglowkiem:800): bez
   tego .montaz (ma wlasny transform -> wlasny kontekst warstwowania) i
   .scena-fade (zwykly z-index:auto) nie daway pewnosci, ktora rysuje sie na
   wierzchu - przy zaciemnieniu na koniec sceny panel montazu byl nadal w
   pelni widoczny przez czarna warstwe (poprawka #4, runda 3). 80 > 70
   (.przegladarka), wiec fade zawsze przykrywa tez przegladarke. */
/* display:block + background JAWNE: baza ma display:none (zwykly dokument
   bez tej warstwy), a is-motion nigdzie tego nie odwracalo - stad rect 0x0 i
   przezroczyste tlo mimo poprawnego opacity/z-index (poprawka #1, runda 4). */
html.is-motion #scena>.scena-fade{display:block;background:#050607;z-index:80}
html.is-motion #scena>.hero-scrim{
  display:block;z-index:2;
  background:linear-gradient(90deg,rgba(5,6,7,.55),rgba(5,6,7,0) 65%);
}
@media (max-width:768px){
  html.is-motion #scena>.hero-scrim{background:rgba(5,6,7,.55)}
}

html.is-motion .tasma{
  padding:0;background:transparent;overflow:visible;
  display:flex;align-items:center;justify-content:center;
}
html.is-motion .tasma-row{width:max-content;margin:0;will-change:transform}
html.is-motion .tasma-frames{padding:14px 0}
html.is-motion .kadr-wrap{scroll-snap-align:none;will-change:transform,opacity}
html.is-motion .tasma-perf{will-change:opacity}

/* Uwaga specificity: uzywamy "#scena>.NAZWA" (nie samego ".NAZWA") dla kazdej
   bezposredniej warstwy sceny, ktora potrzebuje wlasnych left/top - inaczej
   przegrywalyby z blanketowa regula "html.is-motion #scena>*" powyzej (ta ma
   id #scena w selektorze, wiec bije zwykla klase co do position, ale od kiedy
   ta regula juz NIE niesie inset:0, walka dotyczy tylko "position", ktora i
   tak jest ta sama wartosc - zostawiamy prefiks dla porzadku i pewnosci). */
html.is-motion #scena>.klaps{
  position:absolute;left:50%;top:50%;margin:0;overflow:visible;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.8);
  will-change:transform;
}
/* Pozycjonowanie startowe (xPercent/yPercent + x/y/rotate/scale) ustawia
   js/one.js przez GSAP (gsap.set) zaraz po starcie sceny - transform NIE jest
   tu zapisany w CSS, zeby GSAP od pierwszego tweenu w pelni kontrolowal
   macierz (mieszanie CSS transform i pozniejszych tweenow bywa niestabilne). */
html.is-motion .klaps-sync{opacity:0}
@media (max-width:768px){
  /* Runda MOBILE 2: linijka synchronizacji przenosi sie WIZUALNIE do
     wspolnej strefy podpisu (.mob-caption) razem z reszta tresci rozdzialow -
     w klapsie samym nie jest WIDOCZNA, zeby nie dublowac tekstu w dwoch
     miejscach naraz. Runda M3, punkt 7 (dostepnosc): NIE display:none
     (usuwaloby ja z drzewa dostepnosci) - ukrycie WIZUALNE, .klaps ma
     position:relative (patrz #scena>.klaps wyzej), wiec position:absolute
     tutaj jest kontenerowane lokalnie. */
  html.is-motion .klaps-sync{
    position:absolute!important;width:1px!important;height:1px!important;
    overflow:hidden!important;clip-path:inset(50%)!important;white-space:nowrap!important;
    margin:0!important;
  }
}

html.is-motion #scena>.oglos{
  position:absolute;left:6vw;top:50%;transform:translateY(-50%);
  padding:0;margin:0;max-width:480px;opacity:0;
}
/* Mobile (poprawka #2, runda 2): tekst U GORY (nie wyscentrowany na cala
   wysokosc, bo tam ladowal klaps), klaps schodzi PONIZEJ niego - js/one.js
   liczy dokladna pozycje/skale klapsa z rzeczywistej wysokosci tego bloku
   (mierzKlaps(), patrz oglosEl.offsetHeight), zeby nigdy sie nie nachodzily. */
@media (max-width:768px){
  /* Runda MOBILE 2: na telefonie caly .oglos (etykieta+H2+akapity+podpis)
     jest ZASTAPIONY WIZUALNIE przez wspolna strefe tytulu (.mob-title) i
     strefe podpisu (.mob-caption) - patrz nizej. Tresc jest ta sama
     (skopiowana w js/one.js), ale pozycja jest teraz WSPOLNA dla wszystkich
     4 rozdzialow (jeden uklad zamiast czterech oddzielnych). Runda M3,
     punkt 7 (dostepnosc): NIE display:none (usuwaloby ogloszenie z drzewa
     dostepnosci - czytnik ekranu nigdy by go nie przeczytal) - ukrycie
     WIZUALNE, .oglos jest juz position:absolute (regula wyzej). */
  html.is-motion #scena>.oglos{
    width:1px!important;height:1px!important;overflow:hidden!important;
    clip-path:inset(50%)!important;white-space:nowrap!important;
  }
}

html.is-motion .hero-tekst{
  /* .hero-tekst jest teraz PIERWSZA w DOM (zeby poza is-motion H1 szedl przed
     H2 ogloszenia - patrz zorna-x-one/index.html), wiec sama kolejnosc DOM
     juz NIE stawia jej nad tasma/.klaps/.oglos - potrzebny jawny z-index.
     Bezpieczne: pozniejsze warstwy (bramka, przegladarka, montaz...) sa
     przezroczyste, zanim hero-tekst w ogole przestaje byc istotny. */
  z-index:5;
  padding:0 6vw;display:flex;flex-direction:column;
  align-items:flex-start;justify-content:center;gap:22px;max-width:none;
}
/* pozycja przeniesiona z .hero-hint na wrapper .hero-intro-hint (poprawka
   koordynatora): .hero-intro-hint dostaje transform od intro (GSAP), wiec
   to ONO musi byc position:absolute (ustala wlasna pozycje wzgledem
   .hero-tekst raz, transform intro tylko ja przesuwa przy wejsciu) - gdyby
   position:absolute zostal na .hero-hint (dziecku), .hero-hint brałby
   left/bottom wzgledem TEGO WLASNIE transformowanego wrappera (male
   pudelko), a nie .hero-tekst - stad wczesniejszy blad (podpowiedz na
   przycisku/leadzie). */
html.is-motion .hero-intro-hint{position:absolute;left:6vw;bottom:38px}
html.is-motion .hero-hint{margin:0}

html.is-motion #scena>.bramka{
  display:block;position:absolute;left:50%;top:50%;
  width:var(--kadr-w);aspect-ratio:16/9;
  transform:translate(-50%,-50%);
  box-shadow:0 0 0 1px rgba(238,240,242,.5);opacity:0;
}
html.is-motion .bramka-label{
  position:absolute;bottom:100%;left:0;margin-bottom:14px;
  font:400 11px var(--mono);letter-spacing:.12em;color:var(--mut);white-space:nowrap;
}
html.is-motion .bramka-corner{position:absolute;width:14px;height:14px}
html.is-motion .bramka-corner i{position:absolute;background:var(--ink)}
html.is-motion .bramka-corner i:first-child{width:100%;height:1.5px;top:0}
html.is-motion .bramka-corner i:last-child{height:100%;width:1.5px;left:0}
html.is-motion .bramka-corner.bc-tl{top:-1px;left:-1px}
html.is-motion .bramka-corner.bc-tr{top:-1px;right:-1px;transform:scaleX(-1)}
html.is-motion .bramka-corner.bc-bl{bottom:-1px;left:-1px;transform:scaleY(-1)}
html.is-motion .bramka-corner.bc-br{bottom:-1px;right:-1px;transform:scale(-1,-1)}

html.is-motion #scena>.rozdzial-tytul{
  position:absolute;left:6vw;top:88px;padding:0;margin:0;opacity:0;max-width:480px;
}
@media (max-width:768px){
  /* Runda MOBILE 2: #tytul03/#tytul04 (rozdz. 02/03) sa zastapione WIZUALNIE
     przez .mob-title, tak samo jak .oglos wyzej - jeden wspolny uklad
     tytulu. Runda M3, punkt 7 (dostepnosc): ukrycie WIZUALNE zamiast
     display:none, z tego samego powodu co przy .oglos. */
  html.is-motion #scena>.rozdzial-tytul{
    width:1px!important;height:1px!important;overflow:hidden!important;
    clip-path:inset(50%)!important;white-space:nowrap!important;
  }
}

/* ═══════════════ MOBILE: WSPOLNA STREFA TYTULU I PODPISU (runda MOBILE 2) ═══════════════
   Pozycja (left/top/width) jest ustawiana raz na refresh/resize przez
   mobileLayout() w js/one.js (ta sama, stala geometria dla calego pinu
   sceny - patrz komentarz w JS), tresc i opacity/y co klatke przez
   mobTitleTick/mobCaptionTick. Nieobecne na desktopie (0 wysokosci/width w
   layoucie by default) i poza is-motion (nikt tam nie ustawia im tresci). */
.mob-title,.mob-caption{ display:none; }
@media (max-width:768px){
  html.is-motion #scena>.mob-title,
  html.is-motion #scena>.mob-caption{
    display:block;position:absolute;z-index:15;opacity:0;will-change:transform,opacity;
  }
}
.mob-title-label{font:400 10px var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--dim);display:block}
.mob-title-h2{font:300 28px/1.1 var(--font);letter-spacing:-.01em;margin-top:8px;color:var(--ink)}
.mob-caption-body{font:300 14px/1.55 var(--font);color:var(--mut)}
.mob-caption-body .mc-line{font:400 11px var(--mono);letter-spacing:.08em;color:var(--dim)}
.mob-caption-body .mc-sig{display:flex;flex-direction:column;gap:2px;margin-top:8px;font:400 11px var(--mono);letter-spacing:.05em;color:var(--dim)}
.mob-caption-body .mc-tags{font:400 11px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-bottom:6px}
.mob-caption-body .mc-frame{color:var(--mut);display:block;margin-top:2px}
.mob-caption-body .mc-fakt-num{font:400 11px var(--mono);letter-spacing:.14em;color:var(--dim);display:block;margin-bottom:4px}
.mob-caption-body .mc-fakt-h{font:400 16px var(--font);color:var(--ink);margin-bottom:4px;display:block}
.mob-caption-body .mc-krok-num{font:400 11px var(--mono);color:var(--dim);display:block}
.mob-caption-body .mc-krok-h{font:400 15px var(--font);color:var(--ink);display:block;margin:2px 0 4px}
@media (max-height:700px){
  .mob-title-h2{font-size:26px}
  .mob-caption-body{font-size:13px}
}

/* .przegladarka: position:fixed, wycentrowana przez xPercent/yPercent (GSAP,
   ustawione raz), rozmiar CALKOWICIE naturalny/CSS (width w media queries
   wyzej) - js/one.js czyta offsetWidth/offsetHeight i animuje WYLACZNIE
   scale/x/y. Dzieki temu tekst w srodku (naglowek, pigulka) skaluje sie
   plynnie z reszta zamiast reflowowac/obcinac sie przy zmianie realnego
   rozmiaru okna (patrz poprawka B11). */
html.is-motion #scena>.przegladarka{
  position:fixed;left:50%;top:50%;margin:0;opacity:0;z-index:70;
}
html.is-motion .przegladarka-topbar{transform:scaleY(.001)}
html.is-motion .pb-fallback-img{display:none}

html.is-motion #scena>.fakty{
  position:fixed;margin:0;
}
@media (max-width:768px){
  /* Runda MOBILE 2: fakty 1/2/3 pokazywane WIZUALNIE w tej samej wspolnej
     strefie podpisu co reszta tresci rozdzialow (.mob-caption), nie w
     osobnym, wyliczanym wzgledem przegladarki bloku. Runda M3, punkt 7
     (dostepnosc): ukrycie WIZUALNE zamiast display:none - .fakty jest juz
     position:fixed (regula wyzej), wiec jest kontenerowana bez zmiany schematu. */
  html.is-motion #scena>.fakty{
    width:1px!important;height:1px!important;overflow:hidden!important;
    clip-path:inset(50%)!important;white-space:nowrap!important;
  }
}

html.is-motion #scena>.montaz{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(1180px,92vw);margin:0;opacity:0;
}
/* Runda MOBILE 2: .montaz-tytul i .montaz-steps sa zastapione przez wspolna
   strefe tytulu/podpisu (patrz .mob-title/.mob-caption) - na telefonie
   zostaje widoczny tylko .montaz-panel (tasma klipow), skalowany i
   wysrodkowany na "top" wyliczone przez mobileLayout()/mierzMontazScale() w
   js/one.js (stageCY - ten sam srodek co kazdy inny obiekt sceny na
   mobile), zamiast wlasnego, oddzielnego centrowania w pionie na cala
   wysokosc ekranu. */
@media (max-width:768px){
  /* Runda M3, punkt 7 (dostepnosc): ukrycie WIZUALNE zamiast display:none -
     czytnik ekranu ma nadal dostep do tytulu rozdzialu 04 i tekstu krokow
     montazu. position:absolute (kontenerowane w .montaz, ktory jest
     position:absolute - regula wyzej) jest tu WAZNE tez funkcjonalnie, nie
     tylko dla ukrycia: bez tego oba bloki zostalyby elementami flex w
     .montaz (display:flex;flex-direction:column) i doliczalyby swoja
     (nawet zerowa) wysokosc + gap do montazEl.offsetHeight, zaburzajac
     pomiar w mierzMontazScale() (patrz js/one.js). */
  html.is-motion .montaz-tytul,
  html.is-motion .montaz-steps{
    position:absolute!important;width:1px!important;height:1px!important;
    min-height:1px!important;overflow:hidden!important;clip-path:inset(50%)!important;
    white-space:nowrap!important;margin:0!important;
  }
  html.is-motion #scena>.montaz{ width:var(--mob-ws,88vw); }
}

html.is-motion #obsada,html.is-motion #stykowka,html.is-motion #akcja{position:relative}
html.is-motion #obsada{height:100vh;height:100svh;overflow:hidden;display:flex;align-items:center}
html.is-motion .napisy-wrap{width:100%;-webkit-mask-image:linear-gradient(transparent,#000 12%,#000 88%,transparent);mask-image:linear-gradient(transparent,#000 12%,#000 88%,transparent)}
html.is-motion .napisy-final{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0}

html.is-motion .styk-arkusz{transform:rotateX(18deg) translateY(60px);opacity:0;transform-style:preserve-3d}
html.is-motion .styk-klient-okno{transform:rotateY(-14deg) rotateX(6deg);opacity:0;transform-style:preserve-3d}

html.is-motion .akcja-h2 .ch-mask{overflow:hidden}
html.is-motion .akcja-h2 .ch{transform:translateY(110%)}

/* prefers-reduced-motion musi dzialac NIEZALEZNIE od is-motion (js/one.js i
   tak nigdy nie doklei is-motion, gdy reduced-motion jest wlaczone - ale
   czysto CSS-owe animacje dekoracyjne, np. puls kropek czy ziarno, maja
   zgasnac zawsze, dla kazdego, kto ma to ustawienie systemowe). */
@media (prefers-reduced-motion: reduce){
  *{animation:none!important}
}
