/* =========================================================================
   KVLT Magazine 2025 — arkusz glowny
   Mobile-first. Dark mode domyslny, light jako rownorzedny.
   Akcent: karmazyn #C8102E na bazie grafitowej.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Tokeny motywu
   ------------------------------------------------------------------------- */

:root {
	--kvlt-accent: #C8102E;
	--kvlt-accent-hover: #E11836;
	--kvlt-accent-contrast: #FFFFFF;

	--kvlt-font-display: "Fira Sans", "Helvetica Neue", Arial, sans-serif;
	--kvlt-font-body: Manrope, "Segoe UI", system-ui, -apple-system, sans-serif;

	--kvlt-wide: 1360px;
	/* Margines boczny calego serwisu. Jeden token — uzywaja go naglowek,
	   uklad tresci, pasek nawigacji i stopka, wiec wszystko trzyma sie
	   wspolnej linii.
	   Na telefonie bylo 1rem (16 px) i tekst z obrazkami siedzial zbyt blisko
	   krawedzi ekranu; 1,25rem (20 px) daje oddech, a nadal zostawia
	   350 px tresci na 390-pikselowym ekranie. */
	--kvlt-gutter: 1.25rem;
	--kvlt-aside: 300px;
	--kvlt-radius: 4px;
	--kvlt-header-h: 60px;

	--kvlt-transition: 160ms ease;
}

@media (min-width: 48em) {
	:root {
		--kvlt-gutter: 1.5rem;
		/* Zapas na tagline, ktory od tej szerokosci jest pozycjonowany
		   absolutnie pod logo (patrz `.kvlt-logo__tagline`) i nie powieksza
		   juz paska sam z siebie. */
		--kvlt-header-h: 92px;
	}
}

/* Ciemny — domyslny */
:root,
:root[data-theme="dark"] {
	--kvlt-bg: #0E0F11;
	--kvlt-surface: #17191C;
	--kvlt-surface-2: #202327;
	--kvlt-line: #2C3034;
	/* Mocniejsza linia do OBRAMOWAN ELEMENTOW INTERAKCYJNYCH. Zwykle
	   `--kvlt-line` (#2C3034) daje na powierzchni panelu ~1,4:1 — w sam raz na
	   delikatny separator, za malo na granice przycisku. WCAG 1.4.11 wymaga dla
	   nich 3:1. Wersja jasna tego tokenu jest w bloku `[data-theme="light"]`. */
	--kvlt-line-strong: #6E757D;
	--kvlt-text: #ECEDEF;
	--kvlt-muted: #9AA0A6;
	/* Metadane (data, licznik odwiedzin) — jasniejsze niz zwykly tekst
	   przygaszony, bo sa male (11-12 px) i musza byc pewnie czytelne.
	   Kontrast wzgledem tla: ~9,6:1 (WCAG AAA). */
	--kvlt-meta: #B4BAC0;
	/* Karmazyn W TEKSCIE (linki, „Więcej →", nazwy kategorii).
	   Bazowy #C8102E daje na ciemnym tle tylko **3,25:1** — audyt axe-core
	   oflagowal to jako naruszenie AA (maly tekst wymaga 4,5:1). Ten wariant
	   ma 5,41:1 na tle strony i 4,97:1 na powierzchni, a nadal czyta sie jako
	   ten sam karmazyn. Do PLAM koloru (tla, paski, obwodki) uzywamy dalej
	   `--kvlt-accent` — tam kontrast tekstu nie obowiazuje. */
	--kvlt-accent-text: #F4485C;
	/* Hover musi byc jasniejszy od stanu bazowego I nadal spelniac AA —
	   bazowy `--kvlt-accent-hover` (#E11836) ma na ciemnym tylko 4,00:1. */
	--kvlt-accent-text-hover: #FF7A85;
	--kvlt-header-bg: rgba(14, 15, 17, 0.92);
	--kvlt-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
	--kvlt-img-empty: linear-gradient(135deg, #202327, #17191C);
	color-scheme: dark;
}

:root[data-theme="light"] {
	--kvlt-bg: #FFFFFF;
	--kvlt-surface: #FFFFFF;
	--kvlt-surface-2: #F2F3F5;
	--kvlt-line: #E2E4E7;
	/* Mocniejsza linia do OBRAMOWAN ELEMENTOW INTERAKCYJNYCH. Zwykle
	   `--kvlt-line` (#E2E4E7) daje na bieli ~1,2:1 — dobre do delikatnych
	   separatorow, ale za slabe na granice przycisku. WCAG 1.4.11 wymaga dla
	   nich 3:1; ta wartosc trzyma prog, nie robiac z ikony ciezkiej ramki.
	   (Pierwsze podejscie #949AA2 dawalo 2,84 — pomiar zlapal, ze o wlos za
	   malo, stad ciemniejszy odcien.) */
	--kvlt-line-strong: #8A9099;
	--kvlt-text: #14161A;
	--kvlt-muted: #5F6570;
	/* W trybie jasnym metadane sa ciemniejsze niz tekst przygaszony
	   — kontrast ~7,9:1 (WCAG AAA). */
	--kvlt-meta: #4A505A;
	/* W trybie jasnym bazowy karmazyn ma na bieli 5,88:1 — spelnia AA,
	   wiec nie ma po co go zmieniac. */
	--kvlt-accent-text: #C8102E;
	--kvlt-accent-text-hover: #E11836;
	--kvlt-header-bg: rgba(255, 255, 255, 0.94);
	--kvlt-shadow: 0 8px 24px rgba(20, 22, 26, 0.12);
	--kvlt-img-empty: linear-gradient(135deg, #E8EAED, #F5F6F7);
	color-scheme: light;
}

/* -------------------------------------------------------------------------
   2. Reset i podstawy
   ------------------------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body.kvlt {
	margin: 0;
	background: var(--kvlt-bg);
	color: var(--kvlt-text);
	font-family: var(--kvlt-font-body);
	font-size: 1rem;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
	transition: background-color var(--kvlt-transition), color var(--kvlt-transition);
}

.kvlt img,
.kvlt video {
	max-width: 100%;
	height: auto;
}

/* ⚠️ IFRAME: TYLKO ograniczenie szerokosci — bez `height: auto`.
   Iframe jest elementem zastepowanym BEZ wymiarow wlasnych, wiec `height: auto`
   NIE bierze wartosci z atrybutu `height`, tylko spada do specyfikacyjnych
   150 px. Wczesniejsza wspolna regula dla img/video/iframe sprawiala, ze KAZDY
   embed w tresci renderowal sie na 150 px — niezaleznie od tego, ze w tresci
   stoi np. `height="500"`. Zmierzone: attrH="500" -> renderH=150.

   `display: block` — bez tego iframe jest elementem INLINE i siada na linii
   bazowej tekstu (`vertical-align: baseline`), przez co line-box rezerwuje pod
   nim miejsce na znaki schodzace ponizej linii (descender) = kilka-kilkanascie
   px bialego odstepu pod embedem. Block eliminuje ten baseline-gap. */
.kvlt iframe {
	max-width: 100%;
	display: block;
}

/* Odstep NAD embedem w tresci wpisu.
   Embedy siedza w akapicie-owijce (`<p>`), wiec jedyny odstep, jaki dostawaly,
   pochodzil z jego marginesu — zmierzone **18,7 px**. Przy odtwarzaczach wysokich
   na 472-500 px (Bandcamp, Spotify) i 547 px (YouTube) to za malo: embed wygladal
   na doklejony do poprzedzajacego tekstu. Sam iframe ma `margin-top: 0`.

   Dokladamy 1rem — razem ~35 px. Dolnego odstepu nie ruszamy, bo akapit daje
   juz 17 px, a pod embedem zwykle zaczyna sie nowy naglowek z wlasnym marginesem. */
.kvlt-single__content iframe {
	margin-top: 1rem;
}

/* Wyjatek: embed w panelu oceny recenzji. Jego owijka `.kvlt-review-panel__embed`
   ma wlasne `margin-top: 1.25rem`, a panel jest czescia `.kvlt-single__content`,
   wiec bez tego zerowania odstepy by sie sumowaly. */
.kvlt-single__content .kvlt-review-panel__embed iframe {
	margin-top: 0;
}

/* WIDEO — proporcja 16:9 zamiast sztywnej wysokosci.
   Sztywne `height` nie dziala dobrze, bo szerokosc kolumny tresci zmienia sie
   od ~350 px (telefon) do ~970 px (desktop): jedna wartosc byla by na telefonie
   za wysoka (kadr prawie kwadratowy), a na desktopie za niska. `aspect-ratio`
   daje wlasciwe proporcje na kazdej szerokosci — 970 px -> 546 px, 350 px -> 197 px.

   ⚠️ Celowo NIE obejmujemy Bandcampa i Spotify: to odtwarzacze AUDIO, wysokie
   na 250-400 px z zalozenia. Wymuszenie 16:9 rozdelo by je do absurdu.
   (Bandcamp trzyma wysokosc w stylu inline, wiec i tak nie byl dotkniety bugiem.) */
.kvlt iframe[src*="youtube.com/embed"],
.kvlt iframe[src*="youtube-nocookie.com/embed"],
.kvlt iframe[src*="youtu.be/"],
.kvlt iframe[src*="player.vimeo.com"] {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
}

/* SPOTIFY — wymuszona wysokosc playera.
   Wklejane embedy maja `height="350"`, przy ktorym player renderowal sie w
   wersji kompaktowej ~152 px, a nadmiarowe ~200 px to bylo puste, BIALE tlo
   dokumentu iframe pod playerem (render Spotify, cross-origin, poza zasiegiem
   CSS motywu). Przy JAWNIE narzuconej wysokosci Spotify interpretuje ja
   poprawnie i rozklada pelny player (okladka + lista utworow) na cala
   wysokosc — bez bialego pustostanu. Ustawiamy 500 px. Regula obejmuje
   wylacznie iframe z trescia Spotify. */
.kvlt iframe[src*="open.spotify.com/embed"],
.kvlt iframe[src*="spotify.com/embed"] {
	height: 500px;
}

/* BANDCAMP — ograniczenie szerokosci do natywnej szerokosci odtwarzacza.
   Ten sam problem co przy Spotify, tylko w POZIOMIE: kod embedu Bandcampa
   wkleja `style="width: 100%"`, ale odtwarzacz `size=large` renderuje sie na
   STALE ~700 px. W kolumnie tresci (972 px na desktopie) zostawialo to ~270 px
   pustego, BIALEGO tla dokumentu iframe — widoczne tylko na ciemnym motywie.
   Zmierzone: iframe 972 px, odtwarzacz ~700 px.

   Selektor po `data-kvlt-bc-src`, nie po `src`: inc/bandcamp.php przenosi tam
   adres, wiec do czasu podmiany przez JS iframe NIE MA atrybutu `src`.
   Ponizej 700 px `max-width` nie dziala, wiec na telefonie ramka nadal
   wypelnia szerokosc kolumny.

   `margin-inline: auto` — skoro ramke domykamy do 700 px (natywnej szerokosci
   odtwarzacza), w szerszej kolumnie tresci (~890-970 px) blokowy iframe
   dosuwalby sie do LEWEJ. Auto-marginesy centruja go w kolumnie. */
.kvlt iframe[data-kvlt-bc-src],
.kvlt iframe[src*="bandcamp.com/EmbeddedPlayer"] {
	width: 100%;
	/* min(100%, 700px): na desktopie domyka do 700 px (natywna szerokosc
	   odtwarzacza), a na telefonie do szerokosci kolumny — bez wyjscia poza
	   ekran nawet dla starych embedow z inline `width: 800px`. */
	max-width: min(100%, 700px);
	margin-inline: auto;

	/* Bandcamp `size=large` KLAMRUJE ciemne `bgcol` do stalego szarego dna
	   (~#2b2b2b) i ma stale kolory tekstu — nie da sie tego sciemnic parametrem
	   embedu (sprawdzone: bgcol 0e0f11 == 000000, ten sam render). Zamiast tego
	   podbijamy kontrast calego iframe filtrem: szary panel wizualnie ciemnieje,
	   a jasny tekst utworow jasnieje -> lepsza czytelnosc na ciemnym motywie.
	   Na jasnym motywie player jest bialy z czarnym tekstem — tam filtr zdejmujemy. */
	filter: contrast(1.2);
}

:root[data-theme="light"] .kvlt iframe[data-kvlt-bc-src],
:root[data-theme="light"] .kvlt iframe[src*="bandcamp.com/EmbeddedPlayer"] {
	filter: none;
}

/* Linki uzywaja wariantu akcentu przeznaczonego DO TEKSTU — bazowy #C8102E
   nie spelnia AA na ciemnym tle (3,25:1 przy wymaganych 4,5:1). */
.kvlt a {
	color: var(--kvlt-accent-text);
	text-decoration: none;
}

.kvlt a:hover,
.kvlt a:focus-visible {
	color: var(--kvlt-accent-text-hover);
	text-decoration: underline;
}

.kvlt h1,
.kvlt h2,
.kvlt h3,
.kvlt h4 {
	font-family: var(--kvlt-font-display);
	font-weight: 800;
	line-height: 1.12;
	letter-spacing: -0.015em;
	margin: 0 0 0.5em;
	text-wrap: balance;
}

.kvlt :focus-visible {
	outline: 2px solid var(--kvlt-accent);
	outline-offset: 2px;
	border-radius: 2px;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

.kvlt-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 200;
	padding: 0.75rem 1.25rem;
	background: var(--kvlt-accent);
	color: var(--kvlt-accent-contrast);
	font-weight: 700;
}

.kvlt-skip-link:focus {
	left: 0;
	color: var(--kvlt-accent-contrast);
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	.kvlt *,
	.kvlt *::before,
	.kvlt *::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* -------------------------------------------------------------------------
   3. Naglowek
   ------------------------------------------------------------------------- */

.kvlt-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--kvlt-header-bg);
	backdrop-filter: saturate(140%) blur(10px);
	border-bottom: 1px solid var(--kvlt-line);
}

.kvlt-header__bar {
	position: relative; /* kotwica dla wysrodkowanego tagline (patrz .kvlt-logo__tagline) */
	display: flex;
	align-items: center;
	gap: 0.5rem;
	max-width: var(--kvlt-wide);
	min-height: var(--kvlt-header-h);
	margin: 0 auto;
	padding: 0 var(--kvlt-gutter);
}

/* Logo typograficzne — dziala w obu trybach, bez pliku graficznego */
.kvlt-logo {
	/* Bez `position: relative` — tagline kotwiczymy teraz do calego paska
	   (.kvlt-header__bar), zeby wysrodkowac go w poziomie, a nie do logo. */
	flex: none;
	margin: 0;
	font-size: 1rem;
	line-height: 1;
}

.kvlt .kvlt-logo__link {
	display: flex;
	flex-direction: column;
	gap: 2px;
	text-decoration: none;
}

.kvlt .kvlt-logo__link:hover,
.kvlt .kvlt-logo__link:focus-visible {
	text-decoration: none;
}

/* Logo = ORYGINALNA grafika „kvlt" (headlink.png ze starego motywu — biala
   litera na przezroczystym tle). Font 1:1 jak na produkcji. Tekst „kvlt"
   zostaje w HTML (SEO/czytniki), ale jest ukryty — widac obrazek.
   Technika: PNG jako MASKA + `background-color` -> mozna nadac DOWOLNY kolor.
   Baza = kolor tekstu motywu (biale w dark / ciemne w light), hover = karmazyn
   (jak w tekstowym logo). */
.kvlt-logo__mark {
	display: block;
	width: 66px;
	height: 46px;
	max-width: 46vw;
	background-color: var(--kvlt-text);
	-webkit-mask: url("../images/logo.png") left center / contain no-repeat;
	mask: url("../images/logo.png") left center / contain no-repeat;
	/* ukrycie tekstu (image replacement) */
	overflow: hidden;
	text-indent: -110%;
	white-space: nowrap;
	transition: background-color var(--kvlt-transition);
}

@media (min-width: 48em) {
	.kvlt-logo__mark {
		width: 83px;
		height: 58px;
	}
}

/* Hover/fokus — karmazyn, jak w tekstowym logo. */
.kvlt .kvlt-logo__link:hover .kvlt-logo__mark,
.kvlt .kvlt-logo__link:focus-visible .kvlt-logo__mark {
	background-color: var(--kvlt-accent-hover);
}

/* Dark Reader zaciemnia strone niezaleznie od naszego trybu. W trybie jasnym
   logo ma ciemny kolor -> bylby niewidoczny na zaciemnionym tle. Gdy JS wykryje
   wtyczke, wymuszamy jasny kolor (hover na karmazyn dalej dziala — wyzsza specyf.). */
html[data-kvlt-darkreader] .kvlt-logo__mark {
	background-color: #ECEDEF;
}

.kvlt-logo__tagline {
	display: none;
	font-size: 0.6875rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--kvlt-muted);
	margin-bottom: 5px;
}

/* Tagline WYJETY Z UKLADU (position: absolute) i WYSRODKOWANY w poziomie.
   Jako element w toku rozpychal blok logo na pol naglowka i odpychal przelacznik
   jezyka; absolutne pozycjonowanie tego unika. Kotwica to caly pasek
   (.kvlt-header__bar, position: relative), wiec `left: 50% + translateX(-50%)`
   centruje tekst wzgledem strony, a nie wzgledem logo. W pionie siedzi przy
   DOLE paska (--kvlt-header-h ma zapas na te jedna linie pod logo). Na mobilce
   tagline jest ukryty. */
@media (min-width: 48em) {
	.kvlt-logo__tagline {
		display: block;
		position: absolute;
		bottom: 0.4rem;
		left: 50%;
		transform: translateX(-50%);
		margin-bottom: 0;
		white-space: nowrap;
		text-align: center;
	}
}

/* TYMCZASOWO UKRYTY tagline — atrybut `hidden` w header.php. Reguła jest
   potrzebna, bo media query wyzej ustawia `display: block` i nadpisuje domyslne
   dzialanie `hidden`. Zeby przywrocic napis: usun `hidden` z <span> w header.php
   (mozna tez skasowac ten blok). */
.kvlt-logo__tagline[hidden] {
	display: none;
}

.kvlt-header__tools {
	display: flex;
	align-items: center;
	gap: 0.25rem;
	margin-left: auto;
}

/* Przycisk ikonowy — wspolna baza */
.kvlt-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: var(--kvlt-radius);
	background: transparent;
	color: var(--kvlt-text);
	cursor: pointer;
	transition: background-color var(--kvlt-transition), color var(--kvlt-transition);
}

.kvlt-iconbtn:hover,
.kvlt-iconbtn:focus-visible {
	background: var(--kvlt-surface-2);
	color: var(--kvlt-accent);
	text-decoration: none;
}

.kvlt-icon {
	width: 20px;
	height: 20px;
	fill: currentColor;
	display: block;
}

/* Lupka na JASNYM motywie: cienki wypelniony pierscien slabo czyta sie na bieli
   (cienka ciemna kreska "gubi sie" przez antyaliasing mocniej niz biala na czerni
   — dlatego ciemny motyw zostaje bez zmian). Dokladamy obrys tym samym kolorem,
   co pogrubia pierscien i raczke, nie zmieniajac ksztaltu ani koloru. */
:root[data-theme="light"] .kvlt-search-toggle .kvlt-icon--search {
	stroke: currentColor;
	stroke-width: 0.9;
	stroke-linejoin: round;
	stroke-linecap: round;
}

/* Social — na mobile ukryte (wracaja w szufladzie menu) */
.kvlt-social {
	display: none;
	align-items: center;
	gap: 0;
	margin: 0 0.25rem 0 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 62em) {
	.kvlt-social {
		display: flex;
	}
}

.kvlt-social__link .kvlt-icon {
	width: 18px;
	height: 18px;
}

/* Przelacznik trybu — pokazuje ikone trybu, ktory wlaczy */
.kvlt-theme-toggle .kvlt-icon--sun {
	display: block;
}

.kvlt-theme-toggle .kvlt-icon--moon {
	display: none;
}

:root[data-theme="light"] .kvlt-theme-toggle .kvlt-icon--sun {
	display: none;
}

:root[data-theme="light"] .kvlt-theme-toggle .kvlt-icon--moon {
	display: block;
}

/* -------------------------------------------------------------------------
   3b. Przelacznik jezyka — LEWA strona naglowka
   -------------------------------------------------------------------------
   Uklad wg briefu: jezyk po lewej, ikony social po prawej. Kontrolka pokazuje
   BIEZACY jezyk (flaga + kod), zeby czytelnik od razu wiedzial, w czym oglada
   strone; lista rozwija sie jako panel z flagami i pelnymi nazwami.
   ------------------------------------------------------------------------- */

.kvlt-lang {
	position: relative;
	margin-left: 0.5rem;
	flex: none;
}

.kvlt-lang__toggle {
	width: auto;
	gap: 0.3rem;
	padding: 0 0.4rem;
}

.kvlt-lang__current {
	font-family: var(--kvlt-font-display);
	font-size: 0.75rem;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.kvlt-lang__toggle .kvlt-icon--chevron {
	width: 14px;
	height: 14px;
	opacity: 0.7;
	transition: transform var(--kvlt-transition);
}

.kvlt-lang__toggle[aria-expanded="true"] .kvlt-icon--chevron {
	transform: rotate(180deg);
}

/* Na waskich ekranach kod jezyka wystarcza — globus zabiera miejsce menu. */
@media (max-width: 26em) {
	.kvlt-lang__toggle .kvlt-icon--globe {
		display: none;
	}
}

.kvlt-lang__panel {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	z-index: 120;
	min-width: 220px;
	padding: 0.5rem;
	background: var(--kvlt-surface);
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	box-shadow: var(--kvlt-shadow);
}

.kvlt-lang__panel[hidden] {
	display: none;
}

.kvlt-lang__label {
	margin: 0.15rem 0.5rem 0.5rem;
	font-family: var(--kvlt-font-display);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--kvlt-muted);
}

.kvlt-lang__note {
	margin: 0.5rem 0.5rem 0.15rem;
	padding-top: 0.5rem;
	border-top: 1px solid var(--kvlt-line);
	font-size: 0.6875rem;
	line-height: 1.4;
	color: var(--kvlt-muted);
}

/* Lista jezykow — markup pochodzi z GTranslate (`.glink` = flaga + nazwa),
   bo tylko wtedy skrypt wtyczki poprawnie podpina przelaczanie. */
.kvlt-lang__list .gtranslate_wrapper,
.kvlt-lang__list [class^="gt_container"] {
	display: flex;
	flex-direction: column;
	gap: 1px;
}

.kvlt-lang__list .glink {
	display: flex !important;
	align-items: center;
	gap: 0.55rem;
	padding: 0.45rem 0.5rem;
	border-radius: var(--kvlt-radius);
	color: var(--kvlt-text) !important;
	font-size: 0.875rem;
	line-height: 1.2;
	text-decoration: none !important;
	transition: background-color var(--kvlt-transition), color var(--kvlt-transition);
}

.kvlt-lang__list .glink:hover,
.kvlt-lang__list .glink:focus-visible {
	background: var(--kvlt-surface-2);
	color: var(--kvlt-accent) !important;
}

.kvlt-lang__list .glink img {
	flex: none;
	width: 20px;
	height: 20px;
	border-radius: 2px;
}

/* Aktualnie wybrany jezyk — wtyczka oznacza go klasa `gt-current-lang`. */
.kvlt-lang__list .glink.gt-current-lang {
	background: var(--kvlt-surface-2);
	font-weight: 700;
}

.kvlt-lang__list .glink.gt-current-lang::after {
	content: "";
	margin-left: auto;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--kvlt-accent);
}

/* Hamburger — tylko mobile */
.kvlt-header__burger {
	margin-left: -0.5rem;
}

@media (min-width: 62em) {
	.kvlt-header__burger {
		display: none;
	}
}

/* -------------------------------------------------------------------------
   4. Menu glowne
   ------------------------------------------------------------------------- */

.kvlt-nav {
	display: none;
	border-top: 1px solid var(--kvlt-line);
	background: var(--kvlt-surface);
}

.kvlt-nav.is-open {
	display: block;
}

@media (min-width: 62em) {
	.kvlt-nav {
		display: block;
		background: transparent;
	}
}

/* Mobilna szuflada menu przewija sie samodzielnie.
   .kvlt-nav siedzi w SRODKU sticky headera; przy dlugim menu (albo niskim
   ekranie / telefonie w poziomie) dolne pozycje wypadaly pod krawedz ekranu, a
   ze header jest przypiety do gory — nie dalo sie do nich doscrollowac.
   Ograniczamy wysokosc szuflady do reszty ekranu pod paskiem i dajemy jej
   wlasne przewijanie. `100dvh` uwzglednia znikajacy pasek adresu na mobile;
   `100vh` zostaje jako fallback dla starszych przegladarek. */
@media (max-width: 61.99em) {
	.kvlt-nav.is-open {
		max-height: calc(100vh - var(--kvlt-header-h));
		max-height: calc(100dvh - var(--kvlt-header-h));
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		overscroll-behavior: contain;
	}
}

.kvlt-menu,
.kvlt-menu ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.kvlt-menu {
	max-width: var(--kvlt-wide);
	margin: 0 auto;
	padding: 0.5rem var(--kvlt-gutter) 1rem;
}

@media (min-width: 62em) {
	.kvlt-menu {
		display: flex;
		flex-wrap: wrap;
		gap: 0.25rem;
		padding: 0 var(--kvlt-gutter);
	}
}

.kvlt-menu a {
	display: block;
	padding: 0.6rem 0.75rem;
	color: var(--kvlt-text);
	font-family: var(--kvlt-font-display);
	font-weight: 700;
	font-size: 0.9375rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	border-radius: var(--kvlt-radius);
}

.kvlt-menu a:hover,
.kvlt-menu a:focus-visible {
	color: var(--kvlt-accent);
	background: var(--kvlt-surface-2);
	text-decoration: none;
}

.kvlt-menu .current-menu-item > a,
.kvlt-menu .current-menu-ancestor > a,
.kvlt-menu .current-menu-parent > a {
	color: var(--kvlt-accent);
	box-shadow: inset 0 -3px 0 var(--kvlt-accent);
}

/* Poziom 2 — na mobile wciecie, na desktopie rozwijane */
.kvlt-menu .sub-menu a {
	padding-left: 1.75rem;
	font-weight: 500;
	text-transform: none;
	letter-spacing: 0;
	color: var(--kvlt-muted);
}

@media (min-width: 62em) {
	.kvlt-menu > li {
		position: relative;
	}

	.kvlt-menu .sub-menu {
		position: absolute;
		top: 100%;
		left: 0;
		z-index: 110;
		min-width: 200px;
		padding: 0.375rem;
		background: var(--kvlt-surface);
		border: 1px solid var(--kvlt-line);
		border-radius: var(--kvlt-radius);
		box-shadow: var(--kvlt-shadow);
		opacity: 0;
		visibility: hidden;
		transform: translateY(4px);
		transition: opacity var(--kvlt-transition), transform var(--kvlt-transition), visibility var(--kvlt-transition);
	}

	.kvlt-menu > li:hover > .sub-menu,
	.kvlt-menu > li:focus-within > .sub-menu {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}

	.kvlt-menu .sub-menu a {
		padding: 0.5rem 0.625rem;
		font-size: 0.875rem;
	}
}

.kvlt-nav__empty {
	max-width: var(--kvlt-wide);
	margin: 0 auto;
	padding: 0.75rem var(--kvlt-gutter);
	color: var(--kvlt-muted);
	font-size: 0.875rem;
}

/* -------------------------------------------------------------------------
   5. Wyszukiwarka
   ------------------------------------------------------------------------- */

.kvlt-searchpanel {
	border-top: 1px solid var(--kvlt-line);
	background: var(--kvlt-surface);
}

.kvlt-searchpanel[hidden] {
	display: none;
}

.kvlt-searchpanel__inner {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	max-width: var(--kvlt-wide);
	margin: 0 auto;
	padding: 0.75rem var(--kvlt-gutter);
}

.kvlt-searchform {
	display: flex;
	flex: 1;
	align-items: center;
	gap: 0.5rem;
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-bg);
	padding: 0 0.25rem 0 0.75rem;
}

.kvlt-searchform:focus-within {
	border-color: var(--kvlt-accent);
}

.kvlt-searchform__input {
	flex: 1;
	min-width: 0;
	padding: 0.65rem 0;
	border: 0;
	background: transparent;
	color: var(--kvlt-text);
	font: inherit;
	font-size: 1rem;
}

.kvlt-searchform__input:focus {
	outline: none;
}

.kvlt-searchform__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 0;
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-accent);
	color: var(--kvlt-accent-contrast);
	cursor: pointer;
}

.kvlt-searchform__submit:hover {
	background: var(--kvlt-accent-hover);
}

/* -------------------------------------------------------------------------
   6. Uklad stron
   ------------------------------------------------------------------------- */

/* Stopka zawsze przy dolnej krawedzi okna („sticky footer").
   Na krotkich stronach (np. Bilety) stopka wisiala w polowie ekranu,
   bo tresc nie wypelniala widoku. `.kvlt-site` rozciaga sie na cala wysokosc
   okna, a `.kvlt-main` zabiera cala wolna przestrzen — stopka ladzie pod nim.
   `100dvh` uwzglednia chowajacy sie pasek adresu na mobile; `100vh` zostaje
   jako fallback dla starszych przegladarek. */
.kvlt-site {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
}

.kvlt-main {
	display: block;
	/* Bylo `min-height: 50vh` — proteza, ktora i tak nie dosuwala stopki do dolu
	   i psula proporcje na wysokich ekranach. Flex robi to dokladnie. */
	flex: 1 0 auto;
}

.kvlt-footer {
	flex: none;
}

.kvlt-layout {
	max-width: var(--kvlt-wide);
	margin: 0 auto;
	padding: 1.5rem var(--kvlt-gutter) 3rem;
}

@media (min-width: 62em) {
	.kvlt-layout--with-aside,
	.kvlt-layout--single {
		display: grid;
		grid-template-columns: minmax(0, 1fr) var(--kvlt-aside);
		gap: 2.5rem;
		align-items: start;
	}
}

/* Pojedynczy wpis — trzy kolumny (Language | tresc | reklama) TYLKO gdy lewa
   kolumna ma widgety (klasa .kvlt-layout--has-left z single.php). Gdy jej brak
   — a zwykle jest pusta — wpis zostaje przy DWOCH kolumnach z bloku 62em wyzej
   (tresc dosunieta do lewej + reklama), bez rezerwowania pustych 190px.
   W HTML kolejnosc to tresc → lewa → prawa (czytelnik na telefonie dostaje
   wpis od razu); tutaj przestawiamy je jawnie na siatce. */
@media (min-width: 75em) {
	.kvlt-layout--single.kvlt-layout--has-left {
		grid-template-columns: 190px minmax(0, 1fr) var(--kvlt-aside);
		gap: 2rem;
	}

	.kvlt-layout--single.kvlt-layout--has-left .kvlt-layout__main {
		grid-column: 2;
		grid-row: 1;
	}

	.kvlt-layout--single.kvlt-layout--has-left .kvlt-aside--left {
		grid-column: 1;
		grid-row: 1;
	}

	.kvlt-layout--single.kvlt-layout--has-left .kvlt-aside--right {
		grid-column: 3;
		grid-row: 1;
	}
}

/* Ponizej 75em lewa kolumna nie ma gdzie sie zmiescic obok reklamy 300 px —
   ladzie pod trescia, na pelnej szerokosci. */
.kvlt-aside--left {
	margin-top: 2rem;
}

@media (min-width: 62em) and (max-width: 74.99em) {
	.kvlt-layout--single.kvlt-layout--has-left .kvlt-aside--left {
		grid-column: 1 / -1;
		grid-row: 2;
	}
}

@media (min-width: 75em) {
	.kvlt-aside--left {
		margin-top: 0;
		position: sticky;
		top: calc(var(--kvlt-header-h) + 1rem);
	}
}

.kvlt-layout__main {
	min-width: 0;
}

.kvlt-aside {
	min-width: 0;
}

.kvlt-aside--right {
	margin-top: 2.5rem;
}

@media (min-width: 62em) {
	.kvlt-aside--right {
		margin-top: 0;
		position: sticky;
		top: calc(var(--kvlt-header-h) + 1rem);
	}
}

/* Baner reklamowy (SlideAnything) w prawej kolumnie STRONY GLOWNEJ — wyrownanie
   do slidera. Wtyczka owija obrazek w <p> z domyslnym marginesem 16px, przez co
   reklama startowala 16px NIZEJ niz slider. Zdejmujemy ten margines: gorna
   krawedz banera pokrywa sie z gora slidera, a naturalna wysokosc reklamy
   (300x600) sprowadza jej dol do linii pod naglowkiem „Newsy". Zawezone do
   .kvlt-home, wiec ten sam baner na pojedynczym wpisie zostaje bez zmian. */
.kvlt-home .kvlt-aside--right .sa_hover_container p {
	margin-top: 0;
	margin-bottom: 0;
}

/* MOBILE — spojne banery reklamowe w prawej kolumnie (pod trescia).
   Na desktopie kolumna ma dokladnie 300px, wiec sztywne banery (EMP 300px)
   pasuja idealnie. Po zejsciu ponizej 62em kolumna rozciaga sie na pelna
   szerokosc: karuzela SolidRock (SlideAnything) skaluje sie i wypelnia ja rowno,
   ale baner EMP to sztywny <img> 300px dosuniety do LEWEJ — zostawal z brzydka
   luka z boku i wygladal jak doklejony. Tutaj centrujemy plaskie widgety
   reklamowe i pozwalamy banerowi wypelnic szerokosc telefonu, zeby obie reklamy
   trzymaly te sama linie co siatka tresci. Cap 480px chroni zrodlo 300px przed
   nadmiernym powiekszeniem na szerokim tablecie. `.kvlt-reco` (blok redakcyjny)
   i AdSense (wlasna logika 300x600) zostaja nietkniete. */
@media (max-width: 61.99em) {
	.kvlt-home .kvlt-aside--right > .widget_text:not( .widget_custom_html ):not( .kvlt-reco ) {
		text-align: center;
	}

	.kvlt-home .kvlt-aside--right > .widget_text:not( .widget_custom_html ):not( .kvlt-reco ) a {
		display: block;
		max-width: 480px;
		margin-inline: auto;
	}

	.kvlt-home .kvlt-aside--right > .widget_text:not( .widget_custom_html ):not( .kvlt-reco ) img {
		width: 100%;
		height: auto;
	}
}

.kvlt-pagetitle {
	font-size: clamp(1.6rem, 5vw, 2.5rem);
	text-transform: uppercase;
	letter-spacing: 0.01em;
	margin-bottom: 0.25em;
}

.kvlt-pagetitle::after {
	content: "";
	display: block;
	width: 56px;
	height: 4px;
	margin-top: 0.5rem;
	background: var(--kvlt-accent);
}

.kvlt-pagetitle__query {
	color: var(--kvlt-accent);
}

.kvlt-archive-head {
	margin-bottom: 2rem;
}

.kvlt-archive-head__count,
.kvlt-archive-head__desc {
	color: var(--kvlt-muted);
	font-size: 0.9375rem;
}

.kvlt-archive-head__form {
	max-width: 460px;
	margin-top: 1rem;
}

.kvlt-empty {
	padding: 2rem 0;
	color: var(--kvlt-muted);
}

/* -------------------------------------------------------------------------
   7. Siatki i kafle
   ------------------------------------------------------------------------- */

.kvlt-grid {
	display: grid;
	gap: 1.25rem;
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 40em) {
	.kvlt-grid--wide {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.kvlt-grid--square {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

@media (min-width: 75em) {
	.kvlt-grid--wide {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.kvlt-grid--square {
		grid-template-columns: repeat(5, minmax(0, 1fr));
	}
}

.kvlt-card {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

/* Wyzsza specyficznosc niz `.kvlt a`, zeby tytul kafla mial kolor tekstu,
   a nie akcentu — akcent zostaje na hoverze. */
.kvlt .kvlt-card__link {
	display: block;
	color: var(--kvlt-text);
}

.kvlt .kvlt-card__link:hover,
.kvlt .kvlt-card__link:focus-visible {
	color: var(--kvlt-text);
	text-decoration: none;
}

.kvlt-card__media {
	position: relative;
	overflow: hidden;
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface-2);
	aspect-ratio: 16 / 9;
}

.kvlt-card--square .kvlt-card__media {
	aspect-ratio: 1 / 1;
}

.kvlt-card--portrait .kvlt-card__media {
	aspect-ratio: 2 / 3;
}

.kvlt-card--landscape .kvlt-card__media {
	aspect-ratio: 4 / 3;
}

/* Selektor `.kvlt .kvlt-card__img` (specyficznosc 0,2,0), a nie samo
   `.kvlt-card__img` (0,1,0): globalna reguła `.kvlt img { height: auto }`
   (0,1,1) inaczej WYGRYWA i kasuje `height:100%`, przez co obrazek renderuje
   sie w swoich naturalnych proporcjach zamiast wypelnic kadr — `object-fit`
   nie ma wtedy czego kadrowac i miniatury (zwlaszcza panoramy koncertowe w
   sekcji „Zdjecia") rozjezdzaja sie wysokoscia. Analogicznie do listingu
   kategorii (`.pt-cv-thumbnail` z width/height:100%). */
.kvlt .kvlt-card__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Kadrujemy lekko powyzej srodka: na zdjeciach koncertowych i fotkach
	   zespolow to tam sa twarze, srodek geometryczny lapie zwykle tulowia. */
	object-position: center 42%;
	transition: transform 300ms ease;
}

.kvlt-card__img--empty {
	background: var(--kvlt-img-empty);
}

/* Zoom miniatury TYLKO na urzadzeniach z myszatka (`hover: hover`). Bez tego na
   telefonie/tablecie tapniecie lub przewijanie palcem po kaflu wyzwala „przyklejony"
   stan :hover i miniatura zostaje powiekszona / miga — klasyczny problem animacji
   na mobile. */
@media (hover: hover) {
	.kvlt-card__link:hover .kvlt-card__img {
		transform: scale(1.04);
	}
}

/* Prefiks `.kvlt` (0,2,0), nie samo `.kvlt-card__title` (0,1,0): globalny reset
   naglowkow `.kvlt h1..h4 { margin:0 0 .5em }` (0,1,1) inaczej WYGRYWA i zeruje
   `margin-top`. Kafle kompaktowe maja wlasna regule 0,2,0, wiec i tak mialy odstep;
   niekompaktowe (Ksiazki, Relacje) traktowaly tytul tuz przy okladce — teraz maja
   ten sam oddech co reszta. */
.kvlt .kvlt-card__title {
	margin: 0.625rem 0 0.25rem;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: 0;
}

.kvlt .kvlt-card__link:hover .kvlt-card__title,
.kvlt .kvlt-card__link:focus-visible .kvlt-card__title {
	color: var(--kvlt-accent);
}

.kvlt-card__excerpt {
	margin: 0.25rem 0 0;
	color: var(--kvlt-muted);
	font-size: 0.875rem;
}

/* Linia metadanych: data + odslony */
.kvlt-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
	color: var(--kvlt-meta);
	font-size: 0.75rem;
	letter-spacing: 0.03em;
}

.kvlt-meta__views {
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
}

/* Autor w linii meta jest LINKIEM do archiwum autora — tego samego, co box
   autora pod wpisem. Ma jednak zostac czescia linii meta, a nie karmazynowym
   akcentem, wiec nadpisujemy `.kvlt a` (specyficznosc 0,2,1 bije 0,1,1).
   Klikalnosc sygnalizuje kropkowane podkreslenie: widoczne, ale nie krzyczy —
   przy 0.75rem pelne podkreslenie zlewaloby sie z tekstem. Kolor akcentu
   dopiero na hover/fokusie. */
.kvlt a.kvlt-meta__author {
	color: inherit;
	text-decoration: underline;
	text-decoration-style: dotted;
	text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
	text-underline-offset: 0.2em;
	transition: color 0.15s ease;
}

.kvlt a.kvlt-meta__author:hover,
.kvlt a.kvlt-meta__author:focus-visible {
	color: var(--kvlt-accent-text);
	text-decoration-style: solid;
	text-decoration-color: currentColor;
}

.kvlt-meta__views .kvlt-icon {
	width: 14px;
	height: 14px;
	opacity: 0.9;
}

/* Badge oceny na kaflu.
   Kafle recenzji to okladki plyt — dowolne, czesto jasne i kontrastowe
   grafiki. Zeby ocena byla zawsze czytelna, badge stosuje trzy zabezpieczenia:
   1. Tekst ZAWSZE bialy, oddzielony od tla miekkim cieniem (nie obwodka —
      twardy kontur przy 15 px i wadze 900 robil sie ciezki i „naklejkowy").
      Cien daje ten sam efekt czytelnosci na calej skali kolorow, a zostaje
      dyskretny. To standardowe rozwiazanie dla tekstu na kolorowym chipie;
      alternatywy (`-webkit-text-stroke`, `filter: drop-shadow`) albo zjadaja
      ksztalt glifu, albo rozmywaja rowniez tlo badge'a.
   2. Poswiata w KOLORZE OCENY (`--kvlt-badge-glow`), nie neutralnie czarna —
      badge „nalezy" do swojego koloru zamiast rzucac szary cien.
   3. Sila poswiaty rosnie z ocena (`--kvlt-badge-glow-size`, liczone w PHP
      przez kvlt_score_glow()): ponizej 5 praktycznie jej nie ma, przy 10
      siega 14 px. To ma byc lekki akcent na pozycje warte obejrzenia,
      nie halo. Kolory pochodza z tej samej mapy co pasek panelu recenzji. */
/* Badge oceny — wytyczne grafika (widocznosc oceny na dowolnej okladce):
   duza pogrubiona cyfra, STALA szerokosc >=64px / wysokosc >=24px, zaokraglone
   rogi, delikatny obrys + cien dla kontrastu, separator „/" i „10" w nizszym
   kontrascie niz sama ocena. KOLOR TLA badge'a (--kvlt-badge-color) nietkniety. */
.kvlt-badge {
	position: absolute;
	right: 0.5rem;
	bottom: 0.5rem;
	display: inline-flex;
	align-items: baseline;
	justify-content: center;
	gap: 0;
	/* Stala szerokosc niezalezna od oceny (min 64px wg grafika); border-box, zeby
	   padding nie zmienial wymiaru; krotsze oceny wysrodkowuja sie w kadrze. */
	box-sizing: border-box;
	width: 4rem;
	min-height: 1.5rem; /* min 24px */
	padding: 0.22rem 0.5rem;
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-badge-color, var(--kvlt-accent));
	color: #FFFFFF;
	font-family: var(--kvlt-font-display);
	font-weight: 900;
	font-size: 1rem; /* cyfra 16px — gorna granica zalecenia 14-16px */
	line-height: 1.15;
	font-variant-numeric: tabular-nums;

	/* Cien TEKSTU zostaje mocny — ocena musi byc czytelna na dowolnej okladce. */
	text-shadow:
		0 1px 2px rgba(0, 0, 0, 0.9),
		0 0 6px rgba(0, 0, 0, 0.7);

	/* Cien SAMEGO badge'a uproszczony do jednego miekkiego drop-shadow, jak na
	   grafice wzorcowej. Bez bialego obrysu i kolorowej poswiaty rosnacej z ocena
	   (za duzo szumu). Zmienne --kvlt-badge-glow* (z PHP) nie sa juz uzywane. */
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* Sama ocena — dominanta: pelny bialy, najgrubsza. */
.kvlt-badge__score {
	font-weight: 900;
}

/* Separator „/" — najnizszy kontrast (~60%), mniejszy, z odstepem od oceny. */
.kvlt-badge__sep {
	margin-left: 0.18em;
	font-size: 0.7em;
	font-weight: 700;
	opacity: 0.6;
}

/* „10" — przyciszone (~80%), ale czytelne, zeby skala byla jednoznaczna
   (8,5 to nie 8,5 z 6). */
.kvlt-badge__max {
	font-size: 0.7em;
	font-weight: 700;
	/* Bez `opacity` — przygaszenie do 0,8 mieszalo biel z kolorem badge'a
	   i zbijalo kontrast ponizej progu AA (audyt axe-core wskazal wlasnie ten
	   element). Hierarchie wizualna daje juz mniejszy rozmiar i lzejsza waga,
	   wiec przezroczystosc nie wnosila nic poza problemem. */
}

/* -------------------------------------------------------------------------
   7b. Strona glowna — rozmieszczenie blokow (Etap 2)
   ------------------------------------------------------------------------- */

/* HERO — MasterSlider nad ukladem dwukolumnowym.
   Slider ma wlasna, sztywna szerokosc z ustawien wtyczki, wiec zamiast go
   rozciagac (deformacja) centrujemy go i dajemy tlo strony — bez tego po
   bokach widac bylo ciemniejsze pasy „letterboxa". */
/* HERO (MasterSlider) — od Etapu poprawek zywe W KOLUMNIE GLOWNEJ siatki home
   (nie na pelnej szerokosci). Dzieki temu carousel ma szerokosc tresci i stoi
   przy lewej, a prawy baner reklamowy (aside) podnosi sie do gory obok niego.
   Dawny blur-fill („ambient" tlo bocznych pasow) usuniety — nie ma juz pustych
   pasow do zakrycia, bo slajder nie jest wysrodkowany w szerokim kontenerze. */
.kvlt-hero {
	margin-bottom: 2.75rem;
}

.kvlt-hero__inner {
	position: relative;
}

/* Podpis slajdera (warstwa MasterSlidera) na malych ekranach.
   MasterSlider skaluje slajd do szerokosci -> na tablecie/telefonie widok robi
   sie niski (telefon ~180 px), a podpis pozycjonowany jest inline nisko
   (top ~ wysokosc widoku) i wypada poza kadr (`.ms-view` ma overflow:hidden) ->
   na telefonie znika, na tablecie ucieta ostatnia linia.
   Kotwiczymy go do DOLU widoku + ciemna plakietka pod tekst (czytelnosc).
   `!important` bije inline'owe top/left/transform ustawiane przez wtyczke. */
@media (max-width: 991px) {
	/* Kontener warstw (`.ms-slide-layers`) to `offsetParent` podpisu — to
	   wzgledem NIEGO liczy sie `bottom:0`, nie wzgledem `.ms-view`. MasterSlider
	   ustawia jego wysokosc z ORYGINALNEJ proporcji projektu slidera, a kadr
	   (`.ms-view`) dziala w trybie cover (skaluje po wysokosci). Gdy te proporcje
	   sie roznia — a na czesci urzadzen (np. Poco X6 Pro: inne DPR + przeliczenie
	   po schowaniu paska adresu) kontener warstw wychodzi NIZSZY niz kadr i jest
	   wyrownany do gory — `bottom:0` podpisu ladowal NAD dolem zdjecia (tekst za
	   wysoko). Wymuszamy, zeby kontener warstw zawsze wypelnial kadr: wtedy dol
	   podpisu = realny dol widocznego kadru na kazdym urzadzeniu. */
	.kvlt-hero .ms-view .ms-slide-layers {
		top: 0 !important;
		height: 100% !important;
		max-width: 100% !important;
	}

	.kvlt-hero .ms-view .ms-layer {
		top: auto !important;
		bottom: 0 !important;
		left: 0 !important;
		right: 0 !important;
		width: 100% !important;
		max-width: 100% !important;
		margin: 0 !important;
		transform: none !important;
		box-sizing: border-box;
		padding: 0.7rem 1rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
		background: linear-gradient(
			to top,
			rgba(0, 0, 0, 0.85) 0%,
			rgba(0, 0, 0, 0.5) 55%,
			rgba(0, 0, 0, 0) 100%
		);
	}
}

/* Ponizej 480 px MasterSlider skaluje podpis wciaz do ~24 px (za duzo na
   telefonie). Zmniejszamy o ~30%: `3.5vw` odwzorowuje 70% oryginalu w calym
   zakresie (479 px -> ~17 px, 320 px -> ~11 px). `!important` bije inline
   font-size ustawiany przez wtyczke; clamp trzyma sensowne min/max. */
@media (max-width: 480px) {
	.kvlt-hero .ms-view .ms-layer {
		font-size: clamp(11px, 3.5vw, 17px) !important;
	}
}

.kvlt-hero .master-slider,
.kvlt-hero .ms-container {
	position: relative;
	z-index: 1;
	max-width: 100%;
	margin-inline: 0; /* przy lewej krawedzi tresci, nie wysrodkowane */
}

.kvlt-hero img {
	height: auto;
}

/* Sekcje home — rytm pionowy */
.kvlt-section + .kvlt-section {
	margin-top: 2.75rem;
}

.kvlt-section--underground {
	margin-top: 1.75rem; /* blizej newsow — to ich podkategoria */
}

/* Naglowek sekcji: tytul po lewej, „Więcej →" po prawej, linia pod spodem */
.kvlt-sechead {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 1.1rem;
	padding-bottom: 0.5rem;
	border-bottom: 2px solid var(--kvlt-line);
}

/* Drugi (i kolejny) naglowek WEWNATRZ jednej sekcji — np. „Zdjęcia" pod
   „Relacjami". Bez tego zajawki relacji dochodzily prawie do samej linii
   naglowka Zdjec i oba bloki zlewaly sie w jeden.
   `.kvlt-carousel` musi byc na tej liscie: grid relacji jest w nim owiniety,
   wiec sasiadem naglowka „Zdjecia" jest wrapper, a nie sam `.kvlt-grid`. */
.kvlt-grid + .kvlt-sechead,
.kvlt-carousel + .kvlt-sechead,
.kvlt-strip + .kvlt-sechead {
	margin-top: 2.75rem;
}

/* Na mobile karuzela konczy sie rzedem kropek, ktory sam w sobie domyka blok
   wizualnie i zajmuje ~26 px. Pelne 2.75rem robilo pod nia wyraznie wieksza
   dziure niz pod zwykla siatka (np. Newsy), wiec tu odstep jest mniejszy —
   sumarycznie blok oddycha tyle samo, co pozostale sekcje.
   Dotyczy TYLKO karuzeli i TYLKO mobile: `.kvlt-grid`/`.kvlt-strip` zachowuja
   pelny rytm, a od 48em karuzela i tak przestaje istniec (wraca siatka). */
@media (max-width: 47.99em) {
	.kvlt-carousel + .kvlt-sechead {
		margin-top: 1.75rem;
	}
}

.kvlt-sechead__title {
	position: relative;
	margin: 0;
	font-size: clamp(1.15rem, 3.2vw, 1.6rem);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* Karmazynowy znacznik pod tytulem, nachodzacy na linie sekcji */
.kvlt-sechead__title::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: -0.5rem;
	width: 100%;
	height: 2px;
	background: var(--kvlt-accent);
	transform: translateY(1px);
}

.kvlt .kvlt-sechead__title a {
	color: var(--kvlt-text);
}

.kvlt .kvlt-sechead__title a:hover,
.kvlt .kvlt-sechead__title a:focus-visible {
	color: var(--kvlt-accent);
	text-decoration: none;
}

.kvlt-sechead__more {
	flex: none;
	font-family: var(--kvlt-font-display);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* --- Siatka newsow: 2 kolumny → 3 → 5 (2 rzedy x 5 = 10 kafli) --- */
.kvlt-grid--news {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 40em) {
	.kvlt-grid--news {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 62em) {
	.kvlt-grid--news {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 1rem;
	}
}

/* Maksymalnie 4 kolumny (parzysta liczba) — bez rzedu po 5 na szerokich ekranach. */

/* --- Siatka recenzji: kwadratowe okladki plyt. Ksiazki maja teraz WLASNA
   sekcje (`.kvlt-grid--books`) ponizej, wiec recenzje wypelniaja pelne rzedy
   bez wycinania kolumny. --- */
.kvlt-grid--reviews {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 40em) {
	.kvlt-grid--reviews {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 62em) {
	.kvlt-grid--reviews {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 1rem;
	}
}

/* 5 kolumn na szerokich ekranach — recenzje sa celowo WEZSZE niz newsy (4 kol),
   dzieki czemu 10 recenzji uklada sie w rowne 2 rzedy. */
@media (min-width: 75em) {
	.kvlt-grid--reviews {
		grid-template-columns: repeat(5, minmax(0, 1fr));
	}
}

/* --- Ksiazki: osobny rzad pionowych okladek. Ta sama drabinka kolumn co newsy/
   underground: 2 (mobilka) -> 3 (wezszy) -> 4 (normalny widok). Dzieki temu przy
   3 kolumnach niepelny ostatni rzad (4 ksiazki = 3+1) chowa sierote (patrz nizej),
   co likwiduje przesyt. Kafle to zwykle karty `ratio=portrait` -> okladka wypelnia
   kadr 2/3 (`cover`, bez paskow tla), a tytul (bez `compact`) jest w calosci. --- */
.kvlt-grid--books {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 40em) {
	.kvlt-grid--books {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 62em) {
	.kvlt-grid--books {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* --- Ukrywanie „sierot": kafle tworzace NIEPELNY ostatni rzad sa chowane, zeby
   sekcja konczyla sie rowna krawedzia (np. 10 recenzji przy 3 kolumnach = 3+3+3+1
   -> chowamy tego jednego). Sztuczka CSS oparta na liczbie kolumn C:
     - `:nth-child(Cn+1)`         — element jest POCZATKIEM rzedu,
     - `:nth-last-child(-n+{C-1})` — a zarazem miesci sie w ostatnich (C-1)
       kaflach, czyli rozpoczyna rzad, ktoremu brakuje do pelna,
     - `~ *`                      — chowamy jego i wszystkie kolejne,
     - `:nth-child(n+{C+1})`      — zabezpieczenie: dotyczy tylko rzedow OD 2.
       w gore, wiec sekcja z <= C kaflami (jeden rzad) nigdy nie znika w calosci.
   Gdy ostatni rzad jest PELNY, zaden selektor nie trafia — pelne rzedy zostaja.
   C dobrane pod liczbe kolumn kazdej siatki na danej szerokosci (patrz tabela
   grid-template-columns powyzej). --- */
@media (max-width: 39.99em) { /* news / reviews: 2 kolumny */
	.kvlt-grid--news > *:nth-child(2n+1):nth-child(n+3):nth-last-child(-n+1),
	.kvlt-grid--news > *:nth-child(2n+1):nth-child(n+3):nth-last-child(-n+1) ~ *,
	.kvlt-grid--reviews > *:nth-child(2n+1):nth-child(n+3):nth-last-child(-n+1),
	.kvlt-grid--reviews > *:nth-child(2n+1):nth-child(n+3):nth-last-child(-n+1) ~ * {
		display: none;
	}

	/* Ksiazki na mobilce: tylko JEDEN rzad (2 okladki). Pozostale chowamy — pionowe
	   okladki sa wysokie i 4 sztuki zajmowaly pol ekranu (przesyt). Szersze widoki
	   (3 i 4 kolumny) zostaja bez zmian. */
	.kvlt-grid--books > *:nth-child(n+3) {
		display: none;
	}
}

@media (min-width: 40em) and (max-width: 61.99em) { /* news / reviews / books: 3 kolumny */
	.kvlt-grid--news > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2),
	.kvlt-grid--news > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2) ~ *,
	.kvlt-grid--reviews > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2),
	.kvlt-grid--reviews > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2) ~ *,
	.kvlt-grid--books > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2),
	.kvlt-grid--books > *:nth-child(3n+1):nth-child(n+4):nth-last-child(-n+2) ~ * {
		display: none;
	}
}

@media (min-width: 62em) { /* news / books: 4 kolumny (news juz sie nie zwieksza) */
	.kvlt-grid--news > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3),
	.kvlt-grid--news > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3) ~ *,
	.kvlt-grid--books > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3),
	.kvlt-grid--books > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3) ~ * {
		display: none;
	}
}

@media (min-width: 62em) and (max-width: 74.99em) { /* reviews: 4 kolumny */
	.kvlt-grid--reviews > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3),
	.kvlt-grid--reviews > *:nth-child(4n+1):nth-child(n+5):nth-last-child(-n+3) ~ * {
		display: none;
	}
}

@media (min-width: 75em) { /* reviews: 5 kolumn */
	.kvlt-grid--reviews > *:nth-child(5n+1):nth-child(n+6):nth-last-child(-n+4),
	.kvlt-grid--reviews > *:nth-child(5n+1):nth-child(n+6):nth-last-child(-n+4) ~ * {
		display: none;
	}
}

/* --- Relacje: szersze kafle z zajawka --- */
.kvlt-grid--relacje {
	grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 48em) {
	.kvlt-grid--relacje {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* --- Karuzela (Relacje na mobile) ---------------------------------------
   Do 48em siatka zamienia sie w przewijany w poziomie tor ze „snapowaniem".
   Przewijanie jest NATYWNE — zachowuje bezwladnosc palca, obsluge gestow
   i dziala takze bez JS. JS dokłada tylko zapetlenie i kropki.
   ------------------------------------------------------------------------ */

.kvlt-carousel {
	position: relative;
}

@media (max-width: 47.99em) {
	.kvlt-carousel [data-kvlt-carousel-track] {
		display: grid;
		grid-auto-flow: column;
		/* Kafel nie na cala szerokosc — nastepny „wystaje", co samo w sobie
		   informuje, ze da sie przewijac. */
		grid-auto-columns: 86%;
		gap: 0.75rem;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		padding-bottom: 0.25rem;
		-webkit-overflow-scrolling: touch;
		/* Pasek przewijania chowamy — nawigacje pokazuja kropki. */
		scrollbar-width: none;
		/* ⚠️ Zerujemy dziedziczone `html { scroll-behavior: smooth }`.
		   Bez tego skok zapetlajacy (JS) bylby animowany i widac by bylo,
		   jak karuzela przewija sie z powrotem przez wszystkie slajdy.
		   Plynne przejscie po kliknieciu kropki JS wymusza osobno. */
		scroll-behavior: auto;
	}

	.kvlt-carousel [data-kvlt-carousel-track]::-webkit-scrollbar {
		display: none;
	}

	.kvlt-carousel [data-kvlt-carousel-track] > * {
		scroll-snap-align: center;
	}
}

/* Kropki — widoczne tylko wtedy, gdy karuzela jest aktywna (klase ustawia JS). */
.kvlt-carousel__dots {
	display: none;
}

.kvlt-carousel.is-active .kvlt-carousel__dots {
	display: flex;
	justify-content: center;
	align-items: center;
	gap: 0.4rem;
	/* ⚠️ Skrot `margin`, nie samo `margin-top`. Kropki to <ul>, wiec przy samym
	   `margin-top` przeciekal domyslny `margin-block-end: 1em` przegladarki
	   (16 px), ktorego nikt nie zaprojektowal — karuzela byla przez to nizej
	   „osadzona" niz zwykla siatka sekcji. */
	margin: 0.6rem 0 0;
	padding: 0;
	list-style: none;
}

.kvlt-carousel__dot {
	width: 22px;
	height: 22px;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* Sam punkt jest maly, ale POLE DOTYKU ma 22 px — inaczej trafienie
	   palcem w 7-pikselowa kropke jest loteria. */
}

.kvlt-carousel__dot::before {
	content: "";
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--kvlt-muted);
	opacity: 0.55;
	transition: opacity var(--kvlt-transition), background-color var(--kvlt-transition), transform var(--kvlt-transition);
}

.kvlt-carousel__dot[aria-current="true"]::before {
	background: var(--kvlt-accent);
	opacity: 1;
	transform: scale(1.35);
}

.kvlt-carousel__dot:hover::before,
.kvlt-carousel__dot:focus-visible::before {
	opacity: 1;
}

/* --- Zdjecia: pasek przewijany w poziomie na mobile, siatka na desktopie --- */
.kvlt-strip {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 45%;
	gap: 0.75rem;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	padding-bottom: 0.5rem;
	-webkit-overflow-scrolling: touch;
}

.kvlt-strip > * {
	scroll-snap-align: start;
}

@media (min-width: 48em) {
	.kvlt-strip {
		grid-auto-flow: row;
		grid-auto-columns: auto;
		/* 3 kolumny x 2 rzedy, nie 6 x 1. Przy szesciu kolumnach kafel mial
		   ~155 px szerokosci i 116 px wysokosci — tytul na miniaturze zajmowal
		   niemal caly kadr i samo zdjecie przestawalo byc czytelne. Trojka
		   trzyma tez wspolna szerokosc z rzedem „Relacje" nad spodem. */
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 1.25rem;
		overflow: visible;
	}
}

/* Kafel z tytulem na miniaturze (pasek „Zdjecia") */
.kvlt-card--overlay .kvlt-card__media {
	border-radius: var(--kvlt-radius);
}

.kvlt-card__overlay {
	position: absolute;
	inset: auto 0 0 0;
	padding: 1.75rem 0.75rem 0.7rem;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.88), rgba(0, 0, 0, 0));
	/* Podpis wysrodkowany — w pasku „Zdjecia" kafle sa male i kwadratowe,
	   a tytul bywa jedno- albo trzywierszowy; wysrodkowanie trzyma go
	   optycznie w osi kadru niezaleznie od dlugosci. */
	text-align: center;
}

.kvlt-card--overlay .kvlt-card__title {
	margin: 0;
	color: #FFFFFF;
	font-size: 0.8125rem;
	line-height: 1.3;
	/* ⚠️ WYLACZAMY `text-wrap: balance` dziedziczone z globalnej reguly naglowkow.
	   Balansowanie skraca wiersze, zeby mialy podobna dlugosc — w waskim kaflu
	   dawalo to skrajnie nierowne marginesy: zmierzone 10 px z lewej i
	   nawet 132 px z prawej, przez co podpis wygladal, jakby wisial w srodku
	   zdjecia zamiast wypelniac szerokosc.
	   ⚠️ Wartoscia jest `wrap`, NIE `normal` — `text-wrap` przyjmuje
	   `wrap | nowrap | balance | pretty | stable`. `normal` jest niepoprawne,
	   przegladarka odrzuca cala deklaracje i dziedziczone `balance` zostaje. */
	text-wrap: wrap;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* Przenoszenie dlugich slow/adresow, zeby nie rozpychaly kafla. */
	overflow-wrap: anywhere;
}

/* Gestsza wersja kafla — siatki na home.
   Tytul przyciety do 3 linii i o stalej wysokosci, zeby linia metadanych
   (data + odslony) wypadala na tym samym poziomie w calym rzedzie. Bez tego
   rzedy sa poszarpane: przy tytule 2-linijkowym data wjezdza wyzej niz
   przy 4-linijkowym. */
.kvlt-card--compact .kvlt-card__title {
	font-size: 0.875rem;
	margin-top: 0.5rem;
	line-height: 1.3;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

@media (min-width: 40em) {
	.kvlt-card--compact .kvlt-card__title {
		min-height: calc(3 * 1.3em);
	}
}

.kvlt-card--compact .kvlt-meta {
	font-size: 0.6875rem;
	gap: 0.6rem;
	margin-top: auto; /* meta zawsze przy dolnej krawedzi kafla */
	padding-top: 0.25rem;
}

/* Kafel jako kolumna o pelnej wysokosci komorki siatki — warunek dla
   `margin-top:auto` powyzej. */
.kvlt-grid > .kvlt-card {
	height: 100%;
}

/* Sekcja „Polecane" pod wpisem (Etap 4 / C3) — wezsza kolumna niz home,
   wiec 2 kafle na tablecie i 4 na desktopie. */
.kvlt-grid--related {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 48em) {
	.kvlt-grid--related {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.kvlt-related {
	margin-top: 2.75rem;
}

/* Sekcja komentarzy („Dodaj komentarz") — comments_template() renderuje ja jako
   BEZPOSREDNIE dziecko `.kvlt-layout__main`, tuz pod „Polecanymi", a motyw nie ma
   wlasnego comments.php ani stylow, wiec sekcja przylegala bez odstepu. Dokladamy
   margines gorny w rytmie sekcji. `>` celuje w TOP-LEVEL blok: wrapper
   `#comments`/`.comments-area` (gdy sa komentarze) albo sam formularz
   `.comment-respond` (gdy ich nie ma) — nigdy w zagniezdzony formularz w srodku. */
.kvlt-layout__main > .comments-area,
.kvlt-layout__main > #comments,
.kvlt-layout__main > .comment-respond {
	margin-top: 2.75rem;
}

/* Zajawka w Relacjach — rowna dlugosc, zeby rzad byl spokojny */
.kvlt-grid--relacje .kvlt-card__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* -------------------------------------------------------------------------
   7c. Listingi Content Views Pro (strony kategorii)
   -------------------------------------------------------------------------
   Pozycje menu prowadza do STRON z shortcode'em `[pt_view]`, a nie do archiwow
   (patrz kvlt-theme-spec sekcja 7). Siatke rysuje wtyczka kolumnami Bootstrapa
   i pokazuje miniatury w naturalnych proporcjach — okladki ksiazek bywaja
   pionowe 186x300, ale i poziome, wiec rzedy sie rozjezdzaly, a podpisy
   ladowaly na roznych wysokosciach.

   Nadpisujemy to siatka CSS z jednakowymi komorkami i stalym kadrem obrazka.
   `--kvlt-cv-ratio` i `--kvlt-cv-fit` dobiera sie per listing (klasy z body_class
   w inc/compat.php), bo okladka ksiazki musi byc widoczna w calosci, a zdjecie
   z koncertu spokojnie zniesie kadrowanie.
   ------------------------------------------------------------------------- */

.kvlt-cvlisting {
	--kvlt-cv-ratio: 4 / 3;
	--kvlt-cv-fit: cover;
	--kvlt-cv-cols: 4;
}

/* Ksiazki — okladki pionowe RÓŻNEJ proporcji (186x300 ~0.62, ale i 208x260
   ~0.80). Wczesniej `contain` w kadrze 3/4 (0.75) pokazywal okladke w calosci,
   ale zostawial szerokie paski tla po bokach (kadr szerszy niz okladka) —
   listing wygladal niespojnie, „okladki plywaly w ramkach". Zgodnie z decyzja:
   wypelniamy kadr BEZ paskow (`cover`) i zwezamy komorke do 2/3 (~0.667), czyli
   blisko najczestszej proporcji okladek — dzieki temu przyciecie jest minimalne
   (typowo kilka % gora/dol), a cala siatka jest rowna i spojna. */
.kvlt-cvlisting--ksiazki {
	--kvlt-cv-ratio: 2 / 3;
	--kvlt-cv-fit: cover;
}

.kvlt-cvlisting--recenzje {
	--kvlt-cv-ratio: 1 / 1;
	--kvlt-cv-fit: contain;
	--kvlt-cv-cols: 5;
}

.kvlt-cvlisting .pt-cv-page {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1.5rem 1.25rem;
}

@media (min-width: 40em) {
	.kvlt-cvlisting .pt-cv-page {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 62em) {
	.kvlt-cvlisting .pt-cv-page {
		grid-template-columns: repeat(var(--kvlt-cv-cols), minmax(0, 1fr));
	}
}

/* Kolumny Bootstrapa wtyczki (`col-md-3` itp.) — zerujemy szerokosci i floaty,
   zeby nie bily sie z siatka powyzej. Wtyczka narzuca tez `max-width: 300px`
   na dzieci przez wlasny <style> w <head>. */
.kvlt-cvlisting .pt-cv-content-item {
	width: auto !important;
	max-width: none !important;
	float: none !important;
	padding: 0 !important;
	margin: 0 !important;
}

.kvlt-cvlisting .pt-cv-ifield {
	display: flex;
	flex-direction: column;
	height: 100%;
	max-width: none !important;
}

.kvlt-cvlisting .pt-cv-ifield > * {
	max-width: none !important;
	margin-bottom: 0 !important;
}

/* Kadr miniatury — jednakowy dla wszystkich pozycji listingu. */
.kvlt-cvlisting .pt-cv-href-thumbnail {
	display: block;
	position: relative;
	aspect-ratio: var(--kvlt-cv-ratio);
	overflow: hidden;
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface-2);
}

.kvlt-cvlisting .pt-cv-thumbnail {
	position: absolute;
	inset: 0;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	object-fit: var(--kvlt-cv-fit);
	object-position: center;
	transition: transform 300ms ease;
}

/* Powiekszenie na hoverze tylko przy `cover` — przy `contain` odslonilo by
   krawedzie plyty i wygladalo na blad. Ksiazki sa juz `cover`, wiec skaluja sie
   jak reszta; wyjatek zostaje tylko dla recenzji (kwadratowe okladki, `contain`). */
@media (hover: hover) {
	.kvlt-cvlisting .pt-cv-href-thumbnail:hover .pt-cv-thumbnail {
		transform: scale(1.04);
	}

	.kvlt-cvlisting--recenzje .pt-cv-href-thumbnail:hover .pt-cv-thumbnail {
		transform: none;
	}
}

/* Podpis — ten sam rytm co w kaflach motywu, wyrownany do gornej krawedzi
   pod obrazkiem, wiec rzedy czytaja sie jak siatka, a nie jak lista. */
.kvlt-cvlisting .pt-cv-title {
	margin: 0.625rem 0 0 !important;
	font-family: var(--kvlt-font-display);
	font-size: 0.875rem;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: 0;
	text-align: left;
}

/* UWAGA: bez prefiksu `.kvlt` — obie klasy siedza na TYM SAMYM <body>, wiec
   `.kvlt .kvlt-cvlisting` szukaloby potomka i nigdy by nie zadzialalo.
   `.kvlt-cvlisting .pt-cv-title a` ma specyficznosc (0,2,1), czyli i tak
   wygrywa z `.kvlt a` (0,2,0). */
.kvlt-cvlisting .pt-cv-title a {
	color: var(--kvlt-text);
}

.kvlt-cvlisting .pt-cv-title a:hover,
.kvlt-cvlisting .pt-cv-title a:focus-visible {
	color: var(--kvlt-accent);
	text-decoration: none;
}

/* Wtyczka centruje tresc klasa `pt-cv-center` — w siatce wyglada to niechlujnie. */
.kvlt-cvlisting .pt-cv-view.pt-cv-center .pt-cv-ifield {
	text-align: left;
}

/* -------------------------------------------------------------------------
   8. Pojedynczy wpis
   ------------------------------------------------------------------------- */

.kvlt-single__head {
	margin-bottom: 1.5rem;
}

.kvlt-single__cats {
	margin-bottom: 0.5rem;
	font-family: var(--kvlt-font-display);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

/* Prefiks `.kvlt`, bo globalny naglowek `.kvlt h1` (0,1,1) bije samo
   `.kvlt-single__title` (0,1,0) i inaczej `text-wrap` by nie zadzialal. */
.kvlt .kvlt-single__title {
	font-size: clamp(1.75rem, 5.5vw, 2.75rem);
	margin-bottom: 0.5rem;
	/* Dlugi tytul wpisu ma wypelniac CALA szerokosc pola. Globalny nagl. ma
	   `text-wrap: balance` (rowne, krotsze linie — dobre dla krotkich naglowkow,
	   ale dlugi tytul wyglada przez to na „niedokonczony"). `wrap` = zwykle,
	   zachlanne zawijanie: kazda linia wypelniona do maks przed przejsciem dalej. */
	text-wrap: wrap;
}

/* Zrodlo w linii meta (na gorze wpisu) — pogrubione, link w akcencie. */
.kvlt-meta__source {
	font-weight: 700;
}

.kvlt-meta__source a {
	color: var(--kvlt-accent);
}

/* Pogrubienie w tresci. Tekst body ma weight 300 (light), przez co `<strong>`
   z domyslnym `bolder` skakal tylko do 400 (ledwo widoczne). Wymuszamy 700 —
   Manrope to variable font 200-800, wiec 700 renderuje sie poprawnie. */
.kvlt-single__content strong,
.kvlt-single__content b {
	font-weight: 700;
}

.kvlt-single__thumb {
	margin: 0 0 1.5rem;
}

.kvlt-single__thumb img {
	width: 100%;
	border-radius: var(--kvlt-radius);
}

/* Recenzje i Ksiazki — okladka dosunieta do lewej, tresc oplywa ja z prawej.
   Okladka plyty (kwadrat) i ksiazki (pion) czytaja sie w ukladzie „okladka |
   tekst" naturalnie i wykorzystuja szerokosc, ktora wczesniej marnowala pusta
   lewa kolumna. Bez tego pionowa okladka ksiazki spychala cala tresc pod
   siebie — pojawiala sie dopiero po przescrollowaniu. Tylko od tabletu w gore;
   na waskim ekranie okladka zostaje nad trescia (pelna szerokosc). Float
   czyscimy przed panelem oceny, zrodlem i tagami, zeby szly pod obrazkiem. */
@media (min-width: 48em) {
	.category-recenzje .kvlt-single__thumb,
	.category-ksiazki .kvlt-single__thumb {
		float: left;
		width: min(340px, 42%);
		margin: 0.25rem 1.75rem 1rem 0;
	}

	.category-recenzje .kvlt-review-panel,
	.category-recenzje .kvlt-source,
	.category-recenzje .kvlt-single__tags,
	.category-ksiazki .kvlt-review-panel,
	.category-ksiazki .kvlt-source,
	.category-ksiazki .kvlt-single__tags {
		clear: both;
	}
}

.kvlt-single__content {
	font-size: 1.0625rem;
	line-height: 1.75;
}

.kvlt-single__content > * + * {
	margin-top: 1.1em;
}

/* Wyrownania mediow z edytora WordPress. Motyw ich nie mial, wiec np.
   wysrodkowany obrazek (klasa `aligncenter`, jak grafika ZIP na /o-nas/redakcja/)
   i tak lgnal do lewej. */
.kvlt-single__content .aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
}

.kvlt-single__content .alignleft {
	float: left;
	margin: 0.3rem 1.4rem 1rem 0;
}

.kvlt-single__content .alignright {
	float: right;
	margin: 0.3rem 0 1rem 1.4rem;
}

.kvlt-single__content h2,
.kvlt-single__content h3 {
	margin-top: 1.75em;
}

.kvlt-single__content blockquote {
	margin-inline: 0;
	padding-left: 1.25rem;
	border-left: 3px solid var(--kvlt-accent);
	color: var(--kvlt-muted);
	font-style: italic;
}

/* Wstepniak wywiadu („wywiadlead") — akapit-lead z tresci wpisu (klasa z
   redakcji, ~40 wpisow; stary motyw kvlt31 ja stylowal). Wyrozniony box:
   karmazynowa kreska z lewej, przygaszone tlo, nieco wiekszy i cieplejszy tekst.
   Tokeny motywu -> dziala w trybie ciemnym i jasnym. */
.kvlt-single__content .wywiadlead {
	margin: 0 0 1.75rem;
	padding: 1.1rem 1.35rem;
	border-left: 4px solid var(--kvlt-accent);
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface-2);
	color: var(--kvlt-text);
	font-size: 1.15em;
	line-height: 1.6;
	font-weight: 500;
}

/* Wstepniak MA POZOSTAC CIEMNY takze w trybie JASNYM (decyzja klienta).
   Nadpisujemy tylko motyw jasny — tryb ciemny zostaje na tokenach bez zmian.
   Wartosci = ciemne tokeny (surface-2 / text / accent-text z trybu ciemnego);
   jasniejszy karmazyn linkow trzyma kontrast na ciemnym tle. */
:root[data-theme="light"] .kvlt-single__content .wywiadlead {
	background: #202327;
	color: #ECEDEF;
}

:root[data-theme="light"] .kvlt-single__content .wywiadlead a {
	color: #F4485C;
}

/* Osadzony kalendarz koncertow (concerts-metal.com) — obcy iframe. Jedyna zmiana
   to PRZYWROCENIE wysokosci: theme-reset `.kvlt iframe{height:auto}` zapadal
   `height="900"` z embeda i widget sie zwijal. Reszta (kolory, panel) zostaje
   oryginalna — z samego widgetu. */
.kvlt iframe[src*="concerts-metal"] {
	height: 900px;
}

@media (max-width: 600px) {
	.kvlt iframe[src*="concerts-metal"] {
		height: 620px;
	}
}

/* C1 — zrodlo, dyskretnie pod trescia */
.kvlt-source {
	margin-top: 2rem;
	padding-top: 0.75rem;
	border-top: 1px solid var(--kvlt-line);
	color: var(--kvlt-muted);
	font-size: 0.8125rem;
	overflow-wrap: anywhere;
}

.kvlt-source__label {
	font-family: var(--kvlt-font-display);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/* C2 — tagi raz, na koncu */
.kvlt-single__tags {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	margin-top: 2rem;
	padding-top: 1.25rem;
	border-top: 1px solid var(--kvlt-line);
}

.kvlt-single__tags-label {
	font-family: var(--kvlt-font-display);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kvlt-muted);
}

.kvlt-single__tags a {
	display: inline-block;
	padding: 0.2rem 0.55rem;
	border: 1px solid var(--kvlt-line);
	border-radius: 999px;
	color: var(--kvlt-muted);
	font-size: 0.8125rem;
}

.kvlt-single__tags a:hover {
	border-color: var(--kvlt-accent);
	color: var(--kvlt-accent);
	text-decoration: none;
}

/* -------------------------------------------------------------------------
   9. Panel oceny recenzji (C4)
   ------------------------------------------------------------------------- */

.kvlt-review-panel {
	margin-top: 2rem;
	padding: 1.25rem;
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface);
}

.kvlt-review-panel__top {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 0.875rem;
}

/* Ocena po PRAWEJ, dwuwierszowo: „OCENA:" nad wartoscia, obie do prawej
   krawedzi. `margin-left: auto` dosuwa blok do prawej takze wtedy, gdy sociale
   sa ukryte (ksiazki nie maja oceny, ale przy innych wariantach panelu blok
   socialii moze byc pusty i `space-between` nie mialoby czego rozepchnac). */
.kvlt-review-panel__score {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 0.15rem;
	margin-left: auto;
	text-align: right;
}

.kvlt-review-panel__label {
	font-family: var(--kvlt-font-display);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.16em;
	color: var(--kvlt-muted);
}

.kvlt-review-panel__number {
	font-family: var(--kvlt-font-display);
	font-weight: 900;
	font-size: clamp(1.75rem, 6vw, 2.5rem);
	line-height: 1;
	font-variant-numeric: tabular-nums;
	/* Kolor liczby przychodzi z PHP juz z GWARANTOWANYM kontrastem 4,5:1 wobec
	   powierzchni panelu — osobno dla obu motywow (kvlt_ensure_contrast()).
	   Wczesniej byl tu surowy kolor skali: przy ocenie 10 dawal na ciemnym tle
	   2,82:1, a niskie noty (granaty #071326) byly praktycznie niewidoczne.
	   Sztywnej wartosci nie da sie tu podac, bo kolor zalezy od noty. */
	color: var(--kvlt-score-text-dark, var(--kvlt-score-end, var(--kvlt-accent)));
	text-shadow: 0 0 18px var(--kvlt-score-glow, transparent);
}

/* Tryb jasny — wariant przyciemniony, liczony tak samo, tylko wzgledem bieli.
   Zastapil wczesniejszy `color-mix` na sztywne 62%: tamten byl zgadywaniem,
   ten jest wyliczony do progu. Poswiata na jasnym tle jest zbedna. */
:root[data-theme="light"] .kvlt-review-panel__number {
	color: var(--kvlt-score-text-light, var(--kvlt-score-end, var(--kvlt-accent)));
	text-shadow: none;
}

.kvlt-review-panel__socials {
	display: flex;
	align-items: center;
	gap: 0.375rem;
}

/* ⚠️ Selektor MUSI zawierac `a`, zeby przebic `.kvlt a { color: accent }`
   (0,1,1). Bez tego aktywne ikony wychodzily karmazynowe zamiast bialych —
   a zalozenie jest odwrotne: PELNY kolor tekstu = link dziala,
   wyszarzenie = brak linku. Kolor niesie tu informacje, wiec nie moze go
   zjadac globalny styl linkow. */
.kvlt-review-panel__social,
.kvlt a.kvlt-review-panel__social {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	color: var(--kvlt-text);
}

/* AKTYWNA ikona dostaje mocniejsza ramke — w OBU motywach. Domyslne
   `--kvlt-line` jest liczone na delikatne separatory i przy przycisku wypada
   za slabo: ~1,2:1 na bieli i ~1,4:1 na ciemnej powierzchni panelu, przez co
   kwadrat zlewal sie z tlem. `--kvlt-line-strong` trzyma prog 3:1 wymagany
   przez WCAG 1.4.11 dla granic elementow interakcyjnych.

   Dotyczy TYLKO aktywnych (`a`) — wyszarzone zostaja ciche, bo ich rola to
   komunikat „linku brak"; wzmocnienie ich ramki zatarloby te roznice. */
.kvlt a.kvlt-review-panel__social {
	border-color: var(--kvlt-line-strong);
}

.kvlt a.kvlt-review-panel__social:hover,
.kvlt a.kvlt-review-panel__social:focus-visible {
	border-color: var(--kvlt-accent);
	color: var(--kvlt-accent-text);
}

.kvlt-review-panel__social.is-disabled {
	opacity: 0.28;
	pointer-events: none;
}

.kvlt-review-panel__social .kvlt-icon {
	width: 17px;
	height: 17px;
}

/* Pasek: gradient zatrzymuje sie na wartosci oceny (nie sciska calej teczy) */
.kvlt-review-panel__bar {
	height: 10px;
	border-radius: 999px;
	background: var(--kvlt-surface-2);
	overflow: hidden;
}

.kvlt-review-panel__fill {
	display: block;
	width: var(--kvlt-score-width, 0%);
	height: 100%;
	border-radius: 999px;
	/* Punkty gradientu MUSZA odpowiadac mapie w `kvlt_score_color()` (PHP) —
	   inaczej pasek i badge pokazuja dwa rozne kolory dla tej samej oceny.
	   Zaktualizowane razem z poglebieniem skali (2026-07-31). */
	background-image: linear-gradient(90deg, #071326, #1D5F8C, #2A8150, #557F27, #8A6D10, #AC550D, #C93B24, #C62828);
	background-size: var(--kvlt-gradient-size, 100%) 100%;
	background-repeat: no-repeat;
	box-shadow: 0 0 14px var(--kvlt-score-glow, transparent);
}

.kvlt-review-panel__embed {
	margin-top: 1.25rem;
}

.kvlt-review-panel__embed iframe {
	display: block;
	width: 100%;
	border-radius: var(--kvlt-radius);
}

/* -------------------------------------------------------------------------
   10. Paginacja
   ------------------------------------------------------------------------- */

.kvlt-pagination {
	margin-top: 2.5rem;
}

.kvlt-pagination__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center; /* wysrodkowana — wymog specyfikacji */
	gap: 0.375rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.kvlt-pagination__list .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding: 0 0.65rem;
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	color: var(--kvlt-text);
	font-family: var(--kvlt-font-display);
	font-weight: 700;
	font-size: 0.875rem;
}

.kvlt-pagination__list a.page-numbers:hover {
	border-color: var(--kvlt-accent);
	color: var(--kvlt-accent);
	text-decoration: none;
}

.kvlt-pagination__list .page-numbers.current {
	background: var(--kvlt-accent);
	border-color: var(--kvlt-accent);
	color: var(--kvlt-accent-contrast);
}

.kvlt-pagination__list .page-numbers.dots {
	border-color: transparent;
	color: var(--kvlt-muted);
}

/* Paginacja Content Views Pro (strony listingu `/muzyka/…`, `/koncerty/…`).
   Wtyczka rysuje wlasna liste w stylu Bootstrapa (biale kafle, niebieskie cyfry)
   dosunieta do lewej (`.text-left`). Motyw nie ma dostepu do jej szablonu, wiec
   nadpisujemy stylem — wysrodkowana i zgodna z natywna `.kvlt-pagination`.
   Zawezone do `.kvlt-cvlisting` (klasa dodawana stronom z listingiem CV Pro). */
.kvlt-cvlisting .pt-cv-pagination-wrapper {
	margin-top: 2.5rem;
	text-align: center; /* nadpisuje .text-left wtyczki */
}

/* Selektory z podwojna klasa listy (`.pt-cv-pagination.pagination`) + `!important`
   na wlasciwosciach, o ktore walczy CSS wtyczki — inaczej REMISUJEMY z jej
   regulami (2 klasy), a ze laduje sie pozniej, wygrywa. Ta sama technika co przy
   `.pt-cv-thumbnail` wyzej (motyw nie ma dostepu do szablonu CV Pro). */
.kvlt-cvlisting .pt-cv-pagination.pagination {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.375rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.kvlt-cvlisting .pt-cv-pagination.pagination > li {
	margin: 0;
}

.kvlt-cvlisting .pt-cv-pagination.pagination > li > a {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding: 0 0.65rem;
	border: 1px solid var(--kvlt-line) !important;
	border-radius: var(--kvlt-radius) !important;
	background: transparent !important;
	color: var(--kvlt-text) !important;
	font-family: var(--kvlt-font-display);
	font-weight: 700;
	font-size: 0.875rem;
	line-height: 1;
	cursor: pointer;
	transition: color var(--kvlt-transition), border-color var(--kvlt-transition), background-color var(--kvlt-transition);
}

.kvlt-cvlisting .pt-cv-pagination.pagination > li > a:hover,
.kvlt-cvlisting .pt-cv-pagination.pagination > li > a:focus-visible {
	border-color: var(--kvlt-accent) !important;
	color: var(--kvlt-accent) !important;
	text-decoration: none;
}

.kvlt-cvlisting .pt-cv-pagination.pagination > li.active > a {
	background: var(--kvlt-accent) !important;
	border-color: var(--kvlt-accent) !important;
	color: var(--kvlt-accent-contrast) !important;
	cursor: default;
}

.kvlt-cvlisting .pt-cv-pagination.pagination > li.disabled > a {
	border-color: transparent !important;
	color: var(--kvlt-muted) !important;
	cursor: default;
}

/* -------------------------------------------------------------------------
   11. Widgety i sidebar
   ------------------------------------------------------------------------- */

.kvlt-widget {
	margin-bottom: 1.75rem;
	max-width: 100%;
}

.kvlt-widget__title {
	margin: 0 0 0.75rem;
	padding-bottom: 0.5rem;
	border-bottom: 2px solid var(--kvlt-accent);
	font-size: 0.9375rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.kvlt-widget ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.kvlt-widget li + li {
	margin-top: 0.5rem;
}

.kvlt-widget img {
	height: auto;
}

/* Listy w widgetach (TOP10, polecane) — tekst, akcent dopiero na hoverze */
.kvlt .kvlt-widget li a {
	color: var(--kvlt-text);
	font-size: 0.875rem;
	line-height: 1.35;
}

.kvlt .kvlt-widget li a:hover,
.kvlt .kvlt-widget li a:focus-visible {
	color: var(--kvlt-accent);
	text-decoration: none;
}

/* Blok „Polecamy takze" — lista z miniatura (Etap 5).
   Kwadratowa miniatura 56 px + tytul w dwoch liniach: przy 300 px kolumny
   to najgestszy uklad, ktory pozostaje klikalny (cala pozycja jest linkiem). */
.kvlt-reco__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.kvlt-reco__item + .kvlt-reco__item {
	margin-top: 0.35rem;
	padding-top: 0.35rem;
	border-top: 1px solid var(--kvlt-line);
}

.kvlt .kvlt-reco__link {
	display: flex;
	gap: 0.65rem;
	align-items: center;
	padding: 0.3rem;
	margin: -0.3rem;
	border-radius: var(--kvlt-radius);
	color: var(--kvlt-text);
	text-decoration: none;
}

.kvlt .kvlt-reco__link:hover,
.kvlt .kvlt-reco__link:focus-visible {
	background: var(--kvlt-surface-2);
	color: var(--kvlt-text);
	text-decoration: none;
}

.kvlt-reco__media {
	flex: none;
	display: block;
	width: 56px;
	height: 56px;
	overflow: hidden;
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface-2);
}

/* `.kvlt .kvlt-reco__media img` (0,2,1), nie samo `.kvlt-reco__media img`
   (0,1,1): to drugie tylko REMISUJE z globalna `.kvlt img { height:auto }` i
   wygrywa jedynie kolejnoscia w pliku — krucha zaleznosc. Podnosimy specyficznosc,
   zeby miniatura zawsze wypelniala kadr (ten sam problem co przy `.kvlt-card__img`). */
.kvlt .kvlt-reco__media img,
.kvlt-reco__media--empty {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 42%;
}

.kvlt-reco__media--empty {
	background: var(--kvlt-img-empty);
}

.kvlt-reco__body {
	min-width: 0;
}

.kvlt-reco__title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-family: var(--kvlt-font-display);
	font-size: 0.8125rem;
	font-weight: 700;
	line-height: 1.3;
}

.kvlt .kvlt-reco__link:hover .kvlt-reco__title {
	color: var(--kvlt-accent);
}

.kvlt-reco__date {
	display: block;
	margin-top: 0.15rem;
	color: var(--kvlt-meta);
	font-size: 0.6875rem;
	letter-spacing: 0.03em;
}

/* Bloki reklamowe (SlideAnything, EMP) nie moga rozpychac kolumny */
.kvlt-widget .textwidget,
.kvlt-widget .custom-html-widget {
	max-width: 100%;
	overflow: hidden;
}

/* Niewypelniony slot AdSense (300x600) zostawial w ciemnym motywie bialy
   prostokat na kilkaset pikseli — lokalnie reklamy sie nie zaciagaja, ale
   na produkcji tez zdarzaja sie puste odslony. Google ustawia na elemencie
   `data-ad-status="unfilled"`, gdy nie ma czego pokazac — wtedy zwijamy slot
   (to zalecany przez Google sposob; NIE ukrywamy slotow wypelnionych). */
ins.adsbygoogle[data-ad-status="unfilled"] {
	display: none !important;
}

ins.adsbygoogle {
	background: transparent;
	/* AdSense ustawia szerokosc inline'em i na waskich ekranach potrafi
	   wyjsc poza kolumne (przycinal to `overflow:hidden` widgetu). Ograniczamy
	   go do szerokosci kontenera, zeby reklama trzymala sie wspolnego marginesu. */
	max-width: 100%;
}

/* -------------------------------------------------------------------------
   12. Stopka
   ------------------------------------------------------------------------- */

.kvlt-footer {
	border-top: 1px solid var(--kvlt-line);
	background: var(--kvlt-surface);
}

.kvlt-footer__inner {
	max-width: var(--kvlt-wide);
	margin: 0 auto;
	padding: 2rem var(--kvlt-gutter);
	text-align: center;
}

.kvlt-footer__menu {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.25rem 1.25rem;
	margin: 0 0 1rem;
	padding: 0;
	list-style: none;
	font-size: 0.875rem;
}

.kvlt-footer__about {
	max-width: 70ch;
	margin: 0 auto 1.5rem;
	color: var(--kvlt-muted);
	font-size: 0.875rem;
	line-height: 1.6;
}

.kvlt-footer__about strong {
	color: var(--kvlt-text);
	font-family: var(--kvlt-font-display);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.kvlt-footer__copy,
.kvlt-footer__credits {
	margin: 0;
	color: var(--kvlt-muted);
	font-size: 0.8125rem;
	letter-spacing: 0.04em;
}

.kvlt-footer__credits {
	margin-top: 0.4rem;
	font-size: 0.75rem;
	opacity: 0.85;
}

.kvlt-footer__sep {
	margin: 0 0.4rem;
	opacity: 0.5;
}

.kvlt .kvlt-footer__copy a,
.kvlt .kvlt-footer__credits a {
	color: var(--kvlt-muted);
}

.kvlt .kvlt-footer__copy a:hover,
.kvlt .kvlt-footer__credits a:hover {
	color: var(--kvlt-accent);
	text-decoration: none;
}

/* -------------------------------------------------------------------------
   13. 404
   ------------------------------------------------------------------------- */

.kvlt-404 {
	max-width: 560px;
	margin: 0 auto;
	padding: 3rem 0;
	text-align: center;
}

.kvlt-404__code {
	margin: 0;
	font-family: var(--kvlt-font-display);
	font-weight: 900;
	font-size: clamp(4rem, 18vw, 8rem);
	line-height: 1;
	color: var(--kvlt-accent);
}

.kvlt-404 .kvlt-pagetitle::after {
	margin-inline: auto;
}

.kvlt-404__text {
	color: var(--kvlt-muted);
}

.kvlt-404__form {
	margin-top: 1.5rem;
}

/* -------------------------------------------------------------------------
   14. Blokada scrolla przy otwartym menu mobilnym
   ------------------------------------------------------------------------- */

body.kvlt-nav-open {
	overflow: hidden;
}

@media (min-width: 62em) {
	body.kvlt-nav-open {
		overflow: visible;
	}
}

.ms-slide-container .ms-layer,
.ms-slide-container .ms-layer * {
  text-shadow:
    0 2px 10px rgba(0,0,0,.9),
    0 0 26px   rgba(0,0,0,.75),
    0 0 46px   rgba(0,0,0,.55) !important;
  /* Spojnosc z reszta strony: podpis slajdera to tytul polecanego wpisu, wiec
     ten sam font co tytuly (--kvlt-font-display / Fira Sans). MasterSlider
     narzuca wlasny „Open Sans" swoim CSS-em -> nadpisujemy z !important. */
  font-family: var(--kvlt-font-display) !important;
}

/* -------------------------------------------------------------------------
   12. Strona „Bilety" — stan „wkrotce" + oprawa pod integracje
   Placeholder pokazuje sie, DOPOKI kontener integracyjny jest pusty. Gdy
   zewnetrzny system wypelni `.biletomat-events-list`, placeholder znika sam.
   Wszystkie kolory z tokenow motywu -> dziala w trybie ciemnym i jasnym.
   ------------------------------------------------------------------------- */
.kvlt-tickets {
	display: block;
}

.kvlt-tickets__head {
	margin-bottom: 1.5rem;
}

.kvlt-tickets__lead {
	margin: 0.35rem 0 0;
	max-width: 60ch;
	color: var(--kvlt-muted);
	font-size: 1.0625rem;
}

/* Gdy integracja wypelni liste wydarzen — chowamy placeholder „wkrotce". */
.kvlt-tickets .biletomat-events-list:not(:empty) ~ .kvlt-tickets__soon {
	display: none;
}

/* Panel „wkrotce" */
.kvlt-tickets__stage {
	padding: clamp(1.5rem, 4vw, 3rem);
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface);
}

.kvlt-tickets__soon {
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(1.5rem, 4vw, 2.75rem);
	align-items: center;
}

@media (min-width: 56em) {
	.kvlt-tickets__soon {
		grid-template-columns: minmax(0, 42%) 1fr;
	}
}

/* Ilustracja biletow (inline SVG). Kolor linii = --kvlt-muted (adaptuje sie),
   napis „WKROTCE" = akcent. */
.kvlt-tickets__soon-art {
	display: flex;
	justify-content: center;
}

/* Dostarczona grafika biletow (assets/images/bilety.svg) jako <img>.
   Prefiks `.kvlt`, bo globalne `.kvlt img { max-width:100% }` (0,1,1) bije samo
   `.kvlt-tickets__art` (0,1,0) i `max-width` by nie zadzialalo.
   Delikatny cien to `drop-shadow` (idzie za KSZTALTEM przezroczystej grafiki, nie
   za prostokatem). Domyslnie (motyw ciemny) — bialy, subtelny akcent; w motywie
   jasnym — czarny. Niski alpha, zeby byl przyjemnym podkresleniem, nie mocnym. */
.kvlt .kvlt-tickets__art {
	display: block;
	width: 100%;
	max-width: 340px;
	height: auto;
	filter: drop-shadow(0 0 18px rgba(255, 255, 255, 0.16));
}

:root[data-theme="light"] .kvlt .kvlt-tickets__art {
	filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.22));
}

/* Mobile — grafika o 20% mniejsza (340 -> 272 px), zeby nie dominowala kadru. */
@media (max-width: 47.99em) {
	.kvlt .kvlt-tickets__art {
		max-width: 272px;
	}
}

.kvlt-tickets__soon-title {
	margin: 0;
	font-size: clamp(1.5rem, 3.2vw, 2.125rem);
	line-height: 1.15;
}

.kvlt-tickets__soon-title::after {
	content: "";
	display: block;
	width: 56px;
	height: 3px;
	margin-top: 0.7rem;
	border-radius: 2px;
	background: var(--kvlt-accent);
}

.kvlt-tickets__soon-text {
	margin: 1.1rem 0 0;
	max-width: 56ch;
	color: var(--kvlt-muted);
	line-height: 1.7;
}

/* Ramka informacyjna „i" */
.kvlt-tickets__note {
	display: flex;
	align-items: center;
	gap: 0.8rem;
	margin: 1.6rem 0 0;
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--kvlt-line);
	border-radius: var(--kvlt-radius);
	background: var(--kvlt-surface-2);
	color: var(--kvlt-text);
	font-size: 0.95rem;
	line-height: 1.5;
}

.kvlt-tickets__note-icon {
	flex: none;
	display: inline-flex;
	color: var(--kvlt-muted);
}

.kvlt-tickets__note-icon svg {
	width: 22px;
	height: 22px;
	stroke: currentColor;
	stroke-width: 1.6;
}

/* Pasek zaufania (3 cechy) i akapit „Masz pytania o bilety?" — USUNIETE
   na zyczenie klienta 2026-07-30 razem z markupem w page-bilety.php.
   Reguly zdjete, zeby nie zostawal martwy CSS. */

/* -------------------------------------------------------------------------
   13. HERO — rozmycie podczas przejscia miedzy slajdami
   Slajder jest w trybie 'fade' (crossfade zamiast przewijania). JS (kvlt.js)
   dodaje `.is-ms-blur` na `.kvlt-hero` na starcie zmiany slajdu i restartuje
   animacje.
   Blur to JEDNORAZOWY PULS (ostro -> blur -> ostro) o stalym czasie — NIE
   ramp w gore na starcie i w dol na koncu. Wczesniej blur schodzil dopiero na
   CHANGE_END (juz PO crossfade), przez co „ciagnal sie ogonem" i wyostrzal po
   pojawieniu sie nowego zdjecia. Puls domyka sie sam, zsynchronizowany z
   crossfade, wiec nie ma ogona. Rozmywamy TYLKO zdjecie (`.ms-slide-bgcont`),
   podpis zostaje ostry. */
@keyframes kvlt-hero-blur {
	0%   { filter: blur(0); }
	50%  { filter: blur(5px); }
	100% { filter: blur(0); }
}

.kvlt-hero.is-ms-blur .ms-view .ms-slide-bgcont {
	animation: kvlt-hero-blur 0.55s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
	.kvlt-hero.is-ms-blur .ms-view .ms-slide-bgcont {
		animation: none;
	}
}

/* -------------------------------------------------------------------------
   13b. HERO — nowoczesny loader (skeleton z polyskiem, jak na YT)
   MasterSlider domyslnie pokazuje maly bialy box z animowanym GIF-em
   (`.ms-loading` -> loading-2.gif) — staroszkolny spinner. Zastepujemy go
   „skeletonem": sam kontener ladowania (`.ms-loading-container`) wtyczka wstawia
   podczas ladowania z wysokoscia = szerokosc / aspect (czyli w KSZTALCIE hero)
   i USUWA po gotowosci (`MSSliderEvent.INIT`) — wiec nie trzeba zadnego JS.
   Malujemy w nim placeholder z przesuwajacym sie polyskiem; stary GIF chowamy.
   ------------------------------------------------------------------------- */
.kvlt-hero .ms-loading-container {
	background: var(--kvlt-surface-2);
	overflow: hidden; /* hero jest prostokatny (radius 0) — bez zaokraglen */
}

.kvlt-hero .ms-loading-container::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, 0.13) 50%, transparent 80%);
	transform: translateX(-100%);
	animation: kvlt-skeleton-sweep 1.4s ease-in-out infinite;
}

/* Tryb jasny — polysk musi byc ciemniejszy niz jasna powierzchnia, inaczej
   bialy sweep bylby niewidoczny. */
:root[data-theme="light"] .kvlt-hero .ms-loading-container::after {
	background: linear-gradient(100deg, transparent 20%, rgba(0, 0, 0, 0.07) 50%, transparent 80%);
}

@keyframes kvlt-skeleton-sweep {
	100% {
		transform: translateX(100%);
	}
}

/* Stary spinner (bialy box + loading-2.gif) chowamy na rzecz skeletonu. */
.kvlt-hero .ms-loading {
	display: none !important;
}

@media (prefers-reduced-motion: reduce) {
	.kvlt-hero .ms-loading-container::after {
		animation: none;
	}
}

/* (Ken Burns / zoom aktywnego slajdu — WYCOFANY. Animowany `transform: scale()`
   na zdjeciu klatkowal, bo w strukturze MasterSlidera (`overflow:hidden` na
   `.ms-view` i `.ms-slide-bgcont`) przegladarka nie kompozytowala go na GPU i
   re-rasteryzowala obraz co klatke. Probowane: scale na obrazie, scale na
   kontenerze, stala warstwa `translateZ(0)` + skala przez `@property` — objaw
   pozostawal. Zgodnie z decyzja klienta obraz zostaje STATYCZNY. Blur na
   przejsciu (sekcja 13) dziala niezaleznie i zostaje.) */

/* -------------------------------------------------------------------------
   15. HERO — kropki nawigacyjne (bullets)
   Budowane przez JS (kvlt.js) na podstawie liczby slajdow MasterSlidera.
   Wstawione do `.kvlt-hero__inner` (position: relative), na dole-srodku slidera.
   Aktywna kropka = akcent; klik -> gotoSlide(index).
   ------------------------------------------------------------------------- */
.kvlt-hero__dots {
	position: absolute;
	left: 50%;
	bottom: 0.9rem;
	transform: translateX(-50%);
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.35rem 0.55rem;
}

.kvlt-hero__dot {
	width: 9px;
	height: 9px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.45);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
	cursor: pointer;
	transition: background-color var(--kvlt-transition), transform var(--kvlt-transition);
}

.kvlt-hero__dot:hover,
.kvlt-hero__dot:focus-visible {
	background: rgba(255, 255, 255, 0.85);
	outline: none;
}

.kvlt-hero__dot.is-active {
	background: var(--kvlt-accent);
	transform: scale(1.3);
}

@media (max-width: 600px) {
	.kvlt-hero__dots {
		bottom: 0.6rem;
		gap: 0.4rem;
	}

	.kvlt-hero__dot {
		width: 7px;
		height: 7px;
	}
}

/* -------------------------------------------------------------------------
   16. KONKURSY — wyszarzanie zakonczonych + plakietka „Zakonczony"
   Klasa `.kvlt-card--ended` (kafle home/archiwa) i owijka `.kvlt-ended`
   (listing CV Pro) — patrz inc/konkurs.php.
   ------------------------------------------------------------------------- */
.kvlt-ended-badge {
	position: absolute;
	top: 0.5rem;
	left: 0.5rem;
	z-index: 3;
	padding: 0.2rem 0.5rem;
	border-radius: var(--kvlt-radius);
	background: rgba(14, 15, 17, 0.85);
	color: #fff;
	font-family: var(--kvlt-font-display);
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
	pointer-events: none;
}

/* Kafel zakonczonego konkursu (home/archiwa). Miniatura wyszarzona, tytul
   przygaszony; plakietka zostaje w pelnym kolorze (czytelna). */
.kvlt-card--ended .kvlt-card__media {
	filter: grayscale(0.95) brightness(0.85);
}

.kvlt-card--ended .kvlt-card__title {
	color: var(--kvlt-muted);
}

/* Zakonczony konkurs jest nieklikalny — kafel renderuje <span> zamiast <a>
   (patrz template-parts/card.php), wiec brak nawigacji. Tu tylko kursor i
   wylaczenie efektu hover, zeby wygladal na „martwy". */
.kvlt-card--ended .kvlt-card__link {
	cursor: default;
}

.kvlt-card--ended .kvlt-card__link:hover .kvlt-card__img {
	transform: none;
}

/* Listing Content Views Pro — miniatura owinieta w `.kvlt-ended`. */
.kvlt-cvlisting .kvlt-ended .pt-cv-thumbnail {
	filter: grayscale(0.95) brightness(0.85);
}

/* Delikatna biala „mgielka" (duza przezroczystosc) na miniaturze zakonczonego
   konkursu — dodatkowo, obok wyszarzenia, odroznia go od aktywnych (wyblakly,
   nieaktywny wyglad). Nakladka jest POD plakietka „Zakonczony" (z-index 3) i nad
   zdjeciem; nie lapie klikniec. Owijka (`.kvlt-card__media` / `.pt-cv-href-thumbnail`)
   ma `overflow:hidden`, wiec mgielka trzyma zaokraglenie kadru. Ta sama nakladka
   na kaflach (strona glowna, archiwa) i w listingu CV Pro (/konkursy). */
.kvlt-card--ended .kvlt-card__media::after,
.kvlt-cvlisting .kvlt-ended::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	background: rgba(255, 255, 255, 0.14);
	pointer-events: none;
}

/* Blokada przekierowania w listingu CVP: kazda pozycja (`.pt-cv-ifield`),
   ktora zawiera znacznik `.kvlt-ended`, ma wylaczone klikanie linkow —
   miniatury ORAZ osobnego linku tytulu. `:has()` wspierane przez wszystkie
   aktualne przegladarki. */
.kvlt-cvlisting .pt-cv-ifield:has(.kvlt-ended) a {
	pointer-events: none;
	cursor: default;
}


/* -------------------------------------------------------------------------
   17. BOX AUTORA (StarBox / `.abh_box`) pod wpisem

   Wtyczka wnosi WLASNA, jasna palete zakodowana na sztywno: `.abh_tab_content`
   ma `background:#fff`, zakladki `#eee`/`#fff` z tekstem `#333`. W ciemnym
   motywie dawalo to biale pudlo z jasnym, dziedziczonym tekstem — zmierzony
   kontrast **1,17:1**, czyli tresc praktycznie niewidoczna.

   ⚠️ Kazda regula wtyczki (themes/fancy/css/frontend.css) ma `!important`,
   wiec nadpisanie MUSI go uzyc — inaczej nie wygra niezaleznie od
   specyficznosci. To wyjatek uzasadniony, nie skrot.

   Kolory bierzemy wylacznie z tokenow motywu, wiec box dziala w obu motywach
   i zmienia sie razem z reszta strony.
   ------------------------------------------------------------------------- */
.abh_box {
	margin-top: 2rem !important;
	color: var(--kvlt-text) !important;
}

/* Pasek zakladek — linia pod spodem w kolorze obramowan motywu. */
.abh_box .abh_tabs {
	border-bottom: 1px solid var(--kvlt-line) !important;
	padding-left: 0 !important;
}

/* Zakladka NIEAKTYWNA: przygaszona, ale nadal czytelna (--kvlt-meta spelnia
   4.5:1 w obu motywach). Wieksze pola klikalne niz domyslne 4/10 px. */
.abh_box .abh_tabs li a {
	color: var(--kvlt-meta) !important;
	background-color: transparent !important;
	border: 1px solid transparent !important;
	border-bottom: none !important;
	border-radius: var(--kvlt-radius) var(--kvlt-radius) 0 0 !important;
	padding: 0.5rem 0.9rem !important;
	font-family: var(--kvlt-font-display) !important;
	font-size: 0.85rem !important;
	font-weight: 600 !important;
	letter-spacing: 0.03em !important;
	text-transform: uppercase !important;
	transition: color 0.15s ease, background-color 0.15s ease !important;
}

.abh_box .abh_tabs li a:hover {
	color: var(--kvlt-text) !important;
	background-color: var(--kvlt-surface) !important;
	padding: 0.5rem 0.9rem !important;
}

/* Zakladka AKTYWNA: pelny kontrast tekstu, tlo zlaczone z panelem ponizej
   i karmazynowy znacznik u gory — stan aktywny ma byc widoczny takze bez
   rozroznienia koloru (nie polegamy na samym odcieniu). */
.abh_box .abh_tabs li.abh_active a,
.abh_box .abh_tabs li.abh_active a:hover {
	color: var(--kvlt-text) !important;
	background-color: var(--kvlt-surface) !important;
	border: 1px solid var(--kvlt-line) !important;
	border-top: 2px solid var(--kvlt-accent) !important;
	border-bottom: none !important;
	padding: 0.5rem 0.9rem !important;
}

/* Panel tresci — zrodlo problemu: bylo `background:#fff !important`. */
.abh_box .abh_tab_content {
	background: var(--kvlt-surface) !important;
	color: var(--kvlt-text) !important;
	border: 1px solid var(--kvlt-line) !important;
	border-top: none !important;
	border-radius: 0 0 var(--kvlt-radius) var(--kvlt-radius) !important;
	padding: 1rem !important;
}

/* Nazwisko autora — wtyczka wymusza `#333`, nieczytelne na ciemnym tle. */
.abh_box .abh_tab_content .abh_text .abh_name,
.abh_box .abh_tab_content .abh_text .fn,
.abh_box .abh_tab_content .abh_text .fn a,
.abh_box .abh_tab_content .abh_text .abh_name a {
	color: var(--kvlt-text) !important;
	font-family: var(--kvlt-font-display) !important;
	text-decoration: none !important;
}

.abh_box .abh_tab_content .abh_text .fn a:hover,
.abh_box .abh_tab_content .abh_text .abh_name a:hover {
	color: var(--kvlt-accent-text) !important;
}

/* Opis, stanowisko i daty przy liscie wpisow — rola pomocnicza. */
.abh_box .abh_tab_content .abh_text .abh_description,
.abh_box .abh_tab_content .abh_text .abh_job,
.abh_box .abh_tab_content .abh_text .abh_job span,
.abh_box .abh_tab_content .abh_text ul li span {
	color: var(--kvlt-meta) !important;
}

/* Linki w tresci boxa (lista „Latest Posts", „see all"). */
.abh_box .abh_tab_content .abh_text a,
.abh_box .abh_tab_content .abh_text ul li a,
.abh_box .abh_tab_content .abh_text .abh_allposts a {
	color: var(--kvlt-accent-text) !important;
}

.abh_box .abh_tab_content .abh_text a:hover {
	color: var(--kvlt-accent-text-hover) !important;
}

/* Awatar — kolisty, z obwodka w kolorze linii, spojnie z reszta motywu. */
.abh_box .abh_tab_content .abh_image img {
	border-radius: 50% !important;
	border: 1px solid var(--kvlt-line) !important;
}

/* Na waskich ekranach zakladki potrafia sie lamac — zwezamy odstepy zamiast
   pozwolic im zawinac sie w dwa rzedy nachodzace na linie. */
@media (max-width: 480px) {
	.abh_box .abh_tabs li a,
	.abh_box .abh_tabs li a:hover,
	.abh_box .abh_tabs li.abh_active a,
	.abh_box .abh_tabs li.abh_active a:hover {
		padding: 0.45rem 0.6rem !important;
		font-size: 0.78rem !important;
	}
}
