/*
 * ============================================================================
 * MEGA-MENU "MIASTA" — WARSTWA DESKTOPOWA (≥992px)
 * ============================================================================
 *
 * Do 2026-09-07 plik nazywał się css/megamenu-test.css i ładował się wyłącznie
 * na stronie stagingowej "tora-tora-tora" (guard is_page()). Od migracji na
 * produkcję ładuje się na WSZYSTKICH stronach witryny Z WYJĄTKIEM kontekstu
 * sklepu — patrz mobilet_pl_enqueue_megamenu_assets() w inc/megamenu.php.
 *
 * Warstwa mobilna (≤991px) siedzi w osobnym css/megamenu-mobile.css,
 * kolejkowanym PO tym pliku i zależnym od niego. TEN plik pozostaje jedynym
 * źródłem prawdy dla desktopu.
 *
 * ---------------------------------------------------------------------------
 * ZASIĘG REGUŁ — co z tego pliku dotyka rzeczy WSPÓLNYCH z resztą witryny
 * ---------------------------------------------------------------------------
 * Przytłaczająca większość reguł celuje w klasy `.mega-menu*`, które istnieją
 * wyłącznie wewnątrz panelu — te są z definicji nieszkodliwe niezależnie od
 * tego, na ilu stronach plik się załaduje. Wyjątki, świadome i policzalne,
 * są TRZY i wszystkie żyją w `@media (min-width:992px)`:
 *
 *   1. `#header:not(.header-store) { height: var(--header-height) !important }`
 *      — patrz jej własny, obszerny komentarz niżej.
 *   2. `body::after` — overlay przyciemniający/rozmywający stronę pod otwartym
 *      panelem. Istnieje w drzewie ZAWSZE (opacity:0 + visibility:hidden +
 *      pointer-events:none), bo inaczej nie dałoby się go animować.
 *      Zweryfikowane przed migracją: żaden inny arkusz w tym motywie ani
 *      w motywie rodzica nie używa `body::after`, więc nie ma z czym kolidować.
 *   3. `#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open))
 *      #header-icon-actions { display:none }` (2026-09-08) — chowa nowe ikony
 *      lupy/pobierania w headerze (nowymobilet.css), gdy panel "Miasta" jest
 *      otwarty (duplikowałyby własną wyszukiwarkę/przycisk pobierania
 *      panelu). Bezpieczne poza tym plikiem: `#header-icon-actions` istnieje
 *      tylko dzięki tej migracji, nic innego go nie definiuje ani nie czyta.
 *
 * Przy dokładaniu tu KAŻDEJ nowej reguły celującej poza `.mega-menu*`:
 * sprawdzić, czy nie psuje strony bez mega-menu, i dopisać ją do tej listy.
 *
 * ---------------------------------------------------------------------------
 * DLACZEGO TYLE `!important` — i dlaczego to NIE jest lenistwo
 * ---------------------------------------------------------------------------
 * Panel jest potomkiem `#main-menu`, a produkcyjny nowymobilet.css ma na tej
 * ścieżce reguły oparte o ID: `#menu-item-447>.sub-menu{width:650px}`,
 * `#main-menu a{display:inline-block}` (≥992px) oraz — w warstwie mobilnej —
 * `.menu-mobile #main-menu a`/`li`. Selektor czysto klasowy MATEMATYCZNIE nie
 * może przebić selektora z ID, niezależnie od liczby doklejonych klas
 * (specyficzność porównuje najpierw liczbę ID-ków). `!important` jest tu więc
 * jedynym narzędziem, jakie działa — ten sam, udokumentowany w CLAUDE.md
 * wzorzec co "AAA contrast fix" w nowymobilet.css.
 *
 * Ta sama rodzina pułapek zjadła w tym projekcie już cztery osobne bugi
 * (font-size przycisku, padding linków miast, padding kart wyników, szary
 * pasek nad sticky toolbarem). WNIOSEK NA PRZYSZŁOŚĆ: każdy nowy `<a>` albo
 * `<li>` dodawany do panelu, który dostaje własny font-size/padding/
 * line-height/margin, dostaje `!important` OD RAZU — nie po zgłoszeniu buga.
 *
 * ---------------------------------------------------------------------------
 * IDENTYFIKACJA POZYCJI "MIASTA" — po klasie, nie po ID
 * ---------------------------------------------------------------------------
 * Cały ten plik dopasowuje po klasie CSS `.js-mega-menu-miasta` (ustawionej
 * ręcznie w Wygląd > Menu > "Miasta" > Klasy CSS), NIE po `#menu-item-447`.
 * Tamten numer to ID posta nav_menu_item — techniczny, autoinkrementowany,
 * zmienia się przy odtworzeniu pozycji menu, imporcie/eksporcie i migracji
 * środowiska; oparcie o niego dawałoby cichą regresję bez żadnego błędu.
 * To samo po stronie PHP, patrz modify_main_menu() w functions.php.
 * nowymobilet.css nadal używa `#menu-item-447` (świadomie nietknięte —
 * te reguły obsługują stary dropdown, czyli ścieżkę rollbacku) i oba
 * mechanizmy współistnieją bezkolizyjnie, bo WP generuje `id=menu-item-447`
 * niezależnie od dodanej klasy.
 *
 * Reguły ucinające listę na niskich ekranach
 * (`#menu-item-447>.sub-menu>li:nth-child(n+10/11/17){display:none}`,
 * nowymobilet.css) celują w BEZPOŚREDNIE dzieci `<li>` — panel ma ich
 * dokładnie jedno (`.mega-menu__inner-item`, opakowujące `.wrapper`), więc
 * fizycznie go nie łapią. Nie trzeba ich neutralizować; nie usuwać ich też
 * z nowymobilet.css, bo stary dropdown wciąż na nich stoi.
 */

/*
 * REGUŁY BAZOWE — neutralizacja markupu mobilnego na desktopie (2026-09-08)
 * ============================================================================
 * Przeniesione tu z css/megamenu-mobile.css, żeby TEN plik (megamenu-mobile.css)
 * mógł zostać kolejkowany z atrybutem `media="(max-width:991px)"` (patrz
 * mobilet_pl_enqueue_megamenu_assets(), inc/megamenu.php) — bez blokowania
 * renderu na desktopie żadną regułą spoza tej media query. TEN plik
 * (megamenu-desktop.css) ładuje się bezwarunkowo na każdej stronie (bez
 * atrybutu media), więc jest właściwym miejscem na coś, co musi obowiązywać
 * NIEZALEŻNIE od szerokości viewportu:
 *
 *   .mega-menu__toolbar { display: contents }  -> wrapper znika, .mega-menu__top
 *                                                 zostaje bezpośrednim dzieckiem
 *                                                 .mega-menu__grid i jego
 *                                                 flex:0 0 auto działa jak dotąd
 *   .mega-menu__filters { display: none }      -> chipy nie istnieją na desktopie
 *   .mega-menu__char-hint { display: none }    -> licznik brakujących znaków też nie
 *
 * Wszystkie trzy są konieczne właśnie po to, żeby desktop pozostał bez zmian —
 * markup mobilny w PHP musi być dla niego całkowicie przezroczysty, niezależnie
 * od tego, który z dwóch arkuszy faktycznie zastosował swoje reguły w danym
 * viewporcie.
 */

.mega-menu__toolbar {
	display: contents;
}

.mega-menu__filters {
	display: none;
}

.mega-menu__char-hint {
	display: none;
}

/*
 * Pozycjonowanie pełnoszerokościowego panelu — WYŁĄCZNIE desktop (≥992px,
 * ten sam breakpoint co istniejący mechanizm hover-dropdown w
 * nowymobilet.css:3628-4109). Poniżej 992px .sub-menu przechodzi na inny,
 * niedotknięty mechanizm (pełnoekranowy panel #submenu-nav-bar) — mega-menu
 * na mobile ma własną warstwę w css/megamenu-mobile.css, ładowaną PO tym
 * pliku — ten arkusz jej nie dotyczy.
 *
 * position:fixed (NIE absolute — próba position:absolute z 2026-09-02 cofnięta
 * tego samego dnia). Najbliższym pozycjonowanym przodkiem panelu NIE jest
 * #header, tylko sam <li class="js-mega-menu-miasta"> — ma position:relative
 * (.menu-item-has-children{position:relative}, potrzebne dla hover-bridge
 * niżej) i jako BEZPOŚREDNI rodzic <ul class="sub-menu"> przechwytuje
 * containing block dla position:absolute, zanim spec w ogóle dojdzie do
 * #header wyżej w drzewie. Efekt (potwierdzony wizualnie): panel kurczył
 * się do szerokości samej etykiety "Miasta" i pojawiał się tuż pod nią,
 * zamiast rozciągać się na pełną szerokość pod całym headerem. position:
 * fixed nie ma tego problemu — zgodnie ze spec ignoruje zwykłych position:
 * relative/absolute przodków i liczy się od najbliższego przodka z transform/
 * filter/will-change/perspective (żaden taki nie występuje na ścieżce
 * #header→li→ul) albo, w ich braku, wprost od viewportu — stąd oryginalny
 * wybór position:fixed w tym pliku był poprawny, nie przypadkowy.
 *
 * top: var(--header-height) — wraca do custom property (zamiast top:100%,
 * które przy position:fixed i tak liczyłoby się od WYSOKOŚCI VIEWPORTU, nie
 * od headera — inny, jeszcze gorszy błąd). Żeby wyeliminować ryzyko rozjazdu
 * o 1-2px między realną wysokością #header a tą wartością (zgłoszone
 * 2026-09-02 jako jaśniejszy pasek przy fade'zie panelu), #header dostaje
 * niżej w tym pliku (poza kontekstem sklepu) wymuszone realne
 * height:var(--header-height) zamiast dziedziczonego z nowymobilet.css
 * min-height — dzięki temu obie wartości są TĄ SAMĄ liczbą z definicji
 * (CSS to gwarantuje), a nie dwiema niezależnie liczonymi wartościami, które
 * powinny, ale nie muszą, wyjść równe.
 *
 * !important na każdej właściwości — patrz komentarz na górze pliku:
 * musi przebić ID-based "#menu-item-447>.sub-menu{width:650px}" z
 * nowymobilet.css, co czysto klasowy selektor nie osiągnie inaczej.
 */
@media (min-width: 992px) {

	/*
	 * WYSOKOŚĆ HEADERA — jedyna reguła w całym module celująca w element
	 * WSPÓŁDZIELONY z resztą witryny, stąd dwie niezależne warstwy ostrożności
	 * (ta i pominięcie enqueue w kontekście sklepu, patrz
	 * mobilet_pl_enqueue_megamenu_assets() w inc/megamenu.php).
	 *
	 * PO CO: panel jest position:fixed i kotwiczy się na top:var(--header-height),
	 * a hover-bridge liczy z niej swoją wysokość. Produkcyjny #header ma jednak
	 * min-height, nie height (nowymobilet.css) — jego REALNA wysokość wynika
	 * z zawartości (padding #header>div + najwyższy element w środku), a
	 * --header-height to ręcznie dobrana liczba, która MA się z nią pokrywać.
	 * Nic w CSS tego nie gwarantuje. Rozjazd o 1-2px (subpixel rounding, zmiana
	 * zawartości headera w przyszłości) objawiał się jaśniejszym paskiem na
	 * styku header↔panel podczas animacji — zgłoszone 2026-09-02. Wymuszenie
	 * height sprawia, że obie wartości są TĄ SAMĄ liczbą z definicji, a nie
	 * dwiema niezależnie liczonymi, które tylko powinny wyjść równe.
	 *
	 * :not(.header-store) — nagłówek sklepu ma własny układ (woocommerce.css,
	 * flex + order, ikona koszyka zamiast menu) i nigdy nie był testowany
	 * z wymuszoną, sztywną wysokością. Mega-menu tam nie istnieje (header.php
	 * renderuje w tym kontekście hardkodowaną listę bez wp_nav_menu), więc
	 * reguła nie ma tam czego obsługiwać — a ma co zepsuć.
	 *
	 * TEMPO ANIMACJI #header — ŚWIADOMIE NIE NADPISUJEMY (decyzja przy migracji
	 * na produkcję 2026-09-07). Do tej pory ten plik wymuszał tu
	 * `transition-duration:.28s!important`, żeby zbielenie headera szło w
	 * jednym tempie z rosnącym panelem i overlayem. Na jednej stronie
	 * stagingowej to było bezpieczne; sitewide zmieniałoby tempo przejścia
	 * przezroczysty→biały przy scrollu na stronie głównej, czyli zachowanie
	 * niezwiązane z mega-menu. Zostaje produkcyjne `transition: all .1s`
	 * (nowymobilet.css). Przyjęty koszt: na stronie głównej (jedynej z
	 * przezroczystym headerem) header zbieleje szybciej, niż panel skończy
	 * rosnąć. To jest wybór, nie przeoczenie — gdyby desync okazał się
	 * widoczny i przeszkadzający, właściwą naprawą jest dopisanie tu
	 * `transition-duration` z powrotem, nie skracanie animacji panelu.
	 */
	#header:not(.header-store) {
		height: var(--header-height) !important;
	}

	/*
	 * prefers-reduced-motion (2026-09-04) — dopisane razem ze zmianą fade→
	 * height-grow, bo dopiero wtedy animacja stała się wystarczająco widoczna
	 * (wzrost wysokości, nie tylko opacity), żeby jej wyłączenie miało
	 * realne znaczenie dla osób z ustawieniem "ogranicz animacje". Wzorem
	 * FAQ Akordeonu w mobilet.eu (css/faq-accordion.css) — zeruje WSZYSTKIE
	 * animowane właściwości, nie tylko część.
	 *
	 * #header świadomie NIEOBECNY na tej liście (2026-09-07): skoro nie
	 * przejmujemy kontroli nad jego `transition` w stanie zwykłym (patrz
	 * wyżej), nie zerujemy jej też warunkowo — inaczej ten moduł zmieniałby
	 * zachowanie współdzielonego elementu tylnymi drzwiami, tylko dla części
	 * użytkowników.
	 */
	@media (prefers-reduced-motion: reduce) {

		.js-mega-menu-miasta>.sub-menu.mega-menu--test,
		.js-mega-menu-miasta:is(:hover, .mm-force-open)>.sub-menu.mega-menu--test,
		body::after,
		body:has(.js-mega-menu-miasta:is(:hover, .mm-force-open))::after,
		/* 2026-09-06 — search bar UX (kolaps przycisku, crossfade kolumny/wyniki) */
		.mega-menu__top-row .mega-menu__all-link.button,
		.mega-menu--test .mega-menu__columns,
		.mega-menu--test .mega-menu__search-results {
			transition: none !important;
		}

		/*
		 * Karty-szkielety (2026-09-07) — `transition:none` wyżej już zeruje
		 * animację ZMIANY WYSOKOŚCI panelu (setResultsContent() w
		 * js/megamenu-search.js i tak pomija animację przy tym ustawieniu —
		 * RESIZE_MS=0, patrz jej komentarz), ale to osobna właściwość
		 * (`animation`, nie `transition`) odpowiada za sam migoczący
		 * gradient shimmer na kartach — bez jawnego zera migałby w
		 * nieskończoność nawet przy wyłączonych innych animacjach panelu.
		 */
		.mega-menu--test .mega-menu__result-skeleton {
			animation: none !important;
			background-image: none !important;
			background-color: var(--light) !important;
		}
	}

	.js-mega-menu-miasta>.sub-menu.mega-menu--test {
		position: fixed !important;
		top: var(--header-height) !important;
		left: 0 !important;
		right: 0 !important;
		margin-top: 0 !important;
		width: auto !important;
		max-width: none !important;
		/*
		 * ZAOKRĄGLENIE DOLNYCH ROGÓW (2026-09-06, na życzenie) — dotychczas
		 * `0 !important` na wszystkich czterech rogach (panel pełnoszerokościowy,
		 * dotyka lewej/prawej krawędzi viewportu — kwadratowe rogi były wtedy
		 * zamierzone). Zmienione na `0 0 1rem 1rem !important` (góra bez zmian,
		 * dół zaokrąglony) — nadal `!important`, bo bez niego przegrałoby z
		 * odziedziczonym `.sub-menu{border-radius:var(--radius)}`
		 * (nowymobilet.css:4089) tylko przez przypadek kolejności, a properties
		 * nadpisywane tu celowo mają być jednoznacznie wygrywające, niezależnie
		 * od tego, co jeszcze zmieni się w bazowej regule w przyszłości.
		 * ŚWIADOMIE NIE na `.mega-menu--test .mega-menu__grid` (wewnętrzny,
		 * węższy `<div>` centrujący treść do max-width:1200px) — ten element
		 * nie ma własnego tła/obramowania, więc zaokrąglenie na nim byłoby
		 * niewidoczne; to WŁAŚNIE ten `<ul>` (pełnoszerokościowy, z tłem
		 * odziedziczonym z bazowego `.sub-menu`) jest wizualnym pudełkiem
		 * panelu.
		 */
		border-radius: 0 0 1rem 1rem !important;
		/*
		 * WRAPPER (2026-09-03): panel ma wyrównanie identyczne z treścią
		 * strony — na życzenie. `display:grid` + boczny padding (1.25rem,
		 * stała wartość na każdej szerokości) siedziały kiedyś bezpośrednio
		 * na tym elemencie (pełnoszerokościowym, position:fixed), więc siatka
		 * miast wyrównywała się do WŁASNEJ, niezależnej krawędzi — inaczej niż
		 * logo/nawigacja w headerze czy treść sekcji pod spodem, które używają
		 * sitewide `.wrapper` (nowymobilet.css:379-382 + breakpointy
		 * 768/992/1200/1400/1600px, max-width 750→1560px). Naprawa: ten
		 * element zostaje już TYLKO pełnoszerokościową "sekcją" (tłem +
		 * pozycjonowaniem, jak `.section` gdzie indziej w motywie) — grid
		 * kolumn i poziomy padding żyją na `.mega-menu__grid` (klasa
		 * `.wrapper` + `.mega-menu__grid` razem na jednym `<div>`, wnuku tego
		 * elementu, patrz inc/megamenu.php i reguła `.mega-menu__grid`
		 * niżej w tym pliku) — DOKŁADNIE ten sam mechanizm co
		 * `.section > .wrapper` na zwykłych stronach.
		 *
		 * PIONOWY padding (góra/dół panelu jako całości) i `min-height`
		 * PRZENIESIONE na `.mega-menu__grid` (2026-09-04, patrz reguła
		 * `.mega-menu__inner-item`/`.mega-menu__grid` niżej) — nie usunięte,
		 * tylko przesunięte, żeby zadziałała mechanika wzrostu wysokości
		 * poniżej: ten element (`<ul>`) jest teraz kontenerem grida
		 * animowanym przez `grid-template-rows`, a WŁASNY padding takiego
		 * kontenera zawsze dolicza się do jego wysokości niezależnie od tego,
		 * na ile skurczy się rząd (`0fr` zeruje tylko wysokość *rzędu*, nie
		 * paddingu) — zamknięty panel nigdy nie zjechałby do prawdziwego
		 * zera, tylko do ~17px (dawne `1px 0 1rem`). Padding/min-height muszą
		 * więc żyć na potomku wewnątrz `overflow:hidden` (na `<li>`, patrz
		 * niżej) — identyczny wzorzec co `faq-accordion__panel` (bez
		 * paddingu) vs `faq-accordion__panel-inner` (z paddingiem) w
		 * mobilet.eu. Wartości (`1px` góra / `1rem` dół) zostają te same co
		 * ustalone 2026-09-03 — to przeniesienie, nie cofnięcie tamtej
		 * decyzji.
		 */
		padding: 0;
		/*
		 * Cień USUNIĘTY (2026-09-06, decyzja ostateczna) — poprzednia wersja
		 * (2026-09-05) rysowała tu dwuwarstwowy cień "elevation" (te same
		 * wartości co #header:has(...) niżej w tym pliku, patrz historia w
		 * CLAUDE.md). `box-shadow: none` jest tu KONIECZNY, nie tylko brak
		 * deklaracji — bazowa `.sub-menu` (nowymobilet.css:4044) ma własny
		 * `box-shadow:0px 1px 5px 0px var(--shadow)`; bez jawnego `none` ten
		 * odziedziczony cień "wypłynąłby" z powrotem. Cień #header w stanie
		 * otwartego mega-menu (`#header:has(.js-mega-menu-miasta:hover)`
		 * niżej) zostaje bez zmian — to osobny element (header, nie panel),
		 * poza zakresem tej decyzji.
		 */
		box-shadow: none;
		/*
		 * max-height (2026-09-06, PRZYWRÓCONE po przypadkowym cofnięciu —
		 * patrz nagłówek CLAUDE.md — ZASTĘPUJE odziedziczone `max-height:90vh`
		 * z bazowej .sub-menu, nowymobilet.css:4049) — `90vh` było niedokładne:
		 * przy `top:var(--header-height)` (90px na desktopie) panel mógł
		 * wystawać poniżej dolnej krawędzi viewportu na niższych ekranach
		 * (np. 700px wysokości: 90px + 90vh(630px) = 720px, 20px za dużo).
		 * `calc(100vh - var(--header-height))` liczy dokładnie dostępną
		 * przestrzeń pod headerem — ta sama technika co `.module-hero` na
		 * mobile (`calc(100dvh - var(--header-height))`).
		 */
		max-height: calc(100vh - var(--header-height));
		/*
		 * overflow-y:hidden (2026-09-06, PRZYWRÓCONE — ZMIENIONE z `auto`) —
		 * ten `<ul>` przestał być kontenerem scrolla. Refaktor "scrollowalność
		 * mega-menu": `.mega-menu__top` (wiersz "Wszystkie miasta"/search/
		 * "Pobierz aplikację") ma zostać zawsze w pełni widoczny, a scroll ma
		 * dotyczyć WYŁĄCZNIE `.mega-menu__columns` — nie całego panelu naraz,
		 * jak dotychczas. Nowy, wewnętrzny podział flexboksem (patrz
		 * `.mega-menu__inner-item`/`.mega-menu--test .mega-menu__grid`/
		 * `.mega-menu--test .mega-menu__columns` niżej) gwarantuje, że treść
		 * nigdy nie przekroczy wysokości dostępnej w tym `<ul>` — stąd `hidden`
		 * zamiast `auto` jest tu bezpieczne (nic już nie powinno go
		 * przepełniać; scroll przejął `.mega-menu__columns`).
		 */
		overflow-y: hidden;
		/*
		 * Mechanika wzrostu wysokości (2026-09-04) — grid-template-rows
		 * 0fr→1fr, TA SAMA technika co FAQ Akordeon w mobilet.eu
		 * (css/faq-accordion.css, `.faq-accordion__panel`). Świadomie NIE
		 * technika Apple (który mierzy wysokość treści przez JS i animuje
		 * przez CSS custom property, patrz uzasadnienie w planie/CLAUDE.md) —
		 * w tym projekcie jest udokumentowana silna preferencja przeciwko
		 * JS-mierzonej wysokości. `position:fixed` bez `bottom`/`height` nie
		 * przeszkadza: wysokość tego elementu i tak jest dziś `auto`
		 * (content-driven), więc `grid-template-rows` wpina się w ten sam
		 * tor bez konfliktu z position:fixed. Kolaps do zera wymaga też
		 * `overflow:hidden` na jedynym dziecku (`<li class="mega-menu__inner-item">`,
		 * patrz reguła niżej) — samo grid-template-rows na tym elemencie nie
		 * wystarczy.
		 */
		display: grid;
		grid-template-rows: 0fr;
		/*
		 * Bazowa .sub-menu (nowymobilet.css:4040) fade'uje się w/z .2s —
		 * za szybko, odkąd panel realnie ROŚNIE wysokością zamiast tylko
		 * fade'ować (patrz grid-template-rows wyżej). Nadpisane na .28s
		 * ease-in-out — wartość z widełek, w których animuje wysokość swojego
		 * panelu apple.com (.24-.32s, sprawdzone w ich realnym CSS); .2s
		 * wyglądałoby jak skok, nie jak unoszenie się. Overlay (body::after
		 * niżej) używa dokładnie tej samej wartości, żeby oba elementy
		 * poruszały się jako jeden ruch.
		 *
		 * UWAGA (2026-09-07, migracja na produkcję): #header NIE jest już
		 * zsynchronizowany z tą wartością. Ten plik przestał nadpisywać jego
		 * `transition-duration` — zostaje produkcyjne `.1s` z nowymobilet.css,
		 * bo arkusz ładuje się teraz sitewide i zmiana tempa dotknęłaby też
		 * przejścia przezroczysty→biały przy scrollu na stronie głównej,
		 * czyli zachowania niezwiązanego z mega-menu. Skutek: na stronie
		 * głównej (jedynej z przezroczystym headerem) header zbieleje szybciej,
		 * niż panel skończy rosnąć. Świadomie przyjęte — patrz obszerny
		 * komentarz przy regule #header na górze pliku.
		 *
		 * Kierunek zamknięcia (visibility 0s linear .28s) nadpisany osobno
		 * niżej na 0s delay przy :hover, tak jak overlay poniżej — ten sam
		 * wzorzec co FAQ akordeon w mobilet.eu (CLAUDE.md).
		 */
		transition: grid-template-rows .28s ease-in-out, opacity .28s ease-in-out, visibility 0s linear .28s;
	}

	.js-mega-menu-miasta:is(:hover, .mm-force-open)>.sub-menu.mega-menu--test {
		grid-template-rows: 1fr;
		transition: grid-template-rows .28s ease-in-out, opacity .28s ease-in-out, visibility 0s linear 0s;
	}

	/*
	 * `.mm-force-open` (2026-09-08) — drugi wyzwalacz otwarcia panelu, obok
	 * `:hover`, dla nowej ikony lupy w headerze desktopowym (na lewo od
	 * przycisku "Portal", patrz header.php/nowymobilet.css) — panel "Miasta"
	 * był dotąd wyłącznie hover-based, bez żadnego sposobu na otwarcie go z
	 * klawiatury/kliknięcia z dystansu. Klasa jest przełączana przez JS
	 * (js/megamenu-header-icons.js) bezpośrednio na `.js-mega-menu-miasta`,
	 * DOKŁADNIE tak jak realny `:hover`, więc wszędzie tam gdzie reszta tego
	 * pliku (i `.sub-menu` w nowymobilet.css) reaguje na `:hover` na tym
	 * elemencie, selektor rozszerzono o `:is(:hover, .mm-force-open)` —
	 * `:is()` liczy specyficzność jak NAJWIĘKSZY ze swoich argumentów, więc
	 * to zero-ryzykowna podmiana: wynikowa specyficzność selektora jest
	 * DOKŁADNIE taka sama jak samego `:hover` (jedna pseudoklasa = jedna
	 * klasa), żadna z dotychczasowych reguł/kolejności/`!important` nie
	 * wymagała przeliczenia. WYJĄTEK świadomie pominięty: hover-bridge
	 * (`.js-mega-menu-miasta:hover::before` niżej w tym pliku) zostaje
	 * czystym `:hover` — to wyłącznie poszerzenie strefy wykrywania kursora
	 * między etykietą a panelem, nieistotne przy otwarciu bez fizycznego
	 * ruchu myszy.
	 *
	 * Ta konkretna reguła (widoczność/opacity) jest INNA niż pozostałe
	 * podmiany `:is()` w tym pliku — bo prawdziwym źródłem `visibility`/
	 * `opacity` dla KAŻDEGO dropdownu (Miasta/O nas/Pomoc) jest generyczna
	 * `.menu-item-has-children:hover>.sub-menu` w nowymobilet.css (sekcja
	 * "navigation main menu", numer linii przesuwa się przy każdej zmianie
	 * pliku, nie referuję go tu na sztywno), współdzielona z "O nas"/"Pomoc"
	 * — świadomie NIE dotknięta (rozszerzenie
	 * jej o `.mm-force-open` otworzyłoby drzwi do przypadkowego wpływu na
	 * dropdowny, których ta klasa nigdy nie dotyczy). Zamiast tego: osobna,
	 * Miasta-specyficzna reguła tutaj, o tej samej specyficzności (3 klasy)
	 * co reguła generyczna — remis rozstrzyga kolejność w kaskadzie, a ten
	 * plik ładuje się PO nowymobilet.css (patrz zależność w enqueue,
	 * inc/megamenu.php), więc wygrywa bez potrzeby `!important`.
	 */
	.js-mega-menu-miasta.mm-force-open>.sub-menu {
		visibility: visible;
		opacity: 1;
	}

	/*
	 * Hover-bridge — zamyka martwą strefę między dołem etykiety "Miasta"
	 * a górną krawędzią panelu. #main-menu>li jest float-based, więc
	 * "Miasta" (linia tekstu, ~1 wiersz) siedzi mniej więcej na środku
	 * dużo wyższego #header (6.4rem na tym breakpoincie) — między dołem
	 * tekstu a dołem headera (gdzie zaczyna się panel, patrz reguła
	 * position:fixed/top wyżej) jest fizycznie puste tło headera, którego
	 * NIC nie pokrywa. Mysz przechodząca przez ten obszar traci :hover na
	 * .js-mega-menu-miasta (bo pusta przestrzeń nie jest ani częścią li,
	 * ani częścią panelu) zanim zdąży dotrzeć do panelu — stąd zjawisko
	 * "za wolny ruch kursorem w dół zamyka mega-menu".
	 *
	 * Naprawa: niewidoczny ::before, potomek .js-mega-menu-miasta (więc
	 * hover na nim = hover na li, ten sam mechanizm co dziś działający
	 * hover na .sub-menu), zaczynający się dokładnie na dole li
	 * (top:100% — zero przerwy, tak jak zawsze działający dropdown) i
	 * rozciągnięty w dół o pełną wysokość headera. Li może siedzieć
	 * gdziekolwiek między górą a dołem headera — start+var(--header-height)
	 * gwarantuje dotarcie co najmniej do dołu headera (matematycznie: li.bottom
	 * ≥ 0, więc li.bottom + header-height ≥ header-height = header.bottom),
	 * z zapasem wchodzącym w górę panelu (nieszkodliwe, panel i tak jest
	 * wtedy nad nim wizualnie i przejmuje hover bezpośrednio).
	 *
	 * SZEROKOŚĆ 500px, wyśrodkowana, ALE TYLKO gdy li jest już aktywnie
	 * najechane (2026-09-04, dwuetapowa poprawka na życzenie). Etap 1 tego
	 * samego dnia: stałe (zawsze obecne) width:500px zamiast width:100%
	 * (= dokładnie szerokość li) — miało pokryć ruch kursorem na ukos, nie
	 * tylko prostopadle w dół. Zgłoszony na żywym podglądzie skutek uboczny:
	 * most szerokości 500px istniejący ZAWSZE (niezależnie od tego, czy ktoś
	 * w ogóle najeżdża na "Miasta") realnie przechwytywał hover/klik na
	 * sąsiednich pozycjach głównego menu w sposób nieakceptowalny — bo
	 * #main-menu>li mają tylko margin-left:1.2rem odstępu między sobą, więc
	 * 250px zapasu w każdą stronę od środka "Miasta" z definicji nachodziło
	 * na sąsiadów, permanentnie, nie tylko w trakcie faktycznego korzystania
	 * z mega-menu.
	 *
	 * Etap 2 (ten wpis): domyślny stan ::before wraca do width:100%/left:0
	 * (= dokładnie szerokość li, DOKŁADNIE jak przed etapem 1 — zero zapasu,
	 * zero ryzyka nachodzenia na spoczynku) — poszerzenie do 500px
	 * wyśrodkowanych przeniesione do osobnej reguły `.js-mega-menu-miasta:
	 * hover::before`, więc obowiązuje WYŁĄCZNIE w oknie czasowym, w którym
	 * :hover na li i tak już jest true. Działa, bo ::before jest częścią
	 * drzewa renderowania li (generated box) — trafienie weń liczy się jako
	 * hover na li, dokładnie ten sam mechanizm, na którym opiera się cały
	 * bridge. Sekwencja zdarzeń przy realnym ruchu myszą: (1) kursor wchodzi
	 * na tekst "Miasta" → :hover na li staje się true poprzez zwykłe trafienie
	 * w link, ::before w tej samej klatce przelicza się na 500px (przeglądarka
	 * rozstrzyga dopasowanie selektorów synchronicznie, przed hit-testem
	 * kolejnej pozycji kursora — brak opóźnienia/migotania); (2) dalszy ruch
	 * na ukos ląduje już w rozszerzonym (500px) moście, bo ten zdążył urosnąć
	 * zanim kursor go opuścił; (3) most, będąc wciąż potomkiem li, podtrzymuje
	 * :hover → self-sustaining, dokładnie ta sama zasada co dotychczasowe
	 * "hover na .sub-menu = hover na li". Selektor `:hover::before` ma wyższą
	 * specyficzność (0,2,1) niż baza (0,1,1) — wygrywa bez !important.
	 *
	 * RESZTKOWE RYZYKO (świadomie zaakceptowane, dużo węższe niż w etapie 1):
	 * jeśli sąsiednia pozycja menu (np. "O nas") leży fizycznie na tyle
	 * blisko "Miasta", że mieści się w promieniu 250px OD ŚRODKA "Miasta",
	 * to w trakcie, gdy użytkownik JUŻ najechał na "Miasta" (menu otwarte,
	 * :hover aktywny) i przesuwa kursor w stronę tej sąsiedniej pozycji nie
	 * opuszczając jeszcze granic (teraz szerokiego) mostu, ten wciąż
	 * przechwyci hover zamiast oddać go sąsiadowi — aż kursor faktycznie
	 * wyjdzie poza jego (px-owe) granice. W przeciwieństwie do etapu 1 dzieje
	 * się to tylko PODCZAS aktywnej interakcji z "Miasta", nie permanentnie
	 * dla każdego ruchu myszą w tamtym rejonie headera. Do zweryfikowania na
	 * żywo po wgraniu — jeśli nadal odczuwalne, kandydat
	 * na dalszą naprawę: `clip-path` przycinający most do samej pustej strefy
	 * pod headerem zamiast pełnego prostokąta 500px.
	 *
	 * WYSOKOŚĆ zredukowana z pełnego var(--header-height) na
	 * calc(var(--header-height)/2) (2026-09-05, na życzenie, potwierdzone na
	 * żywym podglądzie — nawet po zawężeniu mostu do width:100% w spoczynku,
	 * pełna wysokość nadal "łapała" kursor dużo niżej niż faktycznie trzeba).
	 * Powód, dlaczego pełna wysokość była nadmiarowa w PRAKTYCE (nie tylko
	 * w teoretycznym najgorszym przypadku z komentarza wyżej): #main-menu
	 * jest float-based (li:float:left), a floaty siadają przy GÓRNEJ krawędzi
	 * swojego kontenera, nie centrują się w nim — #main-menu, jako element
	 * gridu #header>div (domyślne align-items:stretch, brak override'u),
	 * jest rozciągnięty na całą wysokość wiersza (~40px, header 90px minus
	 * pionowy padding 25px×2), więc li faktycznie siedzi tuż pod górnym
	 * paddingiem, blisko GÓRY headera — nie na jego środku, jak sugerowałby
	 * ogólny opis wyżej. Dystans od dołu li do dołu headera wychodzi więc
	 * dużo mniejszy niż cała wysokość headera (rząd 40-45px, nie 90px).
	 * calc(/2)=45px to świadomy, przybliżony kompromis: mniej arbitralny niż
	 * sztywna liczba px (nadal skaluje się automatycznie z --header-height,
	 * gdyby ta zmienna znów się zmieniła — ma już historię zmian w tym
	 * projekcie), ale wciąż SZACUNEK, nie wyliczenie — dokładna wysokość
	 * linii tekstu "Miasta" zależy od metryk fontu Commissioner, niemożliwych
	 * do policzenia w 100% z samego CSS (ten sam, wielokrotnie już w tym
	 * projekcie udokumentowany limit, patrz CLAUDE.md przy --header-height).
	 * Współdzielona przez OBA stany (spoczynek i :hover) — reguła `:hover`
	 * niżej nie nadpisuje height, więc zmiana obowiązuje jednakowo w obu;
	 * nie ma powodu, dla którego stan aktywny potrzebowałby innej wysokości
	 * niż spoczynkowy — oba mają dokładnie to samo zadanie: dosięgnąć dołu
	 * headera, niezależnie od aktualnej szerokości mostu. Nie zweryfikowane
	 * w żywej przeglądarce w TEJ sesji (zmiana na słowo użytkownika, który
	 * widział realny render) — jeśli po wgraniu nadal za nisko/za wysoko,
	 * wartość do doregulowania ręcznie, to nie jest liczba z gwarancją.
	 */
	.js-mega-menu-miasta::before {
		content: '';
		position: absolute;
		top: 100%;
		left: 0;
		width: 100%;
		height: 2px;
	}

	.js-mega-menu-miasta:hover::before {
		left: 50%;
		transform: translateX(-50%);
		width: 90vw;
		height: calc(var(--header-height) / 1.8);
	}

	/*
	 * Wymuszenie solid/białego headera, gdy mega-menu jest otwarte —
	 * niezależnie od stanu przezroczystości strony (`.dynamic.transparent`
	 * na starcie strony głównej/staging). Wymóg: mega-menu ma się
	 * pojawiać ZAWSZE pod białym headerem, nigdy pod przezroczystym.
	 *
	 * .js-mega-menu-miasta:hover jest true zarówno przy hover na samym li,
	 * jak i na dowolnym jego potomku — bridge wyżej i sam .sub-menu (mimo
	 * position:fixed, wciąż potomek w DOM) — więc jeden selektor
	 * wystarcza na cały czas otwarcia panelu, nie tylko w pierwszej chwili.
	 *
	 * !important konieczny: #header:has(.js-mega-menu-miasta:hover) ma
	 * tylko 1 ID (#header) + 2 "klasy" (klasa + :hover w argumencie :has),
	 * podczas gdy konkurencyjna reguła sitewide
	 * ".dynamic.transparent:not(.menu-mobile) #header.image-dark *" ma
	 * TEŻ 1 ID + aż 4 klasy — przy remisie liczby ID-ków rozstrzyga liczba
	 * klas, więc bez !important ta reguła by przegrała (w poprzedniej
	 * wersji z "#menu-item-447" wygrywała dzięki 2 ID-kom — utracone przy
	 * przejściu na klasę, świadomy kompromis na rzecz niezależności od ID).
	 *
	 * border-bottom → box-shadow (2026-09-05, na życzenie, zastępuje wpis
	 * z 2026-09-03 o `border-bottom:var(--white)`). Ten sam dzień, dwa kroki:
	 * (1) najpierw ta reguła (test) dostała `border-bottom:none` + własny
	 * box-shadow zamiast maskowania szarej linii kolorem białym; (2) zaraz
	 * potem to samo trafiło na PRODUKCJĘ — bazowa `#header` w
	 * `nowymobilet.css:2981-2994` (stan spoczynku, KAŻDA strona motywu, nie
	 * tylko ta testowa) też zamieniła `border-bottom:1px solid var(--lightgray)`
	 * na dokładnie ten sam box-shadow (te same wartości rgba/blur, celowo —
	 * spójny, jeden cień w obu stanach, nie dwa różne). Efekt: ta reguła
	 * (test, stan otwartego mega-menu) i produkcyjny stan spoczynku #header
	 * używają teraz identycznego box-shadow — `border-bottom:none` tutaj
	 * pozostaje jawnie ustawiony (nieszkodliwie, produkcja i tak już nie ma
	 * border-bottom do przykrycia), a `box-shadow` tutaj jest wciąż POTRZEBNY
	 * mimo tego, że produkcja go już ma domyślnie — bo `.dynamic.transparent
	 * #header` (front page / strona testowa w trybie hero, nowymobilet.css)
	 * jawnie zeruje ten cień (`box-shadow:none`, żeby nic nie rysowało linii
	 * nad zdjęciem hero) i ta reguła musi go przywrócić, gdy mega-menu się
	 * otwiera nawet w tamtym stanie. Dwie warstwy cienia (bliska, ostra
	 * 1px/2px + szeroka, rozmyta 3px/12px) — typowy wzorzec "elevation"
	 * (krótki, mocny cień kontaktowy + długi, delikatny cień otoczenia), nie
	 * jeden gruby blur. Linia pod `.mega-menu__top` (nadal `1px solid
	 * var(--lightgray)`, prawdziwy border, nie cień) świadomie NIETKNIĘTA —
	 * pełni rolę widocznego separatora treści panelu, nie krawędzi headera —
	 * inny cel, inny mechanizm, patrz jej własny komentarz niżej w pliku.
	 */
	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) {
		background-color: var(--white) !important;
		border-bottom: none !important;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 3px 12px rgba(0, 0, 0, 0.06) !important;
	}

	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) * {
		color: var(--black) !important;
	}

	/*
	 * Wyjątek od reguły wyżej — 2026-09-03, naprawa zgłoszonego buga:
	 * `#header:has(...) *` wymusza czarny tekst na KAŻDYM elemencie
	 * wewnątrz #header, gdy panel jest otwarty (a otwarty panel to jedyny
	 * moment, w którym te przyciski są w ogóle widoczne — więc reguła wyżej
	 * jest efektywnie ZAWSZE aktywna, kiedy user może je zobaczyć). Objaw:
	 * czarny przycisk "Zobacz wszystkie miasta" renderował się bez widocznego
	 * tekstu (czarny na czarnym), a niebieski "Pobierz aplikację" — z czarnym
	 * tekstem zamiast białego. Reguła wyżej ma `!important`, więc zwykłe
	 * `color:var(--white)` w regułach przycisków (niżej w tym pliku) nigdy
	 * jej nie przebije niezależnie od specyficzności — `!important` zawsze
	 * wygrywa z nie-`!important`, dopiero między dwoma `!important` liczy się
	 * specyficzność. Stąd ten wyjątek musi: (a) też mieć `!important`, (b) mieć
	 * WYŻSZĄ specyficzność niż `#header:has(...) *` (1 ID + 1 :has = (1,2,0)) —
	 * osiągnięte przez powtórzenie identycznego prefiksu `#header:has(...)`
	 * (ten sam 1 ID + 1 :has) i doklejenie klas konkretnych przycisków, co
	 * daje (1,4,0) > (1,2,0), wygrywa mimo tej samej ważności.
	 */
	/*
	 * 2026-09-05 — `.mega-menu__download-btn` USUNIĘTY z tego wyjątku po
	 * redesignie przycisku (białe tło, czarny tekst zamiast niebieskiego/
	 * białego) — blanket rule wyżej (`#header:has(...) * {color:black!important}`)
	 * daje teraz sam z siebie poprawny kolor, wyjątek nadpisywałby go
	 * błędnie z powrotem na biały. `.mega-menu__all-link.button` zostaje —
	 * nadal potrzebuje białego tekstu na swoim tle.
	 */
	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) .mega-menu__top-row .mega-menu__all-link.button {
		color: var(--white) !important;
	}

	/*
	 * BUG (2026-09-07, zgłoszony na żywym podglądzie): "Zobacz wszystkie
	 * miasta" renderował się CZARNY przez cały czas trwania animacji
	 * ROZWIJANIA panelu i zmieniał się na biały dopiero, gdy animacja się
	 * skończyła — przy zwijaniu dokładnie odwrotnie (biały przez całą
	 * animację, czarny dopiero po jej zakończeniu). Oba wyjątki wyżej
	 * (`#header:has(...) *` i jej override na tym przycisku) są bramkowane
	 * WYŁĄCZNIE przez `:has()` — a `:has()` to wciąż stosunkowo świeży,
	 * relacyjny pseudoselektor, którego przeliczanie stylu w praktyce (na
	 * żywym podglądzie) okazuje się w tym silniku ZDANE NA LOS podczas
	 * trwającej równolegle animacji layoutu (`grid-template-rows` panelu) —
	 * odświeża się dopiero, gdy ta animacja "osiądzie", zamiast natychmiast
	 * przy faktycznej zmianie stanu hover. W tym oknie czasowym NIC z
	 * `:has(...)` nie jest jeszcze aktywne (ani czarny blanket, ani biały
	 * wyjątek) — obowiązuje więc jedyna pozostała deklaracja `color` na tym
	 * elemencie: bazowe `color:var(--black)` (bez `!important`, patrz reguła
	 * `.mega-menu__top-row .mega-menu__all-link.button` wyżej w pliku) —
	 * stąd czarny tekst aż do "dogonienia się" `:has()`.
	 *
	 * Naprawa: DODATKOWA reguła obok istniejącego wyjątku (nie zamiast) —
	 * ten sam efekt (biały tekst), ale bramkowana zwykłym `:hover` na
	 * przodku, BEZ `:has()`. Zwykłe `:hover` przelicza się synchronicznie z
	 * realną zmianą stanu myszy, niezależnie od tego, co w tej samej klatce
	 * robi animacja layoutu gdzie indziej w drzewie — zamyka lukę czasową
	 * opisaną wyżej w obie strony (biały od razu na wejściu w hover, czarny
	 * od razu na wyjściu, nie dopiero po zakończeniu animacji). Specyficzność
	 * (0,5,0, bez ID) jest NIŻSZA niż blanket `#header:has(...) *` (1,2,0) —
	 * nieszkodliwe: gdy `:has()` faktycznie już jest aktywne, isniejący
	 * wyjątek `:has(...)` wyżej (1,4,0 > 1,2,0) i tak wygrywa z blanketem i
	 * daje tę samą wartość (biały) — ta reguła dokłada tylko pokrycie na
	 * czas, zanim `:has()` się "dogoni".
	 */
	.js-mega-menu-miasta:is(:hover, .mm-force-open) .mega-menu__top-row .mega-menu__all-link.button {
		color: var(--white) !important;
	}

	/*
	 * Wyjątek analogiczny do wyżej (2026-09-06, wyszukiwarka miast) —
	 * `.mega-menu__result-subtitle` (druga linia karty wyniku, tekst h1
	 * wpisu) ma być SZARA (`var(--gray)`, ten sam odcień co
	 * `.mega-menu__news-card-start`), a blanket `#header:has(...) *
	 * {color:black!important}` wyżej wymusiłby na niej czarny bez tego
	 * wyjątku — sama specyficzność (0,2,0 tej reguły vs (1,1,0) blanketu,
	 * ID zawsze wygrywa) nie wystarczy nawet bez !important, więc
	 * potrzebne jest DOKŁADNIE to samo obejście: powtórzenie prefiksu
	 * `#header:has(.js-mega-menu-miasta:hover)` (ten sam 1 ID + 1 :has, więc
	 * REMIS na pierwszych dwóch poziomach specyficzności) + własna klasa
	 * (dodatkowy punkt na trzecim poziomie, wygrywa). `.mega-menu__result-title`
	 * (nazwa miasta) NIE potrzebuje analogicznego wyjątku — ma być czarna, a
	 * blanket rule już to zapewnia sama z siebie (ten sam powód, dla którego
	 * `.mega-menu__news-card-title` też nie ma takiego wyjątku).
	 */
	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) .mega-menu__result-subtitle {
		color: var(--gray) !important;
	}

	/*
	 * PRZY OKAZJI ZNALEZIONY I NAPRAWIONY osobny, PREEXISTUJĄCY bug tego
	 * samego rodzaju (2026-09-06) — `.mega-menu__column-empty` (istnieje od
	 * 2026-09-05: "Brak dostępnych miast."/"Brak nowości i zapowiedzi.", a od
	 * teraz też hint/loading/błąd wyszukiwarki, patrz js/megamenu-search.js)
	 * miało `color:var(--gray)` w swojej bazowej regule (niżej w tym pliku)
	 * OD SAMEGO POCZĄTKU bez odpowiadającego wyjątku od blanket rule wyżej —
	 * czyli renderowało się na czarno przez całą dotychczasową historię tego
	 * komponentu, nigdy faktycznie szare. Niezauważone dotąd prawdopodobnie
	 * dlatego, że czarny na jasnym tle wciąż jest czytelny, tylko subtelnie
	 * inny niż zamierzono — ten sam rodzaj cichej, niegroźnej wizualnie
	 * regresji co przy przyciskach `.mega-menu__top-row` opisanych wyżej.
	 * Naprawione tym samym mechanizmem, teraz przy okazji intensywniejszego
	 * użycia tej klasy w wyszukiwarce.
	 */
	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) .mega-menu__column-empty {
		color: var(--gray) !important;
	}

	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) #logo img {
		filter: none !important;
	}

	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) #menu-icon span {
		background-color: var(--black) !important;
	}

	/*
	 * Ikony w headerze (lupa + miniaturka aplikacji, nowymobilet.css,
	 * `#header-icon-actions`) chowane, gdy panel "Miasta" jest otwarty
	 * (2026-09-08) — panel ma już własną wyszukiwarkę i własny przycisk
	 * "Pobierz aplikację" (`.mega-menu__download-btn`), więc oba elementy w
	 * headerze byłyby w tym momencie zbędnym duplikatem. `#header-icon-actions`
	 * nie jest potomkiem `.js-mega-menu-miasta` (jest kuzynem w drzewie —
	 * `#main-menu` i `.nav-menu-right` to rodzeństwo pod `#main-menu-container`,
	 * patrz header.php) — stąd `:has()` na wspólnym przodku `#header`, TEN SAM
	 * mechanizm co reszta stanu "panel otwarty" w tym pliku, nie combinator
	 * rodzeństwa (`~`/`+`), który by tu nie sięgnął. Specyficzność
	 * (2 ID + 2 "klasy" z `:has()`) bije bazowe `#header-icon-actions{display:
	 * flex}` (1 ID) bez potrzeby `!important`.
	 */
	#header:has(.js-mega-menu-miasta:is(:hover, .mm-force-open)) #header-icon-actions {
		display: none;
	}

	/*
	 * Przyciemnienie + blur warstwy pod mega-menu, gdy panel jest otwarty.
	 * Ten sam mechanizm co #header:has() wyżej — CSS-only, bez JS/stanu na
	 * body. Overlay to ::after na <body> (jedyny wspólny przodek #header
	 * i <main> na tej stronie), a nie na <main> wprost — dzięki temu jedna
	 * reguła działa niezależnie od tego, jaki tag/id ma wrapper treści na
	 * danym szablonie (patrz różne warianty #header + X w CLAUDE.md).
	 *
	 * Overlay istnieje w drzewie ZAWSZE (nie tylko pod :has()) — inaczej
	 * przy odpowiedniej selekcji :has() element pojawiałby/znikałby skokowo,
	 * bez możliwości przejścia. Zamiast tego bazowy stan ma opacity:0 +
	 * visibility:hidden, a stan :has(...) go odsłania — ten sam wzorzec
	 * opacity+visibility+transition-delay co panel FAQ akordeonu w
	 * mobilet.eu (CLAUDE.md, "Początek odpowiedzi widoczny przy zwiniętym
	 * akordeonie"): visibility znika/pojawia się DOPIERO po zakończeniu
	 * animacji opacity, więc pod overlayem nie da się kliknąć w trakcie
	 * fade-outu, a pojawia się natychmiast razem z fade-inem.
	 *
	 * z-index:50 — poniżej #header (z-index:100, nowymobilet.css:2991).
	 * .mega-menu--test jest potomkiem #header w DOM, więc mimo position:
	 * fixed stackuje się w obrębie stacking contextu #header (position+
	 * z-index na #header go tworzy) — efektywnie zawsze NAD overlayem, bez
	 * potrzeby podbijania z-index samego panelu.
	 *
	 * top:0 (NIE var(--header-height)) — overlay zaczyna się od samej góry
	 * viewportu, zamiast próbować trafić dokładnie w dół headera. Nie jest
	 * to potrzebne: #header ma z-index:100 (nad overlayem, z-index:50) i jest
	 * w pełni kryjący — a dokładnie w momencie, gdy overlay staje się widoczny
	 * (:has(.js-mega-menu-miasta:hover)), reguła wyżej wymusza na headerze
	 * background-color:white (już nie może być przezroczysty, patrz
	 * #header:has() niżej) — więc górna część overlaya jest ZAWSZE fizycznie
	 * zasłonięta przez nieprzezroczysty header, niezależnie od tego, czy
	 * overlay i header pokrywają się co do piksela. Wyrównanie przez
	 * kolejność malowania (stacking), nie przez zgodność współrzędnych.
	 *
	 * pointer-events:none — overlay jest czysto dekoracyjny/samoznikający:
	 * zjechanie kursorem z triggera/bridge/panelu na obszar pod overlayem
	 * i tak usuwa :hover z .js-mega-menu-miasta, co zamyka panel I overlay
	 * jednym mechanizmem — nie trzeba przechwytywać kliknięć, żeby "kliknij
	 * poza, by zamknąć" zadziałało.
	 *
	 * Czas .28s ease-in-out — DOKŁADNIE ta sama wartość co animacja wysokości
	 * panelu (patrz nadpisanie transition na .sub-menu.mega-menu--test wyżej),
	 * żeby przyciemnienie tła i wyrastanie panelu czytały się jako jeden ruch,
	 * a nie dwie doganiające się animacje. #header od migracji na produkcję
	 * (2026-09-07) NIE jest już do tego tempa dostrajany — zostaje przy
	 * produkcyjnym .1s, patrz komentarz przy regule #header na górze pliku.
	 */
	body::after {
		content: '';
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, .5);
		backdrop-filter: blur(3px);
		-webkit-backdrop-filter: blur(3px);
		z-index: 50;
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		/* .07s → .28s (2026-09-04), patrz komentarz przy #header na górze pliku */
		transition: opacity .28s ease-in-out, visibility 0s linear .28s;
	}

	body:has(.js-mega-menu-miasta:is(:hover, .mm-force-open))::after {
		opacity: 1;
		visibility: visible;
		transition: opacity .28s ease-in-out, visibility 0s linear 0s;
	}
}

/*
 * WRAPPER (2026-09-03) — struktura panelu od tej zmiany: `<ul class="sub-menu
 * mega-menu mega-menu--test">` (pełnoszerokościowe tło/pozycjonowanie, patrz
 * komentarz przy `.js-mega-menu-miasta>.sub-menu.mega-menu--test` wyżej) >
 * JEDEN `<li class="mega-menu__inner-item">` (wymagany przez HTML — `<ul>`
 * może mieć bezpośrednio tylko `<li>` jako dzieci, więc to jedyny sposób,
 * żeby "wepchnąć" pod spód zwykły `<div>`) > `<div class="wrapper
 * mega-menu__grid">` (DWIE klasy na jednym elemencie: `.wrapper` to
 * dosłownie ta sama sitewide klasa co reszta treści strony —
 * centrowanie/boczny padding identyczne jak wszędzie indziej — z jednym
 * świadomym wyjątkiem od 2026-09-05: max-width, patrz override
 * `.mega-menu--test .wrapper.mega-menu__grid` niżej, tuż pod
 * `.mega-menu__grid` — `.mega-menu__grid` niżej dokłada `display:grid` dla
 * layoutu wewnętrznego. Poza `list-style:none` (zbędne dzięki globalnemu resetowi,
 * zostawione jawnie) `.mega-menu__inner-item` nie miało własnego stylu do
 * 2026-09-04 — od tej daty dostaje `overflow:hidden` na desktopie, patrz
 * niżej.
 *
 * Konsekwencja: `.mega-menu__top` (niżej) i przyszła siatka miast żyją teraz
 * jako `<div>`-y WEWNĄTRZ `.wrapper.mega-menu__grid`, nie jako bezpośrednie
 * `<li>` dzieci `.sub-menu` — stąd też usunięcie martwego już override'a
 * ucinania listy na górze pliku, patrz tamten komentarz.
 */
.mega-menu__inner-item {
	list-style: none;
}

.mega-menu__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: .35rem 1.5rem;
}

/*
 * ZMIANA 2026-09-05 — max-width całej treści panelu (searchbar+przyciski,
 * przyszła siatka miast) ograniczony do stałych 1200px, na życzenie —
 * odstępstwo od sitewide `.wrapper` (750/980/1170/1370/1560px na kolejnych
 * breakpointach, nowymobilet.css, patrz komentarz przy "WRAPPER" wyżej),
 * które przy szerokich ekranach (≥1400px) rozciągało panel mega-menu do
 * 1370/1560px — szerzej, niż tu pożądane. Selektor `.mega-menu--test
 * .wrapper.mega-menu__grid` (specyficzność 0,3,0) bije każdą z sitewide
 * reguł `.wrapper{max-width:...}` (0,1,0 każda) niezależnie od breakpointu i
 * kolejności ładowania arkuszy — bez `!important`, bez media query. Poniżej
 * ≥1400px sitewide wartości (750/980/1170px) i tak są już mniejsze niż
 * 1200px, więc ten override efektywnie nic tam nie zmienia (max-width nigdy
 * nie jest osiągane) — praktyczny skutek widoczny dopiero od ≥1400px,
 * gdzie panel przestaje rosnąć razem z resztą strony i zatrzymuje się na
 * 1200px. `.mega-menu__grid` w selektorze (nie sam `.wrapper`) gwarantuje,
 * że reguła dotyczy WYŁĄCZNIE wrappera treści mega-menu, nie żadnego innego
 * użycia sitewide `.wrapper` na stronie.
 */
.mega-menu--test .wrapper.mega-menu__grid {
	max-width: 1200px;

}

/*
 * Mechanika wzrostu wysokości panelu (2026-09-04) — patrz obszerny komentarz
 * przy `.js-mega-menu-miasta>.sub-menu.mega-menu--test` (góra pliku) po pełne
 * uzasadnienie. W skrócie: `<ul class="sub-menu mega-menu--test">` animuje
 * `grid-template-rows` 0fr→1fr, a to jedyne dziecko (`<li class=
 * "mega-menu__inner-item">`) potrzebuje `overflow:hidden`, żeby ta animacja
 * realnie kolapsowała do zera (spec: automatic minimum size grid itemu
 * rozwiązuje się do 0 tylko, gdy jego overflow nie jest `visible` — identyczna
 * mechanika co `.faq-accordion__panel-inner` w mobilet.eu). Pionowy padding
 * (`1px` góra / `1rem` dół, wartości z 2026-09-03) PRZENIESIONY tu z `<ul>`
 * z tego samego powodu — padding bezpośrednio na animowanym kontenerze
 * grida zawsze doliczałby się do jego wysokości, niezależnie od tego, na ile
 * skurczy się rząd. (Tymczasowy `min-height:400px`, potrzebny dopóki siatka
 * miast była pusta, usunięty 2026-09-05 — patrz komentarz przy
 * `.mega-menu--test .mega-menu__grid` niżej.)
 *
 * Scoped do ≥992px celowo — poniżej tego breakpointu mega-menu w ogóle nie
 * jest aktywne (osobny, przyszły mechanizm mobile, patrz komentarz na górze
 * pliku), więc `.mega-menu__inner-item`/`.mega-menu__grid` nie powinny
 * dostawać tych właściwości poza tym kontekstem.
 */
@media (min-width: 992px) {
	.mega-menu__inner-item {
		overflow: hidden;
		/*
		 * display:flex + min-height:0 (2026-09-06, refaktor "scrollowalność
		 * mega-menu", PRZYWRÓCONE po przypadkowym cofnięciu) — ten <li>
		 * (jedyny grid-item animowanego <ul> wyżej) staje się kontenerem
		 * flex-column dla `.wrapper.mega-menu__grid` (jego jedynego dziecka),
		 * żeby ten mógł dostać `flex:1 1 auto` i poprawnie odziedziczyć
		 * ograniczoną wysokość <ul>-a. `min-height:0` pozwala temu <li>
		 * realnie SKURCZYĆ się do wysokości <ul>-a zamiast domyślnego minimum
		 * liczonego z zawartości — bez tego flex nie przekazałby dalej
		 * informacji "masz ograniczoną wysokość, rozdziel ją między dzieci".
		 * Patrz też `.mega-menu--test .mega-menu__grid`/`.mega-menu__top`/
		 * `.mega-menu__columns` niżej — te cztery reguły razem tworzą łańcuch
		 * "top ma naturalną wysokość, columns wypełnia resztę i scrolluje".
		 */
		display: flex;
		flex-direction: column;
		min-height: 0;
	}

	.mega-menu--test .mega-menu__grid {
		/*
		 * Dolny padding PRZENIESIONY na `.mega-menu--test .mega-menu__columns`
		 * (2026-09-06, patrz jej reguła niżej) — przy nowym, wewnętrznym
		 * scrollu `.mega-menu__columns` dolny padding musi scrollować SIĘ Z
		 * TREŚCIĄ (żeby ostatni wiersz miał oddech od dołu też w stanie
		 * przescrollowanym do końca), a nie zostać "na zewnątrz" scrollowalnego
		 * obszaru, gdzie byłby niewidoczny podczas scrolla. Góra/boki
		 * padding bez zmian.
		 */
		padding: 4px 2rem 0;
		/*
		 * `min-height:400px` (placeholder od 2026-09-04) USUNIĘTY 2026-09-05
		 * — na życzenie: "usuń minimalną wysokość mega-menu, i tak będzie
		 * zawsze treść". Był potrzebny wyłącznie dopóki `.mega-menu__columns`
		 * była pusta (świeżo dodany placeholder-nagłówek bez zapytania) —
		 * otwarty panel urósłby wtedy tylko do wysokości jednego wiersza
		 * (`.mega-menu__top`), "chudy pasek" zamiast pełnowymiarowego
		 * mega-menu. Od tej samej sesji wszystkie 3 kolumny mają realną
		 * treść (2 listy miast + karty "Nowości i zapowiedzi", każda z
		 * fallbackiem tekstowym gdy zapytanie nic nie zwróci — nigdy pusty
		 * div o zerowej wysokości), więc wysokość panelu wynika już zawsze z
		 * rzeczywistej zawartości grida, bez potrzeby sztucznego dolnego
		 * progu.
		 */
		/*
		 * ZMIANA 2026-09-07 — `display:flex;flex-direction:column`
		 * (2026-09-06, patrz SUPERSEDED opis niżej) ZASTĄPIONE CSS Gridem,
		 * na życzenie: "szerokość kart wyników wyszukiwania na szerokość
		 * searchbaru". Powód zmiany trybu, nie tylko wartości: dopasowanie
		 * kart wyników do dynamicznej szerokości search bara (zależnej od
		 * długości etykiet przycisków po bokach, patrz `.mega-menu__top-row`
		 * niżej w pliku) wymaga, żeby `.mega-menu__search-results` dzielił
		 * TE SAME kolumnowe tory co `.mega-menu__top-row` — możliwe wyłącznie
		 * przez CSS Grid `subgrid` (kolumny muszą pochodzić ze WSPÓLNEGO
		 * przodka-grida obu elementów; flex nie ma odpowiednika). Stąd ten
		 * kontener MUSI być teraz gridem: 3 kolumny (`auto minmax(0,1fr)
		 * auto`, DOKŁADNIE te same tory co `.mega-menu__top-row`) × 2 wiersze
		 * (`auto` — `.mega-menu__top`, `minmax(0,1fr)` — `.mega-menu__columns`/
		 * `.mega-menu__search-results`, wymiennie). `column-gap:0` jawnie
		 * (baza `.mega-menu__grid` ma `gap:.35rem 1.5rem` — 1.5rem odstępu
		 * MIĘDZY kolumnami zepsułby dopasowanie: `.mega-menu__top-row` samo
		 * NIE używa już `gap` na tym poziomie, odstęp między przyciskami a
		 * search barem idzie przez `margin-right` na przyciskach, patrz
		 * komentarz przy `.mega-menu__top-row` niżej — dodatkowy `column-gap`
		 * tutaj dublowałby ten odstęp i psuł wyrównanie 1:1 z kolumnami
		 * subgrida). `row-gap` ZOSTAJE odziedziczone z bazy (`.35rem`) —
		 * dokładnie ten sam odstęp, jaki dawał wcześniej `flex-direction:
		 * column` (gap działa identycznie dla obu trybów wzdłuż osi
		 * głównej/wierszy).
		 *
		 * Wcześniejsza obawa (SUPERSEDED, patrz poprzedni komentarz w historii
		 * tego pliku) — "grid wymagałby DEFINITYWNEJ wysokości kontenera,
		 * flex sobie z tym radzi" — dotyczyła innego poziomu łańcucha:
		 * `.mega-menu__inner-item` (rodzic TEGO elementu) ma `min-height:0` i
		 * NIEDEFINITYWNĄ własną wysokość (pochodzi z animowanego
		 * `grid-template-rows:0fr→1fr` na `<ul>` wyżej) — TEN poziom
		 * ŚWIADOMIE POZOSTAJE flex (nietknięty w tej zmianie), właśnie żeby
		 * uniknąć tego problemu. `.mega-menu__grid` SAMO w sobie (jako
		 * flex-item tamtego kontenera, `flex:1 1 auto; min-height:0` niżej —
		 * bez zmian) dostaje przez to DEFINITYWNĄ, rozwiązaną wysokość z
		 * layoutu flexboksa nadrzędnego — a definitywna wysokość kontenera
		 * grida jest dokładnie tym, czego `minmax(0,1fr)` w wierszach
		 * potrzebuje, żeby poprawnie działać. Innymi słowy: obawa dotyczyła
		 * `.mega-menu__inner-item`, nie `.mega-menu__grid` — ten drugi
		 * poziom nigdy nie musiał być flexem z tego konkretnego powodu, po
		 * prostu był, dopóki nie było potrzeby subgrida.
		 */
		display: grid;
		grid-template-columns: auto minmax(0, 1fr) auto;
		grid-template-rows: auto minmax(0, 1fr);
		column-gap: 0;
		flex: 1 1 auto;
		min-height: 0;
	}

	/*
	 * Podział flex "top ma naturalną wysokość / columns wypełnia resztę i
	 * scrolluje" (2026-09-06, refaktor "scrollowalność mega-menu" —
	 * PRZYWRÓCONE po przypadkowym cofnięciu, patrz CLAUDE.md). Do tej pory
	 * CAŁY panel (`<ul class="sub-menu mega-menu--test">`) scrollował się
	 * jako jeden blok (`overflow-y:auto` na samym `<ul>`, patrz jej reguła na
	 * górze pliku — ZMIENIONA dziś na `hidden`) — `.mega-menu__top` (link
	 * "Wszystkie miasta"/search/"Pobierz aplikację") znikał ze scrollem razem
	 * z kolumnami miast. `flex:0 0 auto` tutaj = ten wiersz nigdy nie
	 * rośnie/kurczy się, zawsze zajmuje dokładnie tyle, ile potrzebuje jego
	 * treść — efektywnie "przyklejony" do góry panelu bez potrzeby
	 * `position:sticky` (jest strukturalnie POZA scrollowalnym obszarem, nie
	 * tylko wizualnie znieruchomiony w nim).
	 *
	 * Reguła bazowa `.mega-menu--test .mega-menu__top{grid-column:1/-1}`
	 * (niżej w pliku, NIETKNIĘTA) — od 2026-09-07 (patrz `.mega-menu__grid`
	 * wyżej, gdzie ten kontener wrócił z flexa na grid) ZNOWU ma realne
	 * znaczenie na ≥992px: rozpina ten element na wszystkie 3 kolumny
	 * `.mega-menu__grid` (1 do -1), nie tylko 1 z nich.
	 *
	 * ZMIANA 2026-09-07 — `flex:0 0 auto` (element nigdy nie rósł/kurczył
	 * się w kolumnie flexa) ZASTĄPIONE `grid-row:1` (ten sam efekt "zawsze
	 * naturalna wysokość, nigdy nie rośnie" — teraz przez wiersz `auto` w
	 * `grid-template-rows` rodzica, patrz `.mega-menu__grid` wyżej) +
	 * `display:grid; grid-template-columns:subgrid` — PIERWSZY z dwóch
	 * poziomów subgrida, potrzebnych, żeby kolumny `.mega-menu__top-row`
	 * (niżej w pliku, drugi poziom) mogły dziedziczyć DOKŁADNIE te same tory
	 * co `.mega-menu__grid`, mimo że dzieli je jeszcze ten wrapper. Subgrid
	 * "przechodzi" przez kolejne poziomy tylko, gdy KAŻDY pośredni poziom
	 * sam też deklaruje `grid-template-columns:subgrid` (spec) — stąd oba
	 * poziomy (ten i `.mega-menu__top-row`) muszą to zrobić, nie wystarczy
	 * jeden.
	 */
	.mega-menu--test .mega-menu__top {
		grid-row: 1;
		display: grid;
		grid-template-columns: subgrid;
		grid-column: 1 / -1;
	}

	/*
	 * DRUGI poziom subgrida (2026-09-07) — `.mega-menu__top-row` (dziecko
	 * `.mega-menu__top` wyżej) dostaje `grid-template-columns:subgrid`
	 * zamiast własnej, niezależnej definicji `auto minmax(0,1fr) auto`
	 * (patrz baza reguły `.mega-menu__top-row`, niżej w pliku — ta wartość
	 * ZOSTAJE tam jako fallback dla <992px, gdzie ten override w ogóle nie
	 * wchodzi w grę; mobile ma zresztą własny, niezależny override w
	 * megamenu-mobile.css). Efekt: 3 kolumny przycisk/search/przycisk NIE są
	 * już policzone niezależnie w obrębie samego `.mega-menu__top-row`, tylko
	 * odziedziczone 1:1 z `.mega-menu__grid` — te same tory, którymi steruje
	 * też `.mega-menu__search-results` (patrz jej reguła niżej, `grid-column:
	 * 2`), więc szerokość `auto` kolumny 1/3 (liczona z realnej, animowanej
	 * szerokości przycisków w TYM wierszu) automatycznie determinuje też
	 * lewą/prawą krawędź kart wyników w wierszu 2 — bez JS, bez pomiaru.
	 */
	.mega-menu--test .mega-menu__top-row {
		display: grid;
		grid-template-columns: subgrid;
		grid-column: 1 / -1;
	}

	/*
	 * `.mega-menu__columns` — druga połowa tego samego podziału. `flex:1 1
	 * auto` + `min-height:0` każe jej wypełnić WYŁĄCZNIE to, co zostało po
	 * `.mega-menu__top` w ramach ograniczonej wysokości odziedziczonej z
	 * `<ul>` (patrz `max-height:calc(100vh - var(--header-height))` na górze
	 * pliku) — `min-height:0` jest tu konieczne: bez niego flex-item
	 * domyślnie nie kurczy się poniżej wysokości swojej zawartości, więc przy
	 * długiej liście miast po prostu rozepchnąłby całą wysokość panelu
	 * zamiast się ograniczyć i scrollować wewnętrznie. `overflow-y:auto` czyni
	 * z niej JEDYNY scrollowalny obszar panelu (dawniej robił to `<ul>` na
	 * poziomie całego panelu). `overscroll-behavior:contain` — bez tego
	 * scroll gestem po dojechaniu do samego dołu listy "przecieka" i zaczyna
	 * przewijać stronę POD panelem (position:fixed), co wygląda jak błąd.
	 * `padding-bottom:2rem` PRZENIESIONY tu z `.mega-menu--test
	 * .mega-menu__grid` (patrz jej reguła wyżej) — scrolluje razem z
	 * treścią, więc ostatni wiersz miast ma oddech od dołu również przy
	 * scrollu domkniętym do końca.
	 *
	 * Reguła bazowa `.mega-menu--test .mega-menu__columns{grid-column:1/-1;
	 * display:grid;grid-template-columns:repeat(3,1fr);gap:2rem}` (niżej w
	 * pliku, NIETKNIĘTA) zostaje w całości — WŁASNY, zagnieżdżony 3-kolumnowy
	 * grid miast/nowości jest w pełni niezależny od tego, czy TEN element
	 * jest z zewnątrz (z perspektywy SWOJEGO rodzica) flex-itemem czy
	 * grid-itemem; `display` elementu rządzi wyłącznie layoutem JEGO WŁASNYCH
	 * dzieci, nie tym, jak on sam zachowuje się jako dziecko swojego rodzica.
	 */
	/*
	 * PUŁAPKA znaleziona na żywym podglądzie (2026-09-06, na życzenie: "kontener
	 * obcina cień w kartach") — `overflow-y:auto` w tej regule (i w
	 * `.mega-menu__search-results` niżej) ma efekt uboczny nieoczywisty na
	 * pierwszy rzut oka: spec CSS Overflow każe przeglądarce potraktować
	 * `overflow-x` jako `auto`, GDY TYLKO `overflow-y` jest czymkolwiek innym
	 * niż `visible` (nawet jeśli `overflow-x` nigdy nie został jawnie
	 * ustawiony) — więc ten element w praktyce ucina ROWNIEŻ w poziomie, nie
	 * tylko w pionie, mimo że nikt nigdy nie napisał `overflow-x`. Karty w
	 * środku (`.mega-menu__news-card`/`.mega-menu__result`) nie mają własnego
	 * marginesu/paddingu odsuwającego je od lewej/prawej krawędzi TEGO
	 * elementu (dopiero rodzic `.mega-menu__grid` ma padding boczny 2rem,
	 * ale to inny, wyższy poziom — nie ratuje TEJ konkretnej granicy
	 * przycinania) — ich `box-shadow` (wystający poza własną krawędź o
	 * spread+blur, ~7px przy stanie hover) dotyka więc tej granicy i zostaje
	 * ucięty z lewej/prawej.
	 *
	 * NAPRAWA: klasyczny wzorzec "ujemny margines + taki sam padding na TYM
	 * SAMYM elemencie" — `margin:0 -10px` rozciąga box tego elementu o 10px w
	 * każdą stronę (bezpiecznie, bo `.mega-menu__grid` ma 2rem/32px własnego
	 * paddingu wokół, więc 10px bleedu mieści się z zapasem i nie wychodzi
	 * poza zaokrąglone rogi panelu), a `padding:0 10px` odpycha treść W ŚRODKU
	 * z powrotem o te same 10px — treść (karty) ląduje wizualnie DOKŁADNIE w
	 * tym samym miejscu co przedtem (zero zmiany wyrównania względem
	 * `.mega-menu__top` nad nią), ale granica przycinania (`overflow-x:auto`)
	 * przesuwa się o 10px NA ZEWNĄTRZ od krawędzi kart — dający cieniowi
	 * (~7px) zapas z naddatkiem, żeby nigdy nie dotknąć granicy.
	 */
	.mega-menu--test .mega-menu__columns {
		/*
		 * ZMIANA 2026-09-07 — `flex:1 1 auto` ZASTĄPIONE `grid-row:2`
		 * (`.mega-menu__grid` jest teraz gridem, nie flexem, patrz jej
		 * reguła wyżej) — wiersz 2 to `minmax(0,1fr)`, czyli ten sam efekt
		 * "wypełnij resztę wysokości" co dawało `flex:1 1 auto`.
		 * `grid-column:1/-1` (baza, niżej w pliku, NIETKNIĘTA) zostaje —
		 * kolumny miast mają pełną szerokość, w odróżnieniu od
		 * `.mega-menu__search-results` obok (patrz jej reguła niżej, węższa
		 * na życzenie).
		 */
		grid-row: 2;
		min-height: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		margin: 0 -10px;
		padding: 0 10px 2rem;
	}

	/*
	 * `.mega-menu__search-results` (2026-09-06, search bar UX) — dokładnie
	 * ten sam slot flex co `.mega-menu__columns` tuż wyżej (identyczne
	 * flex/min-height/overflow-y/overscroll-behavior/padding-bottom/margin), bo
	 * js/megamenu-search.js pokazuje/ukrywa je ZAMIENNIE (nigdy oba naraz w
	 * normalnym przepływie, patrz `hidden` w markupie i sekwencja w JS) —
	 * panel ma więc tę samą wysokość niezależnie od tego, który z tych
	 * dwóch bloków jest akurat widoczny. `margin:-10px`/`padding:10px` — ta
	 * sama naprawa obcinania cienia co wyżej (`.mega-menu__columns`), z tego
	 * samego powodu (`overflow-y:auto` ucina też w poziomie) — dotyczyła kart
	 * wyników wyszukiwania (`.mega-menu__result`) tak samo jak kart "Nowości".
	 */
	.mega-menu--test .mega-menu__search-results {
		/*
		 * ZMIANA 2026-09-07 (na życzenie: "szerokość kart wyników wyszukiwania
		 * na szerokość searchbaru") — do tej sesji ten element NIE MIAŁ
		 * jawnego `grid-column` w ogóle: pełną szerokość dostawał "za darmo"
		 * z domyślnego stretch cross-axis flexboksa (`.mega-menu__grid` było
		 * `display:flex;flex-direction:column`, patrz SUPERSEDED opis przy
		 * jej regule wyżej) — element po prostu rozciągał się na całą
		 * szerokość kolumny flexa, tak jak `.mega-menu__columns` obok. Teraz,
		 * gdy `.mega-menu__grid` jest gridem (wyżej), element BEZ jawnego
		 * `grid-column` zająłby domyślnie TYLKO jedną komórkę (auto-placement
		 * na pierwszej wolnej), więc jawny `grid-column:2` tutaj nie tyle
		 * "zawęża" wcześniejszą pełną szerokość, ile świadomie kieruje go do
		 * środkowej kolumny — TA SAMA środkowa
		 * kolumna (`minmax(0,1fr)`), którą subgriduje `.mega-menu__top-row`
		 * dla search bara (patrz jej reguła i `.mega-menu__grid` wyżej).
		 * Efekt: lewa/prawa krawędź tego kontenera (i kart wyników w środku)
		 * pokrywa się z lewą/prawą krawędzią KOLUMNY 2 — na żywo, bez JS,
		 * także w trakcie animacji kolapsu przycisku "Zobacz wszystkie
		 * miasta" w trybie `.is-searching` (kolumna 1 kurczy się do 0 razem
		 * z przyciskiem, kolumna 2 rośnie o dokładnie tyle samo w tej samej
		 * klatce — to ta sama mechanika grida, która już dziś rozszerza sam
		 * search bar, patrz komentarz przy `.is-searching
		 * .mega-menu__all-link.button` niżej w pliku).
		 * `flex:1 1 auto` → `grid-row:2` — analogicznie do
		 * `.mega-menu__columns` wyżej.
		 *
		 * POPRAWKA 2026-09-07, zgłoszona na żywym podglądzie ("wyszło za
		 * szeroko") — kolumna 2 to NIE dokładnie szerokość pola wyszukiwania:
		 * `.mega-menu__search` (wrapper inputu) ma WŁASNY, stały
		 * `margin-right:1.5rem` (patrz jego reguła niżej w pliku — odstęp do
		 * przycisku "Pobierz aplikację", niezależny od stanu wyszukiwania) —
		 * input kończy się więc 1.5rem PRZED prawą krawędzią kolumny 2, a
		 * ten kontener bez korekty sięgał całej kolumny, więc wizualnie
		 * "wystawał" o te 1.5rem po prawej stronie inputu (dokładnie
		 * zgłoszony efekt: karty sięgały niemal do przycisku pobierania).
		 * Prawy margines poniżej ODTWARZA ten sam 1.5rem odstęp, ale
		 * pomniejszony o istniejący bleed `10px` (na cień, patrz `padding`
		 * niżej) — `calc(1.5rem - 10px)` zamiast gołego `-10px` jak po lewej
		 * (gdzie inputu NIC nie odsuwa od lewej krawędzi kolumny 2, więc tam
		 * bleed zostaje symetryczny, bez korekty).
		 */
		grid-row: 2;
		grid-column: 2;
		min-height: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		margin: 0 calc(1.5rem - 10px) 0 -10px;
		padding: 5px 10px 2rem;
	}

	/*
	 * Crossfade sekwencyjny (2026-09-06, patrz js/megamenu-search.js po pełny
	 * opis sekwencji) — `.is-hiding` na `.mega-menu__columns` i `.is-visible`
	 * na `.mega-menu__search-results` to jedyne dwie klasy w tej parze;
	 * spoczynkowy stan każdego elementu (widoczny=opacity:1, niewidoczny
	 * przez `hidden`=nie renderuje się wcale) nie wymaga osobnej reguły.
	 * `.2s` MUSI być zgodne z `FADE_MS` w JS (skomentowane tam) — JS czeka
	 * dokładnie tyle przed przełączeniem atrybutu `hidden`.
	 */
	.mega-menu--test .mega-menu__columns {
		opacity: 1;
		transition: opacity .2s ease-in-out;
	}

	.mega-menu--test .mega-menu__columns.is-hiding {
		opacity: 0;
	}

	.mega-menu--test .mega-menu__search-results {
		opacity: 0;
		/*
		 * `height .25s` (2026-09-07) DOPISANE do istniejącego `opacity .2s`
		 * — patrz obszerny komentarz przy `setResultsContent()` w
		 * js/megamenu-search.js po pełne uzasadnienie: JS ustawia jawny,
		 * startowy i docelowy `height` w px przy KAŻDEJ podmianie treści
		 * (hint→skeleton→realne wyniki/błąd), CSS tu odpowiada wyłącznie za
		 * SAMĄ animację przejścia między tymi wartościami. Czas (.25s) musi
		 * być zgodny z `RESIZE_MS` w JS — analogicznie do `.2s`/`FADE_MS`
		 * obok. Niezależny od `opacity` (inny czas, inny trigger — opacity
		 * steruje pokazaniem/ukryciem CAŁEGO bloku przy wejściu/wyjściu z
		 * trybu wyszukiwania, height steruje rozmiarem treści WEWNĄTRZ,
		 * podczas gdy blok jest już widoczny).
		 */
		transition: opacity .2s ease-in-out, height .25s ease-in-out;
	}

	.mega-menu--test .mega-menu__search-results.is-visible {
		opacity: 1;
	}
}

/*
 * Pierwsza sekcja panelu — wiersz 3 elementów (link "Wszystkie miasta" / search
 * bar / przycisk "Pobierz Aplikację Mobilet"), potem 2rem odstępu i pozioma
 * linia. grid-column:1/-1 bo ten element jest teraz bezpośrednim dzieckiem
 * `.wrapper.mega-menu__grid` (`display:grid; grid-template-columns:
 * repeat(4,1fr)`, reguła wyżej) — bez tego zająłby tylko 1 z 4 kolumn
 * zamiast całej szerokości.
 *
 * Linia = border-bottom na tym samym elemencie co padding-bottom:2rem —
 * odstęp i linia w jednym: padding tworzy 2rem "poniżej wiersza", a border
 * rysuje się dokładnie na krawędzi tego paddingu, czyli 2rem pod treścią.
 * Wartość 1px solid var(--lightgray) — HISTORYCZNIE dobrana jako identyczna
 * z border-bottom #header w stanie spoczynku. **Aktualizacja 2026-09-05,
 * drugi raz:** ani stan spoczynku #header (nowymobilet.css:2981-2994), ani
 * stan otwartego mega-menu (`#header:has(.js-mega-menu-miasta:hover)`
 * wyżej) nie mają już border-bottom w ogóle — OBA zastąpione tym samym
 * box-shadow (patrz komentarze przy tamtych regułach). Ta linia panelu jest
 * więc dziś JEDYNYM pozostałym `border-bottom` w tym łańcuchu — celowo
 * NIETKNIĘTA (poza zakresem tamtej zmiany, użytkownik prosił wyłącznie o
 * header), nadal pełni rolę widocznego separatora treści WEWNĄTRZ panelu
 * (nie krawędzi headera), więc pozostanie linią, nie cieniem, dopóki ktoś
 * wyraźnie nie poprosi inaczej. Wartość `var(--lightgray)` nie odnosi się
 * już do niczego na headerze — czysto kosmetyczny wybór koloru, nie
 * współdzielony punkt prawdy.
 */
.mega-menu--test .mega-menu__top {
	grid-column: 1 / -1;

}

/*
 * Druga sekcja panelu — 3 równe kolumny (na życzenie, 2026-09-05), pierwsza
 * "prawdziwa" zawartość mega-menu poza wierszem `.mega-menu__top`. Jak ten,
 * `grid-column:1/-1` — jest bezpośrednim dzieckiem `.wrapper.mega-menu__grid`
 * (outer grid `repeat(4,1fr)`, reguła `.mega-menu__grid` wyżej w tym pliku),
 * bez tego zająłby tylko 1 z 4 kolumn zamiast całej szerokości. Wewnątrz
 * WŁASNY, zagnieżdżony `display:grid; grid-template-columns:repeat(3,1fr)` —
 * trzy kolumny tej sekcji są niezależne od czterech kolumn outer grida.
 *
 * Świadomie NIE scoped do `@media (min-width:992px)` — ten sam wzorzec co
 * już istniejące `.mega-menu__grid`/`.mega-menu__top-row` w tym pliku
 * (żadne z nich nie jest media-scoped): mega-menu na mobile to osobny,
 * przyszły, świadomie tu pominięty krok (patrz komentarz na górze pliku), a
 * do tego czasu ta reguła po prostu współistnieje z niedotkniętym mobilnym
 * mechanizmem panelu (#submenu-nav-bar), tak jak reszta layoutu grida.
 */
.mega-menu--test .mega-menu__columns {
	grid-column: 1 / -1;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 2rem;
}

/*
 * PUŁAPKA znaleziona na żywym podglądzie (2026-09-06) — zgłoszony objaw:
 * "kolumny najpierw na chwilę gasną, a potem znów się pojawiają" po
 * wpisaniu pierwszej litery w search. Diagnoza (headless Edge + log
 * sekwencji zdarzeń w czasie): sama sekwencja JS (`js/megamenu-search.js`)
 * jest w 100% poprawna — `columns.hidden = true` ustawia się dokładnie
 * raz, we właściwym momencie, bez żadnego podwójnego wywołania. Prawdziwa
 * przyczyna leży TU: reguła `display: grid` wyżej jest AUTORSKA i
 * BEZWARUNKOWA (brak `:not([hidden])`/`[hidden]`), a reguła autorska
 * ZAWSZE bije regułę przeglądarki `[hidden]{display:none}` niezależnie od
 * specyficzności (różne "originy" kaskady — UA przegrywa z author przy tej
 * samej wadze, nawet gdyby author miał specyficzność 0). Efekt: atrybut
 * `hidden` ustawiał się poprawnie (potwierdzone: `columns.hasAttribute
 * ('hidden')===true`), ale `getComputedStyle(columns).display` i tak
 * zostawał `grid` — element NIGDY realnie nie znikał z layoutu. To, co
 * wyglądało jak "zgaśnięcie" to sam fade `opacity` do 0 (`.is-hiding`
 * niżej), a "ponowne pojawienie się" to zdjęcie tej klasy zaraz potem
 * (`opacity` wraca do `1` z reguły bazowej) — `display:none` nigdy nie
 * zdążył (bo nie mógł) przejąć kontroli w międzyczasie. Ten sam RODZAJ
 * pułapki co `#main-menu a` opisane w komentarzu na górze tego pliku
 * (autorska reguła bijąca coś, co "powinno" wygrywać) — tu akurat chodzi o
 * PRECEDENCJĘ ORIGINU (author > user-agent), nie o specyficzność
 * selektorów w obrębie jednego originu.
 *
 * NAPRAWA: jawny override dla stanu `[hidden]`, o specyficzności (0,3,0)
 * — bije regułę wyżej (0,2,0) bez potrzeby `!important`.
 */
.mega-menu--test .mega-menu__columns[hidden] {
	display: none;
}

/*
 * ZMIANA 2026-09-05 — ikony po lewej stronie nagłówków (transport/parking/gps,
 * na życzenie, patrz mobilet_pl_megamenu_column_icon() w inc/megamenu.php
 * po pełne uzasadnienie inline SVG). `display:flex; align-items:center` +
 * `gap:.75rem` układa ikonę i tekst obok siebie z jednolitym odstępem, bez
 * wpływu na dotychczasowy `padding-bottom`/`border-bottom` (nadal na całym
 * `<h3>`, pod ikoną i tekstem naraz — separator kolumny, nie samego tekstu).
 */
.mega-menu--test .mega-menu__column-heading {
	display: flex;
	align-items: center;
	gap: .75rem;
	margin: 0 0 1rem;
	padding-bottom: .75rem;
	border-bottom: 1px solid var(--lightgray);
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.3;
	color: var(--black);
}

/*
 * Ikona 44px, kolor --blue (2026-09-05, na życzenie) — dla WSZYSTKICH trzech
 * ikon jednolicie, niezależnie od oryginalnego fill w plikach źródłowych
 * (patrz komentarz przy mobilet_pl_megamenu_column_icon()). `flex-shrink:0`
 * na wrapperze `<span>` — bez tego długi tekst nagłówka (np. "Bilety
 * komunikacji miejskiej" na wąskiej kolumnie) mógłby ścisnąć ikonę poniżej
 * 44px w flex-rowie z `.mega-menu__column-heading` wyżej. `fill` na `svg`
 * (nie na `path`) — `path` w markupie nie ma własnego atrybutu `fill`, więc
 * dziedziczy tę wartość; ten sam wzorzec co `.module-hero__badge-icon` w
 * mobilet.eu, tylko bez dodatkowej klasy na `path`, bo w tym komponencie jest
 * zawsze dokładnie jeden `path` na ikonę.
 */
.mega-menu--test .mega-menu__column-icon {
	display: inline-flex;
	flex-shrink: 0;
}

.mega-menu--test .mega-menu__column-icon svg {
	display: block;
	width: 2rem;
	height: 2rem;
	fill: var(--blue);
}

.mega-menu--test .mega-menu__column-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.mega-menu--test .mega-menu__column-list li {
	margin: 0;
}

/*
 * `.sub-menu a` (nowymobilet.css:4109-4119, descendant selector — trafia w
 * KAŻDY <a> zagnieżdżony wewnątrz `.sub-menu`, na dowolnej głębokości, więc
 * też w te linki) już dostarcza rozsądną bazę (display:block, font-size,
 * color, brak podkreślenia) — tu tylko dostrajany padding/margines pod
 * gęstą, pionową listę miast zamiast dawnego przeznaczenia tej reguły
 * (pojedynczy poziom klasycznego dropdownu z miejscem na chevron po prawej,
 * stąd jej nietrafiony tu `padding-right:2rem`). Specyficzność tej reguły
 * (0,2,1: `.mega-menu--test` + `.mega-menu__column-list` + `a`) > `.sub-menu a`
 * (0,1,1) niezależnie od kolejności ładowania arkuszy — bez `!important`,
 * ten sam wzorzec scopowania co `.mega-menu--test .mega-menu__top` wyżej.
 * Kolor hover (`--red`) świadomie NIETKNIĘTY — `.sub-menu a:hover` już ma
 * `!important`, więc i tak by wygrał; nie ma potrzeby go tu powtarzać.
 */
.mega-menu--test .mega-menu__column-list a {
	padding: .35rem 0;
	margin-bottom: 0;
}

.mega-menu--test .mega-menu__column-empty {
	margin: 0;
	font-size: .85rem;
	color: var(--gray);
}

/*
 * KOLUMNA 3 — "Nowości i zapowiedzi" (2026-09-05, na życzenie): karty miast
 * zamiast prostej listy linków (kolumny 1/2), WZOROWANE na sekcji "Wyróżnione
 * miasta" (`page-miasta.php`, `.city-list.recent` — duże, kwadratowe karty ze
 * zdjęciem w tle) — ale DOSTOSOWANE PROPORCJAMI do tej, dużo węższej kolumny
 * (~1/3 z max-width:1200px minus gapy, patrz `.mega-menu__columns` wyżej):
 * zamiast pionowej karty ze zdjęciem na całą szerokość, tu POZIOMY wiersz o
 * STAŁEJ wysokości 100px (na życzenie, trzecia iteracja tego samego dnia —
 * pierwsza wersja miała wysokość liczoną z paddingu i miniaturę 3.5rem/56px,
 * druga podniosła obie do 120px) — kwadratowa miniatura 100×100, przylegająca
 * do lewej/górnej/dolnej krawędzi karty (zero paddingu wokół niej), blok opisu
 * PO PRAWEJ stronie miniatury. Markup: `.mega-menu__news-list` >
 * `.mega-menu__news-card` (`<a>`, cała karta to jeden link — na życzenie) >
 * miniatura + `.mega-menu__news-card-body` (nazwa miasta — wiersz 1 +
 * `.mega-menu__news-card-labels` — wiersz 2, ikonki-indykatory PRZED
 * etykietami "wkrótce"/"nowość" w TYM SAMYM wierszu, odpowiednik
 * `.city-modules` — na życzenie BEZ TŁA, czarne, "ikona odstęp etykieta") —
 * patrz docblock `mobilet_pl_render_megamenu_news_column()` w
 * inc/megamenu.php po pełne uzasadnienie, czemu to NOWE klasy, nie
 * dosłowne sitewide `.labels`/`.city-modules`.
 *
 * Świadomie `<div>`/`<span>`, NIE `<ul>/<li>` — ten sam, już udokumentowany w
 * tym projekcie pitfall co przy paginacji Splide/FAQ Akordeonie w mobilet.eu:
 * `.section li:before` (nowymobilet.css) wstrzykuje czerwony bullet na każdym
 * `<li>` wewnątrz `.section`; ta kolumna żyje wewnątrz `.section` (panel
 * mega-menu jest częścią `#header`, który NIE jest `.section`, ALE treść
 * strony pod spodem jest — na wszelki wypadek, gdyby ten komponent kiedyś
 * trafił też tam, unikanie `<li>` jest tu bezpieczniejsze i tańsze niż
 * zerowanie `:before` punktowo).
 */
.mega-menu--test .mega-menu__news-list {
	display: flex;
	flex-direction: column;
	gap: .5rem;
}

/*
 * Karta = cała powierzchnia jest linkiem (na życzenie), STAŁA wysokość 100px
 * (na życzenie — ZMIANA, było 120px). `padding:0` na samej karcie — miniatura
 * ma przylegać do lewej/górnej/dolnej krawędzi BEZ marginesu, więc wewnętrzny
 * odstęp od treści żyje teraz WYŁĄCZNIE na `.mega-menu__news-card-body`
 * (patrz niżej), nie na karcie. `overflow:hidden` + `border-radius:var(--radius)`
 * przycina zawartość (w tym miniaturę) do zaokrąglonego kształtu karty jako
 * zabezpieczenie dodatkowe do jawnie zsynchronizowanego promienia na samej
 * miniaturze (patrz `.mega-menu__news-card-thumb` niżej — "na życzenie:
 * promień zaokrąglenia miniaturki i karty równy") — nie przycina własnego
 * box-shadow karty (overflow dotyczy TREŚCI elementu, nie jego własnego
 * cienia rysowanego na zewnątrz border-boxa, więc bezpiecznie współistnieją
 * na tym samym elemencie). Cień spoczynku — ten sam standard co
 * `.city-list.recent li`/`.card.card-link` w nowymobilet.css
 * (`0px 1px 5px 0px var(--transgray)`, patrz też reguła hover niżej po ten
 * sam standard w wersji "podniesionej"). `align-items:stretch` (wartość
 * domyślna, jawnie dla czytelności) — miniatura (100px, dokładnie wysokość
 * karty) i `.mega-menu__news-card-body` mają obie rozciągać się na pełną
 * wysokość karty.
 *
 * ZNALEZIONY I NAPRAWIONY BUG (2026-09-05, na żywym zrzucie ekranu +
 * potwierdzone lokalnym renderem/pomiarem computed style) — treść karty
 * (nazwa miasta, etykiety) była niewidoczna mimo poprawnego markupu w DOM.
 * Przyczyna: `#main-menu a` (nowymobilet.css:3928-3932, wewnątrz
 * `@media(min-width:992px)`) narzuca `display:inline-block` na KAŻDYM `<a>`
 * zagnieżdżonym GDZIEKOLWIEK wewnątrz `#main-menu` — a ten panel JEST
 * potomkiem `#main-menu` (patrz `.js-mega-menu-miasta` w `#main-menu>li`,
 * functions.php). Specyficzność `#main-menu a` to (1,0,1) — jeden selektor
 * ID zawsze bije DOWOLNĄ liczbę samych klas, więc nasza reguła (0,2,0: dwie
 * klasy, bez `!important`) przegrywała mimo pozornie "silniejszego"
 * selektora. Efekt: `<a class="mega-menu__news-card">` renderował się jako
 * `inline-block`, NIE `flex` — miniatura (blokowy `<img>`) i
 * `.mega-menu__news-card-body` przestały być elementami flex ułożonymi
 * OBOK siebie, tylko zwykłymi blokami w normalnym przepływie, jeden POD
 * drugim — `.mega-menu__news-card-body` renderował się więc CAŁY poniżej
 * 100px-owej, przyciętej `overflow:hidden` karty, czyli był w 100% wycięty
 * z widoku (potwierdzone: `getBoundingClientRect()` pokazywał
 * `.mega-menu__news-card-body` zaczynające się DOKŁADNIE na dolnej krawędzi
 * karty, y = top+100px). Naprawa: `!important` na `display` — jedyny sposób
 * (poza dorzuceniem własnego ID, nieadekwatnym tutaj) na przebicie
 * selektora z ID, ten sam, już ugruntowany w tym pliku wzorzec co
 * `#header:has(...) * {color:...!important}` wyżej. Ten sam pierwotny bug
 * (ID `#main-menu` bijące nasze klasy) dotyczy też `display:inline-flex` na
 * `.mega-menu__all-link.button`/`.mega-menu__download-btn` niżej w tym
 * pliku (też `<a>` wewnątrz `#main-menu`) — tam wizualnie niezauważalne
 * (te przyciski nie WYMAGAJĄ flexboksa do poprawnego wyglądu, samo
 * `inline-block` z tekstem+ikoną też "jakoś" wygląda), ale `align-items:
 * center` faktycznie nigdy tam nie działało — poprawione tam też, patrz
 * te reguły.
 */
.mega-menu--test .mega-menu__news-card {
	display: flex !important;
	align-items: stretch;
	height: 100px;
	padding: 0;
	border-radius: var(--radius);
	overflow: hidden;
	background-color: var(--light);
	box-shadow: 0px 1px 5px 0px var(--transgray);
	transition: background-color .2s ease-in-out, box-shadow .2s ease-in-out;
}

/*
 * ZMIANA (na życzenie) — hover na `--blue` (+ inwersja tekstu/ikon na biało)
 * WYCOFANY: w tej formie karty (poziomy wiersz, nie duże zdjęcie w tle jak
 * `.city-list.recent`) pełne, nasycone niebieskie tło okazało się zbyt mocnym
 * efektem. Zastąpiony subtelnym tłem `--light` (ten sam token, co hover/focus
 * na `.mega-menu__search-input` wyżej w tym pliku — spójny, już ustalony w
 * TYM komponencie "hover = lekkie wyszarzenie" zamiast wprowadzania nowego).
 * Tekst/ikony NIE wymagają już żadnej zmiany koloru na hover — ciemny navy na
 * jasnoszarym `--light` ma wystarczający kontrast, dokładnie jak na białym
 * tle w spoczynku — stąd usunięte w całości oba warianty inwersji koloru z
 * poprzedniej iteracji (tytuł→biały, ikony→`invert(100%) brightness(2)`),
 * bez zamiennika (miniatury nadal jaśnieją na hover, patrz reguła niżej —
 * to jedyny efekt hover niezwiązany z decyzją o kolorze tła).
 *
 * ZMIANA 2026-09-06 — pary tła ODWRÓCONE (na życzenie: "inwertuj kolory tła
 * kart... normal light > hover white"): spoczynek dostał `--light`
 * (poprzednio hover), hover dostał `--white` (poprzednio spoczynek) — karta
 * w spoczynku ma teraz LEKKO SZARE tło (odróżnia ją od białego tła kolumny
 * pod spodem), a na hover "rozjaśnia się" do czystej bieli. Uzasadnienie z
 * poprzedniego akapitu (kontrast tekstu/ikon wystarczający na obu odcieniach,
 * miniatura jaśnieje niezależnie od tła) zostaje aktualne w obu kierunkach.
 *
 * Cień hover — USUNIĘTY 2026-09-07 (na życzenie: "cień ma pozostać jak w
 * stanie wyjściowym, tylko zmiana tła"), SUPERSEDED opis wyżej ("Cień hover
 * — STANDARD już używany w stylach") — do 2026-09-07 hover podnosił cień na
 * `0px 1px 6px 1px var(--shadow)` (ten sam wzorzec co `.city-list.recent
 * li:hover`/`.card.card-link:hover`); teraz hover zmienia WYŁĄCZNIE
 * `background-color`, cień zostaje tym samym `0px 1px 5px 0px var(--transgray)`
 * co w spoczynku (dziedziczony, nie trzeba go tu powtarzać).
 */
.mega-menu--test .mega-menu__news-card:hover {
	background-color: var(--white);
}

.mega-menu--test .mega-menu__news-card:hover .mega-menu__news-card-thumb {
	filter: brightness(110%);
}

/*
 * Miniatura 100×100 (na życzenie — dokładnie wysokość karty) — kwadratowa,
 * przylega do lewej/górnej/dolnej krawędzi karty (zero paddingu wokół niej,
 * patrz `.mega-menu__news-card` wyżej: `padding:0`). Promień zaokrąglenia
 * RÓWNY karcie (na życzenie) — `var(--radius)`, ta sama zmienna co karta,
 * zaokrąglone WYŁĄCZNIE lewe rogi (góra-lewo/dół-lewo): prawe rogi celowo
 * proste (0), bo ta krawędź styka się z `.mega-menu__news-card-body`, nie z
 * zaokrągloną krawędzią karty. Ten sam wzorzec jednostronnego zaokrąglenia
 * co `.card.card-link img`/`.city-list.recent li img.archive--card--thumbnail`
 * w nowymobilet.css (tam odwrotnie: zaokrąglone dolne rogi, bo zdjęcie
 * przylega do góry, nie do boku).
 */
.mega-menu--test .mega-menu__news-card-thumb {
	flex-shrink: 0;
	width: 100px;
	height: 100px;
	border-radius: var(--radius) 0 0 var(--radius);
	object-fit: cover;
	transition: filter .3s ease-in-out;
}

/*
 * Blok opisu PO PRAWEJ stronie miniatury (na życzenie) — jedyne miejsce z
 * wewnętrznym paddingiem w tej karcie (karta sama ma `padding:0`, patrz
 * wyżej): miniatura ma być przy krawędziach bez odstępu, tekst — nie.
 * `justify-content:flex-start` — tytuł+etykiety(+termin) zaczynają się zaraz
 * pod górnym paddingiem (`.5rem`), zamiast wisieć na środku pełnej wysokości
 * 100px karty. `min-width:0` — standardowy wzorzec flex-itemu z tekstem,
 * który musi umieć się realnie skurczyć poniżej swojej treściowej
 * szerokości (bez tego długa nazwa miasta mogłaby przepchnąć kartę szerzej
 * niż kolumna). `overflow:hidden` (dziedziczone z `.mega-menu__news-card`)
 * obcina treść, która i tak by się nie zmieściła w 100px.
 *
 * PRÓBA 2026-09-06, COFNIĘTA tego samego dnia — na życzenie krótko
 * testowany był układ CSS Grid dwukolumnowy (ikonki w osobnej kolumnie 1,
 * wspólnej z nazwą TYLKO w pierwszym wierszu, tekst w kolumnie 2 przez
 * wszystkie 3 wiersze), żeby etykiety/termin wyrównać do lewej krawędzi
 * nazwy miasta zamiast do lewej krawędzi karty. Użytkownik zdecydował się
 * cofnąć tę zmianę — wraca prostszy wariant: ikonki jako flex-item
 * ZAGNIEŻDŻONY w `.mega-menu__news-card-title` (patrz ta reguła niżej),
 * etykiety/termin wyrównane do lewej krawędzi CAŁEJ karty (pod ikonkami,
 * nie pod samym tekstem nazwy).
 */
.mega-menu--test .mega-menu__news-card-body {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	gap: .35rem;
	min-width: 0;
	flex: 1 1 auto;
	padding: .5rem .85rem;
}

/*
 * Tytuł = SAMA nazwa miasta (2026-09-06, ZMIANA — ikonki przeniesione do
 * drugiego wiersza, patrz `.mega-menu__news-card-labels` niżej) — zwykły
 * blok tekstu, bez potrzeby `display:flex` (ikonek już tu nie ma).
 */
.mega-menu--test .mega-menu__news-card-title {
	margin: 0;
	font-size: .95rem;
	font-weight: 600;
	line-height: 1.25;
	color: var(--black);
	transition: color .2s ease-in-out;
}

/*
 * Drugi wiersz = ikonki-indykatory + etykiety (2026-09-06, ZMIANA — na
 * życzenie: "przenosimy ikonkę do drugiego wiersza, przed etykietę... ikona
 * odstęp etykieta"). Odpowiednik `.labels` z page-miasta.php — te same dwie
 * kolorystyki (`--offwhiteblue` dla "wkrótce"/planowane, `--green` dla
 * "nowość") po to, żeby język kolorów "wkrótce/nowość" pozostał spójny w
 * całym serwisie, mimo że to nowa, niezależna klasa (nie dosłowne `.labels
 * div.plan`/`.new`). `flex-wrap:wrap` — miasto może mieć naraz etykietę
 * "wkrótce" i "nowość" (różne moduły), obie mają się zawijać, nie ścieśniać
 * w jedną linię. `align-items:center` (nowe) — ikonki (`.mega-menu__news-
 * card-modules`, teraz PIERWSZE dziecko tego elementu w markupie, patrz
 * `mobilet_pl_render_megamenu_news_column()`) i etykiety-pigułki mają różną
 * wysokość naturalną (sam obrazek vs. tekst z paddingiem) — centrowanie w
 * pionie scala je w jedną, spójną linię zamiast wyrównywać do góry.
 */
.mega-menu--test .mega-menu__news-card-labels {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: .3rem;
}

.mega-menu--test .mega-menu__news-card-label {
	display: inline-block;
	padding: .2rem .45rem;
	border-radius: calc(0.5 * var(--radius));
	font-size: .68rem;
	font-weight: 600;
	line-height: 1.3;
	text-transform: uppercase;
	letter-spacing: .2px;
}

.mega-menu--test .mega-menu__news-card-label--plan {
	background-color: var(--offwhiteblue);
	color: var(--black);
}

.mega-menu--test .mega-menu__news-card-label--new {
	background-color: var(--green);
	color: var(--black);
}

/*
 * Trzeci wiersz opisu — termin uruchomienia dla miast "plan-*" (2026-09-06,
 * na życzenie: "wielkość i rodzaj jak <p>, ale uważaj na margins"). Prawdziwy
 * `<p>` (nie `<span>` jak reszta bloku) — świadomie, żeby móc niezależnie od
 * pozostałych wierszy dostroić jej wygląd. Wartości `margin-top`/`font-size`/
 * `color` (ręcznie doprecyzowane po pierwszej wersji, która 1:1 dziedziczyła
 * sitewide `p`) — mniejsze i wyszarzone względem nazwy/etykiet, bo to
 * najmniej istotny informacyjnie z trzech wierszy karty.
 */
.mega-menu--test .mega-menu__news-card-start {
	margin-top: 0.666rem;
	font-size: 0.666rem;
	color: var(--gray);
}

/*
 * Odpowiednik `.city-modules` — na życzenie WYŁĄCZNIE ikonki, BEZ TŁA (ZMIANA
 * — poprzednia iteracja miała każdą ikonę w kółku `--offwhiteblue`, usunięte
 * w całości: żadnego koloru/kształtu pod obrazkiem, sam `<img>`). Umieszczone
 * PRZED etykietami w DRUGIM wierszu (2026-09-06, ZMIANA — poprzednio flex-item
 * wewnątrz `.mega-menu__news-card-title`, patrz `mobilet_pl_render_megamenu_news_column()`
 * w inc/megamenu.php). `aria-hidden` na wrapperze — informacja "ten
 * moduł dotyczy tego miasta" jest już dostępna tekstowo w etykietach obok.
 */
.mega-menu--test .mega-menu__news-card-modules {
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	flex-shrink: 0;
}

/*
 * Kolor czarny + rozmiar zwiększony (2026-09-06, na życzenie, przy okazji
 * przeniesienia do drugiego wiersza). Pliki źródłowe (ico-transport.svg/
 * ico-parking.svg, motyw RODZIC) mają fill na sztywno wpisany w plik
 * (#094B82 ≈ `--blue`) — to zwykłe `<img>`, nie inline SVG, więc nie da się
 * sterować kolorem przez CSS `fill`. `filter:brightness(0)` to sprawdzony w
 * tym motywie trik na wymuszenie koloru ikony niezależnie od oryginalnego
 * (ten sam mechanizm rodziny co `filter:invert(100%) brightness(2)` używany
 * gdzie indziej w tym pliku/nowymobilet.css) — mnoży każdy kanał RGB przez 0
 * (czysta czerń), zachowując kanał alfa (kształt/krawędzie ikony bez zmian).
 * Rozmiar `1rem` → `1.2rem` ("nieco większa", na życzenie).
 */
.mega-menu--test .mega-menu__news-card-module-icon {
	display: block;
	width: 1.2rem;
	height: 1.2rem;
	filter: brightness(0);
}

/*
 * WYNIKI WYSZUKIWANIA (2026-09-06) — karty wstrzykiwane przez
 * js/megamenu-search.js do `.mega-menu__search-results` (PHP:
 * mobilet_pl_render_megamenu_search_results()/..._search_result_card() w
 * inc/megamenu.php). Na życzenie: "wąski pasek-karta, wzorowana na
 * karcie Nowości i Zapowiedzi... zachowaj styl kolorów, zaokrągleń i cieni
 * oraz hoverów jak na kartach" — kolory/radius/box-shadow/transition
 * poniżej to CELOWA DUPLIKACJA dokładnie tych samych wartości co
 * `.mega-menu__news-card`/`:hover` wyżej (nie współdzielona klasa/zmienna) —
 * ten sam wzorzec "siostrzanych", niezależnie edytowalnych komponentów
 * karty co `.city-list.recent li`/`.card.card-link`/`.mega-menu__news-card`
 * już mają w tym motywie (trzy niezależne miejsca z tymi samymi wartościami
 * cienia, nie jedna wspólna klasa) — każdy może być doprecyzowany osobno w
 * przyszłości bez ryzyka zepsucia pozostałych dwóch.
 *
 * Różnica względem karty "Nowości": szeroki, poziomy układ zamiast siatki
 * wielu kolumn (te karty żyją w `.mega-menu__search-results`, tym samym
 * slocie co `.mega-menu__columns` — NIE w wąskiej 1/3 kolumnie), więc "wąski
 * pasek" oznacza tu niską WYSOKOŚĆ, nie małą szerokość. **AKTUALIZACJA
 * 2026-09-07:** ta szerokość to już NIE pełna szerokość panelu — patrz
 * `.mega-menu--test .mega-menu__search-results{grid-column:2}` (media query
 * `≥992px` wyżej w pliku) — kontener jest teraz zawężony do środkowej
 * kolumny subgrida, dokładnie do szerokości search bara, na życzenie
 * ("szerokość kart wyników wyszukiwania na szerokość searchbaru"). Brak miniatury (na życzenie: "nie stosujemy
 * żadnych miniatur zdjęć") zastąpiony blokiem 1-2 dużych ikon-indykatorów
 * (patrz `.mega-menu__result-icons` niżej) w roli, którą u karty "Nowości"
 * pełniła miniatura — stały element po lewej, do którego wyrównuje się
 * reszta wiersza.
 *
 * `display:flex !important` — TA SAMA przyczyna co przy
 * `.mega-menu__news-card`/oba przyciski `.mega-menu__top-row` wyżej w tym
 * pliku: `#main-menu a` (nowymobilet.css:3928, specyficzność ID (1,0,1))
 * narzuca `display:inline-block` KAŻDEMU `<a>` wewnątrz `#main-menu`, a ten
 * panel jest jego potomkiem — żadna liczba klas (bez !important) tego nie
 * przebije. Zastosowane od razu, prewencyjnie (nie po znalezieniu buga na
 * żywo jak poprzednio) — ta sama pułapka jest już udokumentowana na górze
 * tego pliku.
 */
.mega-menu--test .mega-menu__result-list {
	display: flex;
	flex-direction: column;
	gap: .5rem;
}

/*
 * KARTY-SZKIELETY (2026-09-07, na życzenie: "wyszukiwanie trwa dość długo...
 * po wpisaniu 3 liter pojawiają się 3 karty wyników bez treści, styl tła to
 * animowane gradienty w kolorach light i white") — wstrzykiwane przez
 * showSkeleton() w js/megamenu-search.js, WEWNĄTRZ TEGO SAMEGO
 * `.mega-menu__result-list` co realne karty (ten sam `gap:.5rem` wyżej),
 * żeby podmiana skeleton→realne wyniki nie zmieniała odstępów i przez to
 * nie "skakała" dodatkowo ponad samą animację wysokości (patrz
 * setResultsContent() w JS).
 *
 * Wysokość DOKŁADNIE jak prawdziwa karta (`.mega-menu__result` niżej) — nie
 * osobna, przybliżona wartość: `35px` to wysokość SVG w `.mega-menu__result-
 * icon` (jedyny element, który realnie determinuje wysokość zawartości przy
 * `align-items:center`), `1.2rem` to suma pionowego paddingu karty (`.6rem`
 * góra + `.6rem` dół, patrz `.mega-menu__result` niżej) — ta sama formuła,
 * żeby wysokość panelu NIE skoczyła dodatkowo w momencie podmiany
 * skeleton→realne karty (sama liczba kart może się różnić — 3 szkielety vs.
 * N wyników — ale WYSOKOŚĆ POJEDYNCZEJ karty jest identyczna w obu stanach).
 * `border-radius`/`box-shadow` w spoczynku — 1:1 skopiowane z
 * `.mega-menu__result` (nie cień hover, patrz komentarz przy
 * `.mega-menu__result:hover` niżej — karta-szkielet nigdy nie jest hoverowana,
 * to nie jest link).
 *
 * Shimmer — gradient WĘDRUJĄCY po tle (`background-position` animowany
 * przez `background-size:200% 100%`, standardowy wzorzec "skeleton
 * loading"), a nie migający kolor (`opacity`/`background-color` w pętli) —
 * na życzenie "animowane gradienty w kolorach light i white", te same dwa
 * tokeny, których karty wyników już używają jako pary spoczynek/hover
 * (patrz `.mega-menu__result`/`:hover` niżej) — spójny język kolorów.
 * `prefers-reduced-motion` — patrz osobna reguła w `@media(min-width:992px)
 * and (prefers-reduced-motion:reduce)` wyżej w pliku (zeruje `animation`,
 * zostawia statyczne `--light`).
 */
.mega-menu--test .mega-menu__result-skeleton {
	height: calc(35px + 1.2rem);
	border-radius: var(--radius);
	box-shadow: 0px 1px 5px 0px var(--transgray);
	background-image: linear-gradient(90deg, var(--light) 25%, var(--white) 50%, var(--light) 75%);
	background-size: 200% 100%;
	animation: mega-menu-skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes mega-menu-skeleton-shimmer {
	0% {
		background-position: 200% 0;
	}

	100% {
		background-position: -200% 0;
	}
}

.mega-menu--test .mega-menu__result {
	display: flex !important;
	align-items: center;
	gap: .85rem;
	padding: .6rem 1rem;
	border-radius: var(--radius);
	background-color: var(--light);
	box-shadow: 0px 1px 5px 0px var(--transgray);
	transition: background-color .2s ease-in-out, box-shadow .2s ease-in-out;
}

/*
 * Cień hover USUNIĘTY 2026-09-07 (na życzenie, ta sama zmiana co przy
 * `.mega-menu__news-card:hover` wyżej — spójność między "siostrzanymi"
 * komponentami karty, patrz komentarz przy deklaracji `.mega-menu__result`
 * wyżej) — hover zmienia WYŁĄCZNIE `background-color`, cień zostaje tym
 * samym `0px 1px 5px 0px var(--transgray)` co w spoczynku.
 */
.mega-menu--test .mega-menu__result:hover,
.mega-menu--test .mega-menu__result:focus-visible {
	background-color: var(--white);
}

/*
 * Focus-visible (2026-09-06) — konieczny, bo wyniki są nawigowalne
 * strzałkami (patrz js/megamenu-search.js, roving focus między kartami):
 * użytkownik klawiatury musi widzieć, która karta jest aktualnie
 * "aktywna", tak samo wyraźnie jak użytkownik myszy widzi :hover.
 */
.mega-menu--test .mega-menu__result:focus-visible {
	outline: 2px solid var(--darkblue);
	outline-offset: 2px;
}

/*
 * Blok ikon — pierwotnie zlecone 50px, ZMNIEJSZONE do 35px (2026-09-06, na
 * żywym podglądzie) wraz z proporcjonalnie zmniejszonymi odstępami (gap
 * między ikonami .5rem→.4rem, gap blok-ikon↔tekst na `.mega-menu__result`
 * wyżej 1rem→.85rem) — przy mniejszych ikonach te same, większe odstępy
 * wyglądałyby nieproporcjonalnie szeroko. `width` STAŁA (nie zależna od
 * faktycznej liczby ikon w danej karcie) — to WŁAŚNIE gwarantuje, że blok
 * tekstu zaczyna się w tej samej kolumnie X we WSZYSTKICH kartach listy,
 * niezależnie od tego, czy dana karta ma 1 czy 2 ikony (ten sam cel, który
 * u karty "Nowości" spełniała stała szerokość miniatury). `justify-content:
 * flex-end` dosuwa blok do prawej krawędzi (czyli w stronę tekstu/nazwy
 * miasta) zamiast do lewej. `flex-shrink:0` — blok nigdy nie ściska się
 * kosztem tekstu obok.
 *
 * ZMIANA 2026-09-07 — blok renderuje teraz ZAWSZE OBIE ikony (transport,
 * potem parking — stała kolejność, patrz
 * mobilet_pl_render_megamenu_search_result_card() w inc/megamenu.php),
 * zamiast dawnych 1-2 sztuk zależnie od `has_transport`/`has_parking` —
 * `width` (już wcześniej liczona na 2 ikony) i `justify-content:flex-end`
 * zostają bez zmian, ale ich pierwotne uzasadnienie ("pojedyncza ikona
 * dosunięta do tekstu") jest już nieaktualne — blok ma teraz zawsze stałą,
 * dwuikonową szerokość. Ikona usługi nieaktywnej dla danego wpisu dostaje
 * `.mega-menu__result-icon--inactive` (opacity 0.15) zamiast znikać.
 */
.mega-menu--test .mega-menu__result-icons {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	flex-shrink: 0;
	gap: .4rem;
	width: calc(35px * 2 + .4rem);
}

.mega-menu--test .mega-menu__result-icon {
	display: inline-flex;
}

/*
 * 35px (ZMNIEJSZONE z 50px, na życzenie), `fill:var(--blue)` — te same
 * ścieżki SVG (mobilet_pl_megamenu_column_icon()) co nagłówki kolumn (tam
 * 2rem/32px — 35px tutaj jest więc niemal identycznej wielkości, celowo,
 * spójnie z resztą panelu), tylko w roli "zastępnika miniatury" w tej
 * karcie, nie małego indykatora jak `.mega-menu__news-card-module-icon`
 * (1.2rem, czarny) w kolumnie "Nowości" — świadomie inny kolor/rozmiar niż
 * tamten, bo to inna rola wizualna (główny akcent karty, nie drobna
 * etykieta obok tekstu).
 */
.mega-menu--test .mega-menu__result-icon svg {
	display: block;
	width: 35px;
	height: 35px;
	fill: var(--blue);
}

/*
 * Ikona usługi, której dany wpis NIE dotyczy (2026-09-07) — zostaje w
 * markupie (stały, przewidywalny layout bloku, patrz komentarz przy
 * `.mega-menu__result-icons` wyżej), ale przygaszona do opacity:.15 zamiast
 * pełnego koloru `--blue`. Sam `fill` nietknięty — opacity na wrapperze
 * `<span>`, nie na `svg`/`path`, żeby przygasić całość (w tym ewentualny
 * przyszły drugi kolor) jednym mechanizmem.
 */
.mega-menu--test .mega-menu__result-icon--inactive {
	opacity: .15;
}

.mega-menu--test .mega-menu__result-body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: .15rem;
	min-width: 0;
	flex: 1 1 auto;
}

/* Styl jak w karcie "Nowości" (na życzenie) — wartości 1:1 z
   `.mega-menu__news-card-title` wyżej. Ellipsis zamiast line-clamp: przy
   pełnej szerokości panelu (nie wąskiej 1/3 kolumnie jak "Nowości") jedna
   linia praktycznie zawsze wystarcza na nazwę miasta; ellipsis to tylko
   bezpiecznik na wypadek ekstremalnie długiej nazwy. */
.mega-menu--test .mega-menu__result-title {
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .95rem;
	font-weight: 600;
	line-height: 1.25;
	color: var(--black);
}

/* Styl jak info o terminie na karcie "Nowości" (na życzenie) —
   font-size/color 1:1 z `.mega-menu__news-card-start` wyżej. `margin:0`
   (NIE `margin-top:.666rem` jak tamta reguła) — tu odstęp od tytułu
   zapewnia już `gap:.15rem` rodzica (`.mega-menu__result-body` wyżej), a
   ta karta ma tylko 2 wiersze (nie 3 jak "Nowości"), więc dodatkowy
   margines dublowałby odstęp bez potrzeby. Kolor wymaga wyjątku od
   blanket `#header:has(...) * {color:black!important}` — patrz oba
   `#header:has(...) .mega-menu__result-subtitle` wyżej w tym pliku. */
.mega-menu--test .mega-menu__result-subtitle {
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .666rem;
	color: var(--gray);
}

/*
 * ZMIANA 2026-09-04 — `1fr auto 1fr` zastąpione przez `auto minmax(0,1fr)
 * auto`, na życzenie: search bar ma teraz wypełniać DOKŁADNIE tyle miejsca,
 * ile zostaje w wierszu po obu przyciskach (ich szerokość bez zmian —
 * kolumna `auto` = rozmiar naturalny treści), a nie tylko tyle, ile
 * wymuszał jego własny stały rozmiar (dawniej `min-width:500px` na inpucie,
 * patrz `.mega-menu__search-input` niżej). Suma: przycisk1 + gap + search +
 * gap + przycisk2 wychodzi matematycznie równa szerokości kontenera — ani
 * nadmiaru, ani przepełnienia, przy każdej szerokości ekranu.
 *
 * `minmax(0,1fr)`, NIE goły `1fr` — sam `1fr` ma domyślne "automatic
 * minimum size" liczone z zawartości (min-content inputu), więc kolumna i
 * tak nie skurczyłaby się poniżej tego minimum mimo `1fr` — dokładnie ten
 * sam mechanizm, przez który poprzednie `min-width:500px` wymuszało
 * nadmiarową szerokość. `minmax(0,1fr)` jawnie zeruje minimalny rozmiar
 * toru; jedynym pozostałym ograniczeniem jest `min-width:0` na samym
 * inpucie i jego wrapperze (patrz niżej) — standardowy wzorzec na "grid/flex
 * item przepełnia kontener mimo 1fr".
 *
 * Nadal "search na środku" — nie przez centrowanie w przestrzeni (jak w
 * poprzednim modelu, dwie równe skrajne kolumny 1fr wokół zawartościowej
 * "auto"), tylko przez bycie jedynym elastycznym elementem między dwoma
 * stałymi: skoro przyciski mają różną szerokość, search bar i tak nie
 * wypadnie idealnie w geometrycznym środku wiersza — wypełnia to, co
 * zostaje, z lewej i prawej strony dotykając bezpośrednio sąsiadów.
 */
.mega-menu__top-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	/*
	 * `gap:1.5rem` USUNIĘTY stąd 2026-09-06 (na życzenie, po zgłoszeniu na
	 * żywym podglądzie: "rozszerzony searchbar ma po lewej stronie odstęp")
	 * — zastąpiony jawnymi `margin-right:1.5rem` na `.mega-menu__all-link.button`
	 * i `.mega-menu__search` niżej. Powód: CSS Grid `gap` rezerwuje STAŁY
	 * odstęp między KAŻDĄ parą sąsiadujących torów niezależnie od tego, jak
	 * wąski (nawet zerowy) stanie się dowolny z nich — kolaps przycisku
	 * "Zobacz wszystkie miasta" do `max-width:0` (patrz `.is-searching`
	 * niżej) skurczył SAM przycisk do zera, ale `gap` między jego torem a
	 * torem search bara i tak zostawał, więc rozszerzony search bar zaczynał
	 * się 1.5rem za daleko w prawo zamiast dotknąć lewej krawędzi wiersza.
	 * Margines na SAMYM elemencie (w przeciwieństwie do `gap` na
	 * kontenerze) można animować do zera razem z resztą kolapsu — stąd
	 * przeniesienie odstępu z `gap` na `margin-right` konkretnego elementu.
	 * Suma szerokości nadal matematycznie się zgadza (3 elementy + 2×1.5rem
	 * marginesu = to samo, co wcześniej 3 elementy + 2×1.5rem gap) — tylko
	 * mechanizm zmienił się z "na kontenerze" na "na elemencie", żeby był
	 * animowalny per-para, nie globalnie.
	 */
	padding-bottom: 3rem;
	/*
	 * ZMIANA 2026-09-05, trzeci raz — poprzednia naprawa (display:inline-flex
	 * + align-items:center na obu przyciskach, patrz komentarze niżej) była
	 * matematycznie poprawna na papierze (padding/border/line-height
	 * identyczne jak input → ta sama wysokość auto), ale na żywym podglądzie
	 * (zrzut ekranu użytkownika, 2026-09-05) przyciski WCIĄŻ wychodzą wyżej
	 * niż `.mega-menu__search-input` — auto-wysokość liczona z line-height
	 * zależy od metryk fontu i sposobu, w jaki dana przeglądarka liczy line-box
	 * dla zwykłego tekstu (`<a>`) kontra wewnętrzny content-box `<input>`
	 * (który ma własny, częściowo niezależny od `line-height` mechanizm
	 * renderowania tekstu w polu formularza) — te dwa mechanizmy NIE muszą
	 * dawać identycznego wyniku nawet przy identycznym CSS, i w praktyce
	 * nie dają.
	 *
	 * Naprawa odporna na to rozjeżdżanie się: zamiast polegać na tym, że
	 * auto-wysokość obu typów elementów WYJDZIE taka sama, wymuszona jest
	 * JEDNA, dzielona, jawna wysokość (`--mm-control-height`) na wszystkich
	 * trzech elementach na raz + `box-sizing:border-box` (żeby ta wysokość
	 * obejmowała padding+border, tak jak dotychczasowa auto-wysokość) —
	 * `height` jawny + border-box eliminuje różnice w tym, JAK dana
	 * przeglądarka liczy line-box, bo box model przestaje zależeć od
	 * line-height w ogóle. Wartość dobrana tak, by odtworzyć DOKŁADNIE
	 * dotychczasowy, zamierzony rozmiar inputu: border(1px)×2 + padding
	 * pionowy(.75rem)×2 + treść(1rem z line-height:1) = `calc(2.5rem + 2px)`.
	 * Pionowe centrowanie treści w tej stałej wysokości: input robi to
	 * natywnie (przeglądarki centrują tekst/placeholder w polu formularza
	 * niezależnie od line-height), przyciski przez już istniejące
	 * `align-items:center` na `display:inline-flex`.
	 */
	--mm-control-height: calc(2.5rem + 2px);
}

/*
 * ZMIANA 2026-09-07 — w trybie wyszukiwania (`.mega-menu--test.is-searching`,
 * patrz JS `.is-searching` toggle wyżej) `.mega-menu__top-row` dostaje
 * zredukowany `padding-bottom:1.5rem` zamiast standardowych `3rem`. Ten
 * padding był myślany pod odstęp między wierszem przycisków/search bara a
 * siatką miast pod nim w stanie spoczynku — w trybie wyszukiwania
 * kolapsujący przycisk "Zobacz wszystkie miasta" i tak już generuje własny
 * odstęp (`margin-bottom`, patrz `.is-searching .mega-menu__all-link.button`
 * niżej) do `.mega-menu__char-hint`/wyników, więc pełne `3rem` tutaj
 * dublowałoby się z tamtym marginesem — zredukowane, nie wyzerowane
 * całkowicie, żeby jednak zostawić minimalny oddech.
 */
.mega-menu--test.is-searching .mega-menu__top-row {
	padding-bottom: calc(1.5rem - 6px);
}

/*
 * Przycisk "Zobacz wszystkie miasta" — od 2026-09-03 domyślny styl `.button`
 * (klasa dodana w markupie, inc/megamenu.php) + trzy modyfikacje na
 * życzenie: czarne tło, biały tekst, szerokość auto. Bazowy `.button`
 * (nowymobilet.css:1028-1055) jest domyślnie `display:block; width:100%;
 * margin-top:3rem; margin-bottom:1.25rem` — myślany pod przycisk stojący
 * samotnie w kolumnie, nie w poziomym rzędzie obok search bara — stąd
 * `display:inline-block; width:auto; margin:0` niżej. Font-weight
 * świadomie NIE nadpisany (zostaje domyślne 400 z `.button`) — poprzednia
 * wersja tego linku (zwykły <a>, bez klasy `.button`) miała ręczne
 * font-weight:800, ale to nie było częścią zlecenia tej zmiany, więc
 * przy przejściu na "domyślny styl buttona" świadomie porzucone.
 *
 * PUŁAPKA znaleziona na żywym podglądzie (2026-09-03) — pierwsza wersja tej
 * reguły NIE nadpisywała `font-size`/`line-height`, zakładając że `.button`
 * (font-size:1rem; line-height:1) wystarczy do dopasowania wysokości do
 * `.mega-menu__search-input`. W praktyce ten link jest potomkiem `.sub-menu`
 * (WP native dropdown), a `.sub-menu a` (nowymobilet.css:4066-4077) ma
 * WYŻSZĄ specyficzność niż `.button` — (0,1,1) [klasa .sub-menu + typ a]
 * kontra (0,1,0) [sama klasa .button] — więc realnie renderowany był
 * font-size:.85rem + line-height:1.3 z tamtej reguły, nie 1rem/1 z `.button`
 * (widoczne w screenshocie jako niższy box niż search bar / niewidoczny
 * tekst na czarnym tle w kombinacji z drugim bugiem opisanym niżej).
 * Naprawa: `font-size`/`line-height` jawnie nadpisane TU, w regule o
 * specyficzności (0,3,0) — bezpiecznie bije (0,1,1) `.sub-menu a`
 * niezależnie od tego, co jeszcze ta reguła kiedyś ustawi. Ten sam problem
 * (i ta sama naprawa) dotyczy `.mega-menu__top-row .button.mega-menu__download-btn`
 * niżej — przy KAŻDYM przycisku wewnątrz `.sub-menu` w tym pliku pamiętać,
 * że sam `.button`/`.button-blue` NIE wystarczy, trzeba jawnie nadpisać
 * font-size/line-height (i, jak się okazało osobno, `color` — patrz
 * wyjątek `#header:has(.js-mega-menu-miasta:hover) ...` wyżej w tym pliku).
 *
 * Padding poziomy (1.5rem) nie był wprost zlecony — dobrany dla spójności
 * z sąsiednim przyciskiem "Pobierz aplikację" (ten sam 1.5rem, patrz
 * `.mega-menu__top-row .button.mega-menu__download-btn` niżej).
 *
 * WYSOKOŚĆ = DOKŁADNIE jak `.mega-menu__search-input` — `display:inline-
 * block`→`inline-flex` (2026-09-05) SUPERSEDED tego samego dnia przez
 * jawny, dzielony `height:var(--mm-control-height)` + `box-sizing:border-
 * box` (patrz `--mm-control-height` na `.mega-menu__top-row` wyżej i
 * obszerny komentarz "SUPERSEDED" przy `.mega-menu__top-row .button.
 * mega-menu__download-btn` niżej po pełne uzasadnienie, dlaczego samo
 * inline-flex nie wystarczyło na żywym podglądzie). `inline-flex`/
 * `align-items:center` zostają — centrują treść WEWNĄTRZ przycisku, ale o
 * wysokości WZGLĘDEM inputu decyduje już `--mm-control-height`, nie
 * line-height.
 *
 * POPRAWKA 2026-09-05 (dopisana przy okazji naprawy kart kolumny 3, patrz
 * obszerny komentarz przy `.mega-menu--test .mega-menu__news-card` wyżej) —
 * `display` dostaje `!important`. Odkryty wtedy root cause: `#main-menu a`
 * (nowymobilet.css:3928-3932) narzuca WSZYSTKIM `<a>` wewnątrz `#main-menu`
 * (w tym temu linkowi) `display:inline-block` z siłą selektora ID (1,0,1) —
 * bije tę regułę (0,2,0, same klasy) NIEZALEŻNIE od tego, ile klas by tu
 * dopisać. To prawdopodobnie PRAWDZIWA przyczyna, dla której (patrz
 * "SUPERSEDED" niżej) samo `inline-flex` "nie wystarczało" — `align-items:
 * center` nigdy realnie nie działał (bo realny `display` to było
 * `inline-block`, nie `inline-flex`), nie tylko rozjazd auto-wysokości
 * `<a>` vs `<input>`. Poprzednia naprawa (jawny `height`+`box-sizing`)
 * ZOSTAJE — rozwiązuje wysokość niezależnie od tego builda — ale bez tego
 * `!important` samo `align-items:center` i tak nigdy by nie zadziałało.
 */
.mega-menu__top-row .mega-menu__all-link.button {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: auto;
	height: var(--mm-control-height);
	box-sizing: border-box;
	/*
	 * margin-right:1.5rem (2026-09-06, ZASTĘPUJE dawny `gap:1.5rem` z
	 * `.mega-menu__top-row` — patrz obszerny komentarz tam) — odstęp od
	 * search bara przeniesiony na TEN element, żeby dało się go animować
	 * do zera razem z resztą kolapsu w `.is-searching` niżej.
	 */
	margin: 0 1.5rem 0 0;
	padding: .75rem 1.5rem;
	font-size: 1rem;
	line-height: 1;
	background: var(--blue);
	color: var(--black);
	border: solid 1px var(--blue);
	justify-self: start;
	white-space: nowrap;
	/*
	 * Kolaps w trybie wyszukiwania (2026-09-06, patrz .is-searching niżej i
	 * js/megamenu-search.js) — `max-width` startuje od `18rem`, celowo
	 * WIĘKSZEGO niż naturalna szerokość tego przycisku (żeby w spoczynku
	 * `max-width` nigdy realnie nie przycinał treści — działa tu wyłącznie
	 * jako punkt startowy do animacji, nie jako ograniczenie).
	 *
	 * PUŁAPKA znaleziona przy weryfikacji headless Edge: `box-sizing:
	 * border-box` (wyżej w tej regule) NIE pozwala boxowi skurczyć się
	 * poniżej sumy paddingu+bordera — content może zejść do 0, ale
	 * padding/border zawsze zostają, więc samo `max-width:0` zatrzymywało
	 * się na ~56px (2×1.5rem padding + 2×1px border), nie na 0. Dlatego
	 * `padding-left`/`padding-right`/`border-left-width`/`border-right-width`
	 * muszą być RÓWNIEŻ animowane do zera (dokładnie ten sam wzorzec co
	 * przenoszenie paddingu przy animacji wysokości panelu — `.mega-menu__grid`
	 * wyżej w tym pliku — tam padding też trzeba było jawnie wyzerować, nie
	 * tylko wysokość kontenera).
	 *
	 * Transitions muszą być zdefiniowane TUTAJ (na bazowej regule), nie
	 * tylko na stanie `.is-searching` — inaczej przeglądarka animowałaby
	 * tylko WEJŚCIE w tryb wyszukiwania (dodanie klasy), a WYJŚCIE (usunięcie
	 * klasy) skakałoby bez animacji. `overflow:hidden` przycina treść
	 * (tekst) w trakcie kurczenia się boxa, zamiast pozwolić jej się
	 * wylać/zawinąć.
	 */
	max-width: 18rem;
	overflow: hidden;
	transition: max-width .25s ease-in-out, margin-right .25s ease-in-out,
		padding-left .25s ease-in-out, padding-right .25s ease-in-out,
		border-left-width .25s ease-in-out, border-right-width .25s ease-in-out,
		opacity .2s ease-in-out;
}

.mega-menu__top-row .mega-menu__all-link.button:hover {
	background: var(--darkblue);
	border-color: var(--darkblue);
}

/*
 * Tryb wyszukiwania (2026-09-06) — `.is-searching` toggle'owany przez
 * js/megamenu-search.js na `.mega-menu--test` (ten sam `<ul>`, na którym
 * żyją pozostałe stany panelu — spójny wzorzec "stan na
 * korzeniu, style na potomkach"). Przycisk kurczy się do zera: `max-width:0`
 * + `margin-right:0` (2026-09-06, POPRAWIONE z `-1.5rem` — patrz niżej)
 * razem zerują CAŁY footprint elementu, więc środkowy tor search bara
 * (`minmax(0,1fr)`) automatycznie, bez DODATKOWEGO kodu, przejmuje całą
 * zwolnioną szerokość — to WŁAŚNIE "search bar rozszerza się do lewej" z
 * życzenia użytkownika, uzyskane czysto jako efekt uboczny działania CSS
 * Grid, nie osobną animacją na samym search barze.
 *
 * POPRAWKA 2026-09-06 (zgłoszona na żywym podglądzie: "rozszerzony
 * searchbar ma po lewej stronie odstęp") — `margin-right` startował
 * poprzednio od `0` (bo odstęp dawał wtedy jeszcze `gap:1.5rem` z
 * `.mega-menu__top-row`) i schodził do `-1.5rem` w tym stanie, próbując
 * "zjeść" ten `gap`. To nie mogło zadziałać w 100%: `gap` w CSS Grid jest
 * WŁASNOŚCIĄ KONTENERA między TORAMI, nie marginesem elementu — ujemny
 * margines potrafi wizualnie nachodzić na sąsiedni obszar, ale nie zmienia
 * samej rezerwacji `gap`, więc realnie wciąż zostawał niewielki, martwy
 * odstęp. Naprawa właściwa: `gap` usunięty z kontenera CAŁKOWICIE (patrz
 * `.mega-menu__top-row` wyżej), odstęp przeniesiony w całości na
 * `margin-right` samego przycisku — w spoczynku `1.5rem` (na bazowej
 * regule wyżej), tutaj `0`. Bez żadnego `gap` do zrekompensowania, `0`
 * oznacza dokładnie "brak odstępu", nie przybliżenie.
 *
 * `opacity:0` + `pointer-events:none` — element mimo `max-width:0` ma
 * jeszcze przez chwilę trwania animacji niezerowy (kurczący się) box,
 * `pointer-events:none` zapobiega przypadkowemu kliknięciu w niego w tym
 * oknie czasowym.
 */
.mega-menu--test.is-searching .mega-menu__top-row .mega-menu__all-link.button {
	max-width: 0;
	min-width: 0;
	margin-right: 0;
	padding-left: 0;
	padding-right: 0;
	border-left-width: 0;
	border-right-width: 0;
	opacity: 0;
	pointer-events: none;
}

/*
 * ZMIANA 2026-09-04 — `justify-self:center` (dopasowane pod dawną, szerszą
 * niż potrzeba kolumnę `auto`, w której wrapper trzeba było wewnętrznie
 * centrować) zastąpione przez `stretch`: kolumna to teraz `minmax(0,1fr)`,
 * dokładnie tak szeroka jak dostępna przestrzeń, więc wrapper ma ją
 * wypełniać w całości, nie "pływać" pośrodku szerszego toru.
 * `min-width:0` jawnie zeruje domyślne `min-width:auto` grid itemu — patrz
 * komentarz przy `.mega-menu__top-row` wyżej po pełne uzasadnienie wzorca.
 */
.mega-menu__search {
	justify-self: stretch;
	min-width: 0;
	/*
	 * position:relative (2026-09-06) — kotwiczy .mega-menu__search-clear
	 * (przycisk "×" niżej), pozycjonowany absolutnie względem TEGO wrappera,
	 * nie samego inputu (input ma już własny padding-right zajęty przez nic —
	 * lupa jest po LEWEJ, patrz .mega-menu__search-input niżej — więc "×" po
	 * prawej nie koliduje z niczym istniejącym).
	 */
	position: relative;
	/*
	 * margin-right:1.5rem (2026-09-06, ZASTĘPUJE dawny `gap:1.5rem` z
	 * `.mega-menu__top-row` — patrz obszerny komentarz tam) — odstęp od
	 * przycisku "Pobierz aplikację" po prawej. Stały, niezależny od stanu
	 * `.is-searching` (w przeciwieństwie do analogicznego marginesu na
	 * `.mega-menu__all-link.button`) — ten odstęp nigdy się nie zmienia,
	 * bo trzeci element wiersza (przycisk pobierania) nie bierze udziału
	 * w kolapsie.
	 */
	margin-right: 1.5rem;
}

/*
 * Przycisk czyszczenia wyszukiwania (2026-09-06) — patrz js/megamenu-search.js
 * i markup w inc/megamenu.php. CSS-only krzyż (dwa <span>+rotate), ten
 * sam wzorzec geometryczny co #submenu-close/#menu-icon w nowymobilet.css
 * (patrz CLAUDE.md "Ikony mobilnego menu — system CSS-only") — bez nowego
 * assetu SVG. Domyślnie `hidden` (atrybut HTML w markupie) — JS zdejmuje go
 * wyłącznie w trybie wyszukiwania; `display:none` tutaj to czysty
 * bezpiecznik na wypadek gdyby atrybut `hidden` z jakiegoś powodu nie
 * zadziałał (nie powinno się zdarzyć, ale tania, nieszkodliwa redundancja).
 */
.mega-menu__search-clear {
	display: flex;
	align-items: center;
	justify-content: center;
	position: absolute;
	top: 50%;
	right: .75rem;
	transform: translateY(-50%);
	width: 1.5rem;
	height: 1.5rem;
	padding: 0;
	margin: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
}

.mega-menu__search-clear[hidden] {
	display: none;
}

.mega-menu__search-clear span {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 14px;
	height: 2px;
	background-color: var(--gray);
	border-radius: 1px;
}

.mega-menu__search-clear span:first-child {
	transform: translate(-50%, -50%) rotate(45deg);
}

.mega-menu__search-clear span:last-child {
	transform: translate(-50%, -50%) rotate(-45deg);
}

/*
 * Wzorowany na #city-search-input (page-miasta.php / nowymobilet.css:2063-2126)
 * — ta sama baza `input` (nowymobilet.css:519-532: padding, border-radius:
 * var(--radius), transition) + ta sama technika lupy jako background-image
 * zamiast osobnego <img>.
 *
 * KOLORYSTYKA (2026-09-05) — świadomie identyczna z inputami formularza
 * kontaktowego (CF7, np. `/pl/pomoc/`, `.wpcf7-form-control` — te formularze
 * NIE mają własnych reguł koloru, dziedziczą wprost bazowy sitewide `input`
 * z nowymobilet.css:519-552), nie z `#city-search-input`: border
 * `1px solid var(--lightblue)` w spoczynku, `var(--darkblue)` na
 * hover/focus + `background-color:var(--light)` na hover/focus +
 * `box-shadow:0px 0px 0px 1px var(--darkblue)` WYŁĄCZNIE na focus — 1:1 ta
 * sama reguła co bazowy `input:hover,:focus`/`input:focus{box-shadow}`
 * (nowymobilet.css:538-552), rozłożona tu na dwa osobne bloki z tego samego
 * powodu co tam (box-shadow tylko przy klawiaturowym/kliknięciowym fokusie,
 * nie przy samym hoverze myszą).
 *
 * SUPERSEDED 2026-09-05 — poprzednia wersja miała świadomie CAŁKOWICIE
 * czarną kolorystykę (border `var(--black)`, lupa czarna, hover/focus bez
 * zmiany koloru/box-shadow) właśnie po to, żeby ODRÓŻNIĆ się od niebieskiego
 * `#city-search-input`, którego lupa (`images/search.svg`, fill:#7798B3) jest
 * WSPÓLNYM plikiem współdzielonym z `/miasta` i nie mogła zostać podmieniona
 * bez zepsucia tamtego wariantu — stąd wtedy osobny, czarny inline SVG.
 * Teraz na wyraźne życzenie ten wybór odwrócony: lupa poniżej dostała
 * dokładnie TĘ SAMĄ wartość fill (`#7798B3` = `--lightblue`, tego custom
 * property nie da się użyć wewnątrz inline data-URI, stąd hex wpisany na
 * sztywno) — mechanizm inline SVG (zamiast osobnego pliku, ten sam wzorzec
 * co `.module-hero__badge-icon` w mobilet.eu) zostaje BEZ zmian, zmienia się
 * tylko sam kolor, żeby dało się go w pełni kontrolować z poziomu tego pliku.
 *
 * `position:static` (NIE `absolute` jak baza #city-search-input) — tu input
 * jest jedynym elementem w swojej kolumnie grida `.mega-menu__top-row`, nie
 * potrzebuje wychodzić poza normalny przepływ żeby się z czymś nie nachodzić.
 *
 * `min-width:0` (2026-09-04) — pozwala inputowi skurczyć się do szerokości
 * toru `minmax(0,1fr)` zamiast go przepełniać, patrz obszerny komentarz przy
 * `.mega-menu__top-row` wyżej.
 *
 * Świadomie inna klasa (`.mega-menu__search-input`), NIE `#city-search-input`
 * — ten sam `id` powtórzony w headerze (ładowanym na każdej stronie) byłby
 * duplikatem ID w DOM w razie gdyby kiedyś na tej samej stronie znalazł się
 * też blok #module-filter; klasa nie ma tego ryzyka.
 *
 * `height:var(--mm-control-height)` + `box-sizing:border-box` (2026-09-05)
 * — jawna wysokość zamiast auto (border+padding+line-height), żeby
 * gwarantować identyczną wysokość z obu przycisków obok, patrz obszerny
 * komentarz "SUPERSEDED" przy `--mm-control-height` na `.mega-menu__top-row`
 * wyżej po pełne uzasadnienie (auto-wysokość `<input>` i `<a>` nie muszą
 * wyjść identyczne nawet przy identycznym CSS). Wartość dobrana tak, by
 * odtworzyć DOKŁADNIE dotychczasową, zamierzoną auto-wysokość — zero
 * zamierzonej zmiany rozmiaru, tylko mechanizmu, którym się ją osiąga.
 */
.mega-menu__search-input {
	width: 100%;
	min-width: 0;
	height: var(--mm-control-height);
	box-sizing: border-box;
	margin-bottom: 0;
	padding: .75rem 1.2rem .75rem 2.75rem;
	border: 1px solid var(--lightblue);
	border-radius: var(--radius);
	background-color: var(--white);
	background-repeat: no-repeat;
	background-position: left 1rem center;
	background-size: 1.2rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44000 44000'%3E%3Cpath fill='%237798B3' d='M29070 31500c-670,-670 -670,-1760 0,-2430 670,-670 1760,-670 2430,0l12000 12000c670,670 670,1760 0,2430 -670,670 -1760,670 -2430,0l-12000 -12000zm-12210 -31500c4650,0 8870,1890 11920,4940 3050,3050 4930,7260 4930,11920 0,4650 -1880,8870 -4930,11920 -3050,3050 -7270,4930 -11920,4930 -4660,0 -8870,-1880 -11920,-4930 -3050,-3050 -4940,-7270 -4940,-11920 0,-4660 1890,-8870 4940,-11920 3050,-3050 7260,-4940 11920,-4940zm9490 7360c-2430,-2430 -5790,-3930 -9490,-3930 -3710,0 -7070,1500 -9500,3930 -2430,2430 -3930,5790 -3930,9500 0,3700 1500,7060 3930,9490 2430,2430 5790,3930 9500,3930 3700,0 7060,-1500 9490,-3930 2430,-2430 3930,-5790 3930,-9490 0,-3710 -1500,-7070 -3930,-9500z'/%3E%3C/svg%3E");
}

.mega-menu__search-input:hover,
.mega-menu__search-input:focus {
	border-color: var(--darkblue);
	background-color: var(--light);
}

.mega-menu__search-input:focus {
	box-shadow: 0px 0px 0px 1px var(--darkblue);
	/*
	 * outline:none (2026-09-06, na życzenie po weryfikacji na żywo — "usuń
	 * outline na focusie, zmiana zbyt agresywna") — natywny outline
	 * przeglądarki (niezerowany dotąd nigdzie w tym pliku) renderował się
	 * DODATKOWO nad już istniejącym, własnym pierścieniem `box-shadow`
	 * wyżej — dwa nakładające się obrysy naraz. Bezpiecznie usuwalny bez
	 * utraty widocznego wskaźnika fokusu dla klawiatury — `box-shadow` na
	 * tym samym `:focus` już pełni tę rolę samodzielnie.
	 */
	outline: none;
}

/*
 * Miejsce na przycisk "×" (2026-09-06) — dodatkowy padding-right WYŁĄCZNIE
 * w trybie wyszukiwania (`.mega-menu--test.is-searching`, patrz JS), żeby
 * wpisywany tekst nigdy nie chował się pod `.mega-menu__search-clear`
 * (right:.75rem + width:1.5rem ≈ 2.25rem zajęte). Poza trybem wyszukiwania
 * przycisk jest `hidden`, więc bazowy `padding-right:1.2rem` (patrz reguła
 * `.mega-menu__search-input` wyżej) zostaje nietknięty — brak zmiany
 * wyglądu w spoczynku.
 */
.mega-menu--test.is-searching .mega-menu__search-input {
	padding-right: 2.5rem;
}

/*
 * Bazowy `.button`+`.button-blue` (nowymobilet.css:1028-1070) jest zaprojektowany
 * do pełnej szerokości kolumny (display:block; width:100%; margin-top:3rem) —
 * niepasujące do wiersza 3 elementów. Nadpisanie scoped do tego kontekstu na
 * display/width/margin/padding, specyficzność (0,3,0) tej reguły > (0,1,0)
 * każdej z dwóch bazowych, więc te cztery właściwości wygrywają bez
 * `!important`.
 *
 * POPRAWKA 2026-09-03, po buga zgłoszonym na żywym podglądzie: pierwsza
 * wersja tej zmiany zakładała, że `background`/`color`/`border`/wysokość
 * wystarczą z sitewide `.button-blue` (background/color/border) + `.button`
 * (font-size/line-height) — w praktyce przycisk renderował się jako goły
 * tekst bez żadnego tła. Przyczyna: `.sub-menu a` (nowymobilet.css:4066-4077,
 * WP-owy reset linków w dropdownach) ma specyficzność (0,1,1) [klasa
 * .sub-menu + typ a] — WYŻSZĄ niż `.button-blue`/`.button` (0,1,0) każda,
 * bo dolicza się typ selektora `a`. Ten reset ustawia
 * `background-color:transparent; color:var(--black); font-size:.85rem;
 * line-height:1.3` i po cichu WYGRYWAŁ z sitewide klasami koloru/rozmiaru
 * (przegrywał tylko z display/width/margin/padding, bo te były już jawnie
 * nadpisane scoped regułą (0,3,0) poniżej). Naprawa: `background`/`color`/
 * `border`/`font-size`/`line-height` przeniesione tutaj, jawnie, w tej samej
 * regule (0,3,0) — ten sam problem i ta sama naprawa co przy
 * `.mega-menu__all-link.button` wyżej (patrz tamten komentarz po szczegóły
 * matematyki specyficzności). `color` dodatkowo wymaga `!important` +
 * osobnego wyjątku pod `#header:has(.js-mega-menu-miasta:hover) ...`
 * (wyżej w tym pliku) — inaczej `#header:has(...) * {color:black!important}`
 * (uruchamiany zawsze, gdy panel jest w ogóle widoczny) wymusza czarny tekst
 * niezależnie od tej reguły.
 *
 * WYSOKOŚĆ vs. `.mega-menu__search-input` (2026-09-05) — co DOKŁADNIE
 * determinuje wysokość searchbaru: input nie ma ustawionego `height`, więc
 * jego renderowana wysokość to border(1px)×2 + padding pionowy(.75rem)×2 +
 * wysokość treści z `line-height` (dziedziczone z bazowego `input` w
 * nowymobilet.css:519-532: `font-size:1rem; line-height:1` → 1rem). Lupa
 * (`background-image`) NIE dokłada się do tej wysokości w ogóle —
 * background-image nigdy nie uczestniczy w obliczeniach box modelu/line-boxa,
 * niezależnie od jego `background-size`.
 *
 * Oba przyciski mają DOKŁADNIE te same wartości (padding `.75rem` pionowo,
 * `font-size:1rem`, `line-height:1`, `border` 1px) — na papierze więc
 * powinny wychodzić tej samej wysokości co input. W praktyce jednak TEN
 * przycisk ma dodatkowo prawdziwy element `<img class="dwnld">` PO tekście
 * (nie background-image) — a to zupełnie inna sytuacja: obraz inline
 * (`display:inline-block`, `height:1rem`, `margin-bottom:-1.5px`,
 * nowymobilet.css:5113-5121) UCZESTNICZY w normalnym layoutcie inline/line-
 * box razem z tekstem. Przy domyślnym `vertical-align:baseline` przeglądarka
 * wyznacza wysokość linii jako sumę NAJWIĘKSZEGO wystania nad baseline
 * (ascent) i NAJWIĘKSZEGO wystania pod baseline (descent) spośród WSZYSTKICH
 * elementów inline w linii — jeśli geometria ikony (1rem wysokości,
 * zaczepionej marginesem -1.5px o baseline) wystaje pod/nad baseline
 * bardziej niż metryki czcionki tekstu przy `line-height:1`, cała linia (a
 * z nią cały przycisk) renderuje się WYŻSZA niż przycisk bez ikony i niż
 * input — mimo identycznych `padding`/`font-size`/`line-height` w CSS.
 * `display:inline-block` (poprzednia wartość) nie ma żadnego mechanizmu,
 * który by temu zapobiegł — to nieodłączna cecha inline layoutu.
 *
 * NAPRAWA (CZĘŚCIOWA — patrz SUPERSEDED niżej): `display:inline-block` →
 * `inline-flex` + `align-items:center` (na OBU przyciskach, patrz też
 * `.mega-menu__all-link.button` wyżej) — we flex layoutcie wysokość
 * (cross-size) kontenera to `max()` z wysokości poszczególnych flex-itemów
 * liczonych z ICH WŁASNEGO content+padding+border+margin, całkowicie BEZ
 * udziału baseline/ascent/descent tekstu (`align-items:baseline` świadomie
 * NIE użyty). Tekst "Pobierz aplikację" staje się anonimowym flex-itemem o
 * wysokości `1rem` (z `line-height:1`), `<img class="dwnld">` —
 * flex-itemem o wysokości `1rem + (-1.5px marginesu)` ≈ 14.5px, czyli
 * WCIĄŻ mniej niż tekst — `max(1rem, ~14.5px)` = `1rem`, na papierze
 * dokładnie tyle, ile daje sam tekst i dokładnie tyle, ile daje input.
 * `justify-content:center` dodany, bo flex ignoruje dziedziczone
 * `text-align:center` (z bazowego `.button`, nowymobilet.css:1042), które
 * poziomo centrowało treść tylko w modelu inline-block.
 *
 * SUPERSEDED 2026-09-05, drugi raz — mimo poprawnej matematyki wyżej,
 * zrzut ekranu z żywego podglądu pokazał, że OBA przyciski (nie tylko ten
 * z ikoną) nadal renderują się wyżej niż `.mega-menu__search-input`.
 * Wniosek: auto-wysokość `<input>` (wewnętrzny, częściowo niezależny od
 * `line-height` mechanizm centrowania tekstu w polu formularza) i
 * auto-wysokość zwykłego `<a>` liczona z line-boxa NIE są gwarantowane
 * dać identyczny wynik nawet przy identycznym CSS — to zależy od
 * przeglądarki. `inline-flex`/`align-items:center` zostają (nadal
 * potrzebne do poziomego/pionowego centrowania treści WEWNĄTRZ przycisku
 * i do poprawnej wysokości WZGLĘDEM SIEBIE obu przycisków), ale o
 * faktycznej wysokości względem inputu decyduje teraz jawny, dzielony
 * `height: var(--mm-control-height)` + `box-sizing: border-box` (patrz
 * `.mega-menu__top-row` wyżej i `.mega-menu__search-input` niżej) —
 * odporne na to, JAK dana przeglądarka liczy line-box, bo w ogóle
 * przestaje być używany do wyznaczania wysokości.
 *
 * POPRAWKA 2026-09-05 — `display` dostaje `!important`, ten sam powód i to
 * samo odkrycie co przy `.mega-menu__all-link.button` wyżej: `#main-menu a`
 * (nowymobilet.css:3928-3932, specyficzność ID (1,0,1)) narzuca temu `<a>`
 * `display:inline-block`, bijąc naszą regułę (0,3,0: trzy klasy) bez
 * `!important`. To realny, potwierdzony (nie tylko podejrzewany) powód, dla
 * którego opisane wyżej "SUPERSEDED" podejścia oparte na samym
 * `inline-flex` zawodziły — `align-items:center` nigdy faktycznie nie
 * obowiązywał, niezależnie od dobranych wartości padding/font-size.
 */
.mega-menu__top-row .button.mega-menu__download-btn {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: auto;
	height: var(--mm-control-height);
	box-sizing: border-box;
	margin: 0;
	padding: .75rem 1.5rem;
	font-size: 1rem;
	line-height: 1;
	background: var(--light);
	color: var(--black);
	border: solid 1px var(--light);
	border-radius: var(--radius);
	/* Zabezpieczenie — ikonka niżej (.mega-menu__download-btn-icon) "wylewa
	   się" przez ujemne marginesy w padding przycisku aż do wewnętrznej
	   krawędzi bordera; overflow:hidden gwarantuje, że nic nigdy nie
	   wystaje poza zaokrąglony kształt przycisku, niezależnie od
	   subpixelowego rozjazdu promienia ikony vs. przycisku (ten sam wzorzec
	   co overflow:hidden na .mega-menu__news-card niżej w tym pliku). */
	overflow: hidden;
	justify-self: end;
	white-space: nowrap;
}

.mega-menu__top-row .button.mega-menu__download-btn:hover {
	background: var(--white);

}

/*
 * Ikonka aplikacji w .mega-menu__download-btn (2026-09-06) — na życzenie:
 * wyrównana do prawej krawędzi przycisku, bez marginesu, pełna wysokość i
 * te same zaokrąglenia narożników co sam przycisk.
 *
 * Mechanizm: flex layout liczy dostępną przestrzeń dla flex-itemów z
 * CONTENT-boxa kontenera, czyli już PO odjęciu paddingu — samo
 * `align-self:stretch` dałoby więc ikonie wysokość mniejszą niż cały
 * przycisk (bez paddingu pionowego). Ujemne marginesy dokładnie równe
 * paddingowi przycisku ("wyrównanie ujemnym marginesem", własna sugestia)
 * przesuwają wizualny box ikony z powrotem w ten padding: `margin-top`/
 * `-bottom: -.75rem` (= `padding` pionowy przycisku) rozciąga ikonę do
 * pełnej wysokości aż do wewnętrznej krawędzi bordera, `margin-right:
 * -1.5rem` (= `padding-right` przycisku) dosuwa ją do prawej krawędzi bez
 * odstępu. `margin-left:.75rem` to jedyny "prawdziwy" margines — czysto
 * wizualny odstęp od tekstu etykiety, nie ma nic do zrównoważenia.
 * `aspect-ratio:1/1` + `width:auto` liczy szerokość z tak wyznaczonej
 * wysokości, więc ikona zawsze wychodzi kwadratowa niezależnie od
 * `--mm-control-height`. `border-radius` na PRAWYCH rogach = `var(--radius)`,
 * ta sama zmienna co promień przycisku (bazowy `.button`, nowymobilet.css)
 * — geometrycznie zgodne zaokrąglenie; lewe rogi celowo bez promienia
 * (stykają się z tekstem, nie z krawędzią przycisku). `overflow:hidden` na
 * przycisku wyżej to dodatkowy bezpiecznik na wypadek rozjazdu
 * subpixelowego.
 *
 * PLACEHOLDER: `images/app-icon-placeholder.svg` (kwadratowa grafika
 * zastępcza) — do podmiany na docelową ikonę aplikacji Mobilet.
 *
 * Nie zweryfikowane w żywej przeglądarce w sesji, w której powstało — do
 * sprawdzenia po wgraniu.
 */
.mega-menu__download-btn-icon {
	align-self: stretch;
	aspect-ratio: 1 / 1;
	width: auto;
	margin: -.75rem -1.5rem -.75rem 1rem;
	object-fit: cover;
	border-radius: 0 var(--radius) var(--radius) 0;
}