:root {
  --bg: #f7f7f8; --card: #fff; --text: #1a1a1a; --muted: #6b6b6b; --border: #e3e3e6;
  --accent: #2563eb; --accent-fg: #fff; --danger: #dc2626; --ok: #16a34a;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
a { color: var(--accent); text-decoration: none; }

/* ---------------------------------------------------------------- układ
   Menu stoi w kolumnie po lewej, treść wypełnia resztę ekranu.
   Kolumna nie przewija się razem z treścią (position: sticky), więc przy
   długiej liście sprzętu menu zostaje pod ręką. */
.applayout { display: flex; align-items: flex-start; min-height: 100vh; }

.sidebar {
  width: 232px; flex: none; align-self: stretch;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  background: var(--card); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; padding: 16px 12px;
}
/* min-width: 0 jest konieczne, żeby szerokie tabele przewijały się w swoim
   kontenerze, a nie rozpychały całej strony w bok. */
.appmain { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.brand { display: flex; align-items: center; gap: 10px; padding: 4px 8px 14px;
         font-weight: 700; font-size: 15px; color: var(--text); line-height: 1.25; }
.brand-logo { max-width: 130px; max-height: 44px; object-fit: contain; display: block; }
.brand-ico { font-size: 20px; }
/* Z logo układamy pionowo: znak firmy u góry, drobna nazwa programu pod nim.
   Przy samym logo nie byłoby widać, w czym się w ogóle jest, a przy wąskim
   logotypie nazwa obok rozpychałaby kolumnę. */
.brand.z-logo { flex-direction: column; align-items: flex-start; gap: 6px; padding-bottom: 12px; }
.brand.z-logo .brand-text { font-size: 11px; font-weight: 700; letter-spacing: .04em;
                            text-transform: uppercase; color: var(--muted); }

.sidenav { display: flex; flex-direction: column; gap: 1px; }
/* Nagłówek sekcji w menu. Ciemny i ciężki, bo przy szarym i cienkim cała kolumna
   czytała się jak jedna długa lista linków. Linia nad grupą robi właściwy
   podział - samo pogrubienie bez niej nie wystarcza. Pierwsza grupa linii nie
   dostaje: nie ma czego od czego oddzielać, a kreska pod logo wyglądałaby jak
   błąd. */
.navgroup { font-size: 11.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
            color: var(--text); padding: 16px 8px 6px;
            border-top: 1px solid var(--border); margin-top: 10px; }
.sidenav .navgroup:first-child { border-top: 0; margin-top: 0; padding-top: 4px; }
.navlink { display: block; padding: 8px 10px; border-radius: 8px; font-size: 14px;
           font-weight: 600; color: var(--muted); }
.navlink:hover { background: var(--bg); color: var(--text); }
.navlink.active { background: var(--accent); color: var(--accent-fg); }

.sidefoot { margin-top: auto; padding-top: 16px; border-top: 1px solid var(--border);
            display: flex; flex-direction: column; gap: 8px; }
.whoami { display: block; padding: 8px 10px; border-radius: 8px; color: var(--text); line-height: 1.3; }
.whoami:hover { background: var(--bg); }
.whoami.active { background: var(--bg); }
.whoami b { display: block; font-size: 13px; }
.whoami span { font-size: 11px; color: var(--muted); }
.sidefoot-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 10px 4px; }
.wyloguj { font-size: 13px; font-weight: 600; color: var(--muted); }

/* Pasek z przyciskiem menu - tylko na wąskich ekranach */
.navbar { display: none; position: sticky; top: 0; z-index: 40; align-items: center; gap: 12px;
          background: var(--card); border-bottom: 1px solid var(--border); padding: 8px 12px; }
.navtoggle { background: transparent; color: var(--text); border: 1px solid var(--border);
             padding: 7px 12px; font-size: 14px; }
.navtoggle-ico { font-size: 15px; }
.navbar-title { font-weight: 700; font-size: 15px; }
.navbackdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 55; }

/* Przełącznik języka w pasku górnym */
.langswitch { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.langswitch a { padding: 3px 8px; font-size: 12px; font-weight: 700; color: var(--muted); letter-spacing: .3px; }
.langswitch a + a { border-left: 1px solid var(--border); }
.langswitch a.active { background: var(--accent); color: var(--accent-fg); }

/* Przełącznik magazynu. Pokazuje się tylko wtedy, gdy człowiek ma więcej niż
   jeden magazyn do wyboru - przy jednym nie ma czego przełączać. */
.locswitch { display: flex; align-items: center; gap: 6px; padding: 0 10px; }
.locswitch label { font-size: 11px; font-weight: 700; color: var(--muted);
                   text-transform: uppercase; letter-spacing: .4px; margin: 0; }
.locswitch select { flex: 1; min-width: 0; padding: 5px 7px; font-size: 13px; font-weight: 600; }

/* Nazwa magazynu w górnym pasku: na telefonie kolumna jest schowana, a to,
   z którego magazynu się wydaje, musi być widoczne bez otwierania menu. */
.navbar-loc { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--muted);
              white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }

/* Odznaka magazynu przy stanie i przy przyciskach wydania. */
.locbadge { display: inline-block; padding: 2px 7px; border: 1px solid var(--border);
            border-radius: 999px; font-size: 11px; font-weight: 700; color: var(--muted);
            white-space: nowrap; }

/* Rozbicie stanu na magazyny - wąska tabelka na karcie sprzętu. */
.loctable { width: auto; min-width: 0; max-width: 100%; }
.loctable td.liczba { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.loctable tr.tutaj td { background: var(--bg); }
/* Kolumna magazynu, w którym teraz pracujesz (lista sprzętu, 9.45). Delikatne
   tło, bo to podpowiedź „stąd wydajesz", a nie ostrzeżenie. */
table th.tutaj, table td.tutaj { background: var(--bg); font-weight: 600; }
.loctable tr.obcy td.liczba { color: var(--muted); }

/* Skróty języków przy protokole - podgląd dokumentu w innym języku */
.langswitch.doclang { vertical-align: middle; margin-left: 6px; }
.langswitch.doclang a { padding: 4px 7px; font-size: 11px; }
.container { max-width: 1600px; width: 100%; margin: 0 auto; padding: 22px 22px 50px; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 16px; margin-bottom: 18px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; align-items: flex-end; }
input, select { padding: 9px 11px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 14px; max-width: 100%; }
label { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
button, .btn { padding: 9px 16px; border-radius: 8px; border: none; background: var(--accent); color: var(--accent-fg); font-weight: 600; cursor: pointer; font-size: 14px; display: inline-block; }
button.secondary, .btn.secondary { background: transparent; color: var(--muted); border: 1px solid var(--border); }
button.danger, .btn.danger { background: var(--danger); color: var(--accent-fg); border: none; }
button.ok { background: var(--ok); }
button:disabled, button[disabled] { opacity: .45; cursor: not-allowed; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; }
.tablewrap { overflow-x: auto; }
.thumb { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; background: var(--border); display: block; }
/* vertical-align: middle jest konieczne: bez niego dwuwierszowa etykieta
   („Może uzupełnić") ustawia się linią bazową ostatniego wiersza i nachodzi
   na wiersz tabeli powyżej. */
.badge { padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600;
         display: inline-block; vertical-align: middle; line-height: 1.45; }
.badge.upcoming { background: #dbeafe; color: #1d4ed8; }
.badge.active { background: #dcfce7; color: #15803d; }
.badge.done { background: #f1f5f9; color: #64748b; }
.badge.free { background: #e0e7ff; color: #4338ca; }
.badge.reserved { background: #fef9c3; color: #854d0e; }
.badge.issued { background: #fef3c7; color: #b45309; }
.badge.returned { background: #dcfce7; color: #15803d; }
.badge.sprawny { background: #dcfce7; color: #15803d; }
.badge.uszkodzony { background: #fee2e2; color: #b91c1c; }
.badge.w_serwisie { background: #fef3c7; color: #b45309; }
h1 { font-size: 20px; } h2 { font-size: 17px; }
.muted { color: var(--muted); font-size: 13px; }
/* Przycisk, który ma wyglądać jak odnośnik. Potrzebny tam, gdzie akcja musi iść
   POST-em (bo coś zmienia), ale w tekście czyta się jak zwykły link. */
.linkbtn { background: none; border: 0; padding: 0; margin: 0; font: inherit;
           color: var(--accent); text-decoration: underline; cursor: pointer; }
.linkbtn:hover { opacity: .8; }
.error { color: var(--danger); font-size: 13px; margin: 6px 0; }
.notice { color: var(--ok); font-size: 13px; margin: 6px 0; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 640px) { .grid2 { grid-template-columns: 1fr; } }
.login-wrap { max-width: 360px; margin: 80px auto; padding: 0 16px; }
.inline-form { display: inline; }

/* Na wąskich ekranach pola formularzy układają się jeden pod drugim,
   żeby długie nazwy na liście sprzętu nie rozpychały strony w bok. */
@media (max-width: 640px) {
  .row { flex-direction: column; align-items: stretch; }
  .row > label { width: 100%; }
  .row label > input, .row label > select, .row > input, .row > select { width: 100%; max-width: 100%; }
  .modal { padding: 16px; }
}

/* Same przyciski nie muszą zajmować całej szerokości - filtry kategorii
   układają się wtedy jeden pod drugim i zjadają pół ekranu telefonu.
   Niech się zawijają w linii, jak zwykłe pigułki. */
@media (max-width: 640px) {
  .row.buttons, .row:has(> .btn) { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .row:has(> .btn) > label { width: auto; }
}
label { min-width: 0; max-width: 100%; }

/* Okno modalne (wydanie / zwrot sprzętu) */
.overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 50;
           padding: 24px 12px; overflow-y: auto; }
.overlay.open { display: flex; align-items: flex-start; justify-content: center; }
.modal { background: var(--card); border: 1px solid var(--border); border-radius: 14px;
         padding: 20px; width: 100%; max-width: 720px; margin: auto; }
.modal.wide { max-width: 900px; }
.modal h2 { margin-top: 0; }
.modal input[type="checkbox"] { transform: scale(1.2); }

/* Nagłówek bloku w formularzu - oddziela grupy pól (Firma / Osoba kontaktowa).
   Cieńszy od h2, z linią nad sobą, żeby było widać, gdzie kończy się jedna grupa. */
.blocktitle { font-size: 13px; font-weight: 600; text-transform: uppercase;
              letter-spacing: .04em; color: var(--muted);
              margin: 18px 0 10px; padding-top: 14px; border-top: 1px solid var(--border); }
.blocktitle:first-of-type { margin-top: 4px; padding-top: 0; border-top: 0; }

/* Oś czasu eventu w formularzu: siedem momentów obok siebie.
   Kolumny liczą się od szerokości SWOJEGO miejsca (auto-fit), a nie od
   szerokości okna. To nie jest drobiazg: oś stoi raz w modalu na całą stronę,
   a raz w kolumnie treści obok menu - przy regule opartej na oknie laptop
   z menu dostawał siedem kolumn w za wąskim miejscu i cała strona przewijała
   się w bok. 140 px to najwęższa kolumna, w której data i godzina jeszcze się
   mieszczą. */
.timeline-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
                 gap: 10px; margin: 12px 0 8px; }
/* Moment nieobowiązkowy: ta sama kolumna, tylko mniej krzyczy. */
.tl-col.tl-opcja { border-style: dashed; }
.tl-col.tl-opcja .timeline-num { background: var(--muted); }
.tl-col { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--border);
          border-radius: 10px; padding: 10px; background: var(--bg); position: relative; }
.tl-col.locked { opacity: .5; }
.tl-col-head { display: flex; align-items: center; gap: 7px; }
.tl-col-title { font-size: 13px; font-weight: 600; line-height: 1.2; }
.tl-col-hint { font-size: 11px; color: var(--muted); }
.tl-col input, .tl-col select { width: 100%; max-width: 100%; padding: 6px 8px; font-size: 13px; }
.timeline-num { display: inline-flex; align-items: center; justify-content: center;
                width: 20px; height: 20px; border-radius: 50%; background: var(--accent);
                color: var(--accent-fg); font-size: 11px; font-weight: 700; flex: none; }
.tl-col.locked .timeline-num { background: var(--muted); }
/* Strzałek między kolumnami nie ma od 9.26. Przy siedmiu momentach i zawijaniu
   do kolejnego rzędu strzałka trafiała na początek wiersza i wskazywała w pustkę,
   a CSS nie umie rozpoznać, która kolumna jest pierwsza w swoim rzędzie.
   Kolejność niosą numery 1-7 w kółkach i to wystarcza. */

/* Oś czasu na stronie eventu */
.timeline-view { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.tl-item { display: flex; flex-direction: column; gap: 1px; }
.tl-cap { font-size: 11px; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.tl-item .muted { font-size: 12px; }
.tl-arrow { color: var(--muted); font-size: 20px; }
@media (max-width: 640px) { .tl-arrow { display: none; } .timeline-view { gap: 10px; } }

/* Zwarta tabela w oknie wydania i zwrotu */
table.compact { font-size: 13px; }
/* Szerokie tabele z danymi nie zwężają się poniżej 430 px - wtedy kolumny robią
   się nieczytelne, a .tablewrap daje im przewijanie w bok. Tabelka „Gdzie to leży"
   ma dwie kolumny i jest wyjęta, bo na telefonie wypychałaby całą stronę. */
table.compact:not(.loctable) { min-width: 430px; }
table.compact th, table.compact td { padding: 4px 8px; }
table.compact td:nth-child(2) { white-space: nowrap; }
/* Kolumny, które nie mają prawa się łamać: NIP i kolumna z przyciskami.
   Bez tego numer rozjeżdża się na dwie linie, a „Edytuj" i „Usuń" ustawiają
   się jeden pod drugim i rozpychają wiersz na dwukrotną wysokość. */
td.nowrap, th.nowrap { white-space: nowrap; }

/* Pulpit: kafelki z liczbami. Siatka sama się zawija, więc na telefonie
   układają się jeden pod drugim bez osobnego progu. */
.kafelki { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
           gap: 14px; margin-bottom: 18px; }
.kafelek { margin: 0; }
.kafelek-tytul { font-size: 13px; font-weight: 600; text-transform: uppercase;
                 letter-spacing: .04em; color: var(--muted); }
.kafelek-liczba { font-size: 34px; font-weight: 700; line-height: 1.1; margin: 6px 0 2px; }
.kafelek.zly .kafelek-liczba { color: var(--danger); }
table.compact th { font-size: 11px; }
table.compact tbody tr:hover { background: var(--bg); }
table.compact input[type="number"] { padding: 3px 6px; font-size: 13px; width: 100%; max-width: 84px; }
table.compact input[type="checkbox"] { width: auto; }
.modal .tablewrap { max-height: 56vh; overflow-y: auto; }

/* Podświetlenie braków w oknie dodawania zestawu */
tr.row-short { background: #fef2f2; }
td.short { color: var(--danger); font-weight: 700; }

/* Kalendarz dostępności */
table.calendar { font-size: 12px; border-collapse: collapse; }
table.calendar th, table.calendar td { padding: 4px 3px; text-align: center; border: 1px solid var(--border); }
table.calendar th.cal-day { width: 30px; font-size: 10px; line-height: 1.25; text-transform: none; padding: 3px 2px; }
table.calendar th.weekend { background: var(--bg); }
table.calendar .cal-name { text-align: left; min-width: 150px; max-width: 220px; font-size: 13px;
                           position: sticky; left: 0; background: var(--card); z-index: 1; }
table.calendar .cal-cap { color: var(--muted); font-weight: 600; }
table.calendar .cal-cell { font-variant-numeric: tabular-nums; }
table.calendar .cal-some { background: #eff6ff; }
table.calendar .cal-low  { background: #fef3c7; color: #92400e; font-weight: 700; }
table.calendar .cal-none { background: #fee2e2; color: #b91c1c; font-weight: 700; }

/* Sekcja z operacją nieodwracalną wewnątrz okna edycji */
.danger-zone { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.danger-zone b { color: var(--danger); font-size: 14px; }
.danger-zone p { margin: 4px 0 10px; }

/* Lista eventów blokujących sprzęt */
.conflict-list { margin: 4px 0 0; padding-left: 20px; font-size: 14px; }
.conflict-list li { margin-bottom: 3px; }

/* Nagłówek grupy wewnątrz tabeli w oknie */
table.compact tr.group-row td { background: var(--bg); font-weight: 600; font-size: 12px;
                                color: var(--muted); text-transform: uppercase; letter-spacing: .02em; }

/* Grupa egzemplarzy przy wydaniu: nazwa sprzętu musi zostać w oryginalnej
   pisowni, więc bez wersalików. Wiersze z numerami są wcięte, żeby było widać,
   że należą do tej jednej pozycji, a nie są osobnymi rezerwacjami. */
table.compact tr.unit-group td { text-transform: none; font-size: 13px; color: var(--text);
                                 letter-spacing: normal; padding-top: 8px; padding-bottom: 8px; }
table.compact tr.unit-group b { font-weight: 700; }
table.compact tr.unit-row td.unit-cell { padding-left: 22px; font-size: 12px; }
table.compact tr.unit-row td { border-bottom-color: #f1f1f3; }

/* Stopka z numerem wersji */
.appfoot { max-width: 1600px; width: 100%; margin: 0 auto; padding: 8px 22px 28px; color: var(--muted); font-size: 11px; }

/* ------------------------------------------------- wąskie ekrany
   Poniżej 1000 px kolumna wyjeżdża na wierzch po kliknięciu w „Menu",
   zamiast na stałe odbierać miejsce treści. */
@media (max-width: 1000px) {
  .navbar { display: flex; }
  .sidebar { position: fixed; top: 0; bottom: 0; left: -260px; height: auto; z-index: 60;
             width: 250px; transition: left .18s ease; box-shadow: 0 0 24px rgba(0,0,0,.18); }
  .sidebar.open { left: 0; }
  .navbackdrop.open { display: block; }
  body.menu-otwarte { overflow: hidden; }
  .container { padding: 16px 14px 44px; }
  .appfoot { padding: 8px 14px 24px; }
}

/* Pola formularzy nie rozciągają się przez cały szeroki ekran - napis
   w polu długim na pół metra czyta się gorzej, nie lepiej. Szerokość
   dostają tabele, nie inputy. Pola w tabelach mają własne szerokości
   wpisane przy nich, więc ta reguła ich nie dotyczy. */
.card > .row > label,
form > .row > label,
form.row > label,
main > .row > label { max-width: 520px; }
.row > label.wide, .row > label:has(textarea) { max-width: none; }

/* --- Zakładki grup (packlist) na wydarzeniu ---------------------------------
   Duże, klikalne, bez JavaScriptu: każda zakładka to zwykły link z ?pl=.
   Na telefonie pasek przewija się poziomo, żeby nazwy nie łamały się na pół. */
.pltabs { display: flex; gap: 6px; align-items: stretch; margin: 0 0 -1px;
          overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.pltab { display: flex; flex-direction: column; justify-content: center; gap: 2px;
         min-width: 150px; padding: 9px 14px; border: 1px solid var(--border);
         border-bottom: none; border-radius: 10px 10px 0 0; background: #f1f5f9;
         color: inherit; text-decoration: none; white-space: nowrap; }
.pltab:hover { background: #e7edf5; }
.pltab b { font-size: 14px; }
.pltab span { font-size: 11px; color: var(--muted); }
.pltab .badge { align-self: flex-start; }
.pltab-mag { font-size: 11px; }
.pltab.active { background: #fff; border-color: var(--border); font-weight: 700;
                box-shadow: inset 0 3px 0 var(--accent, #2563eb); }
.pltab.active span { color: var(--muted); }
.pltab-add { min-width: 0; padding: 0; background: transparent; border: none; display: flex; }
.pltab-add button { align-self: center; margin: 0 0 0 4px; }
.plpanel { border-top-left-radius: 0; }
@media (max-width: 700px) {
  .pltab { min-width: 130px; padding: 8px 10px; }
}

/* Rząd formularza z podpowiedzią pod jednym z pól (9.39).
   Zwykły rząd wyrównuje pola DO DOŁU, więc etykieta z dodatkową linijką pod
   spodem byłaby wyższa od sąsiednich i podnosiłaby swoje pole ponad resztę -
   na karcie sprzętu „Kategoria" stałaby wyżej niż „Kod / EAN". Taki rząd
   wyrównujemy więc do GÓRY, a podpowiedź po prostu zwisa pod swoim polem.
   Na telefonie pola i tak idą jedno pod drugim i mają być pełnej szerokości. */
.row.gora { align-items: flex-start; }
.pod-polem { font-size: 11px; }
@media (max-width: 640px) {
  .row.gora { align-items: stretch; }
}

/* Ekran dopasowania kolumn przy imporcie (9.39).
   Na telefonie dwie kolumny tabeli się nie mieszczą - lista z nazwą kolumny
   i przykładami z pliku wychodziłaby poza ekran, a przykłady są tu po to,
   żeby dało się wybrać bez pamiętania, co w pliku jest w której kolumnie.
   Dlatego na wąskim ekranie tabela rozwija się w kartki: nazwa pola, pod nią
   lista na całą szerokość. */
@media (max-width: 640px) {
  table.mapowanie, table.mapowanie tbody, table.mapowanie tr, table.mapowanie td { display: block; width: auto; }
  table.mapowanie thead { display: none; }
  table.mapowanie tr { padding: 8px 0; border-bottom: 1px solid var(--border); }
  table.mapowanie td { border: 0; padding: 2px 0; }
  table.mapowanie td:first-child { font-weight: 600; }
  table.mapowanie select { width: 100%; max-width: 100%; }
}

/* Tabele, które na telefonie rozwijają się w KARTKI (9.40, uogólnione w 9.41).
   W tabeli z kilkoma kolumnami na wąskim ekranie ucina się prawa strona -
   a tam stoi zwykle to, po co człowiek na ten ekran przyszedł: ilość, status,
   uwaga. Dlatego wiersz rozwija się w kartkę: nazwa u góry, pod nią reszta.
   Używają tego: okno wyboru sprzętu, dopasowanie kolumn i podgląd importu
   stanów. */
@media (max-width: 640px) {
  table.tabela-kartki, table.tabela-kartki tbody, table.tabela-kartki tr, table.tabela-kartki td { display: block; width: auto; }
  /* Dwie rzeczy z .compact trzeba tu cofnąć, bo w kartkach robią szkodę:
     najmniejsza szerokość (rozpycha kartkę poza ekran) i zakaz zawijania
     w drugiej komórce (ucina długie nazwy i uwagi). */
  table.compact.tabela-kartki { min-width: 0; }
  table.tabela-kartki td, table.compact.tabela-kartki td:nth-child(2) { white-space: normal; }
  table.tabela-kartki thead { display: none; }
  table.tabela-kartki tr { padding: 8px 0; border-bottom: 1px solid var(--border); }
  table.tabela-kartki td { border: 0; padding: 2px 0; }
  table.tabela-kartki td:first-child { font-weight: 600; }
  /* Kategoria, kod i liczba wolnych w jednej linijce, a nie jedna pod drugą.
     Liczba wolnych dostaje podpis, bo tu nie ma nagłówka kolumny, a samo „5"
     w ciągu innych liczb nic nie znaczy. */
  table.tabela-kartki td.sw-opis { display: inline; }
  table.tabela-kartki td.sw-opis + td.sw-opis::before { content: " · "; }
  table.tabela-kartki td.sw-opis + td.sw-opis.sw-wolne::before { content: " · " attr(data-etykieta) ": "; }
  table.tabela-kartki input[type="number"] { width: 100%; max-width: 120px; }
  table.tabela-kartki button { width: 100%; }
  /* Podpis przed liczbą tam, gdzie nagłówka kolumny już nie widać. */
  table.tabela-kartki td[data-etykieta]::before { content: attr(data-etykieta) ": "; color: var(--muted); }
}
