/* Каркас дашборда: шапка, список слева, деталь справа. Собран по правилам
   docs/design-system.md и эталонным артбордам design/*.dc.html.

   Ни одного hex: все цвета, размеры и шрифты приходят переменными из
   tokens.css. Статус красит блок через локальную переменную --c, которую
   ставит класс .s-* — так один и тот же компонент годится и для сервиса,
   и для хоста, и для контейнера. */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); }

.mono { font-family: var(--font-mono); }

/* --- Статусные роли ------------------------------------------------------
   --c      цвет статуса (точка, цифра, слово)
   --c-line обводка блока: подсвечиваем только больное, здоровое не орёт
   --c-tint подложка блока — единственная заливка с прозрачностью в стиле */
.s-ok      { --c: var(--ok);      --c-line: var(--line);      --c-tint: transparent; }
.s-warn,
.s-slow    { --c: var(--warn);    --c-line: var(--warn-line); --c-tint: var(--warn-tint); }
.s-down    { --c: var(--down);    --c-line: var(--down-line); --c-tint: var(--down-tint); }
.s-stale   { --c: var(--stale);   --c-line: var(--line);      --c-tint: transparent; }
.s-unknown { --c: var(--unknown); --c-line: var(--line);      --c-tint: transparent; }

.dot {
  width: var(--dot); height: var(--dot);
  border-radius: 50%; background: var(--c); flex-shrink: 0;
}
.dot-sm { width: 6px; height: 6px; border-radius: 50%; background: var(--c); flex-shrink: 0; }
.in-color { color: var(--c); }

/* --- Шапка --------------------------------------------------------------- */
.top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 18px 26px; border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: baseline; gap: 14px; }
.brand-name { font-size: var(--t-brand); font-weight: 700; letter-spacing: var(--ls-title); }
.brand-sep { color: var(--faintest); }
.counters {
  font-family: var(--font-mono); font-size: var(--t-mono);
  color: var(--faint); letter-spacing: 0.06em;
}
.top-right { display: flex; align-items: center; gap: 18px; }

.seg { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--line); border-radius: var(--r); }
.seg a {
  padding: 5px 14px; border-radius: var(--r-chip);
  font-size: var(--t-meta); font-weight: 500; color: var(--faint);
}
.seg a.on { background: var(--panel-tint); color: var(--ink); }
.seg a:hover { color: var(--ink); }

.live {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-mono); font-size: 12px; color: var(--dim);
}
.live-dot {
  width: var(--dot); height: var(--dot); border-radius: 50%;
  background: var(--ok); box-shadow: 0 0 0 3px var(--ok-glow);
  animation: pulse 2.6s ease-in-out infinite;
}
/* Единственная анимация в стиле: живой индикатор. Всё остальное статично. */
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

/* --- Раскладка «список и деталь» ----------------------------------------- */
.split {
  display: grid; grid-template-columns: var(--sidebar) minmax(0, 1fr);
  flex-grow: 1; align-items: stretch;
}
.list { border-right: 1px solid var(--line); display: flex; flex-direction: column; }
.detail { padding: var(--pad-page); display: flex; flex-direction: column; gap: var(--gap-sec); min-width: 0; }

.filter { padding: 12px 16px; border-bottom: 1px solid var(--line-row); }
.filter input {
  width: 100%; padding: 7px 11px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); color: var(--ink);
  font-family: var(--font-ui); font-size: var(--t-meta);
}
.filter input::placeholder { color: var(--faintest); }
.filter input:focus { outline: none; border-color: var(--line-chip); }

.group {
  padding: 11px 16px 7px; font-size: var(--t-label);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--faintest);
}

.row {
  position: relative; display: flex; align-items: center; gap: 10px;
  padding: 9px 16px; color: var(--ink-2);
}
.row:hover { background: var(--line-row); color: var(--ink-2); }
.row.on { background: var(--panel-tint); }
.row.on::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: var(--c);
}
.row-main { flex-grow: 1; min-width: 0; }
/* Имя и подпись — две строки: <span> внутри ссылки иначе слипаются в одну. */
.row-main, .row-name, .row-sub { display: block; }
.row-name, .row-sub, .row-tag { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-name { font-size: var(--t-body); }
.row.on .row-name { font-weight: 600; color: var(--ink); }
.row-sub { font-family: var(--font-mono); font-size: var(--t-label); color: var(--faintest); }
.row-tag { font-family: var(--font-mono); font-size: 11px; color: var(--c); flex-shrink: 0; }

/* --- Шапка детали -------------------------------------------------------- */
.crumbs {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-mono); font-size: var(--t-mono); color: var(--faint);
  margin-bottom: -8px;
}
.crumbs .sep { color: var(--line-hair); }
.crumbs .here { color: var(--dim); }

.head { display: flex; align-items: flex-start; justify-content: space-between; gap: 28px; }
.head-left { display: flex; gap: 14px; min-width: 0; }
.head-bar { width: var(--accent-w); align-self: stretch; background: var(--c); border-radius: 2px; flex-shrink: 0; }
.head-line { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.head-title { font-size: var(--t-title); font-weight: 700; letter-spacing: var(--ls-title); }
.head-meta {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px;
  font-family: var(--font-mono); font-size: var(--t-mono); color: var(--faint);
}
.head-meta .sep { color: var(--line-hair); }
.head-meta b { font-weight: 400; color: var(--ink-2); }

.chip {
  font-size: 12px; font-weight: 600; color: var(--c);
  border: 1px solid var(--c-line); border-radius: var(--r-chip); padding: 3px 8px;
}
.chip-flat {
  font-size: var(--t-label); font-weight: 600; letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--line-chip); border-radius: var(--r-chip); padding: 3px 7px;
}
.actions { display: flex; gap: 8px; flex-shrink: 0; }
.btn {
  border: 1px solid var(--line-chip); border-radius: var(--r);
  padding: 7px 13px; font-size: var(--t-meta); color: var(--ink-2);
}
a.btn:hover { color: var(--ink); border-color: var(--dim); }

/* --- Плитки показателей --------------------------------------------------- */
.stats { display: flex; gap: var(--gap-stat); }
.stat {
  flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); padding: var(--pad-card);
}
.stat-label {
  font-size: var(--t-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--faintest);
}
.stat-val {
  font-family: var(--font-mono); font-size: var(--t-stat); font-weight: 600;
  color: var(--c, var(--ink)); margin-top: 5px;
}
.stat-note { font-size: var(--t-label); color: var(--faintest); margin-top: 3px; }

/* --- Секции и карточки ---------------------------------------------------- */
.sec {
  font-size: var(--t-label); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--faint); margin-bottom: -8px;
}
.card {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); overflow: hidden;
}
.card.toned { border-color: var(--c-line); }
.cards-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--gap-card); align-items: start; }
.cards-2.wide-left { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 20px; }
.col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.card-head {
  display: flex; align-items: center; gap: 11px; padding: 13px 16px;
  border-bottom: 1px solid var(--line-inner); background: var(--c-tint);
}
.card-head .dot { width: 8px; height: 8px; }
.card-title { font-size: var(--t-h); font-weight: 600; }
.card-sub { font-family: var(--font-mono); font-size: var(--t-label); color: var(--faint); margin-top: 2px; }
.card-state { font-size: var(--t-meta); font-weight: 600; color: var(--c); }
.card-label {
  padding: 10px 16px; border-bottom: 1px solid var(--line-inner);
  font-size: var(--t-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--faintest);
}

/* Таблица проверок: колонки фиксированные, иначе имена разной длины
   разъезжают состояние и время ответа по строкам. */
.check {
  display: grid; grid-template-columns: minmax(0, 1fr) 82px minmax(0, 132px) 66px;
  gap: 10px; align-items: center; padding: var(--pad-row);
  border-bottom: 1px solid var(--line-row);
}
.check:last-child { border-bottom: none; }
.check-name { display: flex; align-items: center; gap: 9px; min-width: 0; }
.check-name span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.check-type { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.check-state { font-size: 12px; font-weight: 500; color: var(--c); }
.check-ms { font-family: var(--font-mono); font-size: var(--t-mono); color: var(--dim); text-align: right; }

/* Строка в карточке: контейнер, сервис на хосте, сосед по стеку */
.lrow {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  border-bottom: 1px solid var(--line-row);
}
.lrow:last-child { border-bottom: none; }
.lrow-name { flex-grow: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lrow-fixed { width: 210px; min-width: 0; }
.lrow-fixed, .lrow-title, .lrow-sub { display: block; }
.lrow-title { font-size: var(--t-body); font-weight: 500; }
.lrow-sub { font-family: var(--font-mono); font-size: var(--t-label); color: var(--faintest);
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lrow-why { flex-grow: 1; min-width: 0; font-size: var(--t-meta); color: var(--muted);
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Соседи по стеку: образ и состояние держат свою ширину, иначе строки
   разъезжаются от длины имени образа. */
.lrow-img { width: 220px; flex-shrink: 0; font-family: var(--font-mono);
            font-size: var(--t-mono); color: var(--faint);
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lrow-fixed.narrow { width: 168px; }
.lrow-health { width: 92px; flex-shrink: 0; font-size: 12px; }
.lrow-why.bad { color: var(--c); }
.lrow-state { font-size: var(--t-meta); color: var(--faint); }
.lrow-state.bad { color: var(--c); }
.lrow-link { font-size: var(--t-mono); flex-shrink: 0; }
.lrow-note { padding: 11px 16px; font-size: var(--t-mono); color: var(--faintest); }

/* --- Паспорт -------------------------------------------------------------- */
.kv { padding: 6px 16px 10px; }
.kv-row { display: flex; align-items: baseline; gap: 14px; padding: 9px 0; border-bottom: 1px solid var(--line-row); }
.kv-row:last-child { border-bottom: none; }
.kv-k { width: 118px; flex-shrink: 0; font-size: var(--t-mono); color: var(--faint); }
.kv-v { flex-grow: 1; min-width: 0; font-size: var(--t-meta); color: var(--ink-2); word-break: break-word; }
.kv-v.mono { font-family: var(--font-mono); }
.kv-v.warn { color: var(--warn); }
.kv-v.empty { color: var(--faintest); }

/* --- Метры ---------------------------------------------------------------- */
.meters { padding: 16px; display: flex; flex-direction: column; gap: 14px; }
.meter-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.meter-name { font-size: var(--t-meta); color: var(--ink-2); }
.meter-right { display: flex; align-items: baseline; gap: 8px; }
/* Само число всегда спокойное: цветом кричит только заливка, перешедшая
   порог. Иначе на здоровом хосте пять зелёных цифр спорят со статусом. */
.meter-val { font-family: var(--font-mono); font-size: 14px; font-weight: 600; color: var(--ink-2); }
.s-warn .meter-val { color: var(--warn); }
.meter-thr { font-family: var(--font-mono); font-size: 10px; color: var(--faintest); }
.meter-track { height: var(--meter-h); border-radius: var(--r-meter); background: var(--line-inner); overflow: hidden; margin-top: 6px; }
.meter-fill { height: var(--meter-h); border-radius: var(--r-meter); background: var(--c, var(--ok)); }

/* --- График --------------------------------------------------------------- */
.chart { padding: 16px; }
.bars { display: flex; align-items: flex-end; gap: 3px; height: 76px; }
.bars.low { height: 46px; }
.bar { flex: 1; border-radius: 2px 2px 0 0; background: var(--chart-idle); }
.bar.ok { background: var(--chart-ok); }
.bar.warn { background: var(--chart-warn); }
.bar.down { background: var(--chart-down); }
.axis {
  display: flex; justify-content: space-between; margin-top: 9px;
  font-family: var(--font-mono); font-size: var(--t-label); color: var(--faintest);
}
/* Полоса состояния — для сервисов, у которых время ответа не измеряется:
   рисовать столбики одинаковой высоты честнее, чем выдумывать миллисекунды. */
.ribbon { display: flex; gap: 3px; height: 14px; }
.ribbon div { flex: 1; border-radius: 1px; background: var(--chart-idle); }

/* --- Вывод healthcheck ----------------------------------------------------- */
.log-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: var(--pad-row); border-bottom: 1px solid var(--line-inner); background: var(--c-tint);
  font-family: var(--font-mono); font-size: 12px; color: var(--c);
}
.log-head .streak { color: var(--faint); font-size: 11px; }
.log {
  padding: 13px 16px; font-family: var(--font-mono); font-size: var(--t-mono);
  line-height: 1.75; color: var(--dim);
}
.log .key { color: var(--ink-2); }
.hint { padding: var(--pad-row); border-top: 1px solid var(--line-inner); font-size: 12px; color: var(--warn); }

.empty { color: var(--faintest); font-size: var(--t-meta); padding: var(--pad-row); }
.empty-inline { color: var(--faintest); }
