/* OBDometer — panel. Wartosci wprost z designu (Claude Design,
   podglad w design/OBDometer Logo Standalone.html).
   Zasady designu: ostre kanty (zero border-radius), linie 1px,
   Archivo, zolty/czerwony TYLKO na stany, cyjan TYLKO przy AdBlue. */

/* Archivo hostowane lokalnie (pliki wyciagniete z bundla designu) — swiadomie
   bez CDN Google, zeby panel dzialal tez bez internetu. To font zmienny:
   jeden plik obsluguje caly zakres grubosci, stad "font-weight: 400 800". */
@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
        U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
        U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('../fonts/archivo-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
        U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
        U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
    /* Kolory: role, nie nazwy odcieni */
    --c-bg:            #14161a;   /* tlo bazowe */
    --c-bg-sunken:     #0e0f12;   /* zaglebienia: wykresy, tlo pod danymi */
    --c-surface:       #1c1f26;   /* panel / karta */
    --c-border:        #2a2e37;   /* obramowanie, linie */
    --c-border-subtle: #1c1f26;   /* linie wewnatrz tabel (slabsze niz --c-border) */
    --c-text:          #e6e8eb;   /* tekst glowny */
    --c-text-muted:    #8a8f99;   /* tekst drugorzedny, etykiety, metadane */
    --c-accent:        #3a7bd5;   /* marka / akcent podstawowy */
    --c-accent-bright: #6fb1fc;   /* akcent jasny: hover, wykresy */
    --c-adblue:        #3ab0d5;   /* TYLKO AdBlue */
    --c-warn:          #d5a83a;   /* ostrzezenie */
    --c-warn-bg:       #2a2419;
    --c-crit:          #d5473a;   /* alarm / stan krytyczny */
    --c-crit-bg:       #2a1c1c;
    --c-ok:            #5ad57a;   /* sukces / OK */
    --c-ok-bg:         #1c2620;

    /* Typografia */
    --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --t-h1:    40px;
    --t-h2:    28px;
    --t-h3:    18px;
    --t-body:   15px;
    --t-help:   13px;
    --t-label:  11px;
    --t-metric: 34px;  /* liczba / dana telemetryczna (zawsze 700) */

    /* Skala odstepow */
    --s-1: 4px;
    --s-2: 8px;
    --s-3: 12px;
    --s-4: 16px;
    --s-6: 24px;
    --s-8: 32px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: var(--t-body);
    background: var(--c-bg);
    color: var(--c-text);
}

/* Topbar */
header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 28px;
    border-bottom: 1px solid var(--c-border);
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
}
/* Sygnet: viewBox 100x100, ale rysunek zajmuje tylko srodkowy pas w pionie
   (y 25-75), wiec widoczny pierscien ma ~pol wysokosci elementu img. */
.brand-mark {
    height: 36px;
    width: auto;
    display: block;
    flex-shrink: 0;
}
.brand-name {
    font-weight: 700;
    font-size: 16px;
    letter-spacing: .03em;
    color: var(--c-text);
}

nav {
    display: flex;
    gap: var(--s-6);
    margin-left: 36px;
}

/* Zakladki: podkreslenie akcentem zamiast pigulki — jak w makiecie topbara.
   Swiadomie BEZ ujemnego marginesu dociagajacego kreske do dolnej krawedzi
   headera: przy align-items:center taki trik przesuwa element o polowe
   marginesu i lamie sie przy kazdej zmianie paddingu/wysokosci headera. */
.tab-btn {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--c-text-muted);
    font-family: inherit;
    font-size: var(--t-help);
    padding: 0 0 6px;
    cursor: pointer;
}
.tab-btn:hover { color: var(--c-text); }
.tab-btn.active {
    color: var(--c-text);
    border-bottom-color: var(--c-accent);
}

main { padding: var(--s-6) 28px; max-width: 1200px; margin: 0 auto; }

.tab { display: none; }
.tab.active { display: block; }

/* Panele
   Kontener sekcji trzyma tlo bazowe i odcina sie linia 1px — karty/widgety
   WEWNATRZ dostaja jasniejsze --c-surface (tak jak w makietach: kontener
   #14161a, widget #1c1f26). Dzieki temu subtelne linie w tabelach
   (--c-border-subtle) sa widoczne, bo leza na ciemniejszym tle. */
.panel {
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    padding: var(--s-6) 28px;
    margin-bottom: var(--s-6);
}
.panel.hidden { display: none; }

.panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--s-4);
}
.panel-header h2 { margin: 0; font-size: var(--t-h3); font-weight: 700; color: var(--c-text); }

/* Tabele */
table { width: 100%; border-collapse: collapse; font-size: var(--t-help); }

th {
    text-align: left;
    padding: 10px var(--s-3);
    font-weight: 700;
    font-size: var(--t-label);
    color: var(--c-text-muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    border-bottom: 1px solid var(--c-border);
}
td {
    padding: 10px var(--s-3);
    border-bottom: 1px solid var(--c-border-subtle);
}
/* --c-surface, nie --c-bg: kontener sekcji ma teraz tlo bazowe, wiec hover
   musi byc JASNIEJSZY, inaczej jest niewidoczny. */
tbody tr:hover { background: var(--c-surface); }
tbody tr.clickable { cursor: pointer; }

/* Przyciski */
.btn-primary, .btn-secondary, .btn-danger {
    font-family: var(--font);
    font-weight: 700;
    font-size: var(--t-help);
    letter-spacing: .02em;
    padding: 11px 22px;
    border: none;
    cursor: pointer;
}
.btn-primary { background: var(--c-accent); color: var(--c-bg-sunken); }
.btn-primary:hover { background: var(--c-accent-bright); }

.btn-secondary { background: transparent; color: var(--c-text); border: 1px solid var(--c-border); }
.btn-secondary:hover { border-color: var(--c-text-muted); }

/* Tekst ciemny, nie bialy — czerwien jest jasna, ciemny tekst daje lepszy kontrast */
.btn-danger { background: var(--c-crit); color: var(--c-bg); }
.btn-danger:hover { filter: brightness(1.12); }

.btn-primary:disabled, .btn-secondary:disabled, .btn-danger:disabled {
    opacity: .4;
    cursor: not-allowed;
}

.btn-small { padding: 6px var(--s-3); font-size: 12px; }

/* Przycisk ikonowy — wariant z makiety designu (kwadrat, tlo karty, linia 1px),
   przeskalowany w dol na gestą tabele. Kolor ikony przez currentColor, wiec
   SVG dziedziczy go z tych regul. */
.btn-icon {
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    color: var(--c-text);
    cursor: pointer;
    vertical-align: middle;
}
.btn-icon:hover { border-color: var(--c-accent); color: var(--c-accent-bright); }
.btn-icon svg { width: 14px; height: 14px; display: block; }
.btn-icon.danger { color: var(--c-crit); }
.btn-icon.danger:hover { border-color: var(--c-crit); color: var(--c-crit); }

/* Formularze */
form { display: flex; flex-direction: column; gap: var(--s-4); max-width: 420px; }
form label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-weight: 700;
    font-size: 12px;
    color: var(--c-text);
}

input, select {
    font-family: var(--font);
    font-size: 14px;
    padding: 10px var(--s-3);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    color: var(--c-text);
}
input:focus, select:focus {
    outline: none;
    border-color: var(--c-accent);
}
input::placeholder { color: var(--c-text-muted); }
input[type="checkbox"] { width: 16px; height: 16px; padding: 0; accent-color: var(--c-accent); }

/* Etykieta z checkboxem ustawia sie w linii, nie w kolumnie jak reszta pol.
   :has() zamiast dodatkowej klasy — dziala automatycznie dla kazdego przyszlego
   checkboxa w formularzu, bez pamietania o modyfikatorze w szablonie. */
form label:has(> input[type="checkbox"]) {
    flex-direction: row;
    align-items: center;
    gap: var(--s-2);
}

/* Stan bledu pola (element 4b designu): obramowanie + komunikat w kolorze alarmu */
input.error, select.error { border-color: var(--c-crit); }
.field-hint { font-size: 12px; color: var(--c-text-muted); }
.field-error { font-size: 12px; color: var(--c-crit); }

/* Wlasna strzalka selecta — natywna jest rysowana przez system i na ciemnym tle
   wyglada obco. Uwaga: sama rozwinieta lista opcji pozostaje systemowa, tego nie
   da sie ostylowac bez pisania wlasnego komponentu. */
select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238a8f99' stroke-width='1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 10px 6px;
    padding-right: 28px;
}

.form-actions { display: flex; gap: 10px; margin-top: 6px; }

.pid-cell-input { width: 90px; }
.pid-cell-input.wide { width: 140px; }

/* Gęste tabele edycyjne (konfiguracja PIDów)
   Świadome odejście od skali z brandbooka: 11 kolumn z polami edycyjnymi nie
   mieści się w 1200px przy odstępach 10/12px i foncie 13px. Zagęszczamy komórki
   i pola; gdy i to nie wystarczy (wąskie okno), kontener przewija się w poziomie
   zamiast rozpychać layout. Szerokości celowane po atrybucie data-f, żeby nie
   mnożyć klas w szablonie wiersza w app.js. */
.table-scroll { overflow-x: auto; }

.table-dense { font-size: 12px; }
.table-dense th,
.table-dense td { padding: 5px 6px; }
.table-dense th { font-size: 10px; letter-spacing: .04em; }
.table-dense input { padding: 5px 7px; font-size: 12px; }
.table-dense input[type="checkbox"] { width: 15px; height: 15px; }
/* Kolumna akcji: przyciski w jednej linii, inaczej wiersz rośnie 3x.
   Odstep przez margines na rodzenstwie, nie flex na <td> — zmiana display
   komorki tabeli potrafi rozjechac layout kolumn. */
.table-dense td:last-child { white-space: nowrap; }
.row-actions .btn-icon + .btn-icon { margin-left: var(--s-1); }
.table-dense .btn-small { padding: 5px var(--s-2); font-size: 11px; }

.table-dense input[data-f="pidHex"]         { width: 54px; }
.table-dense input[data-f="name"]           { width: 132px; }
.table-dense input[data-f="formula"]        { width: 136px; }
.table-dense input[data-f="unit"]           { width: 52px; }
.table-dense input[data-f="minValue"]       { width: 56px; }
.table-dense input[data-f="maxValue"]       { width: 56px; }
.table-dense input[data-f="haEntity"]       { width: 116px; }
.table-dense input[data-f="haDeviceClass"]  { width: 96px; }
.table-dense input[data-f="pollIntervalMs"] { width: 70px; }

/* Bloki szczegolow */
.detail-block { margin-top: var(--s-6); }
.detail-block-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}
.detail-block h3 {
    margin: 0 0 10px;
    font-size: var(--t-help);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--c-text-muted);
}

.empty-hint { color: var(--c-text-muted); font-size: var(--t-help); }
.hidden { display: none !important; }

/* Widget DPF / AdBlue
   Technika z makiety: gap 1px na tle --c-border daje wlosowe linie miedzy
   kartami bez rysowania obramowan (i bez podwojnych kresek na stykach). */
.dpf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1px;
    background: var(--c-border);
    border: 1px solid var(--c-border);
}
.dpf-card {
    background: var(--c-surface);
    padding: 20px;
}
.dpf-card-label {
    font-size: var(--t-label);
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--c-text-muted);
    margin-bottom: var(--s-2);
}
/* Dana telemetryczna. Modyfikatory kolorow stanu: cyjan zarezerwowany wylacznie
   dla AdBlue, zolty/czerwony wylacznie dla ostrzezenia/alarmu — zeby dane nigdy
   nie mylily sie z chromem UI (zasada z designu). */
.dpf-card-value { font-size: var(--t-metric); font-weight: 700; color: var(--c-text); margin-top: var(--s-2); }
.dpf-card-value.adblue { color: var(--c-adblue); }
.dpf-card-value.warn { color: var(--c-warn); }
.dpf-card-value.crit { color: var(--c-crit); }
.dpf-card-sub { font-size: 12px; color: var(--c-text-muted); margin-top: 6px; }

.dpf-bar {
    height: 10px;
    background: var(--c-border);
    overflow: hidden;
}
.dpf-bar-fill {
    height: 100%;
    width: 0;
    background: var(--c-accent);
    transition: width .3s;
}
.dpf-bar-fill.adblue { background: var(--c-adblue); }
.dpf-bar-fill.warn { background: var(--c-warn); }
.dpf-bar-fill.crit { background: var(--c-crit); }

/* Badge statusu */
.badge {
    display: inline-block;
    padding: 3px var(--s-2);
    font-weight: 700;
    font-size: var(--t-label);
    letter-spacing: .03em;
    text-transform: uppercase;
    background: var(--c-border);
    color: var(--c-text-muted);
}
.badge-active { background: var(--c-warn-bg); color: var(--c-warn); }
.badge-inactive { background: var(--c-ok-bg); color: var(--c-ok); }

/* Modal (test formuly) */
.modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 50;
}
.modal-box {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    padding: var(--s-6) 28px;
    width: 340px;
}
.modal-box h3 {
    margin: 0 0 var(--s-3);
    font-size: var(--t-h3);
    font-weight: 700;
    color: var(--c-text);
}

.formula-test-formula {
    background: var(--c-bg-sunken);
    border: 1px solid var(--c-border);
    padding: var(--s-2) 10px;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: var(--t-help);
    margin-bottom: var(--s-3);
    word-break: break-all;
}
.formula-test-inputs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-2);
    margin-bottom: var(--s-4);
}
.formula-test-inputs label {
    display: flex;
    flex-direction: column;
    gap: var(--s-1);
    font-size: 12px;
    font-weight: 700;
    color: var(--c-text-muted);
}
.formula-test-inputs input { width: 100%; padding: 6px var(--s-2); }
.formula-test-result { margin-top: var(--s-3); font-size: 14px; color: var(--c-ok); }
.formula-test-result.error { color: var(--c-crit); }

/* Stopka */
footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4);
    flex-wrap: wrap;
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--s-4) 28px var(--s-8);
    border-top: 1px solid var(--c-border);
    font-size: 12px;
    color: var(--c-text-muted);
}
footer strong { font-weight: 700; letter-spacing: .03em; color: var(--c-text); }

/* Sygnet FilipSoftware + nasz tekst zamiast pelnego logo z nazwa: w pelnej wersji
   napis "FILIP" jest ciemnofioletowy, a czesc kropek ciemnoczerwona — na tle
   --c-bg praktycznie znikaja. Tekst kolorowany przez CSS nie ma tego problemu.
   Pliki hostowane lokalnie (nie hotlink do fsoft.pl), zeby panel dzialal offline. */
.footer-copy {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
}
.footer-logo {
    height: 18px;
    width: auto;
    display: block;
}

/* Toast
   Tlo spojne z charakterem akcji: te same pary tlo/tekst co badge'y statusow
   (--c-ok-bg/--c-ok, --c-crit-bg/--c-crit), wiec potwierdzenie i blad czyta sie
   od razu po kolorze, bez czytania tresci. Zielen/czerwien TYLKO tutaj jako stan,
   nigdy dekoracyjnie — zasada z designu. */
.toast {
    position: fixed;
    bottom: 20px;
    right: 20px;
    background: var(--c-ok-bg);
    border: 1px solid var(--c-ok);
    color: var(--c-ok);
    padding: var(--s-3) var(--s-4);
    font-size: var(--t-help);
    font-weight: 600;
    z-index: 60;
}
.toast.error {
    background: var(--c-crit-bg);
    border-color: var(--c-crit);
    color: var(--c-crit);
}
