/* Biotop – panel pracownika */

:root {
  --pomaranczowy: #ff6600;
  --pomaranczowy-ciemny: #e05c00;
  --pomaranczowy-tlo: #fff3ea;
  --grafit: #2e3a47;
  --grafit-jasny: #5b6876;
  --czarny: #000;
  --szary: #8794a3;
  --tlo: #f1f3f6;
  --karta: #fff;
  --obwodka: #cbcbcb;
  /* Obwodka WIDOCZNA – do pol, ktore maja sie rzucac w oczy, a nie tylko domykac uklad.
     `--obwodka` jest celowo ledwie widoczna (rozdziela wiersze tabel i sekcje kart);
     na polu, ktorego ktos ma SZUKAC wzrokiem, znika razem z jego krawedzia. */
  --obwodka-mocna: #ccd5e0;
  --pole: #f4f6f9;
  --zielony: #16a34a;
  /* Blada zielen pod pastylke „ta ekipa juz to ma" — para do `--pomaranczowy-tlo`. */
  --zielony-tlo: #e9f7ee;
  /* Zolc przygaszona do czytelnej: czysta #ffdd00 na jasnym tle znika, a ciemniejszy
     bursztyn zlewalby sie z pomaranczowym akcentem marki. Ta wartosc czyta sie jako
     zolta i odroznia od obu. */
  --zolty: #eab308;
  --czerwony: #dc2626;
  --r: 12px;
  --cien: 0 1px 2px rgba(46, 58, 71, 0.06), 0 8px 24px rgba(46, 58, 71, 0.06);
  /* Ile miejsca zajmuje wszystko, co przykleja sie do gory ekranu. 60 px paska plus
     24 px oddechu; strony z podmenu sekcji podnosza to nizej o jego wysokosc. */
  --podmenu-h: 0px;
  --gora-lepka: calc(84px + var(--podmenu-h));

  /*
   * PISMO W POLACH FORMULARZA – ZMIENNA, A NIE STALA, i to nie jest ozdoba.
   *
   * Safari na iPhonie POWIEKSZA CALA STRONE, gdy ognisko wchodzi w pole o pismie
   * mniejszym niz 16 px – i po wyjsciu z pola juz jej nie zmniejsza. Skutek: po
   * pierwszym kliknieciu w cokolwiek formularz wyceny jest przyciety z prawej strony
   * i trzeba go recznie odsuwac dwoma palcami. Wyglada to na zepsuty uklad, a jest
   * zachowaniem przegladarki.
   *
   * Zmienna, bo bazowa regula pol ma specyficznosc (0,10,1) przez lancuch `:not()`
   * (patrz komentarz przy niej) i NIE DA SIE jej nadpisac w `@media` zadnym rozsadnym
   * selektorem – trzeba by przepisac caly lancuch drugi raz. Wartosc podmieniamy wiec
   * o poziom wyzej, tam gdzie zadna specyficznosc nie wchodzi w gre.
   */
  --pole-pismo: 15px;
}

/* Prog ten sam co przy szufladzie – ponizej niego pracuje sie palcem, nie myszka. */
@media (max-width: 900px) { :root { --pole-pismo: 16px; } }

body.z-podmenu { --podmenu-h: 47px; }

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--tlo);
  color: var(--grafit);
  font-size: 15px;
  line-height: 1.5;
}

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.02em; }
a { color: var(--pomaranczowy); }

/* ---------------------------------------------------------------- belka */

.belka {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 20px;
  padding: 0 24px; height: 60px;
  background: var(--czarny); color: #fff;
}
.belka .logo { display: flex; align-items: center; color: #fff; text-decoration: none; }

/*
 * Logo Biotop.
 *
 * Znak jest jednokolorowy, wiec zamiast trzymac dwa pliki – bialy na czarny pasek
 * i ciemny na biala karte logowania – wstawiamy go jako MASKE i barwimy `currentColor`.
 * Kolor logo idzie wtedy za kolorem tekstu w miejscu, w ktorym stoi, i nie da sie
 * przypadkiem postawic bialego znaku na bialym tle.
 *
 * Wymiary musza byc podane tutaj: maska, w odroznieniu od <img>, nie wnosi wlasnego
 * rozmiaru i element bez szerokosci i wysokosci byłby po prostu niewidoczny.
 * 126 x 24 to proporcja z pliku (382 x 73).
 */
.znak {
  display: block;
  width: 126px; height: 24px;
  background-color: currentColor;
  -webkit-mask: url('/img/biotop-logo.svg') no-repeat center / contain;
  mask: url('/img/biotop-logo.svg') no-repeat center / contain;
}
/*
 * MENU ODDAJE MIEJSCE JAKO PIERWSZE i przewija sie w sobie, zamiast rozpychac strone.
 *
 * Administrator ma w pasku jedenascie pozycji i przy 1440 px – czyli na zwyklym laptopie –
 * nie miescily sie razem z przyciskiem akcji i nazwiskiem. Pasek nie ma jak urosnac, wiec
 * wypychal `.prawo` poza okno: „+ Dodaj wycene" i menu konta stawaly 95 px za krawedzia,
 * a CALA strona dostawala poziomy pasek przewijania. Wygladalo to jak zle policzony uklad
 * tresci, a bylo przepelnionym naglowkiem.
 *
 * `min-width: 0` jest tu obowiazkowe: element flex domyslnie nie kurczy sie ponizej swojej
 * tresci, wiec bez tego `overflow` nigdy by sie nie wlaczyl. `white-space: nowrap` pilnuje,
 * zeby kurczenie nie zamienilo sie w lamanie etykiet – pasek ma zostac wysoki na 60 px.
 *
 * Ponizej 900 px menu i tak znika (patrz „burger i szuflada”), wiec przewijana wersja jest
 * wylacznie zaworem bezpieczenstwa dla waskich laptopow, a nie sposobem korzystania z menu.
 */
.belka nav { display: flex; gap: 4px; margin-left: 12px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.belka nav::-webkit-scrollbar { display: none; }
.belka .logo, .belka .prawo { flex: 0 0 auto; }
.belka nav a {
  color: #c3ccd6; text-decoration: none; padding: 7px 12px;
  border-radius: 8px; font-size: 14px; font-weight: 500;
  display: flex; align-items: center; gap: 7px; white-space: nowrap;
}
.belka nav a:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.belka nav a.aktywny { background: var(--pomaranczowy); color: #fff; }

/* Ikona jest CIEMNIEJSZA od napisu i dopiero na aktywnej pozycji zrównuje się z nim.
   Przy siedmiu pozycjach rysunki w pełnej sile robiły z paska rząd migających plamek
   i wzrok nie miał się o co zaczepić – etykieta ma zostać treścią, ikona podpowiedzią. */
.belka nav a svg { width: 17px; height: 17px; flex: 0 0 auto; opacity: 0.75; }
.belka nav a:hover svg, .belka nav a.aktywny svg { opacity: 1; }
.belka .prawo { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* Oddziela czynnosc odwracalna od nieodwracalnej – patrz komentarz przy przyciskach
   „Zapisz" i „Wyslij oferte" w wycena.html. */
.belka .rozdzielacz {
  width: 1px; height: 22px; flex: 0 0 auto;
  background: rgba(255, 255, 255, 0.18); margin: 0 6px;
}

/* ---------------------------------------------------- burger i szuflada */

/*
 * MENU NA TELEFONIE SCHODZI DO SZUFLADY.
 *
 * Pozycji menu jest do trzynastu (zaleznie od roli) i zaden zabieg nie zmiesci ich
 * w jednej linii obok logo, przycisku akcji i nazwiska. Stal tu wczesniej pasek
 * przewijany w poziomie: miescil sie, ale pokazywal naraz dwie pozycje z jedenastu
 * i nie bylo po nim widac, ze cokolwiek jest dalej – czyli chronil uklad przed
 * rozjechaniem sie, a nie czlowieka przed szukaniem.
 *
 * Teraz `<nav>` w pasku po prostu znika, a to samo menu – w calosci, jedna pozycja
 * pod druga, razem z pozycjami konta – otwiera burger po lewej. W pasku zostaje to,
 * czego szuka sie na telefonie od razu: logo (powrot na liste) i przycisk akcji.
 *
 * Burger i szuflada powstaja w `konto.mjs`, razem z menu – strony nie maja ich w HTML.
 * Prog 900 px stoi w obu plikach i musi byc ten sam; w JS nazywa sie `PROG_SZUFLADY`.
 */

/*
 * Burger stoi PIERWSZY W PASKU, po lewej – tam, gdzie na telefonie siega kciuk
 * i gdzie kazdy go szuka. Rysowany kreskami w CSS, a nie ikona z `ikony.mjs`:
 * na czarnym pasku sa to trzy prostokaty, wiec plik SVG nie wnosilby nic poza
 * kolejnym miejscem, w ktorym trzeba pilnowac koloru.
 */
.burger {
  display: none;                      /* wlacza sie dopiero ponizej progu – regula na koncu sekcji */
  flex: 0 0 auto;
  flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  width: 40px; height: 40px; margin-left: -6px;
  padding: 0; border: 0; border-radius: 9px;
  background: none; cursor: pointer;
}
.burger span {
  display: block; width: 19px; height: 2px; border-radius: 2px;
  background: #c3ccd6; transition: background .12s;
}
.burger:hover { background: rgba(255, 255, 255, 0.08); }
.burger:hover span, .burger[aria-expanded='true'] span { background: #fff; }

/*
 * SZUFLADA. Zostaje w drzewie dokumentu i chowa sie przez `visibility` – tak samo jak
 * toast nizej w tym pliku i z tego samego powodu: `hidden` albo `display: none` ucinaja
 * animacje wjazdu, a bez niej nie widac, SKAD menu przyjechalo. `visibility: hidden`
 * wyjmuje ja przy tym z czytnika ekranu i z klikania, wiec nie jest to samo schowanie
 * pod krawedz ekranu.
 */
.szuflada {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 120;
  width: min(310px, 86vw);
  display: flex; flex-direction: column;
  background: var(--karta);
  box-shadow: 0 0 40px rgba(46, 58, 71, .28);
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform .22s ease, visibility .22s;
  overflow-y: auto; overscroll-behavior: contain;
}
.szuflada.otwarta { transform: translateX(0); visibility: visible; }

.szuflada-zaslona {
  position: fixed; inset: 0; z-index: 110;
  background: rgba(46, 58, 71, .45);
  opacity: 0; visibility: hidden; transition: opacity .22s, visibility .22s;
}
.szuflada-zaslona.otwarta { opacity: 1; visibility: visible; }

/* Strona pod otwarta szuflada NIE PRZEWIJA SIE – inaczej przeciagniecie palcem po menu
   przesuwa liste za nim i po zamknieciu czlowiek stoi w innym miejscu, niz stal. */
body.szuflada-otwarta { overflow: hidden; }

/* Glowa szuflady jest CZARNA, tak jak pasek, z ktorego szuflada wyjechala – ma sie
   czytac jako jego ciag dalszy, a nie jako nowa strona. Stad tez zamkniecie krzyzykiem
   dokladnie tam, gdzie przed chwila stal burger. */
.szuflada-glowa {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 14px 16px; background: var(--czarny); color: #fff;
}
.szuflada-kto { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 600; }
.szuflada-kto span {
  display: block; margin-top: 2px; font-size: 12px; font-weight: 400; color: #8794a3;
  overflow: hidden; text-overflow: ellipsis;
}

.szuflada-menu, .szuflada-konto { display: flex; flex-direction: column; padding: 8px; }
/* Kreska, a nie odstep: pozycje konta to inny rodzaj miejsca niz ekrany pracy i przy
   samym odstepie czytaly sie jak dalszy ciag tej samej listy. */
.szuflada-konto { border-top: 1px solid var(--obwodka); }

.szuflada-menu a, .szuflada-konto a, .szuflada-konto button {
  display: flex; align-items: center; gap: 12px;
  /* 46 px wysokosci to nie ozdoba: ponizej tego w pozycje menu trafia sie palcem
     co drugi raz, a menu, w ktore trzeba celowac, jest gorsze od braku menu. */
  min-height: 46px; padding: 10px 12px;
  border: 0; border-radius: 9px; background: none;
  font: inherit; font-size: 15px; font-weight: 500; text-align: left;
  color: var(--grafit); text-decoration: none; cursor: pointer;
}
.szuflada-menu a:hover, .szuflada-konto a:hover, .szuflada-konto button:hover { background: var(--pole); }
.szuflada-menu a.aktywny, .szuflada-konto a.aktywny {
  background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); font-weight: 600;
}
.szuflada-menu svg { width: 19px; height: 19px; flex: 0 0 auto; opacity: .6; }
.szuflada-menu a.aktywny svg { opacity: 1; color: var(--pomaranczowy); }
/* Pozycje konta nie maja ikon. Wciecie zamiast pustego miejsca po rysunku – inaczej
   lista wyglada na rzad, w ktorym cos sie nie wczytalo. */
.szuflada-konto a, .szuflada-konto button { padding-left: 43px; font-size: 14.5px; color: var(--grafit-jasny); }
/* Wylogowanie jest jedyna pozycja menu, ktora cos KONCZY – reszta tylko przenosi. */
.szuflada-konto .szuflada-wyloguj { color: var(--czerwony); }

.szuflada-zamknij {
  flex: 0 0 auto; width: 34px; height: 34px; margin: -4px -6px 0 0;
  border: 0; border-radius: 9px; background: none; cursor: pointer;
  color: #c3ccd6; font-size: 21px; line-height: 1;
}
.szuflada-zamknij:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }

/*
 * PROG SZUFLADY. Ponizej niego pasek oddaje jej menu i konto.
 */
@media (max-width: 900px) {
  .belka { gap: 8px; padding: 0 10px; }
  .belka nav { display: none; }
  .burger { display: flex; }
  /* Konto ma wlasna sekcje w szufladzie – rozwijane menu w pasku byloby drugim,
     rownoleglym wejsciem w to samo miejsce, a zabiera 70 px, ktorych brakuje
     przyciskom akcji. */
  .belka .konto-menu { display: none; }

  /*
   * Prawa strona MOZE SIE KURCZYC. Na wycenie stoja tam dwa przyciski plus numer
   * i to one przelewaly pasek – `flex: 0 0 auto` kazalo im zajac tyle, ile chca,
   * niezaleznie od tego, ile zostalo. Teraz oddaja miejsce jako ostatnie (logo
   * i burger zostaja `0 0 auto`), a w ostatecznosci przewijaja sie w poziomie,
   * zamiast wypychac cokolwiek poza ekran.
   */
  .belka .prawo { flex: 0 1 auto; min-width: 0; gap: 6px; overflow-x: auto; scrollbar-width: none; }
  .belka .prawo::-webkit-scrollbar { display: none; }
  .belka .prawo .btn { flex: 0 0 auto; padding: 8px 12px; font-size: 13px; }
  /* Numer wyceny stoi TAKZE w podtytule karty podsumowania („ulica, wojewodztwo, numer"),
     wiec w pasku jest powtorzeniem – i jest jedynym elementem paska, ktory nic nie robi. */
  .belka #numer-wyceny { display: none; }

  /* Znak wchodzi w miejsce napisu "biotop", ktory mial okolo 70 px. W pelnym rozmiarze
     zabralby paskowi 126 px, a prawa strona paska (przycisk akcji plus nazwisko) i tak
     zajmuje juz blisko 280 px. Zeby logo nigdy nie bylo tym, co przelewa pasek, szerokosc
     jest plynna, a wysokosc wylicza sie z proporcji pliku – nie trzeba jej przeliczac recznie. */
  .belka .znak { width: min(100px, 24vw); height: auto; aspect-ratio: 382 / 73; }
}

/* ------------------------------------------------------- podmenu sekcji */

/*
 * Pasek sekcji formularza wyceny – druga linia nawigacji, pod paskiem glownym.
 *
 * PO CO. Karta wyceny ma jedenascie sekcji i ponad 6000 px wysokosci. Do koloru albo do
 * uslug dodatkowych wraca sie kilka razy w trakcie jednej rozmowy z klientem, a dojscie
 * do nich znaczylo przewiniecie calego formularza – w obie strony, za kazdym razem.
 *
 * JASNY, nie czarny. Pasek glowny jest czarny i to on ma byc jedyna mocna pozioma linia
 * na ekranie; drugi czarny pasek pod nim czytalby sie jak dwupietrowy naglowek strony,
 * a to jest nawigacja WEWNATRZ jednej karty. Stad tlo karty i cienka kreska pod spodem.
 */
.podmenu {
  position: sticky; top: 60px; z-index: 45;
  background: var(--karta);
  border-bottom: 1px solid var(--obwodka);
  box-shadow: 0 1px 2px rgba(46, 58, 71, 0.04);
}
.podmenu-tresc {
  max-width: 1500px; margin: 0 auto; padding: 5px 24px;
  display: flex; gap: 4px; align-items: center;
  /* Ta sama sztuczka co w `.belka nav`: pasek przewija sie SAM, zamiast rozpychac strone.
     Pasek przewijania chowamy – przy jednym rzedzie pozycji zabieral wiecej wysokosci,
     niz dawal informacji, a poziome przewijanie i tak dziala kolkiem i gestem. */
  overflow-x: auto; scrollbar-width: none;
}
.podmenu-tresc::-webkit-scrollbar { display: none; }
/* Szerokosc idzie za strona: przy ukladzie trzykolumnowym `.strona-trzykolumnowa` rosnie
   do 1900 px i pierwsza pozycja menu ma stac rowno z lewa kolumna, a nie 200 px w prawo. */
@media (min-width: 1500px) { .podmenu-tresc { max-width: 1900px; } }

.podmenu a {
  display: flex; align-items: center; gap: 7px; flex: 0 0 auto;
  padding: 8px 12px; border-radius: 8px;
  font-size: 13.5px; font-weight: 500; line-height: 20px;
  color: var(--grafit-jasny); text-decoration: none; white-space: nowrap;
}
/* Ikona przygaszona, dopoki sekcja nie jest ta, w ktorej ktos stoi – ta sama zasada co
   w pasku glownym: etykieta jest trescia, ikona podpowiedzia. */
.podmenu a svg { width: 17px; height: 17px; flex: 0 0 auto; opacity: 0.65; }
.podmenu a:hover { background: var(--pole); color: var(--grafit); }
.podmenu a:hover svg { opacity: 1; }
.podmenu a.aktywna { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); }
.podmenu a.aktywna svg { opacity: 1; color: var(--pomaranczowy); }

@media (max-width: 900px) {
  .podmenu-tresc { padding-left: 12px; padding-right: 12px; }
  .podmenu a { padding: 8px 9px; }
}

/* Kotwica ma wyladowac POD oboma paskami, a nie za nimi. Bez tego klikniecie w pozycje
   menu przewija sekcje dokladnie tam, gdzie zaslania ja pasek – czyli naglowek znika
   i wyglada to na przewiniecie o jedna sekcje za daleko. */
body.z-podmenu main > .karta { scroll-margin-top: calc(60px + var(--podmenu-h) + 14px); }

/* Ikona w naglowku sekcji. `inline`, a nie flex na `h2`: `<small>` pod tytulem jest
   blokiem i musi zostac w drugiej linii, a przestawienie `h2` na flexa wciagneloby go
   obok tytulu na KAZDYM ekranie panelu, nie tylko tutaj. */
.karta > h2 > .ikona-sekcji {
  width: 26px; height: 26px; vertical-align: -5px; margin-right: 12px;
  color: var(--pomaranczowy);
}
/* Jedyny wyjatek od pomaranczowego: kosz przy strefie ryzyka. Akcent marki na naglowku,
   pod ktorym stoi „Nie da sie tego cofnac", mowilby nie to, co trzeba. */
.strefa-ryzyka > h2 > .ikona-sekcji { color: var(--czerwony); }

/* --------------------------------------------------------------- layout */

.strona { max-width: 1500px; margin: 0 auto; padding: 24px; }

/* Tablica lejka rzadzi sie inaczej niz formularze: tam 1500 px chroni przed czytaniem
   linii tekstu przez caly monitor, tu liczy sie liczba widocznych kolumn. Margines boczny
   jest wiekszy niz odstep miedzy kolumnami – inaczej skrajne karty wygladaja, jakby byly
   przyklejone do krawedzi okna. Gdy kolumny przestaja sie miescic, tablica przewija sie
   w poziomie (patrz `.tablica`), zamiast sciskac karty do nieczytelnej szerokosci. */
.strona.szeroka { max-width: none; padding-left: 28px; padding-right: 28px; }
@media (max-width: 700px) { .strona.szeroka { padding-left: 14px; padding-right: 14px; } }

.uklad { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 24px; align-items: start; }
@media (max-width: 1180px) { .uklad { grid-template-columns: 1fr; } }

/*
 * Uklad trzykolumnowy na szerokim ekranie: podsumowanie po LEWEJ, formularz w srodku,
 * Aktywnosci po PRAWEJ. Historia przestaje wisiec pod podsumowaniem, gdzie trzeba bylo
 * do niej przewijac przez caly formularz, mimo ze po prawej stala pusta kolumna.
 *
 * UZYWAJA GO DWA EKRANY: wycena i rozliczenie. Na rozliczeniu chodzi o to samo, tylko
 * z drugiej strony biurka – szef akceptujacy kwote czyta historie zlecenia obok jej
 * skladnikow, zamiast przelaczac sie miedzy kartami. Stad neutralna nazwa klasy:
 * `strona-wyceny` kazalaby przy kazdym kolejnym ekranie tlumaczyc, czemu tak sie nazywa.
 *
 * SZEROKOSC KOLUMN ZOSTAJE 380 px – ta sama, ktora ma dzis jedyny sidebar. Drugi sidebar
 * bierze wiec szerokosc ze STRONY, nie z formularza: dlatego `max-width` rosnie z 1500
 * do 1900 px. Przy 1900 px na formularz zostaje 1044 px, czyli tyle co dzis przy jednym
 * sidebarze (1048 px) – uklad nie zabiera nic z miejsca do pracy, tylko dokłada kolumnę.
 *
 * `display: contents` zamiast przestawiania kart w HTML: znosi samo pudelko <aside>,
 * a jego dwie karty staja sie wprost elementami siatki i mozna je posadzic po dwoch
 * stronach formularza. Kolejnosc w HTML zostaje niezmieniona (formularz, podglad,
 * aktywnosci), wiec na waskim ekranie strona czyta sie tak jak dotad: najpierw sie
 * wypelnia, potem oglada podsumowanie. Ponizej progu nie zmienia sie NIC.
 *
 * Wszystko pod `.strona-trzykolumnowa`, bo klasy `uklad` uzywa takze karta klienta – ma jeden
 * sidebar i te reguly rozwalilyby jej siatke.
 */
@media (min-width: 1500px) {
  .strona-trzykolumnowa { max-width: 1900px; }
  .strona-trzykolumnowa .uklad { grid-template-columns: 380px minmax(0, 1fr) 380px; }
  .strona-trzykolumnowa .podsumowanie { display: contents; }

  /*
   * `grid-row: 1` przy KAZDEJ z trzech kolumn jest tu obowiazkowe, a nie ozdobne.
   *
   * Przy samym wskazaniu kolumn automatyczne rozmieszczanie wsadza oba sidebary
   * do DRUGIEGO wiersza, czyli pod formularz. Kursor rozmieszczania nie cofa sie
   * w lewo: `main` bierze kolumne 2, nastepna karta prosi o kolumne 1 – czyli mniej
   * niz poprzednia – wiec przegladarka zgodnie ze specyfikacja schodzi wiersz nizej
   * i juz w nim zostaje. Efekt jest taki, ze przy 4K kolumny wygladaja poprawnie
   * w poziomie i zaczynaja sie dopiero po calym formularzu.
   *
   * Wskazanie wiersza wprost znosi caly ten mechanizm – wszystkie trzy sa w wierszu 1,
   * czyli rowno od gory.
   */
  .strona-trzykolumnowa .uklad > main { grid-column: 2; grid-row: 1; }
  /* Kazda karta lepi sie teraz sama – wspolnego <aside>, ktory to robil, juz nie ma. */
  .strona-trzykolumnowa .podsumowanie > .karta {
    grid-column: 1; grid-row: 1; position: sticky; top: var(--gora-lepka); margin-bottom: 0;
  }
  .strona-trzykolumnowa .podsumowanie > #karta-aktywnosci { grid-column: 3; grid-row: 1; }
}

/*
 * Za waski ekran na trzy kolumny: uklad zwija sie tak jak dotad, ale Podglad
 * i Aktywnosci ida NAD formularz. Wczesniej ladowaly za nim – przy formularzu
 * wysokim na 6500 px oznaczalo to, ze podsumowanie ceny i historia stoja poza
 * zasiegiem, chyba ze ktos przewinie cala strone do konca.
 *
 * `order` przestawia tylko OBRAZ; kolejnosc w HTML zostaje, wiec czytnik ekranu
 * i klawisz Tab dalej ida formularzem od gory.
 */
@media (max-width: 1180px) {
  .strona-trzykolumnowa .podsumowanie { order: -1; }
}

.karta {
  background: var(--karta);
  border-radius: var(--r);
  padding: 26px 28px;
  margin-bottom: 20px;
  box-shadow: var(--cien);
}
.karta > h2 {
  font-size: 26px; text-transform: uppercase; letter-spacing: -0.01em;
  padding-bottom: 16px; margin-bottom: 20px; border-bottom: 1px solid var(--obwodka);
}
.karta > h2 small { display: block; font-size: 13px; font-weight: 400; text-transform: none; color: var(--szary); letter-spacing: 0; margin-top: 4px; }

/* ---------------------------------------------------------------- pola */

.pole { margin-bottom: 22px; }
.pole:last-child { margin-bottom: 0; }
.pole > label,
.etykieta { display: block; font-size: 14px; color: var(--grafit-jasny); margin-bottom: 9px; font-weight: 500; }
.etykieta .wym { color: var(--pomaranczowy); }
.podpowiedz { font-size: 12.5px; color: var(--szary); margin-top: 7px; }

.rzad { display: flex; gap: 14px; flex-wrap: wrap; }
.rzad > * { flex: 1 1 160px; min-width: 0; }

/*
 * Stylujemy pola PRZEZ WYKLUCZENIE, a nie przez wyliczanie typów.
 *
 * Wcześniej była tu lista `input[type='text'], [type='number'], …` i wypadały z niej
 * dwie rzeczy naraz: `type='password'` (nikt go nie dopisał) oraz **każdy `<input>` bez
 * atrybutu `type`** — bo `input[type='text']` wymaga obecności atrybutu i nie trafia
 * w domyślny tekstowy `<input>`. Efekt: surowe, systemowe pola przy logowaniu,
 * w użytkownikach i w całej edycji brygad.
 *
 * Przy wykluczaniu nowy typ pola jest stylowany od razu, zamiast czekać, aż ktoś
 * zauważy, że jedno wygląda inaczej niż reszta.
 *
 * `.w-pastylce` i `.szukajka` TO JAWNE WYJŚCIA Z TEJ REGUŁY i jedyne takie. Biorą się stąd,
 * że dziesięć `:not()` daje specyficzność (0,10,1) — zmierzone, nie oszacowane — więc NIE DA
 * SIĘ jej nadpisać żadnym rozsądnym selektorem klasowym: ani `.pastylka input` (0,1,1),
 * ani `.pole .pastylki .pastylka input` (0,3,1). Zostawały dwa wyjścia: powtórzyć cały
 * łańcuch `:not()` przy każdym komponencie albo sięgnąć po `!important`. Oba znaczą, że
 * następna osoba traci pół godziny na to samo odkrycie.
 *
 * Zamiast tego reguła sama deklaruje swój wyjątek — co jest dokładnie tą filozofią, którą
 * opisuje akapit wyżej, tylko zastosowaną o poziom wyżej: pola, które ŚWIADOMIE wyglądają
 * inaczej, wykluczamy tu, a nie prześcigamy gdzie indziej.
 *
 * Szukajka jest tu z tego samego powodu co pastylka: ramkę i poświatę przejmuje jej
 * otoczka (`.pole-szukania`, razem z przegródką na lupę), więc samo pole musi je oddać.
 * Reguła `.pole-szukania .szukajka` (0,2,0) przegrywała z tym łańcuchem i pole zostawało
 * z drugą obwódką w środku pierwszej — widać to było dopiero przy wpisywaniu.
 */
input:not(.w-pastylce):not(.szukajka):not([type='checkbox']):not([type='radio']):not([type='range']):not([type='file']):not([type='submit']):not([type='button']):not([type='reset']):not([type='image']):not([type='color']):not([type='hidden']),
select, textarea {
  width: 100%; padding: 12px 14px;
  border: 1px solid var(--obwodka); border-radius: 10px;
  font: inherit; font-size: var(--pole-pismo); color: var(--grafit); background: #fff;
}

/* Krzyżyk czyszczenia w polu wyszukiwania rozpycha wysokość w WebKicie. */
input[type='search'] { -webkit-appearance: none; appearance: none; }
input[type='search']::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--pomaranczowy); box-shadow: 0 0 0 3px rgba(255, 102, 0, 0.12);
}
input::placeholder, textarea::placeholder { color: #b9c2cc; }
textarea { resize: vertical; min-height: 76px; }

.z-jednostka { position: relative; }
.z-jednostka input { padding-right: 46px; }
.z-jednostka span {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  color: var(--szary); font-style: italic; font-size: 14px; pointer-events: none;
}

/* ------------------------------------------------------- grupy przyciskow */

.opcje { display: flex; flex-wrap: wrap; gap: 10px; }
.opcje.kolumny-4 { display: grid; grid-template-columns: repeat(4, 1fr); }
.opcje.kolumny-3 { display: grid; grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) { .opcje.kolumny-4, .opcje.kolumny-3 { grid-template-columns: repeat(2, 1fr); } }

.opcja {
  flex: 1 1 auto;
  padding: 13px 18px;
  background: var(--pole);
  border: 2px solid transparent;
  border-radius: 10px;
  color: var(--grafit-jasny);
  font: inherit; font-size: 14.5px; font-weight: 500;
  cursor: pointer; text-align: center;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.opcja:hover { background: #eaeef4; }
.opcja[aria-pressed='true'] {
  background: #fff; border-color: var(--pomaranczowy); color: var(--grafit); font-weight: 600;
}

/* kafle z ikonami (rodzaj pokrycia / ksztalt) */
.kafle { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.kafel {
  padding: 18px 12px 14px; background: var(--pole);
  border: 2px solid transparent; border-radius: 10px;
  cursor: pointer; text-align: center; font: inherit;
  color: var(--grafit-jasny); font-weight: 500;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.kafel:hover { background: #eaeef4; }
.kafel svg { width: 76px; height: 46px; }
.kafel[aria-pressed='true'] { background: #fff; border-color: var(--pomaranczowy); color: var(--grafit); font-weight: 600; }
.kafel[aria-pressed='true'] svg { color: var(--pomaranczowy); }
.kafel svg { color: #c6cedb; }

/*
 * DWIE KOLUMNY NA TELEFONIE, a nie jedna. Przy 180 px na kafel na ekranie 375 px mieści
 * się dokładnie jeden i wybór pokrycia – dziesięć pozycji – rozciągał się na trzy ekrany
 * przewijania, mimo że każdy kafel to rysunek i jedno słowo. Rysunek schodzi o jedną
 * trzecią; nadal jest największą rzeczą w kaflu, czyli tym, po czym się go rozpoznaje.
 *
 * Selektory idą przez `.kafle`, a nie przez samo `.kafel`, i to jest konieczne:
 * nazwy `.kafel` używa TAKŻE kafelek z liczbą na raportach (`.kafelki` niżej w tym
 * pliku), a tamta reguła stoi dalej i przy równej specyficzności wygrywa.
 */
@media (max-width: 560px) {
  .kafle { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
  .kafle .kafel { padding: 13px 8px 11px; gap: 7px; font-size: 13.5px; }
  .kafle .kafel svg { width: 58px; height: 34px; }
  .kafle .kafel .ikona-pokrycia { width: 62px; }
}

/* ------------------------------------------------------ mieszalnia: zbiorniki

   Kafel odpowiada na jedno pytanie zadawane przed nalaniem: ILE SIE JESZCZE ZMIESCI.
   Dlatego pasek pokazuje wypelnienie wzgledem POJEMNOSCI, a nie wzgledem najwiekszego
   zbiornika – czarna 5000 kg i zolta 1000 kg maja byc czytelne obok siebie.

   Stan ujemny jest DOZWOLONY (paragraf 6) i wlasnie dlatego musi krzyczec: dopuszczony,
   ale nie normalny. Czerwien tu nie znaczy "blad systemu", tylko "brakuje wpisu".        */

/* `align-items: start` – bez tego JEDEN kafel z alertem o stanie ujemnym rozciaga
   WSZYSTKIE do swojej wysokosci i cala siatka rosnie o pol ekranu. */
.zbiorniki { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; align-items: start; }

.zbiornik {
  padding: 10px 12px; background: var(--pole); border: 2px solid transparent;
  border-radius: var(--r);
}
.zbiornik-nazwa { font-size: 12.5px; color: var(--grafit-jasny); font-weight: 600; }
.zbiornik-masa { font-size: 19px; font-weight: 700; margin: 2px 0 7px; font-variant-numeric: tabular-nums; }

.pasek-poziomu { height: 7px; background: #dfe5ee; border-radius: 999px; overflow: hidden; }
.pasek-poziomu span { display: block; height: 100%; border-radius: 999px; background: var(--zielony); }

/*
 * KOLOR PASKA MOWI, ILE ZOSTALO, a nie czy grozi przelanie: zielony powyzej 75%, zolty
 * powyzej 50%, czerwony ponizej. To jest pytanie, ktore magazynier zadaje patrzac na
 * ekran rano – „czego zaraz zabraknie", a nie „czego mam za duzo".
 *
 * O przelanie i tak ostrzega wyliczenie serii („zejdzie na minus") oraz `wolne_g`, wiec
 * ta skala nie zabiera zadnej informacji, tylko odpowiada na czesciej zadawane pytanie.
 */
.pasek-poziomu span.srednio { background: var(--zolty); }
.pasek-poziomu span.malo { background: var(--czerwony); }

.zbiornik-stopka {
  display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap;
  margin-top: 6px; font-size: 12px; color: var(--szary);
}
.znacznik-czeka { color: var(--pomaranczowy); font-weight: 600; }

.zbiornik.ujemny { background: #fef2f2; border-color: var(--czerwony); }
.zbiornik.ujemny .zbiornik-masa { color: var(--czerwony); }
.zbiornik.ujemny .pasek-poziomu span { background: var(--czerwony); }
.zbiornik-alert { margin-top: 8px; font-size: 12px; font-weight: 600; color: var(--czerwony); }

.wiersz-czeka {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 0; border-top: 1px solid var(--obwodka);
}
.wiersz-czeka:first-child { border-top: 0; }
.wiersz-czeka > span:first-child { flex: 1 1 220px; }
.wiersz-czeka .podpowiedz { margin-top: 0; }

/* Wiersz ksiegi czekajacy na podpis – wyrozniony tlem, nie czerwienia: to nie jest blad,
   tylko etap. */
.tabela tr.czeka { background: var(--pomaranczowy-tlo); }

/* ------------------------------------------------------- wydawki dla ekip

   Paragraf 26: wydawka NIE MUSI byc kompletna. Dlatego kazda pozycja ma wlasny znacznik,
   a stan calosci jest tylko podsumowaniem – nie da sie go kliknac i nie ma czego klikac. */

.wydawka {
  border: 1px solid var(--obwodka); border-radius: var(--r);
  padding: 10px 12px; margin-bottom: 10px;
}
.wydawka.czesciowo { border-color: #ffd9bd; background: var(--pomaranczowy-tlo); }
.wydawka.zrobione { opacity: .7; }
/* Zlecenie bez wydawki nie jest „w toku" ani „gotowe" — dla magazynu ono NIE ISTNIEJE,
   dopoki ktos go nie rozpisze. Stad czerwona krawedz, a nie pomaranczowa: to nie jest
   etap procesu, tylko dziura w nim. */
.wydawka.bez-wydawki { border-color: #fecaca; background: #fef2f2; }
.wydawka.bez-wydawki .wydawka-glowa { margin-bottom: 0; }
.wydawka.bez-wydawki button { margin-left: auto; }

.wydawka-glowa { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.wydawka-kto { font-weight: 700; font-size: 14.5px; }
.wydawka-ekipa { font-size: 12.5px; color: var(--grafit-jasny); }
.wydawka-stan {
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  color: var(--grafit-jasny);
}
.wydawka.czesciowo .wydawka-stan { color: var(--pomaranczowy); }
.wydawka.zrobione .wydawka-stan { color: var(--zielony); }
.wydawka-glowa .podpowiedz { margin-top: 0; margin-left: auto; }

.wydawka-pozycja {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) minmax(0, auto) auto;
  gap: 10px; align-items: center; padding: 3px 0; font-size: 13.5px;
}
.wydawka-znak { text-align: center; color: var(--szary); }
.wydawka-pozycja.gotowa .wydawka-znak { color: var(--zielony); }
.wydawka-pozycja.gotowa { color: var(--grafit-jasny); }
.wydawka-pozycja .podpowiedz { margin-top: 0; }
.wydawka-pozycja .btn { padding: 3px 10px; font-size: 12px; }

.wydawka-stopka { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.wydawka-miejsce { flex: 1 1 240px; min-width: 180px; padding: 7px 10px; font-size: 13.5px; }
.wydawka-stopka .btn { padding: 6px 12px; font-size: 12.5px; }

.przelacznik { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--grafit-jasny); }
.przelacznik input { width: auto; }

/* ------------------------------------------------------ do wykonania wg RAL

   Paragraf 62: magazynier ma dostac EKRAN OPERACYJNY, a nie wykresy. Liczba wiader jest
   wiec najwieksza rzecza w wierszu – to na nia patrzy, wchodzac rano do hali.            */

/* TABLICA „DO WYKONANIA" JEST TABELA, a nie stosem samodzielnych wierszy.
   Kazdy wiersz byl wczesniej WLASNA siatka `grid`, wiec kolumny `auto` dobieraly szerokosc
   OSOBNO w kazdym z nich: liczba wiader, masa i przycisk zaczynaly sie w innym miejscu
   w kazdej linijce, a wiersz z szescioma ekipami rozpychal sie inaczej niz sasiad z jedna.
   Przy dwoch pozycjach tego nie widac; przy dwudziestu lista traci pion i oko nie ma sie
   o co zaczepic — a magazynier przelatuje ta liste wzrokiem, nie czyta jej wiersz po
   wierszu. Tabela ustala kolumny RAZ, dla calej listy, i dostaje naglowki. */
.tabela-wykonania { table-layout: fixed; }
.tabela-wykonania .kol-znak { width: 30px; }
.tabela-wykonania .kol-ile { width: 78px; }
.tabela-wykonania .kol-masa { width: 94px; }
/* 44%, bo to jest punkt, w ktorym pastylki przestaja sie lamac bez potrzeby: przy 38%
   Extra Bold z dwiema ekipami schodzil do drugiej linii, a wiersz Anticoru z szescioma mial
   142 px wysokosci. Powyzej 44% nie zmienia sie juz nic — kolumna tylko odbiera miejsce
   nazwie koloru. Zmierzone na tablicy z szescioma ekipami przy 1280 px. */
.tabela-wykonania .kol-ekipy { width: 44%; }
.tabela-wykonania .kol-akcja { width: 132px; }

/* Ciasniej niz w `.tabela`: to jest ekran operacyjny, na ktorym ma sie zmiescic dwadziescia
   pozycji naraz, a nie lista klientow do czytania. */
.tabela-wykonania td, .tabela-braki td { padding: 8px 10px; }
.tabela-wykonania th, .tabela-braki th { padding: 0 10px 8px; }
/* Wiersz z pastylkami lamie sie na kilka linii, wiec komorki rownamy DO GORY — wysrodkowanie
   odsuwaloby nazwe koloru od jej wlasnego wiersza o pol pastylki. */
.tabela-wykonania td, .tabela-braki td { vertical-align: top; }
/* Kropka koloru jest tu mniejsza niz w reszcie panelu: kolumna materialu ma stala szerokosc,
   a 28 px kropki plus 18 px odstepu zabieralo z niej tyle, ze „Ceglasty tradycyjny" zawijal
   sie na dwie linijki w tabeli, ktora ma byc plaska. */
.tabela-wykonania .kropka-ral, .tabela-braki .kropka-ral {
  width: 16px; height: 16px; flex-basis: 16px; margin-right: 9px; vertical-align: -2px;
}

/* ZNACZNIK STANU zamiast ramki: jeden znak zamiast czterech pikseli koloru wzdluz calego
   wiersza. Przy dwudziestu pozycjach kolorowe krawedzie zlewaly sie w pas, ktory niczego
   juz nie wyrozniał. */
.do-zrobienia-znak { font-size: 15px; line-height: 1.4; text-align: center; }
.do-zrobienia.zrobione { color: var(--grafit-jasny); }
.do-zrobienia.zrobione .do-zrobienia-znak { color: var(--zielony); }
.do-zrobienia.zrobione .do-zrobienia-co { text-decoration: line-through; }
.do-zrobienia.nowe .do-zrobienia-znak { color: var(--pomaranczowy); }

.do-zrobienia-co { font-weight: 600; font-size: 14.5px; }
.do-zrobienia-ile { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.do-zrobienia-masa { font-size: 12.5px; color: var(--szary); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Masa jest podpisem pod liczba wiodaca, wiec ma siedziec w jej linii bazowej, a nie
   o cztery piksele wyzej — obie kolumny sa cyframi tej samej wysokosci. */
.tabela-wykonania .do-zrobienia-masa { padding-top: 11px; }

/* Rozbicie na ekipy – paragraf 8 wymaga go po wejsciu w konkretny RAL, bo to po nim
   magazynier decyduje, komu przypisac wykonane sztuki. Pastylki LAMIA SIE do nowej linii;
   urywanie ich wielokropkiem chowaloby ostatnia ekipe, czyli jedna z odpowiedzi na
   „dokad to zaniesc". */
.do-zrobienia-ekipy { font-size: 12.5px; color: var(--grafit-jasny); }
.do-zrobienia-akcja { white-space: nowrap; }

/* KOMU IDZIE TA OFERTA — na samej gorze okna wysylki, przed kanalami i trescia.
   Przycisk „Wyslij oferte" wyglada tak samo niezaleznie od odbiorcy, a po drugiej stronie
   jest czlowiek, ktory za chwile odbierze telefon. */
.wys-komu:not(:empty) {
  margin: -6px 0 16px; padding: 10px 14px; border-radius: 10px;
  background: var(--pomaranczowy-tlo); color: var(--grafit); font-size: 14px;
}
.wys-komu b { font-weight: 700; }

/* ROZBICIE NA EKIPY W PASTYLKACH. Jedna linijka („Grupa C2 5 · Grupa M2 - Konrad Kozioł 3
   · Grupa U2 2") urywala sie wielokropkiem przy dluzszych nazwach — a to wlasnie ta czesc
   wiersza mowi, DOKAD zaniesc wiadra. Pastylki lamia sie do nowej linii zamiast znikac. */
.ekipy-pastylki { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pastylka-ekipy {
  padding: 3px 10px; border-radius: 999px; background: var(--tlo);
  font-size: 12.5px; color: var(--grafit-jasny); white-space: nowrap;
}
.pastylka-ekipy b { color: var(--grafit); font-weight: 600; }

/* KOLOR ZAMIAST PODPISU: zielona znaczy „ta ekipa juz to ma", szara — „jeszcze czeka".
   Staly tu wczesniej etykiety „do zaniesienia" i „dla ekip", czyli dwa slowa powtorzone
   przy kazdym z dwudziestu wierszy po to, zeby powiedziec to samo. Zielen jest tu
   naturalna: w calym panelu znaczy „zalatwione" (ptaszek przy wydawce, pasek poziomu). */
.pastylka-ekipy.ma { background: var(--zielony-tlo); color: var(--zielony); }
.pastylka-ekipy.ma b { color: var(--zielony); }
.do-zrobienia-nowa { font-size: 11.5px; font-weight: 700; color: var(--pomaranczowy); letter-spacing: .04em; }

/* WIERSZ „NA WASZE ZLECENIA" ma WLASNY uklad, a nie siatke z ekranu mieszalni.
   Tamta ma szesc kolumn na szesc komorek; ekran kierownika wkladal w nia dwa `div`-y,
   wiec nazwa koloru ladowala w kolumnie szerokiej na 22 px, zawijala sie na trzy linijki
   i nachodzila na tekst obok. Dwa rzedy, nie siatka — tu nie ma czego wyrownywac. */
.potrzeba { padding: 10px 0; border-bottom: 1px solid var(--obwodka); }
.potrzeba:last-child { border-bottom: 0; }
.potrzeba-glowa { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.potrzeba-co { font-weight: 600; font-size: 14.5px; }
.potrzeba-ile { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.potrzeba-glowa .btn { margin-left: auto; padding: 4px 12px; font-size: 12.5px; }
.potrzeba-rozbicie {
  display: flex; gap: 18px; flex-wrap: wrap; margin-top: 4px;
  font-size: 12.5px; color: var(--grafit-jasny);
}
.potrzeba-rozbicie b { font-variant-numeric: tabular-nums; color: var(--grafit); }
/* Przycisk w liscie jest MNIEJSZY niz zwykly `btn-maly`: to on dyktowal wysokosc wiersza,
   a przy dwudziestu pozycjach kazde 6 px to pol ekranu przewijania. */
.do-zrobienia .btn { padding: 4px 12px; font-size: 12.5px; }

/* NA TELEFONIE ZNIKA KOLUMNA MASY, a nie zweza sie wszystkie naraz.
   Magazynier przeglada te liste w hali, wiec przewijanie tabeli w bok odpada — musi widziec
   caly wiersz od razu. Masa jest tu z zalozenia drobnym drukiem OBOK liczby wiodacej, czyli
   jedyna kolumna, ktorej zdjecie niczego nie przerywa: liczba wiader zostaje, ekipy zostaja,
   przycisk zostaje. Szerokosci schodza z `fixed` na automatyczne, zeby nazwa koloru wzięła
   tyle, ile naprawde potrzebuje. */
@media (max-width: 760px) {
  .tabela-wykonania { table-layout: auto; }
  .tabela-wykonania .kol-masa, .tabela-wykonania .do-zrobienia-masa { display: none; }
  .tabela-wykonania .kol-ekipy { width: auto; }
  .tabela-wykonania .kol-akcja { width: auto; }
  .tabela-wykonania td, .tabela-braki td { padding: 8px 6px; }
}

/* Pasek filtrow nad lista – wezszy niz zwykle pola, bo to nie jest formularz do wypelnienia,
   tylko przelacznik widoku. */
.filtry-magazynu { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.filtry-magazynu select { width: auto; min-width: 150px; padding: 8px 12px; font-size: 14px; }

/* ---------------------------------------------------------------- Stan ekipy

   Uklad z paragrafu 21: grupa na RAL, w niej wiersze wedlug klasy. Kierownik czyta to
   z telefonu na dachu, wiec wiersz ma byc JEDNA linijka, ktora da sie ogarnac wzrokiem –
   ilosc, klasa, rozpuszczalnik, wiek. Bez tabeli, bo tabela na 375 px sie nie miesci.

   KLASA NIESIE KOLOR, bo to ona decyduje, co z tym materialem wolno zrobic. A jest
   neutralna (normalny material), B pomaranczowa (tylko pierwsza warstwa), C czerwona
   (nie wolno uzyc), D szara (odpad).                                                    */

.grupa-stanu { padding: 12px 0; border-top: 1px solid var(--obwodka); }
.grupa-stanu:first-child { border-top: 0; padding-top: 0; }
.grupa-nazwa { font-weight: 700; margin-bottom: 8px; }

.pozycja-stanu {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px; margin-bottom: 6px;
  background: var(--pole); border-left: 4px solid transparent; border-radius: 8px;
  font-size: 14px;
}
.pozycja-ilosc { font-weight: 600; min-width: 120px; }
.pozycja-klasa {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  font-size: 12px; font-weight: 700; background: #fff; color: var(--grafit-jasny);
}
.pozycja-rozp { color: var(--grafit-jasny); font-size: 13px; }
.pozycja-stanu .podpowiedz { margin-top: 0; }
.pozycja-stanu button { margin-left: auto; }

.pozycja-stanu.klasa-B { border-left-color: var(--pomaranczowy); }
.pozycja-stanu.klasa-B .pozycja-klasa { color: var(--pomaranczowy); }
.pozycja-stanu.klasa-C { border-left-color: var(--czerwony); background: #fef2f2; }
.pozycja-stanu.klasa-C .pozycja-klasa { color: var(--czerwony); }
.pozycja-stanu.klasa-D { border-left-color: var(--szary); opacity: .75; }

/* Wiek resztki (paragraf 22). Zalegajaca jest WYROZNIONA, a nie ukarana – ma sklonic
   do zagospodarowania, zanim trafi na gielde albo do utylizacji. */
/* Pola weryfikacji zwrotu SIEDZA W WIERSZU, a nie w formularzu pod nim (paragraf 31:
   magazynier otwiera wiadro i od razu wpisuje, co w niej jest).

   SZEROKOSC DAJE `flex-basis`, A NIE `width` – i to nie jest sztuczka. Bazowa regula pol
   ma specyficznosc (0,10,1) przez lancuch `:not()`, wiec `width` z niej nie da sie tu
   nadpisac zadnym rozsadnym selektorem klasowym. `flex-basis` rozstrzyga sie w ukladzie
   flex PRZED `width` i wygrywa bez wyscigu na specyficznosc. Padding zostaje domyslny:
   w hali klika sie w to palcem, wiec nizsze pole byloby gorsze, a nie lepsze. */
.zwrot-klasa { flex: 0 1 200px; min-width: 130px; }
.zwrot-kg { flex: 0 0 100px; }

/* Ile z pozycji policzyl juz magazyn na rozpisane zlecenia. NIE jest to zakaz oddania –
   to informacja, ktorej kierownik inaczej nie ma, a bez ktorej oddanie farby na gielde
   bywa pomylka zauwazona dopiero na dachu. Stad ton ostrzegawczy, nie blokujacy. */
.pozycja-zajete {
  font-size: 12px; font-weight: 600; color: var(--pomaranczowy);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.pozycja-wiek { font-size: 12.5px; color: var(--szary); font-variant-numeric: tabular-nums; }
.pozycja-wiek.stara { color: var(--pomaranczowy); font-weight: 600; }
.pozycja-stanu.zalega { box-shadow: inset 0 0 0 1px #ffd9bd; }

/* --------------------------------------------- mieszalnia: receptury i serie

   SZEROKOSCI POL BIERZE SIATKA, a nie regula na `input`. Globalna regula pol ma
   specyficznosc (0,10,1) i zadnym selektorem klasowym sie jej nie nadpisze (patrz
   komentarz przy niej) – ale `width: 100%`, ktore ona ustawia, wypelnia DOKLADNIE kolumne
   gridu. Zamiast walczyc o szerokosc, dajemy polu waska kolumne.                        */

.siatka-skladnikow { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.skladnik { display: grid; grid-template-columns: 1fr 96px; align-items: center; gap: 10px; font-size: 13.5px; }

/* KAFEL NA KOLOR, nie wiersz przez cala szerokosc. Receptur bedzie kilkadziesiat, a przy
   jednej na wiersz ekran zamienia sie w liste do scrollowania — podczas gdy pytanie jest
   za kazdym razem to samo i punktowe: czy TEN kolor juz umiemy zrobic. */
.receptury { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; align-items: start; }

.receptura { padding: 12px 14px; background: var(--pole); border-radius: var(--r); }
.receptura-ral {
  display: flex; align-items: center; font-weight: 700; font-size: 14.5px; margin-bottom: 8px;
}
/* Kropka w kaflu jest MNIEJSZA niz w listach: tam stoi obok tekstu ciaglego i musi sie
   przebic, tu jest naglowkiem kafla i 28 px spychaloby nazwe koloru do drugiej linijki. */
.receptura-ral .kropka-ral { width: 18px; height: 18px; flex-basis: 18px; margin-right: 10px; vertical-align: 0; }

.receptura-wersja { padding: 8px 10px; border-radius: 8px; background: var(--tlo); }
.receptura-wersja + .receptura-wersja { margin-top: 6px; }
/* Aktywna wersja jest wyrozniona, bo to JEJ szuka magazynier przed seria – reszta jest
   historia i ma byc widoczna, ale nie pierwsza. */
.receptura-wersja.aktywna { background: var(--pomaranczowy-tlo); box-shadow: inset 0 0 0 1px #ffd9bd; }

.receptura-glowa { display: flex; align-items: center; gap: 8px; }
.receptura-nazwa { font-weight: 600; font-size: 12.5px; }
/* Nazwa wlasna i data pod numerem, drobnym drukiem: „ciemniejsza" nie mowi, ktora byla
   wczesniej, a przy trzech wersjach tego samego koloru to jest pierwsze pytanie. */
.receptura-opis { margin: 2px 0 6px; font-size: 11.5px; color: var(--szary); }
.receptura-znak {
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--pomaranczowy);
}
.receptura-glowa .btn { margin-left: auto; padding: 2px 10px; font-size: 12px; }

/* SKLAD JEST TABELKA, a nie zdaniem: nazwa z lewej, kilogramy z prawej, cyfry jedna pod
   druga. Sklejony w jedna linijke („Czarna 5,0 kg + Czerwony tlenkowy 5,0 kg + …") zawijal
   sie w kaflu na cztery wiersze i nie dawal porownac dwoch wersji spojrzeniem. */
.receptura-sklad {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  margin: 0; font-size: 12.5px; color: var(--grafit-jasny);
}
.receptura-sklad dt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.receptura-sklad dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; color: var(--grafit); }

/* Kolor bez ANI JEDNEJ dopuszczonej wersji to zadanie dla laborantki, a nie archiwum —
   i dlatego kafel sie tu wyroznia, a nie chowa niczego pod zwijka. */
.receptura.czeka { box-shadow: inset 0 0 0 2px #ffd9bd; }

/* Historia wersji pod zwijka. Po trzech sezonach jeden kolor ma ich piec i rozwiniete
   przywrocilyby dokladnie ten rozlazly uklad, ktory kafle mialy zlikwidowac. */
.receptura-historia > summary {
  margin-top: 8px; font-size: 12px; color: var(--grafit-jasny);
  cursor: pointer; list-style: none;
}
.receptura-historia > summary::-webkit-details-marker { display: none; }
.receptura-historia > summary::before { content: '▸ '; color: var(--pomaranczowy); }
.receptura-historia[open] > summary::before { content: '▾ '; }
.receptura-historia > summary:hover { color: var(--grafit); }
.receptura-historia .receptura-wersja { margin-top: 6px; }

.wyliczenie { margin-top: 14px; padding: 14px 16px; background: var(--pole); border-radius: var(--r); }
.wyliczenie-suma { font-size: 15px; margin-bottom: 10px; }
.wyliczenie-wiersz {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: baseline;
  padding: 4px 0; font-size: 13.5px; font-variant-numeric: tabular-nums;
}
.wyliczenie-wiersz .podpowiedz { margin-top: 0; }
/* Zejscie zbiornika na minus jest DOZWOLONE (paragraf 6), wiec to ostrzezenie, nie blokada. */
.wyliczenie-wiersz.brakuje { color: var(--czerwony); font-weight: 600; }
.wyliczenie-wiersz.brakuje .podpowiedz { color: var(--czerwony); }

/* ------------------------------------------------- materialy jako pastylki

   Pozycja zamowienia jest KROTKA i jest jej duzo naraz ("8 sniegolapow, 12 mb rynny,
   2 gasiory"), wiec tabela z naglowkami kosztowalaby wiecej pionu niz niesie tresci.
   Pastylka trzyma nazwe, ilosc i kolor w jednej linii, a ilosc zostaje EDYTOWALNA
   w miejscu - poprawka ilosci jest tu czynnoscia codzienna, w odroznieniu od nazwy,
   ktora ustala sie raz.                                                              */

.pastylki { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.pastylki:empty { display: none; }

.pastylka {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 8px 7px 14px;
  background: var(--pomaranczowy-tlo);
  border: 1px solid #ffd9bd;
  border-radius: 999px;
  font-size: 13.5px; color: var(--grafit);
}
.pastylka-nazwa { font-weight: 600; }
/* Pola w pastylce nie maja ramek: obwodka pastylki juz mowi, gdzie sie zaczyna i konczy,
   a druga ramka w srodku robi z niej formularz zamiast etykiety.
   Dzialaja te reguly WYLACZNIE dlatego, ze pola nosza `w-pastylce` i wypadaja przez to
   z globalnej reguly pol – patrz komentarz przy niej. Bez tej klasy nie zadziala tu nic. */
.pastylka input {
  border: 0; background: rgba(255, 255, 255, 0.75); border-radius: 6px;
  font: inherit; font-size: 13.5px; color: var(--grafit); padding: 3px 6px;
}
.pastylka input:focus { outline: 2px solid var(--pomaranczowy); background: #fff; }
.pastylka-ilosc { width: 62px; text-align: right; font-variant-numeric: tabular-nums; }
.pastylka-ral { width: 68px; }
.pastylka-jedn { color: var(--grafit-jasny); }
.pastylka-x {
  border: 0; background: transparent; cursor: pointer;
  color: var(--grafit-jasny); font-size: 17px; line-height: 1;
  padding: 0 6px; border-radius: 999px;
}
.pastylka-x:hover { background: rgba(220, 38, 38, 0.12); color: var(--czerwony); }

/* Wiersz dodawania uzywa ZWYKLYCH pol – ma wygladac jak reszta formularza, bo to jest
   miejsce, w ktorym sie pisze. Szerokosci ida po identyfikatorach, bo tylko one bija
   globalna regule pol; selektor klasowy przegralby z nia tak samo jak w pastylce. */
.material-dodaj { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
#material-nazwa { flex: 1 1 240px; min-width: 180px; }
#material-ilosc { width: 90px; }
#material-ral { width: 92px; }
#material-jednostka { width: 110px; }

/* ------------------------------------------------------------- przyciski */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; border: 0; border-radius: 10px;
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  background: var(--pole); color: var(--grafit-jasny); text-decoration: none;
}
.btn:hover { background: #e6eaf0; }
.btn-glowny { background: var(--pomaranczowy); color: #fff; }
.btn-glowny:hover { background: var(--pomaranczowy-ciemny); }
.btn-ciemny { background: var(--grafit); color: #fff; }
.btn-ciemny:hover { background: #1f2833; }
.btn-maly { padding: 8px 14px; font-size: 13.5px; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* -------------------------------------------------------- zdjecia z pomiaru */

.zdjecia-siatka { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; margin-bottom: 12px; }
.zdjecia-siatka .zdjecie { position: relative; margin: 0; }
.zdjecia-siatka img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  border-radius: 10px; background: var(--pole);
}
.zdjecia-siatka button {
  position: absolute; top: 6px; right: 6px;
  width: 26px; height: 26px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: rgba(14, 18, 24, 0.62); color: #fff; font-size: 17px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.zdjecia-siatka button:hover { background: var(--czerwony); }

.zdjecia-wrzut {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 16px; border: 1.5px dashed var(--obwodka); border-radius: var(--r);
  background: #fbfcfe; color: var(--szary); font-size: 13.5px;
}
.zdjecia-wrzut.nad { border-color: var(--pomaranczowy); background: var(--pomaranczowy-tlo); }

/* Zdjecia usterki pod wierszem reklamacji w bloku „Wykonanie i reklamacje" –
   miniatury w rzedzie, pelny rozmiar po kliknieciu w nowej karcie. */
.rekl-zdjecia { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 10px; }
.rekl-zdjecia img { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; display: block; }

/* --------------------------------------------------------------- filtry */

/* Siatka, nie `flex-wrap`: przy dziewieciu kontrolkach zawijanie ustawia w kazdym
   rzedzie inna liczbe pol roznej szerokosci i pasek wyglada na przypadkowy.
   Siatka trzyma rowne kolumny niezaleznie od tego, ile ich sie miesci w rzedzie. */
.filtry { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.filtry select, .filtry input { font-size: 14px; padding: 10px 12px; }

/* Szukajka dostaje dwie kolumny – wpisuje sie w nia cale nazwisko z adresem,
   a nie jedno slowo jak w pozostalych polach. */
.filtry .szeroko { grid-column: span 2; }
@media (max-width: 560px) { .filtry .szeroko { grid-column: span 1; } }

.filtry .widelki { display: flex; align-items: center; gap: 6px; }
.filtry .widelki input { min-width: 0; }
.filtry .widelki span { color: var(--szary); flex: 0 0 auto; }

/* Dwie listy skladajace JEDNA wartosc (miesiac + rok) trzymamy razem, zeby zawijanie
   nie rozdzielilo ich na dwa rzedy – wygladalyby wtedy na dwa osobne pola. */
.para { display: flex; gap: 6px; }
.para select { min-width: 0; flex: 1 1 auto; }

/* ------------------------------------------------ zwijany pasek filtrow */

/*
 * Kontrolek jest kilkanascie i rozwiniete zajmowaly pol ekranu nad kazda lista.
 * Na wierzchu zostaje szukajka (tak zaczyna sie wiekszosc wejsc), reszta chodzi
 * za `<details>` – bez JS-a do samego otwierania i z klawiatura za darmo.
 */
/*
 * SZUKAJKA – lupa w WŁASNEJ PRZEGRÓDCE, oddzielona kreską od miejsca na tekst.
 *
 * Pole stoi samo na białej karcie i przy zwykłej `--obwodka` (#e6eaf0) jego krawędź
 * gubiła się w tle: wyglądało jak akapit z szarym napisem, a nie jak coś, w co się klika
 * i pisze. Mocniejsza obwódka mówi „to jest pole", a przegródka z lupą – „to jest pole
 * DO SZUKANIA", zanim ktokolwiek przeczyta podpowiedź w środku.
 *
 * Ikona siedzi w CSS jako `data:`, a nie pięć razy w HTML: pasek wyszukiwania stoi na
 * pięciu ekranach (wyceny, tablica, klienci, leady, mapa) i pięć kopii tego samego SVG
 * rozjechałoby się przy pierwszej poprawce. Nie idzie też przez `ikony.mjs`, bo to jedyna
 * ikona na statycznym elemencie strony – doskakiwałaby po wczytaniu modułów.
 */
.pole-szukania {
  display: flex; align-items: stretch; overflow: hidden;
  margin-bottom: 10px;
  border: 1.5px solid var(--obwodka-mocna); border-radius: 10px; background: #fff;
}

/* Przegródka: kreska plus szare tło. Samo tło bez kreski czyta się jak cień pola,
   sama kreska bez tła – jak przypadkowa linia w środku ramki. */
.pole-szukania::before {
  content: ''; flex: 0 0 44px;
  border-right: 1.5px solid var(--obwodka-mocna);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238794a3' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20.5 20.5l-4.2-4.2'/%3E%3C/svg%3E")
      center / 18px 18px no-repeat,
    var(--pole);
}

/*
 * Pole bez własnej ramki i poświaty – obie przejmuje otoczka, inaczej przy pisaniu
 * widać byłoby dwie obwódki, jedna w drugiej. Dlatego `.szukajka` jest wykluczona
 * z bazowej reguły pól (patrz komentarz przy niej) i cały jej wygląd stoi tutaj.
 */
.szukajka {
  flex: 1 1 auto; width: 100%; min-width: 0; margin: 0;
  padding: 12px 14px; border: 0; border-radius: 0; background: transparent;
  font: inherit; font-size: var(--pole-pismo); color: var(--grafit);
}
.szukajka:focus { outline: none; box-shadow: none; }
.pole-szukania:focus-within {
  border-color: var(--pomaranczowy); box-shadow: 0 0 0 3px rgba(255, 102, 0, 0.12);
}
.pole-szukania:focus-within::before { border-right-color: var(--pomaranczowy); }

/* TA SAMA OBWODKA CO SZUKAJKA, bo to jest ta sama warstwa widoku: dwa paski jeden pod
   drugim, oba do zawezania listy. Przy `--obwodka` pasek filtrow gubil krawedz na bialej
   karcie i wygladal jak sam napis „Filtry" – a szukajka nad nim miala juz ramke widoczna,
   wiec roznica czytala sie jako niedokonczony uklad, a nie jako hierarchia. */
.zwijka-filtrow { border: 1.5px solid var(--obwodka-mocna); border-radius: 10px; background: #fff; }
.zwijka-filtrow > summary {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  cursor: pointer; list-style: none; font-size: 14px;
}
.zwijka-filtrow > summary::-webkit-details-marker { display: none; }
.zwijka-filtrow > summary::before { content: '▸'; color: var(--pomaranczowy); }
.zwijka-filtrow[open] > summary::before { content: '▾'; }
.zwijka-filtrow > summary:hover { background: #fafbfd; border-radius: 9px; }
.zwijka-filtrow[open] > summary:hover { border-radius: 9px 9px 0 0; }

.zwijka-filtrow .pf-etykieta { font-weight: 600; flex: 0 0 auto; }
.zwijka-filtrow .pf-licznik {
  flex: 0 0 auto; background: var(--pomaranczowy); color: #fff; font-weight: 600;
  font-size: 12px; line-height: 1; padding: 4px 8px; border-radius: 999px;
}
/* Podpis zwinietego paska mowi, co jest wlaczone. Jedna linia – pasek ma byc paskiem,
   a nie rosnac razem z liczba filtrow, przed czym wlasnie chowamy kontrolki. */
.zwijka-filtrow .pf-skrot {
  flex: 1 1 auto; min-width: 0; color: var(--szary); font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.zwijka-filtrow > .filtry { padding: 4px 14px 14px; }

/* Podsumowanie i „wyczysc” w jednej linii: liczba wynikow i sposob ich skasowania
   to jedna mysl, a przycisk po prawej nie rozpycha paska filtrow. */
.pasek-podsumowania {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin-top: 12px;
}
.pasek-podsumowania .podpowiedz { margin: 0; }

/* --------------------------------------------------------------- tabela */

.tabela { width: 100%; border-collapse: collapse; }
.tabela th {
  text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--szary); font-weight: 600; padding: 0 12px 10px;
}
.tabela td { padding: 12px; border-top: 1px solid var(--obwodka); vertical-align: middle; }
.tabela tbody tr:hover { background: #fafbfd; }
.tabela .prawo, th.prawo { text-align: right; }

/* Tabela szersza niz karta przewija sie sama, zamiast rozpychac cala strone w poziomie.
   `overflow-x` na wrapperze, nie na `<table>` – tabela nie jest kontenerem przewijania. */
.tabela-przewijana { overflow-x: auto; scrollbar-width: thin; scrollbar-color: #c3ccd8 transparent; }
.tabela-przewijana::-webkit-scrollbar { height: 10px; }
.tabela-przewijana::-webkit-scrollbar-track { background: transparent; }
.tabela-przewijana::-webkit-scrollbar-thumb {
  background: #c3ccd8; border-radius: 999px;
  border: 2px solid var(--karta); background-clip: padding-box;
}
.tabela-przewijana .tabela { min-width: 780px; }

/* Lista klientow: jeden klient = jeden wiersz wysokosci jednej linii. Wczesniej kazdy
   rekord byl kafelkiem na cztery linie i na ekran wchodzilo ich piec. */
.tabela-klienci td { padding: 9px 12px; white-space: nowrap; }
.tabela-klienci th { padding-bottom: 8px; }
.tabela-klienci tbody tr { cursor: pointer; }
.tabela-klienci tbody tr:hover .nazwa { color: var(--pomaranczowy); }
.tabela-klienci .przyciszone { color: var(--grafit-jasny); }
.tabela-klienci .pusta { color: var(--szary); }

/* Nazwa firmy, adres i e-mail bywaja dowolnie dlugie i to one rozpychaly tabele –
   jeden klient „Przedsiebiorstwo Handlowo-Uslugowe ... sp. z o.o." wypychal poza ekran
   wszystkie kolumny z liczbami. Skracaja sie wiec wielokropkiem, a pelna tresc zostaje
   w `title`. Ograniczenie siedzi na elemencie w srodku komorki, bo `max-width` na `<td>`
   przy `table-layout: auto` jest tylko sugestia i przegrywa z trescia. */
.tabela-klienci .nazwa,
.tabela-klienci .adres,
.tabela-klienci .email { display: block; overflow: hidden; text-overflow: ellipsis; }
.tabela-klienci .nazwa { max-width: 300px; font-weight: 600; color: var(--grafit); }
.tabela-klienci .email { max-width: 220px; }
.tabela-klienci .adres { max-width: 240px; }
.tabela-klienci td.liczba { font-variant-numeric: tabular-nums; }

/* Na waskim ekranie tabela przewija sie w poziomie, ale kolumna z nazwiskiem zostaje
   na widoku – bez niej przewijanie jest bladzeniem po anonimowych liczbach. */
@media (max-width: 900px) {
  .tabela-klienci th:first-child, .tabela-klienci td:first-child {
    position: sticky; left: 0; background: var(--karta);
  }
  .tabela-klienci tbody tr:hover td:first-child { background: #fafbfd; }
}

/* Lista operatorow: kod po lewej, po co to jest po prawej. Klikniecie wstawia w kursor –
   przepisywanie z listy do pola jest zrodlem literowek, ktore wyjda dopiero u klienta. */
.operatory { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 6px; }
.operator {
  display: flex; align-items: baseline; gap: 8px; text-align: left;
  padding: 8px 10px; border: 1px solid var(--obwodka); border-radius: 8px;
  background: var(--karta); cursor: pointer; font: inherit; font-size: 12.5px;
}
.operator:hover { border-color: var(--pomaranczowy); background: var(--pomaranczowy-tlo); }
.operator code { color: var(--pomaranczowy-ciemny); font-size: 12px; white-space: nowrap; }
.operator span { color: var(--szary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --------------------------------------------------------- podglad wiadomosci */

/* Ramka wokol podgladu jest po to, zeby bylo widac, GDZIE konczy sie panel, a zaczyna
   tresc maila. Bez niej wiadomosc zlewa sie z karta i latwo wziac naglowek sekcji
   za czesc listu do klienta. */
.podglad-maila {
  border: 1px solid var(--obwodka); border-radius: 10px;
  padding: 22px; background: #fff;
}
.podglad-tekst {
  margin: 0; padding: 18px; background: var(--pole); border-radius: 10px;
  font-size: 13px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace; color: var(--grafit-jasny);
}

/* ------------------------------------------------------------- tabela raportu */

/*
 * Siatka raportu ma WIDOCZNE komorki, w odroznieniu od listy klientow obok.
 * Powod jest inny w obu przypadkach: lista to wiersze, ktore czyta sie poziomo, jeden
 * klient naraz. Raport czyta sie w DWIE strony – wzrok idzie w dol kolumny, zeby porownac
 * miesiace, i w bok wiersza, zeby porownac handlowcow. Bez pionowych linii przy siedmiu
 * kolumnach liczb wzrok gubi kolumne w polowie drogi i wartosci przeskakuja o jedna w bok.
 *
 * Osobna klasa, a nie `tabela-klienci`: tamta ustawia `cursor: pointer` i podswietlanie
 * wiersza, bo tam wiersz sie klika. Tu nie ma czego kliknac i kursor lapki tylko klamie.
 */
.tabela-raportu { width: 100%; border-collapse: collapse; font-size: 14px; }
.tabela-raportu th, .tabela-raportu td {
  padding: 9px 12px; white-space: nowrap;
  border: 1px solid var(--obwodka);
}
.tabela-raportu thead th {
  background: var(--pole); font-size: 12.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--grafit-jasny);
}
.tabela-raportu td.liczba, .tabela-raportu th.liczba { text-align: right; font-variant-numeric: tabular-nums; }
.tabela-raportu tbody tr:hover td { background: #fafbfd; }
.tabela-raportu .pusta { color: var(--szary); }

/* Pierwsza kolumna (okres) i ostatnia (razem) to ramy tabeli – trzymaja wzrok, gdy
   w srodku jest kilkanascie kolumn podzialu. */
.tabela-raportu td:first-child { font-weight: 600; color: var(--grafit); }
.tabela-raportu .razem { background: #fbfcfe; font-weight: 600; color: var(--grafit); }

/* Wiersz „Łącznie" jest liczony OSOBNYM zapytaniem, a nie suma kolumny – stad wyraznie
   inne tlo. Ma sie czytac jako odpowiedz na inne pytanie, a nie jako kolejny okres. */
.tabela-raportu tfoot td {
  background: var(--grafit); color: #fff; font-weight: 600;
  border-color: var(--grafit);
}
.tabela-raportu tfoot tr:hover td { background: var(--grafit); }

/* Naglowek zostaje na widoku przy dlugiej tabeli – bez tego po dziesiatym miesiacu
   nie wiadomo, ktora kolumna to ktory handlowiec. */
.tabela-raportu thead th { position: sticky; top: 0; z-index: 1; }

/* ------------------------------------------------------------------ wykresy */

.raport-glowa {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}
.przelacznik-widoku { flex: 0 0 auto; }
.przelacznik-widoku .opcja { flex: 0 0 auto; padding: 8px 16px; font-size: 13.5px; }

/* Kafelki z liczbami – „ile w ogóle”, zanim ktokolwiek spojrzy na rozbicie.
   Pierwszy jest większy, bo to on jest odpowiedzią; reszta go opisuje. */
.kafelki { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.kafel {
  flex: 1 1 160px; padding: 14px 18px;
  background: var(--pole); border-radius: 10px;
}
.kafel-etykieta { display: block; font-size: 12.5px; color: var(--grafit-jasny); margin-bottom: 4px; }
/* Cyfry proporcjonalne, nie tabelaryczne: `tabular-nums` daje każdej cyfrze szerokość
   zera i przy dużym stopniu pisma liczba wygląda na rozstrzeloną. Tabelaryczne
   zostają w kolumnach tabeli, gdzie muszą się pionowo równać. */
.kafel-wartosc { font-size: 24px; font-weight: 700; color: var(--grafit); letter-spacing: -0.02em; }
.kafel.glowny { flex-basis: 240px; background: var(--pomaranczowy-tlo); }
.kafel.glowny .kafel-wartosc { font-size: 32px; }

/* Legenda przy dwóch i więcej seriach jest obowiązkowa – kolor nie może być jedynym
   nośnikiem tożsamości. Tekst zostaje w kolorze tusza; identyfikuje kropka obok. */
.legenda { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-bottom: 10px; }
.legenda-poz { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--grafit-jasny); }
.legenda-poz i { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }

.wykres { width: 100%; overflow: hidden; }
.wykres svg { display: block; }

.dymek {
  position: fixed; z-index: 90; pointer-events: none;
  background: var(--grafit); color: #fff;
  padding: 7px 11px; border-radius: 8px; font-size: 12.5px; font-weight: 500;
  box-shadow: 0 4px 14px rgba(46, 58, 71, 0.22);
}

/* --------------------------------------------------------------- plakietki */

.plakietka {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600; background: var(--pole); color: var(--grafit-jasny);
}
.plakietka.roboczy { background: #eef1f5; color: #6b7787; }
.plakietka.wyslany { background: #e0edff; color: #1d4ed8; }
.plakietka.zainteresowany { background: #fff0e0; color: #c2410c; }
.plakietka.zaakceptowany { background: #dcfce7; color: #15803d; }
.plakietka.odrzucony { background: #fee2e2; color: #b91c1c; }

/* --------------------------------------------------------- panel podsumowania */

/* Klejenie tylko wtedy, gdy panel stoi w bocznej kolumnie. W ukladzie
   jednokolumnowym (<=1180 px) panel idzie NAD formularz (`order: -1` wyzej)
   i sticky zamienialo go w nakladke: przyklejony pod belka zaslanial caly
   ekran, a formularz przewijal sie pod nim, niewidoczny. */
@media (min-width: 1181px) {
  .podsumowanie { position: sticky; top: 84px; }
}
.podsumowanie .karta { padding: 22px; }

.metryka { display: flex; justify-content: space-between; align-items: baseline; padding: 9px 0; font-size: 14px; }
.metryka + .metryka { border-top: 1px solid var(--obwodka); }
.metryka span:first-child { color: var(--grafit-jasny); }
.metryka b { font-size: 16px; }
.metryka.suma { border-top: 2px solid var(--grafit); margin-top: 6px; padding-top: 14px; }
.metryka.suma b { font-size: 22px; color: var(--pomaranczowy); }

/*
 * PODGLAD WARIANTOW – cztery wiersze, w ktore handlowiec patrzy w kolko przy telefonie.
 *
 * Zbite tak ciasno, jak sie da, BEZ zabierania czegokolwiek z tresci: kazda kwota ma dalej
 * swoje „netto"/„brutto" przy sobie. Skrocone sa odstepy, stopnie pisma, interlinia
 * i powtorzone „zl" (patrz `liczba0`/`liczba2` w `pricing.mjs`) – wczesniej kazdy wiersz
 * lamal sie na dwie, a przy rabacie na trzy linie, i cztery warianty zjadaly pol karty
 * podgladu, spychajac rozbicie ceny pod krawedz ekranu.
 */
.wariant-rzad {
  padding: 9px; border-radius: 8px; background: var(--pole); margin-bottom: 4px;
  line-height: 1.25;
}
/* Obwodka schodzi z 2 px na 1,5 px: przy wierszu wysokim na 43 px gruba ramka byla
   najciezszym elementem calej kolumny i przykuwala wzrok mocniej niz sama kwota. */
.wariant-rzad.polecany { background: var(--pomaranczowy-tlo); box-shadow: inset 0 0 0 1.5px var(--pomaranczowy); }
/* Dwie NIEZALEZNE linie, a nie dwie kolumny. W ukladzie dwukolumnowym prawa kolumna brala
   szerokosc najszerszej ze swoich linii, wiec przekreslona cena Premium zwezala kolumne
   opisu o 40 px i to WYLACZNIE wiersz polecany lamal sie na trzy linie – ten jeden, ktory
   ma wygladac najlepiej. Osobne linie dziela szerokosc kazda po swojemu. */
.wariant-rzad .linia { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.wariant-rzad .nazwa { font-weight: 600; font-size: 12.5px; }
/*
 * CENA ZA METR – najciezszy element wiersza, ciezszy nawet od nazwy wariantu (600).
 * To na niej toczy sie negocjacja: handlowiec schodzi o zlotowke na metrze, a nie
 * o trzysta zlotych na sumie. Czern, a nie grafit – jedyne miejsce w panelu, gdzie
 * kontrast idzie na maksa, i to jest cala tresc tego wyroznienia.
 *
 * `min-width: 0` puszcza zawijanie – bez tego element flex nie kurczy sie ponizej swojej
 * tresci i to KWOTA po prawej bylaby wypychana poza wiersz.
 */
.wariant-rzad .m2 { font-size: 14px; font-weight: 700; color: var(--czarny); min-width: 0; }
.wariant-rzad .kwota,
.wariant-rzad .netto { white-space: nowrap; font-size: 11px; color: var(--grafit-jasny); }
/* Podpisy „brutto" i „netto" maja byc CZYTELNE, a nie ledwo widoczne – to one, a nie
   wielkosc czcionki, mowia, ktora z dwoch kwot jest ktora. Stad grafit, nie szarosc. */
.wariant-rzad .kwota b { font-size: 16px; color: var(--grafit); margin-right: 3px; }
.wariant-rzad .kwota s { font-size: 10.5px; color: var(--szary); margin-right: 5px; }

.rozbicie { font-size: 13px; }
.rozbicie div { display: flex; justify-content: space-between; padding: 5px 0; color: var(--grafit-jasny); }
.rozbicie div b { color: var(--grafit); font-weight: 600; }
.rozbicie .razem { border-top: 1px solid var(--obwodka); margin-top: 5px; padding-top: 8px; font-weight: 600; color: var(--grafit); }

/*
 * SYGNALIZATOR DOCHODOWOSCI – ile ta robota daje na dzien pracy ekipy.
 *
 * Klasa nazywa sie KOLOREM, a nie poziomem (`kolor-zielony`, nie `prog-dobry`), bo progi
 * siedza w cenniku i administrator moze je dodac, usunac albo przemianowac. Nazwa poziomu
 * w klasie CSS znaczylaby, ze piaty prog otwiera sie bez zadnego tla — po cichu.
 */
.dochodowosc {
  margin-top: 12px; padding: 8px 10px; border-radius: 8px;
  background: var(--pole);
}
/* Sygnal niesie SAMO TLO, bez kreski z boku. Kafelek stoi w kolumnie, w ktorej lewa
   krawedz maja juz wiersze wariantow nad nim i rozbicie ceny pod nim – czwarta pionowa
   linia na przestrzeni 200 px robila z podgladu drabine, a nie zestaw liczb. */
.dochodowosc.kolor-czerwony { background: #fef2f2; }
.dochodowosc.kolor-pomaranczowy { background: var(--pomaranczowy-tlo); }
.dochodowosc.kolor-zolty { background: #fefce8; }
.dochodowosc.kolor-zielony { background: var(--zielony-tlo); }
.dochod-glowa { display: flex; gap: 8px; align-items: center; line-height: 1.25; }
.dochod-znak { font-size: 16px; line-height: 1; }
/* Wynik punktowy jest tu liczba wiodaca – tyle samo wagi co cena brutto w wierszu wariantu. */
.dochod-glowa b { font-size: 16px; }
.dochod-glowa .ocena { font-size: 12.5px; color: var(--grafit-jasny); }
.dochod-glowa .podpowiedz { margin-top: 1px; font-size: 11px; }
/* Ile punktow zjadl rabat. Czerwien tylko na SAMEJ ZMIANIE, nie na calym kafelku: zlecenie
   moze zjechac o 40 punktow i dalej byc dobre — kolor tla nalezy do wyniku, nie do ubytku. */
.dochod-glowa .strata { color: var(--czerwony); }
.dochod-glowa .zysk { color: var(--zielony); }
/* Zdanie z cennika: od ktorego wyniku cena wymaga rozmowy z przelozonym. */
.dochod-uwaga {
  margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--obwodka);
  font-size: 11.5px; font-weight: 500; color: var(--grafit);
}
/* Pasek „na co rozchodzi sie przychod": ekipa, farba, utrzymanie firmy, zysk planowy,
   gorka ponad plan. Liczby nad nim sa audytem, pasek jest obrazem – szerokosci ida
   proporcjonalnie do kwot, wiec rabat i dopisany dzien widac jako kurczaca sie gorke. */
.dochod-pasek { display: flex; height: 14px; border-radius: 7px; overflow: hidden; margin: 8px 0 6px; }
.dochod-pasek span { min-width: 3px; }
.dochod-legenda { display: flex; flex-wrap: wrap; gap: 3px 12px; font-size: 11px; color: var(--grafit-jasny); margin-bottom: 4px; }
.dochod-legenda i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 4px; font-style: normal; }
.dochod-legenda b { color: var(--grafit); font-variant-numeric: tabular-nums; }

.dochodowosc .rozbicie {
  border-top: 1px solid var(--obwodka); margin-top: 7px; padding-top: 5px; font-size: 11.5px;
}
.dochodowosc .rozbicie div { padding: 2px 0; }
/* Komunikat o brakach w cenniku – jedyna tresc kafelka, gdy nie ma z czego liczyc marzy. */
.dochodowosc .braki { margin-top: 7px; font-size: 11px; }

/* Notatka o cenie – granica negocjacji jednym zdaniem. Wyglada jak karteczka przyklejona
   do ekranu, a nie jak podpowiedz pod polem: ma byc przeczytana, zanim padnie kwota. */
.notatka-ceny {
  padding: 10px 13px; border-radius: 9px; font-size: 13px; line-height: 1.45;
  background: #fffbeb; color: #854d0e; border-left: 3px solid var(--zolty);
}

.ostrzezenie {
  display: flex; gap: 9px; padding: 11px 14px; border-radius: 9px;
  background: #fff7ed; color: #9a3412; font-size: 13px; margin-bottom: 8px;
  border-left: 3px solid var(--pomaranczowy);
}
.info-pasek {
  background: var(--pomaranczowy); color: #fff; padding: 11px 16px;
  border-radius: 8px; font-weight: 600; font-size: 14px; margin-bottom: 16px;
}

/* ----------------------------------------------------------- rozwijane */

details.zwijka { border-top: 1px solid var(--obwodka); padding-top: 14px; margin-top: 14px; }
details.zwijka > summary { cursor: pointer; font-weight: 600; font-size: 14px; color: var(--grafit-jasny); list-style: none; }
details.zwijka > summary::-webkit-details-marker { display: none; }
details.zwijka > summary::before { content: '▸ '; color: var(--pomaranczowy); }
details.zwijka[open] > summary::before { content: '▾ '; }
details.zwijka > div { padding-top: 14px; }

.ukryte { display: none !important; }

/* --------------------------------------------------------------- toast */

/*
 * Schowany toast musi zjechac o WLASNA wysokosc plus odsuniecie od dolu – inaczej nie
 * zjezdza do konca za krawedz okna.
 *
 * Bylo tu `translateY(140%)`, czyli 140% wysokosci samego pudelka. Pusty toast (a taki
 * czeka na kazdej stronie, dopoki nie ma komunikatu) ma tylko 26 px wysokosci: same
 * paddingi, bez linii tekstu. 140% z 26 to 36 px, a do zejscia z ekranu potrzebne bylo
 * 26 + 24 = 50 px. Efekt: ciemny prostokat 48 x 26 px wystawal 14 px nad dol okna
 * na kazdej stronie z toastem. Przy toascie z trescia bylo to 5 px – mniej widoczne,
 * ale ten sam blad.
 *
 * `calc(100% + 24px)` liczy sie od faktycznej wysokosci, wiec dziala niezaleznie od tego,
 * czy i jak dlugi jest komunikat. `visibility` dodatkowo wyjmuje pudelko z malowania
 * i z klikania, zamiast trzymac je tuz za kadrem.
 */
#toast {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(calc(100% + 24px));
  visibility: hidden;
  background: var(--grafit); color: #fff; padding: 13px 24px; border-radius: 10px;
  font-weight: 600; font-size: 14px; z-index: 200;
  transition: transform 0.25s, visibility 0.25s; max-width: 90vw;
}
#toast.pokaz { transform: translateX(-50%) translateY(0); visibility: visible; }
#toast.blad { background: var(--czerwony); }

/* ------------------------------------------------------- suwak rabatu */

input[type='range'] { width: 100%; accent-color: var(--pomaranczowy); }

/* --------------------------------------------------------- pusty stan */

.pusto { text-align: center; padding: 60px 20px; color: var(--szary); }
.pusto h3 { font-size: 18px; color: var(--grafit-jasny); margin-bottom: 8px; }

/* ------------------------------------------- naglowek edytowanej wyceny */

.naglowek-wyceny h1 { font-size: 30px; font-weight: 700; color: var(--grafit); line-height: 1.2; }
.naglowek-wyceny > p { color: var(--grafit-jasny); font-size: 15px; margin-top: 6px; }
.pw-akcje { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 4px; }

.pw-siatka {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 22px; margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--obwodka);
}
.pw-kol h3 {
  font-size: 15px; font-weight: 600; color: var(--grafit); margin-bottom: 10px;
  padding-bottom: 8px; border-bottom: 1px solid var(--obwodka);
}
.pw-kol div { font-size: 13.5px; color: var(--grafit-jasny); line-height: 1.7; }
.pw-kol b { font-weight: 500; color: var(--grafit); }
.pw-kol .sygnal { color: var(--pomaranczowy); font-weight: 600; }
.pw-kol .ryzyko { color: var(--czerwony); font-weight: 500; }

/* ------------------------------------------------------- log aktywnosci */

.dopisz-notatke {
  display: grid; grid-template-columns: 1fr auto; gap: 8px;
  align-items: start; margin-bottom: 18px;
}
.dopisz-notatke .etykieta { grid-column: 1 / -1; margin-bottom: 0; }
.dopisz-notatke textarea { font-size: 13px; resize: vertical; }

.wpis { padding: 12px 0; border-top: 1px solid var(--obwodka); font-size: 13px; }
.wpis:first-child { border-top: 0; padding-top: 0; }
.wpis .gdy { color: var(--szary); font-size: 12px; float: right; }
.wpis .kto { font-weight: 600; color: var(--grafit); }
.wpis .co { color: var(--pomaranczowy); font-weight: 600; }
.wpis .tresc { color: var(--grafit-jasny); line-height: 1.6; margin-top: 3px; white-space: pre-wrap; }
.wpis .ceny { color: var(--grafit-jasny); line-height: 1.55; margin-top: 5px; font-size: 12.5px; }

/* Rozbicie zmian przy edycji: pole po polu, co było i co jest. Dodanie i usunięcie
   pozycji dostaje kolor, bo zmieniają ZAKRES robót, a nie tylko liczbę w polu. */
.wpis .zmiany { margin: 5px 0 0; padding-left: 0; list-style: none; font-size: 12.5px; line-height: 1.6; }
.wpis .zmiany li { color: var(--grafit-jasny); }
.wpis .zmiany li + li { margin-top: 1px; }
.wpis .zmiany .dodano { color: var(--zielony); }
.wpis .zmiany .usunieto { color: var(--czerwony); }
.wpis .zmiany i { color: var(--szary); font-style: normal; }
.wpis.systemowy .kto { color: var(--szary); font-weight: 400; }

tr.klikalny { cursor: pointer; }
tr.klikalny:hover td { background: var(--pole); }

#lista-aktywnosci { max-height: 60vh; overflow-y: auto; padding-right: 4px; }
#lista-aktywnosci::-webkit-scrollbar { width: 6px; }
#lista-aktywnosci::-webkit-scrollbar-thumb { background: var(--obwodka); border-radius: 3px; }
@media (max-width: 1180px) { #lista-aktywnosci { max-height: none; } }

/* ---------------------------------------------- ikony pokryc (/img/surfaces) */

.kafel .ikona-pokrycia { width: 84px; height: auto; display: block; margin-bottom: 2px; }
.kafel .ikona-pokrycia.akt { display: none; }
.kafel[aria-pressed='true'] .ikona-pokrycia { display: none; }
.kafel[aria-pressed='true'] .ikona-pokrycia.akt { display: block; }

.podpowiedz.ostrzezenie { color: var(--czerwony); font-weight: 600; }
/* Ostrzezenie WEWNATRZ podpowiedzi – reszta zdania ma zostac szara. */
.ostrzezenie-tekst { color: var(--czerwony); font-weight: 600; }

/* -------------------------------------------------- lista wycen (wiersze) */

.lista-wycen { display: flex; flex-direction: column; }

.wiersz {
  display: grid; align-items: center; gap: 18px; cursor: pointer;
  grid-template-columns: 84px minmax(0, 1fr) 130px 150px 150px auto;
  padding: 16px 6px; border-top: 1px solid var(--obwodka);
}
.wiersz:first-child { border-top: 0; }
.wiersz:hover { background: var(--pole); }

/* Ikona z podpisem – ten sam układ co kafle wyboru pokrycia w kalkulatorze. */
.w-ikona { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
.w-ikona img { width: 76px; height: auto; }
.w-ikona span {
  font-size: 12px; font-weight: 600; color: var(--grafit-jasny);
  line-height: 1.2; text-align: center;
}

/* Numer wyceny to identyfikator, nie sygnal – drobnym drukiem nad adresem, a nie
   plakietka wsrod informacji, ktore mowia cos o stanie sprawy. */
.w-numer { font-size: 11px; color: var(--szary); letter-spacing: .02em; margin-bottom: 1px; }
.w-tytul { font-size: 17px; font-weight: 600; color: var(--grafit); margin-bottom: 5px; }
.w-tagi { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: 13px; color: var(--grafit-jasny); }
.w-tagi .tag { white-space: nowrap; }
/* Etap lejka: kropka w kolorze etapu – ten sam kolor co pinezka na mapie i kafelek
   legendy, zeby trzy ekrany mowily o etapie jednym jezykiem. Status dokumentu stoi obok
   i zostaje pomaranczowy, bo odpowiada na inne pytanie: czy oferta poszla do klienta. */
.w-tagi .etap { display: inline-flex; align-items: center; gap: 5px; color: var(--grafit); font-weight: 600; }
.w-tagi .etap .kropka { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.w-tagi .status { color: var(--pomaranczowy); font-weight: 600; }

/* Przycisk bedacy sama ikona – podglad oferty na liscie i na karcie klienta. */
.btn.btn-ikona { padding: 5px 8px; line-height: 0; }
.btn.btn-ikona svg { width: 17px; height: 17px; }
/* Wycena bez powierzchni nie ma tresci oferty. Wygaszone oko zamiast pustego miejsca:
   inaczej wracamy do listy, na ktorej czesc wierszy ma przycisk, a czesc nie. */
.btn.btn-ikona.wylaczony { opacity: .28; cursor: not-allowed; background: none; border-color: var(--obwodka); }

/* Pomiarowiec z miarka. Ikona, a nie sam kolor: na plakietce tej wielkosci kolor
   jest nieczytelny przy slabym wzroku i znika przy wydruku. */
.tag.pomiarowiec { display: inline-flex; align-items: center; gap: 4px; }
.tag.pomiarowiec svg { width: 13px; height: 13px; flex: 0 0 auto; opacity: .75; }
.w-tagi .pilne { color: var(--zielony); font-weight: 600; }
.w-tagi .numer { color: var(--szary); }

.w-liczba { text-align: right; line-height: 1.35; }
.w-liczba b { display: block; font-size: 17px; font-weight: 600; color: var(--grafit); }
.w-liczba span { font-size: 13px; color: var(--grafit-jasny); }
.w-akcje { text-align: right; white-space: nowrap; }

/* --------------------------------------------------------------- okno modalne */

.zaslona {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(46, 58, 71, 0.45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.okno {
  background: var(--karta); border-radius: var(--r); box-shadow: var(--cien);
  padding: 26px 28px; width: 100%; max-width: 620px;
  max-height: 88vh; overflow-y: auto;
}
.okno > h2 { font-size: 20px; margin-bottom: 18px; }

/* Kanal wysylki: pole wyboru, adres i podglad tresci w jednym bloku. Wylaczony kanal
   zostaje WIDOCZNY z powodem – zniknięty kazalby sie domyslac, czemu go nie ma. */
.kanal { border: 1px solid var(--obwodka); border-radius: 10px; padding: 14px 16px; margin-bottom: 12px; }
.kanal.wylaczony { opacity: 0.6; }
.kanal-glowa { display: flex; align-items: center; gap: 10px; font-weight: 600; }
.kanal-glowa input { width: 17px; height: 17px; flex: 0 0 auto; }
.kanal-odbiorca { margin-left: auto; font-weight: 400; font-size: 13px; color: var(--grafit-jasny); }
.kanal-tresc {
  margin: 12px 0 0; padding: 12px 14px; background: var(--pole); border-radius: 8px;
  font-size: 13px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere;
  color: var(--grafit-jasny);
}
.kanal-temat { margin-top: 10px; font-size: 13px; }
.kanal-licznik { font-size: 12px; color: var(--szary); margin-top: 6px; }

/* Brak koloru na etapie, na ktorym robota juz czeka na ekipe. Mocniejszy niz reszta
   znacznikow, bo to jedyny, ktory mowi „ta robota nie ruszy" – a nie „warto zerknac". */
.tag.brak-koloru { background: #fee2e2; color: #b91c1c; font-weight: 700; }

/* Zastoj: karta stoi na etapie dluzej niz prog. Zegarek dziedziczy kolor po znaczniku
   (`currentColor`), wiec wystarczy pomalowac plakietke – ikona idzie za nia sama. */
.tag.zastoj {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); font-weight: 600;
}
.tag.zastoj svg { width: 13px; height: 13px; flex: 0 0 auto; }

/* Czy klient otworzyl oferte. WYROZNIONY jest tylko stan „nie otworzyl" – to on jest
   sygnalem do telefonu. Dwa pozostale sa przyciszone, bo gdyby wszystkie trzy krzyczaly,
   lista zamienilaby sie w choinke i przestaloby byc widac ktorykolwiek. */
.tag.otwarcie { font-weight: 600; }
.tag.otwarcie.nieotwarta { background: #fee2e2; color: #b91c1c; }
.tag.otwarcie.otwarta { background: #dcfce7; color: #15803d; }
.tag.otwarcie.niewyslana { background: var(--pole); color: var(--szary); font-weight: 500; }

.zaint { font-weight: 600; border-radius: 20px; padding: 1px 9px; font-size: 12px; }
.zaint.goracy { background: #ffe6dc; color: #c2410c; }
.zaint.cieply { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); }
.zaint.letni  { background: #eef1f6; color: var(--grafit-jasny); }
.zaint.zimny  { background: #eef1f6; color: var(--szary); }

@media (max-width: 900px) {
  .wiersz { grid-template-columns: 60px minmax(0, 1fr); gap: 10px; }
  .w-ikona { align-self: start; }
  .w-ikona img { width: 54px; }
  /* Kolumna ma 60 px – dłuższe nazwy muszą się łamać, a nie rozpychać wiersza. */
  .w-ikona span { font-size: 11px; overflow-wrap: anywhere; }
  .w-liczba { grid-column: 2; text-align: left; display: flex; gap: 8px; align-items: baseline; }
  .w-liczba b { display: inline; font-size: 15px; }
  .w-akcje { grid-column: 2; text-align: left; }
}

/* --------------------------------------------- wskaznik zainteresowania */

.pw-podglowek { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.pw-podglowek p { margin: 0; }

/* ------------------------------------------------- kluczowe czynniki */

/* PASEK W WYCENIE – liczba, prog i link do rozbicia. Jedna linia, bo formularz wyceny
   jest dlugi i pelna karta zajmowala w nim pol ekranu przed polami, po ktore sie tu wchodzi. */
.ocena-pasek {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 14px 0 2px; font-size: 13.5px; color: var(--grafit-jasny);
}
.ocena-pasek .zaint { font-size: 14px; padding: 2px 11px; }
.ocena-pasek b { color: var(--grafit); font-weight: 600; }
.ocena-pasek .rosnie { color: var(--zielony); font-weight: 600; }
.ocena-pasek a { margin-left: auto; color: var(--pomaranczowy-ciemny); font-weight: 600; text-decoration: none; }
.ocena-pasek a:hover { text-decoration: underline; }

/* KARTA NA KARCIE KLIENTA – pelne rozbicie. Bez wlasnej ramki: siedzi w `.karta`,
   ktora juz ja ma, a dwie obwodki jedna w drugiej wygladaja jak blad. */
.ocena { display: flex; gap: 22px; align-items: flex-start; }
@media (max-width: 620px) { .ocena { flex-direction: column; gap: 12px; } }

/*
 * W KOLUMNIE BOCZNEJ KARTA UKLADA SIE W PION, niezaleznie od szerokosci okna.
 *
 * Kolumna ma stale 380 px, wiec po odjeciu marginesow karty zostaje okolo 336 px. Uklad
 * poziomy zabiera z tego 96 px na pierscien z wynikiem i 22 px na odstep – lista czynnikow
 * dostaje wtedy niecale 220 px i kazda pozycja („Klient otworzyl oferte trzy razy") lamie
 * sie na trzy linijki. Pion oddaje jej cala szerokosc, a wynik i tak jest pierwsza rzecza,
 * ktora widac.
 *
 * To NIE jest to samo co reguła 620 px wyzej: tamta patrzy na okno, a tu waska jest sama
 * kolumna – takze na monitorze 4K.
 */
aside .ocena { flex-direction: column; gap: 12px; }
aside .ocena-wynik { width: auto; }

.ocena-wynik { flex: 0 0 auto; text-align: center; width: 96px; }

/* Gruby pierscien, nie wypelnione kolo: liczba ma zostac czytelna, a kolor progu
   ma byc widoczny takze wtedy, gdy jest jasny. */
.ocena-krag {
  width: 84px; height: 84px; margin: 0 auto;
  border: 6px solid var(--szary); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.ocena-krag b { font-size: 30px; font-weight: 700; color: var(--grafit); line-height: 1; }
/* Te same cztery kolory co plakietka progu na liscie i tablicy – legenda nie moze
   znaczyc czegos innego niz pierscien. */
.ocena-krag.goracy { border-color: #f26a4b; }
.ocena-krag.cieply { border-color: var(--pomaranczowy); }
.ocena-krag.letni  { border-color: #9fb0c4; }
.ocena-krag.zimny  { border-color: #cbd5e1; }

.ocena-zmiana { margin-top: 8px; font-size: 12px; line-height: 1.35; }
.ocena-zmiana .rosnie { color: var(--zielony); font-weight: 700; }
.ocena-zmiana .bez-zmian { color: var(--szary); }
.ocena-zmiana small { display: block; color: var(--szary); }

.ocena-tresc { flex: 1 1 auto; min-width: 0; }
.ocena-prog {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0; font-size: 13.5px; color: var(--grafit-jasny);
}
.ocena-tresc h4 {
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--szary); margin: 12px 0 4px;
}
.ocena-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.ocena-lista li { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--grafit); }
.ocena-lista li > span { flex: 1 1 auto; min-width: 0; }
.ocena-lista li > b { flex: 0 0 auto; font-weight: 700; color: var(--zielony); font-size: 12.5px; }
.ocena-lista i { flex: 0 0 auto; display: flex; }
.ocena-lista svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.ocena-lista li.plus i { color: var(--zielony); }
.ocena-lista li.minus i { color: var(--czerwony); }
.ocena-lista li.minus > span { color: var(--grafit-jasny); }
.ocena-lista li.neutralny i { color: var(--szary); }
.ocena-lista li.neutralny > span { color: var(--grafit-jasny); }
.ocena .podpowiedz { margin: 12px 0 0; }

/* Sygnaly punktacji – najdluzsza grupa i czytana najrzadziej, wiec za jednym kliknieciem.
   `<details>` zamiast wlasnego przelacznika: dziala z klawiatury i czytnika ekranu. */
.ocena-zwijka { margin-top: 12px; }
.ocena-zwijka summary {
  display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none;
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--szary);
  padding: 3px 0;
}
.ocena-zwijka summary::-webkit-details-marker { display: none; }
/* Trojkat rysujemy sami, bo domyslny znacznik znika razem z `list-style: none`
   i zwijka przestaje wygladac na klikalna. */
.ocena-zwijka summary::before {
  content: ''; width: 0; height: 0; flex: 0 0 auto;
  border: 4px solid transparent; border-left-color: var(--szary);
  transition: transform .15s;
}
.ocena-zwijka[open] summary::before { transform: rotate(90deg) translateX(2px); }
.ocena-zwijka summary:hover { color: var(--grafit); }
.ocena-zwijka summary:hover::before { border-left-color: var(--grafit); }
.ocena-zwijka summary span { color: var(--grafit-jasny); font-weight: 600; letter-spacing: 0; }
.ocena-zwijka .ocena-lista { margin-top: 4px; }

.termin-wjazdu {
  display: inline-block; background: var(--pomaranczowy); color: #fff;
  font-size: 13px; font-weight: 600; padding: 2px 9px; border-radius: 5px;
  margin-right: 10px; vertical-align: 2px; white-space: nowrap;
}
.w-tagi .ekipa { color: var(--grafit); font-weight: 600; }

.ustawienia-siatka { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px 20px; }
.ustawienia-siatka .pole { margin: 0; }
.ustawienia-siatka code { color: var(--szary); font-size: 11px; }

.brygady-naglowek, .brygady-wiersz {
  display: grid; grid-template-columns: 90px 1fr 240px 110px; gap: 10px; align-items: center;
}
.brygady-naglowek { font-size: 12px; color: var(--szary); text-transform: uppercase; letter-spacing: .04em; padding-bottom: 8px; }
.brygady-wiersz { padding: 4px 0; }
/* Ekipa zaznaczona do archiwum zostaje widoczna, ale wyraznie wylaczona – to jest
   zmiana ZAPLANOWANA, ktora utrwali dopiero "Zapisz", i musi tak wygladac. */
.brygady-wiersz.do-archiwum input, .brygady-wiersz.do-archiwum select {
  text-decoration: line-through; opacity: .5;
}
.brygady-wiersz input { font-size: 13.5px; }
@media (max-width: 900px) { .brygady-naglowek { display: none; } .brygady-wiersz { grid-template-columns: 1fr; padding: 10px 0; border-top: 1px solid var(--obwodka); } }

/* --------------------------------------------------- logowanie i konta */

.ekran-logowania { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.ekran-logowania .karta { width: 100%; max-width: 400px; padding: 34px; }
/* Na bialej karcie znak bierze kolor tekstu, czyli grafit – ten sam plik co na pasku. */
.ekran-logowania .znak { width: 200px; height: 38px; margin-bottom: 10px; }

.wpis.konto { position: relative; padding: 14px 0; }
.wpis.konto .konto-akcje { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.wpis.konto .konto-akcje select { width: auto; min-width: 150px; font-size: 13px; }
.wpis.konto.systemowy { opacity: .55; }

.konto-info { font-size: 13px; color: var(--grafit-jasny); font-weight: 500; }

/* ------------------------------------------------------ rozwijane konto */

.konto-menu { position: relative; }
.konto-przycisk {
  display: flex; align-items: center; gap: 7px; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13.5px; font-weight: 500; color: var(--grafit-jasny);
  padding: 7px 10px; border-radius: 8px;
}
.konto-przycisk:hover { background: var(--pole); color: var(--grafit); }
.konto-przycisk i { font-style: normal; font-size: 11px; color: var(--szary); }

/* Przycisk konta stoi w ciemnym pasku, a nie na bialym tle jak reszta `.konto-*`.
   Kolor spod grafitu (#5b6876) na czarnym tle robi sie nieczytelny, wiec w pasku
   przycisk chodzi w tych samych barwach co linki menu obok niego. */
.belka .konto-przycisk { color: #c3ccd6; }
.belka .konto-przycisk:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.belka .konto-przycisk i { color: #8794a3; }

.konto-panel {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 210px; z-index: 40;
  background: var(--karta); border: 1px solid var(--obwodka); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(46, 58, 71, .14); padding: 6px; display: flex; flex-direction: column;
}
/* Bez tego `display: flex` powyzej wygrywa z atrybutem hidden i panel jest zawsze widoczny. */
.konto-panel[hidden] { display: none; }
.konto-naglowek {
  padding: 9px 12px 11px; font-size: 12.5px; color: var(--grafit); font-weight: 600;
  border-bottom: 1px solid var(--obwodka); margin-bottom: 6px; word-break: break-all;
}
.konto-naglowek span { display: block; font-weight: 400; color: var(--szary); margin-top: 2px; }

.konto-panel a, .konto-panel button {
  display: block; text-align: left; padding: 9px 12px; border-radius: 8px; border: 0;
  background: none; font: inherit; font-size: 13.5px; color: var(--grafit-jasny);
  text-decoration: none; cursor: pointer;
}
.konto-panel a:hover, .konto-panel button:hover { background: var(--pole); color: var(--grafit); }
.konto-panel a.aktywny { color: var(--pomaranczowy); font-weight: 600; }
.konto-panel #konto-wyloguj { margin-top: 6px; border-top: 1px solid var(--obwodka); border-radius: 0 0 8px 8px; }

/* ------------------------------------------------------- strefa ryzyka */

.strefa-ryzyka { border-color: #f3c2c2; }
.strefa-ryzyka > h2 { color: var(--czerwony); border-bottom-color: #f3c2c2; }
.ryzyko-wiersz { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; }
.ryzyko-wiersz b { font-size: 15px; color: var(--grafit); }

.btn-niebezpieczny { background: var(--czerwony); color: #fff; border-color: var(--czerwony); }
.btn-niebezpieczny:hover { background: #b91c1c; border-color: #b91c1c; }

.brutto-pozycji { font-size: 12px; color: var(--szary); }

/* ------------------------------------------------------------- tablica */

/* Kolumny dziela dostepna szerokosc po rowno, ale nie schodza ponizej 290 px – przy
   wezszym ekranie tablica zaczyna sie przewijac w poziomie, zamiast sciskac karty
   do szerokosci, w ktorej adres lamie sie na cztery linie.

   Osiem etapow po 290 px nie miesci sie na zadnym typowym monitorze, wiec pasek przewijania
   jest tu normalnym elementem widoku, a nie awaria – ma byc widac, ze tablica ciagnie sie
   dalej niz krawedz okna. Stad pelnowymiarowy pasek (`scrollbar-width: auto`), a nie
   hairline. `overflow-x: auto` zostawia go tylko wtedy, gdy kolumny faktycznie wystaja.

   Uwaga: w Chrome i Firefoksie samo podanie `scrollbar-color` wylacza `::-webkit-scrollbar`.
   Regoly ponizej sa wiec fallbackiem dla starszego Safari, a nie glownym stylem. */
.tablica {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(290px, 1fr);
  gap: 16px; overflow-x: auto; padding-bottom: 10px; align-items: start;
  overscroll-behavior-x: contain;
  scrollbar-width: auto;
  scrollbar-color: #c3ccd8 transparent;
}
.tablica::-webkit-scrollbar { height: 14px; }
.tablica::-webkit-scrollbar-track { background: transparent; }
.tablica::-webkit-scrollbar-thumb {
  background: #c3ccd8; border-radius: 999px;
  border: 3px solid var(--tlo); background-clip: padding-box;
}
.tablica::-webkit-scrollbar-thumb:hover { background: var(--szary); background-clip: padding-box; }
/* Kolumna stoi na BIALYM tle, a nie na `--pole`. Roznica miedzy tlem strony (#f1f3f6)
   a dawnym tlem kolumny (#f4f6f9) byla trzema punktami jasnosci, czyli praktycznie zadna –
   kolumny zlewaly sie z tlem i jedynym, co je od niego odcinalo, byl kolorowy pas nad
   naglowkiem. Biel robi to, co pas robil przy okazji, i nie potrzebuje do tego kreski. */
.kolumna {
  display: flex; flex-direction: column; min-height: 120px;
  background: var(--karta); border: 1px solid var(--obwodka); border-radius: var(--r);
}
.kolumna > header { padding: 13px 16px 11px; }

.kolumna h2 { font-size: 14px; font-weight: 600; letter-spacing: 0; display: flex; gap: 8px; }
.kolumna h2 span { margin-left: auto; color: var(--szary); font-weight: 600; }
.kolumna .suma { font-size: 12.5px; color: var(--grafit-jasny); margin-top: 3px; min-height: 19px; }
.kolumna .karty { overflow-y: auto; padding: 4px 12px 12px; display: flex; flex-direction: column; gap: 10px; }

/* Pionowy pasek w kolumnie jest waski i pojawia sie dopiero, gdy kart faktycznie
   nie widac – w przeciwienstwie do poziomego, ktory jest tu na stale. */
.kolumna .karty { scrollbar-width: thin; scrollbar-color: #cdd5df transparent; }
.kolumna .karty::-webkit-scrollbar { width: 8px; }
.kolumna .karty::-webkit-scrollbar-thumb {
  background: #cdd5df; border-radius: 999px;
  border: 2px solid var(--karta); background-clip: padding-box;
}
.kolumna .karty:empty::after {
  content: 'pusto'; display: block; text-align: center; padding: 14px 0;
  font-size: 12.5px; color: var(--szary); font-style: italic;
}
/* Cel upuszczenia musi byc widoczny takze wtedy, gdy kolumna jest pusta. */
.kolumna.nad { background: var(--pomaranczowy-tlo); }
.kolumna.nad .karty { outline: 2px dashed var(--pomaranczowy); outline-offset: -4px; border-radius: 8px; }

.kartka {
  background: var(--karta); border: 1px solid var(--obwodka); border-radius: 10px;
  padding: 13px 15px; cursor: grab; box-shadow: 0 1px 2px rgba(46, 58, 71, .05);
  transition: border-color .12s, box-shadow .12s;
}
.kartka:hover { border-color: var(--pomaranczowy); box-shadow: 0 2px 10px rgba(46, 58, 71, .09); }
.kartka.przenoszona { opacity: .4; }
.kartka .glowka { display: flex; align-items: flex-start; gap: 6px; }
.kartka .tytul { flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: 14.5px; line-height: 1.35; }
/* Numer nad adresem, wlasnym wierszem i drobnym drukiem – identyfikator ma byc
   dostepny, ale nie ma konkurowac wzrokiem z tym, gdzie jest robota. */
.kartka .tytul .numer { display: block; font-size: 10.5px; font-weight: 400; color: var(--szary); letter-spacing: .02em; }
.kartka .klient { font-size: 12.5px; color: var(--grafit-jasny); margin-top: 3px; }
.kartka .klient:empty { display: none; }

/* Skrot do edycji wyceny. Karta prowadzi do klienta, wiec wejscie w sama wycene musi
   miec wlasny, widoczny punkt – inaczej byloby dostepne tylko okrezna droga.
   Ujemne marginesy wsuwaja ikone w naroznik, zeby nie podbijala wysokosci tytulu. */
.kartka .edytuj {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 26px; height: 26px; margin: -4px -5px 0 0;
  border-radius: 7px; color: var(--szary); text-decoration: none;
}
.kartka .edytuj svg { width: 15px; height: 15px; }
.kartka .edytuj:hover { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); }
.kartka .liczby {
  display: flex; gap: 10px; align-items: baseline;
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--obwodka);
}
.kartka .liczby b { font-size: 15.5px; }
.kartka .liczby span { font-size: 12.5px; color: var(--grafit-jasny); margin-left: auto; }
.kartka .znaczniki { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; font-size: 11.5px; }
.kartka .znaczniki:empty { display: none; }
/*
 * `:where()` ma ZEROWA specyficznosc, wiec ten selektor waży tyle co samo `.tag`.
 *
 * Bez tego reguła („.kartka .znaczniki .tag", 0-3-0) bila kazdy wariant zapisany jako
 * `.tag.cos` (0-2-0) i plakietki traciły kolor WYLACZNIE na tablicy – na liscie wycen,
 * gdzie kontener jest inny, te same klasy dzialaly. Objawia sie to jako „u mnie dziala",
 * bo trzeba porownac dwa ekrany, zeby zobaczyc roznice.
 *
 * Warianty ponizej (`.ekipa`, `.pilne`) celowo zostaja pelnoprawne – nadal wygrywaja.
 */
:where(.kartka .znaczniki) .tag {
  background: var(--pole); border-radius: 20px; padding: 2px 9px; color: var(--grafit-jasny);
}
.kartka .znaczniki .ekipa { background: #e8edf4; color: var(--grafit); font-weight: 600; }
.kartka .znaczniki .pilne { background: #dcfce7; color: #15803d; font-weight: 600; }
.kartka .znaczniki .zaint { font-size: 11.5px; }

/* Podpowiedz etapu: przycisk, nie automat. Jedno klikniecie przestawia karte. */
.kartka .podpowiedz {
  display: block; width: 100%; text-align: left; margin-top: 8px;
  background: var(--pomaranczowy-tlo); border: 1px solid #ffd9bf; border-radius: 8px;
  padding: 6px 9px; font: inherit; font-size: 11.5px; color: var(--pomaranczowy-ciemny); cursor: pointer;
}
.kartka .podpowiedz:hover { background: #ffe7d4; }
.kartka .podpowiedz b { display: block; font-size: 12px; }

/*
 * Wysokosc tablicy liczona przez uklad, a nie stala.
 *
 * Wczesniej kolumny mialy `max-height: calc(100vh - 265px)`, gdzie 265 to byla suma
 * wysokosci wszystkiego nad tablica. Dzialalo dopoki pasek filtrow mial staly rozmiar.
 * Po dolozeniu filtrow pasek zawija sie na jeden, dwa albo trzy rzedy zaleznie od
 * szerokosci okna – zadna stala nie trafi we wszystkie trzy przypadki, a pomylka
 * spycha poziomy pasek przewijania pod krawedz ekranu.
 *
 * Teraz strona jest kolumna o wysokosci okna, tablica zabiera to, co zostanie po pasku
 * filtrow, a kolumny nie moga przekroczyc tej wysokosci. `min-height: 0` jest konieczne:
 * element flex domyslnie nie kurczy sie ponizej swojej tresci i tablica rozpychalaby
 * strone zamiast przewijac karty w srodku.
 *
 * Tylko na szerokim ekranie – na telefonie kolumny ida jedna pod druga i strona
 * przewija sie normalnie.
 */
@media (min-width: 901px) {
  .strona.szeroka { display: flex; flex-direction: column; height: calc(100vh - 60px); }
  .strona.szeroka .tablica { flex: 1 1 auto; min-height: 0; }
  .strona.szeroka .kolumna { max-height: 100%; }
}

/*
 * ...a ponizej progu KOLUMNY IDA JEDNA POD DRUGA – co akapit wyzej obiecywal, a czego
 * `grid-auto-flow: column` nie robil: prog zdejmowal tylko ograniczenie wysokosci,
 * uklad zostawal poziomy. Osiem etapow po 290 px na ekranie 375 px znaczylo tablice
 * szeroka na 2400 px, po ktorej trzeba bylo wedrowac w bok, zeby sprawdzic, czy
 * w kolejnym etapie cokolwiek stoi – a licznik przy nazwie etapu odpowiada na to
 * pytanie od razu, jak tylko etapy sa jeden pod drugim.
 *
 * Przeciaganie kart palcem i tak nie dziala (obsluga stoi na zdarzeniach `drag`, ktorych
 * przegladarka mobilna nie wysyla), wiec pionowa tablica nic tu nie zabiera: na telefonie
 * jest to lista do CZYTANIA, a etap przestawia sie z karty wyceny.
 *
 * Etapy puste zwijamy do samego naglowka – inaczej polowa ekranu to nagłówki nad
 * napisem „pusto".
 */
@media (max-width: 900px) {
  .tablica { grid-auto-flow: row; grid-auto-columns: auto; overflow-x: visible; gap: 10px; }
  .kolumna { min-height: 0; }
  .kolumna > header { padding: 11px 14px 9px; }
  .kolumna .karty { padding: 0 10px 10px; }
  .kolumna .karty:empty { display: none; }
  .kolumna .karty:empty::after { content: none; }
}

/* --------------------------------------------------------- karta klienta */

.klient-naglowek { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.klient-naglowek .dane { flex: 1 1 260px; }
.klient-naglowek h1 { font-size: 24px; margin-bottom: 4px; }
.klient-naglowek .kontakt-linie { color: var(--grafit-jasny); font-size: 14px; }
.klient-liczby { display: flex; gap: 26px; flex-wrap: wrap; }
.klient-liczby div { line-height: 1.3; }
.klient-liczby b { display: block; font-size: 22px; font-weight: 700; }
.klient-liczby span { font-size: 12.5px; color: var(--szary); }

/*
 * OFERTA, O KTORA TERAZ GRAMY – pelna kartka z tablicy na wierzchu listy wycen.
 *
 * Wyroznienie idzie pomarancza obwodki, a nie kolorowym tlem: kartka niesie wlasne
 * plakietki (otwarcie, zainteresowanie, ekipa) i tlo zaczeloby z nimi konkurowac.
 * Obwodka jest tym samym akcentem, ktory kartka na tablicy dostaje pod kursorem –
 * tutaj po prostu zostaje na stale.
 */
.oferta-glowna { margin-bottom: 18px; }
.oferta-glowna-podpis {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--pomaranczowy-ciemny); margin-bottom: 7px;
}
/* Nieprzeciagalna, wiec `grab` z tablicy bylby obietnica bez pokrycia. */
.oferta-glowna .kartka { cursor: pointer; }
.kartka.glowna { border-color: var(--pomaranczowy); box-shadow: 0 2px 12px rgba(255, 102, 0, .10); }
.kartka.glowna:hover { box-shadow: 0 3px 16px rgba(255, 102, 0, .16); }

/* Naglowek listy pod wyrozniona oferta – mowi, ze to juz historia, a nie biezaca sprawa. */
.podtytul-listy {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--szary); margin: 0 0 2px;
}
.podtytul-listy span {
  background: var(--pole); border-radius: 20px; padding: 1px 8px;
  font-size: 11.5px; letter-spacing: 0; color: var(--grafit-jasny);
}

.wycena-wiersz {
  display: grid; grid-template-columns: 1fr auto auto; gap: 14px; align-items: center;
  padding: 12px 0; border-top: 1px solid var(--obwodka); cursor: pointer;
}
/* Pierwszy wiersz nie ma nad soba czego oddzielac – takze wtedy, gdy stoi tuz pod
   naglowkiem „Pozostale wyceny", czyli nie jest juz pierwszym dzieckiem kontenera. */
.wycena-wiersz:first-child, .podtytul-listy + .wycena-wiersz { border-top: 0; }
.wycena-wiersz:hover .numer-wyceny { color: var(--pomaranczowy); }
.wycena-wiersz .numer-wyceny { font-weight: 600; }
.wycena-wiersz .meta { font-size: 12.5px; color: var(--grafit-jasny); margin-top: 3px; }
.wycena-wiersz .kwota { text-align: right; font-weight: 600; }

/* Plakietka etapu – ten sam zestaw kolorow co pasy kolumn na tablicy. */
.plakietka-etapu {
  display: inline-block; border-radius: 20px; padding: 2px 10px;
  font-size: 12px; font-weight: 600; background: #e8edf4; color: var(--grafit-jasny);
}
.plakietka-etapu[data-typ='wygrany']   { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); }
.plakietka-etapu[data-typ='zamkniety'] { background: #dcfce7; color: #15803d; }
.plakietka-etapu[data-typ='przegrany'] { background: #fee2e2; color: #b91c1c; }

/* Etap w naglowku wyceny – to samo pole co kolumna na tablicy, wiec ma byc widoczne
   od razu, a nie schowane w siatce podsumowania. */
.wybor-etapu {
  width: auto; padding: 4px 10px; font-size: 12.5px; font-weight: 600;
  border-radius: 20px; background: var(--pole); color: var(--grafit-jasny);
}
.wybor-etapu:disabled { opacity: .7; }

/* Numer wyceny przy wpisie na wspolnej osi czasu klienta. */
.wpis .przy-wycenie { margin-left: 8px; font-size: 12px; color: var(--szary); text-decoration: none; }
.wpis .przy-wycenie:hover { color: var(--pomaranczowy); }

/* ------------------------------------------------------- okno etapu */

/* Natywny <dialog>: wbudowana blokada tła i obsługa Escape, zero dodatkowego kodu. */
.okno-etapu {
  width: min(520px, calc(100vw - 32px));
  padding: 0; border: 0; border-radius: var(--r);
  background: var(--karta); color: var(--grafit);
  box-shadow: 0 24px 60px rgba(46, 58, 71, .28);
}
.okno-etapu::backdrop { background: rgba(46, 58, 71, .45); }
.okno-etapu form { padding: 26px 28px 22px; }
.okno-etapu h2 { font-size: 19px; margin-bottom: 4px; }
.okno-etapu > form > .podpowiedz { margin: 0 0 18px; }
.okno-etapu .okno-pola { display: grid; gap: 14px; max-height: 60vh; overflow-y: auto; }
.okno-etapu .pole { margin: 0; }
.okno-etapu .etykieta { margin-bottom: 6px; }
.okno-etapu .podpowiedz { margin-top: 5px; }

/* Brakujące pole podświetlamy dopiero przy próbie zapisu – czerwone ramki od pierwszej
   sekundy w oknie, które dopiero się otworzyło, tylko denerwują. */
.okno-etapu .pole.brak input,
.okno-etapu .pole.brak select,
.okno-etapu .pole.brak textarea { border-color: var(--czerwony); }

.okno-etapu .okno-blad {
  margin-top: 14px; padding: 9px 12px; border-radius: 8px;
  background: #fee2e2; color: #b91c1c; font-size: 13.5px;
}
.okno-etapu .okno-akcje { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

/*
 * KRĄG ODBIORCÓW ZLECENIA W PULI.
 *
 * Dwie role stoją NA WIERZCHU, osoby i grupy za zwijkami – przy czterdziestu kontach
 * rozwinięta lista przykrywa całe okno i wybór roli, którym ustawia się dziewięć zleceń
 * na dziesięć, ląduje poza ekranem.
 *
 * Wewnętrzna lista ma własne przewijanie ograniczone do 190 px, a nie rośnie w nieskończoność:
 * `.okno-pola` przewija się już wyżej i dwa zagnieżdżone paski, z których zewnętrzny nagle
 * przeskakuje o pół ekranu, są gorsze niż jeden krótszy.
 */
.okno-etapu .odbiorcy {
  display: grid; gap: 6px;
  background: var(--pole); border: 1px solid var(--obwodka);
  border-radius: 10px; padding: 10px 12px;
}
.okno-etapu .odb-poz {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; cursor: pointer; padding: 3px 0; margin: 0;
}
.okno-etapu .odb-poz input { width: 16px; height: 16px; margin: 0; flex: none; accent-color: var(--pomaranczowy); }
.okno-etapu .odb-poz > span { flex: 1; }
.okno-etapu .odb-rola { font-style: normal; font-size: 11.5px; color: var(--szary); }

.okno-etapu .odb-zwijka > summary {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--grafit-jasny);
  cursor: pointer; padding: 5px 0; list-style-position: inside;
}
.okno-etapu .odb-licznik {
  background: var(--pomaranczowy); color: #fff; border-radius: 999px;
  font-size: 11px; font-weight: 700; padding: 1px 7px;
}
.okno-etapu .odb-lista {
  max-height: 190px; overflow-y: auto;
  padding: 4px 0 4px 6px; border-left: 2px solid var(--obwodka);
}

/* Karta, której na bieżącym etapie brakuje wymaganych danych. */
.kartka .braki {
  display: block; width: 100%; text-align: left; margin-top: 8px;
  background: #fee2e2; border: 1px solid #fca5a5; border-radius: 8px;
  padding: 6px 9px; font: inherit; font-size: 11.5px; color: #b91c1c; cursor: pointer;
}
.kartka .braki:hover { background: #fecaca; }
.kartka .braki b { display: block; font-size: 12px; }

/* Dane zebrane na etapie, pokazywane w podsumowaniu wyceny. */
.dane-etapu { display: grid; gap: 6px; }
.dane-etapu div { font-size: 13.5px; }
.dane-etapu span { color: var(--grafit-jasny); }

/* Ikony w przyciskach akcji – rozmiar z CSS, zeby skalowaly sie razem z przyciskiem.
   `flex: 0 0 auto` chroni je przed sciscieciem, gdy etykieta jest dluga. */
.btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
.btn-maly svg { width: 15px; height: 15px; }

/* ---------------------------------------------------------------- mapa */

/* Przelaczniki etapow sa jednoczesnie legenda mapy, wiec kolor kropki musi byc
   dokladnie ten sam, ktorym rysuje sie pinezka – oba biora go z `etapy.mjs`. */
.etapy-pasek { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 14px 18px; }
.etapy-przyciski { display: flex; gap: 8px; flex: 0 0 auto; }
.etapy-kafelki { display: flex; flex-wrap: wrap; gap: 7px; flex: 1 1 auto; }

/* Etap zgaszony zostaje na ekranie, tylko blednie – lista, z ktorej pozycje znikaja,
   przestaje byc legenda i nie da sie z niej wrocic bez szukania. */
.etap-kafelek {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px 5px 8px; border-radius: 20px; cursor: pointer;
  background: var(--pole); border: 1px solid var(--obwodka);
  font: inherit; font-size: 12.5px; font-weight: 500; color: var(--szary);
  opacity: .55; transition: opacity .12s, border-color .12s, background .12s;
}
.etap-kafelek.wl { opacity: 1; background: var(--karta); border-color: #d3dae4; color: var(--grafit); }
.etap-kafelek:hover { border-color: var(--pomaranczowy); }
.etap-kafelek .kropka { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; }
.etap-kafelek:not(.wl) .kropka { filter: grayscale(.85); }
.etap-kafelek .ile { font-weight: 700; color: var(--grafit-jasny); }
.etap-kafelek:not(.wl) .ile { color: var(--szary); }

.mapa-karta { padding: 0; overflow: hidden; }

/* Wysokosc z okna, bo mapa jest tu trescia glowna – im wiecej kraju widac naraz,
   tym mniej przewijania przy planowaniu trasy. Dolna granica pilnuje, zeby na laptopie
   z niska rozdzielczoscia nie zostal z niej pasek. */
.mapa-plansza { position: relative; height: min(72vh, 820px); min-height: 420px; }
@media (max-width: 700px) { .mapa-plansza { height: 62vh; min-height: 340px; } }

.mapa-kanwa {
  position: absolute; inset: 0; overflow: hidden;
  background: #e9e5dc;                      /* kolor ladu OSM – kafle doladowuja sie po kolei */
  cursor: grab; user-select: none;
}
.mapa-kanwa.ciagnie { cursor: grabbing; }
.mapa-kafle { position: absolute; inset: 0; overflow: hidden; }
/* `pointer-events: none` na kaflach jest konieczne: bez tego przeciaganie mapy
   zamienialoby sie w natywne przeciaganie obrazka. */
.mapa-kafle img { position: absolute; width: 256px; height: 256px; pointer-events: none; }
.mapa-warstwa { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* Klikalne sa wylacznie pinezki – reszta warstwy przepuszcza mysz do mapy pod spodem. */
.mapa-warstwa .pin { pointer-events: auto; cursor: pointer; stroke: #111827; stroke-width: 1.6; }
.mapa-warstwa .pin:hover { stroke: #fff; stroke-width: 2.4; }
.mapa-warstwa .pin-wybrany { fill: none; stroke: var(--pomaranczowy); stroke-width: 3; }

.mapa-podpis {
  position: absolute; right: 8px; bottom: 6px; z-index: 3;
  font-size: 10.5px; color: var(--grafit-jasny);
  background: rgba(255, 255, 255, .82); padding: 1px 7px; border-radius: 4px;
}
.mapa-narzedzia { position: absolute; left: 12px; top: 12px; z-index: 3; display: flex; gap: 6px; }
.mapa-narzedzia .btn { box-shadow: 0 2px 8px rgba(46, 58, 71, .18); background: var(--karta); }

/* Komunikat „nie ma czego pokazać" jest PASKIEM NAD MAPĄ, a nie mgłą na całej planszy.
   Pierwsza wersja przykrywała mapę półprzezroczystym tłem i wtedy pusty zestaw pinezek
   wyglądał identycznie jak mapa, która się nie wczytała – a to dwie zupełnie różne rzeczy
   i różnie się je naprawia. Kafle mają zostać widoczne zawsze. */
.mapa-pusto {
  position: absolute; left: 50%; top: 16px; transform: translateX(-50%); z-index: 3;
  max-width: calc(100% - 32px); padding: 9px 16px; border-radius: 999px;
  background: var(--karta); border: 1px solid var(--obwodka);
  box-shadow: 0 3px 14px rgba(46, 58, 71, .18);
  color: var(--grafit); font-size: 13.5px; text-align: center;
}
.mapa-pusto.blad { border-color: var(--czerwony); color: #b91c1c; }

/* Dymek pinezki. Pozycje ustawia skrypt – tu tylko wyglad i szerokosc, od ktorej
   zalezy dosuwanie do krawedzi planszy. */
.mapa-dymek {
  position: absolute; z-index: 4; width: 270px;
  background: var(--karta); border: 1px solid var(--obwodka); border-radius: 10px;
  padding: 13px 15px 14px; box-shadow: 0 6px 24px rgba(46, 58, 71, .22);
}
.mapa-dymek .dymek-zamknij {
  position: absolute; right: 6px; top: 4px; border: 0; background: none;
  font-size: 19px; line-height: 1; color: var(--szary); cursor: pointer; padding: 2px 6px;
}
.mapa-dymek .dymek-zamknij:hover { color: var(--grafit); }
.mapa-dymek .dymek-etap { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--grafit-jasny); }
.mapa-dymek .dymek-etap span { width: 9px; height: 9px; border-radius: 50%; }
.mapa-dymek h3 { font-size: 15px; margin: 5px 0 2px; padding-right: 14px; }
.mapa-dymek .dymek-klient { font-size: 12.5px; color: var(--grafit-jasny); }
.mapa-dymek .dymek-liczby {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--obwodka);
}
.mapa-dymek .dymek-liczby b { font-size: 15.5px; }
.mapa-dymek .dymek-liczby span { font-size: 12.5px; color: var(--grafit-jasny); margin-left: auto; }
.mapa-dymek .dymek-tagi { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; font-size: 11.5px; }
.mapa-dymek .dymek-tagi:empty { display: none; }
.mapa-dymek .dymek-tagi .tag { background: var(--pole); border-radius: 20px; padding: 2px 9px; color: var(--grafit-jasny); }
.mapa-dymek .dymek-tagi .ekipa { background: #e8edf4; color: var(--grafit); font-weight: 600; }
.mapa-dymek .dymek-tagi .przyblizona { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); }
.mapa-dymek .dymek-akcje { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }

/* Wyceny bez wspolrzednych. Nie znikaja bez sladu – z tej listy wchodzi sie prosto
   w wycene i uzupelnia adres. */
.braki-lista { display: grid; gap: 2px; margin: 6px 0 14px; }
.braki-lista .brak {
  display: flex; align-items: center; gap: 9px; padding: 7px 10px;
  border-radius: 8px; text-decoration: none; color: var(--grafit); font-size: 13.5px;
}
.braki-lista .brak:hover { background: var(--pole); }
.braki-lista .brak .kropka { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.braki-lista .brak-tytul { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.braki-lista .brak-numer { color: var(--szary); font-size: 12.5px; flex: 0 0 auto; }
.braki-stopka { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.braki-stopka .podpowiedz { margin: 0; }

/* --------------------------------------------------------- pula do obejrzenia */

/* Zlecenia, ktorych ktos jeszcze nie pobral. Pinezka jest KONTUROWA i to nie ozdoba:
   jej polozenie jest przesuniete o 150-500 m (patrz `przesunPinezke` w server/mapa.js),
   wiec musi wygladac inaczej niz pinezka trafiona w dach. Wypelnienie jest, ale prawie
   przezroczyste – bez niego klikalny bylby wylacznie sam kontur. */
.mapa-warstwa .pin-pula {
  fill: #fff; fill-opacity: .35; stroke-width: 2.4; stroke-dasharray: 3.6 2.6;
}
.mapa-warstwa .pin-pula:hover { fill-opacity: .7; stroke-width: 3; stroke-dasharray: none; }

.pula-karta h2 small { font-weight: 500; color: var(--grafit-jasny); }
.pula-kolumny { display: flex; flex-wrap: wrap; gap: 18px; }
.pula-kolumna { flex: 1 1 280px; min-width: 0; }
.pula-kolumna h3 {
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--szary); margin: 4px 0 6px;
}
.pula-lista { display: grid; gap: 3px; }
.pula-wiersz {
  display: flex; align-items: center; gap: 9px; padding: 6px 10px;
  border-radius: 8px; font-size: 13.5px; background: var(--pole);
}
/* Dzien przed powrotem do puli – tylko gdy administrator wlaczyl `picker_alert`. */
.pula-wiersz.pilne { background: var(--pomaranczowy-tlo); box-shadow: inset 0 0 0 1px #ffd9bd; }
.pula-tytul {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--grafit); text-decoration: none; font-weight: 500;
}
a.pula-tytul:hover { text-decoration: underline; }
.pula-info { color: var(--szary); font-size: 12.5px; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pula-wiersz .btn { flex: 0 0 auto; }

.mapa-dymek .dymek-tagi .pula-wraca { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); font-weight: 600; }
/* Powod, dla ktorego przycisk „Pobierz" jest wygaszony. Pelniejsza tresc mowi serwer. */
.pula-blokada {
  margin-top: 10px; padding: 7px 10px; border-radius: 8px;
  background: #fee2e2; color: #b91c1c; font-size: 12.5px; font-weight: 500;
}
.pula-karta .podpowiedz { margin: 12px 0 0; }

/* ------------------------------------------------- dziennik surowych pol */
/* Narzedzie kontroli, nie czesc codziennego ekranu: wygaszone, zwiniete, monospace.
   Tabela scrolluje we wlasnym pudle – lista pol karty klienta ma setki wierszy. */
.dziennik-pol { margin-top: 14px; font-size: 12.5px; color: var(--szary); }
.dziennik-pol > summary { cursor: pointer; user-select: none; padding: 6px 2px; }
.dziennik-pol > summary::-webkit-details-marker { display: none; }
.dziennik-pol > summary::before { content: '▸ '; color: var(--pomaranczowy); }
.dziennik-pol[open] > summary::before { content: '▾ '; }
.dziennik-pol > summary:hover { color: var(--grafit); }
.dziennik-pol > table {
  display: block; max-height: 420px; overflow: auto; margin-top: 6px;
  border: 1px solid #e5e7eb; border-radius: 9px; background: #fafbfd;
  font-family: ui-monospace, Consolas, monospace; font-size: 12px;
  border-collapse: collapse; width: 100%;
}
.dziennik-pol td {
  padding: 3px 10px; border-bottom: 1px solid #eef0f4; vertical-align: top;
  word-break: break-word;
}
.dziennik-pol td:first-child { color: var(--grafit); white-space: nowrap; padding-right: 18px; }
.dziennik-pol td:last-child { width: 100%; }
.dziennik-pol i { color: #b6bcc6; font-style: normal; }
.dziennik-data { color: #9aa1ab; }

/* --------------------------------------------------------------- notatki */

/* Notatki wyjete z osi czasu i postawione pod polem, w ktorym sie je dopisuje.
   Te same wpisy sa nadal w aktywnosci – to ten sam dziennik pokazany dwa razy,
   a nie druga kopia danych. Tutaj chodzi o czytelnosc: przed telefonem do klienta
   czyta sie ustalenia z ostatniej rozmowy, a nie liste otwarc oferty. */
/* KARTECZKI, A NIE WIERSZE LISTY. Notatka jest jedyna trescia w tym panelu, ktora ktos
   napisal RECZNIE, bo uznal, ze trzeba ja zapamietac – cala reszta to wpisy generowane
   przez system. Zolta karteczka mowi tu dokladnie to, co mowi na biurku: przyklejone,
   bo wazne. Historia pod spodem zostaje szarym dziennikiem i to jest polowa tej decyzji:
   gdyby i ona byla w karteczkach, kolor przestalby cokolwiek znaczyc. */
.notatki { display: grid; gap: 14px; margin-top: 14px; }
.notatki:empty { display: none; }
.notatki .notatka {
  position: relative; padding: 11px 14px 13px; border-radius: 2px;
  background: linear-gradient(163deg, #fff6a8 0%, #ffe969 100%);
  /* Cien jest krotki i ciepły — karteczka ma lezec na panelu, a nie unosic sie nad nim. */
  box-shadow: 0 1px 1px rgba(96, 74, 8, .22), 0 9px 16px -11px rgba(96, 74, 8, .6);
  color: var(--grafit);
}
/* Przechyl na przemian, ulamek stopnia. Tyle wystarczy, zeby stos czytal sie jak kartki
   przyklejone jedna po drugiej; wiecej zaczyna wygladac na blad ukladu. */
.notatki .notatka:nth-child(odd) { transform: rotate(-.45deg); }
.notatki .notatka:nth-child(even) { transform: rotate(.5deg); }
/* Zagiety rog: dwa jasniejsze trojkaty z cieniem rzuconym do srodka kartki. */
.notatki .notatka::after {
  content: ''; position: absolute; right: 0; bottom: 0; width: 0; height: 0;
  border: 9px solid transparent;
  border-right-color: #fdf6c9; border-bottom-color: #fdf6c9;
  filter: drop-shadow(-1px -1px 1px rgba(96, 74, 8, .25));
}
.notatki .notatka-glowka {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 11.5px; color: #6f6222; margin-bottom: 3px;
}
/* Podpis i data na zoltym: wlasne, cieple kolory. Szarosci z reszty panelu sa na tym tle
   za jasne – 11,5 px daty przestawaloby byc czytelne przy pierwszym gorszym ekranie. */
.notatki .notatka-glowka .kto { font-weight: 700; color: #4a4014; }
.notatki .notatka-glowka .gdy { color: #6f6222; }
.notatki .notatka-glowka .przy-wycenie {
  margin-left: auto; font-size: 11.5px; color: #6f6222; text-decoration: none;
}
.notatki .notatka-glowka .przy-wycenie:hover { color: var(--pomaranczowy-ciemny); }
/* `pre-wrap` jest tu konieczne: notatka z rozmowy bywa listą ustaleń w kilku linijkach,
   a bez tego skleiłaby się w jeden akapit i przestała być listą. */
.notatki .tresc { font-size: 13.5px; color: #3b3418; white-space: pre-wrap; }

/* Nagłówek osi czasu pod notatkami – bez niego dwie listy zlewają się w jedną. */
.naglowek-osi {
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--szary); margin: 18px 0 8px;
}

/* ----------------------------------------------------------------- leady */

/* Stale listy po kanalach. Kolor kropki to kolor kanalu z `leady.mjs` – jedno zrodlo,
   wiec kafelek nie zacznie znaczyc czegos innego niz znacznik przy zgloszeniu. */
.listy-pasek { padding: 14px 18px; }
.listy { display: flex; flex-wrap: wrap; gap: 7px; }
.lista-kafelek {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px 6px 10px; border-radius: 20px; cursor: pointer;
  background: var(--pole); border: 1px solid var(--obwodka);
  font: inherit; font-size: 13px; font-weight: 500; color: var(--grafit-jasny);
}
.lista-kafelek:hover { border-color: var(--pomaranczowy); }
.lista-kafelek.wl { background: var(--grafit); border-color: var(--grafit); color: #fff; }
.lista-kafelek .kropka { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.lista-kafelek .ile {
  background: var(--pomaranczowy); color: #fff; font-weight: 700; font-size: 11.5px;
  border-radius: 20px; padding: 0 7px; min-width: 20px; text-align: center;
}
/* „Bez opiekuna" z niezerowym licznikiem to awaria rotacji, nie zwykla lista –
   cicha kolejka do nikogo jest najgorszym mozliwym wariantem. */
.lista-kafelek.ostrzega .ile { background: var(--czerwony); }
.lista-kafelek.ostrzega { border-color: var(--czerwony); color: var(--czerwony); }
.lista-kafelek.ostrzega.wl { background: var(--czerwony); border-color: var(--czerwony); color: #fff; }

/* Wiersz leada ma 5 komorek, nie 6 jak wycena – bez wlasnej siatki opiekun
   i przyciski wpadaja w kolumny po 150 px, a ostatnia (`auto`) stoi pusta. */
.lista-leadow .wiersz {
  align-items: center; cursor: default;
  grid-template-columns: 84px minmax(0, 1fr) 130px 190px auto;
}
.lista-leadow .kropka-kanalu { display: block; width: 14px; height: 14px; border-radius: 50%; margin: 0 auto; }

/* Tagi z tlem to plakietki jak na tablicy – samo tlo bez paddingu przykleja
   kolor do tekstu i wyglada jak blad renderowania. */
/* `.kanal` to tez blok kanalu wysylki (ramka, padding 14/16, margines) – tutaj
   te wlasnosci trzeba wyzerowac, inaczej tag kanalu puchnie do rozmiaru kafla. */
.lista-leadow .w-tagi .kanal { border: 0; margin: 0; }
.lista-leadow .w-tagi .kanal,
.lista-leadow .w-tagi .stan-w-kontakcie,
.lista-leadow .w-tagi .stan-przekazane,
.lista-leadow .w-tagi .stan-odrzucone,
.lista-leadow .w-tagi .czekanie { border-radius: 20px; padding: 2px 9px; }

.lista-leadow .w-tagi .kanal { background: var(--kolor); color: #fff; font-weight: 600; }
.lista-leadow .w-tagi .stan-w-kontakcie { background: #e8edf4; color: var(--grafit); font-weight: 600; }
.lista-leadow .w-tagi .stan-przekazane { background: #dcfce7; color: #15803d; font-weight: 600; }
.lista-leadow .w-tagi .stan-odrzucone { background: #fee2e2; color: #b91c1c; font-weight: 600; }

/* Czekanie jest jedynym sygnalem pilnosci, dopoki system nie umie wyslac SMS-a. */
.lista-leadow .czekanie.swieze { background: #dcfce7; color: #15803d; font-weight: 600; }
.lista-leadow .czekanie.stygnie { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy-ciemny); font-weight: 600; }
.lista-leadow .czekanie.zimne { background: #fee2e2; color: #b91c1c; font-weight: 700; }

.lista-leadow .w-wiadomosc {
  font-size: 13px; color: var(--grafit-jasny); margin-top: 6px;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.lista-leadow .w-wiadomosc.odrzucone { color: #b91c1c; }
.lista-leadow .w-opiekun select { font-size: 13px; padding: 7px 9px; }
.lista-leadow .w-akcje { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
@media (max-width: 900px) {
  /* Wlasna siatka wiersza wygrywa specyficznoscia z mobilna regula `.wiersz`,
     wiec waska wersje trzeba tu powtorzyc. Opiekun idzie pod tresc, nie pod kropke. */
  .lista-leadow .wiersz { grid-template-columns: 60px minmax(0, 1fr); }
  .lista-leadow .w-opiekun { grid-column: 2; }
  .lista-leadow .w-akcje { justify-content: flex-start; }
}

/* ------------------------------------------------- oswiadczenie pomiarowca */

/* Pokazuje sie wylacznie przy pomiarze z natury. Ma wygladac jak rzecz, ktora sie CZYTA,
   a nie jak kolejne pole do odklikania – stad wyrozniona ramka i pelna szerokosc. */
.oswiadczenie {
  margin-top: 14px; padding: 13px 15px;
  background: var(--pomaranczowy-tlo); border: 1px solid #ffd9bd; border-radius: 10px;
}
.oswiadczenie.brak-zgody { border-color: var(--pomaranczowy); }

/* Pytanie WYMAGANE, na ktore nikt nie odpowiedzial – zaznaczane dopiero przy probie
   zapisu, a nie od otwarcia formularza: nowa wycena ma wygladac na pusta, a nie na bledna.
   Ramka obejmuje CALA grupe przyciskow, bo brakuje wyboru, a nie konkretnego przycisku. */
[data-opcje].brak-wyboru {
  outline: 2px solid var(--pomaranczowy);
  outline-offset: 4px;
  border-radius: 10px;
}
.oswiadczenie label { display: flex; gap: 11px; align-items: flex-start; cursor: pointer; }
/* Domyslny checkbox ma 13 px i przy szescioliniowym tekscie ginie. Powiekszamy go
   i odsuwamy od pierwszej linijki, zeby stal rowno z jej srodkiem. */
.oswiadczenie input[type='checkbox'] {
  flex: 0 0 auto; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--pomaranczowy);
}
.oswiadczenie span { font-size: 13px; line-height: 1.55; color: var(--grafit); }
.oswiadczenie .wym { color: var(--pomaranczowy); }

/* Podpis wypelniony przez system – nie da sie go edytowac, wiec nie udaje pola. */
.podpis-pomiaru {
  margin-top: 10px; padding-top: 9px; border-top: 1px solid #ffd9bd;
  font-size: 12.5px; font-weight: 600; color: var(--pomaranczowy-ciemny);
}

/* ------------------------------------------------------------- kolory RAL

   KROPKA OBOK NUMERU, NIGDY ZAMIAST NIEGO. „8004" i „8017" to dla oka dwa rownie
   bezbarwne napisy, a na dachu ceglasty i czekoladowy — kropka zamienia liste w cos,
   co da sie przejrzec wzrokiem. Wartosci sa PRZYBLIZONE (karta RAL jest definiowana
   pigmentem, nie sRGB), wiec kropka pomaga rozpoznac, a nie rozstrzygnac.

   OBWODKA JEST OD SRODKA (`inset`), zeby jasne kolory — 9010, 1013 — nie znikaly
   na bialym tle, a ciemne nie dostawaly ramki, ktorej nie potrzebuja. */
.kropka-ral {
  display: inline-block; width: 28px; height: 28px; flex: 0 0 28px;
  margin-right: 18px;
  border-radius: 50%; background: var(--kolor, #C9CCCF);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18);
  vertical-align: -8px;
}
/* Numer spoza karty RAL Classic – kropka ma MOWIC, ze to nie jest odczyt koloru,
   tylko brak odpowiedzi. Przekreslenie zamiast wymyslonej barwy. */
.kropka-ral.nieznany {
  background:
    linear-gradient(45deg, transparent 44%, var(--czerwony) 44%, var(--czerwony) 56%, transparent 56%),
    var(--kolor, #C9CCCF);
}

.wybor-koloru { display: flex; align-items: center; gap: 10px; }
.wybor-koloru select { flex: 1 1 auto; min-width: 0; }

/* Zlecenie zmienilo sie PO zalozeniu wydawki (MAGAZYN.md 4.1). Znacznik jest PRZYCISKIEM,
   bo jego sens polega na tym, ze ktos go przeczytal i zdjal — automat gaszacy go przy
   odswiezeniu robilby z niego migajaca ozdobe, ktora po tygodniu przestaje byc widziana. */
.wydawka-nieaktualna {
  border: 1px solid var(--pomaranczowy); background: var(--pomaranczowy-tlo);
  color: var(--pomaranczowy); border-radius: 999px;
  padding: 3px 11px; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.wydawka-nieaktualna:hover { background: var(--pomaranczowy); color: #fff; }

/* Kolory sprzedane, ktorych mieszalnia nie umie jeszcze zrobic. Osobny blok pod lista
   serii, bo to zadanie o innym rytmie: serie robi sie dzis, recepture ustala sie raz. */
.brak-receptur { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--obwodka); }
.brak-receptur-glowa { font-size: 12.5px; font-weight: 700; color: var(--czerwony); margin-bottom: 6px; }
.brak-receptur .do-zrobienia-znak { color: var(--czerwony); font-weight: 700; }

/* Ten sam znacznik po stronie ekipy jest KOMUNIKATEM, a nie przyciskiem: zdjac go moze
   magazyn, bo to on ma palete. Ekipa ma go przeczytac i zadzwonic. */
.wydawka-nieaktualna.nieklikalna { cursor: default; text-align: left; border-radius: 10px; }
.wydawka-nieaktualna.nieklikalna:hover { background: var(--pomaranczowy-tlo); color: var(--pomaranczowy); }

/* Podpis nad grupa kart magazynu. Bazy stoja w zbiornikach, podklady w wiadrach,
   gotowy RAL w wiadrach — to sa trzy rozne pytania i maja byc rozdzielone wzrokiem,
   a nie samym opisem w naglowku sekcji. */
.polka-nazwa {
  margin: 16px 0 8px; font-size: 12.5px; font-weight: 700;
  color: var(--grafit-jasny); letter-spacing: .03em; text-transform: uppercase;
}
.polka-nazwa:first-of-type { margin-top: 0; }
/* Jednostka stoi PRZY NAGLOWKU POLKI, a nie przy kazdej liczbie. Liczba wiodaca na kafelku
   jest goła — „40", nie „40 wiader" — bo przy dwudziestu pozycjach to samo slowo powtorzone
   dwadziescia razy przestaje cokolwiek znaczyc, a odroznic trzeba je tylko od kilogramow
   pod spodem. Raz, u gory, wystarczy. */
.polka-jednostka {
  margin-left: 8px; font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--szary);
}
/* Kropka w naglowku karty magazynu jest MNIEJSZA niz w listach: tam stoi obok tekstu
   ciaglego, tu nad liczba, wiec 28 px rozpychaloby karte na dwie linijki. */
.zbiornik-nazwa .kropka-ral { width: 14px; height: 14px; flex-basis: 14px; margin-right: 7px; vertical-align: -2px; }

/* ------------------------------------------------------- etap 7: DPM i materialy

   „tylko beton" przy DPM — to nie jest ostrzezenie o bledzie, tylko wlasciwosc materialu,
   ktora kierownik musi miec przed oczami, patrzac na resztke na stanie. Stad znacznik,
   a nie alert: farby z DPM wolno uzyc, tylko nie wszedzie. */
.znacznik-dpm {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  background: var(--pomaranczowy-tlo); color: var(--pomaranczowy);
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
}

/* Wiersz materialu, ktorego brakuje. Kolor niesie CALA informacje, wiec liczba obok
   nie musi krzyczec — inaczej tabela z pietnastoma pozycjami swieci sie cala. */
.tabela tr.brakuje td { background: var(--pomaranczowy-tlo); }
.tabela tr.brakuje b { color: var(--pomaranczowy); }

/* „Ktora receptura" w sekcji materialowej rozliczenia. Drobnym drukiem i pod nazwa
   materialu, bo to nie jest liczba do rozliczenia, tylko slad na pol roku pozniej —
   przy reklamacji. Widzi to wylacznie zgoda `magazyn:sledzenie`. */
.mat-receptura {
  font-size: 11.5px; color: var(--grafit-jasny); cursor: help;
  border-bottom: 1px dotted var(--obwodka);
}

/* ------------------------------------------------------------ alerty (§58, §60)

   WAGA NIESIE KOLOR I STOI PIERWSZA. Alert czyta sie z rozpedu, wiec pierwsze, co ma
   trafic w oko, to „czy to na teraz". Nazwa i opis sa dopiero drugie — bez wagi trzeba
   przeczytac cala liste, zeby dowiedziec sie, co jest pilne. */
.alert {
  display: grid; grid-template-columns: 84px 1fr auto auto auto; gap: 10px;
  align-items: center; padding: 10px 12px; margin-bottom: 8px;
  background: var(--pole); border-radius: 10px; font-size: 14px;
}
.alert-waga {
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.alert-nazwa { font-weight: 600; }
.alert-opis { font-size: 13px; color: var(--grafit-jasny); }
.alert .podpowiedz { margin-top: 2px; }
.alert .btn { padding: 4px 12px; font-size: 12.5px; }

.alert.waga-pilne { background: #fef2f2; }
.alert.waga-pilne .alert-waga { color: var(--czerwony); }
.alert.waga-uwaga { background: var(--pomaranczowy-tlo); }
.alert.waga-uwaga .alert-waga { color: var(--pomaranczowy); }
.alert.waga-info .alert-waga { color: var(--grafit-jasny); }

/* Rozstrzygniety alert zostaje CZYTELNY, tylko przygaszony: „widzialem" nie znaczy
   „nieistotne", a wyszarzenie do niewidocznosci kasowaloby powod, dla ktorego zostaje. */
.alert.rozstrzygniety { opacity: .62; }

@media (max-width: 760px) {
  .alert { grid-template-columns: 1fr auto; }
  .alert-tresc { grid-column: 1 / -1; }
}

/* Kierunek zmiany. SPADEK BYWA DOBRY (zwroty) albo zly (wydajnosc) — o tym decyduje
   wolajacy, a nie znak liczby, dlatego kolor idzie z klasy, a nie z wartosci. */
.kierunek { font-size: 12.5px; font-weight: 700; }
.kierunek.dobrze { color: var(--zielony); }
.kierunek.zle { color: var(--czerwony); }

/* ----------------------------------------------- kafelki liczb nad lista

   Cztery liczby otwierajace liste wycen: ile ich w ogole, ile wyslanych, ile otwartych
   przez klienta, ile zgloszonych przegladow.

   Klasa, a nie `style=""` w HTML – i to jest jedyny powod, dla ktorego ten blok istnieje.
   Siatka stala wczesniej wpisana w atrybut jako `repeat(4, 1fr)`, czyli w miejscu,
   w ktore ZADEN `@media` nie siega: na telefonie kazda z czterech kolumn miala 70 px,
   napis „Otwarte przez klienta" lamal sie na cztery linijki, a liczba pod nim byla
   wyzsza niz szeroka jej kolumna.

   `auto-fit` zamiast progow: przy 375 px wchodza dwie kolumny, przy 700 px cztery,
   i nie trzeba tego nigdzie zapisywac.                                                */

.statystyki {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px 20px; padding: 20px 22px;
}
.statystyki-etykieta { font-size: 13px; color: var(--szary); }
.statystyki-liczba { font-size: 28px; font-weight: 700; line-height: 1.15; }
.statystyki-liczba.wyroznik { color: var(--pomaranczowy); }
/* Prog dobrany tak, zeby DWIE kolumny zostaly takze na 320 px – najwezszym ekranie,
   jaki jeszcze chodzi po firmie. Cztery liczby jedna pod druga to pol ekranu zajete
   przez naglowek listy, zanim widac pierwsza wycene. */
@media (max-width: 560px) {
  .statystyki { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 12px 14px; padding: 16px 15px; }
  .statystyki-etykieta { font-size: 12px; }
  .statystyki-liczba { font-size: 23px; }
}

/* ==================================================================== TELEFON

   GESTOSC I CZYTELNOSC NA WASKIM EKRANIE.

   Reguly przypisane do jednego skladnika stoja przy nim (pasek i szuflada, wiersz listy,
   tablica, kafle, tabela wykonania) – tutaj jest to, co nalezy do CALEJ strony i nie ma
   jednego wlasciciela: ramka strony, karta, naglowki, okna modalne.

   PROBLEM, KTORY TO ROZWIAZUJE, jest jeden i wszedzie ten sam: uklad byl rysowany na
   monitorze, wiec odstepy sa w nim liczone w dziesiatkach pikseli. Na 1500 px to oddech,
   na 375 px to jedna trzecia szerokosci ekranu zjedzona przez marginesy, zanim padnie
   pierwsza litera tresci. Nic tu nie znika – zmienia sie wylacznie to, ile miejsca
   zabiera rama wokol tresci.

   PROGI. 900 px to ten sam prog co szuflada: „to juz nie jest myszka". 560 px to telefon
   trzymany pionowo, na ktorym trzeba dodatkowo zejsc ze stopni pisma w naglowkach.       */

@media (max-width: 900px) {
  /* 24 -> 14 px z kazdej strony. Same marginesy strony i karty zabieraly 108 px z 375,
     czyli 29% ekranu; teraz 58 px. */
  .strona { padding: 16px 14px; }
  .karta { padding: 18px 15px; margin-bottom: 14px; }
  .karta > h2 { font-size: 21px; padding-bottom: 12px; margin-bottom: 15px; }
  .karta > h2 > .ikona-sekcji { width: 22px; height: 22px; margin-right: 9px; vertical-align: -4px; }
  .podsumowanie .karta { padding: 16px 14px; }

  /* Pola formularza sa juz na 16 px przez `--pole-pismo` (patrz `:root`). Te trzy grupy
     maja wlasne, mniejsze pismo z reguly klasowej, ktora bije zmienna – a to wlasnie
     w nie klika sie na telefonie najczesciej: filtr nad lista i wybor ekipy w magazynie. */
  .filtry select, .filtry input, .filtry-magazynu select { font-size: var(--pole-pismo); }

  /* Naglowki stron. 30 px w jednej linii na monitorze to na telefonie trzy linie,
     po ktorych tresc zaczyna sie ponizej krawedzi ekranu. */
  .naglowek-wyceny h1 { font-size: 22px; }
  .klient-naglowek h1 { font-size: 20px; }

  /* Przyciski akcji pod naglowkiem klika sie palcem – 35 px wysokosci `btn-maly`
     to trafienie za drugim razem. */
  .pw-akcje .btn, .okno-akcje .btn, .okno-etapu .okno-akcje .btn { min-height: 40px; }

  /*
   * OKNA MODALNE. Zaslona miala 20 px z kazdej strony, samo okno 28 px – razem 96 px
   * ramy na 375 px ekranu, wiec na tresc zostawalo mniej niz na marginesy wokol niej.
   * Wysokosc idzie do 92vh, bo okno wysylki oferty ma w srodku podglad wiadomosci
   * i przy 88vh przewijalo sie dwa razy: raz w srodku, raz calym oknem.
   */
  .zaslona { padding: 14px 10px; align-items: flex-start; }
  .okno { padding: 18px 15px; max-height: 92vh; }
  .okno > h2 { font-size: 18px; margin-bottom: 14px; }
  .okno-etapu form { padding: 18px 16px 16px; }
  .okno-etapu .okno-pola { max-height: 62vh; }

  /* Przyciski okna dziela szerokosc po rowno. Kolejnosci NIE ruszamy: czynnosc glowna
     stoi w HTML jako ostatnia, czyli po prawej – a to jest rog, do ktorego siega kciuk. */
  .okno-akcje > .btn, .okno-etapu .okno-akcje > .btn { flex: 1 1 auto; }

  /* Kanal wysylki: 16 px ramki na 345 px karty to za duzo, gdy w srodku jest tresc maila. */
  .kanal { padding: 11px 12px; }
  .kanal-tresc { padding: 10px 11px; }
}

@media (max-width: 560px) {
  /* Ostatni stopien: naglowek karty przestaje konkurowac z trescia, ktora opisuje. */
  .karta > h2 { font-size: 19px; }
  .karta > h2 small { font-size: 12.5px; }
  /* Dwie kolumny zamiast czterech – patrz `.statystyki`. */
  .strona { padding: 14px 12px; }
}
