/* ==========================================================================
   Farmersi 2.0 — components.css
   Karty, przyciski-szyldy, tabele, plakietki, akordeon.
   STYL.md: "Karty jak listy gończe / strony gazety", "Przyciski jak szyldy
   w saloonie (obramowanie, nie wypełnienie)".
   ========================================================================== */

/* ==========================================================================
   PRZEŁĄCZANIE ZAKŁADEK — krótka animacja wejścia treści
   Właściciel: „to samo w arkuszu gry — czy przy przełączaniu zakładek mogą
   być jakieś szybkie animacje?" Chodzi o to, żeby gra wyglądała jak
   aplikacja, a nie jak zwykła strona.
   Zasady (ustalone w projekcie, nie rozciągamy czasów):
     - 200 ms, wyłącznie CSS (krycie + drobne przesunięcie 6 px),
     - BEZ wpływu na układ: `transform` nie zmienia przepływu, więc wysokość
       arkusza i pozycja przycisku zapisu nie drgają,
     - klasę `zakladka-wjazd` dodaje `zakladki.js` TYLKO przy zmianie
       zakładki — stan początkowy jej nie dostaje, żeby wejście na stronę
       nie migotało,
     - przy `prefers-reduced-motion: reduce` animacja jest wyłączona.
   ========================================================================== */

/* ANIMACJA ZAKŁADEK USUNIĘTA (27.10.2026).
   Właściciel: „nie ma już chyba skakania, ale jest znikanie. jeśli to jest ta
   animacja, to lepiej bez niej. by było stabilnie”. Przenikanie treści przy
   każdym przełączeniu (a arkusz przebudowuje się także po zmianie oferty)
   czytało się jak mruganie. Zostaje natychmiastowa zmiana widoczności.
   Klasa `.zakladka-wjazd` nie jest już nigdzie dodawana — trzymamy komentarz,
   żeby nikt jej nie przywrócił „bo kiedyś była”. */

@media (prefers-reduced-motion: reduce) {
  [data-zakladka-tresc].zakladka-wjazd {
    animation: none;
  }
}

/* ==========================================================================
   KARTA
   ========================================================================== */

.karta {
  background: var(--tlo-papier);
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  box-shadow: var(--cien-1);
  padding: var(--odst-4);
}

@media (min-width: 48rem) {
  .karta {
    padding: var(--odst-5);
  }
}

.karta--zwarta {
  padding: var(--odst-3);
}

/* AKTUALNOŚCI — PANEL Z KAFELKAMI (21.10.2026).
 *
 * Właściciel: „aktualności — panel i kafelki jak na forum" (lista od Groka,
 * pkt 6). Wcześniej niusy były „stroną gazety": bez ramek, jeden pod drugim,
 * rozdzielone kreską. Teraz jest PANEL (mocna ramka, ciemniejszy papier)
 * i KAFELKI w środku (biały papier, jasna ramka) — dokładnie jak wypowiedzi
 * w „Ostatnio na forum", dzięki czemu oba strumienie wyglądają jak rodzina. */
.aktualnosci-ramka {
  padding: var(--odst-4);
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier-ciemny);
}

/* Kafelek niusa. `karta--gazeta` zostaje w nazwie, bo jest w HTML niusów
 * (statycznych, generowanych) i w testach — ale wygląd jest teraz kafelkowy. */
.aktualnosci-ramka .karta--gazeta {
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  padding: var(--odst-3);
  box-shadow: none;
}

/* Odstęp między kafelkami daje `gap` kontenera `.stos` (16 px) — wcześniej stał
 * tu separator `border-top` (linia między niusami), który przy kafelkach
 * z ramką rysował podwójne linie. */

/* Tytuł niusa — 16 px z arkusza, a nie 18 px wpisane w JS/renderer. */
.aktualnosci-ramka .karta--gazeta h3 {
  margin: 0;
  font-size: 16px;
}

/* JUSTOWANIE + DZIELENIE WYRAZÓW (22.10.2026, uwaga Groka).
 * Właściciel chce tekstów justowanych „po gazetowemu", ale przy wąskiej
 * kolumnie (375 px) justowanie bez dzielenia wyrazów robi rzeki światła.
 * Dlatego: justowanie wraca, a `hyphens: auto` pozwala przeglądarce dzielić
 * wyrazy (wymaga `lang="pl"` na <html> — jest na każdej stronie).
 * `overflow-wrap` łapie bardzo długie wyrazy (np. adresy), których dzielenie
 * nie obejmuje. */
.karta--gazeta p {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
}

.przewodnik p,
.przewodnik li,
.przewodnik dd {
  hyphens: auto;
  -webkit-hyphens: auto;
}

@media (max-width: 600px) {
  .przewodnik p, .przewodnik li, .przewodnik dd,
  .karta--gazeta p {
    hyphens: auto;
    -webkit-hyphens: auto;
  }
}

/* ARCHIWUM STARSZYCH NIUSÓW (pkt 7).
 * Pięć najnowszych widać od razu, reszta leży w `<details>` — w HTML, więc
 * wyszukiwarki widzą całą treść (wcześniej niusy wstawiał JS i Google widział
 * pusty pojemnik). Tylko `<details>`, bez `display:none` i bez JS. */
.nius-archiwum {
  margin-top: var(--odst-3);
}

.nius-archiwum > summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--odst-2);
  min-height: 44px;
  padding: var(--odst-2) var(--odst-3);
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  color: var(--akcent);
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-s);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  cursor: pointer;
  list-style: none;
}

.nius-archiwum > summary::-webkit-details-marker {
  display: none;
}

.nius-archiwum > summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

.nius-archiwum[open] > summary::after {
  transform: rotate(-135deg);
}

.nius-archiwum > summary:hover,
.nius-archiwum > summary:focus-visible {
  color: var(--akcent-czerwony);
}

/* Kafelki w archiwum mają ten sam odstęp co widoczne. */
.nius-archiwum > .karta--gazeta:first-of-type {
  margin-top: var(--odst-3);
}

.karta--wyrozniona {
  background: var(--tlo-papier-ciemny);
  border-color: var(--linia-mocna);
  box-shadow: var(--cien-2);
}

/* MOCNIEJSZA RAMKA DUŻYCH PANELI (21.10.2026).
 *
 * Właściciel: „duże ramki (panele i karty) na stronie głównej mają mieć
 * ciemniejszą ramkę, jasna zostaje tylko dla kafelków WEWNĄTRZ paneli".
 * Dlatego modyfikator, a nie zmiana `.karta` — tamta zmieniłaby karty na
 * wszystkich podstronach, a chodzi wyłącznie o stronę główną. */
.karta--mocna {
  border-color: var(--linia-mocna);
}

/* NIUS Z GRAFIKĄ (aktualności na stronie startowej).
 *
 * Właściciel: „umieść tu to zdjęcie na prawo od tekstu". Układ jest więc
 * jednokolumnowy (grafika POD tekstem — na telefonie) i przechodzi do dwóch
 * kolumn dopiero na szerokim ekranie, gdzie obok tekstu naprawdę jest
 * miejsce. Kolejność w drzewie: tekst, potem grafika — dokładnie ta sama
 * zasada, co w oknie wprowadzenia (`.tutorial-tresc--z-obrazem`). */
.nius-tresc {
  display: grid;
  gap: var(--odst-3);
}

/* SZEROKOŚĆ KOLUMNY OBRAZKA — WSPÓLNA DLA WSZYSTKICH NIUSÓW.
 * Właściciel zauważył, że obrazki niusów mają różne szerokości (zdjęcie Memphis
 * szerokie, wycinanka Izzy'ego wąska) i zapytał, czy grid jest dobrym
 * rozwiązaniem, wspominając `float: right` z przed dwudziestu lat. Zostajemy
 * przy gridzie (float wypływa z układu i wymaga czyszczenia, a przy dwóch
 * kolumnach i tak trzeba pilnować szerokości) — ale szerokość kolumny jest
 * teraz JEDNĄ wartością, wspólną: zdjęcia wypełniają ją w całości, wycinanki
 * mogą być węższe (dostrojenie w `obraz.styl` konkretnego niusa), ale obie
 * wyrównują się do TEJ SAMEJ krawędzi, więc prawy margines jest wspólny.
 * `clamp` sprawia, że na wąskim pulpicie kolumna się zwęża, a na szerokim nie
 * rośnie ponad 15 rem (dawna wartość — układ się nie zmienia). */
:root {
  --nius-obraz-kolumna: clamp(11rem, 26%, 19rem);
}

/* LICZNIK WYZWANIA W NIUSIE („Pogromcy botów: X/10", 20.10.2026).
 * Właściciel: „na końcu niusa: dynamiczny blok »Pogromcy botów: 2/10«
 * z listą nicków".
 * Blok jest ODDZIELONY od treści (własne tło i ramka), bo to stan gry,
 * a nie kolejny akapit — ma się wyróżniać przy przewijaniu. Nagłówek mocny,
 * lista nicków wyciszona, żeby nie konkurowała z przyciskiem wyżej. */
.nius-wyzwanie {
  margin-top: var(--odst-3);
  padding: var(--odst-3);
  /* JEDNA RAMKA ZAMIENIŁA LEWĄ KRESKĘ (21.10.2026): blok miał `--linia` po
     bokach i 3 px akcentu z lewej, co przy reszcie paneli czytało się jak
     inny rodzaj ramki. Teraz pełna `--linia-mocna` — jak duże karty. */
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
}

.nius-wyzwanie-naglowek {
  margin: 0;
  font-family: var(--font-naglowek);
  font-weight: 700;
  font-size: var(--rozmiar-s);
  color: var(--akcent-zloto-tekst);
}

.nius-wyzwanie-lista {
  margin: var(--odst-2) 0 0;
  /* Nicki w kroju tekstu podstawowym — na rozmiarze `s` lista wyglądała jak
     przypis pod licznikiem, a to przecież nazwy graczy (właściciel: lista ma
     być „na pamiątkę"). Zmiana z 20.10.2026, użyta też jako próba trybu
     „bez hashy": po wgraniu JEDNEGO pliku CSS nicki mają być wyraźniejsze. */
  font-size: var(--rozmiar-m);
  color: var(--tekst-mutowany);
  /* Nicki rozdzielone przecinkami muszą się ZAWIJAĆ — przy kilkunastu
     graczach jeden ciąg bez spacji rozpychałby nius poza ekran. */
  overflow-wrap: anywhere;
}

/* DATA NIUSA — pod tytułem, po lewej (właściciel: „data na lewo, pod
 * nagłówkiem […] bo czasami nagłówki mogą być długie").
 * Wcześniej data stała w tym samym wierszu co tytuł, rozsunięta na boki,
 * więc jej położenie zależało od długości nagłówka: krótki tytuł zostawiał
 * datę z boku, długi wypychał ją pod siebie. Teraz jest to STAŁE miejsce. */
.nius-data {
  display: block;
  margin: 0 0 var(--odst-3);
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-xs);
  color: var(--tekst-mutowany);
}

/* Odnośnik w treści niusa — obejmuje PIERWSZE wyrazy zdania (np. „Pierwsze
 * miasto" prowadzące do widoku miasta; właściciel: „link w niusach — daj na
 * pierwszych 2 wyrazach […] oszczędzamy miejsce"). Podkreślenie tylko przy
 * najechaniu, żeby nie konkurowało z czerwonym przyciskiem obok; kolor akcentu
 * jak w innych odnośnikach. */
.nius-link {
  color: var(--akcent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--czas-szybki) var(--krzywa),
    color var(--czas-szybki) var(--krzywa);
}

.nius-link:hover,
.nius-link:focus-visible {
  color: var(--akcent-czerwony);
  border-bottom-color: currentColor;
}

/* Wzmianka w treści niusa (np. „Memphis" prowadzące do strony miasta):
   pogrubiona i PODKREŚLONA, bo wewnątrz akapitu musi być widać, że to link —
   sam kolor nie wystarcza (właściciel: „dodaj jako link pogrubiony"). */
.nius-link--wzmianka {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Przycisk gry w niusie: `przycisk--maly` daje 41 px wysokości, a pole
   dotykowe ma mieć ≥44 px — inaczej na telefonie trudno w nie trafić.
   Klasa + atrybut (0,2,0), bo samo `[data-nius-nowa-gra]` (0,1,0) przegrywa
   z późniejszym `.przycisk--maly { min-height: 36px }` — a wtedy reguła
   wygląda na wpisaną, ale nic nie robi. */
.przycisk[data-nius-nowa-gra] {
  min-height: 44px;
}

.nius-link--wzmianka:hover,
.nius-link--wzmianka:focus-visible {
  text-decoration: underline;
}

.nius-obraz {
  display: block;
  width: 100%;
  max-width: 17rem;
  height: auto;
  margin-inline: auto;
  border: 2px solid var(--linia-mocna);
  border-radius: var(--promien-s);
  box-shadow: var(--cien-2);
}

/* WYCINANKI (przezroczyste tło) — bez ramki zdjęcia.
   Zdjęcia miast z katalogu `miasta/` wyglądają jak fotografie w gazecie i ramka
   im służy, ale wycinanka w ramce wyglądała jak obrazek w passe-partout.
   Właściciel: „obrazek przytnij i daj bez ramki".
   Rozróżniamy po KATALOGU w adresie, żeby nie ruszać zdjęć i nie dodawać
   osobnej klasy do danych niusa (mniej miejsc do pomylenia).
   Miejsca przed wczytaniem obrazka pilnują atrybuty `width`/`height`
   z `dane.js` (wymiary rzeczywiste pliku 160×256), więc nie ma tu
   `aspect-ratio` — nowa wycinanka może mieć inną proporcję. */
.nius-obraz[src*="img/niusy/"] {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  /* WYCINANKA NIE JEST POWIĘKSZANA PONAD NATURALNY ROZMIAR PLIKU.
     Bazowa reguła daje `width: 100%` z `max-width: 17rem` (272 px), a plik ma
     tylko 160 px szerokości — czyli na telefonie grafika była rozciągana
     i rozmywana. `width: auto` + `max-width: 100%` zostawia ją w rozmiarze 1:1
     (ostra), a na szerokim ekranie nadal działa dostrojenie z danych niusa
     (styl inline ma pierwszeństwo nad tą regułą) — patrz `dane.js`, nius
     o Saloonie, gdzie właściciel prosił o mniejszą grafikę. */
  width: auto;
  max-width: 100%;
}

/* TELEFON: wycinanka nie może urosnąć ponad szerokość kolumny z danych niusa.
   Właściciel (19.10.2026) o niusie „Jak grać?" — „obrazek w aktualnościach za
   duży, zrób tej wielkości co ten niżej" — czyli jak wycinanka w niusie
   o Saloonie (128 px). Na szerokim ekranie tę rolę pełni kolumna siatki
   (`--nius-obraz-kolumna`), ale na telefonie układ jest jednokolumnowy i grafika
   dostawała rozmiar naturalny pliku (260 px). Tu ograniczamy ją tą samą
   zmienną, więc jeden mechanizm rządzi obiema szerokościami. */
@media (max-width: 39.99rem) {
  .nius-obraz[src*="img/niusy/"] {
    max-width: min(100%, var(--nius-obraz-kolumna));
  }
}

/* WIDOKI MIAST Z PRZEZROCZYSTOŚCIĄ (webp/png z alfa) — też bez ramki.
   Od 19.10.2026 grafika Memphis na stronie miasta i w niusach ma przezroczyste
   boki; ramka rysowałaby wokół niej prostokąt, a nie „passe-partout” wokół
   ilustracji. Zdjęcia miast z 1.0 (`.jpg`, bez alfy) zachowują ramkę wyżej —
   rozróżniamy po rozszerzeniu, bo tylko pliki z alfą są `.png`/`.webp`. */
.nius-obraz[src$=".png"],
.nius-obraz[src*=".png?"] {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

@media (min-width: 40rem) {
  .nius-tresc {
    /* Kolumna obrazka bierze szerokość ze wspólnego tokenu (patrz wyżej), więc
       każdy nius ma ją taką samą — niezależnie od tego, czy obrazek jest
       zdjęciem (poziomym), czy wycinanką (pionową). */
    grid-template-columns: minmax(0, 1fr) var(--nius-obraz-kolumna);
    gap: var(--odst-4);
    align-items: start;
  }

  /* JUSTOWANIE TREŚCI NIUSA (właściciel, 19.10.2026: „niusy — może mógłbyś
     wyjustować tekst?").
   *
   * TYLKO OD 40 rem — na telefonie kolumna ma ~27–30 znaków, a wyjustowany
   * tekst przy tej szerokości tworzy „rzeki" białych znaków i szare plamy
   * (sprawdzone: przy 375 px pojedyncze wyrazy rozjeżdżają się na całą
   * szerokość). Na wąskim ekranie zostaje zwykłe wyrównanie do lewej, które
   * czyta się lepiej niż „wyjustowana" kolumna o 6 wyrazach.
   *
   * `hyphens: auto` jest potrzebne razem z justowaniem: bez dzielenia wyrazów
   * polskie słowa (dłuższe niż u angielskich) zostawiają szerokie odstępy.
   * Wymaga atrybutu `lang="pl"` na `<html>`, który strona ma. */
  .nius-tekst p {
    /* WYRÓWNANIE DO LEWEJ (21.10.2026). Wcześniej treść była justowana od
       40 rem; w kafelkach o węższej kolumnie justowanie tworzy rzeki światła,
       a właściciel prosił o lewe (lista poprawek, pkt 8). */
    text-align: left;
    hyphens: auto;
    -webkit-hyphens: auto;
  }

  /* Przesunięcie grafiki w górę tylko na szerokim ekranie — wartość przychodzi
     z danych niusa jako zmienna CSS (`--nius-obraz-przesuniecie`), bo statyczny
     HTML nie może warunkować stylu od szerokości okna. */
  .nius-obraz {
    margin-top: var(--nius-obraz-przesuniecie, 0);
  }

  .nius-obraz {
    /* Zdjęcia wypełniają kolumnę. Wycinanki mogą być węższe — ogranicza je
       `styl` z danych niusa, ale wyrównanie do krawędzi kolumny ustawia ten
       sam `styl` (patrz `dane.js`, nius o Saloonie), żeby prawy margines był
       wspólny dla wszystkich niusów. */
    max-width: 100%;
    margin-inline: 0;
    /* Bez `margin-top`: przesunięcie grafiki w górę jest DOSTROJENIEM KONKRETNEGO
       niusa i idzie stylem inline z danych (`dane.js` → `obraz.styl`), a nie
       regułą dla wszystkich. Właściciel: „nie chcę klasy, tylko właśnie inline.
       bo w tym wypadku lepiej podniesiony, ale jakby był długi tytuł, to nie
       byłoby dobrze" — klasa wymuszałaby jedną wartość dla każdego niusa. */
  }
}

.karta-naglowek {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  letter-spacing: 0.01em;
  /* JEDNOLITE NAGŁÓWKI (21.10.2026): ten sam kolor i ta sama kreska co
     `.sekcja-naglowek h2` w kolumnie głównej. Wcześniej nagłówki kart były
     `--akcent` z cienką `--linia-slaba`, więc obok siebie wyglądały jak
     dwie różne rodziny nagłówków. Rozmiary zostają różne — to celowe. */
  color: var(--tekst);
  margin: 0 0 var(--odst-3);
  padding-bottom: var(--odst-2);
  border-bottom: 2px solid var(--linia-mocna);
}

/* Nagłówek sekcji (kolumna główna) — kolor jak w kartach. Kreskę ma już
 * `.sekcja-naglowek` (2 px `--linia-mocna`), więc tu tylko kolor tekstu. */
.sekcja-naglowek h2 {
  color: var(--tekst);
}

/* ==========================================================================
   STRONA GŁÓWNA — KOLEJNOŚĆ NA TELEFONIE (21.10.2026)
   ==========================================================================
   Właściciel: „telefon — logowanie wyżej: sekcja #logowanie ma być nad
   Aktualnościami". W HTML logowanie leży w kolumnie bocznej, więc samo
   `order` na niej nic nie da (to druga kolumna siatki). Dlatego poniżej
   600 px obie kolumny dostają `display: contents`, a ich sekcje stają się
   dziećmi JEDNEJ kolumny — wtedy `order` naprawdę przenosi logowanie nad
   aktualności. Na desktopie nic się nie zmienia (media query). */

@media (max-width: 600px) {
  .siatka-glowna {
    display: flex;
    flex-direction: column;
    gap: var(--odst-4);
  }

  .siatka-glowna > .stos,
  .siatka-glowna > aside {
    display: contents;
  }

  /* Kolejność: akordeon i „zagraj" na górze, potem logowanie, potem treść. */
  .siatka-glowna .sekcja--hero { order: 1; }
  .siatka-glowna .sekcja--akordeon { order: 2; }
  .siatka-glowna #logowanie { order: 3; }
  .siatka-glowna .sekcja--aktualnosci { order: 4; }
  .siatka-glowna .sekcja--forum { order: 5; }

  /* Co zostało (Twoje gry, statystyki, ranking, mistrz dnia, ilustracja) —
   po treści, w kolejności z HTML. */
  .siatka-glowna #logowanie ~ section { order: 6; }

  /* Saloon zostaje na samej górze, jak na desktopie. */
  .siatka-glowna .saloon,
  .siatka-glowna [data-tylko-zalogowany] { order: 0; }
}

/* ==========================================================================
   PRZYCISKI — szyldy w saloonie: obramowanie, nie wypełnienie
   ========================================================================== */

.przycisk {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--odst-2);
  padding: var(--odst-3) var(--odst-4);
  min-height: 44px;
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--tekst);
  background: var(--tlo-papier);
  border: 2px solid var(--tekst);
  border-radius: var(--promien-s);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.6),
    var(--cien-1);
  cursor: pointer;
  transition:
    transform var(--czas-szybki) var(--krzywa),
    background-color var(--czas-szybki) var(--krzywa),
    color var(--czas-szybki) var(--krzywa),
    box-shadow var(--czas-szybki) var(--krzywa);
}

.przycisk:hover {
  background: var(--tlo-papier-ciemny);
  color: var(--akcent-czerwony);
  border-color: var(--akcent-czerwony);
  text-decoration: none;
}

.przycisk:active {
  transform: translateY(1px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}

/* Akcja główna — jedyna wypełniona, żeby była jednoznaczna (CELE.md:
   "ekrany decyzyjne: jedna wyraźna akcja główna"). */
.przycisk--glowny {
  background: var(--akcent-czerwony);
  color: #fff;
  border-color: #6d1f1f;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    var(--cien-2);
}

.przycisk--glowny:hover {
  background: #8f2828;
  color: #fff;
  border-color: #5c1a1a;
}

.przycisk--drugi {
  background: transparent;
  border-color: var(--linia-mocna);
  color: var(--tekst-mutowany);
}

.przycisk--drugi:hover {
  background: rgba(139, 90, 43, 0.08);
  color: var(--tekst);
  border-color: var(--tekst);
}

.przycisk--duzy {
  padding: var(--odst-4) var(--odst-5);
  font-size: var(--rozmiar-l);
  width: 100%;
}

@media (min-width: 34rem) {
  .przycisk--duzy {
    width: auto;
  }
}

.przycisk--maly {
  padding: var(--odst-2) var(--odst-3);
  min-height: 36px;
  font-size: var(--rozmiar-s);
}

.przycisk[aria-disabled="true"],
.przycisk:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.4);
}

/* GŁÓWNY przycisk (np. „ZAPISZ DECYZJE I PRZELICZ TURĘ") w stanie blokady.
   Właściciel zgłaszał, że przy planie ponad limit przycisk „wygląda na
   aktywny" — czerwień i cień sugerowały klikalność, choć był `disabled`.
   Dlatego blokada jest tu MOCNIEJSZA niż w pozostałych przyciskach: bez
   cienia, wyraźnie wygaszona i odbarwiona. */
.przycisk--glowny:disabled,
.przycisk--glowny[aria-disabled="true"] {
  opacity: 0.4;
  filter: grayscale(0.75);
  box-shadow: none;
  cursor: not-allowed;
}

/* ==========================================================================
   TABELE
   ========================================================================== */

.tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--rozmiar-s);
}

.tabela caption {
  text-align: left;
  font-family: var(--font-naglowek);
  font-weight: 700;
  padding-bottom: var(--odst-2);
  color: var(--akcent);
}

.tabela th,
.tabela td {
  padding: var(--odst-2) var(--odst-3);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--linia-slaba);
}

.tabela th {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tekst-mutowany);
  background: rgba(139, 90, 43, 0.07);
  border-bottom: 2px solid var(--linia-mocna);
  white-space: nowrap;
}

.tabela tbody tr:nth-child(even) {
  background: rgba(201, 180, 140, 0.14);
}

.tabela tbody tr:hover {
  background: rgba(201, 162, 39, 0.14);
}

/* WIERSZ ZALOGOWANEGO GRACZA — „to Ty”.
   Strona miasta wyróżnia nim gracza w rankingu (właściciel: „jak wpuścimy
   tam graczy, to chciałbym […] by mogli zobaczyć siebie na liście”).
   Kolor kładziemy na `td`, a nie na `tr`, bo tło komórki zasłania pasy
   `nth-child(even)` i podświetlenie `:hover` — inaczej własny wiersz
   znikałby przy najechaniu myszą. */
.tabela tr.wiersz-gracza td {
  background: rgba(201, 162, 39, 0.22);
  font-weight: 700;
}

.tabela--parametry td:first-child {
  color: var(--tekst-mutowany);
  width: 55%;
}

.tabela--parametry td:last-child {
  font-family: var(--font-liczby);
  font-variant-numeric: tabular-nums;
  text-align: right;
  font-weight: 700;
  white-space: nowrap;
}

.tabela--parametry {
  font-size: var(--rozmiar-s);
}

/* Tabela wielokolumnowa (statystyki miasta) — przewijalna na mobile. */
.przewijalne {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.przewijalne .tabela {
  min-width: 34rem;
}

/* --- Tabela tekstowa na stronie informacji („Stan prac") ------------------
   Komórki tej tabeli zawierają zdania, nie liczby. Globalna reguła
   `.przewijalne .tabela { min-width: 34rem }` (544 px) kazałaby ją przewijać
   w poziomie przez pół ekranu, a przy tak długim tekście to na telefonie
   nieczytelne — dlatego na wąskim ekranie zdejmujemy ten limit, pozwalamy
   zawinąć nagłówki (globalne `.tabela th` ma `nowrap`) i zmniejszamy krój.
   Tabela mieści się wtedy w całości — bez przewijania i bez łamania słów
   w połowie. */
.przewijalne .tabela--strony {
  min-width: 0;
}

@media (max-width: 47.99rem) {
  .tabela--strony {
    font-size: var(--rozmiar-xs);
  }

  .tabela--strony th,
  .tabela--strony td {
    padding-inline: var(--odst-2);
  }

  .tabela--strony th {
    white-space: normal;
  }
}

/* ==========================================================================
   PLAKIETKI / STEMPLE
   ========================================================================== */

.plakietka {
  display: inline-flex;
  align-items: center;
  gap: var(--odst-1);
  padding: 2px var(--odst-2);
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  border-radius: var(--promien-s);
  white-space: nowrap;
}

.plakietka--dane {
  color: #8a6d1f;
  background: rgba(201, 162, 39, 0.16);
}

.plakietka--szybka {
  color: #5c3d7a;
  background: rgba(92, 61, 122, 0.12);
}

.plakietka--druzynowa {
  color: #3f6b2f;
  background: rgba(92, 122, 74, 0.16);
}

.plakietka--zwykla {
  /* AUDYT WIZUALNY (19.10.2026, pkt 8): #8a6d1f przy 12 px dawał 3,7–4,0 : 1,
     czyli poniżej progu AA (4,5 : 1). Ciemniejsze złoto `--akcent-zloto-tekst`
     daje 5,3–5,7 : 1, a odcień zostaje złoty — plakietka nadal czyta się jako
     „cel gry”, tylko bez wysiłku. */
  color: var(--akcent-zloto-tekst);
  background: rgba(201, 162, 39, 0.16);
}

/* ==========================================================================
   NIUS — WIERSZ TYTUŁU Z PLAKIETKĄ „NOWE"
   Pole `nowosc` w danych niusa było martwe: test pilnował, że stoi na górze
   listy, ale renderer go nie używał, więc gracz nie widział oznaczenia.
   Tytuł i plakietka siedzą w jednym wierszu (flex), a `flex-wrap` pozwala
   plakietce zejść do nowej linii, gdy tytuł jest długi.
   Wybór układu: plakietka stoi PO tytule i przy braku miejsca schodzi POD
   niego (a nie nad) — kolejność w drzewie = kolejność czytania dla czytnika
   ekranu, więc „nowe" nie wyprzedza tytułu w interpretacji.
   ========================================================================== */

.nius-tytul {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--odst-2);
  margin: 0 0 var(--odst-1);
}

/* Plakietka nie może się rozciągać ani kurczyć w wierszu flex. */
.nius-nowe {
  flex: 0 0 auto;
}

.plakietka--pojedynek {
  color: #2f6b73;
  background: rgba(47, 107, 115, 0.13);
}

.plakietka--eksperymentalna {
  color: #2f6b73;
  background: rgba(47, 107, 115, 0.13);
}

.plakietka--trening {
  color: var(--akcent-czerwony);
  background: rgba(168, 50, 50, 0.12);
}

.plakietka--zamkniete {
  color: #7a2f2f;
  background: rgba(122, 47, 47, 0.14);
}

/* Stempel "DANE PRZYKŁADOWE" — wymóg CELE.md (placeholdery jawnie oznaczone). */
.stempel {
  display: inline-block;
  padding: 1px var(--odst-2);
  font-family: var(--font-liczby);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--akcent-czerwony);
  border: 1px dashed var(--akcent-czerwony);
  border-radius: var(--promien-s);
  opacity: 0.72;
  transform: rotate(-1.2deg);
}

body[data-placeholdery="0"] .stempel,
body[data-placeholdery="0"] .placeholder-info {
  display: none;
}

/* ==========================================================================
   AKORDEON (1.0: jQuery UI accordion z 4 panelami)
   Używamy <details>/<summary> — działa bez JS i z klawiaturą.
   ========================================================================== */

.akordeon {
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  overflow: hidden;
  background: var(--tlo-papier);
}

/* Wariant wyróżniony — akordeon na stronie głównej. Mocniejsza, podwójna
   ramka i cień, żeby sekcja czytała się jako główny blok treści, a nie
   jako zwykła lista. */
.akordeon--wyrozniony {
  border: 2px solid var(--linia-mocna);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.65),
    var(--cien-2);
}

.akordeon--wyrozniony > details > summary {
  /* KOLORY Z TOKENÓW (21.10.2026): wcześniej tła były wpisane na sztywno
     (#e9dcbe, #e2d2ae, #e7d9ba), więc zmiana palety w `tokens.css` ich nie
     obejmowała — jako jedyne elementy w serwisie żyły własnym życiem. */
  background: var(--tlo-papier-ciemny);
}

/* WYRAŹNY OTWARTY PANEL (21.10.2026, poprawka 22.10.2026): tylko ciemniejsze
 * tło. Właściciel: „nie pasuje mi to pogrubienie z lewej strony przy otwartej
 * zakładce akordeonu — usuń pogrubienie ramki, reszta super”. Sama zmiana tła
 * wystarcza, żeby odróżnić rozwinięty panel, a gruba kreska łamała symetrię
 * ramki. */
.akordeon--wyrozniony > details[open] > summary {
  background: var(--tlo-krem);
}

.akordeon > details {
  border-bottom: 1px solid var(--linia-slaba);
}

.akordeon > details:last-child {
  border-bottom: none;
}

.akordeon summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--odst-3);
  padding: var(--odst-3) var(--odst-4);
  min-height: 48px;
  cursor: pointer;
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--akcent);
  background: var(--tlo-papier-ciemny);
  list-style: none;
  transition: background-color var(--czas-szybki) var(--krzywa);
}

.akordeon summary::-webkit-details-marker {
  display: none;
}

.akordeon summary:hover {
  background: var(--tlo-papier);
  color: var(--akcent-czerwony);
}

/* Wskaźnik rozwijania — czysto CSS, obraca się ≤300 ms. */
.akordeon summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.55em;
  height: 0.55em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--czas) var(--krzywa);
}

.akordeon details[open] > summary::after {
  transform: rotate(-135deg);
}

/* Kolor tekstu otwartego panelu; tło i kreskę ustawia wariant wyróżniony
   wyżej (jeden komplet reguł zamiast dwóch nakładających się). */
.akordeon details[open] > summary {
  color: var(--tekst);
}

/* Animacja rozwijania i zwijania treści (życzenie właściciela: „możesz dodać
   jakieś animacje przy przełączaniu zakładek?").
   Natywny <details> pokazuje i ukrywa treść NATYCHMIAST i tylko w jedną stronę,
   więc wysokość animujemy sami: JS przy zamykaniu wstrzymuje domyślną akcję,
   dokłada klasę `--zwiniety`, a po animacji zamyka <details>. Animację wykonuje
   CSS — JS tylko mierzy i przełącza klasę. Czas bierzemy z tokenów
   (`--czas` = 200 ms, a przy „mniej ruchu" 1 ms), więc ograniczenie ruchu
   działa bez dodatkowego kodu. */
.akordeon-tresc {
  padding: var(--odst-4);
  background: var(--tlo-papier);
  overflow: hidden;
  transition:
    max-height var(--czas) var(--krzywa),
    padding-block var(--czas) var(--krzywa),
    opacity var(--czas) var(--krzywa);
}

/* Stan zwinięty: maksymalna wysokość zero RAZEM z wyzerowanym paddingiem
   pionowym — bez tego `box-sizing: border-box` zostawiłby po zamknięciu pusty
   pas wysokości paddingu (treść zniknęłaby, a odstęp został). */
.akordeon-tresc--zwiniety {
  max-height: 0;
  padding-block: 0;
  opacity: 0;
}

/* ==========================================================================
   LISTA GOŃCZA — karta-gwiazda dla wyróżnionych wpisów
   ========================================================================== */

.lista-goncza {
  position: relative;
  background: var(--tlo-papier);
  border: 2px solid var(--tekst);
  padding: var(--odst-4);
  box-shadow: var(--cien-2);
}

.lista-goncza::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid var(--linia-mocna);
  pointer-events: none;
}

.lista-goncza-tytul {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-l);
  font-weight: 700;
  margin: 0 0 var(--odst-2);
}

/* ==========================================================================
   LISTY BEZ PUNKTÓW (1.0: .piec/.trzy jako wcięcia)
   ========================================================================== */

.lista-czysta {
  list-style: none;
  padding: 0;
  margin: 0;
}

.lista-czysta li {
  margin: 0;
}

.lista-kreska li {
  padding-block: var(--odst-2);
  border-bottom: 1px solid var(--linia-slaba);
}

.lista-kreska li:last-child {
  border-bottom: none;
}

/* --- Lista regulaminu (numerowane punkty na stronie informacji) -----------
   Regulamin ma 9 punktów po kilka linii. Domyślny odstęp `li` (--odst-1) jest
   przy takim tekście za ciasny, a `.lista-kreska` (linie między punktami)
   wygląda tu zbyt technicznie. Stąd jeden mały modyfikator: większy odstęp
   między punktami i tyle. */
.lista-regulamin li + li {
  margin-top: var(--odst-3);
}

/* --- Lista przewijana (pionowo) ------------------------------------------
   Decyzja właściciela: „na stronie głównej — po prawej stronie po zalogowaniu,
   powinna być lista »twoje gry«. […] jeśli gier jest dużo — przewijana lista
   o ograniczonej wysokości (w 1.0 były setki pozycji)”.

   Nowy komponent był konieczny: istniejące klasy przewijania obsługują inne
   przypadki (`.przewijalne` — poziomo tabele, `.nawigacja-lista` — menu
   mobilne, `.tutorial-okno` — okno wprowadzenia). Wartość `60vh` jest wzięta
   z istniejącego precedensu w `arkusz.css` (lista ofert), żeby nie wprowadzać
   nowej zmiennej dla jednego zastosowania. */
.lista-przewijana {
  max-height: 60vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Cały wiersz jest celem dotyku (min. 44 px), bo w liście gier link jest
   jedynym sposobem wejścia w rozgrywkę. */
.lista-przewijana a {
  display: block;
  padding-block: var(--odst-2);
  min-height: 44px;
}

/* --- Lista gier: KOMPAKTOWA (życzenie właściciela) ------------------------
   „te wiersze z zakończonymi rozgrywkami — zrób je dużo niższe. […] może
   lepiej, jakby była po prostu lista, a nie tabela.”

   Lista już była `ul`/`li` (nie tabela) — wysokość brała się z dwóch rzeczy:
   paddingu `.lista-kreska li` + paddingu i `min-height: 44px` z
   `.lista-przewijana a` (cel dotyku). Tutaj zmniejszamy jedno i drugie, ale
   **na dotyku zostawiamy 44 px**, bo wiersz jest linkiem do rozgrywki i nie
   wolno go zmniejszyć poniżej wygodnego trafienia palcem.
   Reguły muszą stać PO `.lista-kreska` i `.lista-przewijana` — mają tę samą
   specyficzność, więc decyduje kolejność w pliku. */
.lista-gry li {
  padding-block: var(--odst-1);
}

.lista-gry a {
  padding-block: var(--odst-1);
  min-height: 0;
}

@media (max-width: 47.99rem) {
  .lista-gry a {
    min-height: 44px;
  }
}

/* ZAKOŃCZONE GRY — TYLKO 5, RESZTA POD „WIĘCEJ" (21.10.2026).
 *
 * Właściciel: „zakończone pokazujmy tylko ostatnie 5. potem »więcej«
 * i możliwość zobaczenia wszystkich". Wiersze nad limitem są w DOM, ale
 * ukryte tą klasą — rozwinięcie jest natychmiastowe i nie pyta API drugi raz.
 * `display: none` zdejmuje je z układu, więc na telefonie nie rozpychają karty. */
.lista-gry-ukryta {
  display: none !important;
}

/* Przycisk „więcej / mniej" — wyśrodkowany pod listą. */
.lista-gry-wiecej {
  display: flex;
  margin: var(--odst-3) auto 0;
}

/* ==========================================================================
   PASEK POSTĘPU (1.0: kolorowe paski aktywności)
   ========================================================================== */

.pasek {
  display: flex;
  align-items: center;
  gap: var(--odst-2);
  font-size: var(--rozmiar-xs);
}

.pasek-opis {
  flex: 0 0 auto;
  min-width: 8.5rem;
  color: var(--tekst-mutowany);
}

.pasek-tor {
  flex: 1 1 auto;
  height: 0.9rem;
  background: rgba(58, 42, 26, 0.12);
  border: 1px solid var(--linia);
  border-radius: var(--promien-s);
  overflow: hidden;
}

.pasek-wypelnienie {
  height: 100%;
  background: linear-gradient(90deg, var(--akcent-zielony), #7fa068);
  transition: width var(--czas-wolny) var(--krzywa);
}

.pasek-wartosc {
  flex: 0 0 auto;
  font-family: var(--font-liczby);
  font-weight: 700;
  min-width: 2.5rem;
  text-align: right;
}

/* ==========================================================================
   FORMULARZE
   ========================================================================== */

.pole {
  display: flex;
  flex-direction: column;
  gap: var(--odst-1);
  margin-bottom: var(--odst-3);
}

.pole label {
  font-size: var(--rozmiar-s);
  font-weight: 700;
  color: var(--tekst-mutowany);
}

.pole input,
.pole select {
  width: 100%;
  padding: var(--odst-2) var(--odst-3);
  min-height: 44px;
  background: var(--tlo-papier);
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-s);
  color: var(--tekst);
}

.pole input:focus-visible,
.pole select:focus-visible {
  border-color: var(--akcent-czerwony);
}

.pole-podpowiedz {
  font-size: var(--rozmiar-xs);
  color: var(--tekst-mutowany);
}

.formularz--waski {
  max-width: 22rem;
}

/* ==========================================================================
   KOMUNIKATY
   ========================================================================== */

.komunikat {
  padding: var(--odst-3) var(--odst-4);
  border-left: 4px solid var(--akcent);
  background: rgba(139, 90, 43, 0.09);
  border-radius: 0 var(--promien-s) var(--promien-s) 0;
  font-size: var(--rozmiar-s);
}

.komunikat--wazny {
  border-left-color: var(--akcent-czerwony);
  background: rgba(168, 50, 50, 0.09);
}

/* KOMUNIKAT PŁCI NIE MOŻE ZAJMOWAĆ MIEJSCA, GDY JEST PUSTY (28.10.2026).
 *
 * Właściciel: „po co na prawo od »kobieta« ten element graficzny?”.
 * To był pusty `.komunikat` (padding + lewa kreska + tło), który stał
 * w jednym wierszu z radiami i wyglądał jak urwany element formularza.
 * Teraz: pusty = niewidoczny, a po zapisie ląduje POD radiami, pełną linią.
 */
[data-profil="plec-komunikat"] {
  flex-basis: 100%;
  margin-top: 0.4rem;
}

[data-profil="plec-komunikat"]:empty {
  display: none;
}

/* AUDYT WIZUALNY (19.10.2026, pkt 6): wstęp fabularny map był najmniejszym
   tekstem w serwisie (13 px na całą szerokość → ~154 znaki w wierszu), choć
   to najciekawszy tekst klimatyczny. Ten wariant go czyta, a nie przewija.
   Zwykły `.komunikat` (np. „To miasto treningowe” na stronie miasta) zostaje
   bez zmian — klasa jest dodawana tylko w HTML trzech map. */
.komunikat--opowiesc {
  /* MNIEJSZA CZCIONKA (właściciel, 2026-10-19: „czcionka może być trochę
     mniejsza”). Było `--rozmiar-m` (15 px) — po podziale na akapity i dwóch
     kolumnach tekst był zbyt „krzykliwy”; teraz `--rozmiar-s` (13 px) z
     luźniejszą interlinią, czyli nadal czytelnie, ale spokojniej. */
  font-size: var(--rozmiar-s);
  line-height: 1.6;
  max-width: calc(var(--szerokosc-tekstu) + 4rem);
}

/* AKAPITY WSTĘPU (właściciel: „treść — zrób podział na paragrafy, bo teraz
   na wszystkich trzech [epokach] jest ściana tekstu”). Każdy akapit trzyma się
   w całości w swojej kolumnie (`break-inside: avoid`), a ostatni nie dokłada
   odstępu pod sobą. */
.komunikat--opowiesc .komunikat-akapit {
  margin: 0 0 var(--odst-3);
  break-inside: avoid;
}

.komunikat--opowiesc .komunikat-akapit:last-child {
  margin-bottom: 0;
}

/* WSTĘP MAP NA CAŁĄ SZEROKOŚĆ (właściciel, 2026-10-19: „mapy — wstęp zrób na
   całą szerokość, dziwnie wygląda ucięty”). Akapit wprowadzający stoi nad
   szerokim pudełkiem opowieści, więc nie może być węższy od niego — globalna
   zasada czytelności (`layout.css: .sekcja > p`) zostaje dla innych stron.
   Selektor jest celowo bardziej szczegółowy niż `.sekcja > p`, żeby wygrał
   kolejnością i specyficznością zarazem. */
.sekcja > p[data-epoka-lead] {
  max-width: none;
}

/* PASEK PODGLĄDU PRZYKŁADOWEGO (`gra.html` bez parametru `?gra=`).
   Właściciel otworzył arkusz bez parametru i zobaczył dane przykładowe —
   wyglądały jak awaria (rok 1834, boty, dymki z zapasów). Pasek jest
   wyraźny, ale nie zajmuje dużo miejsca i nic nie przesuwa poza sobą. */
.podglad-pasek {
  margin-bottom: var(--odst-3);
}

.podglad-pasek[hidden] {
  display: none;
}

/* ==========================================================================
   POWIADOMIENIA — prawy dolny róg (pomysł właściciela)
   ==========================================================================
   Właściciel: „»powiadomienia« z prawej strony na dole w rogu, jak np.
   w grze Cywilizacja […] przycisk »ok« zamyka. krótka animacja przyciąga
   uwagę."

   Mechanizm w `assets/js/powiadomienia.js`. Tu tylko wygląd.
   Kolejność wizualna: na dole ekranu układają się od dołu (najnowsze
   najbliżej krawędzi), więc `flex-direction: column-reverse`. */

.powiadomienia {
  position: fixed;
  right: var(--odst-3);
  bottom: var(--odst-3);
  z-index: 60;
  display: flex;
  flex-direction: column-reverse;
  gap: var(--odst-2);
  width: min(22rem, calc(100vw - 2 * var(--odst-3)));
  /* Sam kontener nie łapie kliknięć — łapią je tylko powiadomienia,
     żeby nie zasłaniał przycisków pod spodem. */
  pointer-events: none;
}

.powiadomienie {
  pointer-events: auto;
  padding: var(--odst-3);
  border: 1px solid var(--linia-mocna);
  border-left-width: 4px;
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  box-shadow: var(--cien-3);
  font-size: var(--rozmiar-s);
  /* Krótki wjazd z boku — „krótka animacja przyciąga uwagę", bez
     spowalniania (limit z STYL.md: 300 ms). */
  animation: powiadomienie-wjazd var(--czas-wolny) var(--krzywa);
}

/* POWIADOMIENIE CENTRALNE (25.10.2026).
   Właściciel: „okienko informacyjne jest z boku z prawej. na wąskim ekranie
   ukryje się za panelem wydatków. wolałbym centralnie tak jak karteczka intro
   — że się nie da przegapić i trzeba zamknąć”.

   To TEN SAM element powiadomienia, tylko w nakładce na przygaszonym tle —
   dzięki temu nie powstaje drugi mechanizm ani drugi zestaw tekstów.
   `z-index` wyżej niż panel wydatków i pasek powiadomień. */
.powiadomienie-tlo {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--odst-3);
  background: rgba(38, 26, 16, 0.45);
  /* Tło przygasza grę, ale jej nie blokuje na wieki: klik w tło nic nie robi,
     zamyka tylko „ok" — komunikat o nowej turze ma zostać przeczytany. */
}

.powiadomienie--centralne {
  position: static;
  width: min(26rem, calc(100vw - 2 * var(--odst-3)));
  padding: var(--odst-4);
  font-size: var(--rozmiar-m);
  box-shadow: var(--cien-3), 0 0 0 100vmax rgba(0, 0, 0, 0);
  animation: powiadomienie-centralne-wejscie 180ms ease-out;
}

/* PRZYCISK PO ŚRODKU (26.10.2026). Właściciel: „i przycisk po środku, jak
   obrazek intro”. W rogu ekranu przycisk stał po prawej, bo tam całe
   powiadomienie było przyklejone do krawędzi. */
.powiadomienie--centralne .powiadomienie-przyciski {
  justify-content: center;
}

@keyframes powiadomienie-centralne-wejscie {
  from { opacity: 0; transform: translateY(0.75rem) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .powiadomienie--centralne { animation: none; }
}

.powiadomienie--ostrzezenie {
  border-left-color: var(--akcent-czerwony);
  background: #fdf3ea;
}

.powiadomienie--sukces {
  border-left-color: var(--akcent-zielony);
  background: #f4f7ef;
}

.powiadomienie--informacja {
  border-left-color: var(--akcent);
}

/* Zniknięcie: schowanie i wyjazd w bok, potem usunięcie z DOM (JS). */
.powiadomienie--znika {
  animation: powiadomienie-wyjazd var(--czas) var(--krzywa) forwards;
}

.powiadomienie--ukryte {
  display: none;
}

.powiadomienie-tresc {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--odst-2);
  font-weight: 700;
  line-height: 1.4;
  color: var(--tekst);
}

.powiadomienie-ikona {
  flex: 0 0 auto;
  line-height: 1.4;
  color: var(--akcent-czerwony);
}

.powiadomienie--sukces .powiadomienie-ikona {
  color: var(--akcent-zielony);
}

.powiadomienie--informacja .powiadomienie-ikona {
  color: var(--akcent);
}

.powiadomienie-szczegoly {
  margin: var(--odst-2) 0 0;
  font-size: var(--rozmiar-xs);
  font-weight: 400;
  color: var(--tekst-mutowany);
}

.powiadomienie-przyciski {
  display: flex;
  justify-content: flex-end;
  gap: var(--odst-2);
  margin-top: var(--odst-3);
}

/* „ok" jest mały i z boku — to nie jest główna akcja ekranu. */
.powiadomienie-ok,
.powiadomienie-akcja {
  min-height: 32px;
  padding: var(--odst-1) var(--odst-3);
  font-size: var(--rozmiar-xs);
}

@keyframes powiadomienie-wjazd {
  from {
    opacity: 0;
    transform: translateX(1.25rem);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes powiadomienie-wyjazd {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(1.25rem);
  }
}

/* Na wąskim ekranie powiadomienie zajmuje całą szerokość i nie zasłania
   przycisku zapisu (ten stoi w treści, więc powiadomienie i tak jest NAD
   nim — dlatego ograniczamy wysokość stosu, a nie pozycję). */
@media (max-width: 44rem) {
  .powiadomienia {
    right: var(--odst-2);
    bottom: var(--odst-2);
    width: calc(100vw - 2 * var(--odst-2));
  }
}

/* ==========================================================================
   TUTORIAL — jednorazowe wprowadzenie
   ==========================================================================
   Właściciel: „tutorial / wprowadzenie — jednorazowo, na początku —
   zamykalne popupy, z odhaczaniem […] w wersji 1.0 był system »karteczki«".
   Mechanizm w `assets/js/tutorial.js`. */

.tutorial {
  position: fixed;
  inset: 0;
  /* WYŻEJ NIŻ WSZYSTKO, CO PŁYWA PO EKRANIE.
     Właściciel zauważył, że „okienko ładnie się wybija, bo reszta jest
     jakby za »mgłą«, ale panel wydatków jest PRZED mgłą, a nie za".
     Miał rację i sam wskazał przyczynę: pływający panel limitu ma
     `z-index: 99` (patrz `arkusz.css`), a dymki pomocy `120` — oba były
     wyżej niż tło wprowadzenia (70). Teraz tło jest najwyżej, więc gdy
     okno wprowadzenia stoi otwarte, CAŁA reszta interfejsu (także panel
     i dymki) jest pod mgłą i przygaszona. */
  z-index: 130;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--odst-3);
  background: rgba(36, 26, 16, 0.62);
  animation: tutorial-tlo var(--czas) var(--krzywa);
}

.tutorial-okno {
  width: min(30rem, 100%);
  max-height: calc(100vh - 2 * var(--odst-3));
  overflow-y: auto;
  padding: var(--odst-5);
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-l);
  background: var(--tlo-papier);
  box-shadow: var(--cien-3);
}

.tutorial-postep {
  margin: 0 0 var(--odst-2);
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tekst-mutowany);
}

.tutorial-tytul {
  margin: 0 0 var(--odst-3);
  /* WIĘKSZY TYTUŁ OKNA.
     Właściciel, patrząc na okno wprowadzenia: „myślę, że lepiej będzie:
     większy nagłówek".
     Miał rację: tytuł dziedziczył po `h3` (15–18 px), czyli był MNIEJSZY niż
     nagłówki kart w arkuszu — a to najważniejszy napis na ekranie, bo wita
     gracza w mieście. Dostaje więc stopień między `h2` i `h1`: 22 px na
     telefonie, 28 px (`--rozmiar-2xl`) na szerokim ekranie. `clamp` pilnuje,
     żeby „Witaj w Memphis" zmieściło się w jednej linii już od 375 px
     (zmierzone w DOM — patrz raport zadania). */
  font-size: clamp(1.375rem, 6vw, var(--rozmiar-2xl));
}

/* OKNO Z GRAFIKĄ (wprowadzenie do miasta).
 *
 * Właściciel: „»Witaj w Memphis« centralnie […] z lewej tekst, wyjustowany;
 * z prawej grafika — nie za duża […] na telefonie (375 px) grafika pod
 * tekstem (inaczej tekst się zmiażdży)".
 *
 * Dlatego: tytuł na środku tylko w tym wariancie (okna czysto tekstowe
 * zostają przy wyrównaniu do lewej), okno szersze niż zwykłe (30rem), a sam
 * układ to siatka JEDNOkolumnowa — grafika ląduje POD tekstem — która do
 * dwóch kolumn przechodzi dopiero tam, gdzie naprawdę jest na to miejsce
 * (44rem). Kolejność w drzewie jest naturalna: tekst, potem grafika. */
.tutorial-okno--z-obrazem {
  width: min(46rem, 100%);
}

.tutorial-okno--z-obrazem .tutorial-tytul {
  text-align: center;
}

/* TEKST WYJUSTOWANY TYLKO TAM, GDZIE JEST NA TO MIEJSCE.
 *
 * Właściciel prosił o tekst wyjustowany („z lewej tekst, wyjustowany") i na
 * szerokim ekranie tak zostaje — tam kolumna ma ~454 px i justowanie wygląda
 * po gazetowemu.
 *
 * Na telefonie (mierzone: 375 px → kolumna ~300 px) justowanie rozjeżdża
 * wyrazy: w słowach „zbawiony opowieściami o wielkich" powstawały szerokie
 * rzeki światła, przez co tekst czyta się gorzej niż wyrównany do lewej.
 * To nie jest moje „widzimisię" — widać to na zrzucie `.podglad/intro-po-375.png`.
 * Dlatego poniżej 44 rem (czyli tam, gdzie grafika i tak ląduje pod tekstem)
 * tekst jest wyrównany do lewej. */
.tutorial-tresc--z-obrazem .tutorial-tekst {
  text-align: left;
}

@media (min-width: 44rem) {
  .tutorial-tresc--z-obrazem .tutorial-tekst {
    text-align: justify;
  }
}

.tutorial-obraz {
  display: block;
  /* Na telefonie grafika jest AKCENTEM, nie tłem okna — dlatego ograniczamy
     jej szerokość i środkujemy. Bez tego kwadratowe zdjęcie zjadało pół
     ekranu i wypychało przycisk „zaczynamy" poza widok. */
  width: 100%;
  max-width: 20rem;
  height: auto;
  margin: 0 auto var(--odst-3);
  /* BEZ RAMKI I CIENIA (właściciel, 20.10.2026: „po zmianie obrazka na png
     ma teraz niepotrzebną ramkę"). Grafiki miast to PNG z własną, malarską
     krawędzią — doklejona ramka i cień dawały DRUGĄ ramkę wokół pierwszej. */
}

@media (min-width: 44rem) {
  .tutorial-tresc--z-obrazem {
    display: grid;
    /* Grafika większa (właściciel, 20.10.2026: „obrazek należałoby zrobić
       większy") — kolumna 13.5rem → 17rem. */
    grid-template-columns: minmax(0, 1fr) 17rem;
    gap: var(--odst-4);
    /* GRAFIKA WYŻEJ NIŻ TEKST (właściciel, 20.10.2026: „do góry trochę
       podnieść"). Wcześniej `center` wyrównywało ją do środka akapitów;
       teraz startuje równo z pierwszym akapitem. */
    align-items: start;
  }

  .tutorial-tresc--z-obrazem .tutorial-obraz {
    max-width: none;
    margin: 0;
  }
}

.tutorial-tekst {
  margin: 0 0 var(--odst-3);
  font-size: var(--rozmiar-m);
  line-height: 1.6;
}

/* INTRO DWUKOLUMNOWE — CLEVELAND (25.10.2026).
 *
 * Właściciel: „może mógłbyś owinąć tekst wokół grafiki? i dodać poniżej
 * awatar George'a? może Cleveland z lewej, a George z prawej?”.
 *
 * PIERWSZA WERSJA UŻYŁA `float` I BYŁA ZŁA — właściciel zauważył dwa błędy:
 *   1. obraz miasta był wyższy niż pierwszy akapit, więc DRUGI akapit
 *      zaczynał się z wielkim wcięciem („Kupujesz niewielką farmę…”),
 *   2. awatar wisiał pod tekstem, otoczony pustką, więc wyglądał doklejony.
 * Dlatego teraz jest SIATKA, a nie opływanie: lewa kolumna to obraz, prawa
 * to tekst zaczynający każdy akapit w tej samej linii, a podpis autora stoi
 * na dole prawej kolumny w JEDNEJ LINII (awatar + imię OBOK, nie pod).
 * Na telefonie jedna kolumna: obraz, tekst, podpis — wszystko w przepływie. */
.tutorial-tresc--oplyw {
  display: grid;
  gap: var(--odst-4);
  align-items: start;
}

.tutorial-oplyw-obraz {
  margin: 0;
}

.tutorial-tresc--oplyw .tutorial-obraz {
  width: 100%;
  /* W JEDNEJ KOLUMNIE (telefon, tablet) obraz nie może zjadać całej
     szerokości — 20 rem to ta sama wartość, co w pozostałych oknach.
     W dwóch kolumnach (>= 48 rem) poniżej zdejmujemy limit. */
  max-width: 20rem;
  margin: 0 auto;
}

/* PODPIS AUTORA W LEWEJ KOLUMNIE (25.10.2026).
 *
 * Właściciel: „słabo intro. zrób obrazek awatara większego i daj na lewo pod
 * obrazek miasta”. Wcześniej awatar stał na dole prawej kolumny i — bez
 * opływającego go zdania — wyglądał jak doklejony. Teraz jest częścią kolumny
 * z obrazem: obraz, odstęp, portret, podpis POD portretem.
 *
 * Rozmiar 7 rem (112 px): mniejszy niż obraz miasta (248 px), ale wyraźnie
 * większy od wcześniejszych 48 px — portret ma być rozpoznawalny, a nie
 * miniaturką przy dolnej krawędzi. Ramka i cień są delikatne, bo grafiki miast
 * mają własną malarską krawędź i mocniejsza oprawa wyglądałaby jak naklejka. */
.tutorial-autor {
  display: grid;
  justify-items: center;
  gap: 0.45rem;
  margin: var(--odst-4) 0 0;
}

/* PORTRET AUTORA BEZ KÓŁECZKA (27.10.2026).
 *
 * Właściciel: „w intro albo poprzednia bez kółeczka, albo nowa bez kółeczka.”
 *
 * Grafiki botów są już wycięte w koło na przezroczystym tle, więc CSS-owe
 * `border-radius: 50%` plus jasne tło i ramka robiły DRUGI okrąg wokół
 * portretu — dokładnie ten sam błąd, co w tabeli wyników. Teraz sam obrazek:
 * bez zaokrąglenia, bez tła, bez ramki, bez cienia. */
.tutorial-autor-awatar {
  width: 9rem;
  height: 9rem;
  border-radius: 0;
  border: 0;
  background: none;
  object-fit: contain;
}

.tutorial-autor-podpis {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.2;
  text-align: center;
  color: var(--tekst-mutowany);
}

/* SZERSZE OKNO INTRO (25.10.2026). Właściciel: „może trochę rozszerzyć
 * okienko?” — cel był praktyczny: mniej pustego miejsca po bokach i na dole,
 * a każdy akapit w 3–4 liniach zamiast 5–6. Dotyczy WYŁĄCZNIE wariantu
 * z lewą kolumną (Cleveland) — okna Memphis i pozostałe tutoriale zostają
 * przy 46 rem, żeby ich układ się nie zmienił. */
.tutorial-okno--oplyw {
  width: min(52rem, 100%);
}

@media (min-width: 48rem) {
  .tutorial-tresc--oplyw {
    grid-template-columns: 15.5rem minmax(0, 1fr);
    /* TRZY ELEMENTY, DWIE KOLUMNY — Rozmieszczenie MUSI być jawne.
       Bez tego siatka układała awatar w prawej kolumnie obok tekstu
       (auto-placement), czyli dokładnie tam, gdzie go NIE chcemy. */
    grid-template-rows: auto 1fr;
  }

  .tutorial-tresc--oplyw .tutorial-oplyw-obraz {
    grid-column: 1;
    grid-row: 1;
  }

  .tutorial-tresc--oplyw .tutorial-autor {
    grid-column: 1;
    grid-row: 2;
    align-self: start;
  }

  .tutorial-tresc--oplyw .tutorial-tresc-tekst {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .tutorial-tresc--oplyw .tutorial-obraz {
    max-width: none;
    margin: 0;
  }
}

/* WARIANTY TEKSTU (A/B) w oknie wprowadzenia.
 *
 * Właściciel sam poprosił, żeby wątpliwe teksty pokazywać mu w interfejsie
 * w dwóch wersjach do wyboru („możesz w UI umieścić dwie wersje i odpowiednio
 * je oznaczyć numerkiem"). Jedną z nich wybierze, druga zniknie — dlatego
 * wyróżnienie jest dyskretne, a nie krzykliwe: każdy wariant ma cienką kreskę
 * z lewej (jak akapit w gazecie), oznaczenie „A."/„B." jest pogrubione
 * w kolorze akcentu, a między wariantami jest odstęp, żeby się nie zlewały.
 *
 * Odstęp od listy punktów pod spodem (`--odst-4`) jest większy niż między
 * samymi wariantami — bez tego „B." kleiło się do pierwszego punktu listy. */
.tutorial-warianty {
  margin: 0 0 var(--odst-4);
}

.tutorial-wariant {
  margin: 0 0 var(--odst-3);
  padding-left: var(--odst-3);
  border-left: 2px solid var(--linia);
}

.tutorial-wariant:last-child {
  margin-bottom: 0;
}

.tutorial-wariant strong {
  color: var(--akcent);
}

.tutorial-lista {
  margin: 0 0 var(--odst-3);
  padding-left: var(--odst-5);
}

.tutorial-niepokazuj {
  display: flex;
  align-items: center;
  gap: var(--odst-2);
  min-height: 44px;
  margin-bottom: var(--odst-2);
  font-size: var(--rozmiar-s);
  color: var(--tekst-mutowany);
  cursor: pointer;
}

.tutorial-przyciski {
  display: flex;
  justify-content: flex-end;
  gap: var(--odst-2);
}

/* PRZYCISK NA DOLE, NA ŚRODKU (okno z grafiką = wprowadzenie do miasta).
   Właściciel: „przycisk na dole centralnie". Wcześniej stał wyrównany do
   prawej, czyli pod grafiką — przez co wyglądał jak przycisk przypisany do
   zdjęcia, a nie zamknięcie całego okna. Wyśrodkowanie + odstęp od treści
   (`--odst-4`) oddziela go od akapitów i domyka okno.
   Okna CZYSTO TEKSTOWE zostają przy wyrównaniu do prawej — tam są dwa
   przyciski („pomiń" i „dalej") i taki układ jest dla nich czytelniejszy. */
.tutorial-okno--z-obrazem .tutorial-przyciski {
  justify-content: center;
  margin-top: var(--odst-4);
}

@keyframes tutorial-tlo {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ==========================================================================
   DEFINICJE (słownik pojęć gry)
   ========================================================================== */

.pojecia {
  display: grid;
  gap: var(--odst-3);
}

.pojecie {
  display: grid;
  gap: var(--odst-1);
  padding-bottom: var(--odst-3);
  border-bottom: 1px solid var(--linia-slaba);
}

.pojecie:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.pojecie dt {
  font-family: var(--font-naglowek);
  font-weight: 700;
  color: var(--akcent);
}

.pojecie dd {
  margin: 0;
  font-size: var(--rozmiar-s);
  line-height: 1.55;
}

/* ==========================================================================
   LICZNIKI GRY
   Cztery kafle w dwóch wierszach po dwa. Szerokość dobrana tak, żeby
   liczba „180 721" mieściła się w jednym wierszu.
   ========================================================================== */

.siatka-licznikow {
  display: grid;
  gap: var(--odst-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Komunikat zamiast kafli, gdy statystyk nie udało się pobrać
   (właściciel: „nie może być NaN" — ma być zdanie po polsku). */
.liczniki-blad {
  margin: 0;
  grid-column: 1 / -1;
  color: var(--tekst-mutowany);
  font-size: var(--rozmiar-s);
}

.licznik {
  padding: var(--odst-3);
  background: var(--tlo-papier-ciemny);
  border: 1px solid var(--linia-slaba);
  border-radius: var(--promien-s);
  min-width: 0;
}

.licznik-wartosc {
  font-size: var(--rozmiar-xl);
  font-weight: 700;
  line-height: 1.1;
  color: var(--akcent-czerwony);
  white-space: nowrap;
  letter-spacing: -0.01em;
}

/* WYŚRODKOWANIE KAFELKÓW STATYSTYK (26.10.2026). Właściciel: „i może
   wyśrodkować teksty?”. Wyrównanie robimy w kafelku, a nie w pojedynczych
   elementach, żeby liczba i podpis zawsze stały w jednej osi — także gdy
   podpis złamie się na dwie linie („zakończone rozgrywki”). */
.licznik {
  text-align: center;
}

.licznik-etykieta {
  text-align: center;
  margin-top: var(--odst-1);
  font-size: 0.6875rem;
  line-height: 1.3;
  color: var(--tekst-mutowany);
}

/* ==========================================================================
   OBRAZ KLIMATYCZNY (z1)
   Grafika ma przezroczyste brzegi i delikatną ramkę wokół ilustracji,
   dlatego lekko ją powiększamy ujemnym marginesem — dzięki temu wypełnia
   szerokość kolumny i nie widać pustego obwodu.

   Ten obrazek NIE jest w karcie (.karta), bo karta ma cień, który
   obrysowywał prostokąt przezroczystego obrazu i wyglądał jak ramka.
   ========================================================================== */

.obraz-klimatyczny {
  margin: -3% -2%;
  width: 104%;
  height: auto;
  display: block;
}

@media (min-width: 48rem) {
  .obraz-klimatyczny {
    margin: -2.5% -2.5%;
    width: 105%;
  }
}

/* ==========================================================================
   ZDJĘCIE MIASTA (1.0: zdjecia/<Miasto><rok>.jpg)
   ========================================================================== */

.miasto-foto {
  display: block;
  width: 100%;
  /* WIĘKSZY OBRAZ (decyzja właściciela 19.10.2026: „miasto — za małe, usuń
     max width […] grafika ładna, wykorzystajmy ją należycie”). 300 px okazało
     się za małe — ilustracja ma teraz wypełniać CAŁĄ kolumnę boczną, a limit
     wynika z szerokości kolumny, nie ze sztywnej wartości. Plik ma 600×348,
     więc do ~600 px szerokości ekranu jest jeszcze w gęstości 2× (ostro na
     retina); wyżej przeglądarka skaluje delikatnie w górę. */
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  /* BEZ RAMKI (ta sama decyzja): grafikę z przezroczystymi bokami obramowanie
     zamieniało w prostokąt. Ramki nie rysuje też żaden element nadrzędny. */
  border: 0;
  border-radius: 0;
  box-shadow: none;
  object-fit: contain;
  /* BEZ TŁA (decyzja właściciela 19.10.2026): grafika Memphis ma przezroczyste
     boki i na pergaminie muszą prześwitywać boki strony, a nie prostokąt koloru.
     Wcześniej było tu background: var(--tlo-papier-ciemny), co dawało widoczną
     ramkę wokół miasta. */
}

/* Zastępnik, gdy brak zdjęcia dla miasta/epoki — kafelek „Wkrótce”.
   Trzyma TEN SAM prostokąt co prawdziwe grafiki (proporcja 3:2, szerokość
   do 300 px jak `.miasto-foto`), żeby po dodaniu obrazka układ się nie
   przesunął. Decyzja właściciela (19.10.2026): „we wszystkich miastach
   grafiki miasta zrób jako placeholder »wkrótce«”. */
.miasto-foto-zastepnik {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--odst-1);
  width: 100%;
  max-width: 100%;
  aspect-ratio: 3 / 2;
  margin-inline: auto;
  border: 2px dashed var(--linia-mocna);
  border-radius: var(--promien-s);
  background: rgba(139, 90, 43, 0.06);
  color: var(--tekst-mutowany);
}

/* PUŁAPKA 17 Z `docs/kroki.md`: atrybut `hidden` PRZEGRYWA z regułą, która
   ustawia `display` — a ta klasa ustawia `flex`. Bez tej linii zastępnik
   pokazywał się ZAWSZE, także pod poprawnie wczytanym zdjęciem: na widoku
   miasta było widać dużą przerywaną ramkę „Memphis 1832" pod fotografią.
   Widać to było dopiero na wyraźnym zdjęciu Memphis, bo wcześniejsze
   miniaturki były małe i ramka zlewała się z tłem. */
.miasto-foto-zastepnik[hidden] {
  display: none;
}

.miasto-foto-zastepnik span {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-l);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.miasto-foto-zastepnik small {
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-s);
  opacity: 0.75;
}

/* ==========================================================================
   ZAKŁADKI — powtarzalny motyw gry
   Używane w opisie gry (dwa poziomy), a docelowo także w arkuszu gry
   i w statystykach.

   Ważne: NIE używamy overflow-x: auto. Pasek zakładek ma się mieścić,
   a gdyby było ciasno, zawija się do dwóch wierszy (flex-wrap) zamiast
   wprowadzać poziome przewijanie.
   ========================================================================== */

/* --- Poziom 1: przełącznik głównych części (Krótki przewodnik / Pełny opis) */

.przelacznik-czesci {
  display: flex;
  flex-wrap: wrap;
  gap: var(--odst-3);
  margin-bottom: var(--odst-5);
  padding-bottom: var(--odst-4);
  border-bottom: 2px solid var(--linia-mocna);
}

.przelacznik-czesci a {
  flex: 1 1 12rem;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: var(--odst-3) var(--odst-4);
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--tekst-mutowany);
  background: var(--tlo-papier-ciemny);
  border: 2px solid var(--linia);
  border-radius: var(--promien-s);
  transition:
    background-color var(--czas-szybki) var(--krzywa),
    color var(--czas-szybki) var(--krzywa),
    border-color var(--czas-szybki) var(--krzywa);
}

.przelacznik-czesci a:hover {
  background: #e7d9ba;
  color: var(--tekst);
}

.przelacznik-czesci a[aria-current="page"] {
  background: var(--tlo-papier);
  color: var(--akcent-czerwony);
  border-color: var(--akcent-czerwony);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.6),
    var(--cien-1);
}

/* --- Poziom 2: rozdziały w obrębie części ------------------------------- */

.zakladki {
  display: flex;
  flex-wrap: wrap;
  gap: var(--odst-2);
  padding-bottom: var(--odst-2);
  margin-bottom: var(--odst-4);
  border-bottom: 2px solid var(--linia-mocna);
}

/* Właściciel: „za zakładki zrób jednakowej szerokości na całą szerokość
   strony". Każda zakładka rozciąga się równo (`flex: 1 1 0`), więc pasek
   wypełnia całą szerokość niezależnie od długości etykiet. Na wąskim ekranie
   siedem zakładek nie zmieściłoby się w jednym rzędzie, dlatego poniżej
   40 rem przechodzimy na siatkę 2 kolumn — nadal równe. */
/* Poniżej 40 rem pasek zakładek przechodzi na siatkę 4 kolumn — patrz blok
   „TELEFON: PASEK ZAKŁADEK W DWÓCH RZĘDACH” na końcu sekcji (musi stać PO
   bazowych regułach `.zakladki a`, inaczej nie wygrywa kolejnością). */

.zakladki a {
  /* Bez overflow-x: auto — elementy zawijają się do kolejnego wiersza. */
  flex: 1 1 0;
  justify-content: center;
  padding: var(--odst-2) var(--odst-1, 5px);
  min-width: 0;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-naglowek);
  /* Właściciel (17.10.2026): „zakładki — powiększ czcionkę w tych zakładkach
     ile się da". Stała wartość 13 px była zbyt mała na szerokim ekranie, a na
     wąskim nie mogła rosnąć. Dlatego `clamp`: 14 px na telefonie, do 16 px na
     szerokim ekranie (rośnie z szerokością okna, więc nigdy nie „wystaje"
     poza kafelek — etykiety mogą się zawijać, patrz blok mobilny niżej). */
  font-size: clamp(0.875rem, 0.78rem + 0.35vw, 1rem);
  font-weight: 700;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tekst-mutowany);
  background: var(--tlo-papier-ciemny);
  border: 1px solid var(--linia);
  border-radius: var(--promien-s);
  white-space: nowrap;
  transition: background-color var(--czas-szybki) var(--krzywa);
}

.zakladki a:hover {
  background: #e7d9ba;
  color: var(--tekst);
}

.zakladki a[aria-current="page"] {
  background: var(--tlo-papier);
  color: var(--akcent-czerwony);
  border-color: var(--linia-mocna);
  box-shadow: inset 0 2px 0 var(--akcent-czerwony);
}

/* --------------------------------------------------------------------------
   TELEFON: PASEK ZAKŁADEK W DWÓCH RZĘDACH
   --------------------------------------------------------------------------
   Właściciel: „pasek zakładek jest za duży — dziś 2 kolumny × 4 rzędy; ma być
   2 rzędy”, czyli 4 kolumny (siedem zakładek = 4 + 3), mniejsze przyciski.
   ⚠ KOLEJNOŚĆ MA ZNACZENIE: te reguły muszą stać PO bazowych regułach
   `.zakladki a` — inaczej mają tę samą specyficzność, a późniejsza wygrywa.
   Wcześniej blok mobilny był wyżej i „nie działał” (czcionka zostawała
   bazowa) — to ta sama pułapka, co z regułą „menu do prawej” w banerze. */
@media (max-width: 40rem) {
  .zakladki {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--odst-1, 4px);
  }

  /* Etykiety MOGĄ się zawijać na dwie linijki: „PODSUMOWANIE” i
     „PRZELICZENIE” są dłuższe niż kolumna siatki na 375 px — przy `nowrap`
     nachodziły na sąsiednie zakładki (widać to na zrzucie: „BAWELNA
     INWESTYCJE PRZELICZENIE” zlepione w jedno). Zawinięcie jest
     czytelniejsze niż ucięty napis, a 44 px trzyma pole dotykowe. */
  .zakladki a {
    min-height: 44px;
    padding: var(--odst-1, 4px) 2px;
    /* 12 → 13 px: właściciel prosił o większą czcionkę „ile się da”.
       Etykiety nadal mogą się zawijać (niżej), a najdłuższe („PRZELICZENIE")
       mieszczą się w dwóch linijkach na 375 px. */
    font-size: var(--rozmiar-s);
    letter-spacing: 0;
    white-space: normal;
    line-height: 1.05;
    text-align: center;
  }
}

/* Najwęższe telefony (375 px i mniej): dodatkowo ciaśniejsze odstępy liter,
   żeby dwuliterowe ogonki („…IE”) nie łamały się bez potrzeby. DODATKOWO
   mniejsza czcionka i łamanie długich słów — na 375 px cztery kolumny były
   za wąskie i etykiety nachodziły na siebie („INWESTYCJE PRZELICZENIE”
   zlepione w jedno, „PODSUMOWANI” ucięte). */
@media (max-width: 26rem) {
  .zakladki a {
    letter-spacing: -0.03em;
    /* Właściciel (17.10.2026): „zakładki — powiększ czcionkę ile się da”.
       Wcześniej 0,54 rem (8,6 px) — nieczytelnie. 0,6875 rem to 11 px i nadal
       mieści „PRZELICZENIE" w kolumnie 79 px na 375 px (sprawdzone pomiarem). */
    font-size: 0.6875rem;
    /* `break-word`, NIE `anywhere`: „PRZELICZENIE” pękało w środku
       („PRZELICZENI / E”), bo `anywhere` łamie zawsze, gdy zabraknie miejsca.
       Przy mniejszej czcionce mieści się w jednej linii, a `break-word`
       zadziała tylko w ostateczności. */
    overflow-wrap: break-word;
    hyphens: auto;
  }
}

/* --------------------------------------------------------------------------
   TABLET: TEN SAM UKŁAD 4 KOLUMN, CO NA TELEFONIE
   --------------------------------------------------------------------------
   AUDYT WIZUALNY (19.10.2026, pkt 2). Między 40 rem a 64 rem nie było ŻADNEJ
   reguły: `.zakladki a` miały `white-space: nowrap` i `flex: 1 1 0`, więc na
   iPadzie i małym laptopie etykiety nie mieściły się w kafelkach —
   zmierzone: przy 641 px strona `opis-gry.html` przewijała się w poziomie
   (649 > 641), a przy 768 px „INWESTYCJE” i „PRZELICZENIE” zlepiały się
   w jedno słowo. Rozwiązanie powtarza układ, który właściciel zaakceptował
   na telefonie (4 kolumny = 2 rzędy po 7 zakładek).
   ⚠ KOLEJNOŚĆ: ten blok MUSI stać PO bloku mobilnym — te same specyficzności,
   wygrywa późniejsza reguła (ta sama pułapka, co wcześniej z menu i fonem). */
@media (min-width: 40.01rem) and (max-width: 56rem) {
  .zakladki {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--odst-2);
  }
}

/* Do 64 rem etykieta może się zawinąć w kafelku, zamiast z niego wystawać. */
@media (min-width: 40.01rem) and (max-width: 64rem) {
  .zakladki a {
    white-space: normal;
    line-height: 1.15;
    text-align: center;
    letter-spacing: 0.01em;
  }
}

/* --- Ukrywanie treści zakładek ------------------------------------------
   Tylko gdy JavaScript działa (znacznik data-js z <head>). Bez JS
   wszystkie rozdziały są widoczne jedna pod drugą. */

html[data-js='tak'] [data-zakladka-tresc][hidden] {
  display: none;
}

html[data-js='tak'] [data-zakladka-tresc] {
  scroll-margin-top: 6rem;
}

/* Wersja zapisana wcześniej dla opisu gry — zostaje dla zgodności. */
html[data-js='tak'] [data-opis-tresc][hidden] {
  display: none;
}

html[data-js='tak'] [data-opis-tresc] {
  scroll-margin-top: 6rem;
}

/* --- Komunikaty formularzy (konta graczy) --------------------------------
   Wstawia je `assets/js/konta.js` po nieudanej albo udanej próbie. Sukces
   i błąd różnią się kolorem, ale oba są zwykłym akapitem w formularzu —
   bez ramek i ikon, żeby nie udawały osobnego komponentu.
   ------------------------------------------------------------------------- */

.formularz-komunikat {
  margin: var(--odst-3) 0 0;
  font-size: var(--rozmiar-s);
  line-height: 1.4;
}

.formularz-komunikat--blad {
  color: var(--akcent-czerwony);
}

.formularz-komunikat--sukces {
  color: var(--akcent-zielony);
}

/* --- Krótkie animacje (konta graczy) -------------------------------------
   Decyzja właściciela: „możesz zrobić jakieś krótkie animacje, by nie było to
   błyskawicznym przeładowaniem. ogólnie krótkie animacje byłyby wskazane przy
   niektórych działaniach. by wyglądało to jak aplikacja, a nie strona www.”

   Zakres jest celowo wąski: 150–250 ms, wyłącznie krycie i drobne przesunięcie
   (bez ruchu, który przeszkadza w czytaniu). Animacje są zadeklarowane na
   elementach, a nie odpalane z JS — przeglądarka odtwarza je na nowo, gdy
   element wraca z `hidden` do widoku (przejście `display: none` → widoczny
   restartuje animację), więc przełączanie paneli logowania i rejestracji
   dostaje efekt bez ani jednej linii w JavaScript.
   ------------------------------------------------------------------------- */

@keyframes panel-wjazd {
  from { opacity: 0; transform: translateY(0.4rem); }
  to   { opacity: 1; transform: none; }
}

@keyframes komunikat-wjazd {
  from { opacity: 0; transform: translateY(-0.2rem); }
  to   { opacity: 1; transform: none; }
}

[data-panel-logowania],
[data-panel-rejestracji],
[data-panel-reset],
[data-panel-reset-hasla] {
  animation: panel-wjazd 220ms ease-out;
}

.formularz-komunikat {
  animation: komunikat-wjazd 180ms ease-out;
}

/* Gracz, który prosi system o mniej ruchu, nie dostaje żadnego. */
@media (prefers-reduced-motion: reduce) {
  [data-panel-logowania],
  [data-panel-rejestracji],
  [data-panel-reset],
  [data-panel-reset-hasla],
  .formularz-komunikat {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   SEKCJA „OSTATNIO NA FORUM" NA STRONIE GŁÓWNEJ

   Właściciel: „chciałbym, by wyświetlały się ostatnie wypowiedzi — zarówno nowe
   wątki, jak i nowe odpowiedzi w wątkach […] linki do konkretnego miejsca.
   trzeba trochę zróżnicować formatowanie. w tooltipach daty."

   Dlatego każda pozycja to: etykieta TYPU (inny kolor dla wątku i odpowiedzi),
   tytuł wątku jako odnośnik, wiersz metadanych (autor · czas · temat)
   i krótki fragment treści. Układ jest listą, a nie tabelą — na telefonie
   tabela z czterema kolumnami byłaby nieczytelna.

   `hidden` na liście działa dzięki globalnej regule `[hidden] { display: none
   !important }` z `base.css` — bez niej `display: grid` wygrałoby z atrybutem
   (dokładnie ta pułapka kosztowała nas widoczny formularz dla gości na forum).
   -------------------------------------------------------------------------- */
/* Sekcja na BEŻOWYM tle, wypowiedzi na BIAŁO (właściciel: „tabelki, tło. może
 * cała sekcja beżowa, a wypowiedzi białe").
 *
 * Właściciel (18.10.2026): „nagłówek ponad sekcję, tak jak wszędzie" — dlatego
 * beżowe tło ma KONTENER TREŚCI (`.forum-ostatnie-ramka`), a nie cała sekcja:
 * `<h2>` stoi wtedy na tle strony, dokładnie jak tytuły pozostałych sekcji
 * („Aktualności", „O gra w skrócie"). Wcześniej tło było na `.sekcja--forum`,
 * więc tytuł siedział w środku karty. */
.sekcja--forum {
  margin-bottom: var(--odst-6);
}

/* Ramka jak inne duże panele (21.10.2026): `--linia-mocna` + cień;
 * kafelki (`li.forum-ostatnie-poz`) zostają na jasnej `--linia`. */
.forum-ostatnie-ramka {
  display: flex;
  flex-direction: column;
  gap: var(--odst-3);
  padding: var(--odst-4);
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier-ciemny);
  box-shadow: var(--cien-2);
}

.forum-ostatnie {
  display: grid;
  gap: var(--odst-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Każda wypowiedź to BIAŁA karta — oddzielona odstępem i tłem, a nie linią
 * (wcześniejsza wersja miała tylko `border-top`, co przy beżowym tle wyglądało
 * jak tabelka bez ramek). */
.forum-ostatnie-poz {
  display: grid;
  gap: var(--odst-1);
  padding: var(--odst-3);
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
}

/* Tytuł i etykieta typu w jednym wierszu: tytuł zajmuje miejsce, etykieta stoi
 * przy prawej krawędzi (właściciel: „oznaczenia typu »nowy wątek« możesz
 * z prawej strony zrobić na prawo od tytułu, by całość była bardziej zwarta"). */
.forum-ostatnie-gora {
  display: flex;
  align-items: baseline;
  gap: var(--odst-2);
}

.forum-ostatnie-gora .forum-ostatnie-tytul {
  flex: 1 1 auto;
  min-width: 0;
}

.forum-ostatnie-gora .forum-ostatnie-typ--gora {
  flex: 0 0 auto;
  margin-left: auto;
}

/* Etykieta typu — rozróżnienie „nowy wątek" i „odpowiedź" kolorem, a nie
 * tylko słowem: przy szybkim przewijaniu kolor czyta się pierwszy. */
.forum-ostatnie-typ {
  padding: 0.1em 0.5em;
  border-radius: 999px;
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-xs);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--tekst-mutowany);
  background: color-mix(in srgb, var(--linia) 35%, transparent);
}

.forum-ostatnie-typ[data-typ='watek'] {
  color: var(--akcent-zielony);
  background: color-mix(in srgb, var(--akcent-zielony) 14%, transparent);
}

.forum-ostatnie-typ[data-typ='wpis'] {
  color: var(--akcent);
  background: color-mix(in srgb, var(--akcent) 12%, transparent);
}

.forum-ostatnie-tytul {
  font-size: var(--rozmiar-m);
  font-weight: 600;
  color: var(--akcent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.forum-ostatnie-tytul:hover,
.forum-ostatnie-tytul:focus-visible {
  color: var(--akcent-czerwony);
  border-bottom-color: currentColor;
}

.forum-ostatnie-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--odst-2);
  margin: 0;
  font-size: var(--rozmiar-xs);
  color: var(--tekst-mutowany);
}

.forum-ostatnie-autor {
  font-weight: 600;
  color: var(--tekst);
}

/* Czas jest „przyciskiem" dymku z pełną datą — kropkowane podkreślenie mówi,
 * że pod spodem coś jest (właściciel: „w tooltipach daty"). */
.forum-ostatnie-czas {
  border-bottom: 1px dotted currentColor;
  cursor: help;
}

.forum-ostatnie-frag {
  margin: 0;
  font-size: var(--rozmiar-s);
  color: var(--tekst-mutowany);
  /* Dwa wiersze zajawki — dłuższy tekst rozpychałby sekcję na cały ekran. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.forum-ostatnie-pusto {
  margin: 0;
  color: var(--tekst-mutowany);
  font-size: var(--rozmiar-s);
}

.forum-ostatnie-link {
  margin: var(--odst-3) 0 0;
  font-size: var(--rozmiar-s);
}

/* Telefon: etykieta typu schodzi pod tytuł, ale ZOSTAJE po prawej — przy 375 px
 * tytuł bywa dłuższy niż pół ekranu, więc trzymanie ich w jednym wierszu
 * ściskałoby tytuł do dwóch–trzech znaków w linii. */
@media (max-width: 47.99rem) {
  .forum-ostatnie-ramka {
    padding: var(--odst-3);
  }

  .forum-ostatnie-gora {
    flex-wrap: wrap;
  }

  .forum-ostatnie-gora .forum-ostatnie-tytul {
    flex: 1 1 100%;
  }

  .forum-ostatnie-gora .forum-ostatnie-typ--gora {
    margin-left: auto;
  }

  .forum-ostatnie-poz {
    padding: var(--odst-2);
  }
}


/* ============================================================================
   IKONKA „?" I DYMEK PODPOWIEDZI (komponent wspólny, 20.10.2026)
   ============================================================================
   Przeniesione z `arkusz.css`, bo potrzebuje ich także strona miasta
   (podpowiedź przy „dolnym progu PD"), a `arkusz.css` ładuje się TYLKO na
   `gra.html`. Reguły są te same co wcześniej — zmieniło się tylko miejsce:
   wspólny komponent nie może mieszkać w arkuszu jednej strony.

   Zachowanie (patrz `pomoc.js`): mysz — najchanie, dotyk — dotknięcie,
   klawiatura — Tab/Esc. Treść z `aria-label` albo `data-pomoc`. */

.pomoc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Odstęp od tekstu przed ikonką — zgłoszenie właściciela: „sklep — brakuje
     spacji przed ikonką" (wartość przyklejała się do „?"). Dotyczy wszystkich
     miejsc, gdzie „?" stoi po liczbie/słowie (inwestycje, kursy, irygacja).
     0,45em ≈ 5 px przy 11 px tekście wyliczeń — zmierzone jako czytelna spacja
     (przy 0,3em było 3 px i nadal wyglądało na sklejone). */
  margin-left: 0.45em;
  width: 1.15rem;
  height: 1.15rem;
  flex: 0 0 auto;
  font-family: var(--font-liczby);
  font-size: 0.7rem;
  font-weight: 700;
  color: #6b4a26;
  background: #e9dcbe;
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-krag);
  cursor: help;
  vertical-align: middle;
}

.pomoc:hover,
.pomoc:focus-visible {
  background: var(--akcent-zloto);
  color: #241a10;
}

/* Dymek jest `fixed`, bo pozycję liczymy z `getBoundingClientRect()` —
   dzięki temu nie zależy od tego, w jakim kontenerze siedzi ikonka. */
.pomoc-dymek {
  position: fixed;
  /* NAD POPUPEM PROFILU (30.10.2026). Popup ma `z-index: 2000`, więc dymek
   z wartością 120 lądował POD nim — właściciel: „tooltip wyświetla się pod
   profilem gracza w popupie”. 3000 jest nad popupem i nad panelem limitu. */
  z-index: 3000;
  max-width: min(22rem, calc(100vw - 2rem));
  padding: var(--odst-3);
  font-size: 0.8rem;
  line-height: 1.45;
  color: #241a10;
  background: #fdf6e6;
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien);
  box-shadow: 0 0.4rem 1.2rem rgba(60, 40, 20, 0.28);
  pointer-events: none;
}

.pomoc-dymek[hidden] {
  display: none;
}

/* ============================================================================
   RANKING MIESIĄCA I MISTRZ DNIA (strona główna, 20.10.2026)
   ============================================================================
   Właściciel: „ranking miesiąca — prosta wersja: ilość zwycięstw w grach
   zakończonych w bieżącym miesiącu. czyli tabelka top-10: login + liczba
   zwycięstw, numeracja 1–10” oraz „mistrz dnia — lista top-1 […] Jeśli kilka
   rezultatów (remis), pokazujemy wszystkie”.

   DECYZJE:
   - tabela używa klas projektu (.tabela), więc wygląda jak reszta serwisu,
   - numer pozycji jest wąski i wyciszony, liczba zwycięstw wyrównana do prawej
     (kolumna liczb — tak jak w pozostałych tabelach),
   - WIERSZ ZALOGOWANEGO gracza jest wyróżniony tłem i pogrubieniem, bo
     właściciel: „gracze będą chcieli zobaczyć swój wynik na liście”,
   - na telefonie zmniejszamy czcionkę i padding, ale NIE zawijamy liczb.
   -------------------------------------------------------------------------- */

/* Opis pod tytułem usunięty (właściciel 20.10.2026: „przecież to oczywiste,
   to gra dla ludzi myślących”) — klasa zostaje pusta, gdyby wrócił. */

/* RANKING — układ zaakceptowany przez właściciela (20.10.2026):
   „tabelę zostawić na pełną szerokość […] liczby wyśrodkować, a nazwę gracza
   bardziej zbliżyć do liczb”. Dlatego tabela jest PEŁNEJ szerokości, login
   wyrównany DO PRAWEJ (kończy się tuż przy kolumnie liczb), a liczby są
   WYŚRODKOWANE w wąskiej kolumnie — wcześniej login i liczba stały na
   przeciwnych krańcach karty i czytały się jak dwie osobne informacje. */
.tabela.ranking-tabela {
  width: 100%;
}

.ranking-tabela th.ranking-nr,
.ranking-tabela td.ranking-nr {
  width: 2.5rem;
  text-align: right;
  color: var(--tekst-mutowany);
  font-weight: 400;
}

/* Kolumna loginu WYŚRODKOWANA — właściciel (20.10.2026): „do prawej źle
   wygląda. wyśrodkuj”. Wcześniejsza wersja wyrównywała login do prawej, żeby
   zbliżyć go do liczb; okazało się, że wyśrodkowanie czyta się lepiej,
   a bliskość zapewnia wąska kolumna liczb. */
.ranking-tabela th:nth-child(2),
.ranking-tabela td:nth-child(2) {
  text-align: center;
}

.ranking-tabela th.ranking-zw,
.ranking-tabela td.ranking-zw {
  width: 5rem;
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.ranking-login {
  overflow-wrap: anywhere;
}

/* Własny wiersz gracza — wyróżnienie, nie „inna tabela”. */
.ranking-wiersz--ja td {
  background: rgba(201, 162, 39, 0.16);
  font-weight: 700;
}

.ranking-status {
  margin: var(--odst-2) 0 0;
  color: var(--tekst-mutowany);
  font-size: var(--rozmiar-s);
}

.ranking-ja {
  margin: var(--odst-2) 0 0;
  font-size: var(--rozmiar-s);
  font-weight: 700;
}

/* Mistrz dnia: login i liczba stoją BLISKO siebie (właściciel 20.10.2026:
   „też daleko login od liczby. może zbliżyć?”). `space-between` na pełnej
   szerokości karty rozrzucał je na dwa krańce, a `max-width` ograniczał tylko
   kontener — para i tak była rozsunięta. Teraz para jest wyrównana do lewej
   z odstępem między loginem a wynikiem, więc czyta się jako jedno zdanie. */
.ranking-mistrzowie {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ranking-mistrz {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  align-items: baseline;
  column-gap: var(--odst-4);
  padding: var(--odst-2) 0;
  border-bottom: 1px solid var(--linia-slaba);
}

.ranking-mistrz:last-child {
  border-bottom: 0;
}

.ranking-mistrz-login {
  font-family: var(--font-naglowek);
  overflow-wrap: anywhere;
}

.ranking-mistrz-wynik {
  color: var(--akcent);
  font-weight: 700;
  white-space: nowrap;
}

@media (max-width: 30rem) {
  .ranking-tabela {
    font-size: var(--rozmiar-s);
  }

  .ranking-tabela th,
  .ranking-tabela td {
    padding: var(--odst-2);
  }

  /* Na telefonie kolumna liczb węższa, żeby login dostał więcej miejsca. */
  .ranking-tabela th.ranking-zw,
  .ranking-tabela td.ranking-zw {
    width: 5rem;
  }

  .ranking-tabela th.ranking-nr,
  .ranking-tabela td.ranking-nr {
    width: 1.75rem;
  }
}
/* ============================================================================
   DOLNA CZĘŚĆ WIDOKU MIASTA — dwie kolumny (20.10.2026)
   ============================================================================
   Właściciel: „chciałbym przeprojektować tę dolną część — układ na dwie
   kolumny”. Lewa karta to charakterystyka miasta, prawa to statystyki
   rozgrywek. Karty mają różną wysokość, dlatego wyrównujemy je do GÓRY —
   inaczej krótsza karta rozciąga się na siłę i tabela w niej „pływa”.
   -------------------------------------------------------------------------- */
.siatka-2--gory {
  align-items: start;
}

/* NAGŁÓWKI KART NA STRONIE MIASTA WYŻEJ (właściciel, 20.10.2026:
   „nagłówki wyżej, formatowane jak inne nagłówki”).

   Nagłówki już korzystają ze wspólnych klas (`.karta-naglowek` / h2 oraz
   `.karta-podtytul` / h3), więc wygląd był poprawny — problemem był ODSTĘP:
   karta ma `padding: var(--odst-4/5)`, przez co tytuł „uciekał” od góry.
   Tu zmniejszamy tylko górny padding tych dwóch kart i odstęp pod tytułem,
   bez ruszania globalnej definicji `.karta` (inne karty mają zostać jak są). */
.karta--miasto {
  padding-top: var(--odst-3);
}

.karta--miasto > .karta-naglowek:first-child {
  margin-bottom: var(--odst-2);
}

@media (min-width: 48rem) {
  .karta--miasto {
    padding-top: var(--odst-4);
  }
}

/* Podtytuł wewnątrz karty (np. „Najlepsi gracze w mieście”, „cel gry: …”). */
.karta-podtytul {
  margin: var(--odst-4) 0 var(--odst-2);
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  color: var(--akcent);
}

.karta-podtytul:first-of-type {
  margin-top: 0;
}

/* Tabela TOP-10 miasta: login pogrubiony i WYŚRODKOWANY w swojej kolumnie
   (decyzja właściciela), liczba zwycięstw przy prawej. */
.tabela--ranking-miasta th:first-child,
.tabela--ranking-miasta td.ranking-miasta-login {
  text-align: center;
}

.tabela--ranking-miasta td.ranking-miasta-login strong {
  font-weight: 700;
}

/* UWAGA: BEZ white-space: nowrap — w tej kolumnie stoi „0 (1 gier, 0%)”,
   a na 375 px wymuszało to przewijanie strony w poziomie. Kolumna ma się
   ZAWIJAĆ, a nie rozpychać kartę. */
.tabela--ranking-miasta th:last-child,
.tabela--ranking-miasta td:last-child {
  text-align: right;
}

/* Wiersz OPISU (pełna szerokość, np. „specyfika miasta”) — normalne zawijanie,
   bez 
owrap od kolumny wartości i bez wyrównania do prawej. */
.tabela--parametry .wiersz-opisu td {
  white-space: normal;
  text-align: left;
  font-family: inherit;
  font-weight: 400;
  color: var(--tekst);
  overflow-wrap: anywhere;
}
/* ============================================================================
   OSIĄGNIĘCIA W PROFILU (schemat 33, 20.10.2026)
   ============================================================================
   Właściciel: „sekcja »osiągnięcia« w profilu — pokazujmy tam wszystkie
   zdobyte przez gracza osiągnięcia razem z licznikiem (małe kółko z liczbą)”.

   DECYZJE:
   - siatka 2 kolumny na telefonie (kafelki ~w połowie szerokości), na
     szerszym ekranie `auto-fill` — liczba odznak ma rosnąć, więc układ nie
     może zależeć od tego, ile ich dziś jest,
   - licznik to MAŁE KÓŁKO w prawym górnym rogu kafelka; pełne zdanie
     („zdobyte: 3”) siedzi w `aria-label`, bo kółko samo w sobie jest tylko
     ozdobą dla oka,
   - grafika 80 px i `object-fit: contain` — odznaki mają różne proporcje,
     a przy `cover` przycinałoby im rogi (ten sam błąd co przy zdjęciach miast).
   -------------------------------------------------------------------------- */

.osiagniecia-pusto {
  margin: 0;
  color: var(--tekst-mutowany);
}

.osiagniecia-siatka {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--odst-3);
}

@media (min-width: 48rem) {
  .osiagniecia-siatka {
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  }
}

.osiagniecie-kafel {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: start;
  gap: var(--odst-2);
  padding: var(--odst-3) var(--odst-2);
  border: 1px solid var(--linia);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  text-align: center;
}

.osiagniecie-kafel-obraz {
  width: 5rem;
  height: 5rem;
  object-fit: contain;
}

.osiagniecie-kafel-nazwa {
  font-family: var(--font-naglowek);
  font-weight: 700;
  font-size: var(--rozmiar-s);
  line-height: 1.25;
}

.osiagniecie-kafel-licznik {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  min-width: 1.6rem;
  height: 1.6rem;
  padding: 0 0.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--akcent);
  color: #fff;
  font-size: var(--rozmiar-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* ============================================================================
   KOMIKS NA STRONIE GŁÓWNEJ (22.10.2026)
   ============================================================================
   Właściciel wrzucił grafikę (1536×1023) i podał gotowy szablon. Komiks nie ma
   przezroczystości, więc przygotowaliśmy WebP z zapasowym JPG — PNG byłby tu
   kilka razy cięższy bez żadnej korzyści.
   -------------------------------------------------------------------------- */
.komiks {
  margin: 0 0 var(--odst-4);
}

.komiks img {
  border: 1px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  box-shadow: var(--cien-2);
  cursor: zoom-in;
  display: block;
  max-width: 100%;
  height: auto;
}

.komiks figcaption {
  text-align: center;
  font-size: 0.85rem;
  margin-top: 0.4rem;
}

.komiks-podpowiedz {
  display: block;
  opacity: 0.7;
}

/* Okno powiększenia. POPRAWKA 22.10.2026 (właściciel: „przy powiększaniu
   pojawiają się paski przewijania […] wystarczyłoby na ok. 800 px”):
   - szerokość ograniczona do ~800 px — obrazek 1600 px zostaje jako źródło,
     więc na ekranie retina jest ostry, ale NIE rozlewa się na cały monitor,
   - `max-height: 90vh`, żeby wysokie obrazki nie wychodziły za ekran.
   - `overflow: visible` (druga poprawka tego samego dnia): przycisk „×” ma
     wisieć POZA ramką obrazka („ujemne marginesy były dobre, teraz zasłania
     tekst”), a `hidden` ucinał go razem z paskami przewijania. Widoczny
     nadmiar nie tworzy pasków, bo `<dialog>` jest w warstwie wierzchniej
     i nie ma własnego obszaru przewijania. */
.komiks-okno {
  max-width: min(95vw, 800px);
  max-height: 90vh;
  overflow: visible;
  padding: 0;
  border: 0;
  background: none;
}

.komiks-okno::backdrop {
  background: rgb(0 0 0 / 0.8);
}

.komiks-okno img {
  width: 100%;
  height: auto;
  max-height: 90vh;
  object-fit: contain;
  display: block;
  border-radius: var(--promien-s);
}

.komiks-zamknij {
  position: absolute;
  top: -0.9rem;
  right: -0.9rem;
  width: 44px;
  height: 44px;
  border: 1px solid var(--linia-mocna);
  border-radius: 50%;
  background: var(--tlo-papier);
  color: var(--tekst);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.komiks-zamknij:hover,
.komiks-zamknij:focus-visible {
  background: var(--tlo-papier-ciemny);
}
/* Komiks na TELEFONIE (23.10.2026): okno ma się mieścić bez przewijania
   w poziomie, a przycisk „×" musi być widoczny bez przewijania — wcześniej
   na telefonie link otwierał goły plik .webp (stara decyzja opisana
   w komiks.js). 100dvh zamiast 100vh, bo na telefonach pasek adresu
   zmienia wysokość i h ucinał dół okna. */
@media (max-width: 600px) {
  .komiks-okno {
    width: 100vw;
    max-width: 100vw;
    max-height: 100dvh;
    margin: auto;
    padding: 0;
  }

  .komiks-okno img {
    width: 100%;
    height: auto;
    max-height: 100dvh;
    object-fit: contain;
  }

  .komiks-zamknij {
    position: fixed;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 2;
    width: 44px;
    height: 44px;
  }
}
/* WIERSZ GRY: LINK + PLAKIETKA OBOK SIEBIE (25.10.2026).
   Właściciel: „tą plakietkę »podejmij decyzje« chciałbym równolegle z linkiem
   do gry”. Pozycje listy są w kolumnie, więc bez tego pojemnika plakietka
   spadała pod link. `flex-wrap` zostawia furtkę na bardzo wąskie ekrany:
   wtedy plakietka zejdzie niżej, ale NIE rozjedzie szerokości listy. */
.lista-gry-wiersz {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 var(--odst-2);
}

/* KAFELEK „TRENING W MEMPHIS" (26.10.2026).
   Właściciel: „jeśli gracz nie ma dyplomu — zamiast przycisku »nowa gra« musi
   być inny przycisk »trening w memphis«”.
   Ten sam kształt co kafelek „nowa gra", ale bez grafiki (jeszcze jej nie ma):
   tekst + podpis. Gdy grafika dojdzie, `img` wypełni kafelek jak poprzednio. */
.nowa-gra-kafelek--trening {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--odst-2);
  padding: var(--odst-4);
  font: inherit;
  text-align: center;
  cursor: pointer;
  background: var(--tlo-papier);
  border: 2px dashed var(--linia-mocna);
  border-radius: var(--promien);
  color: var(--tekst);
}

.nowa-gra-kafelek--trening:hover,
.nowa-gra-kafelek--trening:focus-visible {
  border-color: var(--akcent);
  color: var(--akcent);
}

/* GRAFICZNY PRZYCISK TRENINGU W SEKCJI GOŚCIA (26.10.2026).
   Właściciel: „ten nowy obrazek możesz dać też w widoku dla niezalogowanego
   w miejsce obecnego przycisku”.
   To ten sam kafelek, więc grafika ma jedno źródło prawdy — różni się tylko
   obramowaniem: tutaj nie ma przerywanej ramki (to sekcja „hero", nie lista
   gier), a obrazek zachowuje proporcje i nie rozpycha kolumny na telefonie. */
.nowa-gra-kafelek--przycisk {
  display: inline-block;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--promien);
  line-height: 0;
  cursor: pointer;
}

.nowa-gra-kafelek--przycisk .nowa-gra-kafelek__obraz {
  width: min(363px, 100%);
  height: auto;
  border-radius: var(--promien);
  transition: filter 120ms ease, transform 120ms ease;
}

.nowa-gra-kafelek--przycisk:hover .nowa-gra-kafelek__obraz,
.nowa-gra-kafelek--przycisk:focus-visible .nowa-gra-kafelek__obraz {
  filter: brightness(1.05);
  transform: translateY(-1px);
}

.nowa-gra-kafelek__podpis {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-l);
}

.nowa-gra-kafelek__nota {
  font-size: var(--rozmiar-xs);
  color: var(--tekst-mutowany);
  max-width: 30ch;
}

/* ==========================================================================
   PANEL „GRY" W GÓRNYM MENU (26.10.2026)
   ==========================================================================
   Właściciel: „wysuwany panel »trwające gry« z linkami do arkusza gry.
   z czasami przeliczeń, ikonką »podejmij decyzje« — tak jak na index.html.
   […] w jedynce mieliśmy panel rozwijany z boku. a z góry będzie ładniejszy.”

   UKŁAD: przycisk stoi w pasku nawigacji (lewa strona, obok „Zaloguj"),
   a panel wisi POD paskiem na pełną szerokość ekranu (telefon) albo jako
   karta 22 rem przy prawej krawędzi przycisku (desktop). Tło panelu jest
   jasne (papier), bo pasek jest ciemny — czytelność tekstu i kontrast
   zgodnie z resztą serwisu.

   POSITION: panel jest `absolute` wewnątrz `.nawigacja` (która jest
   `position: sticky`), więc „przykleja się" do paska także po przewinięciu. */

/* PRZYCISK JAKO POZYCJA MENU (27.10.2026). Właściciel: „dajemy go w menu,
   tak jak inne opcje […] na desktopie źle wygląda — rozpycha menu”.
   Dlatego NIE jest już osobnym przyciskiem z ramką: dziedziczy typografię
   pozycji nawigacji, a jedynym wyróżnikiem jest licznik w nawiasie.
   Ramka znika — pozycja menu nie ma ramki. */
/* WYGLĄD DOKŁADNIE JAK POZYCJA MENU (27.10.2026). Wartości przepisane
   z `.nawigacja-lista a` (banner.css): ta sama czcionka, rozmiar i waga —
   inaczej „Gry (6)” wyglądało jak dopisek obok „profil”, a nie jak pozycja
   menu. `inherit` nie wystarczyło, bo te wartości ustawia <a>, nie <li>. */
/* PRZYCISK „moje gry" — W PASKU (telefon) I W MENU (desktop) (27.10.2026).
   Właściciel: „na telefonie teraz znikł ten panel z grami […] na desktopie jest
   ucinane z prawej […] »Gry« zrobić z małej, jako »moje gry«”.
   Jeden węzeł, dwa miejsca w DOM (przenosi go `matchMedia` w panel-gry.js).
   Na telefonie wygląda jak „Zaloguj” (mała czcionka, wersalików NIE wymuszamy —
   ma być „z małej”), na desktopie jak pozycja menu. */
/* PUSTA POZYCJA MENU NIE MOŻE ZAJMOWAĆ WIERSZA (27.10.2026).
   Na telefonie przycisk „moje gry” przenosi się do dolnego paska, więc
   w liście menu zostaje jego `<li>` — pusty, ale zajmujący wysokość
   (widać było pusty pasek nad „start”). Chowamy wyłącznie PUSTE pozycje,
   więc desktop (gdzie w środku jest przycisk) działa bez zmian. */
.nawigacja-pozycja-gry:empty {
  display: none;
}

.nawigacja-gry {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 44px;
  padding: 0.25rem 0.35rem;
  background: transparent;
  border: 0;
  color: var(--tekst-jasny);
  font-family: var(--font-display);
  font-size: var(--rozmiar-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: none;
  white-space: nowrap;
  cursor: pointer;
}

/* „GRY” NA TELEFONIE / „moje gry” NA DESKTOPIE (27.10.2026).
   Dwa napisy w DOM, widoczność sterowana progiem 60 rem — bez JS i bez
   migotania przy pierwszym rysowaniu. Na telefonie napis jest WERSALIKIEM
   jak pozostałe skróty („START”, „ZASADY”), bo tak wygląda cały pasek. */
.nawigacja-gry-etykieta--mobilna {
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.nawigacja-gry-etykieta--desktop {
  display: none;
}

@media (min-width: 60rem) {
  .nawigacja-gry-etykieta--mobilna {
    display: none;
  }

  .nawigacja-gry-etykieta--desktop {
    display: inline;
  }
}

/* ŻÓŁTA CZCIONKA PRZY NAJECHANIU — JAK POZOSTAŁE POZYCJE (27.10.2026).
   Właściciel: „na desktopie wszystkie pozycje w menu po podświetleniu zmieniają
   kolor czcionki na żółty. z wyjątkiem tego nowego panelu z grami”.
   Reguła `.nawigacja-lista a:hover` ustawia `#ffe9a8`, ale „moje gry” jest
   `<button>`-em, więc dziedziczyła tylko tło. Teraz ma TEN SAM kolor —
   spójność paska jest ważniejsza niż to, czy element jest odnośnikiem. */
.nawigacja-gry:hover,
.nawigacja-gry:focus-visible,
.nawigacja-gry[aria-expanded='true'] {
  background: rgba(245, 236, 216, 0.12);
  color: #ffe9a8;
}

.nawigacja-gry[aria-expanded='true'] {
  background: rgba(245, 236, 216, 0.2);
}

/* KÓŁECZKO Z LICZBĄ DECYZJI (27.10.2026). Właściciel: „zamiast liczby gier
   w nawiasie — może lepiej byłoby pokazywać w kółeczku, w ilu grach mamy
   decyzje do podjęcia? jak liczba powiadomień w serwisie”.
   Kolor bierzemy z tokenów (czerwień projektowa + biel), bo to ten sam
   sygnał „wymaga uwagi”, co plakietki w grze. Kontrast biel na `#a83232`
   to 6,6 : 1 — powyżej progu AA. */
.nawigacja-gry-licznik {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3rem;
  height: 1.3rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--akcent-czerwony);
  color: #fff;
  font-family: var(--font-liczby);
  font-size: var(--rozmiar-xs);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* `hidden` musi wygrać z `display: inline-flex` — inaczej „0” świeciłoby
   mimo zerowej liczby decyzji. */
.nawigacja-gry-licznik[hidden] {
  display: none;
}

/* Na szerokim ekranie przycisk jest pozycją menu — te same wymiary i ten sam
   podział kolumn co `.nawigacja-lista > li > a`, żeby nie odstawał. */
@media (min-width: 60rem) {
  .nawigacja-gry {
    min-height: 54px;
    padding: var(--odst-3) var(--odst-4);
    font-size: var(--rozmiar-l);
    letter-spacing: 0.02em;
  }

  /* Prawa krawędź paska — pionowa linia jak przy pozostałych pozycjach. */
  .nawigacja-pozycja-gry {
    border-right: 1px solid rgba(245, 236, 216, 0.14);
  }
}

/* Miejsce przycisku w pasku (telefon). Na desktopie go nie ma — przycisk
   mieszka wtedy w liście menu. */
.nawigacja-gry-miejsce {
  display: inline-flex;
  align-items: center;
}

@media (min-width: 60rem) {
  .nawigacja-gry-miejsce {
    display: none;
  }
}

/* Sam panel — WYGLĄD JAK PODMENU „MAPY” (27.10.2026).
   Właściciel: „może zachować kolor menu taki jak na mapach?”.
   Podmenu „mapy” ma tło `#5c3f21` (banner.css), jasny tekst i obramowanie
   `--tlo-noc`. Powtarzamy DOKŁADNIE te wartości — lokalną zmienną, żeby nie
   wpisywać koloru w pięciu miejscach, ale bez wymyślania nowego odcienia.
   Kontrast tekstu `--tekst-jasny` na tym tle: 8,2 : 1. */
.panel-gry {
  --panel-gry-tlo: #5c3f21;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 45;
  max-height: min(70vh, 32rem);
  overflow-y: auto;
  padding: var(--odst-2) 0;
  background: var(--panel-gry-tlo);
  border-top: 1px solid rgba(245, 236, 216, 0.14);
  border-bottom: 2px solid var(--tlo-noc);
  box-shadow: var(--cien-2);
  color: var(--tekst-jasny);
}

/* Desktop: panel jako karta pod przyciskiem — jak podmenu „mapy”
   (`min-width: 13rem`, ciemne tło, obramowanie). Lewą krawędź ustawia JS,
   przycinając panel do prawej krawędzi okna. */
@media (min-width: 60rem) {
  .panel-gry {
    right: auto;
    width: 22rem;
    border: 1px solid var(--tlo-noc);
    border-top: none;
    border-radius: 0 0 var(--promien-s) var(--promien-s);
  }
}

.panel-gry[hidden] {
  display: none;
}

.panel-gry-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* WIERSZE JEDNAKOWEJ WYSOKOŚCI (27.10.2026). Właściciel: „zrobić wiersze
   jednakowej wysokości”. Bez tego lista była zębata: gra z plakietką
   i terminem miała inny wzrost niż gra bez nich. Stała wysokość + wyśrodkowanie
   w pionie = równa siatka niezależnie od zawartości. */
.panel-gry-element {
  display: flex;
  align-items: center;
  /* STAŁA wysokość, nie `min-height`: zmierzone 63 px z plakietką i 60 px bez
     niej dawało listę zębatą. Wysokość wymuszona = wszystkie wiersze równe.
     Podniesione do 4 rem (64 px), bo plakietka „podejmij decyzje" ma 38 px
     i przy 60 px ucinała się o 2 px. */
  height: 4rem;
  border-bottom: 1px solid rgba(245, 236, 216, 0.14);
}

.panel-gry-element:last-child {
  border-bottom: 0;
}

.panel-gry .lista-gry-wiersz {
  display: flex;
  align-items: center;
  gap: var(--odst-2);
  width: 100%;
  /* WEWNĘTRZNY PASEK WYPEŁNIA CAŁĄ POZYCJĘ (27.10.2026).
     Właściciel: „ciągle to podświetlanie nie jest dobrze. górne wiersze ok,
     a niżej już za wąskie”.
     Zmierzone: pozycje z plakietką miały 62 px, bez plakietki 40 px — bo pasek
     rósł z TREŚCI, a nie z wysokości pozycji listy. Tło podświetlenia leży
     właśnie na tym pasku, więc niższe pozycje dostawały węższy pas.
     Teraz pasek ma 100% wysokości pozycji, a pozycja stałą wysokość. */
  height: 100%;
  box-sizing: border-box;
  padding: var(--odst-1) var(--odst-3);
  overflow: hidden;
  /* WIERSZ JAK POZYCJA PODMENU „MAPY" (27.10.2026).
     Właściciel: „chciałbym by na desktopie wybór gry wyglądał jak w menu
     wybór roku — kursor »łapka«, nie podświetlanie linka, tylko cały wiersz
     się podświetla i reaguje”.
     Dlatego wiersz jest pozycjonowany (link rozciąga się na całość przez
     `::after`), kursor działa na całym wierszu, a podkreślenie tekstu znika —
     jedynym sygnałem jest tło, dokładnie jak w podmenu „mapy". */
  position: relative;
}

.panel-gry-element {
  cursor: pointer;
}

/* Link pokrywa CAŁY wiersz — klik w plakietkę i w wolne miejsce też prowadzi
   do gry. Sam tekst zostaje na swoim miejscu, więc nic się nie rozjeżdża. */
.panel-gry .panel-gry-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.panel-gry-element:hover .lista-gry-wiersz {
  background: rgba(245, 236, 216, 0.12);
}

/* Klawiatura dostaje OBRAMÓWKĘ, a nie tło wiersza — inaczej pierwszy wiersz
   wyglądał na aktywny zaraz po otwarciu panelu (właściciel: „pierwszy wiersz
   podświetlony”). */
.panel-gry .panel-gry-link:focus-visible {
  outline: 2px solid var(--akcent-zloto);
  outline-offset: -2px;
  border-radius: var(--promien-s);
}

/* PODKREŚLENIE ZNIKA — w podmenu „mapy" też go nie ma. Zostaje tło wiersza. */
.panel-gry-link:hover .panel-gry-nazwa,
.panel-gry-link:focus-visible .panel-gry-nazwa {
  text-decoration: none;
}

/* KOLOR I CZCIONKA WYGRYWAJĄ Z NAWIGACJĄ (27.10.2026).
   Panel siedzi wewnątrz `.nawigacja`, a reguła `.nawigacja-lista a` ustawia
   jasny kolor i 18 px — linki w panelu dziedziczyły to i były NIECZYTELNE
   na jasnym tle (zmierzone: rgb(245,236,216) na papierze). Podwajamy klasę,
   żeby wygrać specyficznością bez `!important`. */
.panel-gry .panel-gry-link {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1 1 auto;
  min-width: 0;
  color: var(--tekst-jasny);
  font-size: var(--rozmiar-s);
  font-weight: 400;
  text-decoration: none;
  padding: 0;
  border-bottom: 0;
  min-height: 0;
}

/* NAZWA GRY NA ŻÓŁTO PRZY NAJECHANIU (27.10.2026).
   Właściciel: „na »moje gry« zadziałało, ale nazwy gier w podmenu już nie”.
   W pasku każda pozycja zmienia kolor tekstu na `#ffe9a8`; wiersze panelu
   zmieniały tylko tło. Teraz nazwa gry robi to samo — ten sam sygnał,
   ten sam kolor, niezależnie od tego, czy pozycja jest w pasku, czy w panelu.
   Termin („dzisiaj o 11:31”) zostaje wyciszony: to informacja dodatkowa. */
.panel-gry .panel-gry-link:hover,
.panel-gry .panel-gry-link:focus-visible,
.panel-gry-element:hover .panel-gry-nazwa,
.panel-gry-element:focus-within .panel-gry-nazwa {
  color: #ffe9a8;
}

.panel-gry .panel-gry-link {
  transition: color var(--czas-szybki) var(--krzywa);
}

.panel-gry .panel-gry-nazwa {
  transition: color var(--czas-szybki) var(--krzywa);
}

/* (reguła z `text-decoration: underline` usunięta 27.10.2026 — właściciel
   chce wyróżnienia TYLKO tłem wiersza, jak w podmenu „mapy"; poprzednia
   wersja tej reguły stała WYŻEJ i była nadpisywana) */

.panel-gry .panel-gry-nazwa {
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-m);
  font-weight: 700;
  color: var(--tekst-jasny);
  /* PODKREŚLENIE ZDĘTE TAKŻE Z DZIECKA (27.10.2026). Reguła `a { text-decoration:
     underline }` z `base.css` przechodzi na dzieci, a ustawienie `none` na
     samym odnośniku nie zawsze je zdejmuje. Właściciel chce wyróżnienia
     WYŁĄCZNIE tłem wiersza (jak w podmenu „mapy"). */
  text-decoration: none;
}

.panel-gry .panel-gry-termin {
  text-decoration: none;
}

/* Termin mniejszy i wyciszony — to informacja dodatkowa, nie tytuł. */
.panel-gry .panel-gry-termin {
  font-size: var(--rozmiar-xs);
  color: var(--tlo-sepia);
}

/* PLAKIETKA „PODEJMIJ DECYZJĘ” NA JASNO (27.10.2026).
 *
 * Właściciel: „›podejmij decyzje‹ trzeba zrobić na jasno”.
 *
 * Plakietka dziedziczyła ciemny wariant (`.plakietka--zwykla`) na ciemnym tle
 * panelu (`#5c3f21`) i była praktycznie niewidoczna. Teraz jest JASNA:
 * kremowe tło (ten sam `--tlo-papier` co karty) + ciemny tekst + złota ramka.
 * Kontrast tekstu `#241a10` na `#f7efdc` = 13,2 : 1 (wymóg AA to 4,5 : 1).
 * Rozmiar pisma podniesiony do `--rozmiar-xs`, bo na telefonie 10 px było
 * nieczytelne — plakietka ma przyciągać wzrok, a nie szeptać. */
.panel-gry .panel-gry-decyzja {
  flex: 0 0 auto;
  align-self: center;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--akcent-zloto);
  border-radius: var(--promien-s);
  background: var(--tlo-papier);
  color: #241a10;
  font-size: var(--rozmiar-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* AKTYWNA GRA — WYRÓŻNIONY WIERSZ (27.10.2026).
   Właściciel: „wiersz z aktualnie otwartą grą można wyróżnić jako aktywny.
   by nie przechodzić do otwartej teraz gry”. Jaśniejsze tło + złoty pasek
   z lewej (ten sam sygnał co `aria-current` w menu) i `cursor: default`,
   bo ten wiersz nie jest klikalny.

   POPRAWKA 27.10.2026 (wieczór): „podświetlenie za wysokie”. Wcześniej tło
   wypełniało CAŁY wiersz (60 px z paddingiem), więc aktywna gra wyglądała jak
   wielki kafel. Teraz podświetlenie jest WEWNĄTRZ wiersza: odstęp od góry
   i dołu + zaokrąglenie, czyli ~45 px — czytelne, ale nie dominujące. */
/* PODŚWIETLENIE MA WYPEŁNIAĆ CAŁY WIERSZ (27.10.2026).
   Właściciel: „dalsze podświetlenia mają mniejszą wysokość niż wiersz”.
   Wcześniej aktywne podświetlenie było wcięte (`margin-block` + `calc`),
   a hover pełny — dwa różne sygnały o różnej wysokości. Teraz OBA wypełniają
   wiersz równo, a jedyną różnicą jest złoty pasek z lewej (aktywna gra)
   i brak podkreślenia. */
.panel-gry-element--aktywna .lista-gry-wiersz {
  background: rgba(245, 236, 216, 0.14);
  box-shadow: inset 3px 0 0 var(--akcent-zloto);
}

.panel-gry .panel-gry-link--aktywny {
  cursor: default;
}

/* Aktywna gra nie jest odnośnikiem — cały jej wiersz nie reaguje na kursor. */
.panel-gry-element--aktywna {
  cursor: default;
}

.panel-gry .panel-gry-link--aktywny .panel-gry-nazwa::after {
  content: ' •';
  color: var(--akcent-zloto);
}

.panel-gry .panel-gry-link--aktywny:hover .panel-gry-nazwa {
  text-decoration: none;
}

/* Komunikat też na ciemnym tle — wcześniej dziedziczył `--tekst-mutowany`,
   który na `#5c3f21` dawał kontrast 1,4 : 1 (nieczytelny). */
.panel-gry-komunikat {
  color: var(--tlo-sepia);
  margin: 0;
  padding: var(--odst-2) var(--odst-3);
  font-size: var(--rozmiar-s);
  color: var(--tekst-mutowany);
}

/* Desktop: panel jako karta przy lewej krawędzi (tam stoi przycisk).
   Szerokość ograniczona, żeby przy 1600 px nie rozciągał się na pół ekranu. */
@media (min-width: 60rem) {
  .panel-gry {
    /* `left` ustawia JS pod przyciskiem (`ustawPozycjePanelu`) — tu tylko
       wartość wyjściowa, gdyby skrypt nie zdążył. */
    left: var(--odst-2);
    right: auto;
    /* SZERSZY PANEL (27.10.2026). Właściciel: „za wąski ten panel”.
       Nazwy gier są długie („1832_Cleveland_14”), a przy 22 rem końcówki
       się łamały. 26 rem mieści nazwę i plakietkę w jednej linii. */
    width: 26rem;
    border: 1px solid var(--linia-mocna);
    border-top: none;
    border-radius: 0 0 var(--promien-s) var(--promien-s);
  }
}

/* OSTRZEŻENIE „MNIEJ NIŻ GODZINA DO PRZELICZENIA" (26.10.2026).
   Właściciel: „jeśli zostało mniej niż 1 godzina to przy tooltipie daj ikonkę
   wykrzyknika. albo jakiś trójkącik żółty. ostrzeżenie”.
   Żółty trójkąt rysujemy CSS-em (border), żeby nie dociągać pliku graficznego
   dla jednej ikonki; wykrzyknik jest tekstem, więc czyta go czytnik ekranu
   przez `aria-label` ustawiony w JS. */
.lista-gry-alarm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.2rem;
  margin-left: 0.35rem;
  font-family: var(--font-liczby);
  font-size: 0.72rem;
  font-weight: 700;
  color: #3a2a1a;
  background: var(--akcent-zloto);
  border-radius: 0.15rem;
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  vertical-align: middle;
  cursor: help;
}

.lista-gry-alarm:hover,
.lista-gry-alarm:focus-visible {
  background: var(--akcent);
}

/* ZNACZNIK „TESTOWA" PRZY TURZE (26.10.2026).
   Właściciel: „jak jest rozgrywka testowa to można by dodać znacznik »testowa«
   na prawo od numeru tury”.
   Ma być widoczny, ale NIE krzyczeć — gra toczy się normalnie, tylko wynik
   nie liczy się do statystyk. Dlatego złote tło zwykłej plakietki, mała
   czcionka i odstęp od stempla tury. */
.arkusz-testowa {
  display: inline-block;
  /* Nadpisujemy wygląd ikonki „?”: `.pomoc` ustawia kwadrat 1.15rem, kółko
     i złote tło. Pastylka musi mieć wymiary z treści, a nie z ikony. */
  width: auto;
  height: auto;
  flex: 0 0 auto;
  margin-left: var(--odst-2);
  padding: 0.05rem 0.45rem;
  font-family: var(--font-tekst);
  font-size: var(--rozmiar-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--tekst);
  background: var(--tlo-papier);
  border: 1px solid var(--linia-mocna);
  border-radius: 999px;
  vertical-align: middle;
  cursor: help;
}

/* W grze testowej obwódka dostaje kolor akcentu — tak samo jak plakietka
   „testy zamknięte" w lobby, żeby oba miejsca mówiły tym samym językiem. */
.arkusz-testowa {
  border-color: var(--akcent);
  color: var(--akcent);
}

/* PASTYLKA OBOK STEMPLA (26.10.2026). Stempel tury jest `inline-block`
   i to on wyznacza linię; pastylka ma się ustawić w TEJ SAMEJ linii, tuż
   za nim — tak jak na mapach „Cleveland · 1832 [TESTOWA]”. `inline-block`
   plus `vertical-align: middle` wystarcza; `margin-left` daje oddech. */
.arkusz-testowa--inline {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.5rem;
}

/* ZNACZNIK „PODEJMIJ DECYZJE" w sekcji „Twoje gry" (24.10.2026).
   Właściciel: „odznaka »podejmij decyzje« na stronie głównej". Ma być widoczna
   na pierwszy rzut oka, więc dostaje kolor akcentu (ten sam co główne
   przyciski) zamiast złotego tła zwykłych plakietek. margin-left oddziela
   ją od tekstu gry, a lign-self trzyma w jednej linii z linkiem. */
/* „WYPISZ SIĘ" W WIERSZU GRY OCZEKUJĄCEJ (26.10.2026).
   Właściciel: „jak gracz się zapisał do gry, to potrzebny jest przycisk
   »wypisz się« […] widoczne tam gdzie są gry oczekujące”.
   Wiersz jest `flex-wrap`, więc na 375 px przycisk schodzi pod tekst, a nie
   rozpycha listy. `margin-left: auto` trzyma go po prawej na szerokim ekranie. */
.lista-gry-wypisz {
  flex: 0 0 auto;
  margin-left: auto;
}

@media (max-width: 44rem) {
  /* Na wąskim ekranie przycisk idzie pod tekst — `auto` odsuwałby go w prawo
     i łamał wiersz w środku. */
  .lista-gry-wypisz {
    margin-left: 0;
  }
}

/* „ZOBACZ WYNIKI" — PLAKIETKA JEDNORAZOWA (27.10.2026).
   Właściciel: „gra świeżo zakończona — chciałbym na liście gier zobaczyć
   jednorazowe powiadomienie ›zobacz wyniki‹”.
   To ODLINKOWANA plakietka (prowadzi do arkusza zakończonej gry), więc musi
   wyglądać klikalnie i mieć kontrast tekstu ≥ 4,5:1. Kolor bierzemy z akcentu
   (`--akcent` = czerwień serwisu), a nie ze złota — złote są plakietki
   informacyjne, a ta jest ZAPROSZENIEM. */
/* WSPÓLNE WYMIARY OBU PLAKIETEK (27.10.2026).
   „Podejmij decyzje" i „zobacz wyniki" to ten sam element interfejsu —
   plakietka w wierszu listy gier. Różni je kolor i przeznaczenie, nie
   rozmiar; wcześniej jedna miała własne `white-space` i `align-self`,
   przez co na telefonie wychodziły różne wysokości. */
.lista-gry .lista-gry-plakietka {
  flex: 0 0 auto;
  align-self: center;
  white-space: nowrap;
  /* RÓWNE WYMIARY OBU PLAKIETEK (27.10.2026).
     „zobacz wyniki" jest ODLINKOWANIEM, więc łapało ogólną regułę
     `.lista-gry a { min-height: 44px; padding-block: … }` — i na telefonie
     miało 44 px wysokości, gdy „podejmij decyzje" (span) miało 25 px.
     Podwajamy klasę, żeby wygrać specyficznością, i zerujemy te właściwości:
     plakietka ma swój padding i wysokość z treści, niezależnie od tego,
     czy jest przyciskiem, czy odnośnikiem. */
  min-height: 0;
  padding: 2px var(--odst-2);
  line-height: 1.2;
}

@media (max-width: 44rem) {
  .lista-gry-plakietka {
    align-self: flex-start;
  }
}

.lista-gry-wyniki {
  flex: 0 0 auto;
  color: #ffffff;
  background: var(--akcent);
  border-color: transparent;
  text-decoration: none;
  white-space: nowrap;
}

.lista-gry-wyniki:hover,
.lista-gry-wyniki:focus-visible {
  background: var(--akcent-czerwony);
  color: #ffffff;
  text-decoration: none;
}

/* (reguła `align-self` dla „zobacz wyniki" przeniesiona wyżej — do wspólnej
   klasy `lista-gry-plakietka`, żeby obie plakietki miały ten sam rozmiar) */

.lista-gry-decyzja {
  /* Odstęp od linku daje `gap` pojemnika — własny `margin-left` dublowałby go
     i przesuwał plakietkę o dwa odstępy. */
  color: #ffffff;
  background: var(--akcent);
  border-color: transparent;
}
/* ==========================================================================
   PRZYCISK GRAFICZNY „NOWA GRA" (25.10.2026)
   ==========================================================================
   Właściciel: „na górze sekcji »Twoje gry« pod tym nagłówkiem dodaj przycisk
   graficzny prowadzący do nowe-gry.html […] wersja z prawej z podświetleniem
   jako hover po mouseover”.

   JAK DZIAŁA: w linku leżą DWA obrazki — normalny i podświetlony. Są
   absolutnie nałożone na siebie w pudełku o stałej proporcji, a `hover`
   (i `focus-visible`, żeby działało z klawiatury) tylko zmienia ich
   przezroczystość. Dzięki temu nie ma podmiany `src`, więc nie ma mignięcia
   ani dodatkowego żądania przy pierwszym najechaniu.
   ========================================================================== */
.nowa-gra-kafelek {
  position: relative;
  display: block;
  /* SZEROKOŚĆ = NATURALNY ROZMIAR GRAFIKI (25.10.2026). Wcześniej stało tu
     360 px, a grafiki mają 363 px — przeglądarka skalowała je w dół o 0,8%,
     co przy pikselowej grafice dawało minimalne rozmycie krawędzi.
     Właściciel zauważył to w narzędziach: „przeglądarka pokazuje mi 360 px,
     a obrazki mają 363 px". Teraz obrazek jest wyświetlany 1:1, a na węższym
     ekranie nadal skaluje się w dół (`min(100%, …)`). */
  width: min(100%, 363px);
  /* Sama grafika ma puste rogi (przezroczystość), więc cień i obramowanie
     dorysowywałby drugi, obcy kształt — dlatego ich nie ma. */
  margin: 0 auto var(--odst-3);
  aspect-ratio: 363 / 228;
  text-decoration: none;
  border-radius: var(--promien-m);
  /* Widoczny pierścień fokusu dopiero przy nawigacji klawiaturą. */
  outline: none;
}

.nowa-gra-kafelek:focus-visible {
  outline: 3px solid var(--akcent);
  outline-offset: 4px;
}

.nowa-gra-kafelek__obraz {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 120ms ease;
}

/* PODSTAWA ZOSTAJE W PEŁNI WIDOCZNA — WCHODZI TYLKO PODŚWIETLENIE (25.10.2026).
   Właściciel: „przy najeżdżaniu kursorem widzę, że one lekko migają przy
   podmianie. dałoby się jakoś to zmienić? można zrobić, że ten hover się
   wyświetla, ale ten spód spodu nie znika? może byłoby lepiej”.

   Miał rację i to była wina MOJEGO CSS: oba obrazy zmieniały przezroczystość
   jednocześnie, więc w środku animacji ŻADEN nie był w pełni widoczny —
   przez ułamek sekundy prześwitywało tło i to wyglądało jak mignięcie.
   Teraz blada podstawa ma ZAWSZE `opacity: 1`, a podświetlona wersja tylko
   się „włącza”. Ponieważ oba pliki mają identyczny kadr (363×228), wersja
   z latarnią zasłania wersję zgaszoną bez szwów. */
.nowa-gra-kafelek__obraz--hover {
  opacity: 0;
  transition: opacity 140ms linear;
}

.nowa-gra-kafelek:hover .nowa-gra-kafelek__obraz--hover,
.nowa-gra-kafelek:focus-visible .nowa-gra-kafelek__obraz--hover {
  opacity: 1;
}

/* Bez animacji dla osób, które jej nie chcą — podmiana zostaje natychmiastowa. */
@media (prefers-reduced-motion: reduce) {
  .nowa-gra-kafelek__obraz {
    transition: none;
  }
}
/* ==========================================================================
   SONDA (schemat 60, 27.10.2026)
   ==========================================================================
   Właściciel: „wyświetlamy oczywiście tylko zalogowanym, w index.html nad
   saloonem: h2: Sonda, pytanie, odpowiedzi radio. ›głosuj‹. od odpowiedzi
   to najlepiej przeładowanie tylko tego modułu: zamiast formularza pojawia
   się wykres kołowy z legendą […] ważne by podać na dole ›liczba głosów: xx‹”.

   UKŁAD: kółko po lewej, legenda po prawej (na wąskim ekranie pod kółkiem).
   Wykres to `conic-gradient` na `<div>` — bez SVG i bez bibliotek, bo wycinki
   to dokładnie to, do czego służy gradient stożkowy.
   ========================================================================== */

.sonda {
  margin-bottom: var(--odst-4);
}

.sonda-karta {
  padding: var(--odst-4);
}

/* Pytanie: mniejsze niż nagłówek sekcji, ale wyraźnie mocniejsze od odpowiedzi */
.sonda-pytanie {
  padding: 0;
  margin-bottom: var(--odst-3);
  font-family: var(--font-naglowek);
  font-size: var(--rozmiar-l);
  font-weight: 700;
  line-height: 1.35;
  color: var(--tekst);
}

/* `fieldset` nie może mieć domyślnej ramki — pytanie ma być zwykłym tekstem */
.sonda-odpowiedzi {
  margin: 0;
  padding: 0;
  border: 0;
  display: grid;
  gap: var(--odst-2);
}

.sonda-odpowiedz {
  display: flex;
  align-items: center;
  gap: var(--odst-2);
  min-height: 44px;          /* minimum dotykowe projektu */
  padding: var(--odst-2) var(--odst-3);
  border: 1px solid var(--linia-slaba);
  border-radius: var(--promien-s);
  background: var(--tlo-papier);
  cursor: pointer;
}

.sonda-odpowiedz:hover {
  border-color: var(--linia-mocna);
  background: var(--tlo-papier-ciemny);
}

/* Zaznaczona odpowiedź musi być WIDOCZNA, nie tylko „kropka się wypełniła” */
.sonda-odpowiedz:has(input:checked) {
  border-color: var(--akcent);
  background: rgba(139, 90, 43, 0.08);
}

.sonda-odpowiedz input[type='radio'] {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  accent-color: var(--akcent);
  cursor: pointer;
}

.sonda-pasek {
  margin-top: var(--odst-3);
}

.sonda-blad {
  margin: var(--odst-2) 0 0;
  font-size: var(--rozmiar-s);
  color: var(--akcent-czerwony);
}

/* --- WYNIKI --------------------------------------------------------------- */

.sonda-wyniki-gora {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--odst-4);
}

.sonda-kolo {
  flex: 0 0 auto;
  width: 9rem;
  height: 9rem;
  border-radius: 50%;
  border: 3px solid var(--tlo-papier);
  box-shadow: 0 0 0 1px var(--linia-slaba);
  background: var(--tlo-papier-ciemny);
}

.sonda-kolo--puste {
  background: repeating-conic-gradient(
    var(--tlo-papier-ciemny) 0% 25%,
    var(--tlo-papier) 25% 50%
  );
}

.sonda-legenda {
  flex: 1 1 12rem;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--odst-1);
}

.sonda-legenda-pozycja {
  display: flex;
  align-items: baseline;
  gap: var(--odst-2);
  font-size: var(--rozmiar-s);
  line-height: 1.35;
}

.sonda-legenda-kolor {
  flex: 0 0 auto;
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 0.15rem;
  border: 1px solid rgba(0, 0, 0, 0.18);
}

.sonda-legenda-tresc {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

.sonda-legenda-liczby {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--tekst);
}

.sonda-liczba-glosow {
  margin: var(--odst-3) 0 0;
  font-size: var(--rozmiar-s);
  color: var(--tekst-mutowany);
}

/* Na telefonie kółko nad legendą — obok siebie byłyby dwie wąskie kolumny */
@media (max-width: 30rem) {
  .sonda-wyniki-gora {
    flex-direction: column;
    align-items: flex-start;
  }

  .sonda-kolo {
    width: 7.5rem;
    height: 7.5rem;
  }
}

/* Subtelne pojawienie się wyników. Właściciel lubi spokojny ruch, ale
   przy `prefers-reduced-motion` animacji NIE MA — tak samo jak w zakładkach
   i karteczkach. */
@keyframes sonda-wyniki-wejscie {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

.sonda-wyniki {
  animation: sonda-wyniki-wejscie 180ms ease-out both;
}

@media (prefers-reduced-motion: reduce) {
  .sonda-wyniki {
    animation: none;
  }
}

/* ==========================================================================
   SALOON NA STRONIE GŁÓWNEJ — COFANIE WŁASNEJ WYPOWIEDZI (27.10.2026)
   Właściciel: „chciałbym w ogólnym saloonie na głównej stronie też by była
   opcja cofania swojej wypowiedzi. tak jak zrobiłeś w saloonie rozgrywki”.
   Krzyżyk stoi na końcu wiersza, ledwo widoczny do najechania — nie ma
   konkurować z treścią, ale musi być klikalny na telefonie (stąd 2.25rem).
   ========================================================================== */
.saloon-usun {
  margin-left: 0.5rem;
  padding: 0 0.4rem;
  min-width: 2.25rem;
  min-height: 2.25rem;
  border: 0;
  background: transparent;
  color: var(--tekst-mutowany, #6b5a45);
  font-family: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.75;
}

.saloon-usun:hover,
.saloon-usun:focus-visible {
  color: var(--akcent-czerwony, #a83232);
  opacity: 1;
}

.saloon-potwierdzenie-tlo {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--odst-4, 1rem);
  background: rgba(29, 21, 12, 0.45);
}

.saloon-potwierdzenie {
  width: min(24rem, 100%);
  padding: var(--odst-4, 1rem);
  border: 2px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  box-shadow: var(--cien-3);
  display: flex;
  flex-direction: column;
  gap: var(--odst-3, 0.75rem);
}

.saloon-potwierdzenie-pytanie {
  margin: 0;
  font-size: var(--rozmiar-m, 1rem);
}

.saloon-potwierdzenie-przyciski {
  display: flex;
  gap: var(--odst-2, 0.5rem);
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* ==========================================================================
   OKNO UWAG IZZIEGO PRZED PRZELICZENIEM (schemat 62, 27.10.2026)
   Właściciel: „okienko potwierdzenia z podpowiedziami Izzi i dwoma
   przyciskami: [Popraw decyzje] [Przelicz mimo to]”.
   Wygląd spójny z potwierdzeniem usunięcia w saloonie — ten sam wzorzec,
   żeby gracz nie uczył się dwóch różnych okien.
   ========================================================================== */
.izzi-uwagi-tlo {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--odst-4, 1rem);
  background: rgba(29, 21, 12, 0.45);
}

.izzi-uwagi {
  width: min(30rem, 100%);
  max-height: 80vh;
  overflow-y: auto;
  padding: var(--odst-4, 1rem);
  border: 2px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  box-shadow: var(--cien-3);
  display: flex;
  flex-direction: column;
  gap: var(--odst-3, 0.75rem);
}

.izzi-uwagi-tytul {
  margin: 0;
  font-size: var(--rozmiar-m, 1rem);
  font-weight: 700;
}

.izzi-uwagi-lista {
  margin: 0;
  padding-left: 1.2rem;
  display: grid;
  gap: var(--odst-2, 0.5rem);
}

.izzi-uwagi-przyciski {
  display: flex;
  flex-wrap: wrap;
  gap: var(--odst-2, 0.5rem);
  justify-content: flex-end;
}

/* ==========================================================================
   OKNO PODPOWIEDZI IZZIEGO (27.10.2026)
   Właściciel: „okno Popraw decyzje / Przelicz mimo to ma być we WSZYSTKICH
   grach, także wieloosobowych”. Wygląd spójny z potwierdzeniami w saloonie:
   pergaminowa karta, dwa przyciski, przygaszone tło.
   ========================================================================== */
.izzi-okno-tlo {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--odst-4, 1rem);
  background: rgba(29, 21, 12, 0.45);
}

.izzi-okno {
  width: min(28rem, 100%);
  padding: var(--odst-4, 1rem);
  border: 2px solid var(--linia-mocna);
  border-radius: var(--promien-m);
  background: var(--tlo-papier);
  box-shadow: var(--cien-3);
  display: flex;
  flex-direction: column;
  gap: var(--odst-3, 0.75rem);
}

.izzi-okno-tytul {
  margin: 0;
  font-weight: 700;
}

/* SZYBKIE TEKSTY Z AI W SALOONIE GŁÓWNYM (28.10.2026).
 *
 * Właściciel: „pod polem 3 przyciski-pigułki (ten sam styl co szybkie teksty
 * w saloonie gry), kliknięcie wstawia tekst do pola i nic nie wysyła”.
 * Pigułki są drobne i zawijają się w wiersze — na telefonie trzy teksty
 * po 60 znaków nie zmieszczą się w jednej linii.
 */
.saloon-szybkie {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.4rem 0 0;
}

.saloon-szybki-tekst {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--linia-mocna, #7a5a33);
  border-radius: 999px;
  background: var(--tlo-papier-ciemny, #efe2c8);
  color: var(--tekst, #2b2118);
  font-family: inherit;
  font-size: 0.78rem;
  line-height: 1.3;
  cursor: pointer;
  text-align: left;
}

.saloon-szybki-tekst:hover,
.saloon-szybki-tekst:focus-visible {
  background: var(--tlo-papier, #f7ecd6);
}

/* GRAFIKA IZZIEGO W OKNIE OSTRZEŻEŃ (27.10.2026).
 *
 * Właściciel: „w okienku A fajnie byłoby pokazać obrazek Izzi. może nawet
 * rotacyjnie kilka”. Zdjęcie stoi po lewej, tekst po prawej; na wąskim
 * ekranie obrazek maleje, ale nie znika (jest częścią przekazu, nie ozdobą).
 */
.izzi-okno-uklad {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--odst-3, 0.75rem);
  align-items: start;
}

.izzi-okno-obrazek {
  width: 5.5rem;
  height: auto;
  border-radius: var(--promien-s);
  object-fit: contain;
}

@media (max-width: 30rem) {
  .izzi-okno-uklad {
    grid-template-columns: minmax(0, 1fr);
  }

  .izzi-okno-obrazek {
    width: 4rem;
  }
}

.izzi-okno-lista {
  margin: 0;
  padding-left: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: var(--odst-2, 0.5rem);
  font-size: var(--rozmiar-s, 0.9rem);
}

.izzi-okno-przyciski {
  display: flex;
  gap: var(--odst-2, 0.5rem);
  justify-content: flex-end;
  flex-wrap: wrap;
}


/* Radio płci w jednym wierszu, komunikat pod spodem (28.10.2026). */
.profil-plec {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

/* „O MNIE" W PROFILU (schemat 69, 29.10.2026). */
.profil-o-mnie {
  width: 100%;
  min-height: 6rem;
  resize: vertical;
}

.profil-licznik {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--kolor-tekst-mutowany, #6b5a45);
  text-align: right;
}

.profil-o-mnie-akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

/* PUBLICZNY PROFIL GRACZA — okno (schemat 69, 29.10.2026). */
body.profil-gracza-blokada {
  overflow: hidden;
}

.profil-gracza-tlo {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 1rem;
  padding-top: max(1rem, env(safe-area-inset-top));
  overflow-y: auto;
  background: rgba(30, 20, 12, 0.55);
}

.profil-gracza-okno {
  position: relative;
  width: min(34rem, 100%);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: 1.25rem;
  border-radius: 0.75rem;
  background: var(--kolor-papier, #f5ead2);
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.35);
}

.profil-gracza-x {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 2.25rem;
  height: 2.25rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: inherit;
}

.profil-gracza-x:hover,
.profil-gracza-x:focus-visible {
  background: rgba(92, 63, 33, 0.12);
}

.profil-gracza-tytul {
  margin: 0 2.5rem 0.75rem 0;
  font-size: 1.35rem;
}

.profil-gracza-dane {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 1rem;
  margin: 0 0 1rem;
}

.profil-gracza-dane dt {
  font-weight: 700;
}

.profil-gracza-dane dd {
  margin: 0;
}

.profil-gracza-podtytul {
  margin: 1rem 0 0.35rem;
  font-size: 1.05rem;
}

.profil-gracza-omnie p {
  margin: 0 0 0.5rem;
  overflow-wrap: anywhere;
}

.profil-gracza-omnie a {
  overflow-wrap: anywhere;
}

.profil-gracza-pusto,
.profil-gracza-blad,
.profil-gracza-ladowanie {
  margin: 0.5rem 0;
  color: var(--kolor-tekst-mutowany, #6b5a45);
}

.profil-gracza-blad {
  color: #8a1f1f;
}

.profil-gracza-osiagniecia {
  margin-top: 0.5rem;
}

/* Na małym ekranie okno zajmuje całą szerokość i ma wygodne marginesy. */
@media (max-width: 480px) {
  .profil-gracza-tlo {
    padding: 0.5rem;
  }

  .profil-gracza-okno {
    max-height: calc(100dvh - 1rem);
    padding: 1rem;
  }
}

/* KLIKALNY AUTOR NA FORUM (schemat 69, 29.10.2026). Wygląda jak dotychczasowy
   tekst — dopiero hover pokazuje, że to link do profilu. */
.forum-autor-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
}

.forum-autor-link:hover,
.forum-autor-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* ==========================================================================
   KLIKALNE LOGINY GRACZY (29.10.2026)

   Ten sam wygląd co tekst, ale dostępny przycisk: profil gracza otwiera się
   wszędzie, gdzie pojawia się nick (arkusz, saloon, ranking, forum).
   Resetujemy wygląd przycisku, bo dziedziczy czcionkę i kolor z otoczenia.
   ========================================================================== */
.forum-autor-link,
.arkusz-login-link,
.ranking-login-link,
.ranking-mistrz-link,
.ranking-login button,
.ranking-mistrz button,
.saloon-login[data-profil-login],
.forum-ostatnie-autor[data-profil-login] {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  line-height: inherit;
  text-align: inherit;
  cursor: pointer;
  text-decoration: none;
}

.forum-autor-link:hover,
.forum-autor-link:focus-visible,
.arkusz-login-link:hover,
.arkusz-login-link:focus-visible,
.ranking-login-link:hover,
.ranking-login-link:focus-visible,
.ranking-mistrz-link:hover,
.ranking-mistrz-link:focus-visible,
.saloon-login[data-profil-login]:hover,
.saloon-login[data-profil-login]:focus-visible,
.forum-ostatnie-autor[data-profil-login]:hover,
.forum-ostatnie-autor[data-profil-login]:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.forum-autor-link:focus-visible,
.arkusz-login-link:focus-visible,
.ranking-login-link:focus-visible,
.ranking-mistrz-link:focus-visible,
.saloon-login[data-profil-login]:focus-visible,
.forum-ostatnie-autor[data-profil-login]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: 2px;
}

/* DYMKI OSIĄGNIĘĆ W PROFILU I POPUPIE (30.10.2026).
   `arkusz.css` ma własne `.pomoc--osiagniecie`, ale profil, forum i index
   nie ładują tego arkusza — bez tych reguł kafel dostałby wygląd małej
   ikonki „?” zamiast pozostać kafelkiem. Celowo tylko reset wyglądu:
   mechanizm dymka (pozycjonowanie, mysz/dotyk/klawiatura) jest wspólny. */
.pomoc--osiagniecie {
  display: block;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  font: inherit;
  color: inherit;
  cursor: help;
}
.pomoc--osiagniecie:hover,
.pomoc--osiagniecie:focus-visible {
  /* BEZ RAMKI (30.10.2026). Właściciel: „niepotrzebnie taka ramka się
     pojawia”. Kafel ma już własną ramkę karty — dodatkowy outline wyglądał
     jak drugie obramowanie wokół ikony. */
  background: none;
  color: inherit;
  outline: none;
}
