@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap');

/* ===== OLED monochrome, data-first ===== */
:root{
  --bg:#000000; --panel:#0a0a0a; --panel-2:#0f0f0f;
  --border:#333333; --border-2:#222222;
  --fg:#ffffff; --muted:#8a8a8a; --muted-2:#5a5a5a; --line:#aaaaaa;
  --alert:#ff453a; --alert-bg:#1a0605;
  --radius:4px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--fg);
  font-family:'Inter',system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased; min-height:100vh;
}
.mono{font-family:'Fira Code',ui-monospace,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}
.wrap{max-width:1280px;margin:0 auto;padding:16px 16px 64px}
a{color:var(--fg)}

/* top bar */
.topbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px;
  padding-bottom:14px;border-bottom:1px solid var(--border)}
.brand h1{font-size:15px;font-weight:600;margin:0;letter-spacing:.01em}
.brand .sub{font-size:12px;color:var(--muted);margin:0}
.topbar .spacer{flex:1}

/* chips */
.chip{display:inline-flex;align-items:center;gap:7px;padding:5px 10px;border-radius:var(--radius);
  font-size:12px;font-weight:500;border:1px solid var(--border);background:var(--panel);white-space:nowrap}
.chip .dot{width:7px;height:7px;border-radius:50%;background:var(--muted)}
.chip.live .dot{background:var(--fg);animation:blink 2s infinite}
.chip.live{color:var(--fg)}
.chip.stale{color:var(--muted)} .chip.stale .dot{background:var(--muted)}
.chip.calib{color:var(--fg);border-color:var(--fg)} .chip.calib .dot{background:var(--fg)}
.chip.error,.chip.alarm{color:var(--alert);border-color:var(--alert)} .chip.error .dot,.chip.alarm .dot{background:var(--alert)}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.35}}

/* sections / cards */
.section-title{font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:.08em;margin:22px 2px 10px}
.grid{display:grid;gap:12px}
.cols-2{grid-template-columns:repeat(2,1fr)}
.cols-3{grid-template-columns:repeat(3,1fr)}
.cols-4{grid-template-columns:repeat(4,1fr)}
.card{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:14px}
.card h3{margin:0 0 8px;font-size:11px;font-weight:600;color:var(--muted);
  text-transform:uppercase;letter-spacing:.06em}
.span-all{grid-column:1 / -1}

/* hero gas chart */
.hero canvas{height:360px}
.hero-head{display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;margin-bottom:10px}
.hero-head .big{font-family:'Fira Code',monospace;font-size:30px;font-weight:700;line-height:1}
.hero-head .lbl{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.hero-head .sub{font-size:13px;color:var(--muted)}

/* metric values */
.bigval{font-family:'Fira Code',monospace;font-size:26px;font-weight:700;line-height:1.1}
.bigval.sm{font-size:20px}
.metric-row{display:flex;gap:24px;flex-wrap:wrap;margin-top:8px}
.metric{display:flex;flex-direction:column;gap:2px}
.metric .k{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.metric .v{font-family:'Fira Code',monospace;font-size:16px;font-weight:600}
.kv{display:flex;justify-content:space-between;gap:10px;font-size:13px;padding:3px 0;border-bottom:1px solid var(--border-2)}
.kv:last-child{border-bottom:none}
.kv .key{color:var(--muted)}
.subtle{color:var(--muted);font-size:12px}
.delta-up{color:var(--fg)} .delta-down{color:var(--muted)}

/* badges (mono) */
.badge{display:inline-block;padding:2px 7px;border:1px solid var(--border);border-radius:var(--radius);
  font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.badge.on{color:#000;background:var(--fg);border-color:var(--fg)}

/* ALERT banner — единственный цветной акцент (опасность) */
.alert-banner{display:flex;flex-direction:column;gap:6px;border:1px solid var(--alert);
  background:var(--alert-bg);border-radius:var(--radius);padding:12px 14px;margin-bottom:14px}
.alert-banner .head{display:flex;align-items:center;gap:8px;font-weight:700;color:var(--alert);font-size:14px}
.alert-banner .head svg{width:18px;height:18px}
.alert-row{display:flex;gap:8px;align-items:center;font-size:13px;color:#ffd9d6}
.alert-row .b{font-weight:600;color:#fff}

/* state banner (mono) */
.banner{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--border);
  border-radius:var(--radius);padding:11px 13px;margin-bottom:14px;font-size:13px;background:var(--panel)}
.banner svg{width:18px;height:18px;flex:0 0 auto;margin-top:1px;color:var(--muted)}
.banner .b-title{font-weight:600;margin-bottom:2px}
details.more summary{cursor:pointer;color:var(--muted);font-size:12px;list-style:none;margin-top:4px}
details.more summary::-webkit-details-marker{display:none}
details.more pre{margin:6px 0 0;padding:8px;background:#000;border:1px solid var(--border-2);border-radius:var(--radius);
  font-size:11px;white-space:pre-wrap;word-break:break-word;color:var(--muted)}

/* relay chips */
.relays{display:flex;gap:8px;flex-wrap:wrap}
.relay{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--border);border-radius:var(--radius);
  padding:7px 11px;font-size:13px}
.relay .ind{width:9px;height:9px;border-radius:50%;border:1px solid var(--muted-2);background:transparent}
.relay.on{border-color:var(--fg)}
.relay.on .ind{background:var(--fg);border-color:var(--fg)}
.relay .st{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-left:2px}
.relay.on .st{color:var(--fg)}

/* heatmap (DOM grid) */
.hm-wrap{overflow-x:auto}
.hm{display:grid;gap:2px;min-width:560px}
.hm .lab{font-size:10px;color:var(--muted);display:flex;align-items:center}
.hm .hh{font-size:9px;color:var(--muted-2);text-align:center}
.hm .cell{height:15px;border-radius:1px;background:#111;border:1px solid #161616}
.hm .cell[data-v]{cursor:default}
.hm-legend{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);margin-top:10px;flex-wrap:wrap}
.hm-legend .sw{width:16px;height:16px;border:1px solid #161616;border-radius:1px}
.hm-legend .hm-lg{margin-right:8px}
.hm-axis{display:flex;justify-content:space-between;font-size:10px;color:var(--muted-2);
  padding:0 0 4px 54px;text-transform:uppercase;letter-spacing:.05em}
.hm-note{display:flex;gap:8px;align-items:flex-start;font-size:12px;color:var(--muted);
  border:1px solid var(--border-2);border-radius:var(--radius);padding:8px 10px;margin:0 0 10px}
.hm-note svg{width:15px;height:15px;flex:0 0 auto;margin-top:1px;color:var(--muted)}
.hm-note b{color:var(--fg);font-weight:600}
.hm .cell{height:16px}

/* inputs / buttons */
label.field{display:flex;flex-direction:column;gap:5px;font-size:11px;color:var(--muted);
  text-transform:uppercase;letter-spacing:.04em}
input{width:100%;padding:9px 10px;border-radius:var(--radius);border:1px solid var(--border);
  background:#000;color:var(--fg);font-size:14px;font-family:inherit;outline:none}
input:focus{border-color:var(--fg)}
input.mono{font-family:'Fira Code',monospace}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:9px 15px;border-radius:var(--radius);
  border:1px solid var(--border);background:#000;color:var(--fg);font-size:13px;font-weight:600;font-family:inherit;
  cursor:pointer;min-height:40px;transition:background .15s,color .15s,border-color .15s}
.btn svg{width:15px;height:15px}
.btn:hover{border-color:var(--fg)}
.btn.primary{background:var(--fg);color:#000;border-color:var(--fg)}
.btn.primary:hover{background:#d8d8d8}
.btn.danger{border-color:var(--alert);color:var(--alert)}
.btn.danger:hover{background:var(--alert);color:#000}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* table */
.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius)}
table{width:100%;border-collapse:collapse;font-size:13px;min-width:520px}
thead th{padding:9px 11px;text-align:left;font-size:10px;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;border-bottom:1px solid var(--border);white-space:nowrap;background:var(--panel-2)}
tbody td{padding:8px 11px;border-bottom:1px solid var(--border-2)}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:#0d0d0d}
td.num{font-family:'Fira Code',monospace}
.row-na{color:var(--muted-2)}
.row-err{color:var(--alert);font-size:12px}

/* top strip: период (wide) + счётчик газа */
.top-strip{grid-template-columns:1.7fr 1fr}

/* card head with inline tabs */
.card-head-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px}

/* tabs (per-boiler toggle) */
.tabs{display:inline-flex;gap:4px;border:1px solid var(--border);border-radius:var(--radius);padding:3px;background:#000}
.tab{appearance:none;border:none;background:transparent;color:var(--muted);font-family:inherit;font-size:12px;
  font-weight:600;padding:6px 12px;border-radius:3px;cursor:pointer;min-height:32px;
  transition:background .15s,color .15s;text-transform:uppercase;letter-spacing:.04em}
.tab:hover{color:var(--fg)}
.tab.active{background:var(--fg);color:#000}

/* budget progress bar */
.budget-bar{position:relative;height:12px;border:1px solid var(--border);border-radius:var(--radius);
  background:#000;margin-top:14px}
.budget-fill{height:100%;border-radius:inherit;width:0;
  background:linear-gradient(90deg,#3b0f70,#de4968,#fca50a);transition:width .4s ease}
.budget-fill.over{background:var(--alert)}
.budget-fc{position:absolute;top:-3px;width:2px;height:18px;background:var(--fg);display:none}

/* charts */
canvas{width:100%;height:240px;display:block}
.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:11px;color:var(--muted);margin-top:8px}
.legend i{display:inline-block;width:14px;height:0;border-top:2px solid var(--fg);margin-right:6px;vertical-align:middle}
.legend i.dash{border-top-style:dashed}

/* skeleton */
.skel{background:linear-gradient(90deg,#0d0d0d 25%,#1a1a1a 37%,#0d0d0d 63%);background-size:400% 100%;
  animation:sh 1.4s infinite;border-radius:var(--radius);color:transparent!important}
@keyframes sh{0%{background-position:100% 0}100%{background-position:-100% 0}}

/* modal */
.modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.85);display:none;align-items:center;
  justify-content:center;z-index:50;padding:16px}
.modal-backdrop.open{display:flex}
.modal{width:100%;max-width:440px;background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:18px}
.modal h2{margin:0 0 4px;font-size:17px}
.modal .warn-line{color:var(--muted);font-size:12px;margin-bottom:12px}

/* global error window — OLED-mono, high-contrast red, no shadows */
.err-stack{position:fixed;top:14px;right:14px;z-index:70;display:flex;flex-direction:column;gap:8px;
  width:min(360px,calc(100vw - 28px));pointer-events:none}
.err-item{pointer-events:auto;display:flex;align-items:flex-start;gap:9px;
  background:#000;border:1px solid #ff4444;border-radius:var(--radius);
  padding:10px 11px;color:#ff4444;font-size:12.5px;line-height:1.4;box-shadow:none}
.err-item svg{width:16px;height:16px;flex:0 0 auto;margin-top:1px;color:#ff4444}
.err-item .err-msg{flex:1;font-family:'Fira Code',ui-monospace,monospace;word-break:break-word}
.err-item .err-x{flex:0 0 auto;appearance:none;background:transparent;border:none;color:#ff4444;
  font-size:13px;line-height:1;cursor:pointer;padding:1px 3px;opacity:.7;transition:opacity .15s}
.err-item .err-x:hover{opacity:1}
.err-item.pulse{animation:errpulse .9s ease-out 1}
@keyframes errpulse{0%{border-color:#ff8a84}60%{border-color:#ff8a84}100%{border-color:#ff4444}}
@media(max-width:760px){.err-stack{top:10px;right:10px;left:10px;width:auto}}

/* toast */
.toast-host{position:fixed;left:50%;bottom:20px;transform:translateX(-50%);z-index:60;
  display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast{pointer-events:auto;padding:10px 15px;border-radius:var(--radius);font-size:13px;font-weight:500;
  border:1px solid var(--border);background:var(--panel-2)}
.toast.ok{border-color:var(--fg)} .toast.err{border-color:var(--alert);color:var(--alert)}

/* fade-up */
.fade-up{opacity:0;transform:translateY(8px)}
.fade-up.in{opacity:1;transform:none;transition:opacity .45s ease,transform .45s cubic-bezier(.2,.7,.2,1)}

@media(max-width:980px){.cols-4{grid-template-columns:repeat(2,1fr)}.cols-3{grid-template-columns:1fr}.top-strip{grid-template-columns:1fr}}
@media(max-width:760px){.cols-2{grid-template-columns:1fr}.cols-4{grid-template-columns:1fr}.hero canvas{height:280px}
  .card-head-row{align-items:flex-start}.tabs{width:100%;justify-content:space-between}.tab{flex:1;padding:6px 4px}}
@media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}.fade-up{opacity:1;transform:none}}

/* ===== Экран входа (полная стена) ===== */
#loginOverlay{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;
  background:var(--bg);padding:24px}
#loginForm{display:flex;flex-direction:column;gap:12px;width:100%;max-width:300px;
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:24px}
#loginForm h1{margin:0;font-size:18px;font-weight:600}
#loginForm p{margin:0 0 4px;color:var(--muted);font-size:13px}
#loginForm input{padding:10px 12px;font-size:14px;background:var(--panel-2);color:var(--fg);
  border:1px solid var(--border);border-radius:var(--radius);outline:none}
#loginForm input:focus{border-color:var(--fg)}
#loginForm button{padding:10px 12px;font-size:14px;font-weight:600;cursor:pointer;
  background:var(--fg);color:#000;border:1px solid var(--fg);border-radius:var(--radius)}
#loginForm button:disabled{opacity:.5;cursor:default}
#loginErr{min-height:16px;color:var(--alert);font-size:12px}
