/* ==========================================================================
   HotelFlow — styl.css  v2
   Jeden arkusz zamiast sześciu warstw.

   ARCHITEKTURA TOKENÓW — trzy warstwy, 96 zmiennych + 21 zgodnościowych
     1. PRYMITYWY   (39) — surowe wartości, zero znaczenia. Nigdy nie
                           używane bezpośrednio w regułach komponentów.
     2. SEMANTYCZNE (45) — role. Tego używają komponenty.
     3. KOMPONENTOWE(12) — tylko tam, gdzie wartość powtarza się w kilku
                           regułach jednego komponentu i musi być spójna.

   CZEGO NIE WPROWADZAM
     - tokenów per komponent dla wszystkiego (--btn-tlo, --karta-tlo itd.).
       Przy 30 komponentach to 200 zmiennych, z których 90% ma tę samą
       wartość co token semantyczny. Komponent sięga po rolę.
     - tokenów gradientu. Zostały trzy gradienty w całym systemie, każdy
       lokalny i jednorazowy.
     - osobnej skali z-index. Warstw jest pięć, wpisane wprost.
     - tokenów animacji. Dwa czasy przejścia, wpisane wprost.

   REDUKCJA WZGLĘDEM STANU WYJŚCIOWEGO
     231 kolorów hex        →  26 (8 neutralnych, 4 fazy, 8 sygnałowych,
                                   6 trybu jasnego)
     29 rozmiarów czcionki  →   7 (moduł 1,14; koniec z krokiem pół piksela)
     16 promieni            →   4
     67 cieni               →   2
     89 gradientów          →   3 (wszystkie lokalne, żadnego jako token)

   NAZEWNICTWO
     --n-<n>        prymityw neutralny, n = jasność 0–950
     --pow-<n>      powierzchnia, 0 = najgłębsza
     --tekst-<n>    poziom kontrastu tekstu, 1 = najmocniejszy
     --faza-<nazwa> kolor fazy procesu
     --ksz-<nazwa>  maska kształtu wskaźnika
     --kr-<n>       krok odstępu
     --t-<rozmiar>  krok skali typograficznej
   ========================================================================== */

/* ---------- KRÓJ PISMA --------------------------------------------------
   Inter Variable, self-hosted, SIL OFL. Dwa podzbiory: latin (niemieckie
   ä ö ü ß) i latin-ext (polskie ą ć ę ł ń ś ź ż). Przeglądarka pobiera
   tylko ten, którego użyje.
   Stos zapasowy to kroje systemowe — brak pliku nie psuje układu, tylko
   wygląd. Cyfry tabelaryczne włączone globalnie: kolumny liczbowe muszą
   się zgadzać co do piksela.
   ------------------------------------------------------------------------ */
@font-face{
  font-family:"Inter"; font-style:normal; font-weight:100 900;
  font-display:swap;
  src:url("fonty/inter-latin.woff2") format("woff2-variations");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
    U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,
    U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Inter"; font-style:normal; font-weight:100 900;
  font-display:swap;
  src:url("fonty/inter-latin-ext.woff2") format("woff2-variations");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,
    U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ==========================================================================
   WARSTWA 1 — PRYMITYWY (39)
   ========================================================================== */
:root{
  /* neutralne — 8. Odcien granatu przejety z panelu dashboard.itgration.pl
     (--navy #0c243c, --navy-d #071726), zeby oba narzedzia Michala
     wygladaly na jedna rodzine. Jasnosci zachowane z poprzedniej skali
     szarosci, wiec wszystkie kontrasty rosna lub zostaja bez zmian:
     tekst-1 13,8:1 na karcie, tekst-3 6,07:1 (bylo 5,37). */
  --n-950:#071726; --n-900:#0C243C; --n-850:#112E4A; --n-800:#173A59;
  --n-750:#1E4668; --n-400:#9DB0C4; --n-200:#BECDDC; --n-50:#EAF1F8;
  --n-500:#546E88;

  /* fazy procesu — 4. Kolor WZMACNIA kształt, nigdy nie niesie sam */
  --c-fiolet:#9B8CF0;   /* przygotowanie */
  --c-blekit:#4C9DFF;   /* logistyka     */
  --c-turkus:#2FC5B0;   /* budowa        */
  --c-zielen:#5FD97A;   /* zamknięte     */

  /* sygnały — 4 */
  --c-czerwien:#FF6B5C;
  --c-bursztyn:#FFC24D;
  /* Pomaranczowy doszedl z decyzja Macieja o slowniku kolorow: zolty
     znaczy TERAZ "czeka na moja decyzje", wiec "montaz trwa" musial
     dostac wlasny odcien. Wartosc nie jest dobrana na oko - lezy
     posrodku miedzy bursztynem (39 st.) i czerwienia (5 st.): 23,5 st.,
     czyli ~16 st. od kazdego z nich, powyzej progu rozroznialnosci na
     ramce 2px. Kontrast do tla kafelka 6,0 (WCAG dla elementu
     nietekstowego wymaga 3,0). */
  --c-pomarancz:#FF8C42;
  --c-szmaragd:#3DD68C;
  --c-lazur:#4C9DFF;

  /* skala typograficzna — 7, moduł 1,14 */
  --t-xs:11.5px; --t-s:12.5px; --t-m:14px; --t-l:16px;
  --t-xl:20px; --t-2xl:28px; --t-3xl:40px;

  /* wagi — 3 */
  --w-zwykly:400; --w-sredni:550; --w-mocny:650;

  /* odstępy — 7, moduł 4 px */
  --kr-1:4px; --kr-2:8px; --kr-3:12px; --kr-4:16px;
  --kr-5:24px; --kr-6:36px; --kr-7:56px;

  /* promienie — 4 */
  --r-s:6px; --r-m:10px; --r-l:14px; --r-pelny:999px;

  /* kroje — 1 */
  --font:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,
    Helvetica,Arial,sans-serif;

  /* prymitywy jasne — 16. Jedno miejsce prawdy dla trybu jasnego
     (widok klienta, tablica uwag) i dla druku. Oba wejścia poniżej
     tylko przemapowują role na te wartości. */
  --j-tlo:#FFFFFF;      --j-pow-2:#F4F6F8;  --j-pow-3:#E9EDF1;
  --j-tekst-1:#0D1117;  --j-tekst-2:#2C3542;
  --j-tekst-3:#55606E;  --j-tekst-4:#8A939F;
  --j-linia:#D8DEE5;    --j-linia-mocna:#B9C2CC;
  --j-akcent:#0B57A4;   --j-alarm:#A32418;
  --j-uwaga:#7A5600;    --j-ok:#1C6B3E;
  /* Pomaranczowy w motywie jasnym musi byc PRZYCIEMNIONY jak pozostale
     sygnaly (#FF8C42 na bialym tle ma kontrast 2,3 - ponizej progu 3,0).
     #9A4B0A daje 6,2 i trzyma odcien pomaranczowy (27 st., miedzy
     j-alarm 5 st. i j-uwaga 42 st.). */
  --j-praca:#9A4B0A;
  --j-faza-1:#5B4BA8;   --j-faza-2:#0B57A4;
  --j-faza-3:#0E6B62;
}

/* ==========================================================================
   WARSTWA 2 — SEMANTYCZNE (45)
   ========================================================================== */
:root{
  /* powierzchnie — 5 */
  --pow-0:var(--n-950);
  --pow-1:var(--n-900);
  --pow-2:var(--n-850);
  --pow-3:var(--n-800);
  --pow-hover:var(--n-750);

  /* tekst — 5. Kontrast na --pow-1: 16,6 / 9,2 / 5,0 / 3,0 */
  --tekst-1:var(--n-50);
  --tekst-2:var(--n-200);
  --tekst-3:var(--n-400);
  --tekst-4:var(--n-500);      /* wyłącznie elementy nietekstowe */
  --tekst-na-akcencie:#06101E;

  /* linie — 2. Odcien jak --line/--glass w panelu: chlodny blekit
     zamiast czystej bieli, zeby kreski nie odcinaly sie od granatu. */
  --linia-cicha:rgba(140,180,210,.13);
  --linia-mocna:rgba(140,180,210,.22);

  /* akcent — 3 */
  --akcent:var(--c-lazur);
  --akcent-jasny:#8FC2FF;
  --akcent-tlo:rgba(76,157,255,.14);

  /* sygnały — 8 */
  --alarm:var(--c-czerwien);   --alarm-tlo:rgba(255,107,92,.13);
  --uwaga:var(--c-bursztyn);   --uwaga-tlo:rgba(255,194,77,.13);
  /* --praca: "robota trwa". Osobny token od --uwaga, bo po decyzji
     Macieja te dwa stany znacza co innego: --uwaga = "czeka na moja
     decyzje", --praca = "ekipa wlasnie przy tym pracuje". Wczesniej
     oba szly bursztynem i dlatego zolty mowil na dwoch ekranach
     rzeczy przeciwne. */
  --praca:var(--c-pomarancz);  --praca-tlo:rgba(255,140,66,.13);
  --ok:var(--c-szmaragd);      --ok-tlo:rgba(61,214,140,.13);
  --info-tlo:rgba(76,157,255,.13);
  --neutral-tlo:var(--pow-3);

  /* fazy — 4. Do wskaźnika statusu; kolor jest wzmocnieniem kształtu */
  --faza-przygotowanie:var(--c-fiolet);
  --faza-logistyka:var(--c-blekit);
  --faza-budowa:var(--c-turkus);
  --faza-zamkniete:var(--c-zielen);

  /* maski kształtów — 8. To główny nośnik stanu:
     działa w druku B/W, przy każdej wadzie widzenia i w słońcu.
     Zweryfikowane: najgorsza para różni się o 21,9/255 przy 10 px. */
  --ksz-kwadrat-obrys:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M2%202h16v16H2V2zm3.2%203.2v9.6h9.6V5.2H5.2z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E");
  --ksz-kwadrat-pelny:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M2.6%202.6h14.8v14.8H2.6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E");
  --ksz-strzalka-obrys:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M3.4%201.6L18.6%2010%203.4%2018.4V1.6zm2.9%204.1v8.6L14.1%2010%206.3%205.7z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E");
  --ksz-strzalka-pelny:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M3.4%201.6L18.6%2010%203.4%2018.4z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E");
  --ksz-kolo-obrys:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%201.2a8.8%208.8%200%20110%2017.6%208.8%208.8%200%20010-17.6zm0%203.3a5.5%205.5%200%20100%2011%205.5%205.5%200%20000-11z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E");
  --ksz-kolo-pelny:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%201.2a8.8%208.8%200%20110%2017.6%208.8%208.8%200%20010-17.6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E");
  --ksz-haczyk:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M18.4%204.3L7.9%2014.8%201.6%208.5l2.4-2.4%203.9%203.9%208.1-8.1z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E");
  --ksz-trojkat:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%201.1l9.6%2016.6H.4L10%201.1zm0%205.6a1.25%201.25%200%2000-1.25%201.36l.37%204.1a.88.88%200%20001.76%200l.37-4.1A1.25%201.25%200%200010%206.7zm0%207.3a1.3%201.3%200%20100%202.6%201.3%201.3%200%20000-2.6z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E");
  /* dziewiąty glif — POZA rampą ośmiu. Oś stanu pomieszczenia ma dziewięć
     wartości (SNG-013 dołożyło „zaakceptowany"), a rampa faz obsadza
     siedem z nich; trójkąt jest w tym systemie zarezerwowany dla wyjątku
     (poprawka), więc „rozliczony" dostaje romb. Używany wyłącznie
     w kanale stanu pomieszczenia — plakietki .st-* i .t-* zostają
     przy ośmiu. */
  --ksz-romb:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%201.4L18.6%2010%2010%2018.6%201.4%2010z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E");
  /* dziesiąty glif — „zaakceptowany" (SNG-013). Haczyk WEWNĄTRZ koła,
     bo to potwierdzenie o stopień mocniejsze niż „zakończony": ekipa
     zamyka montaż haczykiem, właściciel przybija na nim pieczęć. Bez
     własnego kształtu ten stan spadałby na domyślny kwadrat pełny, czyli
     wyglądałby dokładnie jak „podłoga gotowa" — a wtedy jedynym, co je
     rozróżnia, byłby kolor. */
  --ksz-haczyk-kolo:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%201.2a8.8%208.8%200%20110%2017.6%208.8%208.8%200%20010-17.6zM14.6%206.6L8.9%2012.3%205.9%209.3%204.3%2010.9l4.6%204.6%207.3-7.3z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E");

  /* cienie — 2, obydwa funkcjonalne (warstwa unosząca się nad treścią) */
  --cien-warstwa:0 8px 28px rgba(0,0,0,.5);
  --cien-modal:0 24px 64px rgba(0,0,0,.6);

  /* wiersz i pole dotykowe — 3. Nadpisywane przez klasy gęstości */
  --dotyk:40px;
  --wys-wiersza:38px;
  --pad-komorki:9px;
}

/* ==========================================================================
   WARSTWA 3 — KOMPONENTOWE (12)
   Tylko tam, gdzie wartość powtarza się w kilku regułach jednego
   komponentu i musi pozostać spójna.
   ========================================================================== */
:root{
  --wsk-rozmiar:10px;        /* wskaźnik statusu */
  --wsk-odstep:7px;
  --pasek-wys:6px;           /* pasek postępu */
  --pasek-wys-duzy:10px;
  /* Pasek przy nagłówku piętra. Cieńszy od zwykłego, bo stoi w jednym
     wierszu z nazwą i procentem — 6 px ciągnęłoby tam oko na siebie. */
  --pasek-wys-maly:4px;
  --pasek-plan-szer:2px;
  --kpi-min:190px;           /* kafelek KPI */
  /* Kafelek pokoju wg makiety właściciela: 84 px to najwęższy kafelek,
     w którym mieści się numer „12.10" i ułamek „17/46" bez łamania. */
  --pok-min:84px;
  --brama-pas:3px;           /* brama odbioru */
  --brama-wciecie:34px;
  --nav-pad:7px;
  /* Okno pokoju miesci liste 46 pozycji wyposazenia z nazwa, kategoria
     i statusem w jednym wierszu. Przy 560px nazwa zlewala sie z kategoria
     ("Kontener prawySzafa"), a status ledwo sie miescil. */
  --modal-szer:820px;
  --asyst-rozmiar:46px;
}

/* ==========================================================================
   ZGODNOŚĆ (21)
   Stare nazwy zmiennych, używane 288 razy w blokach <style> stron.
   Nie usuwać, dopóki audyt nie pokaże zera odwołań.
   ========================================================================== */
:root{
  --tlo:var(--pow-0);        --tlo2:var(--pow-2);
  --karta:var(--pow-1);      --linia:var(--linia-cicha);
  --tekst:var(--tekst-1);    --szary:var(--tekst-3);
  --szary2:var(--tekst-3);   --stal:var(--tekst-3);
  --jasny:var(--tekst-2);    --granat:var(--tekst-1);
  --granat2:var(--pow-2);    --cyjan:var(--akcent);
  --akcent2:var(--akcent-jasny);
  --ziel:var(--ok);          --czerw:var(--alarm);
  --zolty:var(--uwaga);      --r:var(--r-l);
  --cien-s:none;             --cien-m:var(--cien-warstwa);
  --cien-l:var(--cien-modal);
  /* --granat miał w starym systemie DWIE role: tło nagłówka ORAZ kolor
     ciemnego tekstu na białej karcie. Po przejściu na ciemny motyw
     mapowanie na powierzchnię (--pow-3) dawało ciemny tekst na ciemnym
     tle - kontrast 1,23 przy progu 4,5, czyli tekst niewidoczny w 42
     miejscach 16 stron (numery pokoi, nagłówki tabel, kwoty).
     Rola TEKSTU wygrywa, bo tak uzywaja go bloki <style> stron.
     Rola TLA dostaje osobna nazwe ponizej. */
  --granat-tlo:var(--pow-3);
}

/* ==========================================================================
   PODSTAWA
   ========================================================================== */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--pow-0); color:var(--tekst-1);
  font:var(--t-m)/1.45 var(--font);
  font-feature-settings:"tnum" 1,"cv05" 1;
  -webkit-font-smoothing:antialiased;
}
::selection{background:var(--akcent-tlo)}
:focus-visible{outline:2px solid var(--akcent); outline-offset:2px}
img{max-width:100%; display:block}

/* ---------- REGUŁA TRÓJJĘZYCZNA -----------------------------------------
   Pomiar na 20 realnych parach etykiet: średni stosunek DE/PL wynosi 1,00.
   Niemiecki NIE jest tu systematycznie dłuższy — polskie frazy opisowe
   („Uszkodzone w transporcie", 24 znaki) bywają dłuższe niż niemieckie
   złożenia („Transportbeschädigung", 21).
   Problemem nie jest długość, tylko BRAK MIEJSC PODZIAŁU: złożenie typu
   „Materialbedarfsmeldung" nie ma spacji i rozepchnie wąską kolumnę.
   Stąd dwie reguły poniżej, a nie rezerwa szerokości.
   ------------------------------------------------------------------------ */
:root:lang(de),[lang="de"]{hyphens:auto}
th,td,.st,.k-l,.pietro-n,.pok-t,nav button,.zakl-b{
  overflow-wrap:anywhere;
}

/* ==========================================================================
   NAGŁÓWEK
   ========================================================================== */
header{
  display:flex; align-items:center; gap:var(--kr-5); flex-wrap:wrap;
  padding:var(--kr-3) var(--kr-5); background:var(--pow-1);
}
.logo{display:flex; align-items:center}
.logo img{height:20px; width:auto}
.logo-txt{font-size:var(--t-m); font-weight:var(--w-mocny);
  letter-spacing:-.01em}
.logo-txt::before{
  content:""; display:inline-block; width:7px; height:7px; border-radius:2px;
  background:var(--akcent); margin-right:9px; vertical-align:middle;
}
.proj{display:flex; align-items:baseline; gap:var(--kr-2); min-width:0}
.proj-n{font-size:var(--t-m); font-weight:var(--w-sredni);
  letter-spacing:-.01em}
.proj-l{font-size:var(--t-s); color:var(--tekst-3); white-space:nowrap}
.rola{
  font-size:var(--t-xs); font-weight:var(--w-sredni); padding:3px 9px;
  border-radius:var(--r-pelny); background:var(--pow-3); color:var(--tekst-2);
}
.hbox{display:flex; align-items:baseline; gap:7px}
.hbox span{font-size:var(--t-s); color:var(--tekst-3)}
.hbox b{font-size:var(--t-m); font-weight:var(--w-mocny);
  letter-spacing:-.01em; color:var(--tekst-1)}
.hbox b.zle{color:var(--alarm)}
.hdr-p{display:flex; align-items:center; gap:var(--kr-3); flex-wrap:wrap}
.hdr-kto{font-size:var(--t-s); color:var(--tekst-3)}

/* Goly <button> bez klasy dziedziczy czarny tekst z przegladarki.
   Na ciemnym motywie dawalo to kontrast 1,16 - przycisk wygladal na
   pusty prostokat (138 trafien na katalog.html: "Przypisz", "Zmien").
   Strony, ktore stawiaja wlasny kolor, i tak nadpisza ta regule. */
button{color:var(--tekst-2)}

.jezyk,.wyloguj,.btn-w{
  font:inherit; font-size:var(--t-s); color:var(--tekst-2);
  background:transparent; border:0; border-radius:var(--r-s);
  padding:7px 10px; cursor:pointer;
}
.jezyk:hover,.wyloguj:hover,.btn-w:hover{
  background:var(--pow-3); color:var(--tekst-1);
}
.jezyk{
  appearance:none; padding-right:24px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237C8899'%3E%3Cpath d='M4 6.5l4 4 4-4z'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 6px center;
  background-size:13px;
}
.jezyk option{background:var(--pow-2); color:var(--tekst-1)}

/* ==========================================================================
   NAWIGACJA I UKŁAD
   ========================================================================== */
nav{
  display:flex; gap:2px; overflow-x:auto;
  padding:0 var(--kr-5) var(--kr-3); background:var(--pow-1);
}
nav button{
  font:inherit; font-size:var(--t-s); font-weight:500; color:var(--tekst-3);
  background:none; border:0; border-radius:var(--r-s);
  padding:var(--nav-pad) var(--kr-3); cursor:pointer; white-space:nowrap;
  transition:background .12s, color .12s;
}
nav button:hover{color:var(--tekst-1); background:var(--pow-2)}
nav button.on{color:var(--tekst-1); background:var(--pow-3)}

.uklad{max-width:1500px; margin:0 auto; padding:var(--kr-6) var(--kr-5)}
main{min-width:0}
.panel{display:none}
.panel.on{display:block}

/* ==========================================================================
   GĘSTOŚĆ — trzy poziomy
   Ustawiasz klasą na <body>. Nadpisują tylko tokeny, zero reguł.
   ========================================================================== */
/* domyślna: kierownictwo i administracja, duży monitor */
body{--wys-wiersza:38px; --pad-komorki:9px; --dotyk:40px}

/* budowa: telefon, rękawice. Pole dotykowe 48 px — palec w rękawicy
   roboczej ma ok. 14 mm szerokości styku, przy 44 px trafień obok jest
   wyraźnie więcej. Baza tekstu rośnie o jeden krok. */
body.teren{
  --wys-wiersza:52px; --pad-komorki:15px; --dotyk:48px;
  --t-xs:12.5px; --t-s:14px; --t-m:16px; --t-l:18px;
  --nav-pad:11px; --wsk-rozmiar:12px;
}
body.teren{font-size:var(--t-m)}

/* klient: mniej gęstości, więcej powietrza, bez kolorów operacyjnych */
body.klient{
  --wys-wiersza:46px; --pad-komorki:13px;
  --kr-5:28px; --kr-6:44px;
}

/* ==========================================================================
   KARTA
   ========================================================================== */
.karta{
  background:var(--pow-1); border-radius:var(--r-l);
  padding:var(--kr-4) var(--kr-5) var(--kr-5); margin-bottom:var(--kr-5);
}
.karta h3{
  font-size:var(--t-m); font-weight:var(--w-mocny); letter-spacing:-.01em;
  margin:0 0 var(--kr-4); color:var(--tekst-1);
  display:flex; justify-content:space-between; align-items:baseline;
  gap:var(--kr-3); flex-wrap:wrap;
}
.karta h3 .meta{font-weight:var(--w-zwykly); font-size:var(--t-s);
  color:var(--tekst-3)}

/* ==========================================================================
   KAFELKI KPI
   ========================================================================== */
.kpi{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(var(--kpi-min),1fr));
  gap:var(--kr-3); margin-bottom:var(--kr-6);
}
.k{background:var(--pow-1); border-radius:var(--r-l); padding:var(--kr-4)}
.k-l{font-size:var(--t-s); color:var(--tekst-3); margin-bottom:var(--kr-3)}
.k-v,.k-w{
  font-size:var(--t-3xl); font-weight:var(--w-mocny); letter-spacing:-.035em;
  line-height:1; color:var(--tekst-1);
}
.k-w{font-size:var(--t-2xl)}
.k-s{font-size:var(--t-s); color:var(--tekst-3); margin-top:var(--kr-2);
  display:flex; align-items:center; gap:6px; flex-wrap:wrap}
.k-p{font-size:var(--t-xs); color:var(--tekst-4); margin-top:var(--kr-1)}
.k.ok .k-v{color:var(--ok)}
.k.alert .k-v{color:var(--alarm)}
.k.akcent{background:var(--akcent-tlo)}

.delta{font-size:var(--t-xs); font-weight:var(--w-mocny); padding:2px 7px;
  border-radius:var(--r-pelny)}
.delta.plus{color:var(--ok); background:var(--ok-tlo)}
.delta.minus{color:var(--alarm); background:var(--alarm-tlo)}

/* ==========================================================================
   PASKI POSTĘPU — cztery poziomy: obiekt, piętro, pokój, faza

   ZASADA „POKOJE W ROBOCIE"
   Pasek nie może sugerować gotowości przy otwartych pozycjach ani
   katastrofy przy normalnym tempie. Stąd trzy decyzje:

   1. Odniesieniem jest PLAN NA DZIŚ, nie 100%. Kreska planu pokazuje,
      gdzie powinniśmy być. 45% przy planie 44% wygląda dobrze, bo jest
      dobrze — i tak ma wyglądać.
   2. 100% wypełnienia NIE wystarcza do stanu „odebrane". Pasek przy 100%
      z otwartym audytem zostaje w kolorze roboczym i dostaje bursztynową
      końcówkę — wizualnie widać, że czegoś brakuje.
   3. Dopiero .odebrany zmienia pasek na pełną zieleń z haczykiem.

   0%   pusty rowek, kreska planu widoczna
   45%  wypełnienie robocze, kreska planu obok — porównanie natychmiastowe
   95%  wypełnienie robocze, kreska planu przy końcu
   100% + audyt otwarty  → wypełnienie 100%, bursztynowa końcówka 4 px
   100% + audyt zamknięty → .odebrany: zieleń, haczyk zamiast kreski
   ========================================================================== */
/* Pasek jest RZĘDEM segmentów, nie stosem.
   Wcześniej `.bar i` miało samo `display:block` w zwykłym kontekście
   blokowym — każdy segment zajmował własny wiersz o wysokości 100%
   paska, więc drugi i kolejne wychodziły POD pasek i nachodziły na
   sąsiednie karty oraz na nagłówek następnego piętra. Kontener flex
   układa je obok siebie; `flex-shrink:1` zjada zaokrąglenia sumy
   procentów, żeby ostatni segment nie wypchnął paska poza kartę. */
.pasek,.bar{
  position:relative; display:flex; align-items:stretch;
  height:var(--pasek-wys); background:var(--pow-3);
  border-radius:var(--r-pelny);
}
.pasek i,.bar i{
  display:block; height:100%; flex:0 1 auto; min-width:0;
  background:var(--faza-budowa);
}
/* Zaokrąglenie niesie PASEK, nie segment — inaczej każdy segment
   wyglądałby jak osobna pigułka z przewężeniem na styku. */
.pasek i:first-of-type,.bar i:first-of-type{
  border-radius:var(--r-pelny) 0 0 var(--r-pelny)}
.pasek i:last-of-type,.bar i:last-of-type{
  border-radius:0 var(--r-pelny) var(--r-pelny) 0}
.pasek i:only-of-type,.bar i:only-of-type{border-radius:var(--r-pelny)}
.pasek.duzy,.bar.duzy{height:var(--pasek-wys-duzy)}
.pasek.maly,.bar.maly{height:var(--pasek-wys-maly)}
.pasek .plan,.bar .plan{
  position:absolute; top:-4px; bottom:-4px; width:var(--pasek-plan-szer);
  border-radius:2px; background:var(--tekst-2);
}
/* 100% wypełnienia, ale audyt niezamknięty */
.pasek.pelny-nieodebrany i,.bar.pelny-nieodebrany i{
  background:linear-gradient(90deg,
    var(--faza-budowa) 0 calc(100% - 6px), var(--uwaga) calc(100% - 6px) 100%);
}
/* odebrane — jedyny stan z zielenią i haczykiem */
.pasek.odebrany i,.bar.odebrany i{background:var(--faza-zamkniete)}
.pasek.odebrany::after,.bar.odebrany::after{
  content:""; position:absolute; right:-16px; top:50%;
  width:11px; height:11px; transform:translateY(-50%);
  background:var(--ok);
  -webkit-mask:var(--ksz-haczyk) center/contain no-repeat;
  mask:var(--ksz-haczyk) center/contain no-repeat;
}
.pasek.zablok i,.bar.zablok i{background:var(--uwaga)}

.pasek-w{display:flex; height:var(--pasek-wys-duzy); border-radius:var(--r-pelny);
  overflow:hidden; background:var(--pow-3); margin:var(--kr-3) 0}
.pasek-w i{display:block; height:100%}
.leg-w{display:flex; gap:var(--kr-4); flex-wrap:wrap;
  font-size:var(--t-xs); color:var(--tekst-3)}
.leg-w b{color:var(--tekst-2); font-weight:var(--w-sredni)}
.kropka{display:inline-block; width:8px; height:8px; border-radius:2px;
  margin-right:6px; vertical-align:middle}

.pietro{
  display:grid; grid-template-columns:96px 1fr 150px; align-items:center;
  gap:var(--kr-4); padding:9px var(--kr-3); border-radius:var(--r-s);
  transition:background .12s;
}
.pietro:hover{background:var(--pow-2)}
.pietro-n{font-size:var(--t-s); color:var(--tekst-2)}
.pietro-v{font-size:var(--t-s); color:var(--tekst-3); text-align:right;
  display:flex; align-items:center; justify-content:flex-end; gap:var(--kr-2)}
.pietro-v b{color:var(--tekst-1); font-weight:var(--w-mocny)}

/* ---------- BLOK PIĘTRA: nagłówek NAD paskiem ---------------------------
   Nagłówek („Piętro 2 … 88% gotowe") i pasek to dwa osobne wiersze
   z własnym odstępem. Wcześniej żadna z tych klas nie miała reguły:
   nazwa, zakres numerów i procent skleiły się w jedną linię tekstu,
   a pasek startował tuż pod nią. Ustawiony odstęp jest tu warunkiem
   czytelności, nie ozdobą.
   ------------------------------------------------------------------------ */
.pietro-blok{margin-bottom:var(--kr-4)}
.pietro-blok:last-child{margin-bottom:0}
/* Wyrównanie do ŚRODKA, nie do linii pisma: w rzędzie stoją teraz ikona
   piętra i pasek postępu, a wyrównane do baseline wisiały o kilka pikseli
   wyżej niż nazwa. */
.pietro-h{
  display:flex; align-items:center; gap:var(--kr-2) var(--kr-3);
  flex-wrap:wrap; margin-bottom:var(--kr-2); font-size:var(--t-s);
}
.pietro-h b{font-size:var(--t-m); font-weight:var(--w-mocny);
  color:var(--tekst-1); letter-spacing:-.01em}
.pietro-h .zakres{font-size:var(--t-xs); color:var(--tekst-3)}
.pietro-h .proc{margin-left:auto; white-space:nowrap;
  font-weight:var(--w-sredni); color:var(--tekst-2)}
.pietro-blok .pokoje{margin-top:var(--kr-2)}

/* Nagłówek piętra wg makiety właściciela: ikona warstw po lewej, a po
   prawej pasek postępu piętra, procent i przycisk zwijania. */
.pietro-ik{flex:0 0 auto; line-height:0; color:var(--tekst-3)}
.pietro-ik .ik-svg{width:15px; height:15px}
.pietro-post{display:flex; align-items:center; gap:var(--kr-3);
  margin-left:auto}
/* 140 px wg makiety. Bez shrink pasek zjadałby drobny druk obok, bez
   bazy 140 px zwężałby się do zera przy długiej nazwie piętra. */
.pietro-post .pasek{flex:0 1 140px; width:140px; min-width:56px}
.pietro-proc{white-space:nowrap; font-size:var(--t-s);
  font-weight:var(--w-mocny); color:var(--tekst-2);
  font-variant-numeric:tabular-nums}
.pietro-zwin{
  font:inherit; color:var(--tekst-3); background:none; border:0;
  border-radius:var(--r-s); padding:var(--kr-1); cursor:pointer;
  line-height:0; flex:0 0 auto;
}
.pietro-zwin:hover{background:var(--pow-2); color:var(--tekst-1)}
.pietro-zwin .ik-svg{width:16px; height:16px; transition:transform .12s}
/* Zwinięte piętro: daszek obraca się o kwartę, siatka schodzi z ekranu.
   Klasa jest własna („pietro-zwiniete"), bo samo „zwiniety" należy do
   paska bocznego kokpitu i siedzi na <body>. */
.pietro-blok.pietro-zwiniete .pietro-zwin .ik-svg{transform:rotate(-90deg)}
.pietro-blok.pietro-zwiniete .pokoje{display:none}

/* ---------- LEGENDA PIONOWA I POZIOMA ------------------------------------
   Znacznik ma rozmiar i kształt, bo bez tego `<i>` z samym tłem jest
   elementem liniowym o zerowej szerokości — legenda pokazywała nazwy
   stanów i liczby, ale ani jednego koloru.
   ------------------------------------------------------------------------ */
.leg-pion{display:flex; flex-direction:column; gap:var(--kr-2)}
.leg-pion span{display:flex; align-items:center; gap:var(--wsk-odstep);
  font-size:var(--t-s); color:var(--tekst-2)}
.leg-pion b{margin-left:auto; color:var(--tekst-1);
  font-weight:var(--w-mocny); font-variant-numeric:tabular-nums}
.legenda{display:flex; flex-wrap:wrap; gap:var(--kr-2) var(--kr-4);
  margin-top:var(--kr-3); font-size:var(--t-xs); color:var(--tekst-3)}
.legenda span{display:inline-flex; align-items:center; gap:var(--wsk-odstep)}
/* Siatka bezpieczeństwa: ekrany, które wstawiają do legendy goły
   <i style="background:…">, dostają widoczny kwadracik. Bez tego
   element liniowy bez treści ma zerową szerokość i legenda pokazuje
   nazwy stanów oraz liczby, ale ani jednego koloru. */
.leg-pion i:not([class]),.legenda i:not([class]){
  display:inline-block; width:var(--wsk-rozmiar); height:var(--wsk-rozmiar);
  flex-shrink:0; border-radius:2px;
}

/* ==========================================================================
   BRAMA ODBIORU

   Stan zablokowany ma prowadzić do działania, nie wyglądać jak ściana.
   Trzy elementy:
     1. przycisk wyłączony, ale WIDOCZNY i opisany, co go odblokuje
     2. lista blokerów jako klikalne pozycje — każda prowadzi do miejsca
     3. licznik przy jednym blokerze mówi „zostało 1", przy dwudziestu
        grupuje po typie, żeby lista nie stała się ścianą tekstu

   Nigdy nie chowamy przycisku — użytkownik ma widzieć, że akcja istnieje.
   ========================================================================== */
.brama{
  background:var(--pow-2); border-radius:var(--r-m);
  padding:var(--kr-4); margin-top:var(--kr-4);
  border-left:var(--brama-pas) solid var(--uwaga);
}
.brama-h{display:flex; align-items:center; gap:var(--kr-3);
  flex-wrap:wrap; margin-bottom:var(--kr-3)}
.brama-h b{font-size:var(--t-m); font-weight:var(--w-mocny);
  color:var(--tekst-1)}
.brama-h .ile{font-size:var(--t-s); color:var(--uwaga);
  font-weight:var(--w-sredni)}
.brama-lista{display:grid; gap:2px; margin-bottom:var(--kr-3)}
.brama-poz{
  display:flex; align-items:center; gap:var(--kr-3);
  padding:8px var(--kr-3); border-radius:var(--r-s);
  font-size:var(--t-s); color:var(--tekst-2); cursor:pointer;
  background:none; border:0; text-align:left; width:100%;
  min-height:var(--dotyk); font-family:inherit;
}
.brama-poz:hover{background:var(--pow-3); color:var(--tekst-1)}
.brama-poz .gdzie{color:var(--tekst-3); margin-left:auto;
  font-size:var(--t-xs)}
.brama-poz .licz{
  font-size:var(--t-xs); font-weight:var(--w-mocny); color:var(--uwaga);
  background:var(--uwaga-tlo); padding:2px 8px; border-radius:var(--r-pelny);
}
/* przy wielu blokerach lista zwija się do grup po typie */
.brama-lista.zwinieta{max-height:calc(var(--brama-wciecie) * 4);
  overflow:hidden; position:relative}
.brama-wiecej{
  font:inherit; font-size:var(--t-s); color:var(--akcent);
  background:none; border:0; cursor:pointer; padding:6px 0;
}
.brama-akcja{display:flex; align-items:center; gap:var(--kr-3);
  flex-wrap:wrap}
.brama-akcja .powod{font-size:var(--t-xs); color:var(--tekst-3)}

/* ==========================================================================
   TABELE
   ========================================================================== */
table{width:100%; border-collapse:collapse; font-size:var(--t-s)}
th{
  text-align:left; font-size:var(--t-xs); font-weight:var(--w-sredni);
  color:var(--tekst-3); padding:0 var(--kr-3) var(--kr-3);
  white-space:nowrap; background:var(--pow-1);
  box-shadow:0 1px 0 var(--linia-cicha);
}
th.num,td.num{text-align:right}
td{padding:var(--pad-komorki) var(--kr-3); color:var(--tekst-2)}
tbody tr{transition:background .1s}
tbody tr:hover{background:var(--pow-2)}
tbody tr:hover td{color:var(--tekst-1)}
.tab-owijka{overflow-x:auto}

/* ==========================================================================
   STATUSY — podział kanałów

   Kolor NIE jest nośnikiem. Pomiar na obecnej rampie: trzy sąsiadujące
   pary nierozróżnialne przy deuteranopii, a w skali szarości „poprawka"
   i „gotowe do wysyłki" mają identyczną wartość #898989 — na wydrukowanym
   protokole pozycja uszkodzona wygląda jak gotowa do wysyłki.

   PODZIAŁ KANAŁÓW
     KSZTAŁT     → faza procesu (4 glify). Nośnik podstawowy: działa
                   w druku B/W, przy każdej wadzie widzenia, w słońcu.
     WYPEŁNIENIE → krok w fazie (obrys = pierwszy, pełny = drugi)
     KOLOR       → wzmocnienie fazy. Przyspiesza skanowanie, nigdy nie
                   niesie sam.
     TŁO PLAKIETKI → wyłącznie stany terminalne (zamontowane, poprawka)
     KSZTAŁT WYJĄTKOWY → trójkąt ostrzegawczy = poprawka. Poprawka nie
                   jest fazą, tylko wyjątkiem, więc wypada z rampy.
     TEKST       → zawsze obecny w tabeli. Ikona odciąża czytanie,
                   nie zastępuje go.

   MAPOWANIE
     kwadrat  obrys/pełny  → projekt / w produkcji
     strzałka obrys/pełny  → gotowe do wysyłki / w transporcie
     koło     obrys/pełny  → dostarczone / w montażu
     haczyk                → zamontowane
     trójkąt               → poprawka

   ELEMENT NA STATUSIE „MONTAŻ" Z OTWARTĄ USTERKĄ „USZKODZENIE"
   Usterka NIE modyfikuje statusu — to osobny kanał, druga plakietka:
     <span class="st st-w_montazu">W montażu</span>
     <span class="t-uszkodzenie">Uszkodzenie</span>
   Pierwsza mówi, gdzie pozycja jest w procesie (pełne koło, turkus).
   Druga mówi, co ją blokuje (trójkąt, czerwień). Dwie informacje
   ortogonalne zostają ortogonalne — mieszanie ich w jeden kolor
   kosztowałoby jedną z nich.
   ========================================================================== */
.st{
  display:inline-flex; align-items:center; gap:var(--wsk-odstep);
  white-space:nowrap; font-size:var(--t-xs); font-weight:var(--w-sredni);
  padding:3px 9px 3px 7px; border-radius:var(--r-pelny);
  background:var(--pow-3); color:var(--tekst-2);
}
.st::before{
  content:""; width:var(--wsk-rozmiar); height:var(--wsk-rozmiar);
  flex-shrink:0; background:currentColor;
  -webkit-mask-position:center; mask-position:center;
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
}
/* faza 1 — przygotowanie */
.st-projekt::before{
  -webkit-mask-image:var(--ksz-kwadrat-obrys); mask-image:var(--ksz-kwadrat-obrys);
  background:var(--faza-przygotowanie)}
.st-produkcja::before,.st-w_produkcji::before{
  -webkit-mask-image:var(--ksz-kwadrat-pelny); mask-image:var(--ksz-kwadrat-pelny);
  background:var(--faza-przygotowanie)}
/* faza 2 — logistyka */
.st-gotowe_do_wysylki::before{
  -webkit-mask-image:var(--ksz-strzalka-obrys); mask-image:var(--ksz-strzalka-obrys);
  background:var(--faza-logistyka)}
.st-transport::before,.st-w_transporcie::before{
  -webkit-mask-image:var(--ksz-strzalka-pelny); mask-image:var(--ksz-strzalka-pelny);
  background:var(--faza-logistyka)}
/* faza 3 — budowa */
.st-dostarczone::before{
  -webkit-mask-image:var(--ksz-kolo-obrys); mask-image:var(--ksz-kolo-obrys);
  background:var(--faza-budowa)}
.st-montaz::before,.st-w_montazu::before{
  -webkit-mask-image:var(--ksz-kolo-pelny); mask-image:var(--ksz-kolo-pelny);
  background:var(--faza-budowa)}
/* faza 4 — zamknięte */
.st-zamontowane{background:var(--ok-tlo); color:var(--ok)}
.st-zamontowane::before{
  -webkit-mask-image:var(--ksz-haczyk); mask-image:var(--ksz-haczyk)}
/* wyjątek */
.st-poprawka{background:var(--alarm-tlo); color:var(--alarm)}
.st-poprawka::before{
  -webkit-mask-image:var(--ksz-trojkat); mask-image:var(--ksz-trojkat)}

/* statusy usterek — trzy stany, kanał tła + kształt */
.st-otwarta{background:var(--alarm-tlo); color:var(--alarm)}
.st-otwarta::before{
  -webkit-mask-image:var(--ksz-trojkat); mask-image:var(--ksz-trojkat)}
.st-w_toku{background:var(--uwaga-tlo); color:var(--uwaga)}
.st-w_toku::before{
  -webkit-mask-image:var(--ksz-kolo-pelny); mask-image:var(--ksz-kolo-pelny)}
.st-wykonane,.st-zamknieta,.st-zakonczony{background:var(--ok-tlo);
  color:var(--ok)}
.st-wykonane::before,.st-zamknieta::before,.st-zakonczony::before{
  -webkit-mask-image:var(--ksz-haczyk); mask-image:var(--ksz-haczyk)}

/* ---------- TYPY USTEREK — sześć, osobny kanał od statusu ---------------
   Dzielą kształt wyjątkowy (trójkąt) tam, gdzie chodzi o uszkodzenie,
   i neutralny kwadrat tam, gdzie chodzi o braki i uwagi. Kolor rozdziela
   pilność: czerwień — uszkodzenie, bursztyn — wymiana, błękit — naprawa,
   szarość — uwaga i akcesoria.
   ------------------------------------------------------------------------ */
.t-naprawa,.t-do_naprawy,.t-wymiana,.t-do_wymiany,.t-brak,.t-uszkodzenie,
.t-uszkodzone_w_transporcie,.t-poprawka,.t-uwaga,.t-akcesoria{
  display:inline-flex; align-items:center; gap:var(--wsk-odstep);
  font-size:var(--t-xs); font-weight:var(--w-sredni); padding:3px 9px 3px 7px;
  border-radius:var(--r-pelny); white-space:nowrap;
}
.t-naprawa::before,.t-do_naprawy::before,.t-wymiana::before,
.t-do_wymiany::before,.t-brak::before,.t-uszkodzenie::before,
.t-uszkodzone_w_transporcie::before,.t-poprawka::before,.t-uwaga::before,
.t-akcesoria::before{
  content:""; width:var(--wsk-rozmiar); height:var(--wsk-rozmiar);
  flex-shrink:0; background:currentColor;
  -webkit-mask-position:center; mask-position:center;
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-image:var(--ksz-kwadrat-obrys);
  mask-image:var(--ksz-kwadrat-obrys);
}
.t-naprawa,.t-do_naprawy{background:var(--info-tlo); color:var(--akcent)}
.t-naprawa::before,.t-do_naprawy::before{
  -webkit-mask-image:var(--ksz-kolo-obrys); mask-image:var(--ksz-kolo-obrys)}
.t-wymiana,.t-do_wymiany{background:var(--uwaga-tlo); color:var(--uwaga)}
.t-wymiana::before,.t-do_wymiany::before{
  -webkit-mask-image:var(--ksz-strzalka-pelny);
  mask-image:var(--ksz-strzalka-pelny)}
.t-brak{background:var(--neutral-tlo); color:var(--tekst-2)}
.t-brak::before{
  -webkit-mask-image:var(--ksz-kwadrat-obrys);
  mask-image:var(--ksz-kwadrat-obrys)}
.t-uszkodzenie,.t-uszkodzone_w_transporcie,.t-poprawka{
  background:var(--alarm-tlo); color:var(--alarm)}
.t-uszkodzenie::before,.t-uszkodzone_w_transporcie::before,
.t-poprawka::before{
  -webkit-mask-image:var(--ksz-trojkat); mask-image:var(--ksz-trojkat)}
.t-uwaga{background:var(--neutral-tlo); color:var(--tekst-3)}
.t-uwaga::before{
  -webkit-mask-image:var(--ksz-kolo-pelny); mask-image:var(--ksz-kolo-pelny)}
.t-akcesoria{background:var(--neutral-tlo); color:var(--tekst-2)}
.t-akcesoria::before{
  -webkit-mask-image:var(--ksz-kwadrat-pelny);
  mask-image:var(--ksz-kwadrat-pelny)}

/* ==========================================================================
   ZNACZNIK STANU — kwadracik legendy i kafelka pokoju

   Legenda ma mówić, co znaczy kolor na pasku. Sam kolor tego nie mówi
   nikomu, kto go nie rozróżnia, więc znacznik nie jest kwadracikiem:
   nosi TEN SAM glif co plakietka .st-* danego stanu. Kolor wchodzi
   inline z funkcji barwa() — z tej samej, która maluje segmenty paska,
   więc legenda nie ma jak rozjechać się z tym, co widać na pasku.

   Dwa zestawy, bo system ma dwie niezależne osie:
     .zn-<status>  — status pozycji (8 wartości, rampa faz)
     .zs-<stan>    — stan pomieszczenia (9 wartości, z „zaakceptowany")
   ========================================================================== */
.zn,.zs{
  display:inline-block; width:var(--wsk-rozmiar); height:var(--wsk-rozmiar);
  flex-shrink:0; background:var(--tekst-3);
  -webkit-mask-position:center; mask-position:center;
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-image:var(--ksz-kwadrat-pelny);
  mask-image:var(--ksz-kwadrat-pelny);
}
/* statusy pozycji — glify jeden do jednego z .st-* */
.zn-projekt{-webkit-mask-image:var(--ksz-kwadrat-obrys);
  mask-image:var(--ksz-kwadrat-obrys)}
.zn-produkcja{-webkit-mask-image:var(--ksz-kwadrat-pelny);
  mask-image:var(--ksz-kwadrat-pelny)}
.zn-gotowe_do_wysylki{-webkit-mask-image:var(--ksz-strzalka-obrys);
  mask-image:var(--ksz-strzalka-obrys)}
.zn-transport{-webkit-mask-image:var(--ksz-strzalka-pelny);
  mask-image:var(--ksz-strzalka-pelny)}
.zn-dostarczone{-webkit-mask-image:var(--ksz-kolo-obrys);
  mask-image:var(--ksz-kolo-obrys)}
.zn-montaz{-webkit-mask-image:var(--ksz-kolo-pelny);
  mask-image:var(--ksz-kolo-pelny)}
.zn-zamontowane{-webkit-mask-image:var(--ksz-haczyk);
  mask-image:var(--ksz-haczyk)}
.zn-poprawka{-webkit-mask-image:var(--ksz-trojkat);
  mask-image:var(--ksz-trojkat)}
/* stany pomieszczenia — ta sama logika obrys/pełny w obrębie fazy */
.zs-w_budowie{-webkit-mask-image:var(--ksz-kwadrat-obrys);
  mask-image:var(--ksz-kwadrat-obrys)}
.zs-podloga_gotowa{-webkit-mask-image:var(--ksz-kwadrat-pelny);
  mask-image:var(--ksz-kwadrat-pelny)}
.zs-gotowy_do_montazu{-webkit-mask-image:var(--ksz-kolo-obrys);
  mask-image:var(--ksz-kolo-obrys)}
.zs-montaz_trwa{-webkit-mask-image:var(--ksz-kolo-pelny);
  mask-image:var(--ksz-kolo-pelny)}
.zs-zakonczony{-webkit-mask-image:var(--ksz-haczyk);
  mask-image:var(--ksz-haczyk)}
.zs-zaakceptowany{-webkit-mask-image:var(--ksz-haczyk-kolo);
  mask-image:var(--ksz-haczyk-kolo)}
.zs-odebrany{-webkit-mask-image:var(--ksz-strzalka-obrys);
  mask-image:var(--ksz-strzalka-obrys)}
.zs-zafakturowany{-webkit-mask-image:var(--ksz-strzalka-pelny);
  mask-image:var(--ksz-strzalka-pelny)}
.zs-rozliczony{-webkit-mask-image:var(--ksz-romb);
  mask-image:var(--ksz-romb)}

/* ==========================================================================
   CHIPY I PRZYCISKI
   ========================================================================== */
.chip{
  display:inline-block; font-size:var(--t-xs); font-weight:500;
  padding:2px 8px; border-radius:var(--r-pelny); background:var(--pow-3);
  color:var(--tekst-3);
}
.chip.alarm{background:var(--alarm-tlo); color:var(--alarm)}
.chip.uwaga{background:var(--uwaga-tlo); color:var(--uwaga)}
.chip.ok{background:var(--ok-tlo); color:var(--ok)}
.zamek{background:var(--uwaga-tlo); color:var(--uwaga)}
.odebrane{background:var(--ok-tlo); color:var(--ok)}
.zamek,.odebrane{display:inline-block; font-size:var(--t-xs);
  font-weight:var(--w-sredni); padding:2px 8px; border-radius:var(--r-pelny)}

.btn{
  font:inherit; font-size:var(--t-s); font-weight:var(--w-sredni);
  color:var(--tekst-2); background:var(--pow-3); border:0;
  border-radius:var(--r-s); padding:8px 14px; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px; min-height:var(--dotyk);
  transition:background .12s, color .12s;
}
.btn:hover{background:var(--pow-hover); color:var(--tekst-1)}
.btn.pri{background:var(--akcent); color:var(--tekst-na-akcencie)}
.btn.pri:hover{background:var(--akcent-jasny)}
.btn.szary{background:var(--pow-2); color:var(--tekst-3)}
.btn.szary:hover{background:var(--pow-3); color:var(--tekst-2)}
.btn.mini{font-size:var(--t-xs); padding:5px 10px; min-height:0}
.btn.ik{padding:7px 9px}
.btn.alarm{background:var(--alarm-tlo); color:var(--alarm)}
.btn.alarm:hover{background:rgba(255,107,92,.2)}
.btn[disabled]{opacity:.45; cursor:not-allowed}
.btn kbd{font:inherit; font-size:var(--t-xs); opacity:.6}

/* ==========================================================================
   FORMULARZE
   ========================================================================== */
input[type=text],input[type=number],input[type=date],input[type=time],
input[type=password],input[type=email],select,textarea{
  font:inherit; font-size:var(--t-s); color:var(--tekst-1);
  background:var(--pow-2); border:0; border-radius:var(--r-s);
  padding:8px 11px; min-height:var(--dotyk);
}
input::placeholder,textarea::placeholder{color:var(--tekst-4)}
textarea{min-height:88px; resize:vertical; line-height:1.5}
select{appearance:none; padding-right:26px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237C8899'%3E%3Cpath d='M4 6.5l4 4 4-4z'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 8px center;
  background-size:13px}
select option{background:var(--pow-2)}
input:focus,select:focus,textarea:focus{
  box-shadow:inset 0 0 0 1px var(--linia-mocna)}
.pole{display:flex; flex-direction:column; gap:var(--kr-2)}
.pole label{font-size:var(--t-s); color:var(--tekst-3)}
.form-row{display:grid; gap:var(--kr-3);
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}

.filtry{display:flex; gap:var(--kr-2); flex-wrap:wrap; align-items:center;
  margin-bottom:var(--kr-4)}
.zakl{display:flex; gap:2px; flex-wrap:wrap; margin-bottom:var(--kr-4)}
.zakl-b{
  font:inherit; font-size:var(--t-s); font-weight:500; color:var(--tekst-3);
  background:none; border:0; border-radius:var(--r-s);
  padding:var(--nav-pad) var(--kr-3); cursor:pointer;
  min-height:var(--dotyk);
}
.zakl-b:hover{color:var(--tekst-1); background:var(--pow-2)}
.zakl-b.on{color:var(--tekst-1); background:var(--pow-3)}
.pusto{padding:var(--kr-6) var(--kr-4); text-align:center;
  font-size:var(--t-s); color:var(--tekst-3)}

/* ==========================================================================
   KAFELKI POKOI I POZYCJE
   ========================================================================== */
.pokoje{display:grid; gap:var(--kr-3);
  grid-template-columns:repeat(auto-fill,minmax(var(--pok-min),1fr))}
.pok,.pokoj{
  background:var(--pow-2); border-radius:var(--r-m); padding:var(--kr-3);
  cursor:pointer; transition:background .12s;
}
.pok:hover,.pokoj:hover{background:var(--pow-3)}
.pok-nr{font-size:var(--t-m); font-weight:var(--w-mocny);
  color:var(--tekst-1); letter-spacing:-.01em}
.pok-t{font-size:var(--t-xs); color:var(--tekst-3); margin-top:2px}

/* ---------- STANY KAFELKA POKOJU ----------------------------------------
   Obwódka jest jedynym nośnikiem stanu kafelka, więc wszystkie cztery
   warianty muszą wchodzić jednym kanałem: spokojna linia, akcent pod
   kursorem, akcent z tłem dla wybranego, alarm dla pokoju z otwartą
   usterką. Reguły są zakotwiczone w siatce .pokoje, bo klasa .pok żyje
   także w inwenturze i regulacjach jako WIERSZ listy — tam obwódka
   kafelka nie miałaby czego opisywać.
   ------------------------------------------------------------------------ */
.pokoje .pok{
  box-shadow:inset 0 0 0 1px var(--linia);
  transition:background .12s, box-shadow .12s;
}
.pokoje .pok:hover{box-shadow:inset 0 0 0 1px var(--akcent)}
.pokoje .pok.on{box-shadow:inset 0 0 0 1px var(--akcent);
  background:var(--akcent-tlo)}
/* Otwarta usterka bije najechanie i wybór: to jedyny stan, który mówi
   „tu trzeba wejść", i musi być widoczny także pod kursorem. */
.pokoje .pok.alarm,.pokoje .pok.alarm:hover{
  box-shadow:inset 0 0 0 1px var(--alarm)}

/* ---------- SNG-013: STAN MONTAŻU NA KAFELKU -----------------------------
   Maciej: „W widoku pokoi żółta linia dookoła powinna oznaczać pokój
   w montażu" i „Pokój może zapalić się na zielono dopiero kiedy ja go
   zaakceptuję".

   Żółta linia idzie przez `outline`, a NIE przez box-shadow. Ta druga
   właściwość nosi już trzy stany naraz (spokojna obwódka, akcent wybranego
   kafelka, alarm otwartej usterki) i czwarty wykluczałby jeden z nich —
   pokój w montażu z otwartą usterką pokazywałby tylko jedno z dwojga.
   Outline rysuje się niezależnie, a ujemny offset trzyma go w środku
   kafelka, więc siatka nie drga. Kafelek nie jest fokusowalny, więc nie
   ma kolizji z pierścieniem fokusu.

   Zielone TŁO dostaje wyłącznie stan „zaakceptowany".

   SŁOWNIK KOLORÓW — decyzja Macieja, pytanie o żółty (13.10.2026).
   Żółty znaczy w CAŁYM systemie jedno: „czeka na decyzję właściciela,
   piłka u mnie". Dlatego:
     pomarańczowa ramka = montaż trwa (ekipa przy tym pracuje),
     ŻÓŁTA ramka       = zakończony (czeka na akceptację Macieja),
     zielone WYPEŁNIENIE = zaakceptowany,
     czerwony          = element do wymiany.

   Przedtem żółty mówił na dwóch ekranach rzeczy PRZECIWNE: w siatce
   pokoi „robota trwa", a w regulacjach (KAFEL_CZEKA, regulacje.py:472)
   „robota skończona, brakuje podpisu". Regulacje były zgodne z nowym
   słownikiem już wcześniej, więc to siatka dostroiła się do nich.
   Powód biznesowy: Maciej chce widzieć na pierwszy rzut oka, GDZIE
   SYSTEM CZEKA NA NIEGO, a nie gdzie pracuje ekipa - przy kwadracikach
   mebli z SNG-063 ten kolor pojawi się 6 razy na jednym kafelku.

   Stan „zakończony" miał tu wcześniej ZIELONĄ ramkę (SNG-057, ta sama
   osoba zatwierdziła). Zmiana jest świadoma i nowsza: zielony zostaje
   wyłącznie dla tego, co Maciej już przejrzał.

   Klasę dla obu stanów wydaje JEDNA funkcja — mtKlasaKafelka()
   w wspolne.js. Siedem ekranów bierze kolory stamtąd, więc nie ma
   po czym się rozjechać.
   ------------------------------------------------------------------------ */
.pokoje .pok.mt-montaz{outline:2px solid var(--praca); outline-offset:-3px}
.pokoje .pok.mt-zakonczony{outline:2px solid var(--uwaga); outline-offset:-3px}
.pokoje .pok.mt-zaakceptowany{background:var(--ok-tlo)}

/* Rząd znaczników nad nazwą stanu. Każdy znacznik to IKONA z kształtem
   (koło z haczykiem, trójkąt z wykrzyknikiem) plus title i aria-label —
   sam kolor nie dociera do osoby nierozróżniającej barw, a przy 84 px
   nie ma miejsca na trzy podpisy słowem obok siebie. Nazwa stanu
   pomieszczenia stoi wypisana w .pok-stan zaraz pod tym rzędem. */
.pok-znaki{display:flex; align-items:center; gap:var(--kr-1);
  margin-top:var(--kr-2)}
.pok-zn{display:inline-flex; align-items:center; justify-content:center;
  width:18px; height:18px; flex:0 0 auto; border-radius:var(--r-pelny);
  color:var(--kol,var(--tekst-3));
  background:color-mix(in srgb, var(--kol,var(--tekst-3)) 16%, transparent)}
.pok-zn .ik-svg{width:13px; height:13px}

.pok .bar{margin-top:var(--kr-2)}
/* Procent i ułamek stoją OBOK SIEBIE, nie na dwóch końcach kafelka:
   przy 84 px rozjechane na krawędzie czytały się jak dwie osobne dane,
   a to jedna informacja („37% — czyli 17 z 46"). */
.pok-p{display:flex; align-items:baseline; gap:var(--kr-2);
  margin-top:var(--kr-2);
  font-size:var(--t-xs); color:var(--tekst-3);
  font-variant-numeric:tabular-nums}
.pok-p b{font-size:var(--t-s); font-weight:var(--w-mocny);
  color:var(--tekst-1)}
/* Stan pomieszczenia u dołu kafelka: kropka koloru z barwa() plus NAZWA.
   Sam kolor nie dociera do osoby nierozróżniającej barw, więc nazwa jest
   wypisana i może się złamać na dwie linie — przy kafelku 84 px „Gotowy
   do montażu" nie zmieści się w jednym wierszu, a nowrap wypchnąłby
   napis poza kafelek. */
.pok-stan{
  display:flex; align-items:center; gap:var(--kr-1);
  margin-top:var(--kr-2); font-size:var(--t-xs); line-height:1.3;
  color:var(--tekst-3);
}
.pok-stan::before{
  content:""; flex:0 0 auto; width:7px; height:7px; margin-top:1px;
  border-radius:var(--r-pelny); background:var(--kol,var(--tekst-4));
}
/* SNG-073: adnotacja "do naprawy" / "do wymiany" pod stanem pokoju.
   NAPIS, a nie kolejna ikona - przy 84 px trzeci znacznik ikonowy nie
   powiedzialby, ktora z dwoch rzeczy w pokoju czeka.
   Kolor niesie wage, ale sam jej nie niesie - slowo stoi wypisane.

   `white-space:nowrap` na plakietce: bez tego "Do wymiany" lamalo sie
   w POLOWIE NAPISU ("Do" / "wymiany") i kafelek z dwoma rodzajami rosl
   wyzszy od sasiadow w siatce - pokoj wygladal na zepsuty, choc dane
   byly dobre. Zmierzone wzrokowo 16.10.2026 na pokoju 1.1.
   `flex-wrap:wrap` ZOSTAJE: przy dwoch plakietkach maja spasc jedna POD
   DRUGA, a nie zostac obciete w jednym wierszu.

   PLAKIETKA WYCHODZI POZA PADDING KAFELKA (margin ujemny + padding
   wlasny). Napisy biora sie z `se_do_wymiany` - tego samego klucza co
   statusy elementu w innych ekranach - wiec SKROCIC ICH NIE WOLNO bez
   zepsucia tamtych widokow. Przy 84 px kolumny "Do wymiany" nie miesci
   sie w swietle kafelka i konczylo wielokropkiem ("Do wym..."), co przy
   DWOCH rodzajach dawalo dwa nieczytelne skroty jeden pod drugim.
   Oddanie plakietce pelnej szerokosci kafelka jest tansze niz drugi
   slownik skrotow, ktory trzeba by tlumaczyc na trzy jezyki. */
.pok-adn{display:flex; flex-wrap:wrap; gap:var(--kr-1);
  margin:var(--kr-1) calc(-1 * var(--kr-3)) 0;
  padding:0 var(--kr-1)}
.pok-adn span{font-size:var(--t-xs); line-height:1.25;
  padding:0 3px; border-radius:var(--r-s);
  white-space:nowrap; max-width:100%;
  overflow:hidden; text-overflow:ellipsis;
  letter-spacing:-.01em;
  color:var(--kol,var(--tekst-3));
  background:color-mix(in srgb, var(--kol,var(--tekst-3)) 14%, transparent)}
.pok-adn-do_wymiany{--kol:var(--alarm)}
.pok-adn-do_naprawy{--kol:var(--uwaga)}

.poz{display:flex; align-items:center; gap:var(--kr-3);
  padding:var(--pad-komorki) var(--kr-3); border-radius:var(--r-s)}
.poz:hover{background:var(--pow-2)}
.poz-n{font-size:var(--t-s); color:var(--tekst-1); flex:1; min-width:0}
/* Kategoria stoi zaraz za nazwa pozycji. Bez wlasnego odstepu oba
   napisy sklejaly sie w jeden ciag ("Kontener prawySzafa"). */
.poz-k{font-size:var(--t-xs); color:var(--tekst-3); margin-left:var(--kr-2)}
/* Ptaszek przy pozycji.

   To jest <div>, nie <input type=checkbox> - dlatego accent-color nic
   tu nie robil i niezaznaczony ptaszek byl PUSTYM kwadratem bez ramki:
   nie bylo widac, gdzie kliknac. Zglosil to Maciej.
   Ramka rysuje pole zawsze, tlo i znak dochodza po zaznaczeniu, wiec
   stan niesie ksztalt, a nie sam kolor. */
.poz-chk{
  width:22px; height:22px; flex:0 0 22px;
  display:inline-flex; align-items:center; justify-content:center;
  box-sizing:border-box; cursor:pointer;
  font-size:14px; line-height:1; font-weight:var(--w-mocny);
  color:transparent;
  border:2px solid var(--linia-mocna); border-radius:var(--r-s);
  background:var(--pow-2);
  transition:background .12s ease, border-color .12s ease;
}
.poz-chk:hover{border-color:var(--akcent); background:var(--pow-3)}
.poz-chk.done{
  border-color:var(--akcent); background:var(--akcent); color:#fff;
}

/* ---------- POZYCJE POGRUPOWANE WG GRUPY MEBLOWEJ -----------------------
   Płaska lista czterdziestu pozycji w oknie pokoju nie daje się
   przeczytać — szafa, kuchnia i łazienka schodzą osobno i osobno się
   je odbiera. Nagłówek niesie licznik „zamontowane/wszystkie", więc
   widać postęp grupy bez rozwijania. <details> zamiast własnego
   zwijania: zero stanu w JS, działa też bez skryptu.
   ------------------------------------------------------------------------ */
.poz-grupa{border-top:1px solid var(--linia-cicha)}
.poz-grupa:first-child{border-top:0}
.poz-grupa > summary{
  display:flex; align-items:center; gap:var(--kr-2);
  padding:var(--kr-3) var(--kr-2); cursor:pointer; list-style:none;
  font-size:var(--t-s); font-weight:var(--w-sredni); color:var(--tekst-1);
  min-height:var(--dotyk); border-radius:var(--r-s);
}
.poz-grupa > summary:hover{background:var(--pow-2)}
.poz-grupa > summary::-webkit-details-marker{display:none}
.poz-grupa > summary::before{
  content:""; width:7px; height:7px; flex-shrink:0; margin:0 3px;
  border-right:1.6px solid var(--tekst-3);
  border-bottom:1.6px solid var(--tekst-3);
  transform:rotate(-45deg); transition:transform .12s;
}
.poz-grupa[open] > summary::before{transform:rotate(45deg)}
.poz-grupa > summary .licz{margin-left:auto;
  font-size:var(--t-xs); font-weight:var(--w-zwykly); color:var(--tekst-3);
  font-variant-numeric:tabular-nums}

/* ==========================================================================
   OKNO POKOJU — ETAPY, ZAKŁADKI GRUP, BOKSY PRZY POZYCJI
   Zgłoszenia SNG-005 … SNG-008. Cała sekcja dotyczy wyłącznie widoku
   pokoju w panel.html; siatki pokoi i ekranu pokoj.html nie rusza.

   UWAGA: widok pokoju NIE jest już modalem. Właściciel trzy razy prosił,
   żeby kliknięcie kafelka prowadziło na pełny ekran — tak, jak widzi to
   montażysta (montaz-panel.html). Reguły niżej nie zakładają okna:
   żadna nie ustawia własnego przewijania ani wysokości.

   Reguła koloru obowiązująca w całej sekcji: kolor jest DRUGIM kanałem.
   Każdy stan niesie obok niego kształt (maska --ksz-*) albo ikonę, więc
   czyta się go w druku B/W i przy zaburzeniach rozpoznawania barw.
   ========================================================================== */

/* ---------- widok pokoju na pełnym ekranie ----------
   Przycisk powrotu stoi NAD nagłówkiem pokoju i ma podpis mówiący, gdzie
   prowadzi („Wróć do listy pokoi", nie „Wstecz"). Ten sam układ mają
   .mp-wroc w panelu Montażu i .pe-wroc w pokojach ekipy — trzy ekrany,
   jeden nawyk. */
.pok-wroc{margin-bottom:var(--kr-3)}

/* ---------- przełącznik etapów (SNG-006) ---------- */
.pe-pr{display:flex; gap:2px; flex-wrap:wrap; margin-bottom:var(--kr-3)}
.pe-b{
  appearance:none; border:0; cursor:pointer; font:inherit;
  font-size:var(--t-s); font-weight:var(--w-sredni);
  padding:7px var(--kr-3); min-height:var(--dotyk);
  border-radius:var(--r-s); background:transparent; color:var(--tekst-3);
}
.pe-b:hover{background:var(--pow-2); color:var(--tekst-1)}
/* Stan wybrany niesie tło ORAZ podkreślenie u dołu — samo tło różni się
   od sąsiada jasnością, a to jeden kanał za mało. */
.pe-b[aria-pressed="true"]{
  background:var(--pow-3); color:var(--tekst-1);
  box-shadow:inset 0 -2px 0 0 var(--akcent);
}

/* ---------- pasek postępu etapu ---------- */
/* Przy widoku „Wszystko" stoją tu DWA takie bloki, po jednym na etap.
   Każdy ma własny licznik i własne 100% — patrz hfPostepEtapow(). */
.pe-w{margin-bottom:var(--kr-2)}
.pe-w:last-child{margin-bottom:0}
.pe-et{
  display:flex; align-items:baseline; gap:var(--kr-2);
  font-size:var(--t-xs); color:var(--tekst-3); margin-bottom:3px;
}
.pe-et b{color:var(--tekst-1); font-size:var(--t-s);
  font-variant-numeric:tabular-nums}
.pe-ul{margin-left:auto; font-variant-numeric:tabular-nums}

/* ---------- zakładki grup (SNG-007) ---------- */
.gz-zakl{
  display:flex; gap:2px; flex-wrap:wrap;
  border-bottom:1px solid var(--linia-cicha); margin-bottom:var(--kr-3);
}
.gz-tab{
  appearance:none; border:0; cursor:pointer; font:inherit;
  display:flex; align-items:center; gap:var(--kr-2);
  font-size:var(--t-s); font-weight:var(--w-sredni);
  padding:7px var(--kr-3); min-height:var(--dotyk);
  background:transparent; color:var(--tekst-3);
  border-radius:var(--r-s) var(--r-s) 0 0;
}
.gz-tab:hover{background:var(--pow-2); color:var(--tekst-1)}
.gz-tab[aria-selected="true"]{
  background:var(--pow-3); color:var(--tekst-1);
  box-shadow:inset 0 -2px 0 0 var(--akcent);
}
.gz-tab .ik-svg{flex:0 0 auto; opacity:.8}
.gz-l{font-size:var(--t-xs); color:var(--tekst-3);
  font-variant-numeric:tabular-nums}
.gz-tab[aria-selected="true"] .gz-l{color:var(--tekst-2)}

/* Znacznik stanu grupy przy zakładce. Kształt niesie treść, kolor go
   wzmacnia: haczyk = gotowa, trójkąt = do regulacji, koło puste =
   niekompletna. Te same trzy maski co w reszcie systemu. */
.gz-wsk{
  width:var(--wsk-rozmiar); height:var(--wsk-rozmiar); flex:0 0 auto;
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:center; mask-position:center;
}
.gz-wsk-gotowa{background:var(--ok);
  -webkit-mask-image:var(--ksz-haczyk); mask-image:var(--ksz-haczyk)}
.gz-wsk-do_regulacji{background:var(--uwaga);
  -webkit-mask-image:var(--ksz-trojkat); mask-image:var(--ksz-trojkat)}
.gz-wsk-niekompletna{background:var(--alarm);
  -webkit-mask-image:var(--ksz-kolo-obrys); mask-image:var(--ksz-kolo-obrys)}

/* ---------- panel aktywnej zakładki ---------- */
.gz-glowa{
  display:flex; align-items:center; gap:var(--kr-3); flex-wrap:wrap;
  margin-bottom:var(--kr-3);
}
/* Plakietka stanu grupy: ten sam kształt co przy zakładce, powiększony,
   z podpisem. Właściciel odczytuje stan bez wchodzenia w listę. */
.gz-stan{
  display:inline-flex; align-items:center; gap:var(--kr-2);
  padding:5px var(--kr-3); border-radius:var(--r-pelny);
  font-size:var(--t-s); font-weight:var(--w-sredni);
}
.gz-stan .gz-wsk{width:13px; height:13px}
.gz-stan-gotowa{background:var(--ok-tlo); color:var(--ok)}
.gz-stan-do_regulacji{background:var(--uwaga-tlo); color:var(--uwaga)}
.gz-stan-niekompletna{background:var(--alarm-tlo); color:var(--alarm)}
.gz-rada{font-size:var(--t-xs); color:var(--tekst-3)}

/* Rozwijanie listy elementów. Domyślnie ZWINIĘTA: właściciel wchodzi
   do środka dopiero wtedy, gdy plakietka stanu mówi, że jest problem.

   Ramka i powierzchnia, nie samo tło pod kursorem: właściciel dwa razy
   próbował odhaczyć pozycję i nie zauważył, że lista jest zwinięta —
   przycisk bez krawędzi czytał się jak podpis sekcji. Liczbę elementów
   niesie teraz sam podpis („Pokaż 46 elementów"), więc widać, że coś
   pod nim jest. */
.gz-rozwin{
  appearance:none; cursor:pointer; font:inherit; width:100%;
  display:flex; align-items:center; gap:var(--kr-2);
  padding:var(--kr-2) var(--kr-3); min-height:var(--dotyk);
  border:1px solid var(--linia-mocna); background:var(--pow-2);
  color:var(--tekst-1); font-size:var(--t-s);
  font-weight:var(--w-sredni);
  border-radius:var(--r-s); text-align:left;
}
.gz-rozwin:hover{background:var(--pow-3); border-color:var(--akcent)}
.gz-rozwin::before{
  content:""; width:7px; height:7px; flex:0 0 auto; margin:0 3px;
  border-right:1.6px solid var(--tekst-2);
  border-bottom:1.6px solid var(--tekst-2);
  transform:rotate(-45deg); transition:transform .12s;
}
.gz-rozwin[aria-expanded="true"]::before{transform:rotate(45deg)}
/* Liczba siedzi W podpisie, więc podpis dostaje cyfry o stałej szerokości
   — inaczej napis skakał przy każdym wstrzymaniu pozycji. */
.gz-rozwin-p{font-variant-numeric:tabular-nums}

/* ---------- wiersz pozycji z boksami (SNG-005) ---------- */
/* .poz zostaje na górnej linii wiersza (nazwa, cena, status). Boksy,
   komentarz i rysunki schodzą pod nią — w jednym rzędzie nie mieszczą
   się przy 46 pozycjach i trzech językach. */
.poz-w{border-top:1px solid var(--linia-cicha); padding-bottom:var(--kr-2)}
.poz-w:first-child{border-top:0}
.poz-d{padding:0 var(--kr-3) 0 46px}

/* ---------- wiersz zwinięty — wzorzec .el z inwentura.html ----------
   Boksy, komentarz i rysunki przy KAŻDEJ z 19 pozycji dawały wiersz
   o wysokości 201 px i listę na ponad 3800 px. Teraz wiersz bez
   zgłoszenia to jedna linia: ptaszek, nazwa, grupa, plakietka.

   Samego chowania nie robi CSS — wierszPozycji() nie wstawia .poz-d
   do drzewa, dopóki wiersz jest zwinięty. Tu zostaje tylko to, czego
   JS zrobić nie może: odstęp i kreska.

   Bez .poz-d nie ma czego oddzielać od dołu, więc znika i dolny odstęp
   wiersza — to są ostatnie 8 px różnicy wobec .el w inwenturze. */
.poz-w.zwinieta{padding-bottom:0}
/* Kreska przy lewej krawędzi, dokładnie jak .el.ma. Tło zostaje przy
   powierzchni karty: pokolorowane tła zamieniają listę 46 pozycji
   w szachownicę.
   Kolor jest DODATKIEM — plakietka statusu, ikony boksów i ich podpisy
   zostają widoczne, więc nikt nie traci informacji na samym kolorze. */
.poz-w.ma{box-shadow:inset 3px 0 0 var(--kol,var(--uwaga))}
/* Te same trzy kolory, którymi niżej malują się WŁĄCZONE boksy
   (.poz-bok-regulacja / -wymiana / -brak). Żadnego nowego odcienia. */
.poz-kr-regulacja{--kol:var(--uwaga)}
.poz-kr-wymiana{--kol:var(--akcent)}
.poz-kr-brak{--kol:var(--alarm)}
/* Sam komentarz, sam rysunek albo samo wstrzymanie: usterki nie
   zgłoszono, więc kreska jest neutralna i nie udaje alarmu. */
.poz-kr-notka{--kol:var(--tekst-3)}
/* Kliknąć można cały wiersz — kursor ma to mówić, ale tylko tam, gdzie
   jest co rozwinąć. Klasę dokłada wierszPozycji() razem z handlerem,
   więc oba sygnały nigdy się nie rozjadą. Samo .poz tu nie wystarczy:
   te same wiersze rysuje pokoje-ekipa.html, gdzie nic się nie rozwija. */
.poz-klik{cursor:pointer}
/* Daszek: ten sam znak, co przy .gz-rozwin, w rozmiarze ptaszka obok —
   linia ma zostać jedną linią. Dotykowym celem jest cały wiersz;
   ten przycisk istnieje po to, żeby rozwinięcie dało się zrobić także
   tabulatorem i czytnikiem ekranu. */
.poz-roz{
  appearance:none; border:0; padding:0; background:transparent;
  cursor:pointer; flex:0 0 22px; width:22px; height:22px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--r-s);
}
.poz-roz:hover{background:var(--pow-3)}
.poz-roz::before{
  content:""; width:7px; height:7px; margin-bottom:3px;
  border-right:1.6px solid var(--tekst-3);
  border-bottom:1.6px solid var(--tekst-3);
  transform:rotate(-45deg); transition:transform .12s;
}
.poz-roz[aria-expanded="true"]::before{transform:rotate(45deg)}
.poz-boksy{display:flex; gap:var(--kr-2); flex-wrap:wrap;
  margin-bottom:var(--kr-2)}
/* Wstrzymanie pozycji (SNG-006).

   Wyglada inaczej niz boksy usterek obok, bo niesie inna informacje:
   boks mowi "z tym meblem cos jest nie tak", wstrzymanie mowi "ten
   mebel nie liczy sie w tym etapie". Gdyby wygladaly tak samo, latwo
   byloby pomylic usterke z decyzja o zakresie.
   Krawedz przerywana: pozycja jest tymczasowo poza zakresem. */
.poz-wstrz{
  appearance:none; cursor:pointer; font:inherit;
  display:inline-flex; align-items:center; gap:6px;
  padding:5px var(--kr-2); min-height:32px;
  font-size:var(--t-xs); font-weight:var(--w-sredni);
  border:1px dashed var(--linia-mocna); border-radius:var(--r-pelny);
  background:transparent; color:var(--tekst-3);
}
.poz-wstrz:hover{border-color:var(--tekst-2); color:var(--tekst-2)}
.poz-wstrz.wl{
  border-style:solid;
  border-color:color-mix(in srgb, var(--stal) 55%, transparent);
  background:color-mix(in srgb, var(--stal) 14%, transparent);
  color:var(--tekst-2);
}
/* Caly wiersz przygaszony, gdy pozycja jest wstrzymana. Przygaszenie
   NIE jest jedynym sygnalem - obok stoi plakietka z ikona pauzy
   i podpisem, wiec informacja dociera takze bez rozroznienia kolorow. */
.poz-w.wstrzymana{opacity:.62}
.poz-w.wstrzymana .poz-chk{cursor:default; border-style:dashed}

.poz-bok{
  appearance:none; cursor:pointer; font:inherit;
  display:inline-flex; align-items:center; gap:6px;
  padding:5px var(--kr-2); min-height:32px;
  font-size:var(--t-xs); font-weight:var(--w-sredni);
  border:1px solid var(--linia-mocna); border-radius:var(--r-pelny);
  background:transparent; color:var(--tekst-3);
}
/* Podświetlenie tylko dla wersji klikalnej. Plakietka bez prawa zapisu
   jest zwykłym <span> i nie może udawać przycisku. */
button.poz-bok:hover{background:var(--pow-2); color:var(--tekst-1)}
.poz-bok .ik-svg{flex:0 0 auto}
/* Włączony boks niesie TRZY kanały naraz: kształt znacznika (pusty
   kwadrat -> haczyk), tło i kolor napisu. Znacznik jest pseudoelementem,
   więc przeżywa podmianę treści przycisku przez razNaRaz().

   Znacznik WYŁĄCZONY jest jaśniejszy niż napis obok (opacity zamiast
   dziedziczenia currentColor): przy --tekst-3 pusty kwadrat zlewał się
   z tłem i nie było widać, GDZIE kliknąć - zgłosił to Maciej.
   Włączony bierze pełny kolor stanu, więc różnica zostaje czytelna. */
.poz-bok::before{
  content:""; width:13px; height:13px; flex:0 0 auto;
  background:var(--tekst-1); opacity:.55;
  -webkit-mask-image:var(--ksz-kwadrat-obrys);
  mask-image:var(--ksz-kwadrat-obrys);
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  transition:opacity .12s ease;
}
button.poz-bok:hover::before{opacity:1}
/* Klasa .wl to ten sam stan „włączony" dla wersji BEZ prawa zapisu:
   plakietka zamiast przycisku, więc bez aria-pressed. Wygląd wspólny,
   żeby ten sam stan nie wyglądał inaczej u właściciela i u inwestora. */
.poz-bok[aria-pressed="true"]::before,
.poz-bok.wl::before{
  -webkit-mask-image:var(--ksz-haczyk); mask-image:var(--ksz-haczyk);
  background:currentColor; opacity:1;
}
.poz-bok[aria-pressed="true"],
.poz-bok.wl{border-color:transparent}
.poz-bok-regulacja[aria-pressed="true"],
.poz-bok-regulacja.wl{background:var(--uwaga-tlo); color:var(--uwaga)}
.poz-bok-wymiana[aria-pressed="true"],
.poz-bok-wymiana.wl{background:var(--info-tlo); color:var(--akcent)}
.poz-bok-brak[aria-pressed="true"],
.poz-bok-brak.wl{background:var(--alarm-tlo); color:var(--alarm)}
/* Plakietka nie jest klikalna - kursor nie może tego sugerować. */
span.poz-bok{cursor:default}
/* Stan na czas zapisu: razNaRaz() blokuje przycisk, a to ma być widać. */
.poz-bok[disabled]{cursor:default; opacity:.55}

.poz-kom{width:100%; font-size:var(--t-s); margin-bottom:var(--kr-2)}
/* Odczyt bez prawa zapisu: sama treść, bez ramki pola edycji, żeby nikt
   nie próbował w nią pisać. */
.poz-kom-ro{font-size:var(--t-s); color:var(--tekst-2);
  padding:var(--kr-2) 0; margin-bottom:var(--kr-2)}

/* ---------- rysunki przy pozycji (SNG-008) ---------- */
.poz-rys{display:flex; align-items:center; gap:var(--kr-2); flex-wrap:wrap}
.poz-rys-m{
  width:44px; height:44px; object-fit:cover; flex:0 0 auto;
  border-radius:var(--r-s); border:1px solid var(--linia-cicha);
  background:var(--pow-0); cursor:zoom-in;
}
.poz-rys-l{font-size:var(--t-xs); color:var(--tekst-3)}
.poz-rys-add{
  position:relative;
  display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  padding:5px var(--kr-2); min-height:32px;
  font-size:var(--t-xs); color:var(--akcent);
  border:1px dashed var(--linia-mocna); border-radius:var(--r-pelny);
}
.poz-rys-add:hover{background:var(--pow-2)}
/* Pole pliku schowane WIZUALNIE, nie przez display:none — inaczej wypada
   z kolejności tabulatora i przycisk przestaje istnieć dla klawiatury.
   Obramowanie fokusu przejmuje etykieta przez :focus-within. */
.poz-rys-add input{
  position:absolute; width:1px; height:1px; padding:0; margin:0;
  opacity:0; overflow:hidden; clip-path:inset(50%);
}
.poz-rys-add:focus-within{outline:2px solid var(--akcent); outline-offset:2px}
.poz-rys-add input[disabled]{cursor:default}

/* ---------- plakietka statusu DOSTAWY (SNG-012) ----------
   Druga oś stanu przy tym samym meblu: gdzie stoi, czego brakuje, co
   jest uszkodzone. Rysują ją dwa ekrany — panel Dostawy (tam da się
   też klikać) i pokoje ekipy (tam sam odczyt) — więc reguła stoi tutaj,
   a nie dwa razy w blokach <style> obu widoków.

   Kolor wchodzi zmienną --kol i NIGDY nie niesie znaczenia sam: obok
   stoi ikona statusu i jego podpis. Opis („pęknięty front") jest tym,
   po co ten status w ogóle istnieje, więc mieści się w plakietce —
   przycięty wielokropkiem, żeby jedna linia została jedną linią. */
.dst-sum{display:flex; gap:var(--kr-2); flex-wrap:wrap;
  margin-bottom:var(--kr-3)}
.dst-pl{
  display:inline-flex; align-items:center; gap:4px; min-width:0;
  white-space:nowrap; font-size:var(--t-xs);
  font-weight:var(--w-sredni); padding:2px var(--kr-2);
  border-radius:var(--r-pelny); color:var(--kol,var(--tekst-2));
  background:color-mix(in srgb, var(--kol,var(--tekst-3)) 16%, transparent);
}
.dst-pl .ik-svg{width:12px; height:12px; flex:0 0 auto}
.dst-pl i{font-style:normal; opacity:.85; min-width:0;
  overflow:hidden; text-overflow:ellipsis; max-width:22ch}

/* ---------- dwa źródła plików przy pozycji ----------
   Rysunek egzemplarza dotyczy TEGO mebla w TYM pokoju, dokumentacja typu
   jest wspólna dla wszystkich 228 pokoi. Pomyłka kosztuje wyjazd ekipy,
   więc bloki muszą się różnić bez patrzenia na kolor: każdy ma własną
   ikonę, własny nagłówek i podpis mówiący, czego plik dotyczy.
   Krawędź: ciągła = ta sztuka, kreskowana = wspólne dla wszystkich. */
.poz-pliki{margin-top:var(--kr-2); padding-left:var(--kr-3)}
.poz-pliki-sztuka{border-left:2px solid var(--linia-mocna)}
.poz-pliki-typ{border-left:2px dashed var(--akcent)}
.poz-pliki-h{display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  margin-bottom:var(--kr-2); font-size:var(--t-xs); color:var(--tekst-3)}
.poz-pliki-h b{font-weight:var(--w-sredni); color:var(--tekst-2)}
.poz-pliki-h .ik-svg{flex:0 0 auto}
/* Odsyłacz do PDF-a. Dokument nie ma miniatury — zamiast pustego kafla
   stoi podpis, więc widać, co się otworzy w nowej karcie. */
.poz-typ-dok{display:inline-flex; align-items:center; gap:6px;
  max-width:100%; padding:5px var(--kr-2); min-height:32px;
  font-size:var(--t-xs); color:var(--akcent); text-decoration:none;
  border:1px solid var(--linia-cicha); border-radius:var(--r-pelny);
  background:var(--pow-2)}
.poz-typ-dok:hover{border-color:var(--akcent)}
.poz-typ-dok span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

.pusto-mini{font-size:var(--t-s); color:var(--tekst-3);
  padding:var(--kr-3) 0; margin:0}

/* ---------- RZUT POMIESZCZENIA ------------------------------------------
   MIEJSCE na rzut zostaje widoczne zawsze, OBRAZ nie. Właściciel:
   „rysunki rzutów też miały się wyświetlać tylko po kliknięciu, nie
   potrzebny jest podgląd stały […] miejsce na rzuty też powinno być".
   Stąd kafelek z ikoną i podpisem zamiast <img>: dopóki nikt nie kliknie,
   przeglądarka nie pobiera pliku, a widok pokoju otwiera się bez
   czekania na kilkumegabajtowe zdjęcie planu.

   .rzut-mini zostaje dla ekranu pokoj.html (zakładka „Rzut pokoju"), gdzie
   podgląd jest treścią zakładki, a nie dodatkiem obok statusu.
   ------------------------------------------------------------------------ */
.rzut-box{margin-top:var(--kr-3); border:1px solid var(--linia-cicha);
  border-radius:var(--r-m); overflow:hidden; background:var(--pow-2)}
.rzut-nag{display:flex; align-items:center; justify-content:space-between;
  gap:var(--kr-3); padding:var(--kr-2) var(--kr-3);
  font-size:var(--t-s); font-weight:var(--w-sredni); color:var(--tekst-2)}
.rzut-mini{display:block; width:100%; max-height:340px; object-fit:contain;
  background:var(--pow-0); cursor:zoom-in}
.rzut-zmien{display:inline-flex; align-items:center; gap:4px;
  font-size:var(--t-xs); color:var(--akcent); cursor:pointer}
/* Pokój BEZ rzutu, rola która wgrywa pliki: miejsce na plan zostaje, a
   krawędź kreskowana mówi, że jest puste. Stoi W ramce .rzut-box, więc
   własnej obwódki ani zaokrąglenia nie potrzebuje — wystarczy kreska
   oddzielająca od nagłówka. */
.rzut-brak{display:flex; align-items:center; gap:var(--kr-2);
  width:100%; padding:var(--kr-3); min-height:var(--dotyk);
  border-top:1px dashed var(--linia-cicha);
  font-size:var(--t-s); color:var(--tekst-3); cursor:pointer}
.rzut-brak:hover{color:var(--akcent)}
/* Kafelek „Pokaż rzut pokoju". Ikona planu plus podpis — dwa kanały, więc
   czyta się go bez koloru. Lupa w kursorze mówi, że kliknięcie powiększa. */
.rzut-kafel{
  appearance:none; cursor:zoom-in; font:inherit; width:100%;
  display:flex; align-items:center; gap:var(--kr-2);
  padding:var(--kr-3); min-height:var(--dotyk); text-align:left;
  border:0; border-top:1px solid var(--linia-cicha);
  background:var(--pow-0); color:var(--tekst-1); font-size:var(--t-s);
}
.rzut-kafel:hover{background:var(--pow-3); color:var(--akcent)}
.rzut-kafel .ik-svg{flex:0 0 auto}
/* Pokój BEZ rzutu w roli, która plików nie wgrywa: miejsce zostaje, ale
   mówi wprost, że planu nie ma — puste miejsce wygląda jak błąd. */
.rzut-pusto{margin:0; padding:var(--kr-3);
  border-top:1px solid var(--linia-cicha);
  font-size:var(--t-s); color:var(--tekst-3)}
.lupa{position:fixed; inset:0; z-index:60; display:flex;
  align-items:center; justify-content:center; padding:var(--kr-4);
  background:rgba(5,8,12,.86); cursor:zoom-out}
.lupa img{max-width:100%; max-height:100%; border-radius:var(--r-m)}

/* ---------- RANKING WYDAJNOŚCI -----------------------------------------
   Obecnie pozycje 1–3 mają tła medalowe z białym tekstem: kontrast
   2,23–3,34:1. Rozwiązanie: medal niesie OBWÓDKA, nie tło. Tekst zostaje
   na --tekst-1, czyli 15,3:1. Dodatkowo czyta się to jako narzędzie
   przydziału zadań, a nie tablicę wstydu — bo tło wszystkich wierszy
   jest identyczne.
   ------------------------------------------------------------------------ */
.r-poz{display:flex; align-items:center; gap:var(--kr-3);
  padding:var(--pad-komorki) var(--kr-3); border-radius:var(--r-s);
  background:var(--pow-2); color:var(--tekst-1); margin-bottom:2px}
.r-poz .msc{width:26px; font-weight:var(--w-mocny); color:var(--tekst-3);
  font-size:var(--t-s)}
.r-poz.z1{box-shadow:inset 3px 0 0 var(--uwaga)}
.r-poz.z2{box-shadow:inset 3px 0 0 var(--tekst-2)}
.r-poz.z3{box-shadow:inset 3px 0 0 #E8A06A}
.r-poz.z1 .msc,.r-poz.z2 .msc,.r-poz.z3 .msc{color:var(--tekst-1)}
.r-poz .wynik{margin-left:auto; font-weight:var(--w-mocny)}

/* ==========================================================================
   MODAL I ASYSTENT
   ========================================================================== */
/* Modal jest ukryty do czasu otwarcia klasa .on - strony przelaczaja go
   przez classList.add("on")/remove("on"). Bez tej pary regul pusty modal
   wisial na srodku kazdej strony i przyciemnial cala tresc. */
.modal{display:none; position:fixed; inset:0; background:rgba(5,8,12,.72);
  align-items:center; justify-content:center;
  padding:var(--kr-4); z-index:50}
.modal.on{display:flex}
.modal-in{background:var(--pow-1); border-radius:var(--r-l); width:100%;
  max-width:var(--modal-szer); max-height:88vh; overflow:auto;
  box-shadow:var(--cien-modal)}
.modal-h{display:flex; align-items:center; gap:var(--kr-3);
  padding:var(--kr-4) var(--kr-5); box-shadow:0 1px 0 var(--linia-cicha)}
.modal-h h2{font-size:var(--t-l); font-weight:var(--w-mocny); margin:0;
  letter-spacing:-.015em}
.modal-x{font:inherit; font-size:var(--t-xl); line-height:1;
  color:var(--tekst-3); background:none; border:0; cursor:pointer;
  margin-left:auto; padding:0 var(--kr-1)}
.modal-x:hover{color:var(--tekst-1)}
.modal-b{padding:var(--kr-5)}

/* Panele z hf-panel.js — zamienniki confirm() i prompt(). Waskie, bo
   miesci sie w nich jedno pytanie i dwa przyciski. */
.hf-panel-in{max-width:420px}
.hf-panel-opis{margin:0 0 var(--kr-4); color:var(--tekst-2);
  font-size:var(--t-s); line-height:1.55}
.hf-panel-pole{width:100%}
/* Etykieta pojawia sie tylko w panelu z kilkoma polami - przy jednym
   pytanie niesie tytul panelu. */
.hf-panel-etyk{display:block; font-size:var(--t-s); color:var(--tekst-2)}
.hf-panel-etyk + .hf-panel-etyk{margin-top:var(--kr-3)}
.hf-panel-etyk .hf-panel-pole{margin-top:var(--kr-1)}
/* SNG-052: komunikat pustego pola obowiązkowego. Stoi NAD przyciskami,
   bo tam trafia wzrok po nieudanym kliknięciu — i niesie ikonę obok
   koloru, żeby czerwień nie była jedynym nośnikiem. */
.hf-panel-blad{
  display:flex; align-items:flex-start; gap:var(--kr-2);
  margin:var(--kr-3) 0 0; padding:var(--kr-2) var(--kr-3);
  border-radius:var(--r-s); background:var(--alarm-tlo); color:var(--alarm);
  font-size:var(--t-s); line-height:1.5;
}
.hf-panel-blad::before{content:"!"; font-weight:var(--w-mocny)}
.hf-panel-akcje{display:flex; gap:var(--kr-3); justify-content:flex-end;
  margin-top:var(--kr-4); flex-wrap:wrap}

#asystent-btn{
  position:fixed; right:var(--kr-5); bottom:var(--kr-5);
  width:var(--asyst-rozmiar); height:var(--asyst-rozmiar);
  border-radius:var(--r-pelny); border:0;
  background:var(--akcent); color:var(--tekst-na-akcencie); cursor:pointer;
  box-shadow:var(--cien-warstwa); font-size:var(--t-l);
  display:flex; align-items:center; justify-content:center;
  transition:background .14s, transform .14s;
}
#asystent-btn:hover{background:var(--akcent-jasny); transform:scale(1.05)}

/* ==========================================================================
   IKONY (hf-ikony.js)
   ========================================================================== */
.ik-svg{width:1em; height:1em; flex-shrink:0; display:inline-block;
  vertical-align:-.13em}
.ik-grupa{width:16px; height:16px; color:var(--tekst-3); flex-shrink:0}

/* ==========================================================================
   WYKRESY I TABELA WIRTUALIZOWANA
   ========================================================================== */
.wyk-owijka{position:relative}
.wyk-owijka canvas{display:block; width:100%; cursor:crosshair}
.wyk-tip{position:absolute; pointer-events:none; opacity:0; z-index:5;
  background:var(--pow-3); border-radius:var(--r-s); padding:9px 11px;
  font-size:var(--t-xs); white-space:nowrap; box-shadow:var(--cien-warstwa);
  transition:opacity .1s}
.wyk-tip .d{color:var(--tekst-3); margin-bottom:5px}
.wyk-tip .r{display:flex; align-items:center; gap:7px; line-height:1.7}
.wyk-tip .r i{width:7px; height:7px; border-radius:2px; display:inline-block}
.wyk-tip .r b{margin-left:auto; font-weight:var(--w-mocny);
  padding-left:var(--kr-3)}
.wyk-leg{display:flex; gap:var(--kr-4); flex-wrap:wrap;
  font-size:var(--t-xs); color:var(--tekst-3); margin-top:var(--kr-3)}
.wyk-leg i{width:12px; height:2px; display:inline-block; margin-right:7px;
  vertical-align:middle; border-radius:2px}
/* Znacznik serii kreskowanej. Na wykresie plan i prognoza roznia sie od
   wykonania nie tylko kolorem, ale i wzorem linii - legenda ma mowic to
   samo, bo sam kolor nie dociera do osoby nierozrozniajacej barw.
   Kolor podawany w --k przy renderze, zawsze nazwa tokenu. */
.wyk-leg i.przerywana{border-radius:0;
  background-image:repeating-linear-gradient(to right,
    var(--k) 0 4px, transparent 4px 7px)}

.hf-okno{overflow-y:auto; overflow-x:hidden; position:relative}
.hf-rozpieracz{position:relative; width:100%}
.hf-wiersz{position:absolute; left:0; right:0; align-items:center;
  font-size:var(--t-s); color:var(--tekst-2); border-radius:var(--r-s);
  cursor:pointer; contain:layout style paint; display:grid;
  padding:0 var(--kr-3)}
.hf-wiersz:hover{background:var(--pow-2); color:var(--tekst-1)}
.hf-wiersz.zazn{background:var(--akcent-tlo)}
.hf-glowa{display:grid; padding:0 var(--kr-3) var(--kr-3);
  font-size:var(--t-xs); font-weight:var(--w-sredni); color:var(--tekst-3);
  box-shadow:0 1px 0 var(--linia-cicha)}
.hf-glowa button{font:inherit; color:inherit; background:none; border:0;
  padding:0; cursor:pointer; text-align:left; display:flex;
  align-items:center; gap:5px}
.hf-glowa button:hover{color:var(--tekst-1)}
.hf-glowa .strzalka{opacity:0; font-size:9px}
.hf-glowa button.sort .strzalka{opacity:1; color:var(--akcent)}
.hf-komorka{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* ==========================================================================
   RESPONSYWNOŚĆ
   ========================================================================== */
@media (max-width:900px){
  header{gap:var(--kr-3); padding:var(--kr-3)}
  nav{padding:0 var(--kr-3) var(--kr-3)}
  .uklad{padding:var(--kr-4) var(--kr-3)}
  .karta{padding:var(--kr-3)}
  .pietro{grid-template-columns:72px 1fr 116px; gap:var(--kr-3)}
  .k-v,.k-w{font-size:var(--t-2xl)}
  #asystent-btn{right:var(--kr-3); bottom:var(--kr-3)}
  /* Poniżej 900 px liczba kolumn jest USTALONA, nie wyliczana z auto-fill:
     przy 84 px minimum telefon dostawał sześć kafelków w rzędzie i numer
     pokoju robił się nieczytelny. */
  .pokoje{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:600px){
  .pokoje{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  :root{--kpi-min:140px}
}

/* ==========================================================================
   TRYB JASNY — widok klienta, tablica uwag, druk

   Ten sam system, przemapowane role na prymitywy --j-*. Wartości żyją
   w jednym miejscu (warstwa 1), tu tylko przypisanie ról.

   Dwa wejścia:
     <html data-motyw="jasny">   — widok klienta i tablica uwag
     @media print                — protokoły, dokumenty kontraktowe

   Kontrast w trybie jasnym: tekst-1 18,9:1, tekst-2 12,4:1, tekst-3 6,4:1.
   To rozwiązuje wzorzec starego --stal (#6d8190, 3,59–4,04:1 na jasnych
   tłach), który dawał 34 trafienia poniżej progu.
   ========================================================================== */
[data-motyw="jasny"]{
  --pow-0:var(--j-tlo); --pow-1:var(--j-tlo);
  --pow-2:var(--j-pow-2); --pow-3:var(--j-pow-3);
  --pow-hover:var(--j-pow-3);
  --tekst-1:var(--j-tekst-1); --tekst-2:var(--j-tekst-2);
  --tekst-3:var(--j-tekst-3); --tekst-4:var(--j-tekst-4);
  --tekst-na-akcencie:#fff;
  --linia-cicha:var(--j-linia); --linia-mocna:var(--j-linia-mocna);
  --akcent:var(--j-akcent); --akcent-jasny:var(--j-akcent);
  --akcent-tlo:#E6EFFA;
  --alarm:var(--j-alarm); --uwaga:var(--j-uwaga); --ok:var(--j-ok);
  --praca:var(--j-praca); --praca-tlo:#FBEDE0;
  --alarm-tlo:#FBEAE8; --uwaga-tlo:#FBF2DD; --ok-tlo:#E7F3EC;
  --info-tlo:#E6EFFA; --neutral-tlo:#EDF1F4;
  --faza-przygotowanie:var(--j-faza-1);
  --faza-logistyka:var(--j-faza-2);
  --faza-budowa:var(--j-faza-3);
  --faza-zamkniete:var(--j-ok);
  --cien-warstwa:0 2px 10px rgba(13,17,23,.09);
  --cien-modal:0 12px 40px rgba(13,17,23,.16);
  /* Zgodnosc: w trybie jasnym stare nazwy musza wskazywac na JASNE
     odpowiedniki, inaczej karty zostaja ciemne mimo motywu. */
  --granat:var(--j-tekst-1);   /* rola TEKSTU - ciemny na jasnym */
  --granat-tlo:var(--j-pow-3); /* rola TLA - jasna powierzchnia */
  --granat2:var(--j-pow-2);
}

/* ==========================================================================
   TRYB JASNY — druk i widok klienta
   Ten sam system, podmienione wartości. Protokoły odbioru są dokumentami
   kontraktowymi i drukują się na białym.
   Kontrast w trybie jasnym: tekst-1 18,9:1, tekst-2 12,4:1, tekst-3 6,4:1.
   To rozwiązuje wzorzec starego --stal (#6d8190, 3,59–4,04:1 na jasnych
   tłach), który dawał 34 trafienia poniżej progu.
   ========================================================================== */
@media print{
  :root{
    --pow-0:var(--j-tlo); --pow-1:var(--j-tlo);
    --pow-2:var(--j-pow-2); --pow-3:var(--j-pow-3);
    --pow-hover:var(--j-pow-3);
    --tekst-1:var(--j-tekst-1); --tekst-2:var(--j-tekst-2);
    --tekst-3:var(--j-tekst-3); --tekst-4:var(--j-tekst-4);
    --tekst-na-akcencie:#fff;
    --linia-cicha:var(--j-linia); --linia-mocna:var(--j-linia-mocna);
    --akcent:var(--j-akcent); --akcent-jasny:var(--j-akcent);
    --akcent-tlo:#E6EFFA;
    --alarm:var(--j-alarm); --uwaga:var(--j-uwaga); --ok:var(--j-ok);
    --praca:var(--j-praca); --praca-tlo:#FBEDE0;
    --alarm-tlo:#FBEAE8; --uwaga-tlo:#FBF2DD; --ok-tlo:#E7F3EC;
    --info-tlo:#E6EFFA; --neutral-tlo:#EDF1F4;
    --faza-przygotowanie:var(--j-faza-1);
    --faza-logistyka:var(--j-faza-2);
    --faza-budowa:var(--j-faza-3); --faza-zamkniete:var(--j-ok);
    --cien-warstwa:none; --cien-modal:none;
  }
  /* Kokpit dokladamy do listy: na wydruku pasek boczny i gorny to dwa
     pasy nawigacji, ktorej na papierze nie da sie kliknac, a zabieraja
     jedna trzecia szerokosci arkusza. */
  header,nav,.btn,#asystent-btn,.filtry,.zakl,.nodruk,.brama-akcja,
  .kok-bok,.kok-gora,.kok-zaslona{
    display:none}
  .kok-uklad{display:block}
  .kok-tresc{padding:0; max-width:none}
  body{background:#fff}
  .karta{break-inside:avoid; padding:0 0 var(--kr-4);
    margin-bottom:var(--kr-4); box-shadow:0 1px 0 var(--linia-cicha)}
  .uklad{padding:0; max-width:none}
  a[href]::after{content:""}
}

/* ==========================================================================
   KOKPIT (klient.html — inwestor, panel.html — CEO)

   Uklad: pasek boczny + gorny pasek + tresc. Wszystko z tokenow warstwy 2,
   zero wartosci wprost poza geometria (szerokosci, wysokosci pasow).

   JEDEN zestaw klas na oba ekrany. Roznia sie tym, co w pasku: inwestor
   ma cztery pozycje i przewija do sekcji, CEO ma osiemnascie w zwijanych
   grupach (.kok-grupa) i przelacza panele. Uklad, pasek gorny, baner,
   rzedy kart i progi responsywne sa wspolne - stad sa tutaj, a nie
   w dwoch kopiach po stronach.

   DWA TRYBY PASKA BOCZNEGO, bo to dwie rozne sytuacje:
     - szeroki ekran: pasek stoi zawsze, przycisk zwija go do samych ikon
       (--kok-pasek maleje, etykiety znikaja)
     - telefon: pasek nie miesci sie obok tresci, wiec wyjezdza z lewej
       nad trescia i zamyka sie kliknieciem w tlo
   Jedna klasa na <body> nie obsluzy obu: "zwiniety" zmienia szerokosc
   kolumny, "kok-otwarty" pokazuje szuflade. Stad dwie nazwy.
   ========================================================================== */
/* Pasek boczny: 268px. Przy 236 dlugie etykiety w grupie LOGISTYKA
   ciagle stykaly sie z krawedzia. Zwiniety zostaje na 68px - tam
   widac same ikony. */
body.kok{--kok-pasek:268px; background:var(--pow-0)}
body.kok.zwiniety{--kok-pasek:68px}

.kok-uklad{display:grid; grid-template-columns:var(--kok-pasek) minmax(0,1fr)}
/* Kolumna tresci musi MOC sie zwezic ponizej szerokosci swojej
   zawartosci. Element siatki ma domyslnie min-width:auto, wiec jedna
   szeroka tabela (transporty, faktury) rozpychala cala strone w bok -
   a pasek boczny zabral jej 208 px wzgledem starego ukladu. */
.kok-uklad>*{min-width:0}

/* ---------- pasek boczny ---------- */
.kok-bok{
  background:var(--pow-1); border-right:1px solid var(--linia-cicha);
  padding:var(--kr-4) var(--kr-3); display:flex; flex-direction:column;
  gap:var(--kr-2); position:sticky; top:0; height:100vh; overflow-y:auto;
  z-index:6;
}
.kok-bok-gora{display:flex; align-items:center; gap:var(--kr-2);
  padding:0 var(--kr-2) var(--kr-5)}
/* Pasek boczny nosi nazwe PRODUKTU, nie logo klienta - ten sam zapis co
   .marka na ekranie logowania, przyciety do wysokosci paska. Logo obiektu
   stoi w gornym pasku, przy nazwie obiektu, ktory opisuje. */
/* Znak marki: zaokraglony kwadrat z litera S, jak na makiecie.
   Kolor zmierzony probnikiem (#3970A9) mieści sie w tokenie --akcent,
   wiec bierzemy token - instancja z wlasna paleta dostanie swoj kolor
   bez dotykania tego pliku.
   aria-hidden, bo zaraz obok stoi pelna nazwa produktu - czytnik
   ekranu przeczytalby "S Snagless". */
.kok-znak{
  width:30px; height:30px; flex:0 0 auto; border-radius:var(--r-m);
  background:var(--akcent); color:var(--tekst-na-akcencie);
  display:flex; align-items:center; justify-content:center;
  font-size:var(--t-l); font-weight:var(--w-mocny); line-height:1;
}
.kok-marka{
  flex:1; min-width:0; font-size:var(--t-l); font-weight:var(--w-mocny);
  color:var(--tekst-1); letter-spacing:.5px; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
.kok-zwin{
  font:inherit; color:var(--tekst-3); background:none; border:0;
  border-radius:var(--r-s); padding:6px; cursor:pointer; line-height:0;
}
.kok-zwin:hover{background:var(--pow-3); color:var(--tekst-1)}
body.kok.zwiniety .kok-zwin svg{transform:rotate(180deg)}

.kok-nawig{display:flex; flex-direction:column; gap:2px}
/* Przewija sie SAMA lista pozycji, nie caly pasek: marka u gory i blok
   dolny zostaja na miejscu. Panel CEO ma osiemnascie zakladek - na
   ekranie laptopa lista nie miesci sie w calosci i bez tego przewijal
   sie takze naglowek paska. */
.kok-bok>.kok-nawig{flex:1 1 auto; min-height:0; overflow-y:auto;
  overscroll-behavior:contain}
.kok-nawig button{
  font:inherit; font-size:var(--t-s); font-weight:var(--w-sredni);
  color:var(--tekst-3); background:none; border:0; border-radius:var(--r-s);
  padding:0 var(--kr-3); min-height:var(--dotyk); cursor:pointer;
  display:flex; align-items:center; gap:var(--kr-3); text-align:left;
  width:100%; border-left:3px solid transparent;
  transition:background .12s, color .12s;
}
.kok-nawig button:hover{background:var(--pow-2); color:var(--tekst-1)}
.kok-nawig button.on{
  background:var(--pow-3); color:var(--tekst-1);
  border-left-color:var(--akcent);
}
.kok-nawig svg{flex-shrink:0; width:18px; height:18px}
/* Pigulka z liczba przy pozycji paska (SNG-020: alerty przy Montazu).
   Stoi PO etykiecie i dosuwa sie do prawej krawedzi przycisku, zeby
   liczby przy roznych zakladkach ustawialy sie w jednej kolumnie.
   W pasku zwinietym etykieta znika, a pigulka zostaje - jest wtedy
   jedynym znakiem, ze cos czeka. */
.kok-pig{
  margin-left:auto; flex-shrink:0; min-width:18px; padding:0 5px;
  border-radius:var(--r-pelny); background:var(--alarm);
  color:var(--tekst-na-akcencie); font-size:var(--t-xs);
  line-height:18px; font-weight:var(--w-mocny); text-align:center;
  font-variant-numeric:tabular-nums;
}
body.kok.zwiniety .kok-pig{margin-left:0}
.kok-dol{margin-top:auto; padding-top:var(--kr-4);
  border-top:1px solid var(--linia-cicha)}

/* ---------- grupy pozycji w pasku ----------
   Cztery zakladki inwestora miesza sie na jednej liscie. Osiemnascie
   zakladek CEO juz nie: to sciana, po ktorej wzrok nie ma sie o co
   zaczepic. Pozycje stoja wiec w grupach po 2-6, kazda zwijana osobno,
   a stan zwiniecia zapisuje localStorage - pasek wraca taki, jaki go
   zostawiono. Grupa z BIEZACA zakladka otwiera sie zawsze, inaczej
   wejscie z adresu #koszty nie pokazywaloby, gdzie sie jest. */
.kok-grupa{display:flex; flex-direction:column}
.kok-grupa+.kok-grupa{margin-top:var(--kr-3)}
/* Selektor przez .kok-nawig NIE jest ozdoba: regula .kok-nawig button
   wyzej ma wyzsza specyficznosc niz sama klasa i narzucilaby naglowkowi
   grupy rozmiar oraz kolor zwyklej pozycji - czyli dokladnie to
   rozroznienie, po ktore ten naglowek istnieje. */
.kok-nawig .kok-grupa-n{
  font:inherit; font-size:var(--t-xs); font-weight:var(--w-mocny);
  letter-spacing:.07em; text-transform:uppercase; color:var(--tekst-4);
  background:none; border:0; cursor:pointer; text-align:left; width:100%;
  display:flex; align-items:center; gap:var(--kr-2); min-height:0;
  padding:var(--kr-2) var(--kr-3); border-radius:var(--r-s);
}
.kok-nawig .kok-grupa-n:hover{color:var(--tekst-2); background:var(--pow-2)}
/* Strzalka stanu - ta sama geometria co w .poz-grupa, zeby zwijanie
   w calym systemie wygladalo tak samo. */
.kok-grupa-n::after{
  content:""; width:6px; height:6px; margin-left:auto; flex-shrink:0;
  border-right:1.6px solid currentColor;
  border-bottom:1.6px solid currentColor;
  transform:rotate(45deg); transition:transform .12s;
}
.kok-grupa.zwinieta .kok-grupa-n::after{transform:rotate(-45deg)}
.kok-grupa.zwinieta .kok-grupa-l{display:none}
.kok-grupa-l{display:flex; flex-direction:column; gap:2px}
/* Pasek zwiniety do samych ikon nie ma gdzie pokazac naglowkow grup.
   Chowamy je razem z etykietami - i odslaniamy wszystkie pozycje, bo
   inaczej zwinieta grupa nie dalaby sie juz rozwinac. */
body.kok.zwiniety .kok-nawig .kok-grupa-n{display:none}
body.kok.zwiniety .kok-grupa.zwinieta .kok-grupa-l{display:flex}
/* Zwiniety pasek: zostaja same ikony, etykieta wraca jako title.
   Bez wysrodkowania ikony wisialyby przy lewej krawedzi. */
body.kok.zwiniety .kok-etyk,
body.kok.zwiniety .kok-marka{display:none}
body.kok.zwiniety .kok-nawig button{justify-content:center; padding:0}
body.kok.zwiniety .kok-bok-gora{justify-content:center; padding-left:0}

/* ---------- gorny pasek ---------- */
/* Gorny pasek: wyzszy o jeden stopien odstepu (--kr-4 zamiast --kr-3).
   Mieszcza sie w nim logo klienta i awatar, ktore przy niskim pasku
   stykaly sie z krawedziami. */
.kok-gora{
  display:flex; align-items:center; gap:var(--kr-3); flex-wrap:wrap;
  padding:var(--kr-4) var(--kr-5); background:var(--pow-1);
  border-bottom:1px solid var(--linia-cicha);
  position:sticky; top:0; z-index:5;
}
/* Logo klienta bywa rysowane w ciemnym kolorze, pod jasne tlo
   papieru. Na granatowym pasku ginie, wiec je odwracamy. Filtr
   dziala niezaleznie od tego, jaki plik wgra dany klient. */
.kok-obiekt .logo img,.kok-obiekt img.logo{
  height:36px; width:auto;
  filter:brightness(0) invert(1) opacity(.9)}
.kok-obiekt{display:flex; align-items:center; gap:var(--kr-3);
  flex-wrap:wrap; min-width:0}
/* Logo klienta przy nazwie obiektu - opisuje OBIEKT, nie aplikacje.
   Gdy instancja nie ma pliku, owijka znika w calosci (onerror), wiec
   nie zostaje po niej ani dziura, ani odstep. */
.kok-logo{display:flex; align-items:center; flex-shrink:0}
/* Logo klienta: 36px. Reguly nizej celowaly w .logo img, a znacznik
   ma klase .kok-logo - dlatego podnoszenie wysokosci wczesniej nie
   dawalo efektu. */
.kok-logo img{height:36px; width:auto}
.kok-obiekt .jezyk{font-size:var(--t-m); font-weight:var(--w-sredni);
  color:var(--tekst-1)}
.kok-opis{font-size:var(--t-s); color:var(--tekst-3)}
.kok-szukaj{
  display:flex; align-items:center; gap:var(--kr-2); flex:1 1 160px;
  max-width:320px; background:var(--pow-2); border-radius:var(--r-pelny);
  padding:0 var(--kr-3); min-height:var(--dotyk); color:var(--tekst-3);
}
.kok-szukaj input{
  font:inherit; font-size:var(--t-s); color:var(--tekst-1);
  background:none; border:0; outline:none; width:100%; min-width:0;
}
.kok-narz{display:flex; align-items:center; gap:var(--kr-2);
  margin-left:auto}
.kok-ikbtn{
  position:relative; font:inherit; color:var(--tekst-3); background:none;
  border:0; border-radius:var(--r-s); padding:9px; cursor:pointer;
  line-height:0;
}
.kok-ikbtn:hover{background:var(--pow-3); color:var(--tekst-1)}
.kok-licznik{
  position:absolute; top:2px; right:2px; min-width:16px; height:16px;
  padding:0 4px; border-radius:var(--r-pelny); background:var(--alarm);
  color:var(--tekst-na-akcencie); font-size:10px; line-height:16px;
  font-weight:var(--w-mocny); text-align:center;
}
.kok-awatar{
  width:34px; height:34px; border-radius:var(--r-pelny); flex-shrink:0;
  background:var(--akcent-tlo); color:var(--akcent-jasny);
  display:flex; align-items:center; justify-content:center;
  font-size:var(--t-s); font-weight:var(--w-mocny); letter-spacing:.02em;
}
/* Przycisk szuflady i zaslona pod nia — tylko na waskim ekranie */
.kok-menu{display:none}
.kok-zaslona{display:none}

/* Ikony z hf-ikony.js maja domyslnie 1em. W paskach, kolkach etapu
   i przy alertach 1em to 14 px - za malo, zeby odczytac ksztalt.
   Rozmiary podane wprost, bo nie zaleza od kroku typografii. */
.kok-ikbtn .ik-svg,.kok-zwin .ik-svg,.kok-kolo .ik-svg{width:19px; height:19px}
.kok-szukaj .ik-svg{width:16px; height:16px}
.kok-alert-ik .ik-svg{width:18px; height:18px}

/* ---------- tresc ---------- */
/* Tresc kokpitu wypelnia dostepna szerokosc. Limit 1500px zostawial
   na monitorze 1920 dwa puste pasy po ~200px, a karty i tak sa w siatce,
   wiec same sie rozkladaja. Gorny limit 2200px jest po to, zeby na
   ekranie ultraszerokim wiersz tabeli nie mial metra dlugosci - tam
   oko gubi sie miedzy kolumna pierwsza a ostatnia. */
.kok-tresc{padding:var(--kr-5); max-width:2200px; margin:0 auto; width:100%}

/* ---------- naglowek sekcji ----------
   Karta na calej szerokosci, ktora otwiera KAZDY widok poza Przegladem
   (tam te role gra baner). Mowi trzy rzeczy: gdzie jestem (ikona +
   tytul), o czym to jest (opis) i jedna liczba, po ktora sie tu wchodzi.
   Buduje ja hf-kokpit.js z opcji {tytul, opis, ikona}, wiec zaden widok
   nie przepisuje tego ukladu u siebie. */
.kok-naglowek{
  display:flex; align-items:center; gap:var(--kr-4); flex-wrap:wrap;
  background:var(--pow-1); border-radius:var(--r-l);
  padding:var(--kr-4) var(--kr-5); margin-bottom:var(--kr-5);
}
/* Ikona naglowka jest wieksza od ikony karty i w zaokraglonym KWADRACIE,
   nie w kolku - to rozroznienie miedzy naglowkiem ekranu a kafelkiem. */
.kok-naglowek .kok-ikonka{width:44px; height:44px; border-radius:var(--r-m)}
.kok-naglowek .kok-ikonka .ik-svg{width:22px; height:22px}
.kok-naglowek-t{flex:1 1 220px; min-width:0}
.kok-naglowek-t h1{
  font-size:var(--t-xl); font-weight:var(--w-mocny); letter-spacing:-.02em;
  line-height:1.2; margin:0; color:var(--tekst-1);
}
.kok-naglowek-t p{margin:var(--kr-2) 0 0; max-width:56ch}
/* Licznik po prawej: duza liczba, pod nia podpis. Wyrownany do prawej,
   zeby przy roznych dlugosciach tytulu stal zawsze w tym samym miejscu. */
.kok-naglowek-l{text-align:right; margin-left:auto}
.kok-naglowek-l b{
  display:block; font-size:var(--t-2xl); font-weight:var(--w-mocny);
  letter-spacing:-.03em; line-height:1.1; color:var(--tekst-1);
}
.kok-naglowek-l span{font-size:var(--t-s); color:var(--tekst-3)}

/* ---------- baner powitalny ---------- */
.kok-baner{
  display:grid; grid-template-columns:minmax(0,1fr) 280px; gap:var(--kr-5);
  align-items:center; background:var(--pow-1); border-radius:var(--r-l);
  padding:var(--kr-5); margin-bottom:var(--kr-5);
}
/* USUNIETE: .kok-baner h1, .kok-baner h1 em, .kok-baner p, .kok-baner p+p.
   Nalezaly do wersji banera, w ktorej tytul i opis byly zwyklymi <h1>/<p>
   wprost w karcie. Dzis tresc buduje rysujBaner() z klasami .hero-tytul
   i .hero-opis, a starych znacznikow w HTML juz nie ma.
   Musialy zniknac, nie tylko przestac byc uzywane: '.kok-baner p' ma
   wage (0,1,1), czyli WYZSZA niz '.hero-opis' (0,1,0), wiec narzucalo
   kolor --tekst-3 obu akapitom - drugi wiersz opisu miejscami nie
   odrozzial sie od pierwszego, mimo poprawnej reguly nizej. */
/* Trzy liczby, ktore w panelu CEO staly dotad w gornym pasku
   (zaawansowanie, dni do odbioru, prognoza). Pasek kokpitu jest zajety
   wyborem obiektu i wyszukiwarka, wiec liczby schodza do banera - nadal
   widoczne od razu po wejsciu, bez przewijania. */
.kok-baner-licz{display:flex; flex-wrap:wrap; gap:var(--kr-3) var(--kr-5);
  margin-top:var(--kr-4)}

/* ---------- pasek skrotow nad banerem ----------
   Te same trzy liczby, ale NAD grafika, nie w niej: baner jest jednym
   obrazem z wpisanym haslem i tekst polozony na nim bywa nieczytelny.
   Pionowe kreski zamiast odstepu, bo trzy pary "podpis + liczba" bez
   podzialu czytaja sie jak jedno zdanie. */
.kok-skroty{
  display:flex; flex-wrap:wrap; align-items:baseline;
  gap:var(--kr-2) var(--kr-4); margin-bottom:var(--kr-3);
}
.kok-skroty .hbox+.hbox{border-left:1px solid var(--linia);
  padding-left:var(--kr-4)}
.kok-foto{height:158px; border-radius:var(--r-m); overflow:hidden}
.kok-foto img{width:100%; height:100%; object-fit:cover}
/* Brak zdjec to nie powod na dziure w ukladzie — zostaje plaszczyzna
   z tokenow, w tym samym miejscu i rozmiarze co zdjecie. */
.kok-foto.pusta{
  background:linear-gradient(135deg,var(--pow-3),var(--akcent-tlo));
  display:flex; align-items:center; justify-content:center;
  color:var(--tekst-4); font-size:var(--t-xs); text-align:center;
  padding:var(--kr-3);
}

/* ---------- rzedy kart ---------- */
.kok-rzad5{display:grid; gap:var(--kr-3); margin-bottom:var(--kr-5);
  grid-template-columns:repeat(5,minmax(0,1fr))}
.kok-rzad4{display:grid; gap:var(--kr-3); margin-bottom:var(--kr-5);
  grid-template-columns:repeat(2,minmax(0,1fr))}
.kok-rzad5 .karta,.kok-rzad4 .karta{margin-bottom:0; display:flex;
  flex-direction:column}
.kok-rzad5 .karta{padding:var(--kr-4); position:relative}
.kok-tyt{
  font-size:var(--t-s); color:var(--tekst-3); margin:0 0 var(--kr-3);
  font-weight:var(--w-sredni);
}
.kok-tyt.dalszy{margin-top:var(--kr-4)}
/* Tytul nie moze wejsc pod kolko ikony w rogu karty. */
.kok-rzad5 .karta>.kok-tyt:first-child{padding-right:44px}

/* ---------- ikona karty w kolorowym kolku ----------
   Kolor niesie ZNACZENIE karty (zielone pokoje, bursztynowe usterki,
   czerwona prognoza przy obsuwie), wiec stoi w zmiennej --ik ustawianej
   przy renderze - z tokenu, nigdy z wartosci wprost. */
/* Ikona karty: NA MAKIECIE stoi PRZED tytulem, w jednej linii z nim -
   nie w rogu karty. Rog ciagnal wzrok w bok od liczby, ktora jest
   najwazniejsza. Tlo zmierzone probnikiem z makiety (#102840 na tle
   karty #0A1825) wychodzi mocniejsze niz 14% - stad 22% i obwodka 34%,
   inaczej kolko gubi sie na granacie. */
.kok-ikonka{
  width:34px; height:34px; border-radius:var(--r-pelny);
  display:inline-flex; align-items:center; justify-content:center;
  color:var(--ik); line-height:0; flex:0 0 auto;
  background:color-mix(in srgb, var(--ik) 22%, transparent);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--ik) 34%, transparent);
}
/* Tytul karty siedzi obok ikony, nie pod nia. */
.kok-tyt{display:flex; align-items:center; gap:var(--kr-3)}
.kok-ikonka .ik-svg{width:18px; height:18px}
/* Plakietka roznicy w karcie kokpitu jest o stopien wieksza niz
   w gestych tabelach - stoi obok liczby wielkosci --t-3xl. */
.kok-rzad5 .delta{font-size:var(--t-s)}
.kok-rzad-v{display:flex; align-items:baseline; gap:var(--kr-2);
  flex-wrap:wrap}

/* ---------- wskaznik polkolisty ---------- */
.kok-gauge{width:100%; max-width:168px; margin:0 auto; display:block}
.kok-gauge .tlo{stroke:var(--pow-3)}
.kok-gauge .wyp{stroke:var(--akcent)}
.kok-gauge .liczba{fill:var(--tekst-1); font:var(--w-mocny) 26px var(--font);
  letter-spacing:-.03em}

/* ---------- pipeline realizacji ---------- */
.kok-pipe{display:flex; align-items:flex-start; gap:var(--kr-2)}
.kok-etap{flex:1; min-width:0; text-align:center; position:relative}
/* Kreska laczaca kolka. Rysowana na etapie, nie miedzy nimi, zeby
   przy zawijaniu na telefonie nie zostawala wisiec w powietrzu.
   Odcinek PRZED etapem, do ktorego cos juz doszlo, dostaje kolor tego
   etapu (--kol); dalej zostaje cicha linia. Sciezka czyta sie wtedy
   jak pasek postepu, a nie jak piec niezaleznych kolek. */
.kok-etap+.kok-etap::before{
  /* Polowa wysokosci kolka (46px), zeby kreska wchodzila w jego srodek.
     Bylo 19px - wartosc z czasow kolka 38px; po powiekszeniu kreska
     przecinala ikone w poprzek.
     z-index:0 trzyma ja POD kolkiem (kolko ma z-index:1) - inaczej
     linia klada sie na ikonie i wygladala jak przekreslenie. */
  content:""; position:absolute; top:23px; right:50%; left:-50%;
  height:2px; background:var(--linia); z-index:0;
}
.kok-etap+.kok-etap.osiagniety::before{background:var(--kol)}
/* Kolor kolka: barwa pasma etapu, ta sama, ktora maluje segmenty
   paskow postepu i kropki w legendzie. */
/* Kolko etapu: 46px zamiast 38. Ikona w srodku ma 20px i przy obwodce
   w 45% krycia gubila sie na granacie - na zrzucie wlasciciela kolka
   wygladaly na puste. Tlo 22%, obwodka 60%, ikona pelnym kolorem. */
.kok-kolo{
  position:relative; z-index:1; width:46px; height:46px; margin:0 auto;
  border-radius:var(--r-pelny); color:var(--kol);
  /* Dwie warstwy tla: kolor etapu w 22% NA nieprzezroczystym tle karty.
     Samo color-mix z 'transparent' przepuszczalo kreske lacznika,
     ktora przebiegala przez srodek kolka jak przekreslenie. */
  background:linear-gradient(color-mix(in srgb, var(--kol) 22%, var(--pow-2)),
    color-mix(in srgb, var(--kol) 22%, var(--pow-2)));
  border:2px solid color-mix(in srgb, var(--kol) 60%, transparent);
  display:flex; align-items:center; justify-content:center;
}
.kok-kolo .ik-svg,.kok-kolo svg{width:22px; height:22px;
  stroke-width:2; color:var(--kol); opacity:1}
.kok-etap.zrobiony .kok-kolo,
.kok-etap.biezacy .kok-kolo{border-color:var(--kol)}
.kok-etap.biezacy .kok-kolo{
  box-shadow:0 0 0 3px color-mix(in srgb, var(--kol) 14%, transparent);
}
.kok-etap b{display:block; margin-top:var(--kr-2); font-size:var(--t-m);
  font-weight:var(--w-mocny); letter-spacing:-.02em}
.kok-etap span{display:block; font-size:var(--t-xs); color:var(--tekst-3);
  line-height:1.3}
/* Ulamek pod procentem: z czego ten procent wyszedl. */
.kok-etap .ul{font-size:var(--t-s); color:var(--tekst-3);
  font-variant-numeric:tabular-nums; margin-bottom:2px}

/* ---------- co stoi na kazdym etapie ----------
   Sciezka wyzej mowi ILE, ta lista mowi CO. Karta stoi w rzedzie obok
   listy pieter, ktora jest kilka razy wyzsza; bez tresci zostawal pod
   kolkami pusty prostokat na pol ekranu. */
.kok-etapy{display:flex; flex-direction:column; gap:var(--kr-3)}
.kok-etap-w{
  display:grid; align-items:center; gap:var(--kr-1) var(--kr-3);
  grid-template-columns:10px minmax(0,1fr) auto; font-size:var(--t-s);
}
.kok-etap-w .nz{color:var(--tekst-2); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.kok-etap-w .ile{font-weight:var(--w-mocny); color:var(--tekst-1);
  font-variant-numeric:tabular-nums}
/* Chipy zaczynaja sie pod nazwa etapu, nie pod kropka - wciecie wiaze
   je wzrokowo z etapem, do ktorego naleza. */
.kok-etap-w .chipy{grid-column:2/4; display:flex; flex-wrap:wrap;
  gap:var(--kr-1)}
.kok-chip{
  font-size:var(--t-xs); color:var(--tekst-3); background:var(--pow-2);
  border-radius:var(--r-pelny); padding:2px 9px; max-width:100%;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.kok-chip b{color:var(--tekst-2); font-weight:var(--w-sredni);
  font-variant-numeric:tabular-nums}

/* ---------- lista pieter ---------- */
.kok-pietra{display:flex; flex-direction:column; gap:var(--kr-2);
  max-height:420px; overflow-y:auto}
.kok-pietro{
  display:grid; grid-template-columns:34px minmax(0,1fr) 46px 12px;
  align-items:center; gap:var(--kr-3); font-size:var(--t-s);
}
.kok-pietro .nr{font-weight:var(--w-mocny); color:var(--tekst-1);
  font-variant-numeric:tabular-nums}
.kok-pietro .nz{font-size:var(--t-xs); color:var(--tekst-3);
  margin-bottom:3px; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap}
.kok-pietro .pr{text-align:right; font-weight:var(--w-sredni);
  color:var(--tekst-2); font-variant-numeric:tabular-nums}
.kok-kropka{width:10px; height:10px; border-radius:var(--r-pelny);
  flex-shrink:0}

/* ---------- postep wg pieter w panelu CEO ----------
   Jeden wiersz na pietro: nazwa, pod spodem zakres numerow i liczba
   pokoi, pasek segmentowy przez reszte szerokosci, procent po prawej.
   Pasek jest ten sam co w karcie "Zaawansowanie" (pasek() z wspolne.js),
   wiec kolor znaczy na calym ekranie to samo.
   Kolumna nazwy nie ma stalej szerokosci: "Piętro 12" i "Parter" roznia
   sie dlugoscia, a ucinanie nazwy pietra nie ma sensu przy dwunastu
   wierszach jeden pod drugim. */
.kok-pietro-w{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center; gap:var(--kr-2) var(--kr-4); font-size:var(--t-s);
}
.kok-pietro-w .nz{font-weight:var(--w-mocny); color:var(--tekst-1);
  white-space:nowrap; letter-spacing:-.01em}
.kok-pietro-w .zakres{display:block; font-size:var(--t-xs);
  color:var(--tekst-3); margin-bottom:3px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.kok-pietro-w .pr{text-align:right; white-space:nowrap;
  font-weight:var(--w-sredni); color:var(--tekst-2);
  font-variant-numeric:tabular-nums}
/* Na telefonie nazwa i procent zostaja w jednej linii, a pasek schodzi
   pod nie na cala szerokosc - trzy kolumny na 360 px daja pasek szeroki
   na kciuk i nie da sie z niego niczego odczytac. */
@media (max-width:560px){
  .kok-pietro-w{grid-template-columns:minmax(0,1fr) auto}
  .kok-pietro-w>div{grid-column:1/3; order:1}
  .kok-pietro-w .pr{order:0}
}
/* Pasek pietra jako kratki, nie ciagla wstega. Oko liczy kratki
   („trzy z dwudziestu"), a dlugosci ciaglego paska nie porownuje
   miedzy wierszami. Liczba kratek jest stala, wiec wiersze sa
   porownywalne niezaleznie od liczby pozycji na pietrze. */
.kok-segmenty{display:flex; gap:2px; height:var(--pasek-wys)}
.kok-segmenty i{flex:1 1 0; min-width:0; border-radius:1px;
  background:var(--pow-3)}

/* ---------- usterki i alerty ---------- */
.kok-alerty{display:flex; flex-direction:column; gap:var(--kr-2);
  max-height:320px; overflow-y:auto}
.kok-alert{
  display:flex; gap:var(--kr-3); align-items:flex-start;
  background:var(--pow-2); border-radius:var(--r-m); padding:var(--kr-3);
}
.kok-alert-ik{color:var(--uwaga); line-height:0; flex-shrink:0;
  margin-top:2px}
.kok-alert.zamkniety .kok-alert-ik{color:var(--ok)}
.kok-alert-tr{min-width:0; flex:1}
.kok-alert-tr b{display:block; font-size:var(--t-s);
  font-weight:var(--w-sredni); color:var(--tekst-1)}
.kok-alert-meta{display:flex; flex-wrap:wrap; gap:var(--kr-1) var(--kr-3);
  margin-top:var(--kr-1); font-size:var(--t-xs); color:var(--tekst-3)}
.kok-liczniki{display:grid; grid-template-columns:repeat(3,1fr);
  gap:var(--kr-2); margin-top:var(--kr-4)}
.kok-licz{background:var(--pow-2); border-radius:var(--r-m);
  padding:var(--kr-3); text-align:center}
.kok-licz b{display:block; font-size:var(--t-xl);
  font-weight:var(--w-mocny); letter-spacing:-.02em}
.kok-licz span{font-size:var(--t-xs); color:var(--tekst-3)}
/* Licznik z podpowiedzia: kursor ma powiedziec, ze jest co najechac.
   Bez tego kreska zamiast liczby wyglada na zepsuty ekran, a wyjasnienie
   nigdy sie nie pokazuje, bo nikt nie wie, ze tam jest. */
.kok-licz[title]{cursor:help}

/* ---------- skrocona lista usterek w karcie rzedu liczb ----------
   Sama liczba otwartych zgloszen nie mowi, CO jest otwarte. Kropka
   niesie stan (otwarte / zamkniete), plakietka - typ zgloszenia
   z bazy. Pilnosc idzie z kolumny komentarz.priorytet (pasek .kok-prio
   nad lista), a nie z oceny na oko. */
.kok-us{display:flex; flex-direction:column; gap:var(--kr-2);
  margin-top:var(--kr-1)}
.kok-us-w{display:grid; grid-template-columns:10px minmax(0,1fr) auto;
  align-items:start; gap:var(--kr-2)}
.kok-us-w>.kok-kropka{margin-top:5px}
.kok-us-tr{min-width:0}
.kok-us-tr b{display:block; font-size:var(--t-s);
  font-weight:var(--w-sredni); color:var(--tekst-1);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kok-us-meta{display:flex; flex-wrap:wrap; gap:2px var(--kr-2);
  font-size:var(--t-xs); color:var(--tekst-3)}

/* ---------- miniatura wykresu w karcie licznika ----------
   Sama liczba nie mowi, w ktora strone idzie. Pod liczba stoi wiec
   sparkline: bez osi, bez siatki, bez podpisow - 40 px wysokosci,
   tyle ile trzeba, zeby zobaczyc kierunek. Liczba zostaje najwazniejsza:
   miniatura jest pod nia, nigdy na niej, i nie lapie kursora. */
.kok-mini{margin-top:var(--kr-3)}
.kok-mini canvas{display:block; width:100%; height:40px}
/* Podpis miniatury mowi, CO jest na niej narysowane. Sparkline bez osi
   jest nieczytelna bez tego jednego zdania. */
.kok-mini-p{font-size:var(--t-xs); color:var(--tekst-4);
  margin-top:var(--kr-1)}

/* ---------- proporcja priorytetow zgloszen ----------
   Cztery zgloszenia w czterech roznych dniach to za malo na wykres
   w czasie — sparkline z takich danych pokazywalaby szum. Pasek
   proporcji odpowiada na pytanie, ktore ma sens przy tej liczbie:
   CO jest otwarte, a nie kiedy przyszlo. */
.kok-prio{display:flex; flex-wrap:wrap; gap:var(--kr-1) var(--kr-3);
  margin-top:var(--kr-2); font-size:var(--t-xs); color:var(--tekst-3)}
.kok-prio span{display:inline-flex; align-items:center;
  gap:var(--wsk-odstep)}
.kok-prio i{width:8px; height:8px; border-radius:var(--r-pelny);
  flex-shrink:0}
.kok-prio b{color:var(--tekst-2); font-weight:var(--w-sredni);
  font-variant-numeric:tabular-nums}

/* ---------- mini-os czasu (karta prognozy) ----------
   Prognoza to JEDNA data w przyszlosci — szeregu czasowego nie ma
   i rysowanie go byloby wymyslaniem pomiaru. Zostaje odcinek miedzy
   terminem umownym a prognoza: czerwony, gdy prognoza wypada pozniej.
   Pozycje znacznikow sa STALE (10% i 90%, patrz OS_LEWY/OS_PRAWY
   w panel.html). Przy karcie szerokiej na jedna piata rzedu odleglosc
   miedzy nimi i tak nie dalaby sie odczytac jako liczba dni — liczba dni
   stoi nad osia, wprost. Podpisy sa dosuniete do krawedzi karty, a nie
   wysrodkowane pod kolkiem: data dluga na 10 znakow wystawalaby wtedy
   poza karte. */
.kok-os{position:relative; height:48px; margin-top:var(--kr-3)}
.kok-os-linia{position:absolute; left:0; right:0; top:5px; height:2px;
  border-radius:var(--r-pelny); background:var(--linia-mocna)}
.kok-os-odc{position:absolute; top:5px; height:2px;
  border-radius:var(--r-pelny); background:var(--kol-os)}
.kok-os-zn{position:absolute; top:0; width:12px; height:12px;
  margin-left:-6px; border-radius:var(--r-pelny);
  background:var(--pow-1); box-shadow:0 0 0 2px var(--kol-zn)}
.kok-os-zn.pelny{background:var(--kol-zn)}
.kok-os-p{position:absolute; top:17px; font-size:var(--t-xs);
  line-height:1.25; color:var(--tekst-3); white-space:nowrap}
.kok-os-p b{display:block; color:var(--tekst-2);
  font-weight:var(--w-sredni); font-variant-numeric:tabular-nums}
.kok-os-p.lewy{left:0; text-align:left}
.kok-os-p.prawy{right:0; text-align:right}

/* ---------- stan pusty ----------
   Karta bez danych ma powiedziec, CZEGO brakuje. Pusty prostokat
   i zmyslona liczba sa tak samo bezuzyteczne — pierwszy nie informuje,
   druga wprowadza w blad. */
.kok-pusto{
  border:1px dashed var(--linia-mocna); border-radius:var(--r-m);
  padding:var(--kr-3); color:var(--tekst-3); font-size:var(--t-s);
  display:flex; flex-direction:column; gap:var(--kr-1);
  justify-content:center; min-height:64px;
}
.kok-pusto b{color:var(--tekst-2); font-weight:var(--w-sredni)}
.kok-pusto span{font-size:var(--t-xs); color:var(--tekst-4)}

/* ---------- drobiazgi wspolne kokpitu ---------- */
.kok-srodek{justify-content:center; text-align:center}
.kok-zle{color:var(--alarm); font-weight:var(--w-sredni)}
.kok-akcje{display:flex; gap:var(--kr-2); flex-wrap:wrap}
.kok-rzad5 .karta .bar{margin-top:var(--kr-3)}
/* Karty w rzedzie sa rownej wysokosci (siatka), a ich tresc rozna:
   karta z wykresem tempa jest dwa razy wyzsza od karty z sama liczba.
   Przycisk siada na DNIE karty, a stan pusty rozciaga sie na to, co
   zostalo - inaczej pod trescia wisial pusty prostokat, ktory wygladal
   na niedokonczony ekran. */
.kok-rzad5 .karta .btn{margin-top:auto; align-self:flex-start}
.kok-rzad5 .kok-pusto{margin-top:var(--kr-3); flex:1 1 auto}
/* Odstep kotwicy = wysokosc gornego paska. Pasek jest sticky, wiec bez
   tego naglowek sekcji chowa sie pod nim po skoku z menu. Wartosc rosnie
   razem z paskiem (--kr-4 zamiast --kr-3 to +16px). */
.kok-tresc section{scroll-margin-top:92px}

/* ---------- galeria zdjec ---------- */
.kok-galeria{display:grid; gap:var(--kr-3);
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.kok-zdj{margin:0; border:1px solid var(--linia-cicha);
  border-radius:var(--r-m); overflow:hidden; background:var(--pow-2)}
.kok-zdj img{width:100%; height:112px; object-fit:cover}
.kok-zdj figcaption{padding:var(--kr-2) var(--kr-3)}
.kok-zdj figcaption b{display:block; font-size:var(--t-s);
  font-weight:var(--w-sredni)}
.kok-zdj figcaption span{font-size:var(--t-xs); color:var(--tekst-3)}

/* ---------- pasek stanu projektu nad stopka ----------
   Jedno zdanie o tym, czy prognoza miesci sie w terminie odbioru.
   Kolor jest powtorzeniem tego, co mowi tekst, nie jedynym nosnikiem;
   gdy prognozy policzyc sie nie da, paska po prostu nie ma. */
.kok-stan{
  display:flex; align-items:center; gap:var(--kr-3);
  margin-top:var(--kr-5); padding:var(--kr-3) var(--kr-4);
  border-radius:var(--r-m); border-left:3px solid var(--kol-stan);
  background:color-mix(in srgb, var(--kol-stan) 12%, transparent);
  font-size:var(--t-s); color:var(--tekst-2);
}
.kok-stan.alarm{--kol-stan:var(--alarm)}
.kok-stan.ok{--kol-stan:var(--ok)}
.kok-stan-ik{line-height:0; color:var(--kol-stan); flex-shrink:0}
.kok-stan-ik .ik-svg{width:18px; height:18px}

/* ---------- stopka ---------- */
.kok-stopka{
  display:flex; align-items:center; gap:var(--kr-3) var(--kr-5);
  flex-wrap:wrap; padding:var(--kr-4) 0 0;
  border-top:1px solid var(--linia-cicha); margin-top:var(--kr-5);
  font-size:var(--t-xs); color:var(--tekst-3);
}
.kok-legenda{display:flex; flex-wrap:wrap; gap:var(--kr-2) var(--kr-4)}
.kok-legenda span{display:inline-flex; align-items:center;
  gap:var(--wsk-odstep)}
.kok-legenda b{color:var(--tekst-2); font-weight:var(--w-sredni);
  font-variant-numeric:tabular-nums}
.kok-akt{margin-left:auto; display:flex; align-items:center;
  gap:var(--kr-2)}

/* ---------- responsywnosc kokpitu ---------- */
@media (max-width:1200px){
  .kok-rzad5{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kok-baner{grid-template-columns:minmax(0,1fr)}
  .kok-foto{height:120px}
}
@media (max-width:900px){
  .kok-uklad{grid-template-columns:minmax(0,1fr)}
  .kok-bok{
    position:fixed; top:0; left:0; width:240px;
    transform:translateX(-100%); transition:transform .18s;
    box-shadow:var(--cien-warstwa);
  }
  body.kok.kok-otwarty .kok-bok{transform:none}
  /* Zaslona pod szuflada: bez niej klikniecie w tresc nie zamyka paska,
     a na telefonie nie ma gdzie indziej kliknac. */
  body.kok.kok-otwarty .kok-zaslona{
    display:block; position:fixed; inset:0; z-index:5;
    background:rgba(5,8,12,.55);
  }
  .kok-menu{display:inline-flex}
  .kok-gora{padding:var(--kr-3)}
  .kok-tresc{padding:var(--kr-4) var(--kr-3)}
  /* Ponizej 900 px karty ida w JEDNA kolumne - oba rzedy. Dwie karty
     obok siebie na 800 px daly wykres tempa szeroki na 380 px, w ktorym
     podpisy osi X zlewaly sie w jeden ciag. */
  .kok-rzad4,.kok-rzad5{grid-template-columns:minmax(0,1fr)}
  /* Pasek w szufladzie jest zawsze pelny — zwijanie do ikon nie ma tu
     sensu, bo szuflada i tak zaslania tresc. Trzeba odkrecic KAZDA
     regule trybu zwinietego: zwiniecie na duzym ekranie zostaje
     w klasie body i przenosi sie na telefon. */
  body.kok.zwiniety .kok-etyk{display:inline}
  body.kok.zwiniety .kok-marka{display:block}
  body.kok.zwiniety .kok-bok-gora{justify-content:flex-start;
    padding:0 var(--kr-2) var(--kr-5)}
  body.kok.zwiniety .kok-nawig button{justify-content:flex-start;
    padding:0 var(--kr-3)}
  /* Naglowki grup wracaja razem z etykietami, a zwiniete grupy znow
     sa zwiniete - w szufladzie jest na nie miejsce i jest czym je
     otworzyc. */
  body.kok.zwiniety .kok-nawig .kok-grupa-n{display:flex}
  body.kok.zwiniety .kok-grupa.zwinieta .kok-grupa-l{display:none}
  .kok-zwin{display:none}
}
@media (max-width:560px){
  .kok-rzad5{grid-template-columns:minmax(0,1fr)}
  /* Na telefonie piec kart stoi jedna pod druga i kazda miniatura
     dorzuca 55 px do kolumny, ktora i tak jest za dluga. Znika WYKRES
     razem ze swoim podpisem (podpis bez wykresu opisywalby nic);
     zostaje liczba karty, jej ulamek i pasek priorytetow - to one niosa
     tresc. Miedzy 560 a 900 px karty sa juz pelnej szerokosci i sparkline
     czyta sie tam lepiej niz na biurku, wiec zostaje. */
  .kok-mini,.kok-mini-p{display:none}
  .kok-pipe{flex-wrap:wrap; gap:var(--kr-4) var(--kr-2)}
  .kok-etap{flex:0 0 calc(33.333% - var(--kr-2))}
  .kok-etap+.kok-etap::before{display:none}
  .kok-szukaj{order:5; max-width:none; flex-basis:100%}
}

/* ==========================================================================
   OGRANICZONY RUCH
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* --- BANER: historia zmian ---------------------------------------------
   Byla tu wersja z gotowa grafika reklamowa, ktora miala haslo WPISANE
   w obraz. Odeszla, bo tekst na obrazie jest ostry tylko wtedy, gdy plik
   ma dokladnie tyle pikseli, ile karta na ekranie - przy szerszym oknie
   litery mieky.
   Dzis baner sklada sie z tekstu HTML i osobnego zdjecia: reguly .hero,
   .hero__text, .hero__title, .hero__accent, .hero__lead i .hero__photo
   stoja nizej, w sekcji BANER HERO.
   Byly tu tez osierocona deklaracja 'object-fit:cover}' bez selektora
   i pusty @media - pozostalosci po przerobkach kadru. Przegladarka
   odrzucala oba po cichu, ale psuly bilans nawiasow. */

/* Link ze skrotu do pelnego ekranu. Karta podaje LICZBE, szczegoly
   sa tam, gdzie jest miejsce na tresc zgloszenia i filtry. */
.kok-link{display:flex;align-items:center;justify-content:space-between;
  gap:var(--kr-2);margin-top:auto;padding:var(--kr-2) var(--kr-3);
  border-radius:var(--kr-2);background:var(--pow-2);color:var(--tekst-2);
  font-size:var(--t-s);font-weight:var(--w-sredni);text-decoration:none;
  border:1px solid var(--linia);transition:background .15s,color .15s}
.kok-link:hover{background:var(--pow-hover);color:var(--tekst-1);
  border-color:var(--tekst-3)}
.kok-link svg{flex:0 0 auto}
/* Karta usterek rozciaga sie tak jak pozostale w rzedzie - link
   ma siedziec przy dolnej krawedzi, nie tuz pod paskiem. */
.kok-rzad5>.karta{display:flex;flex-direction:column}

/* ---------- wybor stanu pomieszczenia ----------
   Osiem stanow jako przyciski zajmowalo dwa rzedy i gubilo kolor.
   Lista rozwijana + kropka koloru: jedna linia, kolor widoczny,
   a pelna nazwa stanu czytelna po rozwinieciu. Kolor nie jest
   jedynym nosnikiem - nazwa stoi obok w tej samej linii. */
.stan-wybor{display:flex; align-items:center; gap:var(--kr-3);
  margin-bottom:var(--kr-4)}
.stan-kropka{width:14px; height:14px; border-radius:var(--r-pelny);
  flex:0 0 auto; box-shadow:0 0 0 2px var(--pow-2)}
.stan-select{flex:1 1 auto; min-width:0; padding:var(--kr-2) var(--kr-3);
  background:var(--pow-2); color:var(--tekst-1);
  border:1px solid var(--linia); border-radius:var(--kr-2);
  font-size:var(--t-m); font-family:inherit; cursor:pointer}
.stan-select:hover{border-color:var(--tekst-3); background:var(--pow-hover)}
.stan-select:focus-visible{outline:2px solid var(--akcent); outline-offset:1px}
.stan-select option:disabled{color:var(--tekst-3)}
/* SNG-059: podpis pod wygaszona kontrolka stanu. Kolor jest tylko
   dodatkiem - powod stoi w tresci, wiec czyta sie go takze bez niego. */
.stan-podpis{font-size:var(--t-xs); color:var(--tekst-3);
  line-height:1.45; margin-bottom:var(--kr-4)}
.pole-et{font-size:var(--t-s); color:var(--tekst-3);
  margin-bottom:var(--kr-2)}

/* ---------- BANER: zdjecie w tle, tekst w HTML ----------
   Wczesniej baner byl jedna grafika z wpisanym haslem. Zrodlowy pas
   makiety mial ~1140px, a baner rozciaga sie do 2200 - powiekszenie
   1.9x rozmywalo litery. Teraz zdjecie jest tlem (fotografia znosi
   skalowanie), a tekst zyje w HTML: ostry zawsze, tlumaczalny,
   czytelny dla czytnika ekranu. */
/* ---------- BANER HERO ----------

   Zdjecie jest <img>, nie background-image: tylko znacznik pozwala
   odczytac naturalWidth i udowodnic, ze obraz nie jest skalowany w gore.

   Nad zdjeciem NIE stoi nic: zero ::before, ::after, opacity, filter,
   transform i mix-blend-mode. Jasnosc, kontrast i nasycenie prawej
   czesci sa takie jak w pliku. Jedyna ingerencja to maska przejscia
   na lewych 22% - maska dziala na kanale alfa, wiec nie zmienia
   koloru pikseli, tylko ich krycie.

   Tokeny: specyfikacja mowi o --border i --radius-card, w tym repo
   odpowiadaja im --linia i --r-l. Uzywam nazw z repo, zeby baner
   zmienial sie razem z motywem zamiast zyc obok niego.
   Tlo #02152a zostaje liczba wprost: to kolor z oryginalnej grafiki
   wlasciciela, nie pozycja palety - token zmienilby go przy motywie. */
.hero{position:relative; display:flex; align-items:center;
  min-height:clamp(220px, 15vw, 300px); background:#02152a;
  border:1px solid var(--linia); border-radius:var(--r-l);
  overflow:hidden; margin-bottom:var(--kr-5)}

/* 52%, nie 48% ze specyfikacji: przy 48% niemiecki tytul lamal sie
   na TRZY wiersze ("die in Erinnerung" + "bleiben."), przez co baner
   rosl o 43 px wzgledem PL i EN. Niemiecki jest najdluzszy, wiec to
   on wyznacza minimum.
   Odstep poziomy to var(--kr-5) - dokladnie tyle, ile maja kafelki
   ponizej (.karta, styl.css:375). Dzieki temu napis banera stoi
   w JEDNEJ LINII z tytulami kart. Wczesniej byl tu clamp rosnacy
   z szerokoscia okna i tekst uciekal w prawo, wygladajac na wciety.
   Pion zostaje 32 px, bo baner jest wyzszy niz zwykla karta. */
.hero__text{position:relative; z-index:1; width:52%;
  padding:32px var(--kr-5)}

/* font-weight 500, nie token --w-mocny (700): napis ma byc czytelny,
   ale nie ciezki. */
.hero__title{margin:0; font-size:clamp(28px, 2.6vw, 48px);
  font-weight:500; line-height:1.15; letter-spacing:-.01em; color:#fff}
.hero__title span{display:block}

/* Gradient na literach: tlo przyciete do ksztaltu tekstu, wiec sam
   kolor musi byc przezroczysty, inaczej przykrylby gradient. */
.hero__accent{background:linear-gradient(90deg, #3b82f6, #2dd4bf);
  -webkit-background-clip:text; background-clip:text; color:transparent}

/* Lead to JEDEN akapit - jednolity rozmiar i kolor w obu wierszach.
   i18n trzyma tlumaczenia jako osobne klucze, wiec zamiast <br>
   sa dwa <span class="wiersz"> z display:block. */
.hero__lead{margin:16px 0 0; font-size:clamp(14px, 1.05vw, 18px);
  line-height:1.6; color:#c3cad5}
.hero__lead .wiersz{display:block}

/* Zdjecie 72%, nie 54%: przy 54% maska zjadala 228-294 px obrazu
   i miedzy tekstem a lobby zostawal pusty granatowy pas - zdjecie
   wygladalo na urwane.
   max-width:1280px pilnuje, zeby obraz nigdy nie byl skalowany w gore
   ponad rozdzielczosc pliku; to ta liczba, nie procent, trzyma warunek
   "brak upscalingu" na ekranie 2560.

   Szerokosc i dlugosc fade dobrane POMIAREM. Wlasciciel poprosil,
   zeby zdjecie podeszlo blizej napisu, a przejscie bylo dluzsze.
   Zmierzone na oknie 1920 - gdzie zaczyna sie zdjecie wzgledem konca
   napisu:
     76% / 330px  -182 px, fade 27% szerokosci zdjecia
     84% / 430px  -244 px, fade 35%
     92% / 520px  -244 px, fade 41%  <- wybrane
    100% / 620px  -244 px, fade 48%  <- fade zjada polowe obrazu
   Powyzej 84% pozycja startu juz sie nie zmienia, bo max-width:1280px
   zatrzymuje zdjecie na szerokosci pliku - rosnie wylacznie dlugosc
   przejscia. 92% dobrane pod WEZSZE okna: przy 1440 daje 1034 px
   zamiast 944 px, wiec i tam zdjecie podchodzi blizej tekstu.

   Dluzszy fade nie rozjasnia tla pod napisem - maska dziala na kanale
   alfa i im blizej tekstu, tym obraz bardziej przezroczysty.

   max-width:1280px pilnuje, zeby obraz nigdy nie byl skalowany w gore
   ponad rozdzielczosc pliku.
   object-position 45% zamiast 50%: przy szerszym kadrze srodek lobby
   przesuwa sie w prawo i lampy uciekaly poza widoczny obszar. */
.hero__photo{position:absolute; top:0; right:0; bottom:0;
  width:92%; max-width:1280px; height:100%;
  object-fit:cover; object-position:45% 55%;
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 520px);
  mask-image:linear-gradient(to right, transparent 0, #000 520px)}

/* USUNIETE: @media (min-width:2200px){ .hero{max-width:1780px;
   margin-inline:auto} }
   Dodane bylo po to, zeby na ekranie 2560 zdjecie nie musialo byc
   rozciagane ponad rozdzielczosc pliku. Efekt uboczny okazal sie
   gorszy od problemu: baner byl zwezany i WYSRODKOWANY, wiec odstawal
   od reszty strony z obu stron naraz - z lewej pusty granatowy pas
   przed napisem, z prawej koniec karty 101 px przed kafelkami.
   Na zrzucie wlasciciela napis banera zaczynal sie 130 px dalej niz
   tytuly kafelkow ponizej i to wlasnie bylo widac.
   Baner ma teraz te sama szerokosc co cala strona. Zdjecie na bardzo
   szerokim ekranie zatrzymuje sie na max-width:1280px, wiec po prawej
   dociaga je tlo #02152a - lepsze niz rozjechany uklad. */

@media (max-width:767px){
  /* Zdjecie znika zamiast schodzic pod tekst: przy jednej kolumnie
     lobby jest nieczytelne, a kazda proba wtopienia go pod napis
     wymagalaby opacity, ktorego specyfikacja zabrania. */
  .hero__photo{display:none}
  .hero__text{width:100%}
}

/* USUNIETE ze starym banerem (zero odwolan w HTML i JS):
   .kok-baner-foto   - padding i siatka karty z obrazem na calosc
   .kok-foto.tlo     - proporcja i tlo wersji jednowarstwowej
   .hero-foto        - zdjecie jako background-image
   .hero-foto::after - gradient przyciemniajacy do 72% szerokosci
   .hero-foto @media - opacity:.22 na waskim ekranie
   .hero-tresc, .hero-tytul, .hero-tytul span, .hero-opis,
   .hero-opis.drobny - zastapione przez .hero__* wyzej
   Wczesniej (commit 83df9df) zniknely juz: .kok-baner h1,
   .kok-baner h1 em, .kok-baner p, .kok-baner p+p. */

/* ---------- ZAAWANSOWANIE JAKO PIERSCIEN ----------
   Pasek 10px pokazywal proporcje bez skali. Pierscien daje ja od razu,
   a srodek niesie liczbe, ktora interesuje najbardziej.
   SVG zamiast canvas: ostry przy kazdym powiekszeniu, a kazdy segment
   ma <title> czytany przez kursor i czytnik ekranu.
   Nazwa .kok-pierscien, NIE .kok-kolo - ta druga jest zajeta przez
   kolka etapow w pipeline (styl.css:1524). */
.kok-pierscien{position:relative; width:100%; max-width:150px;
  margin:0 auto; aspect-ratio:1}
.kok-pierscien svg{width:100%; height:100%; display:block}
.kolo-seg{transition:opacity .15s}
.kok-pierscien:hover .kolo-seg{opacity:.5}
.kok-pierscien .kolo-seg:hover{opacity:1}
.kok-pierscien-srodek{position:absolute; inset:0; display:flex;
  flex-direction:column; align-items:center; justify-content:center;
  pointer-events:none; text-align:center}
.kok-pierscien-srodek b{font-size:var(--t-2xl); font-weight:var(--w-mocny);
  color:var(--tekst-1); line-height:1.1; letter-spacing:-.5px}
.kok-pierscien-srodek span{font-size:var(--t-s); color:var(--tekst-3);
  margin-top:var(--kr-1)}
/* Pierscien i legenda obok siebie - karta jest szeroka, legenda pod
   kolem zostawialaby pusty pas po prawej. */
/* Dwie karty w jednej linii: zaawansowanie (pierscien) i pipeline.
   Pierwsza kolumna wezsza - pierscien ma stala szerokosc, pipeline
   potrzebuje miejsca na piec kolek z podpisami.
   Ponizej 1000px karty wracaja jedna pod druga: pipeline sciety do
   polowy szerokosci gubi podpisy etapow. */
.kok-para{display:grid; gap:var(--kr-4); margin-bottom:var(--kr-4)}
@media (min-width:1000px){
  .kok-para{grid-template-columns:minmax(0,380px) minmax(0,1fr)}
}
.kok-para > .karta{margin-bottom:0}

/* Tabela terminow odbioru pieter.
   "termin w ustalaniu" ma wygladac na STAN, a nie na brakujaca dana -
   stad pigulka z obwodka, nie sama szara kreska. Kursywa dodatkowo
   oddziela to od prawdziwych dat, wiec informacja nie idzie samym
   kolorem.

   .pig-przyg ("w przygotowaniu", SNG-010) niesie DOKLADNIE ten sam
   komunikat na innych ekranach: miejsce jest znane, tresci jeszcze nie
   ma. Stoi w tym samym selektorze, zeby dwa napisy o tym samym nie
   rozjechaly sie wygladem przy pierwszej poprawce. */
.term-brak,.pig-przyg{display:inline-block; padding:1px var(--kr-2);
  border:1px dashed var(--linia); border-radius:999px;
  font-size:var(--t-xs); font-style:italic; color:var(--tekst-3)}
/* Odchylenie od planu przy pietrze juz odebranym. */
.term-znak{margin-left:var(--kr-2); font-size:var(--t-xs);
  font-variant-numeric:tabular-nums}
.term-znak.pozno{color:var(--alarm)}
.term-znak.wczas{color:var(--ok)}

/* Lista usterek i alertow wg makiety: pilnosc, tresc, pokoj, kiedy.
   Tresc dostaje minmax(0,1fr) i lamie sie, reszta kolumn ma szerokosc
   z zawartosci - bez tego dlugi opis rozpychalby date poza karte. */
.kok-alerty{list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column}
.kok-alerty li{display:grid; align-items:center; gap:var(--kr-3);
  grid-template-columns:auto minmax(0,1fr) auto auto;
  padding:var(--kr-3) 0; border-bottom:1px solid var(--linia)}
.kok-alerty li:last-child{border-bottom:none}
.kok-alerty .tre{color:var(--tekst-1); min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kok-alerty .gdzie{font-size:var(--t-xs); color:var(--tekst-2);
  font-variant-numeric:tabular-nums; white-space:nowrap}
.kok-alerty .kiedy{font-size:var(--t-xs); color:var(--tekst-3);
  white-space:nowrap}
@media (max-width:640px){
  /* Na telefonie tresc idzie w drugi wiersz, zeby nie byla obcieta
     po trzech slowach. */
  .kok-alerty li{grid-template-columns:auto auto minmax(0,1fr)}
  .kok-alerty .tre{grid-column:1 / -1; white-space:normal}
}

/* Tabela pieter wg makiety: Pietro / Postep / % / Status.
   Wczesniej byla to lista paskow - tabela daje wyrownane kolumny,
   wiec procenty czyta sie pionowo, jeden pod drugim. */
.kok-tabela-pietra{width:100%; border-collapse:collapse}
.kok-tabela-pietra thead th{text-align:left; font-size:var(--t-xs);
  text-transform:uppercase; letter-spacing:.04em;
  color:var(--tekst-3); font-weight:600;
  padding:0 var(--kr-3) var(--kr-2) 0; border-bottom:1px solid var(--linia)}
.kok-tabela-pietra tbody tr{border-bottom:1px solid var(--linia)}
.kok-tabela-pietra tbody tr:last-child{border-bottom:none}
.kok-tabela-pietra th[scope="row"]{text-align:left; font-weight:400;
  padding:var(--kr-3) var(--kr-3) var(--kr-3) 0; white-space:nowrap}
.kok-tabela-pietra th[scope="row"] b{display:block;
  font-size:var(--t-m); color:var(--tekst-1)}
.kok-tabela-pietra th[scope="row"] span{font-size:var(--t-xs);
  color:var(--tekst-3)}
.kok-tabela-pietra td{padding:var(--kr-3) var(--kr-3) var(--kr-3) 0;
  vertical-align:middle}
.kok-tabela-pietra td:nth-child(2){width:45%}
.kok-tabela-pietra td.pr{font-variant-numeric:tabular-nums;
  font-weight:600; color:var(--tekst-1); text-align:right;
  white-space:nowrap; width:1%}
.kok-pietro-pasek{height:8px; border-radius:999px;
  background:var(--pow-3); overflow:hidden}
.kok-pietro-pasek > i{display:block; height:100%; border-radius:999px;
  transition:width .4s ease}
/* Pigulka stanu - kolor Z TOKENU, ksztalt znacznika niesie te sama
   informacje (daltonizm, wydruk cz-b). */
.kok-stan-pigulka{display:inline-flex; align-items:center;
  gap:var(--kr-2); padding:2px var(--kr-3); border-radius:999px;
  font-size:var(--t-xs); white-space:nowrap; color:var(--kol);
  background:color-mix(in srgb, var(--kol) 14%, transparent);
  border:1px solid color-mix(in srgb, var(--kol) 40%, transparent)}
.kok-znacznik{width:8px; height:8px; background:currentColor;
  flex:none}
.kok-znacznik.kolo{border-radius:50%}
.kok-znacznik.kwadrat{border-radius:1px}
.kok-znacznik.kreska{height:2px; width:10px; border-radius:1px}
@media (max-width:640px){
  /* Na waskim ekranie kolumna paska zjadalaby nazwe pietra. */
  .kok-tabela-pietra td:nth-child(2){display:none}
  .kok-tabela-pietra thead th:nth-child(2){display:none}
}

/* Wskaznik polkolisty (luk 270 stopni) - karta "Zaawansowanie" wg
   makiety. Zastapil pelny pierscien: ten pokazywal piec segmentow,
   czyli to samo co pipeline nizej. */
.kok-wskaznik{position:relative; width:100%; max-width:200px;
  margin:0 auto; aspect-ratio:1}
.kok-wskaznik svg{width:100%; height:100%; display:block}
.wsk-wart{transition:stroke-dasharray .4s ease}
.kok-wskaznik-srodek{position:absolute; inset:0; display:flex;
  flex-direction:column; align-items:center; justify-content:center;
  gap:2px; pointer-events:none}
.kok-wskaznik-srodek b{font-size:var(--t-3xl); font-weight:700;
  color:var(--tekst-1); line-height:1}
.kok-wskaznik-srodek span{font-size:var(--t-s); color:var(--tekst-3)}

/* Karta wskaznika jest pierwszym polem rzedu, a #kpi wnosi pozostale
   cztery. display:contents sprawia, ze karty z #kpi staja sie polami
   TEJ siatki, zamiast siedziec w jednej komorce jako osobna siatka. */
.kok-podsiatka{display:contents}
.kok-karta-wsk{display:flex; flex-direction:column;
  justify-content:center}

/* Pasek postepu pod liczba - karta "Pokoje".
   Karty rzedu musza byc kolumnami flex, inaczej margin-top:auto nie ma
   od czego odbic paska i ten przykleja sie do tekstu zamiast do dolu. */
.kok-rzad5 > .karta{display:flex; flex-direction:column}
.kok-pasek-p{height:6px; border-radius:999px; background:var(--pow-3);
  overflow:hidden; margin-top:auto}
.kok-pasek-p > i{display:block; height:100%; border-radius:999px;
  background:var(--akcent); transition:width .4s ease}
/* Przycisk na dole karty - wg makiety ramka, nie sam tekst. */
.kok-rzad5 .kok-link{margin-top:auto; justify-content:center;
  padding:var(--kr-2) var(--kr-3); border:1px solid var(--linia);
  border-radius:var(--r-m); text-decoration:none}
.kok-rzad5 .kok-link:hover{border-color:var(--akcent);
  background:color-mix(in srgb, var(--akcent) 10%, transparent)}

/* Karta zaawansowania nie jest juz paskiem - .bar.duzy trzyma wskaznik.
   Bez tego dziedziczy wysokosc paska (--pasek-wys-duzy) i tlo, ktore
   zgniotloby go do 10px.
   Siatka "wskaznik obok legendy" usunieta razem z legenda - wskaznik
   stoi teraz sam, wysrodkowany w karcie. */
.bar.duzy{height:auto; background:none; border-radius:0;
  display:block; overflow:visible}

/* ==========================================================================
   PRZEGLAD WG MAKIETY WLASCICIELA (panel.html, ekran #p-przeglad)

   Klasy sa scalone z istniejacymi .kok-*, ale KAZDA zmiana wygladu, ktora
   dotyczy tylko tego ekranu, siedzi pod wlasnym modyfikatorem
   (.kok-rzad5-wsk, .kok-pipe-mak, .kok-alerty.mak, .kok-licz.ramka).
   Powod: te same klasy bazowe rysuja kokpit inwestora (klient.html)
   i zmiana bez modyfikatora przerysowalaby takze jego.
   ========================================================================== */

/* ---------- rzad 1: wskaznik + cztery liczniki ----------
   Karta wskaznika jest SZERSZA od pozostalych (pierwsza kolumna 1,4fr)
   i to ona wyznacza wysokosc rzedu - pozostale cztery rozciagaja sie do
   niej, wiec rzad zostaje rowny, tak jak w makiecie.
   Ponizej 1200px podzial na piec kolumn nie ma sensu (karta ma wtedy
   180px i liczba nie miesci sie obok podpisu), wiec wraca uklad bazowy. */
.kok-rzad5-wsk{grid-template-columns:1.4fr repeat(4,minmax(0,1fr))}
.kok-rzad5-wsk .kok-karta-wsk{min-height:296px}
@media (max-width:1200px){
  .kok-rzad5-wsk{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kok-rzad5-wsk .kok-karta-wsk{min-height:0}
}
@media (max-width:900px){
  .kok-rzad5-wsk{grid-template-columns:minmax(0,1fr)}
}

/* ---------- karta zaawansowania ----------
   Ikonka "i" w prawym gornym rogu: z czego liczony jest procent.
   Sam znak jest juz okregiem z konturu (ikona "uwaga"), wiec nie
   dokladamy drugiej obwodki - dwa kola jedno w drugim czytaja sie
   jak blad renderu. */
.kok-karta-wsk h3{padding-right:30px}
.kok-info{
  position:absolute; top:var(--kr-4); right:var(--kr-4);
  display:inline-flex; color:var(--tekst-3); cursor:help; line-height:0;
  border-radius:var(--r-pelny);
}
.kok-info:hover{color:var(--tekst-1)}
.kok-info .ik-svg{width:16px; height:16px}
/* Dwa odcienie TEGO SAMEGO tokenu akcentu. stop-color="currentColor"
   czyta wlasnosc color ze stopu, wiec gradient zyje w tokenach i zmienia
   sie razem z motywem - zaden hex nie wchodzi do SVG. */
.wsk-g1{color:var(--akcent)}
.wsk-g2{color:var(--akcent-jasny)}
.kok-karta-wsk .kok-wskaznik{max-width:236px}
/* Procent w srodku luku - najwieksza liczba na ekranie. clamp, bo przy
   dwoch kolumnach (ponizej 1200px) 48px rozpycha karte. */
.kok-karta-wsk .kok-wskaznik-srodek b{font-size:clamp(var(--t-2xl),2.4vw,48px)}

/* ---------- karta pokoi ----------
   Podpis "94 zakonczone" wg makiety jest czytelnym tekstem, nie
   znakiem wodnym - --tekst-4 jest w systemie zarezerwowany dla
   elementow NIETEKSTOWYCH. */
.kok-rzad5 .k-p{color:var(--tekst-3)}

/* ---------- karta tempa ----------
   Sparkline siada na dnie karty, plakietka "vs plan" pod nim, przy
   prawej krawedzi. Wysokosc 60px zamiast 40: krzywa jest tu glownym
   obrazkiem karty, a nie dopiskiem pod liczba. */
.kok-rzad5 .kok-mini.wys{margin-top:auto}
.kok-mini.wys canvas{height:60px}
.kok-tempo-stopka{display:flex; justify-content:flex-end;
  margin-top:var(--kr-2)}

/* ---------- rzad 2: cztery karty tresci ----------
   Cztery kolumny miesci dopiero 1500px (przy 1920 karta ma 465px).
   Ponizej ida po dwie: pipeline sciety do 250px gubi podpisy etapow,
   a wykres - podpisy osi X. */
.kok-rzad4b{display:grid; gap:var(--kr-3); margin-bottom:var(--kr-5);
  grid-template-columns:repeat(4,minmax(0,1fr))}
.kok-rzad4b>.karta{margin-bottom:0; display:flex; flex-direction:column}
@media (max-width:1500px){
  .kok-rzad4b{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:900px){
  .kok-rzad4b{grid-template-columns:minmax(0,1fr)}
}
/* Naglowek karty z linkiem po prawej (karta usterek wg makiety). */
.kok-karta-glowa{display:flex; align-items:baseline;
  justify-content:space-between; gap:var(--kr-3); margin-bottom:var(--kr-4)}
.kok-karta-glowa h3{margin:0}
.kok-link-maly{font-size:var(--t-s); color:var(--akcent);
  text-decoration:none; white-space:nowrap; font-weight:var(--w-sredni)}
.kok-link-maly:hover{text-decoration:underline}

/* ---------- pipeline wg makiety ----------
   Kolejnosc podpisow pod kolkiem: nazwa etapu, procent, ulamek.
   Etap zamkniety ma kolko WYPELNIONE, biezacy - sama obwodke. Ksztalt
   niesie te sama informacje co kolor. */
.kok-pipe-mak .kok-etap .nz{display:block; margin-top:var(--kr-2);
  font-size:var(--t-xs); color:var(--tekst-2); line-height:1.3}
.kok-pipe-mak .kok-etap b{margin-top:2px; color:var(--tekst-1)}
.kok-pipe-mak .kok-etap .ul{margin:0}
.kok-pipe-mak .kok-etap.zrobiony .kok-kolo{
  background:var(--kol); border-color:var(--kol)}
.kok-pipe-mak .kok-etap.zrobiony .kok-kolo .ik-svg{
  color:var(--tekst-na-akcencie)}

/* ---------- tabela pieter: kolumna postepu jako kratka ----------
   Dwadziescia kwadracikow po 5% kazdy. Oko liczy kratki i porownuje
   wiersze miedzy soba; dlugosci ciaglego paska nie porownuje.
   Kratka kurczy sie ponizej 10px (flex-basis), zeby przy karcie
   szerokiej na cwierc rzedu nie wypchnac kolumny statusu. */
.kok-kratka{display:flex; gap:2px; align-items:center}
.kok-kratka i{flex:0 1 10px; min-width:3px; height:10px; border-radius:2px;
  background:var(--pow-3)}
.kok-kratka i.pelny{background:var(--kol)}
/* Lista pieter jest najdluzsza trescia rzedu - wlasne przewijanie
   zamiast rzedu wysokiego na dwa ekrany. Przycisk zostaje POD oknem
   przewijania, wiec nie ucieka razem z wierszami. */
.kok-przewij{overflow-y:auto; max-height:430px; margin-bottom:var(--kr-3)}
/* Czwarty ksztalt znacznika. Progi postepu maja cztery pasma, a rampa
   ksztaltow miala trzy - romb jest czwartym, poza rampa faz. */
.kok-znacznik.romb{transform:rotate(45deg); border-radius:1px}

/* ---------- wykres prognoza vs plan ----------
   Legenda NAD wykresem wg makiety. Plakietka terminu odbioru jest
   warstwa DOM nad plotnem, nie rysunkiem w silniku: hf-wykres.js
   umie postawic pionowa kreske, ale nie kolorowa etykiete, a silnik
   rysuje takze pozostale wykresy systemu. */
.wyk-leg.gora{margin-top:0; margin-bottom:var(--kr-3)}
.wyk-plakietka{
  position:absolute; top:0; z-index:4; pointer-events:none;
  transform:translateX(-50%); text-align:center; white-space:nowrap;
  font-size:var(--t-xs); line-height:1.25; padding:3px var(--kr-2);
  border-radius:var(--r-s); color:var(--kol-pl);
  background:color-mix(in srgb, var(--kol-pl) 16%, var(--pow-1));
  border:1px solid color-mix(in srgb, var(--kol-pl) 45%, transparent);
}
/* Termin blisko prawej krawedzi - plakietka wisi w lewo od kreski,
   inaczej wychodzi poza karte i zostaje ucieta. */
.wyk-plakietka.prawa{transform:translateX(-100%)}
.wyk-plakietka b{display:block; font-weight:var(--w-mocny);
  font-variant-numeric:tabular-nums}
/* Dwa kafelki pod wykresem: data z umowy i data z prognozy. */
.kok-kafelki{display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--kr-2); margin-top:var(--kr-3)}
.kok-kafel{background:var(--pow-2); border-radius:var(--r-m);
  padding:var(--kr-3); min-width:0}
.kok-kafel span{display:block; font-size:var(--t-xs); color:var(--tekst-3)}
.kok-kafel b{display:block; margin-top:2px; font-size:var(--t-m);
  font-weight:var(--w-mocny); color:var(--kol);
  font-variant-numeric:tabular-nums}

/* ---------- lista usterek i alertow wg makiety ----------
   Trzy kolumny: ikona pilnosci w kolowym tle, tresc ze wskazaniem
   miejsca, po prawej slowo pilnosci i czas wzgledny. */
.kok-alerty.mak li{grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center}
.kok-alerty.mak .kok-ikonka{width:30px; height:30px}
.kok-alerty.mak .kok-ikonka .ik-svg{width:16px; height:16px}
.kok-alerty.mak .tre-w{min-width:0}
.kok-alerty.mak .tre-w b{display:block; font-size:var(--t-s);
  font-weight:var(--w-mocny); color:var(--tekst-1);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kok-alerty.mak .tre-w span{display:block; font-size:var(--t-xs);
  color:var(--tekst-3); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap}
.kok-alerty.mak .pil{text-align:right; white-space:nowrap}
.kok-alerty.mak .pil b{display:block; font-size:var(--t-xs);
  font-weight:var(--w-mocny); color:var(--kol)}
.kok-alerty.mak .pil span{display:block; font-size:var(--t-xs);
  color:var(--tekst-3)}
/* Na waskim ekranie uklad zostaje trzykolumnowy: kolumna tresci ma
   minmax(0,1fr) i skraca sie wielokropkiem, a nie lamie w drugi wiersz.
   Regula 640px dla .kok-alerty (bez .mak) dotyczy starego ukladu
   z pigulka pilnosci i tej listy nie obejmuje. */
/* Liczniki stanu zgloszen. DWA, nie trzy: stan posredni "w trakcie"
   nie istnieje w bazie (komentarz.zamkniety to 0 albo 1). Obwodka
   w kolorze stanu, tlo zostaje przy powierzchni karty. */
.kok-liczniki.dwa{grid-template-columns:repeat(2,minmax(0,1fr))}
.kok-licz.ramka{background:transparent;
  border:1px solid color-mix(in srgb, var(--kol) 45%, transparent)}
.kok-licz.ramka b{color:var(--kol)}

/* ---------- pasek legendy na dole ekranu ----------
   Progi pasm sa TE SAME, ktore koloruja kratke w tabeli pieter:
   obie strony czytaja je z PROGI_POSTEPU w panel.html. Kropka niesie
   takze ksztalt, wiec pasmo da sie odczytac bez koloru. */
.kok-legenda .kok-znacznik{color:var(--kol)}
.kok-legenda-tyt{font-weight:var(--w-sredni); color:var(--tekst-2)}
.kok-akt b{color:var(--tekst-2); font-weight:var(--w-sredni);
  font-variant-numeric:tabular-nums}
.kok-akt .kok-ikbtn{padding:5px}
.kok-akt .kok-ikbtn .ik-svg{width:15px; height:15px}

/* ==========================================================================
   SZKIELET PODSTRON (A-E) wg makiet wlasciciela

   JEDEN komplet klas dla wszystkich ekranow poza Przegladem. Kazda
   podstrona sklada sie z tych samych pieciu warstw i zadna nie dopisuje
   sobie wlasnego wariantu w bloku <style>:

     A  naglowek strony   .kok-naglowek (buduje go hf-kokpit.js) + .mot-*
     B  pasek filtrow     .hf-filtry
     C  rzad kafelkow KPI .hf-kpi > .hf-kpi-k
     D  sekcje tresci     .hf-sek-h + .hf-sek-opis w .karta
     E  tabele            .hf-tab, .hf-stan, .hf-pasek

   Kolor tematu strony idzie przez --motyw i klase .mot-* na <body>.
   Wszystkie wartosci sa TOKENAMI - zadnego hexa w tej sekcji.
   ========================================================================== */

/* ---------- A. NAGLOWEK STRONY -------------------------------------------
   hf-kokpit.js stawia w naglowku <span class="kok-ikonka" style="--ik:…">.
   Inline style wygrywa z kazda regula arkusza, wiec kolor tematu NIE
   moze isc przez --ik: nadpisujemy wprost wlasciwosci (specyficznosc
   0,2,0 kontra 0,1,0 reguly bazowej), a --ik zostaje nieuzyte.
   Kafel 56 px i ikona 28 px, bo naglowek ma byc pierwsza rzecza, ktora
   oko znajduje po wejsciu na ekran - kolko karty (34 px) gubilo sie
   obok tytulu o wielkosci 2rem. */
:root{--motyw:var(--akcent)}
.kok-naglowek .kok-ikonka{
  width:56px; height:56px; border-radius:var(--r-m);
  color:var(--motyw);
  background:color-mix(in srgb, var(--motyw) 14%, transparent);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--motyw) 30%, transparent);
}
.kok-naglowek .kok-ikonka .ik-svg{width:28px; height:28px}
/* 2rem wg makiety, ale dopiero od szerokosci, na ktorej tytul i licznik
   mieszcza sie w jednym wierszu. Ponizej schodzi do kroku --t-2xl,
   inaczej dluzszy tytul ("Inwentura 12.09.2026") lamie sie na dwa. */
.kok-naglowek-t h1{font-size:clamp(var(--t-2xl), 2.4vw, 2rem);
  font-weight:700}
.kok-naglowek-t p{font-size:.875rem; color:var(--tekst-3)}
/* Licznik nagłówka razem z kaflem ikony. Liczba stoi PO LEWEJ od kafla,
   bo oko czyta wtedy „228 w obiekcie", a nie „budynek 228". Kafel jest
   ten sam co przy tytule — dwa rozmiary w jednym nagłówku wyglądałyby
   na przypadek. */
.kok-naglowek-licz{
  display:flex; align-items:center; gap:var(--kr-4); margin-left:auto;
}

/* Kolor tematu strony. Ustawiany klasa na <body>, zeby ten sam kafel
   naglowka i te same ikony sekcji mialy jeden kolor na calym ekranie.
   Przypisanie idzie za GRUPA paska bocznego, nie za kaprysem: logistyka
   blekit, produkcja fiolet, zamkniecia zielen, pieniadze szmaragd. */
.mot-transport {--motyw:var(--faza-logistyka)}
/* SNG-010: kolor idzie za GRUPA paska, nie za kaprysem - Dostawy dziela
   blekit z transportem i rozladunkiem, Montaz turkus z budowa. */
.mot-dostawy   {--motyw:var(--faza-logistyka)}
.mot-montaz    {--motyw:var(--faza-budowa)}
.mot-zamowienia{--motyw:var(--uwaga)}
.mot-raporty   {--motyw:var(--akcent)}
.mot-produkcja {--motyw:var(--faza-przygotowanie)}
.mot-inwentura {--motyw:var(--faza-budowa)}
.mot-katalog   {--motyw:var(--uwaga)}
.mot-regulacje {--motyw:var(--alarm)}
.mot-odbiory   {--motyw:var(--faza-zamkniete)}
.mot-godziny   {--motyw:var(--akcent)}
.mot-wydajnosc {--motyw:var(--faza-budowa)}
.mot-budzet    {--motyw:var(--ok)}
.mot-admin     {--motyw:var(--faza-przygotowanie)}

/* ---------- B. PASEK FILTROW ---------------------------------------------
   Rzad pigulek pod naglowkiem: pola dat, przelaczniki zakresu, po prawej
   przycisk glowny. Wszystko w jednej linii bazowej, zeby pasek czytal sie
   jak jedno zdanie ("od … do … za 30 dni → pokaz"). */
.hf-filtry{
  display:flex; align-items:flex-end; flex-wrap:wrap;
  gap:var(--kr-2) var(--kr-3); margin-bottom:var(--kr-5);
}
.hf-filtry-pole{display:flex; flex-direction:column; gap:var(--kr-1);
  min-width:0}
.hf-filtry-pole>span{
  font-size:.7rem; text-transform:uppercase; letter-spacing:.05em;
  color:var(--tekst-3); font-weight:var(--w-sredni);
}
/* Pole daty z ikona kalendarza po lewej. Ikona jest OZDOBA pola, nie
   przyciskiem - pointer-events wylaczone, zeby klikniecie w nia otwieralo
   kalendarz przegladarki, a nie lapalo sie na span. */
.hf-data{
  display:inline-flex; align-items:center; gap:var(--kr-2);
  background:var(--pow-2); border:1px solid var(--linia);
  border-radius:var(--r-pelny); padding:0 var(--kr-3);
  min-height:var(--dotyk); color:var(--tekst-3);
}
.hf-data .ik-svg{width:16px; height:16px; flex:0 0 auto;
  pointer-events:none}
.hf-data input{
  font:inherit; font-size:var(--t-s); color:var(--tekst-1);
  background:none; border:0; outline:none; padding:0; min-width:112px;
}
/* Przelaczniki zakresu. Aktywny ma tlo --akcent i tekst z tokenu
   "na akcencie" - nie goly #fff, bo w motywie jasnym bialy napis na
   blekicie spada ponizej progu. */
.hf-zakres{display:flex; flex-wrap:wrap; gap:var(--kr-1)}
.hf-zakres button{
  font:inherit; font-size:var(--t-s); color:var(--tekst-2);
  background:none; border:1px solid var(--linia);
  border-radius:var(--r-pelny); padding:0 var(--kr-4);
  min-height:var(--dotyk); cursor:pointer; white-space:nowrap;
}
.hf-zakres button:hover{background:var(--pow-2); color:var(--tekst-1)}
.hf-zakres button.on{
  background:var(--akcent); border-color:var(--akcent);
  color:var(--tekst-na-akcencie); font-weight:var(--w-sredni);
}
.hf-filtry .hf-glowny{margin-left:auto}

/* Wariant paska, w którym pola dzielą CAŁĄ szerokość rzędu (ekran Pokoje
   wg makiety właściciela). Piętro, stan i numer są tu równorzędne — żadne
   nie ma prawa być szersze od pozostałych — a przycisk czyszczenia stoi
   przy prawej krawędzi. Pola dostają obwódkę i --r-m, bo w tym pasku są
   głównym elementem ekranu, nie dodatkiem do tabeli poniżej. */
.hf-filtry.rozciagniete{align-items:center}
.hf-filtry.rozciagniete>select,
.hf-filtry.rozciagniete>.hf-szukajka{
  flex:1 1 180px; min-width:0;
  border:1px solid var(--linia); border-radius:var(--r-m);
  min-height:var(--dotyk);
}
/* background-COLOR, nie skrót background: reguła bazowa selecta trzyma
   w background-image strzałkę rozwijania, a skrót by ją wymazał. */
.hf-filtry.rozciagniete>select{background-color:var(--pow-2)}
.hf-filtry.rozciagniete>.hf-szukajka{background:var(--pow-2)}
/* Pole szukania z lupą. Lupa jest OZDOBĄ pola, nie przyciskiem —
   pointer-events wyłączone, żeby klik w nią ustawiał kursor w polu. */
.hf-szukajka{
  display:flex; align-items:center; gap:var(--kr-2);
  padding:0 var(--kr-3); color:var(--tekst-3);
}
.hf-szukajka .ik-svg{width:16px; height:16px; flex:0 0 auto;
  pointer-events:none}
.hf-szukajka input{
  font:inherit; font-size:var(--t-s); color:var(--tekst-1);
  background:none; border:0; outline:none; padding:0;
  width:100%; min-width:0; min-height:var(--dotyk);
}

/* ---------- C. RZAD KAFELKOW KPI -----------------------------------------
   Ikona w kolowym tle w lewym gornym rogu, obok kolumna podpis-liczba-
   jednostka, przy prawej krawedzi sparkline. Karty maja rowna wysokosc
   (stretch z siatki), wiec sparkline siada na dole kazdej z nich. */
.hf-kpi{
  display:grid; gap:var(--kr-3); margin-bottom:var(--kr-5);
  grid-template-columns:repeat(auto-fit,minmax(var(--kpi-min),1fr));
}
.hf-kpi-k{
  display:flex; align-items:flex-start; gap:var(--kr-3); min-width:0;
  background:var(--pow-1); border-radius:var(--r-l); padding:var(--kr-4);
}
.hf-kpi-ik{
  width:40px; height:40px; border-radius:var(--r-pelny); flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  line-height:0; color:var(--kol);
  background:color-mix(in srgb, var(--kol) 16%, transparent);
}
.hf-kpi-ik .ik-svg{width:20px; height:20px}
.hf-kpi-t{flex:1 1 auto; min-width:0}
.hf-kpi-l{
  display:block; font-size:.7rem; text-transform:uppercase;
  letter-spacing:.05em; color:var(--tekst-3); font-weight:var(--w-sredni);
}
.hf-kpi-v{
  display:block; margin-top:var(--kr-2); font-size:2rem; font-weight:700;
  letter-spacing:-.035em; line-height:1; color:var(--tekst-1);
  font-variant-numeric:tabular-nums;
}
.hf-kpi-p{display:block; margin-top:var(--kr-2); font-size:var(--t-s);
  color:var(--tekst-3)}
/* Sparkline: ~90x36 wg makiety. Rysowany TYLKO tam, gdzie dane maja
   szereg czasowy - pusta owijka nie zostawia dziury, bo ma zerowa
   wysokosc, dopoki nie dostanie plotna. */
.hf-kpi-mini{flex:0 0 90px; width:90px; margin-left:auto;
  align-self:flex-end}
.hf-kpi-mini canvas{display:block; width:100%; height:36px}

/* SNG-070: KAFELEK Z AKCJA. Bramkuje go [role="button"], ktory kpiKarta
   stawia TYLKO wtedy, gdy ekran podal akcje - dziewiec ekranow na dziesiec
   jej nie podaje i te maja wygladac dokladnie jak dotad. Kursor wskaznika
   i obwodka fokusu na kafelku, ktory nie reaguje, to obietnica bez
   pokrycia.

   KOLEJNOSC TYCH REGUL NIE ROZSTRZYGA NICZEGO i tak ma zostac: :hover
   rusza tylko transform i cien, a [data-stan] tylko tlo, ramke i padding.
   Zbiory wlasciwosci sa rozlaczne, wiec kafelek z wlaczonym filtrem NIE
   gubi zaznaczenia pod kursorem (to wlasnie zdarzylo sie przy .pok.on,
   patrz regulacje.html). */
.hf-kpi-k[role="button"]{cursor:pointer;
  transition:transform .18s, box-shadow .18s}
.hf-kpi-k[role="button"]:hover{transform:translateY(-2px);
  box-shadow:var(--cien-s)}
.hf-kpi-k[role="button"]:focus-visible{outline:2px solid var(--akcent);
  outline-offset:2px}

/* FILTR WLACZONY. Stan niesie data-stan, nie klasa sklejana w stringu.
   DWA NOSNIKI OPROCZ SLOWA w podpisie: tlo z color-mix NIEPRZEZROCZYSTE
   (var(--pow-1) pod spodem, nie "transparent") i ramka - roznica
   ksztaltu dziala tez w sloncu i przy daltonizmie.
   Padding schodzi o 2 px razem z ramka rosnaca o 2 px, inaczej caly rzad
   kafelkow przeskakiwalby przy kazdym klikniecu filtru. */
.hf-kpi-k[data-stan="wlaczony"]{
  background:color-mix(in srgb, var(--akcent) 14%, var(--pow-1));
  border:2px solid var(--akcent); padding:calc(var(--kr-4) - 2px)}

/* ---------- D. SEKCJE TRESCI ---------------------------------------------
   Naglowek karty: ikona 18 px + <h3>, pod spodem opcjonalne jedno zdanie
   wyjasnienia. Wyjasnienie stoi tam, gdzie liczba da sie zle zrozumiec -
   nie pod kazdym naglowkiem. */
.hf-sek-h{
  display:flex; align-items:center; gap:var(--kr-3); flex-wrap:wrap;
  margin:0 0 var(--kr-3);
}
.hf-sek-h .ik-svg{width:18px; height:18px; flex:0 0 auto;
  color:var(--motyw)}
.hf-sek-h h3{margin:0; flex:1 1 auto; min-width:0}
.hf-sek-h .meta{font-size:var(--t-s); color:var(--tekst-3);
  font-weight:var(--w-zwykly)}
.hf-sek-opis{
  margin:calc(-1 * var(--kr-2)) 0 var(--kr-4); max-width:78ch;
  font-size:.8rem; line-height:1.55; color:var(--tekst-3);
}
.hf-sek-opis b{color:var(--tekst-2); font-weight:var(--w-sredni)}

/* ---------- E. TABELE -----------------------------------------------------
   Naglowek wersalikami z dolna linia, wiersze rozdzielone linia (ostatni
   bez), liczby tabularne do prawej, tekst do lewej. Reguly bazowe tabeli
   daja th tlo i cien - tu oba sa zerowane, bo linia ma byc jedna i pelna. */
.hf-tab{width:100%; border-collapse:collapse; font-size:var(--t-s)}
.hf-tab th{
  text-align:left; font-size:.7rem; text-transform:uppercase;
  letter-spacing:.05em; font-weight:var(--w-sredni); color:var(--tekst-3);
  padding:0 var(--kr-3) var(--kr-2); background:none; box-shadow:none;
  border-bottom:1px solid var(--linia); white-space:nowrap;
}
.hf-tab td{
  padding:var(--pad-komorki) var(--kr-3); color:var(--tekst-2);
  border-bottom:1px solid var(--linia); vertical-align:middle;
}
.hf-tab tbody tr:last-child td{border-bottom:0}
.hf-tab th.num,.hf-tab td.num{text-align:right}
.hf-tab td.num{font-variant-numeric:tabular-nums; color:var(--tekst-1)}
.hf-tab td b{color:var(--tekst-1); font-weight:var(--w-mocny)}
.hf-tab .pusto{padding:var(--kr-5) var(--kr-3); text-align:center}

/* Pigulka stanu: kropka + tekst. Kropka niesie kolor, tekst niesie
   znaczenie - zadne z dwojga nie wystarcza samo. */
.hf-stan{
  display:inline-flex; align-items:center; gap:var(--wsk-odstep);
  font-size:var(--t-xs); line-height:1.4; white-space:nowrap;
  padding:3px var(--kr-3); border-radius:var(--r-pelny);
  color:var(--tekst-2);
  background:color-mix(in srgb, var(--kol, var(--tekst-4)) 15%, transparent);
}
.hf-stan::before{
  content:""; flex:0 0 auto; width:8px; height:8px;
  border-radius:var(--r-pelny); background:var(--kol, var(--tekst-4));
}
/* Wariant konturowy dla stanu ZAMKNIETEGO - drugi kanal poza kolorem:
   pelna kropka = w toku, pierscien = zamkniete. */
.hf-stan.domkniety::before{background:none;
  box-shadow:inset 0 0 0 2px var(--kol, var(--tekst-4))}

/* Pasek postepu w komorce tabeli. */
.hf-pasek{
  height:var(--pasek-wys); border-radius:var(--r-pelny);
  background:var(--pow-3); overflow:hidden; min-width:60px;
}
.hf-pasek i{display:block; height:100%; border-radius:inherit;
  background:var(--kol, var(--akcent))}
/* Pasek z procentem obok - procent zawsze po prawej, tabularnie. */
.hf-pasek-w{display:flex; align-items:center; gap:var(--kr-3)}
.hf-pasek-w .hf-pasek{flex:1 1 auto}
.hf-pasek-w b{flex:0 0 auto; font-variant-numeric:tabular-nums;
  font-size:var(--t-s); color:var(--tekst-1)}

/* Znacznik miejsca w rankingu. NIE .kok-kolo - ta klasa nalezy do kolek
   pipeline'u i ma wlasne wymiary oraz obwodke. */
.hf-miejsce{
  width:28px; height:28px; border-radius:var(--r-pelny); flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:var(--t-s); font-weight:var(--w-mocny);
  font-variant-numeric:tabular-nums;
  background:var(--pow-3); color:var(--tekst-2);
}
/* Podium: kolor niesie OBWODKA, nie tlo - pelne tlo medalowe dawalo
   kontrast ponizej progu (jasna cyfra na jasnym zlocie). */
.hf-miejsce.m1{background:transparent; color:var(--uwaga);
  box-shadow:inset 0 0 0 2px var(--uwaga)}
.hf-miejsce.m2{background:transparent; color:var(--tekst-2);
  box-shadow:inset 0 0 0 2px var(--tekst-3)}
.hf-miejsce.m3{background:transparent; color:var(--faza-logistyka);
  box-shadow:inset 0 0 0 2px var(--faza-logistyka)}

/* Stan pusty sekcji: ikona + jedno zdanie, co zrobic. Sam napis "brak
   danych" nie mowi, czy to blad, czy po prostu nikt jeszcze nic nie
   wpisal. */
.hf-pusto{
  display:flex; flex-direction:column; align-items:center; gap:var(--kr-3);
  padding:var(--kr-6) var(--kr-4); text-align:center; color:var(--tekst-3);
  font-size:var(--t-s);
}
.hf-pusto .ik-svg{width:28px; height:28px; color:var(--tekst-4)}
.hf-pusto b{display:block; color:var(--tekst-2); font-size:var(--t-m);
  font-weight:var(--w-sredni)}

/* ---------- BRAMA: WYNIK TAK / NIE ---------------------------------------
   Pasek werdyktu nad trescia ("obiekt jednorodny" / "pokoje sie roznia",
   "pietro gotowe do odbioru" / "sa usterki"). Dotad kazdy ekran mial
   wlasna kopie tych klas, a ikone niosl emoji - tu jest jedna definicja
   i ikona z hf-ikony.js, wiec znak wyglada tak samo w calym systemie. */
.brama.tak,.brama.nie{
  display:flex; align-items:center; gap:var(--kr-4); flex-wrap:wrap;
  background:var(--pow-2); border-radius:var(--r-m);
  padding:var(--kr-4); margin-bottom:var(--kr-4);
}
.brama.tak{border-left:var(--brama-pas) solid var(--ok)}
.brama.nie{border-left:var(--brama-pas) solid var(--alarm)}
.brama-i{flex:0 0 auto; line-height:0}
.brama-i .ik-svg{width:26px; height:26px}
.brama.tak .brama-i{color:var(--ok)}
.brama.nie .brama-i{color:var(--alarm)}
.brama-t{flex:1 1 190px; min-width:0}
.brama-t b{display:block; font-size:var(--t-m); color:var(--tekst-1);
  margin-bottom:2px}
.brama-t span{font-size:var(--t-s); color:var(--tekst-3)}

/* Plakietka odchylenia od sredniej. */
.hf-delta{
  display:inline-flex; align-items:center; gap:var(--kr-1);
  font-size:var(--t-xs); font-weight:var(--w-mocny);
  padding:2px var(--kr-2); border-radius:var(--r-pelny);
}
.hf-delta.plus{color:var(--ok); background:var(--ok-tlo)}
.hf-delta.zero{color:var(--tekst-3); background:var(--pow-3)}
.hf-delta.minus{color:var(--alarm); background:var(--alarm-tlo)}

/* ---------- ROZDZIELACZ: KAFELKI PROWADZACE DO EKRANOW -------------------
   Ekran, ktory sam nie ma danych, tylko rozprowadza do tych, ktore je
   maja (Dostawy, Montaz, Zamowienia, Raporty - SNG-010). Jeden komplet
   klas na cztery ekrany, zeby zaden nie dopisywal sobie wlasnej wersji
   kafelka w bloku <style>.

   Kafelek MA dwa warianty i rozroznia je KSZTALT krawedzi, nie kolor:
     <a class="roz-kafel">           - prowadzi do istniejacego ekranu,
                                       krawedz ciagla
     <div class="roz-kafel wkrotce"> - miejsce na tresc, ktorej nie ma,
                                       krawedz przerywana + pigulka
   Wariant "wkrotce" nie jest linkiem, wiec nie da sie go kliknac ani
   zlapac tabulatorem - martwy link jest gorszy niz jego brak. */
.roz-kafle{
  display:grid; gap:var(--kr-3); margin-bottom:var(--kr-3);
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
}
.roz-kafel{
  display:flex; align-items:flex-start; gap:var(--kr-3); min-width:0;
  padding:var(--kr-4); border-radius:var(--r-l);
  background:var(--pow-1); border:1px solid var(--linia);
  color:inherit; text-decoration:none;
}
a.roz-kafel:hover{border-color:var(--motyw); background:var(--pow-hover)}
a.roz-kafel:focus-visible{outline:2px solid var(--motyw); outline-offset:2px}
.roz-kafel.wkrotce{border-style:dashed; background:transparent}
.roz-ik{
  width:40px; height:40px; border-radius:var(--r-pelny); flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  line-height:0; color:var(--motyw);
  background:color-mix(in srgb, var(--motyw) 16%, transparent);
}
.roz-ik .ik-svg{width:20px; height:20px}
.roz-kafel.wkrotce .roz-ik{color:var(--tekst-3);
  background:var(--pow-3)}
.roz-t{flex:1 1 auto; min-width:0}
.roz-t b{display:block; font-size:var(--t-m); color:var(--tekst-1);
  font-weight:var(--w-sredni)}
.roz-t p{margin:var(--kr-1) 0 0; font-size:var(--t-s); color:var(--tekst-3);
  line-height:1.5}
/* Liczba na kafelku stoi TYLKO tam, gdzie da sie ja wziac z danych,
   ktore ekran docelowy i tak oddaje. Kafelek bez liczby nie pokazuje
   myslnika - puste miejsce mowi mniej niz wymyslone zero. */
.roz-licz{display:block; margin-top:var(--kr-2); font-size:var(--t-m);
  color:var(--tekst-1); font-variant-numeric:tabular-nums;
  font-weight:var(--w-sredni)}
/* Lista zapowiedzi: co sie na ekranie znajdzie, gdy powstanie. */
.roz-lista{margin:0; padding-left:var(--kr-5); color:var(--tekst-2);
  font-size:var(--t-s); line-height:1.7}

/* ---------- PASEK ALERTOW O USTERCE (SNG-020) ----------------------------
   Stoi na samej gorze ekranu glownego i ma byc widoczny od razu, bez
   przewijania - stad mocna krawedz z lewej zamiast calego czerwonego
   tla. Tlo na pelnej szerokosci przykrywaloby gore kazdego ekranu
   i po trzech dniach przestaloby byc zauwazane.

   Kazdy wiersz jest LINKIEM do pokoju i mebla, wiec dostaje podswietlone
   tlo przy najechaniu i obwodke przy fokusie z klawiatury - bez tego
   drugiego nie da sie po pasku chodzic tabulatorem.
   Powod rozpoznaje sie po IKONIE, nie po barwie.
   ------------------------------------------------------------------------ */
.al-pasek{
  background:var(--pow-1); border:1px solid var(--linia);
  border-left:3px solid var(--alarm); border-radius:var(--r-m);
  padding:var(--kr-3); margin-bottom:var(--kr-4);
  box-shadow:var(--cien-s);
}
.al-h{display:flex; align-items:center; gap:var(--kr-2);
  color:var(--alarm); font-size:var(--t-s); margin-bottom:var(--kr-2)}
.al-h svg{width:16px; height:16px; flex-shrink:0}
.al-lic{margin-left:auto; color:var(--tekst-3); font-size:var(--t-xs);
  font-variant-numeric:tabular-nums}
.al-w{
  display:flex; align-items:flex-start; gap:var(--kr-3);
  padding:var(--kr-2) var(--kr-2); border-radius:var(--r-s);
  color:var(--tekst-1); text-decoration:none;
}
.al-w+.al-w{border-top:1px solid var(--linia-cicha)}
.al-w:hover{background:var(--pow-2)}
.al-w:focus-visible{outline:2px solid var(--akcent); outline-offset:1px}
.al-ik{flex-shrink:0; color:var(--alarm); line-height:0;
  padding-top:2px}
.al-ik svg{width:16px; height:16px}
.al-t{display:flex; flex-direction:column; gap:1px; min-width:0}
.al-t b{font-size:var(--t-s)}
.al-gdzie{font-size:var(--t-s); color:var(--tekst-2)}
/* Opis to zdanie z audytu - bywa dlugie. Jedna linia z wielokropkiem:
   pelna tresc czeka w pokoju, do ktorego ten wiersz prowadzi. */
.al-opis{font-size:var(--t-xs); color:var(--tekst-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.al-kiedy{margin-left:auto; flex-shrink:0; font-size:var(--t-xs);
  color:var(--tekst-3); white-space:nowrap; padding-top:2px}
@media (max-width:640px){
  /* Na telefonie data schodzi pod tresc - inaczej zjada polowe
     szerokosci wiersza i opis nie miesci sie w ogole. */
  .al-w{flex-wrap:wrap}
  .al-kiedy{margin-left:calc(16px + var(--kr-3)); padding-top:0}
}

/* ---------- ZAKRES SZEROKOSCI 1000-2200 px -------------------------------
   Ponizej 900 px karty ida jedna pod druga, a kolumny oznaczone
   .hf-kol-opc (najmniej wazne) znikaja - lepiej pokazac piec kolumn
   czytelnie niz osiem sciete wielokropkiem. */
@media (max-width:900px){
  .hf-kpi{grid-template-columns:minmax(0,1fr)}
  .hf-kpi-mini{display:none}
  .hf-filtry .hf-glowny{margin-left:0}
  .hf-tab th.hf-kol-opc,.hf-tab td.hf-kol-opc{display:none}
  .kok-naglowek .kok-ikonka{width:44px; height:44px}
  .kok-naglowek .kok-ikonka .ik-svg{width:22px; height:22px}
}
@media print{
  .hf-filtry,.hf-kpi-mini{display:none !important}
}

/* ---------- ATRYBUT hidden ----------------------------------------------
   Przegladarka daje elementowi z atrybutem hidden domyslne
   display:none, ale KAZDA wlasna regula z display bije ten domyslny
   styl - i element z hidden zostaje na ekranie. W tym arkuszu jest
   158 klas z wlasnym display, wiec pulapka dotyczyla siedmiu miejsc
   (m.in. raporty.html pokazywaly tabele z danymi i pod nia napis
   "Nikt nie wpisal jeszcze godzin").

   Regula stoi na KONCU pliku, bo ma te sama wage co selektor klasy
   (0,1,0) - przy rownej wadze wygrywa pozniejsza. Dlatego nie trzeba
   tu !important, ktory w tym repo jest zakazany.
   ------------------------------------------------------------------------ */
[hidden]{display:none}
