/* Symulator Sowy — ekrany 1a–1f, komponenty, responsywność (mobile-first, min 360 px). */

/* `clip` po `hidden`: przycina tak samo, ale nie robi z powłoki pudełka przewijania - fokus
   (klawiatura, okno zdarzenia) nie przesunie całej aplikacji, zostawiając pusty pas pod nawigacją. */
.sowa-app { position: relative; border-radius: var(--radius-sm); overflow: hidden; overflow: clip; isolation: isolate; container: sowa / inline-size; }

/* Warstwa (powiększenie zdjęcia) nosi klasę `sowa-app` wyłącznie dla palety i typografii -
   nie jest pudełkiem aplikacji, więc wszystko, co z tej klasy robi pudełko, trzeba cofnąć.
   Najbardziej szkodzi `isolation: isolate`: zamyka warstwę we własnym kontekście układania,
   a wtedy `z-index: 9999` powiększenia przegrywa z przyciskiem „Zamknij” okna (z-index: 2),
   bo porównywane są dopiero pudełka, nie ich wnętrza. */
.sowa-app.sowa-warstwa { position: static; overflow: visible; isolation: auto; container-type: normal; border-radius: 0; }

.sowa-app .sowa-loading { padding: 40px; text-align: center; color: var(--color-neutral-700); }
.sowa-app .sowa-error { padding: 24px; color: var(--color-accent-800); }
.sowa-app .sowa-error--box { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; background: var(--color-accent-100); border-radius: var(--radius-md); margin: 16px; }
.sowa-app .sowa-error--box p { margin: 0; }
.sowa-app--maintenance { padding: 8px; }

/* animacje wg ustawień (look.animations) */
.sowa-app[data-animations="none"] *, .sowa-app[data-animations="none"] *::before, .sowa-app[data-animations="none"] *::after { animation: none !important; transition: none !important; }
.sowa-app[data-animations="reduced"] .sowa-screen, .sowa-app[data-animations="reduced"] .sowa-event, .sowa-app[data-animations="reduced"] .sowa-event-backdrop { animation: none; }
.sowa-app[data-animations="reduced"] .sowa-meter__fill, .sowa-app[data-animations="reduced"] .sowa-weight__marker, .sowa-app[data-animations="reduced"] .sowa-weight__band { transition-duration: .15s; }
.sowa-app .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sowa-app .sowa-stack { display: flex; flex-direction: column; gap: 14px; }
.sowa-app .sowa-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.sowa-app .sowa-screen { animation: sowa-fade .25s ease-out; }
.sowa-app .sowa-icon { width: 1em; height: 1em; stroke: currentColor; fill: none; stroke-width: 2.75; stroke-linecap: round; stroke-linejoin: round; flex: none; }

@keyframes sowa-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sowa-pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: scale(1); } }
@keyframes sowa-drift { 0% { transform: translateY(0); } 50% { transform: translateY(-4px); } 100% { transform: translateY(0); } }
@keyframes sowa-spin { to { transform: rotate(360deg); } }

/* ================= 1a Start ================= */
.sowa-start .nav { padding: 12px 20px; border-bottom: 1px solid var(--color-divider); }
.sowa-start .nav a.is-hidden-mobile { display: none; }
.sowa-start__grid { padding: 24px 20px 32px; display: grid; grid-template-columns: 1fr; gap: 28px; align-items: start; }
/* Tytuł po klasie, nie po znaczniku: ekran startowy ma teraz `h2` (patrz screens/Start.js),
   a wygląd nie ma się zmienić przez sam poziom nagłówka. */
.sowa-start__intro .sowa-start__title { font-size: clamp(30px, 6vw, 46px); margin: 14px 0 12px; line-height: 1.05; text-wrap: balance; }
.sowa-start__intro .lead { font-size: 15px; color: var(--color-neutral-700); text-wrap: pretty; }
/* Nadanie imienia: pierwsza decyzja gracza, więc stoi tuż nad przyciskiem startu. */
.sowa-start__imie { display: grid; gap: 4px; margin-top: 20px; max-width: 320px; }
.sowa-start__imie-label { font-size: 13px; font-weight: 700; color: var(--color-accent-800); }
.sowa-start__imie-input {
	font: inherit; font-size: 16px; padding: 9px 12px;
	border-radius: var(--radius-sm); border: 1px solid var(--color-neutral-500);
	background: var(--color-bg); color: var(--color-text); width: 100%;
}
.sowa-start__imie-input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.sowa-start__imie-hint { margin: 0; font-size: 12px; line-height: 1.45; color: var(--color-neutral-700); text-wrap: pretty; }
.sowa-start__cta { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.sowa-start__cta .btn-primary { padding: 12px 24px; font-size: 15px; }
.sowa-start__footer { font-size: 12px; color: var(--color-neutral-700); margin-top: 20px; }
.sowa-species-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
/* .sowa-app .card ustawia border: 0 — selektory zaznaczenia muszą mieć wyższą specyficzność */
.sowa-app .card.sowa-species-card { gap: 10px; cursor: pointer; border: 2px solid transparent; width: 100%; position: relative; transition: border-color .15s, transform .15s, box-shadow .15s; }
.sowa-app .card.sowa-species-card:hover { transform: translateY(-2px); border-color: var(--color-accent-300); }
.sowa-app .card.sowa-species-card.is-selected { border-color: var(--color-accent); box-shadow: 0 0 0 4px var(--color-accent-100), var(--shadow-md); background: var(--color-bg); }
.sowa-app .card.sowa-species-card.is-selected::after { content: '✓'; position: absolute; top: 12px; right: 12px; width: 26px; height: 26px; border-radius: 50%; background: var(--color-accent-700); color: var(--color-bg); font-weight: 700; font-size: 14px; display: grid; place-items: center; box-shadow: var(--shadow-sm); }
.sowa-app .card.sowa-species-card.is-selected .card-title { color: var(--color-accent-800); }
.sowa-app[data-animations="reduced"] .card.sowa-species-card, .sowa-app[data-animations="none"] .card.sowa-species-card { transition: none; }
.sowa-species-card__tags { display: flex; gap: 6px; flex-wrap: wrap; }
.sowa-species-card .card-body { min-height: 0; }
.sowa-resume { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; background: var(--color-accent-2-100); color: var(--color-accent-2-900); border-radius: var(--radius-md); padding: 10px 14px; font-size: 13px; margin-top: 16px; }

.sowa-start__intro-link { font-size: 12px; margin-top: 8px; }

/* ================= Intro (zanim zaczniesz) ================= */
.sowa-intro { padding: 20px 16px 24px; display: grid; place-items: center; min-height: 520px; background: linear-gradient(180deg, var(--color-surface), var(--color-bg)); }
.sowa-intro__card { width: min(760px, 100%); background: var(--color-bg); border-radius: calc(var(--radius-lg) * 1.15); box-shadow: var(--shadow-lg); padding: 20px 20px 18px; display: flex; flex-direction: column; gap: 16px; }
.sowa-intro__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sowa-intro__skip { font-size: 12px; }
.sowa-intro__body { display: flex; flex-direction: column; gap: 12px; animation: sowa-fade .25s ease-out; }
.sowa-intro__body.is-highlight { background: var(--color-accent-100); border-radius: var(--radius-lg); padding: 16px; margin: 0 -4px; }
.sowa-intro__icon { width: 52px; height: 52px; border-radius: 50%; background: var(--color-accent-2-100); color: var(--color-accent-2-800); display: grid; place-items: center; }
.sowa-intro__icon .sowa-icon { width: 24px; height: 24px; }
.sowa-intro .sowa-intro__title { font-size: clamp(26px, 5vw, 36px); margin: 0; line-height: 1.1; text-wrap: balance; }
.sowa-intro__text p { font-size: 15px; color: var(--color-neutral-800); margin: 0 0 10px; text-wrap: pretty; }
.sowa-intro__text p:last-child { margin-bottom: 0; }
.sowa-intro__phases { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 10px; position: relative; }
.sowa-intro__phase { position: relative; padding: 10px 12px 10px 34px; border-radius: var(--radius-md); background: var(--color-surface); font-size: 13px; display: grid; gap: 2px; }
.sowa-intro__phase strong { font-family: var(--font-heading); font-weight: 700; font-size: 15px; }
.sowa-intro__phase span { color: var(--color-neutral-700); }
.sowa-intro__phase em { font-style: normal; font-size: 11px; color: var(--color-accent-800); letter-spacing: .06em; text-transform: uppercase; }
.sowa-intro__phase-dot { position: absolute; left: 12px; top: 15px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--color-accent); background: var(--color-bg); }
.sowa-intro__phase.is-current { background: var(--color-accent-100); outline: 2px solid var(--color-accent); }
.sowa-intro__phase.is-current .sowa-intro__phase-dot { background: var(--color-accent); }
.sowa-intro__nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; border-top: 1px solid var(--color-divider); padding-top: 14px; flex-wrap: wrap; }
.sowa-intro__dots { display: flex; gap: 6px; }
.sowa-intro__dot { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--color-accent); background: transparent; padding: 0; cursor: pointer; }
.sowa-intro__dot.is-done { background: var(--color-accent); }
.sowa-intro__dot.is-current { background: var(--color-accent-300); }

/* ================= Image circle / placeholder ================= */
.sowa-img { position: relative; width: var(--sowa-img-size, 96px); height: var(--sowa-img-size, 96px); border-radius: 50%; overflow: hidden; background: var(--color-neutral-200); display: grid; place-items: center; flex: none; }
/*
 * Zdjęcie kotwiczymy absolutnie do kółka, zamiast zostawiać je komórką siatki.
 * W siatce `height: 100%` nie miało do czego się odnieść (wiersz `auto` + wyśrodkowanie),
 * więc pionowe zdjęcia zachowywały naturalną wysokość i były UCINANE od dołu zamiast
 * wykadrowane - w kółku lądowała gałąź, a sowa poza kadrem. Procent liczony od
 * pozycjonowanego rodzica rozwiązuje się zawsze, więc `object-fit: cover` ma wreszcie ramę.
 * Placeholder zostaje zwykłą komórką siatki i nadal jest wyśrodkowany.
 */
.sowa-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 40%; }
.sowa-img--placeholder { color: var(--color-neutral-500); }
.sowa-img--placeholder svg { width: 45%; height: 45%; stroke-width: 1.6; }
/*
 * Prostokąt wypełnia pozycjonowaną ramkę rodzica (zdjęcie pytania w quizie i w trybie zajęć).
 * Nie `height: 100%`: ramki mają samo `min-height`, a procent od wysokości `auto` daje zero -
 * od 0.2.0-beta11 zdjęcia pytań miały 0 px wysokości i widać je było tylko po powiększeniu.
 */
.sowa-img--rect { position: absolute; inset: 0; width: auto; height: auto; border-radius: 0; aspect-ratio: auto; }

/* ================= Powłoka rozgrywki (0.2) =================
   Pasek górny na całą szerokość, pod nim korpus: nawigacja + treść ekranu.
   Postać nawigacji wybiera CSS, nie JavaScript - decyduje szerokość POJEMNIKA aplikacji,
   bo symulator bywa osadzony w wąskiej kolumnie tekstu na szerokim ekranie. */
/* ---- Pora dnia ----
   Rozgrywka trwa czternaście dni po trzy pory, a do 0.2 jedynym śladem pory był napis
   w pasku. Teraz zmienia się cała oprawa: barwa tła, gęstość lasu i światło na zdjęciu
   sowy. Zmiana jest **powolna** (1,6 s) - ma być odczuwalna jako zapadanie zmroku,
   a nie jako przeskok; gracz kończy turę i widzi, że zrobiło się ciemniej.

   Kolory dobierane WYŁĄCZNIE jako półprzezroczyste warstwy nad tłem, nigdy jako zmiana
   koloru tekstu. To celowe: kontrast napisów został policzony raz i ma taki zostać
   niezależnie od pory.

   Efektów jest pięć i każdy działa gdzie indziej, bo pojedyncza płaska warstwa barwy była
   za słaba - żeby dało się ją zauważyć, musiałaby przyciemnić też napisy stojące wprost
   na tle („Codzienne czynności”, „Czas w tej turze”), a tego robić nie wolno. Zamiast
   jednej mocnej warstwy pracuje więc pięć słabszych, każda tam, gdzie tekstu nie ma:

     1. barwa pory na tle aplikacji (`.sowa-gra__pora`),
     2. łuna nieba u góry i winieta przy dolnych rogach (`.sowa-gra__niebo`),
     3. gwiazdy - wyłącznie nocą, z powolnym migotaniem (`.sowa-gra__niebo::after`),
     4. sylwetka lasu, gęstniejąca po zmroku (`.sowa-gra::before`),
     5. światło i barwa samego zdjęcia sowy (`.sowa-hero__foto`).

   Razem dają zmianę, którą widać kątem oka; osobno żaden nie dotyka czytelności. */
.sowa-gra {
	position: relative; display: flex; flex-direction: column; min-height: 0;
	--sowa-pora-barwa: transparent;
	--sowa-pora-krycie: 0;
	--sowa-las-krycie: .20;
	--sowa-swiatlo: transparent;
	--sowa-niebo: none;
	--sowa-gwiazdy-krycie: 0;
	--sowa-foto-filtr: none;
	--sowa-nalot: transparent;
}
.sowa-gra[data-phase="day"] {
	--sowa-pora-barwa: var(--color-accent-200);
	--sowa-pora-krycie: .38;
	--sowa-las-krycie: .16;
	--sowa-swiatlo: linear-gradient(200deg, rgba(255, 240, 205, .46), transparent 58%);
	/* Dzień: światło wpada z góry i rozjaśnia, zamiast przyciemniać. */
	--sowa-niebo:
		radial-gradient(150% 70% at 50% -10%, rgba(255, 246, 219, .55), transparent 62%),
		radial-gradient(60% 40% at 88% 4%, rgba(255, 228, 160, .42), transparent 70%);
	--sowa-foto-filtr: saturate(1.08) brightness(1.04);
	/* Dzień jest punktem odniesienia - nic nie nakładamy. */
	--sowa-nalot: transparent;
}
.sowa-gra[data-phase="evening"] {
	--sowa-pora-barwa: var(--color-accent-500);
	--sowa-pora-krycie: .30;
	--sowa-las-krycie: .34;
	--sowa-swiatlo: linear-gradient(200deg, rgba(255, 168, 78, .52), rgba(105, 58, 24, .30) 76%);
	/* Wieczór: słońce nisko przy prawej krawędzi, a od dołu podchodzi już cień. */
	--sowa-niebo:
		radial-gradient(90% 52% at 82% 8%, rgba(255, 168, 82, .50), transparent 68%),
		radial-gradient(150% 85% at 50% 108%, rgba(78, 42, 18, .40), transparent 62%);
	--sowa-foto-filtr: saturate(1.15) brightness(.95) sepia(.12);
	--sowa-nalot: rgba(255, 196, 140, .40);
}
.sowa-gra[data-phase="night"] {
	--sowa-pora-barwa: var(--color-accent-2-900);
	--sowa-pora-krycie: .26;
	--sowa-las-krycie: .52;
	--sowa-swiatlo: linear-gradient(200deg, rgba(150, 182, 232, .30), rgba(10, 16, 34, .58) 70%);
	/* Noc: zimna poświata księżyca w lewym górnym rogu i ciemność wchodząca od dołu. */
	--sowa-niebo:
		radial-gradient(42% 26% at 14% 6%, rgba(198, 218, 255, .38), transparent 72%),
		radial-gradient(160% 95% at 50% 106%, rgba(6, 11, 28, .58), transparent 66%),
		radial-gradient(120% 60% at 50% -6%, rgba(16, 24, 52, .40), transparent 60%);
	--sowa-gwiazdy-krycie: 1;
	--sowa-foto-filtr: saturate(.68) brightness(.74) contrast(1.06);
	--sowa-nalot: rgba(150, 170, 220, .40);
}
/* Barwa pory jako osobna warstwa pod treścią - nie dotyka żadnego koloru tekstu. */
.sowa-gra__pora {
	position: absolute; inset: 0; z-index: 0; pointer-events: none;
	background: var(--sowa-pora-barwa); opacity: var(--sowa-pora-krycie);
	transition: background-color 1.6s ease, opacity 1.6s ease;
}
/*
 * Niebo: łuna z góry i cień od dołu. Osobny element, a nie pseudoelement warstwy barwy,
 * bo `opacity` rodzica mnoży się przez krycie dziecka - gwiazdy przygaszone kryciem nocnej
 * barwy (26 %) byłyby ledwo widoczne. Tu krycie siedzi w samych gradientach.
 */
.sowa-gra__niebo {
	position: absolute; inset: 0; z-index: 0; pointer-events: none;
	background: var(--sowa-niebo);
	transition: background 1.6s ease;
}
/*
 * Gwiazdy: stałe punkty, nie obrazek. Stoją w LEWEJ kolumnie, nad koronami lasu - to jedyny
 * duży kawałek ekranu, na którym naprawdę widać tło. Pierwsza wersja rozsypywała je po całej
 * górnej krawędzi i nie było ich widać wcale: tam stoi pasek i karty z własnym tłem.
 * Migotanie jest powolne (7 s) i płytkie, żeby dało się je zauważyć dopiero przy dłuższym
 * patrzeniu, a nie żeby ciągnęło wzrok znad rozgrywki.
 */
.sowa-gra__niebo::after {
	content: ''; position: absolute; inset: 0; pointer-events: none;
	opacity: var(--sowa-gwiazdy-krycie);
	transition: opacity 1.6s ease;
	background-repeat: no-repeat;
	background-image:
		radial-gradient(1.7px 1.7px at 4% 44%, rgba(255, 255, 245, .95), transparent 100%),
		radial-gradient(1.2px 1.2px at 9% 38%, rgba(255, 255, 245, .7), transparent 100%),
		radial-gradient(1.5px 1.5px at 13% 49%, rgba(255, 255, 245, .85), transparent 100%),
		radial-gradient(1.1px 1.1px at 6% 55%, rgba(255, 255, 245, .65), transparent 100%),
		radial-gradient(1.8px 1.8px at 17% 41%, rgba(255, 255, 245, .9), transparent 100%),
		radial-gradient(1.2px 1.2px at 2% 61%, rgba(255, 255, 245, .75), transparent 100%),
		radial-gradient(1.4px 1.4px at 11% 64%, rgba(255, 255, 245, .8), transparent 100%),
		radial-gradient(1.1px 1.1px at 20% 57%, rgba(255, 255, 245, .6), transparent 100%),
		radial-gradient(1.6px 1.6px at 7% 71%, rgba(255, 255, 245, .7), transparent 100%),
		radial-gradient(1.3px 1.3px at 15% 34%, rgba(255, 255, 245, .8), transparent 100%);
	animation: sowa-migotanie 7s ease-in-out infinite;
}
/*
 * Nalot barwny NAD treścią - jedyna warstwa, która dosięga kart i paska, więc bez niej
 * zmiana pory kończyła się na marginesach między kartami. Krycie dobrane pomiarem: przy
 * nocnych 14 % najsłabsza para tekstu na karcie trzyma się powyżej progu 4,5:1 (mierzone
 * w przeglądarce, nie z palety - paleta nie wie o warstwach). `multiply`, bo ma przyciemniać
 * scenę, a nie kłaść na niej mlecznej mgły.
 */
.sowa-gra::after {
	content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
	background: var(--sowa-nalot);
	mix-blend-mode: multiply;
	transition: background 1.6s ease;
}
@keyframes sowa-migotanie {
	0%, 100% { filter: brightness(1); }
	50% { filter: brightness(.55); }
}
/* Sylwetka lasu w lewym dolnym rogu rozgrywki - jak w projekcie graficznym. Drzewa stoją
   na dolnej krawędzi i rosną w górę, więc nic pod nimi nie trzeba dopełniać: wcześniejsza
   wersja rosła spod menu i kończyła się w powietrzu, przez co pod koronami musiała stać
   druga warstwa maski udająca grunt.

   Maska, nie obrazek: kształt bierze kolor z palety, więc działa też w motywie ciemnym
   i wysokokontrastowym. `pointer-events: none`, bo to tło; `aria-hidden` niepotrzebne,
   bo pseudoelement i tak nie trafia do drzewa dostępności. Przy zredukowanym ruchu nic
   nie znika: to obraz, nie animacja. */
.sowa-gra::before {
	content: ''; position: absolute; left: 0; bottom: 0; z-index: 0;
	/*
	 * Proporcja pliku to 500×750, więc wysokość jest półtora raza większa od szerokości.
	 * Las jest szerszy niż pasek nawigacji i celowo wychodzi spod kart - inaczej zostawał
	 * niską kępą w samym rogu i gubił się na tle pustej kolumny.
	 */
	width: min(300px, 22vw); height: min(450px, 33vw);
	pointer-events: none; background: var(--color-accent-2-900);
	/* Nocą las gęstnieje - o zmroku sylwetki drzew są najwyraźniejsze. */
	opacity: var(--sowa-las-krycie);
	transition: opacity 1.6s ease;
	-webkit-mask: url(../img/las.svg) no-repeat left bottom / 100% 100%;
	mask: url(../img/las.svg) no-repeat left bottom / 100% 100%;
}
/* `:not(.sowa-gra__pora)` jest tu konieczne: bez niego ta reguła nadpisywała warstwie
   pory `position: absolute` na `relative`, więc jej wysokość spadała do zera i barwa
   pory nie malowała niczego. Wyszło to dopiero z pomiaru pudełka - na oko wyglądało,
   że działa, bo tło przyciemniało okno zdarzenia. */
.sowa-gra > *:not(.sowa-gra__pora):not(.sowa-gra__niebo) { position: relative; z-index: 1; }
@container sowa (max-width: 900px) {
	/* Na telefonie nawigacja schodzi na dół ekranu jako pasek ikon - las nie ma tam gdzie
	   rosnąć i tylko zaciemniałby podpisy. W projekcie mobilnym też go nie ma.
	   Barwa pory i światło na zdjęciu zostają: one nie zabierają miejsca. */
	.sowa-gra::before { display: none; }
	/* Przycisk „Zamknij” zwisa ze środka górnej krawędzi okna. Na szerokim ekranie wisi nad
	   pustym środkiem paska, ale na telefonie kładł się na nazwie symulatora i na pogodzie.
	   Robimy mu miejsce, zamiast przenosić go w róg: stałe miejsce wyjścia jest warte
	   te kilkadziesiąt pikseli, a w rogach stoją logo i przyciski pomocy. */
	.sowa-modal__tresc .sowa-pasek { padding-top: 52px; }
}

/* Zmiana pory to informacja o stanie gry, więc przy zredukowanym ruchu **zostaje** -
   znika samo przejście. Ustawienie z panelu (`data-animations`) traktujemy tak samo
   jak systemowe: ktoś, kto prosi o mniej ruchu, dostaje zmianę natychmiastową. */
@media (prefers-reduced-motion: reduce) {
	.sowa-gra__pora, .sowa-gra__niebo, .sowa-gra::before, .sowa-gra::after,
	.sowa-hero__foto::after, .sowa-hero__foto img { transition: none !important; }
	/* Gwiazdy zostają, gaśnie samo migotanie: to ozdoba w ruchu, a nie nośnik informacji. */
	.sowa-gra__niebo::after { animation: none; transition: none; }
}
.sowa-app[data-animations="none"] .sowa-gra__pora,
.sowa-app[data-animations="none"] .sowa-gra__niebo,
.sowa-app[data-animations="none"] .sowa-hero__foto img,
.sowa-app[data-animations="none"] .sowa-hero__foto::after { transition: none; }
.sowa-app[data-animations="none"] .sowa-gra__niebo::after,
.sowa-app[data-animations="reduced"] .sowa-gra__niebo::after { animation: none; }
/* Wąsko: treść, a pod nią zakładki. Szeroko: pasek z boku, treść obok.
   To ten sam węzeł `.sowa-nav` w obu przypadkach - w drzewie stoi przed treścią
   (czytnik ekranu dostaje najpierw nawigację), a `order` przesuwa go wzrokowo pod nią. */
.sowa-gra__korpus { display: flex; flex-direction: column; align-items: stretch; min-height: 0; flex: 1; }
.sowa-gra__tresc { flex: 1; min-width: 0; }
/*
 * Zakładki trzymają się dolnej krawędzi ekranu, zamiast odjeżdżać z treścią.
 *
 * `position: sticky` stało dotąd na `.sowa-nav__dol`, czyli na elemencie, którego rodzic
 * `.sowa-nav` ma **dokładnie tę samą wysokość** - a sticky przesuwa się wyłącznie w obrębie
 * pudełka rodzica. Nie było więc czym się przykleić i zakładki jechały w dół razem z kartami.
 * Przypięcie siedzi teraz na `.sowa-nav`, którego rodzic (`.sowa-gra__korpus`) rośnie z całą
 * treścią, więc zakres jest tak długi jak ekran gry.
 *
 * Sticky, nie fixed: symulator bywa osadzony w kolumnie tekstu na zwykłej stronie, a `fixed`
 * przykleiłby menu do okna przeglądarki także wtedy, gdy gra jest daleko poza widokiem.
 */
.sowa-nav { order: 2; display: flex; flex-direction: column; position: sticky; bottom: 0; z-index: 3; }

/* Zakładki u dołu: domyślna postać, bo wąsko jest częściej niż szeroko. */
.sowa-nav__bok { display: none; }
.sowa-nav__dol {
	display: grid; grid-template-columns: repeat(5, 1fr); gap: 2px;
	padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px));
	background: var(--color-bg); border-top: 1px solid var(--color-divider);
}
.sowa-nav__zakladka {
	display: flex; flex-direction: column; align-items: center; gap: 3px;
	padding: 7px 2px; border: 0; border-radius: var(--radius-md);
	background: none; color: var(--color-neutral-700); cursor: pointer;
	font-size: 11px; line-height: 1.15; font-family: inherit;
}
.sowa-nav__zakladka .sowa-icon { width: 20px; height: 20px; }
.sowa-nav__zakladka.is-active { background: var(--color-accent-2-700); color: var(--color-bg); }
.sowa-nav__zakladka:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

@container sowa (min-width: 900px) {
	.sowa-gra__korpus { flex-direction: row; }
	/* Na szerokim ekranie nawigacja jest kolumną z boku - przypinanie do dołu nie ma sensu. */
	.sowa-nav { order: 0; position: static; }
	.sowa-nav__dol { display: none; }
	.sowa-nav__bok {
		display: flex; flex-direction: column; gap: 4px;
		width: 190px; flex: none; padding: 16px 12px;
		border-right: 1px solid var(--color-divider);
	}
	.sowa-nav__poz {
		display: flex; align-items: center; gap: 10px;
		padding: 10px 12px; border: 0; border-radius: var(--radius-md);
		background: none; color: var(--color-text); cursor: pointer;
		font-size: 14px; font-family: inherit; text-align: left;
	}
	.sowa-nav__poz:hover { background: var(--color-surface); }
	.sowa-nav__poz.is-active { background: var(--color-accent-2-700); color: var(--color-bg); }
	.sowa-nav__poz:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
}

/* ---- Miękkość: karty jaśniejsze od tła, uniesione cieniem ----
   Do 0.2.0-beta10 karta miała tło `surface`, czyli CIEMNIEJSZE niż strona, zero cienia
   i wąski margines wewnętrzny. Wychodziło z tego beż na beżu: wszystko na jednym
   poziomie, każdy prostokąt tak samo ważny. Projekt robi odwrotnie - strona jest ciepła
   i ciemniejsza, a karty na niej leżą jasne i lekko uniesione.

   Zmiana jest zamknięta w `.sowa-gra`, czyli w samej rozgrywce. Encyklopedia, quizy
   i tryb zajęć zostają jak były - właściciel je już zaakceptował i nie ma powodu ich
   ruszać przy okazji.

   Kontrast na tym zyskuje, nie traci: tekst drugoplanowy na jasnej karcie ma 5,53:1
   zamiast 4,92:1, a napisy stojące wprost na tle strony zostają przy 4,92:1. */
.sowa-gra { background: var(--color-surface); }
.sowa-gra .card {
	background: var(--color-bg);
	box-shadow: var(--shadow-sm);
	padding: 18px;
	gap: 12px;
}
/* Pasek górny jasny, oddzielony od tła rozgrywki cienką kreską - jak w projekcie. */
.sowa-gra .sowa-pasek { background: var(--color-bg); }
/*
 * Pasek tury pod paskiem górnym: zegar, czas zużyty w turze i „Zakończ turę” na każdej
 * zakładce (0.2.0-beta23). Wąsko zegar zajmuje cały wiersz, a licznik z przyciskiem idą pod nim.
 */
.sowa-tura {
	display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
	padding: 8px 16px; background: var(--color-bg); border-bottom: 1px solid var(--color-divider);
}
/* Wąsko: zegar i przycisk w jednym wierszu, licznik czasu drobno pod nimi - na telefonie
   pasek górny z paskiem tury i tak zjada ćwierć ekranu. */
.sowa-tura__zegar { flex: 1 1 160px; min-width: 0; }
.sowa-tura__koniec { flex: none; }
.sowa-tura__budzet { order: 3; flex: 1 1 100%; font-size: 11px; color: var(--color-neutral-700); }
@container sowa (min-width: 700px) {
	.sowa-tura { flex-wrap: nowrap; padding: 8px 24px; gap: 8px 18px; }
	.sowa-tura__zegar { flex: 0 1 360px; }
	.sowa-tura__budzet { order: 0; flex: 0 1 auto; font-size: 12px; }
	.sowa-tura__koniec { margin-left: auto; }
}

/* Nagłówek karty w rozgrywce: ikona i zwykły napis, nie drobne wersaliki.
   Dziesięciopunktowe wielkie litery z rozstrzeleniem czytają się jak etykieta w panelu
   sterowania - projekt chce czegoś cieplejszego, a przy okazji łatwiej to przeczytać. */
.sowa-gra .card-kicker {
	display: flex; align-items: center; gap: 8px;
	font-family: var(--font-heading); font-size: 16px; font-weight: 700;
	letter-spacing: 0; text-transform: none; color: var(--color-text);
}
.sowa-gra .card-kicker .sowa-icon { flex: none; color: var(--color-accent); }

/* Ekrany zakładek (poza pulpitem) - wspólny oddech i wspólny nagłówek. */
.sowa-widok { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.sowa-widok__glowa { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.sowa-widok__tytul { margin: 0; font-size: clamp(20px, 4vw, 26px); line-height: 1.15; }
.sowa-widok__wstep { margin: 4px 0 0; font-size: 13px; color: var(--color-neutral-700); text-wrap: pretty; }
.sowa-widok__pusto { margin: 0; padding: 20px; border-radius: var(--radius-md); background: var(--color-surface); color: var(--color-neutral-700); }

/* Ekran „Sowa”: zdjęcie i tożsamość z lewej, liczby z prawej. */
.sowa-sowa__uklad { display: grid; grid-template-columns: 1fr; gap: 12px; align-items: start; }
.sowa-sowa__lewa,
.sowa-sowa__prawa { display: flex; flex-direction: column; gap: 12px; }
.sowa-sowa__foto {
	position: relative; border-radius: var(--radius-lg); overflow: hidden;
	background: var(--color-neutral-200); aspect-ratio: 4 / 3;
}
.sowa-sowa__foto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sowa-sowa__nazwa { margin: 0; font-size: 20px; line-height: 1.15; }
.sowa-sowa__latin { margin: 2px 0 0; font-size: 13px; color: var(--color-neutral-700); }
.sowa-sowa__stan { margin: 6px 0 0; font-size: 13px; font-weight: 700; color: var(--color-accent-800); }
.sowa-sowa__znaczniki { display: flex; flex-wrap: wrap; gap: 6px; }

/*
 * Dziennik: jedna karta na dzień.
 *
 * Szerokość ograniczona, bo to czysty tekst: na pełnej szerokości pulpitu wiersz miał ponad
 * tysiąc pikseli i oko gubiło początek następnego, a skutek wyrównany do prawej krawędzi
 * odjeżdżał od zdania, którego dotyczy.
 */
.sowa-app .card.sowa-dziennik__dzien { gap: 8px; max-width: 820px; }

/* Ustawienia: opis po lewej, sterowanie po prawej. */
.sowa-app .card.sowa-ustawienie { flex-direction: row; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.sowa-ustawienie__opis { min-width: 0; }
.sowa-ustawienie__opis strong { display: block; font-size: 15px; }
.sowa-ustawienie__opis p { margin: 2px 0 0; font-size: 13px; color: var(--color-neutral-700); text-wrap: pretty; }

@container sowa (min-width: 700px) {
	.sowa-sowa__uklad { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); }
}
@container sowa (min-width: 900px) {
	/* Ograniczenie szerokości, nie tylko odstęp: pasek 1300 px szeroki i 8 px wysoki
	   przestaje być czytelny jako miernik, a lista dwóch zdań rozciągnięta na cały
	   monitor czyta się gorzej niż ta sama lista w kolumnie. */
	.sowa-widok { padding: 24px 28px; max-width: 1180px; }
}

/* ---- Pasek górny 0.2 ----
   Komórki „ikona + wartość + podpis”. Na telefonie marka i pogoda w jednym rzędzie,
   dzień i budżet w drugim - tak jak w projekcie. */
.sowa-pasek {
	display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px;
	padding: 10px 14px; border-bottom: 1px solid var(--color-divider);
	background: var(--color-surface);
}
.sowa-pasek__marka { display: flex; align-items: center; gap: 9px; min-width: 0; margin-right: auto; }
/* Logo jako maska - kolor z palety, jeden plik, bez zależności od motywu witryny
   (kopia leży w `assets/img/`, bo wtyczka musi działać także pod obcym motywem). */
.sowa-pasek__logo {
	flex: none; width: 26px; height: 26px; background: var(--color-accent-800);
	-webkit-mask: url(../img/logo-sowa.svg) no-repeat center / contain;
	mask: url(../img/logo-sowa.svg) no-repeat center / contain;
}
.sowa-pasek__nazwa { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.sowa-pasek__nazwa strong { font-family: var(--font-heading); font-size: 15px; white-space: nowrap; }
/* `neutral-700`, nie 600: przy 11 px szary 600 dawał 3,2:1, a próg to 4,5:1. */
.sowa-pasek__nazwa em { font-style: normal; font-size: 11px; color: var(--color-neutral-700); }
.sowa-pasek__dni { display: flex; align-items: center; gap: 10px; order: 5; width: 100%; }
.sowa-pasek__dzien { font-size: 13px; font-weight: 700; white-space: nowrap; }
.sowa-pasek__komorka { display: flex; align-items: center; gap: 8px; min-width: 0; }
.sowa-pasek__ikona { flex: none; color: var(--color-accent-800); display: grid; place-items: center; }
.sowa-pasek__tekst { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.sowa-pasek__tekst strong { font-size: 14px; white-space: nowrap; }
.sowa-pasek__tekst em { font-style: normal; font-size: 11px; color: var(--color-neutral-700); }
/* Budżet: najpierw etykieta, pod nią kwota - jak w projekcie. Kolejność zmieniamy
   stylem, nie w kodzie, żeby czytnik ekranu dostał najpierw wartość. */
.sowa-pasek__tekst--odwrotnie { flex-direction: column-reverse; }
.sowa-pasek__ikony { display: flex; gap: 2px; margin-left: auto; }
.sowa-pasek__ikony .btn.is-active { background: var(--color-accent-2-700); color: var(--color-bg); }
/* Hasło marki zjada całą szerokość na telefonie, a mówi mniej niż pogoda. */
@container sowa (max-width: 560px) {
	.sowa-pasek__nazwa em { display: none; }
	.sowa-pasek__komorka .sowa-pasek__tekst em { display: none; }
}
@container sowa (min-width: 900px) {
	.sowa-pasek { padding: 12px 24px; gap: 22px; flex-wrap: nowrap; }
	.sowa-pasek__dni { order: 0; width: auto; }
	.sowa-pasek__marka { margin-right: 0; }
	.sowa-pasek__dni { margin-right: auto; }
}

/* ================= 1b Dashboard ================= */
.sowa-dash__grid { display: grid; grid-template-columns: 1fr; gap: 0; }
.sowa-dash__main { padding: 16px 16px 12px; display: flex; flex-direction: column; gap: 14px; }
.sowa-dash__aside { padding: 0 16px 16px; display: flex; flex-direction: column; gap: 12px; }

/* ---- Pulpit 0.2: hero, stan sowy, kafelki czynności, karty podsumowania ---- */
.sowa-dash { padding: 16px; display: flex; flex-direction: column; gap: 22px; }
.sowa-dash__gora,
.sowa-dash__dol { display: grid; grid-template-columns: 1fr; gap: 16px; }
/* Prawa kolumna: stan sowy i stan woliery jedno pod drugim. */
.sowa-dash__stan { display: grid; gap: 12px; align-content: start; }

.sowa-hero { display: grid; grid-template-columns: 1fr; gap: 16px; }
.sowa-hero__foto {
	position: relative; border-radius: var(--radius-lg); overflow: hidden;
	background: var(--color-neutral-200); aspect-ratio: 4 / 3;
	box-shadow: var(--shadow-sm);
}
/*
 * Zdjęcie kotwiczone absolutnie, żeby NIE wyznaczało wysokości karty. Wcześniej `height: 100%`
 * nie miało do czego się odnieść i obraz przyjmował własne proporcje - wysokość całego pulpitu
 * zależała więc od tego, jakie zdjęcie wgrał redaktor. Pionowe rozpychało ekran o kilkaset
 * pikseli i spychało czynności poniżej krawędzi okna.
 */
.sowa-hero__foto img {
	position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover;
	/* Barwa samego zdjęcia idzie za porą: nocą przygaszona i odbarwiona, wieczorem cieplejsza.
	   Sama półprzezroczysta warstwa światła tego nie dawała - rozjaśniała obraz zamiast go
	   ściemniać, bo nie da się przyciemnić czegoś, dokładając na wierzch koloru. */
	filter: var(--sowa-foto-filtr);
	transition: filter 1.6s ease;
}
/* Światło pory dnia na zdjęciu: ciepłe z góry rano, pomarańczowe wieczorem,
   chłodne i przygaszone nocą. Warstwa nad zdjęciem, więc działa na każdym materiale -
   także wtedy, gdy redaktor wgra zdjęcie zrobione w samo południe. */
.sowa-hero__foto::after {
	content: ''; position: absolute; inset: 0; pointer-events: none;
	background: var(--sowa-swiatlo); transition: background 1.6s ease;
}
/* Pigułka, „zzz” i cytat stoją NAD światłem - to informacje, nie część obrazu. */
.sowa-hero__pigulka, .sowa-zzz, .sowa-hero__cytat { z-index: 1; }
.sowa-hero__brak { position: absolute; inset: 0; display: grid; place-items: center; color: var(--color-neutral-700); }
.sowa-hero__pigulka { position: absolute; top: 10px; left: 10px; }
/* Cytat na zdjęciu: własne tło, bo nie wiemy, co jest pod spodem. */
.sowa-hero__cytat {
	position: absolute; left: 10px; right: 10px; bottom: 10px; margin: 0;
	background: color-mix(in srgb, var(--color-neutral-900) 72%, transparent);
	color: var(--color-bg); border-radius: var(--radius-md);
	padding: 8px 12px; font-size: 13px; line-height: 1.4;
}
/* „zzz” nad śpiącą sową. Trzy litery unoszą się z opóźnieniem jedna po drugiej.
   Przy `prefers-reduced-motion` animacja znika, ale napis zostaje - to informacja
   o stanie gry, a nie ozdoba, więc nie wolno go chować razem z ruchem. */
/* Własne tło, nie sam cień: pod spodem bywa jasne zdjęcie albo puste miejsce,
   gdy gatunek nie ma jeszcze materiału - biały napis znikał wtedy bez śladu. */
.sowa-zzz {
	position: absolute; top: 10px; right: 10px;
	display: flex; align-items: flex-end; gap: 3px;
	padding: 4px 10px 6px; border-radius: 999px;
	background: color-mix(in srgb, var(--color-neutral-900) 62%, transparent);
	font-family: var(--font-heading); font-weight: 700; color: var(--color-bg);
	line-height: 1; pointer-events: none;
}
.sowa-zzz span { animation: sowa-zzz 2.4s ease-in-out infinite; }
.sowa-zzz span:nth-child(1) { font-size: 14px; animation-delay: 0s; }
.sowa-zzz span:nth-child(2) { font-size: 18px; animation-delay: .35s; }
.sowa-zzz span:nth-child(3) { font-size: 23px; animation-delay: .7s; }
@keyframes sowa-zzz {
	0% { opacity: 0; transform: translateY(6px); }
	25% { opacity: 1; }
	70% { opacity: .9; transform: translateY(-8px); }
	100% { opacity: 0; transform: translateY(-14px); }
}
@media (prefers-reduced-motion: reduce) {
	.sowa-zzz span { animation: none; opacity: 1; transform: none; }
}

/* Opis sowy stoi na własnej karcie, tak jak w projekcie - inaczej wygląda jak tekst
   zgubiony na tle, a nie jak wizytówka obok zdjęcia. */
.sowa-hero__opis {
	display: flex; flex-direction: column; gap: 6px; min-width: 0;
	padding: 24px 26px; border-radius: var(--radius-lg); background: var(--color-bg);
	box-shadow: var(--shadow-sm);
}
.sowa-hero__nazwa { margin: 0; font-size: clamp(22px, 4.5vw, 30px); line-height: 1.1; }
.sowa-hero__latin { margin: 0; font-size: 14px; color: var(--color-neutral-700); }
/* Imię i ołówek w jednym wierszu; formularz zmiany imienia schodzi niżej (`flex-wrap`). */
.sowa-hero__tytul { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Narzędzie do nadania imienia. Wiek, płeć i charakter stoją w siatce faktów niżej. */
.sowa-metryczka { margin: 0; font-size: 13px; color: var(--color-neutral-700); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sowa-metryczka__olowek { position: relative; background: none; border: 0; padding: 2px; cursor: pointer; color: var(--color-accent-800); display: inline-flex; border-radius: var(--radius-sm); }
/*
 * Powiększony obszar dotyku bez powiększania ikony. Sam ołówek ma 14 px, więc cel miał
 * około 18×18 - poniżej progu 24×24 z WCAG 2.5.8, a na telefonie po prostu nie do trafienia.
 * Nakładka rozszerza go do ~46×46, nie ruszając wyglądu metryczki.
 */
.sowa-metryczka__olowek::after { content: ''; position: absolute; inset: -14px; }
.sowa-metryczka__olowek:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.sowa-metryczka--edycja { display: grid; gap: 6px; align-items: start; }
.sowa-metryczka__pole { display: grid; gap: 3px; font-size: 12px; }
.sowa-metryczka__pole input { font: inherit; font-size: 15px; padding: 7px 10px; border-radius: var(--radius-sm); border: 1px solid var(--color-neutral-500); background: var(--color-bg); color: var(--color-text); max-width: 240px; }
.sowa-metryczka__przyciski { display: flex; gap: 8px; }
.sowa-metryczka__uwaga { color: var(--color-neutral-700); font-size: 12px; }
.sowa-hero__tekst { margin: 6px 0 0; font-size: 14px; line-height: 1.5; color: var(--color-neutral-800); text-wrap: pretty; }
.sowa-hero__fakty { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--color-divider); }
.sowa-fakt { display: flex; align-items: center; gap: 8px; color: var(--color-neutral-700); }
.sowa-fakt span { display: flex; flex-direction: column; line-height: 1.25; }
.sowa-fakt em { font-style: normal; font-size: 11px; text-transform: uppercase; letter-spacing: .02em; }
.sowa-fakt strong { font-size: 14px; color: var(--color-text); }

.sowa-app .card.sowa-stan { gap: 12px; }
/* Na telefonie sześć pasków jeden pod drugim to pół ekranu - projekt ustawia je
   w dwóch kolumnach. Na szerokim wracamy do jednej, bo karta jest wąska. */
.sowa-stan__mierniki { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
.sowa-wskaznik { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* 26 px zamiast 34: mierniki plus karta woliery muszą zmieścić się w prawej kolumnie
   bez przewijania, a kółko z ikoną jest tu najgrubszym elementem wiersza. */
.sowa-wskaznik__ikona {
	flex: none; width: 26px; height: 26px; border-radius: 50%;
	display: grid; place-items: center;
	/* Barwę ikony ustawia komponent (ta sama co pasek), a tło bierze się z niej -
	   dzięki temu kółko zawsze pasuje do stanu wskaźnika i do palety motywu. */
	color: var(--color-accent-800);
	background: color-mix(in srgb, currentColor 14%, transparent);
}
.sowa-wskaznik .sowa-meter { flex: 1; min-width: 0; }

.sowa-czynnosci { display: flex; flex-direction: column; gap: 9px; }
.sowa-czynnosci__glowa { display: flex; flex-direction: column; gap: 2px; }
.sowa-czynnosci__tytul { margin: 0; font-size: 20px; display: flex; align-items: center; gap: 8px; }
.sowa-czynnosci__tytul .sowa-icon { flex: none; color: var(--color-accent); }
.sowa-czynnosci__wstep { margin: 0; font-size: 13px; color: var(--color-neutral-700); }
.sowa-czynnosci__siatka { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
/* Kafelek to karta, nie ramka: cień zamiast obramowania, więcej powietrza w środku
   i okrągła ikona na jasnym tle akcentu - tak jak reszta kart po tej zmianie. */
.sowa-kafelek {
	display: flex; flex-direction: column; gap: 5px; text-align: left;
	padding: 11px 13px; border: 0; border-radius: var(--radius-lg);
	background: var(--color-bg); color: var(--color-text); cursor: pointer;
	box-shadow: var(--shadow-sm);
	font-family: inherit; transition: box-shadow .15s, transform .15s;
}
.sowa-kafelek:hover:not(:disabled) { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.sowa-kafelek:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.sowa-kafelek:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.sowa-kafelek__ikona {
	width: 36px; height: 36px; margin-bottom: 0;
	border-radius: 50%; display: grid; place-items: center;
	background: var(--color-accent-100); color: var(--color-accent-800);
}
.sowa-kafelek__nazwa { font-weight: 700; font-size: 14px; line-height: 1.2; }
.sowa-kafelek__koszt { font-size: 12px; font-weight: 600; color: var(--color-accent-800); font-variant-numeric: tabular-nums; }
/*
 * Opis skrócony do trzech linii. Redaktor pisze tu czasem cztery zdania, a siedem kafelków
 * w rzędzie wyrównuje się do najwyższego - jeden rozwlekły opis podnosił cały rząd o kilkadziesiąt
 * pikseli i spychał resztę pulpitu poza ekran. Pełna treść zostaje w `title` i na ekranie akcji,
 * więc nic nie ginie.
 */
.sowa-kafelek__opis {
	font-size: 12px; line-height: 1.35; color: var(--color-neutral-700);
	display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* Na telefonie klika się cały kafelek, więc osobny przycisk byłby zmyleniem. */
.sowa-kafelek__akcja { display: none; }

@container sowa (max-width: 1400px) {
	/*
	 * Opis czynności chowamy - ale tylko wzrokowo. Siedem kafelków po trzy linijki tekstu
	 * to pół ekranu do przewijania, a do wyboru czynności wystarcza jej nazwa i ikona.
	 * Nie używamy `display: none`, bo dla kogoś, kto słucha czytnika ekranu, ten opis jest
	 * jedyną informacją, co dana czynność robi i czego wymaga; pełna treść jest też w dymku.
	 *
	 * Próg 1400, nie 700: siedem kafelków mieści się w jednym rzędzie dopiero, gdy pojemnik
	 * ma około 1350 px (siedem kolumn po 150 px plus odstępy, minus pasek nawigacji). Poniżej
	 * tej granicy rzędy są dwa, więc opisy kosztują podwójnie - każdy rząd rośnie o te same
	 * trzy linijki. Przy 940 px pulpit miał przez to 1143 px wysokości zamiast 869, a przy
	 * 1300 px - 1050 px. Próg dobrany pomiarem, z zapasem nad momentem domknięcia rzędu.
	 */
	.sowa-kafelek__opis {
		position: absolute; width: 1px; height: 1px; overflow: hidden;
		clip: rect(0 0 0 0); white-space: nowrap;
	}
	/*
	 * Opis gatunku skrócony do dwóch linii. Między 900 a 1200 px karta podopiecznej dzieli
	 * się na dwie kolumny po ~170 px i to ona dyktuje wysokość całej górnej sekcji - zdanie
	 * o temperamencie zawijało się tam na pięć linijek. Pełna treść zostaje w dymku i na
	 * ekranie „Sowa”.
	 */
	.sowa-hero__tekst {
		display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
	}
}

/* Odsyłacz w nagłówku karty („Szczegóły →”, „Zobacz dziennik →”). Przycisk, nie link:
   nie prowadzi pod adres, tylko przełącza zakładkę - a wygląda jak w projekcie. */
.sowa-link {
	display: inline-flex; align-items: center; gap: 4px; flex: none;
	/* `min-height` pilnuje progu 24×24 z WCAG 2.5.8 - sam padding dawał 23 px. */
	min-height: 24px;
	padding: 4px 10px; border: 1px solid var(--color-divider); border-radius: 999px;
	background: var(--color-bg); color: var(--color-accent-800); cursor: pointer;
	font-family: inherit; font-size: 12px; font-weight: 700; white-space: nowrap;
}
.sowa-link:hover { background: var(--color-accent-100); }
.sowa-link:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.sowa-stan__glowa,
.sowa-log__glowa { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.sowa-woliera__foto {
	display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
	border-radius: var(--radius-md); background: var(--color-neutral-200);
}
.sowa-czynnosci__stopka { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.sowa-czynnosci__budzet { font-size: 12px; color: var(--color-neutral-700); }

/* Stan woliery pokazuje tę samą liczbę co „Czystość”, ale jako osobną kartę - opiekun
   czyta ją inaczej („czy mam dziś sprzątać”) niż pasek w rzędzie sześciu mierników. */
.sowa-app .card.sowa-woliera { gap: 10px; justify-content: flex-start; }
.sowa-woliera .sowa-meter__row span { font-weight: 700; }

@container sowa (min-width: 700px) {
	.sowa-hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; }
	.sowa-hero__foto { aspect-ratio: auto; min-height: 260px; }
	.sowa-czynnosci__siatka { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
	/* Wygląda jak przycisk, bo w projekcie jest przyciskiem - ale klikalny jest cały
	   kafelek, więc to `span` bez własnego zdarzenia. Zieleń, nie pomarańcz: pomarańcz
	   jest kolorem głównego przycisku, a tu siedem kafelków obok siebie i siedem
	   pomarańczowych prostokątów krzyczałoby mocniej niż cokolwiek innego na ekranie. */
	.sowa-kafelek__akcja {
		display: inline-flex; align-items: center; justify-content: center; gap: 4px;
		margin-top: auto; padding: 7px 12px; border-radius: 999px;
		background: var(--color-accent-2-700); color: var(--color-bg);
		font-size: 12px; font-weight: 700;
	}
	.sowa-kafelek:hover:not(:disabled) .sowa-kafelek__akcja { background: var(--color-accent-2-800); }
	.sowa-kafelek:disabled .sowa-kafelek__akcja { background: var(--color-neutral-300); color: var(--color-neutral-800); }
	/* Dwie karty, nie trzy - woliera przeniosła się pod stan sowy. */
	.sowa-dash__dol { grid-template-columns: repeat(2, 1fr); align-items: start; }
}

@container sowa (min-width: 900px) {
	/* Pulpit ma się mieścić na jednym ekranie - dlatego odstępy są tu ciaśniejsze niż
	   w pozostałych widokach. Przewijanie po stan sowy przeczy sensowi tego ekranu:
	   ma odpowiadać na „co się dzieje” jednym spojrzeniem. */
	.sowa-dash { padding: 12px 24px 10px; gap: 10px; }
	.sowa-dash__gora, .sowa-dash__dol { gap: 12px; }
	/* Karty pulpitu ciaśniejsze niż w pozostałych widokach - tu liczy się, żeby wszystko
	   było widać naraz. Na innych ekranach wyściółka zostaje taka jak była. */
	.sowa-dash .card { padding: 14px 16px; }
	.sowa-dash__gora { grid-template-columns: minmax(0, 1fr) 330px; }
	.sowa-stan__mierniki { grid-template-columns: 1fr; gap: 7px; }
	/*
	 * Wstęp obok tytułu, nie pod nim - jak w projekcie. Licznik tury dosuwamy do prawej.
	 *
	 * Ujemny margines wiesza ikonę nagłówka na marginesie, poza krawędzią kart. Bez tego
	 * napis „Codzienne czynności” stał 8 px dalej w prawo niż napisy w kafelkach pod nim:
	 * krawędzie kart się zgadzały, ale teksty nie tworzyły jednej linii pionowej i oko to
	 * wyłapywało. 17 px to różnica między odsunięciem ikony nagłówka (22 + 8) a wyściółką
	 * kafelka (13). Tylko na szerokim ekranie - na telefonie wyszłoby poza wyściółkę ekranu.
	 */
	.sowa-czynnosci__glowa { flex-direction: row; align-items: baseline; gap: 12px; margin-left: -17px; }
	.sowa-czynnosci__timer { margin-left: auto; flex: none; }
}
.sowa-actions { display: flex; gap: 8px; flex-wrap: wrap; position: sticky; bottom: 0; background: var(--color-bg); padding: 10px 0 4px; z-index: 5; }
.sowa-actions .btn { padding: 10px 14px; }
.sowa-actions .btn-ghost { margin-left: auto; }
.sowa-actions__left { font-size: 11px; color: var(--color-neutral-700); width: 100%; }

/* wskaźniki */
.sowa-status { gap: 12px; }
.sowa-status__head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.sowa-status__head .card-title { font-size: 17px; }
.sowa-status__species { font-size: 12px; color: var(--color-neutral-700); text-align: right; }
.sowa-status__flags { display: flex; gap: 4px; flex-wrap: wrap; }
.sowa-meter__row { display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 4px; }
.sowa-meter__track { height: 8px; border-radius: 999px; background: var(--color-neutral-300); overflow: hidden; }
.sowa-meter__fill { height: 100%; border-radius: 999px; transition: width .4s ease-out, background .4s ease-out; }
.sowa-weight__track { position: relative; height: 10px; border-radius: 999px; background: var(--color-neutral-300); }
.sowa-weight__band { position: absolute; top: 0; bottom: 0; background: var(--color-accent-2-300); border-radius: 999px; transition: left .4s ease-out, right .4s ease-out; }
.sowa-weight__marker { position: absolute; top: -3px; width: 16px; height: 16px; margin-left: -8px; border-radius: 50%; background: var(--color-accent); border: 2px solid var(--color-bg); transition: left .4s ease-out; }
.sowa-weight__marker.is-unknown { background: var(--color-neutral-500); }
.sowa-weight__hint { font-size: 11px; color: var(--color-neutral-700); margin-top: 4px; }
.sowa-risk { background: var(--color-accent-100); gap: 6px; }
/* (nadpisanie koloru nagłówka usunięte - `accent-800` jest teraz wartością domyślną) */
.sowa-risk__value { display: flex; align-items: baseline; gap: 8px; }
.sowa-risk__word { font-family: var(--font-heading); font-weight: 700; font-size: 28px; line-height: 1; }
.sowa-risk__pct { font-size: 12px; color: var(--color-accent-800); }
.sowa-risk .card-body { opacity: 1; color: var(--color-accent-900); }
.sowa-risk.is-high { background: var(--color-accent-200); }
.sowa-risk.is-critical { background: var(--color-accent-300); }
.sowa-log { gap: 6px; }
.sowa-log__list { font-size: 12px; line-height: 1.6; color: var(--color-neutral-800); margin: 0; padding: 0; list-style: none; }
/* Szary 500 dawał 2,15:1 - prefiks „D3 noc” był praktycznie niewidoczny. */
.sowa-log__turn { color: var(--color-neutral-700); margin-right: 4px; }
/*
 * Skutki czynności przy wpisie. Barwa idzie za ZNACZENIEM, nie za znakiem: spadek stresu
 * jest dobry, wzrost zużycia sprzętu zły. Sama barwa jednak nie wystarczy - znak plus albo
 * minus stoi przy każdej liczbie, więc informacja nie ginie przy daltonizmie.
 */
/* Wiersz dziennika: kiedy | co | skutek przy prawej krawędzi. */
.sowa-log__list li { display: flex; align-items: baseline; gap: 6px; }
.sowa-log__tekst { flex: 1; min-width: 0; }
.sowa-log__efekty { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: auto; flex: none; justify-content: flex-end; }
.sowa-log__efekt { font-size: 11px; line-height: 1.5; padding: 0 6px; border-radius: 999px; white-space: nowrap; }
.sowa-log__efekt.is-good { background: var(--color-accent-2-100); color: var(--color-accent-2-900); }
.sowa-log__efekt.is-bad { background: var(--color-accent-100); color: var(--color-accent-900); }

/* day dots */
.sowa-daydots { display: flex; gap: 4px; flex-wrap: wrap; }
.sowa-daydots__dot { width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid var(--color-accent); background: transparent; transition: background .3s; }
.sowa-daydots__dot.is-past { background: var(--color-accent); }
.sowa-daydots__dot.is-current { background: var(--color-accent-300); }

/* timer */
.sowa-timer { height: 4px; background: var(--color-neutral-300); border-radius: 999px; overflow: hidden; }
.sowa-timer__fill { height: 100%; background: var(--color-accent); transition: width .25s linear; }
.sowa-timer__label { font-size: 11px; color: var(--color-neutral-700); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
/* „Pauza” to jedyny sposób zatrzymania odliczania tury, a miała 17 px wysokości - poniżej
   progu 24×24 z WCAG 2.5.8. Wygląd zostaje kompaktowy, rośnie samo pole trafienia. */
.sowa-timer__label .btn { padding: 4px 10px; font-size: 11px; min-height: 24px; }

/* Grafika akcji zamiast ikony (pole „Grafika akcji”): PNG z przezroczystym tłem */
.sowa-action__img { width: 20px; height: 20px; object-fit: contain; margin-right: 2px; flex: none; }

/* ================= Atak / agresja =================
   Sam atak zostaje mechaniką gry; zniknęła tylko jego animacja, bo rysowała się
   wyłącznie na scenie wolierowej. Znacznik „agresywna” pokazuje się dalej. */
.sowa-status__flags .tag.is-aggr { background: var(--color-accent-200); color: var(--color-accent-900); }

/* ================= Sklep / inwentarz / karma (panele) ================= */
.sowa-app .sowa-panel-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, var(--color-neutral-900) 45%, transparent); display: grid; place-items: start center; padding: 16px; z-index: 55; overflow: auto; animation: sowa-fade .2s ease-out; }
.sowa-panel { width: min(680px, 100%); gap: 14px; animation: sowa-pop .2s ease-out; max-height: 100%; overflow: auto; }
.sowa-panel__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.sowa-panel__head .dialog-title { font-size: clamp(22px, 4vw, 26px); }
.sowa-panel__head .dialog-body { margin: 4px 0 0; font-size: 13px; }
.sowa-panel__notice { background: var(--color-accent-100); color: var(--color-accent-900); border-radius: var(--radius-md); padding: 8px 12px; font-size: 13px; }
.sowa-panel__hint, .sowa-panel__empty { font-size: 12px; color: var(--color-neutral-700); }
.sowa-panel__group { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.sowa-item { display: flex; gap: 12px; align-items: center; justify-content: space-between; background: var(--color-neutral-100); border-radius: var(--radius-md); padding: 10px 12px; border: 2px solid transparent; }
.sowa-item.is-locked { opacity: .7; }
.sowa-item.is-fitted { border-color: var(--color-accent-2-400); background: var(--color-accent-2-100); }
.sowa-item--pick { width: 100%; cursor: pointer; text-align: left; transition: transform .15s, border-color .15s; }
/*
 * Wybór niedostępny (np. apteczka, której gracz nie kupił) nie udaje klikalnego.
 *
 * Przygaszamy ikonę i nazwę, ale NIE zdanie pod spodem: to ono mówi, czemu się nie da
 * i ile kosztuje odblokowanie. Wspólne `opacity: .7` na całej karcie spychało je do 2,8:1
 * - czyli jedyna instrukcja na ekranie była najmniej czytelnym napisem w oknie. WCAG zwalnia
 * z progu kontrastu elementy nieaktywne, ale zwolnienie nie sprawia, że tekst da się odczytać.
 */
.sowa-item--pick:disabled, .sowa-item--pick.is-locked { cursor: not-allowed; }
.sowa-item--pick.is-locked:hover { transform: none; }
.sowa-item.sowa-item--pick.is-locked { opacity: 1; }
.sowa-item--pick.is-locked .sowa-item__icon,
.sowa-item--pick.is-locked .sowa-item__name { opacity: .6; }
.sowa-item--pick.is-locked .sowa-item__desc { color: var(--color-accent-800); }
.sowa-item--pick:hover { transform: translateX(2px); border-color: var(--color-accent); }
.sowa-item--pick.is-preferred { border-color: var(--color-accent-300); }
.sowa-item__head { display: flex; gap: 10px; align-items: flex-start; min-width: 0; flex: 1; }
.sowa-item__icon { width: 40px; height: 40px; border-radius: 50%; background: var(--color-surface); display: grid; place-items: center; flex: none; color: var(--color-accent-800); }
.sowa-item__icon .sowa-icon { width: 20px; height: 20px; }
.sowa-item__text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sowa-item__name { font-family: var(--font-heading); font-weight: 700; font-size: 15px; line-height: 1.2; }
.sowa-item__desc { font-size: 12px; color: var(--color-neutral-700); line-height: 1.4; }
.sowa-item__fx { display: flex; gap: 4px; flex-wrap: wrap; }
.sowa-item__fx .tag { font-size: 10px; padding: 2px 8px; }
.sowa-item__side { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; text-align: right; }
.sowa-item__price { font-family: var(--font-heading); font-weight: 700; font-size: 15px; }
.sowa-item__owned, .sowa-item__locked { font-size: 11px; color: var(--color-neutral-700); }
.sowa-item__locked { color: var(--color-accent-800); max-width: 180px; }
.sowa-item__side .btn { padding: 6px 12px; font-size: 12px; }

/* ================= Cel dnia ================= */
.sowa-goal { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: var(--radius-md); background: var(--color-accent-2-100); color: var(--color-accent-2-900); font-size: 13px; }
.sowa-goal__icon { width: 26px; height: 26px; border-radius: 50%; background: var(--color-bg); display: grid; place-items: center; flex: none; }
.sowa-goal__icon .sowa-icon { width: 14px; height: 14px; }
.sowa-goal__text em { font-style: normal; font-weight: 700; }
.sowa-goal.is-done { background: var(--color-accent-2-200); }
.sowa-goal.is-failed { background: var(--color-neutral-200); color: var(--color-neutral-700); }
.sowa-goal.is-compact { background: rgba(249, 244, 237, .14); color: inherit; padding: 4px 0; font-size: 11px; gap: 6px; border-radius: 0; }
.sowa-goal.is-compact .sowa-goal__icon { width: 18px; height: 18px; background: rgba(249, 244, 237, .2); }
.sowa-goal.is-compact.is-done { color: var(--color-accent-2-300); }

/*
 * Wariant kartowy na pulpicie - jak w projekcie graficznym. Cel dnia był jednym wierszem
 * („Cel dnia: Sprawdź inwentarz”) i przez to wyglądał na przypis, a nie na zadanie. Nagroda
 * w ogóle nie była widoczna przed wykonaniem, więc nie mogła do niczego zachęcić.
 */
.sowa-goal--karta { display: grid; gap: 6px; align-content: start; padding: 14px 16px; }
.sowa-goal__glowa { display: flex; align-items: center; gap: 8px; }
.sowa-goal__tytul { font-family: var(--font-heading); font-size: 16px; font-weight: 700; }
/* Licznik przy prawej krawędzi - jak „0/1” w projekcie. */
.sowa-goal__postep { margin-left: auto; font-size: 12px; font-variant-numeric: tabular-nums; opacity: .85; }
.sowa-goal__nazwa { margin: 0; font-weight: 700; font-size: 14px; }
.sowa-goal__opis { margin: 0; font-size: 12px; line-height: 1.45; opacity: .9; text-wrap: pretty; }
.sowa-goal__pasek { height: 6px; border-radius: 999px; background: var(--color-bg); overflow: hidden; margin-top: 2px; }
.sowa-goal__pasek b { display: block; height: 100%; background: var(--color-accent-2-600); border-radius: inherit; transition: width .3s ease; }
/* Stan i nagroda dzielą kształt: jedno zastępuje drugie, więc karta nie ma się przy tym przesuwać. */
.sowa-goal__stan,
.sowa-goal__nagroda {
	justify-self: start; display: inline-flex; align-items: center; gap: 5px;
	padding: 3px 10px; border-radius: 999px;
	background: var(--color-accent-100); color: var(--color-accent-900);
	font-size: 12px; font-weight: 700;
}
.sowa-goal__stan.is-ok { background: var(--color-accent-2-100); color: var(--color-accent-2-900); }
.sowa-goal__stan.is-bad { background: var(--color-danger-100); color: var(--color-danger-900); }
.sowa-app[data-animations="reduced"] .sowa-goal__pasek b,
.sowa-app[data-animations="none"] .sowa-goal__pasek b { transition: none; }

/* ================= Stan sowy (maszyna stanów) ================= */
.sowa-machine { gap: 8px; }
.sowa-machine.is-escaped { background: var(--color-accent-100); }
.sowa-machine__list { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.sowa-machine__row { display: grid; grid-template-columns: 82px 1fr; gap: 8px; align-items: start; font-size: 12px; }
.sowa-machine__row dt { color: var(--color-neutral-700); padding-top: 3px; }
.sowa-machine__row dd { margin: 0; }
.sowa-machine__row .tag { white-space: normal; text-align: left; line-height: 1.35; font-size: 11px; }
.sowa-machine__row.is-strong .tag { background: var(--color-accent-700); color: var(--color-bg); font-weight: 700; }
.sowa-machine__cta { margin-top: 4px; }
.sowa-signal { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; background: rgba(32, 30, 29, .6); color: var(--color-neutral-100); font-size: 12px; font-weight: 700; letter-spacing: .04em; backdrop-filter: blur(6px); }
.sowa-signal__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--color-accent-400); box-shadow: 0 0 0 0 rgba(198, 113, 57, .6); animation: sowa-signal 1.4s ease-out infinite; }
@keyframes sowa-signal { 0% { box-shadow: 0 0 0 0 rgba(198, 113, 57, .6); } 100% { box-shadow: 0 0 0 14px rgba(198, 113, 57, 0); } }
.sowa-app .sowa-notice { position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); background: var(--color-neutral-900); color: var(--color-neutral-100); padding: 8px 16px; border-radius: 999px; font-size: 13px; z-index: 58; box-shadow: var(--shadow-lg); animation: sowa-pop .2s; max-width: calc(100% - 32px); text-align: center; }

/* ================= 1d Event dialog ================= */
.sowa-event-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, var(--color-neutral-900) 45%, transparent); display: grid; place-items: start center; padding: 16px; z-index: 50; overflow: auto; animation: sowa-fade .2s ease-out; }
.sowa-event { width: min(620px, 100%); gap: 16px; animation: sowa-pop .2s ease-out; max-height: 100%; overflow: auto; }
.sowa-event__head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.sowa-event__stress { font-size: 12px; color: var(--color-neutral-700); }
.sowa-event .dialog-title { font-size: clamp(22px, 4vw, 28px); line-height: 1.1; }
.sowa-event .dialog-body { margin: 0; }
.sowa-event__answers { display: flex; flex-direction: column; gap: 10px; }
.sowa-answer { cursor: pointer; gap: 4px; padding: 14px 18px; background: var(--color-neutral-100); border: 2px solid transparent; transition: border-color .15s, transform .15s; width: 100%; }
.sowa-answer:hover { transform: translateX(2px); }
.sowa-answer.is-recommended { border-color: var(--color-accent); background: var(--color-surface); }
.sowa-answer.is-locked { opacity: .55; cursor: not-allowed; }
.sowa-answer.is-locked:hover { transform: none; }
.sowa-answer .card-title { font-size: 15px; }
.sowa-answer .card-meta.is-risky { color: var(--color-accent-800); }
/* Zdjęcie zdarzenia: niski pas, żeby odpowiedzi zostały w oknie bez przewijania. */
.sowa-event__foto { margin: 0; border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 16 / 7; max-height: 26vh; background: var(--color-neutral-200); }
.sowa-event__foto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sowa-event__fact { font-size: 12px; color: var(--color-neutral-700); border-top: 1px solid var(--color-divider); padding-top: 12px; }
.sowa-event__message { background: var(--color-accent-2-100); color: var(--color-accent-2-900); border-radius: var(--radius-md); padding: 10px 14px; font-size: 14px; }

/* ================= 1e Ending ================= */
/*
 * Ekran końca jest jasny jak cała reszta aplikacji. Wcześniej miał własny tryb ciemny
 * z równoległym zestawem reguł `.is-light`; dwa motywy w jednym miejscu oznaczały, że
 * każdy nowy blok trzeba było pamiętać o dopisaniu dwa razy - i to się zemściło:
 * `.sowa-rachunek` dostał style tylko pod jasne tło, a wylądował na ciemnym, dając
 * kontrast 1,22:1. Jeden motyw = jedno miejsce do popsucia.
 */
.sowa-end { display: grid; grid-template-columns: 1fr; min-height: 560px; background: var(--color-bg); color: var(--color-text); }
/*
 * Treść wizualu trzyma się GÓRY. Przy szerokim oknie kolumna rozciąga się na wysokość
 * całego podsumowania, więc dociśnięcie jej do dołu (`flex-end`) wypychało nagłówek
 * "Nie przeżyła." poza pierwszy ekran - gracz po przegranej widział samą tabelę liczb.
 */
.sowa-end__visual { position: relative; overflow: hidden; min-height: 300px; padding: 28px 20px; display: flex; flex-direction: column; justify-content: flex-start; background: linear-gradient(180deg, #d7e3ef, var(--color-accent-2-200) 60%, var(--color-accent-200)); }
/* Wariant zakończenia zmienia już tylko nastrój gradientu, nie jasność całego ekranu. */
.sowa-end.is-death .sowa-end__visual { background: linear-gradient(180deg, #e9e5dd, var(--color-neutral-300) 55%, var(--color-neutral-400)); }
.sowa-end.is-seized .sowa-end__visual { background: linear-gradient(180deg, #e5eadd, var(--color-accent-2-100) 55%, var(--color-accent-2-200)); }
/* „Przetrwała bez opieki”: sowa jest, ale to nie jest wygrana - szaro, bez nieba sukcesu. */
.sowa-end.is-neglect .sowa-end__visual { background: linear-gradient(180deg, #e7e4dc, var(--color-neutral-200) 55%, var(--color-accent-100)); }
/*
 * Zdjęcie sowy wypełnia CAŁY blok wizualu - `cover` przycina je do kształtu kolumny,
 * więc przy szerokim oknie nie zostaje pustej płachty gradientu.
 */
.sowa-end__visual img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/*
 * Odbarwienie zależy od tego, jak skończyła się opieka. To nie ozdobnik: pełnokolorowe
 * zdjęcie pod napisem "Nie przeżyła." czytałoby się jak zdjęcie z sesji, a nie pożegnanie.
 */
.sowa-end.is-death .sowa-end__visual img { filter: grayscale(1) sepia(.4) contrast(.9); opacity: .45; }
.sowa-end.is-seized .sowa-end__visual img { filter: grayscale(.6) sepia(.25); opacity: .5; }
.sowa-end.is-escape .sowa-end__visual img { filter: sepia(.2); opacity: .55; }
.sowa-end.is-neglect .sowa-end__visual img { filter: grayscale(.4) sepia(.2); opacity: .5; }
.sowa-end.is-success .sowa-end__visual img { opacity: .6; }
/*
 * Welon pod tekstem. Tytuł jest ciemny, a zdjęcie w tym miejscu bywa dowolnie jasne lub
 * ciemne - bez tej warstwy czytelność zależałaby od tego, co akurat wgrał redaktor.
 */
.sowa-end__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--color-bg) 86%, transparent), color-mix(in srgb, var(--color-bg) 20%, transparent) 46%, transparent 72%);
  pointer-events: none;
}
/* „Przetrwała bez opieki” wymienia wszystkie przyczyny, więc tekst sięga niżej niż welon innych zakończeń. */
.sowa-end.is-neglect .sowa-end__visual::after {
  background: linear-gradient(180deg, color-mix(in srgb, var(--color-bg) 90%, transparent), color-mix(in srgb, var(--color-bg) 78%, transparent) 70%, color-mix(in srgb, var(--color-bg) 30%, transparent) 100%);
}
.sowa-end__visual-inner { position: relative; z-index: 1; }
.sowa-end__kicker { background: var(--color-accent-800); color: var(--color-accent-100); }
.sowa-end__title { font-size: clamp(40px, 8vw, 56px); line-height: 1; margin: 14px 0 10px; color: inherit; }
.sowa-end__metryczka { margin: 0 0 8px; font-size: 14px; color: var(--color-neutral-700); }
.sowa-end__body { font-size: 15px; line-height: 1.5; color: var(--color-neutral-700); text-wrap: pretty; max-width: 420px; }
.sowa-end__summary { padding: 28px 20px; display: flex; flex-direction: column; gap: 22px; }
.sowa-end__summary-kicker { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-accent-700); }
.sowa-end__stats { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 24px; margin-top: 14px; }
.sowa-end__stat-v { font-family: var(--font-heading); font-weight: 700; font-size: clamp(24px, 4vw, 30px); line-height: 1; }
.sowa-end__stat-l { font-size: 12px; color: var(--color-neutral-700); margin-top: 4px; }
.sowa-end__lesson { background: var(--color-surface); border-radius: var(--radius-lg); padding: 18px 20px; font-size: 14px; line-height: 1.55; }
.sowa-end__lesson strong { font-family: var(--font-heading); font-weight: 700; font-size: 16px; display: block; margin-bottom: 4px; }
.sowa-end__cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: auto; }
.sowa-end__cta .btn-outline { border: 1px solid var(--color-neutral-500); color: var(--color-text); }
.sowa-end__cta .btn-ghost { color: var(--color-accent-700); }
.sowa-end__toast { font-size: 12px; color: var(--color-accent-700); }

/* Ocena opieki (ekran końca) */
.sowa-end__grade { background: var(--color-surface); border-radius: var(--radius-lg); padding: 14px 20px; font-size: 13px; display: grid; gap: 10px; }
.sowa-end__grade-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sowa-end__grade-head strong { font-family: var(--font-heading); font-weight: 700; font-size: 16px; }
.sowa-end__stars { font-size: 20px; letter-spacing: 2px; line-height: 1; }
/* Niezdobyte gwiazdki to nadal treść oceny ("dwie z pięciu"), więc muszą być czytelne. */
.sowa-end__stars i { font-style: normal; color: var(--color-neutral-700); }
.sowa-end__stars i.is-on { color: var(--color-accent-800); }
.sowa-end__grade-label { color: var(--color-neutral-700); }
/* Jedno zdanie zamiast tabeli sześciu pasków - patrz komentarz w `screens/Ending.js`. */
.sowa-end__grade-slabo { margin: 0; font-size: 13px; color: var(--color-neutral-700); }
.sowa-actions__min { font-size: 10px; opacity: .7; margin-left: 4px; font-weight: 400; }

/* Dziennik opiekuna (ekran końca) */
.sowa-end__journal { background: var(--color-surface); border-radius: var(--radius-lg); padding: 12px 20px; font-size: 13px; line-height: 1.5; }
.sowa-end__journal-head { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: 0; color: inherit; font: inherit; padding: 4px 0; cursor: pointer; text-align: left; }
.sowa-end__journal-head strong, .sowa-end__journal > strong { font-family: var(--font-heading); font-weight: 700; font-size: 16px; }
.sowa-end__journal-head .sowa-icon { margin-left: auto; flex: none; }
.sowa-end__journal-goals { font-size: 12px; color: var(--color-neutral-700); }
.sowa-end__journal-empty { margin: 4px 0 0; color: var(--color-neutral-700); }
.sowa-end__journal-list { list-style: none; margin: 10px 0 4px; padding: 0; display: grid; gap: 10px; max-height: 320px; overflow: auto; }
.sowa-end__journal-day { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-accent-700); margin-bottom: 2px; }
.sowa-end__journal-goal { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; margin-bottom: 2px; }
.sowa-end__journal-goal.is-good { color: var(--color-accent-2-800); }
.sowa-end__journal-goal.is-bad { color: var(--color-neutral-700); }
.sowa-end__journal-decision { display: grid; gap: 1px; padding-left: 10px; border-left: 2px solid var(--color-neutral-600); margin-top: 4px; }
.sowa-end__journal-decision.is-good { border-color: var(--color-accent-2-500); }
.sowa-end__journal-decision.is-bad { border-color: var(--color-accent-500); }
.sowa-end__journal-ev { font-weight: 600; }
.sowa-end__journal-ans em { font-style: normal; font-weight: 600; }

/* Sesja grupowa (kod zajęć) */
.sowa-session { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border-radius: var(--radius-md); background: var(--color-accent-2-100); color: var(--color-accent-2-900); font-size: 13px; margin-top: 16px; max-width: 440px; }
.sowa-session.is-bad { background: var(--color-accent-100); color: var(--color-accent-900); }
.sowa-session.is-compact { margin-top: 0; max-width: none; }
.sowa-session__icon { width: 28px; height: 28px; border-radius: 50%; background: var(--color-bg); display: grid; place-items: center; flex: none; }
.sowa-session__body { display: grid; gap: 6px; flex: 1; min-width: 0; }
.sowa-session__code { font-size: 12px; opacity: .8; letter-spacing: .06em; }
.sowa-session__warn { font-size: 12px; }
.sowa-session__nick { display: grid; gap: 3px; font-size: 12px; }
.sowa-session__nick input { font: inherit; font-size: 14px; padding: 7px 10px; border-radius: var(--radius-sm); border: 1px solid var(--color-accent-2-400); background: var(--color-bg); color: var(--color-text); max-width: 280px; }
.sowa-session__nick small { color: inherit; opacity: .75; }
.sowa-start__hint { font-size: 13px; color: var(--color-accent-800); margin: 8px 0 0; }

/* ================= Lista quizów ([sowa_quizy]) ================= */
/*
 * `width: 100%` przy liście quizów, quizie i trybie zajęć: w oknie (tryb domyślny od 0.1.23)
 * rodzic jest kolumną flex, a `margin: 0 auto` w takiej kolumnie nie rozciąga elementu, tylko
 * dociska go do szerokości treści. Quiz miał wtedy 230 px na szerokim ekranie, szerokość
 * skakała między pytaniami, a zdjęcie pytania było malutkie.
 */
.sowa-picker { width: 100%; max-width: 960px; margin: 0 auto; padding: 24px 16px; display: flex; flex-direction: column; gap: 20px; min-height: 420px; }
.sowa-picker--quiz { gap: 4px; }
.sowa-picker__bar { max-width: 720px; margin: 0 auto; width: 100%; padding: 12px 16px 0; }
.sowa-picker__head h2 { margin: 8px 0 6px; font-size: clamp(26px, 4vw, 34px); }
.sowa-picker__head .lead { margin: 0; max-width: 640px; }
.sowa-picker__group { display: flex; flex-direction: column; gap: 10px; }
.sowa-picker__group-title { margin: 0; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-accent-700); }
.sowa-picker__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.sowa-app .card.sowa-picker__card { cursor: pointer; text-align: left; display: flex; flex-direction: column; gap: 8px; padding: 18px; background: var(--color-neutral-100); border: 2px solid transparent; width: 100%; transition: transform .15s, border-color .15s; }
.sowa-app .card.sowa-picker__card:hover, .sowa-app .card.sowa-picker__card:focus-visible { border-color: var(--color-accent); transform: translateY(-2px); }
.sowa-picker__card-title { font-family: var(--font-heading); font-weight: 700; font-size: 18px; line-height: 1.2; }
.sowa-picker__card-summary { margin: 0; font-size: 13px; color: var(--color-neutral-700); line-height: 1.45; flex: 1; }
.sowa-picker__card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
.sowa-picker__go { font-size: 13px; font-weight: 700; color: var(--color-accent-700); }
.sowa-quiz__levels { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sowa-quiz__levels-label { font-size: 13px; color: var(--color-neutral-700); }
.sowa-quiz__note { margin: 0; font-size: 13px; color: var(--color-neutral-700); }

/* ================= 1f Class mode ================= */
.sowa-class { width: 100%; max-width: 820px; margin: 0 auto; border-radius: 28px; padding: 20px 16px; display: flex; flex-direction: column; gap: 18px; min-height: 560px; }
.sowa-class__head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.sowa-class__day { font-family: var(--font-heading); font-weight: 700; font-size: 22px; }
.sowa-class__group { margin-left: auto; font-size: 13px; color: var(--color-neutral-700); }
.sowa-class__grid { display: grid; grid-template-columns: 1fr; gap: 18px; flex: 1; }
.sowa-class__photo { border-radius: calc(var(--radius-lg) * 1.15); overflow: hidden; position: relative; min-height: 200px; background: var(--color-surface); }
.sowa-class__photo img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.sowa-class__q { display: flex; flex-direction: column; gap: 12px; }
.sowa-class__q h2 { font-size: clamp(22px, 4vw, 30px); line-height: 1.1; margin: 0; }
.sowa-class__q .instruction { font-size: 14px; color: var(--color-neutral-700); margin: 0; }
.sowa-class__answer { cursor: pointer; padding: 16px 18px; font-size: 16px; font-family: var(--font-heading); font-weight: 700; text-align: left; background: var(--color-neutral-100); border: 2px solid transparent; width: 100%; }
.sowa-class__answer.is-selected { background: var(--color-surface); border-color: var(--color-accent); }
.sowa-class__answer.is-good { border-color: var(--color-accent-2-500); }
.sowa-class__answer.is-bad { opacity: .7; }
.sowa-class__comment { font-size: 14px; background: var(--color-accent-2-100); color: var(--color-accent-2-900); border-radius: var(--radius-md); padding: 10px 14px; animation: sowa-fade .25s; }
.sowa-class__foot { display: flex; align-items: center; gap: 12px; border-top: 1px solid var(--color-divider); padding-top: 14px; flex-wrap: wrap; }
.sowa-class__tags { display: flex; gap: 6px; flex-wrap: wrap; }
.sowa-class__tags .tag { font-size: 12px; padding: 6px 12px; }
.sowa-class__nav { margin-left: auto; display: flex; gap: 8px; }

/* ================= Quiz ================= */
.sowa-quiz { width: 100%; max-width: 720px; margin: 0 auto; padding: 24px 16px; display: flex; flex-direction: column; gap: 16px; min-height: 420px; }
.sowa-quiz h2 { font-size: clamp(22px, 4vw, 30px); margin: 0; }
.sowa-quiz > .tag, .sowa-class > .tag { align-self: flex-start; }
.sowa-quiz__progress { font-size: 12px; color: var(--color-neutral-700); }
.sowa-quiz__answers { display: flex; flex-direction: column; gap: 10px; }
.sowa-quiz__note { font-size: 13px; color: var(--color-neutral-700); margin: 0; }

/* Odpowiedzi graficzne: kafelki ze zdjęciem i podpisem */
.sowa-quiz__answers--grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.sowa-quiz__tile-wrap { position: relative; display: flex; }
.sowa-quiz__tile-wrap > .card { flex: 1; }
.sowa-app .card.sowa-quiz__tile { display: flex; flex-direction: column; gap: 8px; padding: 10px; text-align: center; align-items: stretch; }
/* Domyślnie pokazujemy CAŁE zdjęcie (contain) — przycięcie obcinałoby skrzydła albo głowę,
   a w quizie rozpoznawania to właśnie sylwetka jest treścią pytania. */
.sowa-quiz__tile-img { display: block; position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-md); overflow: hidden; background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.sowa-quiz__tile-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.sowa-quiz__tile-img.is-cover img { object-fit: cover; }

/* Lupka: osobny przycisk nad kafelkiem — klik w kafelek to wybór odpowiedzi, klik w lupkę to podgląd */
/*
 * Zdjęcie pytania „co to za gatunek" ma pokazać całego ptaka: proporcje 4:3 zamiast paska
 * o stałej wysokości i `contain` zamiast `cover`. Przycięty kadr gubił głowę i oczy - czyli
 * dokładnie to, po czym rozpoznaje się sowę.
 */
.sowa-quiz__photo { position: relative; aspect-ratio: 4 / 3; max-height: 60vh; }
.sowa-quiz__photo .sowa-img img { object-fit: contain; object-position: center; }
.sowa-quiz__zoom { position: absolute; top: 14px; right: 14px; z-index: 3; width: 38px; height: 38px; display: grid; place-items: center; border: 0; border-radius: 50%; cursor: pointer; background: color-mix(in srgb, var(--color-bg) 88%, transparent); color: var(--color-text); box-shadow: var(--shadow-sm); }
.sowa-quiz__zoom:hover, .sowa-quiz__zoom:focus-visible { background: var(--color-bg); }
.sowa-quiz__tile-wrap .sowa-quiz__zoom { top: 16px; right: 16px; width: 34px; height: 34px; }

/* Podgląd na wierzchu */
.sowa-lightbox { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; padding: 16px; background: rgba(20, 17, 15, .82); animation: sowa-fade .15s; }
.sowa-lightbox__box { position: relative; margin: 0; max-width: min(1100px, 96vw); max-height: 92vh; display: flex; flex-direction: column; gap: 8px; }
.sowa-lightbox__box img { max-width: 100%; max-height: 86vh; width: auto; height: auto; border-radius: var(--radius-md); background: #fff; }
.sowa-lightbox__box figcaption { color: #f7f1e9; font-size: 14px; text-align: center; }
.sowa-lightbox__close { position: absolute; top: -6px; right: -6px; width: 40px; height: 40px; display: grid; place-items: center; border: 0; border-radius: 50%; cursor: pointer; background: var(--color-bg); color: var(--color-text); box-shadow: var(--shadow-md); }
.sowa-quiz__tile-label { font-size: 14px; }

/* Odpowiedzi dźwiękowe: odsłuch obok wyboru */
.sowa-quiz__answers--audio { gap: 12px; }
.sowa-app .card.sowa-quiz__sound { display: flex; flex-direction: row; align-items: center; gap: 12px; padding: 10px 12px; text-align: left; }
.sowa-quiz__sound-pick { flex: 1; text-align: left; background: none; border: 0; cursor: pointer; font: inherit; color: inherit; padding: 6px 4px; min-height: 40px; }
.sowa-quiz__sound-pick:disabled { cursor: default; opacity: .6; }
.sowa-quiz__listen { display: flex; align-items: center; gap: 12px; }
.sowa-quiz__listen-label { font-family: var(--font-heading); font-weight: 700; }

/* Przycisk odtwarzania */
.sowa-audio { display: inline-flex; align-items: center; gap: 8px; }
.sowa-audio__btn { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; border: 2px solid var(--color-divider); background: var(--color-neutral-100); color: inherit; border-radius: 999px; padding: 8px 12px; min-height: 40px; min-width: 40px; }
.sowa-audio__btn:hover { border-color: var(--color-accent); }
.sowa-audio__btn.is-playing { background: var(--color-accent-100, var(--color-surface)); border-color: var(--color-accent); }
.sowa-audio--lg .sowa-audio__btn { padding: 12px 16px; min-height: 52px; }
.sowa-audio__wave { display: inline-flex; align-items: flex-end; gap: 2px; height: 14px; }
.sowa-audio__wave i { width: 3px; height: 4px; border-radius: 2px; background: currentColor; opacity: .55; }
.sowa-audio__btn.is-playing .sowa-audio__wave i { animation: sowa-wave .9s ease-in-out infinite; }
.sowa-audio__btn.is-playing .sowa-audio__wave i:nth-child(2) { animation-delay: .15s; }
.sowa-audio__btn.is-playing .sowa-audio__wave i:nth-child(3) { animation-delay: .3s; }
.sowa-audio__err { font-size: 12px; color: var(--color-danger, #b3462e); }
@keyframes sowa-wave { 0%, 100% { height: 4px; } 50% { height: 14px; } }
@media (prefers-reduced-motion: reduce) { .sowa-audio__btn.is-playing .sowa-audio__wave i { animation: none; height: 10px; } }

.sowa-weight__trend { font-size: 12px; font-weight: 600; margin-left: 6px; }
.sowa-weight__trend.is-up { color: var(--color-accent-2-700, #5c6b45); }
.sowa-weight__trend.is-down { color: #b3462e; }

/* Dyplom po quizie */
.sowa-cert__cta { margin-top: 18px; }
.sowa-cert { margin-top: 18px; padding: 18px; border-radius: var(--radius-lg); background: var(--color-neutral-100); text-align: left; display: flex; flex-direction: column; gap: 10px; }
.sowa-cert__title { margin: 0; font-size: 18px; }
.sowa-cert__field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; font-weight: 600; }
.sowa-cert__field input { padding: 12px 14px; border-radius: 12px; border: 2px solid var(--color-divider); font: inherit; min-height: 44px; background: var(--color-bg); }
.sowa-cert__field input:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 1px; }
.sowa-cert__note { margin: 0; font-size: 12px; color: var(--color-neutral-700); line-height: 1.5; }
.sowa-cert__note--warn { color: #b3462e; }
/* Podgląd: ramka ma prawdziwe wymiary A4 (px przy 96 dpi) i jest skalowana do szerokości kontenera. */
.sowa-cert__preview { position: relative; width: 100%; border-radius: var(--radius-md); overflow: hidden; background: #fff; box-shadow: var(--shadow-sm); }
.sowa-cert__preview iframe { position: absolute; top: 0; left: 0; border: 0; transform-origin: top left; pointer-events: none; }

.sowa-quiz__result { text-align: center; padding: 24px 0; }
.sowa-quiz__score { font-family: var(--font-heading); font-weight: 700; font-size: 56px; line-height: 1; color: var(--color-accent); }
.sowa-quiz__bar { max-width: 320px; margin: 12px auto 16px; }

/* ================= Debug ================= */
.sowa-debug { position: absolute; left: 8px; bottom: 8px; z-index: 60; max-width: min(420px, calc(100% - 16px)); max-height: 60%; overflow: auto; background: rgba(32,30,29,.92); color: #f9f4ed; font: 11px/1.4 ui-monospace, Menlo, monospace; padding: 10px 12px; border-radius: 10px; box-shadow: var(--shadow-lg); }
.sowa-debug h6 { color: var(--color-accent-300); margin: 8px 0 4px; }
.sowa-debug table { border-collapse: collapse; }
.sowa-debug td { padding: 1px 6px 1px 0; }
.sowa-debug-toggle { position: absolute; left: 8px; bottom: 8px; z-index: 61; }

/* ================= Mobile (< 600) — doszlifowanie ================= */
@container sowa (max-width: 599px) {
  .sowa-panel { padding: 14px; }
  .sowa-item { flex-direction: column; align-items: stretch; }
  .sowa-item__side { flex-direction: row; align-items: center; justify-content: space-between; text-align: left; }
  .sowa-machine__row { grid-template-columns: 1fr; gap: 2px; }
  .sowa-actions .btn { min-height: 44px; }
  .sowa-answer, .sowa-class__answer { min-height: 48px; }
  .sowa-quiz__answers--grid { gap: 8px; }
  .sowa-quiz__tile { padding: 8px; }
  .sowa-quiz__tile-label { font-size: 13px; }
  .sowa-dash__top .nav-brand { font-size: 14px; }
  .sowa-dash__money .tag { font-size: 10px; }
  .sowa-event { padding: 16px; gap: 12px; }
  .sowa-end__visual { min-height: 240px; padding: 20px 16px; }
  .sowa-end__stats { gap: 12px 16px; }
  .sowa-intro__card { padding: 16px 14px 14px; }
}

/* ================= Responsive ≥ 600 ================= */
@container sowa (min-width: 600px) {
  .sowa-species-grid { grid-template-columns: 1fr 1fr; }
  .sowa-start .nav a.is-hidden-mobile { display: inline; }
  .sowa-event-backdrop { place-items: center; }
  .sowa-intro { padding: 36px 24px; }
  .sowa-intro__card { padding: 28px 32px 22px; }
  .sowa-intro__phases { grid-template-columns: 1fr 1fr; }
  .sowa-end__stats { grid-template-columns: 1fr 1fr; }
  .sowa-class { padding: 24px 28px; }
  .sowa-class__grid { grid-template-columns: 1fr 1fr; }
  .sowa-class__photo { min-height: 340px; }
}

/* ================= Responsive ≥ 900 ================= */
@container sowa (min-width: 900px) {
  /*
   * Górna granica kolumn + wyśrodkowanie. Bez tego na monitorze 1920 px karty gatunków
   * rozciągały się na ~700 px każda, choć mieszczą zdjęcie i trzy linijki tekstu - ekran
   * wyglądał na rozrzedzony, a nie na przestronny. Marginesy po bokach są teraz równe
   * i wyglądają na zamierzone.
   */
  .sowa-start__grid { grid-template-columns: minmax(320px, 400px) minmax(0, 880px); justify-content: center; gap: 44px; padding: 28px 44px 44px; }
  /* Nadpisujemy `width`/`height`, a nie zmienną: tę `ImageCircle` ustawia inline, więc
     wartość z karty i tak by przegrała. */
  .sowa-species-card .sowa-img { width: 112px; height: 112px; }
  .sowa-start .nav { padding: 14px 28px; }
  .sowa-dash__top { padding: 14px 28px; flex-wrap: nowrap; }
  .sowa-dash__top .sowa-daydots { order: 0; width: auto; margin-left: 12px; }
  .sowa-dash__grid { grid-template-columns: 1fr 340px; }
  .sowa-dash__main { padding: 24px 28px 28px; }
  .sowa-dash__aside { padding: 24px 28px 28px 0; }
  .sowa-actions { position: static; padding: 0; background: transparent; }
  .sowa-actions .btn { padding: 12px 20px; }
  .sowa-end { grid-template-columns: 1fr 1fr; min-height: 620px; }
  .sowa-end__visual { padding: 44px; }
  .sowa-end__summary { padding: 44px 44px 40px; }
}

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

/* ---------------------------------------------------------------- Praca nad błędami po quizie */

/*
 * Sekcja pojawia się pod wynikiem i jest jedynym miejscem, w którym quiz tłumaczy, czego
 * uczeń nie umiał. Dlatego ma wyglądać na osobną całość — wcięcie i linia u góry, a nie
 * kolejny akapit doklejony do punktacji.
 */
.sowa-quiz__review {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--color-divider, rgba(0, 0, 0, .12));
  text-align: left;
}

.sowa-quiz__review-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.sowa-quiz__review-head h3 { margin: 0; }

.sowa-quiz__review-intro,
.sowa-quiz__review-perfect {
  margin: 8px 0 0;
  color: var(--color-text-soft, #6a6f78);
  font-size: .95em;
}

.sowa-quiz__review-perfect { text-align: center; margin-top: 20px; }

.sowa-quiz__review-list {
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 16px;
}

.sowa-quiz__review-item {
  padding: 16px 18px;
  border: 1px solid var(--color-divider, rgba(0, 0, 0, .12));
  border-radius: 14px;
  background: var(--color-surface, #fff);
}

.sowa-quiz__review-q { margin: 0 0 10px; font-weight: 600; }

.sowa-quiz__review-img {
  width: 100%;
  max-width: 220px;
  border-radius: 10px;
  margin-bottom: 10px;
}

.sowa-quiz__review-audio {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  font-size: .9em;
  color: var(--color-text-soft, #6a6f78);
}

.sowa-quiz__review-a { margin: 0 0 4px; font-size: .96em; }

/* Kolor nie jest jedynym nośnikiem informacji — etykieta „Twoja odpowiedź” / „Poprawnie”
   mówi to samo słowami, więc przekaz działa też przy daltonizmie. */
.sowa-quiz__review-a--bad { color: var(--color-danger, #b3462e); }
.sowa-quiz__review-a--good { color: var(--color-success, #1a7f37); }

.sowa-quiz__review-label { font-weight: 700; }

.sowa-quiz__review-why {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px dashed var(--color-divider, rgba(0, 0, 0, .12));
  font-size: .92em;
  color: var(--color-text-soft, #6a6f78);
}

@media (max-width: 600px) {
  .sowa-quiz__review-item { padding: 14px; }
}

/* ================= 1g Encyklopedia ================= */

.sowa-enc { display: flex; flex-direction: column; gap: 18px; padding: 20px 16px; }
.sowa-enc__head { display: flex; flex-direction: column; gap: 8px; }

/*
 * Wyszukiwarka pojawia się dopiero przy kilkunastu hasłach — przy sześciu kartach pole „szukaj”
 * jest wolniejsze od spojrzenia na listę.
 */
.sowa-enc__search { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sowa-enc__search-label { font-size: 13px; color: var(--color-neutral-700); }
.sowa-enc__search-input { flex: 1; min-width: 180px; padding: 10px 12px; border: 1px solid var(--color-neutral-300); border-radius: var(--radius-md); background: var(--color-bg); font: inherit; font-size: 14px; }
.sowa-enc__search-input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.sowa-enc__nothing { margin: 0; font-size: 14px; color: var(--color-neutral-700); }

/* ---- Lista gatunków ----
 *
 * Układ zależy od tego, ile miejsca dostała aplikacja - i to jest tu sedno, bo encyklopedia
 * stoi raz w kolumnie tekstu (ok. 600 px), raz na całym oknie.
 *
 * Skąd ta przebudowa: w kolumnie tekstu mieściły się dwie karty w rzędzie, każda z dużym
 * zdjęciem u góry. Trzynaście gatunków dawało siedem rzędów i **3700 px samej siatki** -
 * wstęgę, przez którą trzeba było przewijać ekran za ekranem, oglądając po dwa ptaki naraz.
 * W wąskim miejscu lista ma być listą: małe zdjęcie z boku, tekst obok, jedna pozycja
 * w rzędzie. Ta sama treść mieści się wtedy na jednej trzeciej dawnej długości.
 *
 * Dopiero gdy aplikacja ma szerokość galerii, przechodzimy na siatkę z dużymi zdjęciami.
 */
.sowa-enc__grid { display: grid; grid-template-columns: 1fr; gap: 10px; }

.sowa-app .card.sowa-enc__card {
	cursor: pointer;
	text-align: left;
	display: flex;
	flex-direction: row;
	align-items: stretch;
	gap: 0;
	padding: 0;
	overflow: hidden;
	background: var(--color-neutral-100);
	border: 2px solid transparent;
	width: 100%;
	transition: transform .15s, border-color .15s;
}
.sowa-app .card.sowa-enc__card:hover,
.sowa-app .card.sowa-enc__card:focus-visible { border-color: var(--color-accent); transform: translateY(-2px); }

/*
 * Kadr dobrany dokładnie do proporcji materiałów: 17/24, czyli 0,708.
 *
 * Pomiar na plikach, które naprawdę leżą w bibliotece: dziesięć z trzynastu ma 340x480,
 * czyli równo 0,708. To nie są zdjęcia „z aparatu”, tylko **złożone grafiki z wpisaną
 * nazwą łacińską u góry** - a to zmienia regułę: z takiej planszy nie wolno uciąć niczego,
 * bo razem z marginesem znika podpis.
 *
 * Każdy inny kadr coś psuł. 4:3 obcinał pionowym wszystko poza środkiem. Kwadrat z `contain`
 * mieścił całość, ale obudowywał ją pustymi pasami i rozdymał kartę do 561 px. Kadr 4:5
 * (0,8) jest SZERSZY od materiałów, więc `cover` przycinał im górę i dół - i ucinał właśnie
 * te nazwy łacińskie.
 *
 * Przy kadrze równym proporcji źródła `cover` nic nie przycina: plansza wypełnia ramkę
 * co do piksela. `contain` byłby tu gorszy - chroniłby te trzy pliki, które z proporcji
 * odstają, ale kosztem pozostałych dziesięciu: płomykówka (jedyne prawdziwe zdjęcie,
 * poziome 4:3) kurczyłaby się do jednej trzeciej wysokości ramki i zostawiała pod sobą
 * pustkę, a karta obok wyglądałaby na zepsutą.
 *
 * `object-position: center top` rozstrzyga, co poświęcić przy tych trzech odstających:
 * przycinamy DÓŁ, nigdy górę - bo u góry plansz stoi nazwa łacińska i to ona zniknęłaby
 * pierwsza. Zdjęcia poziome tracą brzegi po bokach, gdzie i tak jest tło, a nie ptak.
 */
.sowa-enc__card-photo {
	display: block;
	width: 116px;
	flex: none;
	align-self: stretch;
	/* Kadr podaje aplikacja: to mediana proporcji materiałów, które naprawdę są w bibliotece.
	   17/24 zostaje jako wartość zapasowa, gdy wymiarów nie znamy. */
	aspect-ratio: var(--sowa-enc-kadr, 17 / 24);
	height: auto;
	object-fit: cover;
	object-position: center top;
	background: var(--color-neutral-100);
}

/* Zdjęcie, które od kadru odstaje (dwa poziome na trzynaście), mieści się w CAŁOŚCI.
   Tło jest takie samo jak tło karty, więc pas nad i pod zdjęciem nie wygląda na dziurę,
   tylko na margines. Lepszy margines niż ucięte skrzydło. */
.sowa-enc__card-photo--mieszcz { object-fit: contain; object-position: center; }

.sowa-enc__card-photo--brak { background: var(--color-accent-2-100); }
.sowa-enc__card-body { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; justify-content: center; min-width: 0; flex: 1; }
.sowa-enc__card-gora { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.sowa-enc__card-name { font-family: var(--font-heading); font-weight: 700; font-size: 17px; line-height: 1.2; }

/* Aplikacja dostała szerokość galerii - wracamy do siatki z dużymi zdjęciami. */
@container sowa (min-width: 700px) {
	.sowa-enc__grid { grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 16px; }
	.sowa-app .card.sowa-enc__card { flex-direction: column; }
	.sowa-enc__card-photo { width: 100%; align-self: auto; }
	.sowa-enc__card-body { justify-content: flex-start; padding: 14px 16px 16px; }
	.sowa-enc__card-summary { -webkit-line-clamp: 3; line-clamp: 3; }
}

/* ---- Oznaczenie lęgowości ----
 *
 * Kolor NIE jest jedynym nośnikiem znaczenia: obok stoi ikona i słowo, bo zieleni od szarości
 * nie odróżnia jeden na dwunastu mężczyzn. Pary kolorów policzone pod WCAG AA:
 * zieleń 800 na zieleni 100 daje 9,1:1, szarość 800 na szarości 200 - 8,1:1, a obwódki
 * (element nietkstowy, próg 3:1) odpowiednio 3,9:1 i 3,5:1. Szarość 500 odpadła: 2,35:1. */
.sowa-enc__legowosc {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 3px 9px;
	border-radius: var(--radius-pill, 999px);
	border: 1px solid;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.3;
	white-space: nowrap;
}
.sowa-enc__legowosc .sowa-icon { width: 13px; height: 13px; }
.sowa-enc__legowosc--legowa {
	background: var(--color-accent-2-100);
	border-color: var(--color-accent-2-600);
	color: var(--color-accent-2-800);
}
.sowa-enc__legowosc--zalatuje {
	background: var(--color-neutral-200);
	border-color: var(--color-neutral-600);
	color: var(--color-neutral-800);
}

/* Nazwa łacińska i oznaczenie stoją w jednym wierszu, ale na wąskim ekranie schodzą pod siebie. */
.sowa-enc__podtytul { margin: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sowa-enc__podtytul .sowa-enc__latin { font-size: 14px; color: var(--color-neutral-700); font-style: italic; }
.sowa-enc__card-latin { font-size: 12px; color: var(--color-neutral-700); }
/* Zajawka w liście: dwa wiersze wystarczą, żeby wiedzieć, czy wejść głębiej. Bez ograniczenia
   karty w jednym rzędzie mają różną wysokość i lista faluje. */
.sowa-enc__card-summary {
	font-size: 13px;
	color: var(--color-neutral-700);
	line-height: 1.45;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* ---- Karta otwarta ---- */

.sowa-enc__detail { display: flex; flex-direction: column; gap: 20px; }
.sowa-enc__bar { display: flex; }
.sowa-enc__detail-head { display: flex; flex-direction: column; gap: 6px; }
.sowa-enc__name { margin: 0; }
/* Nagłówek dostaje fokus po otwarciu karty — obwódka wokół samego tekstu jest zbędna. */
.sowa-enc__name:focus { outline: none; }
.sowa-enc__name:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; border-radius: var(--radius-sm); }
.sowa-enc__latin { margin: 0; font-size: 14px; color: var(--color-neutral-700); }
.sowa-enc__summary { margin: 0; }

.sowa-enc__section { display: flex; flex-direction: column; gap: 10px; }
.sowa-enc__section-title { margin: 0; font-family: var(--font-heading); font-size: 16px; }

.sowa-enc__gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.sowa-enc__shot { margin: 0; display: flex; flex-direction: column; gap: 4px; }
.sowa-enc__shot-btn { padding: 0; border: 0; border-radius: var(--radius-md); overflow: hidden; background: none; cursor: zoom-in; display: block; }
.sowa-enc__shot-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* W galerii hasła każdy materiał dostaje ramkę równą swojej proporcji (zmienna z JS-a),
   więc `contain` nic nie zostawia na boki. Kadr zapasowy działa tylko bez wymiarów. */
.sowa-enc__shot-btn img { display: block; width: 100%; aspect-ratio: var(--sowa-enc-kadr, 17 / 24); object-fit: contain; background: var(--color-surface); }
.sowa-enc__shot-caption { display: flex; flex-direction: column; gap: 2px; }
.sowa-enc__shot-note { font-size: 13px; }

.sowa-enc__calls { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sowa-enc__call { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--color-surface); }
.sowa-enc__call-desc { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sowa-enc__call-note { font-size: 14px; }

/*
 * Podpis autora jest drobny, ale zawsze widoczny: licencje Wikimedia Commons i xeno-canto
 * wymagają go przy każdym pokazaniu materiału, więc nie chowamy go pod „pokaż źródła”.
 */
.sowa-enc__credit { margin: 0; font-size: 11px; line-height: 1.4; color: var(--color-neutral-600, var(--color-neutral-700)); }
.sowa-enc__credit a { color: inherit; }

.sowa-enc__facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; margin: 0; }
.sowa-enc__fact { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--color-surface); }
.sowa-enc__fact-label { font-size: 12px; font-weight: 700; color: var(--color-neutral-700); text-transform: uppercase; letter-spacing: .02em; }
.sowa-enc__fact-value { margin: 0; font-size: 14px; line-height: 1.45; }

@container sowa (max-width: 600px) {
  .sowa-enc { padding: 16px 12px; }
  /* Kolumn listy gatunków TU NIE USTAWIAMY.
     Stała tu kiedyś siatka `minmax(160px, 1fr)` - z czasów, gdy karta miała zdjęcie u góry.
     Gdy karta zmieniła się w wiersz (zdjęcie z boku, tekst obok), ta reguła została i przy
     wąskim pojemniku wciskała dwie kolumny po 163 px: na zdjęcie szło 116 px, a na nazwę,
     oznaczenie i opis zostawały 43 px. Wąski pojemnik to telefon - czyli dokładnie to
     miejsce, gdzie lista musi być listą. Kolumny ustawia teraz wyłącznie `.sowa-enc__grid`
     (jedna) i blok `@container sowa (min-width: 700px)` (siatka). */
  .sowa-enc__gallery { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ================= 1h Słowniczek ================= */

/*
 * Podkreślone pojęcie w tekście. Kropkowana linia, a nie kolor: kolorowy wyraz w akapicie czyta
 * się jak odnośnik, a to nie jest odnośnik — nigdzie nie prowadzi, tylko się rozwija.
 */
.sowa-termin-wrap { position: relative; }

.sowa-termin {
  padding: 0;
  border: 0;
  border-bottom: 1px dotted currentColor;
  background: none;
  color: inherit;
  font: inherit;
  cursor: help;
}
.sowa-termin:hover { border-bottom-style: solid; }
.sowa-termin:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 2px; }
.sowa-termin.is-otwarty { border-bottom-style: solid; font-weight: 600; }

/*
 * Wyjaśnienie rozwija się pod akapitem, a nie unosi nad tekstem. Dymek nad treścią zasłania
 * zdanie, od którego się zaczęło — czyli dokładnie to, do czego czytający chce wrócić.
 */
.sowa-termin__opis {
  display: block;
  margin: 8px 0;
  padding: 10px 12px;
  border-left: 3px solid var(--color-accent);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--color-accent-100);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
}
.sowa-termin__nazwa { display: block; font-weight: 700; margin-bottom: 2px; }
.sowa-termin__tresc { display: block; }
.sowa-termin__uwaga { display: block; margin-top: 6px; font-size: 13px; color: var(--color-neutral-700); }

/* ---- Ekran słowniczka ---- */

.sowa-glos { display: flex; flex-direction: column; gap: 18px; padding: 20px 16px; }
.sowa-glos__head { display: flex; flex-direction: column; gap: 8px; }

.sowa-glos__search { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sowa-glos__search-label { font-size: 13px; color: var(--color-neutral-700); }
.sowa-glos__search-input { flex: 1; min-width: 180px; padding: 10px 12px; border: 1px solid var(--color-neutral-300); border-radius: var(--radius-md); background: var(--color-bg); font: inherit; font-size: 14px; }
.sowa-glos__search-input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.sowa-glos__nothing { margin: 0; font-size: 14px; color: var(--color-neutral-700); }

.sowa-glos__grupa { display: flex; flex-direction: column; gap: 8px; }
.sowa-glos__grupa-tytul { margin: 0; font-family: var(--font-heading); font-size: 16px; }

.sowa-glos__lista { margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.sowa-glos__haslo { padding: 12px 14px; border-radius: var(--radius-md); background: var(--color-surface); }
.sowa-glos__termin { margin: 0 0 4px; font-weight: 700; font-size: 15px; }
.sowa-glos__opis { margin: 0; font-size: 14px; line-height: 1.5; }
.sowa-glos__uwaga { display: block; margin-top: 6px; font-size: 13px; color: var(--color-neutral-700); }

@container sowa (max-width: 600px) {
  .sowa-glos { padding: 16px 12px; }
  .sowa-glos__lista { grid-template-columns: 1fr; }
}

/* ================= 1i Rachunek na całe życie ================= */

/*
 * Wyróżniony, ale nie krzykliwy. To nie jest ostrzeżenie ani reklama — to rachunek, i ma wyglądać
 * jak rachunek: liczby duże, komentarz mały, zero wykrzykników.
 */
.sowa-rachunek {
  margin-top: 18px;
  padding: 18px 16px;
  border: 1px solid var(--color-neutral-300);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.sowa-rachunek__tytul { margin: 0 0 6px; font-family: var(--font-heading); font-size: 18px; }
.sowa-rachunek__wstep { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--color-neutral-700); }

.sowa-rachunek__liczby {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin: 0;
}

.sowa-rachunek__poz { display: flex; flex-direction: column; gap: 2px; }
.sowa-rachunek__poz dt { font-size: 12px; text-transform: uppercase; letter-spacing: .03em; color: var(--color-neutral-700); }
/* Liczba jest treścią tej sekcji — reszta to podpisy. */
.sowa-rachunek__poz dd { margin: 0; font-family: var(--font-heading); font-size: 22px; line-height: 1.15; font-variant-numeric: tabular-nums; }

.sowa-rachunek__porownanie {
  margin: 14px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--color-accent);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--color-accent-100);
  font-size: 14px;
  line-height: 1.5;
}

.sowa-rachunek__uwaga { margin: 12px 0 0; font-size: 13px; line-height: 1.5; color: var(--color-neutral-700); }

@container sowa (max-width: 600px) {
  .sowa-rachunek { padding: 14px 12px; }
  .sowa-rachunek__poz dd { font-size: 19px; }
}

/* ------------------------------------------------------------------ */
/*  Tryb modal: ozdobny przycisk w treści + aplikacja na pełnym ekranie */
/* ------------------------------------------------------------------ */

/* Przycisk jest jedynym śladem symulatora w kolumnie tekstu, więc ma wyglądać na zaproszenie,
   a nie na link. Cała karta jest klikalna — stąd <button> opakowujący treść. */
.sowa-launcher { margin: 28px 0; }

.sowa-launcher__btn {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: 44px;
  padding: 18px 20px;
  border: 1px solid var(--color-accent-300);
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--color-accent-100), var(--color-surface) 70%);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}

.sowa-launcher__btn:hover { border-color: var(--color-accent-500); box-shadow: var(--shadow-md); transform: translateY(-1px); }
.sowa-launcher__btn:focus-visible { outline: 3px solid var(--color-accent-600); outline-offset: 2px; }
.sowa-launcher__btn:active { transform: none; box-shadow: var(--shadow-sm); }

/* Glif: sowa w kółku. Rysowany CSS-em, żeby przycisk nie czekał na żaden plik. */
.sowa-launcher__glif {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--color-accent-500) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3c-4.4 0-8 3.1-8 7v5a6 6 0 0 0 6 6h4a6 6 0 0 0 6-6v-5c0-3.9-3.6-7-8-7Z'/%3E%3Ccircle cx='9' cy='11' r='2.2'/%3E%3Ccircle cx='15' cy='11' r='2.2'/%3E%3Cpath d='M12 14.5v2'/%3E%3Cpath d='m5 5 2 2.5M19 5l-2 2.5'/%3E%3C/svg%3E") center / 28px 28px no-repeat;
}

.sowa-launcher__tekst { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sowa-launcher__tytul { font-family: var(--font-heading); font-size: 19px; line-height: 1.2; }
.sowa-launcher__opis { font-size: 14px; line-height: 1.45; color: var(--color-text-soft); }

@media (max-width: 480px) {
  .sowa-launcher__btn { gap: 12px; padding: 14px; }
  .sowa-launcher__glif { width: 38px; height: 38px; background-size: 23px 23px; }
  .sowa-launcher__tytul { font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  .sowa-launcher__btn { transition: none; }
  .sowa-launcher__btn:hover { transform: none; }
}

/* Okno wypełnia cały ekran co do piksela. <dialog> siedzi w warstwie top layer,
   więc z-index motywu nas nie obchodzi. `position: fixed` czyni z okna układ odniesienia
   dla przycisku zamykania. */
.sowa-modal {
  position: fixed;
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--color-bg);
  color: var(--color-text);
  overflow: hidden;
}

.sowa-modal::backdrop { background: rgb(0 0 0 / .72); }

/* Cała wysokość dla aplikacji — przycisk zamykania nie zabiera jej paska u góry,
   tylko leży nad treścią. Przewija się zawartość okna, nie strona pod spodem. */
.sowa-modal__tresc { height: 100dvh; overflow: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
/*
 * Powłoka gry wypełnia okno niezależnie od tego, ile treści ma bieżąca zakładka.
 *
 * Bez tego `.sowa-app` dopasowywał wysokość do zawartości: „Ustawienia” mają dwa wiersze,
 * więc powłoka kurczyła się do jednej trzeciej ekranu, pasek boczny i las urywały się
 * w powietrzu, a pod spodem świeciło puste tło okna. Przy przełączaniu zakładek cały
 * układ skakał, bo każdy widok ma inną wysokość.
 *
 * `min-height` zamiast `height`: pulpit bywa wyższy niż okno i ma się normalnie przewijać.
 */
.sowa-modal__tresc .sowa-app { max-width: none; margin: 0; min-height: 100%; display: flex; flex-direction: column; }
.sowa-modal__tresc .sowa-app > * { flex: 1 0 auto; }

/*
 * Telefon: zakładki przypięte do dolnej krawędzi ekranu, pasek górny do górnej, a przewija
 * się tylko treść pomiędzy nimi.
 *
 * Dwa wcześniejsze podejścia nie mogły zadziałać i warto wiedzieć dlaczego, zanim ktoś
 * spróbuje ich znowu:
 *   - `sticky` na samych zakładkach - rodzic `.sowa-nav` ma dokładnie ich wysokość, więc
 *     element nie ma się w czym przesuwać; przeniesienie o poziom wyżej nie pomaga, bo
 *     `.sowa-nav` jest ostatnim dzieckiem i już leży przy dolnej krawędzi rodzica;
 *   - `fixed` - `.sowa-app` niesie `container-type: inline-size`, czyli `contain: layout`,
 *     a to ustanawia własny blok odniesienia dla elementów `fixed`. Przykleiłyby się więc
 *     do dołu aplikacji, nie okna, czyli znowu na koniec treści.
 *
 * Zostaje jedyne rozwiązanie, które w ogóle działa: przewijanie schodzi z okna modala
 * do środkowej kolumny, a pasek i nawigacja zostają poza nim.
 *
 * `@media`, nie `@container`: regułę trzeba nałożyć na samo `.sowa-app`, a zapytanie
 * kontenerowe dotyczy wyłącznie POTOMKÓW kontenera - element nie zapyta o własną szerokość.
 * W oknie pełnoekranowym szerokość okna i tak równa się szerokości aplikacji.
 */
@media (max-width: 899px) {
	.sowa-modal__tresc { overflow: hidden; }
	.sowa-modal__tresc .sowa-app { height: 100%; min-height: 0; }
	.sowa-modal__tresc .sowa-app > * { flex: 1 1 auto; min-height: 0; }
	.sowa-modal__tresc .sowa-gra { min-height: 0; }
	.sowa-modal__tresc .sowa-gra__korpus { min-height: 0; }
	.sowa-modal__tresc .sowa-gra__tresc { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
	.sowa-modal__tresc .sowa-pasek,
	.sowa-modal__tresc .sowa-tura { flex: none; }
	.sowa-modal__tresc .sowa-nav { flex: none; position: static; }
	/*
	 * Ekrany spoza gry (wstęp, wybór gatunku, koniec gry, quizy) nie mają środkowej kolumny,
	 * więc przewijają się same. Od beta18 przewijała się tylko kolumna gry: na telefonie koniec
	 * gry urywał się na krawędzi ekranu, a rachunek na całe życie i „Zagraj jeszcze raz” były
	 * nieosiągalne (odbiór lokalny, etap 6).
	 */
	/*
	 * Przewija się każdy ekran stojący wprost w aplikacji - nie tylko ten z klasą `sowa-screen`.
	 * Quiz wybrany z listy siedzi w opakowaniu `.sowa-picker--quiz` (bez `sowa-screen`, bo ta
	 * klasa niesie animację wejścia, a quiz w środku ma własną), a ładowanie i błąd quizu
	 * i zajęć nie mają jej wcale. Na telefonie wszystkie one ucinały się na krawędzi ekranu:
	 * w pytaniach ze zdjęciem „Następne pytanie” było nieosiągalne, a z wyników widać było
	 * jedną czwartą (audyt 28.09, beta28). `overscroll-behavior` - żeby koniec przewijania
	 * nie szarpał stroną pod oknem (iOS).
	 */
	.sowa-modal__tresc .sowa-app > .sowa-screen,
	.sowa-modal__tresc .sowa-app > .sowa-picker,
	.sowa-modal__tresc .sowa-app > .sowa-quiz,
	.sowa-modal__tresc .sowa-app > .sowa-class { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
	/* Pojedynczy quiz: kolumna 720 px zostaje, ale przewija się całą szerokością okna
	   (na tablecie palec na marginesie nic nie robił), a „Zamknij” nie kładzie się na
	   „Pytanie 1 z 10”. */
	.sowa-modal__tresc .sowa-app > .sowa-quiz { max-width: none; padding-inline: max(16px, calc((100% - 688px) / 2)); padding-top: 56px; }
	/* Siatka końca gry w przewijanym pudełku ściskała wiersz ze zdjęciem do `min-height`,
	   a ukryte przepełnienie ucinało opis w pół zdania. Wiersze według treści. */
	.sowa-modal__tresc .sowa-end { grid-auto-rows: max-content; }
	/* Tryb zajęć nie ma paska gry, pod którym „Zamknij” ma swoje miejsce (patrz `.sowa-pasek`),
	   więc przycisk zasłaniał dzień zajęć - aż do ok. 700 px, gdzie nagłówek łamie się na dwa. */
	.sowa-modal__tresc .sowa-class { padding-top: 56px; }
}
/*
 * Niski ekran (telefon trzymany poziomo, mały telefon): pasek, pasek tury i zakładki były
 * przypięte, a przewijała się tylko kolumna między nimi. Przy 740×360 zostawało na nią 64 px
 * (pasek 170, tura 54, zakładki 71) - grać się nie dało (audyt 28.09).
 * Tu przewija się cała gra: pasek i tura odjeżdżają z treścią, zakładki zostają przyklejone
 * do dołu (sticky w `.sowa-gra__korpus`, który rośnie z treścią). Aplikacja dalej ma
 * wysokość ekranu - okna dialogowe gry są `fixed` względem niej (`container-type`), więc
 * w wydłużonej aplikacji wyskakiwałyby poza widokiem.
 * Barwa pory dnia i niebo są rozpięte na `.sowa-gra`; w przewijanym pudełku zabarwiłyby
 * tylko pierwszy ekran, więc przypinamy je do widoku (`fixed` = względem aplikacji).
 */
@media (max-width: 899px) and (max-height: 600px) {
	.sowa-modal__tresc .sowa-gra { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
	.sowa-modal__tresc .sowa-gra__korpus { flex: none; }
	.sowa-modal__tresc .sowa-gra__tresc { overflow: visible; }
	/* Reguła dla telefonu wyżej robi zakładkom `static` (tam przewija się tylko kolumna) -
	   tu muszą znów trzymać się dołu przewijanej gry. */
	.sowa-modal__tresc .sowa-nav { position: sticky; bottom: 0; }
	.sowa-modal__tresc .sowa-gra__pora,
	.sowa-modal__tresc .sowa-gra__niebo,
	.sowa-modal__tresc .sowa-gra::after { position: fixed; }
}
/* „Lista quizów” nad pytaniem sięga środka ekranu dopiero na telefonie. */
@media (max-width: 599px) {
	.sowa-modal__tresc .sowa-picker__bar { padding-top: 52px; }
}

/* Wyjście: zakładka zwisająca ze środka górnej krawędzi. Jedno stałe miejsce, w którym
   oko szuka wyjścia. Własne tło i cień, bo pod spodem może być cokolwiek — zdjęcie,
   ciemna scena nocna albo biała karta quizu. */
/* Selektor z rodzicem, bo zaokraglenie przegrywalo z ogolna regula motywu na <button>. */
.sowa-modal .sowa-modal__zamknij {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 10px 22px;
  border: 1px solid var(--color-neutral-300);
  border-top: 0;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-md);
  color: var(--color-text);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s ease, padding .15s ease;
}

.sowa-modal .sowa-modal__zamknij:hover { background: var(--color-neutral-100); padding-bottom: 14px; }
.sowa-modal .sowa-modal__zamknij:focus-visible { outline: 3px solid var(--color-accent-600); outline-offset: 2px; }

/* Krzyżyk rysowany dwiema kreskami — bez pliku i bez czekania na font ikon. */
.sowa-modal__krzyzyk {
  position: relative;
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

.sowa-modal__krzyzyk::before,
.sowa-modal__krzyzyk::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.sowa-modal__krzyzyk::before { transform: rotate(45deg); }
.sowa-modal__krzyzyk::after { transform: rotate(-45deg); }

@media (max-width: 480px) {
  .sowa-modal .sowa-modal__zamknij { padding: 10px 16px; font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .sowa-modal__zamknij { transition: none; }
  .sowa-modal .sowa-modal__zamknij:hover { padding-bottom: 10px; }
}

/* Strona pod otwartym oknem nie ma się przewijać. Warunek w CSS-ie, a nie klasa zdejmowana
   w JS-ie: okno zamyka Esc, przycisk i kliknięcie w tło, więc jedno źródło prawdy jest tu
   odporniejsze niż trzy miejsca sprzątające po sobie. */
html:has(dialog.sowa-modal[open]) { overflow: hidden; }
