/*
 * Uzupełnienia stylów wprowadzane po 2018 roku.
 *
 * Dlaczego osobny plik: `assets/css/styles.css` to kompilat SCSS-a z 2018 roku,
 * a w motywie nie ma już narzędzi budujących (brak package.json, źródła i kompilat
 * mają tę samą datę). Ręczne dopisywanie do zminifikowanego kompilatu skończyłoby
 * się utratą zmian przy pierwszym ponownym buildzie, dlatego nowe reguły trzymamy
 * tutaj i wczytujemy po `styles-css`. Te same reguły są dopisane w źródłach SCSS,
 * żeby przyszły rebuild ich nie pominął.
 */

/*
 * Rodzaj miejsc przy godzinie seansu.
 *
 * Bilety24 sprzedaje czasem ten sam seans dwoma kanałami równolegle: wejściówki
 * (miejsca nienumerowane) i konkretne miejsca na sali. Feed wystawia wtedy dwa
 * wpisy o tej samej godzinie, więc kafelki muszą się różnić dla widza.
 *
 * Adnotacja jest częścią treści kafelka (wewnątrz `.movie-type__content`), a nie
 * osobnym elementem pod spodem. Kafelek ma absolutnie pozycjonowany
 * `.movie-type__details` (top: 0, width: 100%) z etykietą i przyciskiem biletu,
 * pokazywany na hover — każdy element dodany obok treści powiększał kafelek, więc
 * ten blok nachodził na adnotację i przycisk „Kup bilet" nakładał się na tekst.
 */
.movie-type__seats {
    margin-left: .35em;
    font-size: .55em;
    letter-spacing: .04em;
    text-transform: uppercase;
    /* Bez tego adnotacja PODWYZSZA kafelek, choc ma mniejszy tekst: kafelek ma
       `line-height` podany w pikselach (28 px przy 28 px czcionki), a adnotacja to
       dziedziczy razem z mniejszym `font-size`. Nadwyzka odstepu miedzywierszowego
       nad jej wlasnym tekstem rozpycha wiersz z 30 na 35 px, kafelek przestaje sie
       zgadzac z paskiem formatu obok i „Kup bilet" nachodzi na sasiednie elementy.
       `line-height: 1` sprowadza pole adnotacji do jej wlasnego rozmiaru. */
    line-height: 1;
    /* Kafelek ma białą treść na czarnym tle; adnotacja jest drugorzędna, ale musi
       zostać czytelna — 0.75 na czerni daje kontrast ok. 8:1, czyli powyżej AAA. */
    opacity: .75;
}

/* Na wąskich ekranach kafelki godzin już są ciasne, więc adnotacja schodzi
   o oczko niżej rozmiarem, zamiast rozpychać wiersz. */
@media (max-width: 800px) {
    .movie-type__seats {
        font-size: .5em;
        margin-left: .25em;
    }
}

/*
 * Komunikat awaryjny na stronie repertuaru (gdy feed Bilety24 nie zwrocil seansow).
 * Wczesniej style byly wstrzykiwane w <style> wewnatrz szablonu Twig.
 */
.repertoire__fallback-link:hover {
    color: #fff;
}

.repertoire__fallback h1 .repertoire__fallback-link:hover {
    color: #f00;
}

/*
 * Tresc czytana tylko przez czytniki ekranu i indeksowana przez wyszukiwarki.
 * Uzywane dla naglowka H1 na stronie glownej, ktora graficznie zaczyna sie
 * od slidera i nie ma miejsca na widoczny naglowek.
 * Implementacja jak w WordPressie (nie display:none - to ukrywa tez przed czytnikami).
 */
.screen-reader-text {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/*
 * Kafelki godzin seansów w pasku „W repertuarze" i na stronie wydarzenia.
 *
 * Jak to działa w motywie. Kafelek godziny (`.movie-type__expand-details`) jest
 * elementem `inline-block` z czarnym tłem, obejmującym tylko tekst godziny.
 * Format seansu i przycisk biletu siedzą w `.movie-type__details` — bloku
 * pozycjonowanym absolutnie, o pełnej szerokości, z tłem czarnym w pierwszym
 * wierszu i tekstem dociągniętym do prawej. Kafelek ma `z-index: 5`, blok `4`,
 * więc godzina jest nad blokiem, a „2D NAPISY" widać po prawej stronie paska.
 * W `.showtime-item` blok jest widoczny zawsze (nie tylko po najechaniu).
 *
 * Poprawiamy tu dwie rzeczy.
 */

/*
 * 1. Wyrównanie paska formatu z kafelkiem godziny.
 *
 * Kafelek godziny i pasek formatu („2D NAPISY") to ten sam element `.movie-type`
 * z tymi samymi odstępami i tą samą czcionką, więc mają identyczną wysokość —
 * zmierzone 30 px przy oknie 1440 px, 53,3 px przy 2560 px. Kompilat przesuwa
 * jednak pasek w dół o `top: .1388888889vw`, a to jednostka zależna od szerokości
 * okna: 2 px przy 1440 px, 3,6 px przy 2560 px, 4,8 px przy 3440 px. Im większy
 * ekran, tym wyraźniej pasek zwisa poniżej godziny i czarne tło robi się schodkiem.
 *
 * Skoro wysokości się zgadzają, właściwym przesunięciem jest zero — wtedy oba
 * elementy tworzą jeden równy pasek przy każdej szerokości okna. Reguła ma dwie
 * klasy, więc wygrywa też z wariantami `top` z zapytań medialnych kompilatu
 * (`.1953125vw` dla tabletu i `1.6vw` dla telefonu).
 */
.showtime-item .movie-type__details {
    top: 0;
}

/* Poniżej 500 px kompilat dodaje kafelkowi godziny `border: 2px solid transparent`,
   którego pasek formatu nie ma — kafelek był tam o 4 px wyższy (zmierzone 35,2
   wobec 31,2 px przy oknie 390 px) i czarne tło robiło widoczny schodek. Zamiast
   przesuwać pasek w dół, dokładamy mu tę samą ramkę: wysokości się zgadzają, więc
   `top: 0` działa też tutaj. Element ma `box-sizing: border-box`, a szerokość
   `100%`, więc ramka nie zmienia szerokości paska (sprawdzone: 336 px przed i po). */
@media (max-width: 500px) {
    .showtime-item .movie-type__details .movie-type-w-100 {
        border: 2px solid transparent;
    }
}

/*
 * 2. Dzień z więcej niż jednym seansem.
 *
 * `.movie-type__details` liczy pozycję od najbliższego przodka z `position`, a był
 * nim `.movie-type__container` — WSPÓLNY kontener wszystkich godzin danego dnia.
 * Przy dwóch seansach oba bloki lądowały więc w tym samym miejscu: przycisk
 * „Kup bilet" pierwszego seansu nachodził na godzinę drugiego. Bilety24 wystawia
 * dwa seanse o tej samej godzinie, gdy równolegle sprzedaje wejściówki i miejsca
 * numerowane, więc taki dzień przestał być wyjątkiem.
 *
 * Każdy seans dostaje własny `.showtime-slot` (patrz szablony w
 * templates/partial/showtimes/) i to on jest teraz punktem odniesienia. Sam kafelek
 * zostaje bez zmian — dalej jest `inline-block` z czarnym tłem wokół godziny — więc
 * wygląd pojedynczego seansu jest dokładnie taki jak w motywie.
 */
.showtime-item .showtime-slot {
    position: relative;
    display: block;
    width: 100%;
}

/*
 * Miejsce na wystającą część bloku szczegółów — TYLKO w dniach z kilkoma seansami.
 *
 * Blok jest pozycjonowany absolutnie, więc jego drugi wiersz (przycisk „Kup bilet")
 * nie zajmuje miejsca w układzie i wchodzi na kolejny seans. Rezerwujemy dokładnie
 * tyle, ile ten przycisk wystaje poniżej kafelka godziny.
 *
 * Dlaczego `vw`, a nie `em`: cały kompilat z 2018 skaluje typografię jednostką `vw`,
 * więc wysokość przycisku rośnie razem z szerokością okna, a `em` liczyłoby się od
 * 16 px korzenia i przy 2560 px zabrakłoby ponad 28 px. Zmierzone wartości
 * (`ticket.bottom - kafelek.bottom`) są stałe w obrębie każdego progu motywu:
 *
 *   2560 px → 49,8 px │ 1440 px → 28,0 px │ 1280 px → 24,9 px   = 1,945vw
 *   1024 px → 28,0 px │  768 px → 21,0 px                        = 2,73vw
 *    500 px → 35,3 px │  375 px → 26,0 px                        = 7,0vw
 *
 * Do każdej wartości dokładamy ułamek vw, żeby godzina kolejnego seansu nie
 * dotykała przycisku poprzedniego.
 *
 * Ostatni seans dnia rezerwacji nie dostaje: pod nim nie ma już godziny, którą blok
 * mógłby zasłonić, a kontener ma własny odstęp (`mb-25`). Dzięki temu dzień z jednym
 * seansem — i ostatni kafelek każdego dnia — zachowuje wysokość z motywu.
 */
.showtime-item .movie-type__container--wiele .showtime-slot:not(:last-child) {
    margin-bottom: 2.1vw;
}

@media (min-width: 501px) and (max-width: 1279px) {
    .showtime-item .movie-type__container--wiele .showtime-slot:not(:last-child) {
        margin-bottom: 2.9vw;
    }
}

@media (max-width: 500px) {
    .showtime-item .movie-type__container--wiele .showtime-slot:not(:last-child) {
        margin-bottom: 7.6vw;
    }
}

/*
 * Seans bez przycisku biletu (rozpoczęty, zakończony albo bez linku w feedzie) ma
 * w bloku wyłącznie pasek formatu, który mieści się w kafelku — rezerwacja
 * zostawiłaby wtedy puste miejsce. Zerujemy ją, ale osobną regułą z `:has()`:
 * gdyby przeglądarka tego selektora nie znała, odrzuci tylko tę regułę i zostanie
 * rezerwacja, czyli wariant bezpieczny (odstęp zamiast nakładania).
 */
.showtime-item .movie-type__container--wiele .showtime-slot:not(:last-child):not(:has(.showtime-item__ticket)) {
    margin-bottom: 0;
}

/*
 * Strona wyników wyszukiwania.
 *
 * Wyniki były wcześniej listą nagich linków rozdzielonych `<hr>`, bez informacji
 * o typie treści i bez paginacji. Style trzymają się typografii motywu — porządkują
 * to, co już jest, zamiast wprowadzać nowy wygląd.
 */
.search-result {
    padding-bottom: 18px;
    border-bottom: 1px solid rgba(0, 0, 0, .12);
}

.search-result__meta {
    margin-bottom: 6px;
}

.search-result__type {
    display: inline-block;
    padding: 2px 8px;
    background: #1f6b73;
    color: #fff;
    font-family: "BebasNeue", sans-serif;
    font-size: 13px;
    letter-spacing: .04em;
    line-height: 1.5;
    text-transform: uppercase;
}

.search-result__excerpt {
    margin: 0;
    color: #333;
}

.janosik-paginacja__list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Pola nawigacji spełniają minimum 24 x 24 px z WCAG 2.5.8 z zapasem. */
.janosik-paginacja__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    min-height: 40px;
    padding: 0 10px;
    background: #f0f0f0;
    color: #1a1a1a;
    font-family: "BebasNeue", sans-serif;
    font-size: 18px;
    text-decoration: none;
}

.janosik-paginacja__link:hover {
    background: #1f6b73;
    color: #fff;
}

.janosik-paginacja__link--current {
    background: #000;
    color: #fff;
}

/* Wielokropek miedzy odleglymi numerami stron: to nie jest przycisk, wiec nie ma
   tla ani reakcji na najechanie - inaczej wygladalby na klikalny. */
.janosik-paginacja__link--przerwa {
    min-width: 24px;
    background: none;
    color: #6a6a6a;
}

/*
 * Archiwum filmów.
 *
 * Lista blisko 2 800 wpisów bez seansu (patrz lib/archiwum.php). Wygląd trzyma się
 * typografii motywu: plakat w proporcji 2:3, tytuł czcionką kafelków, szczegóły
 * krojem szeryfowym jak opisy.
 *
 * LICZBA KOLUMN JEST ZAWSZE DZIELNIKIEM 24 — to nie kwestia gustu. Strona archiwum
 * wyświetla równo 24 pozycje (JANOSIK_ARCHIWUM_NA_STRONIE w lib/archiwum.php), więc
 * tylko przy 2, 3, 4, 6 albo 8 kolumnach ostatni wiersz wychodzi pełny. Przy 5
 * kolumnach zostaje w nim jedna pozycja i cztery dziury, przy 7 — trzy pozycje
 * i cztery dziury, przy 9 — sześć pozycji i trzy dziury. Dlatego NIE wracać tu do
 * `repeat(auto-fill, minmax(…, 1fr))`: auto-fill dobiera liczbę kolumn do
 * szerokości okna i trafiał dokładnie na te zakazane wartości — zmierzone 5 kolumn
 * przy oknie 1440 px, 9 przy 2560 px i 12 przy 3440 px (plakat miał wtedy 158 px,
 * czyli mniej niż na telefonie).
 *
 * Progi poniżej wynikają z szerokości kolumny treści motywu, która zmienia się
 * dwoma skokami: zmierzone 0,867 x szerokość okna do 500 px, 0,951 x od 501 px,
 * a od 1280 px (dochodzi kolumna repertuaru) tylko 0,632 x. Dobrane tak, żeby
 * plakat nie zszedł poniżej 150 px ani nie przekroczył ~260 px.
 */
.archiwum {
    display: grid;
    /* Domyślnie telefon: 2 kolumny. Przy jednej strona z 24 pozycjami miała
       16 000 px wysokości — przewinięcie do paginacji było dłuższe niż sama lista. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /*
       Każdy wiersz dostaje wysokość najwyższego, dzięki czemu dolne krawędzie
       plakatów leżą w jednej linii w całej siatce, a nie tylko w obrębie jednego
       wiersza. Przed zmianą wiersze przy 2560 px miały 848, 864 i 844 px, bo opisy
       mają od 1 do 8 linii — kolejne rzędy plakatów były przesunięte względem
       siebie o kilkadziesiąt pikseli i to czytało się jako nierówna siatka.
    */
    grid-auto-rows: 1fr;
    /* Odstęp pionowy większy od poziomego: między wierszami spotykają się opis
       poprzedniego kafelka i plakat następnego, a 20 px za mało je rozdzielało.
       Na telefonie poziomy jest mniejszy, bo przy 360 px okna decyduje o tym, czy
       plakat ma jeszcze 149 px, czy już 146 px. */
    gap: 22px 14px;
    width: 100%;
}

/* 3 kolumny. Próg 501 px nie jest okrągły, ale to dokładnie tam motyw przełącza
   swoją skalę: kolumna treści skacze z 433 na 476 px, a tytuł kafelka z 32 na
   11,8 px (klasy `box-text-*` liczą się poniżej od 375 px szerokości odniesienia,
   powyżej od 1024 px). Trzymanie dwóch kolumn nad tym progiem dawało plakat 240 px
   pod 12-pikselowym tytułem — proporcje kafelka rozjeżdżały się bardziej niż przy
   plakacie 145 px, jaki wypada tu przy 501 px okna (152 px przy 520 px). */
@media (min-width: 501px) {
    .archiwum {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 28px 20px;
    }
}

/* 4 kolumny: przy 720 px okna (kolumna treści 685 px) plakat ma 156 px, przy
   1149 px — 258 px, czyli tuż pod górną granicą. */
@media (min-width: 720px) {
    .archiwum {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* 6 kolumn: powyżej 1149 px czwórka rozdmuchałaby plakat ponad 260 px (przy
   1279 px okna wypadłoby 289 px). Szóstka daje 166–186 px. */
@media (min-width: 1150px) {
    .archiwum {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

/* Powrót do 4 kolumn: przy 1280 px motyw dokłada z prawej kolumnę repertuaru
   i kolumna treści spada z 1216 px do 809 px (zmierzone), więc mieści tyle samo
   plakatów co tablet — 187 px przy 1280 px okna, 238 px przy 1599 px. */
@media (min-width: 1280px) {
    .archiwum {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* 6 kolumn dla szerokich monitorów: przy 1600 px okna plakat ma 152 px, przy
   1920 px — 186 px, przy 2560 px — 253 px. Dla typowego 2560 px daje to cztery
   pełne wiersze po 6 pozycji. */
@media (min-width: 1600px) {
    .archiwum {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

/* 8 kolumn od 2700 px: szóstka dałaby przy 3440 px plakat 345 px, czyli wyraźnie
   powyżej granicy 260 px. Ósemka daje 196 px przy 2700 px i 254 px przy 3440 px —
   i trzy pełne wiersze po 8 pozycji. `max-width` jest dopiero dla monitorów
   powyżej ~3500 px, gdzie i ósemka przebiłaby 260 px na plakat. */
@media (min-width: 2700px) {
    .archiwum {
        grid-template-columns: repeat(8, minmax(0, 1fr));
        max-width: 2220px;
    }
}

.archiwum__item {
    display: flex;
    flex-direction: column;
    /* Domyślne `min-width: auto` pozwala elementowi siatki rozepchnąć się do
       szerokości najdłuższego wyrazu: zmierzone 219 px treści w torze 158 px,
       tytuł wychodził na sąsiedni kafelek. */
    min-width: 0;
    color: #1a1a1a;
    text-decoration: none;
}

.archiwum__plakat {
    position: relative;
    /* Stała proporcja rezerwuje miejsce przed wczytaniem obrazu — bez tego lista
       przeskakuje w trakcie ładowania (Cumulative Layout Shift). */
    aspect-ratio: 2 / 3;
    margin-bottom: 10px;
    background: #ededed;
    overflow: hidden;
}

/* `cover` kadruje, ale plakaty kinowe są niemal zawsze w proporcji 2:3, więc
   przycięcie dotyczy marginesów, a nie treści. `contain` dałoby szare pasy przy
   każdej pozycji o innej proporcji i siatka przestałaby się czytać jako siatka. */
.archiwum__plakat img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.archiwum__plakat-brak {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    transform: translateY(-50%);
    color: #6a6a6a;
    font-family: "BebasNeue", sans-serif;
    font-size: 15px;
    letter-spacing: .04em;
    text-align: center;
    text-transform: uppercase;
}

.archiwum__opis {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.archiwum__rok {
    align-self: flex-start;
    padding: 1px 7px;
    background: #000;
    color: #fff;
    font-family: "BebasNeue", sans-serif;
    letter-spacing: .04em;
}

.archiwum__tytul {
    font-family: "BebasNeue", sans-serif;
    text-transform: uppercase;
    /*
       Trzy linie mieszczą przy plakacie 200 px i 24 px Bebasa około 66 znaków,
       czyli nawet tytuł w rodzaju "Klub filmowy Urania: Pejzaż w kolorze sepii".
       Ograniczenie jest tu po to, żeby jeden rekordowo długi tytuł (zmierzone
       413 px w ośmiu liniach przy "Janosik szkrabom: Reksio sadownik, bieg na
       przełaj, myszka nad wodą") nie podnosił razem z `grid-auto-rows: 1fr`
       wszystkich wierszy siatki. Pełny tytuł jest na stronie filmu, do której
       prowadzi cały kafelek.
    */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    /* Bebas nie ma dzielenia wyrazów, a w kafelku trafiają się długie: zmierzone
       "sentymentalna" i "komediodramat" zajmowały 188-219 px w torze 158 px
       i nachodziły na sąsiedni kafelek. */
    overflow-wrap: anywhere;
}

.archiwum__item:hover .archiwum__tytul {
    color: #b04a16;
}

.archiwum__szczegoly {
    color: #333;
    /* Dwie linie (~60 znaków przy plakacie 200 px i 14 px Merriweathera) mieszczą
       gatunek plus kraj albo reżyserię. Bez ograniczenia rekordy z pięcioma krajami
       produkcji miały 320 px opisu przy 238 px plakatu — wysokość wiersza siatki
       wyznaczał opis, nie plakat. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/*
 * Powyżej 1440 px klasy `box-text-*` motywu liczą rozmiar w `vw` — zmierzone dla
 * tytułu kafelka: 24 px przy oknie 1440 px, 32 px przy 1920 px, 42,7 px przy
 * 2560 px i 57,3 px przy 3440 px. Ma to sens tam, gdzie kafelek rośnie razem
 * z oknem, ale plakat archiwum zatrzymuje się na 200 px: 42-pikselowy tytuł
 * zajmował w nim osiem linii i wychodził poza kolumnę, a wiersz siatki puchł do
 * 848 px przy 238 px plakatu. Skoro siatka i filtr nie skalują się z oknem,
 * typografia też nie może — zamrażamy ją na wartościach z 1440 px.
 */
@media (min-width: 1441px) {
    .archiwum__rok {
        font-size: 18px;
        line-height: 18px;
    }

    .archiwum__tytul {
        font-size: 24px;
        line-height: 29px;
    }

    .archiwum__szczegoly {
        font-size: 14px;
        line-height: 20px;
    }

    /* Etykieta i pole mają klasę `box-text-18-22`, którą motyw ustawia
       z `!important` — stąd wyjątek od reszty tego bloku. */
    .archiwum__filtr-label {
        font-size: 18px !important;
        line-height: 22px !important;
    }

    .archiwum__filtr-input {
        font-size: 18px !important;
    }

    .archiwum__filtr-submit {
        font-size: 28px;
        line-height: 28px;
    }

    .archiwum__filtr-reset {
        font-size: 16px;
        line-height: 19px;
    }

    .archiwum__licznik {
        font-size: 16px;
        line-height: 28px;
    }
}

/*
 * Formularz filtrowania. `flex-wrap` zamiast zapytań medialnych: pola schodzą
 * jedno pod drugie, kiedy zabraknie miejsca, i to samo działa w wąskiej kolumnie
 * treści na desktopie.
 */
.archiwum__filtr {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px 16px;
    width: 100%;
    /* Ta sama granica co siatka, żeby wiersz filtra i pierwszy rząd plakatów
       kończyły się w tym samym miejscu. */
    max-width: 1300px;
}

.archiwum__filtr-pole {
    display: flex;
    flex-direction: column;
    /*
       Pole tekstowe rosło do całej szerokości kolumny treści — zmierzone 660 px
       przy oknie 1440 px i 1250 px przy 2560 px, przy czym najdłuższa realna
       fraza to kilka wyrazów. 30 em to przy 16 px około 60 znaków; powyżej rosłaby
       już tylko odległość między wpisaną frazą a przyciskiem.
    */
    flex: 1 1 240px;
    max-width: 30em;
    gap: 4px;
}

.archiwum__filtr-pole--rok {
    /* Najszersza opcja ("wszystkie") plus strzałka selecta mieszczą się w 8,5 em
       (136 px przy 16 px). Wcześniej pole roku dzieliło wolne miejsce z polem
       tekstowym i puchło do 198 px przy 2560 px, a przy 768 px ściskało się do
       120 px — ta sama kontrolka miała w każdym układzie inną szerokość. */
    flex: 0 0 8.5em;
    max-width: 8.5em;
}

.archiwum__filtr-label {
    font-family: "BebasNeue", sans-serif;
}

.archiwum__filtr-input {
    min-height: 40px;
    padding: 6px 10px;
    border: 1px solid #6a6a6a;
    background: #fff;
    color: #1a1a1a;
    font-family: "Merriweather", Georgia, serif;
    /*
       Kontrolki mają w szablonie klasę `box-text-18-22`, a ta w kompilacie motywu
       liczy wysokość linii w `vw` i to z `!important` (`line-height: 5,867vw` na
       telefonie, `1,528vw` wyżej) — bez `!important` po tej stronie nie da się
       tego nadpisać. Bez nadpisania pole tekstowe miało zmierzone 43 px przy
       oknie 1920 px, 53 px przy 2560 px i 67 px przy 3440 px, a select nawet
       73 px, podczas gdy przycisk "Szukaj" trzymał stałe 40 px — wiersz filtra
       rozjeżdżał się w pionie. Stała linia daje 22 + 12 padding + 2 obramowanie
       = 36 px, więc o wysokości decyduje `min-height` i wszystkie trzy kontrolki
       mają dokładnie 40 px przy każdej szerokości okna.

       Rozmiar pisma zostaje ten z motywu (18 px przy 1440 px): poniżej 16 px iOS
       przybliża stronę przy wejściu w pole.
    */
    line-height: 22px !important;
}

/* Przycisk jest kafelkiem `.movie-type`, ktory w kompilacie nie ma stylu dla
   elementu <button> - dopelniamy tylko to, czego brakuje.
   Tlo to przyciemniony pomaranacz marki: jasny #f08758 z bialym tekstem daje 2,6:1,
   a ten odcien 5,5:1, czyli powyzej progu AA dla zwyklego tekstu. */
.archiwum__filtr-submit {
    min-height: 40px;
    padding: 0 20px;
    border: 0;
    /* 16 px z `gap` to za mało: przycisk stał tuż przy strzałce selecta i czytał
       się jak jego rozwinięcie. Razem z marginesem wychodzi 24 px. */
    margin-left: 8px;
    background: #b04a16;
    color: #fff;
    cursor: pointer;
}

.archiwum__filtr-submit:hover {
    background: #000;
}

.archiwum__filtr-reset {
    /* Link stoi w wierszu z polami, więc wyrównuje się jak one dolną krawędzią.
       `min-height` daje mu cel dotyku 40 px — sam tekst ma 19 px wysokości linii,
       czyli poniżej progu 24 px z WCAG 2.2 (2.5.8 Target Size). */
    display: inline-flex;
    align-items: center;
    align-self: flex-end;
    min-height: 40px;
    color: #12545c;
}

/*
 * Granica jest tu wyżej niż w siatce (599 px, nie 499 px), bo trzy kontrolki
 * potrzebują w jednej linii 240 + 136 + 87 px plus 40 px odstępów, czyli 503 px,
 * a kolumna treści ma przy oknie 599 px zmierzone 570 px. Bez tej reguły wiersz
 * łamał się w przypadkowym miejscu: pole tekstowe zostawało samo w pierwszej
 * linii, a rok i przycisk schodziły razem do drugiej. Jedna kolumna czyta się
 * lepiej, a przycisk na całą szerokość ma większy cel dotyku.
 */
@media (max-width: 599px) {
    .archiwum__filtr {
        flex-direction: column;
        align-items: stretch;
    }

    .archiwum__filtr-pole,
    .archiwum__filtr-pole--rok {
        flex: 0 0 auto;
        max-width: none;
    }

    .archiwum__filtr-submit {
        width: 100%;
        margin-left: 0;
    }

    .archiwum__filtr-reset {
        align-self: flex-start;
    }
}

.archiwum__licznik {
    margin: 0;
}

/* ==========================================================================
 * iOS / dotyk — poprawki z 2026-08-24
 *
 * Wszystkie reguły z tego bloku są też dopisane w `assets/scss/` (styles.scss,
 * _menu.scss, _showtime.scss) z adnotacją, że wersją OBOWIĄZUJĄCĄ jest ten
 * plik. Nie ruszam `assets/css/styles.css`, bo różni się między witrynami
 * barwami motywu (`#F18755` na janosiku, `#5591F1` na bałtyku) — plik nie jest
 * przenośny kopią, a ręczne edycje w dwóch zminifikowanych kompilatach osobno
 * są dokładnie tym, przed czym ostrzega nagłówek tego pliku.
 * ========================================================================== */

/*
 * Wysokość WIDOCZNEGO obszaru okna — jedna zmienna dla całego motywu.
 *
 * `100%` i `vh` dla elementu `position: fixed` odnoszą się w iOS Safari do
 * DUŻEGO viewportu, czyli wysokości ekranu ze SCHOWANYMI paskami narzędzi,
 * a nie do tego, co widz widzi. Zmierzone 2026-08-24 (WebKit, okno 390×844 px):
 * uchwyt szuflady „W REPERTUARZE" siedział na `top: 794,08 px`, czyli 130 px
 * PONIŻEJ krawędzi obszaru widocznego (664 px przy rozwiniętych paskach).
 * Główny element nawigacyjny witryny był niewidoczny do pierwszego przewinięcia.
 *
 * Drabinka, od najstarszego do najnowszego — każdy krok tylko tam, gdzie
 * przeglądarka go rozumie:
 *   1. `100vh`  — wszędzie; w iOS mierzy duży viewport, czyli stan wyjściowy,
 *   2. `100dvh` — Safari 15.4+ / iOS 15.4+, jednostka wprost do tego celu,
 *   3. `window.innerHeight` z JS — TYLKO gdy brak `dvh` (patrz scripts.js);
 *      wpisywane w styl elementu `<html>`, więc bije obie reguły niżej.
 *
 * Dlaczego przez zmienną, a nie trzy deklaracje `top:` obok siebie: zmienna
 * daje jedno miejsce na tę decyzję dla wszystkich reguł, które z niej
 * korzystają, i pozwala zapasowi z JS wygrać bez `!important`.
 *
 * PUŁAPKA: nie wolno pisać `var(--janosik-vh, 100dvh)`. Przeglądarka bez `dvh`
 * uznaje taką wartość za niepoprawną dopiero na etapie wyliczania, a wtedy
 * `top` spada do `auto` — nie wraca do poprzedniej deklaracji. Dlatego wartość
 * domyślna zmiennej jest bezpieczna (`100vh`), a `dvh` wchodzi przez `@supports`.
 */
:root {
    --janosik-vh: 100vh;
}

@supports (height: 1dvh) {
    :root {
        --janosik-vh: 100dvh;
    }
}

/*
 * Szuflada repertuaru i menu mobilne liczone z widocznego obszaru.
 *
 * `:not(.showtime-box--open)` jest konieczne: `.showtime-box--open{top:0}`
 * z `styles.css` ma tę samą specyficzność co `.showtime-box`, a ten plik
 * wczytuje się PÓŹNIEJ — bez tego zastrzeżenia otwarta szuflada wróciłaby
 * na dół ekranu i nie dałoby się jej otworzyć w ogóle.
 */
@media (max-width: 1279px) {
    .showtime-box:not(.showtime-box--open) {
        top: calc(var(--janosik-vh) - 4.6875vw);
    }

    #showtime {
        height: calc(var(--janosik-vh) - 4.6875vw);
    }
}

@media (max-width: 500px) {
    .showtime-box:not(.showtime-box--open) {
        top: calc(var(--janosik-vh) - 12.8vw);
    }

    #showtime {
        height: calc(var(--janosik-vh) - 12.8vw);
    }

    /* Ten sam mechanizm, ten sam błąd: otwarte menu mobilne wystawało 170 px
     * pod widoczną krawędź, więc dolne pozycje trzeba było odgadnąć.
     * `!important` nie jest tu moją decyzją — reguła w `styles.css` już go ma
     * i bez niego ta poprawka nie weszłaby. */
    body.nav-opened #nav-main {
        height: calc(var(--janosik-vh) - 17.1875vw) !important;
    }
}

/*
 * Blokada przewijania tła (szuflada repertuaru, opis godziny seansu).
 *
 * Poprzednia wersja — `.block-body{max-height:100%;overflow:hidden}` — nie
 * blokowała niczego w ŻADNEJ przeglądarce. Dwie niezależne przyczyny:
 * kontenerem przewijania dokumentu jest `<html>`, a nie `<body>`, więc
 * `overflow` na `<body>` nie ma nad nim władzy; a `max-height:100%` nie miało
 * odniesienia, bo `<html>` nie ma zadanej wysokości. Zmierzone 2026-08-24:
 * przy założonej klasie tło przewijało się z 400 px na 900 px.
 *
 * Ale nawet poprawne `overflow:hidden` na `<html>` NIE zatrzymuje inercyjnego
 * gestu w iOS Safari — to zachowanie WebKita niezmienne do Safari 18. Jedyne
 * pewne rozwiązanie to `position: fixed`, i ono działa wszędzie.
 *
 * `position: fixed` gubi pozycję przewijania, dlatego przesunięcie w górę
 * przychodzi z JS przez `--janosik-scroll-y` (patrz scripts.js). Bez tego
 * zamknięcie menu przenosiłoby widza na górę strony, czyli poprawka
 * wprowadziłaby błąd gorszy od naprawianego.
 */
body.block-body {
    position: fixed;
    top: calc(-1 * var(--janosik-scroll-y, 0px));
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    /* Bez tego przy dojściu do końca listy w otwartej szufladzie gest przenosi
     * się na dokument i widać „gumowanie" całej strony. */
    overscroll-behavior: none;
}

/*
 * Podmenu menu głównego: sterowane przyciskiem, nie hoverem.
 *
 * Stan wyjściowy miał dwa błędy naraz. `.list__hasDropdown` był jedynym
 * elementem klikalnym motywu bez `cursor:pointer`, `role`, `tabindex` i `href`
 * — a iOS Safari wytwarza zdarzenie `click` tylko dla elementów, które uznaje
 * za klikalne (link z `href`, przycisk, kontrolka, element z `role`/`tabindex`/
 * `onclick` ALBO z `cursor:pointer`). Gołe `<li>` nie spełnia żadnego z tych
 * warunków, więc stuknięcie nie wytwarzało `click` i delegowany handler nie
 * miał czego złapać: cztery pozycje z podmenu były na iPhonie nieotwieralne.
 * Drugi błąd: na desktopie ratował je wyłącznie `:hover`, którego na dotyku
 * nie ma — a iOS zostawia „sticky hover" aktywny do stuknięcia w inne miejsce.
 *
 * Rozwiązanie: prawdziwy `<button aria-expanded>` w szablonie (menu.twig),
 * a `:hover` obwarowany rodzajem wskaźnika.
 */
@media (hover: none), (pointer: coarse) {
    /* Reguła `display:flex` na `:hover` z `styles.css` musi tu zniknąć, bo na
     * dotyku nie ma czym zdjąć hoveru — podmenu zostawało otwarte i zasłaniało
     * treść. Wystarcza tu jedna specyficzność 3 klas, bo tyle ma oryginał. */
    .list .list__hasDropdown:hover .list__dropdown {
        display: none;
    }
}

/* Stan otwarty nakładany przez przycisk. Musi być silniejszy od reguły wyżej,
 * i jest: cztery klasy przeciw trzem. */
.list .list__hasDropdown.list__hasDropdown--opened > .list__dropdown {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
}

.list__dropdown-toggle {
    position: absolute;
    top: 50%;
    right: 0;
    z-index: 2;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    /* 44 px, nie „tyle, ile trzeba na ikonę": to minimalny cel dotykowy
     * z WCAG 2.5.5. Ikona ma 12 px i sama byłaby nie do trafienia palcem. */
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.list__dropdown-toggle svg {
    width: 12px;
    height: 12px;
    /* Strzałka w pliku wskazuje w prawo — ten sam znacznik co w wyszukiwaniu.
     * Obrót zamiast drugiego SVG: mniej bajtów i jedno miejsce do poprawiania. */
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
    -webkit-transition: -webkit-transform .2s ease;
    transition: transform .2s ease;
}

.list__hasDropdown--opened > .list__dropdown-toggle svg {
    -webkit-transform: rotate(-90deg);
    transform: rotate(-90deg);
}

@media (hover: hover) and (pointer: fine) {
    /* Przy myszy podmenu otwiera hover, więc przycisk jest tu tylko dla
     * klawiatury: nie zabiera kliknięć (`pointer-events:none`, bo przezroczysty
     * element nad linkiem połknąłby je) i pokazuje się dopiero z fokusem.
     * `:focus`, nie `:focus-visible` — przy zablokowanych kliknięciach fokus
     * może tu przyjść wyłącznie z klawiatury, a `:focus` rozumie każde Safari. */
    .list__dropdown-toggle {
        opacity: 0;
        pointer-events: none;
    }

    .list__dropdown-toggle:focus {
        opacity: 1;
        pointer-events: auto;
    }
}

@media (max-width: 500px) {
    /* W menu mobilnym wiersz ma stałą wysokość i `overflow:hidden`, a po
     * otwarciu rośnie do `height:auto`. Przycisk musi więc trzymać się GÓRY
     * wiersza, nie jego środka — inaczej po otwarciu podmenu zjeżdżałby na
     * środek rozwiniętego bloku. */
    .list__dropdown-toggle {
        top: 0;
        height: 13.8666666667vw;
        -webkit-transform: none;
        transform: none;
        /* Odsunięcie od prawej krawędzi: tam stoi ogólna strzałka „przejdź",
         * którą ma KAŻDA pozycja menu. Nałożenie na nią przycisku podmenu
         * znaczyłoby, że to samo miejsce robi dwie różne rzeczy. */
        right: 11.7333333333vw;
    }

    /* Miejsce na przycisk: bez tego długa nazwa pozycji wchodzi pod ikonę. */
    #nav-main .list__hasDropdown > .list__item {
        padding-right: 25.6vw;
    }
}

/* ==========================================================================
 * WDROŻENIE AUDYTU DOSTĘPNOŚCI — poprawki NIEWIDOCZNE dla osoby z myszą.
 *
 * Te reguły są kolejkowane ZAWSZE, poza przełącznikiem `janosik_a11y_kontrast`,
 * bo żadna z nich nie zmienia wyglądu ani zachowania w normalnym użyciu.
 * Poprawki, które coś dokładają na ekran, siedzą w `janosik-a11y-kontrast.css`
 * i wchodzą dopiero po włączeniu opcji.
 *
 * Kopia źródłowa w SCSS: `assets/scss/_menu.scss` (menu mobilne) — ale wersją
 * OBOWIĄZUJĄCĄ jest ten plik, bo `styles.css` jest kompilatem trzymanym
 * w repozytorium i nie jest odbudowywany od 2018 r.
 * ========================================================================== */

/*
 * P2-8: zamknięte menu mobilne nie może być w kolejności klawisza Tab.
 *
 * Stan zastany: `#nav-main` w wariancie mobilnym miał `opacity: 0`, `height: 0`
 * i `overflow: hidden` — czyli był niewidoczny, ale JEGO 44 ODNOŚNIKI DALEJ
 * DAWAŁO SIĘ SKUPIĆ. Osoba nawigująca klawiaturą przechodziła po zamkniętym,
 * niewidocznym menu, zanim w ogóle dotarła do treści strony.
 *
 * `visibility: hidden` jest jedyną z tych trzech właściwości, która wyjmuje
 * potomków z kolejności fokusu. Dla myszy nie zmienia nic: element o wysokości
 * zero z `overflow: hidden` i tak nie zajmował ani jednego piksela.
 *
 * Przejście `visibility 0s linear .3s` przy zamykaniu: bez opóźnienia menu
 * znikałoby natychmiast, zamiast zgasnąć razem z `opacity`. Przy otwieraniu
 * opóźnienia nie ma, bo menu ma być widoczne od pierwszej klatki.
 */
@media (max-width: 800px) {
    #nav-main {
        visibility: hidden;
        -webkit-transition: opacity .3s ease, visibility 0s linear .3s;
        transition: opacity .3s ease, visibility 0s linear .3s;
    }

    body.nav-opened #nav-main {
        visibility: visible;
        -webkit-transition: opacity .3s ease, visibility 0s;
        transition: opacity .3s ease, visibility 0s;
    }
}

/*
 * P2-12: tytuły pozycji na listach są nagłówkami, a wyglądają jak wcześniej.
 *
 * Czytnik ekranu ma standardową nawigację po nagłówkach (klawisz `H`), która na
 * `/repertuar/` nie dawała nic: 78 pozycji repertuaru i ani jednego nagłówka
 * poza `h1`. Zamiana `<span>`/`<div>` na `<h2>`/`<h3>` przywraca tę nawigację.
 *
 * PROBLEM, KTÓRY TA REGUŁA ROZWIĄZUJE. Sam znacznik `<h2>` niesie w tym motywie
 * własny wygląd: `styles.css` ma `h1,h2,…{font-weight:500; font-family:BebasNeue;
 * text-transform:uppercase; margin-bottom:2.08vw; line-height:1.25}` plus
 * domyślne `display:block` przeglądarki. Podmiana znacznika bez tego zerowania
 * przesunęłaby układ i zmieniła krój pisma — czyli byłaby poprawką WIDOCZNĄ.
 *
 * DLACZEGO `:where()`, A NIE ZWYKŁA KLASA. Specyficzność musi wyjść dokładnie
 * (0,0,1) — tyle, ile mają reguły `h1,h2,…`. Ten plik wczytuje się PO
 * `styles.css`, więc przy równej specyficzności wygrywa i zeruje wygląd
 * nagłówka. Jednocześnie PRZEGRYWA z każdym selektorem klasy, więc
 * `box-text-40-40`, `box-text-merri`, `box-text-uppercase` i `color--*` działają
 * tak samo jak na `<span>`. Zwykła klasa `.naglowek-jak-tekst` miałaby (0,1,0)
 * i zabiłaby te klasy — mimo że to one niosą cały wygląd.
 * `:where()` jest w Safari od 14; motyw i tak wymaga nowszego (`:focus-visible`).
 */
h1:where(.naglowek-jak-tekst, .naglowek-jak-blok),
h2:where(.naglowek-jak-tekst, .naglowek-jak-blok),
h3:where(.naglowek-jak-tekst, .naglowek-jak-blok),
h4:where(.naglowek-jak-tekst, .naglowek-jak-blok) {
    margin: 0;
    padding: 0;
    /* Skrót `font` zeruje naraz rodzinę, wagę, styl, rozmiar i interlinię. */
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
}

/* Nagłówek w miejscu `<span>` — zostaje elementem liniowym. */
h1:where(.naglowek-jak-tekst),
h2:where(.naglowek-jak-tekst),
h3:where(.naglowek-jak-tekst),
h4:where(.naglowek-jak-tekst) {
    display: inline;
}

/* Nagłówek w miejscu `<div>` — zostaje elementem blokowym. */
h1:where(.naglowek-jak-blok),
h2:where(.naglowek-jak-blok),
h3:where(.naglowek-jak-blok),
h4:where(.naglowek-jak-blok) {
    display: block;
}

/*
 * P1-3: kafelek godziny seansu jako `<button>`.
 *
 * Znacznik `<button>` niesie wlasny wyglad z arkusza przegladarki: ramke, tlo,
 * krój systemowy, wysrodkowanie tekstu, wlasne odstepy. Bez wyzerowania kafelek
 * po zamianie wygladalby jak przycisk formularza, a nie jak czarny prostokat
 * z godzina.
 *
 * Ta sama sztuczka ze specyficznoscia co przy naglowkach: `button:where(.movie-type)`
 * ma dokladnie (0,0,1), wiec bije arkusz przegladarki (ktory jest slabszy od
 * kazdej reguly autora), a przegrywa z KAZDA regula klasowa motywu. Dzieki temu
 * `.movie-type`, `.movie-type--black`, `.box-text-28-28` i `.movie-type__expand-details`
 * (ta ostatnia ma wlasne `border: 2px solid transparent`) dzialaja bez zmian.
 */
button:where(.movie-type) {
    -webkit-appearance: none;
    appearance: none;
    border: 0;
    border-radius: 0;
    margin: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    word-spacing: inherit;
    text-align: inherit;
    text-indent: 0;
    text-shadow: none;
    cursor: pointer;
}

/*
 * Odsloniecie bloku szczegolow („2D NAPISY" + „Kup bilet").
 *
 * Blok jest SASIADEM kafelka, a nie jego dzieckiem - musial wyjsc na zewnatrz
 * przycisku, bo `<button>` nie przyjmuje odnosnika. Regula z kompilatu
 * (`.movie-type__expand-details:hover > .movie-type__details`) przestala wiec
 * pasowac i trzeba ja bylo odtworzyc.
 *
 * PIERWSZA PROBA BYLA SELEKTOREM SASIADA (`:hover + .movie-type__details`)
 * I ZEPSULA ZAKUP BILETU. Powod jest w samej definicji `:hover`: pasuje on do
 * elementu, nad ktorym jest wskaznik, ORAZ do kazdego jego przodka. Gdy blok byl
 * DZIECKIEM kafelka, najechanie na „Kup bilet" trzymalo `:hover` takze na
 * kafelku, wiec blok zostawal widoczny i dalo sie w niego kliknac. Po zamianie
 * na sasiada ta droga znikla: kursor opuszczal kafelek, `:hover` gasl i blok
 * chowal sie ZANIM wskaznik dotarl do odnosnika. Przycisk mignal i uciekal.
 *
 * Wniosek do zapamietania: „wyglada tak samo" nie znaczy „zachowuje sie tak
 * samo". Zmiana rodzica nie ruszyla ani jednego piksela i wlasnie dlatego
 * przeszla przez przeglad - a skutkiem bylo to, ze na obu witrynach nie dalo
 * sie kupic biletu mysza z prawej kolumny.
 *
 * Poprawnie jest oprzec `:hover` na `.showtime-slot`, czyli na wspolnym rodzicu
 * kafelka i bloku. To wraca DOKLADNIE do zachowania sprzed zmiany: wlasny box
 * slotu to sam kafelek (blok szczegolow jest pozycjonowany absolutnie, wiec
 * wypada z ukladu), a `:hover` na slocie trzyma sie tak dlugo, jak wskaznik
 * jest nad kafelkiem ALBO nad odslonietym blokiem.
 */
.showtime-slot:hover .movie-type__details {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity .3s ease;
    transition: opacity .3s ease;
}

/*
 * To samo dla klawiatury (1.4.13 Content on Hover or Focus).
 *
 * `:focus-visible`, NIE `:focus` ani `:focus-within` - i to jest warunek tego,
 * ze poprawka jest niewidoczna. `:focus` zapalaloby blok takze po KLIKNIECIU
 * myszka (przegladarka ustawia fokus na przycisku), czyli szczegoly zostawalyby
 * odsloniete po zabraniu kursora. `:focus-visible` nie pasuje przy wskazniku.
 *
 * Klasa `.showtime-slot--otwarty` (nakladana z JS) obejmuje przypadek, w ktorym
 * fokus wszedl juz w odnosnik „Kup bilet" wewnatrz bloku. Pierwsza wersja robila to
 * selektorem `.showtime-slot:has(:focus-visible)` i BYLA ZEPSUTA: przy przejsciu
 * Tabem przycisk traci `:focus-visible` zanim odnosnik je dostaje, blok na jedna
 * klatke robi sie niewidoczny, a Chromium odbiera fokus elementowi, ktory wlasnie
 * zniknal - zmierzone, fokus ladowal na `<body>`. Klasa zdejmowana dopiero po
 * sprawdzeniu, gdzie fokus wyladowal, tej dziury nie ma.
 */
.movie-type__expand-details:focus-visible + .movie-type__details,
.showtime-slot--otwarty .movie-type__details {
    visibility: visible;
    opacity: 1;
}

/*
 * Zamkniecie klawiszem Escape (1.4.13 wymaga „dismissible").
 * Klasa jest zdejmowana przy opuszczeniu kafelka, wiec nie utrwala sie.
 */
.movie-type__expand-details.movie-type__expand-details--zamkniete + .movie-type__details,
.showtime-slot--otwarty .movie-type__expand-details--zamkniete + .movie-type__details {
    visibility: hidden;
    opacity: 0;
}

/*
 * P1-1 (czesc klawiaturowa): kalendarz „Inny dzien".
 *
 * Ten sam blad co w zamknietym menu mobilnym (P2-8): `.calendar-slide` ma
 * `height: 0; overflow: hidden`, wiec kalendarza nie widac - ale gdyby jego
 * komorki dni byly skupialne (a po tej poprawce SA, przez `tabindex`), Tab
 * wchodzilby w 42 niewidoczne komorki. `visibility` to zalatwia i nie zmienia
 * ani jednego piksela: element ma zerowa wysokosc i tak.
 */
.calendar-container .calendar-slide {
    visibility: hidden;
}

/*
 * Sama biblioteka wymusza na kalendarzu `visibility: visible`
 * (`.flatpickr-calendar.inline` w flatpickr.css), a `visibility` dziedziczy sie
 * tylko wtedy, gdy potomek jej NIE ustawia. Bez tej reguly komorki dni zostawaly
 * skupialne mimo ukrytego rodzica - zmierzone: 42 skupialne komorki przy
 * zamknietym kalendarzu. Cztery klasy przeciw dwom, wiec pierwszenstwo jest tu.
 */
.calendar-container:not(.in) .calendar-slide .flatpickr-calendar {
    visibility: hidden;
}

.calendar-container.in .calendar-slide {
    visibility: visible;
}

/*
 * Strzalki zmiany miesiaca sa w bibliotece `<span>`-ami bez roli i bez nazwy
 * (zmierzone: `SPAN:(BRAK)`). Dostaja `role="button"`, nazwe i `tabindex` z JS -
 * tu tylko pole dotyku, zeby obwodka fokusu nie wychodzila poza kalendarz.
 * Nic z tego nie zmienia wygladu przy myszy: `outline` pokazuje sie wylacznie
 * przy `:focus-visible`.
 */
.flatpickr-prev-month:focus-visible,
.flatpickr-next-month:focus-visible,
.flatpickr-day:focus-visible {
    outline-offset: -1px !important;
}

/* ---------------------------------------------------------------------------
   Listing podstron z menu (partial/podstrony-menu.twig)

   Trzyma się typografii i odstępów artykułu, bo wyświetla się wewnątrz jego
   treści. Świadomie bez tła i ramek: to nawigacja uzupełniająca, a nie
   wyróżniony blok — strona, na której się pojawia, ma być czytana jako
   całość, nie jako lista pudełek.
   --------------------------------------------------------------------------- */

.podstrony {
    margin: 2rem 0 0;
}

.podstrony__naglowek {
    margin: 0 0 .75rem;
    font-family: "BebasNeue", Impact, "Arial Narrow", sans-serif;
    font-size: 1.5rem;
    line-height: 1.2;
}

.podstrony__lista {
    margin: 0;
    padding: 0;
    list-style: none;
}

.podstrony__element {
    border-top: 1px solid rgba(0, 0, 0, .12);
}

.podstrony__element:last-child {
    border-bottom: 1px solid rgba(0, 0, 0, .12);
}

.podstrony__odnosnik {
    display: block;
    padding: .7rem 0;
    font-family: "Merriweather", Georgia, serif;
    font-size: 1rem;
    line-height: 1.4;
    text-decoration: none;
}

/* Cel dotykowy ma mieć co najmniej 44 px wysokości - to samo kryterium,
   które audyt dostępności stosował do pozostałych elementów klikalnych. */
@media (pointer: coarse) {
    .podstrony__odnosnik {
        min-height: 44px;
        padding: .9rem 0;
    }
}

a.podstrony__odnosnik:hover,
a.podstrony__odnosnik:focus-visible {
    text-decoration: underline;
}

/* ==========================================================================
   PRZEŁĄCZALNE ELEMENTY DOSTĘPNOŚCI (przycisk pauzy, pole wyboru dnia)
   oraz oznaczenie PODGLĄDU dla zalogowanych.

   Dlaczego te reguły są w arkuszu wczytywanym ZAWSZE, choć elementy są
   przełączalne: warunkowy jest ZNACZNIK. Szablon renderuje przycisk pauzy
   tylko przy opcji „pauza", a pole daty tylko przy opcji „data" — więc przy
   wyłączonej opcji te selektory nie mają czego dotyczyć i nic nie kosztują.
   Odwrotnie się nie da: do 25.08.2026 style leżały w
   `janosik-a11y-kontrast.css`, wczytywanym razem z poprawkami kontrastu.
   Po rozbiciu jednego przełącznika na trzy niezależne włączenie samej pauzy
   dałoby przycisk BEZ WYGLĄDU — znacznik w kodzie, nic na ekranie.
   ========================================================================== */

/*
 * 2.2.2 Pause, Stop, Hide — przycisk zatrzymania karuzeli.
 *
 * Cztery karuzele przewijają się same co 6–12 s i bez tego przycisku nie da się
 * ich zatrzymać. Dotyczy osób z zaburzeniami przedsionkowymi i każdego, kto
 * czyta wolniej niż jeden slajd na 6 sekund.
 *
 * PUŁAPKA, KTÓREJ TU NIE MA: przycisk jest widoczny wtedy, gdy karuzela jedzie —
 * czyli dokładnie wtedy, gdy jest potrzebny. Nie ma reguły chowającej go na czas
 * odtwarzania. Znika wyłącznie wtedy, gdy nie ma czego zatrzymywać (autoplay
 * wyłączony przez `prefers-reduced-motion` albo czas ustawiony na 0) — usuwa go
 * wtedy `scripts.js`, a nie CSS.
 */
.swiper-pauza {
    position: absolute;
    left: 10px;
    bottom: 10px;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    /* 44 × 44 px to minimalny cel dotykowy z WCAG 2.5.5. */
    width: 44px;
    height: 44px;
    padding: 0;
    margin: 0;
    border: 2px solid #fff;
    border-radius: 50%;
    background: rgba(0, 0, 0, .78);
    color: #fff;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

/* Ikona z dwóch prostokątów („pauza"). Rysowana w CSS, żeby nie dokładać pliku
   ani czcionki ikonowej; dla czytnika ekranu jest `aria-hidden`, nazwę niesie
   `aria-label` przycisku. */
.swiper-pauza__ikona {
    display: block;
    width: 12px;
    height: 14px;
    border-left: 4px solid currentColor;
    border-right: 4px solid currentColor;
}

/* Po zatrzymaniu ikona zmienia się w trójkąt „odtwórz" — stan musi być widoczny
   także bez czytnika ekranu (1.4.1 Use of Color: kształt, nie sam kolor). */
.swiper-pauza--zatrzymana .swiper-pauza__ikona {
    width: 0;
    height: 0;
    border-left: 12px solid currentColor;
    border-right: 0;
    border-top: 7px solid transparent;
    border-bottom: 7px solid transparent;
    margin-left: 3px;
}

/* --------------------------------------------------------------------------
   2.1.1 Keyboard — pole wyboru dnia obok kalendarza repertuaru.

   Kalendarz flatpickr zostaje jako dodatek dla myszy. Pole `<input type="date">`
   jest drogą podstawową: obsługa klawiaturą, komunikaty w języku strony i tryb
   wysokiego kontrastu systemu pochodzą od przeglądarki.

   DLACZEGO TA SEKCJA JEST DŁUŻSZA NIŻ „kilka pikseli odstępu”. Zgłoszenie od
   właściciela: na szerokim ekranie etykieta „Wybierz dzień:” była ucięta z lewej
   („IERZ DZIEŃ:”), a pole nachodziło na sąsiedni blok. Zmierzona przyczyna:

     - `.box--fullwidth` w kompilacie to wzorzec „ujemny margines + wyrównujące
       go wypełnienie”: `margin: 0 -1.7361vw; padding: 0 1.7361vw`. Obie połowy
       muszą zostać razem, bo znoszą się nawzajem;
     - poprzednia reguła pola daty ustawiała `padding: 12px 0 4px` — SKRÓTEM,
       który kasuje wypełnienie poziome. Ujemny margines został sam, więc blok
       wystawał 25 px poza panel z KAŻDEJ strony (zmierzone przy 1440 px:
       panel [1040..1360], blok [1015..1385], etykieta zaczynała się na 1015).

   Dlatego blok nie używa już `box--fullwidth` (usunięte z szablonu), tylko ma
   własne wypełnienie — takie samo jak `.filter__container`, czyli kolumna,
   w której stoją „Dziś / Jutro / Inny dzień” i kafelki godzin. Zmierzone: przy
   1440, 1280, 1024, 768 i 390 px lewa krawędź etykiety trafia dokładnie
   w lewą krawędź przycisku „Dziś”.

   Przy WYŁĄCZONEJ opcji szablon nie renderuje tego bloku w ogóle, więc nie
   zostaje po nim żaden odstęp — wypełnienie jest na samym bloku, a nie na
   kontenerze kalendarza.
   -------------------------------------------------------------------------- */
.janosik-filtr-data {
    display: flex;
    flex: 1 1 100%;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    width: 100%;
    margin: 0;
    /* Poziomo: tyle co `.filter__container` w kompilacie — to jest kolumna
       tekstu całego panelu. Pionowo: odstęp od kalendarza nad i od listy
       seansów pod spodem. */
    padding: 12px 1.7361111111vw 10px;
}

.janosik-filtr-data label {
    /* Etykieta ma się mieścić w całości - nigdy nie skracamy jej wielokropkiem
       ani nie pozwalamy jej wyjechać poza panel. Gdy zabraknie miejsca w wierszu,
       pole daty schodzi do następnego (`flex-wrap` wyżej). */
    flex: 0 1 auto;
    min-width: 0;
    overflow-wrap: break-word;
    color: #000;
}

.janosik-filtr-data input[type="date"] {
    /* 44 px wysokości — ten sam próg celu dotykowego co przy przycisku pauzy. */
    min-height: 44px;
    /* Szerokość pola rysuje przeglądarka i różni się między nimi (Chrome ~130 px,
       Safari i Firefox więcej). Dlatego nie ustawiamy jej na sztywno: pole
       kurczy się do treści, a gdy i tak nie mieści się obok etykiety, schodzi
       do następnego wiersza. `max-width` pilnuje, żeby nigdy nie wyszło poza
       panel. */
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 6px 10px;
    border: 2px solid #000;
    background: #fff;
    color: #000;
    font-family: inherit;
    /* 16 px to próg, poniżej którego iOS Safari powiększa całą stronę przy
       wejściu w pole. */
    font-size: 16px;
}

@media (max-width: 500px) {
    /* Ta sama zmiana wypełnienia, którą kompilat robi dla `.filter__container`:
       na wąskim ekranie panel jest szufladą na całą szerokość i kolumna tekstu
       jest szersza. */
    .janosik-filtr-data {
        padding-left: 6.6666666667vw;
        padding-right: 6.6666666667vw;
    }
}

/* --------------------------------------------------------------------------
   PODGLĄD DLA ZALOGOWANYCH — oznaczenie PRZY SAMYM ELEMENCIE.

   Po co, skoro jest już wpis w pasku administracyjnym i komentarz w kodzie
   strony: bo to nie wystarczyło. 25.08.2026 właściciel zobaczył pole wyboru
   daty jako zalogowany, uznał, że przeciekło do gości, i zgłosił błąd —
   sprawdzone `curl`-em, gość go nie widział, mechanizm działał poprawnie.
   Sygnalizacja, której nie widać przy elemencie, nie chroni przed tą pomyłką.

   Znika sama, gdy opcja zostanie naprawdę włączona: klasę nadaje szablon
   wyłącznie wtedy, gdy `janosik_a11y_podglad(<opcja>)` zwraca prawdę.
   -------------------------------------------------------------------------- */
.janosik-podglad {
    /* `outline`, nie `border`: nie zajmuje miejsca w układzie, więc podgląd
       wygląda dokładnie tak, jak będzie wyglądał po włączeniu opcji. */
    outline: 2px dashed #b3261e;
    outline-offset: 3px;
}

/*
 * TU NIE MA `position: relative` — i to jest świadome, bo pierwsza wersja je
 * miała i ZEPSUŁA przycisk pauzy.
 *
 * Zmierzone: `.swiper-pauza` ma `position: absolute`, a `.janosik-podglad` ma tę
 * samą specyficzność (jedna klasa) i stoi w arkuszu NIŻEJ — więc w podglądzie
 * wygrywało i przycisk przestawał być pozycjonowany względem karuzeli. Wypadał
 * 44 px poniżej jej dolnej krawędzi, a że karuzela ma `overflow: hidden`, było
 * go widać w jednej trzeciej. Zmierzone przy 1440 px: przycisk [594..638],
 * karuzela [112..604].
 *
 * Nie jest potrzebne: podpis przy przycisku pauzy pozycjonuje się względem
 * samego przycisku, który JEST pozycjonowany, a podpis przy polu daty jest
 * zwykłym elementem flex i nie pozycjonuje się wcale.
 */

.janosik-podglad::after {
    content: "podgląd — goście tego nie widzą";
    font-family: "Merriweather", Georgia, serif;
    font-size: 11px;
    line-height: 1.3;
    letter-spacing: .02em;
    text-transform: none;
    white-space: nowrap;
    padding: 2px 6px;
    border-radius: 3px;
    background: #b3261e;
    /* Biel na tym czerwonym daje kontrast 5,9 : 1 - powyżej progu 4,5 : 1 także
       dla tak małego tekstu. */
    color: #fff;
    pointer-events: none;
}

/* W bloku pola daty podpis jest zwykłym elementem układu: `.janosik-filtr-data`
   jest kontenerem flex ze zawijaniem, więc `::after` staje się jego elementem
   i schodzi do własnego wiersza. Nic nie zasłania i nic nie przesuwa. */
.janosik-filtr-data.janosik-podglad::after {
    flex: 0 0 100%;
    width: -moz-fit-content;
    width: fit-content;
    margin-top: 2px;
}

/* Przy przycisku pauzy podpis musi być POZA przyciskiem - inaczej stałby się
   elementem flex wewnątrz koła 44 × 44 px i rozepchnął je. Idzie nad przycisk,
   bo pod nim jest już krawędź karuzeli. */
.swiper-pauza.janosik-podglad::after {
    position: absolute;
    left: 0;
    bottom: calc(100% + 8px);
}
