/* Дополнения к Tabler. Общий вид веба устройства и облачной панели. */

/* ------------------------------------------------------------------
   Цвета данных. Цвет закреплён за сущностью (солнце, дом, батарея,
   сеть) — одинаковый на плитках обзора и на всех графиках.
   Тёмная тема — отдельные шаги тех же оттенков, а не автоматическая
   инверсия. Пары, которые встречаются на одном графике (солнце+дом,
   батарея+сеть), проверены валидатором палитры (различимость при
   дальтонизме) на фонах карточек обеих тем.
   ------------------------------------------------------------------ */
:root {
  --viz-solar: #eda100;
  --viz-home: #4a3aa7;
  --viz-battery: #1baf7a;
  --viz-grid: #2a78d6;
  --viz-text: #1f2937;
  --viz-muted: #6b7280;
  --viz-gridline: #eef0f3;
  --viz-baseline: #cfd4db;
}
[data-bs-theme="dark"] {
  --viz-solar: #c98500;
  --viz-home: #9085e9;
  --viz-battery: #199e70;
  --viz-grid: #3987e5;
  --viz-text: #e5e7eb;
  --viz-muted: #9ca3af;
  --viz-gridline: #2c3646;
  --viz-baseline: #4b5563;
}

/* Шрифт интерфейса — Inter (подключён в _fonts.html); графики берут его у body */
:root,
[data-bs-theme] {
  --tblr-font-sans-serif: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --tblr-body-font-family: var(--tblr-font-sans-serif);
}
body {
  font-family: var(--tblr-font-sans-serif);
  font-feature-settings: "cv05", "ss03"; /* l с хвостиком (не путать с 1/I), округлые кавычки */
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, .page-title, .card-title {
  letter-spacing: -0.011em;
}

.viz-solar { --viz-c: var(--viz-solar); }
.viz-home { --viz-c: var(--viz-home); }
.viz-battery { --viz-c: var(--viz-battery); }
.viz-grid { --viz-c: var(--viz-grid); }

/* Иконка сущности на плитках обзора */
.viz-avatar {
  color: var(--viz-c);
  background: color-mix(in srgb, var(--viz-c) 14%, transparent);
}
/* Цветная метка рядом с подписью (текст сам остаётся цвета текста) */
.viz-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--viz-c);
  flex: none;
}

/* Крупные числа — пропорциональные цифры; моноширинные только в колонках */
.stat-value {
  font-size: 1.625rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--viz-text);
  white-space: nowrap;
}
.energy-tile .h1 {
  white-space: nowrap;
}
.table td {
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ графики */
.viz-chart {
  width: 100%;
  height: 300px; /* вместе с осями — без вложенной прокрутки */
}
.viz-chart[data-chart="soc"],
.viz-chart[data-chart="energy"] {
  height: 260px;
}
@media (max-width: 575.98px) {
  .viz-chart { height: 240px; }
}
/* Обновление данных: прежняя картинка приглушается, без мигания и скачков */
#history .viz-chart,
#history .stat-value {
  transition: opacity 0.2s ease;
}
#history.viz-loading .viz-chart,
#history.viz-loading .stat-value {
  opacity: 0.55;
}

/* Текущие значения в шапке карточки графика */
.viz-now {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  justify-content: flex-end;
}
#history .card-header {
  flex-wrap: wrap;
  row-gap: 8px;
}
@media (max-width: 575.98px) {
  .viz-now {
    width: 100%;
    margin-left: 0;
    justify-content: flex-start;
  }
}
.viz-now-item {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.viz-now-item strong {
  font-weight: 600;
  color: var(--viz-text);
}

/* Подсказка: значение крупно, название вторично, ключ — короткая линия цвета серии */
.viz-tip-head {
  font-size: 12px;
  color: var(--viz-muted);
  margin-bottom: 6px;
}
.viz-tip-row {
  display: flex;
  align-items: center;
  gap: 8px;
  line-height: 1.6;
}
.viz-tip-key {
  width: 14px;
  height: 3px;
  border-radius: 2px;
  flex: none;
}
.viz-tip-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.viz-tip-label {
  color: var(--viz-muted);
}

/* ------------------------------------------------------------------
   Главная: схема энергопотоков
   ------------------------------------------------------------------ */
.flow-card {
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 45% at 50% 0%, color-mix(in srgb, var(--viz-solar) 9%, transparent), transparent 70%),
    radial-gradient(ellipse 45% 40% at 0% 60%, color-mix(in srgb, var(--viz-grid) 6%, transparent), transparent 70%),
    radial-gradient(ellipse 45% 40% at 100% 60%, color-mix(in srgb, var(--viz-home) 6%, transparent), transparent 70%),
    var(--tblr-bg-surface);
}
[data-bs-theme="dark"] .flow-card {
  background:
    radial-gradient(ellipse 60% 45% at 50% 0%, color-mix(in srgb, var(--viz-solar) 16%, transparent), transparent 70%),
    radial-gradient(ellipse 45% 40% at 0% 60%, color-mix(in srgb, var(--viz-grid) 14%, transparent), transparent 70%),
    radial-gradient(ellipse 45% 40% at 100% 60%, color-mix(in srgb, var(--viz-home) 14%, transparent), transparent 70%),
    radial-gradient(ellipse 50% 40% at 50% 100%, color-mix(in srgb, var(--viz-battery) 12%, transparent), transparent 70%),
    linear-gradient(180deg, #1c2433, #161d2b);
}

.flow {
  --ring: 116px;
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas:
    "solar-stats solar   ."
    "grid        hub     home"
    "grid-stats  battery home-stats"
    ".           battery-stats .";
  align-items: center;
  justify-items: center;
  row-gap: 46px; /* место под подписи узлов */
  column-gap: 12px;
  max-width: 720px;
  margin: 8px auto 4px;
  transition: opacity 0.4s ease, filter 0.4s ease;
}
.flow-dim {
  opacity: 0.55;
  filter: grayscale(0.5);
}

/* Линии потоков — под узлами */
.flow-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 0;
}
.flow-edge {
  fill: none;
  stroke: var(--viz-muted);
  stroke-opacity: 0.45;
  stroke-width: 2;
  stroke-dasharray: 1 7; /* нет потока — пунктир из точек */
  stroke-linecap: round;
  transition: stroke 0.5s ease, stroke-opacity 0.5s ease;
}
.flow-edge.is-active {
  stroke: var(--viz-c);
  stroke-opacity: 0.9;
  stroke-width: 2.5;
  stroke-dasharray: none;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--viz-c) 60%, transparent));
}
.flow-dot {
  fill: var(--viz-c);
  filter: drop-shadow(0 0 5px var(--viz-c));
}

/* Узлы */
.flow-node {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  animation: flow-node-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.flow-node[data-node="grid"] { animation-delay: 0.08s; }
.flow-node[data-node="home"] { animation-delay: 0.16s; }
.flow-node[data-node="battery"] { animation-delay: 0.24s; }

.flow-ring {
  position: relative;
  width: var(--ring);
  height: var(--ring);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--viz-c) 12%, var(--tblr-bg-surface)), var(--tblr-bg-surface) 70%);
  box-shadow: 0 8px 28px -12px color-mix(in srgb, var(--viz-c) 55%, transparent);
  transition: box-shadow 0.6s ease;
}
[data-bs-theme="dark"] .flow-ring {
  background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--viz-c) 18%, #1a2231), #151c29 72%);
}
.flow-node.is-active .flow-ring {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--viz-c) 25%, transparent),
              0 10px 36px -8px color-mix(in srgb, var(--viz-c) 70%, transparent);
}
/* Мягкая пульсация активного источника */
.flow-node.is-active .flow-ring::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid var(--viz-c);
  opacity: 0;
  animation: flow-pulse 2.8s ease-out infinite;
}
.flow-ring-svg {
  position: absolute;
  inset: 0;
  transform: rotate(-90deg); /* дуга заряда начинается сверху */
}
.flow-ring-track {
  fill: none;
  stroke: color-mix(in srgb, var(--viz-c) 22%, transparent);
  stroke-width: 5;
}
.flow-ring-arc {
  fill: none;
  stroke: var(--viz-c);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.flow-ring-body {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.15;
}
.flow-icon {
  color: var(--viz-c);
  margin-bottom: 4px;
}
.flow-icon .icon {
  width: 28px;
  height: 28px;
  stroke-width: 1.75;
}
.flow-value {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--viz-text);
  white-space: nowrap;
}
.flow-sub {
  font-size: 0.7rem;
  color: var(--viz-muted);
  white-space: nowrap;
  margin-top: 2px;
}
/* Подпись под кольцом вынесена из потока вёрстки: центр узла = центр кольца,
   поэтому линии к инвертору идут ровно по горизонтали и вертикали. */
.flow-label {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-weight: 600;
  color: var(--viz-text);
}
.flow-card .status {
  white-space: nowrap;
}
@media (min-width: 992px) {
  .flow { --ring: 128px; }
}

/* Инвертор в центре */
.flow-hub {
  position: relative;
  z-index: 1;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 14px;
  color: var(--viz-muted);
  background: var(--tblr-bg-surface);
  border: 1px solid var(--tblr-border-color);
  box-shadow: 0 6px 20px -10px rgba(0, 0, 0, 0.35);
  animation: flow-node-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
[data-bs-theme="dark"] .flow-hub {
  background: #151c29;
}

/* Энергия за сегодня рядом с узлами */
.flow-stats {
  font-size: 0.8rem;
  color: var(--viz-muted);
  line-height: 1.7;
  white-space: nowrap;
  z-index: 1;
  animation: flow-fade-in 0.8s 0.3s ease both;
}
.flow-stats strong {
  color: var(--viz-text);
  font-size: 0.95rem;
  font-weight: 700;
}
.flow-stats-solar {
  justify-self: end;
  text-align: right;
}
/* Сеть и дом: подписи сразу под названием узла, а не на уровне батареи */
.flow-stats-grid,
.flow-stats-home {
  align-self: start;
}
/* Куплено из сети — красный, продано — зелёный (+ стрелка, не только цвет) */
:root {
  --flow-buy: #d63939;
  --flow-sell: #1f9d3a;
}
[data-bs-theme="dark"] {
  --flow-buy: #f06b6b;
  --flow-sell: #4cc764;
}
.flow-stat-buy { --stat-c: var(--flow-buy); }
.flow-stat-sell { --stat-c: var(--flow-sell); }
.flow-stat-buy strong,
.flow-stat-sell strong {
  color: var(--stat-c);
}
.flow-stat-arrow {
  display: inline-flex;
  vertical-align: -0.15em;
  margin-right: 3px;
  color: var(--stat-c);
}
.flow-stat-arrow .icon {
  width: 0.95em;
  height: 0.95em;
  stroke-width: 2.6;
}

@keyframes flow-node-in {
  from { opacity: 0; transform: scale(0.85) translateY(6px); }
  to { opacity: 1; transform: none; }
}
@keyframes flow-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes flow-pulse {
  0% { transform: scale(0.96); opacity: 0.55; }
  70% { transform: scale(1.14); opacity: 0; }
  100% { opacity: 0; }
}

@media (max-width: 575.98px) {
  .flow {
    --ring: 88px;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    column-gap: 4px;
    row-gap: 38px;
  }
  /* подписи переносятся, а не раздвигают колонку за край экрана */
  .flow-stats {
    white-space: normal;
    text-align: center;
    line-height: 1.35;
  }
  .flow-stats > div + div { margin-top: 4px; }
  .flow-stats-solar { justify-self: center; }
  .flow-value { font-size: 0.9rem; }
  .flow-sub { font-size: 0.62rem; }
  .flow-icon .icon { width: 22px; height: 22px; }
  .flow-hub { width: 38px; height: 38px; border-radius: 11px; }
  .flow-stats { font-size: 0.72rem; }
  .flow-stats strong { font-size: 0.85rem; }
}

@media (prefers-reduced-motion: reduce) {
  .flow-node,
  .flow-hub,
  .flow-stats,
  .flow-node.is-active .flow-ring::after {
    animation: none;
  }
  .flow-ring-arc { transition: none; }
}

/* Кнопки режимов под схемой */
.flow-modes {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 28px;
  animation: flow-fade-in 0.8s 0.4s ease both;
}
.mode-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 230px;
  padding: 8px 14px 8px 8px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--viz-c) 45%, transparent);
  background: color-mix(in srgb, var(--viz-c) 8%, var(--tblr-bg-surface));
  color: var(--viz-text);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
}
[data-bs-theme="dark"] .mode-pill {
  background: color-mix(in srgb, var(--viz-c) 12%, #151c29);
}
.mode-pill:hover,
.mode-pill[aria-expanded="true"] {
  border-color: var(--viz-c);
  box-shadow: 0 6px 22px -10px color-mix(in srgb, var(--viz-c) 80%, transparent);
}
.mode-pill:active {
  transform: scale(0.98);
}
.mode-pill:focus-visible {
  outline: 2px solid var(--viz-c);
  outline-offset: 2px;
}
.mode-pill-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--viz-c);
  background: color-mix(in srgb, var(--viz-c) 16%, transparent);
  flex: none;
}
.mode-pill-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  flex: 1;
}
.mode-pill-caption {
  font-size: 0.7rem;
  color: var(--viz-muted);
}
.mode-pill-value {
  font-weight: 600;
  white-space: nowrap;
}
.mode-pill-state {
  color: var(--viz-muted);
  display: grid;
  place-items: center;
}
.mode-chevron {
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
}
.mode-pill.is-pending .mode-pill-value {
  color: var(--viz-muted);
}
.mode-menu {
  min-width: 260px;
}
.mode-menu .dropdown-item {
  gap: 8px;
}
.mode-check {
  color: var(--tblr-primary);
}
.mode-check.is-off {
  visibility: hidden; /* место под галочку сохраняется — пункты выровнены */
}
.mode-note {
  max-width: 260px;
  white-space: normal;
}

/* Всплывающее уведомление о результате команды */
.flow-toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 20px);
  z-index: 1080;
  max-width: min(92vw, 440px);
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--tblr-bg-surface);
  color: var(--viz-text);
  border: 1px solid var(--tblr-border-color);
  border-left: 4px solid var(--toast-c, var(--tblr-primary));
  box-shadow: 0 12px 40px -12px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.flow-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
.flow-toast.is-ok { --toast-c: var(--tblr-success); }
.flow-toast.is-error { --toast-c: var(--tblr-danger); }

@media (max-width: 575.98px) {
  .mode-pill { min-width: 0; width: 100%; }
  .flow-modes > .dropdown { width: 100%; }
}

/* ------------------------------------------------------------------
   Главная: «Усі показники» — карточки по группам
   ------------------------------------------------------------------ */
.metrics-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  margin: 4px 2px 12px;
}
.metrics-section-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}
.metric-card {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 60% at 100% 0%, color-mix(in srgb, var(--viz-c) 9%, transparent), transparent 70%),
    var(--tblr-bg-surface);
  animation: flow-fade-in 0.6s ease both;
}
.metric-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--viz-c), color-mix(in srgb, var(--viz-c) 30%, transparent));
}
.metric-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.metric-card-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--viz-text);
}
.metric-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin-bottom: 12px;
}
.metric-hero-num {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--viz-text);
  white-space: nowrap;
}
.metric-hero-sub {
  font-size: 0.8rem;
  color: var(--viz-muted);
}
.metric-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--tblr-border-color-translucent, var(--tblr-border-color));
}
.metric-label {
  font-size: 0.85rem;
  color: var(--viz-muted);
}
.metric-value {
  font-weight: 600;
  color: var(--viz-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.metric-unit {
  margin-left: 0.25em;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--viz-muted);
}
.is-error .metric-value,
.is-error .counter-value,
.technical-item.is-error .fw-medium {
  color: var(--tblr-danger);
}

/* Полоски: доля PV-строки, уровень заряда */
.metric-bar {
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--viz-c) 16%, transparent);
  overflow: hidden;
}
.metric-bar-lg {
  height: 8px;
}
.metric-bar > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--viz-c);
  transition: width 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* PV-строки */
.pv-string {
  padding: 10px 0;
  border-top: 1px solid var(--tblr-border-color-translucent, var(--tblr-border-color));
}
.pv-string-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 6px;
}
.pv-string-name {
  font-size: 0.85rem;
  color: var(--viz-muted);
}
.pv-string-power {
  font-weight: 600;
  color: var(--viz-text);
  font-variant-numeric: tabular-nums;
}
.pv-string-meta {
  display: flex;
  gap: 14px;
  margin-top: 6px;
  font-size: 0.8rem;
  color: var(--viz-muted);
  font-variant-numeric: tabular-nums;
}

/* Лічильники інвертора */
.counter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
  gap: 12px;
}
.counter-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--viz-c) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--viz-c) 20%, transparent);
}
.counter-icon {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  color: var(--viz-c);
  background: color-mix(in srgb, var(--viz-c) 16%, transparent);
  flex: none;
}
.counter-icon .icon {
  width: 22px;
  height: 22px;
}
.counter-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--viz-muted);
}
.counter-value {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--viz-text);
  white-space: nowrap;
}

/* Технічні дані */
.metrics-technical {
  border: 1px solid var(--tblr-border-color);
  border-radius: 12px;
  background: var(--tblr-bg-surface);
  padding: 0 16px;
}
.metrics-technical > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  list-style: none;
  cursor: pointer;
  padding: 12px 0;
  font-size: 0.85rem;
  color: var(--viz-text);
}
.metrics-technical > summary::-webkit-details-marker { display: none; }
.metrics-technical > summary::before {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
  opacity: 0.6;
}
.metrics-technical[open] > summary::before { transform: rotate(45deg); }
.metrics-technical[open] { padding-bottom: 10px; }
.technical-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0 28px;
  margin-top: 8px;
}
.technical-item {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 2px;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--tblr-border-color-translucent, var(--tblr-border-color));
}

/* Раскрывающийся список всех показаний */
.metrics-details > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
}
.metrics-details > summary::-webkit-details-marker { display: none; }
.metrics-details > summary::before {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
  opacity: 0.6;
}
.metrics-details[open] > summary::before {
  transform: rotate(45deg);
}
.metrics-details:not([open]) > summary {
  border-bottom: 0;
}

/* Выбор языка в меню пользователя */
.lang-item {
  display: flex;
  align-items: center;
  gap: 10px;
}
.lang-code {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 18px;
  border-radius: 4px;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--viz-muted);
  border: 1px solid var(--tblr-border-color);
}
.lang-item[aria-current="true"] .lang-code {
  color: var(--tblr-primary);
  border-color: var(--tblr-primary);
}
.login-langs .btn {
  min-width: 96px;
}

/* Логи поллера — тёмная «консоль» в любой теме */
.log-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.log-search {
  width: 16rem;
  max-width: 100%;
}
.log-view {
  height: 65vh;
  min-height: 320px;
  overflow: auto;
  padding: 10px 0;
  background: #0d1117;
  color: #c9d1d9;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12.5px;
  line-height: 1.55;
}
.log-row {
  display: grid;
  grid-template-columns: 5.2em 5.8em 11em 1fr;
  gap: 0 12px;
  padding: 1px 16px;
}
.log-row:hover {
  background: rgba(255, 255, 255, 0.04);
}
.log-time { color: #6e7681; }
.log-source { color: #8b949e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.log-message { white-space: pre-wrap; word-break: break-word; }
.log-level { font-weight: 600; color: #58a6ff; }
.log-warning .log-level, .log-warning .log-message { color: #e3b341; }
.log-error .log-level, .log-error .log-message,
.log-critical .log-level, .log-critical .log-message { color: #ff7b72; }
.log-debug .log-level { color: #6e7681; }
.log-empty {
  padding: 24px 16px;
  color: #8b949e;
}
@media (max-width: 575.98px) {
  .log-row { grid-template-columns: 5.2em 1fr; }
  .log-source, .log-level { display: none; }
}

/* Таблица, которая на телефоне превращается в карточки (строка = блок) */
@media (max-width: 575.98px) {
  .stack-mobile thead { display: none; }
  .stack-mobile tr { display: block; padding: 12px 16px; border-bottom: 1px solid var(--tblr-border-color); }
  .stack-mobile td { display: block; padding: 3px 0 !important; border: 0 !important; }
  .stack-mobile td:first-child { font-weight: 600; }
}

/* Система: поле Modbus-адреса */
.unit-input {
  width: 5.5rem;
}

/* ------------------------------------------------------------------ прочее */
.theme-toggle {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}
[data-bs-theme="dark"] .theme-icon-dark,
[data-bs-theme="light"] .theme-icon-light,
:root:not([data-bs-theme]) .theme-icon-light {
  display: none;
}

/* Отключённые настройки — явно "заблокированы" */
.setting-form input:disabled {
  cursor: not-allowed;
}

/* ------------------------------------------------------------------
   События: лента по дням. Цвет иконки — по смыслу (как на главной):
   заряд — батарея, разряд — дом, покупка — красный, продажа — зелёный.
   ------------------------------------------------------------------ */
.event-filters { gap: 12px; flex-wrap: wrap; }
.event-filters .btn-group { flex-wrap: wrap; }
.event-list { padding-top: 4px; }
.event-day {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 14px 0 4px;
  padding: 4px 0;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--viz-muted);
  background: var(--tblr-bg-surface);
}
.event-day:first-child { margin-top: 0; }
.event-row {
  --ev-c: var(--viz-muted);
  position: relative;
  display: grid;
  grid-template-columns: 3.4rem 34px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 7px 0;
}
/* вертикальная линия времени через иконки */
.event-row::before {
  content: "";
  position: absolute;
  left: calc(3.4rem + 12px + 17px - 1px);
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--viz-gridline);
  z-index: 0;
}
.event-day + .event-row::before { top: 50%; }
.event-row:has(+ .event-day)::before,
.event-row:has(+ .event-more)::before,
.event-row:last-child::before { bottom: 50%; }
.event-time {
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  color: var(--viz-muted);
  text-align: right;
  line-height: 1.2;
}
.event-time-day { display: block; font-size: 0.68rem; }
.event-icon {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--ev-c);
  background: color-mix(in srgb, var(--ev-c) 14%, var(--tblr-bg-surface));
  box-shadow: 0 0 0 3px var(--tblr-bg-surface);
}
.event-icon .icon { width: 19px; height: 19px; }
.event-title { font-weight: 600; color: var(--viz-text); }
.event-meta { font-size: 0.8rem; color: var(--viz-muted); font-variant-numeric: tabular-nums; }
.event-meta:empty { display: none; }
.event-meta span + span::before { content: " · "; }
.event-duration {
  font-size: 0.8rem;
  color: var(--viz-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.event-duration.is-ongoing {
  color: var(--ev-c);
  font-weight: 600;
}
.event-battery { --ev-c: var(--viz-battery); }
.event-home { --ev-c: var(--viz-home); }
.event-buy { --ev-c: var(--flow-buy); }
.event-sell { --ev-c: var(--flow-sell); }
.event-mode { --ev-c: var(--viz-grid); }
.event-ok { --ev-c: var(--flow-sell); }
.event-alert { --ev-c: var(--flow-buy); }
.event-muted .event-duration.is-ongoing { color: var(--viz-text); }
.event-more { padding: 12px 0 4px; text-align: center; }
.event-list-compact .event-row { padding: 5px 0; }

@media (max-width: 575.98px) {
  .event-row {
    grid-template-columns: 2.9rem 30px minmax(0, 1fr);
    column-gap: 10px;
  }
  .event-row::before { left: calc(2.9rem + 10px + 15px - 1px); }
  .event-icon { width: 30px; height: 30px; }
  .event-icon .icon { width: 17px; height: 17px; }
  .event-duration { grid-column: 3; margin-top: -2px; }
}

/* ------------------------------------------------------------------
   Журнал команд (страница «Керування»): лента по дням.
   ------------------------------------------------------------------ */
.cmd-list { padding: 4px 20px 12px; }
.cmd-day {
  margin: 14px 0 2px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--viz-muted);
}
.cmd-row {
  --st-c: var(--viz-muted);
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--viz-gridline);
}
.cmd-row:last-child { border-bottom: 0; }
.cmd-done { --st-c: var(--flow-sell); }
.cmd-failed { --st-c: var(--flow-buy); }
.cmd-rejected { --st-c: #e8820c; }
.cmd-pending { --st-c: var(--viz-grid); }
.cmd-icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  color: var(--viz-c, var(--viz-muted));
  background: color-mix(in srgb, var(--viz-c, var(--viz-muted)) 14%, var(--tblr-bg-surface));
}
.cmd-icon > .icon { width: 21px; height: 21px; }
/* значок статуса в углу иконки */
.cmd-status-dot {
  position: absolute;
  right: -5px;
  bottom: -5px;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  color: #fff;
  background: var(--st-c);
  box-shadow: 0 0 0 2px var(--tblr-bg-surface);
}
.cmd-status-dot .icon { width: 12px; height: 12px; stroke-width: 3; }
.cmd-pending .cmd-status-dot { animation: cmd-pulse 1.4s ease-in-out infinite; }
@keyframes cmd-pulse {
  50% { box-shadow: 0 0 0 2px var(--tblr-bg-surface), 0 0 0 6px color-mix(in srgb, var(--st-c) 30%, transparent); }
}
.cmd-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}
.cmd-setting { font-weight: 600; color: var(--viz-text); }
.cmd-value {
  padding: 1px 9px;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--viz-text);
  background: color-mix(in srgb, var(--viz-c, var(--viz-muted)) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--viz-c, var(--viz-muted)) 30%, transparent);
  white-space: nowrap;
}
.cmd-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  margin-top: 4px;
  font-size: 0.8rem;
  color: var(--viz-muted);
}
.cmd-who { display: inline-flex; align-items: center; gap: 5px; }
.cmd-avatar {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--viz-text);
  background: var(--viz-gridline);
}
.cmd-failed .cmd-result,
.cmd-rejected .cmd-result { color: var(--st-c); }
.cmd-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.cmd-badge {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--st-c);
  background: color-mix(in srgb, var(--st-c) 13%, transparent);
  white-space: nowrap;
}
.cmd-time {
  font-size: 0.8rem;
  color: var(--viz-muted);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 575.98px) {
  .cmd-list { padding-inline: 14px; }
  .cmd-row { grid-template-columns: 34px minmax(0, 1fr); column-gap: 10px; align-items: start; }
  .cmd-icon { width: 34px; height: 34px; }
  .cmd-side { grid-column: 2; flex-direction: row; align-items: center; justify-content: flex-start; margin-top: 6px; }
}

/* ------------------------------------------------------------------
   «Сьогодні» на главной: енергобаланс, економія, прогноз сонця.
   ------------------------------------------------------------------ */
.today-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.today-card .card-body { display: flex; flex-direction: column; }
.today-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--viz-text);
}
.today-title .icon { width: 20px; height: 20px; color: var(--viz-muted); }
.today-lead { font-size: 0.85rem; color: var(--viz-muted); margin-bottom: 10px; }
.today-lead strong { font-size: 1.6rem; font-weight: 700; color: var(--viz-text); font-variant-numeric: tabular-nums; }
.today-foot { margin-top: auto; padding-top: 10px; font-size: 0.75rem; color: var(--viz-muted); }

/* Енергобаланс: полоса долей + легенда */
.balance-bar {
  display: flex;
  gap: 2px;
  height: 14px;
  border-radius: 7px;
  overflow: hidden;
  background: var(--viz-gridline);
}
.balance-seg { background: var(--viz-c); min-width: 4px; }
.balance-legend { list-style: none; margin: 14px 0 0; padding: 0; }
.balance-legend li {
  display: grid;
  grid-template-columns: 12px 1fr auto 3.2rem;
  align-items: center;
  column-gap: 8px;
  padding: 5px 0;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--viz-gridline);
}
.balance-legend li:last-child { border-bottom: 0; }
.balance-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--viz-c); }
.balance-name { color: var(--viz-text); }
.balance-kwh { color: var(--viz-muted); font-variant-numeric: tabular-nums; }
.balance-share { text-align: right; font-variant-numeric: tabular-nums; color: var(--viz-text); }

/* Економія */
.money-lead {
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--flow-sell);
  font-variant-numeric: tabular-nums;
}
.money-lead span { display: block; margin-top: 2px; font-size: 0.8rem; font-weight: 400; color: var(--viz-muted); }
.money-lead.is-negative { color: var(--flow-buy); }
.money-rows { list-style: none; margin: 12px 0 0; padding: 0; }
.money-rows li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  font-size: 0.85rem;
  color: var(--viz-muted);
  border-bottom: 1px solid var(--viz-gridline);
}
.money-rows li:last-child { border-bottom: 0; }
.money-rows strong { color: var(--viz-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.money-rows .money-paid { color: var(--flow-buy); }
.money-rows .money-earned { color: var(--flow-sell); }

/* Прогноз сонця: столбики по часам (прогноз светлый, факт — насыщенный поверх) */
.today-card.viz-solar .today-title .icon { color: var(--viz-solar); }
.forecast-lead {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: var(--viz-muted);
}
.forecast-lead strong { font-size: 1.6rem; font-weight: 700; color: var(--viz-text); font-variant-numeric: tabular-nums; }
.forecast-tomorrow { text-align: right; }
.forecast-tomorrow span { display: block; font-size: 0.75rem; }
.forecast-tomorrow strong { font-size: 1.05rem; }
.forecast-chart {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 96px;
  padding-bottom: 16px;
  position: relative;
  border-bottom: 1px solid var(--viz-baseline);
}
.forecast-col { position: relative; flex: 1 1 0; height: 100%; }
.forecast-bar,
.forecast-actual {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 4px 4px 0 0;
}
.forecast-bar { background: color-mix(in srgb, var(--viz-solar) 28%, transparent); }
.forecast-actual { left: 22%; right: 22%; background: var(--viz-solar); }
.forecast-hour {
  position: absolute;
  bottom: -17px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.62rem;
  color: var(--viz-muted);
  font-variant-numeric: tabular-nums;
}
.forecast-col:nth-child(odd) .forecast-hour { visibility: hidden; }
.forecast-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 22px;
  font-size: 0.75rem;
  color: var(--viz-muted);
}
.forecast-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }
.forecast-legend .lg-forecast { background: color-mix(in srgb, var(--viz-solar) 28%, transparent); }
.forecast-legend .lg-actual { background: var(--viz-solar); }
.forecast-source { font-size: 0.7rem; opacity: 0.85; }

/* ------------------------------------------------------------------
   Нижнее меню на телефоне (как в мобильном приложении).
   ------------------------------------------------------------------ */
.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1030;
  display: flex;
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--tblr-bg-surface) 92%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--tblr-border-color);
  box-shadow: 0 -6px 20px -12px rgba(0, 0, 0, 0.25);
}
.bottom-nav > .bottom-nav-item,
.bottom-nav-more { flex: 1 1 0; min-width: 0; }
.bottom-nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  padding: 4px 2px;
  border: 0;
  border-radius: 12px;
  background: none;
  font-size: 0.68rem;
  line-height: 1.2;
  color: var(--viz-muted);
  text-decoration: none;
}
.bottom-nav-item span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bottom-nav-item .icon { width: 22px; height: 22px; stroke-width: 1.75; }
.bottom-nav-item:hover { color: var(--viz-text); text-decoration: none; }
.bottom-nav-item.is-active { color: var(--tblr-primary); font-weight: 600; }
.bottom-nav-item.is-active .icon {
  background: color-mix(in srgb, var(--tblr-primary) 14%, transparent);
  border-radius: 10px;
  padding: 2px 10px;
  width: 42px;
  box-sizing: content-box;
  height: 22px;
}
@media (max-width: 991.98px) {
  /* место под нижнее меню, чтобы оно не закрывало конец страницы */
  .page { padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 575.98px) {
  /* переключатели вариантов (RTU/TCP, тариф) — во всю ширину, текст переносится */
  form .btn-group[role="radiogroup"] { display: flex; width: 100%; }
  form .btn-group[role="radiogroup"] > .btn { flex: 1 1 0; white-space: normal; }
}

/* ------------------------------------------------------------------
   Отключения: баннер на главной и страница графика.
   ------------------------------------------------------------------ */
.outage-banner {
  --ob-c: var(--tblr-orange, #f76707);
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
  padding: 12px 16px;
  border-radius: 14px;
  color: var(--viz-text);
  text-decoration: none;
  background: color-mix(in srgb, var(--ob-c) 10%, var(--tblr-bg-surface));
  border: 1px solid color-mix(in srgb, var(--ob-c) 35%, transparent);
}
.outage-banner:hover { text-decoration: none; color: var(--viz-text); border-color: var(--ob-c); }
.outage-banner.is-now { --ob-c: var(--flow-buy); }
.outage-banner.is-preparing { --ob-c: var(--viz-battery); }
.outage-banner-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  color: var(--ob-c);
  background: color-mix(in srgb, var(--ob-c) 16%, transparent);
}
.outage-banner-text { display: flex; flex-direction: column; min-width: 0; }
.outage-banner-text span { font-size: 0.82rem; color: var(--viz-muted); }
.outage-banner-arrow { margin-left: auto; color: var(--viz-muted); }
.is-preparing .outage-banner-icon { animation: cmd-pulse 1.8s ease-in-out infinite; --st-c: var(--ob-c); }

.outage-list, .manual-list { list-style: none; margin: 0; padding: 0; }
.outage-item, .manual-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--viz-gridline);
}
.outage-item:last-child, .manual-list li:last-child { border-bottom: 0; }
.manual-list { margin-bottom: 12px; }
.outage-when { display: flex; align-items: baseline; gap: 10px; }
.outage-day { min-width: 5.5rem; font-size: 0.85rem; color: var(--viz-muted); }
.outage-when strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.outage-status { display: flex; align-items: center; gap: 8px; }
.outage-item.is-ongoing strong { color: var(--flow-buy); }
.prep-status {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 0.85rem;
  background: var(--viz-gridline);
}
.prep-status.is-active { color: var(--viz-text); background: color-mix(in srgb, var(--viz-battery) 14%, transparent); }
.prep-status .icon { flex: none; color: var(--viz-battery); }

/* Поиск координат по адресу */
.geocode-results { max-height: 260px; overflow-y: auto; }
.geocode-item { display: flex; flex-direction: column; gap: 2px; text-align: left; font-size: 0.85rem; }
.geocode-coords { font-size: 0.75rem; color: var(--viz-muted); font-variant-numeric: tabular-nums; }
.geocode-filled { animation: geocode-flash 1.6s ease; }
@keyframes geocode-flash {
  0%, 40% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--flow-sell) 45%, transparent); border-color: var(--flow-sell); }
  100% { box-shadow: none; }
}

/* Карта точки прогноза (Leaflet + плитки OpenStreetMap) */
.geo-map {
  height: 260px;
  border-radius: 12px;
  border: 1px solid var(--tblr-border-color);
  overflow: hidden;
  background: var(--viz-gridline);
  z-index: 0;
}
.geo-map .leaflet-control-attribution { font-size: 0.65rem; }
.geo-pin { background: none; border: 0; }
.geo-pin-dot {
  position: absolute;
  left: 50%;
  top: 0;
  width: 22px;
  height: 22px;
  margin-left: -11px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: var(--viz-solar);
  border: 3px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
/* тёмная тема: приглушить яркие плитки, чтобы карта не «светила» */
[data-bs-theme="dark"] .geo-map .leaflet-tile-pane {
  filter: invert(1) hue-rotate(180deg) brightness(0.85) contrast(0.9);
}

/* ------------------------------------------------------------------
   Режим симуляции: плашка на всех страницах и страница «Симулятор».
   ------------------------------------------------------------------ */
.sim-banner {
  padding: 8px 0;
  font-size: 0.85rem;
  color: #3b2f00;
  background: repeating-linear-gradient(135deg, #ffd43b, #ffd43b 14px, #fcc419 14px, #fcc419 28px);
}
.sim-banner .icon { flex: none; }
.sim-banner-link { color: inherit; font-weight: 600; white-space: nowrap; }
.sim-hero-icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 16px;
  color: var(--viz-muted);
  background: var(--viz-gridline);
}
.sim-hero-icon .icon { width: 30px; height: 30px; }
.sim-hero.is-on { border-color: #fcc419; box-shadow: 0 0 0 1px #fcc419 inset; }
.sim-hero.is-on .sim-hero-icon { color: #b8860b; background: color-mix(in srgb, #fcc419 25%, transparent); }
.sim-hero-text { flex: 1 1 320px; min-width: 0; }
.sim-status { display: flex; flex-wrap: wrap; gap: 6px; }
/* погода — отдельные «чипы» с переносом (5 вариантов не помещаются в ряд на телефоне) */
form .btn-group.sim-weather { display: flex; flex-wrap: wrap; gap: 6px; width: auto; }
form .btn-group.sim-weather > .btn {
  flex: 0 1 auto;
  margin-left: 0 !important;
  border-radius: var(--tblr-border-radius) !important;
  white-space: nowrap;
}
.sim-scenarios { display: flex; flex-direction: column; gap: 12px; }
.sim-scenario {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  padding: 12px 14px;
  border: 1px solid var(--tblr-border-color);
  border-radius: 12px;
}
.sim-scenario.is-active {
  border-color: var(--flow-buy);
  background: color-mix(in srgb, var(--flow-buy) 8%, transparent);
}
.sim-scenario-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 200px; }
.sim-scenario-text strong { display: flex; align-items: center; gap: 6px; }
.sim-scenario-text span { font-size: 0.8rem; color: var(--viz-muted); }
.sim-soc { width: auto; flex: 0 0 auto; flex-wrap: nowrap; }
.sim-soc .form-control { width: 5rem; flex: none; }

/* Сети нет (напряжение 0): узел «Мережа» красный, кольцо пунктиром */
.flow-node.is-down { --viz-c: var(--flow-buy); }
.flow-node.is-down .flow-ring-arc { stroke-dasharray: 6 8; }
.flow-node.is-down .flow-sub { color: var(--flow-buy); font-weight: 600; }

/* Входы PV: своё название + код входа, мощность панелей */
.pv-string-code {
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 4px;
  font-size: 0.68rem;
  color: var(--viz-muted);
  background: var(--viz-gridline);
}
.pv-string-kwp { margin-left: 4px; font-size: 0.75rem; font-weight: 400; color: var(--viz-muted); }
.pv-kwp { max-width: 9rem; }
.pv-inputs-table select { min-width: 9rem; }

/* ------------------------------------------------------------------
   Статусы узлов схемы и карточек: «пилюля» с цветом по смыслу.
   Продажа — зелёный, покупка — красный (как «куплено/продано» и события),
   заряд — цвет батареи, разряд — цвет дома (как счётчики), генерация — солнце,
   нет потока — серый. Текст темнее/светлее фона пилюли — читается в обеих темах.
   ------------------------------------------------------------------ */
/* цвет по умолчанию — с нулевой специфичностью, чтобы .state-* всегда его переопределяли */
:where(.flow-sub, .status-pill) { --st: var(--viz-muted); }
.flow-sub[class*="state-"],
.status-pill {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 600;
  line-height: 1.45;
  color: color-mix(in srgb, var(--st) 72%, var(--viz-text));
  background: color-mix(in srgb, var(--st) 15%, transparent);
}
.status-pill { padding: 2px 9px; font-size: 0.76rem; vertical-align: 2px; }
.state-sell { --st: var(--flow-sell); }
.state-buy { --st: var(--flow-buy); }
.state-down { --st: var(--flow-buy); background: color-mix(in srgb, var(--flow-buy) 24%, transparent) !important; }
.state-charge { --st: var(--viz-battery); }
.state-discharge { --st: var(--viz-home); }
.state-production { --st: var(--viz-solar); }
.state-consumption { --st: var(--viz-home); }
.state-idle, .state-none, .state-unknown {
  --st: var(--viz-muted);
  font-weight: 500 !important;
  background: color-mix(in srgb, var(--viz-muted) 10%, transparent) !important;
}
/* в кольце узла места мало: компактнее и с переносом на 2 строки («немає генерації») */
.flow-sub[class*="state-"] {
  max-width: 86%;
  padding: 1px 6px;
  border-radius: 8px;
  white-space: normal;
  text-align: center;
  line-height: 1.25;
}

/* Подсказка над столбиками «Прогноз сонця» (static/forecast-tip.js) */
.forecast-col { cursor: default; outline: none; isolation: isolate; }
.forecast-col.is-active .forecast-bar { background: color-mix(in srgb, var(--viz-solar) 45%, transparent); }
.forecast-col.is-active .forecast-actual { filter: brightness(1.08) saturate(1.1); }
.forecast-col.is-active::after {
  content: "";
  position: absolute;
  inset: -2px -1px 14px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--viz-solar) 8%, transparent);
  z-index: -1;
}
.forecast-col:focus-visible { box-shadow: 0 0 0 2px var(--tblr-primary); border-radius: 4px; }
.forecast-tip {
  position: absolute;
  z-index: 1080;
  min-width: 170px;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 0.8rem;
  color: var(--viz-text);
  background: var(--tblr-bg-surface);
  border: 1px solid var(--tblr-border-color);
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.3);
  pointer-events: none;
}
.forecast-tip-time { margin-bottom: 4px; font-weight: 600; font-variant-numeric: tabular-nums; }
.forecast-tip-row {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  align-items: center;
  column-gap: 8px;
  padding: 1px 0;
}
.forecast-tip-row span { display: inline-block; color: var(--viz-muted); }
.forecast-tip-row span::first-letter { text-transform: uppercase; }
.forecast-tip-row strong { font-variant-numeric: tabular-nums; }
.forecast-tip-row i { width: 10px; height: 10px; border-radius: 3px; }
.forecast-tip-row i.lg-forecast { background: color-mix(in srgb, var(--viz-solar) 28%, transparent); }
.forecast-tip-row i.lg-actual { background: var(--viz-solar); }
.forecast-tip-diff {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--viz-gridline);
  text-align: right;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--viz-muted);
}
.forecast-tip-diff.is-more { color: var(--flow-sell); }
.forecast-tip-diff.is-less { color: var(--flow-buy); }

/* «Уменьшить движение» в системе: вместо бегущих точек — неподвижные шевроны направления */
.flow-chevron {
  fill: none;
  stroke: var(--viz-c);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Имя пользователя в шапке (логин — email, бывает длинным) */
.navbar-user { max-width: 11rem; }

/* Код устройства на странице первичной настройки — как на наклейке */
.setup-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .08em; text-transform: uppercase; }
.setup-code::placeholder { text-transform: none; letter-spacing: .08em; }



/* ------------------------------------------------------------------
   Стан пристрою (страница «Система»): процессор, температура, память, SD.
   Уровни: is-ok / is-warn / is-crit / is-unknown — всегда с подписью, не только цветом.
   ------------------------------------------------------------------ */
.health { --lvl-ok: var(--tblr-green); --lvl-warn: var(--tblr-orange); --lvl-crit: var(--tblr-red); --lvl-unknown: var(--tblr-secondary); }
.health .is-ok { --lvl: var(--lvl-ok); }
.health .is-warn { --lvl: var(--lvl-warn); }
.health .is-crit { --lvl: var(--lvl-crit); }
.health .is-unknown { --lvl: var(--lvl-unknown); }
.health-overall {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  font-size: .8125rem; font-weight: 600; color: var(--lvl);
  background: color-mix(in srgb, var(--lvl) 12%, transparent);
}
.health-overall .icon { width: 16px; height: 16px; }
.health-issues { border-bottom: 1px solid var(--tblr-border-color); }
.health-issues li {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 20px; font-size: .875rem;
  background: color-mix(in srgb, var(--lvl) 8%, transparent);
  border-left: 3px solid var(--lvl);
}
.health-issues li + li { border-top: 1px solid var(--tblr-border-color); }
.health-issues .icon { color: var(--lvl); flex: none; margin-top: 1px; }
.health-tile {
  height: 100%; padding: 14px 16px; border: 1px solid var(--tblr-border-color); border-radius: 10px;
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
.health-tile-head { display: flex; align-items: center; gap: 8px; font-size: .8125rem; color: var(--tblr-secondary); }
.health-tile-head .icon { width: 18px; height: 18px; }
.health-tile-head > span:first-of-type { flex: 1; }
.health-level { font-size: .6875rem; font-weight: 600; color: var(--lvl); text-transform: lowercase; }
.health-value { font-size: 1.625rem; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.health-bar { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--tblr-secondary) 16%, transparent); overflow: hidden; }
.health-bar > span { display: block; height: 100%; border-radius: inherit; background: var(--lvl); transition: width .4s ease; }
.health-sub { font-size: .75rem; color: var(--tblr-secondary); font-variant-numeric: tabular-nums; }
.health-spark { margin-top: auto; padding-top: 6px; }
.health-spark svg { display: block; width: 100%; height: 28px; overflow: visible; }
.health-spark path { fill: none; stroke: var(--tblr-primary); stroke-width: 1.5; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.health-spark .spark-mark { stroke: var(--lvl-warn); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; opacity: .7; }
.health-spark-caption { font-size: .6875rem; color: var(--tblr-secondary); margin-top: 2px; }
.health-section { font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--tblr-secondary); margin-bottom: 10px; }
.health-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--lvl); margin-right: 6px; vertical-align: 1px; }
.health-dl dt { font-weight: 400; color: var(--tblr-secondary); }
@media (prefers-reduced-motion: reduce) { .health-bar > span { transition: none; } }

.health-procs li { padding: 10px 0; border-bottom: 1px solid var(--tblr-border-color); }
.health-procs li:first-child { padding-top: 0; }
.health-procs li:last-child { border-bottom: 0; }
.health-proc-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.health-proc-name { font-weight: 500; }
.health-proc-state { font-size: .8125rem; color: var(--lvl); font-weight: 500; }
.health-proc-stats { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 4px; font-size: .75rem; color: var(--tblr-secondary); font-variant-numeric: tabular-nums; }

/* График нагрузки устройства (страница «Система») */
.sysmon-body { display: flex; flex-direction: column; gap: 14px; }
.sysmon-head { display: flex; align-items: center; gap: 8px; font-size: .8125rem; color: var(--tblr-secondary); }
.sysmon-head .icon { width: 18px; height: 18px; }
.sysmon-head strong { margin-left: auto; font-size: .9375rem; color: var(--viz-text); font-variant-numeric: tabular-nums; }
.sysmon-chart { height: 130px; }
.sysmon-row + .sysmon-row { padding-top: 14px; border-top: 1px solid var(--tblr-border-color); }
#sysmon > .card-header { flex-wrap: wrap; row-gap: 10px; }
@media (max-width: 575.98px) { #sysmon > .card-header .card-actions { margin-left: 0; width: 100%; } }

/* Подсказка на мини-графиках плиток (static/health-spark.js) */
.health-spark { position: relative; }
.health-spark svg[data-spark] { cursor: crosshair; touch-action: pan-y; }
.spark-guide { position: absolute; width: 1px; background: var(--viz-baseline); pointer-events: none; }
.spark-dot {
  position: absolute; width: 8px; height: 8px; border-radius: 50%; transform: translate(-50%, -50%);
  background: var(--tblr-primary); box-shadow: 0 0 0 2px var(--tblr-bg-surface); pointer-events: none;
}
.spark-tip {
  position: fixed; z-index: 1080; pointer-events: none; padding: 6px 10px; border-radius: 8px;
  background: var(--tblr-bg-surface); color: var(--viz-text); border: 1px solid var(--viz-gridline);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .12); font-size: .75rem; white-space: nowrap;
}
.spark-tip-key { background: var(--tblr-primary); }

/* ------------------------------------------------------------------
   Облако: панель домохозяйства (cloud/web/templates).
   ------------------------------------------------------------------ */
.cloud-badge {
  margin-left: 8px; padding: 2px 7px; border-radius: 999px; font-size: .6875rem; font-weight: 600;
  letter-spacing: .02em; color: var(--tblr-primary); background: color-mix(in srgb, var(--tblr-primary) 12%, transparent);
  vertical-align: middle;
}
.cloud-status { --lvl: var(--tblr-secondary); display: inline-flex; align-items: center; font-size: .8125rem; font-weight: 500; color: var(--lvl); }
.cloud-status.is-online { --lvl: var(--tblr-green); }
.cloud-status.is-offline { --lvl: var(--tblr-orange); }
.cloud-status .health-dot { background: var(--lvl); }
.cloud-backlog { padding: 8px 20px; font-size: .8125rem; color: var(--tblr-secondary); background: color-mix(in srgb, var(--tblr-primary) 6%, transparent); border-bottom: 1px solid var(--tblr-border-color); }
.cloud-inverter + .cloud-inverter { border-top: 1px solid var(--tblr-border-color); }
.cloud-inverter-head { display: flex; align-items: baseline; gap: 4px; margin-bottom: 12px; flex-wrap: wrap; }
.cloud-tile { height: 100%; padding: 12px 14px; border: 1px solid var(--tblr-border-color); border-radius: 10px; min-width: 0; }
.cloud-tile-label { display: flex; align-items: center; gap: 6px; font-size: .8125rem; color: var(--tblr-secondary); }
.cloud-tile-value { font-size: 1.5rem; font-weight: 600; line-height: 1.2; margin-top: 4px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cloud-tile-sub { font-size: .75rem; color: var(--tblr-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cloud-chart-head { display: flex; justify-content: space-between; margin: 18px 0 4px; font-size: .8125rem; color: var(--tblr-secondary); }
.cloud-chart { height: 240px; }
.cloud-device-settings > summary, .cloud-household-settings > summary { cursor: pointer; color: var(--tblr-secondary); font-size: .875rem; }
@media (max-width: 575.98px) { .cloud-tile-value { font-size: 1.25rem; } .cloud-chart { height: 200px; } }

/* Облако: участники домохозяйства */
.member-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 4px 12px; align-items: center; }
.member-who { min-width: 0; }
.member-actions { display: flex; align-items: center; gap: 8px; }
.member-actions .form-select { width: 10.5rem; }
.member-actions > form:last-child { min-width: 6.5rem; text-align: end; }  /* «Вийти»/«Видалити» — ряды выровнены */
@media (max-width: 767.98px) {
  .member-row { grid-template-columns: auto minmax(0, 1fr); }
  .member-actions { grid-column: 2; margin-top: 6px; min-width: 0; }
  .member-actions > form:first-child { flex: 1 1 0; min-width: 0; }
  .member-actions > form:last-child { min-width: 0; }
  .member-btn { width: 34px; padding-inline: 0; }
  .member-actions .form-select { width: 0; flex: 1 1 0; min-width: 0; }
}
.invite-link .form-control { font-family: var(--tblr-font-monospace); font-size: .8125rem; }

/* Облако: установщики */
.org-client { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; }
.org-client-state { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.org-code { font-family: var(--tblr-font-monospace); font-size: 1.75rem; font-weight: 600; letter-spacing: .06em; margin: 2px 0 6px;
  user-select: all; }
.org-code-input { font-family: var(--tblr-font-monospace); text-transform: uppercase; letter-spacing: .06em; }
.org-note { display: flex; gap: 8px; align-items: flex-start; padding: 10px 14px; border-radius: 8px; font-size: .8125rem;
  background: color-mix(in srgb, var(--tblr-azure) 10%, transparent); border-left: 3px solid var(--tblr-azure); }
.org-note .icon { color: var(--tblr-azure); flex: none; width: 18px; height: 18px; }

/* Облако: панель администратора сервиса */
.admin-note { display: flex; gap: 8px; align-items: flex-start; padding: 10px 14px; border-radius: 8px; font-size: .8125rem;
  color: var(--tblr-body-color); background: color-mix(in srgb, var(--tblr-red) 8%, transparent); border-left: 3px solid var(--tblr-red); }
.admin-note .icon { color: var(--tblr-red); flex: none; width: 18px; height: 18px; }
.admin-tabs { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.admin-tabs .nav-link { white-space: nowrap; }
.admin-stat-value { font-size: 1.75rem; font-weight: 600; line-height: 1.2; font-variant-numeric: tabular-nums; }
.admin-wrap { min-width: 180px; max-width: 360px; white-space: normal; }
.admin-temp-password code { font-size: 1.25rem; padding: 4px 10px; user-select: all; }
.admin-search { max-width: 420px; }
.admin-name { min-width: 170px; }

.cloud-sim { margin-left: 6px; padding: 1px 8px; border-radius: 999px; font-size: .6875rem; font-weight: 600;
  color: #7a4f00; background: #fde68a; }

/* Облако: логер, приславший свою главную (шаблоны устройства) */
.cloud-device-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.cloud-device-name { font-size: 1.05rem; font-weight: 600; }
.cloud-device-view + .cloud-device-view, .cloud-device-view + .cloud-device { margin-top: 28px; }
