/* Wybor ikony zakladki: SIATKA SYMBOLI, nie lista nazw. Nazwa w <select> nie mowi, jak ikona
   wyglada - trzeba bylo zgadywac i sprawdzac po zapisie. Tu widac wszystkie naraz. */
.ico-pick { position: relative; display: inline-flex; }
.ico-pick > .icon-btn { border: 1px solid var(--line, #d5d8de); border-radius: 6px; }
.ico-grid {
    position: absolute; z-index: 40; top: calc(100% + 4px); left: 0;
    display: grid; grid-template-columns: repeat(5, 1.8rem); gap: 2px; padding: 5px;
    background: var(--panel, #fff); border: 1px solid var(--line, #d5d8de);
    border-radius: 8px; box-shadow: 0 10px 24px rgba(0, 0, 0, .28);
}
.ico-grid .icon-btn { width: 1.8rem; height: 1.8rem; border-radius: 5px; }
.ico-grid .icon-btn:hover { background: var(--hover, rgba(127, 127, 127, .16)); }

/* ============================================================================
   ARKUSZ WSPÓLNY — ten sam plik w obu aplikacjach, co do bajtu.
   wewnętrzna: public/css/app.css   ·   zewnętrzna: public/assets/app.css
   Pilnuje tego bin/parity.py w trybie ścisłym: zmiana zrobiona po jednej stronie
   przerywa push, zamiast rozjechać wygląd bez żadnego sygnału.

   Wcześniej arkusz zewnętrzny był BAZĄ, a wewnętrzny dokładał do niego sekcję
   „DODATKI". Podział przestał mieć sens, gdy interfejsy zostały ujednolicone:
   reguła dopisana po jednej stronie i tak jest potrzebna po drugiej, a wtedy
   „dodatek" jest tylko nazwą dla opóźnienia, z jakim tam trafia.

   Selektory nieużywane w danej aplikacji są NIESZKODLIWE — kosztują tyle, co
   ich długość. Jeden plik do czytania jest wart więcej niż ta oszczędność.
   ============================================================================ */

*{box-sizing:border-box}
[x-cloak]{display:none!important}
body{font:13px/1.35 system-ui,-apple-system,"Segoe UI",sans-serif;margin:0;color:#1f2937;background:#fff}
main{padding:.6rem .75rem}
.container{max-width:1000px;margin:0 auto}
.container.wide{max-width:none}
h1{font-size:1.2em;margin:.1em 0}
h2.sub{font-size:1.05em;margin:.4em 0;color:#374151}
.mono{font-family:ui-monospace,Consolas,monospace}
.muted{color:#9ca3af}.italic{font-style:italic}.green{color:#166534}
.small{font-size:.85em}.center{text-align:center}.nowrap{white-space:nowrap}
.indent{padding-left:1.4em}

/* topbar */
.topbar{display:flex;justify-content:space-between;align-items:center;gap:.7em;background:#fff;border-bottom:1px solid #e5e7eb;padding:.25em .75em;position:sticky;top:0;z-index:40}
.topbar-left,.topbar-right{display:flex;align-items:center;gap:.55em}
.badge{font-size:.7em;background:#ede9fe;color:#6d28d9;border-radius:6px;padding:.1em .5em;font-weight:600}
.menu{position:relative}
.menu-list{position:absolute;right:0;top:110%;background:#fff;border:1px solid #e5e7eb;border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,.12);min-width:290px;padding:.4em;z-index:50}
.menu-group{font-size:.7em;text-transform:uppercase;color:#9ca3af;padding:.35em .5em .15em;letter-spacing:.05em}
.menu-list a{display:flex;gap:.55em;align-items:center;padding:.35em .5em;border-radius:8px;text-decoration:none;color:inherit}
.menu-list a:hover{background:#f3f4f6}
.menu-list a.active{background:#eef2ff}
.menu-list small{color:#9ca3af}
.menu-ico{display:flex;align-items:center;flex:none}
.tile-btn svg{stroke-width:2}

/* przyciski / inputy */
/* inline-flex + gap: przyciski nosza ikone i tekst, bez tego brak odstepu i rownania w pionie.
   min-height 24px: dolna granica sensownego celu klikalnego po zageszczeniu interfejsu. */
.btn{font:inherit;padding:.3em .65em;border:1px solid #d1d5db;border-radius:7px;background:#fff;
    cursor:pointer;color:#1f2937;display:inline-flex;align-items:center;justify-content:center;
    gap:.4em;min-height:24px;line-height:1.25;text-decoration:none}
.btn:hover{background:#f9fafb}
.btn:disabled{opacity:.45;cursor:default}
.btn-primary{background:#2563eb;border-color:#2563eb;color:#fff}
.btn-primary:hover{background:#1d4ed8}
.btn-gray{background:#6b7280;border-color:#6b7280;color:#fff}
.btn-danger{background:#dc2626;border-color:#dc2626;color:#fff}
.btn-ghost{border-color:transparent;background:transparent}
.btn-xs{padding:.15em .5em;font-size:.85em}
.btn-block{width:100%}
.icon-btn{border:none;background:transparent;cursor:pointer;font-size:1em;padding:.2em .3em;
    color:#64748b;border-radius:6px;vertical-align:middle}
.icon-btn:hover{background:#e2e8f0;color:#1e293b}
.icon-btn svg{display:block}
.icon-split{color:#ef4444}
.icon-split:hover{background:#fee2e2;color:#b91c1c}
.icon-del:hover{background:#fee2e2;color:#b91c1c}
input,select,textarea{font:inherit}
textarea{width:100%;border:1px solid #d1d5db;border-radius:7px;padding:.35em .5em}

/* kafelki */
.group-title{font-size:.75em;text-transform:uppercase;letter-spacing:.06em;color:#6b7280;margin:.9em 0 .35em}
.tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(185px,1fr));gap:.6em}
.tile{background:#fff;border:1px solid #e5e7eb;border-radius:10px;padding:.6em;text-align:center;text-decoration:none;color:inherit;transition:transform .12s,box-shadow .12s}
.tile:hover{transform:scale(1.04);box-shadow:0 8px 22px rgba(0,0,0,.1)}
.tile-btn{display:flex;align-items:center;justify-content:center;gap:.45em;color:#fff;font-weight:600;border-radius:8px;padding:.5em;margin-bottom:.35em}
.tile-icon{font-size:1.2em}
.tile small{color:#6b7280}

/* pasek modułu */
/* Trzy kolumny zamiast rozpychania na boki: powrot po lewej, tytul NA SRODKU, akcje po prawej.
   Skrajne kolumny sa rowne (1fr), wiec tytul stoi posrodku paska niezaleznie od tego, ile
   przyciskow ma dana strona. Kolumna pierwsza bywa pusta — nie kazdy ekran ma powrot. */
.module-band{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:.6em;
    background:#fff;border:1px solid #e8edf3;border-left:5px solid #334155;border-radius:10px;
    padding:.35em .8em;margin:.1em 0 .55em;box-shadow:0 1px 2px rgba(15,23,42,.04)}
.module-band > .btn-back{grid-column:1;justify-self:start}
.module-band-left{grid-column:2;justify-self:center;display:flex;align-items:center;gap:.65em}
.module-band > .panel-actions{grid-column:3;justify-self:end}
@media (max-width: 60rem){
    .module-band{grid-template-columns:auto 1fr;row-gap:.4em}
    .module-band > .btn-back{grid-column:1}
    .module-band-left{grid-column:2;justify-self:start}
    .module-band > .panel-actions{grid-column:1 / -1;justify-self:end}
}
.module-icon{background:#f8fafc;border:1px solid #e2e8f0;border-radius:9px;width:2.1em;height:2.1em;
    display:flex;align-items:center;justify-content:center;line-height:1;color:#475569;flex:none}
.module-title{display:flex;align-items:center;gap:.55em;font-size:1em;margin:0;
    letter-spacing:.09em;font-weight:700;color:#1e293b;text-transform:uppercase}
.module-sub{color:#64748b;font-size:.85em;margin-top:.1em}
.module-band .pill-dark{background:#f1f5f9;color:#64748b;font-size:.72em;font-weight:500;letter-spacing:.02em;
    text-transform:none;padding:.25em .8em;border-radius:999px}
/* Wyszukiwarka i przyciski MUSZA zostac w jednej linii. .filter-input ma width:100% (potrzebne
   w paskach filtrow nad tabela), a w kontenerze z flex-wrap znaczy to 'zajmij cala linie' — przez
   co Refresh spadal do drugiego wiersza. Zawezamy oba zachowania TYLKO wewnatrz paska modulu. */
.module-band .panel-actions{gap:.55em;flex-wrap:nowrap}
.module-band .filter-input{width:auto;max-width:14rem;box-sizing:border-box;
    font-size:.92em;padding:.35em .7em;border-radius:7px;min-height:24px;line-height:1.25}
.module-band .btn{border-radius:7px;padding:.35em .7em;display:flex;align-items:center;gap:.4em;font-size:.92em}
.module-band .ico,.po-act .ico,.icon-btn .ico{flex:none;display:block}
.ico{flex:none}
.btn-square{border:1px solid #bfdbfe;color:#2563eb;background:#fff;padding:.35em .5em}
.btn-square:hover{background:#eff6ff}
.btn-square-on{background:#2563eb;border-color:#2563eb;color:#fff}
.btn-square-on:hover{background:#1d4ed8}
.btn-import{background:#2563eb;border-color:#2563eb;color:#fff;font-weight:600}
.btn-import:hover{background:#1d4ed8}
.btn-export{background:#fff;border:1px solid #22c55e;color:#16a34a;font-weight:600}
.btn-export:hover{background:#f0fdf4}

/* panele i tabele */
.panel-head{display:flex;justify-content:space-between;align-items:center;gap:.7em;margin:.25em 0 .5em;flex-wrap:wrap}
.panel-actions{display:flex;align-items:center;gap:.4em;flex-wrap:wrap}
.pill{background:#e5e7eb;border-radius:999px;padding:.1em .55em;font-size:.82em}
.tabs{display:flex;gap:.4em}
.tbl-scroll{overflow-x:auto}
.tbl{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;overflow:hidden;margin-bottom:.3em}
.tbl th,.tbl td{padding:.24em .45em;border-bottom:1px solid #eef0f3;text-align:center;font-size:.9em}
.tbl th.left,.tbl td.left{text-align:left}
.tbl td.num{text-align:right}
.dict-head th{background:#334155;color:#fff;font-size:.78em;text-transform:uppercase;letter-spacing:.03em}

/* nagłówek PO: ciemny wiersz etykiet + jasny wiersz kontrolek */
.po-labels th{background:#334155;color:#e2e8f0;border-bottom:none;vertical-align:middle;text-align:left;
    font-size:.72em;text-transform:uppercase;letter-spacing:.08em;font-weight:700;padding:.45em .5em;
    white-space:nowrap}
.po-head th,.po-head td{background:#f1f5f9;border-bottom:1px solid #dbe2ea;vertical-align:middle;text-align:left;
    padding:.35em .3em;white-space:nowrap;width:1%}
.po-head td:has(> .po-input),.po-head td:has(> .date-cell),.po-head td:has(> .po-status){padding:0}
.po-head th.po-number,.po-head td.po-number{color:#1d4ed8;font-weight:700;letter-spacing:.02em;
    font-family:ui-monospace,Consolas,monospace}
.chev{border:none;background:transparent;color:#2563eb;cursor:pointer;font-size:.95em;
    transition:transform .15s;display:inline-block}
.chev-open{transform:rotate(90deg)}

.date-field{position:relative;display:inline-flex;align-items:center;gap:.35em;background:transparent;
    border:none;padding:.24em .45em;cursor:pointer;min-width:7em;justify-content:flex-start;
    line-height:1.35}
.date-field .date-ico{display:flex;color:#2563eb;flex:none}
.date-field .date-val{color:#1e3a8a;font-weight:600;white-space:nowrap}
.date-field input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none}
.date-field.is-disabled{opacity:.55;cursor:default}
.date-field.is-disabled:hover{border-color:#cbd5e1}

.po-input{background:transparent;border:none;padding:.35em .45em;color:#1e3a8a;width:100%;
    font-weight:600;font-size:1em;line-height:1.35;box-sizing:border-box;outline:none;display:block}
.po-input:disabled{opacity:.55}
.po-status{width:100%}
.status-dot{display:inline-block;width:.6em;height:.6em;border-radius:999px;margin-left:.45em;
    vertical-align:middle}

/* kolumna akcji wchłania wolną szerokość — reszta zwęża się do zawartości */
.po-head th.po-actions{width:auto}

/* Etykiety zamowienia stoja w OSOBNEJ tabeli nad lista, wiec kolumny nie zgraja sie same:
   `table-layout: fixed` plus te same szerokosci po obu stronach to jedyne, co je trzyma w pionie.
   Ostatnia kolumna (akcje) zostaje bez szerokosci i zabiera reszte. */
.po-grid{table-layout:fixed}
.po-grid th:nth-child(1){width:2.4em}
.po-grid th:nth-child(2){width:15%}
.po-grid th:nth-child(3){width:12%}
.po-grid th:nth-child(4){width:8.5em}
.po-grid th:nth-child(5){width:8.5em}
.po-grid th:nth-child(6){width:11%}
.po-grid th:nth-child(7){width:8.5em}
.po-grid th:nth-child(8){width:11%}

/* Naglowek zostaje na wierzchu przy przewijaniu. `top` odpowiada wysokosci paska gornego, ktory
   sam jest przyklejony — bez tego etykiety chowalyby sie pod nim. */
.po-labels-table{position:sticky;top:2.1rem;z-index:6;margin-bottom:0;border-radius:10px 10px 0 0}
.po-labels-table .po-labels th:first-child{border-radius:10px 0 0 0}
.po-labels-table .po-labels th:last-child{border-radius:0 10px 0 0}
.po-head th.po-actions,.po-head td.po-actions{text-align:right}
.po-act{display:inline-flex;align-items:center;gap:.4em;background:transparent;border:none;
    color:#475569;cursor:pointer;font:inherit;font-size:.92em;padding:.4em .7em;border-radius:8px}
.po-act:hover{background:#e2e8f0;color:#1d4ed8}
.po-act-danger{color:#dc2626}
.po-act-danger:hover{background:#fecaca;color:#b91c1c}
.po-group{margin-bottom:1.1em;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden;
    transition:box-shadow .12s,border-color .12s}
.po-group.drop-target{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.18)}
.po-group.drop-target .po-head th,.po-group.drop-target .po-head td{background:#dbeafe}
.row-dragging{opacity:.4}
.drag-cell{cursor:grab;color:#94a3b8;user-select:none;font-size:1.05em}
.drag-cell:active{cursor:grabbing}
.drag-badge{position:fixed;z-index:200;pointer-events:none;background:#fef9c3;border:1px solid #fde047;
    border-radius:10px;padding:.6em .85em;font-size:.82em;line-height:1.4;color:#713f12;
    box-shadow:0 8px 20px rgba(15,23,42,.18)}
.drag-hint{margin-top:.3em;font-weight:700;color:#1d4ed8}
.po-group .tbl{margin-bottom:0;border-radius:0}
.basket thead th{background:#dbeafe;color:#1d4ed8;font-size:.75em;border:1px solid #bfdbfe;font-weight:700}
.basket thead .basket-strip th{background:#bfdbfe;color:#1d4ed8;font-size:.85em;text-transform:none;
    letter-spacing:0;font-weight:600;border:none;padding:.22em .7em;white-space:nowrap}
.basket-strip th svg{display:inline-block;vertical-align:-3px;margin-right:.4em}
.basket td{border:1px solid #dbeafe;border-top:none}
.basket .editable:hover{background:transparent}
.bulk-row{background:#dbeafe}
.bulk-row td{padding:.35em;border-color:#bfdbfe}
.bulk-row .cell-input{width:100%;max-width:none;border-color:#93c5fd;background:#fff}
.bulk-label{font-weight:600;color:#1d4ed8;white-space:nowrap}
.basket td:nth-child(4){font-weight:700}
.w-chevron{width:2em}
.filters-bar{display:flex;gap:.35em;flex-wrap:wrap;background:transparent;padding:.1em 0;margin-bottom:.6em}
.filters-row th{background:#fff;padding:.25em}
.filter-input{width:100%;min-width:70px;max-width:150px;border:1px solid #d1d5db;border-radius:5px;padding:.2em .4em;font-size:.85em}
/* JEDEN sposob edycji w obu apkach: kontrolka jest w komorce ZAWSZE, bez trybu edycji.
   Domyslnie plaska (przezroczysta ramka i tlo), zeby tabela czytala sie jak tabela, a nie jak
   formularz; ramka pojawia sie pod kursorem, a niebieska obwodka przy ognisku. Klasa .edit
   zostaje jako alias — nic juz jej nie ustawia, ale stare szablony jej nie zepsuja. */
/* Komorka jak w arkuszu: pole WYPELNIA cala komorke, zamiast siedziec w niej jako osobne pudelko.
   Wczesniej wypelnienie bylo dwa razy — raz na `td`, raz na polu — i te kilkanascie pikseli na
   kazdej komorce sumowalo sie w calej tabeli. Komorka z polem oddaje mu wiec swoje wypelnienie.
   `:has()` nie dziala w starszych przegladarkach; tam zostaje dotychczasowy wyglad, nie awaria. */
.tbl td:has(> .cell-input){padding:0}
.tbl td:has(> [x-data] > .cell-input){padding:0}
.cell-input{border:none;border-radius:0;font-size:1em;padding:.24em .45em;
    background:transparent;color:inherit;width:100%;max-width:none;font-family:inherit;
    display:block;box-sizing:border-box;line-height:1.35;outline:none}
/* Zapala sie KOMORKA, nie pole — inaczej w tabeli widac szereg pudelek zamiast siatki.
   Zawezone do komorek z polem: komorka akcji ma same przyciski i nie ma sie po co zapalac,
   gdy ktos przejdzie po niej tabulatorem. */
.tbl td:has(input, select, textarea):focus-within{box-shadow:inset 0 0 0 2px #2563eb;background:#fff}
.tbl td:has(> .cell-input.dirty){background:#fefce8}

.cell-input:disabled{background:transparent;border-color:transparent;color:inherit;opacity:1;cursor:default}
/* Komorka z niezapisana zmiana — bursztynowa kropka, zeby nie zgubic edycji przy kliknieciu gdzie indziej. */

.cell-input.edit{width:100%;max-width:none}
td.editable{cursor:pointer}
td.editable:hover{background:#f0f6ff}
.bad-factory{color:#b91c1c;font-weight:600}
.new-row{background:#ecfdf5}
.new-row td{padding:.3em}
.dragging{opacity:.5}
.drag-grip{cursor:grab;color:#9ca3af;user-select:none}
.swatch{display:inline-block;width:.95em;height:.95em;border-radius:4px;border:1px solid #d1d5db;vertical-align:-2px;margin-right:.35em}
.sql-preview{display:inline-block;max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;cursor:pointer}
.row-link{cursor:pointer}
.row-link:hover{background:#f0f6ff}
.cell-clip{max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sticky-col{position:sticky;left:0;background:#fff;z-index:2}
.dict-head .sticky-col{background:#4b5563}
.brand-row{background:#fef3c7;cursor:pointer;font-weight:600}
.brand-row:hover{background:#fde68a}
.total-row{background:#dcfce7;font-weight:700}
.edit-wrap{display:flex;gap:.3em;align-items:center}

/* users / dostepy */
.access-row{display:flex;align-items:center;gap:.7em;padding:.35em 0;border-bottom:1px dashed #eef0f3;flex-wrap:wrap}
.access-label{min-width:150px;font-weight:600}
.access-btns{display:flex;gap:.25em}
.cond-box{padding:.5em;background:#f9fafb;border-radius:8px;margin:.3em 0}
.factory-grid{display:grid;grid-template-columns:1fr 1fr;gap:.15em .8em}
.factory-grid label{font-size:.85em}
.dimmed{opacity:.45;pointer-events:none}

/* modale i toasty */
.modal-bg{position:fixed;inset:0;background:rgba(15,23,42,.45);display:flex;align-items:center;justify-content:center;z-index:60;padding:1em}
.modal{background:#fff;border-radius:14px;padding:1.2em;max-width:760px;width:100%;max-height:88vh;overflow:auto;box-shadow:0 20px 60px rgba(0,0,0,.25)}
.modal-lg{max-width:1000px}
.modal-actions{display:flex;justify-content:flex-end;gap:.5em;margin-top:.8em}
.toast{position:fixed;bottom:1.4em;right:1.4em;display:flex;align-items:center;gap:.6em;
    background:#fff;color:#1e293b;padding:.85em 1.2em;border:1px solid #e2e8f0;border-radius:12px;
    box-shadow:0 10px 30px rgba(15,23,42,.15);z-index:99;animation:fadein .15s;font-size:.95em}
.toast-ico{display:flex;align-items:center;justify-content:center;width:1.5em;height:1.5em;flex:none;
    border-radius:999px;background:#0f172a;color:#fff;font-size:.8em;line-height:1}
.toast-err{border-color:#fecaca;color:#991b1b}
.toast-err .toast-ico{background:#b91c1c}
@keyframes fadein{from{opacity:0;transform:translateY(6px)}to{opacity:1}}

.copy-fallback{position:fixed;bottom:1.4em;right:1.4em;display:flex;align-items:center;gap:.6em;
    background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:.85em 1.2em;
    box-shadow:0 10px 30px rgba(15,23,42,.18);z-index:100;font-size:.95em}
.copy-fallback input{border:1px solid #bfdbfe;border-radius:8px;padding:.35em .6em;width:11em;
    background:#f8fafc;color:#1e293b}

.btn-clock{font-family:ui-monospace,Consolas,monospace;background:#f8fafc;color:#334155;
    border-color:#e2e8f0;border-radius:9px;padding:.45em .8em}
.btn-clock:hover{background:#eff6ff;border-color:#bfdbfe;color:#2563eb}
.btn-clock:active{transform:scale(.97)}

/* logowanie */
.login-main{display:flex;justify-content:center;padding-top:8vh}
.login-box{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:2em;width:340px;box-shadow:0 10px 30px rgba(0,0,0,.08)}
.login-box h1{text-align:center;font-size:1.15em}
.login-box input{width:100%;padding:.55em .7em;border:1px solid #d1d5db;border-radius:8px}
.err{background:#fee2e2;color:#991b1b;padding:.35em .6em;border-radius:7px}
.notice{background:#dcfce7;color:#166534;padding:.35em .6em;border-radius:7px}
/* kod bezpieczenstwa z maila */
.code-hint{color:#4b5563;font-size:.9em;line-height:1.45;text-align:center}
.code-input{font-family:ui-monospace,Consolas,monospace;font-size:1.6em;text-align:center;letter-spacing:.35em}
.code-actions{display:flex;justify-content:space-between;margin-top:.4em}
.code-actions .btn{color:#2563eb}

/* --- „View as": lista kont w menu + pasek trybu podgladu (obie apki) --- */
.menu-list-left{right:auto;left:0}
.menu-list form{margin:0}
/* Pozycja wybierana POST-em, nie linkiem (zmienia stan sesji), a ma wygladac jak .menu-list a. */
.menu-list button.pick{display:flex;width:100%;align-items:center;justify-content:flex-start;gap:.55em;
    padding:.35em .5em;border:none;background:transparent;border-radius:8px;color:inherit;font:inherit;
    text-align:left;cursor:pointer;min-height:0}
.menu-list button.pick:hover{background:#f3f4f6}
.menu-list button.pick.active{background:#eef2ff}
/* Bursztyn, zeby nie dalo sie pomylic z komunikatem sukcesu. */
.viewas-bar{display:flex;align-items:center;justify-content:space-between;gap:.8em;flex-wrap:wrap;
    background:#fef9c3;border-bottom:1px solid #fde047;color:#713f12;padding:.3em .75em;font-size:.85em}
.viewas-bar .muted{color:#a16207}

/* --- Zakladki: ikona strony (favicon) z fallbackiem na ikone wektorowa --- */
/* Favicon lezy NA ikonie SVG. Gdy adres nie odpowiada, onerror usuwa <img> i spod spodu
   odslania sie ikona wektorowa — bez migania i bez pustego miejsca. */
.bm-ico{position:relative;display:flex;align-items:center;flex:none;width:16px;height:16px}
.bm-ico .ico{width:16px;height:16px}
.bm-favicon{position:absolute;inset:0;width:16px;height:16px;background:#fff;border-radius:3px;object-fit:contain}

/* ============================================================================
   KOMPONENTY FORMULARZY SERWEROWYCH — komunikaty PRG, formularze pionowe,
   macierz uprawnień, tabela kont z colgroup i filtrami per kolumna.
   Powstały dla panelu wewnętrznego, ale po ujednoliceniu modułu kont używa ich
   też panel zewnętrzny. Nic tutaj nie nadpisuje reguł powyżej.
   ============================================================================ */

/* Komunikaty PRG. `.err` i `.notice` są w bazie; brakuje wariantu „w toku”,
   który NIE jest porażką — eksport potrafi się nie zmieścić w oknie proxy. */
.flash { padding: .35em .6em; border-radius: 7px; margin-bottom: .5em; }
.flash.err { background: #fee2e2; color: #991b1b; }
.flash.ok { background: #dcfce7; color: #166534; }
.flash.warn { background: #fef9c3; color: #713f12; }

/* Podtytuł/nota pod nagłówkiem — w SCMMW tę rolę pełni .module-sub wewnątrz paska. */
.meta { color: #6b7280; font-size: .85em; margin: .3em 0 .6em; }
.meta code { font-size: .95em; }

/* Formularz pionowy (SCMMW nie ma formularzy serwerowych — wszystko idzie AJAX-em). */
form.stack { display: flex; flex-direction: column; gap: .5em; max-width: 520px; margin-bottom: .8em; }
form.stack label { display: flex; flex-direction: column; gap: .3em; font-size: .88em; color: #374151; font-weight: 600; }
form.stack label input, form.stack label textarea { font-weight: 400; }
form.stack input, form.stack select { border: 1px solid #d1d5db; border-radius: 7px; padding: .3em .55em; background: #fff; }
.actions, form .actions { display: flex; align-items: center; gap: .5em; margin: .7em 0; }
input:focus, select:focus, textarea:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, .15); }
/* ...ale NIE w tabelach. Tam zapala sie KOMORKA (:focus-within), a obwodka wokol samego
   pola rysowala sie na wierzchu i konczyla przed ikona kalendarza albo strzalka wyboru —
   wygladalo to jak ucięte podswietlenie. */
.cell-input:focus,.po-input:focus,.po-status:focus{border-color:transparent;box-shadow:none}

/* Select z własną strzałką — natywna jest ściśnięta przy prawej krawędzi. */
select {
    appearance: none; -webkit-appearance: none; padding-right: 2em;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239ca3af' stroke-width='1.8'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right .7em center; background-size: .8em;
}

/* Akcje w wierszu tabeli — SCMMW renderuje je Alpine'em, tu są zwykłe <form>. */
.row-actions { display: flex; align-items: center; justify-content: center; gap: .25em; white-space: nowrap; }
.row-actions form { margin: 0; display: inline; }

/* Tabela users: 12 kolumn z polami edycyjnymi. Przewijanie bierze KONTENER, nie tabela —
   inaczej display:block unieważnia colgroup i kolumny rozpychają się poza prawą krawędź. */
.grid-scroll { overflow-x: auto; margin-bottom: .5em; }
table.tbl.users { min-width: 84em; table-layout: fixed; }
table.users th, table.users td { white-space: normal; vertical-align: middle; }
table.users th.nowrap, table.users td.nowrap { white-space: nowrap; }
table.users td.access { font-size: .95em; line-height: 1.25; overflow-wrap: break-word; }
table.users td input[type="text"], table.users td input[type="email"] { width: 100%; min-width: 0; }
table.users td.twofa { display: flex; flex-wrap: wrap; align-items: center; gap: .3em .5em; }
/* 6.6em + odstęp na strzałkę: przy 5.6em „E-mail” ucinało się do „E-mai”. */
table.users td.twofa select { width: 6.6em; min-width: 0; flex: 0 0 auto; padding-right: 1.6em; background-position: right .4em center; }

/* Wiersz filtrów pod ciemnym wierszem etykiet — układ z nagłówka PO w SCMMW (.po-head). */
tr.filters th { background: #f1f5f9; border-bottom: 1px solid #dbe2ea; font-weight: 400; padding: .25em .3em; text-transform: none; letter-spacing: 0; }
tr.filters input, tr.filters select { width: 100%; min-width: 0; font-size: 1em; padding: .3em .45em; border: 1px solid #d1d5db; border-radius: 5px; }
tr.filters select { padding-right: 1.4em; background-position: right .35em center; }
tr.filters button { padding: .3em .6em; font-size: 1em; width: 100%; }

/* Macierz uprawnień — SCMMW ma do tego .access-row/.cond-box w panelu Alpine,
   tu jest zwykły <form> z <fieldset> na moduł. */
fieldset.module { border: 1px solid #e2e8f0; border-radius: 8px; padding: .5em .7em .6em; margin: 0 0 .5em; background: #fff; box-shadow: 0 1px 2px rgba(15, 23, 42, .04); }
fieldset.module legend { padding: .1em .6em; font-weight: 700; color: #1e293b; font-size: .78em; text-transform: uppercase; letter-spacing: .06em; background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 999px; }
fieldset.module legend .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }
fieldset.module .levels { display: flex; flex-wrap: wrap; gap: .9em; margin-bottom: .35em; }
fieldset.module .levels label { display: flex; align-items: center; gap: .35em; font-size: .9em; }
fieldset.module .conditions { background: #f9fafb; border-radius: 7px; padding: .35em .55em; margin-top: .35em; font-size: .9em; }
fieldset.module .conditions strong { margin-right: .5em; }
fieldset.module .checks { display: flex; flex-wrap: wrap; gap: .2em 1em; margin-top: .3em; }
fieldset.module .checks label { display: flex; align-items: center; gap: .35em; font-weight: 400; }

/* Kod TOTP na żywo (widok szczegółu konta). */
.big-number { font-size: 1.8em; font-weight: 700; margin: .1em .2em .1em 0; color: #1d4ed8; font-family: ui-monospace, Consolas, monospace; letter-spacing: .08em; }

/* Nota wyjaśniająca — SCMMW nie ma tekstów tej długości w UI. */
blockquote { margin: .6em 0; padding: .55em .8em; background: #f8fafc; border: 1px solid #e2e8f0; border-left: 4px solid #2563eb; border-radius: 8px; }
ul { padding-left: 1.2em; }
li { margin: .15em 0; }
code { background: #f1f5f9; padding: .05em .3em; border-radius: 5px; font-size: .92em; color: #334155; font-family: ui-monospace, Consolas, monospace; }


/* Diagram schematu (dbbrowser/schema.twig). Karty i linie rysuje serwer; JS tylko przesuwa. */
/* Diagram ma zajac ekran: pasek modulu, zwinieta legenda i marginesy `main` to okolo 150px. */
.schema-wrap{overflow:auto;border:1px solid #e5e7eb;border-radius:10px;background:#fafafa;
    height:calc(100vh - 118px);min-height:22rem}
.schema-tips{margin:.2em 0 .6em;line-height:1.5;max-width:70rem}
.schema-dim{opacity:.15;transition:opacity .12s}

/* Powrot O JEDEN POZIOM. Stoi po lewej paska modulu, bo tam odruchowo szuka sie powrotu —
   wczesniej wygrywala z nim ikona wyboru modulow z paska gornego. */
.btn-back{border-color:#94a3b8;font-weight:500;margin-right:.15em}
.btn-back:hover{background:#f1f5f9;border-color:#64748b}
.schema-card{cursor:grab}
.schema-card.schema-dragging{cursor:grabbing}
.schema-box{fill:#fff;stroke:#d1d5db;stroke-width:1}
.schema-card:hover .schema-box{stroke:#9ca3af}
.schema-dragging .schema-box{stroke:#6366f1;stroke-width:1.5}
.schema-div{stroke:#e5e7eb;stroke-width:1}
.schema-name{font:600 12px system-ui,-apple-system,"Segoe UI",sans-serif;fill:#1f2937;pointer-events:none}
.schema-count{font:11px system-ui,-apple-system,"Segoe UI",sans-serif;fill:#9ca3af;pointer-events:none}
.schema-col{font:11px system-ui,-apple-system,"Segoe UI",sans-serif;fill:#374151;pointer-events:none}
.schema-key{font-weight:600;fill:#1f2937}
.schema-type{font:11px ui-monospace,SFMono-Regular,Menlo,monospace;fill:#9ca3af;pointer-events:none}
.schema-rel{stroke-width:1.5;pointer-events:stroke}
.schema-pct{font:10px system-ui,-apple-system,"Segoe UI",sans-serif;pointer-events:none}
.schema-rel.rel-ok{stroke:#16a34a}
.schema-rel.rel-warn{stroke:#d97706;stroke-dasharray:5 3}
.schema-rel.rel-bad{stroke:#dc2626;stroke-dasharray:5 3}
.schema-pct.rel-ok{fill:#16a34a}
.schema-pct.rel-warn{fill:#d97706}
.schema-pct.rel-bad{fill:#dc2626}
.rel-legend{font-weight:600}
.rel-legend.rel-ok{color:#16a34a}
.rel-legend.rel-warn{color:#d97706}
.rel-legend.rel-bad{color:#dc2626}
.schema-rel.rel-none{stroke:#9ca3af;stroke-dasharray:2 4}
.schema-pct.rel-none{fill:#9ca3af}
.rel-legend.rel-none{color:#9ca3af}

/* Tozsamosc w pasku gornym wyglada jak przycisk takze wtedy, gdy nie ma czego kliknac —
   pasek ma byc spojny, ale udawany przycisk kusilby do klikania w nic. */
.btn-static{cursor:default;background:#fff}
.btn-static:hover{background:#fff}

/* ── Orders Management: jedna tabela na cala liste ────────────────────────────────────────────
   Kazde zamowienie to teraz PARA wierszy w tej samej tabeli — wiersz z danymi PO i rozwijany
   wiersz z koszykiem — a nie osobna tabela. Kolumny zgrywaja sie same, bo to jeden model kolumn.
   Grupa jest <tbody>, wiec ramki i zaokraglenia nie dzialaja na niej tak jak na <div>: odstep
   miedzy zamowieniami robi gorna ramka pierwszego wiersza grupy. */
.po-table{width:100%;border-collapse:separate;border-spacing:0}
.po-table > thead th{position:sticky;top:2.1rem;z-index:6}
tbody.po-group > tr.po-head > td{border-top:1px solid #e2e8f0}
tbody.po-group + tbody.po-group > tr.po-head > td{border-top:5px solid transparent;
    background-clip:padding-box}
tbody.po-group.drop-target > tr.po-head > td{background:#dbeafe}

/* Koszyk siedzi w komorce na cala szerokosc.
   FONT-SIZE:1em NIE JEST OZDOBA. `.tbl td` ma .9em, wiec komorka nosaca koszyk juz jest
   pomniejszona, a jego wlasne komorki mnozylyby to po raz drugi: 0,9 x 0,9 x 13px = 10,5px
   zamiast 11,7px. Reset do 1em liczy sie od tabeli (13px), wiec koszyk wraca do rozmiaru
   sprzed przebudowy. Ta sama pulapka co przy polach edycyjnych w komorkach.
   WCIECIE od lewej rowna koszyk pod kolumne rozwijania, dzieki czemu widac, ze nalezy
   do zamowienia nad nim, a nie stoi obok niego. */
.po-basket-row > td{font-size:1em;background:#eef2f7;border-bottom:1px solid #cbd5e1;
    padding:0 0 0 1.4em}
/* Bez zaokraglen: koszyk ma czytac sie jako ciag dalszy tabeli, a nie osobna karta w srodku.
   `.tbl` zaokragla rogi domyslnie, wiec trzeba to tu wprost wylaczyc. */
.po-basket-row .basket{margin-bottom:0;border:1px solid #dbe2ea;border-radius:0}

/* ── Data: pisana recznie, kalendarz tylko jako pomocnik ──────────────────────────────────────
   Natywny <input type="date"> ma wlasna maske w formacie systemu i nie da sie w nim pisac
   RRRR-MM-DD. Rozdzielamy wiec role: pisze sie w polu TEKSTOWYM, a kalendarz sluzy do wskazania
   myszka. Kalendarz jest JEDEN na strone i przed otwarciem dostaje wartosc z pola, wiec startuje
   na dacie juz wpisanej, a nie na dzisiejszej. */
.date-cell{display:flex;align-items:center;gap:.15em;width:100%}
.date-pick{border:none;background:transparent;color:#94a3b8;cursor:pointer;padding:0 .15em;
    display:inline-flex;align-items:center;line-height:1}
.date-pick:hover:not(:disabled){color:#2563eb}
.date-pick:disabled{opacity:.4;cursor:default}
.date-pick-cell{position:absolute;right:.2em;top:50%;transform:translateY(-50%)}
.basket td:has(> .date-pick-cell){position:relative}
.po-date{flex:1;min-width:6.6em}

/* Kalendarz-pomocnik: musi byc w drzewie i moc dostac ognisko, wiec nie `display:none`.
   Pozycjonuje go pickDate() tuz pod klikanym polem, zeby okno otwieralo sie przy komorce. */
.cal-proxy{position:absolute;width:1px;height:1px;opacity:0;border:none;padding:0;
    pointer-events:none}

/* Napis na czas pobierania zamowien. Tabela pojawia sie dopiero z danymi, zeby modul nie rysowal
   sie dwa razy: najpierw pusty szkielet, potem wiersze. */
.po-loading{padding:1.6em 0;font-size:.95em}

/* Klucz zamowienia z bazy — pomocniczy, wiec ciszej niz numer, ktorym ludzie sie posluguja. */
.po-head td.po-id{padding:0}
.po-id-input{color:#64748b;font-weight:400;font-size:.9em}

/* "Zapamietaj mnie" na ekranie logowania. Cale pole jest klikalne razem z podpisem — przy
   samym kwadraciku trafienie bywa loteria. */
.login-remember{margin:.2em 0 .8em}
.login-remember label{display:flex;align-items:center;gap:.5em;cursor:pointer;color:#475569}
.login-remember input{margin:0}
