/* ============================================================ HUB — ETAP 1
   Szkielet głównego ekranu: pasek górny, menu boczne, scena, panel prawy,
   dolna nawigacja. Świat ma być W ŚRODKU, a UI dookoła niego — dlatego to
   siatka na całą wysokość okna, a nie karty układane jedna pod drugą.

   Bez scrolla strony: `100dvh` i `minmax(0, 1fr)` na wierszu sceny, żeby
   środek się kurczył zamiast rozpychać okno.                                */

:root {
  --tlo:        #0B0A12;   /* prawie czarne */
  --tlo-panel:  #12101C;
  --granat:     #171531;
  --braz:       #2A1E16;
  --fiolet:     #8B3FD9;
  --fiolet-jasny:#C77DFF;
  --zloto:      #E8B44A;
  --zloto-ciemne:#8A6520;
  --zielen:     #4FA845;
  --krem:       #E8DCC8;
  --krem-dim:   #9A8F7E;
  --linia:      #2E2740;
  --linia-jasna:#4A3F63;

  --h-top: 76px;
  --w-menu: 200px;
  --w-prawy: 390px;
  --h-dol: 150px;
}

* { box-sizing: border-box; }

/* `[hidden]` MUSI WYGRAĆ Z `display` Z KLASY.
   Atrybut `hidden` to tylko `display: none` ze stylu przeglądarki, więc
   klasa ekranu ustawiająca `display: grid` go biła — schowany ekran dalej
   się układał i targ nakładał się na kopalnię. Jedna reguła zamiast
   pilnowania tego w każdej klasie ekranu z osobna. */
[hidden] { display: none !important; }

html, body {
  margin: 0; height: 100%;
  background: var(--tlo);
  color: var(--krem);
  font-family: "Trebuchet MS", "Segoe UI", sans-serif;
  /* PIXEL ART NIE MOŻE BYĆ ROZMYWANY — to reguła całego ekranu, nie wyjątek. */
  image-rendering: pixelated;
  overflow: hidden;
}
img, canvas { image-rendering: pixelated; }

/* Portal składa się z dwóch płócien. `hubPortal` trzyma kamienny pierścień,
   a pełnoekranowa aura pozwala pikselom, światłu i odłamkom naprawdę wyjść
   poza jego kwadrat. Warstwa niczego nie klika i tylko dodaje światło. */
#portalAura {
  position: fixed; inset: 0; z-index: 38;
  width: 100%; height: 100%; pointer-events: none;
  mix-blend-mode: screen;
  image-rendering: pixelated; image-rendering: crisp-edges;
}

#hubPortal {
  filter: drop-shadow(0 0 24px color-mix(in srgb, var(--aura-portalu, #6E7A94) 42%, transparent));
}

@keyframes wstrzas {
  0%, 100% { transform: translate(0, 0); }
  12% { transform: translate(-3px, 2px); }
  26% { transform: translate(3px, -2px); }
  40% { transform: translate(-2px, -1px); }
  56% { transform: translate(2px, 1px); }
  72% { transform: translate(-1px, 1px); }
}
@keyframes wstrzas-mocny {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-6px, 4px); }
  22% { transform: translate(6px, -4px); }
  36% { transform: translate(-5px, -3px); }
  50% { transform: translate(4px, 3px); }
  66% { transform: translate(-3px, 2px); }
  82% { transform: translate(2px, -1px); }
}
#hub.wstrzas { animation: wstrzas .22s ease-out; }
#hub.wstrzas-mocny { animation: wstrzas-mocny .30s ease-out; }

.bialy-flash {
  position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: #fff; opacity: 0; mix-blend-mode: screen;
}
.bialy-flash.gra { animation: bialy-flash .42s cubic-bezier(.1,.8,.2,1) forwards; }
@keyframes bialy-flash {
  0% { opacity: 0; }
  4% { opacity: .95; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  #hub.wstrzas, #hub.wstrzas-mocny { animation: none; }
  .bialy-flash { display: none; }
}

/* --------------------------------------------------------------- SIATKA
   Menu trzyma całą wysokość (logo u góry, stopka na dole). Pasek górny idzie
   nad sceną I nad panelem prawym. Dolna nawigacja siedzi TYLKO pod sceną,
   bo to nawigacja świata, a nie pasek stanu aplikacji. */
#hub {
  display: grid;
  grid-template-columns: var(--w-menu) minmax(0, 1fr) var(--w-prawy);
  grid-template-rows: var(--h-top) minmax(0, 1fr) var(--h-dol);
  grid-template-areas:
    "menu  top    top"
    "menu  scena  prawy"
    "menu  dol    dol";
  /* DWIE WYSOKOŚCI, NIE JEDNA. `dvh` zna dopiero WebView 108 (koniec 2022);
     starszy odrzuca całą deklarację jako nieznaną i siatka zostaje BEZ
     wysokości, czyli układ się składa. Wcześniejsze `vh` łapie taki WebView,
     nowszy i tak nadpisze je linijkę niżej. */
  height: 100vh;
  height: 100dvh;
  gap: 8px;
  padding: 8px;
}

/* Ramka pixel-artowa: dwie krawędzie zamiast cienia. Cień rozmywa piksele,
   a ostra linia trzyma styl. */
.ramka {
  background: linear-gradient(180deg, var(--tlo-panel), #0D0B15);
  border: 2px solid var(--linia);
  box-shadow: inset 0 0 0 1px rgba(232, 180, 74, .06);
}

/* ------------------------------------------------------------ PASEK GÓRNY */
#hubTop {
  grid-area: top;
  display: flex; align-items: center; gap: 14px;
  padding: 0 14px;
  background:
    radial-gradient(circle at 48% 120%, rgba(105,62,170,.16), transparent 45%),
    linear-gradient(180deg, rgba(20,17,34,.91), rgba(9,8,17,.82));
  border-color: rgba(86,72,112,.62);
  box-shadow: inset 0 -1px 0 rgba(232,180,74,.10), 0 5px 20px rgba(0,0,0,.24);
  backdrop-filter: blur(7px);
}

.dusza { display: flex; align-items: center; gap: 10px; min-width: 240px; }
.dusza-awatar {
  width: 52px; height: 52px; flex: 0 0 auto;
  border: 2px solid var(--zloto-ciemne);
  background: radial-gradient(circle at 50% 40%, #3A2358, #140F22);
  display: grid; place-items: center;
  font-size: 26px;
  color: inherit; cursor: pointer;
}
.dusza-awatar:hover { border-color: var(--zloto); }

/* ======================================================= PROFIL GRACZA */
.scena-profil {
  position: relative; min-height: 0; overflow: auto; padding: 22px;
  background:
    radial-gradient(circle at 15% 15%, rgba(139,63,217,.18), transparent 30%),
    linear-gradient(145deg, #12101C, #0B0A12 72%);
}
body.profil-otwarty #scenaKonto { grid-column: 2 / 4; grid-row: 2 / 4; z-index: 45; }
body.profil-otwarty #hubPrawy, body.profil-otwarty #hubDol { display: none; }
#scenaKonto > .wroc-do-miasta { display: none; }
.profil-gracza-gora { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; padding-bottom: 18px; border-bottom: 1px solid var(--linia); }
.profil-gracza-kicker { color: var(--zloto); font-size: 8px; letter-spacing: .2em; }
.profil-gracza-gora h2 { margin: 6px 0 4px; font-size: 25px; color: var(--krem); letter-spacing: .06em; }
.profil-gracza-gora p { margin: 0; color: var(--krem-dim); font-size: 10px; }
.profil-poziom-karta { min-width: 150px; display: grid; justify-items: end; padding: 10px 12px; border: 1px solid rgba(232,180,74,.4); background: rgba(232,180,74,.06); }
.profil-poziom-karta small { color: var(--krem-dim); font-size: 7px; letter-spacing: .14em; }
.profil-poziom-karta strong { color: var(--zloto); font-size: 29px; line-height: 1.1; }
.profil-poziom-karta span { color: var(--krem); font-size: 8px; }
.profil-gracza-siatka { display: grid; grid-template-columns: minmax(260px,.9fr) minmax(280px,1.1fr); gap: 12px; margin-top: 14px; }
.profil-sekcja { padding: 14px; border: 1px solid #3A3150; background: rgba(15,13,25,.85); }
.profil-sekcja h3 { margin: 0 0 12px; padding-bottom: 7px; color: var(--zloto); font-size: 9px; letter-spacing: .15em; border-bottom: 1px solid var(--linia); }
.profil-tozsamosc { grid-row: span 2; display: grid; align-content: start; gap: 10px; }
.profil-duzy-avatar { width: 96px; height: 96px; display: grid; place-items: center; justify-self: center; font-size: 48px; border: 2px solid var(--zloto-ciemne); background: radial-gradient(circle, #332050, #0C0A14 72%); box-shadow: 0 0 28px rgba(139,63,217,.22); }
.profil-sekcja label { display: grid; gap: 5px; color: var(--krem-dim); font-size: 8px; letter-spacing: .09em; }
.profil-sekcja input[type="text"], .profil-sekcja input:not([type]) { width: 100%; padding: 9px; border: 1px solid var(--linia-jasna); outline: 0; background: #0C0A14; color: var(--krem); font: inherit; font-size: 11px; }
.profil-sekcja input:focus { border-color: var(--zloto); }
.profil-tozsamosc > small { color: #776E89; font-size: 8px; letter-spacing: .1em; }
.profil-avatary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.profil-avatar-opcja { height: 44px; display: grid; place-items: center; padding: 0; color: inherit; font-size: 22px; cursor: pointer; border: 1px solid var(--linia); background: #151121; }
.profil-avatar-opcja:hover { border-color: var(--fiolet-jasny); }
.profil-avatar-opcja[aria-pressed="true"] { border-color: var(--zloto); background: rgba(232,180,74,.12); box-shadow: inset 0 0 0 1px rgba(232,180,74,.18); }
.profil-suwak { margin: 13px 0; }
.profil-suwak span { display: flex; justify-content: space-between; }
.profil-suwak b { color: var(--zloto); }
.profil-suwak input { accent-color: var(--zloto); width: 100%; }
.profil-przelacznik { grid-template-columns: 18px 1fr !important; align-items: center; margin: 10px 0; color: var(--krem) !important; line-height: 1.35; }
.profil-przelacznik input { width: 16px; height: 16px; accent-color: var(--zloto); }
.profil-gra p { margin: 12px 0 0; color: var(--krem-dim); font-size: 8px; line-height: 1.5; }
.profil-konto-info > div { display: flex; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid #282138; color: var(--krem-dim); font-size: 8px; }
.profil-konto-info b { color: var(--krem); }
.profil-konto-info a { display: block; margin-top: 12px; padding: 8px; text-align: center; color: var(--zloto); border: 1px solid var(--zloto-ciemne); text-decoration: none; font-size: 8px; }
.profil-bezpieczenstwo { grid-column: 1 / -1; }
.profil-haslo-pola { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.profil-haslo-pola input { width: 100%; box-sizing: border-box; padding: 9px; border: 1px solid var(--linia-jasna); outline: 0; background: #0C0A14; color: var(--krem); font: inherit; }
.profil-haslo-dol { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; }
.profil-haslo-dol span { color: var(--krem-dim); font-size: 8px; }
.profil-haslo-dol button { padding: 8px 12px; color: var(--zloto); background: #151126; border: 1px solid var(--zloto-ciemne); font: inherit; font-size: 8px; cursor: pointer; }
.profil-haslo-dol button:disabled { opacity: .45; cursor: default; }
.profil-haslo-akcje { display: flex; gap: 8px; }
.profil-haslo-dol .profil-reset-test { color: #FF948A; border-color: #883E45; background: rgba(91,25,34,.28); }
.profil-akcje { position: sticky; z-index: 5; bottom: -22px; display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin: 14px -22px -22px; padding: 12px 22px; border-top: 1px solid var(--linia); background: rgba(11,10,18,.97); }
.profil-akcje span { margin-right: auto; color: var(--krem-dim); font-size: 9px; }
.profil-akcje button { padding: 10px 18px; color: #17100A; border: 1px solid #F2CA69; background: linear-gradient(#F0C35D,#D79A32); font: inherit; font-size: 9px; letter-spacing: .1em; cursor: pointer; }
.profil-akcje button:disabled { opacity: .45; cursor: default; }
@media (max-width: 920px) {
  .profil-gracza-siatka { grid-template-columns: 1fr; }
  .profil-tozsamosc { grid-row: auto; }
}
.dusza-opis { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dusza-nazwa { font-size: 15px; letter-spacing: .04em; color: var(--krem); }
.dusza-poziom { font-size: 11px; color: var(--krem-dim); }
.xp-pasek {
  width: 150px; height: 7px;
  background: #241D33; border: 1px solid var(--linia-jasna);
}
.xp-pasek i { display: block; height: 100%; background: linear-gradient(90deg, var(--zloto-ciemne), var(--zloto)); }

/* ZASOBY. Ikona i wartość — licznik bez ikony po sekundzie przestaje cokolwiek
   znaczyć, bo gracz nie czyta etykiet, tylko rozpoznaje kształty. */
.zasoby { display: flex; align-items: center; gap: 11px; margin: 0 auto; }
.zasob {
  --zasob-rgb: 232,180,74;
  position: relative; isolation: isolate; overflow: hidden;
  min-width: 128px; height: 48px;
  display: flex; align-items: center; gap: 9px;
  padding: 5px 14px 5px 8px;
  background:
    linear-gradient(105deg, rgba(var(--zasob-rgb),.15), rgba(15,12,27,.64) 46%, rgba(8,7,15,.80));
  border: 1px solid rgba(var(--zasob-rgb),.42);
  clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px);
  box-shadow: inset 0 0 18px rgba(var(--zasob-rgb),.08);
}
.zasob--diamenty { --zasob-rgb: 79,169,255; }
.zasob::after {
  content: attr(data-symbol); position: absolute; z-index: -1;
  right: 6px; top: -13px; color: rgba(var(--zasob-rgb),.09);
  font-size: 55px; line-height: 1; transform: rotate(-8deg);
}
.zasob::before {
  content: attr(data-label); position: absolute; left: 51px; top: 7px;
  color: rgba(var(--zasob-rgb),.82); font-size: 7px; letter-spacing: .16em;
}
.zasob-ikona {
  width: 34px; height: 34px; flex: 0 0 auto;
  display: grid; place-items: center; font-size: 20px; line-height: 1;
  background: radial-gradient(circle, rgba(var(--zasob-rgb),.22), rgba(var(--zasob-rgb),.03) 68%);
  border: 1px solid rgba(var(--zasob-rgb),.36);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  filter: drop-shadow(0 0 7px rgba(var(--zasob-rgb),.45));
}
.zasob-ile {
  min-width: 54px; padding-top: 11px;
  font-size: 15px; color: #F2ECDF; letter-spacing: .03em;
  text-shadow: 0 0 10px rgba(var(--zasob-rgb),.42);
}
.zasob-plus {
  display: none; /* przycisk sklepu wróci dopiero razem z działającym zakupem */
}

/* Stan świata to nie trzecia waluta. Trzy krótkie, żywe odczyty mówią od razu,
   czy profesje pracują i czy jest przepustka do lochu. */
.stan-swiata { display: flex; height: 48px; border: 1px solid var(--linia); background: rgba(10,8,18,.62); }
.stan-swiata-kafelek {
  min-width: 70px; padding: 4px 7px; display: grid; grid-template-columns: 18px auto; grid-template-rows: 15px 18px;
  column-gap: 5px; align-items: center; color: var(--krem); background: transparent; border: 0; border-right: 1px solid var(--linia); font: inherit; text-align: left; cursor: pointer;
}
.stan-swiata-kafelek:last-child { border-right: 0; }
.stan-swiata-kafelek > span { grid-row: 1 / 3; font-size: 16px; filter: drop-shadow(0 0 5px rgba(124,193,255,.45)); }
.stan-swiata-kafelek small { color: var(--krem-dim); font-size: 7px; letter-spacing: .08em; }
.stan-swiata-kafelek b { color: #EDE3D4; font-size: 13px; letter-spacing: .04em; }
.stan-swiata-kafelek:hover { background: rgba(112,68,164,.20); }
.stan-swiata-kafelek:hover b { color: var(--zloto); }
.stan-swiata-kafelek--klucze > span { filter: drop-shadow(0 0 5px rgba(235,180,74,.55)); }

.narzedzia { display: flex; align-items: center; gap: 6px; }
.narzedzie {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: #0E0C18; border: 2px solid var(--linia);
  color: var(--krem-dim); font-size: 17px; cursor: pointer;
  position: relative;
}
.narzedzie:hover { border-color: var(--linia-jasna); color: var(--krem); }
.narzedzie[data-znacznik]::after {
  content: attr(data-znacznik);
  position: absolute; top: -6px; right: -6px;
  min-width: 16px; height: 16px; padding: 0 3px;
  background: #C0392B; border: 1px solid #0B0A12;
  color: #fff; font-size: 10px; line-height: 14px; text-align: center;
}

/* ------------------------------------------------------------ MENU BOCZNE */
#hubMenu {
  grid-area: menu;
  display: flex; flex-direction: column;
  padding: 0; overflow: hidden;
}

.marka {
  padding: 14px 12px 12px;
  text-align: center;
  border-bottom: 2px solid var(--linia);
}
.marka-tytul {
  margin: 0; font-size: 21px; letter-spacing: .10em;
  color: var(--zloto);
  text-shadow: 0 2px 0 #000;
}
.marka-pod {
  margin: 2px 0 0; font-size: 11px; letter-spacing: .42em; text-indent: .42em;
  color: var(--krem-dim);
}

.menu-lista {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 6px;
  scrollbar-width: thin;
}

/* POZYCJA MENU TO ELEMENT GRY, NIE WIERSZ TABELI. Aktywna dostaje fioletowy
   blok, złotą krawędź i strzałkę — ma być widać z drugiego końca pokoju. */
.menu-poz {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px;
  background: none; border: 2px solid transparent;
  color: var(--krem-dim); font-size: 13px; letter-spacing: .06em;
  text-align: left; cursor: pointer;
  font-family: inherit;
}
.menu-poz:hover { background: #16132A; color: var(--krem); }
.menu-poz-ikona { font-size: 17px; width: 22px; text-align: center; }
.menu-poz[aria-current="page"] {
  background: linear-gradient(90deg, #3A1D66, #24123F);
  border-color: var(--fiolet);
  color: var(--krem);
  position: relative;
}
.menu-poz[aria-current="page"]::after {
  content: "";
  position: absolute; right: -2px; top: 50%; transform: translateY(-50%);
  border: 7px solid transparent; border-right-color: var(--fiolet-jasny);
}

.menu-stopka {
  padding: 8px; border-top: 2px solid var(--linia);
  display: flex; flex-direction: column; gap: 6px;
}
.menu-link {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px;
  background: #12172E; border: 2px solid #253154;
  color: #8FA4D8; font-size: 12px; cursor: pointer;
  font-family: inherit;
}
.menu-wersja { text-align: center; font-size: 10px; color: #5A5268; }

/* ------------------------------------------- SCENA, PANEL PRAWY, DÓŁ
   Na tym etapie to PUSTE POJEMNIKI — treść wchodzi w kolejnych krokach.
   Stoją tu po to, żeby sprawdzić proporcje na 16:9, zanim cokolwiek w nie
   wleci. */
#hubScena {
  grid-area: scena;
  position: relative; overflow: hidden;
}
#scenaPlotno { display: block; width: 100%; height: 100%; }

/* MIEJSCE NA PORTAL. `PortalArt` sam przycina swój canvas do całkowitej
   wielokrotności siatki 160×160, więc dostaje pudełko, a nie sztywny rozmiar —
   wpasuje się w nie tak, żeby piksel został kwadratem.

   Portal stoi w GÓRNEJ POŁOWIE sceny i jest jednym z największych elementów
   ekranu; `pointer-events: none` na pudełku, bo klikalny ma być sam portal. */
.portal-miejsce {
  /* WYŻEJ I MNIEJ — brama ma stać DALEJ. Na rzucie z góry odległość robi się
     pozycją w kadrze i rozmiarem, nie perspektywą. */
  /* WIĘKSZY. `PortalArt` przycina bufor do wielokrotności 160, więc rozmiar
     skacze co 160 px — pudełko musi mieć zapas, żeby złapać następny stopień
     (480 zamiast 320). */
  /* `top` USTAWIA SKRYPT — dół pierścienia musi wylądować na linii trawy,
     a rozmiar canvasu skacze co 160 px, więc w CSS nie da się tego policzyć. */
  position: absolute; left: 52%; top: 0;
  transform: translateX(-50%);
  width: min(52%, 72vh); aspect-ratio: 1;
  display: grid; place-items: center;
  pointer-events: none;
}
/* Canvas MUSI mieć rozmiar z CSS. Bez tego `dopasuj()` mierzy jego domyślne
   300×150 zamiast pudełka i zawsze wychodzi skala 1 — portal był cztery razy
   za mały. `PortalArt` i tak nadpisze to swoim snapem do siatki. */
#hubPortal {
  display: block; width: 100%; height: 100%;
  cursor: pointer; pointer-events: auto;
}

/* KULKI PRZY OGNISKU. Warstwa nie łapie kliknięć — łapią je same kulki,
   więc klikanie w pustą scenę dalej należy do sceny. */
.kulki-warstwa {
  position: absolute; inset: 0;
  pointer-events: none;
}
.kulka-hub {
  position: absolute;
  image-rendering: pixelated;
  pointer-events: auto; cursor: pointer;
  /* IDLE: kulka oddycha. Ruch jest CELOWO drobny — przy większym sześć kulek
     skacze jak sprężyny i scena przestaje być czytelna. */
  animation: kulka-oddech 3.4s ease-in-out infinite;
  filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .5));
}
.kulka-hub:hover { filter: drop-shadow(0 0 4px var(--fiolet-jasny)); }

/* ATAK BEZ KLATEK ATAKU. Kulki z sekwencją PNG puszczają prawdziwą animację
   `strzal`; GIF-owe jej nie mają, więc dostają krótki WYPAD do przodu.
   `steps()` trzyma ruch skokowy — płynny wyglądałby obco przy pixel arcie. */
.kulka-hub.kulka-atak {
  animation: kulka-atak .42s steps(3) 1;
}
@keyframes kulka-atak {
  0%   { transform: translateY(0) scale(var(--kier, 1), 1); }
  35%  { transform: translateY(-5px) scale(calc(var(--kier, 1) * 1.12), 1.12); }
  70%  { transform: translateY(2px) scale(calc(var(--kier, 1) * 0.94), 0.94); }
  100% { transform: translateY(0) scale(var(--kier, 1), 1); }
}

/* KIERUNEK PATRZENIA SIEDZI W ZMIENNEJ, NIE W OSOBNEJ REGULE.
   Sprite'y są narysowane twarzą w prawo, więc kulki z prawej połowy kręgu
   trzeba odbić, żeby patrzyły na podest. Odbicie MUSI wejść do klatek
   kluczowych — `animation` nadpisuje `transform`, więc osobna reguła
   `scaleX(-1)` przegrywała z oddechem i nic nie robiła. */
@keyframes kulka-oddech {
  0%, 100% { transform: translateY(0) scale(var(--kier, 1), 1); }
  50%      { transform: translateY(-2px) scale(var(--kier, 1), 1.03); }
}
@media (prefers-reduced-motion: reduce) {
  .kulka-hub { animation: none; }
}

/* ŚWIEŻO PRZYWOŁANA KULKA NA PODEŚCIE.
   Leży nad ekipą, bo to ona jest w tej chwili treścią ekranu. Warstwa nie
   łapie kliknięć — podest ma być pokazem, nie kolejnym przyciskiem. */
.podest-warstwa { position: absolute; inset: 0; pointer-events: none; z-index: 25; }

.kulka-nowa {
  position: absolute;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 10px rgba(199, 125, 255, .75));
  /* WEJŚCIE: z niczego, przez przeskalowanie, do spoczynku. `steps()` trzyma
     ruch skokowy — płynne narastanie wygląda obco przy pixel arcie. */
  animation: nowa-wejscie .5s steps(5) 1;
}
@keyframes nowa-wejscie {
  0%   { opacity: 0; transform: translateY(-14px) scale(.35); }
  60%  { opacity: 1; transform: translateY(0) scale(1.14); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.nowa-etykieta {
  position: absolute; transform: translateX(-50%);
  padding: 3px 9px;
  background: rgba(10, 8, 18, .88);
  border: 1px solid;
  font-size: 10px; letter-spacing: .12em; white-space: nowrap;
  animation: nowa-etykieta-wejscie .5s ease-out 1;
}
@keyframes nowa-etykieta-wejscie {
  0%   { opacity: 0; transform: translateX(-50%) translateY(-5px); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .kulka-nowa, .nowa-etykieta { animation: none; }
}

/* PRZYCISK PRZYWOŁANIA. Największa akcja ekranu, więc wygląda jak przedmiot
   ze świata, nie jak przycisk formularza: kamienna ramka, złoty tekst,
   pulsujący blask od portalu. */
/* LEWA KOLUMNA STEROWANIA: panel szans + przyciski przywołania, jedno pod
   drugim. Wspólny kontener zamiast dwóch bytów przypiętych osobno do rogów —
   przy zmianie wysokości panelu przyciski nie muszą nic wiedzieć. */
.lewa-kolumna {
  position: absolute; top: 10px; left: 10px;
  z-index: 30; width: 214px;
  display: flex; flex-direction: column; gap: 8px;
}
.summon-pasek { display: flex; flex-direction: column; gap: 7px; }

/* Pierwsze trzy przywołania są całym onboardingiem. Karta siedzi pod portalem,
   prowadzi jedną akcją i znika dopiero po wysłaniu gotowej drużyny w trasę. */
.tutorial-portalu {
  position: absolute; z-index: 42; left: 50%; bottom: 24px;
  width: min(430px, calc(100% - 40px)); transform: translateX(-50%);
  display: grid; justify-items: center; gap: 8px; padding: 16px 18px;
  text-align: center; background: linear-gradient(145deg, rgba(12,9,22,.97), rgba(31,18,53,.96));
  border: 2px solid var(--zloto); box-shadow: 0 12px 36px rgba(0,0,0,.6), 0 0 28px rgba(139,63,217,.28);
}

.tutorial-portalu[hidden] { display: none; }
.tutorial-kicker { color: var(--zloto); font-size: 8px; letter-spacing: .2em; }
.tutorial-portalu h2 { margin: 0; color: var(--krem); font-size: 18px; letter-spacing: .08em; }
.tutorial-portalu p { max-width: 360px; margin: 0; color: var(--krem-dim); font-size: 10px; line-height: 1.5; }
.tutorial-kroki { display: flex; align-items: center; gap: 18px; margin: 2px 0; }
.tutorial-kroki[hidden] { display: none; }
.tutorial-krok { width: 22px; height: 22px; display: grid; place-items: center; position: relative; border: 1px solid var(--linia-jasna); border-radius: 50%; color: var(--krem-dim); font-style: normal; font-size: 8px; background: #151022; }
.tutorial-krok + .tutorial-krok::before { content: ''; position: absolute; right: 100%; top: 50%; width: 18px; border-top: 1px solid var(--linia); }
.tutorial-krok--gotowy { border-color: #79C97F; color: #9BE39F; background: rgba(67,135,72,.18); }
#tutorialAkcja { min-width: 270px; padding: 10px 14px; border: 2px solid var(--zloto); background: linear-gradient(180deg, #3A2861, #241640); color: var(--zloto); font: inherit; font-size: 10px; letter-spacing: .12em; cursor: pointer; animation: summon-tetno 2.6s ease-in-out infinite; }
#tutorialAkcja:disabled { opacity: .55; animation: none; cursor: default; }
body:not(.tutorial-aktywny) .tutorial-portalu:not([hidden]) { border-color: #79C97F; }
body:not(.tutorial-aktywny) #tutorialAkcja { border-color: #79C97F; color: #B9E9AD; animation: none; }
body:not(.tutorial-aktywny) .tutorial-kicker { color: #9BE39F; }
body:not(.tutorial-aktywny) .tutorial-portalu:not([hidden]) .tutorial-krok { border-color: #79C97F; color: #9BE39F; }

body.tutorial-widoczny .lewa-kolumna { display: none; }
body.tutorial-prolog #hubScena::after {
  content: ''; position: absolute; z-index: 35; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 42%, transparent 8%, rgba(4,3,11,.28) 48%, rgba(4,3,11,.76) 100%);
}
body.tutorial-prolog .tutorial-portalu { z-index: 44; border-color: #75618E; box-shadow: 0 16px 55px rgba(0,0,0,.8); }
body.tutorial-prolog #tutorialAkcja { border-color: #8D79A8; color: #D8C9EA; animation: none; }
body.tutorial-aktywny #hubPrawy,
body.tutorial-aktywny #hubDol,
body.tutorial-aktywny .zasoby,
body.tutorial-aktywny .narzedzia { opacity: .22; pointer-events: none; }
.menu-poz.ekran-zablokowany, .miasto-skrot.ekran-zablokowany {
  opacity: .26; filter: grayscale(1); cursor: not-allowed;
}
.menu-poz.ekran-zablokowany::before { content: '🔒'; position: absolute; right: 8px; font-size: 8px; }

.btn-summon {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px;
  font-family: inherit; font-size: 13px; letter-spacing: .10em;
  color: var(--zloto); cursor: pointer;
  background: linear-gradient(180deg, #2A1D48, #1A1130);
  border: 2px solid var(--zloto-ciemne);
  box-shadow: 0 0 18px rgba(139, 63, 217, .45), inset 0 1px 0 rgba(232, 180, 74, .18);
  animation: summon-tetno 2.6s ease-in-out infinite;
}
.btn-summon:hover {
  border-color: var(--zloto);
  background: linear-gradient(180deg, #3A2861, #241640);
}
.btn-summon:active { transform: translateY(2px); }
.btn-summon:disabled { opacity: .55; cursor: default; animation: none; }

/* DZIESIĄTKA JEST WAŻNIEJSZYM PRZYCISKIEM — fioletowa ramka odróżnia ją od
   pojedynczego przywołania bez dokładania trzeciego koloru do ekranu. */
.btn-summon--x10 { border-color: var(--fiolet); }
.btn-summon--x10:hover { border-color: var(--fiolet-jasny); }

/* NIE STAĆ CIĘ. Gaśnie i przestaje pulsować, ale zostaje klikalny wizualnie —
   blokadę trzyma kod, żeby stan „brak diamentów" nie zależał od samego CSS. */
.btn-summon--bez-stac { opacity: .45; animation: none; filter: grayscale(.6); }
.btn-summon-glif { font-size: 17px; color: var(--fiolet-jasny); }
.btn-summon-koszt {
  margin-left: auto;                  /* koszt zawsze przy prawej krawędzi */
  font-size: 11px; letter-spacing: .02em;
  color: var(--krem-dim);
  padding-left: 9px; border-left: 1px solid var(--linia-jasna);
}

@keyframes summon-tetno {
  0%, 100% { box-shadow: 0 0 14px rgba(139, 63, 217, .35), inset 0 1px 0 rgba(232, 180, 74, .18); }
  50%      { box-shadow: 0 0 26px rgba(199, 125, 255, .60), inset 0 1px 0 rgba(232, 180, 74, .18); }
}
@media (prefers-reduced-motion: reduce) { .btn-summon { animation: none; } }

/* PANEL PORTALU LEŻY NA ŚWIECIE, NIE OBOK NIEGO.
   Wisi w rogu sceny, żeby nie zasłaniać bramy — spec mówi wprost: obok
   portalu, nie na nim. */
.portal-info {
  /* Pozycję trzyma `.lewa-kolumna` — panel jest tylko jej pierwszym wierszem. */
  padding: 9px 10px;
  background: rgba(12, 10, 22, .82);
  border: 2px solid var(--linia);
}
.pi-naglowek {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; letter-spacing: .10em; color: var(--krem-dim);
}
.pi-znak {
  width: 15px; height: 15px; flex: 0 0 auto;
  background: #1B1730; border: 1px solid var(--linia-jasna);
  color: var(--krem-dim); font-size: 9px; line-height: 1; cursor: pointer;
}
.pi-procent { margin: 3px 0 4px; font-size: 19px; color: var(--zloto); letter-spacing: .02em; }
.pi-pity { margin: 7px 0 3px; font-size: 10px; letter-spacing: .08em; color: var(--krem-dim); }
.pi-pasek { height: 6px; background: #241D33; border: 1px solid var(--linia-jasna); }
.pi-pasek i { display: block; height: 100%; background: var(--fiolet); }
.pi-pasek--szansa i { background: linear-gradient(90deg, #C4531C, var(--zloto)); }
.pi-btn {
  width: 100%; margin-top: 9px; padding: 7px;
  background: #1B1730; border: 2px solid var(--linia-jasna);
  color: var(--krem); font-size: 11px; letter-spacing: .12em; cursor: pointer;
  font-family: inherit;
}
.pi-btn:hover { border-color: var(--fiolet); color: var(--fiolet-jasny); }
#hubPrawy {
  grid-area: prawy;
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px;
  /* Panel skrócił się, odkąd dok drużyny przestał dzielić z nim kolumnę
     i zajął pełną szerokość na dole — bez przewijania treść, która wcześniej
     ledwo się mieściła na pełną wysokość, zaczęłaby się ucinać u dołu. */
  overflow-x: hidden; overflow-y: auto;
}
#hubDol {
  grid-area: dol;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 10px;
}

/* Znacznik miejsca — widać podział, ale nic nie udaje gotowej treści. */

/* ZAKŁADKI TELEFONU. Poza siatką na desktopie — bez `display:none` tu,
   element bez `grid-area` trafiłby do niejawnej siatki i dołożył pusty
   wiersz pod spodem. Treść i pozycja przychodzą wyłącznie z media query
   prawdziwego telefonu niżej w tym pliku. */
#hubTabyTelefonu { display: none; }

/* Znacznik miejsca — widać podział, ale nic nie udaje gotowej treści. */
.zaslepka {
  color: #453D5A; font-size: 12px; letter-spacing: .24em;
  border: 2px dashed #2A2440; padding: 14px 18px;
}

/* --------------------------------------------------------------- WĄSKO
   Poniżej 1280 px kolumny boczne zjadają scenę — oddajemy im szerokość,
   bo to scena jest treścią, a nie panele. */
@media (max-width: 1280px) {
  :root { --w-menu: 168px; --w-prawy: 320px; }
  .menu-poz { font-size: 12px; padding: 8px; }
  .zasoby { gap: 6px; }
  .zasob { min-width: 112px; padding: 5px 8px; }
}

/* ============================================ TELEFON W POZIOMIE (APK)
   Cel to APK, więc realny ekran ma ~800×360 CSS px. Menu 200 px i panel
   390 px zabrałyby 590 z 800 i scena zostałaby paskiem — dlatego poniżej
   900 px MENU ZWIJA SIĘ DO IKON, a panele chudną. Układ zostaje ten sam:
   te same obszary siatki, tylko węższe.

   Wysokość ~360 px: pasek górny i dolny muszą oddać piksele scenie, bo to
   ona jest grą. Dotyk potrzebuje ~40 px celu, więc niżej nie schodzimy. */
@media (max-width: 900px), (max-height: 560px) {
  :root {
    /* 58 px kolumny daje ~46 px kwadratu dotyku — poniżej ~40 px palec zaczyna
       trafiać w sąsiada. */
    --h-top: 52px; --w-menu: 58px; --w-prawy: 250px; --h-dol: 78px;
  }
  :root { --siatka-luz: 5px; }
  #hub { gap: var(--siatka-luz); padding: var(--siatka-luz); }

  /* Menu na ikony: podpisy znikają, cel dotyku zostaje kwadratowy. */
  .marka { padding: 6px 2px; }
  .marka-tytul { font-size: 12px; letter-spacing: .02em; }
  .marka-pod { display: none; }
  .menu-lista { padding: 4px 2px; gap: 3px; }
  .menu-poz {
    justify-content: center; gap: 0; padding: 9px 0;
    font-size: 0; letter-spacing: 0;
    min-height: 44px;
  }
  .menu-poz-ikona { font-size: 19px; width: auto; }
  .menu-poz[aria-current="page"]::after { display: none; }
  .menu-stopka { padding: 4px 3px; }
  .menu-link { justify-content: center; font-size: 0; gap: 0; padding: 7px 0; }
  .menu-link::first-letter { font-size: 15px; }
  .menu-wersja { display: none; }

  /* Pasek górny: awatar mniejszy, zasoby ciaśniej, „+” wylatuje — na telefonie
     i tak otwiera się je dotknięciem licznika. */
  #hubTop { gap: 8px; padding: 0 8px; }
  .dusza { min-width: 0; gap: 7px; }
  .dusza-awatar { width: 38px; height: 38px; font-size: 19px; }
  .dusza-nazwa { font-size: 12px; }
  .dusza-poziom { font-size: 9px; }
  .xp-pasek { width: 84px; height: 5px; }
  .zasoby { gap: 5px; }
  .zasob { min-width: 72px; height: 38px; padding: 3px 6px; gap: 4px; }
  .zasob::before { left: 36px; top: 4px; font-size: 5px; }
  .zasob::after { display: none; }
  .zasob-ikona { width: 27px; height: 27px; font-size: 14px; }
  .zasob-ile { min-width: 32px; padding-top: 8px; font-size: 11px; }
  .zasob-plus { display: none; }
  .narzedzie { width: 32px; height: 32px; font-size: 14px; }

  /* Panel portalu: węższy i niższy, dalej w rogu sceny. */
  .portal-info { width: 148px; padding: 6px 7px; top: 6px; left: 6px; }
  .pi-naglowek { font-size: 8px; letter-spacing: .04em; }
  .pi-procent { font-size: 14px; margin: 2px 0 3px; }
  .pi-pity { font-size: 8px; margin: 5px 0 2px; }
  .pi-btn { padding: 6px; font-size: 9px; margin-top: 6px; }

}

/* PANELE ZNIKAJĄ TYLKO NA PRAWDZIWYM TELEFONIE, nie na wąskim oknie desktopu.
   Ten sam warunek co wyżej miał „albo" zamiast „i" — okno 874×639 (zwykłe
   przycięte okno przeglądarki, wcale nie telefon) traciło CAŁY panel POSTAĆ
   (ekwipunek, magazyn) i cały dok drużyny tylko dlatego, że szerokość spadła
   poniżej 900 px, mimo że wysokości było pod dostatkiem. Komentarz przy tej
   regule był już nieaktualny: panele przestały być zaślepkami, gdy doszły
   sloty i magazyn — i od tej pory było co pokazywać, tylko okno je ukrywało.

   Prawdziwy telefon w poziomie jest NISKI — to jedyny pewny sygnał. Szerokość
   nie jest: większe Androidy w poziomie mają CSS-owy viewport 900–950 px
   (np. 915×410), a próg 900 px zostawiał je BEZ nowego dolnego paska zakładek
   i BEZ pełnego menu — trafiały w środek, do ogólnego ścieśniania z reguły
   wyżej, które tylko zwija menu do samych ikon. Efekt: szary pasek 58 px po
   lewej zamiast bocznego menu, zamiast dolnych zakładek. Próg szerokości
   podniesiony z zapasem ponad realne telefony, żeby żaden nie wpadł w tę
   szczelinę; wysokość zostaje niska, bo to ona odróżnia telefon od zwykłego,
   przyciętego okna desktopu. */
@media (max-width: 1024px) and (max-height: 560px) {
  /* MENU BOCZNE ZNIKA CAŁKOWICIE — telefon dostaje DOLNY PASEK ZAKŁADEK
     zamiast niego. Kolumna menu na realnym ekranie ~800×360 zabierała
     szerokość, której scena potrzebuje najbardziej, a ikony bez podpisów
     i tak nie mieściły wszystkich piętnastu pozycji. Menu nie znika z DOM-u —
     staje się treścią kafla WIĘCEJ, pełnoekranową nakładką (patrz niżej). */
  :root { --h-taby: 54px; }
  #hub {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--h-top) minmax(0, 1fr) var(--h-taby);
    grid-template-areas:
      "top"
      "scena"
      "taby";
  }

  /* PASEK GÓRNY DO KOŚCI: awatar+poziom, złoto, diamenty, poczta. Klucze/
     kopacze/łowi i reszta narzędzi (ranking, kronika, ustawienia) i tak są
     osiągalne przez WIĘCEJ albo KONTO — trzymanie ich tu na stałe zabierałoby
     miejsce częściej, niż ktokolwiek by na nie spojrzał. */
  .stan-swiata { display: none; }
  .narzedzie:not([aria-label="Wiadomości"]) { display: none; }

  #hubTabyTelefonu {
    grid-area: taby;
    display: flex;
    z-index: 40;                 /* nad sceną, pod nakładkami paneli */
  }
  .taby-poz {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; padding: 4px 2px;
    font: inherit; color: var(--krem-dim); background: transparent; border: none;
    border-top: 2px solid transparent;           /* miejsce na podświetlenie, nie skacze przy aktywacji */
  }
  .taby-poz-ikona { font-size: 18px; line-height: 1; }
  .taby-poz-etykieta { font-size: 8px; letter-spacing: .04em; }
  .taby-poz--aktywny {
    color: var(--zloto);
    border-top-color: var(--zloto);
    background: rgba(232, 180, 74, .08);
  }

  /* TRZY NAKŁADKI, JEDEN MECHANIZM. POSTAĆ (staty + sloty + magazyn, plus
     dok drużyny nad nią) i WIĘCEJ (dawne menu boczne) chowają się pod
     `display:none`, dopóki `panel-telefonu--otwarty` (JS, patrz hub.html) ich
     nie odsłoni — wtedy stają się pełnoekranowe, NAD sceną i NAD paskiem
     zakładek, ale POD nim jest scena dalej żywa z tyłu.
     `!important` bije zwykłe `display:none` z bazowego arkusza dla `#hubMenu`
     w tym samym pliku — bez niego selektor o tej samej sile jako drugi
     przegrywałby kolejnością, nie trafnością. */
  #hubPrawy, #hubDol, #hubMenu { display: none; }
  #hubPrawy.panel-telefonu--otwarty,
  #hubDol.panel-telefonu--otwarty,
  #hubMenu.panel-telefonu--otwarty {
    display: flex !important;
    position: fixed; left: 0; right: 0;
    overflow-y: auto;
    z-index: 45;
    background: var(--tlo);
  }
  /* POZYCJE LICZONE Z ODSTĘPEM SIATKI, NIE SAMĄ WYSOKOŚCIĄ PASKA. `#hub` ma
     `gap`+`padding` po `var(--siatka-luz)` — scena zaczyna się więc nie od
     razu za paskiem górnym, tylko po jednym odstępie dalej (padding góry
     siatki + przerwa między wierszami), i kończy się jeden odstęp przed
     paskiem zakładek. Nakładki są `position:fixed`, więc gridowego `gap` nie
     dziedziczą same z siebie — pierwsza wersja liczyła `top: var(--h-top)`
     wprost i panel wchodził 10 px za wysoko/nisko na oba pęknięcia siatki.
     `calc()` z `--siatka-luz` * 2 (padding brzegu + odstęp między wierszami)
     naprawia oba naraz i zostaje poprawne, choćby ktoś zmienił sam odstęp. */

  /* Dok drużyny stoi NAD panelem POSTAĆ — to on odpowiada „kto jest w drużynie",
     zanim gracz w ogóle zajrzy w staty. Wysokość na sztywno: sam dobiera się
     do trzech-czterech portretów i nie ma powodu rosnąć razem z ekranem. */
  #hubDol.panel-telefonu--otwarty {
    top: calc(var(--h-top) + var(--siatka-luz) * 2); height: 84px;
    border-bottom: 2px solid var(--linia);
  }
  #hubPrawy.panel-telefonu--otwarty {
    top: calc(var(--h-top) + var(--siatka-luz) * 2 + 84px);
    bottom: calc(var(--h-taby) + var(--siatka-luz) * 2);
  }
  #hubMenu.panel-telefonu--otwarty {
    top: calc(var(--h-top) + var(--siatka-luz) * 2);
    bottom: calc(var(--h-taby) + var(--siatka-luz) * 2);
  }
}

/* ============================================================== KOPALNIA
   Powierzchnia i sztolnia to dwa `<main>` w tym samym polu siatki co scena
   portalu — widoczny jest zawsze dokładnie jeden. */
/* WSZYSTKIE EKRANY DZIELĄ POLE `scena`. Bez tego nowe `<main>` wypadały
   poza siatkę i rozpychały układ zamiast podmieniać scenę portalu. */
.scena-kopalnia, .scena-folk { grid-area: scena; }
.scena-kopalnia { position: relative; overflow: hidden; }
.scena-kopalnia canvas { display: block; width: 100%; height: 100%; }

.scena-podpis {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  padding: 6px 14px;
  background: rgba(10, 8, 18, .82);
  border: 1px solid var(--linia);
  color: var(--krem-dim); font-size: 11px; letter-spacing: .10em;
  pointer-events: none;
}

.btn-powrot {
  position: absolute; top: 12px; left: 12px; z-index: 20;
  padding: 9px 14px;
  background: linear-gradient(180deg, #2A1D48, #1A1130);
  border: 2px solid var(--zloto-ciemne);
  color: var(--zloto); font-family: inherit; font-size: 12px;
  letter-spacing: .12em; cursor: pointer;
}
.btn-powrot:hover { border-color: var(--zloto); }

/* ZŁOŻA. Hałdy leżą NAD obrazem komory, bo mają być klikalne i będą znikać,
   gdy górnik je wybierze. Wycięte z arkusza w locie — patrz `hub-kopalnia.js`. */
.zloza-warstwa { position: absolute; inset: 0; }
.zloze {
  position: absolute; cursor: pointer;
  filter: drop-shadow(0 3px 0 rgba(0, 0, 0, .45));
  transition: filter .12s;
}
.zloze img { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.zloze:hover { filter: drop-shadow(0 0 6px var(--zloto)); }

/* ============================================================ TWÓJ FOLK */
.scena-folk { display: flex; flex-direction: column; padding: 14px; overflow: hidden; }
.folk-naglowek {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 10px; margin-bottom: 12px;
  border-bottom: 2px solid var(--linia);
}
.folk-tytul { margin: 0; font-size: 17px; letter-spacing: .22em; color: var(--krem); }
.folk-licznik {
  padding: 2px 9px; background: #1B1730;
  border: 1px solid var(--zloto-ciemne); color: var(--zloto); font-size: 12px;
}
.folk-siatka {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px; align-content: start;
}
.folk-karta {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px;
  background: linear-gradient(180deg, rgba(26, 21, 44, .8), rgba(13, 11, 21, .9));
  border: 2px solid var(--linia); cursor: pointer;
}
.folk-karta:hover { border-color: var(--fiolet); }
/* GNIAZDO PORTRETU MA STAŁY ROZMIAR, sprite w środku nie.
   Mnożnik rodzaju potrafi urosnąć do 2,05 (skrzydlaty), a bez gniazda taki
   obrazek rozpychał kartę: podpisy w jednym rzędzie lądowały na różnych
   wysokościach, a przy najwyższych sprite wchodził na własną nazwę. Teraz
   karta ma zawsze te same wymiary, a to, co wystaje, jest przycinane. */
/* ŚRODKOWANIE PRZEZ POŁOŻENIE, NIE PRZEZ SIATKĘ. `place-items: center` przy
   `overflow: hidden` przykleja element SZERSZY od kontenera do lewej krawędzi
   zamiast wypuścić go równo na obie strony — przeglądarka broni się wtedy
   przed ucięciem początku treści. A tutaj szerszy jest prawie każdy: portret
   ma 76 px razy mnożnik rodzaju, czyli do 156 px w gnieździe 88 px.
   Bezwzględne położenie plus `translate(-50%)` nie ma tego zabezpieczenia
   i tnie symetrycznie. */
.folk-gniazdo {
  width: 88px; height: 88px; flex: 0 0 auto;
  position: relative; overflow: hidden;
}
.folk-portret {
  position: absolute; left: 50%; top: 50%;
  width: 76px; height: 76px; image-rendering: pixelated;
}
.folk-nazwa { font-size: 11px; letter-spacing: .08em; color: var(--krem-dim); }
.folk-klasa {
  margin-top: -4px; padding: 2px 5px;
  color: var(--zloto); font-size: 8px; letter-spacing: .12em;
  border: 1px solid rgba(232, 180, 74, .42); background: rgba(232, 180, 74, .08);
}

/* ========================================================== ZBROJOWNIA
   Kowal i stół leżą w osobnych warstwach nad płótnem; pozycję i rozmiar
   ustawia skrypt, tu zostaje sam sposób rysowania. `pixelated`, bo to sprite'y
   pixel-artowe skalowane w GÓRĘ — wygładzanie zamieniłoby je w papkę. */
.zbrojownia-postac, .zbrojownia-stol {
  position: absolute; left: 0; top: 0;
  image-rendering: pixelated;
  pointer-events: none;
}
.zbrojownia-postac { filter: drop-shadow(0 3px 0 rgba(0, 0, 0, .5)); }

.zbrojownia-panel {
  position: absolute; z-index: 35; right: 12px; bottom: 12px;
  width: min(470px, calc(100% - 24px)); max-height: calc(100% - 92px);
  overflow: auto; padding: 10px; background: rgba(13, 11, 21, .94);
  border: 2px solid var(--linia); color: var(--krem); font-size: 10px;
}
.zbrojownia-gora { display: flex; gap: 10px; justify-content: space-between; align-items: center; }
.zbrojownia-gora label { color: var(--zloto); letter-spacing: .08em; }
.zbrojownia-gora select { margin-left: 5px; background: #16122A; color: var(--krem); border: 1px solid var(--linia); }
.zbrojownia-zalozone { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; margin: 9px 0; }
.zbrojownia-kolumny { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.zbrojownia-kolumny h3 { margin: 0 0 5px; font-size: 10px; color: var(--zloto); letter-spacing: .12em; }
.zbrojownia-lista { display: grid; gap: 5px; }
.zbrojownia-wpis { padding: 6px; background: #16122A; border: 1px solid #332A4D; line-height: 1.45; }
.zbrojownia-wpis button { margin: 5px 4px 0 0; padding: 3px 5px; background: #29203C; border: 1px solid var(--linia); color: var(--krem); font: inherit; font-size: 9px; cursor: pointer; }
.zbrojownia-wpis button:hover:not(:disabled) { border-color: var(--zloto); color: var(--zloto); }
.zbrojownia-wpis button:disabled { opacity: .45; cursor: default; }
@media (max-width: 700px) { .zbrojownia-kolumny { grid-template-columns: 1fr; } .zbrojownia-panel { max-height: calc(100% - 78px); } }

/* ====================================================== KOKPIT DRUŻYNY */
.inspektor { height: 100%; box-sizing: border-box; padding: 12px; overflow-y: auto; font-size: 10px; color: var(--krem-dim); }
.inspektor-naglowek { display: flex; justify-content: space-between; gap: 8px; color: var(--zloto); letter-spacing: .12em; border-bottom: 1px solid var(--linia); padding-bottom: 8px; }
.inspektor-naglowek b { color: var(--krem); text-align: right; }
.inspektor-stan { padding: 9px 0; line-height: 1.45; }
.inspektor h3 { margin: 11px 0 5px; font-size: 9px; letter-spacing: .14em; color: var(--zloto); }
.inspektor-staty { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; color: var(--krem); }
.inspektor-stat { min-width: 0; padding: 5px 6px; background: #16122A; border: 1px solid #332A4D; }
.inspektor-stat b { display: flex; justify-content: space-between; gap: 5px; color: var(--krem-dim); font-size: 8px; letter-spacing: .05em; }
.inspektor-stat strong { color: var(--zloto); font-size: 11px; }
.inspektor-stat small { display: block; margin-top: 3px; color: #827A98; font-size: 7px; line-height: 1.1; white-space: nowrap; }
.inspektor-stat--kryt { border-color: rgba(232, 180, 74, .42); background: rgba(232, 180, 74, .07); }
.inspektor-sloty, .inspektor-magazyn { display: grid; gap: 4px; }
.inspektor-slot { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding: 5px; background: #16122A; border: 1px solid #332A4D; }
.inspektor button { font: inherit; font-size: 8px; color: var(--krem); background: #29203C; border: 1px solid var(--linia); padding: 3px 5px; cursor: pointer; }
.inspektor button:hover { border-color: var(--zloto); color: var(--zloto); }
.inspektor-przedmiot { text-align: left; }
.dok-druzyny { height: 100%; box-sizing: border-box; display: flex; align-items: center; gap: 8px; padding: 8px 12px; overflow-x: auto; }
.dok-etykieta { flex: 0 0 auto; font-size: 10px; letter-spacing: .12em; color: var(--krem-dim); }
.dok-etykieta b { color: var(--zloto); }
.dok-postacie { display: flex; gap: 5px; }
.dok-postac, .dok-zmien, .tablica-odnow { font: inherit; font-size: 9px; letter-spacing: .06em; color: var(--krem); background: #16122A; border: 1px solid var(--linia); padding: 6px 8px; cursor: pointer; white-space: nowrap; }
.dok-postac--wybrana { border-color: var(--zloto); color: var(--zloto); }
.dok-zmien { margin-left: auto; }
.tablica-odnow { position: absolute; z-index: 35; top: 12px; right: 12px; }
.tablica-odnow:disabled { opacity: .55; cursor: default; }

/* Prawy panel ma wyglądać jak karta bohatera, nie jak kolumna formularza. */
.inspektor { padding: 0; }
.inspektor-naglowek { padding: 11px 12px 8px; background: #0E0C18; }
.inspektor-wizytowka { display: flex; align-items: center; min-height: 76px; padding: 8px 12px; gap: 10px; border-bottom: 1px solid var(--linia); background: linear-gradient(90deg, rgba(139,63,217,.16), transparent); }
.inspektor-portret { width: 58px; height: 58px; flex: 0 0 auto; position: relative; overflow: hidden; border: 2px solid var(--zloto-ciemne); background: #0B0A12; }
.inspektor-sprite { position: absolute; width: 62px; height: 62px; left: 50%; bottom: -5px; transform: translateX(-50%); }
.inspektor-stan { padding: 0; font-size: 10px; line-height: 1.65; }
.inspektor-staty, .inspektor-sloty, .inspektor-magazyn { margin: 0 12px; }
.inspektor h3 { margin: 12px 12px 6px; padding-bottom: 4px; border-bottom: 1px solid var(--linia); }
.inspektor-sekcja-tytul { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin: 12px 12px 6px; padding-bottom: 4px; border-bottom: 1px solid var(--linia); }
.inspektor-sekcja-tytul h3 { margin: 0; padding: 0; border: 0; }
.inspektor-sekcja-tytul button { flex: 0 0 auto; padding: 3px 5px; color: var(--zloto); border-color: rgba(232,180,74,.55); background: rgba(232,180,74,.08); }
.inspektor-sekcja-tytul button:disabled { opacity: .45; cursor: default; }
.inspektor-stat { padding: 6px; }
.inspektor-slot { min-height: 30px; padding: 6px 7px; color: var(--krem); }
.inspektor-item-opis { min-width: 0; display: grid; gap: 2px; }
.inspektor-item-opis b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 9px; color: var(--krem); }
.inspektor-item-opis small { font-size: 8px; color: var(--zloto); line-height: 1.35; }
.inspektor-magazyn { padding-bottom: 12px; }

/* EKRAN EKWIPUNKU: osiem slotów układa się jak sylwetka, nie jak lista.
   Środek niesie pancerz i buty, ręce są po bokach, a biżuteria nad nimi. */
.inspektor-sloty {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(3, 62px);
  grid-template-areas:
    "naszyjnik helm pierscien"
    "glowna zbroja pomocna"
    "rekawiczki buty .";
  gap: 6px;
}
.inspektor-slot {
  position: relative; display: grid; place-items: center; min-height: 0;
  padding: 5px; text-align: center; border-color: #3B3158;
  background: radial-gradient(circle at 50% 35%, #1B1730, #100D1C);
}
.inspektor-slot--glowna { grid-area: glowna; }
.inspektor-slot--pomocna { grid-area: pomocna; }
.inspektor-slot--helm { grid-area: helm; }
.inspektor-slot--zbroja { grid-area: zbroja; }
.inspektor-slot--rekawiczki { grid-area: rekawiczki; }
.inspektor-slot--buty { grid-area: buty; }
.inspektor-slot--naszyjnik { grid-area: naszyjnik; }
.inspektor-slot--pierscien { grid-area: pierscien; }
.inspektor-slot--zbroja { border-color: rgba(232,180,74,.48); box-shadow: inset 0 0 14px rgba(232,180,74,.04); }
.inspektor-item-opis { width: 100%; align-content: center; }
.inspektor-item-opis b { white-space: normal; font-size: 8px; line-height: 1.15; }
.inspektor-item-opis small { overflow: hidden; max-height: 18px; font-size: 7px; }
.inspektor-slot > button { position: absolute; right: 3px; bottom: 3px; padding: 2px 3px; font-size: 7px; opacity: 0; }
.inspektor-slot:hover > button, .inspektor-slot:focus-within > button { opacity: 1; }

/* Szyk jest skrótem wizualnym: portret, imię, pozycja. Przestaje wyglądać
   jak przypadkowa lista małych przycisków przyklejona na środku pustego pola. */
/* `width: 100%`. `#hubDol` (rodzic) ma `justify-content: center` — z jednym
   dzieckiem bez zadeklarowanej szerokości centrowało je przy JEGO WŁASNEJ,
   naturalnej szerokości zamiast rozciągać na cały pasek. Karty w środku
   poprawnie dzieliły między siebie przestrzeń `.dok-druzyny`, tylko samo
   `.dok-druzyny` nigdy nie dostawało więcej niż potrzebowała jego zawartość —
   stąd rząd zatrzymywał się w okolicy 600 px bez względu na szerokość okna. */
.dok-druzyny { width: 100%; padding: 12px 16px; gap: 14px; background: linear-gradient(90deg, #0E0C18, transparent); }
.dok-etykieta { display: grid; gap: 3px; min-width: 78px; }
/* KARTY ROZCIĄGAJĄ SIĘ NA CAŁĄ SZEROKOŚĆ zamiast trzymać się swojej
   minimalnej treści. Bez `flex: 1` rząd stawał na `min-width` każdej karty
   i cała reszta paska między nimi a przyciskiem ZARZĄDZAJ zostawała martwą,
   czarną przestrzenią — trzy karty w rogu ekranu, trzy czwarte paska puste. */
/* `flex-basis: 0`, NIE `auto`. Z `auto` przeglądarka najpierw liczy naturalną
   szerokość z zawartości i rosła od niej — w praktyce zatrzymywało się to
   w okolicy 600 px bez względu na to, ile miejsca naprawdę było w rzędzie,
   bo dzieci-karty (same z `flex-basis: 0`) nie dawały żadnej podpowiedzi
   co do rozmiaru „naturalnego”. `0` każe liczyć WYŁĄCZNIE z dostępnego
   miejsca w rodzicu, tak jak już działało dla pojedynczej karty. */
.dok-postacie { flex: 1 1 0; min-width: 0; gap: 10px; align-items: stretch; }
.dok-postac {
  flex: 1 1 0; min-width: 0;
  min-height: 76px; display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; text-align: left; background: #12101C;
}
.dok-postac:hover { border-color: var(--fiolet-jasny); }
.dok-portret { width: 56px; height: 56px; object-fit: contain; image-rendering: pixelated; }
.dok-postac span { display: grid; gap: 3px; min-width: 0; }
.dok-postac b { font-size: 12px; color: var(--krem); }
.dok-postac small { font-size: 9.5px; color: var(--krem-dim); }
.dok-postac--wybrana { background: rgba(232,180,74,.12); box-shadow: inset 0 0 0 1px rgba(232,180,74,.25); }
.dok-postac--puste { border-style: dashed; border-color: var(--linia); background: transparent; color: var(--krem-dim); justify-content: flex-start; }
.dok-postac--puste:hover { border-color: var(--linia-jasna); }
.dok-portret--puste { display: flex; align-items: center; justify-content: center; border: 1px dashed var(--linia); color: var(--krem-dim); font-size: 16px; }

.inspektor-stat--puste, .inspektor-slot--puste { border-style: dashed; background: transparent; color: var(--krem-dim); }
.inspektor-stat--puste strong { color: var(--krem-dim); }
.dok-zmien { padding: 8px 11px; }

/* =============================================================== PLECAK */
.plecak-zakladki { display: flex; flex-wrap: wrap; gap: 6px; }
.plecak-zakladki button { padding: 6px 9px; font: inherit; font-size: 9px; letter-spacing: .08em; color: var(--krem-dim); background: #16122A; border: 1px solid var(--linia); cursor: pointer; }
.plecak-zakladki button[aria-selected="true"] { color: var(--zloto); border-color: var(--zloto); }
.plecak-lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; overflow-y: auto; min-height: 0; }
.plecak-rzecz { display: grid; gap: 5px; padding: 10px; background: #16122A; border: 1px solid var(--linia); }
.plecak-rzecz b { color: var(--krem); letter-spacing: .05em; }
.plecak-rzecz span { color: var(--zloto); font-size: 10px; }
.plecak-rzecz small { color: var(--krem-dim); font-size: 9px; }

/* ============================================================ DUNGEONY
   Tytuł leży NA scenie, nie nad nią — obraz ma wypełniać całe pole, a napis
   być jego częścią, tak jak etap i prędkość w idlu. */
.dungeon-naglowek {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 30; text-align: center;
  padding: 8px 18px;
  background: rgba(10, 8, 18, .78);
  border: 2px solid var(--linia);
}
.dungeon-tytul {
  margin: 0; font-size: 15px; letter-spacing: .22em; color: var(--zloto);
}
.dungeon-pod {
  display: block; margin-top: 3px;
  font-size: 10px; letter-spacing: .14em; color: var(--krem-dim);
}
.dungeon-panel { position: absolute; z-index: 32; right: 22px; bottom: 22px; width: min(370px, calc(100% - 44px)); }
.dungeon-karta { padding: 14px; background: rgba(13, 11, 21, .94); border: 2px solid var(--linia); box-shadow: 0 10px 30px rgba(0,0,0,.45); }
.dungeon-karta-gora { display: flex; justify-content: space-between; gap: 8px; color: var(--krem-dim); font-size: 8px; letter-spacing: .12em; }
.dungeon-karta-gora b { color: #8FE07B; font-size: 8px; }
.dungeon-karta h3 { margin: 9px 0 4px; color: var(--zloto); font-size: 15px; letter-spacing: .08em; }
.dungeon-karta p { margin: 0 0 10px; color: var(--krem-dim); font-size: 9px; }
.dungeon-fale { display: grid; gap: 4px; margin-bottom: 9px; }
.dungeon-fale span { padding: 6px 7px; background: #171326; border-left: 2px solid #645475; color: var(--krem); font-size: 9px; }
.dungeon-fale .dungeon-fala--trudna { border-left-color: #BB5864; color: #D9A5AB; }
.dungeon-moc { margin-bottom: 9px; padding: 7px; border: 1px solid #3B3158; color: var(--zloto); font-size: 9px; letter-spacing: .06em; }
.dungeon-karta button { width: 100%; padding: 8px; border: 1px solid var(--zloto); background: rgba(232,180,74,.14); color: var(--zloto); font: inherit; font-size: 9px; letter-spacing: .1em; cursor: pointer; }
.dungeon-karta button:hover:not(:disabled) { background: rgba(232,180,74,.25); }
.dungeon-karta button:disabled { opacity: .5; cursor: default; }
.dungeon-komunikat { display: block; min-height: 18px; margin-top: 9px; color: var(--krem-dim); font-size: 8px; line-height: 1.35; }
.dungeon-karta--zamkniety { filter: saturate(.55); }
.dungeon-karta--zamkniety .dungeon-karta-gora b { color: #D58189; }

/* Wrota są osobnym wyborem, a nie guzikiem wetkniętym w prawy dolny róg.
   Po wejściu panel zmienia się w kartę wyprawy: drużyna, trasa, stan i start. */
.dungeon-panel { left: 50%; right: auto; bottom: 28px; width: min(690px, calc(100% - 46px)); transform: translateX(-50%); }
.dungeon-karta--brama { display: grid; grid-template-columns: 104px minmax(0, 1fr) 190px; grid-template-rows: auto auto 1fr auto; gap: 8px 14px; padding: 18px; border-color: rgba(232,180,74,.72); background: linear-gradient(125deg, rgba(18,14,31,.97), rgba(8,8,15,.94)); }
.dungeon-karta--brama .dungeon-karta-gora { grid-column: 1 / -1; }
.dungeon-brama-znak { grid-row: 2 / span 3; display: grid; place-items: center; min-height: 112px; color: var(--zloto); font-size: 70px; line-height: 1; border: 1px solid rgba(232,180,74,.32); background: radial-gradient(circle, rgba(139,63,217,.32), transparent 68%); text-shadow: 0 0 20px rgba(232,180,74,.4); }
.dungeon-karta--brama h3 { margin: 4px 0 0; align-self: end; font-size: 20px; }
.dungeon-karta--brama p { margin: 0; align-self: start; }
.dungeon-mini-trasa { grid-column: 2; display: flex; gap: 0; align-items: center; }
.dungeon-mini-trasa span { width: 25px; height: 25px; display: grid; place-items: center; border: 1px solid var(--zloto); border-radius: 50%; background: #1B1530; color: var(--zloto); font-size: 10px; }
.dungeon-mini-trasa span + span { margin-left: 25px; position: relative; }
.dungeon-mini-trasa span + span::before { content: ''; position: absolute; right: 100%; top: 50%; width: 25px; border-top: 1px solid var(--linia); }
.dungeon-karta--brama .dungeon-moc { grid-column: 3; grid-row: 2 / span 2; margin: 0; display: grid; align-content: center; text-align: center; }
.dungeon-karta--brama button { grid-column: 2 / 4; }
.dungeon-karta--brama .dungeon-komunikat { grid-column: 2 / 4; margin: 0; }
.dungeon-wyprawa { padding: 16px; border: 2px solid rgba(232,180,74,.72); background: linear-gradient(135deg, rgba(12,10,20,.97), rgba(27,18,44,.95)); box-shadow: 0 12px 35px rgba(0,0,0,.52); }
.dungeon-wyprawa-gora { display: flex; align-items: center; justify-content: space-between; padding-bottom: 10px; border-bottom: 1px solid var(--linia); font-size: 8px; color: var(--krem-dim); letter-spacing: .12em; }
.dungeon-wyprawa-gora b { color: #8FE07B; }
.dungeon-wroc { padding: 0; border: 0; color: var(--krem-dim); background: none; font: inherit; font-size: 8px; cursor: pointer; }
.dungeon-wroc:hover { color: var(--zloto); }
.dungeon-wyprawa-nazwa { display: flex; align-items: center; gap: 10px; margin: 13px 0; }
.dungeon-wyprawa-nazwa > span { width: 44px; height: 44px; display: grid; place-items: center; color: var(--zloto); border: 1px solid var(--zloto); background: rgba(139,63,217,.18); font-size: 27px; }
.dungeon-wyprawa-nazwa small, .dungeon-sekcja { color: var(--krem-dim); font-size: 8px; letter-spacing: .12em; }
.dungeon-wyprawa-nazwa h3 { margin: 3px 0 0; color: var(--zloto); font-size: 18px; letter-spacing: .06em; }
.dungeon-druzyna, .dungeon-trasa { padding: 10px; border: 1px solid #3B3158; background: rgba(8,7,14,.55); }
.dungeon-sekcja { display: flex; justify-content: space-between; margin-bottom: 7px; }
.dungeon-sekcja b { color: var(--zloto); }
.dungeon-druzyna-lista { display: flex; flex-wrap: wrap; gap: 5px; }
.dungeon-członek { display: flex; align-items: center; gap: 4px; min-width: 110px; padding: 4px; border: 1px solid #332A4D; background: #16122A; color: var(--krem); font-size: 7px; }
.dungeon-członek-portret { width: 24px; height: 24px; object-fit: contain; image-rendering: pixelated; }
.dungeon-trasa { margin-top: 7px; }
.dungeon-trasa-lista { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.dungeon-krok { display: flex; gap: 6px; align-items: center; min-height: 38px; padding: 5px; border: 1px solid #332A4D; color: var(--krem-dim); background: #13101E; }
.dungeon-krok > b { width: 18px; height: 18px; display: grid; place-items: center; flex: 0 0 auto; border: 1px solid #645475; border-radius: 50%; font-size: 8px; }
.dungeon-krok span { min-width: 0; display: grid; gap: 2px; }
.dungeon-krok strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--krem); font-size: 8px; }
.dungeon-krok small { font-size: 7px; }
.dungeon-krok--teraz { border-color: var(--zloto); box-shadow: inset 0 0 15px rgba(232,180,74,.12); }
.dungeon-krok--teraz > b { border-color: var(--zloto); color: var(--zloto); }
.dungeon-krok--czysty { border-color: rgba(110,202,120,.55); }
.dungeon-krok--czysty > b { border-color: #6ECA78; color: #8FE07B; }
.dungeon-krok--porażka { border-color: #BB5864; }
.dungeon-krok--porażka > b { border-color: #BB5864; color: #E18A92; }
.dungeon-podsumowanie { display: flex; justify-content: space-between; gap: 8px; margin: 8px 0; padding: 8px; border: 1px solid rgba(232,180,74,.35); color: var(--krem-dim); font-size: 8px; }
.dungeon-podsumowanie b { display: block; margin-top: 2px; color: var(--zloto); font-size: 10px; }
.dungeon-start { width: 100%; padding: 9px; border: 1px solid var(--zloto); background: linear-gradient(90deg, rgba(232,180,74,.12), rgba(139,63,217,.2)); color: var(--zloto); font: inherit; font-size: 9px; letter-spacing: .13em; cursor: pointer; }
.dungeon-start:hover:not(:disabled) { background: rgba(232,180,74,.24); }
.dungeon-start:disabled { opacity: .55; cursor: default; }
.dungeon-wyprawa .dungeon-komunikat { margin: 8px 0 0; }
.dungeon-arena { position: absolute; z-index: 31; inset: 0; overflow: hidden; pointer-events: none; }
.dungeon-status { z-index: 34; top: 10px; bottom: auto; white-space: nowrap; }
.loch-unit { position: absolute; left: var(--x); bottom: calc(17% + var(--y)); width: 118px; height: 146px; transform: translateX(-50%); filter: drop-shadow(0 5px 2px rgba(0,0,0,.7)); }
.loch-unit--wrog { transform: translateX(-50%) scaleX(-1); }
.loch-sprite { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
.loch-unit--martwy { opacity: .2; filter: grayscale(1); }
.loch-unit--trafiony { animation: loch-trafienie .22s ease-out; }
@keyframes loch-trafienie { 50% { filter: brightness(2.4) drop-shadow(0 0 10px #F38C94); } }
.loch-dmg { position: absolute; left: 50%; top: 6px; transform: translateX(-50%); color: #F38C94; font-size: 16px; text-shadow: 1px 1px #120910; animation: loch-dmg .65s ease-out forwards; }
.loch-dmg--leczenie { color: #8FE07B; }
.loch-unit--skok { animation: loch-skok .28s ease-out; }
@keyframes loch-skok { from { opacity: 0; filter: brightness(2.5) drop-shadow(0 0 12px #B869FF); } to { opacity: 1; } }
@keyframes loch-dmg { to { transform: translate(-50%, -30px); opacity: 0; } }
@media (max-width: 700px) { .dungeon-karta--brama { grid-template-columns: 76px 1fr; } .dungeon-brama-znak { min-height: 90px; font-size: 50px; } .dungeon-karta--brama .dungeon-moc, .dungeon-karta--brama button, .dungeon-karta--brama .dungeon-komunikat { grid-column: 1 / -1; grid-row: auto; } .dungeon-trasa-lista { grid-template-columns: 1fr; } .dungeon-roster { width: 108px; left: 7px; } .dungeon-roster--wrogowie { left: auto; right: 7px; } .loch-unit { width: 82px; height: 104px; } }

/* Pusta kolekcja. Komunikat stoi tam, gdzie byłyby karty — nie na pasku
   u dołu, bo wtedy gracz patrzy na pustkę i szuka wzrokiem wyjaśnienia. */
.folk-pusto {
  margin: 0; padding: 28px 16px;
  text-align: center; font-size: 11.5px; line-height: 1.7;
  letter-spacing: .05em; color: var(--krem-dim);
}

/* ============================================================== POZIOMY
   Panel na karcie folku: poziom, pasek XP i cztery statystyki z plusem.
   Karta z nierozdanym punktem świeci ramką — bez tego trzeba obejść całą
   kolekcję, żeby sprawdzić, czy gdzieś nie zalega awans. */
.folk-karta--punkty { border-color: var(--zloto); }

.poziom { width: 100%; display: flex; flex-direction: column; gap: 4px; }
.poziom-gora {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 10px; letter-spacing: .08em;
}
.poziom-lvl { color: var(--krem-dim); }
.poziom-punkty { color: var(--zloto); }
/* Przypięty do prawej krawędzi zamiast `justify-content: space-between` —
   przy trzech elementach ten drugi wariant wepchnąłby RESET między poziom
   a licznik punktów, rozdzielając dwie rzeczy, które czyta się razem. */
.poziom-reset {
  margin-left: auto;
  padding: 1px 5px;
  background: transparent; border: 1px solid var(--linia);
  color: var(--krem-dim); font-family: inherit; font-size: 8px; letter-spacing: .06em;
  cursor: pointer;
}
/* Czerwony akcent, nie złoty — to jedyny przycisk w tej karcie, który coś
   zabiera zamiast dawać, i ma się wyraźnie odróżniać od „+". */
.poziom-reset:hover:not(:disabled) { border-color: #D9455A; color: #D9455A; }
.poziom-reset:disabled { opacity: .25; cursor: default; }
.poziom-xp {
  height: 4px; background: #16122A; border: 1px solid var(--linia);
  overflow: hidden;
}
.poziom-xp i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--fiolet), var(--fiolet-jasny));
}
.poziom-stat {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 18px;
  align-items: center; gap: 4px;
  font-size: 9.5px; letter-spacing: .06em; color: var(--krem-dim);
}
.poziom-stat-ile { color: var(--krem); font-variant-numeric: tabular-nums; }
.poziom-plus {
  width: 18px; height: 16px; padding: 0; line-height: 1;
  background: #16122A; border: 1px solid var(--linia);
  color: var(--krem-dim); font-family: inherit; font-size: 11px; cursor: pointer;
}
.poziom-plus:hover:not(:disabled) { border-color: var(--zloto); color: var(--zloto); }
/* Wyłączony plus zostaje WIDOCZNY, tylko przygaszony — znikający przycisk
   przesuwałby wiersze przy każdym wydanym punkcie. */
.poziom-plus:disabled { opacity: .3; cursor: default; }

/* GÓRNIK PRZY PRACY. Jeden element wędruje między warstwą sztolni a warstwą
   powierzchni — to ta sama postać, więc nie ma dwóch kopii do zsynchronizowania. */
.gornik-warstwa { position: absolute; inset: 0; pointer-events: none; }
.gornik-pracuje {
  /* Pozycję i kierunek ustawia `transform` ze skryptu — `left`/`top` zostają
     w zerze, żeby marsz nie przeliczał układu przy każdej klatce. */
  position: absolute; left: 0; top: 0;
  transform-origin: center bottom;
  image-rendering: pixelated;
  filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .55));
  will-change: transform;
  z-index: 40;
}

/* Złoże, przy którym ktoś stoi — obwódka mówi, co jest zajęte. */
.zloze--zajete { filter: drop-shadow(0 0 7px var(--zloto)); }
.zloze--zajete::after {
  content: "⛏";
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  font-size: 15px; text-shadow: 0 0 5px #000;
}

/* Licznik urobku — ten sam tekst na dole i na górze, bo to jeden skład. */
.urobek {
  position: absolute; top: 12px; right: 12px;
  padding: 7px 12px;
  background: rgba(10, 8, 18, .85);
  border: 2px solid var(--linia);
  color: var(--krem); font-size: 12px; letter-spacing: .06em;
  pointer-events: none;
}

/* ================================================================ MARKET
   Kram po lewej, lada po prawej. NPC ma być POSTACIĄ w scenie, a nie ikoną
   w nagłówku listy — dlatego dostaje własną połowę ekranu. */
.scena-market {
  grid-area: scena;
  display: grid; grid-template-columns: minmax(200px, 34%) minmax(0, 1fr);
  gap: 14px; padding: 14px; overflow: hidden;
}

/* Kwestia alchemika — nad ladą, nie w rogu ekranu. */
.market-dymek {
  position: absolute; left: 12px; bottom: 12px; z-index: 20;
  max-width: 42%; padding: 8px 12px;
  background: rgba(10, 8, 18, .9);
  border: 2px solid var(--linia-jasna);
  color: var(--krem-dim); font-size: 11px; line-height: 1.5;
}

.market-lada {
  position: absolute; top: 12px; right: 12px; z-index: 20;
  width: 300px; max-height: calc(100% - 24px);
  display: flex; flex-direction: column;
  padding: 12px;
  background: rgba(10, 8, 18, .88);
  border: 2px solid var(--linia);
}
.market-naglowek {
  display: flex; align-items: baseline; gap: 10px;
  padding-bottom: 10px; margin-bottom: 12px;
  border-bottom: 2px solid var(--linia);
}
.market-tytul { margin: 0; font-size: 17px; letter-spacing: .20em; color: var(--krem); }
.market-alchemik { font-size: 11px; letter-spacing: .12em; color: var(--zloto); }

/* PIONOWO, NIGDY W POZIOMIE. Poziomy pasek przewijania w panelu to zawsze
   znak, ze cos w srodku sie rozpycha - tu rozpychaly go przyciski skupu. */
.market-lista {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 8px;
}
.market-wiersz {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "opis opis" "jeden wszystko";
  gap: 6px 8px;
  padding: 9px 10px;
  background: linear-gradient(180deg, rgba(26, 21, 44, .8), rgba(13, 11, 21, .9));
  border: 2px solid var(--linia);
}
.mw-nazwa { grid-area: opis; font-size: 13px; color: var(--krem); letter-spacing: .06em; }
.mw-ile { grid-area: opis; justify-self: end; font-size: 12px; color: var(--krem-dim); }
.mw-cena { display: none; }
.mw-btn {
  padding: 7px 6px; min-width: 0;
  background: #1B1730; border: 2px solid var(--zloto-ciemne);
  color: var(--zloto); font-family: inherit; font-size: 10.5px;
  letter-spacing: .04em; cursor: pointer; white-space: nowrap;
}
.mw-btn:hover:not(:disabled) { border-color: var(--zloto); background: #2A2148; }
.mw-btn:disabled { opacity: .4; cursor: default; }
.market-wiersz .mw-btn:nth-of-type(1) { grid-area: jeden; }
.market-wiersz .mw-btn:nth-of-type(2) { grid-area: wszystko; }

.market-stopka { margin-top: 4px; font-size: 11px; color: var(--krem-dim); letter-spacing: .06em; }

/* ============================================================== MIKSTURY
   Oferta alchemika: karty jedna pod drugą po lewej stronie kramu.
   Klasa mikstury niesie barwę (`--klasa`) — obwódka, etykieta i poświata
   biorą ją z jednego miejsca, więc nie da się ich rozjechać. */
.potki {
  position: absolute; top: 12px; left: 12px; z-index: 20;
  width: 340px;
  /* KOŃCZY SIĘ NA POŁOWIE BUTELEK NA LADZIE (~0,56 wysokości sceny).
     Na pełnej wysokości panel przykrywał cały stragan i efekt „stoisko za
     ladą" znikał; ucięty tutaj przecina flakony w połowie, więc widać,
     że lista LEŻY NA scenie, a nie zamiast niej.
     Lista ma się PRZEWIJAĆ, więc sufit musi być twardy - bez niego panel
     rosnie z trescia zamiast oddac miejsce scenie. */
  height: calc(56% - 12px);
  display: flex; flex-direction: column;
  padding: 12px;
  background: rgba(10, 8, 18, .88);
  border: 2px solid var(--linia);
}
.potki-naglowek {
  display: flex; align-items: baseline; gap: 9px;
  padding-bottom: 9px; margin-bottom: 10px;
  border-bottom: 2px solid var(--linia);
}
.potki-tytul { margin: 0; font-size: 15px; letter-spacing: .20em; color: var(--krem); }
.potki-pod { font-size: 10px; letter-spacing: .10em; color: var(--krem-dim); }

/* PRZEWIJANIE W PIONIE, nigdy w poziomie. Pasek stylizowany, żeby nie był
   jasnym prostokątem na ciemnym panelu. */
.potki-lista {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 8px;
  padding-right: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--linia-jasna) transparent;
}
.potki-lista::-webkit-scrollbar { width: 8px; }
.potki-lista::-webkit-scrollbar-track { background: rgba(0,0,0,.3); }
.potki-lista::-webkit-scrollbar-thumb {
  background: var(--linia-jasna); border: 2px solid rgba(0,0,0,.3);
}
.potki-lista::-webkit-scrollbar-thumb:hover { background: var(--fiolet); }

.potka {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  grid-template-areas: "szklo tresc" "kup kup";
  gap: 8px;
  padding: 9px;
  background: linear-gradient(180deg, rgba(26, 21, 44, .85), rgba(13, 11, 21, .92));
  border: 2px solid var(--linia);
  border-left: 4px solid var(--klasa);
  transition: border-color .12s, transform .12s;
}
.potka:hover { border-color: var(--klasa); transform: translateX(2px); }

.potka-szklo {
  grid-area: szklo;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .35);
  border: 1px solid var(--linia);
}
.potka-ikona {
  width: 34px; height: 34px;
  image-rendering: pixelated;               /* SVG z prostokątów — bez rozmycia */
  filter: drop-shadow(0 0 5px var(--klasa));
}

.potka-tresc { grid-area: tresc; min-width: 0; }
.potka-gora { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.potka-nazwa { font-size: 12.5px; color: var(--krem); letter-spacing: .04em; }
.potka-klasa {
  padding: 1px 6px;
  border: 1px solid var(--klasa);
  color: var(--klasa); font-size: 9px; letter-spacing: .10em;
}
.potka-opis { margin: 4px 0 0; font-size: 10.5px; line-height: 1.45; color: var(--krem-dim); }

.potka-kup {
  grid-area: kup;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 10px;
  background: #1B1730; border: 2px solid var(--zloto-ciemne);
  color: var(--zloto); font-family: inherit; font-size: 11px;
  letter-spacing: .12em; cursor: pointer;
}
.potka-kup:hover:not(:disabled) { border-color: var(--zloto); background: #2A2148; }
.potka-kup:disabled { cursor: default; }
.potka-cena { color: var(--krem); letter-spacing: .02em; }

/* NIE STAĆ CIĘ — karta gaśnie, ale zostaje czytelna. */
.potka--bez-stac { opacity: .5; filter: grayscale(.5); }
.potka--bez-stac:hover { transform: none; border-color: var(--linia); }

@media (prefers-reduced-motion: reduce) {
  .potka, .potka:hover { transition: none; transform: none; }
}

/* LADA NAD ALCHEMIKIEM. Trzecia warstwa targu: kram jest tłem, alchemik stoi
   na nim, a stół zasłania go do pasa. Bez tego postać zawsze leży na wierzchu
   obrazu i wygląda, jakby stała PRZED ladą. */
.stol-warstwa { position: absolute; inset: 0; pointer-events: none; z-index: 60; }
.lada-obraz {
  position: absolute; left: 0; top: 0;
  image-rendering: pixelated;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, .45));
}

/* ============================================================== DRUŻYNA
   Wybór piątki. Karta jest przyciskiem, nie diveM — daje klawiaturę i focus
   za darmo, a wybór ma NUMER, żeby było widać kolejność w szeregu. */
.druzyna-pod { margin-left: auto; font-size: 10.5px; color: var(--krem-dim); letter-spacing: .06em; }

.druzyna-karta {
  position: relative;
  font-family: inherit; color: inherit;
  text-align: center;
}
.druzyna-karta--wybrana {
  border-color: var(--zloto);
  background: linear-gradient(180deg, rgba(58, 44, 20, .85), rgba(20, 15, 8, .9));
}
.druzyna-karta--pelna { opacity: .42; }
.druzyna-karta--pelna:hover { border-color: var(--linia); }

.druzyna-znacznik {
  position: absolute; top: 6px; right: 6px;
  min-width: 20px; height: 20px;
  display: grid; place-items: center;
  color: #120E06; font-size: 11px; line-height: 1;
}
.druzyna-karta--wybrana .druzyna-znacznik { background: var(--zloto); }

/* JEDNOSTKA W MARSZU: sprite plus pasek życia w jednym pudełku, bo oba muszą
   jechać razem. Pozycję ustawia skrypt przez `transform`. */
.idacy-box {
  position: absolute; left: 0; top: 0;
  will-change: transform, opacity;
  transition: opacity .28s ease-out;
}
.idacy-box--ukryty { opacity: 0; }
.profil--ukryty { opacity: 0; }

.idle-start {
  position: absolute; z-index: 20; left: 50%; top: 18%; transform: translateX(-50%);
  display: grid; justify-items: center; gap: 6px; min-width: 300px; padding: 13px 20px;
  text-align: center; background: linear-gradient(90deg, transparent, rgba(12,9,24,.88) 18%, rgba(12,9,24,.88) 82%, transparent);
  text-shadow: 0 2px 4px #000;
}
.idle-start small { color: var(--zloto); font-size: 8px; letter-spacing: .18em; }
.idle-start b { color: var(--krem); font-size: 18px; letter-spacing: .12em; }
.idle-start span { color: var(--krem-dim); font-size: 10px; }
.liczba-bojowa {
  position: absolute; left: 0; top: 0; z-index: 600; pointer-events: none;
  color: #FF9A88; font-size: 16px; font-weight: bold; font-style: normal;
  text-shadow: 2px 2px 0 #16070B, -1px -1px 0 #16070B;
  will-change: transform, opacity;
}
.liczba-bojowa--leczenie { color: #89F18D; text-shadow: 2px 2px 0 #09220E, -1px -1px 0 #09220E; }

/* ======================================================= NAGRODA ETAPU */
.nagroda-etapu {
  position: fixed; inset: 0; z-index: 10000;
  display: grid; place-items: center; padding: 18px;
  background:
    radial-gradient(circle at 50% 42%, rgba(135, 62, 218, .36), transparent 34%),
    rgba(5, 4, 10, .80);
  backdrop-filter: blur(6px) saturate(.72);
}
.nagroda-etapu[hidden] { display: none; }
.nagroda-etapu-karta {
  position: relative; isolation: isolate;
  width: min(410px, 100%); padding: 38px 34px 30px; text-align: center;
  border: 2px solid var(--zloto); background: linear-gradient(155deg, #291C42 0%, #151025 52%, #0D0B16 100%);
  box-shadow: 0 0 0 5px rgba(232,180,74,.08), 0 18px 70px rgba(0,0,0,.72), 0 0 70px rgba(137,64,218,.36);
}
.nagroda-etapu-karta::before {
  content: '✦'; position: absolute; z-index: 1; left: 50%; top: -34px;
  width: 68px; height: 68px; display: grid; place-items: center;
  transform: translateX(-50%); color: #FFF0AD; font-size: 34px;
  border: 2px solid var(--zloto); border-radius: 50%; background: #20152F;
  box-shadow: 0 0 24px rgba(232,180,74,.6);
}
.nagroda-etapu-karta > * { position: relative; z-index: 2; }
.nagroda-etapu-kicker { color: var(--zloto); font-size: 9px; letter-spacing: .24em; }
.nagroda-etapu h2 { margin: 10px 0 20px; color: var(--krem); font-size: 24px; letter-spacing: .15em; text-shadow: 0 2px 0 #09060E; }
.nagroda-etapu p { margin: 0 0 8px; color: var(--krem-dim); font-size: 10px; letter-spacing: .1em; }
.nagroda-etapu-drop { position: relative; display: grid; gap: 7px; padding: 22px 15px 18px; border: 1px solid rgba(232,180,74,.78); background: linear-gradient(135deg, rgba(232,180,74,.18), rgba(124,58,190,.12)); box-shadow: inset 0 0 22px rgba(232,180,74,.06); }
.nagroda-etapu-drop::before { content: 'NOWY ŁUP'; position: absolute; left: 50%; top: -8px; transform: translateX(-50%); padding: 2px 8px; color: #160F07; background: var(--zloto); font-size: 7px; font-weight: bold; letter-spacing: .16em; white-space: nowrap; }
.nagroda-etapu-drop b { color: #FFE7A0; font-size: 15px; letter-spacing: .07em; }
.nagroda-etapu-drop small { color: var(--krem); font-size: 10px; }
.nagroda-etapu button { width: 100%; margin-top: 23px; padding: 13px 14px; color: #160F07; font: inherit; font-size: 10px; font-weight: bold; letter-spacing: .14em; background: linear-gradient(#FFE29A, var(--zloto)); border: 1px solid #FFF0AD; box-shadow: 0 3px 0 #7F5612; cursor: pointer; }
.nagroda-etapu button:hover { filter: brightness(1.12); transform: translateY(-1px); }
#nagrodaEtapuAuto { display: block; margin-top: 8px; color: var(--krem-dim); font-size: 9px; letter-spacing: .06em; text-align: center; }

/* SPRITE ZOSTAJE W UKŁADZIE PUDEŁKA.
   Pierwsza wersja idle'a stawiała go na `position: absolute` — wtedy sam
   ustawiał swoją pozycję. Po przejściu na pudełko reguła została i wyjmowała
   go z układu, więc pudełko miało ZEROWĄ wysokość: pasek życia lądował pod
   stopami, a `z-index` liczony z dołu pudełka był bez sensu. */
.idacy {
  display: block;
  image-rendering: pixelated;
  filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .55));
}
.idacy--wrog { filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .55)) hue-rotate(150deg) saturate(1.3); }

/* NAD GŁOWAMI NIC NIE WISI. Pasek życia i etykieta jechały razem ze sprite'em
   przez całą scenę i przy kilku idących obok siebie robiły z drogi plątaninę
   kresek. Życie obu stron stoi teraz na kartach po bokach sceny. */
.idacy-box--trup { opacity: .35; }

/* BŁYSK TELEPORTU. Tancerz ostrzy nie idzie na tyły — znika i pojawia się.
   Skok jest natychmiastowy, więc to animacja MUSI powiedzieć, że coś się
   stało; bez niej postać po prostu przeskakuje i wygląda jak błąd. */
.idacy-box--blysk .idacy { animation: blysk-teleportu .42s steps(4) 1; }
@keyframes blysk-teleportu {
  0%   { opacity: 0; filter: brightness(4) drop-shadow(0 0 10px var(--fiolet-jasny)); }
  40%  { opacity: 1; filter: brightness(2.4) drop-shadow(0 0 14px var(--fiolet-jasny)); }
  100% { opacity: 1; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .55)); }
}
@media (prefers-reduced-motion: reduce) {
  .idacy-box--blysk .idacy { animation: none; }
}

/* FURIA. Sam wzrost sylwetki bywa nieczytelny w kotłowaninie, więc dochodzi
   złota poświata — postać ma wyglądać na rozpaloną, nie tylko na większą. */
.idacy-box--furia .idacy {
  filter: drop-shadow(0 0 10px var(--zloto)) brightness(1.25) saturate(1.2);
}

/* CZAR NAD GŁOWĄ. Kula rośnie, aż wybuchnie, i wtedy rozdyma się i gaśnie —
   pozycję, rozmiar i klatkę ustawia skrypt, tu zostaje sam wygląd.
   `z-index` wyżej niż pociski i jednostki: to najważniejsza rzecz na ekranie
   w chwili, gdy leci. */
.czar {
  position: absolute; left: 0; top: 0; z-index: 60;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  /* Kadry mają 256 px, a kula leci w ~150 px — POMNIEJSZAMY, więc wygładzanie
     ma być włączone. Scena ustawia wyżej `pixelated`, stąd jawne `auto`. */
  image-rendering: auto;
  pointer-events: none;
  filter: drop-shadow(0 0 14px rgba(255, 140, 40, .85));
}
.czar--wybuch { filter: drop-shadow(0 0 26px rgba(255, 190, 90, 1)) brightness(1.5); }

/* Pełne kółko ładowania pulsuje — inaczej gracz nie wie, że ult czeka
   na starcie, i wygląda to jak zacięty pasek. */
.profil--gotowy .profil-kolo { animation: gotowy-ult 1.1s ease-in-out infinite; }
@keyframes gotowy-ult {
  0%, 100% { filter: none; }
  50%      { filter: drop-shadow(0 0 7px var(--zloto)) brightness(1.35); }
}
@media (prefers-reduced-motion: reduce) {
  .profil--gotowy .profil-kolo { animation: none; }
}

/* POCISKI. Pozycję i rozmiar ustawia skrypt (`transform`, `width`), tu zostaje
   sam wygląd. `pointer-events` wyłączone, bo kule przelatują nad kartami
   profili — bez tego łapałyby kliknięcia zamiast nich. */
.pocisk {
  position: absolute; left: 0; top: 0; z-index: 25;
  pointer-events: none;
}
/* Zaklinacz — fioletowa kula z jaśniejszym rdzeniem. */
.pocisk--fioletowy {
  border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #F2E4FF 0 18%, var(--fiolet-jasny) 42%, #4A1E8C 100%);
  box-shadow: 0 0 10px 2px rgba(157, 92, 255, .75);
}
/* Żar — ta sama kula w ogniu. Trzy różne barwy pocisków to jedyny sposób,
   żeby w kotłowaninie rozpoznać, kto właśnie strzelił. */
.pocisk--ognisty {
  border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #FFF3D6 0 18%, #FFA23C 42%, #8C2A06 100%);
  box-shadow: 0 0 10px 2px rgba(255, 150, 60, .8);
}

/* Skrzydlaty — animowana błyskawica. GIF zapętla się sam, więc nie ma tu
   żadnego kodu animacji; skrypt ustawia rozmiar, pozycję i OBRÓT.
   BEZ `pixelated`: klatka 96×96 leci na ekranie w rozmiarze ~26 px, czyli to
   POMNIEJSZANIE — a przy pomniejszaniu wygładzanie ma być włączone, inaczej
   z błyskawicy zostaje migocząca sieczka. Odwrotnie niż przy nabojach. */
.pocisk--niebieski {
  background-image: url('assets/pociski/blyskawica.gif');
  background-size: 100% 100%;
  background-repeat: no-repeat;
  /* `auto` JAWNIE, bo scena ustawia `pixelated` wyżej i to się tu dziedziczy. */
  image-rendering: auto;
  filter: drop-shadow(0 0 6px rgba(99, 200, 255, .8));
}
/* Strzelec — wycinek z arkusza nabojów; `background-size`/`-position` liczy
   skrypt, bo zależą od rozmiaru sceny. Bez `pixelated` 9×4 piksele rozmyłyby
   się w plamę przy powiększeniu. */
.pocisk--nabój {
  background-image: url('assets/pociski/naboje.png');
  background-repeat: no-repeat;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 4px rgba(255, 214, 138, .85));
}

/* ================================================= IDLE: ETAP I PRĘDKOŚĆ
   Dwie jedyne rzeczy, którymi gracz steruje w idle, więc siedzą razem
   u góry sceny i nic nie zasłaniają. */
.idle-gora {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  z-index: 30;
  display: flex; align-items: center; gap: 12px;
  padding: 6px 10px;
  background: rgba(10, 8, 18, .85);
  border: 2px solid var(--linia);
}
.idle-etap {
  font-size: 15px; letter-spacing: .18em; color: var(--zloto);
  min-width: 46px; text-align: center;
}
/* Licznik fal jest PODRZĘDNY wobec numeru etapu — mniejszy i przygaszony,
   żeby jedno spojrzenie dawało „gdzie jestem", a dopiero drugie „ile jeszcze". */
.idle-fala {
  font-size: 10px; letter-spacing: .12em; color: var(--krem-dim);
  white-space: nowrap;
}
.idle-tempo { display: flex; gap: 4px; }
.idle-tempo-btn {
  padding: 5px 9px;
  background: #16122A; border: 2px solid var(--linia);
  color: var(--krem-dim); font-family: inherit; font-size: 11px;
  letter-spacing: .06em; cursor: pointer;
}
.idle-tempo-btn:hover { color: var(--krem); border-color: var(--linia-jasna); }
.idle-tempo-btn[aria-pressed="true"] {
  border-color: var(--fiolet); color: var(--fiolet-jasny);
  background: linear-gradient(180deg, #3A1D66, #24123F);
}

/* ------------------------------------------------------- PROFILE DRUŻYNY */
/* U GÓRY, NIE PRZY DOLE. Drużyna maszeruje po drodze na 84,5% wysokości
   sceny, więc panele zaczepione o dół siedziały dokładnie na niej i zasłaniały
   pierwszych dwóch idących. Pięć kart zajmuje ~230 px — kończą się grubo nad
   drogą, a niebo pod nimi i tak jest puste. */
.idle-profile {
  position: absolute; left: 10px; top: 10px; z-index: 30;
  display: flex; flex-direction: column; gap: 6px;
}
.profil {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 34px;
  align-items: center; gap: 8px;
  width: 232px; padding: 6px 8px;
  background: rgba(10, 8, 18, .86);
  border: 2px solid var(--linia);
}
.profil--trup { opacity: .42; border-color: #4A2530; }

/* PRZECIWNICY PO PRAWEJ, W LUSTRZE. Karta jest ta sama, odwrócona kolejność
   kolumn stawia portret od strony sceny — tak jak nasze portrety patrzą
   w stronę drogi. Rama w barwie wroga, żeby dwie kolumny kart nie zlewały się
   w jedną listę. */
.idle-profile--wrog { left: auto; right: 10px; align-items: flex-end; }
.profil--wrog {
  grid-template-columns: 34px minmax(0, 1fr) 40px;
  border-color: #6B2B3A;
}
.profil--wrog .profil-portret { order: 3; }
.profil--wrog .profil-dane { order: 2; text-align: right; }
.profil--wrog .profil-kolo { order: 1; }
.profil--wrog .profil-hp i { background: linear-gradient(90deg, #D17A7A, #D1A47A); }
/* Poziom wroga bierze się z numeru fali, nie z rozdanych punktów — bez tej
   liczby nie widać, czy przeciwnik jest wyżej od nas. */
.profil-lvl {
  font-size: 9px; color: var(--krem-dim);
  letter-spacing: .04em; margin-left: 4px;
}

.profil-portret {
  width: 40px; height: 40px; overflow: hidden;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .35); border: 1px solid var(--linia);
}
.profil-sprite { width: 46px; height: 46px; image-rendering: pixelated; }

.profil-dane { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.profil-nazwa { font-size: 11px; color: var(--krem); letter-spacing: .06em; }
.profil-hp {
  display: block; height: 6px;
  background: #241D33; border: 1px solid var(--linia-jasna);
}
.profil-hp i { display: block; height: 100%; background: linear-gradient(90deg, #7AD17A, #D1C47A); }
.profil-liczby { font-size: 9.5px; color: var(--krem-dim); }
.profil-dps { color: #F6DB8D; font-size: 8px; letter-spacing: .03em; white-space: nowrap; }

/* KÓŁKO UMIEJĘTNOŚCI jest widoczne tylko przy Żarze — jedynej postaci z ultem
   na tym etapie. Reszta kart nie dostaje pustego ozdobnika. */
.profil-kolo {
  width: 34px; height: 34px; border-radius: 50%;
  background: conic-gradient(var(--fiolet-jasny) var(--ladunek, 0deg), #241D33 0);
  display: none;
  position: relative;
}
.profil-kolo::after {
  content: ""; position: absolute; inset: 4px;
  background: #100C1E; border-radius: 50%;
}
.profil-kolo-srodek {
  position: relative; z-index: 1;
  font-size: 12px; color: var(--krem-dim);
}

/* ============================================================= ŁOWISKO
   Panel akcji leży NA scenie, w lewym dolnym rogu — pomost i woda zajmują
   cały kadr, więc sterowanie musi na nim usiąść, a nie obok. */
.lowisko-panel {
  position: absolute; left: 12px; bottom: 40px; z-index: 30;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  background: rgba(10, 8, 18, .82);
  border: 2px solid var(--linia);
}
.lowisko-stan {
  font-size: 10.5px; letter-spacing: .06em; color: var(--krem-dim);
  white-space: nowrap;
}
/* Rybacy chodzą po pomoście i siedzą w łodzi — pozycję ustawia skrypt. */
.rybak { position: absolute; left: 0; top: 0; image-rendering: pixelated; }

/* ------------------------------------- SKŁAD DRUŻYNY NA KARCIE FOLKU
   Osobna zakładka DRUŻYNA zniknęła — kolekcja i skład to jeden ekran, więc
   karta musi nieść jedno i drugie. Przycisk jest własnym elementem, a nie
   klikalną kartą: obok siedzą plusy statystyk i portret z animacją. */
.folk-druzyna-licznik {
  margin-left: auto;
  font-size: 10.5px; letter-spacing: .1em; color: var(--krem-dim);
}
.folk-druzyna-licznik b { color: var(--zloto); font-weight: normal; }

.folk-do-druzyny {
  width: 100%; padding: 5px 6px;
  background: #16122A; border: 1px solid var(--linia);
  color: var(--krem-dim); font-family: inherit; font-size: 9.5px;
  letter-spacing: .08em; cursor: pointer;
}
.folk-do-druzyny:hover:not(:disabled) { border-color: var(--zloto); color: var(--zloto); }
.folk-do-druzyny:disabled { opacity: .35; cursor: default; }
.druzyna-karta--wybrana .folk-do-druzyny {
  border-color: var(--zloto); color: #120E06; background: var(--zloto);
}

/* =============================================== MIASTO JAKO NAWIGACJA
   Mapa jest głównym sposobem chodzenia po mieście, więc lista z boku zwija
   się pod MIASTEM. Nagłówek i strzałka stoją w jednym rzędzie: nagłówek
   otwiera mapę, strzałka rozwija spis — dwie osobne czynności, dwa osobne
   przyciski, żeby jedna nie robiła drugiej przypadkiem. */
.menu-grupa { display: flex; align-items: stretch; gap: 2px; }
.menu-poz--grupa { flex: 1 1 auto; min-width: 0; }
.menu-strzalka {
  width: 30px; flex: 0 0 auto;
  background: none; border: 2px solid transparent;
  color: var(--krem-dim); font-family: inherit; font-size: 12px;
  cursor: pointer;
}
.menu-strzalka:hover { background: #16132A; color: var(--zloto); }
/* Wcięcie mówi, że to podrzędne miejsca, a nie kolejne pozycje główne. */
.menu-podlista {
  display: flex; flex-direction: column; gap: 2px;
  margin: 2px 0 2px 10px;
  border-left: 2px solid var(--linia);
  padding-left: 4px;
}

/* ---------------------------------------------- TABLICZKI NA BUDYNKACH
   Warstwa nie łapie kliknięć, łapią je same tabliczki — inaczej przezroczyste
   pole nad całą mapą przechwytywałoby wszystko dookoła nich. */
.miasto-skroty { position: absolute; inset: 0; pointer-events: none; z-index: 25; }

.miasto-skrot {
  position: absolute; left: 0; top: 0;
  /* `translate` ustawia skrypt; `translate(-50%,-50%)` w środku dołożyłoby się
     do tamtego, więc środkujemy marginesem ujemnym przez `transform-origin`
     na samym elemencie — pozycja z kodu wskazuje ŚRODEK tabliczki. */
  margin-left: -0.5px; margin-top: -0.5px;
  display: flex; align-items: center; gap: 7px;
  padding: 6px 11px 6px 8px;
  background: rgba(10, 8, 18, .82);
  border: 2px solid var(--linia-jasna);
  color: var(--krem);
  font-family: inherit; font-size: 10.5px; letter-spacing: .1em;
  white-space: nowrap; cursor: pointer;
  pointer-events: auto;
  transition: border-color .12s, background .12s;
}
.miasto-skrot-ikona { font-size: 15px; line-height: 1; }
.miasto-skrot:hover, .miasto-skrot:focus-visible {
  border-color: var(--zloto);
  background: rgba(26, 18, 6, .92);
  color: var(--zloto);
  outline: none;
}
/* Kropka-wskaźnik: łączy tabliczkę z miejscem, w które prowadzi. */
.miasto-skrot::after {
  content: "";
  position: absolute; left: 50%; bottom: -9px;
  width: 7px; height: 7px; margin-left: -3.5px;
  background: var(--linia-jasna);
  transform: rotate(45deg);
}
.miasto-skrot:hover::after, .miasto-skrot:focus-visible::after { background: var(--zloto); }

@media (prefers-reduced-motion: reduce) {
  .miasto-skrot { transition: none; }
}

/* Tabliczka niesie NAZWĘ i OPIS. Sama nazwa „DUNGEON" nic nie mówi komuś, kto
   tam jeszcze nie był — druga linia tłumaczy, czym jest to miejsce. */
.miasto-skrot { align-items: center; }
.miasto-skrot-tresc {
  display: flex; flex-direction: column; gap: 1px; align-items: flex-start;
}
.miasto-skrot-opis {
  font-size: 9px; letter-spacing: .05em; color: var(--krem-dim);
  text-transform: none;
}
.miasto-skrot:hover .miasto-skrot-opis,
.miasto-skrot:focus-visible .miasto-skrot-opis { color: #C9A85E; }

/* ------------------------------------------------- POWRÓT DO MIASTA
   Jedna strzałka w prawym górnym rogu KAŻDEGO ekranu prócz samego miasta.
   Wszystkie ekrany to `<main>` w tym samym polu siatki, więc przycisk musi
   być w środku ekranu, a nie obok — stąd `position: relative` na każdym. */
#hubScena, #scenaKopalnia, #scenaSztolnia, #scenaMarket, #scenaIdle,
#scenaFolk, #scenaMiasto, #scenaZbrojownia, #scenaDungeony,
#scenaJezioro, #scenaLodz, #scenaTablica { position: relative; }

.wroc-do-miasta {
  position: absolute; top: 10px; right: 10px; z-index: 45;
  display: flex; align-items: center; gap: 6px;
  padding: 7px 11px;
  background: rgba(10, 8, 18, .85);
  border: 2px solid var(--linia-jasna);
  color: var(--krem-dim);
  font-family: inherit; font-size: 10.5px; letter-spacing: .12em;
  cursor: pointer;
}
.wroc-do-miasta:hover, .wroc-do-miasta:focus-visible {
  border-color: var(--zloto); color: var(--zloto); outline: none;
}
.wroc-do-miasta span { font-size: 14px; line-height: 1; }

/* ============================== TELEFON: MAPA I NAGŁÓWKI
   Te reguły MUSZĄ stać na końcu pliku. Style tabliczek dopisywały się
   niżej niż media query z góry, więc przy równej wadze wygrywała kolejność
   i telefon dostawał pełnowymiarowe tabliczki, które na siebie zachodziły. */
@media (max-width: 900px), (max-height: 560px) {
  /* TABLICZKI NA MAPIE muszą się zmieścić w dziewięciu na ciasnej scenie —
     przy pełnym rozmiarze zachodziły na siebie w pięciu miejscach. */
  .miasto-skrot { padding: 4px 7px 4px 5px; gap: 5px; font-size: 8.5px; }
  .miasto-skrot-ikona { font-size: 12px; }
  .miasto-skrot-opis { font-size: 7.5px; }
  .miasto-skrot::after { bottom: -7px; width: 5px; height: 5px; margin-left: -2.5px; }

  .wroc-do-miasta { top: 6px; right: 6px; padding: 5px 8px; font-size: 9px; }
  .dungeon-naglowek { top: 6px; padding: 5px 12px; }
  .dungeon-tytul { font-size: 12px; letter-spacing: .16em; }
  .dungeon-pod { font-size: 8.5px; }
}

/* Portal na telefonie: przy niskim kadrze `min(52%, 72vh)` dawało pudełko
   wyższe od sceny, bo `vh` liczy się z CAŁEGO okna, a scena to jego kawałek.
   Sufit w procentach szerokości trzyma bramę w kadrze niezależnie od tego,
   ile miejsca zabrał pasek górny. */
@media (max-width: 900px), (max-height: 560px) {
  .portal-miejsce { width: min(42%, 46vh); }

  /* DWIE KOLUMNY KART NA TELEFONIE. Przy pełnych 232 px na stronę zostawało
     na samą walkę ~310 px z 800 — więcej miejsca zajmowały liczby o walce niż
     ona sama. Węższa karta oddaje po sto pikseli na stronę.

     Pięć kart musi się zmieścić na wysokość, więc znika też kółko umiejętności:
     mechaniki pod nim jeszcze nie ma, a zabiera najwięcej. */
  .profil {
    width: 148px; gap: 5px; padding: 4px 6px;
    grid-template-columns: 28px minmax(0, 1fr);
  }
  .profil--wrog { grid-template-columns: minmax(0, 1fr) 28px; }
  .profil-kolo { display: none; }
  .profil-portret { width: 28px; height: 28px; }
  .profil-sprite { width: 32px; height: 32px; }
  .profil-nazwa { font-size: 9px; }
  .profil-liczby { font-size: 8px; }
  .profil-dps { font-size: 7px; }
  .profil-lvl { font-size: 7.5px; }
  .idle-profile { gap: 4px; }
}

/* ======================================================= EKRANY LISTOWE
   RANKING i WIADOMOŚCI to jedyne ekrany bez sceny — nie ma tła, po którym
   chodzą postacie, jest treść do przeczytania. Dostają wspólny szkielet:
   nagłówek u góry, przewijana treść w środku, jedna linia podsumowania
   u dołu. Nagłówek i stopka NIE PRZEWIJAJĄ SIĘ RAZEM Z LISTĄ, bo przy
   dwudziestu wierszach tytuł uciekałby z ekranu razem z liczbą wyników. */
/* KOLUMNA, NIE SIATKA O STAŁYCH RZĘDACH. Przy `grid-template-rows` trzeba
   z góry wiedzieć, ile elementów ma ekran — ranking ma podium między
   nagłówkiem a tabelą, skrzynka nie ma. Kiedy rzędów było trzy, a elementów
   cztery, `1fr` dostawało PODIUM: rosło do 139 px z 333, a na tabelę zostawały
   trzy wiersze. W kolumnie rozciąga się to, co samo o to prosi. */
.scena-lista {
  position: relative;
  display: flex; flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  overflow: hidden;                     /* przewija się środek, nie ekran */
}

.lista-naglowek {
  display: flex; align-items: baseline; gap: 12px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--linia);
}
.lista-tytul {
  margin: 0; font-size: 15px; letter-spacing: .18em; color: var(--zloto);
}
.lista-pod { font-size: 10px; color: var(--krem-dim); letter-spacing: .06em; }
/* Przycisk odsuwa się na prawo sam, żeby nie trzeba było pustego elementu. */
.lista-btn {
  margin-left: auto;
  padding: 5px 12px;
  font: inherit; font-size: 9.5px; letter-spacing: .12em;
  color: var(--krem); background: var(--granat);
  border: 2px solid var(--linia-jasna); cursor: pointer;
}
.lista-btn:hover { border-color: var(--fiolet-jasny); color: var(--fiolet-jasny); }
.lista-info {
  margin: 0; padding-top: 8px;
  border-top: 2px solid var(--linia);
  font-size: 10px; color: var(--krem-dim);
}

/* ------------------------------------------------------------- RANKING */
/* PODIUM. Trzy pierwsze miejsca to jedyne, o które ktokolwiek gra — reszta
   jest listą do przewinięcia. Wysokość słupków robi `order` plus margines
   od góry: pierwszy stoi najwyżej, trzeci najniżej. */
.ranking-podium {
  display: flex; align-items: flex-end; justify-content: center; gap: 10px;
  padding: 6px 0 10px;
}
.podium-kafel {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  width: 128px; padding: 8px 6px;
  background: var(--tlo-panel);
  border: 2px solid var(--linia-jasna);
}
/* Srebro po lewej, złoto na środku, brąz po prawej — tak stoi podium i tak
   je czyta oko. W kodzie lista idzie po kolei, przestawia `order`. */
.podium-kafel--m1 { order: 2; padding-bottom: 22px; border-color: var(--zloto); }
.podium-kafel--m2 { order: 1; padding-bottom: 10px; }
.podium-kafel--m3 { order: 3; }
.podium-kafel--ja { outline: 2px solid var(--fiolet-jasny); outline-offset: -4px; }
.podium-medal { font-size: 22px; line-height: 1; }
.podium-kto {
  font-size: 11px; color: var(--krem); letter-spacing: .05em;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.podium-etap { font-size: 13px; color: var(--zloto); }
.podium-lvl { font-size: 9px; color: var(--krem-dim); }

/* Ten element bierze całą wolną wysokość i to on się przewija; `min-height: 0`
   jest konieczne, bo bez niego element w kolumnie nie schodzi poniżej swojej
   treści i przewijanie nigdy się nie włącza. */
.ranking-przewijak { flex: 1 1 auto; overflow-y: auto; min-height: 0; }
.ranking-tabela {
  width: 100%; border-collapse: collapse;
  font-size: 11px; color: var(--krem);
}
.ranking-tabela th {
  position: sticky; top: 0; z-index: 1;
  padding: 6px 8px; text-align: left;
  font-size: 9px; letter-spacing: .1em; color: var(--krem-dim);
  background: var(--tlo-panel);
  border-bottom: 2px solid var(--linia);
}
.ranking-tabela td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--linia);
}
.ranking-tabela td:first-child { color: var(--krem-dim); width: 42px; }
.ranking-tabela tr:nth-child(-n+3) td:first-child { color: var(--zloto); }
/* WŁASNY WIERSZ ŚWIECI. Przy dwudziestu graczach szukanie siebie wzrokiem po
   loginie to najczęstsza rzecz, jaką się tu robi. */
.ranking-ja td {
  background: rgba(199, 125, 255, .1);
  color: var(--fiolet-jasny);
}

/* --------------------------------------------------------- WIADOMOŚCI */
.wiadomosci-lista {
  flex: 1 1 auto; overflow-y: auto; min-height: 0;
  display: flex; flex-direction: column; gap: 8px;
}
.wiadomosc {
  padding: 8px 10px;
  background: var(--tlo-panel);
  border: 2px solid var(--linia);
  border-left-width: 4px;
}
/* Nieprzeczytane mają jaśniejszą krawędź od strony, od której czyta się
   listę — kolor w treści byłby trudniejszy do złapania okiem. */
.wiadomosc--nowa { border-left-color: var(--fiolet-jasny); }
.wiadomosc-gora {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px;
}
.wiadomosc-od { font-size: 10px; color: var(--zloto); letter-spacing: .06em; }
.wiadomosc-kiedy { margin-left: auto; font-size: 9px; color: var(--krem-dim); }
.wiadomosc-tresc {
  margin: 0; font-size: 11px; line-height: 1.5; color: var(--krem);
  white-space: pre-wrap;                /* admin pisze akapity, nie jeden ciąg */
  overflow-wrap: anywhere;
}

@media (max-width: 900px), (max-height: 560px) {
  .scena-lista { padding: 8px 10px 8px; gap: 6px; }
  .lista-tytul { font-size: 12px; }
  /* PODIUM SCHODZI DO JEDNEGO RZĘDU. Na 333 px wysokości słupki zajmowały
     139 — dwie piąte ekranu na trzy nazwiska, a na samą tabelę zostawały trzy
     wiersze. Różnicę wysokości między miejscami zostawiamy symboliczną: przy
     tej skali i tak czyta się ją z medalu, nie z tego, że słupek jest wyższy. */
  .ranking-podium { gap: 6px; padding: 0 0 4px; }
  .podium-kafel { width: 92px; padding: 4px 4px; gap: 0; }
  .podium-kafel--m1 { padding-bottom: 8px; }
  .podium-kafel--m2 { padding-bottom: 4px; }
  .podium-medal { font-size: 14px; }
  .podium-kto { font-size: 9px; }
  .podium-etap { font-size: 11px; }
  .ranking-tabela { font-size: 10px; }
  .ranking-tabela td, .ranking-tabela th { padding: 4px 6px; }
  .wiadomosc-tresc { font-size: 10px; }
}

/* ============================================================ OKNA PORTALU
   Tabela szans i wybór obozu. Leżą NA SCENIE, nie na całej stronie: obie
   rzeczy dotyczą wyłącznie bramy, a przykrywanie nimi paska zasobów
   znaczyłoby, że gracz przy wyborze traci z oczu, ile ma kryształów. */
.okno {
  position: absolute; z-index: 60;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(420px, 88%); max-height: 84%;
  display: flex; flex-direction: column;
  background: rgba(10, 8, 18, .96);
  border: 2px solid var(--linia-jasna);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .6);
}
.profil--ma-ult .profil-kolo { display: block; }
/* Szczegóły są objaśnieniem portalu, nie modalem wymagającym przerwania gry.
   Stoją po jego prawej stronie, więc sama brama i świeżo wylosowana postać
   pozostają widoczne. W ciasnym kadrze wracają bezpiecznie na środek. */
#oknoSzanse {
  left: calc(50% + 270px); top: 29%; transform: translateY(-50%);
  width: min(340px, 31vw); max-height: 76%;
}
.okno-gora {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-bottom: 2px solid var(--linia);
}
.okno-tytul {
  margin: 0; font-size: 11px; letter-spacing: .16em; color: var(--zloto);
}
.okno-licznik { font-size: 10px; color: var(--krem-dim); }
.okno-zamknij {
  margin-left: auto;
  width: 24px; height: 24px; padding: 0;
  font: inherit; font-size: 12px; line-height: 1;
  color: var(--krem-dim); background: transparent;
  border: 2px solid var(--linia); cursor: pointer;
}
.okno-zamknij:hover { color: var(--fiolet-jasny); border-color: var(--fiolet-jasny); }
.okno-tresc { overflow-y: auto; min-height: 0; padding: 8px 10px; }
.okno-tresc--siatka {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 6px;
}
.okno-stopka {
  margin: 0; padding: 7px 10px;
  border-top: 2px solid var(--linia);
  font-size: 9px; line-height: 1.5; color: var(--krem-dim);
}
.okno-pusto { grid-column: 1 / -1; margin: 0; font-size: 10px; color: var(--krem-dim); }

/* --------------------------------------------------------- TABELA SZANS */
.szansa-rzad {
  display: grid;
  grid-template-columns: 10px 84px 58px 1fr 62px;
  align-items: center; gap: 6px;
  padding: 4px 0;
  border-bottom: 1px solid var(--linia);
}
.szansa-rzad:last-child { border-bottom: none; }
/* Stopień bez ani jednej postaci zostaje na liście, ale przygaszony — gracz
   ma wiedzieć, że taki istnieje, i że dziś nie ma w nim kogo wylosować. */
.szansa-rzad--pusty { opacity: .45; }
.szansa-kropka { width: 8px; height: 8px; border-radius: 50%; }
.szansa-nazwa { font-size: 9.5px; letter-spacing: .06em; }
.szansa-ile { font-size: 10px; color: var(--krem); text-align: right; }
.szansa-slupek {
  height: 6px; background: #241D33; border: 1px solid var(--linia-jasna);
}
.szansa-slupek i { display: block; height: 100%; }
.szansa-postaci { font-size: 8.5px; color: var(--krem-dim); text-align: right; }

/* -------------------------------------------------------- WYBÓR OBOZU */
.oboz-kafel {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 3px;
  background: var(--tlo-panel);
  border: 2px solid var(--linia);
  cursor: pointer;
  /* Ramka trzyma barwę rzadkości, więc stan „stoi przy bramie" nie może iść
     kolorem ramki — idzie tłem i pełną siłą, zamiast przygaszenia. */
  opacity: .5;
}
.oboz-kafel--stoi { opacity: 1; background: rgba(199, 125, 255, .14); }
.oboz-sprite { width: 42px; height: 42px; image-rendering: pixelated; }
.oboz-nazwa {
  font-size: 8px; color: var(--krem); letter-spacing: .04em;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 900px), (max-height: 560px) {
  .okno { width: min(360px, 92%); max-height: 90%; }
  .okno-tresc { padding: 6px 8px; }
  .szansa-rzad { grid-template-columns: 8px 70px 52px 1fr 52px; gap: 4px; }
  .szansa-nazwa { font-size: 8.5px; }
  .oboz-sprite { width: 34px; height: 34px; }
}

/* ================================================= DROGA DUSZY 1–20 */
.kronika-panel {
  position: fixed; z-index: 300; top: 76px; right: 168px;
  width: min(370px, calc(100vw - 24px)); padding: 14px;
  background: rgba(12, 9, 24, .98); border: 2px solid var(--linia-jasna);
  box-shadow: 0 14px 40px rgba(0, 0, 0, .55);
}
.kronika-panel[hidden] { display: none; }
.kronika-gora { display: flex; justify-content: space-between; align-items: center; color: var(--zloto); font-size: 9px; letter-spacing: .14em; }
.kronika-gora button { width: 25px; height: 25px; color: var(--krem-dim); background: #17122A; border: 1px solid var(--linia); cursor: pointer; }
.kronika-panel h2 { margin: 12px 0 7px; color: var(--krem); font-size: 17px; letter-spacing: .06em; }
.kronika-panel p { margin: 0 0 12px; color: var(--krem-dim); font-size: 11px; line-height: 1.6; }
.kronika-postep { position: relative; height: 22px; overflow: hidden; background: #17122A; border: 1px solid var(--linia); }
.kronika-postep i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(90deg, #6340A8, #C99235); }
.kronika-postep span { position: relative; display: grid; height: 100%; place-items: center; color: #fff; font-size: 9px; letter-spacing: .08em; }
.kronika-akcja { width: 100%; margin-top: 9px; padding: 9px; color: #17101F; background: var(--zloto); border: 0; font: inherit; font-size: 10px; letter-spacing: .1em; cursor: pointer; }
.kronika-dalej { display: grid; grid-template-columns: auto 1fr; gap: 8px; margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--linia); font-size: 9px; }
.kronika-dalej small { color: var(--krem-dim); }
.kronika-dalej b { color: var(--zloto); font-weight: 400; }
.osiagniecia-lista { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 10px 0; }
.osiagniecie { min-height: 48px; padding: 7px; border: 1px solid var(--linia); background: rgba(18,13,31,.82); opacity: .48; }
.osiagniecie--zdobyte { opacity: 1; border-color: rgba(232,180,74,.62); background: linear-gradient(135deg, rgba(232,180,74,.13), rgba(41,24,65,.5)); }
.osiagniecie span { float: left; margin-right: 6px; font-size: 16px; filter: grayscale(1); }
.osiagniecie--zdobyte span { filter: none; }
.osiagniecie b, .osiagniecie small { display: block; }
.osiagniecie b { color: var(--krem); font-size: 8px; letter-spacing: .06em; }
.osiagniecie small { margin-top: 3px; color: var(--krem-dim); font-size: 7px; line-height: 1.25; }

.market-skup { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; padding: 7px; background: rgba(10, 8, 20, .96); border-bottom: 1px solid var(--linia); }
.market-skup button { padding: 6px 4px; color: var(--krem); background: #1B1530; border: 1px solid var(--linia); font: inherit; font-size: 8px; cursor: pointer; }
.market-skup button:disabled { opacity: .4; cursor: default; }

@media (max-width: 800px) {
  .kronika-panel { position: fixed; top: 64px; right: 12px; }
  .profil-haslo-pola { grid-template-columns: 1fr; }
}
.oboz-strona { font-size: 7px; letter-spacing: .06em; color: var(--zloto); }
@media (max-width: 700px) {
  #oknoSzanse { left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(360px, 92%); }
}

/* ================================================= ZLECENIA NA TABLICY
   Kartki wiszą NA DESCE z tła, więc lista leży na płótnie sceny, a nie obok
   niego. Deska zajmuje środek obrazu, stąd margines z góry — pod nagłówkiem
   i nad dolną krawędzią kadru. */
/* Położenie i rozmiar USTAWIA SKRYPT — deska jest miejscem na obrazie, a ten
   jest kadrowany „cover", więc w CSS nie da się jej trafić procentami sceny. */
.zlecenia-lista {
  position: absolute;
  display: flex; gap: 14px;
  /* NA ŚRODKU DESKI, W OBU OSIACH. Kartki mają się na niej ZMIEŚCIĆ, a nie
     wystawać poza krawędź — przy zaczepieniu u góry wyższa kartka schodziła
     pod dolną listwę i ucinało jej przycisk. */
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.zlecenie {
  /* WYSOKOŚĆ Z TREŚCI, nie z pojemnika. Przy rozciąganiu na całą deskę
     kartka miała pół ekranu pustki między opisem a paskiem. */
  /* Kartka nie może być wyższa od deski — `max-height` w parze z ucinanym
     opisem trzyma ją w kadrze także wtedy, gdy scena jest niska. */
  flex: 1 1 250px; max-width: 250px; max-height: 100%;
  display: flex; flex-direction: column; gap: 7px;
  padding: 11px 13px;
  /* Prawie nieprzezroczyste tło: przy .9 słoje deski przebijały przez opis
     i tekst robił się nieczytelny na ciemnym drewnie. */
  background: rgba(10, 8, 16, .97);
  border: 2px solid var(--linia-jasna);
  /* Lekki obrót — to kartki przybite do deski, nie rząd kafelków w tabeli. */
  transform: rotate(-.5deg);
}
.zlecenie:nth-child(2) { transform: rotate(.7deg); }
.zlecenie:nth-child(3) { transform: rotate(-.35deg); }
.zlecenie--gotowe { border-color: var(--zloto); }
.zlecenie--wziete { opacity: .5; }

.zlecenie-tytul {
  margin: 0; font-size: 13px; letter-spacing: .08em; color: var(--zloto);
}
/* Opis jasnym kremem, nie przygaszonym — to jedyne zdanie, które mówi, o co
   w zleceniu chodzi, a stało w najciemniejszym kolorze na ekranie.
   Przy ciasnym kadrze ucinamy go do dwóch wierszy: lepiej stracić ogon zdania
   niż wypchnąć z kartki licznik i przycisk, po których się w nią klika. */
.zlecenie-opis {
  margin: 0; font-size: 11px; line-height: 1.5; color: var(--krem);
  min-height: 0; overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
}
.zlecenie-cel { display: flex; align-items: center; gap: 6px; }
.zlecenie-portret {
  width: 38px; height: 38px; overflow: hidden;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .35); border: 1px solid var(--linia);
}
.zlecenie-sprite { width: 44px; height: 44px; image-rendering: pixelated; }
.zlecenie-licznik { font-size: 14px; color: var(--krem); letter-spacing: .04em; }
.zlecenie-pasek {
  display: block; height: 9px;
  background: #241D33; border: 1px solid var(--linia-jasna);
}
.zlecenie-pasek i {
  display: block; height: 100%;
  background: linear-gradient(90deg, #7AD17A, #D1C47A);
}
.zlecenie-btn {
  padding: 8px 8px;
  font: inherit; font-size: 10.5px; letter-spacing: .08em;
  color: var(--krem); background: var(--granat);
  border: 2px solid var(--linia-jasna); cursor: pointer;
}
.zlecenie-btn:disabled { opacity: .45; cursor: default; }
.zlecenie-btn:not(:disabled):hover { border-color: var(--zloto); color: var(--zloto); }

/* Znacznik przy pozycji menu — ta sama czerwona kropka co na kopercie,
   bo znaczy dokładnie to samo: coś na ciebie czeka. */
.menu-poz { position: relative; }
.menu-poz[data-znacznik]::after {
  content: attr(data-znacznik);
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  min-width: 16px; height: 16px; padding: 0 3px;
  background: #C0392B; border: 1px solid #0B0A12;
  color: #fff; font-size: 10px; line-height: 14px; text-align: center;
}

@media (max-width: 900px), (max-height: 560px) {
  .zlecenia-lista { gap: 8px; padding-top: 6px; }
  .zlecenie { flex-basis: 168px; padding: 7px 8px; gap: 5px; }
  .zlecenie-tytul { font-size: 11px; }
  .zlecenie-opis { font-size: 9.5px; line-height: 1.45; }
  .zlecenie-licznik { font-size: 12px; }
  .zlecenie-sprite { width: 32px; height: 32px; }
  .zlecenie-portret { width: 28px; height: 28px; }
  .zlecenie-btn { font-size: 9px; padding: 6px; }
}
