/* ==========================================================================
   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;
  --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;
  --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);
  --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". Pokój zakończony
   zostaje przy żółtej ramce z zielonym znacznikiem — to znaczy „czeka na
   sprawdzenie przez właściciela", a nie „gotowe".
   ------------------------------------------------------------------------ */
.pokoje .pok.mt-montaz{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));
}

.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)}
.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);
  --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);
    --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)}
.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}

/* ---------- 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}
