body{
    --bs-logo-lg-height: 30px;    
    --bs-body-font-size: 0.82rem;
    --bs-body-font-size-sm: 0.82rem;    
}
/* Plakietki (statusy na listach) odrobinę większe.
   Motyw dawał `--bs-badge-font-size: 0.75em`, a że `--bs-body-font-size` wyżej to
   0.82rem, plakietka wychodziła realnie ~9,8 px — stąd wrażenie mikroskopijnych
   statusów. 0.85em to ~11,2 px (+14%).
   Nadpisujemy samą ZMIENNĄ, nie `font-size` — motyw deklaruje
   `font-size: var(--bs-badge-font-size)`, więc reszta jego reguł zostaje spójna.
   Jednostka zostaje `em`, żeby plakietka skalowała się z otoczeniem (inaczej
   rozjedzie się w nagłówkach i stopkach o innym rozmiarze tekstu).
   Padding w górę proporcjonalnie, inaczej tekst zaczyna dotykać krawędzi. */
.badge {
    --bs-badge-font-size: 0.85em;
    --bs-badge-padding-x: 7px;
    --bs-badge-padding-y: 4px;
}

.table>:not(caption)>*>* {
    vertical-align: middle !important;
}

td.no-wrap {
    white-space: nowrap;
  
}
.thumb-sm {
    height: 36px;
    width: 36px;
}
.card-box {
    padding: 20px;
    border-radius: 3px;
    margin-bottom: 30px;
    background-color: #fff;
}
taskList {
    min-height: 40px;
    margin-bottom: 0
}

.taskList li {
    background-color: #fff;
    border: 1px solid rgba(121, 121, 121, .2);
    padding: 10px;
    margin-bottom: 20px;
    border-radius: 3px
}

.taskList li:last-of-type {
    margin-bottom: 0
}

.taskList a {
    font-size: 13px
}

.taskList .checkbox {
    margin-left: 20px;
    margin-top: 5px
}
.text-muted {
    color: #98a6ad!important;
}
/* Styl dla aktywnego użytkownika w sidebarze */
/* Domyślnie pokazuj pełne nazwy */
.user-full { display: inline; }
.user-short { display: none; }
/* Gdy sidebar zwężony */
html[data-menu-size=condensed] .user-full { display: none !important; }
html[data-menu-size=condensed] .user-short { display: inline !important; }
html[data-menu-size=condensed] .active-users-title { display: none !important; }

.timeline-operations {
  border-left: 1px solid hsl(0, 0%, 90%);
  position: relative;
  list-style: none;
}

.timeline-operations .timeline-item-content {
  position: relative;
}

.timeline-operations .timeline-item-content:after {
  position: absolute;
  display: block;
  top: 0;
}

.timeline-operations .timeline-item-content:after {
  background-color: hsl(0, 0%, 90%);
  left: -38px;
  border-radius: 50%;
  height: 11px;
  width: 11px;
  content: "";
}

/* ===== WZORY: hierarchia bloków formularza ===== */
.wz-positions-head { letter-spacing:.5px; font-size:12px; }

/* Pozycja — najmocniejszy kontener */
.position-card { border:1px solid #d4dae2; margin-bottom:20px; background:#fff; box-shadow:0 1px 3px rgba(20,30,50,.05); overflow:hidden; }
.position-card .position-head { display:flex; justify-content:space-between; align-items:center; padding:13px 18px;}
.position-card .position-head .pn { font-size:15px; font-weight:600; display:flex; align-items:center; gap:10px; }
.position-card .position-head .pn .badge { background:#5a6b82; }
.position-card .position-body { padding:18px; }

/* Sekcja wewnątrz pozycji */
.wz-sub { border-radius:10px; margin-top:16px; overflow:hidden; border:1px solid #e2e7ee; }
.wz-sub .wz-sub-head { display:flex; justify-content:space-between; align-items:center; padding:9px 14px; font-size:11.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase; }
.wz-sub-mat .wz-sub-head { background:#eef3fb; color:#3a6ea5; border-bottom:1px solid #dce6f4; }
.wz-sub-op  .wz-sub-head { background:#eef7f0; color:#2e8b57; border-bottom:1px solid #d7ecdd; }
.wz-sub .wz-sub-body { padding:12px 14px; background:#fafbfc; }

/* Operacja — biała karta z zielonym akcentem */
.operation-card { background:#fff; border:1px solid #e2e7ee; border-left:3px solid #2e8b57; border-radius:8px; padding:12px 14px; margin-bottom:10px; }
.operation-card:last-child { margin-bottom:0; }

/* Parametry — wcięte */
.params-wrap { margin-top:10px; margin-left:6px; padding-left:12px; border-left:2px dashed #cfd6df; }
.params-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:7px; }
.params-head small { font-size:10.5px; letter-spacing:.4px; color:#8a929c; text-transform:uppercase; }

.material-row { padding:7px 0; }
.material-row + .material-row { border-top:1px dashed #e6eaf0; }

.position-card label, .wz-sub label { font-size:12.5px; margin-bottom:3px; color:#555; font-weight:500; }

/* Usuń pozycję — czytelny na ciemnym nagłówku */
.wz-remove-pos { background:#e9657b; border:1px solid #e9657b; color:#fff; font-weight:500; }
.wz-remove-pos:hover { background:#d64a63; border-color:#d64a63; color:#fff; }

/* ===== WZORY: tryb ciemny =====
   Sekcja wyżej ma zahardkodowane jasne kolory (#fff, #eef3fb, #555...).
   Tu nadpisujemy je zmiennymi motywu Bootstrap 5.3, zachowując niebieski/
   zielony akcent nagłówków SUROWCE/OPERACJE (jako półprzezroczysty tint). */
[data-bs-theme="dark"] .position-card { background: var(--bs-body-bg); border-color: var(--bs-border-color); box-shadow:none; }
[data-bs-theme="dark"] .wz-sub { border-color: var(--bs-border-color); }
[data-bs-theme="dark"] .wz-sub .wz-sub-body { background: var(--bs-tertiary-bg); }
[data-bs-theme="dark"] .wz-sub-mat .wz-sub-head { background: rgba(58,110,165,.20); color:#8fb4e0; border-bottom-color: rgba(58,110,165,.38); }
[data-bs-theme="dark"] .wz-sub-op  .wz-sub-head { background: rgba(46,139,87,.20);  color:#7fc99b; border-bottom-color: rgba(46,139,87,.38); }
[data-bs-theme="dark"] .operation-card { background: var(--bs-tertiary-bg); border-color: var(--bs-border-color); border-left-color:#2e8b57; }
[data-bs-theme="dark"] .params-wrap { border-left-color: var(--bs-border-color); }
[data-bs-theme="dark"] .material-row + .material-row { border-top-color: var(--bs-border-color); }
[data-bs-theme="dark"] .position-card label,
[data-bs-theme="dark"] .wz-sub label { color: var(--bs-secondary-color); }

/* ===== TABELE: warianty kontekstowe w trybie ciemnym =====
   Motyw nadpisuje dla ciemnego tylko `.table-light`. Pozostałe warianty
   (`.table-warning`, `.table-secondary`) zostają z wartości Bootstrapa, czyli
   z jasnym tłem (#feeede) i niemal czarnym tekstem (#323a46) — na ciemnej
   stronie taki wiersz świeci jak plaster. Widać to np. na /shipments/index.html,
   gdzie CAŁA tabela przerw w dostawach ma `table-warning`, a wiersze z przerwą
   dostają tę klasę też na liście wysyłek.

   Zamiast twardych kolorów dajemy półprzezroczysty tint akcentu: wiersz nadal
   czyta się jako wyróżniony, ale trzyma się palety motywu. Nadpisujemy CAŁY
   komplet zmiennych wariantu — sam `--bs-table-bg` nie wystarczy, bo `hover`
   i `striped` mają własne, też jasne, i wracałyby przy najechaniu myszą. */
[data-bs-theme="dark"] .table-warning {
    --bs-table-color: var(--bs-body-color);
    --bs-table-bg: rgba(var(--bs-warning-rgb), .14);
    --bs-table-border-color: var(--bs-border-color);
    --bs-table-striped-color: var(--bs-body-color);
    --bs-table-striped-bg: rgba(var(--bs-warning-rgb), .18);
    --bs-table-active-color: var(--bs-body-color);
    --bs-table-active-bg: rgba(var(--bs-warning-rgb), .22);
    --bs-table-hover-color: var(--bs-body-color);
    --bs-table-hover-bg: rgba(var(--bs-warning-rgb), .22);
}

[data-bs-theme="dark"] .table-secondary {
    --bs-table-color: var(--bs-body-color);
    --bs-table-bg: var(--bs-secondary-bg);
    --bs-table-border-color: var(--bs-border-color);
    --bs-table-striped-color: var(--bs-body-color);
    --bs-table-striped-bg: var(--bs-tertiary-bg);
    --bs-table-active-color: var(--bs-body-color);
    --bs-table-active-bg: var(--bs-tertiary-bg);
    --bs-table-hover-color: var(--bs-body-color);
    --bs-table-hover-bg: var(--bs-tertiary-bg);
}

/* Motyw ustawia `.table-light` w ciemnym na `--bs-table-border-color: currentcolor`,
   czyli na kolor TEKSTU. Przy `table-bordered` daje to jasną siatkę wokół każdej
   komórki nagłówka — mocniejszą niż same dane. Wracamy do koloru obramowań motywu. */
[data-bs-theme="dark"] .table-light {
    --bs-table-border-color: var(--bs-border-color);
}


/* ============ WYSZUKIWARKA W LISTACH SŁOWNIKOWYCH (Choices) ============
   Choices renderuje własny kontener, więc klasa `form-select-sm` przestaje na niego
   działać: lista w wierszu formularza była wyższa od sąsiednich pól, a bazowe
   `.choices { margin-bottom: 24px }` dokładało pod nią pusty odstęp.
   Klasę `.choices--sm` nakłada webroot/js/components/searchable-select.js. */
.choices--sm {
    margin-bottom: 0;
}

.choices--sm .choices__inner {
    /* !important, bo motyw ustawia `.choices__inner { padding: .5rem 1rem !important }` */
    padding: 0.25rem 0.5rem !important;
    min-height: calc(1.5em + 0.5rem + 2px);
    font-size: 0.875rem;
}

.choices--sm .choices__list--dropdown,
.choices--sm .choices__list[aria-expanded] {
    font-size: 0.875rem;
}

/* Rozwinięta lista musi być NAD sąsiednimi polami wiersza — bez tego wchodziła
   pod input stojący obok (przelicznik, czas operacji). */
.choices--sm.is-open {
    z-index: 5;
}

/* Zdejmuje przycinanie z kart nad rozwiniętą listą Choices — `.wz-sub`
   i `.position-card` mają `overflow: hidden` (zaokrąglone rogi nagłówków), przez co
   lista dekorów w ostatnim wierszu surowców była ucinana na krawędzi karty i wyglądała,
   jakby chowała się pod kartą „Operacje". Klasę nakłada i zdejmuje
   webroot/js/components/searchable-select.js na czas rozwinięcia. */
.wz-unclip {
    overflow: visible !important;
}

/* ============ LISTY WIELOKROTNEGO WYBORU W WIERSZU FORMULARZA ============
   Ten sam kłopot co przy `.choices--sm`, tylko w wariancie wielokrotnego wyboru:
   bazowe `.choices { margin-bottom: 24px }` zostawiało pod polem pustą dziurę, przez
   którą podpowiedź spod listy odrywała się od niej i lądowała bliżej następnego
   wiersza. Do tego kontener Choices jest niższy niż `.form-control` obok, więc pola
   w jednym formularzu nie trzymały wspólnej linii.
   Klasę nakładają widoki, które inicjalizują Choices ręcznie (Documents, Departments). */
.choices--field {
    margin-bottom: 0;
}

.choices--field .choices__inner {
    /* !important, bo motyw ustawia `.choices__inner { padding: .5rem 1rem !important }` */
    padding: 0.25rem 0.5rem !important;
    /* równo z sąsiednim .form-control: wysokość linii + padding + obramowanie */
    min-height: calc(1.5em + 0.75rem + 2px);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}

/* Chip ma być etykietą w polu, a nie kafelkiem podnoszącym całe pole */
.choices--field .choices__list--multiple .choices__item {
    margin: 2px 4px 2px 0;
    padding: 3px 8px;
    font-size: 0.75rem;
}

/* Choices zamienia znaki nowej linii z etykiety <option> na <br>, więc wcięcie
   w szablonie albo nazwa z bazy z łamaniem linii robiły z chipa dwuwierszowy
   kafelek (62 px zamiast 24 px) i rozpychały całe pole. Źródło poprawiamy
   w szablonach — ta reguła pilnuje, żeby jedna taka nazwa nie psuła układu. */
.choices--field .choices__item br {
    display: none;
}

/* Pole wpisywania siedzi w tym samym wierszu co chipy — własny margines
   dokładałby drugą linię przy pierwszym wybranym dziale. */
.choices--field .choices__input {
    margin-bottom: 0;
    padding: 2px 0 2px 2px;
}

/* Rozwinięta lista nad sąsiednimi polami — inaczej wchodzi pod następny wiersz */
.choices--field.is-open {
    z-index: 5;
}

/* ============ OKRUSZKI Z NAZWAMI Z BAZY ============
   Nagłówki kart trzymają tytuł po lewej i okruszki po prawej w jednym `d-flex
   justify-content-between`. Dopóki okruszki są krótkie („Szkolenia / Nowy"), to
   działa. Ale w module dokumentów wchodzą w nie NAZWY Z BAZY — pełny tytuł
   procedury i nazwa pliku potrafią mieć po kilkadziesiąt znaków. Wtedy okruszki
   rozpychają się na całą szerokość, wchodzą na tytuł karty i nagłówek się rozjeżdża.

   Nakładamy dwa ograniczenia:
   • pasek okruszków łamie się do kolejnej linii, zamiast spychać tytuł,
   • pozycja oznaczona `.wz-crumb-name` jest przycinana wielokropkiem — pełna nazwa
     zostaje w `title`, więc nic nie ginie, tylko przestaje rozpychać układ.

   Przycinanie jest WŁĄCZANE KLASĄ, nie zgadywane po `.active`: na karcie pliku
   ostatnia pozycja to nazwa pliku (do przycięcia), a w formularzu wersji to stałe
   „Szkic" (przycinać nie ma czego). Klasę nakłada szablon, który wie, co wstawia.

   Same nagłówki dostają jeszcze `flex-wrap gap-2` w szablonach — bez tego pasek
   nie ma się gdzie złamać. */
.wz-breadcrumb {
    max-width: 100%;
    flex-wrap: wrap;
}

.wz-breadcrumb .wz-crumb-name {
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Bootstrap stawia separator „/" przez ::before na `.breadcrumb-item`. Gdy pozycja
   ma `overflow: hidden`, separator zostaje w środku obszaru przycinania i przy
   długiej nazwie znika razem z tekstem. Dlatego łamiemy pozycję na dwa poziomy:
   przycinamy WNĘTRZE (link), a nie samo `li`. */
.wz-breadcrumb .wz-crumb-name > a,
.wz-breadcrumb .wz-crumb-name > span {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* Na wąskim ekranie nagłówek i tak jest jednokolumnowy — tam okruszki mogą wziąć
   całą szerokość, więc przycinamy ostrzej zamiast zawijać na trzy linie. */
@media (max-width: 575.98px) {
    .wz-breadcrumb .wz-crumb-name {
        max-width: 14ch;
    }
}

/* ============ PODŚWIETLENIE AKTYWNYCH FILTRÓW NA LISTACH ============
   Klasę `.filter-active` nakłada webroot/js/filter-highlight.js na kolumnę
   z kontrolką filtra, która ma ustawioną wartość. Jeden zestaw reguł łapie
   input daty (flatpickr), zwykły <select> i <select> owinięty w Choices
   (widoczny box to wtedy .choices__inner).

   Bez zewnętrznej poświaty — `.choices { overflow: hidden }` by ją przycinało
   i pola z wyszukiwarką wyglądałyby inaczej niż reszta; zostaje sama obwódka. */
.filter-active label,
.filter-active .form-label {
    color: var(--bs-primary) !important;
    font-weight: 600;
}
.filter-active label::after,
.filter-active .form-label::after {
    content: " \25CF";
    font-size: .65em;
    vertical-align: middle;
}
.filter-active .form-control,
.filter-active .form-select,
.filter-active .choices__inner {
    border-color: var(--bs-primary) !important;
    background-color: rgba(var(--bs-primary-rgb), .07) !important;
    box-shadow: inset 0 0 0 1px var(--bs-primary) !important;
}

/* ============ POLA Z WYSZUKIWARKĄ (Choices) W PASKU FILTRÓW LIST ============
   Choices renderuje własny kontener, na który `form-select-sm` nie działa, a motyw
   (app.css) wymusza `.choices__inner { padding: .5rem 1rem !important }` + większą
   czcionkę — przez co na listach te pola były wyższe od sąsiednich selectów/inputów.
   Sprowadzamy je 1:1 do metryk `.form-control-sm` z motywu. Łapiemy po `.card-header`
   (tam siedzą paski filtrów) i tylko pojedynczy wybór — multi-select w formularzach
   (`.choices--field`) to `data-type=select-multiple` i tu nie wpada. */
.card-header .choices[data-type*="select-one"] {
    margin-bottom: 0;
}
.card-header .choices[data-type*="select-one"] .choices__inner {
    min-height: calc(1.5em + .696rem + 2px) !important;
    height: calc(1.5em + .696rem + 2px);
    padding: .348rem 1.75rem .348rem .625rem !important;
    font-size: .7875rem;
    line-height: 1.5;
    border-radius: .15rem !important;
    display: flex;
    align-items: center;
}
.card-header .choices[data-type*="select-one"] .choices__list--single {
    padding: 0;
}
.card-header .choices[data-type*="select-one"] .choices__list--single .choices__item {
    font-size: .7875rem;
}
/* motyw ma na strzałce `top: 18px` na sztywno (liczone dla wysokiego pola) */
.card-header .choices[data-type*="select-one"]::after {
    top: 50%;
    right: .625rem;
    font-size: 16px;
}
.card-header .choices[data-type*="select-one"] .choices__input {
    margin-bottom: 0;
}
