:root {

    /* Та же форма/блюр, что и в основном дашборде (static/style.css) —
       единая система "Liquid Glass" на весь сайт. */
    --lg-shadow: 0 10px 34px rgba(0, 0, 0, 0.34), 0 1px 1px rgba(0, 0, 0, 0.20);
    --lg-shadow-sm: 0 4px 14px rgba(0, 0, 0, 0.26);

    /* Прозрачность стекла — как на эталонной странице инвертера
       (static/style.css): иначе на разных страницах степень размытия
       читается по-разному, хотя backdrop-filter один и тот же. */
    --panel-tag-bg: rgba(20, 20, 22, 0.85);
    /* Цвета показаний. На тёмной подложке годятся яркие, на светлой те же
       превращаются в блёклые пятна — поэтому они переменные, а не хексы
       по месту, и светлая тема задаёт свои, затемнённые. */
    --m-temp: #ff9f43;
    --m-hum:  #64d2ff;
    --m-co2:  #3498db;
    --m-pm:   #9aa4b2;
    --m-voc:  #34c759;
    --m-hcho: #ff9f0a;
    --m-power: #30d158;
    --unit-w: calc((100% - (10 * 4px)) / 11);
}

/* Світла тема — системна або примусова */
@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) {
        --bg-file: url('/static/wallpaper.jpg');
        --dash-bg: rgba(255, 255, 255, 0.12);
        --card-bg: rgba(255, 255, 255, 0.22);
        --card-bg-strong: rgba(255, 255, 255, 0.55);
        --card-border: rgba(255, 255, 255, 0.55);
        --card-highlight: rgba(255, 255, 255, 0.75);
        --text-main: #1c1c1e;
        --panel-tag-bg: #ffffff;
        --lg-shadow: 0 10px 34px rgba(31, 38, 74, 0.14), 0 1px 1px rgba(31, 38, 74, 0.05);
        --lg-shadow-sm: 0 4px 14px rgba(31, 38, 74, 0.10);
        --m-temp: #d2620b;
        --m-hum:  #0a7095;
        --m-co2:  #14639f;
        --m-pm:   #5b6675;
        --m-voc:  #17803d;
        --m-hcho: #a35f00;
        --m-power: #14803c;
        --good-color: #1a8f43;
        --warning-color: #b06d00;
    }
}

/* Примусова світла тема (data-theme="light" перезаписує системну dark) */
:root[data-theme="light"] {
    --bg-file: url('/static/wallpaper.jpg');
    --dash-bg: rgba(255, 255, 255, 0.12);
    --card-bg: rgba(255, 255, 255, 0.22);
    --card-bg-strong: rgba(255, 255, 255, 0.55);
    --card-border: rgba(255, 255, 255, 0.55);
    --card-highlight: rgba(255, 255, 255, 0.75);
    --text-main: #1c1c1e;
    --panel-tag-bg: #ffffff;
    --lg-shadow: 0 10px 34px rgba(31, 38, 74, 0.14), 0 1px 1px rgba(31, 38, 74, 0.05);
    --lg-shadow-sm: 0 4px 14px rgba(31, 38, 74, 0.10);
    --m-temp: #d2620b;
    --m-hum:  #0a7095;
    --m-co2:  #14639f;
    --m-pm:   #5b6675;
    --m-voc:  #17803d;
    --m-hcho: #a35f00;
    --m-power: #14803c;
    --good-color: #1a8f43;
    --warning-color: #b06d00;
}

/* Примусова темна тема (data-theme="dark" перезаписує системну light) */
:root[data-theme="dark"] {
    --bg-file: url('/static/wallpaper_dark.jpg');
    --dash-bg: rgba(0, 0, 0, 0.28);
    --card-bg: rgba(28, 28, 32, 0.55);
    --card-bg-strong: rgba(40, 40, 46, 0.62);
    --card-border: rgba(255, 255, 255, 0.16);
    --card-highlight: rgba(255, 255, 255, 0.14);
    --text-main: #f2f2f7;
    --panel-tag-bg: rgba(20, 20, 22, 0.85);
    --m-temp: #ff9f43;
    --m-hum:  #64d2ff;
    --m-co2:  #3498db;
    --m-pm:   #9aa4b2;
    --m-voc:  #34c759;
    --m-hcho: #ff9f0a;
    --m-power: #30d158;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-font-smoothing: antialiased; }
body {
    font-family: var(--font-apple);
    letter-spacing: -0.01em;
    color: var(--text-main);
    height: 100vh; overflow: hidden;
    padding: var(--sat) var(--sar) var(--sab) var(--sal);
    position: relative;
}

/* Фон — отдельным зафиксированным слоем (::before), а НЕ
   background-attachment:fixed на body: в Chromium это ломает
   backdrop-filter у потомков (см. static/style.css) — размытие
   карточек переставало рендериться вовсе. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    background-image: var(--bg-file);
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
}

/* Оболочка страницы: шапка сверху, рабочая область под ней. Стекло перенесено
   сюда с .dashboard, чтобы шапка лежала на том же фоне, а не висела отдельно. */
.page-shell {
    display: flex; flex-direction: column; height: 100vh;
    background: var(--dash-bg);
    backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    will-change: backdrop-filter;
}
.page-head {
    display: flex; align-items: center; gap: 12px; flex-shrink: 0;
    padding: 12px 18px; border-bottom: 1px solid var(--card-border);
}
.page-head h1 { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; }
.page-head .brand { color: #ff4800; }
.brand-logo { width: 28px; height: 28px; border-radius: 7px; display: block; flex-shrink: 0; }

/* flex:1 вместо height:100vh — высоту теперь делит оболочка. Внутренняя
   геометрия щитка от этого не зависит: ширины идут от --unit-w, высота
   автомата задана жёстко, а сама колонка как прокручивалась, так и
   прокручивается. */
.dashboard { display: flex; flex: 1; min-height: 0; width: 100%; }

.shield-side {
    width: 44%; flex-shrink: 0; background: var(--dash-bg);
    overflow-y: auto; padding: 15px 10px; border-right: 1px solid var(--card-border);
}
.panel {
    background: var(--card-bg); backdrop-filter: blur(var(--lg-blur-soft));
    border: 1px solid var(--card-border); border-radius: var(--lg-radius-lg);
    box-shadow: inset 0 1px 0 var(--card-highlight);
    padding: 25px 8px 10px 8px; position: relative;
}
/* Раньше подпись была зашита в content: — из-за этого она одна на
   странице оставалась непереводимой. Теперь это элемент разметки. Цвет
   серый: по смыслу это такой же заголовок группы, как разделы справа. */
.panel-tag {
    position: absolute; top: -10px; left: 15px;
    background: var(--panel-tag-bg); padding: 3px 12px;
    color: var(--text-main); opacity: 0.75;
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    border-radius: var(--lg-radius-pill); border: 1px solid var(--card-border);
}
.phase-container { margin-bottom: 30px; }
.rail, .labels-panel { display: flex; gap: 4px; width: 100%; }
.rail { background: rgba(128, 128, 128, 0.08); padding: 6px; border-radius: var(--lg-radius-md); border: 1px solid var(--card-border); }
.breaker {
    width: var(--unit-w); flex-shrink: 0; background: rgba(128, 128, 128, 0.12); border: 1px solid var(--card-border);
    border-radius: var(--lg-radius-sm); display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 10px 2px; height: 145px;
}
.breaker.unit-2 { width: calc((var(--unit-w) * 2) + 4px); }
.breaker.unit-4 { width: calc((var(--unit-w) * 4) + (3 * 4px)); }

.params-text { font-size: 0.7rem; text-align: center; color: var(--text-main); font-weight: 600; line-height: 1.1; width: 100%; }
.params-text div { height: 1.1em; }

.val-good { color: var(--good-color); }
.val-warn { color: var(--warning-color); }
.val-danger { color: var(--danger-color); }

.labels-panel { margin-top: 10px; min-height: 65px; padding: 0 5px; }
/* Индикатор связи. Раньше рисовался эмодзи 🟢/🔴: у них свой размер и
   отступы в каждом шрифте, поэтому ряд подписей в щитке плясал по высоте.
   Точка с подсветкой ведёт себя предсказуемо и выглядит так же, как на
   странице Xiaomi — единый приём на весь сайт. */
.dot {
    width: 8px; height: 8px; border-radius: 50%;
    display: inline-block; flex-shrink: 0;
}
.dot.on  { background: var(--good-color);   box-shadow: 0 0 7px var(--good-color); }
.dot.off { background: var(--danger-color); box-shadow: 0 0 7px var(--danger-color); }

/* В щитке точка живёт в строке прежних размеров: font-size и margin те же,
   что были у эмодзи, — высота панели подписей не сдвигается ни на пиксель.
   Геометрия щитка снята с настоящего щита, и трогать её нельзя. */
.label-unit .dot-line {
    font-size: 0.6rem; margin-bottom: 4px; line-height: 1.2;
    display: flex; align-items: center; justify-content: center;
}

.label-unit { width: var(--unit-w); font-size: 0.7rem; color: var(--text-main); font-weight: 500; text-align: center; line-height: 1.1; }
.label-unit.unit-2 { width: calc((var(--unit-w) * 2) + 4px); }
.label-unit.unit-4 { width: calc((var(--unit-w) * 4) + (3 * 4px)); }

.devices-side { flex: 1; overflow-y: auto; padding: 15px; }
/* Колонка мельче самой карточки: обычная занимает две, узкая — одну.
   Узкие — это выключатели и кормушка: у них есть только имя и кнопка,
   и полная ширина им ни к чему. */
.cards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(99px, 1fr)); gap: 10px; }
.device-card { grid-column: span 2; }

/* Уличные термометры стоят в одной группе с комнатными, но меряют погоду,
   а не квартиру. Отдельной группой они смотрелись огрызком на две карточки,
   поэтому выделены холодным акцентом и идут в группе первыми. */
.device-card.outdoor {
    --edge: rgba(100, 210, 255, 0.55);   /* запас, пока температура не прочитана */
    border-color: var(--edge);
    box-shadow: var(--lg-shadow), inset 0 1px 0 var(--card-highlight),
                0 0 0 1px var(--edge), 0 0 18px -6px var(--edge);
    transition: border-color 0.6s ease, box-shadow 0.6s ease;
}
.device-card.outdoor .val-temp { color: var(--edge); }

/* Узкая карточка: только имя и кнопка. Разделитель под именем ей не нужен —
   Разделитель под именем оставлен как у всех: стиль карточки общий.
   Имя центрируем, кнопку оставляем внизу, чтобы она стояла на одной линии
   с кнопками обычных карточек в том же ряду. */
.device-card.slim { grid-column: span 1; text-align: center; }
.device-card.slim .metric-row { display: none; }
.device-card.slim .card-header { justify-content: center; gap: 6px; }
.device-card.slim .card-title { font-size: 0.78rem; }
.device-card.slim .last-update { font-size: 0.6rem; }

/* Разделы правой части: датчики, обогрев, свет, прочее */
.card-section { margin-bottom: 22px; }
.card-section:last-child { margin-bottom: 0; }
.section-title {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text-dim, var(--text-main));
    opacity: 0.75; margin: 0 2px 9px;
}
.section-title::after {
    content: ''; flex: 1; height: 1px; background: var(--card-border);
}
.section-count {
    order: 3; font-size: 0.7rem; font-weight: 600; opacity: 0.7;
    letter-spacing: 0; font-variant-numeric: tabular-nums;
}

/* Сводка снизу: раньше все эти правила висели инлайном в разметке */
.summary-block {
    margin-top: 20px; text-align: center; padding: 16px;
    background: var(--card-bg);
    backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    border: 1px solid var(--card-border);
    border-radius: var(--lg-radius-lg);
    box-shadow: var(--lg-shadow), inset 0 1px 0 var(--card-highlight);
}
.summary-air {
    font-size: 0.8rem; margin-top: 5px; text-transform: uppercase;
    color: var(--text-main);
}
.summary-air.air-good { color: var(--good-color); }
.summary-air.air-mid  { color: var(--warning-color); }
.summary-air.air-bad  { color: var(--danger-color); }

.device-card {
    background: var(--card-bg);
    backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
    /* Слой под backdrop-filter раньше возникал случайно, из-за transform
       в :hover ниже — просим его явно, чтобы не зависеть от совпадения */
    will-change: backdrop-filter;
    border: 1px solid var(--card-border); border-radius: var(--lg-radius-lg);
    box-shadow: var(--lg-shadow), inset 0 1px 0 var(--card-highlight);
    padding: 11px 12px; display: flex; flex-direction: column; justify-content: space-between;
    min-height: 122px; height: 100%;
    transition: background 0.3s ease, border-color 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.device-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--lg-shadow), inset 0 1px 0 var(--card-highlight), 0 14px 40px rgba(0, 0, 0, 0.18);
}
.card-header { display: flex; justify-content: space-between; align-items: center; gap: 6px; border-bottom: 1px solid var(--card-border); padding-bottom: 6px; margin-bottom: 7px; }
.card-title { font-weight: 700; font-size: 0.8rem; color: var(--text-main); letter-spacing: -0.01em; line-height: 1.25; }
/* Севшая батарейка: имя датчика горит красным. Значок мелкий, и по нему
   одному пропажу замечали не сразу — а датчик с пустой батарейкой врёт
   молча, продолжая показывать последнее измеренное. */
.card-title.low-bat { color: var(--danger-color); }
/* Недоступный прибор: имя приглушено. Севшая батарейка важнее молчания —
   она его обычно и объясняет, — поэтому красный её цвет остаётся. */
.card-title.offline-name { color: var(--text-main); opacity: 0.42; }

/* Карточка Tuya-камеры — вне #cardsGrid (снимок ей не по чему опрашивать,
   в общий цикл renderPeriphery её было бы незачем тащить), поэтому своя
   ширина, а не span из грида выше. Классы cam-thumb-* — те же, что и на
   плитке камеры на главной (overview.css), тут их пришлось продублировать:
   страницы держат каждая свой CSS-файл. */
/* Камера идёт вдоль: слева снимок, справа управление. Общий стиль
   карточек задаёт height: 100% и justify-content: space-between — для
   плитки с показаниями это правильно, а камеру растягивало на всю высоту
   колонки: снимок улетал вверх, крестовина вниз, между ними чёрная
   пустота в пол-экрана. */
.cam-card { max-width: 900px; margin-bottom: 14px; height: auto;
            justify-content: flex-start; }
/* Три колонки в ряд: снимок, крестовина, настройки. Столбиком всё это
   занимало пол-экрана в высоту при пустом месте справа. */
.cam-body { display: flex; gap: 14px; align-items: flex-start; }
.cam-body .cam-thumb-wrap { flex: 0 0 300px; }
.cam-body .cam-controls { flex: 1 1 auto; margin-top: 0; min-width: 0;
                          flex-direction: row; gap: 14px; align-items: flex-start; }
/* Крестовина прижата влево и не сжимается: справа от неё живут настройки */
.cam-body .cam-pad { margin: 0; flex: 0 0 auto; }
.cam-settings { display: flex; flex-direction: column; gap: 8px;
                flex: 1 1 auto; min-width: 0; }

/* Не хватает ширины — настройки уходят под крестовину, а снимок под всё */
@media (max-width: 1100px) {
    .cam-body .cam-controls { flex-direction: column; }
}
@media (max-width: 720px) {
    .cam-body { flex-direction: column; }
    .cam-body .cam-thumb-wrap { flex: 1 1 auto; width: 100%; }
    .cam-body .cam-pad { margin: 0 auto; }
}
.cam-thumb-wrap {
    border-radius: 12px; overflow: hidden; aspect-ratio: 16/9;
    background: rgba(0, 0, 0, 0.25); position: relative;
}
.cam-thumb { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0;
             transition: opacity 0.25s; position: relative; z-index: 1; }
.cam-thumb.loaded { opacity: 1; }
.cam-thumb-empty {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: 0.78rem; opacity: 0.5;
}

/* Управление камерой: крестовина как в приложении и переключатели.
   Кнопка держится нажатой, пока камера едет, — отпустили, камера встала. */
.cam-controls { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
.cam-pad {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
    width: 132px; margin: 0 auto;
}
.cam-dir {
    aspect-ratio: 1; border-radius: 9px; cursor: pointer;
    background: var(--lg-bg-weak, rgba(255, 255, 255, 0.06));
    border: 1px solid var(--card-border, rgba(255, 255, 255, 0.16));
    color: inherit; font-size: 0.95rem; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.12s ease, transform 0.12s ease;
    -webkit-user-select: none; user-select: none; touch-action: none;
}
.cam-dir:hover { background: var(--lg-bg, rgba(255, 255, 255, 0.12)); }
.cam-dir.active { background: #0a84ff; border-color: #0a84ff; transform: scale(0.94); }
.cam-dir-stop { font-size: 0.7rem; opacity: 0.75; }

.cam-switches { display: flex; flex-wrap: wrap; gap: 5px; }
.cam-sw {
    padding: 5px 10px; border-radius: 999px; cursor: pointer;
    background: var(--lg-bg-weak, rgba(255, 255, 255, 0.06));
    border: 1px solid var(--card-border, rgba(255, 255, 255, 0.16));
    color: inherit; font-size: 0.72rem; font-weight: 600;
    transition: background 0.15s ease, opacity 0.15s ease;
}
.cam-sw:hover { background: var(--lg-bg, rgba(255, 255, 255, 0.12)); }
.cam-sw:disabled { opacity: 0.5; cursor: default; }
/* Включённое — зелёным, как индикаторы приборов рядом на этой же странице */
.cam-sw.on { background: rgba(48, 209, 88, 0.22); border-color: rgba(48, 209, 88, 0.55); }
/* Выбор из нескольких: подпись и кнопки в одной обойме, чтобы не
   путались с самостоятельными переключателями */
.cam-pick { display: inline-flex; align-items: center; gap: 4px;
            padding: 2px 6px 2px 8px; border-radius: 999px;
            background: rgba(255, 255, 255, 0.03); }
.cam-pick i { font-style: normal; font-size: 0.68rem; opacity: 0.55; margin-right: 2px; }
.cam-sd { font-size: 0.7rem; opacity: 0.55; }
.cam-wait { font-size: 0.72rem; opacity: 0.5; }

/* Живое видео занимает место миниатюры, а не добавляет своё: карточка
   от нажатия на «эфир» не должна прыгать в размерах. */
.cam-video { width: 100%; height: 100%; object-fit: cover; display: block;
             background: #000; position: relative; z-index: 2; }
/* Кнопка поверх картинки, в углу: снимок и так мелкий, отдавать под
   кнопку отдельную строку жалко. */
.cam-live-btn {
    position: absolute; right: 6px; bottom: 6px; z-index: 3;
    width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    font-size: 0.7rem; line-height: 1; color: #fff;
    background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(6px);
    transition: background 0.15s ease, transform 0.12s ease;
}
.cam-live-btn:hover { background: rgba(0, 0, 0, 0.75); }
.cam-live-btn:active { transform: scale(0.92); }
.cam-live-btn:disabled { opacity: 0.6; cursor: default; }
/* Красная точка «в эфире» — та же условность, что у всех камер мира */
.cam-live-tag {
    position: absolute; left: 6px; top: 6px; z-index: 3;
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 8px 2px 6px; border-radius: 999px;
    background: rgba(0, 0, 0, 0.55); color: #fff;
    font-size: 0.62rem; font-weight: 700; letter-spacing: 0.02em;
}
.cam-live-tag::before {
    content: ''; width: 6px; height: 6px; border-radius: 50%;
    background: #ff453a; animation: cam-live-pulse 1.6s ease-in-out infinite;
}
@keyframes cam-live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
    .cam-live-tag::before { animation: none; }
}

/* Карточки стали уже, поэтому метрики раскладываются по месту, а не жёстко
   по три в ряд — иначе на узкой карточке значения налезали друг на друга. */
.metric-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(48px, 1fr)); gap: 7px 4px; width: 100%; }
.metric-item { display: flex; align-items: center; gap: 2px; font-size: 0.8rem; font-weight: 600; white-space: nowrap; }
.val-temp { color: var(--m-temp); } .val-power { color: var(--m-power); }
.val-target { color: var(--m-hum); }
.unit-s { font-size: 0.6rem; font-weight: 400; opacity: 0.7; }

.card-footer {
    min-height: 32px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding-top: 8px;
}

/* ----- Спільні базові стилі кнопок ----- */
.power-btn {
    display: inline-grid;
    place-items: center;
    width: 2.3rem;
    height: 2.3rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    overflow: visible;
    font-size: 1.8rem;
    line-height: 1;
    transition: transform 0.12s ease, box-shadow 0.2s ease;
}

.power-btn:active {
    transform: scale(0.94);
}

.power-btn:focus-visible {
    outline: 2px solid #64d2ff;
    outline-offset: 2px;
}

/* Темна тема (за замовчуванням) */
.power-btn {
    background: #3f1518;
    color: #f87171;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255,255,255,0.06);
}

.power-btn.on {
    background: #14532d;
    color: #4ade80;
}

.power-btn:hover {
    color: #fca5a5;
}
.power-btn.on:hover {
    color: #86efac;
}

.power-btn.feeder-btn:hover {
    color: #f87171;
}
.power-btn.feeder-btn.on {
    background: #14532d;
    color: #4ade80;
}

.power-btn.offline,
.power-btn:disabled {
    background: #4a4a4a !important;
    color: #888888 !important;
    cursor: default !important;
    box-shadow: none !important;
    transform: none !important;
    opacity: 0.6;
    pointer-events: none;
}

/* Світла тема — кнопки (системна або примусова) */
@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .power-btn {
        background: #e4e6ea;
        color: #e74c3c;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255,255,255,0.6);
    }
    :root:not([data-theme="dark"]) .power-btn.on {
        background: #e4e6ea;
        color: #2ecc71;
    }
    :root:not([data-theme="dark"]) .power-btn:hover,
    :root:not([data-theme="dark"]) .power-btn.on:hover {
        color: inherit;
        background: #e4e6ea;
    }
    :root:not([data-theme="dark"]) .power-btn.feeder-btn {
        background: #e4e6ea;
        color: #e74c3c;
    }
    :root:not([data-theme="dark"]) .power-btn.feeder-btn.on {
        background: #e4e6ea;
        color: #e74c3c;
    }
    :root:not([data-theme="dark"]) .power-btn.feeder-btn.on.temporary {
        background: #86efac;
        color: #14532d;
    }
    :root:not([data-theme="dark"]) .power-btn.offline,
    :root:not([data-theme="dark"]) .power-btn:disabled {
        background: #c7cad1 !important;
        color: #6b7280 !important;
        opacity: 0.5;
    }
}

/* Примусова світла тема */
:root[data-theme="light"] .power-btn {
    background: #e4e6ea;
    color: #e74c3c;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255,255,255,0.6);
}
:root[data-theme="light"] .power-btn.on {
    background: #e4e6ea;
    color: #2ecc71;
}
:root[data-theme="light"] .power-btn:hover,
:root[data-theme="light"] .power-btn.on:hover {
    color: inherit;
    background: #e4e6ea;
}
:root[data-theme="light"] .power-btn.feeder-btn {
    background: #e4e6ea;
    color: #e74c3c;
}
:root[data-theme="light"] .power-btn.feeder-btn.on {
    background: #e4e6ea;
    color: #e74c3c;
}
:root[data-theme="light"] .power-btn.feeder-btn.on.temporary {
    background: #86efac;
    color: #14532d;
}
:root[data-theme="light"] .power-btn.offline,
:root[data-theme="light"] .power-btn:disabled {
    background: #c7cad1 !important;
    color: #6b7280 !important;
    opacity: 0.5;
}

.last-update {
    font-size: 0.6rem;
    opacity: 0.6;
    white-space: nowrap;
}

.update-time {
    position: fixed; bottom: 12px; right: 16px; font-size: 0.68rem; color: var(--text-main); opacity: 0.5;
    background: var(--dash-bg); backdrop-filter: blur(var(--lg-blur-soft));
    padding: 4px 10px; border-radius: var(--lg-radius-pill); border: 1px solid var(--card-border);
}
#summaryBlock { font-weight: 600; font-size: 0.9rem; line-height: 1.4; }

@media (max-width: 768px) {
    body {
        height: auto;
        overflow-y: auto;
    }
    .dashboard {
        flex-direction: column;
        height: auto;
        min-height: 100vh;
    }
    .shield-side {
        width: 100%;
        border-right: none;
        overflow-x: auto;
        padding: 10px;
    }
    .devices-side {
        width: 100%;
        overflow-y: visible;
        padding: 10px;
    }
    .panel {
        padding: 20px 5px 10px 5px;
    }
    .rail, .labels-panel {
        gap: 3px;
    }
}

/* ===== THEME TOGGLE ===== */




/* Зірки (темна) */

/* Хмари (світла) */


/* Кратери місяця */

/* Стан "увімкнено" = світла тема */



/* ── Общая шапка страниц ──────────────────────────────────────────────
   Три страницы писали заголовок по-своему: разный кегль, разный размер
   значка, где-то по центру, где-то слева. Здесь один образец на всех:
   значок 28 px со скруглением, кегль 21, версия рядом с названием,
   всё прижато к левому верхнему углу. */
/* Отступ и черта убраны: полоса должна выглядеть так же, как на других
   страницах, а поля даёт сама оболочка. */
.page-shell { padding: 20px 22px 0; }
.page-head h1 {
    display: flex; align-items: center; gap: 9px;
    margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -0.02em;
    line-height: 1.2;
}
.page-head .brand-logo,
.brand-logo {
    width: 28px; height: 28px; border-radius: 7px;
    display: block; flex-shrink: 0; object-fit: contain;
}
.page-head .ver {
    font-size: 12px; font-weight: 600; opacity: 0.5;
    letter-spacing: 0; margin-left: 2px;
}
.page-head .sub { font-size: 13px; opacity: 0.6; }

/* Заряд датчика — значком, а не числом: уровень читается мгновенно,
   а точное значение остаётся в подсказке при наведении */
.metric-item.bat { gap: 0; }
.metric-item.bat svg { display: block; }

/* Заряд стоит в строке названия, перед индикатором связи. Первый элемент
   после названия прижимается вправо, остальные идут за ним — так батарейка
   и точка держатся вместе у края, а не расползаются по ширине. */
.card-header > :nth-child(2) { margin-left: auto; }
.card-header .bat { flex-shrink: 0; opacity: 0.85; }
.card-header .bat svg { width: 19px; height: 9px; }
.bat-ok  { color: var(--good-color); }
.bat-mid { color: var(--warning-color); }
.bat-low { color: var(--danger-color); }

/* График за сутки в карточке датчика — занимает низ, где раньше была
   пустота. Осей и подписей нет: важна форма хода, а не отсчёты. */
/* Ход суток в карточке датчика: влажность заливкой, температура линией,
   сетка по шестичасовым отметкам, остаток дня притушен. Подписи границ
   шкалы стоят обычным текстом поверх — внутри svg их растянуло бы. */
.spark { position: relative; margin: 10px -2px 0; margin-top: auto;
         padding-top: 8px; height: 44px; }
.spark svg { width: 100%; height: 100%; display: block; overflow: visible; }
.spark-t { color: var(--m-temp); }
.spark-h { color: var(--m-hum); }
.spark-fill { fill: currentColor; opacity: 0.13; stroke: none; }
.spark-grid { stroke: currentColor; stroke-width: 1; opacity: 0.10; }
.spark-ahead { fill: currentColor; opacity: 0.05; }
.spark-hi, .spark-lo {
    position: absolute; right: 1px;
    font-size: 0.52rem; font-weight: 700; line-height: 1;
    color: var(--m-temp); opacity: 0.8; pointer-events: none;
    font-variant-numeric: tabular-nums;
}
.spark-hi { top: 15px; }
.spark-lo { bottom: 1px; }

/* Свои значки в метриках: размер по строке, цвет от самой метрики */
.mi { width: 15px; height: 15px; display: block; flex-shrink: 0; }
.val-hum { color: var(--m-hum); }

/* Цвета метрик: инлайновые стили ушли в классы вместе с эмодзи */
.val-co2  { color: var(--m-co2); }
.val-pm   { color: var(--m-pm); }
.val-voc  { color: var(--m-voc); }
.val-hcho { color: var(--m-hcho); }
.val-volt { opacity: 0.85; }
.val-door-open { color: var(--danger-color); }
.val-door-closed { color: var(--m-pm); }
.val-flood { color: var(--danger-color); }
.val-flood-ok { color: var(--good-color); }
.val-amp  { opacity: 0.85; }

/* Навигация между разделами — одинаковая на всех страницах */
.topnav { display: flex; gap: 6px; flex-wrap: wrap; }
.topnav-item {
    padding: 6px 14px; border-radius: var(--lg-radius-pill, 999px);
    background: var(--lg-bg-weak, rgba(255,255,255,0.06));
    border: 1px solid var(--card-border, rgba(255,255,255,0.14));
    box-shadow: inset 0 1px 0 var(--card-highlight, rgba(255,255,255,0.14));
    color: var(--text-main, inherit); text-decoration: none;
    font-size: 0.78rem; font-weight: 600; white-space: nowrap;
    transition: background 0.18s ease;
}
.topnav-item:hover { background: var(--lg-bg, rgba(255,255,255,0.12)); }
.topnav-item.current { background: var(--lg-bg, rgba(255,255,255,0.12)); opacity: 0.75; cursor: default; }



/* ── Кнопки в шапке: один вид и одно место на всех страницах ───────
   Слева заголовок и разделы, справа управление. «Выйти» — самый правый и
   красный: это выход, его не нажимают вслепую. */
.head-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.hdr-btn {
    padding: 6px 13px; border-radius: var(--lg-radius-pill, 999px);
    background: var(--lg-bg-weak, rgba(255,255,255,0.06));
    border: 1px solid var(--card-border, rgba(255,255,255,0.14));
    box-shadow: inset 0 1px 0 var(--card-highlight, rgba(255,255,255,0.14));
    color: var(--text-main, inherit); font: inherit;
    font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em;
    cursor: pointer; white-space: nowrap;
    transition: background 0.18s ease, border-color 0.18s ease;
}
.hdr-btn:hover { background: var(--lg-bg, rgba(255,255,255,0.12)); }
.hdr-btn.danger {
    background: rgba(255, 69, 58, 0.16);
    border-color: rgba(255, 69, 58, 0.45);
    color: #ff6b60;
}
.hdr-btn.danger:hover { background: rgba(255, 69, 58, 0.28); }


/* ── Общий верхний бар: одна мерка на все страницы ─────────────────
   Высота, кегль, размер значка и место кнопок заданы здесь и одинаковы
   везде. Заголовку задана постоянная ширина: без неё навигация начиналась
   на разном месте — у «Умный дом» и «Tuya · Устройства» разная длина, и
   кнопки плавали от страницы к странице. */
.page-head {
    display: flex; align-items: center; gap: 16px;
    min-height: 56px; box-sizing: border-box;
    /* Ширина обязательна: во флекс-колонке (страница Tuya) без неё шапка
       сжималась по содержимому, и margin: auto уводил её в центр. */
    width: 100%; flex-shrink: 0;
    margin: 0 auto 20px; max-width: min(100%, 2400px);
    padding: 0 2px; border-bottom: none;
}
.page-head h1 {
    display: flex; align-items: center; gap: 9px; margin: 0;
    width: 290px; flex-shrink: 0;
    font-size: 21px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2;
}
.page-head .brand-logo,
.page-head .title-icon {
    width: 28px; height: 28px; border-radius: 7px;
    display: block; flex-shrink: 0; object-fit: contain; margin: 0;
}
.page-head .ver {
    font-size: 12px; font-weight: 600; opacity: 0.5; letter-spacing: 0;
}
.topnav { display: flex; gap: 6px; flex-shrink: 0; }
.topnav-item {
    padding: 6px 14px; font-size: 0.78rem; font-weight: 600;
    line-height: 1.4; white-space: nowrap;
}
.head-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* Прибор отвечает только через облако: точка синяя, а не зелёная */
.dot.cloud { background: #4a9eff !important; box-shadow: 0 0 8px #4a9eff !important; }

/* Устаревшие показания датчика.

   Батарейный датчик просыпается раз в несколько минут: час молчания уже
   странно, сутки — значит умер, чаще всего села батарейка. Число остаётся
   на карточке (оно последнее известное), но принять его за свежее теперь
   нельзя: карточка гаснет, а время говорит цветом. */
.device-card.stale { opacity: 0.62; }
.device-card.stale .last-update { color: var(--warning-color); font-weight: 700; }

.device-card.dead { opacity: 0.45; }
.device-card.dead .last-update { color: var(--danger-color); font-weight: 700; }
.device-card.dead::after {
    content: "";
    position: absolute; inset: 0;
    border: 1px solid var(--danger-color);
    border-radius: inherit;
    opacity: 0.35;
    pointer-events: none;
}
.device-card { position: relative; }

/* Места: квартира, кабинет, дом. Внутри каждого — прежние подгруппы. */
.area-block { margin-bottom: 34px; }
.area-title {
    display: flex; align-items: center; gap: 10px;
    font-size: 1.35rem; font-weight: 800; letter-spacing: -0.02em;
    margin: 0 0 14px; padding-bottom: 10px;
    border-bottom: 2px solid rgba(128, 128, 128, 0.25);
}
.area-count {
    font-size: 0.72rem; font-weight: 700; opacity: 0.55;
    padding: 2px 9px; border-radius: 999px;
    background: rgba(128, 128, 128, 0.18);
}
.area-block .card-section { margin-bottom: 18px; }

/* Каналы многоканального реле: у секций их четыре, у подачи тепла две.
   Номер канала и его состояние — цветом, чтобы читалось одним взглядом. */
.chan-row { display: inline-flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.chan {
    display: inline-flex; align-items: center; justify-content: center; gap: 3px;
    height: 26px; padding: 0 8px; border-radius: 8px;
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em;
    border: 1px solid rgba(128, 128, 128, 0.35);
    background: rgba(128, 128, 128, 0.10);
    color: var(--text-dim, #8a8f98);
    cursor: pointer;
    transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.1s ease;
}
.chan-num { opacity: 0.7; font-size: 0.62rem; }
.chan:hover { background: rgba(128, 128, 128, 0.2); }
.chan:active { transform: scale(0.92); }
.chan.on {
    background: rgba(48, 209, 88, 0.22);
    border-color: rgba(48, 209, 88, 0.55);
    color: var(--good-color, #30d158);
}
.chan-labels {
    display: flex; flex-direction: column; gap: 2px;
    width: 100%; margin-top: 4px;
}
.chan-label {
    font-size: 0.72rem; color: var(--text-dim, #8a8f98);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ==========================================================================
   Светодиодная лента: цвет, режимы, сцены, таймер.

   Карточка шире прочих — на узкой ползунки превращаются в обрубки. Цвет
   самой ленты живёт в переменной --c и подсвечивает и образец, и кромку
   карточки: так видно, что горит, не читая цифр.
   ========================================================================== */
/* Места по ширине вдоволь, поэтому карточка занимает всю строку, а её
   содержимое идёт вдоль: слева кнопка с образцом цвета, посередине
   ползунки, справа режимы и таймер. Раньше всё это стояло столбиком и
   карточка тянулась вниз при пустых боках. */
.light-card { grid-column: 1 / -1; gap: 9px; }
.lt-wrap { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.lt-sliders { flex: 1 1 300px; min-width: 240px; display: flex; flex-direction: column; gap: 7px; }
.lt-side { display: flex; flex-direction: column; gap: 7px; flex-shrink: 0; }
.light-card.lit { border-color: color-mix(in srgb, var(--c) 55%, transparent); }
.light-card.lit .lt-swatch { box-shadow: 0 0 14px var(--c); }

.lt-top { display: flex; align-items: center; gap: 10px; }
.lt-swatch {
    width: 24px; height: 24px; border-radius: 50%;
    background: var(--c, #888);
    border: 1px solid var(--card-border);
    flex-shrink: 0;
}
.lt-state { font-size: 0.74rem; font-weight: 600; opacity: 0.7; }

.lt-modes, .lt-scenes, .lt-timers { display: flex; gap: 5px; flex-wrap: wrap; }
.lt-chip, .lt-scene {
    padding: 5px 11px; border-radius: 999px;
    border: 1px solid transparent; background: rgba(120, 120, 128, 0.16);
    color: var(--text-main); font: inherit; font-size: 0.72rem; font-weight: 600;
    cursor: pointer; white-space: nowrap;
    transition: background 0.18s ease, transform 0.1s ease;
}
.lt-chip.small { padding: 4px 9px; font-size: 0.68rem; }
.lt-scene { width: 26px; padding: 5px 0; text-align: center; }
.lt-chip:hover, .lt-scene:hover { background: rgba(120, 120, 128, 0.28); }
.lt-chip:active, .lt-scene:active { transform: scale(0.94); }
.lt-chip.on, .lt-scene.on {
    background: color-mix(in srgb, var(--c) 30%, transparent);
    border-color: color-mix(in srgb, var(--c) 60%, transparent);
}
.lt-chip:disabled, .lt-scene:disabled { opacity: 0.4; cursor: default; }

.lt-row { display: flex; align-items: center; gap: 8px; }
.lt-k { font-size: 0.66rem; font-weight: 700; opacity: 0.55;
        letter-spacing: 0.04em; text-transform: uppercase; width: 112px; flex-shrink: 0; }
.lt-v { font-size: 0.7rem; font-weight: 700; width: 38px; text-align: right;
        font-variant-numeric: tabular-nums; opacity: 0.8; }
.lt-block { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Ползунки: дорожка сама показывает, что выбирают — радугу для тона,
   растяжку от серого к цвету для насыщенности, от чёрного для яркости */
.lt-range { flex: 1; min-width: 0; height: 18px; -webkit-appearance: none; appearance: none;
            background: transparent; cursor: pointer; }
.lt-range::-webkit-slider-runnable-track { height: 8px; border-radius: 999px; }
.lt-range::-moz-range-track { height: 8px; border-radius: 999px; }
.lt-range.hue::-webkit-slider-runnable-track {
    background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%,
                                #00f 67%, #f0f 83%, #f00 100%);
}
.lt-range.hue::-moz-range-track {
    background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%,
                                #00f 67%, #f0f 83%, #f00 100%);
}
.lt-range.sat::-webkit-slider-runnable-track {
    background: linear-gradient(to right, #b0b0b0, var(--c, #fff));
}
.lt-range.sat::-moz-range-track { background: linear-gradient(to right, #b0b0b0, var(--c, #fff)); }
.lt-range.bright::-webkit-slider-runnable-track {
    background: linear-gradient(to right, #101010, var(--c, #fff));
}
.lt-range.bright::-moz-range-track { background: linear-gradient(to right, #101010, var(--c, #fff)); }
.lt-range::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 16px; height: 16px; margin-top: -4px; border-radius: 50%;
    background: #fff; border: 1px solid rgba(0, 0, 0, 0.25);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.lt-range::-moz-range-thumb {
    width: 16px; height: 16px; border-radius: 50%;
    background: #fff; border: 1px solid rgba(0, 0, 0, 0.25);
}
.lt-range:disabled { opacity: 0.4; cursor: default; }

@media (max-width: 700px) {
    .lt-wrap { gap: 12px; }
    .lt-sliders { flex-basis: 100%; }
    .lt-k { width: 92px; }
}

/* Кормушка: та же круглая кнопка, что у розеток и автоматов, — размер,
   посадка и цвета общие. Разница только в поведении: у кормушки нет
   положения «включено», поэтому вместо значка питания знак «+» (он же на
   самом приборе), а вместо застывшего состояния — короткая отдача:
   кнопка проседает, отпружинивает и расходится кольцом. */
.power-btn.feed-key { position: relative; font-size: 1.5rem; font-weight: 300; }
.power-btn.feed-key.fired { animation: feed-spring 0.4s cubic-bezier(0.22, 1.3, 0.36, 1); }
.power-btn.feed-key::after {
    content: ''; position: absolute; inset: -2px; border-radius: 50%;
    border: 2px solid var(--good-color); opacity: 0; pointer-events: none;
}
.power-btn.feed-key.fired::after { animation: feed-ring 0.6s ease-out forwards; }
@keyframes feed-spring {
    0%   { transform: scale(0.9); }
    55%  { transform: scale(1.06); }
    80%  { transform: scale(0.98); }
    100% { transform: scale(1); }
}
@keyframes feed-ring {
    0%   { transform: scale(1);    opacity: 0.9; }
    100% { transform: scale(1.5);  opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .power-btn.feed-key.fired,
    .power-btn.feed-key.fired::after { animation: none; }
}
