/* ===== Табло МЦ (JMB) — ЖИВЫЕ надстройки над статичным дизайном MC =====
   theme.css + board.css скопированы из MC 1:1 (пиксель-парити). Здесь ТОЛЬКО то, чего нет у статичного
   MC: экран логина, цветные статус-точки объектов (online/alarm/offline/unlinked) и индикатор связи табло.
   Дизайн-токены (--panel/--ink/--accent/...) берём из theme.css — не переопределяем. */

/* ---------- Экран логина ---------- */
.login-screen{
  position:fixed; inset:0; z-index:50; display:grid; place-items:center;
  background:
    radial-gradient(1000px 620px at 82% -10%, var(--accent-soft), transparent 58%),
    linear-gradient(180deg, var(--bg-grad-1), var(--bg-grad-2));
}
/* 🔴 КРИТИЧНО: без этого правила `display:grid` выше ПЕРЕБИВАЕТ дефолтный UA-стиль браузера [hidden]{display:
   none} — авторские CSS-правила ВСЕГДА выигрывают у UA-стилей в каскаде, независимо от специфичности. wallboard.js
   ставит el.hidden=true после успешного логина (hideLogin()), атрибут выставляется корректно, но экран логина
   визуально остаётся на весь экран (position:fixed;inset:0;z-index:50) НАВСЕГДА, маскируя уже отрендеренную под
   собой доску — «жмёт Войти → тихо ничего не происходит», хотя логин/рендер отрабатывают штатно. Подтверждено
   вживую (headless Edge, CDP): getComputedStyle().display оставался "grid" при hidden-атрибуте true. */
.login-screen[hidden]{ display:none !important; }
.login-card{
  width:min(92vw, 360px); background:var(--panel); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow-hover); padding:26px 24px 22px;
}
.login-card .lc-brand{ display:flex; align-items:center; gap:12px; margin-bottom:18px; }
.login-card .lc-logo-img{ width:44px; height:44px; border-radius:12px; flex:0 0 auto; box-shadow:var(--shadow); object-fit:cover; }
.login-card h1{ font-size:17px; margin:0; line-height:1.2; letter-spacing:-.01em; }
.login-card .lc-sub{ font-size:12.5px; color:var(--ink-2); margin-top:2px; }
.login-card label{ display:block; font-size:12.5px; color:var(--ink-2); margin:12px 0 5px; }
.login-card input{
  width:100%; font:inherit; font-size:14px; color:var(--ink); background:var(--panel-2);
  border:1px solid var(--border); border-radius:10px; padding:10px 12px; outline:none;
}
.login-card input:focus{ border-color:var(--accent); }
.login-card button{
  width:100%; margin-top:18px; font:inherit; font-size:14px; font-weight:650; cursor:pointer;
  color:#fff; background:var(--accent); border:0; border-radius:10px; padding:11px 12px;
}
.login-card button:disabled{ opacity:.6; cursor:default; }
.login-card .lc-err{ margin-top:12px; font-size:12.5px; color:#dc2626; min-height:16px; }
:root[data-theme="dark"] .login-card .lc-err{ color:#f87171; }

/* ---------- Бренд JARWITS в сайдбаре (замена плейсхолдера «МЦ» на настоящий логотип) ----------
   board.css рисовал `.side .brand .logo` градиентным квадратом с текстом-инициалами — тут переиспользуем
   РЕАЛЬНЫЙ логотип JARWITS (тот же PNG, что в шапке JMC/JAD: frontend/monitoring/public/icons/
   jarwits_server.png, скопирован байт-в-байт в public/wallboard/icons/) вместо плейсхолдера. Разметка
   сменилась на <img class="logo-img">, поэтому board.css-правило `.logo` больше не матчится (мёртвое,
   но board.css не трогаем — вербатим-порт). h1 теперь пара «JARWITS» (бренд) + «Мониторинговый центр»
   (модуль/продукт) — тот же паттерн, что в шапке JMC/JAD (<strong>JARWITS</strong><span>Monitoring</span>). */
.side .brand .logo-img{
  width:4.6cqh; height:4.6cqh; border-radius:1.1cqh; flex:0 0 auto; box-shadow:var(--shadow); object-fit:cover;
}
.side .brand h1{ display:flex; align-items:baseline; gap:.4cqw; flex-wrap:wrap; }
.side .brand .brand-name{ font-weight:800; }
.side .brand .brand-sub{ font-weight:600; color:var(--ink-2); font-size:.92em; }

/* ---------- Статус-точка объекта (ЖИВОЕ, чего нет у MC) ----------
   Ненавязчиво в начале строки .obj: маленький кружок online/alarm/offline/unlinked. */
.obj{ position:relative; }
.obj .ost{
  width:.85cqh; height:.85cqh; border-radius:50%; flex:0 0 auto; align-self:center;
  box-shadow:0 0 0 .15cqh rgba(255,255,255,.06);
}
.ost.st-online{ background:#22c55e; }
.ost.st-offline{ background:var(--muted); }
.ost.st-unlinked{ background:#f59e0b; }
.ost.st-alarm{ background:#ef4444; animation:ost-pulse 1.4s ease-in-out infinite; }
@keyframes ost-pulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(239,68,68,.55); } 50%{ box-shadow:0 0 0 .6cqh rgba(239,68,68,0); } }
/* Аларм-строка чуть подсвечена, чтобы ловилась взглядом на настенном табло */
.obj.obj-alarm{ background:color-mix(in srgb, #ef4444 12%, var(--panel-2)); }

/* ---------- Индикатор связи + версия сборки (в подвале сайдбара) ----------
   side-foot по умолчанию (board.css) — простой блок в одну строку (только .conn). Кладём версию туда же
   вторым элементом, flex разводит по краям — ненавязчиво, не конкурирует за внимание с алармами/статусами. */
.side-foot{ display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
.conn{ display:inline-flex; align-items:center; gap:.6cqw; }
.conn .cdot{ width:1cqh; height:1cqh; border-radius:50%; flex:0 0 auto; background:var(--muted); }
.conn.live .cdot{ background:#22c55e; }
.conn.stale .cdot{ background:#f59e0b; }
.conn.down .cdot{ background:#ef4444; }
.wb-version{ color:var(--muted); font-size:.95cqh; white-space:nowrap; }

/* Фото-контейнеры: пока грузится blob — показываем инициалы (в noimg), после fetch добавим <img>. */
.pm-ph img, .hc-ph img, .cc-ph img{ opacity:0; transition:opacity .3s ease; }
.pm-ph img.loaded, .hc-ph img.loaded, .cc-ph img.loaded{ opacity:1; }

/* ---------- Пустой ростер (ничего не заведено в JMC → «Табло МЦ») ----------
   Без этого блока пустые данные дают ПУСТУЮ main-зону — визуально неотличимо от «ничего не произошло
   после логина». Явно говорим: вход выполнен, просто нет данных. */
.main-empty{ display:flex; align-items:center; justify-content:center; }
.empty-state{
  text-align:center; max-width:70cqw; padding:3cqh 3cqw;
  background:var(--panel-2); border:.15cqh dashed var(--border-strong); border-radius:1.2cqh;
}
.empty-state .es-ico{ font-size:5cqh; line-height:1; margin-bottom:1cqh; opacity:.7; }
.empty-state .es-title{ font-size:2.1cqh; font-weight:750; color:var(--ink); margin-bottom:.8cqh; }
.empty-state .es-sub{ font-size:1.4cqh; color:var(--ink-2); line-height:1.4; }

/* ---------- Адаптивность под 5 форматов ----------
   (1) телефон-портрет (390×844) (2) планшет-портрет (800×1280) (3) планшет-ландшафт (1280×800)
   (4) десктоп (5) настенный 16:9 (оригинал MC, НЕ ломаем). board.css/theme.css НЕ трогаем — вся
   адаптация здесь. Планшет-ландшафт/десктоп/стена ШИРЕ 1024px → board.css отрабатывает как есть
   (letterbox 16:9, боковой сайдбар) — уже устойчиво проверено, доп. правил не требуют.

   Брейкпоинт ≤1024px (телефон-портрет 390 И планшет-портрет 800 — ОБА уже, планшет-ландшафт 1280 —
   уже НЕТ) переключает .board на вертикальный стек: сайдбар СВЕРХУ компактной ГОРИЗОНТАЛЬНОЙ шапкой,
   зоны-города СНИЗУ со скроллом.

   🔴 БАГ, который поймал владелец на планшете-портрете: .stage держит container-type:size (из board.css)
   с явным width/height=100vw/100vh (НЕ auto — иначе cqw/cqh обнулятся у ВСЕХ потомков), поэтому cqh
   внутри .side (часы/head-card/chief-card/KPI/легенда) продолжали считаться от ПОЛНОЙ высоты экрана
   (100vh), а не от реального размера сжатой шапки — на планшете-портрете 100vh=1280px давало
   font-size:4.6cqh≈59px для часов, вылезающих за компактный бокс и налезающих на chief-card. ФИКС:
   внутри компактной шапки контент .side переведён с cqh/cqw на фикс/clamp/rem — размер больше НЕ
   зависит от высоты всего экрана, только от реальной ширины бара. */
@media (max-width: 1024px){
  .stage{ width:100vw; height:100vh; box-shadow:none; }
  .board{ display:flex; flex-direction:column; width:100%; height:100%; }
  .main{ flex:1 1 auto; min-height:0; height:auto; overflow-y:auto; display:block; }
  .main-empty{ min-height:100%; }
  .zone{ margin-bottom:16px; }
  .zone-grid{ grid-template-columns:repeat(auto-fit, minmax(240px,1fr)) !important; grid-template-rows:none !important; gap:10px; }
  .pcard{ padding:10px 12px; }

  /* ── Компактная шапка: горизонтальный wrap-бар вместо вертикального full-height сайдбара. ── */
  .side{
    /* height:auto ПЕРЕБИВАЕТ board.css `.side{height:100%}` — иначе flex-basis:auto (при flex:0 0 auto)
       наследует те 100% высоты .board, компактная шапка растягивается на весь экран, а align-content
       (по умолчанию stretch у многострочного flex) раздвигает wrap-строки пустыми промежутками. */
    flex:0 0 auto; width:100%; height:auto; max-height:none; overflow:visible;
    display:flex; flex-direction:row; flex-wrap:wrap; align-items:center; align-content:flex-start;
    gap:6px 16px; padding:10px 14px; border-right:0; border-bottom:1px solid var(--border);
  }
  .side .brand{ flex:0 0 auto; gap:8px; }
  .side .brand .logo-img{ width:32px; height:32px; border-radius:8px; }
  .side .brand h1{ font-size:13px; }
  .side .brand .date{ font-size:10.5px; margin-top:1px; }

  .clockbox{ flex:0 0 auto; padding:5px 10px; border-radius:9px; text-align:left; }
  .clockbox .clock{ font-size:clamp(18px,3.2vw,26px); }
  .clock .ss{ font-size:11px; padding:1px 5px; border-radius:5px; margin-left:3px; margin-top:0; }
  .clockbox .datefull{ display:none; }   /* дублирует .side .brand .date — избыточно в узком баре */
  .clockbox .mode{ margin-top:2px; justify-content:flex-start; }
  .clockbox .mode .badge{ font-size:10px; padding:2px 6px; gap:4px; }
  .clockbox .mode .badge .dot{ width:6px; height:6px; }
  .dayprog{ display:none; }   /* шкала суток — избыточна в компактной шапке */

  /* 🔴 grid, НЕ flex-row: разметка JS кладёт hc-ph/hc-name/hc-title ТРЕМЯ РАВНОПРАВНЫМИ соседями (в отличие
     от chief-card, где текст уже обёрнут в .cc-tx) — в flex-row они разъезжаются вширь одним рядом и
     вылезают за viewport на узких экранах (было: head-card.right=402px при vw=390px). Grid 2 колонки ×
     2 строки: фото слева на всю высоту (row 1/3), имя/должность справа друг под другом — компактно и
     не зависит от длины текста. */
  .head-card{
    flex:0 0 auto; max-width:100%; min-width:0;
    display:grid; grid-template-columns:32px minmax(0,1fr); grid-template-rows:auto auto;
    align-items:center; column-gap:8px; row-gap:0;
    padding:5px 10px; border-radius:9px;
  }
  .head-card::before{ display:none; }
  .head-card .hc-ph{ grid-row:1/3; grid-column:1; width:32px; height:32px; aspect-ratio:1; border-radius:8px; margin-top:0; }
  .head-card .hc-ph .ini{ font-size:13px; }
  .head-card .hc-tag{ display:none; }   /* оверлей-бейдж внутри hc-ph — на 32px-фото не влезает читаемо */
  .head-card .hc-name{ grid-row:1; grid-column:2; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; margin-top:0; line-height:1.2; }
  .head-card .hc-title{ grid-row:2; grid-column:2; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:9.5px; color:var(--ink-2); line-height:1.15; }

  .chief-card{ flex:0 0 auto; gap:8px; padding:5px 10px; border-radius:9px; }
  .chief-card::before{ width:3px; }
  .chief-card .cc-ph{ width:32px; height:32px; border-radius:8px; }
  .chief-card .cc-ph .ini{ font-size:12px; }
  .chief-card .cc-title{ font-size:9px; }
  .chief-card .cc-name{ font-size:12px; }

  .kpi-col{ flex:0 0 auto; }
  .kpi-col .sk-title{ display:none; }
  .kpi-grid{ display:grid; grid-template-columns:repeat(4,auto); gap:4px 10px; }
  .skpi{ flex-direction:row; gap:5px; padding:4px 8px; border-radius:7px; }
  .skpi .v{ font-size:13px; }
  .skpi .l{ font-size:9.5px; }

  .side-legend{ flex-direction:row; flex-wrap:wrap; gap:4px 10px; font-size:10px; flex:0 0 auto; }
  .side-legend .sk-title{ display:none; }
  .side-legend .dot, .side-legend .sq{ width:7px; height:7px; }

  .conn .cdot{ width:7px; height:7px; }
  .side-foot{ margin-top:0; flex:1 1 100%; order:99; font-size:10px; padding-top:4px; border-top:1px solid var(--border); }
  .wb-version{ font-size:9px; }
}

/* Телефон-портрет — ещё уже: плотнее переносим KPI, убираем избыточный заголовок бренда. */
@media (max-width: 480px){
  .kpi-grid{ grid-template-columns:repeat(2,auto); }
  .side .brand h1{ display:none; }
}
