/* NPS2 — arkusz stylów interfejsu.
   Kopia arkusza Przybyła 2026 (wygląd MAM ZAPISANE z paletą Przybyła: bordo
   jako kolor wiodący, chłodne szarości) — nagłówki, klawisze, okna, listy
   jak w Przybyle. Zastąpił prostszy arkusz superadmina MZ (2026-09-28).
   Na końcu dodatki tylko dla NPS2. */

:root {
    /* Paleta Przybyła (chłodne szarości) na układzie z MAM ZAPISANE. */
    --bg:        #f4f6f9;
    --surface:   #ffffff;
    --border:    #e2e6ec;
    --text:      #1f2933;
    --muted:     #67707b;

    --danger:    #c8332b;
    --danger-d:  #a5271f;
    --ok:        #1f7a44;
    --warning:   #a3480a;
    --info:      #1c4e80;

    /* Niebieski — linki i elementy informacyjne (jak dotąd w Przybyle). */
    --primary:       #2f5fda;
    --primary-d:     #244bb0;

    /* Kolor wiodący Przybyła: bordo — klawisze funkcyjne (edycja/zapis),
       aktywne elementy, akcenty. Jaśniejsze odcienie do tła aktywnej pozycji
       menu, kółek ikon i wyróżnień. */
    --accent:        #7a1e2e;
    --accent-d:      #55141f;
    --accent-border: #661a27;
    --accent-light:  #a8485a;
    --rose:          #d7a3ac;
    --rose-light:    #f3e3e6;
    --beige:         #e3e6eb;

    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --radius:    var(--radius-md);

    --shadow-sm: 0 1px 2px rgba(16, 24, 40, .05);
    --shadow-md: 0 4px 16px rgba(16, 24, 40, .08);
    --shadow:    var(--shadow-md);

    --control-h: 34px;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
}

body {
    font: 15px/1.55 "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    color: var(--text);
    background: var(--bg);
}

a { color: var(--primary); transition: color .14s ease; }
a:hover { color: var(--primary-d); text-decoration-thickness: 1.5px; }
a:active { color: var(--accent-border); }
a:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 35%, transparent);
    border-radius: 2px;
}

code {
    font: 13px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    background: rgba(15, 23, 42, .06);
    padding: 1px 5px;
    border-radius: 4px;
}

.muted { color: var(--muted); }
.pre-wrap { white-space: pre-wrap; }

/* Pola Zamawiającego 2 (moduł Klienci) — pokazane tylko gdy zaznaczony
   checkbox "drugi zamawiający"; czysty CSS (:has), działa też bez JS. */
.orderer2-fields { display: none; }
.form:has(#has-orderer2:checked) .orderer2-fields { display: flex; flex-direction: column; gap: 13px; }

/* Zlecenia — przełącznik "istniejący klient" / "nowy zamawiający" (moduł
   Zlecenia), tym samym czystym CSS (:has) co pola Zamawiającego 2. */
.existing-client-block, .new-orderer-block { display: none; }
.form:has(#order-mode-existing:checked) .existing-client-block { display: block; }
.form:has(#order-mode-new:checked) .new-orderer-block { display: flex; flex-direction: column; gap: 13px; }

/* Edycja zlecenia — bez przełącznika istniejący/nowy, pola zamawiającego
   zawsze widoczne (patrz .new-orderer-block powyżej, ten sam układ). */
.orderer-fields { display: flex; flex-direction: column; gap: 13px; }

/* Checkbox „Dane do zlecenia wypełni klient" (zakładanie zlecenia) — ten sam
   czysty CSS (:has) — chowa pola zamawiającego/„Zapisz w bazie klientów",
   pokazuje w zamian krótką notkę. Walidacja i tak już rozluźniona po stronie
   serwera (patrz OrderController::resolveInput()) — to czysto kosmetyczne. */
#client-fills-data-note { display: none; color: var(--muted); font-size: 13px; margin: -4px 0 4px; }
.form:has(#client-fills-data:checked) #client-fills-data-note { display: block; }
.orderer-input-fields { display: flex; flex-direction: column; gap: 13px; }
.form:has(#client-fills-data:checked) .orderer-input-fields { display: none; }

/* Combobox wyboru klienta z wyszukiwaniem (moduł Zlecenia) */
.client-picker { position: relative; display: block; }
.client-picker__results {
    position: absolute;
    z-index: 60;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 2px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 7px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .16);
    max-height: 240px;
    overflow-y: auto;
}
.client-picker__item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 12px;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: none;
    font: inherit;
    font-size: 14px;
    cursor: pointer;
}
.client-picker__item:last-child { border-bottom: 0; }
.client-picker__item:hover { background: #eceff3; }
.client-picker__empty { padding: 8px 12px; color: var(--muted); font-size: 13px; }

/* ---------- Ekran logowania -------------------------------------- */

body.auth {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}

.auth__card {
    width: 100%;
    max-width: 360px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 28px 26px 30px;
}

.auth__brand {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 22px;
}

.auth__logo-img {
    display: block;
    max-width: 240px;
    max-height: 72px;
    width: auto;
    height: auto;
}

.auth__name { font-weight: 700; font-size: 17px; }
.auth__title { font-size: 16px; margin: 0 0 14px; }
.auth__foot { color: var(--muted); font-size: 13px; margin-top: 16px; }

/* ---------- Układ aplikacji ------------------------------------- */

/* Baner na każdej stronie, gdy baza ma zaległe migracje (zapisy zablokowane
   przez Router — patrz WRITE_GUARD_EXEMPT). Nad całym .app__shell, nie tylko
   nad treścią, żeby było widać zawsze, nawet przy wąskim/schowanym menu. */
.update-banner {
    background: #fff4e0;
    color: #8a5a00;
    border-bottom: 1px solid #f0d9a8;
    padding: 10px 22px;
    font-size: 14px;
    text-align: center;
}
.update-banner a { color: inherit; font-weight: 700; text-decoration: underline; }

/* Menu boczne i górny pasek mają zostawać na miejscu podczas przewijania
   treści — tylko .content przewija się niezależnie, reszta (body) nigdy. */
body.app { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.update-banner { flex-shrink: 0; }

.app__shell {
    display: flex;
    flex: 1;
    min-height: 0;
}

.sidebar {
    width: 234px;
    flex-shrink: 0;
    background: #222222;
    color: #cdd7e4;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.sidebar__brand {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px 16px;
    min-height: 56px;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.sidebar__logo-img {
    display: block;
    max-width: 100%;
    max-height: 46px;
    width: auto;
    height: auto;
}

.sidebar__name { font-weight: 700; color: #fff; font-size: 15px; }

.sidebar__nav { padding: 14px 12px; display: flex; flex-direction: column; gap: 6px; }

.navitem {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: 10px;
    color: #cdd7e4;
    text-decoration: none;
    font-size: 14px;
    transition: background .12s ease;
}

.navitem:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.navitem.is-active { background: var(--accent); color: #fff; } /* bordo jak w poprzedniej wersji Przybyła */
.navitem__icon {
    width: 30px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: .75;
}
.navitem__icon svg { display: block; }
.navitem.is-active .navitem__icon { opacity: 1; }
.navitem--disabled { opacity: .5; cursor: default; }
.navitem__tag {
    margin-left: auto;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #99a1ae;
}

.app__main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.topbar {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 22px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
    flex-shrink: 0;
}

.topbar__toggle {
    display: none;
    border: 0;
    background: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text);
}

/* Wyszukiwarka — na razie WYŁĄCZNIE wizualna, bez podpiętej logiki
   przeszukiwania (patrz notatka nad polem w widoku). */
.topbar__search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 320px;
    max-width: 420px;
    padding: 8px 14px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--muted);
    transition: border-color .16s ease, background .16s ease;
}
.topbar__search:focus-within { border-color: var(--accent-light); background: var(--surface); }
.topbar__search svg { flex-shrink: 0; }
.topbar__search input {
    border: 0;
    outline: none;
    background: none;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    width: 100%;
}
.topbar__search input::placeholder { color: var(--muted); }

.topbar__actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 14px;
}

.topbar__bell {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
    transition: background .16s ease, color .16s ease;
}
.topbar__bell:hover { background: var(--bg); color: var(--text); }

/* Dropdown ogólny — menu użytkownika w pasku górnym (.user-menu) I menu ⋮
   wierszowe w tabelach (.dropdown-menu, np. lista Klientów) współdzielą
   panel/pozycje (`__panel`/`__item`); tylko wygląd PRZYCISKU otwierającego
   różni się (awatar+nazwa w topbarze vs. sama ikonka `.btn--icon` w
   wierszu). Otwieranie/zamykanie: [data-dropdown] w app.js (klik poza /
   ESC zamyka, tylko jeden otwarty naraz). */
.user-menu, .dropdown-menu { position: relative; display: inline-flex; }
.user-menu__trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 4px 4px;
    border: 0;
    background: none;
    border-radius: 999px;
    cursor: pointer;
    transition: background .16s ease;
}
.user-menu__trigger:hover { background: var(--bg); }
.user-menu__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    flex-shrink: 0;
}
.user-menu__name { font-size: 13px; font-weight: 600; color: var(--text); }
.user-menu__chevron { color: var(--muted); transition: transform .16s ease; }
.user-menu.is-open .user-menu__chevron { transform: rotate(180deg); }

.user-menu__panel, .dropdown-menu__panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 190px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 50;
    /* Zawsze w DOM (bez display:none) — tylko opacity/transform/visibility,
       żeby dało się animować pojawienie/zniknięcie czystym CSS. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-4px);
    transition: opacity .15s ease, transform .15s ease, visibility 0s linear .15s;
}
.user-menu.is-open .user-menu__panel,
.dropdown-menu.is-open .dropdown-menu__panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
    transition: opacity .15s ease, transform .15s ease;
}

.user-menu__item, .dropdown-menu__item {
    display: block;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font: inherit;
    font-size: 14px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background .12s ease;
}
.user-menu__item:hover, .dropdown-menu__item:hover { background: var(--bg); color: var(--text); }
.user-menu__item--danger, .dropdown-menu__item--danger { color: var(--danger-d); }
.user-menu__item--danger:hover, .dropdown-menu__item--danger:hover { color: var(--danger-d); }
.dropdown-menu__sep { height: 1px; background: var(--border); margin: 4px 2px; }
.dropdown-menu__label {
    padding: 6px 12px 4px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted);
}
.dropdown-menu__item.is-active {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    color: var(--accent);
    font-weight: 700;
}

/* Nowy, płaski pasek wyszukiwarki/filtrów list — zastępuje stary gradientowy
   .toolbar--card-top (styl SMOK/Przybył). Pierwsze użycie: lista Klientów;
   docelowo ten sam wzór dla pozostałych list. Bez osobnej "konsoli" — mieści
   się w zwykłym paddingu karty, tylko cienka linia oddziela od zawartości. */
.list-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding-bottom: 16px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
/* Reużyty jako nagłówek sekcji karty (tytuł + akcja), np. szczegóły zlecenia
   — .card__title ma domyślnie własny dolny margines, tu niepotrzebny. */
.list-toolbar .card__title { margin: 0; }
.list-toolbar__search-form {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 280px;
    max-width: 400px;
}
.list-toolbar__search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    height: 42px;
    padding: 0 14px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--muted);
    transition: border-color .16s ease, background .16s ease;
}
.list-toolbar__search:focus-within { border-color: var(--accent-light); background: var(--surface); }
.list-toolbar__search svg { flex-shrink: 0; }
.list-toolbar__search input {
    border: 0;
    outline: none;
    background: none;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    width: 100%;
}
.list-toolbar__search input::placeholder { color: var(--muted); }
.list-toolbar__search-btn { flex-shrink: 0; }
.list-toolbar__actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.list-toolbar__actions .btn { font-weight: 400; }
.list-toolbar__actions .btn svg { stroke-width: 1.5; }
.list-toolbar__select { width: auto; min-width: 170px; height: 42px; cursor: pointer; }

/* Aktywny filtr listy (inny niż "Wszystkie...") — obwódka w kolorze wiodącym,
   żeby było widać z daleka, że lista jest zawężona. Wzorem SMOK-a
   (.toolbar__input--filter-active). */
.list-toolbar__select.is-filtered {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 1px var(--accent);
}

.filter-btn__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    margin-left: 6px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
}

@media (max-width: 560px) {
    .user-menu__name { display: none; }
    .topbar__search { display: none; }
}

/* Pasek narzędzi zakładki — przyciski + pola wyszukiwania w jednym,
   segmentowym pasku u góry treści zakładki. */
.toolbar {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    min-height: 42px;
    background: #dde1e7;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 18px;
}

.toolbar--card-top {
    margin: -20px -22px 14px;
    border-radius: var(--radius) var(--radius) 0 0;
    border: none;
    border-bottom: 1px solid var(--border);
}

.toolbar__title {
    display: flex;
    align-items: center;
    padding: 0 16px;
    font-weight: 700;
    font-size: 14px;
    color: var(--text);
    white-space: nowrap;
}

.toolbar__actions { display: flex; align-items: stretch; margin-left: auto; }
.toolbar__group { display: flex; align-items: stretch; }

.toolbar__input {
    margin: 6px 4px;
    padding: 0 10px;
    border: none;
    border-left: 1px solid #c6ccd4;
    border-right: 1px solid #c6ccd4;
    border-radius: 5px;
    background: #fff;
    font: inherit;
    color: var(--text);
    width: 86px;
}
.toolbar__input:focus { outline: none; background: #eef4ff; }
.toolbar__input--wide { width: 200px; }

.toolbar__btn {
    display: inline-flex;
    align-items: center;
    height: 100%;
    margin: 0;
    padding: 0 16px;
    border: none;
    border-left: 1px solid #c6ccd4;
    border-right: 1px solid #c6ccd4;
    background: linear-gradient(to bottom, #f1f3f6, #d3d7dd);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    transition: background .16s ease;
}
.toolbar__btn:hover { background: linear-gradient(to bottom, #b8bfc9, #cbd2db); }
.toolbar__btn:active { background: linear-gradient(to bottom, #aab1bd, #c7cdd6); }
.toolbar__btn:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* Filtr aktywny (np. Wszyscy/Firmy/Osoby prywatne na liście Klientów). */
.toolbar__btn.is-active {
    background: var(--accent);
    color: #fff;
    border-left-color: var(--accent-border);
    border-right-color: var(--accent-border);
}

/* Klawisze funkcyjne (prowadzące do edycji/zapisu) — kolor wiodący. */
.toolbar__btn--accent {
    color: #fff;
    border-left: 1px solid var(--accent-border);
    border-right: 1px solid var(--accent-border);
    background: linear-gradient(to bottom, var(--accent-light), var(--accent));
}
.toolbar__btn--accent:hover { background: linear-gradient(to bottom, #98283a, #55141f); }
.toolbar__btn--accent:active { background: linear-gradient(to bottom, #55141f, var(--accent-d)); }

@media (max-width: 720px) {
    .toolbar,
    .toolbar__actions,
    .toolbar__group {
        flex-direction: column;
        align-items: stretch;
    }
    .toolbar__actions { margin-left: 0; width: 100%; }
    .toolbar__title { padding: 10px 16px; }

    .toolbar__input {
        width: auto;
        margin: 8px 10px;
        padding: 12px 10px;
        border: 1px solid #c6ccd4;
    }

    .toolbar__btn {
        width: 100%;
        justify-content: center;
        margin: 0;
        padding: 16px 20px; /* wysokość jak .btn--tall */
        font-size: 15px;
        border-left: none;
        border-right: none;
        border-top: 1px solid #c6ccd4;
    }
    .toolbar__btn--accent { border-top-color: var(--accent-border); }

    /* Wyjątek: grupa nawigacji „‹ nazwa ›" (miesiąc w kalendarzu) zostaje
       w jednej linii — strzałki po bokach, nazwa pośrodku. */
    .toolbar__group--inline {
        flex-direction: row;
        align-items: stretch;
    }
    .toolbar__group--inline .toolbar__btn {
        width: auto;
        flex: 0 0 auto;
        padding: 12px 26px;
        font-size: 24px; /* strzałki ‹ › — większy cel dotyku */
    }
    .toolbar__group--inline .toolbar__title {
        flex: 1 1 auto;
        justify-content: center;
        padding: 10px 8px;
        font-size: 16px;
    }
}

/* Zawartość modułu wypełnia całą dostępną szerokość; węższe bloki (np.
   formularze) ograniczamy klasą .card--narrow. Jedyny element, który się
   przewija — sidebar/topbar zostają na miejscu (patrz body.app wyżej). */
.content { padding: 22px; width: 100%; flex: 1; overflow-y: auto; }

/* ---------- Karty --------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 20px 22px;
    margin-bottom: 18px;
}

.card--narrow { max-width: 480px; }

/* Dwie powiązane karty obok siebie (np. dane zlecenia + zamawiający),
   zwijane w jedną kolumnę na wąskim ekranie. */
.detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    margin-bottom: 18px;
    align-items: stretch;
}
.detail-grid > .card { margin-bottom: 0; min-width: 0; }
@media (max-width: 900px) {
    .detail-grid { grid-template-columns: 1fr; }
}

/* Wariant 40/60 (np. dane zlecenia węższe, zamawiający szerszy) */
.detail-grid--40-60 { grid-template-columns: 2fr 3fr; }
@media (max-width: 900px) {
    .detail-grid--40-60 { grid-template-columns: 1fr; }
}

/* Szczegóły zlecenia: Zamawiający szeroko, Notatki wąsko — szerokość karty
   Notatek dobrana tak, by wizualnie odpowiadała szerokości kafelka "Pakiet"
   w .stat-grid--order nad nią (spójna kolumna w pionie). */
.detail-grid--order { grid-template-columns: 2.1fr 1fr; }
@media (max-width: 900px) {
    .detail-grid--order { grid-template-columns: 1fr; }
}

/* Wariant bez rozciągania kart do równej wysokości (np. Pakiet usług + Finanse —
   karty mają różną ilość treści i nie powinny sztucznie dorównywać wysokością). */
.detail-grid--top { align-items: start; }

/* Pion dwóch kart jako JEDNA kolumna .detail-grid (np. Lokalizacja + Pakiet
   usług po lewej, Finanse po prawej na całą wysokość obu) — odstęp między
   kartami bierze się z ich własnego .card{margin-bottom}, bez dodatkowego gap. */
.detail-grid__stack { display: flex; flex-direction: column; min-width: 0; }

/* Karta na połowę szerokości ekranu (np. szczegóły pakietu pod danymi zlecenia) */
.card--half { max-width: 50%; }
@media (max-width: 900px) {
    .card--half { max-width: 100%; }
}
/* Kafelek w kolorze wiodącym (np. „dostępna aktualizacja bazy" na pulpicie) */
.card--accent-work { border-left: 4px solid var(--accent); background: var(--rose-light); }
.card__title { font-size: 16px; margin: 0 0 12px; }
.card__lead { color: var(--muted); margin: 0 0 16px; }

/* ---------- Formularze ---------------------------------------- */

.form { display: flex; flex-direction: column; gap: 13px; }
.form__row { display: flex; flex-direction: column; gap: 5px; }
/* Jak przy .form__group[hidden] wyżej — display:flex jako reguła autora inaczej
   nadpisałoby wbudowaną [hidden]{display:none}, np. wiersz ceny pakietu ręcznego
   albo nazwy lokalizacji ręcznej zostałby zawsze widoczny mimo atrybutu hidden. */
.form__row[hidden] { display: none; }
.form__label { font-size: 13px; font-weight: 600; }
.form__hint { font-weight: 400; color: var(--muted); }

/* Edytor Quill (modal wysyłki potwierdzenia wpłaty, edycja komunikatów
   i szablonów umów w Ustawienia → Konfiguracja/Umowy) — port z panelu
   superadmina. */
#payment-confirm-editor,
#message-body-editor,
#contract-body-editor { background: #fff; border-radius: 7px; }
#payment-confirm-editor .ql-toolbar.ql-snow,
#message-body-editor .ql-toolbar.ql-snow,
#contract-body-editor .ql-toolbar.ql-snow { border-color: #c6ccd4; border-radius: 7px 7px 0 0; }
#payment-confirm-editor .ql-container.ql-snow,
#message-body-editor .ql-container.ql-snow,
#contract-body-editor .ql-container.ql-snow,
#order-remarks-editor .ql-container.ql-snow { border-color: #c6ccd4; border-radius: 0 0 7px 7px; }
#payment-confirm-editor .ql-editor,
#message-body-editor .ql-editor,
#contract-body-editor .ql-editor,
#order-remarks-editor .ql-editor { min-height: 220px; font-size: 15px; }
/* Treść umowy jest zwykle znacznie dłuższa niż komunikat e-mail — więcej
   miejsca od razu, żeby nie przewijać przy każdej linijce. Górny limit +
   własne przewijanie (zamiast rosnąć bez końca) — inaczej przy dłuższej
   umowie przewijał się CAŁY modal razem z paskiem narzędzi (znikał z
   widoku), a klik w treść przesuwał okno z powrotem do góry. Dzięki temu
   pasek narzędzi zawsze zostaje widoczny, a przewijanie dzieje się TYLKO
   wewnątrz treści. */
#contract-body-editor .ql-editor { min-height: 420px; max-height: 55vh; overflow-y: auto; }

/* Podgląd treści e-maila (HTML z edytora WYSIWYG) w trybie widoku. Świadomie
   ZERO marginesu na akapicie — dokładnie jak .ql-editor p w quill.snow.css
   (edytor) — żeby liczba pustych linii w podglądzie 1:1 zgadzała się z tym,
   co widać podczas edycji (a nie dodatkowo "na oko" powiększała się o
   osobny odstęp między-akapitowy doklejany tutaj). Odstęp między akapitami
   bierze się WYŁĄCZNIE z wysokości linii, tak samo jak w edytorze. */
.email-preview { border: 1px solid var(--border); border-radius: 7px; padding: 14px 16px; }
.email-preview p { margin: 0; }

.form__input {
    font: inherit;
    line-height: 1.4;
    padding: 8px 10px;
    border: 1px solid #c6ccd4;
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--text);
    width: 100%;
    min-height: 39px;
    transition: border-color .14s ease, box-shadow .14s ease, background .14s ease;
}

.form__input:hover:not(:focus):not(:disabled) { border-color: #b7bec8; }
textarea.form__input { resize: vertical; }

.form__input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent);
}

.form__input.is-invalid,
.form__input:user-invalid {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 18%, transparent);
}

.form__input:disabled {
    background: var(--bg);
    color: var(--muted);
    opacity: .7;
    cursor: not-allowed;
}

.form__check { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.form__check.is-invalid { color: var(--danger-d); }
.form__check.is-invalid input { outline: 2px solid var(--danger); outline-offset: 2px; }

/* Checkboxy i radio (checkboxy/"opcje" wyboru) w kolorze wiodącym wszędzie,
   2x większe niż domyślny rozmiar przeglądarki. */
input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--accent);
    width: 26px;
    height: 26px;
    cursor: pointer;
}

.form__color-wrap { margin-top: 4px; }
.form__color-wrap[hidden] { display: none; }
.form__color {
    width: 58px;
    height: 34px;
    padding: 2px;
    background: #fff;
    border: 1px solid #c6ccd4;
    border-radius: 7px;
    cursor: pointer;
    vertical-align: middle;
}

.form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.form__actions--confirm { justify-content: flex-start; }
.form__actions--confirm .btn { flex: 1 1 0; padding-top: 16px; padding-bottom: 16px; }

/* Treść modala potwierdzenia — nagłówek-pytanie, opis, pogrubiona nazwa
   rekordu i ostrzeżenie o nieodwracalności, każde w osobnej linii, do lewej
   (patrz app.js — ikona kosza siedzi w nagłówku modala, nie tutaj). */
.confirm-title { margin: 0 0 8px; font-size: 17px; font-weight: 700; color: var(--text); }
.confirm-text { margin: 0; color: var(--muted); }
.confirm-name { margin: 4px 0 0; font-weight: 700; color: var(--text); }
.confirm-warning {
    margin: 24px 0 0;
    padding: 20px 0;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--danger-d);
}

.btn--right { margin-left: auto; }

/* Formularz w jednej linii (np. NIP + „Pobierz dane") */
.form-inline { display: flex; gap: 6px; align-items: center; }
.form__input--inline { width: auto; flex: 1 1 auto; min-width: 0; }

/* Pole + przycisk zrośnięte w jedną kontrolkę (np. NIP + „Pobierz dane") —
   bez odstępu, wspólna wysokość (align-items: stretch rozciąga przycisk do
   wysokości pola), zewnętrzne rogi zaokrąglone, wewnętrzne płaskie. */
.input-group { display: flex; align-items: stretch; }
.input-group .form__input {
    flex: 1 1 auto;
    min-width: 0;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.input-group .btn {
    flex: 0 0 auto;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    margin-left: -1px;
}

/* Śródtytuł sekcji w dłuższym formularzu */
.form__subhead {
    margin: 6px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
}

/* Wydzielony blok formularza (np. wszystko dot. pakietu przy zakładaniu
   zlecenia) — odróżniony od reszty pól tłem, żeby było widać na pierwszy
   rzut oka, że dotyczą jednej rzeczy, bez ciężaru pełnej .card (ten blok
   siedzi już wewnątrz modala/formularza). */
.form__group {
    display: flex;
    flex-direction: column;
    gap: 13px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
}
/* Bez tego reguła display:flex wyżej (jako reguła autora) nadpisałaby
   wbudowaną [hidden]{display:none} przeglądarki niezależnie od specyficzności
   — karta zostałaby zawsze widoczna mimo atrybutu hidden (patrz ta sama
   pułapka przy podglądzie podpisu, .signature-preview[hidden]). */
.form__group[hidden] { display: none; }
.form__group .form__subhead:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.form__group__title {
    margin: 0;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
}

/* Dwie kolumny w formularzu (np. kod pocztowy + miasto) */
.form__grid2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.form__grid2 > .form__row { margin: 0; }

@media (max-width: 520px) {
    .form__grid2 { grid-template-columns: 1fr; gap: 13px; }
}

/* Siatka pól formularza na pełnej szerokości karty — tyle kolumn po ~220px,
   ile się zmieści (zwykle 3-4 na desktopie), bez zmiany szerokości/wyglądu
   pojedynczego pola. Pole, które ma zająć cały wiersz mimo siatki (np. duży
   textarea) dostaje `.form__row--full` (grid-column: 1 / -1). */
.form__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 13px 16px;
}
.form__grid > .form__row,
.form__grid > .form__check { margin: 0; }
.form__row--full { grid-column: 1 / -1; }

/* ---------- Listy definicji -------------------------------- */

.deflist { margin: 0 0 16px; display: flex; flex-direction: column; gap: 6px; }
.deflist > div { display: flex; gap: 10px; font-size: 14px; }
.deflist dt { color: var(--muted); min-width: 90px; }
.deflist dd { margin: 0; font-weight: 600; }

.name { font-weight: 700; }
a.name { color: var(--text); text-decoration: none; }
a.name:hover { color: var(--primary); }

/* ---------- Przyciski ---------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font: inherit;
    font-weight: 600;
    padding: 8px 15px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    line-height: 1.2;
    white-space: nowrap;
    transition: background .16s ease, border-color .16s ease, transform .08s ease, opacity .14s ease;
}
.btn > svg:first-child { margin-right: 8px; }
.btn--icon > svg:first-child { margin-right: 0; }
/* Przycisk z SAMĄ ikoną, ale NIE .btn--icon (np. Informacja o zleceniu —
   ma być wielkości .btn--ghost.btn--tall) — usuwa odstęp myślany na tekst,
   który by tu i tak nie nastąpił. Celowo osobna klasa zamiast selektora
   :only-child na wszystkich .btn, żeby nie ruszać przycisków gdzie indziej. */
.btn--icon-solo > svg:first-child { margin-right: 0; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}
.btn:disabled, .btn.is-disabled {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Stan "loading" — tekst niewidoczny (ale zajmuje miejsce, więc przycisk NIE
   zmienia rozmiaru), na środku subtelny spinner. Dodawana/usuwana w JS razem
   z `disabled` przy operacjach AJAX (modal formularza, potwierdzenie usuń). */
.btn.is-loading {
    position: relative;
    color: transparent !important;
    opacity: 1;
}
.btn.is-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, .55);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btn-spin .6s linear infinite;
}
.btn--ghost.is-loading::after,
.btn--icon.is-loading::after {
    border-color: color-mix(in srgb, var(--text) 25%, transparent);
    border-top-color: var(--text);
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .btn.is-loading::after { animation-duration: 1.5s; }
}

/* Primary/Accent (to samo w tej apce — --primary i --accent mają tę samą
   wartość): hover JAŚNIEJSZY/bardziej nasycony (--accent-light), active
   CIEMNIEJSZY — dokładnie odwrotne kierunki, zgodnie z briefem ("hover:
   nieco jaśniejsza zieleń, active: delikatnie ciemniejsza"). */
.btn--primary { background: var(--primary); color: #fff; }
.btn--primary:hover { background: var(--accent-light); color: #fff; }
.btn--primary:active { background: var(--accent-border); }
.btn--accent { background: var(--accent); color: #fff; }
.btn--accent:hover { background: var(--accent-light); color: #fff; }
.btn--accent:active { background: var(--accent-border); }

/* "Secondary" z briefu — jasne tło + border, przyciemnia się na hover/active.
   Zostaje pod nazwą --ghost (już tak się zachowuje i jest wszędzie używana —
   zmiana nazwy klasy byłaby przebudową 18+ widoków bez żadnej zmiany wyglądu). */
.btn--ghost { background: #fff; border-color: #c6ccd4; color: var(--text); }
.btn--ghost:hover { background: #eceff3; color: var(--text); }
.btn--ghost:active { background: #e3e6eb; }

/* "Soft" z briefu — bardzo jasne tło w kolorze akcentu, tekst w kolorze
   akcentu, delikatne podświetlenie na hover. Nowy wariant (wcześniej nie
   było odpowiednika) — do akcji pomocniczych, mniej ważnych niż Primary,
   ale bardziej wyróżnionych niż Ghost. */
.btn--soft { background: color-mix(in srgb, var(--accent) 12%, var(--surface)); color: var(--accent-border); border-color: transparent; }
.btn--soft:hover { background: color-mix(in srgb, var(--accent) 20%, var(--surface)); color: var(--accent-border); }
.btn--soft:active { background: color-mix(in srgb, var(--accent) 28%, var(--surface)); }

.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { background: var(--danger-d); color: #fff; }
.btn--danger:active { background: #a5271f; }

/* Wyjątek od głównego koloru wiodącego (róż/terakota) — przyciski "+ Dodaj..."
   i awatary zostają w dawnej zieleni na wyraźną prośbę (2026-09-17). */
.btn--add { background: #4a5b6e; color: #fff; }
.btn--add:hover { background: #71958b; color: #fff; }
.btn--add:active { background: #33534c; }
.btn--sm { padding: 5px 10px; font-size: 13px; }
.btn--block { width: 100%; text-align: center; margin-top: 4px; }

/* Icon button — akcje wierszowe w tabelach (podgląd/edycja/duplikuj/usuń),
   ikona zamiast tekstu. Domyślnie "ghost" (przezroczysty), subtelne tło na
   hover. Destrukcyjne akcje (--danger) dostają delikatny czerwony akcent
   TYLKO na hover/focus, nie pełne czerwone tło. */
.btn--icon {
    width: 40px;
    height: 40px;
    padding: 0;
    flex-shrink: 0;
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
}
.btn--icon svg { display: block; }
.btn--icon:hover { background: var(--bg); border-color: var(--border); color: var(--text); }
.btn--icon:active { background: #e8ecf2; }
.btn--icon--danger:hover {
    background: color-mix(in srgb, var(--danger) 12%, transparent);
    border-color: color-mix(in srgb, var(--danger) 30%, transparent);
    color: var(--danger-d);
}
/* .btn--icon samo w sobie nadpisuje tło/kolor na neutralne (bo w arkuszu jest
   NIŻEJ niż .btn--accent) — ten wariant przywraca akcent tam, gdzie ikonka ma
   sygnalizować akcję główną/pilną (np. „Podpisz" przy niepodpisanej umowie),
   a nie zwykłą, drugorzędną (edytuj/pobierz). */
.btn--icon.btn--accent { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn--icon.btn--accent:hover { background: var(--accent-light); color: #fff; border-color: var(--accent-light); }
/* Zielony wariant — odróżnia wizualnie podpis wykonawcy (firmy) od podpisu
   zamawiającego (ten zostaje na kolorze akcentu wyżej), przy dwóch osobnych
   przyciskach „Podpisz" obok siebie w karcie Umowa. */
.btn--icon.btn--ok { background: var(--ok); color: #fff; border-color: var(--ok); }
.btn--icon.btn--ok:hover { background: color-mix(in srgb, var(--ok) 85%, #fff); color: #fff; border-color: var(--ok); }

/* ---------- Tabele ----------------------------------------- */

.table-wrap { overflow-x: auto; }
.table__addrow { margin-top: 10px; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.table th, .table td {
    text-align: left;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.table th {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    background: #eceff3;
    color: var(--text);
    font-weight: 700;
    padding: 16px 12px;
}

/* Sortowalny nagłówek kolumny — wygląda jak zwykły nagłówek (nie link),
   strzałka pokazuje aktualny kierunek; neutralna/przygaszona gdy kolumna nie
   jest aktywnym sortowaniem. */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--text);
    text-decoration: none;
}
.th-sort:hover { color: var(--text); }
.th-sort__icon { font-size: 11px; color: var(--muted); }

/* Podświetlenie dopasowanej frazy wyszukiwania w wynikach (patrz helpers.php highlight()). */
mark {
    background: color-mix(in srgb, var(--accent) 18%, var(--surface));
    color: var(--accent);
    font-weight: 700;
    padding: 0 2px;
    border-radius: 3px;
}

.table tbody tr { transition: background .15s ease; }
.table tbody tr:hover { background: #f7f9fc; }
.table tbody tr[data-href], .table tbody tr[data-drawer-row] { cursor: pointer; }

/* Tabela klucz-wartość (np. szczegóły zlecenia) — jak .table, ale bez
   nagłówka (nie dołączany <thead>) i bez podświetlenia wiersza, bo wiersze
   nie są klikalne. Pierwsza kolumna = etykieta (wąska, wyszarzona), druga =
   wartość (pogrubiona) — ten sam układ co .deflist, tylko jako tabela. */
.table--kv tbody tr:hover { background: transparent; }
.table--kv td:first-child { width: 1%; padding-right: 28px; white-space: nowrap; color: var(--muted); }
.table--kv td:not(:first-child) { font-weight: 600; }

/* Wariant bez żadnych linii między wierszami — wygląda jak zwykły wpis
   danych, nie jak tabela (np. Dane zlecenia, Zamawiający), przy zachowanym
   układzie kolumn etykieta/wartość. Nieco mniejszy padding niż zwykła
   .table. Wybrane wartości (nazwisko, data zlecenia) wyróżnione większą
   czcionką (.val-lg), adres celowo bez pogrubienia (.val-normal). */
.table--kv--plain td { border-bottom: none; padding: 6px 10px; }
.table--kv--plain td.val-lg { font-size: 1.2em; }
.table--kv--plain td.val-normal { font-weight: 400; }

/* Klikalny e-mail/telefon w tabelach szczegółów (np. Zamawiający w
   zleceniu) — wygląda jak zwykły tekst, kolor wiodący dopiero po
   najechaniu, żeby nie zaburzać czarno-szarej tabeli danych. */
.value-link { color: inherit; text-decoration: none; }
.value-link:hover { color: var(--accent); text-decoration: underline; }

/* Nazwa + mały przycisk-ikona w tej samej komórce tabeli (np. "otwórz mapę"
   przy pozycji lokalizacji). */
.name-with-action { display: inline-flex; align-items: center; gap: 4px; }

.table th.col-actions,
.table td.col-actions {
    width: 1px;
    white-space: nowrap;
    text-align: right;
}

.table th.col-realization,
.table td.col-realization {
    width: 1px;
    white-space: nowrap;
}

/* Uchwyt przeciągania wiersza (zmiana kolejności pozycji pakietu) —
   patrz [data-sortable-rows] w app.js. */
.table th.col-drag,
.table td.table__drag { width: 1px; white-space: nowrap; }
.table td.table__drag {
    color: var(--muted);
    cursor: grab;
    text-align: center;
    vertical-align: middle;
}
.table td.table__drag svg { display: block; margin: 0 auto; }
tbody[data-sortable-rows] > tr.is-dragging { opacity: .4; }
tbody[data-sortable-rows] > tr { cursor: default; }

.table__actions { white-space: nowrap; }
.table__actions .btn + .btn,
.table__actions .inline-form + .btn { margin-left: 6px; }
.table__actions .inline-form { margin-left: 6px; }

/* Ikony akcji wierszowych zawsze w pełni widoczne (bez przygaszania domyślnie
   — użytkownik uznał to za mylące/nieczytelne). */
.table tbody tr .table__actions .btn--icon { opacity: 1; }
.inline-form { display: inline; }

/* Etykieta statusu (pill) — wypełnione tło, biała czcionka. */
.tag {
    display: inline-block;
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 999px;
    background: rgba(15, 23, 42, .08);
    color: var(--muted);
    white-space: nowrap;
}

.tag--aktywny    { background: var(--ok); color: #fff; }
.tag--nieaktywny { background: var(--danger-d); color: #fff; }
.tag--warning    { background: var(--warning); color: #fff; }
.tag--danger     { background: var(--danger); color: #fff; }

/* Kropka koloru przed nazwą (rodzaje zleceń itd.) */
.color-dot {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: middle;
}

/* Awatar — inicjały na kolorowym tle (listy/karty klientów, drawer szczegółów). */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #4a5b6e;
    color: #fff;
    font-weight: 700;
    flex-shrink: 0;
}
.avatar--sm { width: 36px; height: 36px; font-size: 13px; }
.avatar--lg { width: 64px; height: 64px; font-size: 22px; }

.drawer-profile { display: flex; flex-direction: column; align-items: center; margin-bottom: 14px; }

/* Imię/nazwa Zamawiającego w drawerze szczegółów klienta — wyśrodkowane,
   pogrubione (patrz Clients/Views/drawer.php). */
.drawer-person { margin-bottom: 4px; text-align: center; }
.drawer-person--left { text-align: left; }
.drawer-person__name { font-size: 18px; font-weight: 700; color: var(--text); }

.drawer-divider { border-top: 1px solid var(--border); margin: 14px 0; }

.drawer-tag-row {
    margin: 10px 0 18px;
    text-align: center;
}
.drawer-tag-row .tag { font-size: 14px; }

/* Wiersz danych z ikoną (E-mail/Telefon/Firma/NIP/Adres/Aktywność) — ikona
   w zaokrąglonym polu z lewej, etykieta nad wartością z prawej. */
.drawer-field {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 14px;
}
.drawer-field__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-top: 2px;
    color: var(--text);
    flex-shrink: 0;
}
.drawer-field__icon svg { width: 19px; height: 19px; }
.drawer-field__label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
    line-height: 1.2;
}
.drawer-field__value { font-size: 14px; color: var(--text); font-weight: 500; margin-top: 0; line-height: 1.2; }
.drawer-field__value .value-link { color: var(--text); }
.drawer-field__value .value-link:hover { color: var(--accent); }

/* Lista pozycji w drawerze (np. zawartość lokalizacji) — karty zamiast
   wąskiej dwukolumnowej tabeli, bo panel z prawej jest za wąski na tabelę. */
.drawer-items { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.drawer-item { padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.drawer-item__name { font-size: 14px; font-weight: 600; color: var(--text); }
.drawer-item__text { font-size: 13px; color: var(--muted); margin-top: 4px; line-height: 1.4; }

.btn--tall { padding: 16px 20px; font-size: 15px; }

/* ---------- Statystyki pulpitu ---------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 18px;
}

/* Szczegóły zlecenia: 4 znane z góry karty (Klient/Data/Rodzaj/Pakiet) —
   węższa Data, szerszy Pakiet (dłuższa nazwa+cena), zamiast równych kolumn. */
.stat-grid--order { grid-template-columns: 1fr .7fr 1fr 1.3fr; }
@media (max-width: 900px) {
    .stat-grid--order { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}

.stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.stat-card__icon {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
    color: #fff;
    margin-bottom: 2px;
}

/* Kolory kółek ikon — dobrane wg referencyjnego mockupu (przygaszona,
   stonowana paleta), NIEZALEŻNE od --accent (osobna, celowo szersza paleta). */
.stat-card__icon--terracotta { background: #b8825a; }
.stat-card__icon--rose       { background: #b97c82; }
.stat-card__icon--teal       { background: #3f6b5c; }
.stat-card__icon--gold       { background: #c9a866; }
.stat-card__icon--slate      { background: #6b7f99; }
/* Dopisek obok wartości (np. „· ofert wysłanych: 3") — mniejszy, stonowany. */
.stat-card__sub { font-size: 13px; font-weight: 400; color: var(--muted); }

.stat-card__label { font-size: 13px; color: var(--muted); }
.stat-card__value { font-size: 26px; font-weight: 700; }
/* Wariant na tekstowe (nie liczbowe) wartości kart — nazwa klienta/pakietu
   bywa długa, 26px jak dla liczb by się nie mieściło (np. szczegóły zlecenia). */
.stat-card__value--text { font-size: 16px; font-weight: 600; line-height: 1.3; }

/* Wariant kart bez etykiety — ikona i wartość obok siebie w jednej linii
   (zamiast ikony nad opisaną etykietą), np. szczegóły zlecenia. */
.stat-card--inline { flex-direction: row; align-items: center; gap: 14px; }
.stat-card--inline .stat-card__icon { margin-bottom: 0; flex-shrink: 0; }

/* Kafelki pulpitu (ikona nad etykietą/wartością/deltą) — ikona z lewej, reszta
   tekstu obok niej (jak .stat-card--inline w szczegółach zlecenia), zamiast
   ikony nad tekstem. Zawsze, na każdej szerokości ekranu. Bez zmiany HTML:
   ikona rozciąga się na 3 wiersze siatki (label/value/delta), a te trzy
   automatycznie trafiają w drugą kolumnę — CSS Grid sam pomija komórki
   zajęte przez ikonę. */
.stat-grid:not(.stat-grid--order) .stat-card {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 14px;
    row-gap: 2px;
    align-items: center;
}
.stat-grid:not(.stat-grid--order) .stat-card__icon {
    grid-column: 1;
    grid-row: 1 / span 3;
    margin-bottom: 0;
}

/* Zamawiający 1/2 obok siebie na szerokim ekranie (szczegóły zlecenia) —
   jedna kolumna, gdy jest tylko jeden zamawiający. */
.orderer-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 24px;
}

/* Nazwa i cena pakietu nad tabelą jego zawartości (szczegóły zlecenia). */
.package-summary {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.package-summary__name { font-size: 15px; font-weight: 600; }
.package-summary__price { font-size: 20px; font-weight: 700; color: var(--text); }

/* Załączniki zlecenia (karta „Pliki", szczegóły zlecenia) — port z SMOK-a. */
.filelist { list-style: none; margin: 0; padding: 0; }
.filelist__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
}
.filelist__item:last-child { border-bottom: 0; }
.filelist__name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-weight: 600;
}
.filelist__meta { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* Klawisz „Wgraj pliki" — <input type="file"> niewidoczny, ale naciągnięty
   na cały przycisk (opacity:0), żeby cały jego obszar był klikalny. */
.filepicker { position: relative; overflow: hidden; }
.filepicker__input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    font-size: 0;
}
.filepicker__name {
    font-size: 13px;
    color: var(--muted);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.filepicker__error { flex-basis: 100%; color: var(--danger-d); font-size: 13px; }
.filepicker__error:empty { display: none; }

/* Notatki do zlecenia — lista wpisów (karta "Notatki", szczegóły zlecenia).
   Wysokość ograniczona do ok. 2 wpisów — po przekroczeniu włącza się
   przewijanie zamiast rozciągania całej karty. */
.order-notes {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-height: 190px;
    overflow-y: auto;
    padding-right: 4px;
}
/* Dwie kolumny: treść (tag/opis/meta) z lewej, akcje z prawej — wąska,
   dokładnie na szerokość jednego przycisku ikonowego, Edytuj/Usuń pod sobą. */
.order-note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
}
.order-note:last-child { padding-bottom: 0; border-bottom: none; }
.order-note__main { flex: 1 1 auto; min-width: 0; }
.order-note__actions { flex-direction: column; flex-shrink: 0; gap: 4px; }
.order-note__content { margin: 6px 0 0; font-size: 13px; color: var(--text); }
.order-note__meta { margin-top: 6px; font-size: 11px; color: var(--muted); }

/* Karta "Finanse" (szczegóły zlecenia) — wartość/wpłacono/pozostało + pasek
   postępu. Kolorystyka celowo stonowana (kolor wiodący appki), bez
   agresywnej zieleni/czerwieni. */
.finance-summary { display: flex; flex-wrap: wrap; gap: 28px; margin-bottom: 16px; }
.finance-summary__item { display: flex; flex-direction: column; gap: 4px; }
.finance-summary__label { font-size: 12px; color: var(--muted); }
.finance-summary__value { font-size: 20px; font-weight: 700; color: var(--text); }
.finance-summary__value--warning { color: var(--warning); }
.finance-summary__value--ok { color: var(--ok); }

.finance-progress { display: flex; align-items: center; gap: 12px; }
.finance-progress__bar {
    flex: 1 1 auto;
    height: 8px;
    border-radius: 999px;
    background: var(--bg);
    overflow: hidden;
}
.finance-progress__fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width .3s ease; }
.finance-progress__fill--over { background: var(--warning); }
/* Karta „Realizacja" (moduł fotografia) — termin minął, nie tylko "za dużo
   wpłacone" jak --over, stąd mocniejszy czerwony zamiast pomarańczowego. */
.finance-progress__fill--danger { background: var(--danger); }
/* Zlecenie zakończone — pasek zawsze pełny i zielony, niezależnie od
   faktycznego terminu (patrz Order::realizationInfo() isCompleted). */
.finance-progress__fill--ok { background: var(--ok); }
.finance-progress__label { flex-shrink: 0; font-size: 12px; font-weight: 600; color: var(--muted); }
.finance-progress__label--danger { color: var(--danger-d); }
.finance-progress__label--ok { color: var(--ok); }

/* Widok komórkowy (karta „Realizacja"/„Finanse" w szczegółach zlecenia) —
   dłuższy napis (np. "zrealizowano w X z Y dni") obok wąskiego paska ściskał
   go do minimum albo wychodził poza kartę; na wąskim ekranie napis schodzi
   pod pasek, na pełną szerokość. */
@media (max-width: 560px) {
    .finance-progress { flex-wrap: wrap; }
    .finance-progress__bar { flex-basis: 100%; }
    .finance-progress__label { flex-basis: 100%; }
}

/* Lista zleceń — mini wykres kołowy „ile dni zostało do realizacji" (moduł
   fotografia, patrz Order::realizationInfo()). Pierścień malowany przez
   conic-gradient (bez SVG), środek wybity kolorem tła karty. Zanim
   wydarzenie nadejdzie, realizacja jeszcze się nie zaczęła — zamiast
   wykresu pokazujemy szarą ikonę zegara. */
.realization-donut {
    position: relative;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: conic-gradient(var(--accent) calc(var(--pct, 0) * 1%), var(--border) 0);
}
.realization-donut--overdue { background: conic-gradient(var(--danger-d) calc(var(--pct, 0) * 1%), var(--border) 0); }
.realization-donut::before {
    content: '';
    position: absolute;
    inset: 5px;
    border-radius: 50%;
    background: var(--surface);
}
.realization-donut__value { position: relative; font-size: 10px; font-weight: 700; color: var(--text); line-height: 1; }
.realization-donut--overdue .realization-donut__value { color: var(--danger-d); }
/* Po terminie — ikona ostrzeżenia zamiast liczby dni (zawsze i tak "0"). */
.realization-donut__warn { position: relative; color: var(--danger-d); }
.realization-clock {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    color: var(--muted);
}
/* Zlecenie zrealizowane — w tym samym miejscu co wykres kołowy, zamiast
   dawnej osobnej kolumny statusu (patrz Orders::index). */
.realization-done {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    color: var(--ok);
}

/* Znacznik „najbliższe zlecenie" (Order::nextUpcoming()) — dostawiany OBOK
   ikony/wykresu realizacji w tej samej komórce, ma się rzucać w oczy na
   liście, stąd nasz czerwony (ten sam co przeterminowana realizacja). */
.realization-cell {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.next-order-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--danger-d);
}

/* Lista zleceń — kompaktowy pasek „% opłacone" (celowo bez kwot, tylko
   procent — patrz Order::financeSummary()). Węższy wariant .finance-progress
   dopasowany do komórki tabeli/karty zamiast pełnej szerokości karty. */
.list-progress { display: flex; align-items: center; gap: 6px; width: 90px; }
.list-progress__bar { flex: 1 1 auto; height: 6px; border-radius: 999px; background: var(--bg); overflow: hidden; }
.list-progress__fill { height: 100%; background: var(--accent); border-radius: 999px; }
.list-progress__fill--over { background: var(--warning); }
.list-progress__fill--ok { background: var(--ok); }
.list-progress__label { flex-shrink: 0; font-size: 11px; font-weight: 600; color: var(--muted); }

/* Tabela wpłat — wysokość ograniczona do ok. 3 wierszy (+ nagłówek), dalej
   przewijanie zamiast rozciągania całej karty. */
.payments-table-wrap,
.extras-table-wrap { max-height: 220px; overflow-y: auto; }
.stat-card__delta { font-size: 12px; font-weight: 600; color: var(--muted); }
.stat-card__delta--up { color: var(--ok); }
.stat-card__delta--down { color: var(--danger-d); }

/* ---------- Szybkie akcje (pulpit) ------------------------ */

.quick-actions { display: flex; flex-direction: column; gap: 8px; }
.quick-actions__btn { justify-content: flex-start; gap: 10px; width: 100%; padding: 10px 14px; }
.quick-actions__btn svg { flex-shrink: 0; }

/* ---------- Mini-kalendarz (pulpit) ----------------------- */

.mini-cal {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
}
.mini-cal__dow {
    text-align: center;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
    padding: 4px 0 6px;
}
.mini-cal__day {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding-bottom: 5px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13px;
    color: var(--text);
    text-decoration: none;
    transition: background .14s ease;
}
.mini-cal__day:hover { background: var(--bg); }
/* Dni spoza bieżącego miesiąca — puste miejsce w siatce (bez numeru, bez
   ramki), żeby nie mylić z faktycznymi dniami miesiąca (patrz Dashboard/index.php). */
.mini-cal__day.is-out { border-color: transparent; }
/* Niedziele/soboty i święta (App\Models\Holiday::isWorkingDay()) — ten sam
   czerwony odcień co pełny moduł Kalendarz (.cal__day.is-off). */
.mini-cal__day.is-off { background: #f7ecec; color: var(--danger-d); }
/* Sobota bez święta — jasnoniebieski, odróżnia od świąt/niedziel (patrz
   .cal__day.is-saturday); jeśli w sobotę wypada święto, wygrywa .is-off. */
.mini-cal__day.is-saturday { background: #e7f0f7; color: var(--info); }
.mini-cal__day.is-today { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
/* Pasek (nie kropka) — dużo lepiej widoczny "na pierwszy rzut oka" niż mała
   kropka, szczególnie na tle .is-off (czerwone) albo .is-today (kolor
   akcentu), gdzie kropka ginęła. Leży NA WIERZCHU tła komórki (osobna
   warstwa), więc działa niezależnie od stanu dnia (weekend/święto/dziś). */
.mini-cal__day { padding-bottom: 5px; }
.mini-cal__dot {
    position: absolute;
    bottom: 3px;
    left: 15%;
    right: 15%;
    height: 4px;
    border-radius: 3px;
    background: var(--accent);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .15);
}
.mini-cal__day.is-today .mini-cal__dot { background: #fff; box-shadow: 0 0 0 1px var(--accent); }

/* ---------- Wykres 6-miesięczny (pulpit) ------------------ */

.mini-chart {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 10px;
    height: 140px;
    margin-top: 8px;
}
.mini-chart__col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1 1 0;
    height: 100%;
}
.mini-chart__bars {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    flex: 1 1 auto;
    width: 100%;
    justify-content: center;
}
.mini-chart__bar {
    width: 9px;
    min-height: 3px;
    border-radius: 3px 3px 0 0;
    transition: height .2s ease;
}
.mini-chart__bar--orders { background: var(--accent-light); }
.mini-chart__bar--revenue { background: var(--rose); }
.mini-chart__bar--inquiries { background: #6b7f99; }
.mini-chart__label { font-size: 11px; color: var(--muted); }

.mini-chart__legend {
    display: flex;
    gap: 16px;
    margin-top: 12px;
    font-size: 12px;
    color: var(--muted);
}
.mini-chart__legend span { display: inline-flex; align-items: center; gap: 6px; }
.mini-chart__swatch { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.mini-chart__swatch--orders { background: var(--accent-light); }
.mini-chart__swatch--revenue { background: var(--rose); }
.mini-chart__swatch--inquiries { background: #6b7f99; }

/* ---------- Najpopularniejsze usługi (pulpit) ------------- */

.top-services { display: flex; flex-direction: column; gap: 14px; }
.top-services__head {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    margin-bottom: 5px;
}
.top-services__track {
    height: 7px;
    background: var(--bg);
    border-radius: 999px;
    overflow: hidden;
}
.top-services__fill {
    height: 100%;
    background: var(--accent);
    border-radius: 999px;
    transition: width .2s ease;
}

/* ---------- Komunikaty ---------------------------------- */

.alert {
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 14px;
    margin-bottom: 14px;
    border: 1px solid transparent;
}

.alert--success { background: #e9f3ec; color: var(--ok); border-color: #c3ddc9; }
.alert--info { background: #e8f1f6; color: var(--info); border-color: #c3d9e6; }
.alert--error { background: #f7ecec; color: var(--danger-d); border-color: #e6c3ca; }
.alert--muted { background: #eceff3; color: var(--muted); border-color: #d3d7dd; }
.alert--warning { background: #f7f0e3; color: var(--warning); border-color: #e6d6b3; }

/* Toast — komunikaty jednorazowe, same znikają (patrz flash.php i
   showToast() w app.js). Stos w prawym dolnym rogu, ponad wszystkim
   (wyżej niż modal — user musi widzieć potwierdzenie nawet z otwartym
   modalem, np. po usunięciu). */
.toast-stack {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 200;
    display: flex;
    flex-direction: column-reverse;
    gap: 8px;
    max-width: min(360px, calc(100vw - 36px));
}
.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--ok);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    font-size: 14px;
    animation: toast-in .18s ease;
}
.toast--info { border-left-color: var(--info); }
.toast--error { border-left-color: var(--danger); }
.toast.is-leaving { animation: toast-out .18s ease forwards; }
.toast__msg { flex: 1 1 auto; }
.toast__close {
    flex-shrink: 0;
    border: 0;
    background: none;
    color: var(--muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    padding: 0 2px;
}
.toast__close:hover { color: var(--text); }
@keyframes toast-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
@keyframes toast-out {
    to { opacity: 0; transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; }
    .toast.is-leaving { animation: none; opacity: 0; }
}

/* ---------- Zakładki (np. Ustawienia) ------------------ */

.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 18px;
}

.tab {
    padding: 9px 14px;
    margin-bottom: -1px;
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}

.tab:hover { color: var(--accent); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- Przełącznik „widok → Edytuj" (data-edit-toggle) ---------- */
/* Domyślnie: widok tylko do odczytu (.js-view) widoczny, formularz (.js-edit)
   ukryty. Klik przycisku [data-edit-toggle] dodaje .is-editing na wskazanym
   zasięgu (jego JS-owa obsługa jest generyczna, patrz app.js) — wtedy się
   zamieniają. Ten sam wzorzec co w Przybył 2026 (tam po tabelach ustawień,
   tu też po całych sekcjach/formularzach jednego rekordu). */
.js-edit { display: none; }
.is-editing .js-view { display: none; }
.is-editing div.js-edit,
.is-editing section.js-edit { display: block; }
.is-editing form.js-edit,
.is-editing div.js-edit.form { display: flex; }
/* Warianty per-komórka tabeli (np. Ustawienia → Dni wolne — każdy wiersz
   swobodnie przełącza podgląd nazwy na pole edycji, bez zagnieżdżonego
   <form> w <table>, patrz komentarz w holidays/index.php). */
.is-editing input.js-edit,
.is-editing span.js-edit { display: inline-block; }
.is-editing td.js-edit,
.is-editing th.js-edit { display: table-cell; }
.is-editing tr.js-edit { display: table-row; }

/* ---------- Paginacja ---------------------------------- */

.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 14px;
    font-size: 13px;
    flex-wrap: wrap;
}

.pager__info { color: var(--muted); }
.pager__links { display: flex; gap: 4px; }
.pager__perpage { display: flex; align-items: center; gap: 4px; }

.pager__link {
    display: inline-block;
    min-width: 30px;
    text-align: center;
    padding: 5px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    text-decoration: none;
    color: var(--text);
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}

.pager__link:not(.is-active):hover { background: #eceff3; color: var(--text); border-color: #c6ccd4; }
.pager__link.is-active { background: var(--primary); color: #fff; border-color: var(--primary); }
.pager__gap { padding: 5px 4px; color: var(--muted); }

/* ---------- Modal ------------------------------------- */

.modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 7vh 16px 16px;
}

.modal[hidden] { display: none; }

/* Płynne pojawianie/znikanie (~180ms) — .is-visible dodawana/usuwana w JS
   (openModal()/closeModal() w app.js), NIE samym [hidden] (na display:none
   nie da się animować przejścia). */
.modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .45);
    opacity: 0;
    transition: opacity .18s ease;
}
.modal.is-visible .modal__backdrop { opacity: 1; }

.modal__dialog {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 520px;
    transition: max-width .15s ease;
    max-height: 86vh;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: 0 12px 44px rgba(15, 23, 42, .28);
    overflow: hidden;
    opacity: 0;
    transform: translateY(-6px) scale(.98);
    transition: opacity .18s ease, transform .18s ease;
}
.modal.is-visible .modal__dialog { opacity: 1; transform: none; }

.modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 13px 18px;
    border-bottom: 1px solid var(--border);
}

/* Wyższy nagłówek niż domyślny — więcej oddechu wokół ikony+tytułu. Dotyczy
   WSZYSTKICH modali z ikoną w tytule (usuwanie, ale też zwykłe dodawanie/
   edycja formularzy — patrz app.js, wariant "confirm" ustawiany w obu
   miejscach dla spójności wysokości). */
.modal--confirm .modal__head { padding: 26px 18px; }

.modal__head-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.modal__title { margin: 0; font-size: 16px; font-weight: 600; }
.modal__title-icon { display: flex; align-items: center; justify-content: center; color: var(--text); flex-shrink: 0; }
.modal__title-icon svg { display: block; width: 18px; height: 18px; }
.modal__title-icon--danger { color: var(--danger-d); }

/* Ten sam wzorzec co ikonowe przyciski akcji w tabelach (.btn--icon) —
   kwadrat, ramka i tło dopiero na hover, zamiast gołego znaku "×". */
.modal__x {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: 20px;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    color: var(--muted);
    transition: background .16s ease, border-color .16s ease, color .16s ease;
}
.modal__x:hover { background: var(--bg); border-color: var(--border); color: var(--text); }

/* Okno w kolorze wiodącym — nagłówek na --accent, biały tytuł/X.
   Domyślne dla wszystkich okien modalnych (edycja/zapis/usuwanie). */
.modal--accent .modal__head { background: var(--accent); border-bottom-color: var(--accent-d); }
.modal--accent .modal__title { color: #fff; }
.modal--accent .modal__x { color: rgba(255, 255, 255, .8); }
.modal--accent .modal__x:hover { color: #fff; }

/* Szerszy wariant — formularze z kilkoma polami w jednej linii (np. dodawanie/
   edycja klienta), żeby krótkie pola (kod pocztowy, miasto...) nie musiały
   rozciągać się na całą szerokość ekranu. Włączany przez [data-modal-wide]
   na linku otwierającym formularz. */
.modal--wide .modal__dialog { max-width: 720px; }

/* Jeszcze szerszy wariant — formularze z tabelą wielu kolumn (np. zawartość
   lokalizacji: uchwyt+godzina+nazwa+adres+link+usuń), gdzie nawet .modal--wide
   ciasno ściska pola. Włączany przez [data-modal-xwide]. */
.modal--xwide .modal__dialog { max-width: 1040px; }

.modal__body { padding: 18px; overflow-y: auto; }
.modal__body > .card,
.modal__body > .card--narrow { border: 0; box-shadow: none; padding: 0; margin: 0; max-width: none; }

body.modal-open { overflow: hidden; }

/* ---------- Panel wysuwany z prawej (drawer) ---------- */

.drawer { position: fixed; inset: 0; z-index: 90; display: flex; justify-content: flex-end; }
.drawer[hidden] { display: none; }

.drawer__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .45);
    opacity: 0;
    transition: opacity .2s ease;
}
.drawer.is-visible .drawer__backdrop { opacity: 1; }

.drawer__panel {
    position: relative;
    width: 100%;
    max-width: 420px;
    height: 100%;
    background: var(--surface);
    box-shadow: -12px 0 44px rgba(15, 23, 42, .16);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform .2s ease;
}
.drawer.is-visible .drawer__panel { transform: translateX(0); }

.drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.drawer__title { margin: 0; font-size: 16px; font-weight: 600; }
.drawer__x { border: 0; background: none; font-size: 22px; line-height: 1; padding: 0 4px; cursor: pointer; color: var(--muted); }
.drawer__x:hover { color: var(--text); }

.drawer__body { padding: 20px; flex: 1 1 auto; overflow-y: auto; }

@media (max-width: 560px) {
    .drawer__panel { max-width: 100%; }
}

/* ---------- Nakładka „przetwarzanie" ------------------ */

.overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(15, 23, 42, .38);
}

.overlay[hidden] { display: none; }

.overlay__spinner {
    width: 46px;
    height: 46px;
    border: 4px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: overlay-spin .75s linear infinite;
}

@keyframes overlay-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .overlay__spinner { animation-duration: 2s; }
}

/* ---------- Wąskie ekrany ----------------------------- */

@media (max-width: 820px) {
    .topbar__toggle { display: block; }

    .sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 40;
        transform: translateX(-100%);
        transition: transform .18s ease;
    }

    .sidebar.is-open { transform: translateX(0); }
}

/* Link "powrót" nad nagłówkiem strony (np. szczegóły zlecenia) — zwykły,
   dyskretny tekst, nie przycisk. */
.back-link {
    display: inline-block;
    margin-bottom: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
}
.back-link:hover { color: var(--accent); }

/* ---------- Nagłówek strony (np. Klienci) ----------------- */

.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.page-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.page-head__title-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-head__title { margin: 0; font-size: 19px; }
.page-head__subtitle { margin: 0; color: var(--muted); font-size: 13px; }

/* ---------- Lista Klientów: komórka "Klient" + widok kart --- */

/* Kolumny mieszczą się bez przewijania, a poniżej 720px tabela i tak znika
   na rzecz .client-cards — poziomy scroll z .table-wrap tu niepotrzebny. */
.client-table-wrap { overflow: visible; }

/* Wyjątek: tabela Umowa (Nr umowy + Szablon + Status obu stron + do 4 ikon
   akcji) bywa szersza niż karta zlecenia — bez poziomego scrolla wiersz
   wychodził poza kontener karty zamiast się zawinąć/przewinąć. */
.contracts-table-wrap { overflow-x: auto; }

/* Te same tabele (Lokalizacji: Godzina/Nazwa/Adres i Pakietu usług:
   Usługa/Opis) w szczegółach zlecenia (panel) i publicznym podglądzie
   klienta (ClientPortal) — karty siedzą w węższej kolumnie .detail-grid__stack,
   więc długi adres/opis bywa szerszy niż karta. Zamiast poziomego scrolla
   (jak przy Umowie wyżej) komórki się zawijają — adres/opis to zwykle jedna
   dłuższa fraza, czytelniej ją zawinąć niż przewijać całą tabelę. Komórka
   mobilna zostaje bez zmian (.client-cards poniżej 720px, jak wszędzie indziej). */
.locations-table-wrap .table td,
.package-items-table-wrap .table td { white-space: normal; }

.client-cell { display: flex; align-items: center; gap: 10px; }

/* Druga, dyskretna linia pod główną wartością komórki (np. data + "X dni
   temu" w kolumnie Ostatnia aktywność) — generyczne, wielokrotnego użytku. */
.cell-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Grupa akcji Edytuj/Usuń (lista Klientów, tabela i karty mobilne) — stały
   odstęp między ikonami niezależny od gapu rodzica. */
.row-actions { display: inline-flex; align-items: center; gap: 12px; flex-shrink: 0; }
/* Karta „Umowa" w szczegółach zlecenia (widok mobilny) potrafi mieć 4-5
   ikon na wiersz (wypowiedzenie/podpisy/wyślij/pobierz/usuń) — za dużo na
   wąski ekran obok nazwy w .client-card__top. Zamiast wypychać poza kartę,
   ten wariant stoi jako WŁASNY, pełnej szerokości wiersz POD nazwą (patrz
   Orders/show.php) i swobodnie zawija się na kolejne linie. */
.row-actions--wrap { flex-wrap: wrap; width: 100%; flex-shrink: 1; gap: 8px; margin-top: 2px; }
.client-cell__name { font-weight: 600; }
.client-cell__email { font-size: 12px; color: var(--muted); }

.client-cards { display: none; flex-direction: column; gap: 10px; }

.client-card {
    display: block;
    width: 100%;
    text-align: left;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px;
    background: var(--surface);
    transition: background .14s ease;
}
.client-card[data-href], .client-card[data-drawer-row] { cursor: pointer; }
.client-card[data-href]:hover, .client-card[data-drawer-row]:hover { background: var(--bg); }
.client-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
/* Nazwa/e-mail w nagłówku karty mogą się zwężać i zawijać (min-width:0 —
   domyślnie flex-item nie schodzi poniżej szerokości treści), żeby długi
   e-mail nie wypychał ikon akcji (.row-actions) poza kartę. */
.client-card__top > .client-cell { flex: 1 1 auto; min-width: 0; }
.client-card__top > .client-cell > div { min-width: 0; }
.client-card__top .client-cell__name,
.client-card__top .client-cell__email { overflow-wrap: anywhere; }
.client-card__meta { margin: 0; display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.client-card__meta > div { display: flex; justify-content: space-between; gap: 10px; }
.client-card__meta dt { color: var(--muted); font-weight: 400; }
.client-card__meta dd { margin: 0; font-weight: 500; }

@media (max-width: 720px) {
    .client-table-wrap { display: none; }
    .client-cards { display: flex; }
    .list-toolbar__actions { width: 100%; margin-left: 0; }
    .list-toolbar__select { width: 100%; }

    /* Telefon: przyciski nagłówka strony i sekcji kart (Edytuj, Dodaj…,
       Wgraj pliki…) na całą szerokość, każdy w swojej linii. Wyjątek:
       „Wyślij link podglądu" + „Informacja o zleceniu" dzielą jedną linię
       ~80/20 (szczegóły zlecenia). */
    .page-head__actions { width: 100%; }
    .list-toolbar__actions { flex-wrap: wrap; }
    .page-head__actions > .btn,
    .page-head__actions > form,
    .list-toolbar__actions > .btn,
    .list-toolbar__actions > form { flex: 1 1 100%; }
    .page-head__actions > form .btn,
    .list-toolbar__actions > form .btn { width: 100%; }
    /* Wszystkie przyciski nagłówka strony (Dodaj rezerwację/zlecenie/
       klienta…) i sekcji (Kartoteka klienta, Dodaj notatkę/koszt, Edytuj
       lokalizację…) tej samej wysokości co .btn--tall. */
    .page-head__actions > .btn,
    .page-head__actions > form .btn,
    .list-toolbar__actions > .btn,
    .list-toolbar__actions > form .btn { padding: 16px 20px; font-size: 15px; }
    /* Przyciski pod formularzami (Zapisz/Anuluj/Usuń — strony i modale)
       i szybkie akcje pulpitu — analogicznie: pełna szerokość, wysokość
       .btn--tall. Modal potwierdzenia (.form__actions--confirm) zostaje
       z dwoma przyciskami obok siebie. */
    .form__actions:not(.form__actions--confirm) > .btn,
    .form__actions:not(.form__actions--confirm) > form { flex: 1 1 100%; margin-left: 0; }
    .form__actions:not(.form__actions--confirm) > form .btn { width: 100%; }
    .form__actions .btn,
    .quick-actions__btn { padding: 16px 20px; font-size: 15px; }
    /* Przycisk wstawiony wprost w .page-head (bez .page-head__actions —
       Użytkownicy, Klienci, Kalendarz, podglądy w Ustawieniach) i przyciski
       pustego stanu listy („Dodaj pierwszego…") — tak samo. */
    .page-head > .btn,
    .empty-state .btn { width: 100%; padding: 16px 20px; font-size: 15px; }
    .page-head__actions > .page-head__share { flex: 4 1 0; min-width: 0; }
    .page-head__actions > .page-head__info { flex: 1 1 0; min-width: 0; }
}

/* ---------- Pusty stan (np. brak klientów / brak wyników) --- */

.empty-state {
    text-align: center;
    padding: 48px 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}
.empty-state__title { margin: 0; font-size: 16px; font-weight: 600; }
.empty-state__text { margin: 0 0 10px; color: var(--muted); font-size: 14px; }


/* =====================================================================
   KOMPONENTY PRZYBYŁA (nie ma ich w MAM ZAPISANE) — przeniesione bez zmian
   z poprzedniego arkusza. Kolory z tokenów :root na górze pliku.
   ===================================================================== */

/* Logo firmy — poziomy prostokąt (assets/img/logo.png) */
.auth__logo-img {
    display: block;
    max-width: 240px;
    max-height: 72px;
    width: auto;
    height: auto;
}

.auth__name { font-weight: 700; font-size: 17px; }
.auth__title { font-size: 16px; margin: 0 0 14px; }
.auth__foot { color: var(--muted); font-size: 13px; margin-top: 16px; }

.badge {
    display: inline-block;
    padding: 2px 7px;
    font-size: 11px;
    font-weight: 600;
    border-radius: 999px;
    background: rgba(47, 95, 218, .12);
    color: var(--primary-d);
}

/* Rola przy koncie (pasek górny) — jak status aktywny/nieaktywny: wypełnione
   tło, biała czcionka. Admin = ciemnoczerwony, Użytkownik = ciemnozielony,
   Pracownik = ciemnopomarańczowy. */
.badge--role-admin    { background: var(--danger-d); color: #fff; }
.badge--role-user     { background: var(--ok); color: #fff; }
.badge--role-employee { background: #a3480a; color: #fff; }

/* Pasek podnawigacji — pod górnym paskiem, cała szerokość, ciemniejszy.
   Mieści (po prawej) przycisk „Powrót". */
.subnav {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 22px;
    min-height: 46px;
    background: #e8ecf2;
    border-bottom: 1px solid var(--border);
}

.subnav__title { font-size: 13px; color: var(--muted); }
.subnav__back { margin-left: auto; }

/* Status sprawdzenia lokalizacji w formularzach Start/Stop (moduł Praca). */
.geo-check { margin-top: 4px; }
.geo-check__status { font-size: 13px; }
.geo-check__status.is-ok { color: var(--ok); font-weight: 600; }
.geo-check__status.is-error { color: var(--danger-d); font-weight: 600; }

/* Odsuwa przycisk (zwykle destrukcyjny) na prawą stronę rzędu akcji */
.btn--right { margin-left: auto; }

/* Nazwiska osób — wszędzie pogrubione; jako link bez podkreślenia */
.name { font-weight: 700; }
a.name { color: var(--text); text-decoration: none; }
a.name:hover { color: var(--primary); }

/* Osobna akcja (np. „Usuń wpis") pod głównym formularzem w tej samej karcie. */
.form__subhead-actions { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }

/* ---------- Datepicker (dd.mm.rrrr) ------------------------- */

.dp-field { position: relative; display: block; }
.dp-field .dp__input { padding-right: 36px; }
/* Węższe pole daty (.form__input--narrow) — otoczka ma się kurczyć razem z nim,
   inaczej klawisz kalendarza „odklei się" po prawej stronie komórki. */
.dp-field:has(.form__input--narrow) { display: inline-block; width: auto; }

.dp__toggle {
    position: absolute;
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    border-radius: 0 6px 6px 0;
}

.dp__toggle:hover { color: var(--primary); }
.dp__toggle svg { width: 16px; height: 16px; }

.dp {
    position: absolute;
    z-index: 150;
    width: 250px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 9px;
    box-shadow: 0 8px 28px rgba(15, 23, 42, .18);
    user-select: none;
}

.dp__head { display: flex; align-items: center; gap: 2px; margin-bottom: 6px; }

.dp__title {
    flex: 1;
    text-align: center;
    font-weight: 700;
    font-size: 13px;
    text-transform: capitalize;
}

.dp__nav {
    width: 24px;
    height: 24px;
    border: 0;
    background: transparent;
    color: var(--muted);
    border-radius: 6px;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.dp__nav:hover { background: #eef1f6; color: var(--text); }

.dp__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }

.dp__dow {
    text-align: center;
    font-size: 10px;
    text-transform: uppercase;
    color: var(--muted);
    padding: 2px 0 4px;
}

.dp__day {
    height: 30px;
    border: 0;
    background: transparent;
    color: var(--text);
    border-radius: 6px;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.dp__day:hover:not(:disabled) { background: #eef1f6; }
.dp__day.is-out { color: #b7bec8; }
.dp__day.is-today { box-shadow: inset 0 0 0 1px var(--primary); }
.dp__day.is-sel { background: var(--primary); color: #fff; }
.dp__day:disabled { color: #cfd4dc; cursor: default; }

/* Kolumna statusu (np. wniosku urlopowego) — wyrównana do prawej */
.table th.col-status,
.table td.col-status { text-align: right; }

/* Przyciski Edytuj / Usuń w jednej linii, dosunięte do prawej */
.table__actions { white-space: nowrap; }
.table__actions .btn { vertical-align: middle; }
.table__actions .btn + .btn,
.table__actions .inline-form + .btn { margin-left: 6px; }
.table__actions .inline-form { margin-left: 6px; }

/* Rząd przycisków akcji (np. zarządzanie dostępem) */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.btn-row .inline-form { display: inline; }
.inline-form { display: inline; }

/* Zasada dla statusów aktywny/nieaktywny (dowolna zakładka) — wypełnione tło,
   biała czcionka, zamiast dawnego jasnego tła + kolorowego tekstu. */
.tag--aktywny    { background: var(--ok); color: #fff; }
.tag--nieaktywny { background: var(--danger-d); color: #fff; }
.tag--archiwum   { background: #eceff3; color: var(--muted); }

/* Status wniosku urlopowego — ta sama zasada co aktywny/nieaktywny: wypełnione
   tło, biała czcionka. Oczekujący w tym samym odcieniu co rola „Pracownik". */
.tag--leave-zatwierdzony { background: var(--ok); color: #fff; }
.tag--leave-oczekujacy   { background: #a3480a; color: #fff; }
.tag--leave-odrzucony    { background: var(--danger-d); color: #fff; }
.tag--leave-anulowany    { background: #eceff3; color: var(--muted); }

.tag--veh-aktywny    { background: var(--ok); color: #fff; }
.tag--veh-w_naprawie { background: #fff4e0; color: #8a5a00; }
.tag--veh-wycofany   { background: #eceff3; color: var(--muted); }

/* Status wpisu czasu pracy — ta sama triada co wnioski urlopowe, plus
   „w toku" (zmiana jeszcze trwa) w kolorze wiodącym. */
.tag--work-w_toku      { background: var(--primary); color: #fff; }
.tag--work-zatwierdzony { background: var(--ok); color: #fff; }
.tag--work-oczekujacy   { background: #a3480a; color: #fff; }
.tag--work-odrzucony    { background: var(--danger-d); color: #fff; }

/* Status wpisu badania/uprawnienia — ta sama triada co reszta apki. */
.tag--check-ok              { background: var(--ok); color: #fff; }
.tag--check-wygasa          { background: #a3480a; color: #fff; }
.tag--check-przeterminowane { background: var(--danger-d); color: #fff; }

/* Wartość ujemna (np. przekroczone saldo urlopu) */
.is-negative { color: var(--danger); font-weight: 700; }

/* Formularz w jednej linii (np. edycja nazwy dnia wolnego) */
.form-inline { display: flex; gap: 6px; align-items: center; }
.form__input--inline { width: auto; flex: 1 1 auto; min-width: 0; }
.form__input--narrow { width: 130px !important; }

/* Kolumna „Data" (Dni wolne) — szerokość stała, żeby dodanie dynamicznego
   wiersza z polem daty (szerszym niż zwykły tekst) nie przesuwało tabeli.
   min-width = suma szerokości kolumn z <colgroup>: bez tego table-layout:
   fixed + width:100% na wąskim ekranie ściskały kolumny poniżej deklarowanej
   szerokości (tekst z nich, nadal nowrap, nachodził na sąsiednie komórki)
   zamiast pozwolić tabeli po prostu przewinąć się w poziomie (.table-wrap). */
#holidaysTable { table-layout: fixed; min-width: 640px; }
#holidaysTable td:nth-child(3) { white-space: normal; } /* dłuższa nazwa niech się zawija, nie zachodzi na sąsiada */

#vehicleTypesTable { table-layout: fixed; min-width: 320px; }
#vehicleTypesTable td:nth-child(1) { white-space: normal; }

/* Kolumna „Akcje" (Dni wolne, Rodzaje pojazdów) — poza edycją całkiem zwinięta
   (`<col class="js-edit-col">` w widoku), więc tabela w podglądzie zajmuje
   pełną szerokość; dopiero „Edycja ustawień" (klasa .is-editing na panelu)
   rozwija ją razem z nagłówkiem i klawiszami „Usuń" (patrz .js-edit). */
.js-edit-col { width: 0; }
.is-editing .js-edit-col { width: 90px; }

/* ---------- Statystyki pulpitu ---------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
}

.stat {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.stat__value { font-size: 24px; font-weight: 700; }
.stat__label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }

/* Tykający licznik „w pracy od" (moduł Czas pracy) */
.work-timer { margin: 4px 0 14px; }
.work-timer .js-live-timer {
    display: inline-block;
    font-size: 32px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

/* Ikona stopera przed licznikiem czasu w tabelach (np. lista Pracownicy) */
.worktimer-icon { margin-right: 3px; }

/* ---------- Wyszukiwarka --------------------------------- */

.searchbar { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.searchbar__input {
    font: inherit;
    padding: 6px 10px;
    border: 1px solid #cbd2db;
    border-radius: 7px;
}

/* Pasek narzędzi nad tabelą — pola i przyciski tej samej wysokości */
.card__actions { align-items: center; }
.searchbar__input,
.searchbar .btn,
.card__actions > .btn {
    height: var(--control-h);
    line-height: 1;
}

/* ---------- Kalendarz (widok miesięczny) -------------- */

.cal__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.cal__nav { display: flex; align-items: center; gap: 8px; }
.cal__nav .btn,
.cal__bar > .btn { height: var(--control-h); }
.cal__month { min-width: 170px; text-align: center; font-size: 16px; }

.cal__grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.cal__dow {
    background: var(--bg);
    padding: 6px 8px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
    text-align: center;
}

.cal__day {
    background: var(--surface);
    min-height: 108px;
    padding: 4px 5px 6px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.cal__day.is-out { background: var(--bg); }
.cal__day.is-today { box-shadow: inset 0 0 0 2px var(--primary); }
.cal__day[data-day] { cursor: pointer; }

/* Dni wolne od pracy (weekendy + święta) — na czerwono */
.cal__day.is-off { background: #fdf3f3; }

.cal__daynum {
    align-self: flex-start;
    min-width: 22px;
    height: 22px;
    line-height: 22px;
    text-align: center;
    font-size: 12px;
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
    border-radius: 50%;
}

.cal__day.is-out .cal__daynum { color: var(--muted); }
.cal__day.is-off .cal__daynum { color: var(--danger); }
.cal__daynum:hover { background: var(--primary); color: #fff; }
.cal__wd { display: none; } /* nazwa dnia tygodnia przy numerze — widoczna tylko w widoku listy (mobile) */

.cal__events { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.cal__event {
    display: block;
    padding: 2px 6px;
    font-size: 12px;
    line-height: 1.35;
    border-radius: 4px;
    border: 1px solid #bcd3fb;
    background: #e8f0fe;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cal__event:hover { filter: brightness(0.96); }
.cal__event.is-multi { border-radius: 3px; }
.cal__time { font-weight: 700; margin-right: 4px; }

/* Urlop na kalendarzu — osobny styl względem zwykłych wydarzeń */
span.cal__event { cursor: default; }
.cal__event--leave { background: #eef6ec; border-color: #cbe4c1; color: #1f5130; }
.cal__event--leave-oczekujacy {
    background: repeating-linear-gradient(45deg, #f4f8f2, #f4f8f2 5px, #e8f1e4 5px, #e8f1e4 10px);
    border-style: dashed;
    color: #4a5b44;
}

/* Zwolnienie lekarskie (L4) — inny kolor niż urlop */
.cal__event--l4 { background: #e6effb; border-color: #b9d3ee; color: #1c4e80; }

/* Miesiąc na telefonie: siatka 7×6 robi się za ciasna (kwadraty ~45px,
   ucięte tytuły wydarzeń) — zamiast niej pionowa lista, jeden dzień pod
   drugim, na pełną szerokość. Dni spoza miesiąca (dopełniające siatkę)
   są tu zbędne — ukryte. Nazwa dnia tygodnia (.cal__wd) dopisana przy
   dacie, bo nagłówek pn–nd (kolumnowy) już nie pasuje. */
@media (max-width: 720px) {
    .cal__grid {
        display: block;
        background: none;
        border: none;
        border-radius: 0;
    }
    .cal__dow { display: none; }
    .cal__day.is-out { display: none; }

    .cal__day {
        flex-direction: row;
        align-items: flex-start;
        gap: 10px;
        min-height: 0;
        padding: 10px 4px;
        border-bottom: 1px solid var(--border);
    }

    .cal__daynum {
        flex: 0 0 auto;
        align-self: auto;
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 38px;
        height: auto;
        line-height: 1.2;
        padding: 4px 0;
        border-radius: 8px;
    }
    .cal__wd {
        display: block;
        font-size: 10px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .02em;
    }
    .cal__day.is-off .cal__wd { color: var(--danger); }
    .cal__daynum:hover { background: none; color: inherit; }
    .cal__day.is-today .cal__daynum,
    .cal__day.is-today .cal__wd { background: var(--primary); color: #fff; }
    .cal__day.is-today .cal__wd { background: none; }

    .cal__events { flex: 1 1 auto; min-height: 22px; justify-content: center; }
    .cal__event {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-size: 12px;
        padding: 3px 8px;
    }
}

/* ---------- Podgląd terminu urlopu (mini-kalendarz w modalu) ---------- */

.term-cal,
.day-detail { max-width: none; }
.modal__dialog:has(.term-cal) { max-width: 760px; }
.modal__dialog:has(.day-detail) { max-width: 620px; }

/* ---------- Szczegóły dnia (modal kalendarza) ---------- */

.daylist { list-style: none; margin: 0 0 6px; padding: 0; display: flex; flex-direction: column; gap: 10px; }

.daylist__item { display: flex; gap: 10px; }

.daylist__dot {
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    margin-top: 5px;
    border-radius: 50%;
    background: var(--primary);
}

.daylist__dot--leave { background: #1f7a44; }
.daylist__dot--l4 { background: #1c4e80; }

.daylist__body { min-width: 0; }
.daylist__row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.daylist__when { font-weight: 700; font-size: 13px; white-space: nowrap; }
.daylist__title { font-size: 14px; }
.daylist__desc { margin: 3px 0 0; font-size: 13px; color: var(--muted); }

.mcal { margin-bottom: 16px; }
.mcal__month { font-weight: 700; font-size: 14px; margin: 0 0 6px; }

.mcal__grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}

.mcal__dow {
    background: var(--bg);
    text-align: center;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
    padding: 3px 0;
}

.mcal__day {
    background: var(--surface);
    min-height: 56px;
    padding: 2px 3px 3px;
}

.mcal__day.is-out { background: var(--bg); }
.mcal__day.is-off { background: #fdf3f3; }
.mcal__day.is-full { background: #fdecec; }
.mcal__day.in-req { box-shadow: inset 0 0 0 2px var(--primary); }
.mcal__day.is-today { box-shadow: inset 0 0 0 2px var(--primary); }

/* ---------- Kalendarz — widok roku (3 miesiące w linii) --------- */

.ycal {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px 24px;
}

@media (max-width: 900px) {
    .ycal { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .ycal { grid-template-columns: 1fr; }
}

.ycal .mcal__day {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 28px;
    padding: 3px 0 0;
    text-decoration: none;
    cursor: pointer;
}
.ycal .mcal__day:hover { box-shadow: inset 0 0 0 1px var(--primary); }

.ycal__dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--primary);
    margin-top: 2px;
}

.mcal__num { font-size: 10px; font-weight: 700; color: var(--muted); }
.mcal__day.is-out .mcal__num { color: #b7bec8; }
.mcal__day.is-off .mcal__num { color: var(--danger); }
.mcal__day.is-full .mcal__num { color: var(--danger-d); }

.mcal__names { display: flex; flex-direction: column; gap: 1px; margin-top: 1px; }

.mcal__name {
    font-size: 11px;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mcal__name--zatwierdzony { color: #1f7a44; }
.mcal__name--oczekujacy  { color: #8a5a00; }
.mcal__name--l4 { color: #1c4e80; }
.mcal__name--self { font-weight: 700; text-decoration: underline; }


/* Przełącznik edycji — przyciski/linki pokazywane dopiero w trybie edycji (np. „Usuń" w Dni wolne). */
.is-editing button.js-edit,
.is-editing a.js-edit,
.is-editing label.js-edit { display: inline-flex; }
.js-edit-col { width: 0; }
.is-editing .js-edit-col { width: 90px; }

/* Górny pasek: tytuł bieżącej strony (Przybył — strony nie mają jeszcze
   własnego nagłówka .page-head) + rola konta przy nazwie w menu użytkownika. */
.topbar__title { margin: 0; font-size: 17px; font-weight: 700; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu__role { display: block; padding: 10px 14px 6px; font-size: 12px; color: var(--muted); }
/* Strona z własnym nagłówkiem (.page-head) — tytuł w górnym pasku zbędny (nie dublujemy). */
.app__main:has(.page-head) .topbar__title { visibility: hidden; }

/* =====================================================================
   KOLORY KLAWISZY — jak w poprzedniej wersji Przybyła (bordo), na prośbę
   2026-09-28. Kształty/odstępy/ikony zostają z MAM ZAPISANE, nadpisane są
   tylko kolory: bordo zamiast szaroniebieskiego „Dodaj…", hover CIEMNIEJSZY
   (jak dawniej), klawisze paska narzędzi z dawnymi gradientami.
   ===================================================================== */
.btn--accent,
.btn--add { background: var(--accent); color: #fff; }
.btn--accent:hover,
.btn--add:hover { background: var(--accent-d); color: #fff; }
.btn--accent:active,
.btn--add:active { background: #3d0e15; }
.btn--primary:hover { background: var(--primary-d); color: #fff; }
.btn--primary:active { background: var(--primary-d); }
.btn--ghost { background: #fff; border-color: #cbd2db; color: var(--text); }
.btn--ghost:hover { background: #f1f3f6; }

.toolbar__btn {
    border-left: 1px solid #c6ccd4;
    border-right: 1px solid #c6ccd4;
    background: linear-gradient(to bottom, #e3e6eb, #d3d7dd);
    color: var(--text);
}
.toolbar__btn:hover { background: linear-gradient(to bottom, #aab1bd, #c7cdd6); }
.toolbar__btn:active { background: linear-gradient(to bottom, #99a1ae, #b8bfc9); }
.toolbar__btn--accent {
    color: #fff;
    border-left: 1px solid var(--accent-border);
    border-right: 1px solid var(--accent-border);
    background: linear-gradient(to bottom, #98283a, var(--accent));
}
.toolbar__btn--accent:hover { background: linear-gradient(to bottom, #3d0e15, #551620); }
.toolbar__btn--accent:active { background: linear-gradient(to bottom, #2e0a10, var(--accent-d)); }

/* Zwijana sekcja formularza (<details class="form-section">) — np. dane z
   dowodu / masy / wymiana oleju w formularzu pojazdu. */
.form-section { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.form-section[open] { background: #f7f9fc; }
.form-section__head { padding: 12px 14px; font-weight: 600; cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; }
.form-section__head::-webkit-details-marker { display: none; }
.form-section__head::before { content: "▸"; color: var(--muted); transition: transform .15s ease; }
.form-section[open] > .form-section__head::before { transform: rotate(90deg); }
.form-section__body { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 12px; }
/* Ikona akcji pozytywnej (np. „Zatwierdź" wniosek urlopowy) — zielona, jak --danger jest czerwona. */
.btn--icon.btn--icon--ok { color: var(--ok); }
.btn--icon.btn--icon--ok:hover { background: #e7f6ec; color: var(--ok); }
/* Filtry listy urlopów — kilka selectów w jednym rzędzie, zawijają się na węższym ekranie. */
/* Komputer: wszystkie w jednym rzędzie, dosunięte do prawej; telefon: jeden pod drugim. */
.list-toolbar > .list-filters { flex-wrap: nowrap; margin-left: auto; justify-content: flex-end; }
.list-filters .list-toolbar__select { width: 210px; min-width: 0; flex: 0 1 210px; }
@media (max-width: 720px) {
    .list-toolbar > .list-filters { flex-wrap: wrap; margin-left: 0; }
    .list-filters .list-toolbar__select { width: 100%; flex: 1 1 100%; }
}
/* Pulpit Przybyła: kółko ikony w kolorze wiodącym + kafelki nie szersze niż potrzeba. */
.stat-card__icon--accent { background: var(--accent); }
.stat-grid--dash { grid-template-columns: repeat(auto-fit, minmax(240px, 320px)); margin-bottom: 18px; }
a.stat-card__delta { color: var(--primary); text-decoration: none; font-size: 13px; }
a.stat-card__delta:hover { text-decoration: underline; }

/* Linki w treści — bordo (kolor wiodący Przybyła) zamiast niebieskiego, na prośbę 2026-09-28.
   Przyciski, menu i paski narzędzi mają własne kolory i tego nie dziedziczą. */
a { color: var(--accent); }
a:hover { color: var(--accent-d); }
a.stat-card__delta,
.attention__meta a,
.value-link { color: var(--accent); }
a.name:hover { color: var(--accent); }

/* ---------- Tankowanie ---------------------------------------------- */
.fuel-stats { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
/* Ikona rodzaju wpisu w kółku: pojazd bordo, pracownik grafit, inne szary,
   napełnienie zielony, korekta niebieski. */
.fuel-type { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 30px; height: 30px; border-radius: 50%; color: #fff; }
.fuel-type--vehicle    { background: var(--accent); }
.fuel-type--employee   { background: #4a5b6e; }
.fuel-type--other      { background: #99a1ae; }
.fuel-type--refill     { background: var(--ok); }
.fuel-type--correction { background: var(--primary); }
.fuel-liters { font-weight: 700; white-space: nowrap; }
.fuel-liters--out { color: var(--danger-d); }
.fuel-liters--in  { color: var(--ok); }
.fuel-warn { color: var(--warning); margin: -4px 0 0; }
.fuel-summary { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 12px 14px; border-radius: var(--radius-sm);
    background: #f7f9fc; border: 1px solid var(--border); font-size: 14px; }
.fuel-summary [data-fuel-result] { font-weight: 600; }
.fuel-last { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: -4px 0 0; }

/* Powiadomienia push — Ustawienia → Powiadomienia (wzór: MAM ZAPISANE) */
.push-prefs { display: flex; flex-direction: column; gap: 8px; }
.push-pref { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; }
.push-pref:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.push-pref input { flex-shrink: 0; width: 18px; height: 18px; margin-top: 2px; accent-color: var(--accent); }
.push-pref__label { display: block; font-weight: 600; }
.push-pref__hint { display: block; font-size: 13px; color: var(--muted); }

/* Karty (widok komórkowy) — klawisze akcji na samym dole karty */
.client-card__actions { display: flex; justify-content: flex-end; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.client-card__actions:not(:has(.row-actions > *)) { display: none; }

/* Rozpocznij / Zakończ pracę (Pulpit, Moje dane) — na telefonie na całą szerokość */
@media (max-width: 720px) {
    .btn--work { display: flex; width: 100%; justify-content: center; padding-top: 24px; padding-bottom: 24px; font-size: 17px; }
}

/* Użytkownicy → Dostęp do modułów (Pełne prawa / Tylko odczyt / Brak dostępu) */
.access-grid { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.access-grid[hidden] { display: none; }
.access-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.access-row__label { min-width: 0; }
.access-row__name { display: block; font-weight: 600; }
.access-row__hint { display: block; font-size: 12px; color: var(--muted); }
.form__input.access-row__select { width: 170px; flex-shrink: 0; }
.access-row__select--manage { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.access-row__select--none { color: var(--muted); }
.access-summary { font-size: 12px; color: var(--muted); }
@media (max-width: 560px) {
    .access-row { flex-direction: column; align-items: stretch; }
    .form__input.access-row__select { width: 100%; }
}
/* ---------- Panel wysuwany z prawej (drawer) ---------- */

.drawer { position: fixed; inset: 0; z-index: 90; display: flex; justify-content: flex-end; }
.drawer[hidden] { display: none; }

.drawer__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .45);
    opacity: 0;
    transition: opacity .2s ease;
}
.drawer.is-visible .drawer__backdrop { opacity: 1; }

.drawer__panel {
    position: relative;
    width: 100%;
    max-width: 420px;
    height: 100%;
    background: var(--surface);
    box-shadow: -12px 0 44px rgba(15, 23, 42, .16);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform .2s ease;
}
.drawer.is-visible .drawer__panel { transform: translateX(0); }

.drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.drawer__title { margin: 0; font-size: 16px; font-weight: 600; }
.drawer__x { border: 0; background: none; font-size: 22px; line-height: 1; padding: 0 4px; cursor: pointer; color: var(--muted); }
.drawer__x:hover { color: var(--text); }

.drawer__body { padding: 20px; flex: 1 1 auto; overflow-y: auto; }

@media (max-width: 560px) {
    .drawer__panel { max-width: 100%; }
}


/* Szczegóły użytkownika w drawerze — dostęp do modułów (podgląd) */
.access-view { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.access-view__name { font-size: 14px; font-weight: 600; }
.access-level { font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.access-level--manage { background: var(--accent); color: #fff; }
.access-level--view   { background: var(--bg); color: var(--text); border: 1px solid var(--border); }
.access-level--none   { color: var(--muted); }
.drawer__body .form__actions { flex-direction: column; }
.drawer__body .form__actions .inline-form { width: 100%; }
/* Kilka selectów filtra w jednym formularzu GET (np. Pracownicy: terminy + status). */
.list-filters__form { display: flex; gap: 10px; align-items: center; }
@media (max-width: 720px) {
    .list-filters__form { flex-wrap: wrap; width: 100%; }
}

/* Dłużnicy */
.debtor-amount { font-weight: 700; white-space: nowrap; }
.debtor-notes { white-space: normal; overflow-wrap: anywhere; word-break: break-word; font-size: 13px; color: var(--muted); }
.table td.debtor-notes { white-space: normal; width: 40%; min-width: 220px; }
.table td.num, .table th.num { text-align: right; }
.table td.nowrap { white-space: nowrap; }
.table tfoot th { border-top: 2px solid var(--border); font-weight: 700; }
/* Dłużnicy — szerszy kafelek „Suma należności" (kwoty 6–7 cyfr). */
.stat-grid--debtors { grid-template-columns: minmax(280px, 440px) minmax(200px, 260px); }
@media (max-width: 720px) {
    .stat-grid--debtors { grid-template-columns: 1fr; }
}

/* „Pokaż więcej" pod tabelą (np. Tankowania na karcie pojazdu / pracownika) */
.show-more { display: flex; justify-content: center; padding-top: 12px; }
.table tr[hidden] { display: none; }
.fuel-mini-stats { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-bottom: 12px; font-size: 13px; color: var(--muted); }
.fuel-mini-stats strong { color: var(--text); font-size: 15px; }
/* Poziom „Administrator" modułu (Tankowanie) — ponad Pełne prawa */
.access-row__select--admin { border-color: var(--accent); background: var(--accent); color: #fff; font-weight: 600; }
.access-level--admin { background: #3b0a13; color: #fff; }
.access-row__select--admin option { background: #fff; color: var(--text); font-weight: 400; }

/* ==================================================================
 * NPS2 — dodatki
 * ================================================================== */

/* Grupa checkboxów (np. branże firmy) — jeden pod drugim. */
.form__check-group { display: flex; flex-direction: column; gap: 8px; }

/* Edytor treści e-maila powitalnego (Quill) — Ustawienia → E-mail powitalny. */
#email-body-editor { background: #fff; border-radius: 7px; }
#email-body-editor .ql-toolbar.ql-snow { border-color: var(--border); border-radius: 7px 7px 0 0; }
#email-body-editor .ql-container.ql-snow { border-color: var(--border); border-radius: 0 0 7px 7px; }
#email-body-editor .ql-editor { min-height: 220px; font-size: 15px; }
