/* Atrybut hidden ma wygrywac z kazda regula display ponizej. Bez tego
   .auth-step{display:flex} przykrywa [hidden] i element zostaje na ekranie. */
[hidden]{display:none !important}

/* server/public/css/admin2.css
   Affido bv — warstwa „master admin 2.0" (standard panelu lechistan.org przeniesiony
   na nasz stack: EJS + czysty CSS, zero frameworków, zero zewnętrznych fontów).
   Dokłada się PO admin.css i tylko podnosi: grupowany sidebar z licznikami, szklany
   topbar, paleta poleceń, kafle KPI z iskierką (inline SVG), toasty, sortowanie
   i filtrowanie tabel, gęstość, tryb jasny, pasek piaskownicy.

   Zasady: kontrast min 4.5:1 w obu motywach, focus zawsze widoczny, animacje
   150-300 ms i wyłączane przy prefers-reduced-motion, zero poziomego scrolla
   od 320 px, cele dotykowe min 44 px na mobile. Ikony to SVG, nigdy emoji. */

/* ==========================================================================
   1. Tokeny — ciemny (domyślny) i jasny
   ========================================================================== */
:root{
  /* powierzchnie */
  --s-0:#0a0c0f;      /* tło aplikacji */
  --s-1:#0f1216;      /* sidebar */
  --s-2:#151a20;      /* karta */
  --s-3:#1c222a;      /* karta podniesiona / hover */
  --s-glass:rgba(15,18,22,.72);
  --line-1:#242c36;
  --line-2:#333d4a;

  /* tekst */
  --tx-1:#f4f1ea;
  --tx-2:#b9c1cc;
  --tx-3:#8d95a1;

  /* marka Affido (z logo klienta) */
  --brand:#f5911e;
  --brand-2:#e8481c;
  --kas:#4a9e2f;

  /* semantyka */
  --pos:#3ecf8e;
  --warn:#ffcc4d;
  --neg:#ff5f52;
  --info:#6aa9ff;

  /* rytm i kształt */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px;
  --r-1:8px; --r-2:12px; --r-3:16px; --r-4:22px;
  --elev-1:0 1px 2px rgba(0,0,0,.4);
  --elev-2:0 6px 22px rgba(0,0,0,.36);
  --elev-3:0 24px 70px rgba(0,0,0,.55);
  --glow:0 0 0 1px rgba(245,145,30,.28), 0 8px 32px rgba(245,145,30,.14);
  --dur:200ms;
  --ez:cubic-bezier(.2,.7,.2,1);
}

html[data-theme="light"]{
  --s-0:#f6f4ef;
  --s-1:#fffdf9;
  --s-2:#ffffff;
  --s-3:#f1ede5;
  --s-glass:rgba(255,253,249,.82);
  --line-1:#e2ddd2;
  --line-2:#cec7b8;
  --tx-1:#181c22;
  --tx-2:#4a525d;
  --tx-3:#6b7482;
  --elev-1:0 1px 2px rgba(24,28,34,.08);
  --elev-2:0 6px 22px rgba(24,28,34,.10);
  --elev-3:0 24px 70px rgba(24,28,34,.18);
}

/* Motyw przykrywa fundament z bald.css, ale nie kasuje jego zmiennych —
   inne widoki (np. logowanie) dalej działają bez tej warstwy. */
html[data-theme] body{background:var(--s-0);color:var(--tx-1)}
html[data-theme="light"] body::before,
html[data-theme="light"] body::after{opacity:.25}
html[data-theme] .app-shell{background:var(--s-0)}

/* ==========================================================================
   2. Pasek piaskownicy — widać od razu, że zapis jest wyłączony
   ========================================================================== */
.sandbox-bar{
  grid-column:1/-1;display:flex;gap:var(--sp-3);align-items:center;justify-content:center;
  padding:7px var(--sp-4);background:linear-gradient(90deg,var(--brand),var(--brand-2));
  color:#14100b;font:700 12px/1.4 var(--font);letter-spacing:.08em;text-transform:uppercase;
}
.sandbox-bar svg{width:15px;height:15px;flex:none}

/* ==========================================================================
   3. Sidebar — grupy, liczniki, zwijanie
   ========================================================================== */
html[data-theme] .app-sidebar{background:var(--s-1);border-right:1px solid var(--line-1)}
.side-group{padding:var(--sp-3) 0 var(--sp-1)}
.side-group + .side-group{border-top:1px solid var(--line-1)}
.side-group > .side-group-h{
  display:flex;align-items:center;gap:8px;width:100%;padding:6px 18px;
  font:700 10.5px/1 var(--font);letter-spacing:.18em;text-transform:uppercase;color:var(--tx-3);
}
.side-group > .side-group-h .chev{margin-left:auto;transition:transform var(--dur) var(--ez)}
.side-group[data-collapsed="1"] > .side-group-h .chev{transform:rotate(-90deg)}
.side-group[data-collapsed="1"] .side-group-items{display:none}
.side-group-h svg{width:12px;height:12px}

html[data-theme] .side-nav a{
  display:flex;align-items:center;gap:11px;padding:10px 18px;color:var(--tx-2);
  border-left:2px solid transparent;transition:background var(--dur) var(--ez),color var(--dur) var(--ez);
  min-height:44px;
}
html[data-theme] .side-nav a:hover{background:var(--s-2);color:var(--tx-1)}
html[data-theme] .side-nav a[aria-current="page"]{
  background:linear-gradient(90deg,rgba(245,145,30,.16),transparent 70%);
  color:var(--tx-1);border-left-color:var(--brand);
}
.side-nav a .ico{width:18px;text-align:center;flex:none;opacity:.9}
.side-nav a .label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side-nav .badge{
  flex:none;min-width:20px;height:20px;padding:0 6px;border-radius:999px;
  background:var(--brand);color:#14100b;font:800 11px/20px var(--font);text-align:center;
}
.side-nav .badge.quiet{background:var(--s-3);color:var(--tx-2)}

/* stopka sidebara: wersja + status licencji */
.side-foot{margin-top:auto;padding:var(--sp-4) 18px;border-top:1px solid var(--line-1);display:grid;gap:8px}
.side-foot .lic{
  display:flex;align-items:center;gap:7px;font:600 11px/1.3 var(--font);
  letter-spacing:.05em;text-transform:uppercase;color:var(--tx-3);
}
.side-foot .lic .dot{width:8px;height:8px;border-radius:50%;background:var(--pos);flex:none}
.side-foot .lic[data-state="trial"] .dot{background:var(--warn)}
.side-foot .lic[data-state="readonly"] .dot,
.side-foot .lic[data-state="suspended"] .dot,
.side-foot .lic[data-state="cancelled"] .dot{background:var(--neg)}

/* ==========================================================================
   4. Topbar — szkło, wyszukiwarka, skróty
   ========================================================================== */
html[data-theme] .app-topbar{
  background:var(--s-glass);backdrop-filter:blur(14px) saturate(1.25);
  -webkit-backdrop-filter:blur(14px) saturate(1.25);border-bottom:1px solid var(--line-1);
}
.topbar-search{
  display:flex;align-items:center;gap:9px;height:36px;padding:0 12px;min-width:190px;
  background:var(--s-2);border:1px solid var(--line-1);border-radius:999px;color:var(--tx-3);
  font:500 13px/1 var(--font);transition:border-color var(--dur) var(--ez),box-shadow var(--dur) var(--ez);
}
.topbar-search:hover{border-color:var(--line-2);color:var(--tx-2)}
.topbar-search:focus-visible{box-shadow:var(--glow)}
.topbar-search svg{width:15px;height:15px;flex:none}
.topbar-search .kbd{margin-left:auto}
@media(max-width:720px){.topbar-search .txt,.topbar-search .kbd{display:none}.topbar-search{min-width:0;padding:0 10px}}

.kbd{
  display:inline-flex;align-items:center;gap:2px;padding:2px 6px;border-radius:6px;
  background:var(--s-3);border:1px solid var(--line-1);color:var(--tx-3);
  font:600 10.5px/1.4 var(--mono);
}

html[data-theme] .app-topbar .icon-btn{background:var(--s-2);border:1px solid var(--line-1);color:var(--tx-2);min-width:38px;min-height:38px}
html[data-theme] .app-topbar .icon-btn:hover{background:var(--s-3);color:var(--brand)}
html[data-theme] .app-topbar .user-chip{background:var(--s-2);border-color:var(--line-1)}

/* ==========================================================================
   5. Paleta poleceń (⌘K / Ctrl+K)
   ========================================================================== */
.cpal-backdrop{
  position:fixed;inset:0;z-index:120;background:rgba(4,6,9,.62);
  backdrop-filter:blur(3px);display:none;
}
.cpal-backdrop[data-open="1"]{display:block}
.cpal{
  position:fixed;z-index:121;left:50%;top:12vh;transform:translateX(-50%);
  width:min(620px,92vw);background:var(--s-2);border:1px solid var(--line-2);
  border-radius:var(--r-3);box-shadow:var(--elev-3);overflow:hidden;display:none;
}
.cpal[data-open="1"]{display:block;animation:cpal-in 180ms var(--ez)}
@keyframes cpal-in{from{opacity:0;transform:translateX(-50%) translateY(-8px) scale(.985)}to{opacity:1}}
.cpal-input-row{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line-1)}
.cpal-input-row svg{width:18px;height:18px;color:var(--tx-3);flex:none}
.cpal input{
  flex:1;min-width:0;background:none;border:0;outline:none;color:var(--tx-1);
  font:500 16px/1.4 var(--font);
}
.cpal input::placeholder{color:var(--tx-3)}
.cpal-list{max-height:min(52vh,420px);overflow:auto;padding:6px}
.cpal-item{
  display:flex;align-items:center;gap:11px;width:100%;padding:10px 12px;border-radius:var(--r-1);
  color:var(--tx-2);text-align:left;min-height:44px;
}
.cpal-item .ico{width:18px;text-align:center;flex:none}
.cpal-item .t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--tx-1);font-weight:600;font-size:14px}
.cpal-item .g{font:600 10.5px/1 var(--font);letter-spacing:.14em;text-transform:uppercase;color:var(--tx-3);flex:none}
.cpal-item[aria-selected="true"],.cpal-item:hover{background:var(--s-3);color:var(--tx-1)}
.cpal-empty{padding:22px 16px;color:var(--tx-3);font-size:14px;text-align:center}
.cpal-foot{
  display:flex;gap:14px;align-items:center;padding:9px 16px;border-top:1px solid var(--line-1);
  color:var(--tx-3);font:500 11.5px/1 var(--font);
}

/* ==========================================================================
   6. KPI z iskierką i deltą
   ========================================================================== */
html[data-theme] .kpis{display:grid;gap:var(--sp-4);grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
html[data-theme] .kpi{
  position:relative;background:var(--s-2);border:1px solid var(--line-1);border-radius:var(--r-3);
  padding:var(--sp-5) var(--sp-5) var(--sp-4);overflow:hidden;min-width:0;
  transition:border-color var(--dur) var(--ez),transform var(--dur) var(--ez);
}
html[data-theme] .kpi:hover{border-color:var(--line-2);transform:translateY(-2px)}
html[data-theme] .kpi small{
  display:block;color:var(--tx-3);font:600 11px/1.4 var(--font);
  letter-spacing:.14em;text-transform:uppercase;
}
html[data-theme] .kpi b{
  display:block;margin-top:10px;font:800 clamp(26px,3.4vw,34px)/1 var(--font);
  letter-spacing:-.02em;color:var(--tx-1);font-variant-numeric:tabular-nums;
}
.kpi-delta{
  display:inline-flex;align-items:center;gap:5px;margin-top:10px;padding:3px 8px;border-radius:999px;
  font:700 11.5px/1.4 var(--font);background:rgba(62,207,142,.14);color:var(--pos);
}
.kpi-delta[data-dir="down"]{background:rgba(255,95,82,.14);color:var(--neg)}
.kpi-delta[data-dir="flat"]{background:var(--s-3);color:var(--tx-3)}
.kpi-delta svg{width:12px;height:12px}
.kpi-spark{margin-top:var(--sp-4);display:block;width:100%;height:34px;overflow:visible}
.kpi-spark path.line{fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.kpi-spark path.area{stroke:none}
.kpi-spark circle{fill:var(--brand)}
.kpi.kpi-warn{border-color:rgba(255,204,77,.4)}
.kpi.kpi-warn b{color:var(--warn)}
.kpi.kpi-warn .kpi-spark path.line{stroke:var(--warn)}

/* ==========================================================================
   7. Karty, nagłówek strony, paski narzędzi
   ========================================================================== */
html[data-theme] .panel-card{
  background:var(--s-2);border:1px solid var(--line-1);border-radius:var(--r-3);
  padding:var(--sp-5);box-shadow:var(--elev-1);min-width:0;
}
html[data-theme] .page-head{
  display:flex;align-items:flex-end;gap:var(--sp-4);flex-wrap:wrap;
  margin-bottom:var(--sp-5);padding-bottom:var(--sp-4);border-bottom:1px solid var(--line-1);
}
html[data-theme] .page-head h2{
  font:800 clamp(21px,2.6vw,27px)/1.15 var(--font);letter-spacing:-.02em;
  text-transform:none;color:var(--tx-1);
}
html[data-theme] .page-head .actions{margin-left:auto;display:flex;gap:var(--sp-2);flex-wrap:wrap}

html[data-theme] .toolbar{
  display:flex;gap:var(--sp-3);align-items:flex-end;flex-wrap:wrap;
  background:var(--s-2);border:1px solid var(--line-1);border-radius:var(--r-2);
  padding:var(--sp-3) var(--sp-4);margin-bottom:var(--sp-4);
}
html[data-theme] .toolbar .field{margin:0}
html[data-theme] .toolbar .field.grow{flex:1;min-width:180px}

/* ==========================================================================
   8. Tabele — sortowanie, filtr na żywo, przyklejony nagłówek, gęstość
   ========================================================================== */
html[data-theme] table.t{width:100%;border-collapse:collapse;font-size:14px}
html[data-theme] table.t th{
  position:sticky;top:0;z-index:1;background:var(--s-3);color:var(--tx-2);text-align:left;
  font:700 11px/1.4 var(--font);letter-spacing:.12em;text-transform:uppercase;
  padding:11px var(--sp-3);border-bottom:1px solid var(--line-2);white-space:nowrap;
}
html[data-theme] table.t td{padding:12px var(--sp-3);border-bottom:1px solid var(--line-1);color:var(--tx-1);vertical-align:top}
html[data-theme] table.t tbody tr:hover td{background:var(--s-3)}
html[data-theme] table.t tbody tr[hidden]{display:none}
html[data-theme=""] table.t td{}
[data-density="compact"] table.t td{padding:7px var(--sp-3)}
[data-density="compact"] table.t th{padding:8px var(--sp-3)}

th[data-sort]{cursor:pointer;user-select:none}
th[data-sort]:hover{color:var(--tx-1)}
th[data-sort]::after{content:"";display:inline-block;width:0;height:0;margin-left:7px;vertical-align:middle;opacity:.35;
  border-left:4px solid transparent;border-right:4px solid transparent;border-top:5px solid currentColor}
th[aria-sort="ascending"]::after{opacity:1;border-top:0;border-bottom:5px solid var(--brand)}
th[aria-sort="descending"]::after{opacity:1;border-top:5px solid var(--brand)}

.table-tools{display:flex;gap:var(--sp-2);align-items:center;margin-bottom:var(--sp-3);flex-wrap:wrap}
.table-tools input[type="search"]{
  flex:1;min-width:170px;height:38px;padding:0 12px;border-radius:var(--r-1);
  background:var(--s-2);border:1px solid var(--line-1);color:var(--tx-1);font:500 14px/1 var(--font);
}
.table-tools input[type="search"]:focus-visible{outline:none;box-shadow:var(--glow);border-color:var(--brand)}
.table-count{color:var(--tx-3);font:600 12px/1 var(--mono);white-space:nowrap}

/* ==========================================================================
   9. Pigułki statusów
   ========================================================================== */
html[data-theme] .pill{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;
  background:var(--s-3);color:var(--tx-2);font:700 11.5px/1.5 var(--font);white-space:nowrap;
}
html[data-theme] .pill.ok{background:rgba(62,207,142,.14);color:var(--pos)}
html[data-theme] .pill.draft{background:rgba(255,204,77,.14);color:var(--warn)}
html[data-theme] .pill.no{background:rgba(255,95,82,.14);color:var(--neg)}

/* ==========================================================================
   10. Toasty
   ========================================================================== */
.toast-wrap{position:fixed;right:16px;bottom:16px;z-index:130;display:grid;gap:10px;max-width:min(380px,92vw)}
.toast{
  display:flex;gap:11px;align-items:flex-start;padding:13px 15px;border-radius:var(--r-2);
  background:var(--s-2);border:1px solid var(--line-2);box-shadow:var(--elev-2);color:var(--tx-1);
  font:500 14px/1.45 var(--font);animation:toast-in 200ms var(--ez);
}
.toast[data-kind="ok"]{border-left:3px solid var(--pos)}
.toast[data-kind="err"]{border-left:3px solid var(--neg)}
.toast[data-kind="info"]{border-left:3px solid var(--info)}
.toast svg{width:18px;height:18px;flex:none;margin-top:1px}
.toast[data-kind="ok"] svg{color:var(--pos)}
.toast[data-kind="err"] svg{color:var(--neg)}
.toast button{margin-left:auto;color:var(--tx-3);flex:none;min-width:32px;min-height:32px}
.toast button:hover{color:var(--tx-1)}
@keyframes toast-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ==========================================================================
   11. Przyciski — wyrównane do marki
   ========================================================================== */
html[data-theme] .btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:10px 16px;border-radius:var(--r-1);font:700 13.5px/1 var(--font);
  min-height:40px;transition:transform var(--dur) var(--ez),background var(--dur) var(--ez),border-color var(--dur) var(--ez);
}
html[data-theme] .btn:active{transform:scale(.98)}
html[data-theme] .btn-primary{background:var(--brand);color:#14100b}
html[data-theme] .btn-primary:hover{background:#ffa63c}
html[data-theme] .btn-ghost{background:var(--s-2);border:1px solid var(--line-1);color:var(--tx-1)}
html[data-theme] .btn-ghost:hover{background:var(--s-3);border-color:var(--line-2)}
html[data-theme] .btn-danger{background:rgba(255,95,82,.16);color:var(--neg);border:1px solid rgba(255,95,82,.36)}
html[data-theme] .btn-danger:hover{background:rgba(255,95,82,.24)}
html[data-theme] .btn-sm{padding:7px 12px;min-height:34px;font-size:12.5px}

/* ==========================================================================
   12. Pola formularzy
   ========================================================================== */
html[data-theme] .field label{display:block;margin-bottom:6px;color:var(--tx-3);font:600 11.5px/1.4 var(--font);letter-spacing:.1em;text-transform:uppercase}
html[data-theme] .field input,html[data-theme] .field select,html[data-theme] .field textarea{
  width:100%;padding:10px 12px;min-height:42px;border-radius:var(--r-1);
  background:var(--s-2);border:1px solid var(--line-1);color:var(--tx-1);font:500 15px/1.4 var(--font);
}
html[data-theme] .field input:focus-visible,html[data-theme] .field select:focus-visible,html[data-theme] .field textarea:focus-visible{
  outline:none;border-color:var(--brand);box-shadow:var(--glow);
}
html[data-theme] .field .hint{margin-top:5px;color:var(--tx-3);font-size:12.5px}
html[data-theme] .field .err{margin-top:5px;color:var(--neg);font-size:12.5px}

/* ==========================================================================
   13. Dostępność i ruch
   ========================================================================== */
html[data-theme] :focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
  .cpal[data-open="1"]{animation:none}
}
@media(max-width:980px){
  .cpal{top:8vh}
  .toast-wrap{left:12px;right:12px;max-width:none}
}

/* ==========================================================================
   14. Przełącznik języka — globus i rozwijane menu (nigdy rząd przycisków)
   ========================================================================== */
.lang-menu{position:relative;flex:none}
.lang-menu > summary{
  display:flex;align-items:center;gap:6px;list-style:none;cursor:pointer;
  height:38px;padding:0 10px;border-radius:var(--r-1);
  background:var(--s-2);border:1px solid var(--line-1);color:var(--tx-2);
  font:700 12px/1 var(--font);letter-spacing:.06em;
}
.lang-menu > summary::-webkit-details-marker{display:none}
.lang-menu > summary:hover{background:var(--s-3);color:var(--tx-1)}
.lang-menu > summary svg{width:17px;height:17px}
.lang-menu[open] > summary{border-color:var(--brand);color:var(--tx-1)}
.lang-list{
  position:absolute;right:0;top:calc(100% + 6px);z-index:50;min-width:180px;padding:6px;
  background:var(--s-2);border:1px solid var(--line-2);border-radius:var(--r-2);box-shadow:var(--elev-2);
  display:grid;gap:2px;
}
.lang-list a{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-1);
  color:var(--tx-2);font-size:13.5px;min-height:40px;
}
.lang-list a:hover{background:var(--s-3);color:var(--tx-1)}
.lang-list a.on{color:var(--brand)}
.lang-list .code{font:700 11px/1 var(--mono);letter-spacing:.08em;opacity:.75;width:26px;flex:none}

/* ==========================================================================
   15. Stany puste — ikona w kółku zamiast emoji
   ========================================================================== */
html[data-theme] .empty-state{
  display:grid;justify-items:center;gap:10px;padding:var(--sp-7) var(--sp-4);
  border:1px dashed var(--line-2);border-radius:var(--r-3);color:var(--tx-3);text-align:center;
}
html[data-theme] .empty-state .ico{
  display:grid;place-items:center;width:52px;height:52px;border-radius:50%;
  background:var(--s-3);color:var(--tx-2);
}
html[data-theme] .empty-state.is-error .ico{background:rgba(255,95,82,.14);color:var(--neg)}
html[data-theme] .empty-state p{margin:0;font-size:14px}

/* ==========================================================================
   16. Tabele w kartach — poziome przewijanie zamiast obcinania kolumn
   ========================================================================== */
html[data-theme] .tscroll{overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch;margin-inline:calc(var(--sp-4) * -1);padding-inline:var(--sp-4)}
html[data-theme] .tscroll table.t{min-width:640px}
html[data-theme] .tscroll::-webkit-scrollbar{height:8px}
html[data-theme] .tscroll::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:999px}
html[data-theme] .scrollhint{margin-top:8px;color:var(--tx-3);font-size:12px}
@media(min-width:1100px){html[data-theme] .scrollhint{display:none}}

/* ==========================================================================
   17. Topbar na telefonie — nic nie wypada poza ekran
   ========================================================================== */
@media(max-width:820px){
  html[data-theme] .app-topbar{gap:8px;padding:0 12px}
  html[data-theme] .app-topbar h1{font-size:14px}
  #densityToggle{display:none}
  .lang-menu > summary .cur{display:none}
  .lang-menu > summary{padding:0 8px}
  html[data-theme] .app-topbar .user-chip{padding:5px;gap:0}
  html[data-theme] .app-topbar .user-meta{display:none}
}
@media(max-width:560px){
  html[data-theme] .app-topbar h1{display:none}
  .topbar-search{margin-left:auto}
}

/* ==========================================================================
   14. Marka instancji — logo klienta wgrane w kreatorze instalacji
   ========================================================================== */
.app-sidebar .brand-row .mark img,
.auth-brand .mark img{
  width:100%;height:100%;object-fit:contain;border-radius:inherit;
  /* Logo bywa jasne albo ciemne: kafelek marki daje mu stale tlo, wiec kontrast
     nie zalezy od tego, co klient wgral. */
  padding:2px;background:transparent;
}
.app-sidebar .brand-row a > span:last-child{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:168px;
}

/* BSN: maska + przycisk odsloniecia. Numer przychodzi dopiero po kliknieciu,
   z audytowanego endpointu, wiec komorka musi pomiescic obie dlugosci bez skakania. */
.bsn-cell{display:inline-flex;align-items:center;gap:10px;justify-content:flex-end}
.bsn-cell .mono{min-width:11ch;text-align:right}
.btn-xs{font-size:11.5px;padding:4px 9px;border-radius:7px;line-height:1.4;cursor:pointer}
.btn-xs[disabled]{opacity:.55;cursor:progress}
.field-locked{display:flex;align-items:center;gap:8px}

/* ==========================================================================
   15. Kolumna akcji zawsze w kadrze
   --------------------------------------------------------------------------
   Przy oknie 1440 px oprawa .tscroll ma ~1136 px, a tabela pracownikow ~1196 px
   zawartosci. Roznica jest mala, ale wypada na nia dokladnie kolumna "Akcje",
   wiec zeby kliknac "Edytuj" trzeba bylo przewijac tabele w bok. Przyklejamy
   ostatnia kolumne do prawej krawedzi scrollportu: reszta tabeli dalej przewija
   sie poziomo, a glowna akcja wiersza jest widoczna od razu, takze na telefonie.

   Komorka przyklejona musi miec nieprzezroczyste tlo, inaczej tekst spod spodu
   przebija. Tlo bierzemy z tokenow motywu, wiec dziala i ciemny, i jasny.
   ========================================================================== */
html[data-theme] .tscroll{position:relative}

html[data-theme] table.t th.col-actions,
html[data-theme] table.t td.col-actions{
  position:sticky;right:0;
  /* cien tylko od lewej — sygnalizuje, ze pod spodem jest jeszcze tresc */
  box-shadow:-14px 0 16px -14px rgba(0,0,0,.85);
}
/* naglowek jest juz sticky top; z-index musi byc wyzszy niz komorki, zeby rog
   naglowek x akcje nie migal przy przewijaniu w obu osiach */
html[data-theme] table.t th.col-actions{z-index:3;background:var(--s-3)}
html[data-theme] table.t td.col-actions{z-index:2;background:var(--s-0)}
/* tabela w karcie stoi na innej powierzchni niz tabela na golej stronie */
html[data-theme] .panel-card .tscroll table.t td.col-actions{background:var(--s-2)}
/* hover wiersza nie moze omijac przyklejonej komorki */
html[data-theme] table.t tbody tr:hover td.col-actions{background:var(--s-3)}

html[data-theme="light"] table.t th.col-actions,
html[data-theme="light"] table.t td.col-actions{
  box-shadow:-14px 0 16px -14px rgba(24,28,34,.30);
}

/* Na waskim ekranie przyciski akcji lamia sie w pion zamiast rozpychac tabele. */
@media(max-width:560px){
  html[data-theme] table.t .row-actions{flex-direction:column;align-items:stretch;gap:5px}
  html[data-theme] table.t td.col-actions{max-width:132px}
}

/* Ikony Phosphor w tresci przyciskow i naglowkow: linia bazowa i odstep. */
html[data-theme] .btn svg.ph,
html[data-theme] .tag svg.ph{vertical-align:-2px;flex:none}
html[data-theme] .field-locked svg.ph{flex:none}
html[data-theme] .empty-state .ico svg.ph{display:block}
html[data-theme] .search-field .ico svg.ph{display:block}

/* Kropka statusu w pigulce. Byla znakiem "●" wpisanym w tresc widoku — czytnik
   ekranu ja odczytywal, a rozmiar zalezal od font-size. Teraz rysuje ja CSS,
   wiec tresc pigulki to sam tekst statusu. */
html[data-theme] .pill::before{
  content:"";flex:none;width:6px;height:6px;border-radius:50%;
  background:currentColor;opacity:.9;
}

/* Lupa w polu wyszukiwania. admin.css centruje ikone wzgledem CALEGO pola
   (etykieta + input), wiec ladowala na granicy etykiety zamiast w srodku inputa.
   Kotwiczymy ja do dolnej krawedzi i centrujemy na wysokosci samego inputa. */
html[data-theme] .search-field .ico{
  top:auto;bottom:0;transform:none;
  height:42px;display:flex;align-items:center;
  color:var(--tx-3);pointer-events:none;
}
/* admin2 nadpisuje padding pol formularza, wiec lupa wchodzila na tekst.
   Przywracamy miejsce na ikone. */
html[data-theme] .search-field input{padding-left:38px}

/* Naglowki tabel sa nowrap, wiec dluzsze etykiety (PL/UK: "DATA ZAKONCZENIA
   KONTRAKTU") rozpychaly tabele ponad szerokosc oprawy juz przy 1440 px.
   Na szerokim ekranie pozwalamy im sie zlamac — tabela miesci sie w kadrze,
   a przyklejona kolumna akcji zostaje zabezpieczeniem dla weszszych okien. */
@media(min-width:1100px){
  html[data-theme] table.t th{white-space:normal;min-width:0}
}

/* ==========================================================================
   Modul podpisow elektronicznych (/panel/handtekeningen)
   Obraz podpisu jest jasnym rysunkiem na przezroczystym tle, wiec w ciemnym
   motywie sam z siebie bylby niewidoczny. Dlatego miniatura i podglad dostaja
   wlasne, zawsze jasne tlo - podpis ma byc czytelny w obu motywach.
   ========================================================================== */
html[data-theme] .page-sub{
  margin-top:6px;color:var(--tx-3);font-size:13.5px;max-width:60ch;
}
html[data-theme] .muted{color:var(--tx-3);font-size:12.5px}

html[data-theme] .sig-hash{
  display:inline-block;margin-left:8px;padding:2px 7px;border-radius:6px;
  background:var(--s-3);color:var(--tx-3);
  font:600 11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;
  letter-spacing:.04em;vertical-align:1px;
}
html[data-theme] .sig-reason{
  display:block;margin-top:5px;color:var(--tx-3);font-size:12px;max-width:32ch;
}

html[data-theme] .sig-thumb{
  width:120px;height:44px;object-fit:contain;display:block;
  background:#f4f1ea;border:1px solid var(--line-1);border-radius:var(--r-1);padding:2px;
}

html[data-theme] .sig-view-frame{
  background:#f4f1ea;border:1px solid var(--line-1);border-radius:var(--r-2);
  padding:var(--sp-3);margin:var(--sp-3) 0;
}
html[data-theme] .sig-view-frame img{
  display:block;width:100%;max-width:100%;height:auto;max-height:44vh;object-fit:contain;
}
html[data-theme] .sig-view-meta{color:var(--tx-2);font-size:13.5px}
html[data-theme] .sig-view-hash{
  color:var(--tx-3);font:600 11.5px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;
  overflow-wrap:anywhere;
}

/* Telefon: kolumna z miniatura zjada szerokosc, ktorej i tak nie ma.
   Zmniejszamy podglad zamiast pozwolic tabeli rozepchnac strone. */
@media(max-width:520px){
  html[data-theme] .sig-thumb{width:84px;height:34px}
  html[data-theme] .sig-reason{max-width:22ch}
}

/* ===========================================================================
   KODY AKTYWACYJNE (/panel/kody)
   Dopisek do arkusza, zero zmian w regulach powyzej. Kod jest widoczny raz,
   wiec musi byc czytelny bez zgadywania: monospace, duzy rozstaw znakow,
   pelna szerokosc wiersza takze na telefonie.
   =========================================================================== */
html[data-theme] .codes-issue{margin-bottom:var(--sp-4)}
html[data-theme] .codes-issue-title{
  display:flex;align-items:center;gap:8px;margin:0 0 4px;font-size:15px;
}
html[data-theme] .codes-issue-sub{margin:0 0 var(--sp-3);color:var(--tx-3);font-size:13px}
html[data-theme] .codes-issue-form{margin:0}

html[data-theme] .codes-id{
  display:inline-block;margin-left:8px;color:var(--tx-3);
  font:600 11.5px/1 ui-monospace,SFMono-Regular,Menlo,monospace;vertical-align:1px;
}
html[data-theme] .codes-sub{display:block;margin-top:3px;color:var(--tx-3);font-size:12px}

/* Ostrzezenie w oknie z nowymi kodami. Nie jest ozdobne: to jedyny moment,
   w ktorym kod da sie odczytac, wiec komunikat ma zatrzymac wzrok. */
html[data-theme] .codes-warning{
  display:flex;align-items:flex-start;gap:9px;margin:0 0 var(--sp-3);
  padding:10px 12px;border-radius:var(--r-2);
  border:1px solid color-mix(in srgb,var(--warn,#e0a200) 45%,transparent);
  background:color-mix(in srgb,var(--warn,#e0a200) 12%,transparent);
  color:var(--tx-1);font-size:13.5px;line-height:1.5;
}
html[data-theme] .codes-warning svg{flex:0 0 auto;margin-top:1px}

html[data-theme] .codes-fresh{list-style:none;margin:0;padding:0;display:grid;gap:8px}
html[data-theme] .codes-fresh-row{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 11px;border:1px solid var(--line-1);border-radius:var(--r-2);
  background:var(--bg-2,transparent);
}
html[data-theme] .codes-fresh-code{
  flex:1 1 14ch;
  font:700 17px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace;
  letter-spacing:.16em;color:var(--tx-1);overflow-wrap:anywhere;
}
html[data-theme] .codes-fresh-exp{flex:1 1 100%;color:var(--tx-3);font-size:12px;order:3}

@media(min-width:560px){
  html[data-theme] .codes-fresh-exp{flex:0 1 auto;order:0}
}

/* ==========================================================================
   Galeria zdjec z budowy (/panel/fotos). Grid dopasowany do szerokosci,
   zero przewijania w bok. Miniatura 4:3, klik otwiera pelny obraz w nowej
   karcie (widok jest bezskryptowy, zgodnie z CSP script-src 'self').
   ========================================================================== */
html[data-theme] .photo-grid{
  display:grid;gap:var(--sp-3,12px);margin-top:var(--sp-3,12px);
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
}
html[data-theme] .photo-card{
  margin:0;border:1px solid var(--line-1);border-radius:var(--r-2,12px);
  background:var(--bg-2,transparent);overflow:hidden;display:flex;flex-direction:column;min-width:0;
}
html[data-theme] .photo-thumb{
  display:block;aspect-ratio:4/3;background:var(--bg-1,#111);overflow:hidden;
}
html[data-theme] .photo-thumb img{width:100%;height:100%;object-fit:cover;display:block}
html[data-theme] .photo-thumb:focus-visible{outline:3px solid var(--brand);outline-offset:-3px}
html[data-theme] .photo-meta{
  display:flex;flex-direction:column;gap:2px;padding:9px 11px;min-width:0;
}
html[data-theme] .photo-meta b{font-size:13.5px;color:var(--tx-1);overflow-wrap:anywhere}
html[data-theme] .photo-proj{font-size:12px;color:var(--tx-2,var(--tx-1));overflow-wrap:anywhere}
html[data-theme] .photo-note{
  font-size:12.5px;color:var(--tx-1);overflow-wrap:anywhere;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
html[data-theme] .photo-when{font-size:11px;color:var(--tx-3);font-variant-numeric:tabular-nums}
