:root{
  --red:#FF0000;
  --ink:#171718;
  --void:#0B0B0D;
  --bone:#EFEDE9;
  --steel:#C3C6CD;
  --hair:rgba(239,237,233,.16);
  --rim:rgba(239,237,233,.8);
  --gut:clamp(18px,4.2vw,72px);
  --hdr:64px;
  --ff:"Helvetica Neue",Helvetica,Arial,"Liberation Sans",sans-serif;
  --poster:"Archivo","Helvetica Neue",Arial,sans-serif;
  --tick:cubic-bezier(.16,1,.3,1);
  --punch:cubic-bezier(.76,0,.24,1);
}
*{box-sizing:border-box}
/* iOS Safari, odbicie w bok: samo overscroll-behavior-x blokuje tylko elastyczny odbój POZA zakresem scrolla —
   jeśli cokolwiek jest realnie szersze niż viewport (a na Safari to się zdarza inaczej niż w Chromium, np. przez
   zaokrąglenia), telefon i tak przewinie się w bok i tam zostanie, bo nic go nie cofa. overflow-x:hidden na
   html/body by to zablokowało, ale ma dwa problemy: (1) w specyfikacji overflow-x i overflow-y są sprzężone —
   "hidden" na jednej osi wymusza drugiej "auto", a "auto" na html/body zamiast domyślnego psuje position:sticky
   w #onas (scena przestawała się przypinać — złapane i cofnięte wcześniej w tym samym audycie), (2) na iOS
   Safari samo overflow-x:hidden na body bywa ignorowane przy przeciąganiu palcem — to właśnie dlatego tamten
   fix nie usunął bocznego przewijania u znajomego z iPhone 12 mini. overflow-x:clip nie ma żadnej z tych wad:
   nie tworzy kontekstu przewijania (więc nic nie ma czego "zapamiętać" jako pozycję scrolla), a jednoosiowe
   clip nie wymusza drugiej osi do "auto" tak jak hidden/scroll/auto — sprawdzone w headless Chromium: sticky
   w #onas trzyma się, overflow-y zostaje "visible" */
html{scroll-behavior:smooth;overflow-x:clip;overscroll-behavior-x:none}
body{margin:0;background:var(--void);color:var(--bone);font-family:var(--ff);
  -webkit-font-smoothing:antialiased;overflow-x:clip;overscroll-behavior-x:none;letter-spacing:-.01em}
/* treść musi stać ponad wspólnym tłem i welonem */
main{position:relative;z-index:2}
body[data-lock="1"]{overflow:hidden}
canvas,video,img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--red);outline-offset:4px}
#szum-defs{position:absolute;width:0;height:0;overflow:hidden}
.mark,.lockup{display:block;width:100%;height:auto;fill:currentColor}
.lbl{font-size:10px;font-weight:700;letter-spacing:.2em;text-transform:uppercase}

/* krój plakatowy — szeroki i ciężki, w duchu znaku */
.pf{font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 118;
  letter-spacing:-.035em;text-transform:uppercase;line-height:.84}

/* ===== jedno sprzężone tło całej strony — animacja WebGL2 klienta, bez szwów ===== */
/* host canvasu WebGL — jeden na całą stronę, position:fixed więc bez szwów między sekcjami */
#fx{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
#heroVid{position:absolute;inset:0;width:100%;height:100%}
#veil{position:fixed;inset:0;z-index:1;pointer-events:none;background:rgba(11,11,13,.27)}
#grain{position:fixed;inset:0;z-index:95;pointer-events:none;mix-blend-mode:overlay;opacity:.38}

.fx-pulse{position:absolute;left:50%;top:50%;width:62vmin;height:62vmin;margin:-31vmin 0 0 -31vmin;
  border-radius:50%;z-index:0;pointer-events:none;mix-blend-mode:screen;
  background:radial-gradient(circle,rgba(255,0,0,.32),rgba(255,0,0,0) 68%);
  animation:fxPulse 3.6s ease-out infinite}
@keyframes fxPulse{0%{transform:scale(.28);opacity:.85}70%{opacity:.12}100%{transform:scale(1.15);opacity:0}}

/* ================= PRELOADER ================= */
/* "VHS wake-up": zamiast dwuprzebiegowego shaderu WebGL2 liczonego na każdej klatce (poprzednia wersja —
   realnie zacinała się na zwykłym WordPressie, nie tylko w piaskownicy artefaktu) — gotowy szum (4 klatki
   canvas 2D, cyklowane timerem co 60ms, dokładnie ta sama, już sprawdzona technika co #grain niżej) + znak
   łapiący ostrość przez CSS (blur+jitter, kompozytor). Zero per-klatkowego rysowania — fizycznie nie ma czego
   przycinać, niezależnie od mocy urządzenia */
#boot{position:fixed;inset:0;z-index:200;background:#000;display:grid;place-items:center;overflow:hidden}
/* telefon i desktop to TEN SAM prelodera: automat klienta "WARNING! SZUM" z wycięciem-ekranem, w którym szeroki
   poziomy znak (963:216) "rolluje się" przez całą wysokość ekranu (patrz uLogoVFrac w shaderze niżej). Telefon
   (domyślnie) dostaje węższą wersję pliku na pionowym kadrze 881:1214 (wycięcie zmierzone z przezroczystości:
   9.19%/22.57% od lewej/góry, 81.04%×43.99% szerokości/wysokości) i box liczony z wysokości ekranu ALBO z
   szerokości (95vw — wtedy automat prawie dotyka boków, jak na kadrze 923×2000 od klienta), zależnie co
   mniejsze; desktop (@media niżej) — własny, poziomy plik 1244:1065 (marquee + szeroki ekran, dół obudowy
   zanika w tło). Ekran desktopu jest szerszy (1.74:1 wobec 1.34:1 na telefonie), ale znak zawsze zajmuje 90%
   jego szerokości, więc proporcje rollu zostają te same, tylko bęben ma więcej miejsca w pionie.
   Box zaczyna prawie przezroczysty i wchodzi dopiero, gdy JS potwierdzi zdekodowaną ramkę (patrz
   bootFrameReady) — bez tego obudowa "wskakiwała" w połowie rollu na wolnym łączu. Dół to .01, nie 0:
   przeglądarka nie maluje poddrzewa z opacity:0, więc ramka dopiero by się rasteryzowała w trakcie
   wejścia (na słabym telefonie ekran bez obudowy w pierwszych klatkach); przy .01 jest gotowa z góry */
#bootCabinet{position:relative;height:min(86vh,130.9vw);height:min(86svh,130.9vw);width:auto;aspect-ratio:881/1214;
  opacity:.01;transition:opacity .45s ease-out}
#bootCabinet.on{opacity:1}
#bootFrame{display:block;position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none}
#bootScreen{position:absolute;left:9.19%;top:22.57%;width:81.04%;height:43.99%;overflow:hidden;background:#0a0a0c;
  border-radius:1.5%/2%;box-shadow:inset 0 0 min(6vw,60px) rgba(0,0,0,.85)}
#bootNoise{position:absolute;inset:0;width:100%;height:100%;opacity:.5;mix-blend-mode:screen}
#bootScan{position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(0deg,rgba(0,0,0,.35) 0 1px,rgba(0,0,0,0) 1px 3px)}
#bootVign{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse at center,rgba(0,0,0,0) 52%,rgba(0,0,0,.8) 100%)}
#bootLogoWrap{position:absolute;inset:0;display:grid;place-items:center}
/* canvas (#bootLogoTV) wypełnia CAŁY ekran automatu, styk do styk, bez wewnętrznego marginesu — roll ma
   miejsce do "lotu" przez cały ekran. #bootLogo (prawdziwy SVG, ukryty przez cały roll — patrz flyLogoToHero)
   = 100% canvasu razy LOGO_SCALE (0.9, patrz shader w JS) = 90%, żeby podmiana przy settle() była bez
   "skoku" rozmiaru */
#bootLogo{width:90%;height:auto;display:block;color:var(--bone);fill:currentColor;opacity:0;grid-area:1/1}
#bootLogo.jit{animation:bootTune 1.1s var(--tick) forwards,bootJit .09s steps(1) 6}
#bootLogoTV{width:100%;height:100%;display:block;grid-area:1/1}
/* desktop: poziomy plik automatu 1244×1065 (wycięcie zmierzone z przezroczystości: 7.48%/29.39% od lewej/góry,
   84.65%×56.90% szerokości/wysokości obudowy). Box z wysokości okna (88vh, nie więcej niż 1065 px = natywna
   wysokość pliku, żeby na wielkich monitorach nie rozciągać bitmapy), ale też nie szerszy niż 92% okna
   (78.7vw = 92vw / 1.168) — bez tego na wąskich oknach (761–1000 px) i tabletach w pionie automat wychodziłby
   poza boki */
@media(min-width:761px){
  #bootCabinet{height:min(88vh,1065px,78.7vw);aspect-ratio:1244/1065}
  #bootScreen{left:7.48%;top:29.39%;width:84.65%;height:56.9%}
}
@keyframes bootTune{
  0%{opacity:0;filter:blur(9px);transform:scaleY(1.06) translateY(-3%)}
  40%{opacity:.55;filter:blur(4px)}
  100%{opacity:1;filter:blur(0);transform:none}
}
@keyframes bootJit{0%,100%{transform:translateX(0)}25%{transform:translateX(-1.5%)}50%{transform:translateX(1%)}75%{transform:translateX(-.5%)}}
/* lot znaku z ekranu prelodera na miejsce .hero-mark — sam element #bootLogo, przeniesiony do <body>
   na czas lotu (patrz JS flyLogoToHero); czysty transform/opacity, więc gaśnięcie #bootScreen (osobny
   tween) go nie dotyka */

/* ================= HEADER ================= */
/* menu zostaje na górze strony (nie przykleja się do ekranu przy scrollu);
   po lewej „najbliższa impreza", po prawej linki — te same krawędzie co duży znak w hero */
#hdr{position:absolute;top:0;left:0;right:0;z-index:120;min-height:var(--hdr);display:flex;
  align-items:center;justify-content:space-between;gap:var(--gut);padding:12px var(--gut);
  opacity:0;color:var(--bone)}
#nav{margin-left:auto;padding:0;display:flex;flex-wrap:nowrap;justify-content:flex-end;
  gap:10px clamp(14px,2.4vw,38px);align-items:baseline}
#nav a{position:relative;padding:4px 0;font-family:var(--poster);font-weight:900;
  font-variation-settings:"wdth" 112;font-size:clamp(13px,1.5vw,19px);letter-spacing:.035em;
  text-transform:uppercase;opacity:1;transition:opacity .3s,color .3s}
#nav a:last-child{margin-right:-.035em}
#nav a::after{content:"";position:absolute;left:0;right:100%;bottom:-2px;height:2px;background:var(--red);
  transition:right .45s var(--tick)}
#nav a:hover,#nav a[data-on="1"]{opacity:1}
#nav a:hover::after,#nav a[data-on="1"]::after{right:0}
/* telefon: w menu trzy linki, na całą szerokość w jednej linii (rozmiar liczony z szerokości ekranu,
   a w JS dodatkowo dopasowywany do faktycznej szerokości); „najbliższa impreza" — zaraz pod nimi, wyśrodkowana */
@media(max-width:600px){
  #hdr{flex-wrap:wrap;align-items:flex-start;row-gap:15px;padding:14px var(--gut) 0}
  #nav{order:1;flex:0 0 100%;margin:0;gap:0;justify-content:space-between}
  #nav a{font-size:var(--navfs,min(15px,calc((100vw - 2 * var(--gut) - 16px) / 22)))}
  #hdr .tonight{order:2;flex:0 0 100%;justify-content:center}
}

/* ================= HERO ================= */
/* 94vh — u dołu widać skrawek następnej sekcji, to on ciągnie do scrolla */
#hero{position:relative;min-height:94vh;display:flex;flex-direction:column;
  justify-content:flex-end;padding:calc(var(--hdr) + 34px) 0 clamp(48px,7vh,90px);
  overflow:hidden}
/* telefon: gap hero → o nas o połowę mniejszy (sekcja o nas zaczyna się zaraz pod logo) */
@media(max-width:760px){ #hero{padding-bottom:clamp(12px,1.75vh,22px)} }
#heroBg{position:absolute;inset:0;z-index:0}
#heroBg::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(11,11,13,.5) 0%,rgba(11,11,13,.08) 46%,rgba(11,11,13,0) 100%)}
.tonight{--dot:var(--red);display:inline-flex;align-items:center;gap:10px;color:var(--bone);flex:none}
.tonight.live{--dot:#1FE06A}                                   /* klub otwarty: trwa wydarzenie z kolekcji (start ≤ teraz < end) */
.tonight i{position:relative;width:8px;height:8px;border-radius:50%;background:var(--dot);flex:none;transition:background .6s}
/* fala pulsu: transform + opacity (kompozytor), a nie box-shadow — ta animacja co klatkę przemalowywała nagłówek */
.tonight i::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--dot);
  opacity:0;animation:pulseDot 2.6s ease-out infinite}
@keyframes pulseDot{
  0%{transform:scale(1);opacity:.55}
  70%,100%{transform:scale(3.75);opacity:0}
}
/* normalne, duże, białe logo na środku dołu — bez rozlewania poza ekran */
/* od lewej krawędzi pierwszego elementu menu do prawej krawędzi ostatniego — te same marginesy --gut */
.hero-lockup{position:relative;z-index:2;width:calc(100% - 2 * var(--gut));margin:0 auto}
.hero-words{display:block;width:100%;height:auto;fill:currentColor;color:var(--bone);
  margin-bottom:clamp(10px,1.8vh,22px)}
.hero-mark{display:block;width:100%;height:auto;fill:currentColor;color:var(--bone)}

/* ================= O NAS (AUTOMAT) ================= */
/* Automat ze strony /koncerty jako "ekran" sekcji O nas: na ekranie ziarnem (bayer 8, #FF0000/#000) wywołuje się
   zdjęcie aktywnego poziomu, przy zmianie — błysk statyki jak przy przełączaniu kanału. Tekst ekranu (menu, OSD)
   leży na nim przez matrix3d, z czerwonym poświatą CRT. Desktop (> 760px): scena przypięta na 440vh scrolla, 4
   poziomy w menu gry. Telefon (≤ 760px): sekcja przypięta, na pierwszych ~360px scrolla kamera "wjeżdża" w ekran
   automatu, dalej scroll strony 1:1 przewija kolumnę WEWNĄTRZ ekranu (menu → 4 poziomy → "Continue?" z przyciskiem
   rezerwacji), na końcu kamera odjeżdża. Cały tekst stoi na czarnym ekranie — nic nie nachodzi na zdjęcie ani obudowę.
   Współdzieli tło/welon/ziarno strony (#fx/#veil/#grain) i tokeny (--red/--ink/--bone/--steel/--hair/--gut/--tick/
   --punch/.lbl/.pf) z resztą strony — bez własnych duplikatów. --col (odstęp kolumn siatki 12-kolumnowej sceny
   desktopowej) jest lokalny dla #onas, bo poza tym komponentem nic z tej siatki nie korzysta. */
#onas{--col:clamp(12px,1.6vw,28px)}
#onas em{font-style:normal;color:var(--red)}                    /* "Continue? 9" na końcu ekranu telefonu */
/* tekst dekodowany z szumu (JS "shield") zostawia dwie kopie: tę czytają czytniki ekranu (chowamy wizualnie),
   drugą, widoczną, JS przepisuje z szumu na docelowy tekst */
.sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.oa-wrap{padding-inline:var(--gut)}
.oa-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--col)}
.oa-w{display:inline;transition:opacity .25s linear}             /* pojedyncze słowo w tekście dekodowanym z szumu (JS) */
.lvl p,.stat-k{text-shadow:0 0 14px rgba(11,11,13,.95),0 0 3px rgba(11,11,13,.9)}

/* ---- automat: pudełko, które rysuje #fxl (desktop); tekst ekranu nałożony przez matrix3d ---- */
/* fixed, jak #fx/#veil/#grain — bez tego canvas siedzi w normalnym przepływie i (po tym, jak JS ustawi mu
   atrybuty width/height na rozmiar okna) spycha całą resztę strony w dół o wysokość viewportu */
#fxl{position:fixed;inset:0;z-index:2;width:100%;height:100%;display:block;pointer-events:none}
.arc{position:relative;display:block;aspect-ratio:1300/1600;height:min(96vh,123.2vw);max-width:100%;margin-inline:auto}
.arc-fb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top;opacity:0}
html.nofx .arc-fb{opacity:1}
.scr{position:absolute;left:0;top:0;width:1000px;height:700px;transform-origin:0 0;pointer-events:none;
  font-family:var(--poster);font-variation-settings:"wdth" 70;font-weight:800;text-transform:uppercase;color:var(--bone);
  text-shadow:0 0 10px rgba(255,26,26,.85),0 0 2px rgba(255,255,255,.6);letter-spacing:.04em}
.scr .row{position:absolute;left:44px;right:44px;display:flex;justify-content:space-between;align-items:center;font-size:40px}
.scr .top{top:34px}
.scr .bot{bottom:34px}
.blink{animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.scr .menu{position:absolute;left:0;top:0;bottom:0;width:56%;padding:118px 44px 0;
  background:linear-gradient(90deg,rgba(0,0,0,.72),rgba(0,0,0,.45) 80%,rgba(0,0,0,0));display:grid;align-content:start;gap:14px}
.scr .menu h5{margin:0 0 12px;font-size:36px;color:var(--steel);font-weight:800}
.scr .menu span{display:block;font-size:48px;padding:6px 12px;line-height:1}
.scr .menu span.on{background:var(--red);color:var(--bone);text-shadow:none}
.scr .menu span.on::before{content:"▶ "}

/* ============ DESKTOP (> 760px) — menu gry: przypięta scena, poziomy ============ */
.mod-b{position:relative;height:220vh}
/* welon sekcji leży pod warstwą, którą rysuje #fxl (automat + zdjęcia) — tekst jest nad nim */
.mod-b::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,11,13,0) 0,rgba(11,11,13,.32) 14%,rgba(11,11,13,.32) 86%,rgba(11,11,13,0) 100%)}
.b-stage{position:sticky;top:0;height:100vh;z-index:3}
.b-inner{height:100%;align-items:center}
.b-arc-col{grid-column:1 / span 6;display:grid;justify-items:center}
.b-arc-col .arc{height:min(98vh,123.2vw)}
/* container-type — nie vw: "Rezydenci" (najdłuższe pojedyncze słowo poziomu) przy 7vw wychodził poza kolumnę
   na szerokościach ~1280–1536px (kolumna rośnie wolniej niż całe okno). Skalowanie do WŁASNEJ szerokości panelu
   (cqw) samo pilnuje, żeby się zmieściło na każdej szerokości — i zostanie bezpieczne, gdy treść się zmieni */
.b-panel{container-type:inline-size;grid-column:7 / span 6;display:grid;gap:clamp(14px,2.4vh,26px);align-content:center}
.b-rail{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}
.b-rail i{height:4px;background:rgba(239,237,233,.2);transition:background .35s}
.b-rail i.on{background:var(--red)}
.lvls{position:relative;height:clamp(360px,54vh,560px)}
.lvl{position:absolute;left:0;right:0;top:0;opacity:0;transition:opacity .16s linear;display:grid;gap:clamp(12px,2vh,20px);align-content:start}
.lvl.on{opacity:1;transition:opacity .34s var(--tick) .14s}
.lvl .k{color:var(--red)}
/* --tem = szerokość najdłuższej linii tytułu w em (liczy serwer, szum_em_width()); min() zmniejsza literę tylko wtedy,
   gdy tytuł wpisany w panelu "Treść strony" nie mieści się w panelu (dla domyślnych tytułów 12cqw jest mniejsze, więc bez zmian) */
.lvl h3{margin:0;font-size:min(clamp(52px,12cqw,132px),calc(96cqw / var(--tem,7.2)))}
.lvl h3 span{display:block;white-space:nowrap}
.lvl h3 [data-bscr] + [data-bscr]{margin-top:.2em}   /* tytuły dwuliniowe ("Dwa/parkiety", "Do/świtu") — celujemy w zewnętrzne
  opakowania słów (nie w "span+span" ogólnie — shield() w JS owija każde słowo w .sr + widoczny span, więc zwykłe
  "span+span" łapało też TĘ parę wewnątrz jednego słowa); --pf ma line-height .84, za ciasno na tak duży stopień */
.lvl p{margin:0;max-width:40ch;font-size:clamp(16px,1.3vw,20px);line-height:1.5}
.stat{display:flex;align-items:flex-end;gap:18px;margin-top:6px;padding-top:16px;border-top:1px solid var(--hair)}
.stat-n{font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 122;letter-spacing:-.045em;line-height:.8;
  font-size:clamp(56px,12cqw,130px);font-variant-numeric:tabular-nums;white-space:nowrap}
.stat-n sup{font-size:.3em;vertical-align:top;letter-spacing:-.02em}
.stat-n sup.u{vertical-align:baseline}   /* "h" (godziny) to nie wykładnik jak m² — stoi przy liczbie, nie nad nią */
.stat-k{color:var(--steel);font-size:clamp(13px,1vw,15px);line-height:1.4;max-width:20ch;padding-bottom:6px}
.b-hint{color:var(--steel);display:none}

/* ============ TELEFON (≤ 760px) — cała sekcja dzieje się na ekranie automatu ============
   automat = zwykły <img>; WebGL tylko w prostokącie ekranu (#fxl na desktopie w ogóle się nie tworzy — patrz JS);
   tekst ekranu = DOM w matrix3d. Scena przypięta (sticky) → nic nie "goni" strony; scroll strony 1:1 przesuwa
   kolumnę w ekranie. */
.mob{display:none;position:relative}
/* kiedyś spacer 28px + safe-area nad notchem — z czasów samodzielnego prototypu automatu, gdy sekcja otwierała stronę.
   W stronie głównej sekcja leży pod hero, więc to była tylko martwa przerwa (na iPhonie z wyspą nawet ~75px) między
   znakiem hero a automatem; odstęp od notcha załatwia teraz sam start kadru (patrz S.up w JS) */
.m-head{position:relative;z-index:3;height:0}
.m-track{position:relative;height:calc(100vh + var(--run,1400px));height:calc(100svh + var(--run,1400px))}
.m-stage{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;z-index:3}
.m-track::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,11,13,0) 0,rgba(11,11,13,.28) 18%,rgba(11,11,13,.28) 82%,rgba(11,11,13,0) 100%)}
.m-stage::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 85% 60% at 50% 46%,rgba(11,11,13,.31),rgba(11,11,13,0) 80%)}
.m-cab{position:absolute;left:0;top:0;width:143vw;aspect-ratio:1192/1600}
.m-img,.m-gl{position:absolute;display:block;pointer-events:none;-webkit-user-select:none;user-select:none}
.m-img{inset:0;width:100%;height:100%}
.m-scr{position:absolute;left:0;top:0;width:320px;height:250px;transform-origin:0 0;overflow:hidden;opacity:0;--u:1;
  color:var(--bone);font-family:var(--ff);-webkit-tap-highlight-color:transparent}
.m-nogl .m-scr{background:#070708}
.m-bar{position:absolute;left:0;right:0;z-index:2;height:calc(24px*var(--u));display:flex;align-items:center;justify-content:space-between;
  gap:calc(10px*var(--u));padding:0 calc(11px*var(--u));background:#060607;white-space:nowrap;
  font-family:var(--poster);font-variation-settings:"wdth" 72;font-weight:800;font-size:calc(9.5px*var(--u));
  letter-spacing:.1em;text-transform:uppercase;text-shadow:0 0 8px rgba(255,26,26,.85)}
.m-top{top:0;box-shadow:0 1px 0 rgba(255,26,26,.45)}
.m-bot{bottom:0;box-shadow:0 -1px 0 rgba(255,26,26,.45)}
.m-rail{flex:1;max-width:58%;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:calc(3px*var(--u))}
.m-rail i{position:relative;height:3px;overflow:hidden;background:rgba(239,237,233,.18)}
.m-rail b{position:absolute;inset:0;background:var(--red);transform-origin:0 50%;transform:scaleX(0)}
.m-view{position:absolute;left:0;right:0;top:calc(24px*var(--u));bottom:calc(24px*var(--u));overflow:hidden}
.m-col{position:relative}
.m-card{padding:calc(12px*var(--u)) calc(12px*var(--u)) calc(18px*var(--u))}
.m-card + .m-card{border-top:1px dashed rgba(239,237,233,.18)}
.m-start,.m-end{min-height:var(--vv,200px);display:flex;flex-direction:column;justify-content:center}
.m-k{font-size:calc(8.5px*var(--u));font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--red)}
/* 296u = szerokość ekranu automatu (320u) minus padding karty; --tem = szerokość całego tytułu w em (serwer) — dłuższy tytuł
   kurczy się, zamiast wyjechać poza ekran (domyślne „Activity Spot” 9,1 em mieści się przy 29u, więc nic się nie zmienia) */
.m-card h3{margin:calc(9px*var(--u)) 0 calc(7px*var(--u));font-size:min(calc(29px*var(--u)),calc(296px*var(--u) / var(--tem,9.2)));white-space:nowrap;text-shadow:0 0 14px rgba(255,26,26,.4)}
.m-card h3 em{font-style:normal;color:var(--red)}
.m-card p{margin:0;font-size:calc(12.5px*var(--u));line-height:1.42;color:#DDDAD4}
.m-ph{position:relative;height:calc(108px*var(--u));background-size:cover;background-position:center 45%}
.m-nogl .m-ph{filter:grayscale(1) contrast(1.25) brightness(.8)}
.m-tag{position:absolute;left:0;top:0;padding:calc(4px*var(--u)) calc(6px*var(--u));background:#060607;color:var(--red);
  font-size:calc(8.5px*var(--u));font-weight:700;letter-spacing:.16em;line-height:1;text-transform:uppercase}
.m-stat{display:flex;align-items:flex-end;gap:calc(10px*var(--u));margin-top:calc(10px*var(--u));padding-top:calc(9px*var(--u));border-top:1px solid var(--hair)}
.m-stat b{font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 122;letter-spacing:-.045em;line-height:.8;
  font-size:calc(30px*var(--u));font-variant-numeric:tabular-nums;white-space:nowrap}
.m-stat sup{font-size:.34em;vertical-align:top;letter-spacing:-.02em}
.m-stat sup.u{vertical-align:baseline}
.m-stat > span{font-size:calc(10px*var(--u));line-height:1.3;color:var(--steel)}
.m-menu{list-style:none;margin:calc(4px*var(--u)) 0 calc(10px*var(--u));padding:0;display:grid;gap:calc(2px*var(--u))}
.m-menu a{display:flex;justify-content:space-between;gap:10px;padding:calc(5px*var(--u)) calc(7px*var(--u));
  font-family:var(--poster);font-variation-settings:"wdth" 72;font-weight:800;font-size:calc(12.5px*var(--u));
  letter-spacing:.07em;text-transform:uppercase;line-height:1}
.m-menu a span:last-child{color:var(--steel)}
.m-menu li[data-on] a{background:var(--red)}
.m-menu li[data-on] a span:first-child::before{content:"▶ "}
.m-menu li[data-on] a span:last-child{color:var(--bone)}
.m-press{margin-top:auto;font-family:var(--poster);font-variation-settings:"wdth" 72;font-weight:800;font-size:calc(10px*var(--u));
  letter-spacing:.12em;text-transform:uppercase;text-shadow:0 0 8px rgba(255,26,26,.85)}
.m-start .m-press{margin-top:0}
.m-cta{align-self:flex-start;display:inline-flex;align-items:center;gap:8px;margin-top:calc(12px*var(--u));
  padding:calc(9px*var(--u)) calc(12px*var(--u));background:var(--red);color:var(--bone);
  font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 112;font-size:calc(12px*var(--u));
  letter-spacing:.06em;text-transform:uppercase}
.m-cta i{font-style:normal}
.m-fx{position:absolute;inset:0;z-index:3;pointer-events:none;background:
  repeating-linear-gradient(0deg,rgba(0,0,0,.22) 0 1px,rgba(0,0,0,0) 1px 3px),
  linear-gradient(118deg,rgba(255,255,255,0) 36%,rgba(255,255,255,.055) 47%,rgba(255,255,255,0) 60%),
  radial-gradient(ellipse 80% 75% at 50% 50%,rgba(0,0,0,0) 58%,rgba(0,0,0,.55) 100%)}
.m-hint{position:absolute;left:0;right:0;bottom:calc(26px + env(safe-area-inset-bottom,0px));text-align:center;color:var(--steel);pointer-events:none;display:none}

@media(max-width:760px){
  #onas{--col:12px}
  #b,#fxl{display:none}
  .mob{display:block}
}

/* ================= IMPREZY ================= */
#imprezy{position:relative;padding:clamp(70px,12vh,160px) var(--gut) calc(clamp(70px,12vh,160px) + 38px)}   /* +38px = miejsce po usuniętym podpisie CMS — odstęp kart od Koncertów bez zmian */
/* telefon: gap o nas → imprezy o połowę mniejszy (tylko góra — dół ma swoje odstępy do Koncertów, niżej) */
@media(max-width:760px){ #imprezy{padding-top:clamp(17px,3vh,40px)} }
.imp-top{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap;
  margin-bottom:clamp(26px,4.5vh,52px)}
.imp-top h2{margin:0;font-size:clamp(46px,11vw,150px)}
.imp-top .mo{font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 108;
  font-size:clamp(18px,2.4vw,34px);letter-spacing:-.025em;text-transform:uppercase;opacity:.5}
.imp-cols{display:grid;grid-template-columns:minmax(0,1.62fr) minmax(0,1fr);gap:clamp(14px,2.4vw,32px);align-items:stretch}
@media(max-width:940px){.imp-cols{grid-template-columns:1fr}}
.card{background:var(--bone);color:var(--ink);padding:clamp(20px,2.8vw,38px);display:flex;flex-direction:column}
.card.red{background:var(--red);color:var(--bone)}
/* wyrównanie do góry: wierzch liter tytułu = wierzch kwadracika z datą (patrz .ev .t b);
   w rozciągniętych wierszach pop-upów cała zawartość zostaje wyśrodkowana w pionie */
.ev{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(14px,2vw,28px);align-items:start;align-content:center;
  padding:clamp(13px,1.8vh,20px) 0;border-bottom:1px solid rgba(23,23,24,.16);
  transition:padding-left .45s var(--tick)}
.ev:last-of-type{border-bottom:0}
.ev:hover{padding-left:10px}
.card.red .ev{border-color:rgba(239,237,233,.3)}
/* pop-upy: lista rozciągnięta na całą wysokość karty, wiersze równe i równo do krawędzi — jak w Dance Floor */
.card.red #popList{flex:1;display:flex;flex-direction:column}
.card.red #popList .ev{flex:1}
/* stała szerokość w obu kartach — inaczej zakresy dat w pop-upach rozjeżdżają kolumny */
.chip{background:var(--red);color:var(--bone);padding:7px 9px;
  width:clamp(88px,10.5vw,120px);flex:none;text-align:center;
  font-variant-numeric:tabular-nums;line-height:1.1}
.chip b{display:block;font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 108;
  font-size:clamp(15px,1.7vw,20px);letter-spacing:.015em}
.chip em{font-style:normal;display:block;font-size:10px;font-weight:400;opacity:.85;margin-top:2px}
.card.red .chip{background:var(--ink)}
/* zakres dat jest dłuższy, więc odrobinę mniejszy stopień — wiersze zostają wyrównane */
.card.red .chip b{font-size:clamp(13px,1.45vw,17px)}
.ev .t b{display:block;font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 108;
  font-size:clamp(17px,2.2vw,28px);letter-spacing:-.028em;text-transform:uppercase;line-height:1.06;
  margin-top:-.155em} /* zapas: ≈ odstęp od góry linii do górnej krawędzi wersalików Archivo 900 */
/* nowoczesne przeglądarki: obcięcie do wysokości wersalików — dokładnie, bez zgadywania */
@supports (text-box-trim:trim-start){
  .ev .t b{margin-top:0;text-box-trim:trim-start;text-box-edge:cap alphabetic}
}
.ev .t b sup{font-family:var(--ff);font-size:.42em;font-weight:700;opacity:.55;margin-left:7px;
  letter-spacing:.06em;vertical-align:super;text-transform:uppercase;line-height:0}
.ev .t span{display:block;font-family:var(--ff);font-weight:500;
  font-size:clamp(12.5px,1.35vw,16px);opacity:.62;margin-top:7px;letter-spacing:.005em}
.card.red .ev .t span{opacity:.82}
.ev-empty{margin:0;padding:clamp(24px,4vh,48px) 0;font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 108;
  font-size:clamp(17px,2.2vw,28px);letter-spacing:-.028em;text-transform:uppercase;opacity:.5}
.card-foot{margin-top:auto;padding-top:clamp(22px,3.4vh,40px);display:flex;align-items:flex-end;
  justify-content:space-between;gap:16px}
.punkt{display:flex;align-items:center;gap:9px}
.punkt::before{content:"";width:13px;height:13px;border-radius:50%;border:3px solid currentColor;flex:none}
.card-foot .mark{width:72px}

/* ================= KONCERTY ================= */
/* bez overflow:hidden — cień plakatów (26px w dół + 64px rozmycia) przechodzi przez granicę sekcji zamiast być ucięty prostą linią;
   same plakaty i tak nie wychodzą poza sekcję (limit w JS), a pulsy tła przycina #konField */
#koncerty{position:relative;min-height:86vh;display:grid;place-items:center;
  padding:calc(var(--hdr) + 40px) var(--gut) 73px}
/* telefon: sekcja o 30% niższa niż dotąd (86vh × 70%); gap od Imprezy mniejszy (góra: 104px → 72px) */
@media(max-width:600px){ #koncerty{min-height:60.2vh;padding-top:calc(var(--hdr) + 8px)} }
#konField{position:absolute;inset:0;z-index:0;overflow:hidden}
/* ciemne tylko pod znakiem, przezroczyste przy krawędziach — bez szwu z sąsiadami */
#konVeil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(58% 54% at 50% 48%,rgba(11,11,13,.6),rgba(11,11,13,0) 78%)}
#stageWrap{position:absolute;inset:0;z-index:2;perspective:1250px;perspective-origin:50% 48%}
#stage3d{position:absolute;inset:0;transform-style:preserve-3d;will-change:transform}
.poster{position:absolute;left:50%;top:50%;width:clamp(92px,12vw,168px);aspect-ratio:3/4;
  margin:-8% 0 0 -6%;transform-style:preserve-3d;will-change:transform;overflow:hidden;
  background:var(--ink);box-shadow:0 26px 64px rgba(0,0,0,.66);border:1px solid rgba(239,237,233,.1);cursor:pointer}
.poster canvas{position:absolute;inset:0;width:100%;height:100%;opacity:.92}
.poster .pt{position:absolute;inset:0;padding:10px;display:flex;flex-direction:column;
  justify-content:space-between;color:var(--bone);
  background:linear-gradient(180deg,rgba(11,11,13,.08),rgba(11,11,13,.8))}
.poster .pt b{font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 106;
  font-size:clamp(11px,1.3vw,16px);line-height:.94;letter-spacing:-.025em;text-transform:uppercase}
.poster .pt .d{font-size:8.5px;font-weight:700;letter-spacing:.16em;color:var(--red)}
/* znak i słowo to jeden blok: ta sama szerokość (dopasowana w JS) i ten sam kolor */
#konBtn{position:relative;z-index:4;cursor:pointer;
  display:grid;gap:clamp(10px,1.8vh,22px);justify-items:stretch;width:min(56vw,620px);
  color:var(--bone);transition:color .45s var(--tick)}
#konBtn .mark{display:block;width:100%;transition:transform .7s var(--tick)}
#konBtn .word{display:block;width:100%;white-space:nowrap;text-align:center;
  font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 122;
  font-size:clamp(30px,7.4vw,96px);line-height:.86;text-transform:uppercase;
  color:inherit;position:relative}
#konBtn .wtxt{display:inline-block;white-space:nowrap}
#konBtn:hover{color:var(--red)}
#konBtn:hover .mark{transform:translateY(-7px)}

/* ================= GALERIA ================= */
/* przewijane rzędy zdjęć + kula dyskotekowa na środku */
#media{position:relative;padding:clamp(20px,3.5vh,44px) 0}
#galBox{position:relative;height:clamp(1140px,174vh,1920px);overflow:hidden;contain:layout paint}
/* trzy rzędy zdjęć: siatka dzieli wysokość na 3 równe rzędy z odstępem 11 px; rząd przesuwa animacja CSS
   transform — robi ją kompozytor (GPU), więc na wątku głównym nie dzieje się nic: zero JS na klatkę */
#gal{position:absolute;inset:0;display:grid;grid-template-rows:repeat(3,minmax(0,1fr));gap:11px;padding:11px 0;
  opacity:0;transition:opacity 1s var(--tick)}
#gal.on{opacity:1}
.g-row{position:relative;overflow:hidden;min-height:0}
.g-track{display:flex;height:100%;width:max-content;will-change:transform;
  animation:gSlide var(--dur,60s) linear infinite}
@keyframes gSlide{from{transform:translate3d(0,0,0)}to{transform:translate3d(calc(var(--cycle) * -1),0,0)}}
#gal.off .g-track{animation-play-state:paused}
.g-t{flex:none;height:100%;margin-right:11px;background:#0A0A0C;overflow:hidden}
.g-t.l{aspect-ratio:1.35 / 1}
.g-t.p{aspect-ratio:3 / 4}
.g-t img{display:block;width:100%;height:100%;max-width:none;object-fit:cover;opacity:0;transition:opacity .7s}
.g-t img.ok{opacity:1}
@media(prefers-reduced-motion:reduce){ .g-track{animation:none} }
/* kula dyskotekowa (Three.js): STAŁY rozmiar, na środku galerii — 420×420 px na telefonie i tablecie, 2,5× większa (1050×1050 px) na komputerze (okno ≥1024 px);
   nie łapie dotyku ani myszy — strona się normalnie przewija */
#ball{position:absolute;left:50%;top:50%;width:420px;height:420px;max-width:none;margin:-210px 0 0 -210px;
  pointer-events:none;opacity:0;transition:opacity 1s var(--tick)}
#ball.on{opacity:1}
@media(min-width:1024px){ #ball{width:1050px;height:1050px;margin:-525px 0 0 -525px} }
@media(max-width:600px){
  #galBox{height:clamp(750px,108vh,900px)}
  #media{padding-top:calc(clamp(20px,3.5vh,44px) + 16px)}                 /* koncerty → galeria: odrobinę więcej */
  #imprezy{padding-bottom:calc(clamp(70px,12vh,160px) + 26px)}            /* imprezy → koncerty: odrobinę mniej (−12px względem desktopu) */
}
/* wąskie telefony: usunięty podpis CMS zajmował tam dwie linie (+10 px) */
@media(max-width:385px){ #imprezy{padding-bottom:calc(clamp(70px,12vh,160px) + 36px)} }

/* ================= REZERWACJE ================= */
/* tło sekcji jest przezroczyste — widać wspólne tło strony (#fx). Po lewej tekst, po prawej plan lóż, który zawsze obraca się w stronę
   kursora (3D, patrz skrypt „plan lóż"). Funkcjonalna rezerwacja żyje na zewnętrznym serwisie — tu tylko wizytówka z linkiem wychodzącym */
#rezerwacje{position:relative;padding:clamp(63px,10.8vh,126px) var(--gut) clamp(70px,12vh,140px)}
/* tekst i plan stoją obok siebie, jako jedna grupa wyśrodkowana na stronie (kolumny mają szerokość treści, nie rozciągają się na brzegi) */
.rez-grid{display:grid;grid-template-columns:auto auto;grid-template-rows:1fr auto auto 1fr;justify-content:center;column-gap:clamp(36px,5vw,90px)}
/* wiersze siatki: rozpórka · tekst · przycisk · rozpórka; plan obejmuje wszystkie cztery, więc tekst z przyciskiem stoi na środku jego wysokości.
   Na telefonie ta sama siatka składa się w jedną kolumnę: tekst › plan › przycisk (patrz @media na końcu sekcji) */
.rez-in{grid-column:1;grid-row:2;display:grid;justify-items:start;gap:clamp(14px,2.4vh,26px);max-width:720px;color:var(--bone);text-shadow:0 1px 18px rgba(11,11,13,.45)}
/* bez kickera nad nim ten nagłówek jest teraz pierwszą rzeczą, na którą pada wzrok — trochę większy i ciaśniejszy niż
   poprzednio (był skalibrowany pod sąsiedztwo etykiety, teraz stoi sam) */
/* --rl = szerokość najdłuższej linii nagłówka w em (liczy serwer z realnych szerokości liter, patrz szum_em_width());
   drugi człon min() dopasowuje rozmiar do wolnej szerokości kolumny tekstu (max 720px, minus plan lóż obok), więc
   edytor może wpisać dłuższe słowo bez wyjechania nagłówka na obrazek. Dla domyślnego „Loże VIP” (3,18 em) nie działa. */
.rez-h{margin:0;font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 122;
  font-size:min(clamp(66px,10.6vw,164px),calc(min(720px,100vw - 2 * var(--gut) - clamp(36px,5vw,90px) - min(75vh,760px) * .5625) / var(--rl,3.2)));
  line-height:.86;letter-spacing:-.035em;text-transform:uppercase}
.rez-h .mask{display:block;overflow:hidden;padding:0 .04em .1em;margin:0 -.04em -.1em}
.rez-h .ln{display:block}
.rez-sub{display:none}
.rez-p{margin:0;max-width:46ch;font-size:clamp(15px,1.7vw,19px);line-height:1.5;color:var(--steel);letter-spacing:.002em}
.rez-cta{grid-column:1;grid-row:3;justify-self:start;margin-top:calc(clamp(14px,2.4vh,26px) + 6px);display:inline-flex;align-items:center;gap:10px;
  background:var(--bone);color:var(--ink);padding:16px 26px;
  font-family:var(--poster);font-weight:900;font-variation-settings:"wdth" 112;
  font-size:clamp(14px,1.5vw,17px);letter-spacing:.05em;text-transform:uppercase;
  transition:transform .35s var(--tick),background .35s,color .35s}
.rez-cta i{font-style:normal;transition:transform .35s var(--tick)}
.rez-cta .m{display:none}
/* adres rezerwacji jeszcze nie ustawiony (wp-admin → Treść strony → Rezerwacje): przycisk bez href, nieaktywny — zamiast "#", które przewijało stronę na górę */
.rez-cta[aria-disabled="true"]{cursor:default;pointer-events:none}
/* najechanie tylko tam, gdzie jest kursor — na dotyku „lepiłoby się" po kliknięciu */
@media(hover:hover){
  .rez-cta:hover{transform:translateY(-3px);background:var(--ink);color:var(--bone)}
  .rez-cta:hover i{transform:translateX(4px)}
}
/* plan lóż — dwustronna karta 3D: przód = plan, tył = ten sam plan z opisami sal; klik obraca kartę o 180° (animacja WAAPI, sam transform → kompozytor/GPU).
   Warstwy: .rez-stage (perspektywa) › .rez-card (przechył za kursorem, JS) › .rez-lift (wyniesienie ku widzowi na czas obrotu) › .rez-flip (sam obrót) › .rez-face ×2 (backface-visibility:hidden).
   Obrót i wyniesienie to dwie osobne animacje na dwóch warstwach — dzięki temu obrót ma jedną, ciągłą krzywą prędkości (bez przystanku w połowie).
   Cień leży na ściankach, nie na karcie — obraca się razem z nimi i znika, gdy ścianka jest tyłem do widza */
.rez-vis{grid-column:2;grid-row:1 / 5;align-self:center;display:grid;justify-items:center;gap:clamp(14px,2.2vh,22px);cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}
.rez-stage{perspective:1100px}
.rez-card{position:relative;height:min(75vh,760px);aspect-ratio:9 / 16;transform-style:preserve-3d;will-change:transform}
.rez-lift,.rez-flip{position:absolute;inset:0;transform-style:preserve-3d}
.rez-face{position:absolute;inset:0;overflow:hidden;background:#171718;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  box-shadow:0 34px 90px rgba(0,0,0,.55),0 0 0 1px rgba(239,237,233,.1)}
.rez-back{transform:rotateY(180deg)}
.rez-face img{display:block;width:100%;height:100%;max-width:none;object-fit:cover}
.rez-back img{opacity:0;transition:opacity .5s}
.rez-back img.ok{opacity:1}
/* połysk za kursorem: mały kwadrat z miękkim gradientem (nie 200% karty — kilkanaście razy mniej pamięci GPU), przesuwany transformem */
.rez-glare{position:absolute;left:50%;top:50%;width:90%;aspect-ratio:1;pointer-events:none;will-change:transform;transform:translate3d(-50%,-50%,0);
  background:radial-gradient(closest-side,rgba(255,255,255,.14),rgba(255,255,255,0))}
/* błysk przebiegający po odsłanianej ściance w trakcie obrotu — istnieje jako warstwa tylko na czas animacji */
.rez-sheen{position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,rgba(255,255,255,0) 32%,rgba(255,255,255,.36) 48%,rgba(255,255,255,.1) 56%,rgba(255,255,255,0) 70%)}
.rez-hint{display:none;align-items:center;gap:9px;font-size:10px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--bone);text-shadow:0 1px 14px rgba(11,11,13,.5);transition:opacity .35s}
.rez-hint i{font-style:normal;font-size:16px;line-height:1;display:inline-block;transition:transform .7s var(--tick)}
.rez-vis:hover .rez-hint i{transform:rotate(180deg)}
.rez-vis.flipping .rez-hint{opacity:0}
@media(max-width:900px){
  #rezerwacje{padding:clamp(49px,7.65vh,76px) var(--gut) clamp(50px,7.5vh,76px)}
  /* jedna kolumna: tekst › plan › przycisk. Wszystkie trzy dzielą szerokość --rez-w (cała szerokość treści, ale nie więcej niż 400 px,
     a na niskim ekranie węższa, by plan 9:16 zajmował najwyżej ~78% jego wysokości) — przycisk nie ma jak wyjść poza kartę */
  .rez-grid{--rez-w:min(100%,400px,44svh);grid-template-columns:minmax(0,1fr);grid-template-rows:none;justify-content:stretch}
  .rez-in,.rez-vis,.rez-cta{grid-column:1;grid-row:auto;justify-self:center;width:var(--rez-w)}
  /* nagłówek w jednej linii, dopasowany do szerokości bloku (cqw); kolejność: etykieta › tytuł › podtytuł › tekst */
  .rez-in{container-type:inline-size;justify-items:stretch;gap:0;margin-bottom:clamp(18px,3vh,26px)}
  /* telefon: oba słowa w jednej linii — --rem = ich łączna szerokość w em (+ odstęp .26em); 5,95 to pojemność dla „Loże VIP” */
  .rez-h{display:flex;align-items:flex-end;gap:.26em;white-space:nowrap;font-size:15vw;font-size:calc(100cqw / max(var(--rem,5.67),5.95));line-height:.86}
  .rez-sub{display:flex;flex-wrap:wrap;align-items:center;gap:6px 9px;margin-top:clamp(12px,1.9vh,16px);font-size:11px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--bone);opacity:.72}
  .rez-sub i{flex:none;width:5px;height:5px;background:var(--red)}
  .rez-p{max-width:none;margin-top:clamp(10px,1.6vh,14px);font-size:14px;line-height:1.5}
  /* karta wypełnia całą szerokość bloku; podpisu „kliknij" na telefonie nie ma */
  .rez-vis{gap:0}
  .rez-stage{width:100%}
  .rez-card{height:auto;width:100%}
  .rez-face{box-shadow:0 22px 56px rgba(0,0,0,.5),0 0 0 1px rgba(239,237,233,.1)}   /* mniejszy cień = mniej pikseli do wypełnienia przy obrocie na telefonie */
  .rez-hint{display:none}
  /* przycisk pod kartą: pełna szerokość karty minus 12 px z każdej strony — kołysanie karty (±6°) cofa jej dolną krawędź nawet o ~7 px,
     ten zapas gwarantuje, że przycisk nigdy nie wystaje poza obraz. Wszystko, co się w nim rusza, jest przycięte przez overflow:hidden */
  .rez-cta{--rez-arrow:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 12'%3E%3Cpath d='M0 6h20M15 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='square'/%3E%3C/svg%3E");
    position:relative;isolation:isolate;overflow:hidden;width:calc(var(--rez-w) - 24px);height:58px;margin-top:clamp(14px,2.2vh,20px);padding:0;gap:0;
    justify-content:space-between;font-size:15px;-webkit-tap-highlight-color:transparent;transition:transform .3s var(--tick)}
  .rez-cta .lb{position:relative;z-index:2;display:flex;align-items:center;min-width:0;padding:0 clamp(16px,5vw,22px);white-space:nowrap}   /* napis nad połyskiem — zostaje ostry */
  .rez-cta .d{display:none}
  .rez-cta .m{display:inline}
  .rez-cta i{position:relative;overflow:hidden;flex:none;align-self:stretch;width:58px;display:grid;place-items:center;background:var(--red);color:var(--bone)}
  .rez-cta:hover i{transform:none}
  /* strzałka rysowana maską SVG (ostra, kwadratowe końce jak w przycisku „do góry"), dwie kopie: jedna wyjeżdża, druga wjeżdża */
  .rez-cta i b,.rez-cta i::after{content:"";display:block;width:22px;height:12px;background:currentColor;
    -webkit-mask:var(--rez-arrow) center/contain no-repeat;mask:var(--rez-arrow) center/contain no-repeat}
  .rez-cta i b{font-size:0}
  .rez-cta:active{transform:scale(.985)}
  /* animacja przycisku (tylko transform, kompozytor; pauzowana poza ekranem klasą .off): raz na 4,8 s po przycisku przebiega połysk,
     a strzałka wyjeżdża w prawo i wjeżdża z lewej */
  .rez-cta::before{content:"";position:absolute;z-index:1;top:0;bottom:0;left:0;width:34%;pointer-events:none;
    background:linear-gradient(100deg,rgba(255,255,255,0),rgba(255,255,255,.8) 50%,rgba(255,255,255,0));
    transform:translateX(-140%) skewX(-18deg);animation:rezShine 4.8s cubic-bezier(.4,0,.2,1) infinite}
  .rez-cta i b{animation:rezArrOut 4.8s cubic-bezier(.7,0,.3,1) infinite}
  .rez-cta i::after{position:absolute;left:50%;top:50%;margin:-6px 0 0 -11px;transform:translateX(-48px);animation:rezArrIn 4.8s cubic-bezier(.7,0,.3,1) infinite}
}
@keyframes rezShine{0%{transform:translateX(-140%) skewX(-18deg)}42%,100%{transform:translateX(340%) skewX(-18deg)}}
@keyframes rezArrOut{0%,52%{transform:none}70%,100%{transform:translateX(48px)}}
@keyframes rezArrIn{0%,52%{transform:translateX(-48px)}70%,100%{transform:none}}
/* ekran dotykowy nie ma kursora — plan łagodnie kołysze się sam (animacja CSS, pauzowana poza ekranem klasą .off) */
@media(hover:none){
  .rez-card{animation:rezSway 9s ease-in-out infinite alternate}
  .rez-glare{display:none}
}
@keyframes rezSway{from{transform:rotateY(-6deg) rotateX(2.5deg)}to{transform:rotateY(6deg) rotateX(-2.5deg)}}

/* ================= FOOTER ================= */
/* +40% w pionie względem poprzedniej wersji: padding i odstęp przeskalowane ×1.4 */
footer{position:relative;background:var(--ink);
  padding:clamp(64px,11vh,134px) var(--gut) clamp(36px,6vh,70px);
  display:grid;justify-items:center;gap:clamp(31px,4.8vh,53px)}
/* telefon: ta sama stopka na każdej stronie (znak + ikony), ~2,5% niższa niż wcześniej na /koncerty;
   link „Regulamin" wchodzi w dolny padding, więc nie zmienia wysokości */
@media(max-width:600px){
  footer{padding:52px var(--gut) 36px;gap:28px}
  #regLink{position:absolute;left:0;right:0;bottom:8px;margin-inline:auto;width:max-content;padding-bottom:0}
}
/* logo w stopce = powrót na górę strony głównej, bez żadnej animacji (ani wejścia, ani hovera, ani płynnego scrolla) */
#footLogo{display:block;width:min(46vw,300px);color:var(--bone);-webkit-tap-highlight-color:transparent}
.socials{display:flex;gap:clamp(18px,3vw,38px);align-items:center}
.socials a{width:clamp(28px,3.4vw,38px);color:var(--bone);opacity:.72;
  transition:opacity .35s var(--tick),transform .45s var(--tick),color .35s}
.socials a:hover{opacity:1;color:var(--red);transform:translateY(-5px)}
.socials svg{width:100%;height:auto;display:block}
#regLink{color:var(--steel);font-size:10px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  opacity:.5;padding-bottom:2px;border-bottom:1px solid transparent;transition:opacity .3s,color .3s,border-color .3s}
#regLink:hover{opacity:1;color:var(--red);border-color:var(--red)}

/* ================= DO GÓRY ================= */
/* kwadrat 42 px, 30 px od prawej krawędzi treści; gdy brakuje miejsca — dosunięty do krawędzi ekranu (może wejść na treść) */
#toTop{position:fixed;left:min(calc(100% - var(--gut) + 30px),calc(100% - 52px));bottom:18px;z-index:125;
  width:42px;height:42px;padding:0;
  display:flex;align-items:center;justify-content:center;background:var(--ink);
  border:2px solid var(--rim);color:var(--bone);cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .35s var(--tick),transform .35s var(--tick),border-color .3s,background .3s}
#toTop.show{opacity:1;visibility:visible;transform:none}
#toTop:hover{border-color:var(--red);background:var(--red)}
#toTop svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:square}
/* telefon: prawa krawędź na linii z marginesem strony */
@media(max-width:720px){ #toTop{left:calc(100% - var(--gut) - 42px)} }

/* animacje w nieskończoność liczą się tylko dla widocznych sekcji (klasę .off ustawia IntersectionObserver w JS) */
.off,.off *,.off *::before,.off *::after{animation-play-state:paused!important}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important}
}
