/* ============================================================================
   cp.lv — вид панели HostBill в стиле сайта (шаблон Snowlake).

   ЧТО ЭТО. Панель идёт на своей теме 2019 (Bootstrap 4) и CSS сайта не подключает.
   Здесь её вид приводится к сайту БЕЗ правки разметки: файл подключён из
   templates/2019/custom/auth.tpl, а тот включён в header.tpl — значит, работает
   на ВСЕХ страницах панели сразу. Поменял правило здесь — изменилось везде:
   /studio/products/, /studio/clientarea/ccard/, корзина, тикеты, партнёрка.
   Именно поэтому вёрстку страниц трогать не нужно и не следует.

   ОТКУДА ЗНАЧЕНИЯ. Сняты с живых эталонов шаблона Snowlake
   (snowlake.tortoizthemes.com/elements/icon_box и /elements/tabs, секции
   «Icons with Background» и «Tabs with Icons in Box»), локальный исходник —
   template/elements/*.html и template/assets/css/{style,plugins}.css:
     бокс      #fff, border 0, radius 4px, тень 0 5px 20px rgba(0,0,0,.04),
               тень при наведении 0 1px 2px rgba(0,0,0,.07)
     заголовок 20px/500 #404040, текст 16px/28px #606060
     вкладка   иконка НАД подписью, вкладки равной ширины, активная — белая
               плашка с той же тенью, обычная — прозрачная
     кнопка    зелёная #9ccd7e, радиус 1.25rem

   Файл лежит в custom/ — папка в auto-upgrade exclude, стоковые файлы темы целы.
   Копия в репозитории: hostbill/panel-templates/cplv-panel.css
   ============================================================================ */

/* ============================================================================
   ШКАЛА ОТСТУПОВ (правило «Отступы и плотность», DESIGN-SPEC.md §4)

   Шаг 4. В файле используются ТОЛЬКО эти значения:
       4 · 6 · 7 · 8 · 10 · 13 · 14 · 16 · 18 · 20 · 22 · 24 · 32
   (7 — подпись над полем, 13–14 — заголовок блока, 16 и 18 — телефон,
   20–24 — поля блока по бокам, 22 — между блоками, 32 — потолок пустой полосы).
   Число вне этого ряда — ошибка, а не оттенок вкуса: 12, 15, 26, 30, 36, 40, 48
   приведены к шкале 05.09.2026 (задача E1 из UI-AUDIT.md).

   ⚠️ ИСКЛЮЧЕНИЯ — числа, которые задают не ритм, а механику. Их не трогать:
     -9px        центровка ручки ползунка (её ширина 18)
     38/42/44px  место под знак внутри поля, отступ подменю, место под галочку
     60px        выравнивание заголовка раздела в шапке по названию услуги
     72px        высота нижней панели на телефоне и просвет под неё
     2px         смещение подписи под заголовком — это межстрочный интервал,
                 а не отступ раскладки, на рисунок блоков он не влияет
   ============================================================================ */

/* ============================================================================
   ТОКЕНЫ И ДВЕ ТЕМЫ

   Тему выбирает УСТРОЙСТВО, а не клиент: переключателя в панели нет, всё решает
   системная настройка (prefers-color-scheme). Светлый режим — значения ниже,
   тёмный — переопределения в медиазапросе.

   ⚠️ Каждый цвет объявлен в базовом :root, а в медиазапросе только меняет
   значение. Цвет, у которого единственное объявление лежит внутри @media,
   в другой теме не применится — это классическая причина «белый на белом».

   ⚠️ Левое меню и шапка тёмные в ОБЕИХ темах (решение владельца 30.08.2026):
   это навигация, она не должна спорить с рабочей областью. Их цвета живут
   в теме и здесь не трогаются.
   ============================================================================ */
:root {
    /* --- поверхности и текст (светлый режим) --- */
    --cplv-bg: #f6f7f9;           /* полотно страницы */
    --cplv-surface: #ffffff;      /* блок: карточка, список, форма */
    --cplv-surface-2: #eef0f4;    /* вложенная плашка, неактивная вкладка, полоса */
    --cplv-line: #e2e5ea;         /* контур блока и разделители внутри него */
    --cplv-line-strong: #cdd2da;  /* контур под курсором */
    --cplv-ink: #14181f;          /* основной текст */
    --cplv-muted: #6b7280;        /* подписи и второстепенное */

    /* --- действие ---
       ⚠️ Фирменный зелёный #9ccd7e кнопкой работает только на тёмном: на белом
       контраст с белым текстом ниже 3:1. Поэтому в светлом режиме действие —
       #3f8f57, а #9ccd7e остаётся индикатором состояния. */
    --cplv-accent: #3f8f57;
    --cplv-accent-hover: #35784a;
    --cplv-on-accent: #ffffff;

    /* --- состояния (значение, а не украшение) --- */
    --cplv-ok: #2f7a53;
    --cplv-warn: #8a6a15;
    --cplv-danger: #b3423a;
    /* Тона ошибки для ПЛАШКИ: подложка, контур и текст на ней. Отдельно от
       --cplv-danger, потому что тот — цвет знака и кнопки на белом, а на своей
       подложке он читается хуже и его приходится притемнять. */
    --cplv-danger-bg: rgba(179, 66, 58, .08);
    --cplv-danger-line: rgba(179, 66, 58, .42);
    --cplv-danger-ink: #8f2f28;
    /* Два тона только для различения категорий услуг — состояния ими не
       кодируются, поэтому в ряд «ок/внимание/ошибка» они не входят. */
    --cplv-info: #2f6f9f;
    --cplv-violet: #6b4fa0;
    --cplv-teal: #2e7d78;
    --cplv-rose: #a04a6f;

    /* --- форма блока --- */
    --cplv-radius: 12px;
    --cplv-radius-sm: 8px;
    --cplv-shadow: 0 1px 2px rgba(16, 20, 28, .04);
    --cplv-shadow-hover: 0 6px 18px rgba(16, 20, 28, .08);
    --cplv-ink-shadow: 0 6px 16px rgba(0, 0, 0, .18);
    --cplv-glow: 0 0 0 3px rgba(63, 143, 87, .30);

    /* --- навигация ---
       ⚠️ Левое меню и шапка МЕНЯЮТСЯ ВМЕСТЕ С ТЕМОЙ (решение владельца
       30.08.2026, после того как неизменно тёмное меню в светлом режиме было
       воспринято как поломка). Токены отдельные не потому, что цвет другой, а
       потому что у навигации свои роли: подложка, линия, активный пункт. */
    --cplv-nav-bg: #ffffff;
    --cplv-nav-line: #e2e5ea;
    --cplv-nav-ink: #14181f;
    --cplv-nav-muted: #5c6472;   /* подписи меню: темнее, чем общий muted — иначе бледнят */
    --cplv-nav-active: #eef0f4;
    --cplv-nav-hover: #f3f4f7;

    /* --- совместимость со старыми правилами файла ---
       Имена ниже встречаются в правилах, написанных до перехода на две темы.
       Переписывать их все ради переименования смысла нет: пусть указывают на
       новые токены — тогда цвет остаётся один и меняется в одном месте. */
    --cplv-green: var(--cplv-accent);
    --cplv-green-dark: var(--cplv-accent-hover);
    --cplv-dark: var(--cplv-ink);
    /* Тёмная кнопка (вход через GitHub). НЕ токен темы: --cplv-ink в тёмном режиме
       становится светлым (#e6eaf0), и кнопка выходила почти белой с белой подписью —
       страницы входа при этом остаются светлыми, потому что их рисует css сайта.
       Замечание владельца 01.09.2026. Цвет один в обеих темах. */
    --cplv-btn-dark: #181717;
    --cplv-text: var(--cplv-muted);
    --cplv-border: var(--cplv-line);
}

/* ---- ручной выбор темы ----
   По умолчанию режим берётся у устройства, но человек может решить иначе:
   переключатель в шапке ставит на <html> атрибут data-theme и запоминает выбор
   (localStorage, скрипт — в header.shared.tpl и custom/auth.tpl).
   Поэтому тёмные значения объявлены ДВАЖДЫ: в медиазапросе — со страховкой
   :root:not([data-theme="light"]), чтобы явно выбранная светлая тема побеждала
   тёмную систему, и отдельно для data-theme="dark", чтобы выбранная тёмная
   побеждала светлую систему.

   ⚠️ Тёмные значения объявляются на `body.template_2019`, а не на :root.
   Страницы входа, регистрации и восстановления пароля рисует вёрстка САЙТА
   (у них тело без классов темы), они всегда светлые — но тот же css им
   подключён, и на :root они забирали тёмные токены: заголовок «С возвращением»
   становился #e6eaf0 на белом (контраст 1,2:1 — не виден), а зелёная кнопка
   входа светлела до нечитаемой. Тем же был вызван случай с кнопкой GitHub
   (01.09.2026), который тогда закрыли отдельным токеном --cplv-btn-dark.
   Внутри панели ничего не меняется: всё её содержимое лежит в body. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) body.template_2019 {
        --cplv-bg: #0f1216;
        --cplv-surface: #171c22;
        --cplv-surface-2: #1e242c;
        --cplv-line: #262e37;
        --cplv-line-strong: #3a444f;
        --cplv-ink: #e6eaf0;
        --cplv-muted: #8b95a3;

        --cplv-accent: #9ccd7e;
        --cplv-accent-hover: #aed992;
        --cplv-on-accent: #0f1216;

        --cplv-ok: #9ccd7e;
        --cplv-warn: #c9a227;
        --cplv-danger: #e0736b;
        --cplv-danger-bg: rgba(224, 115, 107, .14);
        --cplv-danger-line: rgba(224, 115, 107, .45);
        --cplv-danger-ink: #f0a49e;
        --cplv-info: #7fb6e0;
        --cplv-violet: #b39ae0;
        --cplv-teal: #7fd0c9;
        --cplv-rose: #e39ab8;

        --cplv-shadow: 0 1px 2px rgba(0, 0, 0, .30);
        --cplv-shadow-hover: 0 6px 18px rgba(0, 0, 0, .45);
        --cplv-glow: 0 0 0 3px rgba(156, 205, 126, .30);

        --cplv-nav-bg: #0b0e11;
        --cplv-nav-line: #1e242c;
        --cplv-nav-ink: #e6eaf0;
        --cplv-nav-muted: #6f7c8b;
        --cplv-nav-active: #1a2129;
        --cplv-nav-hover: #151a20;
    }
}

:root[data-theme="dark"] body.template_2019 {
        --cplv-bg: #0f1216;
        --cplv-surface: #171c22;
        --cplv-surface-2: #1e242c;
        --cplv-line: #262e37;
        --cplv-line-strong: #3a444f;
        --cplv-ink: #e6eaf0;
        --cplv-muted: #8b95a3;

        --cplv-accent: #9ccd7e;
        --cplv-accent-hover: #aed992;
        --cplv-on-accent: #0f1216;

        --cplv-ok: #9ccd7e;
        --cplv-warn: #c9a227;
        --cplv-danger: #e0736b;
        --cplv-danger-bg: rgba(224, 115, 107, .14);
        --cplv-danger-line: rgba(224, 115, 107, .45);
        --cplv-danger-ink: #f0a49e;
        --cplv-info: #7fb6e0;
        --cplv-violet: #b39ae0;
        --cplv-teal: #7fd0c9;
        --cplv-rose: #e39ab8;

        --cplv-shadow: 0 1px 2px rgba(0, 0, 0, .30);
        --cplv-shadow-hover: 0 6px 18px rgba(0, 0, 0, .45);
        --cplv-glow: 0 0 0 3px rgba(156, 205, 126, .30);

        --cplv-nav-bg: #0b0e11;
        --cplv-nav-line: #1e242c;
        --cplv-nav-ink: #e6eaf0;
        --cplv-nav-muted: #6f7c8b;
        --cplv-nav-active: #1a2129;
        --cplv-nav-hover: #151a20;
    }

/* ============================================================================
   0. КНОПКИ И ПОЛЯ — без изменений с 13.08.2026
   ============================================================================ */

/* ---- базовая форма кнопки: скругление и вес как на сайте ---- */
.btn,
.btn.btn-sm,
.btn.btn-lg {
    border-radius: 1.25rem;
    font-weight: 600;
    letter-spacing: .01em;
    transition: background-color .15s ease, box-shadow .15s ease, color .15s ease;
}

/* ---- главные действия: зелёные, как «Заказать» на сайте ---- */
.btn-primary,
.btn-success,
.btn-info {
    background-color: var(--cplv-green);
    border-color: var(--cplv-green);
    color: #fff;
}

.btn-primary:hover, .btn-primary:focus, .btn-primary:active,
.btn-success:hover, .btn-success:focus, .btn-success:active,
.btn-info:hover, .btn-info:focus, .btn-info:active {
    background-color: var(--cplv-green-dark);
    border-color: var(--cplv-green-dark);
    color: #fff;
    box-shadow: var(--cplv-glow);
}

/* «Оплатить сейчас!» и прочие ключевые действия в списках — тот же зелёный */
.btn_pay, .btn-paynow, .btn-paynow2 {
    background-color: var(--cplv-green);
    border-color: var(--cplv-green);
    border-radius: 1.25rem;
    color: #fff;
}
.btn_pay:hover, .btn-paynow:hover, .btn-paynow2:hover {
    background-color: var(--cplv-green-dark);
    color: #fff;
}

/* ---- второстепенные действия: светлая кнопка с рамкой ---- */
.btn-secondary,
.btn-light,
.btn-default {
    background-color: #fff;
    /* Рамка задаётся целиком, а не одним border-color: у кнопок темы ширина
       рамки нулевая, и белая кнопка на белой карточке читалась как простой
       текст — «Управление доменом» в карточке выглядело неактивным. */
    border: 1px solid var(--cplv-border);
    color: var(--cplv-dark);
}
.btn-secondary:hover, .btn-secondary:focus,
.btn-light:hover, .btn-light:focus,
.btn-default:hover, .btn-default:focus {
    background-color: #f7f8fa;
    border-color: #cfd4dc;
    color: var(--cplv-dark);
}

.btn-dark {
    background-color: var(--cplv-btn-dark);
    border-color: var(--cplv-btn-dark);
    color: #fff;
}
.btn-dark:hover { background-color: #2b2b2b; border-color: #2b2b2b; color: #fff; }

/* ---- контурные кнопки ---- */
.btn-outline-primary,
.btn-outline-success {
    color: var(--cplv-green-dark);
    border-color: var(--cplv-green);
    background-color: transparent;
}
.btn-outline-primary:hover,
.btn-outline-success:hover {
    background-color: var(--cplv-green);
    border-color: var(--cplv-green);
    color: #fff;
}

/* Опасные действия остаются красными — цвет здесь несёт смысл, меняем только форму */
.btn-danger, .btn-outline-danger { border-radius: 1.25rem; }

/* ---- элементы, которые смотрятся вместе с кнопками ---- */
/* фокус полей — той же зелёной подсветкой, а не bootstrap-синим */
.form-control:focus,
.custom-select:focus {
    border-color: var(--cplv-green);
    box-shadow: var(--cplv-glow);
}

/* ссылки-действия в таблицах и карточках */
a.btn-link, .btn-link { color: var(--cplv-green-dark); }
a.btn-link:hover, .btn-link:hover { color: var(--cplv-dark); }

/* статус счёта: зелёный «оплачен» в тон кнопкам */
.badge-Paid, .badge-Active { background-color: var(--cplv-green); color: #fff; }

/* ---------------------------------------------------------------------------
   Ниже те же правила, но с приоритетом: файл подключается раньше основного CSS
   темы, поэтому без усиления селектора тема перебивала цвет и скругление.
   Область ограничена кнопками — на остальную вёрстку панели это не влияет.
   --------------------------------------------------------------------------- */
/* ⚠️ Радиус здесь с !important, потому что тема задаёт свой той же силой.
   Значение — из макета (8), а не «таблетка» 1.25rem: до 31.08.2026 кнопки были
   скруглены до овала, и рядом с вкладками-таблетками 40 px это читалось как
   второй набор форм. Правило ниже по файлу («КНОПКИ ПО МАКЕТУ») задаёт размеры;
   радиус остаётся тут, иначе флаг из этой строки перебивает его. */
body .btn, body .btn.btn-sm, body .btn.btn-lg,
body .btn_pay, body .btn-paynow, body .btn-paynow2 {
    border-radius: var(--cplv-radius-sm) !important;
    font-weight: 600;
}
body .btn-primary, body .btn-success, body .btn-info,
body .btn_pay, body .btn-paynow, body .btn-paynow2 {
    background-color: var(--cplv-green) !important;
    border-color: var(--cplv-green) !important;
    color: #fff !important;
}
body .btn-primary:hover, body .btn-success:hover, body .btn-info:hover,
body .btn_pay:hover, body .btn-paynow:hover, body .btn-paynow2:hover {
    background-color: var(--cplv-green-dark) !important;
    border-color: var(--cplv-green-dark) !important;
    box-shadow: var(--cplv-glow);
}
body .btn-secondary, body .btn-light, body .btn-default {
    background-color: #fff !important;
    border: 1px solid var(--cplv-border) !important;
    color: var(--cplv-dark) !important;
}
body .btn-secondary:hover, body .btn-light:hover, body .btn-default:hover {
    background-color: #f7f8fa !important;
    color: var(--cplv-dark) !important;
}
body .btn-dark { background-color: var(--cplv-btn-dark) !important; border-color: var(--cplv-btn-dark) !important; color: #fff !important; }
/* Контурные кнопки. Исключаем те, у которых уже есть цветовой класс темы сайта
   (.btn-green/.btn-red/.btn-dark/.btn-blue/.btn-sky): такими свёрстаны кнопки входа
   и соцсетей на страницах логина, регистрации и восстановления пароля — им нужен
   свой фон, а не прозрачный. */
body .btn-outline-primary:not(.btn-green):not(.btn-red):not(.btn-dark):not(.btn-blue):not(.btn-cobalt):not(.btn-sky),
body .btn-outline-success:not(.btn-green):not(.btn-red):not(.btn-dark):not(.btn-blue):not(.btn-cobalt):not(.btn-sky) {
    color: var(--cplv-green-dark) !important;
    border-color: var(--cplv-green) !important;
    background-color: transparent !important;
}
body .btn-outline-primary:not(.btn-green):not(.btn-red):not(.btn-dark):not(.btn-blue):not(.btn-cobalt):not(.btn-sky):hover,
body .btn-outline-success:not(.btn-green):not(.btn-red):not(.btn-dark):not(.btn-blue):not(.btn-cobalt):not(.btn-sky):hover {
    background-color: var(--cplv-green) !important;
    color: #fff !important;
}

/* ---- цветные кнопки темы сайта: вход и соцсети ----
   Значения те же, что в sites/cp.lv/assets/css (--color-red/blue/sky/dark/green). */
body .btn-green { background-color: var(--cplv-green) !important; border-color: var(--cplv-green) !important; color: #fff !important; }
body .btn-green:hover { background-color: var(--cplv-green-dark) !important; border-color: var(--cplv-green-dark) !important; color: #fff !important; }
body .btn-red { background-color: #d75959 !important; border-color: #d75959 !important; color: #fff !important; }
body .btn-red:hover { background-color: #c44e4e !important; border-color: #c44e4e !important; color: #fff !important; }
body .btn-cobalt { background-color: #4267b2 !important; border-color: #4267b2 !important; color: #fff !important; }
body .btn-cobalt:hover { background-color: #375593 !important; border-color: #375593 !important; color: #fff !important; }
body .btn-blue { background-color: #5ca7db !important; border-color: #5ca7db !important; color: #fff !important; }
body .btn-blue:hover { background-color: #4b95c8 !important; border-color: #4b95c8 !important; color: #fff !important; }
body .btn-sky { background-color: #5f86be !important; border-color: #5f86be !important; color: #fff !important; }
body .btn-sky:hover { background-color: #4f74a9 !important; border-color: #4f74a9 !important; color: #fff !important; }
body .form-control:focus, body .custom-select:focus {
    border-color: var(--cplv-green) !important;
    box-shadow: var(--cplv-glow) !important;
}
body .badge-Paid, body .badge-Active { background-color: var(--cplv-green) !important; color: #fff !important; }

/* Выбранный тариф в каталоге: тема красит его синим — переводим в фирменный зелёный,
   чтобы выделение совпадало с кнопкой заказа. */
body .cart-product.selected,
body .card.cart-product.selected {
    background-color: var(--cplv-green) !important;
    border-color: var(--cplv-green) !important;
}
body .cart-product.selected * { color: #fff !important; }
body .cart-product.selected .text-muted { color: rgba(255, 255, 255, .8) !important; }

/* ---- полотно панели ----
   Белое (решение владельца 30.08.2026). Сначала было наоборот: серое полотно
   #f3f4f7 под белыми боксами, как в эталонной секции Snowlake. Теперь роли
   поменялись — полотно белое, а блок держится не заливкой, а контуром в 1px
   и мягкой тенью (см. --cplv-line): цветных заливок в панели нет.
   Шапка, боковое меню и сами боксы красят себя сами и не затрагиваются. */
body.template_2019 { background-color: var(--cplv-bg); }

/* ============================================================================
   1. БОКСЫ — один вид на всю панель
   ============================================================================
   Эталон — «Icons with Background» шаблона Snowlake: белый блок без рамки,
   слабое скругление и мягкая тень. В теме 2019 «бокс» встречается под разными
   именами, поэтому перечислены все, а не переписана разметка страниц:
     .card                     — карточки Bootstrap (каталог /studio/products/,
                                 тикеты, кредитные карты, апгрейды, корзина);
     .table-responsive.table-borders — обёртка ЛЮБОГО списка-таблицы в панели
                                 (50 мест в шаблонах — все списки услуг, счетов,
                                 доменов, тикетов, контактов, партнёрки);
     .info-box .info-box-items — виджеты-сводки;
     .box                      — блоки страниц заказа;
     .cplv-card                — наши карточки клиентской зоны.
   ⚠️ Рамку снимаем, а не перекрашиваем: в эталоне её нет, глубину даёт тень.
   Если оставить рамку и добавить тень — получается «двойная обводка», самый
   заметный признак чужеродного блока. */
.cplv-box,
body .card,
body .table-responsive.table-borders,
body .info-box .info-box-items,
body .box,
body .cplv-card {
    background: var(--cplv-surface);
    /* ⚠️ Здесь рамка НУЖНА, хотя в эталоне Snowlake её нет. В эталоне белый бокс
       лежит на сером полотне, и границу рисует сам контраст; у нас полотно тоже
       белое, поэтому без линии блок теряет края и страница «разъезжается». */
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius) !important;
    box-shadow: var(--cplv-shadow);
}

/* ⚠️ У бокса тень при наведении НЕ меняется: в эталоне правила `.shadow:hover`
   нет вовсе, тень одна и та же. Подсветку оставляем только там, где карточка
   целиком кликабельна, — там это не украшение, а единственный признак ссылки. */
/* Под курсором карточка не меняет цвет — темнеет только контур. В монохроме
   это единственный способ показать «сюда можно нажать», не вводя лишний цвет. */
body .cplv-card--link:hover {
    box-shadow: var(--cplv-shadow-hover);
    border-color: var(--cplv-line-strong) !important;
}

/* Внутренние линии карточки Bootstrap: в стоке это серые полосы во всю ширину,
   в эталоне их нет — оставляем только тонкий разделитель у подвала карточки. */
body .card > .card-header,
body .card > .card-footer {
    background-color: transparent;
    border-color: var(--cplv-line);
}
body .card > .card-body { padding: 32px; }

/* Каталог услуг /studio/products/: заголовок карточки в стоке синий и мелкий —
   приводим к типографике эталона (20px/500, тёмно-серый), описание — 16/28. */
body .section-product-card .card-title {
    color: var(--cplv-dark) !important;
    font-size: 20px;
    font-weight: 500;
    line-height: 1.35;
}
body .section-product-card .card-title:hover { color: var(--cplv-accent) !important; }
body .section-product-card .card-text {
    color: var(--cplv-text);
    font-size: 15px;
    line-height: 1.6;
}

/* Таблицы внутри бокса: у бокса теперь своё скругление, поэтому у таблицы
   верхняя рамка не нужна — иначе она рисует линию поперёк скруглённого угла. */
body .table-responsive.table-borders > .table > thead > tr > th { border-top: 0; }

/* ============================================================================
   2. ВКЛАДКИ РАЗДЕЛОВ — таблетки 40 px
   ============================================================================
   Один вид вкладок на всю панель (решение владельца 31.08.2026). Раньше разделы
   биллинга, аккаунта, истории и партнёрки рисовались большими плитками с
   иконками — они появились до DESIGN-SPEC.md, а на странице сервера уже стояли
   таблетки, и панель выглядела как две разные системы. Теперь везде одно:
   высота 40, радиус 8, активная — заливка --cplv-ink, текст --cplv-bg;
   остальные — --cplv-surface-2, текст --cplv-muted (DESIGN-SPEC, §3).
   Эталон в коде — вкладки разделов клиентской зоны (.nav-tabs ниже по файлу):
   значения совпадают специально, чтобы ряд читался одинаково.

   ⚠️ КОГО ТРОГАЕМ. Тем же классом .nav-tabs в теме свёрстаны ДВЕ разные вещи:
     а) навигация по разделам — биллинг, детали аккаунта, история, контакты,
        партнёрка, безопасность, вкладки услуг на главной. Их и переделываем;
     б) ФИЛЬТРЫ списков — «Все / Активные / Отменённые» в услугах, доменах,
        тикетах. У них у ссылки класс .nav-link-slider, href="#Active" и
        data-sorter. Это не разделы, у них свой вид со слайдером.
   Разделяем их по .nav-link-slider — единственному надёжному признаку в разметке.

   ⚠️ Область правил задана через :has(): ширину и отступы надо менять у того
   <ul>, ВНУТРИ которого лежат вкладки, а он в разных шаблонах на разной глубине
   (на главной — сам .nav-tabs, в биллинге и партнёрке — вложенный <ul>).
   Браузер без :has() просто не применит блок и покажет стоковые вкладки —
   безопасная деградация.

   ⚠️ Префикс `body` у КАЖДОГО селектора обязателен. Тема описывает ту же вкладку
   селектором ровно такой же силы (.nav-tabs-wrapper .nav-tabs li.nav-item a.nav-link),
   а её app.css подключается ПОЗЖЕ нашего файла — при равном весе побеждает она.
   Без префикса молча терялись padding, кегль, начертание, цвет и white-space:
   вкладка оставалась стоковой (padding: 0, 16px/300, nowrap), хотя правила в файле
   были. Наступали на это 30.08.2026 — то же самое уже описано выше про кнопки. */

body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) {
    overflow: visible;
    /* Полоса вкладок отбита от соседей общим шагом 22 сверху и снизу. */
    margin: 22px 0;
}

/* Полоса вкладок. Таблетки идут по содержимому и переносятся: подписи на пяти
   языках разной длины, растягивать их до равной ширины нельзя (DESIGN-SPEC §6). */
body .nav-tabs-wrapper ul:has(> li.nav-item > a.nav-link:not(.nav-link-slider)) {
    display: flex;
    /* ⚠️ !important обязателен: тема вешает на этот же <ul> бутстраповские
       .flex-nowrap и .justify-content-between, а они объявлены с !important.
       Без перебивки ряд не переносился и на 390 px просто обрезался по краю
       (у обёртки PerfectScrollbar overflow:hidden, а его рельсу мы прячем). */
    flex-wrap: wrap !important;
    justify-content: flex-start !important;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    border: 0;
    list-style: none;
    background: none;
    overflow: visible !important;
    width: 100%;
}

/* Внешний <ul class="nav-tabs">, когда вкладки лежат во вложенном списке:
   он делит строку между полосой вкладок и кнопкой справа («Фильтр», «Создать
   тикет»). Полосе отдаём всю свободную ширину, кнопке — сколько нужно. */
body .nav-tabs-wrapper > ul.nav-tabs:has(li.nav-item > a.nav-link:not(.nav-link-slider)) {
    align-items: flex-start;
    /* !important — по той же причине, что и у полосы вкладок: на этом <ul> висит
       бутстраповский .flex-nowrap. Без перебивки на 390 px полоса вкладок и кнопка
       «Фильтровать данные» делили одну строку пополам, и таблетки вставали столбиком. */
    flex-wrap: wrap !important;
}
body .nav-tabs-wrapper > ul.nav-tabs > li:has(> ul > li.nav-item > a.nav-link:not(.nav-link-slider)) {
    /* Базис 320 px, а не 100%: на десктопе кнопка справа остаётся в одной строке
       с вкладками, а на узком экране (390) ей уже не хватает места и она честно
       переносится под полосу. С flex:1 1 100% кнопка падала вниз всегда. */
    flex: 1 1 320px;
    min-width: 0;
    padding: 0;
    margin: 0 0 10px;
    list-style: none;
}

body .nav-tabs-wrapper li.nav-item:has(> a.nav-link:not(.nav-link-slider)) {
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    border: 0;
    list-style: none;
    display: flex;
}

body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider) {
    /* ⚠️ border-box обязателен: иначе padding прибавляется к ширине и активная
       плашка выпирает из ряда. */
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 18px;
    margin: 0;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    text-align: center;
    white-space: normal;       /* в теме nowrap — длинные подписи вылезали */
    text-decoration: none;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

/* Знак вкладки. Кегль приводим к подписи: иконочный шрифт рисует глиф 24 px
   и роняет базовую линию. Отступ до слова даёт gap самой таблетки. */
body .nav-tabs-wrapper li.nav-item > a.nav-link .cplv-tab-ic {
    font-size: 18px;
    line-height: 1;
    margin: 0 !important;
    color: inherit !important;
    flex: 0 0 auto;
}

/* Наведение — только текст темнеет: подложка та же, иначе неактивная вкладка под
   курсором притворяется активной. */
body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider):hover,
body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider):focus {
    background: var(--cplv-surface-2);
    color: var(--cplv-ink);
    text-decoration: none;
}

/* Тема помечает активной то <li class="nav-item active"> (навигация по разделам),
   то саму ссылку (переключение вкладок на месте), поэтому оба варианта.
   ⚠️ Цвет подписи — полотно, а не #fff: в тёмном режиме --cplv-ink светлый,
   и белая подпись на нём становится нечитаемой (наступали 30.08.2026). */
body .nav-tabs-wrapper li.nav-item.active > a.nav-link:not(.nav-link-slider),
body .nav-tabs-wrapper li.nav-item > a.nav-link.active:not(.nav-link-slider),
body .nav-tabs-wrapper li.nav-item.active > a.nav-link:not(.nav-link-slider):hover,
body .nav-tabs-wrapper li.nav-item > a.nav-link.active:not(.nav-link-slider):hover {
    background: var(--cplv-ink);
    color: var(--cplv-bg) !important;
    font-weight: 600;
    box-shadow: none;
}

/* Счётчик у подписи (тема кладёт его в .badge внутри ссылки) — на активной
   вкладке подложка та же, что у текста, поэтому только меняем тон. */
body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider) .badge {
    background: transparent;
    color: inherit;
    font-weight: 600;
    padding: 0;
}

/* ⚠️ Тема впрыскивает в полосу вкладок свой индикатор-подчёркивание
   (div.slider) и рельсы PerfectScrollbar, а по бокам обёртки — стрелки
   прокрутки. Во флекс-раскладке они становятся полноценными колонками:
   слайдер рисует полосу под вкладками, рельсы съедают место. Вкладки у нас
   переносятся сами, прокрутка не нужна — прячем. Только там, где переделали:
   у фильтров подчёркивание остаётся стоковым. */
body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) .slider,
body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) .ps__rail-x,
body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) .ps__rail-y,
body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) > .nav-tabs-arrow-left,
body .nav-tabs-wrapper:has(li.nav-item > a.nav-link:not(.nav-link-slider)) > .nav-tabs-arrow-right {
    display: none !important;
}

/* Единственный раздел — полосу не показываем: выбирать не из чего, а место
   она занимает как полноценный переключатель. Считаем соседа: правило
   срабатывает, только если второго .nav-item в полосе нет. */
body .nav-tabs-wrapper ul:has(> li.nav-item > a.nav-link:not(.nav-link-slider)):not(:has(> li.nav-item ~ li.nav-item)) {
    display: none;
}

/* На телефоне таблетки те же, только плотнее и с чуть меньшим шагом. */
@media (max-width: 767px) {
    body .nav-tabs-wrapper ul:has(> li.nav-item > a.nav-link:not(.nav-link-slider)) { gap: 6px; }
    body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider) { padding: 0 14px; font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
    body .nav-tabs-wrapper li.nav-item > a.nav-link:not(.nav-link-slider) { transition: none; }
}

/* ---- одна-единственная вкладка: ряд не нужен ----
   Если у клиента услуги только одного вида, переключать нечего: ряд из одной
   вкладки лишь занимает первый экран и обманывает — выглядит как выбор, которого
   нет. Прячем его целиком, заголовок раздела остаётся.

   Считаем именно <li>, а не детей списка: тема впрыскивает в <ul> свой .slider
   и рельсы прокрутки, поэтому :nth-child ошибся бы. Условие «есть второй
   li.nav-item» читается как li.nav-item ~ li.nav-item.

   Класс cplv-tabs-wrap стоит только на вкладках услуг клиентской зоны — в других
   разделах панели единственная вкладка бывает подписью раздела, её не трогаем. */
body .cplv-tabs-wrap:not(:has(li.nav-item ~ li.nav-item)) {
    display: none;
}

/* ============================================================================
   3. КАРТОЧКИ КЛИЕНТСКОЙ ЗОНЫ
   ============================================================================
   Раньше эти правила лежали в <style> внутри clientarea/dashboard.tpl и
   действовали на одной странице. Перенесены сюда: карточка — такой же элемент
   панели, как бокс и вкладка, и должна выглядеть одинаково везде, где появится.
   Форма (фон, скругление, тень) теперь берётся из общего правила боксов выше —
   здесь остаётся только внутреннее устройство карточки. */

.cplv-cards { margin-top: 4px; }
.cplv-cards > [class^="col-"] { margin-bottom: 24px; display: flex; }
.cplv-card {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 24px 24px;
    transition: box-shadow .15s ease, transform .15s ease;
}

/* Кликабельная карточка: нажимается вся площадь, а не только кнопка.
   Приём stretched-link — ссылке-кнопке ::after растягивается на весь блок,
   поэтому ссылка в карточке остаётся ОДНА (заголовок — обычный текст), так же
   её читают скринридеры.
   ⚠️ Сама ссылка НЕ должна быть позиционированной: ::after считает координаты
   от ближайшего позиционированного предка, и стоит поставить кнопке
   position:relative — растянутая область схлопнется до размера кнопки. */
.cplv-card--link { position: relative; cursor: pointer; }
.cplv-card--link:hover { transform: translateY(-2px); }
.cplv-card--link:active { transform: translateY(0); }
.cplv-card--link .cplv-stretch::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: var(--cplv-radius);
}
.cplv-card--link:hover .cplv-card__title { color: var(--cplv-accent); text-decoration: underline; }
/* Бейдж поднимаем над растянутой областью, иначе он в неё проваливается */
.cplv-card--link .badge { position: relative; z-index: 2; }
/* Клавиатурная доступность: фокус на ссылке подсвечивает всю карточку */
.cplv-card--link:focus-within { box-shadow: 0 0 0 3px rgba(29, 29, 31, .22) !important; }

.cplv-card__head { display: flex; align-items: flex-start; gap: 10px; }
.cplv-card__headtext { flex: 1 1 auto; min-width: 0; }

/* Иконка типа услуги. Размер ОДИНАКОВЫЙ у всех карточек — это опорная точка,
   по которой глаз находит и сравнивает карточки; меняются только знак и
   подсветка. Различаются ЗНАКОМ, а не только цветом: так карточки читаются
   и при дальтонизме, и в чёрно-белой печати. */
.cplv-icon {
    flex: 0 0 44px; width: 44px; height: 44px; border-radius: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    /* Схема бело-чёрная, поэтому плашка серая, а знак чернильный — у ВСЕХ типов.
       Цветные знаки (синий VPS, зелёный домен и прочие) убраны вместе с цветными
       заливками: тип услуги различается САМИМ ЗНАКОМ, и это работает одинаково
       в цвете, при дальтонизме и в чёрно-белой печати. */
    background: var(--cplv-surface-2); color: var(--cplv-ink);
    border: 1px solid var(--cplv-line);
}
.cplv-icon .cplv-svg { width: 22px; height: 22px; display: block; }

.cplv-card__head > .cplv-card__title,
.cplv-card__head > .badge { align-self: center; }
.cplv-card__head > .cplv-card__title { flex: 1 1 auto; min-width: 0; }
.cplv-card__cat { display: block; text-transform: uppercase; letter-spacing: .04em; font-size: 11px; font-weight: 700; color: #8a92a6; margin-bottom: 2px; }
.cplv-card__title { display: block; font-size: 17px; font-weight: 600; line-height: 1.3; color: var(--cplv-dark); word-break: break-word; transition: color .15s ease; }
.cplv-card__sub { font-size: 13px; color: #8a92a6; margin-top: 2px; word-break: break-all; }
.cplv-card__meta { margin: 14px 0 18px; }
.cplv-card__meta > div { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; border-top: 1px solid var(--cplv-line); }
.cplv-card__meta dt { font-weight: 400; color: #8a92a6; font-size: 13px; margin: 0; }
.cplv-card__meta dd { margin: 0; font-size: 13px; font-weight: 600; color: var(--cplv-dark); text-align: right; }
/* margin-top:auto прижимает кнопку к низу — в ряду кнопки соседних карточек
   встают на одну линию при разной высоте содержимого. Отступ сверху задаём
   нижним полем блока характеристик: margin-top у кнопки перебил бы auto. */
.cplv-card__cta { margin-top: auto; padding-top: 10px; padding-bottom: 10px; }
.cplv-card--empty { align-items: center; text-align: center; padding: 32px 24px; }

/* ---- Карточка счёта ----
   Порядок как на образце от владельца: в первой строке знак, сумма и статус,
   под ней — за что счёт, затем срок оплаты и кнопка. Сумма поднята в шапку
   намеренно: это единственное, ради чего карточку открывают, и она должна
   читаться первой, без перевода взгляда на вторую строку. */
.cplv-card--invoice .cplv-card__amount {
    flex: 1 1 auto;
    min-width: 0;
    align-self: center;
    margin: 0;
    font-size: 28px;
    font-weight: 800;
    line-height: 1.1;
    color: var(--cplv-dark);
    letter-spacing: -.01em;
}
.cplv-card--invoice .cplv-card__subject {
    margin: 14px 0 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--cplv-dark);
    word-break: break-word;
}
.cplv-card--invoice .cplv-card__meta { margin-top: 10px; }

@media (max-width: 575px) {
    .cplv-card { padding: 18px; }
    .cplv-card--invoice .cplv-card__amount { font-size: 24px; }
}
@media (prefers-reduced-motion: reduce) {
    .cplv-card--link { transition: none; }
    .cplv-card--link:hover { transform: none; }
}

/* ============================================================================
   4. ПЕРЕХОД С ВИТРИНЫ /studio/ В КЛИЕНТСКУЮ ЗОНУ

   Клиента с услугами страница /studio/ переадресует на /studio/clientarea/
   (условие и разметка — в templates/2019/root.tpl). Пока грузится следующая
   страница, вместо мигания витрины показывается тот же экран ожидания, что и
   на сайте: полотно панели и расширяющееся кольцо из шаблона Snowlake
   (.page-loading, @keyframes loader-scale в assets/css/style.css).
   ============================================================================ */

.cplv-goto {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999999;
    background: var(--cplv-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.cplv-goto-in {
    padding: 0 1.5rem;
}

/* Кольцо расходится из центра и гаснет — один в один анимация лоадера сайта.
   Высота задана явно: у пустого элемента её нет, а кольцо нарисовано
   псевдоэлементом, и без коробки текст подпрыгнул бы к самому верху. */
.cplv-goto-spinner {
    position: relative;
    width: 2.5rem;
    height: 2.5rem;
    margin: 0 auto 1.5rem;
}

.cplv-goto-spinner::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 2.5rem;
    height: 2.5rem;
    border: 4px solid var(--cplv-dark);
    border-radius: 50%;
    animation: cplv-goto-scale 1s ease-out infinite;
}

@keyframes cplv-goto-scale {
    0%   { transform: scale(0); opacity: 0; }
    50%  { opacity: 1; }
    100% { transform: scale(1); opacity: 0; }
}

/* Кому анимация мешает (укачивает, отвлекает) — показываем спокойное кольцо. */
@media (prefers-reduced-motion: reduce) {
    .cplv-goto-spinner::after {
        animation: none;
        opacity: .35;
    }
}

.cplv-goto-text {
    margin: 0 0 .75rem;
    color: var(--cplv-text);
    font-size: 16px;
    line-height: 28px;
}

/* Ссылка — страховка: если переход не сработал (JS выключен, медленная сеть,
   заблокированный redirect), человек всё равно видит, куда идти. */
.cplv-goto-link {
    color: var(--cplv-green-dark);
    font-weight: 600;
    text-decoration: underline;
}

/* ============================================================================
   5. ТЁМНЫЙ РЕЖИМ УСТРОЙСТВА И ТИПОГРАФИКА ТЕМЫ cp-lv

   Тема HostBill свёрстана под светлый интерфейс: у неё жёстко заданы белые
   подложки, тёмный текст и серые рамки. Ниже эти места переведены на токены,
   поэтому в тёмном режиме устройства панель становится тёмной целиком, а не
   пятнами. Правила намеренно перечисляют стоковые классы: своей разметки у нас
   почти нет — её рисует закрытый код HostBill.
   ============================================================================ */

/* ---- типографика ----
   Onest — интерфейс, IBM Plex Mono — адреса, хосты, имена ОС и ключи: они
   должны читаться как код, а не как проза. Шрифты подключены в
   templates/cp-lv/header.shared.tpl. */
body,
body.template_2019,
body input, body select, body textarea, body button {
    font-family: Onest, "Segoe UI", system-ui, -apple-system, sans-serif;
}
/* ⚠️ Иконочный шрифт возвращаем ЯВНО. Тема опирается на лигатуры Material Icons:
   в разметке написано слово («shopping_cart»), а шрифт рисует значок. Стоит
   перебить у них font-family — и в шапке вместо иконок появляются слова
   «shopping_cart», «notifications», «dark_mode» (наступали 30.08.2026, когда
   общий Onest применился и к ним). */
body .material-icons,
body i.material-icons,
body .material-icons-outlined {
    font-family: "Material Icons" !important;
    font-weight: normal;
    font-style: normal;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
    direction: ltr;
    -webkit-font-feature-settings: "liga";
    font-feature-settings: "liga";
}
body code, body pre, body kbd, body samp,
body .cplv-mono,
body .cplv-card__sub {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
/* Деньги, даты и объёмы — табличными цифрами: в списке они встают в колонку. */
body .cplv-card__amount,
body .cplv-card__meta dd,
body table td, body table th {
    font-variant-numeric: tabular-nums;
}

/* ---- полотно и текст ---- */
body.template_2019 {
    background-color: var(--cplv-bg);
    color: var(--cplv-ink);
}
body h1, body h2, body h3, body h4, body h5, body h6,
body .h1, body .h2, body .h3, body .h4, body .h5, body .h6 {
    color: var(--cplv-ink);
}
body p, body span, body div, body li, body dt, body dd, body label {
    color: inherit;
}
body .text-muted, body .text-secondary, body small.text-muted {
    color: var(--cplv-muted) !important;
}

/* ---- блоки ----
   Форму блоку даёт контур: в тёмном режиме тень не видна вовсе, а в светлом
   одной тени мало — полотно светло-серое, но близкое к белому. */
.cplv-box,
body .card,
body .table-responsive.table-borders,
body .info-box .info-box-items,
body .box,
body .cplv-card {
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius) !important;
    box-shadow: var(--cplv-shadow);
    color: var(--cplv-ink);
}

/* ---- таблицы ----
   Стоковые списки остаются таблицами (их рисует закрытый код), но перестают
   быть белым пятном: подложка прозрачная, линии — токеном, шапка приглушена. */
body .table,
body .table > thead > tr > th,
body .table > tbody > tr > td,
body .table > tbody > tr > th {
    background-color: transparent;
    color: var(--cplv-ink);
    border-color: var(--cplv-line);
}
body .table > thead > tr > th {
    color: var(--cplv-muted);
    font-weight: 600;
    background-color: var(--cplv-surface-2);
}
body .table-hover > tbody > tr:hover,
body .table-striped > tbody > tr:nth-of-type(odd) {
    background-color: var(--cplv-surface-2);
}
body .table a { color: var(--cplv-ink); }
body .table a:hover { color: var(--cplv-accent); }

/* ---- поля ввода ----
   ⚠️ Поле обязано отличаться от блока, в котором лежит: в тёмном режиме это
   заметнее всего — одинаковый фон превращает форму в сплошное пятно. */
body .form-control,
body .custom-select,
body textarea.form-control,
body .selectize-input,
body .input-group-text {
    background-color: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    color: var(--cplv-ink);
    border-radius: var(--cplv-radius-sm);
}
body .form-control::placeholder,
body textarea.form-control::placeholder { color: var(--cplv-muted); }
body .form-control:focus,
body .custom-select:focus,
body .selectize-input.focus {
    background-color: var(--cplv-bg);
    border-color: var(--cplv-accent);
    box-shadow: var(--cplv-glow);
    color: var(--cplv-ink);
}
body label, body .form-group label { color: var(--cplv-muted); }

/* ---- поле под курсором и в наборе ----
   ⚠️ Тема красит ЛЮБОЕ поле в белый на :hover, :focus и :active
   (`app.css`: `.form-control:not([disabled],[readonly],…):hover{background:#FFFFFF;
   border:…!important;box-shadow:none}`). В тёмном режиме подпись остаётся светлой,
   поэтому набранный текст пропадал на белом — заметнее всего на форме обращения.
   Специфичность правила темы — (0,3,1), поэтому здесь у каждого селектора по два
   `:not()`: с одним правило просто не доходит. Контур темы стоит с `!important`,
   значит и свой держим так же. */
body input:not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="radio"]):not([type="checkbox"]):not([type="file"]):hover,
body input:not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="radio"]):not([type="checkbox"]):not([type="file"]):focus,
body input:not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="radio"]):not([type="checkbox"]):not([type="file"]):active,
body textarea:not([disabled]):not([readonly]):hover,
body textarea:not([disabled]):not([readonly]):focus,
body textarea:not([disabled]):not([readonly]):active,
body select:not([disabled]):not([readonly]):hover,
body select:not([disabled]):not([readonly]):focus,
body select:not([disabled]):not([readonly]):active,
body .form-control:not([disabled]):not([readonly]):hover,
body .form-control:not([disabled]):not([readonly]):focus,
body .form-control:not([disabled]):not([readonly]):active,
body .custom-select:not([disabled]):not([readonly]):hover,
body .custom-select:not([disabled]):not([readonly]):focus,
body .custom-select:not([disabled]):not([readonly]):active {
    background-color: var(--cplv-bg);
    color: var(--cplv-ink);
    border: 1px solid var(--cplv-line-strong) !important;
}
body input:not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="radio"]):not([type="checkbox"]):not([type="file"]):focus,
body textarea:not([disabled]):not([readonly]):focus,
body select:not([disabled]):not([readonly]):focus,
body .form-control:not([disabled]):not([readonly]):focus,
body .custom-select:not([disabled]):not([readonly]):focus {
    border-color: var(--cplv-accent) !important;
    box-shadow: var(--cplv-glow);
}

/* ---- всплывающие поверхности ----
   Меню, модалки и подсказки рисуются поверх страницы и в стоке всегда белые. */
body .dropdown-menu,
body .modal-content,
body .popover,
body .selectize-dropdown {
    background-color: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    color: var(--cplv-ink);
    border-radius: var(--cplv-radius);
}
body .dropdown-item, body .selectize-dropdown-content .option { color: var(--cplv-ink); }
body .dropdown-item:hover,
body .dropdown-item:focus,
body .selectize-dropdown-content .option.active {
    background-color: var(--cplv-surface-2);
    color: var(--cplv-ink);
}
body .dropdown-divider,
body .modal-header, body .modal-footer { border-color: var(--cplv-line); }

/* ---- прочие подложки темы ---- */
body .list-group-item,
body .card-header, body .card-footer,
body .nav-tabs, body .breadcrumb, body .page-link, body .accordion .card {
    background-color: transparent;
    border-color: var(--cplv-line);
    color: var(--cplv-ink);
}
body hr { border-color: var(--cplv-line); }

/* ---- кнопки в новой схеме ----
   Действие — единственное цветное пятно на экране; всё остальное контурное. */
body .btn,
body .btn.btn-sm,
body .btn.btn-lg { border-radius: var(--cplv-radius-sm); }
body .btn-primary, body .btn-success, body .btn-info,
body .btn_pay, body .btn-paynow, body .btn-paynow2 {
    background-color: var(--cplv-accent) !important;
    border-color: var(--cplv-accent) !important;
    color: var(--cplv-on-accent) !important;
}
body .btn-primary:hover, body .btn-success:hover, body .btn-info:hover,
body .btn_pay:hover, body .btn-paynow:hover, body .btn-paynow2:hover {
    background-color: var(--cplv-accent-hover) !important;
    border-color: var(--cplv-accent-hover) !important;
    color: var(--cplv-on-accent) !important;
}
body .btn-secondary, body .btn-light, body .btn-default {
    background-color: transparent !important;
    border: 1px solid var(--cplv-line) !important;
    color: var(--cplv-ink) !important;
}
body .btn-secondary:hover, body .btn-light:hover, body .btn-default:hover {
    background-color: var(--cplv-surface-2) !important;
    border-color: var(--cplv-line-strong) !important;
    color: var(--cplv-ink) !important;
}

/* ---- бейджи состояний ----
   Состояние читается словом и цветом сразу: цвет не единственный носитель
   смысла (дальтонизм, чёрно-белая печать). */
body .badge {
    border-radius: 6px;
    font-weight: 600;
    padding: 6px 10px;
    background-color: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
body .badge-Paid, body .badge-Active {
    background-color: var(--cplv-surface-2) !important;
    color: var(--cplv-ok) !important;
}
body .badge-Unpaid, body .badge-Pending, body .badge-Suspended {
    background-color: var(--cplv-surface-2) !important;
    color: var(--cplv-warn) !important;
}
body .badge-Cancelled, body .badge-Terminated, body .badge-Overdue {
    background-color: var(--cplv-surface-2) !important;
    color: var(--cplv-danger) !important;
}

/* ---- фокус с клавиатуры ----
   Видимое кольцо на всём, что можно активировать: без него тёмная тема
   становится непроходимой для клавиатуры. */
body a:focus-visible,
body button:focus-visible,
body .btn:focus-visible,
body .nav-link:focus-visible {
    outline: 2px solid var(--cplv-accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    body * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ---- шапка и всплывающие меню ----
   ⚠️ Шапка и левое меню тёмные В ОБЕИХ темах, поэтому их цвета — отдельные
   токены, а не общие: в светлом режиме они не должны светлеть вместе с полотном.
   Стоковый .navbar белый; тёмный вид ему даёт вложенный блок темы, но сам nav
   всё равно просвечивает по краям — красим явно.
   Выпадающие меню (корзина, уведомления, язык, аккаунт) тема красит белым с
   высокой специфичностью, поэтому здесь !important: без него в тёмном режиме
   из шапки вываливается белый прямоугольник. */
/* ⚠️ Шапка красится в цвет ПОЛОТНА, а не в цвет бокового меню: по макету это
   верхний край рабочей области, отделённый одной линией, а не второй тёмный
   слой. Белая шапка на сером полотне выглядела чужой (правка 30.08.2026). */
body .navbar,
body .navbar.fixed-top,
body .navbar > .container-fluid,
body .navbar-header,
body .navbar-body,
body .main-overlay {
    background-color: var(--cplv-bg) !important;
    border-bottom: 1px solid var(--cplv-line) !important;
    box-shadow: none !important;
}
body .navbar .nav-link,
body .navbar .navbar-text,
body .navbar a { color: var(--cplv-ink); }

body .dropdown-menu,
body .dropdown-menu.dropdown-menu-lg,
body .dropdown-menu.notifications-drop,
body .dropdown-menu.dropdown-order-items {
    background-color: var(--cplv-surface) !important;
    border: 1px solid var(--cplv-line) !important;
    color: var(--cplv-ink) !important;
    box-shadow: var(--cplv-shadow-hover);
}
body .dropdown-menu .dropdown-item,
body .dropdown-menu a,
body .dropdown-menu .media-body,
body .dropdown-menu h6, body .dropdown-menu p { color: var(--cplv-ink) !important; }
body .dropdown-menu .text-muted { color: var(--cplv-muted) !important; }
body .dropdown-menu .dropdown-item:hover,
body .dropdown-menu .dropdown-item:focus {
    background-color: var(--cplv-surface-2) !important;
}

/* Иконки шапки — корзина, уведомления, язык, аккаунт — остаются на месте:
   убран из шапки только поиск. Приводим их к одному размеру и расстоянию,
   чтобы ряд читался как один блок, а не как случайный набор. */
body .navbar .navbar-icon { color: var(--cplv-muted); }
body .navbar .badge { background-color: var(--cplv-accent); color: var(--cplv-on-accent); }

/* Пустая полоса, оставшаяся в шапке от удалённого поиска, в стоке белая. */
body .navbar-body,
body .navbar-collapse,
body .navbar .navbar-nav { background-color: transparent !important; }
body .navbar > .container-fluid,
body .navbar-header { background-color: var(--cplv-nav-bg) !important; }

/* Иконки шапки (корзина, уведомления, баланс, язык, аккаунт) в стоке лежат на
   белых плашках — шапка изначально была светлой. Красим их подложку в цвет
   шапки, иначе справа от кнопки «Заказать» тянется белая полоса. Сами кнопки
   остаются на месте: из шапки убран только поиск. */
body .navbar .nav-link,
body .navbar .nav-item,
body .navbar .nav-item > a,
body .navbar .dropdown > a {
    background-color: transparent !important;
    color: var(--cplv-ink) !important;
    border-color: var(--cplv-line) !important;
}
body .navbar .nav-link:hover,
body .navbar .nav-item > a:hover {
    background-color: var(--cplv-surface-2) !important;
    border-radius: var(--cplv-radius-sm);
}
body .navbar .nav-link .text-muted,
body .navbar .nav-link small { color: var(--cplv-muted) !important; }
body .navbar .material-icons { color: var(--cplv-muted) !important; }
body .navbar .nav-link:hover .material-icons { color: var(--cplv-ink) !important; }

/* ============================================================================
   6. СПИСКИ: ТАБЛИЦА, КОТОРАЯ ЧИТАЕТСЯ КАК СТРОКИ

   Списки счетов, услуг и доменов остаются <table> — на них завязаны сортировка,
   фильтры, пагинация и массовые действия темы. Меняем не разметку, а вид:
   строка получает воздух, действие вместо стрелки, а на телефоне таблица
   превращается в карточки (подписи берутся из data-label, которые тема уже
   проставляет ячейкам).
   ============================================================================ */

body .table > tbody > tr > td,
body .table > thead > tr > th { padding: 14px 16px; vertical-align: middle; }
body .table > tbody > tr > td { font-size: 15px; }
body .table > thead > tr > th { font-size: 12px; letter-spacing: .03em; text-transform: uppercase; }
body .table td.cplv-col-action { text-align: right; white-space: nowrap; width: 1%; }
body .table .cplv-inv-num { font-weight: 600; }

/* Пустое состояние списка: заголовок и объяснение вместо «Нечего отобразить». */
body .table td.cplv-empty {
    padding: 32px 24px;
    text-align: center;
}
body .cplv-empty__title {
    display: block;
    font-size: 17px;
    font-weight: 600;
    color: var(--cplv-ink);
}
body .cplv-empty__text {
    display: block;
    margin: 8px auto 0;
    max-width: 460px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--cplv-muted);
}

@media (max-width: 767px) {
    /* Таблица → карточки. Шапка не нужна: подпись каждой величины уходит в саму
       строку из data-label, иначе на 390 px колонки схлопываются в кашу. */
    body .table-responsive.table-borders > .table > thead { display: none; }
    body .table-responsive.table-borders > .table,
    body .table-responsive.table-borders > .table > tbody,
    body .table-responsive.table-borders > .table > tbody > tr,
    body .table-responsive.table-borders > .table > tbody > tr > td { display: block; width: 100%; }
    body .table-responsive.table-borders > .table > tbody > tr {
        border: 1px solid var(--cplv-line);
        border-radius: var(--cplv-radius);
        margin-bottom: 10px;
        padding: 6px 4px;
    }
    body .table-responsive.table-borders > .table > tbody > tr > td {
        border: 0;
        display: flex;
        justify-content: space-between;
        gap: 14px;
        padding: 10px 14px;
        text-align: right;
    }
    body .table-responsive.table-borders > .table > tbody > tr > td::before {
        content: attr(data-label);
        color: var(--cplv-muted);
        font-size: 14px;
        text-align: left;
    }
    /* Действие — во всю ширину карточки: это единственная цель для пальца. */
    body .table td.cplv-col-action { width: auto; text-align: center; }
    body .table td.cplv-col-action::before { content: none; }
    body .table td.cplv-col-action .btn { width: 100%; padding: 13px 18px; font-size: 15px; }
}

/* ============================================================================
   7. ЛЕВОЕ МЕНЮ ПО МАКЕТУ

   Тема подсвечивает текущий раздел ярко-синей плашкой — единственным синим
   пятном во всей панели: он спорит и с зелёной кнопкой действия, и с бейджами
   статусов. В макете текущий раздел показан спокойной тёмной плашкой и белой
   подписью, а остальные пункты приглушены.
   ============================================================================ */
body .sidebar,
body .sidebar-wrap,
body aside.sidebar {
    /* !important: тему сайдбара задаёт её собственный CSS с высокой
       специфичностью, и без этого в светлом режиме он остаётся тёмным. */
    background-color: var(--cplv-nav-bg) !important;
    border-right: 1px solid var(--cplv-nav-line);
    color: var(--cplv-nav-ink);
}
body .sidebar .sidebar-heading {
    color: var(--cplv-nav-muted);
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding-top: 18px;
}
body .sidebar .nav-link,
body .sidebar a {
    color: var(--cplv-nav-muted);
    border-radius: var(--cplv-radius-sm);
    margin: 2px 10px;
    padding: 10px 10px;
    font-size: 14px;
}
body .sidebar .nav-link .material-icons,
body .sidebar .nav-link .cplv-svg { color: inherit; }
body .sidebar .nav-link:hover {
    background-color: var(--cplv-nav-hover);
    color: var(--cplv-nav-ink);
}
body .sidebar .nav-link.active,
body .sidebar .nav-item.active > .nav-link {
    background-color: var(--cplv-nav-active) !important;
    color: var(--cplv-nav-ink) !important;
    font-weight: 600;
}
/* Подменю раздела «Услуги» — тем же приглушённым цветом, с отступом. */
body .sidebar .sub-nav .nav-link { padding-left: 42px; font-size: 14px; }

/* Строка списка услуг по макету: имя крупно, под ним — адрес приглушённым
   моноширинным. Дальше идут значения и действие. */
body .cplv-row-title { font-weight: 600; font-size: 15px; display: block; }
body .cplv-row-sub {
    display: block;
    margin-top: 4px;
    font-family: "IBM Plex Mono", ui-monospace, monospace;
    font-size: 13px;
    color: var(--cplv-muted);
}
body .table td.cplv-mono {
    font-family: "IBM Plex Mono", ui-monospace, monospace;
    font-size: 14px;
    color: var(--cplv-muted);
}

/* Точка состояния в строке услуги: цвет дублирует бейдж, но виден раньше —
   глаз находит проблемную строку до того, как прочитает слово. */
body .cplv-row-name { display: flex; align-items: center; gap: 10px; }
body .cplv-dot { width: 9px; height: 9px; flex: 0 0 9px; border-radius: 50%; background: var(--cplv-muted); }
body .cplv-dot--Active { background: var(--cplv-ok); }
body .cplv-dot--Pending { background: var(--cplv-warn); }
body .cplv-dot--Suspended { background: var(--cplv-danger); }
body .cplv-dot--Cancelled, body .cplv-dot--Terminated { background: var(--cplv-muted); }
/* Состояния счёта: у них свой набор значений, и без этих строк точка у счёта
   всегда была серой — «оплачен» и «просрочен» выглядели одинаково. */
body .cplv-dot--Paid, body .cplv-dot--Receiptpaid { background: var(--cplv-ok); }
body .cplv-dot--Unpaid, body .cplv-dot--Receiptunpaid { background: var(--cplv-warn); }
body .cplv-dot--Chargeback, body .cplv-dot--Refunded { background: var(--cplv-danger); }
body .cplv-dot--Open { background: var(--cplv-ok); }
body .cplv-dot--Answered, body .cplv-dot--Customer-Reply { background: var(--cplv-warn); }
body .cplv-dot--Closed { background: var(--cplv-muted); }
/* Остальные состояния обращения: без них точка у «ответа клиента» и «в работе»
   была серой — они выглядели закрытыми. */
body .cplv-dot--Client-Reply { background: var(--cplv-info); }
body .cplv-dot--In-Progress { background: var(--cplv-teal); }

/* ---- сайдбар целиком, а не только его корень ----
   Тема красит тёмным несколько вложенных блоков: шапку с логотипом и кнопкой
   «скрыть панель», обёртку списка и раскрывающееся подменю раздела «Услуги».
   Пока они не переведены на токены, светлая тема выглядит поломанной: верх
   меню тёмный, низ белый (наступали 30.08.2026). */
body .sidebar,
body .sidebar-wrap,
body .sidebar-header,
body .sidebar-brand,
body .sidebar .sub-nav,
body .sidebar .collapse,
body .sidebar .collapsing,
body .sidebar .nav,
body .sidebar .nav-item,
body .navbar-brand-wrapper {
    background-color: var(--cplv-nav-bg) !important;
    color: var(--cplv-nav-ink);
}
/* Раскрытое подменю раздела отличается не цветом фона, а отступом и приглушённым
   текстом: лишняя заливка внутри меню делит его на несвязанные куски. */
body .sidebar .sub-nav .nav-link {
    background-color: transparent !important;
    color: var(--cplv-nav-muted) !important;
}
body .sidebar .sub-nav .nav-link:hover,
body .sidebar .sub-nav .nav-link.active {
    background-color: var(--cplv-nav-active) !important;
    color: var(--cplv-nav-ink) !important;
}
/* Счётчик услуг в пункте меню — приглушённая плашка, а не цветной бейдж. */
body .sidebar .badge {
    background-color: var(--cplv-nav-active) !important;
    color: var(--cplv-nav-muted) !important;
    font-weight: 600;
}
/* Кнопка «скрыть панель» и логотип. */
body .sidebar-toggler,
body .navbar-toggler,
body .sidebar .navbar-toggler {
    background-color: transparent !important;
    color: var(--cplv-ink) !important;
    border-color: var(--cplv-line) !important;
}
body .sidebar-toggler .material-icons,
body .navbar-toggler .material-icons,
body .navbar-toggler-icon { color: var(--cplv-ink) !important; }

/* ---- выпадающие меню шапки ----
   Их содержимое (аватар, строки, разделители, подписи) тема тоже красит своими
   цветами, поэтому перечисляем внутренности, а не только контейнер. */
body .dropdown-menu .media,
body .dropdown-menu .media-body,
body .dropdown-menu .list-group-item,
body .dropdown-menu .dropdown-header,
body .dropdown-menu .notification-item {
    background-color: transparent !important;
    color: var(--cplv-ink) !important;
    border-color: var(--cplv-line) !important;
}
body .dropdown-menu .dropdown-divider { border-top-color: var(--cplv-line) !important; }
body .dropdown-menu .material-icons { color: var(--cplv-muted) !important; }
body .dropdown-menu .dropdown-item:hover .material-icons { color: var(--cplv-ink) !important; }

/* ---- левый верхний блок шапки ----
   Тема красит .navbar .navbar-left (полоса над сайдбаром с логотипом и кнопкой
   «скрыть панель») в свой серый #464851 — он не менялся вместе с темой и в
   светлом режиме выглядел серым пятном между белой шапкой и белым меню.
   Тот же цвет тема даёт .sidebar и мобильной .navbar-body — перекрываем все три.
   ⚠️ Правило нужно ПОСЛЕ секций про меню и шапку: селекторы темы короткие,
   но подключается её файл раньше нашего, поэтому берём !important. */
/* Только .navbar-left принадлежит меню (он над сайдбаром). Остальные полосы
   шапки — часть рабочей области и красятся в цвет полотна, иначе сверху
   тянется белый прямоугольник. */
body .navbar > .navbar-collapse,
body .navbar .navbar-body {
    background-color: var(--cplv-bg) !important;
    border-color: var(--cplv-line) !important;
}
body .navbar .navbar-left {
    background-color: var(--cplv-nav-bg) !important;
    border-color: var(--cplv-nav-line) !important;
    color: var(--cplv-nav-ink) !important;
}
body .navbar .navbar-left .material-icons { color: var(--cplv-nav-ink) !important; }
/* Полоса-перетяжка ширины сайдбара и затемнение под мобильным меню — тоже
   стоковый #464851; в светлой теме от них остаются серые артефакты. */
body .sidebar-resizer,
body .sidebar .resizer { background-color: var(--cplv-nav-line) !important; }
body .sidebar-overlay { background-color: var(--cplv-ink) !important; }

/* ---- разделители в шапке ----
   В стоковой теме кнопки шапки разделены тонкими вертикальными линиями: они
   показывают, где кончается одна кликабельная зона и начинается другая. Когда
   подложки кнопок стали прозрачными, линии пропали и ряд слипся в кашу.
   Возвращаем их — и нижнюю границу самой шапки. */
body .navbar { border-bottom: 1px solid var(--cplv-line) !important; }
body .navbar .navbar-nav > .nav-item,
body .navbar .navbar-nav > li.nav-item {
    border-left: 1px solid var(--cplv-line);
}
body .navbar .navbar-nav > .nav-item:first-child { border-left: 0; }
body .navbar .navbar-nav > .nav-item > .nav-link,
body .navbar .navbar-nav > .nav-item > a,
body .navbar .navbar-nav > .nav-item > span.nav-link {
    padding-left: 18px;
    padding-right: 18px;
    height: 100%;
    display: flex;
    align-items: center;
    gap: 8px;
}
/* Кнопка «Заказать» — отдельное действие, а не пункт ряда: разделитель ей не нужен. */
body .navbar .btn,
body .navbar .btn-group { border-left: 0; }

/* ---- марка cp.lv в шапке меню ----
   Логотипом в настройках темы стоит прозрачный пиксель, поэтому верх меню был
   пустым. Знак рисуется разметкой: зелёный квадрат с «cp» и подпись. */
body .navbar-brand.cplv-logo {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0;
    text-decoration: none;
}
body .cplv-logo__mark {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    border-radius: 8px;
    background: var(--cplv-accent);
    color: var(--cplv-on-accent);
    font-size: 13px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
body .cplv-logo__text {
    font-size: 15px;
    font-weight: 600;
    color: var(--cplv-nav-ink);
    letter-spacing: -.01em;
}

/* Кнопка «скрыть панель» остаётся и на десктопе (возвращена по просьбе
   владельца 31.08.2026): на широком экране ею освобождают место под таблицы
   и графики, а на узком без неё не открыть меню. */
body .btn-left-navbar.btn-toggler,
body .navbar-toggler {
    color: var(--cplv-nav-muted) !important;
    /* Рамку снимаем: это не самостоятельная кнопка, а служебный переключатель
       рядом с маркой — в рамке он спорит с логотипом за внимание. */
    border: 0 !important;
    box-shadow: none !important;
    background-color: transparent !important;
    border-radius: var(--cplv-radius-sm);
}
body .btn-left-navbar.btn-toggler:hover,
body .navbar-toggler:hover {
    background-color: var(--cplv-nav-hover) !important;
    color: var(--cplv-nav-ink) !important;
}

/* ---- контраст подписей в меню ----
   Тема приглушает пункты меню прозрачностью поверх цвета, поэтому подписи
   выглядели бледнее, чем в макете (замечание владельца 30.08.2026). Прозрачность
   снимаем и задаём цвет явно: неактивный пункт — приглушённый, текущий — полный
   контраст и полужирный. */
body .sidebar .nav-link,
body .sidebar .nav-link span,
body .sidebar .nav-link i,
body .sidebar a {
    color: var(--cplv-nav-muted) !important;
    opacity: 1 !important;
}
body .sidebar .nav-link.active,
body .sidebar .nav-link.active span,
body .sidebar .nav-link.active i,
body .sidebar .nav-item.active > .nav-link,
body .sidebar .nav-item.active > .nav-link span,
body .sidebar .nav-item.active > .nav-link i {
    color: var(--cplv-nav-ink) !important;
    font-weight: 600;
}
body .sidebar .nav-link:hover,
body .sidebar .nav-link:hover span,
body .sidebar .nav-link:hover i { color: var(--cplv-nav-ink) !important; }
/* Заголовки разделов меню («УПРАВЛЯТЬ», «АККАУНТ») — тоже без прозрачности. */
body .sidebar .sidebar-heading,
body .sidebar .sidebar-heading span {
    color: var(--cplv-nav-muted) !important;
    opacity: 1 !important;
}

/* ---- линия под шапкой идёт через весь экран ----
   В макете нижняя граница шапки не обрывается на сайдбаре: она проходит и под
   блоком с логотипом, отделяя верхнюю полосу целиком. У .navbar-left своя
   подложка (цвет меню), поэтому границу ему нужно задать отдельно. */
body .navbar .navbar-left {
    border-bottom: 1px solid var(--cplv-nav-line) !important;
    border-right: 1px solid var(--cplv-nav-line) !important;
}

/* ============================================================================
   ГЛАВНАЯ КЛИЕНТСКОЙ ЗОНЫ — макет 01
   ============================================================================
   Три вещи сверху вниз: сумма к оплате, работающий сервер, остальные услуги
   строками. Разметка — clientarea/dashboard.tpl. Здесь только вид; цвета
   берутся из токенов, поэтому обе темы получаются из одного набора правил. */

.cplv-dash > .cplv-box + .cplv-box { margin-top: 22px; }

/* ---- «Всего к оплате» ----
   Сумма — единственное крупное число на экране, поэтому она набрана 34-м
   кеглем и табличными цифрами: в такой строке глаз читает порядок величины,
   не разбирая цифры по одной. Кнопка одна: платят всё сразу. */
.cplv-due { display: flex; align-items: center; gap: 24px; padding: 22px 24px; }
.cplv-due__text { flex: 1 1 auto; min-width: 0; }
.cplv-due__label { font-size: 14px; color: var(--cplv-muted); }
.cplv-due__amount {
    margin-top: 2px;
    font-size: 34px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.025em;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}
.cplv-due__note { margin-top: 6px; font-size: 14px; color: var(--cplv-muted); }
/* Подпись у кнопки не переносится по буквам, но длинную латышскую строку
   разрешено перенести целыми словами — фиксированной ширины у кнопки нет. */
.cplv-due__cta { flex: 0 0 auto; white-space: normal; }

/* ---- блок сервера ---- */
.cplv-server { padding: 22px 24px; }
.cplv-server__head { display: flex; align-items: center; gap: 16px; }
.cplv-server .cplv-dot { width: 10px; height: 10px; flex: 0 0 10px; }
.cplv-server__id { flex: 1 1 auto; min-width: 0; }
.cplv-server__name { font-size: 20px; font-weight: 600; color: var(--cplv-ink); word-break: break-word; }
.cplv-server__sub {
    margin-top: 4px;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    color: var(--cplv-muted);
    word-break: break-word;
}
.cplv-server__actions { display: flex; flex: 0 0 auto; gap: 10px; flex-wrap: wrap; }

/* ---- полосы занятости ----
   Полоса появляется только там, где есть знаменатель (выделенный объём диска
   или памяти). У счётчика трафика лимита нет — там остаётся одно число, и
   рисовать под ним пустую шкалу было бы враньём. */
.cplv-server__stats {
    display: grid;
    /* Показателей бывает три или четыре (у сервера добавляется трафик) —
       колонки раскладываются по месту, а не пересчитываются под каждый случай. */
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
    margin-top: 18px;
}
.cplv-stat { display: flex; flex-direction: column; gap: 8px; }
.cplv-stat__row { display: flex; justify-content: space-between; gap: 10px; font-size: 14px; }
.cplv-stat__label { color: var(--cplv-muted); }
.cplv-stat__value { color: var(--cplv-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cplv-bar { height: 6px; border-radius: 3px; background: var(--cplv-surface-2); overflow: hidden; }
.cplv-bar__fill { height: 6px; border-radius: 3px; background: var(--cplv-accent); }

/* ---- заголовок раздела и строка «заголовок + ссылка» ---- */
.cplv-h-section { margin: 22px 0 14px; font-size: 18px; font-weight: 600; color: var(--cplv-ink); }
/* Заголовок с действием справа — такой же блок: 22 сверху, 14 до содержимого.
   ⚠️ margin-top у вложенного .cplv-h-section наружу не выходит: строка — flex. */
.cplv-h-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 22px 0 14px; }
.cplv-h-row .cplv-h-section { margin-bottom: 0; }
.cplv-more { margin-top: 16px; display: flex; gap: 10px; flex-wrap: wrap; }

/* Числовые колонки списка: даты и суммы выстраиваются в столбик и сравниваются
   взглядом, без чтения. */
body .table td.cplv-num {
    font-variant-numeric: tabular-nums;
    color: var(--cplv-muted);
    white-space: nowrap;
}
/* Счётчик рядом с названием свёрнутой строки («Домены 7»). */
body .cplv-row-count {
    display: inline-block;
    margin-left: 6px;
    padding: 0 7px;
    border-radius: 9px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    vertical-align: 1px;
}

/* ---- телефон ----
   Сумма и кнопка встают друг под другом, кнопка — во всю ширину (правило
   макета: цель нажатия не уже экрана). Полосы занятости — в одну колонку. */
@media (max-width: 767px) {
    .cplv-due { flex-direction: column; align-items: stretch; gap: 18px; }
    .cplv-due__cta { width: 100%; text-align: center; }
    .cplv-server__head { flex-wrap: wrap; }
    .cplv-server__actions { width: 100%; }
    .cplv-server__actions > .btn { flex: 1 1 auto; text-align: center; }
    .cplv-server__stats { grid-template-columns: 1fr; gap: 14px; margin-top: 16px; }
}

/* ============================================================================
   СТРАНИЦА СЕРВЕРА (VPS/облако) — макет 13
   ============================================================================
   Разметку дают наши переопределения overrides/cloud_header.tpl и
   overrides/cloud_server_details.tpl (подставляются вместо стоковых шаблонов
   через $custom_overrides — см. plugins/smarty_variables.json).

   ⚠️ Тема рисует эту страницу в раскладке «меню слева» (.service-layout-left):
   .cloud-nav у неё уходит в левую колонку. Макет требует вкладок сверху,
   поэтому раскладка переопределяется здесь, а не переключением продукта на
   layout=top: в режиме top скрипт темы сливает пункты меню с кнопками действий
   в один ряд, и разделить навигацию и действия уже нельзя. */

/* ---- строка опознания: состояние, имя, факты, действия ---- */
body .section-main .cloud .cloud-top { display: block; float: none; width: auto; margin: 0 0 22px; }
body .section-main .cloud #content-cloud { float: none; width: auto; margin: 0; padding: 0; }
body .section-main .cloud { display: block; }

.cplv-srv-head {
    display: flex;
    align-items: center;
    /* Строка опознания — ряд элементов: промежуток по правилу 5. */
    gap: 10px;
    flex-wrap: wrap;
    float: none !important;
    width: auto !important;
    /* До следующего блока — общий шаг 22. */
    margin-bottom: 22px;
}
/* Цвет точки состояния перебивает базовое правило .cplv-dot, у которого в
   селекторе есть body, — без body здесь точка осталась бы серой. */
body .cplv-srv-dot { width: 10px; height: 10px; flex: 0 0 10px; }
body .cplv-srv-dot--running { background: var(--cplv-ok); }
body .cplv-srv-dot--stopped, body .cplv-srv-dot--paused { background: var(--cplv-muted); }
body .cplv-srv-dot--error { background: var(--cplv-danger); }
.cplv-srv-id { flex: 1 1 auto; min-width: 0; }
/* h1 темы несёт свои отступы, размер и фоновую картинку логотипа ОС — гасим:
   знак операционной системы дублирует строку фактов, где написано её имя. */
/* ⚠️ Длинный селектор: тема красит заголовки внутри раздела своим тёмно-серым
   (#464851), и на тёмной теме имя услуги читалось хуже подписи под ним. */
body .cloud .cloud-top h1.cplv-srv-name,
body h1.cplv-srv-name {
    float: none;
    margin: 0;
    padding: 0;
    background: none;
    font-size: 22px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cplv-ink);
}
.cplv-srv-facts {
    margin-top: 4px;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    color: var(--cplv-muted);
}
.cplv-srv-facts > span + span::before { content: " · "; }
.cplv-srv-back { font-size: 14px; color: var(--cplv-muted); }

/* ---- блок «Действия» ----
   Карточка на действие: значок, название, строка объяснения. Тон значка
   говорит о последствиях раньше, чем прочитана подпись: зелёный — доступ к
   серверу, жёлтый — прервёт работу, красный — данные пропадут.

   ⚠️ Длинные селекторы намеренно: тема и стили модуля адресуют этот список
   как `.cloud #lockable-vm-menu #vm-menu li a` (два id), и правило короче
   до него не доходит. */
body .cloud #lockable-vm-menu { float: none; margin: 0; }
.cplv-actions {
    margin-bottom: 22px;
    padding: 20px 24px 24px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
.cplv-actions__label {
    margin-bottom: 14px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}
body .cloud #lockable-vm-menu ul#vm-menu.cplv-actions__grid {
    display: grid;
    /* Та же сетка, что у разделов сервера и у блока домена: разделы и действия
       стоят одним блоком, и колонки в нём обязаны совпадать. */
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 10px;
    margin: 0;
    padding: 0;
    float: none;
    position: static;
    width: 100%;
    /* ⚠️ Тема держит этот список в половину ширины и высотой 48 px
       (`max-width:50%`, `max-height:48px`) — под ряд кнопок. Сетке карточек
       оба ограничения надо снять, иначе она вылезает поверх соседних блоков. */
    max-width: none;
    max-height: none;
    list-style: none;
    visibility: visible;
}
body .cloud #lockable-vm-menu #vm-menu.cplv-actions__grid > li {
    display: block;
    float: none;
    margin: 0;
    padding: 0;
    list-style: none;
    background: transparent;
    border: 0;
}
body .cloud #lockable-vm-menu #vm-menu.cplv-actions__grid > li > a.cplv-action {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    height: auto;
    margin: 0;
    padding: 10px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: 10px;
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    text-align: left;
    text-decoration: none;
    text-shadow: none;
    box-shadow: none;
    white-space: normal;
    transition: border-color .15s ease, background-color .15s ease;
}
body .cloud #lockable-vm-menu #vm-menu.cplv-actions__grid > li > a.cplv-action:hover {
    border-color: var(--cplv-line-strong);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    text-decoration: none;
}
/* Стоковые png-значки модуля не выводим — у каждого действия свой знак. */
body .cloud #lockable-vm-menu #vm-menu .vpsdo-icon,
body .cloud #lockable-vm-menu #vm-menu img { display: none; }

.cplv-action__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 38px;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-action__icon svg { width: 20px; height: 20px; }
/* Подложка значка — тот же цвет, что и знак, но едва заметный: цветную
   плашку под цветным знаком глаз читает как «эта кнопка про другое». */
.cplv-action__icon--accent { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
.cplv-action__icon--warn { background: rgba(138, 106, 21, .12); color: var(--cplv-warn); }
.cplv-action__icon--danger { background: rgba(179, 66, 58, .12); color: var(--cplv-danger); }
:root:not([data-theme="light"]) .cplv-action__icon--accent { background: rgba(156, 205, 126, .14); }
:root:not([data-theme="light"]) .cplv-action__icon--warn { background: rgba(201, 162, 39, .14); }
:root:not([data-theme="light"]) .cplv-action__icon--danger { background: rgba(224, 115, 107, .14); }
:root[data-theme="dark"] .cplv-action__icon--accent { background: rgba(156, 205, 126, .14); }
:root[data-theme="dark"] .cplv-action__icon--warn { background: rgba(201, 162, 39, .14); }
:root[data-theme="dark"] .cplv-action__icon--danger { background: rgba(224, 115, 107, .14); }

/* ---- остальные тона знака: те же, что у плиток меню «Разместить заказ» ----
   Знаки разделов были серыми, и блок читался одним пятном (замечание
   владельца 02.09.2026). Палитра взята из плиток заказа, чтобы разделы и
   каталог услуг говорили одним языком цвета. */
.cplv-action__icon--info   { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
.cplv-action__icon--violet { background: rgba(107, 79, 160, .12); color: var(--cplv-violet); }
.cplv-action__icon--teal   { background: rgba(46, 125, 120, .12); color: var(--cplv-teal); }
.cplv-action__icon--rose   { background: rgba(160, 74, 111, .12); color: var(--cplv-rose); }
:root:not([data-theme="light"]) .cplv-action__icon--info   { background: rgba(127, 182, 224, .14); }
:root:not([data-theme="light"]) .cplv-action__icon--violet { background: rgba(179, 154, 224, .14); }
:root:not([data-theme="light"]) .cplv-action__icon--teal   { background: rgba(127, 208, 201, .14); }
:root:not([data-theme="light"]) .cplv-action__icon--rose   { background: rgba(227, 154, 184, .14); }
:root[data-theme="dark"] .cplv-action__icon--info   { background: rgba(127, 182, 224, .14); }
:root[data-theme="dark"] .cplv-action__icon--violet { background: rgba(179, 154, 224, .14); }
:root[data-theme="dark"] .cplv-action__icon--teal   { background: rgba(127, 208, 201, .14); }
:root[data-theme="dark"] .cplv-action__icon--rose   { background: rgba(227, 154, 184, .14); }

.cplv-action__text { display: block; min-width: 0; }
body .cplv-action__title {
    display: block;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cplv-ink);
}
.cplv-action__desc {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: var(--cplv-muted);
}

/* ---- «сервер выполняет задачу» ----
   Показывается, пока идёт перезагрузка, переустановка или снапшот. Плашку
   рисует наш overrides/cloud_server_actions.tpl, а показывает и прячет сам
   модуль — классом active на #lock. */
body .cloud #lockable-vm-menu #lock.cplv-task {
    display: none;
    /* ⚠️ Стиль модуля кладёт плашку абсолютом — она уезжала вправо и ложилась
       поверх ряда вкладок. Возвращаем в поток над блоком действий. */
    position: static;
    width: auto;
    /* ⚠️ И ЗАДАЁТ ЕЙ ВЫСОТУ 40 px ЖЁСТКО, через !important. С нашими отступами
       14 px и кнопками 34 px содержимому нужно 66 — подпись, кольцо и кнопки
       вылезали ИЗ плашки вниз, и она выглядела съехавшей (замечание владельца
       05.09.2026). Высоту должно считать содержимое; перебить чужой !important
       можно только своим. */
    height: auto !important;
    min-height: 0;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    padding: 14px 18px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-ink);
    font-size: 14px;
}
body .cloud #lockable-vm-menu #lock.cplv-task.active { display: flex; }
/* Спиннер и подпись идут слева друг за другом, кнопки прижаты к правому краю:
   иначе между значком и текстом зияла пустая полоса во всю плашку. */
body .cloud #lockable-vm-menu #lock.cplv-task { justify-content: flex-start; }
.cplv-task__text { min-width: 0; }
.cplv-task__actions { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
/* Кнопки внутри плашки модуль красит своими правилами — задаём вид сами.
   ⚠️ Тон по последствию, как у карточек действий: зелёная «Обновить» —
   безопасное «посмотреть ещё раз», янтарная «Отменить» — прервать начатое.
   Белыми они сливались со светлой плашкой (замечание владельца 05.09.2026). */
body .cloud #lockable-vm-menu #lock.cplv-task .btn {
    height: 34px;
    padding: 0 14px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    font-size: 13px;
    font-weight: 600;
    text-shadow: none;
    box-shadow: none;
}
body .cloud #lockable-vm-menu #lock.cplv-task .btn > .material-icons {
    font-size: 17px;
    line-height: 1;
    margin: 0 !important;
}
/* «Обновить» — заливкой: это то действие, которого от человека ждут, пока он
   смотрит на плашку. */
body .cloud #lockable-vm-menu #lock.cplv-task .cplv-task__btn--go {
    background: var(--cplv-accent);
    border-color: var(--cplv-accent);
    color: var(--cplv-on-accent);
}
body .cloud #lockable-vm-menu #lock.cplv-task .cplv-task__btn--go:hover {
    background: var(--cplv-accent-hover);
    border-color: var(--cplv-accent-hover);
    color: var(--cplv-on-accent);
}
/* «Отменить» — контуром в янтаре: действие обратимое по смыслу, но прерывает
   начатое, поэтому не заливка и не красный (красный у нас про потерю данных). */
body .cloud #lockable-vm-menu #lock.cplv-task .cplv-task__btn--stop {
    /* ⚠️ Прозрачный фон, а не --cplv-surface: кнопка стоит НА плашке, и её
       собственная подложка спорила бы с плашкой в тёмной теме (белое пятно). */
    background: transparent;
    /* ⚠️ Янтарь ЧИСЛОМ и ОДИН на обе темы, а не токеном --cplv-warn.
       Модуль помечает отмену своим классом btn-danger, и на элементе с ним
       наши тематические правила не срабатывали: цвет оставался дневным даже
       в тёмной теме, а откуда берётся подмена — в закрытом css модуля не
       видно. #a8801c выбран так, чтобы читаться на ОБЕИХ плашках:
       на светлой #eef0f4 контраст 4,1:1, на тёмной #1e242c — 4,3:1. */
    border-color: #a8801c !important;
    color: #a8801c !important;
}

body .cloud #lockable-vm-menu #lock.cplv-task .cplv-task__btn--stop:hover {
    background: #a8801c;
    border-color: #a8801c !important;
    color: #fff !important;
}

body .cloud #lockable-vm-menu #lock.cplv-task img { display: none; }
/* Кольцо крутится трансформацией, поэтому останавливается там, где человек
   попросил систему не анимировать (см. правило ниже). */
.cplv-task__spinner {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    border: 2px solid var(--cplv-line-strong);
    border-top-color: var(--cplv-accent);
    border-radius: 50%;
    animation: cplv-spin .8s linear infinite;
}
@keyframes cplv-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .cplv-task__spinner { animation: none; border-top-color: var(--cplv-accent); }
}
/* Пока задача идёт, действия недоступны: нажимать их бессмысленно, а модуль
   всё равно откажет. Гасим их вместо того, чтобы делать вид, что всё готово. */
body .cloud #lockable-vm-menu #lock.cplv-task.active ~ .cplv-actions {
    opacity: .45;
    pointer-events: none;
}

/* ---- разделы сервера: полоса таблеток ----
   Решение владельца 04.09.2026 (макет «Экран машины: три раскладки», вариант 2):
   на экране машины первым идёт блок ДЕЙСТВИЙ, под ним — разделы одной строкой.
   У разделов короткие имена и свой знак, объяснение ушло в подсказку: это
   навигация, а не выбор действия, и трёх рядов карточек она не стоит.

   ⚠️ Порядок «действия → разделы» собирает cplv-panel.js (initCloudOrder):
   модуль рисует действия ниже, в #content-cloud, и переставить их разметкой
   нельзя. Двигать узел безопасно — модуль обновляет его через innerHTML по id.

   ⚠️ Селекторы длинные намеренно: свой styles.css модуль подключает уже в теле
   страницы, то есть ПОЗЖЕ нашего, и адресует это меню цепочкой
   `.cloud .cloud-top .cloud-nav .level-1 .menu-item a`. При равной
   специфичности выигрывает он — короткое правило просто не доходит. */
body .section-main .cloud .cloud-top .cloud-nav.cplv-srv-tabs {
    float: none;
    width: auto;
    max-width: none;
    margin: 0 0 22px;
    padding: 0;
    background: none;
    border: 0;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    float: none;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    list-style: none;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item {
    display: block;
    position: relative;
    float: none;
    margin: 0;
    padding: 0 !important;
    border: 0;
    background: none;
    list-style: none;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 40px;
    padding: 0 16px;
    border: 1px solid transparent;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    text-align: left;
    text-decoration: none;
    text-shadow: none;
    box-shadow: none;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill:hover {
    color: var(--cplv-ink);
    text-decoration: none;
}
/* Открытый раздел — заливка цветом текста: та же отметка, что у вкладок
   в остальной панели. */
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill--on,
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill--on:hover {
    background: var(--cplv-ink);
    color: var(--cplv-bg);
    font-weight: 600;
}
/* Выход к списку машин — светлая таблетка с рамкой: она о другом, чем соседние
   (те про саму машину), и это видно раньше, чем прочитана подпись. */
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill--home {
    background: var(--cplv-surface);
    border-color: var(--cplv-line);
    color: var(--cplv-ink);
    font-weight: 600;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item > a.cplv-srv-pill--home:hover {
    border-color: var(--cplv-line-strong);
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item .cplv-srv-pill__ic {
    display: inline-flex;
    flex: 0 0 16px;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    margin: 0;
    padding: 0;
    background: none;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item .cplv-srv-pill__ic svg {
    width: 16px;
    height: 16px;
}
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item .cplv-srv-pill__t {
    background: none;
    padding: 0;
    margin: 0;
}
/* Стоковые png-значки модуля не выводим — у каждого раздела свой знак. */
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item img,
body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item .vpsdo-icon { display: none; }

/* ⚠️ Модуль держит у .cloud-top отступ справа в 30 px — шапка сервера, строка
   денег и разделы были на 30 px уже всего остального на странице, и правые
   края блоков разъезжались. Отступ снимаем. */
body .section-main .cloud .cloud-top { padding-right: 0; }

/* Разделы стоят НАД блоком действий (решение владельца 04.09.2026): именно в
   этом порядке страницу и рисуют шаблон с модулем, переставлять нечего. */

/* ---- содержимое: заголовок раздела и обёртки модуля ----
   Заголовок («Подробности сервера», «Использование CPU») ничего не сообщает:
   раздел уже назван активной вкладкой. Прячем только его, а саму полосу
   оставляем — на «Использовании» в ней лежит выбор периода, и вместе с
   заголовком он пропадал. Пустая полоса схлопывается в ноль. */
/* ⚠️ .cloud в селекторе добавлен ради специфичности: у модуля ровно такое же
   правило `#content-cloud .header-bar h3`, и подключается его файл ПОЗЖЕ
   нашего (из тела страницы), поэтому при равном весе выигрывал он. */
body .cloud #content-cloud .header-bar {
    height: auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    line-height: normal;
}
body .cloud #content-cloud .header-bar h3 { display: none; }
body .cloud #content-cloud .header-bar::after { content: none; }
body .cloud #content-cloud .header-bar form { margin-bottom: 18px; }
body #content-cloud > .content-bar,
body #content-cloud .content-bar {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
}
.cplv-srv-stats,
.cplv-srv-fields,
.cplv-svc-fields,
.cplv-srv-billing,
.cplv-srv-tags { padding: 22px 24px; margin-bottom: 22px; }

/* ---- поля доступа ---- */
.cplv-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 18px;
}
.cplv-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.cplv-field__label { font-size: 14px; color: var(--cplv-muted); }
.cplv-field__value {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    min-height: 46px;
    padding: 10px 16px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    font-size: 15px;
    word-break: break-word;
}
.cplv-field__value.cplv-mono { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace; }
.cplv-field__link { font-size: 13px; color: var(--cplv-accent); white-space: nowrap; }
.cplv-field__empty { color: var(--cplv-muted); font-style: normal; font-size: 14px; }
/* Поле пароля модуля: поле и три кнопки в один ряд, без рамки внутри рамки. */
/* ⚠️ nowrap обязателен: тема разрешает перенос, и в узкой колонке ряд ломался —
   поле вставало отдельной строкой, а три знака под ним. Без переноса поле
   сжимается (flex: 1 1 auto; min-width: 0) и всё умещается в одну строку. */
.cplv-field .pw-input-group { display: flex; align-items: center; flex-wrap: nowrap; gap: 10px; width: 100%; }
.cplv-field .pw-input-group > input.form-control {
    flex: 1 1 auto;
    min-width: 0;
    height: auto;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 15px;
    color: var(--cplv-ink);
}
/* Три знака подряд: 4 px между ними — промах мимо нужного, шаг ряда 8 (правило 6). */
.cplv-field .pw-input-group-append { display: flex; gap: 8px; }
.cplv-field .pw-input-group-append .btn {
    /* Ростом со своей строкой: рядом поле 46 и обычные кнопки 42. */
    height: 42px;
    min-height: 42px;
    padding: 0 10px;
    border: 1px solid var(--cplv-line);
    border-radius: 6px;
    background: var(--cplv-surface);
    color: var(--cplv-muted);
}
.cplv-field .pw-input-group-append .btn:hover { color: var(--cplv-ink); border-color: var(--cplv-line-strong); }
.cplv-field .form-inline { display: flex; gap: 8px; width: 100%; }
.cplv-field .form-inline > .form-control { flex: 1 1 auto; min-width: 0; }
.cplv-note { margin: 16px 0 0; font-size: 13px; color: var(--cplv-muted); }

/* ---- деньги ---- */
.cplv-srv-billing { display: flex; align-items: center; gap: 18px; }
.cplv-srv-billing__text { flex: 1 1 auto; min-width: 0; }
.cplv-srv-billing__title { font-size: 15px; font-weight: 600; line-height: 1.35; color: var(--cplv-ink); }
.cplv-srv-billing__sub { margin-top: 6px; font-size: 14px; line-height: 1.35; color: var(--cplv-muted); font-variant-numeric: tabular-nums; }

/* ---- метки ---- */
.cplv-srv-tags__list { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.cplv-srv-tags .vm-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--cplv-surface-2);
    color: var(--cplv-ink);
    font-size: 13px;
}
/* stretch, а не center: кнопка добирает высоту поля (46px) и ряд выходит ровным —
   в панели поле и кнопка рядом всегда одной высоты. */
.cplv-srv-tags__form { display: flex; align-items: stretch; gap: 8px; margin-top: 10px; max-width: 420px; }

@media (max-width: 767px) {
    .cplv-srv-head { align-items: flex-start; }
    /* Действия на телефоне — в одну колонку, целиком видимые. */
    body .cloud #lockable-vm-menu ul#vm-menu.cplv-actions__grid { grid-template-columns: 1fr; }
    .cplv-actions { padding: 16px 18px 18px; }
    .cplv-srv-billing { flex-direction: column; align-items: stretch; }
    .cplv-srv-billing .btn { width: 100%; text-align: center; }
    /* Разделов у сервера дюжина: на телефоне они ехали в четыре ряда и съедали
       экран. Прокручиваем ряд вбок — как в приложениях. */
    body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 4px;
        -webkit-overflow-scrolling: touch;
    }
    body .cloud .cloud-top .cloud-nav.cplv-srv-tabs .level-1 .menu-item { flex: 0 0 auto; }
    /* Строка опознания: имя, факты, потом действия во всю ширину. */
    .cplv-srv-head { gap: 10px; }
    .cplv-srv-id { flex: 1 1 100%; }
}

/* ============================================================================
   СПИСКИ: колонка выбора, действия в строке, ряд массовых действий
   ============================================================================ */

/* Флажок выбора занимает ровно свою ширину: в стоке колонка расползалась. */
body .table td.cplv-col-check,
body .table th.cplv-col-check { width: 34px; padding-right: 0; }

/* Действие и меню «⋮» в одной строке: слово читается, точки остаются рядом
   для редких операций (метка, запрос на отмену). */
body .cplv-row-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
body .cplv-row-more { border: 0; background: none; line-height: 1; color: var(--cplv-muted); }
body .cplv-row-more:hover { color: var(--cplv-ink); }

/* ---- ряд массовых действий под списком ----
   Пока ничего не выбрано, кнопки выключены и ряд читается подписью: понятно,
   что он появится в деле, а не сломан. */
.cplv-bulk {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    padding: 14px 18px;
    border: 1px solid var(--cplv-accent);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
/* ⚠️ Своё правило для hidden: у элемента задан display:flex, а он сильнее
   встроенного `[hidden]{display:none}` браузера. Без этой строки ряд был бы
   виден всегда. Показывает его initBulkBar по отметкам в списке. */
.cplv-bulk[hidden] { display: none; }
.cplv-bulk__text { flex: 1 1 auto; min-width: 0; }
.cplv-bulk__label { display: block; font-size: 15px; font-weight: 600; color: var(--cplv-ink); }

/* Кнопка массового действия: знак сверху, подпись под ним. Одни знаки без
   подписей приходилось разгадывать наведением (замечание владельца
   02.09.2026). */
.cplv-bulk__btn {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 96px;
    height: auto;
    padding: 10px 10px;
    line-height: 1.2;
}
.cplv-bulk__btn .material-icons { font-size: 20px; }
.cplv-bulk__btn-t { font-size: 12px; font-weight: 600; white-space: nowrap; }
.cplv-bulk .selected-names { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.cplv-bulk__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cplv-bulk__actions .btn.disabled { opacity: .45; pointer-events: none; }

/* ---- пустое состояние в строке таблицы ----
   Не «Нечего отобразить», а объяснение и следующий шаг. */
body .table td.cplv-empty {
    padding: 32px 24px;
    text-align: center;
    border: 0;
}
body .cplv-empty__title { display: block; font-size: 17px; font-weight: 600; color: var(--cplv-ink); }
body .cplv-empty__text {
    display: block;
    max-width: 520px;
    margin: 8px auto 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--cplv-muted);
}

/* ============================================================================
   ФОРМЫ — макеты 17, 03, 18
   ============================================================================
   Один вид поля на всю панель: подпись сверху приглушённая, само поле в рамке
   на цвет полотна, подсказка под полем. Разметку дают наши шаблоны
   (support/addticket.tpl и другие) классами .cplv-form / .cplv-field. */

.cplv-lead { max-width: 640px; margin: 0 0 20px; font-size: 15px; line-height: 1.6; color: var(--cplv-muted); }

/* ⚠️ Блок формы занимает всю колонку — иначе на фоне вкладок во всю ширину он
   выглядит обрезанным (замечание владельца 31.08.2026). А вот сами поля
   остаются читаемой колонкой: поле ввода пароля шириной в экран — это не
   «шире», это неудобно. В макете «17 · Новое обращение» ровно так и есть:
   блок во всю ширину, содержимое — колонка 620 px. */
.cplv-form { padding: 22px 24px; max-width: none; }
.cplv-form > .cplv-field,
.cplv-form > .cplv-lead,
.cplv-form > .cplv-more,
.cplv-form > .fileupload,
.cplv-form > .cplv-form__actions { max-width: 620px; }
/* Формы, у которых поля идут сеткой, ограничивать нечем — там колонки сами. */
.cplv-editfields > .cplv-fields,
.cplv-editfields > .cplv-form__actions,
.cplv-settings .cplv-form > .cplv-field,
.cplv-settings .cplv-form > .cplv-form__actions { max-width: none; }
/* Отступ между полями — только у полей, лежащих в форме подряд. Внутри
   сетки .cplv-fields расстояние задаёт сама сетка (gap), и лишний margin
   сдвигал бы поля одной строки друг относительно друга. */
.cplv-form > .cplv-field + .cplv-field,
.cplv-form > .cplv-field + .fileupload,
.cplv-form > .cplv-field + .cplv-more { margin-top: 18px; }
.cplv-form__actions { margin-top: 24px; }
.cplv-form__actions .btn { min-width: 180px; }

/* Поле формы: то же, что и «поле доступа» на странице сервера, но с вводом. */
/* ⚠️ Правила поля действуют и вне обёртки .cplv-form: подпись с полем часто
   стоят просто в .cplv-field (страница домена, машина, образец элементов), и
   при узкой привязке поле оставалось стоковым — 41 px вместо 46, а подпись
   отбивалась бутстраповским margin-bottom .5rem поверх gap 7. */
.cplv-form .cplv-field__label,
.cplv-field > .cplv-field__label { margin-bottom: 0; font-size: 14px; font-weight: 400; color: var(--cplv-muted); }
.cplv-form .cplv-field__hint,
.cplv-field > .cplv-field__hint { display: block; margin-top: 6px; font-size: 13px; color: var(--cplv-muted); }
body .cplv-form .form-control,
body .cplv-form select.form-control,
body .cplv-form textarea.form-control,
body .cplv-field > .form-control,
body .cplv-field > select.form-control,
body .cplv-field > textarea.form-control {
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    font-size: 15px;
}
body .cplv-form .form-control:focus,
body .cplv-field > .form-control:focus { border-color: var(--cplv-accent); box-shadow: var(--cplv-glow); }
body .cplv-form input.form-control,
body .cplv-form select.form-control,
body .cplv-field > input.form-control,
body .cplv-field > select.form-control { height: 46px; padding: 0 14px; }
body .cplv-form textarea.form-control,
body .cplv-field > textarea.form-control { padding: 10px 14px; min-height: 160px; }

/* «Дополнительно» — родной <details>, поэтому раскрывается и без JS. */
.cplv-more { margin-top: 22px; border-top: 1px solid var(--cplv-line); padding-top: 16px; }
.cplv-more > summary {
    cursor: pointer;
    list-style: none;
    font-size: 14px;
    font-weight: 600;
    color: var(--cplv-ink);
}
.cplv-more > summary::-webkit-details-marker { display: none; }
.cplv-more > summary::before { content: "+ "; color: var(--cplv-muted); }
.cplv-more[open] > summary::before { content: "– "; }
.cplv-more__body { margin-top: 16px; }
.cplv-more__body .cplv-field + .cplv-field { margin-top: 18px; }

/* Загрузка файла: стоковая зона перекрашена под панель, без своей палитры. */
body .cplv-form .fileupload .fileinput-button {
    border: 1px dashed var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
}
body .cplv-form .fileupload .fileinput-button:hover { border-color: var(--cplv-line-strong); }
body .cplv-form .fileupload label { color: var(--cplv-muted); margin-bottom: 0; }

/* ---- каталог услуг /studio/products/ (макет 16) ----
   Цена перестаёт быть синей: в панели один цвет действия — зелёный, а синий
   у темы означал ссылку. Цена не ссылка, её читают, а нажимают «Выбрать». */
body .section-product-card-price { color: var(--cplv-muted); font-size: 15px; }
body .section-product-card-price b,
body .section-product-card-price b.text-primary {
    color: var(--cplv-ink) !important;
    font-variant-numeric: tabular-nums;
}

/* ============================================================================
   АККАУНТ: обзор, безопасность, контакты — макеты 07, 08, 09
   ============================================================================ */

/* Незаполненное поле подписано словами и приглушено: пустая рамка читается
   как «не догрузилось», а слово — как «здесь ничего нет». */
.cplv-field__value--empty { color: var(--cplv-muted); }

/* Пустое состояние вне таблицы (SSH-ключи и т.п.). */
.cplv-empty-box { padding: 32px 24px; text-align: center; }

/* ---- текущий IP и «разрешить только его» ---- */
.cplv-myip { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; padding: 20px 24px; }
.cplv-myip__text { flex: 1 1 auto; min-width: 0; }
.cplv-myip__addr {
    margin-top: 4px;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 20px;
    font-weight: 500;
    color: var(--cplv-ink);
}
.cplv-myip__note { margin-top: 6px; font-size: 14px; color: var(--cplv-muted); }
.cplv-myip__form { flex: 0 0 auto; margin: 0; }

/* Поле правила и кнопка — в одну строку, на телефоне друг под другом. */
.cplv-iprule__row { display: flex; gap: 10px; }
.cplv-iprule__row .form-control { flex: 1 1 auto; min-width: 0; }
.cplv-iprule__row .btn { flex: 0 0 auto; }
@media (max-width: 575px) {
    .cplv-iprule__row { flex-direction: column; }
    .cplv-iprule__row .btn { width: 100%; }
    .cplv-myip__form,
    .cplv-myip__form .btn { width: 100%; }
}

/* ---- партнёрский центр (макет 10) ----
   Три числа вместо таблицы: сколько заработано, что на балансе, сколько
   приведено. Ссылка — полем с кнопкой «скопировать», а не строкой таблицы,
   которую надо выделять мышью. */
.cplv-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 18px;
    margin-bottom: 22px;
}
.cplv-stat-card { padding: 20px 24px; }
.cplv-stat-card__label { font-size: 14px; color: var(--cplv-muted); }
.cplv-stat-card__value {
    margin-top: 4px;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}
.cplv-stat-card__note { margin-top: 6px; font-size: 13px; color: var(--cplv-muted); }
.cplv-reflink { padding: 20px 24px; }
.cplv-reflink__row { display: flex; gap: 10px; margin-top: 8px; }
body .cplv-reflink__row .form-control {
    flex: 1 1 auto;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
}
.cplv-reflink__row .btn { flex: 0 0 auto; }
@media (max-width: 575px) {
    .cplv-reflink__row { flex-direction: column; }
    .cplv-reflink__row .btn { width: 100%; }
}

/* ---- форма данных аккаунта (макет 18) ----
   Поля идут сеткой в две-три колонки, у каждого подпись сверху. Значение,
   которое HostBill выводит текстом (поле закрыто для правки), выравнивается
   по той же высоте, что и поле ввода, — ряд не «скачет». */
.cplv-editfields .cplv-fields { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.cplv-editfields .cplv-field__control { display: flex; flex-direction: column; justify-content: center; min-height: 46px; }
.cplv-field__req { color: var(--cplv-danger); margin-left: 2px; }
.cplv-editfields .cplv-form__actions { margin-top: 24px; }

/* ============================================================================
   ТЕЛЕФОН: нижняя навигация и шапка — очередь 4 макетов
   ============================================================================
   Панель открывают с телефона чаще, чем с ноутбука, поэтому мобильный экран —
   свой макет, а не сжатый десктоп. Разметка панели — в custom/auth.tpl. */

.cplv-tabbar { display: none; }

@media (max-width: 767px) {
    .cplv-tabbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1030;
        display: flex;
        align-items: flex-start;
        height: 72px;
        /* Панель жёсткого дна касается системной полосы жестов — добавляем
           безопасный отступ, иначе подписи перекрывает индикатор iOS. */
        padding-bottom: env(safe-area-inset-bottom, 0);
        background: var(--cplv-nav-bg);
        border-top: 1px solid var(--cplv-nav-line);
    }
    .cplv-tabbar__item {
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        padding: 10px 4px 6px;
        color: var(--cplv-nav-muted);
        font-size: 11px;
        text-align: center;
        text-decoration: none;
        min-width: 0;
    }
    .cplv-tabbar__item svg { width: 22px; height: 22px; flex: 0 0 22px; }
    .cplv-tabbar__item span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .cplv-tabbar__item.is-active { color: var(--cplv-nav-ink); font-weight: 600; }
    .cplv-tabbar__item:hover,
    .cplv-tabbar__item:focus { color: var(--cplv-nav-ink); text-decoration: none; }

    /* Место под панель, чтобы она не закрывала последнюю строку страницы
       и подвал. */
    body.template_2019 { padding-bottom: 72px; }

    /* ---- шапка на телефоне ----
       Остаются корзина, уведомления и баланс — то, что показывает состояние.
       Язык и аккаунт уходят в боковое меню: их открывают раз в полгода, а
       места в строке они занимают столько же, сколько всё остальное. */
    body .navbar .navbar-menu-language,
    body .navbar .navbar-menu-account,
    body .navbar li.nav-item.dropdown.language,
    body .navbar li.nav-item.dropdown.account { display: none !important; }
}

/* ---- каталог услуг: строка карточек не должна вылезать за экран ----
   У бутстраповской .row поля −15 px, а её родитель .section-product-cards
   в этой теме без внутреннего отступа: на телефоне строка оказывалась шире
   экрана и добавляла горизонтальную прокрутку. */
body .section-product-cards > .row { margin-left: 0; margin-right: 0; }
body .section-product-cards > .row > [class^="col"] { padding-left: 0; padding-right: 0; }
@media (min-width: 576px) {
    body .section-product-cards > .row { margin-left: -10px; margin-right: -10px; }
    body .section-product-cards > .row > [class^="col"] { padding-left: 10px; padding-right: 10px; }
}

/* ============================================================================
   ВКЛАДКИ СЕРВЕРА: сеть, хранилище, снапшоты, журналы, ISO, шаблоны, биллинг
   ============================================================================
   Всё это рисует модуль proxmox2 своей разметкой поверх старого стиля
   templates/common/cloudhosting/styles.css. Тот написан под светлую тему
   образца 2013 года: цвета зашиты числами (#7B858A, #505050, #B2B2B2),
   подложки строк — фоновыми картинками, у заголовков белая тень.
   В тёмной теме это давало нечитаемые шапки таблиц и белые пятна.

   Переопределять приходится не выборочно, а целыми правилами: чужие цвета
   заданы на тех же узлах, что и наши. Правило одно на все вкладки — новая
   вкладка модуля получит правильный вид сама.

   ⚠️ Селекторы начинаются с #content-cloud НЕ для красоты: свои таблицы
   стилей модуль подключает из header.cloud.tpl, то есть уже В ТЕЛЕ страницы —
   позже нашей. При равной специфичности выигрывает он, и правило без id
   просто не доходит. */

body .cloud, body #content-cloud { color: var(--cplv-ink); }

/* ---- таблицы модуля ----
   .tonapp и .data-table — списки (интерфейсы, диски, снапшоты, журналы, ISO,
   шаблоны, правила фаервола). Оформляем как остальные списки панели: блок с
   контуром, приглушённая шапка, разделители внутри. */
body #content-cloud table.tonapp,
body #content-cloud table.data-table {
    width: 100%;
    margin: 0 0 18px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    box-shadow: var(--cplv-shadow);
}
body #content-cloud .tonapp thead tr,
body #content-cloud table.data-table thead tr {
    background: var(--cplv-surface-2);
    background-image: none;
    color: var(--cplv-muted);
}
body #content-cloud .tonapp tbody tr,
body #content-cloud table.data-table tbody tr {
    background: transparent;
    background-image: none;
}
body #content-cloud .tonapp tbody tr:hover,
body #content-cloud table.data-table tbody tr:hover { background: var(--cplv-bg); }
body #content-cloud .tonapp th,
body #content-cloud .tonapp thead tr td,
body #content-cloud table.data-table th,
body #content-cloud table.data-table thead tr td {
    padding: 10px 16px;
    background: transparent;
    background-image: none;
    border-bottom: 1px solid var(--cplv-line);
    color: var(--cplv-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .03em;
    text-transform: uppercase;
    text-shadow: none;
}
body #content-cloud .tonapp tbody td,
body #content-cloud table.data-table tbody td {
    padding: 14px 16px;
    background: transparent;
    background-image: none;
    border-bottom: 1px solid var(--cplv-line);
    color: var(--cplv-ink);
    font-size: 14px;
    text-shadow: none;
}
body #content-cloud .tonapp tbody tr:last-child td,
body #content-cloud table.data-table tbody tr:last-child td { border-bottom: 0; }

/* ---- таблицы «поле — значение» (.ttable): биллинг, ресурсы ----
   У них своя фоновая картинка на каждой ячейке и белая линия сверху —
   в тёмной теме это светлые полосы поперёк блока. */
body #content-cloud table.ttable { width: 100%; margin: 0 0 18px; }
body #content-cloud table.ttable tr td {
    padding: 10px 4px;
    border-top: 0;
    border-bottom: 1px solid var(--cplv-line);
    background: transparent;
    background-image: none;
    color: var(--cplv-ink);
    text-shadow: none;
}
body #content-cloud table.ttable tr:last-child td { border-bottom: 0; }
body #content-cloud table.ttable tr td b,
body #content-cloud table.ttable thead th {
    color: var(--cplv-muted);
    font-weight: 400;
    font-style: normal;
}
body #content-cloud table.ttable td.bigger { color: var(--cplv-ink); }

/* Подписи биллинга и сводок модуля идут отдельными узлами со своим цветом. */
body #content-cloud .text-muted,
body #content-cloud .fs11,
body #content-cloud small { color: var(--cplv-muted); }
body #content-cloud h4, body #content-cloud h5 { color: var(--cplv-ink); }

/* ---- графики раздела «Использование» ----
   Полотно графика модуль красит белым — в тёмной теме это белый прямоугольник
   во весь экран. Сам холст Chart.js прозрачный, поэтому достаточно подложки. */
body #content-cloud .graph_usage {
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    padding: 10px;
    margin-bottom: 18px;
}
body #content-cloud .content-bar[style] { background: none !important; }

/* Выбор периода на «Использовании». */
body #content-cloud .header-bar select,
body #content-cloud select:not(.form-control) {
    height: 42px;
    padding: 0 10px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    font-size: 14px;
}

/* ---- поля ввода в разделах модуля (фаервол, ISO, снапшоты) ---- */
body #content-cloud input[type="text"],
body #content-cloud input[type="number"],
body #content-cloud textarea {
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
}

/* ---- блок действий на остальных вкладках ----
   На всех вкладках, кроме «Обзора», модуль держит контейнер действий в
   отдельном узле с классом .right — с ним блок карточек уезжал вправо и
   ложился поверх кнопок раздела. */
body #content-cloud #lockable-vm-menu.right,
body #content-cloud #content-cloud > #lockable-vm-menu {
    float: none;
    width: 100%;
    margin: 0;
}
body #content-cloud #content-cloud > #lockable-vm-menu:empty { display: none; }

/* Пустая строка «Нечего отобразить» в таблицах модуля. */
body #content-cloud .tonapp tbody td[colspan],
body #content-cloud table.data-table tbody td[colspan] { color: var(--cplv-muted); }

/* ---- подвкладки раздела (.sub-ul) ----
   «Снапшоты / Расписание снапшотов», выбор периода на «Использовании».
   Модуль рисует их белой полосой во всю ширину — в тёмной теме это самое
   заметное пятно на странице. Приводим к тому же виду, что и вкладки
   раздела, только скромнее: это второй уровень. */
body .cloud #content-cloud .header-bar .sub-ul {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 18px;
    padding: 0;
    list-style: none;
    background: transparent;
    border-bottom: 1px solid var(--cplv-line);
}
body .cloud #content-cloud .header-bar .sub-ul > li { float: none; margin: 0; padding: 0; list-style: none; background: none; }
body .cloud #content-cloud .header-bar .sub-ul > li > a {
    display: inline-block;
    padding: 10px 14px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--cplv-muted);
    font-size: 14px;
    text-decoration: none;
}
body .cloud #content-cloud .header-bar .sub-ul > li > a:hover { color: var(--cplv-ink); }
body .cloud #content-cloud .header-bar .sub-ul > li > a.active {
    color: var(--cplv-ink);
    font-weight: 600;
    border-bottom-color: var(--cplv-accent);
}

/* ---- строка вкладок и содержимое не должны наезжать друг на друга ----
   Ряд вкладок переносится на вторую строку, и без собственного контекста
   форматирования нижний отступ .cloud-top «вытекал» наружу: содержимое
   раздела начиналось выше, чем кончались вкладки. */
body .section-main .cloud .cloud-top { display: flow-root; }
body .section-main .cloud #content-cloud { clear: both; }

/* Таблицы виджетов модуля (Reverse DNS и т.п.) размечены классом .table темы,
   но без обёртки-блока — оформляем так же, как списки выше. */
body .cloud #content-cloud table.table {
    width: 100%;
    margin: 0 0 18px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow);
}
body .cloud #content-cloud table.table th {
    padding: 10px 16px;
    border-top: 0;
    border-bottom: 1px solid var(--cplv-line);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .03em;
    text-transform: uppercase;
}
body .cloud #content-cloud table.table td {
    padding: 14px 16px;
    border-top: 0;
    border-bottom: 1px solid var(--cplv-line);
    color: var(--cplv-ink);
}
body .cloud #content-cloud table.table tr:last-child td { border-bottom: 0; }

/* ============================================================================
   ОБЛАКО: создание машины, ресурсы, пустой список
   ============================================================================
   Облачная услуга — это пул ресурсов, из которого клиент сам создаёт машины.
   Разметку рисует модуль proxmox2; форма создания подставляется нашим
   overrides/cloud_create_server_form.tpl, остальное правится стилями. */

/* ---- блок «Доступные ресурсы» над формой ----
   В стоке это врезка с курсивом и таблицей в 70 px — переносим в вид
   показателей, как на странице сервера. */
body .cloud #content-cloud .resources_box {
    margin: 0 0 22px;
    padding: 18px 22px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow);
    position: static;
    width: auto;
}
body .cloud #content-cloud .resources_box > strong {
    display: block;
    margin-bottom: 10px;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}
body .cloud #content-cloud .resources_box > strong em { font-style: normal; }
body .cloud #content-cloud .resources_box table.ttable { margin: 0; }
body .cloud #content-cloud .resources_box table.ttable tbody {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px 20px;
}
/* У строки таблицы в этой врезке своя светлая рамка из стиля модуля —
   в тёмной теме она обводила каждое число белым прямоугольником. */
body .cloud #content-cloud .resources_box table.ttable tr {
    display: flex;
    flex-direction: column;
    gap: 2px;
    border: 0;
    background: none;
}
body .cloud #content-cloud .resources_box table.ttable td {
    display: block;
    width: auto !important;
    padding: 0;
    border: 0;
    text-align: left !important;
    color: var(--cplv-muted);
    font-size: 13px;
}
body .cloud #content-cloud .resources_box table.ttable td b {
    color: var(--cplv-ink);
    font-size: 18px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
body .cloud #content-cloud .resources_box .fs11 { font-size: 13px; }

/* ---- форма создания машины ----
   ⚠️ ЧЕРЕЗ CSS, А НЕ ЧЕРЕЗ ПЕРЕОПРЕДЕЛЕНИЕ ШАБЛОНА.
   У блока {cloudservices section='tableform'} есть хук
   cloud_create_server_form, и соблазн переверстать форму им большой. Но
   $cloud.form, который он отдаёт, — НЕПОЛНОЕ представление формы: в нём нет
   строки «Интерфейс netN» с выбором пула IP и количеством адресов. Машина,
   созданная без этой строки, остаётся без сети, и модуль отвечает
   net_ip_no_bridge_error (наступали 31.08.2026). Поэтому разметка формы
   остаётся стоковой целиком, а вид задаётся стилями.

   Таблица «подпись слева — поле справа» превращается в сетку полей: строка
   таблицы = поле, подпись сверху. Сложные строки (сеть, кнопка) занимают всю
   ширину. */
body #content-cloud #create-vm-form {
    max-width: 860px;
    margin: 0;
    padding: 24px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
body #content-cloud table.vm-create-attr { display: block; width: 100%; margin: 0; }
body #content-cloud table.vm-create-attr tbody {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 18px 20px;
}
body #content-cloud table.vm-create-attr tr {
    display: flex;
    flex-direction: column;
    gap: 7px;
    border: 0;
    background: none;
}
body #content-cloud table.vm-create-attr td {
    display: block;
    width: auto !important;
    padding: 0;
    border: 0;
    background: none;
    text-shadow: none;
}
/* Первая ячейка строки — подпись поля. */
body #content-cloud table.vm-create-attr td:first-child {
    color: var(--cplv-muted);
    font-size: 14px;
}
/* Сеть и кнопка — во всю ширину сетки; у кнопки подписи нет. */
body #content-cloud table.vm-create-attr tr:has(.interface-config-flex),
body #content-cloud table.vm-create-attr tr:has(#btn-submit) { grid-column: 1 / -1; }
body #content-cloud table.vm-create-attr tr:has(#btn-submit) td:first-child { display: none; }
body #content-cloud table.vm-create-attr tr:has(#btn-submit) { margin-top: 6px; }
/* Блок сетевых настроек внутри строки — своей сеткой, без карточки:
   карточка тут уже есть, вложенная выглядела бы коробкой в коробке. */
body #content-cloud .interface-config-flex {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
    align-items: flex-end;
}
body #content-cloud .interface-config-flex:empty { display: none; }
body #content-cloud .interface-config-flex .form-group { margin-bottom: 0; min-width: 220px; }
/* Подпись — над полем, как у остальных: в стоке «Количество IP» стояла
   сбоку от ползунка и ряд получался разноуровневым. */
body #content-cloud .interface-config-flex .form-group > label {
    display: block;
    margin-bottom: 7px;
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 400;
}
body #content-cloud .range-input { display: flex; align-items: center; gap: 10px; }
body #content-cloud .range-input input[type="number"] {
    height: 46px;
    padding: 0 10px;
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    text-align: center;
}
/* ⚠️ У нативного input[type=range] своя белая подложка — в тёмной теме
   «Количество IP» светилось белой полосой. accent-color красит только
   заполнение и ручку, фон надо снимать отдельно. */
body #content-cloud .range-input input[type="range"] {
    flex: 1 1 auto;
    min-width: 120px;
    accent-color: var(--cplv-accent);
    background: transparent;
}

body #content-cloud #create-vm-form input[type="text"],
body #content-cloud #create-vm-form select {
    width: 100%;
    max-width: none;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    font-size: 15px;
}
body #content-cloud #create-vm-form input:focus,
body #content-cloud #create-vm-form select:focus { border-color: var(--cplv-accent); box-shadow: var(--cplv-glow); }

/* ---- строка «число + ползунок» ----
   Разметку собирает скрипт модуля: он оборачивает поле и единицу измерения
   в .slider-value и ставит рядом дорожку jQuery UI. Порядок в разметке
   обратный (сначала дорожка), поэтому он задан явно: число слева, дорожка
   занимает остаток строки, единица сразу за числом. */
body #content-cloud .input-with-slider {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
}
body #content-cloud .slider-value {
    order: 0;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--cplv-muted);
    font-size: 14px;
    white-space: nowrap;
}
body #content-cloud .slider-value input[type="text"] {
    flex: 0 0 92px;
    width: 92px !important;
    text-align: center;
}
body #content-cloud .input-with-slider .slider {
    order: 1;
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
    margin: 0;
}

/* Дорожка ползунка (jQuery UI) — в цветах панели. */
body #content-cloud .slider,
body #content-cloud .ui-slider {
    height: 6px;
    border: 0;
    border-radius: 3px;
    background: var(--cplv-surface-2);
    box-shadow: none;
}
body #content-cloud .ui-slider .ui-slider-range {
    background: var(--cplv-accent);
    border: 0;
    border-radius: 3px;
}
/* ⚠️ Ручку центрируем по дорожке сами: jQuery UI сдвигает её отрицательным
   margin-top, рассчитанным на дорожку своей высоты, и на нашей 6-пиксельной
   она висела на 10 px выше линии. */
body #content-cloud .ui-slider .ui-slider-handle {
    width: 18px;
    height: 18px;
    top: 50%;
    margin-top: 0;
    margin-left: -9px;
    transform: translateY(-50%);
    border: 2px solid var(--cplv-accent);
    border-radius: 50%;
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow);
    cursor: pointer;
}
body #content-cloud .ui-slider .ui-slider-handle:focus { box-shadow: var(--cplv-glow); outline: none; }

/* Кнопка отправки формы модуля — обычная зелёная кнопка панели.
   ⚠️ !important: тема красит кнопку классом .blue с тем же флагом, и без него
   действие остаётся синим — а синий в панели означает ссылку, не кнопку. */
body #content-cloud #btn-submit,
body #content-cloud #create-vm-form input[type="submit"] {
    height: 46px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-accent) !important;
    color: var(--cplv-on-accent) !important;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    width: auto;
}
body #content-cloud #create-vm-form input[type="submit"]:hover { background: var(--cplv-accent-hover) !important; }

/* ---- страница «Ресурсы»: полосы использования ----
   Модуль рисует их белыми прямоугольниками во всю ширину — в тёмной теме
   это самое яркое пятно на экране, хотя это всего лишь шкала. */
body .cloud #content-cloud .progress-bar,
body .cloud #content-cloud .progress,
body .cloud #content-cloud .bar-holder {
    height: 8px;
    border: 0;
    border-radius: 4px;
    background: var(--cplv-surface-2);
    box-shadow: none;
}
body .cloud #content-cloud .progress-bar > div,
body .cloud #content-cloud .progress .bar,
body .cloud #content-cloud .progress > div {
    height: 8px;
    border-radius: 4px;
    background: var(--cplv-accent);
    box-shadow: none;
}

/* Подсказки модуля (жёлтая врезка «список доступных ресурсов…»).
   У модуля она размечена классом .notice со своей светло-жёлтой заливкой. */
body .cloud #content-cloud .notice,
body .cloud #content-cloud .alert,
body .cloud #content-cloud .alert-warning,
body .cloud #content-cloud .alert-info {
    padding: 14px 18px;
    border: 1px solid var(--cplv-line);
    border-left: 3px solid var(--cplv-warn);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface);
    color: var(--cplv-muted);
    font-size: 14px;
    text-shadow: none;
}

/* ---- формы разделов модуля (создать шаблон, снапшот, правило и т.п.) ----
   Размечены бутстраповскими .form-group/.form-control, но без блока вокруг:
   поля растягивались на всю ширину экрана, и форма из трёх строк выглядела
   разъехавшейся. Даём ей тот же блок и те же поля, что и остальным формам
   панели. :has() отбирает именно формы с полями — у периода на «Использовании»
   и у мелких форм модуля своя разметка, их трогать не нужно; браузер без
   :has() просто оставит форму без карточки, поля всё равно будут правильные. */
body .cloud #content-cloud form:has(.form-group),
body .cloud form#content-cloud:has(.form-group) {
    max-width: 720px;
    margin: 0 0 22px;
    padding: 24px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
body .cloud #content-cloud .form-group { margin-bottom: 18px; }
body .cloud #content-cloud .form-group > label {
    display: block;
    margin-bottom: 7px;
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 400;
}
body .cloud #content-cloud .form-control {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    font-size: 15px;
    box-shadow: none;
}
body .cloud #content-cloud textarea.form-control {
    height: auto;
    min-height: 120px;
    padding: 10px 14px;
    resize: vertical;
}
body .cloud #content-cloud .form-control:focus {
    border-color: var(--cplv-accent);
    box-shadow: var(--cplv-glow);
}
/* Последняя группа — ряд кнопок, а не поле. */
body .cloud #content-cloud .form-group:last-of-type {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 0;
    margin-top: 24px;
}
/* ⚠️ …но не всегда: в форме переустановки последняя группа — это ПАРОЛЬ, а
   кнопка стоит вообще вне групп. Из-за правила выше подпись «Пароль» уезжала
   влево от поля, а кнопка «Переустановить VPS» прилипала к полю без отступа
   (замечание владельца 04.09.2026). Признак ряда кнопок — в группе НЕТ полей
   ввода; браузер без :has() ведёт себя как раньше. */
body .cloud #content-cloud .form-group:last-of-type:has(input, select, textarea) {
    display: block;
    margin-top: 0;
    margin-bottom: 18px;
}
/* Кнопка отправки, стоящая вне групп, отбивается от последнего поля сама. */
body .cloud #content-cloud form > .btn,
body .cloud #content-cloud form > button {
    margin-top: 22px;
}
/* ⚠️ Кроме форм-строк, где поле и кнопка стоят В ОДИН РЯД (теги у услуги, смена
   имени хоста): там этот отступ ронял кнопку на 22px ниже поля — было видно в
   блоке «Теги» (замечание владельца 04.10.2026). Отступ нужен только тогда,
   когда кнопка стоит ПОД полями, то есть в колоночной форме. */
body .cloud #content-cloud form.cplv-srv-tags__form > .btn,
body .cloud #content-cloud form.cplv-srv-tags__form > button,
body .cloud #content-cloud form.form-inline > .btn,
body .cloud #content-cloud form.form-inline > button {
    margin-top: 0;
}

/* ---- графики нагрузки ----
   Холсты Chart.js растягивались во всю ширину и брали высоту по соотношению
   2:1 — три графика по 1334×667 подряд (замечание владельца 04.09.2026).
   Ширину задаёт сетка: два графика в ряд, а высоту Chart.js пересчитает сам.
   Пары «заголовок + холст» заворачивает в карточки cplv-panel.js
   (initUsageGraphs) — в разметке модуля они лежат соседями. */
body .cloud #content-cloud .cplv-graphs {
    display: grid;
    /* ⚠️ auto-FILL, а не auto-fit: на «Сетевом трафике» график ОДИН, и auto-fit
       растягивал его на всю ширину — ровно то, от чего уходили. auto-fill держит
       колонку, и одинокий график занимает её, а не весь экран. */
    grid-template-columns: repeat(auto-fill, minmax(520px, 1fr));
    gap: 14px;
    margin: 0 0 22px;
}
body .cloud #content-cloud .cplv-graph {
    min-width: 0;
    padding: 14px 16px 16px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
body .cloud #content-cloud .cplv-graph > h3,
body .cloud #content-cloud .cplv-graph > h4,
body .cloud #content-cloud .cplv-graph > h5 {
    margin: 0 0 10px;
    color: var(--cplv-ink);
    font-size: 14px;
    font-weight: 600;
    text-shadow: none;
}
body .cloud #content-cloud .cplv-graph .graph_usage {
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
}
/* ⚠️ Холст не трогаем размерами: Chart.js пишет их сам и перерисовывает
   картинку при изменении контейнера. Своя ширина у холста дала бы растянутую
   мыльную картинку вместо перерисованной. */
@media (max-width: 767px) {
    body .cloud #content-cloud .cplv-graphs { grid-template-columns: 1fr; gap: 10px; }
    body .cloud #content-cloud .cplv-graph { padding: 10px 10px 14px; }
}

/* ---- выпадающие списки модуля (плагин Chosen) ----
   Часть <select> модуль подменяет плагином Chosen 2013 года: он прячет
   настоящий select и рисует свой список. Знаки — стрелку, крестик, лупу — он
   берёт из png-спрайта, нарисованного под светлую тему тех лет: в панели это
   было грязное пятно у правого края, а в тёмной теме знак пропадал вовсе
   (замечание владельца 04.09.2026 про выбор ISO). Поэтому знаки рисуем сами
   маской, а список приводим к виду наших полей.

   ⚠️ Ширину Chosen считает скриптом и пишет инлайном — перебиваем important,
   иначе список остаётся шириной со скрытый select.
   ⚠️ Правила действуют только внутри .cloud: тем же плагином размечены и
   чужие места панели, которые мы не трогаем. */
body .cloud .chzn-container { width: 100% !important; font-size: 15px; }
body .cloud .chzn-container-single .chzn-single {
    display: flex;
    align-items: center;
    height: 46px;
    padding: 0 44px 0 14px;
    background: var(--cplv-bg);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    box-shadow: none;
    color: var(--cplv-ink);
    line-height: normal;
}
body .cloud .chzn-container-single .chzn-single:hover { border-color: var(--cplv-line-strong); }
body .cloud .chzn-container-active .chzn-single {
    border-color: var(--cplv-accent);
    box-shadow: var(--cplv-glow);
}
body .cloud .chzn-container-single .chzn-single span {
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Стрелка: свой знак маской по цвету текста вместо спрайта. */
body .cloud .chzn-container-single .chzn-single div {
    width: 44px;
    background: none;
    border: 0;
}
body .cloud .chzn-container-single .chzn-single div b {
    display: block;
    width: 100%;
    height: 100%;
    background: none;
    background-color: var(--cplv-muted);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center / 16px 16px no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center / 16px 16px no-repeat;
}
/* Раскрытый список — как выпадающие меню панели. */
body .cloud .chzn-container .chzn-drop {
    width: 100% !important;
    margin-top: 6px;
    padding: 6px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    box-shadow: var(--cplv-shadow-hover);
}
body .cloud .chzn-container .chzn-search { padding: 2px; }
body .cloud .chzn-container .chzn-search input {
    width: 100% !important;
    height: 38px;
    margin: 0;
    padding: 0 10px;
    background: var(--cplv-bg) !important;
    /* ⚠️ Отдельной строкой: у Chosen лупа приходит фоновой картинкой спрайта,
       и сокращённое `background` её не всегда снимает. */
    background-image: none !important;
    border: 1px solid var(--cplv-line);
    border-radius: 6px;
    color: var(--cplv-ink);
    font-size: 14px;
}
/* Заголовок группы в списке («Публичный», «Свои образы»). */
body .cloud .chzn-container .chzn-results li.group-result {
    padding: 10px 10px 4px;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}
body .cloud .chzn-container .chzn-results {
    margin: 6px 0 0;
    padding: 0;
    max-height: 280px;
    color: var(--cplv-ink);
}
body .cloud .chzn-container .chzn-results li {
    margin: 0;
    padding: 10px 10px;
    border-radius: 6px;
    background: none;
    color: var(--cplv-ink);
    font-size: 14px;
    line-height: 1.35;
}
body .cloud .chzn-container .chzn-results li.highlighted {
    background: var(--cplv-surface-2);
    color: var(--cplv-ink);
}
body .cloud .chzn-container .chzn-results li.result-selected {
    background: var(--cplv-surface-2);
    font-weight: 600;
}
body .cloud .chzn-container .chzn-results li.no-results { background: none; color: var(--cplv-muted); }

/* Ряд «список + кнопка добавить»: между ними был ноль. */
body .cloud .iso-flex { display: flex; align-items: center; gap: 10px; }
body .cloud .iso-flex .chzn-container { flex: 1 1 auto; min-width: 0; }
body .cloud .iso-flex .btn-add-iso { flex: 0 0 auto; }

/* ---- поле пароля модуля ----
   Модуль кладёт рядом с полем два значка: «показать» и «сгенерировать».
   В стоке они висели голыми глифами в потоке, поэтому поле выглядело
   оборванным. Делаем их кнопками одного роста с полем. */
/* ⚠️ max-width через min(): на телефоне строка поля (ввод + две кнопки по 44 px)
   шире экрана, и жёсткие 460 px утаскивали её за правый край — страница ехала вбок
   (замечание владельца 04.10.2026, Pixel 412 px). min-width:0 обязателен: у поля
   модуля size="30", без него flex-элемент не сжимается ниже своей «естественной»
   ширины и переполняет строку. */
body .cloud #content-cloud .vm-password-input {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    max-width: min(460px, 100%);
}
body .cloud #content-cloud .vm-password-input .form-control { flex: 1 1 auto; width: auto; min-width: 0; }
body .cloud #content-cloud .vm-password-mask,
body .cloud #content-cloud .vm-password-generate {
    display: inline-flex;
    flex: 0 0 44px;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 46px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-muted);
    cursor: pointer;
}
body .cloud #content-cloud .vm-password-mask:hover,
body .cloud #content-cloud .vm-password-generate:hover {
    border-color: var(--cplv-line-strong);
    color: var(--cplv-ink);
}
/* Требования к паролю — строкой под полем: без неё красная рамка ничего не
   объясняет (текст собирает cplv-panel.js из data-policy поля). */
.cplv-pass-hint {
    margin-top: 7px;
    color: var(--cplv-muted);
    font-size: 13px;
    line-height: 1.4;
}
.cplv-pass-hint--bad { color: var(--cplv-danger); }
body .cloud #content-cloud .btn-default {
    height: 42px;
    display: inline-flex;
    align-items: center;
    padding: 0 20px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    font-size: 14px;
    font-weight: 600;
}
body .cloud #content-cloud .btn-default:hover { border-color: var(--cplv-line-strong); color: var(--cplv-ink); }

/* ---- пул ресурсов облака (вкладка «Ресурсы») ----
   Карточка на ресурс: знак, подпись, «занято из всего» крупно, полоса и
   остаток. Цвет знака и полосы меняется по заполненности — жёлтый с 70 %,
   красный с 90 %: «ядер не осталось» должно быть видно раньше, чем прочитано
   число. Разметка — proxmox2/templates/clientarea/resources.tpl. */
.cplv-res-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 16px;
    margin-bottom: 22px;
}
.cplv-res { padding: 18px 20px; }
.cplv-res__head { display: flex; align-items: center; gap: 10px; }
.cplv-res__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-res__icon svg { width: 19px; height: 19px; }
.cplv-res__label { color: var(--cplv-muted); font-size: 14px; }
.cplv-res__value {
    margin: 14px 0 8px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}
.cplv-res__note { margin-top: 8px; font-size: 13px; color: var(--cplv-muted); font-variant-numeric: tabular-nums; }
.cplv-bar__fill--warn { background: var(--cplv-warn); }
.cplv-bar__fill--danger { background: var(--cplv-danger); }
.cplv-res-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

/* Состояние машины в списке облака: бейдж рядом с именем, а не колонкой —
   колонок в списке и так три. */
body #content-cloud .cplv-row-name .badge { margin-left: 10px; flex: 0 0 auto; }

/* ============================================================================
   СТРАНИЦА УСЛУГИ, КОТОРУЮ РИСУЕТ НЕ МОДУЛЬ (выделенный сервер, админ-услуга)
   ============================================================================
   Разметку даёт наш templates/cp-lv/services/service_details.tpl. Вид тот же,
   что и у страницы VPS, но правила приходится писать заново: у VPS блок
   действий живёт внутри `.cloud #lockable-vm-menu #vm-menu`, и все его
   селекторы завязаны на эти два id — сюда они не доходят.

   Здесь id-ов нет и перебивать некого, поэтому селекторы короткие. На странице
   VPS они не мешают: правила модуля специфичнее и выигрывают. */

.cplv-actions__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}
/* ⚠️ li тянется сеткой, а ссылка внутри — нет: карточка с длинным
   объяснением делала ряд выше, а соседние оставались короткими.
   Отдаём ссылке всю высоту ячейки. */
.cplv-actions__grid > li { display: flex; margin: 0; padding: 0; list-style: none; background: none; }
.cplv-actions__grid > li > a.cplv-action { flex: 1 1 auto; }
.cplv-actions__grid > li > a.cplv-action {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    height: auto;
    padding: 14px 16px;
    border: 1px solid var(--cplv-line);
    border-radius: 10px;
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    text-align: left;
    text-decoration: none;
    white-space: normal;
    transition: border-color .15s ease, background-color .15s ease;
}
.cplv-actions__grid > li > a.cplv-action:hover {
    border-color: var(--cplv-line-strong);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    text-decoration: none;
}
@media (prefers-reduced-motion: reduce) {
    .cplv-actions__grid > li > a.cplv-action { transition: none; }
}

/* Ряд действий темы на этой странице остаётся пустым (всё ушло в карточки),
   но саму разметку удалять нельзя — по ней ходит скрипт темы. Пустую прячем,
   иначе она держит собственную высоту и отступ. */
body .section-account-service #vm-menu:empty { display: none; }

/* Секция услуги больше не двухколоночная: вкладки переехали наверх, левая
   колонка (белый бокс с ссылками) не выводится. */
body .section-account-service { display: block; }
body .section-account-service > .w-100 { width: 100%; }

/* Полоса вкладок у услуги стоит сразу под строкой опознания. */
/* Шапка страницы услуги/домена — блок: до следующего блока общий шаг 22.
   ⚠️ Поле нужно именно здесь: у внутренних блоков оно выходит наружу
   (у .cplv-srv-top нет ни рамки, ни padding) и склеивается с чужим. */
.cplv-srv-top { margin-bottom: 22px; }
.cplv-srv-top > .nav-tabs-wrapper { margin-top: 0; }

/* ---- облако: сводка по услуге (&vpsdo=billing) ----
   Разметку даёт proxmox2/templates/clientarea/billing.tpl (файл ядра модуля,
   в auto-upgrade exclude). Здесь только раскладка блоков. */

/* Карточки «сколько» и «когда» — их читают первыми, поэтому они шире
   ресурсных и стоят в два столбца. */
.cplv-cloud-money { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); margin-bottom: 22px; }
.cplv-cloud-money .cplv-res__value { font-size: 28px; }

.cplv-cloud-res { margin: 24px 0 22px; }
.cplv-cloud-res .cplv-res-grid { margin-bottom: 14px; }

/* «Закрыть услугу» стоит отдельно, ниже всего остального и над линией:
   отделяющая линия делает границу «дальше — необратимое» видимой. */
.cplv-danger-zone {
    display: flex;
    justify-content: flex-end;
    margin-top: 32px;
    padding-top: 18px;
    border-top: 1px solid var(--cplv-line);
}
/* ⚠️ !important обязателен: правило кнопок выше задаёт .btn-secondary цвет
   с !important, и без перебивки «Закрыть услугу» ничем не отличалась от
   обычной кнопки. */
body a.btn.cplv-btn-danger,
body a.btn.cplv-btn-danger:hover {
    color: var(--cplv-danger) !important;
    background: transparent !important;
}
body a.btn.cplv-btn-danger:hover { border-color: var(--cplv-danger) !important; }

/* Помесячная тарификация (billing_metered.tpl ядра): у наших тарифов её нет,
   но если её включат — плитки итогов не должны остаться белыми на тёмном. */
body .metered-reports .button {
    background: var(--cplv-surface-2);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
}
body .metered-reports .button.green { background: var(--cplv-surface-2); border-color: var(--cplv-accent); }
body .metered-reports .button .value { color: var(--cplv-ink); font-variant-numeric: tabular-nums; }
body .metered-reports .button .attr { color: var(--cplv-muted); }

/* ============================================================================
   ОБЛАКО: ИЗМЕНЕНИЕ РЕСУРСОВ (&vpsdo=upgrade)
   ============================================================================
   Разметку даёт proxmox2/templates/clientarea/upgrade.tpl + стоковый шаблон
   опции includes/libs/configoptions/slider/upgrades.tpl (оба в auto-upgrade
   exclude). Таблица там остаётся таблицей: за её поля цепляется расчёт цены
   и сам апгрейд. Карточку строке даёт раскладка ниже. */

body #content-cloud table.table-upgrades,
body #content-cloud table.table-upgrades tbody { display: block; width: 100%; border: 0; background: none; }
/* Шапка «Текущая настройка / Новая настройка / Цена» не нужна: подписи теперь
   стоят внутри самой карточки. */
body #content-cloud table.table-upgrades thead { display: none; }

body #content-cloud tr.cplv-upg-row {
    display: grid;
    grid-template-columns: minmax(180px, 1.1fr) minmax(240px, 2fr) minmax(110px, .7fr);
    align-items: center;
    gap: 18px;
    margin-bottom: 10px;
    padding: 16px 20px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
/* ⚠️ !important у рамки: линию ячейкам рисует тема селектором
   `.table > tbody > tr > td`, и без флага под каждой ячейкой карточки
   оставалась поперечная черта. */
body #content-cloud tr.cplv-upg-row > td {
    display: block;
    padding: 0;
    border: 0 !important;
    background: none;
    text-align: left;
    vertical-align: middle;
}
/* Слева — знак, подпись и что сейчас. */
body #content-cloud tr.cplv-upg-row > td.upgrade-name {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 15px;
    color: var(--cplv-ink);
}
body #content-cloud tr.cplv-upg-row > td.upgrade-name b { font-weight: 600; }
body #content-cloud tr.cplv-upg-row > td.upgrade-from {
    /* Текущее значение — подписью под именем ресурса, а не отдельной колонкой:
       колонка «Текущая настройка» стояла на другой строке, чем сама подпись. */
    grid-column: 1;
    grid-row: 2;
    font-size: 13px;
    color: var(--cplv-muted);
    font-variant-numeric: tabular-nums;
}
body #content-cloud tr.cplv-upg-row > td.upgrade-to { grid-column: 2; grid-row: 1 / span 2; }
body #content-cloud tr.cplv-upg-row > td.upgrade-price {
    grid-column: 3;
    grid-row: 1 / span 2;
    text-align: right;
    font-size: 17px;
    font-weight: 600;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}

/* Ползунок и новое значение. Дорожку рисует jQuery UI, число — сам модуль
   в #custom_slider_N_value_indicator. */
body #content-cloud .cplv-upg-row .slider-group {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
body #content-cloud .cplv-upg-row .slider-group .slides {
    order: 0;
    flex: 1 1 180px;
    min-width: 140px;
    width: auto !important;
    margin: 0 !important;
    float: none !important;
}
body #content-cloud .cplv-upg-row .slider-group > div[id$="_value_indicator"] {
    order: 1;
    flex: 0 0 auto;
    padding-top: 0 !important;
    font-size: 18px !important;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}
/* «+2» / «−1» — насколько новая настройка отличается от нынешней. Считает
   cplv-panel.js: без этой подписи разницу приходилось вычислять глазами. */
.cplv-upg__diff {
    order: 2;
    flex: 0 0 auto;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--cplv-surface-2);
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.cplv-upg__diff--up { color: var(--cplv-accent); }
.cplv-upg__diff--down { color: var(--cplv-warn); }

/* Итоги — отдельным блоком под списком, крупными числами и с кнопкой рядом. */
.cplv-upg-total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    margin-top: 18px;
    padding: 20px 24px;
}
.cplv-upg-total__nums { display: flex; gap: 32px; flex-wrap: wrap; }
.cplv-upg-total__label { font-size: 13px; color: var(--cplv-muted); }
.cplv-upg-total__value {
    margin-top: 4px;
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}
/* ⚠️ !important: тема красит `input.blue` своим синим с тем же флагом. */
body #content-cloud input.cplv-upg-submit {
    height: 46px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-accent) !important;
    color: var(--cplv-on-accent) !important;
    font-size: 15px;
    font-weight: 600;
    width: auto;
    cursor: pointer;
}

@media (max-width: 767px) {
    body #content-cloud tr.cplv-upg-row { grid-template-columns: 1fr auto; padding: 14px 16px; }
    body #content-cloud tr.cplv-upg-row > td.upgrade-to { grid-column: 1 / span 2; grid-row: 3; }
    body #content-cloud tr.cplv-upg-row > td.upgrade-price { grid-column: 2; grid-row: 1; }
    .cplv-upg-total { flex-direction: column; align-items: stretch; }
    .cplv-upg-total .cplv-upg-submit { width: 100%; }
}

/* Шаблон опции slider/upgrades.tpl общий: он же рисует строки апгрейда на
   странице обычной услуги (services/service_upgrades.tpl), где карточек нет и
   раскладка осталась табличной. Там знак только мешает — показываем его
   только внутри страницы модуля. */
td.upgrade-name > .cplv-res__icon { display: none; }
body #content-cloud tr.cplv-upg-row > td.upgrade-name > .cplv-res__icon { display: inline-flex; }

/* ---- облако: форма создания машины (&vpsdo=createvm) ----
   Разметку даёт proxmox2/templates/clientarea/createvm.tpl (файл ядра модуля,
   в auto-upgrade exclude). ⚠️ Поля формы там стоковые целиком — переверстать
   их через хук cloud_create_server_form нельзя, в $cloud.form нет блока сети.
   Здесь только блок доступных ресурсов и заголовки частей формы. */

.cplv-vm-limits { margin-bottom: 22px; }
.cplv-vm-limits .cplv-res-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin-bottom: 10px; }
.cplv-vm-limits .cplv-res__value { font-size: 20px; }

/* Заголовок части формы.
   ⚠️ Ищем его по содержимому (:has(.cplv-form-sec__text)), а не по классу
   строки: разметку блока модуль пропускает через свой разбор — он оставляет
   пары «подпись — содержимое» и ВЫБРАСЫВАЕТ классы <tr>. Заголовок приходит
   вторым <td> с пустым первым, поэтому первый прячем, а строку растягиваем
   на всю ширину сетки. */
body #content-cloud table.vm-create-attr tr:has(.cplv-form-sec__text) {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}
body #content-cloud table.vm-create-attr tr:has(.cplv-form-sec__text) > td:first-child { display: none; }
body #content-cloud table.vm-create-attr tr:has(.cplv-form-sec__text) > td {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 !important;
    border: 0 !important;
    background: none;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}
/* Первая часть стоит сразу под шапкой формы — лишний отступ ей не нужен. */
body #content-cloud table.vm-create-attr tr:has(.cplv-form-sec__text):first-child { margin-top: 0; }
.cplv-form-sec__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border-radius: 8px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-form-sec__icon svg { width: 15px; height: 15px; }

/* Текст письма в разделе «Письма»: блок с обычными полями текста, без своих
   отступов из письма. */
.cplv-email-body { padding: 22px 24px; line-height: 1.65; overflow-wrap: anywhere; }
.cplv-email-body img { max-width: 100%; height: auto; }

/* ============================================================================
   ПЕРЕПИСКА ОБРАЩЕНИЯ (/studio/tickets/view/<номер>/)
   ============================================================================
   Разметку рисует шаблон темы support/viewticket.tpl, а вид ей задавал стиль
   темы 2019: у сообщения белая подложка числом (#FFFFFF) и серая рамка
   (#EBECF0), у вложений — плитка #fcfcfc с подписью на #f5f5f5. В тёмной теме
   это самые светлые пятна на странице.

   Здесь переписка приведена к токенам, а сообщения различаются не только
   стороной, но и кромкой: ответ поддержки — зелёной, своё сообщение — обычной.
   Одного положения слева/справа мало: на телефоне тема ставит их в колонку
   (.comment { flex-direction: column }), и стороны пропадают. */
body .comments { margin: 24px 0 0; }
body .comments .comment { margin: 0 0 14px; }
body .comments .comment .comment-body {
    padding: 18px 20px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    color: var(--cplv-ink);
    box-shadow: var(--cplv-shadow);
}
body .comments .comment-admin .comment-body { border-left: 3px solid var(--cplv-accent); }
body .comments .comment .comment-body p { margin: 0; line-height: 1.6; overflow-wrap: anywhere; }
body .comments .comment .comment-sender { color: var(--cplv-muted); font-size: 14px; }
body .comments .comment .comment-sender strong,
body .comments .comment .comment-sender b { color: var(--cplv-ink); font-weight: 600; }
body .comments .comment .comment-date,
body .comments .comment .comment-date .date,
body .comments .comment .comment-date .time { color: var(--cplv-muted); font-variant-numeric: tabular-nums; }
body .comments .comment hr { border-color: var(--cplv-line); }

/* Шапка обращения: состояние, дата, отдел и действия. */
body .content-view-details {
    gap: 10px;
    flex-wrap: wrap;
    margin: 18px 0 6px;
    padding: 16px 20px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
}
body .content-view-details .badges-group .badge {
    border: 0 !important;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted) !important;
}
body .content-view-details form { margin: 0; }

/* Вложения. */
body .hbfiles .hbfile {
    background: var(--cplv-surface-2);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
}
body .hbfiles .hbfile:hover { border-color: var(--cplv-line-strong); }
body .hbfiles .hbfile .hbfile-control { background: var(--cplv-surface); }
body .hbfiles .hbfile .hbfile-title { color: var(--cplv-ink); }
body .hbfiles .hbfile .hbfile-control-icon { color: var(--cplv-muted); }
body .hbfiles .hbfile .hbfile-control-icon:hover { color: var(--cplv-accent); }

/* Настройки аккаунта: группа = блок, поля друг под другом, флажки списком. */
.cplv-settings .cplv-h-section { margin: 22px 0 14px; }
.cplv-settings .cplv-h-section:first-child { margin-top: 0; }
.cplv-settings .cplv-form { max-width: none; }
.cplv-settings .cplv-field + .cplv-field { margin-top: 20px; }
.cplv-settings .cplv-field .controls { margin-top: 8px; }
.cplv-settings .cplv-field .controls input[type="radio"],
.cplv-settings .cplv-field .controls input[type="checkbox"] {
    margin: 0 8px 0 0;
    vertical-align: -2px;
}
/* Строка «переключатель + подпись»: в стоке подпись шла сразу за <input> без
   обёртки, и на части настроек кружок прилипал к первой букве. */
.cplv-settings .cplv-field .controls { line-height: 1.9; }
.cplv-settings .cplv-field .controls br + input { margin-top: 8px; }
.cplv-settings .settings-nameservers { margin-top: 10px; }

/* Раздел «Загрузки» лежит не в бутстраповском .container, поэтому
   отрицательные поля у .row вылезали за край: на 390 px страница получала
   горизонтальную прокрутку в 5 px. Поля гасим, просветы даёт padding колонок. */
body .section-downloads > .row { margin-left: 0; margin-right: 0; }

/* ⚠️ На 390 px сетка формы создания машины (minmax(320px, 1fr)) шире самой
   колонки — колонка получалась 320 px в контейнере 301 px, и страница ехала
   вбок на 7 px. На телефоне поля идут в одну колонку. */
@media (max-width: 767px) {
    /* ⚠️ minmax(0,1fr), а не 1fr: у `1fr` минимум — min-content, и строка с
       ползунком раздвигала колонку шире экрана. */
    body #content-cloud table.vm-create-attr tbody { grid-template-columns: minmax(0, 1fr); }
    body #content-cloud table.vm-create-attr tr { min-width: 0; }
    body #content-cloud table.vm-create-attr td { min-width: 0; }
    /* Кнопка создания: подпись «Создать новую виртуальную машину» в одну строку
       на 390 px не помещалась и растягивала сетку — на телефоне она во всю
       ширину и переносится (DESIGN-SPEC §5: действие во всю ширину). */
    body #content-cloud #create-vm-form input[type="submit"] {
        width: 100%;
        height: auto;
        min-height: 46px;
        padding: 10px 16px;
        white-space: normal;
    }
    body #content-cloud #create-vm-form { padding: 18px; }
    /* ⚠️ Ширину дорожки ползунка модуль ставит скриптом в пикселях по ширине
       родителя на момент загрузки. После переноса полей в одну колонку она
       осталась прежней и выпирала — на телефоне отдаём ширину раскладке. */
    /* ⚠️ Ручка ползунка стоит на 100 % дорожки и торчит вправо на половину
       своей ширины (jQuery UI + наш margin-left:-9px). На узком экране эти
       9 px и давали горизонтальную прокрутку — освобождаем их полем справа. */
    body #content-cloud .input-with-slider { flex-wrap: wrap; padding-right: 16px; }
    body #content-cloud .input-with-slider .slider {
        width: auto !important;
        max-width: 100%;
        min-width: 0;
        flex: 1 1 100%;
    }
    body #content-cloud .slider-value input[type="text"] { flex: 0 0 76px; width: 76px !important; }
}

/* ---- поля, которые тема красит в белое мимо .form-control ----
   ⚠️ !important: свои правила тема объявляет позже нашего файла и с той же
   силой, поэтому обычное переопределение до них не доходит. */
body .affiliates_landing_input {
    background-color: var(--cplv-bg) !important;
    border: 1px solid var(--cplv-line) !important;
    color: var(--cplv-ink) !important;
}

/* ---- автозаполнение браузера ----
   Chrome красит подставленное поле своим светло-жёлтым/голубым фоном и
   чёрным текстом — в тёмной теме поле светится, а на светлой спорит с формой.
   Фон подменяем внутренней тенью: сам background у автозаполненного поля
   браузер не отдаёт. */
body input:-webkit-autofill,
body input:-webkit-autofill:hover,
body input:-webkit-autofill:focus,
body select:-webkit-autofill,
body textarea:-webkit-autofill {
    -webkit-text-fill-color: var(--cplv-ink);
    -webkit-box-shadow: 0 0 0 1000px var(--cplv-bg) inset;
    box-shadow: 0 0 0 1000px var(--cplv-bg) inset;
    caret-color: var(--cplv-ink);
    /* Задержка в «вечность»: иначе Chrome возвращает свой фон анимацией. */
    transition: background-color 9999s ease-in-out 0s;
}

/* Поиск по базе знаний: тема рисует блок белой плашкой числом
   (.input-self-box) и снимает у поля рамку (.form-control-noborders) —
   в тёмном режиме это белый прямоугольник во всю ширину. */
body .input-self-box {
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    padding: 10px;
}
body .input-self-box .form-control,
body .input-self-box .form-control-noborders {
    background: transparent !important;
    border: 0 !important;
    color: var(--cplv-ink);
    box-shadow: none;
}

/* ---- страница обращения: строка действий, знак стороны, форма ответа ---- */
.cplv-ticket__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 22px;
}
.cplv-ticket__bar .cplv-ticket__form { margin: 0; }

/* Знак стороны вместо картинки-заглушки: у клиента человек, у поддержки —
   гарнитура. Стоковый аватар (dist/images/user.svg) — синий рисунок 2013 года,
   в панели он единственное цветное пятно и ничего не сообщает. */
/* ---- сообщение в переписке ----
   Раскладка — стоковая (решение владельца): у клиента подпись справа от блока,
   у поддержки слева. Своими остаются только знак автора и подпись: знак 60 px
   со скруглением, под ним имя и роль — «Вы» либо имя и «поддержка cp.lv».
   На телефоне знак уменьшается, иначе он занял бы треть экрана. */
/* ⚠️ Ширину задаём явно: тема сжимает .comment-sender по содержимому, и без
   этого подпись под знаком ломалась по одной букве в строке. */
body .comments .comment.cplv-msg .comment-sender {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    flex: 0 0 60px;
    width: 60px;
    margin: 0;
    font-size: 14px;
    text-align: center;
}
/* ⚠️ Расстояние до блока с текстом задаём через gap самой строки, а не
   margin-right у подписи: у сообщения клиента порядок обратный (подпись
   справа), и односторонний отступ прижимал бы её к тексту. */
body .comments .comment.cplv-msg { gap: 22px; }
body .comments .comment.cplv-msg .cplv-msg__who { display: block; min-width: 0; }
.cplv-msg__name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cplv-ink);
}
.cplv-msg__role {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    line-height: 1.3;
    color: var(--cplv-muted);
}

@media (max-width: 767px) {
    body .comments .comment.cplv-msg { gap: 14px; }
    body .comments .comment.cplv-msg .comment-sender { flex: 0 0 52px; width: 52px; }
    .cplv-msg__icon { flex: 0 0 52px; width: 52px; height: 52px; border-radius: 13px; }
    .cplv-msg__icon svg { width: 24px; height: 24px; }
}

.cplv-msg__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 60px;
    width: 60px;
    height: 60px;
    border-radius: 14px;
    border-radius: 10px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-msg__icon svg { width: 28px; height: 28px; }
/* ⚠️ Тон знака задаём селектором из двух классов: правило .cplv-msg__icon
   стоит в файле позже модификатора --accent и при равной силе перебивало его,
   из-за чего знак поддержки был таким же серым, как у клиента. */
.cplv-msg__icon.cplv-action__icon--accent { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
.cplv-msg__icon.cplv-action__icon--muted { background: var(--cplv-surface-2); color: var(--cplv-muted); }
:root:not([data-theme="light"]) .cplv-msg__icon.cplv-action__icon--accent,
:root[data-theme="dark"] .cplv-msg__icon.cplv-action__icon--accent { background: rgba(156, 205, 126, .14); }
/* ⚠️ .comment у темы — это .media (flex). Без flex:1 у тела сообщение
   съёживалось до ширины текста: в стоке ширину давал класс .media-body,
   которого в нашей разметке нет. */
/* ⚠️ .comment у темы — это .media (flex). Без flex:1 у тела сообщение
   съёживалось до ширины текста: в стоке ширину давал класс .media-body,
   которого в нашей разметке нет. */
body .comments .comment.cplv-msg .comment-body { padding: 18px 20px; flex: 1 1 auto; min-width: 0; }
body .comments .comment.cplv-msg { align-items: flex-start; }

.cplv-msg__foot {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 10px;
    font-size: 13px;
    color: var(--cplv-muted);
}
.cplv-msg__quote { font-size: 13px; color: var(--cplv-accent); }
.cplv-msg__note { color: var(--cplv-warn); }
.cplv-msg__rate { display: inline-flex; align-items: center; gap: 8px; }

/* Форма ответа. Раньше это была карточка с БЕЛОЙ шапкой «Ответить» — в тёмной
   теме светлая полоса поперёк экрана. */
.cplv-ticket__reply { max-width: none; }
body .cplv-ticket__reply .card-header { display: none; }
body .cplv-ticket__reply textarea.form-control { min-height: 150px; }
body .cplv-ticket__reply .fileupload-buttonbar { display: flex; align-items: center; gap: 10px; }
body .cplv-ticket__reply .fileinput-button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    position: relative;
    overflow: hidden;
    height: 46px;
    padding: 0 16px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    cursor: pointer;
}
body .cplv-ticket__reply .fileinput-button:hover { border-color: var(--cplv-line-strong); }
body .cplv-ticket__reply .fileinput-button input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}
body .cplv-ticket__reply #dropzone { display: none; }
/* ⚠️ flex-direction: row — .cplv-field ставит колонку, и флажок оказывался
   НАД подписью по центру. */
.cplv-check { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.cplv-check input[type="checkbox"] { margin: 0; }
.cplv-check label { margin: 0; color: var(--cplv-muted); font-size: 14px; }
/* Блок вложений: рамку #EBECF0 тема рисует числом — в форме ответа она
   превращала подпись поля в подобие ещё одного поля ввода. */
body .cplv-ticket__reply #fileupload,
body .cplv-form .fileupload { border: 0 !important; padding: 0 !important; background: none; }

/* ============================================================================
   СТРАНИЦА СЧЁТА (/studio/clientarea/invoice/<id>/)
   ============================================================================
   Тело счёта HostBill отдаёт готовым HTML-документом и пишет его скриптом в
   <iframe>. Это печатная форма со своими цветами, зашитыми числами: тёмно-серый
   текст, белая шапка таблицы, тонкие серые линии. Панель её перекрасить не
   может — документ живёт в отдельном документе iframe, наш CSS туда не попадает.
   В тёмной теме страница выглядела пустой: тёмный текст на тёмном.

   Решение: позиции, итоги и действия рисует сама панель (см. invoice.tpl,
   модификатор cplvinvrows), а печатная форма убрана в свёрнутый блок и лежит
   на БЕЛОМ листе в обеих темах — это документ, а не элемент интерфейса. */

.cplv-inv-rows { margin-bottom: 22px; }
.cplv-inv-rows .cplv-row-sub { display: block; }

.cplv-inv-total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    padding: 20px 24px;
    margin-bottom: 22px;
}
.cplv-inv-total__lines { display: flex; flex-direction: column; gap: 6px; min-width: 220px; }
.cplv-inv-total__line { display: flex; justify-content: space-between; gap: 24px; font-size: 14px; color: var(--cplv-muted); }
.cplv-inv-total__line b { color: var(--cplv-ink); font-variant-numeric: tabular-nums; }
.cplv-inv-total__label { font-size: 13px; color: var(--cplv-muted); }
.cplv-inv-total__value {
    margin-top: 4px;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}

/* Печатная форма. Лист белый всегда: счёт — документ, и на экране он должен
   выглядеть так же, как на бумаге и в PDF. */
.cplv-inv-paper { padding: 0; overflow: hidden; }
.cplv-inv-paper__summary {
    padding: 16px 24px;
    cursor: pointer;
    font-size: 14px;
    color: var(--cplv-ink);
    list-style: none;
}
.cplv-inv-paper__summary::-webkit-details-marker { display: none; }
.cplv-inv-paper__summary::before { content: "+ "; color: var(--cplv-muted); }
.cplv-inv-paper[open] .cplv-inv-paper__summary::before { content: "− "; }
.cplv-inv-paper__summary:hover { color: var(--cplv-accent); }
.cplv-inv-paper__sheet {
    background: #ffffff;
    border-top: 1px solid var(--cplv-line);
    padding: 8px 16px 16px;
}
body .cplv-inv-paper__sheet #invoice_iframe { background: #ffffff; }

@media (max-width: 767px) {
    .cplv-inv-total { flex-direction: column; align-items: stretch; }
    .cplv-inv-total .btn { width: 100%; text-align: center; }
}
/* На телефоне список позиций складывается в карточку «подпись — значение».
   Описание услуги — единственное длинное значение, и по правому краю оно
   читается плохо: возвращаем ему левый край. */
@media (max-width: 767px) {
    .cplv-inv-rows .cplv-row-title { display: block; text-align: left; }
}

/* ============================================================================
   СПИСКИ УСЛУГ, ДОМЕНОВ И ОБРАЩЕНИЙ — макеты 12, 14, 19, 11
   ============================================================================
   В макетах таблиц нет: список — это блок, внутри которого строки, разделённые
   линией. У строки: точка состояния, имя с подписью моноширинным, состояние
   словом, две величины и одно действие. Шапки с названиями колонок и сортировки
   в макете нет — величин в строке три, и подписывать их нечем.

   Разметка остаётся <table>: на ней держатся постраничная подгрузка (#updater),
   фильтры (data-sorter), выделение доменов (.idchecker) и меню «⋮». Меняем не
   разметку, а раскладку — строка становится флексом, шапка прячется.
   ⚠️ Поэтому же не переписываем список на <div>: потеряется всё перечисленное. */

body .cplv-list-rows.table,
body .cplv-list-rows.table > tbody { display: block; width: 100%; }
body .cplv-list-rows.table > thead { display: none; }
body .cplv-list-rows.table > tbody > tr {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--cplv-line);
}
body .cplv-list-rows.table > tbody > tr:last-child { border-bottom: 0; }
body .cplv-list-rows.table > tbody > tr > td {
    display: block;
    padding: 0;
    border: 0 !important;
    background: none;
    vertical-align: middle;
}
/* Имя с подписью забирает всё свободное место, остальное — по содержимому. */
body .cplv-list-rows.table > tbody > tr > td.inline-row { flex: 1 1 auto; min-width: 0; }
body .cplv-list-rows.table > tbody > tr > td.cplv-num,
body .cplv-list-rows.table > tbody > tr > td.cplv-list-state {
    flex: 0 0 auto;
    text-align: right;
    white-space: nowrap;
    font-size: 14px;
    color: var(--cplv-muted);
    font-variant-numeric: tabular-nums;
}
body .cplv-list-rows.table > tbody > tr > td.cplv-col-action,
body .cplv-list-rows.table > tbody > tr > td.cplv-col-check { flex: 0 0 auto; width: auto; }
body .cplv-list-rows.table > tbody > tr > td.cplv-empty { flex: 1 1 100%; }

/* Состояние — словом, а не бейджем: цвет уже несёт точка слева, а бейдж рядом
   с ней повторял его второй раз и спорил с кнопкой действия. */
.cplv-list-state { font-size: 14px; color: var(--cplv-muted); }

@media (max-width: 767px) {
    /* На телефоне строка складывается: имя сверху, величины и действие ниже.
       ⚠️ Правило перебивает общую «таблица → карточки» ниже по файлу, поэтому
       селектор длиннее: там строки получают рамку и превращаются в карточки,
       а здесь карточка уже есть — сам блок списка. */
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr {
        display: flex;
        flex-wrap: wrap;
        border: 0;
        border-bottom: 1px solid var(--cplv-line);
        border-radius: 0;
        margin: 0;
        padding: 14px 16px;
        gap: 8px 14px;
    }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr:last-child { border-bottom: 0; }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td {
        display: block;
        width: auto;
        padding: 0;
        text-align: left;
    }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td::before { content: none; }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td.inline-row { flex: 1 1 100%; }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td.cplv-col-action { flex: 1 1 100%; }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td.cplv-col-action .btn { width: 100%; text-align: center; }
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td.cplv-num,
    body .table-responsive.table-borders > .cplv-list-rows.table > tbody > tr > td.cplv-list-state { text-align: left; }
}

/* ---- фильтры списка — такие же таблетки, как разделы ----
   В макете «Все / Открытые / Отвеченные» и «VPS · 2 / Выделенные · 1» нарисованы
   одинаково: таблетка, активная залита чернильным. Стоковый вид — текст с
   подчёркиванием-ползунком — в макете не встречается нигде.
   ⚠️ Правила разделов выше исключают .nav-link-slider (`:not(...)`), поэтому
   два набора не пересекаются. */
body .nav-tabs-wrapper:has(a.nav-link-slider) { overflow: visible; margin: 20px 0 24px; }
body .nav-tabs-wrapper > ul.nav-tabs:has(a.nav-link-slider) {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap !important;
    margin: 0;
    padding: 0;
    border: 0;
    list-style: none;
    background: none;
}
body .nav-tabs-wrapper > ul.nav-tabs:has(a.nav-link-slider) > li { flex: 0 0 auto; padding: 0; margin: 0; list-style: none; background: none; }
body .nav-tabs-wrapper > ul.nav-tabs:has(a.nav-link-slider) > li:first-child { flex: 1 1 auto; min-width: 0; }
body ul.nav-slider {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap !important;
    margin: 0;
    padding: 0;
    border: 0;
    list-style: none;
    background: none;
}
body ul.nav-slider > li.nav-item { flex: 0 0 auto; margin: 0; padding: 0; list-style: none; background: none; }
/* ⚠️ Длинный селектор обязателен: у этих ссылок ДВА класса — .nav-link и
   .nav-link-slider, и тема адресует их как
   `.nav-tabs-wrapper .nav-tabs li.nav-item a.nav-link` (padding: 0). Правило
   короче проигрывает по специфичности, и таблетка остаётся без полей —
   активная схлопывалась до обрезанного слова. */
body .nav-tabs-wrapper .nav-tabs li.nav-item > a.nav-link.nav-link-slider {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 18px;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    white-space: normal;
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}
body .nav-tabs-wrapper .nav-tabs li.nav-item > a.nav-link.nav-link-slider:hover { color: var(--cplv-ink); text-decoration: none; }
body .nav-tabs-wrapper .nav-tabs li.nav-item.active > a.nav-link.nav-link-slider,
body .nav-tabs-wrapper .nav-tabs li.nav-item > a.nav-link.nav-link-slider.active {
    background: var(--cplv-ink);
    color: var(--cplv-bg) !important;
    font-weight: 600;
}
/* Подчёркивание-ползунок темы и рельсы прокрутки в этом виде не нужны. */
body .nav-tabs-wrapper:has(a.nav-link-slider) .slider,
body .nav-tabs-wrapper:has(a.nav-link-slider) .ps__rail-x,
body .nav-tabs-wrapper:has(a.nav-link-slider) .ps__rail-y,
body .nav-tabs-wrapper:has(a.nav-link-slider) > .nav-tabs-arrow-left,
body .nav-tabs-wrapper:has(a.nav-link-slider) > .nav-tabs-arrow-right { display: none !important; }
@media (max-width: 767px) {
    body ul.nav-slider { gap: 6px; }
    body .nav-tabs-wrapper .nav-tabs li.nav-item > a.nav-link.nav-link-slider { padding: 0 14px; font-size: 13px; min-height: 36px; }
    body .nav-tabs-wrapper > ul.nav-tabs:has(a.nav-link-slider) { gap: 8px; }
}
@media (prefers-reduced-motion: reduce) {
    body .nav-tabs-wrapper .nav-tabs li.nav-item > a.nav-link.nav-link-slider { transition: none; }
}

/* ---- знак в пустом состоянии ----
   В макете пустой список — это знак в тонированном квадрате, заголовок,
   две строки объяснения и кнопка. Знака у нас не было. */
.cplv-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    margin-bottom: 10px;
    border-radius: 12px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-empty__icon svg { width: 22px; height: 22px; }

/* ---- строки «подпись — значение» в блоке (макеты 07, 15) ----
   Подпись колонкой слева, значение справа, строки разделены линией. Тот же
   кирпич используют обзор аккаунта и состав счёта. ⚠️ У блока с такими
   строками внутренних отступов нет: их даёт сама строка, иначе первая и
   последняя прижимаются к краю вдвойне. */
.cplv-lines { padding: 0; overflow: hidden; }
.cplv-line { display: flex; gap: 20px; padding: 14px 20px; }
.cplv-line + .cplv-line { border-top: 1px solid var(--cplv-line); }
.cplv-line__label { flex: 0 0 220px; width: 220px; font-size: 14px; color: var(--cplv-muted); }
.cplv-line__value { min-width: 0; font-size: 15px; color: var(--cplv-ink); overflow-wrap: anywhere; }
.cplv-line__value--empty { color: var(--cplv-muted); }
@media (max-width: 575px) {
    .cplv-line { flex-direction: column; gap: 4px; }
    .cplv-line__label { flex: 1 1 auto; width: auto; }
}

/* ---- блоки аккаунта, у которых своих отступов не было ----
   Блок «скачать данные / удалить аккаунт» и подобные лежали без padding, и
   содержимое упиралось в рамку. */
.cplv-overview__extra { padding: 22px 24px; }

/* ---- форма «Изменить детали» ----
   Ширина была ограничена 720 px из общего правила .cplv-form, и на фоне
   вкладок во всю ширину форма выглядела обрезанной. По макету 18 блок занимает
   всю колонку, а поля идут в ДВЕ колонки. */
.cplv-editfields { max-width: none; }
.cplv-editfields .cplv-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 20px; }
@media (max-width: 767px) {
    .cplv-editfields .cplv-fields { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================================
   КНОПКИ ПО МАКЕТУ (31.08.2026)
   ============================================================================
   В макетах кнопка — это прямоугольник со скруглением 8: заливка --cplv-accent
   у действия, контур --cplv-line у второстепенной, подпись 14/600. У нас они
   оставались «таблетками» (радиус 20) из первой версии стиля — рядом с
   вкладками-таблетками 40 px это читалось как второй набор форм.

   ⚠️ Радиус задаём и у .btn-sm/.btn-lg отдельно: тема объявляет их своими
   правилами той же силы. */
body .btn,
body .btn.btn-sm,
body .btn.btn-lg,
body .btn-danger,
body .btn-outline-danger,
body .btn_pay,
body .btn-paynow,
body .btn-paynow2 {
    border-radius: var(--cplv-radius-sm);
    font-weight: 600;
    letter-spacing: 0;
}
body .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Высота 42 — на два пункта выше таблетки 40 (DESIGN-SPEC §8): так кнопка
       и вкладка не читаются одним и тем же элементом. */
    min-height: 42px;
    padding: 10px 22px;
    font-size: 14px;
    line-height: 1.25;
}
body .btn.btn-sm { min-height: 40px; padding: 8px 16px; font-size: 13px; }
body .btn.btn-lg { min-height: 46px; padding: 10px 24px; font-size: 15px; }

/* Знак внутри кнопки. Иконочный шрифт темы рисует глиф 24 px и роняет базовую
   линию — приводим к размеру подписи; отступ даёт gap у самой кнопки, поэтому
   собственные поля глифа снимаем. */
body .btn > .material-icons,
body .btn > i.material-icons {
    font-size: 18px;
    line-height: 1;
    margin: 0 !important;
}
body .btn > svg { width: 18px; height: 18px; flex: 0 0 18px; }

/* ============================================================================
   ЗАГОЛОВОК РАЗДЕЛА В ШАПКЕ
   ============================================================================
   Переносит его cplv-panel.js: разметку страницы HostBill печатает сам, и
   заголовок приходит внутри содержимого. Здесь только вид и место. */
/* Заголовок открывает шапку рабочей области: слева, на цвете полотна, а всё
   остальное — кнопка «Заказать» и правый ряд — отходит к краю (margin-right).
   Размер как в макетах: 17 px, полужирный. */
body .navbar .navbar-body > .cplv-page-title {
    margin: 0;
    /* Отступ от границы меню — по названию услуги в списке под ним (замечание
       владельца 31.08.2026): 20 px даёт сама рабочая область, ещё 20 — поле
       блока, остальное — знак состояния перед названием. Заголовок и первая
       строка списка встают на одну вертикаль. */
    padding-left: 60px;
    padding-right: 20px;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.01em;
    color: var(--cplv-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 42vw;
}
/* Заголовок, уехавший в шапку, в содержимом больше не нужен. */
body h1.cplv-title-moved { display: none !important; }
/* На телефоне в шапке и так тесно: там заголовок остаётся в содержимом. */
@media (max-width: 767px) {
    .cplv-page-title { display: none; }
    body h1.cplv-title-moved { display: block !important; }
}

/* ============================================================================
   ШАПКА РАБОЧЕЙ ОБЛАСТИ: «ЗАКАЗАТЬ», БАЛАНС, ЯЗЫК
   ============================================================================
   Состав и вид — из макетов: слева заголовок раздела, справа зелёная кнопка со
   знаком «+», за ней баланс и служебные знаки. */

/* Кнопка «Заказать» и правый ряд знаков всегда у правого края — даже там, где
   заголовка нет (страница услуги открывается строкой опознания). Отступ даёт
   кнопка сама, поэтому заголовку auto-поля не нужны: иначе свободное место
   делилось бы между ними и кнопка вставала посреди шапки. */
body .navbar .navbar-body > .navbar-order { margin-left: auto !important; }

/* ---- кнопка «Заказать» ----
   Размеры макета: 14 px, полужирный, отступы 10/18, радиус 8, знак и слово через 8.
   ⚠️ Цвет при наведении держим сами и в обеих темах: тема красит любую .btn:hover
   в тёмно-серый (custom.min.css), и на зелёном фоне подпись бы гасла. */
body .navbar .cplv-order-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    border-radius: var(--cplv-radius-sm) !important;
    background-color: var(--cplv-accent) !important;
    border-color: var(--cplv-accent) !important;
    color: var(--cplv-on-accent) !important;
}
body .navbar .cplv-order-btn > .material-icons {
    font-size: 18px;
    line-height: 1;
    margin: 0 !important;
    color: inherit !important;
}
body .navbar .cplv-order-btn:hover,
body .navbar .cplv-order-btn:focus,
body .navbar .cplv-order-btn:active,
body .navbar .cplv-order-btn[aria-expanded="true"] {
    background-color: var(--cplv-accent-hover) !important;
    border-color: var(--cplv-accent-hover) !important;
    color: var(--cplv-on-accent) !important;
    text-decoration: none;
}
body .navbar .cplv-order-btn:hover > .material-icons,
body .navbar .cplv-order-btn:focus > .material-icons { color: inherit !important; }

/* ---- баланс ----
   Две строки, как в макете шапки: приглушённая подпись сверху, сумма под ней.
   Показывается только при долге (условие в menu.top.logged.tpl), поэтому сумма
   всегда красная и полновесная — ради неё пункт и существует. Цифры табличные,
   чтобы сумма не «прыгала» по ширине от обновления к обновлению. */
/* ⚠️ Селектор длинный не для красоты: ряд шапки задаёт своим ссылкам
   `display:flex` с горизонтальной осью (правило `.navbar .navbar-nav >
   .nav-item > .nav-link` выше), и более короткое правило проигрывает ему
   специфичностью — баланс оставался в одну строку. */
body .navbar .navbar-nav > .nav-item > .nav-link.cplv-balance,
body .navbar .cplv-balance {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2px;
    line-height: 1.25;
    font-size: 14px;
    white-space: nowrap;
}
body .navbar .cplv-balance:hover { text-decoration: none; }
body .cplv-balance__label { color: var(--cplv-muted); }
body .cplv-balance__sum {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--cplv-ok);
}
body .cplv-balance__sum--due { color: var(--cplv-danger); }

/* ---- язык ----
   Кнопка — один знак; какой язык выбран, видно в списке: галочка и полный
   контраст подписи. Пустой знак у остальных пунктов держит подписи в одной
   колонке, поэтому список не «съезжает» на строке текущего языка. */
body .navbar .cplv-lang-btn .material-icons { color: var(--cplv-muted); }
body .navbar .cplv-lang-btn:hover .material-icons,
body .navbar .cplv-lang-btn[aria-expanded="true"] .material-icons { color: var(--cplv-ink); }
body .cplv-lang-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
}
body .cplv-lang-menu .cplv-lang__tick {
    font-size: 18px;
    width: 18px;
    flex: 0 0 18px;
    color: var(--cplv-accent) !important;
}
body .cplv-lang-menu .cplv-lang--current {
    font-weight: 600;
    color: var(--cplv-ink) !important;
    background-color: var(--cplv-surface-2);
}
/* Тот же список в бургер-меню телефона: там подсветка идёт цветами меню. */
body .sidebar .nav-link.cplv-lang--current,
body .sidebar .nav-link.cplv-lang--current span {
    color: var(--cplv-nav-ink) !important;
    font-weight: 600;
}

/* ---- выход в конце левого меню ----
   Отделён чертой: это не раздел панели, а конец работы. */
body .sidebar .cplv-nav-exit {
    margin-top: 18px;
    padding-top: 10px;
    border-top: 1px solid var(--cplv-nav-line);
}

/* Полоса, где остались одни кнопки действий (список доменов — фильтры оттуда
   убраны): ряд прижимается вправо и не занимает высоту полосы вкладок. */
body .nav-tabs-wrapper:not(:has(a.nav-link)) {
    overflow: visible;
    margin: 0 0 18px;
    border: 0;
}
body .nav-tabs-wrapper:not(:has(a.nav-link)) > ul.nav-tabs {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: wrap !important;
    gap: 10px;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    list-style: none;
}
body .nav-tabs-wrapper:not(:has(a.nav-link)) ul.nav { display: flex; gap: 10px; margin: 0; padding: 0; list-style: none; }
body .nav-tabs-wrapper:not(:has(a.nav-link)) li { margin: 0; padding: 0; list-style: none; background: none; }
body .nav-tabs-wrapper:not(:has(a.nav-link)) .btn { margin-left: 0 !important; }

/* Подпись под номером счёта — за что он выставлен. Описание позиции HostBill
   пишет целиком («Регистрация домена: … Период: 1 Год/а»), и в две строки оно
   ломает высоту строки списка: держим одну строку с многоточием. */
body .invoices-table .cplv-row-sub {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
body .invoices-table .cplv-row-title { min-width: 0; }
/* На телефоне одной строки мало: от «VPS - Standard 1 618264.vps (04/10/2026 -
   03/11/2026)» в 313 px оставалось «VPS - Standard 1 618264.vp…», то есть
   пропадало главное — за какую машину и за какой период счёт. Разрешаем две
   строки: высота списка подрастает на строку, зато счёт опознаётся.
   Найдено при обходе мобильной версии 04.10.2026. */
@media (max-width: 767px) {
    body .invoices-table .cplv-row-sub {
        white-space: normal;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        line-height: 1.35;
    }
}

/* ============================================================================
   ФИЛЬТР СПИСКОВ (счета, кредит-ноты)
   ============================================================================
   Механика — темина: `data-sorter-select` при изменении шлёт ajax и заменяет
   тело списка, `#filter-reset` очищает все поля разом. Здесь только вид и то,
   чего в стоке не хватало: подпись у каждого поля, состояние кнопки сброса,
   счётчик включённых условий и строка результата. Без них фильтр работал
   молча — список менялся, а сказать об этом было некому (замечание владельца
   31.08.2026, new-desing/filter.png). */

body .cplv-filters {
    margin: 0 0 22px;
    padding: 20px 22px;
}
body .cplv-filters__row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    align-items: end;
    gap: 14px 18px;
}
/* Поле выбора услуги длиннее прочих: в нём и номер, и категория, и домен. */
body .cplv-filters__field--wide { grid-column: span 2; }
body .cplv-filters .cplv-field__label {
    font-size: 13px;
    line-height: 1.2;
}
body .cplv-filters select.form-control {
    height: 42px;
    padding: 0 38px 0 14px;
    font-size: 14px;
    /* Свой знак раскрытия: браузерная стрелка в тёмной теме остаётся чёрной. */
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 18px 18px;
}
body .cplv-filters__reset {
    height: 42px;
    align-self: end;
    white-space: nowrap;
}
/* Пока ничего не выбрано, сбрасывать нечего — кнопка молчит. */
body .cplv-filters__reset[disabled] {
    opacity: .55;
    pointer-events: none;
}
body .cplv-filters__note {
    margin: 14px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--cplv-line);
    font-size: 14px;
    color: var(--cplv-muted);
}
body .cplv-filters__note--empty { color: var(--cplv-ink); }

/* Кнопка, раскрывающая панель. Счётчик показывает, сколько условий включено:
   свёрнутая панель иначе прячет причину, по которой список короткий. */
body .cplv-filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
body .cplv-filter-toggle > .material-icons {
    font-size: 18px;
    margin: 0 !important;
}
body .cplv-filter-toggle.shown,
body .cplv-filter-toggle.cplv-filter-toggle--on {
    border-color: var(--cplv-accent) !important;
    color: var(--cplv-ink) !important;
}
body .cplv-filter-toggle__count {
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    background: var(--cplv-accent);
    color: var(--cplv-on-accent);
    font-size: 12px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}

/* ============================================================================
   СПИСОК КАТЕГОРИЙ ПОД КНОПКОЙ «ЗАКАЗАТЬ»
   ============================================================================
   Категория — плитка во всю ширину колонки: нажимается вся, а не одно слово
   (замечание владельца 31.08.2026). Знак в тонированном квадрате отличает вид
   услуги с одного взгляда; тона здесь ничего не «сообщают», поэтому взяты
   спокойные и разные — иначе весь список выходил одинаково зелёным. */

body .dropdown-menu.cplv-order-menu {
    min-width: 520px;
    max-width: min(680px, calc(100vw - 32px));
    padding: 18px;
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius) !important;
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow-hover);
}
body .cplv-order-menu__head {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--cplv-muted);
    padding: 0 4px 10px;
}
body .cplv-order-menu__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 8px;
}
body .cplv-order-cat {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 10px;
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink) !important;
    text-decoration: none;
    min-height: 56px;
}
body .cplv-order-cat:hover,
body .cplv-order-cat:focus {
    background: var(--cplv-surface-2);
    text-decoration: none;
}
body .cplv-order-cat:focus-visible { outline: 2px solid var(--cplv-accent); outline-offset: 2px; }
body .cplv-order-cat__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    border-radius: 10px;
}
body .cplv-order-cat__icon .material-icons { font-size: 20px; color: inherit !important; }
body .cplv-order-cat__icon--accent { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
body .cplv-order-cat__icon--info { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
body .cplv-order-cat__icon--violet { background: rgba(107, 79, 160, .12); color: var(--cplv-violet); }
body .cplv-order-cat__icon--warn { background: rgba(138, 106, 21, .12); color: var(--cplv-warn); }
body .cplv-order-cat__icon--teal { background: rgba(46, 125, 120, .12); color: var(--cplv-teal); }
body .cplv-order-cat__icon--rose { background: rgba(160, 74, 111, .12); color: var(--cplv-rose); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--accent,
:root[data-theme="dark"] .cplv-order-cat__icon--accent { background: rgba(156, 205, 126, .14); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--info,
:root[data-theme="dark"] .cplv-order-cat__icon--info { background: rgba(127, 182, 224, .14); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--violet,
:root[data-theme="dark"] .cplv-order-cat__icon--violet { background: rgba(179, 154, 224, .14); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--warn,
:root[data-theme="dark"] .cplv-order-cat__icon--warn { background: rgba(201, 162, 39, .14); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--teal,
:root[data-theme="dark"] .cplv-order-cat__icon--teal { background: rgba(127, 208, 201, .14); }
:root:not([data-theme="light"]) .cplv-order-cat__icon--rose,
:root[data-theme="dark"] .cplv-order-cat__icon--rose { background: rgba(227, 154, 184, .14); }
body .cplv-order-cat__title {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.25;
    min-width: 0;
}

/* Два действия разного веса: каталог смотрят, в корзину идут платить. */
body .cplv-order-menu__foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--cplv-line);
}
body .cplv-order-menu__foot .btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 18px;
}
body .cplv-order-menu__foot .btn > .material-icons { font-size: 18px; margin: 0 !important; }
body .cplv-order-menu__foot .badge {
    background: rgba(255, 255, 255, .22);
    color: inherit;
    font-weight: 700;
}

@media (max-width: 575px) {
    body .dropdown-menu.cplv-order-menu { min-width: 0; width: calc(100vw - 24px); }
    body .cplv-order-menu__grid { grid-template-columns: 1fr; }
    body .cplv-order-menu__foot { flex-direction: column-reverse; align-items: stretch; }
}

/* ============================================================================
   КОРЗИНА (второй шаг заказа)
   ============================================================================
   Главное действие — «Оформить заказ» — стоит и над сводкой, и под ней: до
   правки оно было только внизу, за списком позиций, способами оплаты, данными
   клиента и заметками (замечание владельца 31.08.2026). Рядом мелкими —
   «Продолжить покупки» и «Очистить корзину»: это отходы в сторону, а не
   развилка равных дорог, поэтому и размер у них другой. */

body .cplv-cart-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}
body .cplv-cart-head__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
body .cplv-cart-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 24px 0 32px;
}
body .cplv-cart-foot__go { margin-left: auto; }

/* Мелкое второстепенное действие: контур, приглушённый текст, высота 34. */
body .btn.cplv-cart-mini {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius-sm) !important;
    background: transparent !important;
    color: var(--cplv-muted) !important;
    font-size: 13px;
    font-weight: 600;
}
body .btn.cplv-cart-mini:hover {
    color: var(--cplv-ink) !important;
    border-color: var(--cplv-line-strong) !important;
    background: var(--cplv-surface-2) !important;
}
body .btn.cplv-cart-mini > .material-icons { font-size: 16px; margin: 0 !important; }
/* Очистка корзины — единственное здесь необратимое действие: цвет появляется
   только при наведении, чтобы кнопка не кричала на каждом заходе. */
body .btn.cplv-cart-mini--danger:hover {
    color: var(--cplv-danger) !important;
    border-color: var(--cplv-danger) !important;
    background: transparent !important;
}

body .btn.cplv-cart-checkout {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 22px;
    border-radius: var(--cplv-radius-sm) !important;
    background: var(--cplv-accent) !important;
    border-color: var(--cplv-accent) !important;
    color: var(--cplv-on-accent) !important;
    font-size: 15px;
    font-weight: 600;
}
body .btn.cplv-cart-checkout:hover,
body .btn.cplv-cart-checkout:focus {
    background: var(--cplv-accent-hover) !important;
    border-color: var(--cplv-accent-hover) !important;
    color: var(--cplv-on-accent) !important;
}
body .btn.cplv-cart-checkout > .material-icons { font-size: 18px; margin: 0 !important; }

/* Список способов оплаты в корзине: строки одной высоты вместо ряда мелких
   переключателей по центру — по ним трудно попасть и не видно, что выбрано.
   Порядок и марки — те же, что на странице счёта. */
body .cart-gateway-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
body .cplv-gw {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    padding: 10px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    font-size: 15px;
    cursor: pointer;
}
body .cplv-gw:hover { border-color: var(--cplv-line-strong); background: var(--cplv-surface-2); }
body .cplv-gw.is-active { border-color: var(--cplv-accent); }
body .cplv-gw input[type="radio"] { margin: 0; width: 18px; height: 18px; accent-color: var(--cplv-accent); }
body .cplv-gw__name { font-weight: 600; }
/* Марка на белой плашке: фирменные цвета на тёмной подложке тускнеют. */
body .cplv-gw__logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 76px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--cplv-line);
    border-radius: 8px;
    background: #ffffff;
}
body .cplv-gw__logotext { font-size: 13px; font-weight: 700; line-height: 1; }
body .cplv-gw__logo--plain {
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 15px;
    font-weight: 700;
    text-transform: uppercase;
}

/* ============================================================================
   ШИРОКИЕ ВЫПАДАЮЩИЕ ПАНЕЛИ: «ЗАКАЗАТЬ» И КОРЗИНА
   ============================================================================
   Макет владельца «Подменю на всю ширину экрана» (31.08.2026). Обе панели
   занимают всю рабочую область — от правого края меню до края окна, — делят
   одну сетку и один подвал: это одно и то же место экрана, и клиенту не нужно
   заново искать кнопку.

   ⚠️ Левый край и верх ставит cplv-panel.js по фактическому положению шапки:
   меню сворачивается кнопкой «скрыть панель», и фиксированные числа здесь
   разъезжаются. CSS задаёт только вид и поведение. */

body .cplv-wm__overlay {
    position: fixed;
    inset: 0;
    z-index: 1010;
    background: rgba(16, 32, 24, .30);
    opacity: 0;
    transition: opacity .16s ease-out;
}
body .cplv-wm__overlay.is-open { opacity: 1; }

body .cplv-wm {
    position: fixed;
    z-index: 1020;
    background: var(--cplv-surface);
    border-bottom: 1px solid var(--cplv-line);
    box-shadow: 0 26px 50px rgba(16, 32, 24, .16);
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity .16s ease-out, transform .16s ease-out;
    max-height: calc(100vh - 74px);
    overflow-y: auto;
}
body .cplv-wm.is-open { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
    body .cplv-wm, body .cplv-wm__overlay { transition: none; }
}

body .cplv-wm__head {
    padding: 24px 32px 14px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}

body .cplv-wm__grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 16px;
    padding: 8px 32px 32px;
}

/* ---- плитка категории ---- */
body .cplv-wm__tile,
body .cplv-wm__cell {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 95px;
    padding: 0 20px;
    border-radius: 14px;
    color: var(--cplv-ink) !important;
    text-decoration: none !important;
    min-width: 0;
}
body .cplv-wm__tile {
    transition: transform .15s ease, box-shadow .15s ease;
    background: var(--cplv-surface-2);
}
body .cplv-wm__tile:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(20, 40, 30, .14); }
body .cplv-wm__tile:focus-visible,
body .cplv-wm__cell-del:focus-visible,
body .cplv-wm__cta:focus-visible,
body .cplv-wm__side:focus-visible { outline: 2px solid var(--cplv-accent); outline-offset: 2px; }

body .cplv-wm__tile-ic,
body .cplv-wm__cell-ic {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; flex: 0 0 40px;
    border-radius: 11px;
    color: #fff;
}
body .cplv-wm__tile-ic .material-icons,
body .cplv-wm__cell-ic .material-icons { font-size: 20px; color: inherit !important; }
/* Иконки контурные (макет владельца: «пустые внутри»): рисуются штрихом
   currentColor, поэтому цвет им задаёт сама плашка. */
body .cplv-wm__tile-ic svg,
body .cplv-wm__cell-ic svg,
body .cplv-wm__cell-plus svg,
body .cplv-wm__sum-ic svg,
body .cplv-wm__side svg,
body .cplv-wm__cta svg,
body .cplv-wm__cell-del svg { display: block; }
body .cplv-wm__side svg,
body .cplv-wm__cta svg { flex: 0 0 auto; }
body .cplv-wm__tile-txt, body .cplv-wm__cell-txt { min-width: 0; }
/* Длинные названия («Администрирование», «Выделенные серверы») переносятся,
   а не упираются в край плитки: обрезать название категории нельзя — по нему
   её и выбирают. */
body .cplv-wm__tile-name {
    display: block; font-size: 16px; font-weight: 700; line-height: 1.2;
    /* ⚠️ Перенос по слогам, а не по буквам: «Администрирование» — одно длинное
       слово, и `anywhere` рвал его посреди буквы («Администрировани / е»).
       Язык страницы выставлен, поэтому браузер переносит правильно. */
    hyphens: auto; -webkit-hyphens: auto;
    overflow-wrap: break-word; text-wrap: pretty;
}
body .cplv-wm__tile-sub {
    display: block; margin-top: 2px; font-size: 12px; color: var(--cplv-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Тона плиток — те же шесть, что в списке категорий: подложка мягкая, знак
   полновесный. В тёмной теме подложка гасится, иначе она светит пятном. */
body .cplv-wm__tile--accent { background: rgba(63, 143, 87, .12); }
body .cplv-wm__tile--info { background: rgba(47, 111, 159, .12); }
body .cplv-wm__tile--violet { background: rgba(107, 79, 160, .12); }
body .cplv-wm__tile--warn { background: rgba(138, 106, 21, .12); }
body .cplv-wm__tile--teal { background: rgba(46, 125, 120, .12); }
body .cplv-wm__tile--rose { background: rgba(160, 74, 111, .12); }
body .cplv-wm__tile--accent .cplv-wm__tile-ic { background: var(--cplv-accent); color: var(--cplv-on-accent); }
body .cplv-wm__tile--info .cplv-wm__tile-ic { background: var(--cplv-info); }
body .cplv-wm__tile--violet .cplv-wm__tile-ic { background: var(--cplv-violet); }
body .cplv-wm__tile--warn .cplv-wm__tile-ic { background: var(--cplv-warn); }
body .cplv-wm__tile--teal .cplv-wm__tile-ic { background: var(--cplv-teal); }
body .cplv-wm__tile--rose .cplv-wm__tile-ic { background: var(--cplv-rose); }
:root:not([data-theme="light"]) .cplv-wm__tile--accent,
:root[data-theme="dark"] .cplv-wm__tile--accent { background: rgba(156, 205, 126, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile--info,
:root[data-theme="dark"] .cplv-wm__tile--info { background: rgba(127, 182, 224, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile--violet,
:root[data-theme="dark"] .cplv-wm__tile--violet { background: rgba(179, 154, 224, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile--warn,
:root[data-theme="dark"] .cplv-wm__tile--warn { background: rgba(201, 162, 39, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile--teal,
:root[data-theme="dark"] .cplv-wm__tile--teal { background: rgba(127, 208, 201, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile--rose,
:root[data-theme="dark"] .cplv-wm__tile--rose { background: rgba(227, 154, 184, .12); }
:root:not([data-theme="light"]) .cplv-wm__tile-ic,
:root[data-theme="dark"] .cplv-wm__tile-ic { color: var(--cplv-bg); }

/* ---- ячейки корзины ---- */
body .cplv-wm__cell { background: var(--cplv-surface-2); }
body .cplv-wm__cell-ic { background: var(--cplv-violet); }
/* Знак уведомления — зелёный, как кнопки панели (решение владельца
   01.09.2026): фиолетовый квадрат в списке уведомлений читался как чужой,
   ни с чем в панели не связанный цвет. У ячеек корзины он остаётся —
   там он отличает товар от действия. */
body .cplv-wm__cell-ic--accent { background: var(--cplv-accent); color: var(--cplv-on-accent) !important; }
body .cplv-wm__tile-ic--violet { background: var(--cplv-violet); }
body .cplv-wm__tile-ic--warn { background: var(--cplv-warn); }
body .cplv-wm__cell-name { display: block; font-size: 15px; font-weight: 700; line-height: 1.25;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body .cplv-wm__cell-price {
    display: block; margin-top: 2px;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px; font-weight: 600; color: var(--cplv-accent);
}
body .cplv-wm__cell-del {
    margin-left: auto; display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; flex: 0 0 32px; border-radius: 8px;
    color: var(--cplv-muted) !important;
}
body .cplv-wm__cell-del:hover { color: var(--cplv-danger) !important; background: var(--cplv-surface); }
body .cplv-wm__cell--empty { color: var(--cplv-muted); font-size: 14px; grid-column: span 2; }

body .cplv-wm__cell--add {
    background: transparent;
    border: 1px dashed var(--cplv-line-strong);
    color: var(--cplv-muted) !important;
    font-size: 14px; font-weight: 600;
}
body .cplv-wm__cell--add:hover { color: var(--cplv-ink) !important; border-color: var(--cplv-accent); }
body .cplv-wm__cell-plus {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; flex: 0 0 34px; border-radius: 9px;
    background: var(--cplv-surface-2); color: var(--cplv-accent);
}
body .cplv-wm__cell-plus .material-icons { font-size: 20px; color: inherit !important; }

body .cplv-wm__cell--promo { background: rgba(63, 143, 87, .10); gap: 10px; }
:root:not([data-theme="light"]) .cplv-wm__cell--promo,
:root[data-theme="dark"] .cplv-wm__cell--promo { background: rgba(156, 205, 126, .10); }
body .cplv-wm__promo-label {
    margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .12em;
    text-transform: uppercase; color: var(--cplv-muted); white-space: nowrap;
}
body .cplv-wm__promo-input {
    flex: 1 1 auto; min-width: 0; height: 42px;
    padding: 0 14px; border: 1px solid var(--cplv-line); border-radius: 9px;
    background: var(--cplv-bg); color: var(--cplv-ink); font: inherit; font-size: 14px;
}
body .cplv-wm__promo-input:focus { outline: none; border-color: var(--cplv-accent); box-shadow: var(--cplv-glow); }

/* ---- подвал ---- */
body .cplv-wm__foot {
    display: flex; align-items: center; justify-content: space-between; gap: 22px;
    padding: 22px 32px 20px;
    background: var(--cplv-surface-2);
    border-top: 1px solid var(--cplv-line);
}
body .cplv-wm__side {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 15px; font-weight: 700; white-space: nowrap;
    color: var(--cplv-accent) !important; text-decoration: none !important;
}
body .cplv-wm__side .material-icons { font-size: 18px; }
body .cplv-wm__side--danger { color: var(--cplv-danger) !important; }
body .cplv-wm__foot-right { display: flex; align-items: center; gap: 22px; }
body .cplv-wm__cta {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 14px 24px; border-radius: 12px;
    background: var(--cplv-accent); color: var(--cplv-on-accent) !important;
    font-size: 16px; font-weight: 700; white-space: nowrap; text-decoration: none !important;
    box-shadow: 0 8px 20px rgba(31, 107, 69, .26);
}
body .cplv-wm__cta:hover { background: var(--cplv-accent-hover); }
body .cplv-wm__cta .material-icons { font-size: 18px; }
body .cplv-wm__sum { display: flex; align-items: center; gap: 10px; }
body .cplv-wm__sum-ic {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; flex: 0 0 44px; border-radius: 12px;
    background: rgba(63, 143, 87, .12); color: var(--cplv-accent);
}
:root:not([data-theme="light"]) .cplv-wm__sum-ic,
:root[data-theme="dark"] .cplv-wm__sum-ic { background: rgba(156, 205, 126, .12); }
body .cplv-wm__sum-ic .material-icons { font-size: 20px; color: inherit !important; }
body .cplv-wm__sum-label {
    display: block; font-size: 12px; font-weight: 800; letter-spacing: .12em;
    text-transform: uppercase; color: var(--cplv-muted);
}
body .cplv-wm__sum-value {
    display: block;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 30px; font-weight: 700; line-height: 1.1; color: var(--cplv-ink);
    font-variant-numeric: tabular-nums;
}

/* Активный триггер: кнопка заказа остаётся зелёной, ячейка корзины заливается. */
body .cplv-cart-btn.is-open { background: var(--cplv-accent); }
body .cplv-cart-btn.is-open .material-icons { color: var(--cplv-on-accent) !important; }

/* ---- ширины ---- */
@media (max-width: 1439px) { body .cplv-wm__grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 1199px) {
    body .cplv-wm__grid { grid-template-columns: repeat(3, 1fr); padding-left: 24px; padding-right: 24px; }
    body .cplv-wm__head, body .cplv-wm__foot { padding-left: 24px; padding-right: 24px; }
}
@media (max-width: 1023px) {
    body .cplv-wm__grid { grid-template-columns: repeat(2, 1fr); }
    body .cplv-wm__foot { flex-wrap: wrap; gap: 16px; }
}
@media (max-width: 767px) {
    /* На телефоне это уже не выпадашка, а лист во весь экран: сеткой в одну
       колонку по нему проходят большим пальцем, подвал прилипает к низу. */
    body .cplv-wm {
        position: fixed !important;
        inset: 0 !important;
        max-height: none;
        border-radius: 0;
    }
    body .cplv-wm__grid { grid-template-columns: 1fr; padding-bottom: 24px; }
    body .cplv-wm__tile, body .cplv-wm__cell { height: 72px; }
    body .cplv-wm__foot {
        position: sticky; bottom: 0;
        flex-direction: column-reverse; align-items: stretch;
    }
    body .cplv-wm__foot-right { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
    body .cplv-wm__cta { justify-content: center; }
    body .cplv-wm__side { justify-content: center; min-height: 44px; }
}

/* ============================================================================
   ЕДИНЫЙ НАБОР ИКОНОК — КОНТУРНЫЙ
   ============================================================================
   Тема несёт локальный Material Icons: он весь залитый, и значки в шапке
   выглядели тяжёлыми пятнами (макет владельца icon-top-meny.png). Material
   Symbols — тот же набор имён, но вариативный, и при FILL 0 рисует контур.
   Подменяем семейство у .material-icons целиком, поэтому контурными
   становятся и значки, которые рисует закрытый код HostBill.
   ⚠️ Локальный Material Icons оставлен вторым в стеке: имени, которого в
   Symbols нет, иначе достался бы вид голого слова. */
body .material-icons,
body i.material-icons,
body .material-icons.notranslate {
    font-family: "Material Symbols Outlined", "Material Icons" !important;
    font-variation-settings: "FILL" 0, "wght" 300, "GRAD" 0, "opsz" 24;
    font-weight: normal;
    font-style: normal;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    direction: ltr;
    -webkit-font-feature-settings: "liga";
    -webkit-font-smoothing: antialiased;
}

/* ============================================================================
   КАТАЛОГ УСЛУГ (/studio/products/)
   ============================================================================
   Карточки категорий получили тот же знак и тот же тон, что плитки в меню
   «Заказать» (решение владельца 31.08.2026): человек видит одну и ту же
   категорию в двух местах панели и должен узнавать её по цвету, а не читать
   заново. Иконки из настроек категории не подходят — у cp.lv они не заданы
   ни у одной, и карточки стояли голыми. */

body .cplv-prod {
    background: var(--cplv-surface) !important;
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius) !important;
    box-shadow: var(--cplv-shadow);
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
body .cplv-prod:hover { transform: translateY(-2px); box-shadow: var(--cplv-shadow-hover); }
body .cplv-prod__body { display: flex; align-items: flex-start; gap: 16px; padding: 22px 22px 16px; }
body .cplv-prod__ic { width: 44px; height: 44px; flex: 0 0 44px; border-radius: 12px; }
body .cplv-prod__txt { min-width: 0; }
body .cplv-prod__name {
    display: block; font-size: 18px; font-weight: 700; line-height: 1.25;
    color: var(--cplv-ink) !important; text-decoration: none !important;
}
body .cplv-prod__name:hover { color: var(--cplv-accent) !important; }
body .cplv-prod__desc { margin: 6px 0 0; font-size: 14px; line-height: 1.5; color: var(--cplv-muted); }

/* Тон — как у плиток меню: подложка мягкая, знак полновесный. */
body .cplv-prod__ic--accent { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
body .cplv-prod__ic--info { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
body .cplv-prod__ic--violet { background: rgba(107, 79, 160, .12); color: var(--cplv-violet); }
body .cplv-prod__ic--warn { background: rgba(138, 106, 21, .12); color: var(--cplv-warn); }
body .cplv-prod__ic--teal { background: rgba(46, 125, 120, .12); color: var(--cplv-teal); }
body .cplv-prod__ic--rose { background: rgba(160, 74, 111, .12); color: var(--cplv-rose); }
:root:not([data-theme="light"]) .cplv-prod__ic--accent,
:root[data-theme="dark"] .cplv-prod__ic--accent { background: rgba(156, 205, 126, .14); }
:root:not([data-theme="light"]) .cplv-prod__ic--info,
:root[data-theme="dark"] .cplv-prod__ic--info { background: rgba(127, 182, 224, .14); }
:root:not([data-theme="light"]) .cplv-prod__ic--violet,
:root[data-theme="dark"] .cplv-prod__ic--violet { background: rgba(179, 154, 224, .14); }
:root:not([data-theme="light"]) .cplv-prod__ic--warn,
:root[data-theme="dark"] .cplv-prod__ic--warn { background: rgba(201, 162, 39, .14); }
:root:not([data-theme="light"]) .cplv-prod__ic--teal,
:root[data-theme="dark"] .cplv-prod__ic--teal { background: rgba(127, 208, 201, .14); }
:root:not([data-theme="light"]) .cplv-prod__ic--rose,
:root[data-theme="dark"] .cplv-prod__ic--rose { background: rgba(227, 154, 184, .14); }
/* ⚠️ Плитки меню красят свой знак в белый (там подложка сплошная) — здесь
   подложка мягкая, поэтому цвет знака перебиваем обратно на цвет тона. */
body .cplv-prod__ic svg { color: inherit; }

/* Подвал карточки: цена слева, действие справа, на одной линии. */
body .cplv-prod .card-footer {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 14px 22px 20px;
    background: transparent !important;
    border-top: 1px solid var(--cplv-line) !important;
}
body .cplv-prod .section-product-card-price { font-size: 14px; color: var(--cplv-muted); }
body .cplv-prod .section-product-card-price b { color: var(--cplv-ink); font-size: 16px; }

/* ============================================================================
   КАРТОЧКА VPS — все состояния услуги
   ============================================================================
   Макет: Claude Design «VPS Card States» (A1–A7, B1–B5, C1–C2). Значения взяты
   из него один в один: карточка 12/20, плитка 64 высотой и радиусом 8, сетка
   1.5fr + четыре равные, подписи 12/700 капсом, значения моношириной 15/600.

   Правило макета, которое здесь главное: где метрик нет — строка-объяснение с
   действием, а не пустое место; зелёная кнопка в карточке ровно одна. */

.cplv-vpslist { display: flex; flex-direction: column; gap: 22px; }
.cplv-vpslist__count { font-size: 13.5px; color: var(--cplv-muted); margin-bottom: 2px; }

.cplv-vps {
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: 12px;
    box-shadow: var(--cplv-shadow);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Закрытая услуга приглушена целиком: она в списке ради истории, а не работы. */
.cplv-vps--terminated { opacity: .78; }

.cplv-vps__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cplv-vps__dot { flex: none; width: 11px; height: 11px; border-radius: 50%; background: var(--cplv-muted); }
.cplv-vps__dot--ok { background: var(--cplv-ok); }
.cplv-vps__dot--warn { background: var(--cplv-warn); }
.cplv-vps__dot--danger { background: var(--cplv-danger); }
/* Пульсация — только пока идёт задача: это единственное состояние, которое
   меняется само и за которым имеет смысл следить. */
.cplv-vps.is-busy .cplv-vps__dot { background: var(--cplv-accent); animation: cplvDot 2.2s ease-out infinite; }
@keyframes cplvDot {
    0%, 100% { box-shadow: 0 0 0 0 rgba(63, 143, 87, .45); }
    70% { box-shadow: 0 0 0 9px rgba(63, 143, 87, 0); }
}
@media (prefers-reduced-motion: reduce) { .cplv-vps.is-busy .cplv-vps__dot { animation: none; } }

body a.cplv-vps__name {
    font-size: 17px; font-weight: 700; letter-spacing: -.01em;
    color: var(--cplv-ink) !important; text-decoration: none !important;
}
body a.cplv-vps__name:hover { color: var(--cplv-accent) !important; }
.cplv-vps__state { font-size: 14px; font-weight: 600; color: var(--cplv-muted); }
.cplv-vps__state--ok { color: var(--cplv-ok); }
.cplv-vps__state--warn { color: var(--cplv-warn); }
.cplv-vps__state--danger { color: var(--cplv-danger); }
.cplv-vps__facts {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px; color: var(--cplv-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 46ch;
}
.cplv-vps__hint { font-size: 13px; color: var(--cplv-muted); }
.cplv-vps__gap { flex: 1; }

body a.cplv-vps__act,
.cplv-vps__act {
    display: inline-flex; align-items: center; justify-content: center;
    height: 40px; padding: 0 18px;
    border: 1px solid var(--cplv-line-strong); border-radius: 8px;
    font-size: 14px; font-weight: 600; white-space: nowrap;
    color: var(--cplv-ink) !important; text-decoration: none !important;
}
body a.cplv-vps__act:hover { border-color: var(--cplv-accent); color: var(--cplv-accent) !important; }
/* Действие, которого сейчас нет: кнопка на месте, но приглушена — так видно,
   что оно вернётся, а не исчезло навсегда. */
.cplv-vps__act--off { border-color: var(--cplv-line); color: var(--cplv-muted) !important; cursor: not-allowed; }

/* ---- плитки ---- */
/* Последняя колонка (трафик) шире остальных: в ней два числа с единицами,
   и в равной доле строка не помещалась. */
.cplv-vps__tiles { display: grid; grid-template-columns: 1.5fr repeat(3, 1fr) 1.45fr; gap: 10px; }
.cplv-vps.is-busy .cplv-vps__tiles { opacity: .6; pointer-events: none; }
body .cplv-vps__tile {
    display: flex; align-items: center; gap: 10px;
    height: 64px; padding: 0 16px;
    border-radius: 8px; background: var(--cplv-surface-2); border: 1px solid var(--cplv-line);
    color: var(--cplv-ink) !important; text-decoration: none !important;
    min-width: 0;
}
.cplv-vps__tile-ic {
    flex: none; width: 32px; height: 32px; border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    background: var(--cplv-surface); border: 1px solid var(--cplv-line); color: var(--cplv-ink);
}
.cplv-vps__tile-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cplv-vps__tile-label {
    font-size: 12px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--cplv-muted);
}
.cplv-vps__tile-value {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 15px; font-weight: 600; color: var(--cplv-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Доступ к машине — единственная плитка-действие, поэтому она в контуре
   акцента, а не в общей заливке. */
body a.cplv-vps__tile--kvm {
    background: transparent; border: 1.5px solid var(--cplv-accent); padding: 0 18px;
}
body a.cplv-vps__tile--kvm:hover { background: var(--cplv-surface-2); }
.cplv-vps__tile--kvm .cplv-vps__tile-ic { background: transparent; border: 0; color: var(--cplv-accent); }
.cplv-vps__tile--kvm .cplv-vps__tile-value {
    font-family: inherit; font-size: 16px; font-weight: 700;
    color: var(--cplv-accent); letter-spacing: -.01em;
}
/* Выключенная машина: вместо доступа — включение, единственная цветная кнопка. */
body a.cplv-vps__tile--power {
    background: var(--cplv-accent); border-color: var(--cplv-accent); padding: 0 18px;
}
body a.cplv-vps__tile--power:hover { background: var(--cplv-accent-hover); border-color: var(--cplv-accent-hover); }
.cplv-vps__tile--power .cplv-vps__tile-ic { background: rgba(255, 255, 255, .16); border: 0; color: var(--cplv-on-accent); }
.cplv-vps__tile--power .cplv-vps__tile-label { color: var(--cplv-on-accent); opacity: .72; }
.cplv-vps__tile--power .cplv-vps__tile-value {
    font-family: inherit; font-size: 16px; font-weight: 700; color: var(--cplv-on-accent);
}
/* Значение, которого нет: прочерк приглушён — так видно, что это не ноль. */
.cplv-vps__tile-value.is-dash { color: var(--cplv-muted); }

/* Трафик — единственная плитка с ДВУМЯ числами и двумя единицами
   («↓ 9.75 MB · ↑ 378.36 KB»): при общем кегле 15 строке нужно 207 px, а
   в колонке её 129 — значение обрывалось многоточием. Поэтому здесь кегль
   меньше, колонка шире остальных, а строке разрешено переноситься: рвётся
   она только по разделителю «·» (внутри пар стоят неразрывные пробелы),
   и на узком экране вместо обрезанного числа получаются две строки. */
.cplv-vps__tile[data-cplv-stat="net"] .cplv-vps__tile-value {
    font-size: 13px;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.15;
}

/* ---- строка-объяснение ---- */
.cplv-vps__explain {
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    padding: 14px 16px; border-radius: 8px;
    background: var(--cplv-surface-2); border: 1px solid var(--cplv-line);
}
.cplv-vps__explain--dashed { border-style: dashed; }
.cplv-vps__explain-txt { font-size: 14px; color: var(--cplv-muted); }
body a.cplv-vps__btn {
    display: inline-flex; align-items: center; justify-content: center;
    height: 40px; padding: 0 18px; border-radius: 8px;
    border: 1px solid var(--cplv-line-strong);
    font-size: 14px; font-weight: 600; white-space: nowrap;
    color: var(--cplv-ink) !important; text-decoration: none !important;
}
body a.cplv-vps__btn:hover { border-color: var(--cplv-accent); color: var(--cplv-accent) !important; }
body a.cplv-vps__btn--accent {
    background: var(--cplv-accent); border-color: var(--cplv-accent);
    color: var(--cplv-on-accent) !important;
}
body a.cplv-vps__btn--accent:hover {
    background: var(--cplv-accent-hover); border-color: var(--cplv-accent-hover);
    color: var(--cplv-on-accent) !important;
}

/* ---- полоса подготовки (машина создаётся) ---- */
.cplv-vps__prep {
    display: flex; align-items: center; gap: 20px;
    padding: 14px 16px; border-radius: 8px;
    background: var(--cplv-surface-2); border: 1px solid var(--cplv-line);
}
.cplv-vps__prep-txt { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.cplv-vps__prep-label { font-size: 13.5px; font-weight: 600; color: var(--cplv-ink); }
.cplv-vps__prep-track { display: block; height: 6px; border-radius: 3px; background: var(--cplv-line); overflow: hidden; }
.cplv-vps__prep-fill { display: block; height: 100%; border-radius: 3px; background: var(--cplv-accent); }

@media (max-width: 991px) {
    .cplv-vps__tiles { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 575px) {
    .cplv-vps { padding: 16px; }
    .cplv-vps__tiles { grid-template-columns: 1fr; }
    .cplv-vps__explain { flex-direction: column; align-items: stretch; }
    .cplv-vps__facts { max-width: 100%; white-space: normal; }
}

/* У машины облака трафика в списке нет — модуль отдаёт его массивом, а не
   числом, и колонка показывала бы «Array». Плиток четыре, сетка равняется
   по ним. */
.cplv-vps__tiles--4 { grid-template-columns: 1.5fr repeat(3, 1fr); }

/* Строка над списком услуг: счёт слева, отбор справа. */
.cplv-vpslist__bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 2px;
}
.cplv-vpslist__tabs { display: flex; gap: 8px; }
body .cplv-vpslist__tab {
    display: inline-flex; align-items: center; height: 32px; padding: 0 10px;
    border: 1px solid var(--cplv-line); border-radius: 8px;
    background: transparent; color: var(--cplv-muted);
    font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
body .cplv-vpslist__tab:hover { border-color: var(--cplv-line-strong); color: var(--cplv-ink); }
body .cplv-vpslist__tab.is-active {
    background: var(--cplv-surface); border-color: var(--cplv-line-strong); color: var(--cplv-ink);
}

/* ⚠️ Карточка сама по себе flex, а `display:flex` перебивает атрибут hidden —
   отбор по состоянию «скрывал» карточки, а они оставались на экране. */
.cplv-vps[hidden] { display: none !important; }

/* ============================================================================
   ГЛАВНАЯ: РАССТОЯНИЯ МЕЖДУ КАРТОЧКАМИ
   ============================================================================
   Карточки услуг на главной шли вплотную и читались как одна простыня
   (замечание владельца 31.08.2026). Расстояние то же, что в списке услуг, —
   12 px: одна и та же карточка не должна стоять по-разному в двух местах. */
.cplv-dash .cplv-vps + .cplv-vps { margin-top: 22px; }
.cplv-dash .cplv-box + .cplv-vps,
.cplv-dash .cplv-vps + .cplv-box { margin-top: 22px; }
.cplv-dash .cplv-vps:first-of-type { margin-top: 22px; }

/* Уведомления в широкой панели: строка — тема письма и дата, непрочитанное
   отмечено рамкой акцента. */
body .cplv-wm__cell-date {
    display: block; margin-top: 2px; font-size: 13px; color: var(--cplv-muted);
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
body .cplv-wm__cell--new { border: 1px solid var(--cplv-accent); }
body .cplv-note-btn.is-open { background: var(--cplv-accent); }
body .cplv-note-btn.is-open .material-icons { color: var(--cplv-on-accent) !important; }

/* Блок денег стоит на первом экране, под строкой опознания: отделяем его от
   разделов, чтобы он читался как отдельное сообщение, а не как их часть. */
/* Блок списания — такой же блок: общий шаг 22 сверху, снизу шаг задаёт
   следующий блок (иначе поле выходит наружу через .cplv-srv-top и склеивается). */
/* ⚠️ Отступ СНИЗУ блоку обязателен: ряд вкладок раздела идёт сразу за ним без
   собственного margin-top, и при `margin: 22px 0 0` блок счёта прилипал к вкладкам
   вплотную (замер: 0 px). Трижды принимали это за отступ между строками внутри
   блока и правили не то. Замечание владельца 04.10.2026. */
.cplv-srv-top .cplv-srv-billing { margin: 22px 0 22px; }

/* ============================================================================
   РАЗДЕЛ DNS  (услуга типа «dnsservice», все семь экранов)

   Разметку рисуют шаблоны ядра `templates/common/dnsmodules/tpl/*.tpl` —
   вёрстка 2013 года: таблицы с полосатыми строками, плитки-картинки, поля без
   подписей сверху. Хуков `$custom_overrides` у них нет, поэтому два экрана
   (список зон и записи зоны) правятся в самих шаблонах, а весь остальной вид
   задаётся отсюда.

   ⚠️ Все селекторы начинаются с `#dns-service` НЕ для порядка: свой style.css
   модуль подключает из `dnsmodules/clientarea.tpl`, то есть уже в теле
   страницы — позже нашего. При равной специфичности выигрывает он, и правило
   без id просто не доходит. Та же история, что со вкладками сервера.

   Макет: https://claude.ai/code/artifact/5131d5ec-2fb9-4e9a-b145-d8e0944e4fc6
   ============================================================================ */

/* ---- блок ---- */
#dns-service .wbox {
    margin: 0 0 22px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
    overflow: hidden;
}
#dns-service .wbox_header {
    padding: 14px 24px;
    border-bottom: 1px solid var(--cplv-line);
    background: transparent;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}
#dns-service .wbox_header strong { font-weight: 600; }
#dns-service .wbox_content { padding: 22px 24px; }

/* ---- строка действий над списком зон ----
   Плитки с картинками заменены карточками (разметка — в zones.tpl). Структура
   ul/li/a сохранена: по ней ходит скрипт модуля, включая и гасящий действия,
   пока не отмечена ни одна зона. */
#dns-service .icons {
    margin: 0 0 22px;
    padding: 20px 24px 24px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
}
#dns-service .icons .dwarrow {
    float: none;
    margin-bottom: 14px;
    background: none;
    /* ⚠️ !important здесь вынужденно: модуль сжимает подпись на -1px через
       собственный !important, и при 11px слова слипались в «СВЫБРАННЫМИДОМЕНАМИ». */
    letter-spacing: .08em !important;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}
#dns-service .icons > ul {
    display: grid;
    /* 200 px, а не 280: карточек здесь до шести, и на рабочей ширине они
       умещаются в одну строку. Не умещаются — переносятся сами. */
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 10px;
    float: none;
    margin: 0;
    padding: 0;
    list-style: none;
}
#dns-service .icons > ul > li {
    /* flex, а не block: карточка внутри тянется на всю высоту ячейки, и
       соседи в ряду не разъезжаются по высоте из-за длинной подписи. */
    display: flex;
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    list-style: none;
    text-align: left;
}
#dns-service .icons > ul > li > a {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    /* ⚠️ Карточка обязана занять ВСЮ ячейку сетки. Ячейки одинаковые, а сама
       карточка — флекс-элемент внутри li и без этого тянулась по своему
       содержимому: рядом стояли карточки разной ширины и с разными на вид
       отступами (замечание владельца 02.09.2026). */
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    padding: 13px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: 10px;
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    text-align: left;
    text-decoration: none;
}
#dns-service .icons > ul > li > a:hover {
    border-color: var(--cplv-line-strong);
    background: var(--cplv-bg);
    text-decoration: none;
}
/* Пока ни одна зона не отмечена, действие ничего не сделает — показываем это
   бледностью, а не тем же видом, что у рабочей карточки. */
#dns-service .icons > ul > li.disabled > a { opacity: .55; }
#dns-service .cplv-act__ic {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
#dns-service .cplv-act__ic svg { width: 18px; height: 18px; }
#dns-service .cplv-act__ic--accent { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
#dns-service .cplv-act__ic--info { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
:root:not([data-theme="light"]) #dns-service .cplv-act__ic--accent { background: rgba(156, 205, 126, .14); }
:root:not([data-theme="light"]) #dns-service .cplv-act__ic--info { background: rgba(127, 182, 224, .14); }
:root[data-theme="dark"] #dns-service .cplv-act__ic--accent { background: rgba(156, 205, 126, .14); }
:root[data-theme="dark"] #dns-service .cplv-act__ic--info { background: rgba(127, 182, 224, .14); }
#dns-service .cplv-act__title {
    display: block;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cplv-ink);
}
#dns-service .cplv-act__desc {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: var(--cplv-muted);
}

/* ---- списки вместо таблиц ----
   Таблицу превращаем в набор строк: колонок больше трёх не бывает, а на
   телефоне таблица всё равно не помещается. */
#dns-service table.display,
#dns-service table.dns-zones {
    display: block;
    width: 100%;
    margin: 0;
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow);
    overflow: hidden;
}
#dns-service table.display > thead,
#dns-service table.display > tbody,
#dns-service table.display > tfoot { display: block; }
/* ⚠️ Рамки задаём жёстко. У thead и tbody тема ставит свою светлую рамку
   (#ebecf0), а разделителям строк — цвет #e6eaf0; оба из светлой темы, и в
   тёмной это белые линии поперёк списка (замечание владельца 01.09.2026).
   Без !important наши правила проигрывают её цепочкам. */
#dns-service table.display > thead,
#dns-service table.display > tbody,
#dns-service table.display > tfoot { border: 0 !important; }
#dns-service table.display tr {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 24px;
    border: 0 !important;
    border-top: 1px solid var(--cplv-line) !important;
    background: transparent;
}
/* Заголовок списка — служебная строка, а не запись: отступы вдвое меньше,
   чем у строк с содержимым (замечание владельца 01.09.2026). */
#dns-service table.display > thead tr { padding-top: 10px; padding-bottom: 10px; }
#dns-service table.display > thead tr:first-child,
#dns-service table.display > tbody:first-of-type tr:first-child { border-top: 0 !important; }
#dns-service table.display tr.even,
#dns-service table.display tr.odd { background: transparent; }
/* ⚠️ Скрытие строки при отборе по типу: правило display:flex выше несёт id,
   и штатного [hidden] из браузера ему не хватает — строка остаётся видна. */
#dns-service table.display tr[hidden] { display: none; }
#dns-service table.display tr:hover { background: var(--cplv-bg); }
/* ⚠️ Отступы и подложку ячеек перебиваем с !important: их задаёт и модуль
   (padding 5px 8px), и сама тема (подложка заголовка) — каждый своей длинной
   цепочкой, и без этого строка списка остаётся таблицей. */
#dns-service table.display th,
#dns-service table.display td {
    display: block;
    width: auto;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    color: inherit;
    font-size: 14px;
    text-align: left;
    vertical-align: middle;
}
#dns-service table.display th {
    /* ⚠️ Тема держит у ячейки заголовка высоту 50px — строка выходила вдвое
       выше строк с содержимым (замечание владельца 01.09.2026). */
    height: auto !important;
    min-height: 0 !important;
    line-height: 1.4;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}
#dns-service table.display thead th[colspan] {
    font-size: 11px;
}

/* ---- список зон ---- */
#dns-service table.dns-zones tr > td:nth-child(2),
#dns-service table.dns-zones tr > th:nth-child(2) { flex: 1 1 auto; min-width: 0; }
#dns-service table.dns-zones tr > td:first-child,
#dns-service table.dns-zones tr > th:first-child { flex: 0 0 18px; }
#dns-service table.dns-zones td:nth-child(2) > a {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 15px;
    font-weight: 600;
    color: var(--cplv-ink);
}
#dns-service table.dns-zones td:nth-child(2) > a:hover { color: var(--cplv-accent); text-decoration: none; }
#dns-service table.dns-zones td:nth-child(3) {
    color: var(--cplv-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ---- записи зоны ---- */
#dns-service .cplv-dns-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}
#dns-service .cplv-dns-head h4 {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--cplv-ink);
}
#dns-service .cplv-dns-head .cplv-dns-zone {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
#dns-service .cplv-dns-head__sub { margin-top: 4px; font-size: 14px; color: var(--cplv-muted); }
#dns-service .cplv-dns-head__right { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* отбор по типу записи */
#dns-service .cplv-dns-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 14px 24px;
    border-bottom: 1px solid var(--cplv-line);
}
#dns-service .cplv-dns-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 14px;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
#dns-service .cplv-dns-pill:hover { color: var(--cplv-ink); }
#dns-service .cplv-dns-pill.is-active { background: var(--cplv-ink); color: var(--cplv-bg); }
#dns-service .cplv-dns-pill__n { opacity: .65; font-variant-numeric: tabular-nums; }

#dns-service .cplv-dns-type {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 62px;
    padding: 6px 8px;
    border-radius: 6px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    font-weight: 600;
}
/* Тон говорит о роли записи: адрес, псевдоним, почта. Состояния им не
   кодируются — это разные виды записей, а не «хорошо/плохо». */
#dns-service .cplv-dns-type[data-t="A"],
#dns-service .cplv-dns-type[data-t="AAAA"] { color: var(--cplv-info); }
#dns-service .cplv-dns-type[data-t="CNAME"],
#dns-service .cplv-dns-type[data-t="ALIAS"] { color: var(--cplv-violet); }
#dns-service .cplv-dns-type[data-t="MX"] { color: var(--cplv-teal); }
#dns-service .cplv-dns-type[data-t="NS"] { color: var(--cplv-warn); }

#dns-service table.dns-records tr > td:nth-child(1) { flex: 0 0 62px; }
#dns-service table.dns-records tr > td:nth-child(2) { flex: 1.2 1 0; min-width: 0; }
#dns-service table.dns-records tr > td:nth-child(3) { flex: 1.6 1 0; min-width: 0; }
/* ⚠️ Колонки TTL и действий держим фиксированной ширины, а свободное место
   отдаём margin-left:auto у TTL. Если auto повесить на действия, то у записей
   без кнопок (NS, MX — их модуль править не даёт) ячейка пустая, место
   распределяется иначе, и колонки в списке разъезжаются. */
#dns-service table.dns-records tr > td:nth-child(4) {
    flex: 0 0 90px; margin-left: auto; text-align: right; color: var(--cplv-muted);
    font-size: 13px; font-variant-numeric: tabular-nums;
}
#dns-service table.dns-records tr > td:nth-child(5) { flex: 0 0 150px; }
#dns-service .rr-name {
    display: block;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
    font-weight: 600;
    color: var(--cplv-ink);
    overflow: hidden;
    text-overflow: ellipsis;
}
#dns-service .rr-content {
    display: block;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
    color: var(--cplv-ink);
    word-break: break-word;
}
#dns-service .dns-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
#dns-service .dns-actions a { font-size: 13px; color: var(--cplv-muted); }
#dns-service .dns-actions a:hover { color: var(--cplv-ink); text-decoration: none; }
#dns-service .dns-actions a.lmore:hover { color: var(--cplv-danger); }

/* Служебная запись зоны: её открывают редко, поэтому она свёрнута и не
   занимает первый экран. */
#dns-service .cplv-dns-soa { margin-bottom: 22px; }
#dns-service .cplv-dns-soa > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 24px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
    box-shadow: var(--cplv-shadow);
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
}
#dns-service .cplv-dns-soa > summary::-webkit-details-marker { display: none; }
#dns-service .cplv-dns-soa[open] > summary { border-radius: var(--cplv-radius) var(--cplv-radius) 0 0; border-bottom: 0; }
#dns-service .cplv-dns-soa__note { margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 13px; }
#dns-service .cplv-dns-soa table.display { border-radius: 0 0 var(--cplv-radius) var(--cplv-radius); border-top: 0; }
#dns-service table.soa tr { align-items: flex-start; }
#dns-service table.soa td:nth-child(5) { flex: 1 1 auto; min-width: 0; font-size: 13px; line-height: 1.6; }

/* ---- формы ----
   Подпись сверху, поле в контуре, объяснение снизу — как во всей панели.
   ⚠️ `#contentbox` наполняет скрипт модуля (record_edit.js) уже в браузере,
   поэтому его содержимое трогаем только стилями. */
#dns-service .recordbox,
#dns-service .control-group {
    display: flex;
    flex-direction: column;
    gap: 7px;
    max-width: 560px;
    margin: 0 0 18px;
    line-height: 1.4;
}
#dns-service .recordbox > label,
#dns-service .control-label {
    display: block;
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 400;
    text-align: left;
}
#dns-service .control-label b { font-weight: 400; }
#dns-service .controls { margin: 0; }
#dns-service .cplv-dns-hint {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--cplv-muted);
}
#dns-service input[type="text"],
#dns-service input[type="number"],
#dns-service input[type="password"],
#dns-service select,
#dns-service textarea {
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    min-height: 46px;
    height: auto;
    padding: 10px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    font-family: inherit;
    font-size: 15px;
    box-shadow: none;
}
#dns-service textarea,
#dns-service .zone-file-input {
    min-height: 170px;
    line-height: 1.6;
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
}
#dns-service input:focus,
#dns-service select:focus,
#dns-service textarea:focus {
    border-color: var(--cplv-accent);
    box-shadow: var(--cplv-glow);
    outline: none;
}
/* ---- флажки и переключатели ----
   Вид — обычный, браузерный (решение владельца 01.09.2026): свой рисунок
   отменён. Здесь остаётся только сброс общих правил раздела: у полей задана
   ширина 100% и высота 46px, и без этого флажок растянулся бы во всю строку. */
/* ⚠️ all:revert, а не набор свойств по одному: обнулённые вручную border и
   background снимают у флажка и родную отрисовку — остаётся серый квадрат.
   revert возвращает ровно то, что рисует браузер.
   flex:none нужен отдельно: строка списка — гибкая, и флажок в ней сжимается
   до нуля. */
#dns-service input[type="checkbox"],
#dns-service input[type="radio"] {
    all: revert;
    flex: none;
    cursor: pointer;
}

/* Отмеченная строка списка видна целиком, а не только по флажку. */
#dns-service table.display tr:has(input[type="checkbox"]:checked) { background: var(--cplv-surface-2); }
#dns-service .nitem:has(input:checked),
#dns-service .dns-form-check:has(input:checked) {
    border-color: var(--cplv-accent);
    background: var(--cplv-surface);
}
/* Имя записи и адрес — техника, их читают посимвольно. */
#dns-service input[name="name"],
#dns-service input[name="axfr-server"],
#dns-service input[name="ipv4"],
#dns-service input[name="ipv6"],
#dns-service #contentbox input[type="text"] {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
#dns-service #contentbox input + br { display: none; }
#dns-service #contentbox input[type="text"] { margin-bottom: 10px; }
#dns-service .recordbox.form-inline { flex-direction: column; align-items: stretch; }
/* Имя записи и хвост домена — одна строка: «www» + «.example.lv» читаются
   вместе, иначе клиент не понимает, что вводит только левую часть. */
#dns-service .cplv-dns-inline { display: flex; align-items: center; gap: 10px; }
#dns-service .cplv-dns-inline > input { flex: 1 1 auto; min-width: 0; }
#dns-service .cplv-dns-suffix {
    flex: 0 0 auto;
    color: var(--cplv-muted);
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
    white-space: nowrap;
}
/* ⚠️ Поля «Содержимого» рисует скрипт модуля с классом .w-auto, а тема несёт
   для него width:auto!important — без ответного !important поле остаётся
   узким и не совпадает с остальными. */
#dns-service #contentbox input[type="text"],
#dns-service #contentbox select { width: 100% !important; }
#dns-service #contentbox { display: flex; flex-direction: column; gap: 10px; }
#dns-service #contentbox > * { max-width: 100%; }

/* переключатели «откуда брать записи» */
#dns-service .dns-form-check {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0 0 10px;
    padding: 14px 16px;
    border: 1px solid var(--cplv-line);
    border-radius: 10px;
    background: var(--cplv-bg);
}
#dns-service .dns-form-check label { margin: 0; font-size: 14px; font-weight: 600; color: var(--cplv-ink); }
#dns-service .dns-form-check input { margin-top: 2px; }
#dns-service .sh_option {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--cplv-line);
}
#dns-service .alert {
    margin-top: 10px;
    padding: 10px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 13px;
    line-height: 1.5;
}

/* ---- готовые наборы записей ---- */
/* ⚠️ Строку таблицы раскладываем СЕТКОЙ, а не гибкой строкой: у гибкой ячейка
   предпросмотра считает ширину по содержимому, при переносе уезжала вниз, и
   полоса с кнопкой оставалась сбоку. У сетки места ячеек заданы явно. */
#dns-service .ntable { display: block; width: 100%; }
#dns-service .ntable > tbody { display: block; width: 100%; }
#dns-service .ntable > tbody > tr {
    display: grid;
    grid-template-columns: 380px minmax(0, 1fr);
    gap: 22px;
    width: 100%;
}
#dns-service .ntable td {
    display: block;
    padding: 0;
    border: 0;
    background: none;
}
/* ⚠️ У ячеек в разметке стоит атрибут width="33%" — внутри сетки он считается
   от ширины колонки, и список сжимался до трети её ширины. Снимаем. */
#dns-service .ntable > tbody > tr > td { width: auto !important; }
#dns-service .ntable > tbody > tr > td:first-child { min-width: 0; }
#dns-service .ntable > tbody > tr > td.orderbox1 { min-width: 0; }
#dns-service .nitem {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 8px;
    padding: 13px 16px;
    border: 1px solid var(--cplv-line);
    border-radius: 10px;
    background: var(--cplv-bg);
    font-size: 14px;
    font-weight: 600;
    color: var(--cplv-ink);
    cursor: pointer;
}
#dns-service .nitem:hover { border-color: var(--cplv-line-strong); }
#dns-service .nitem input[type="radio"] { flex: 0 0 auto; }
#dns-service .orderbox1,
#dns-service .orderbox2 {
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
#dns-service .orderbox1 { padding: 0; overflow: hidden; }
#dns-service .oitem { padding: 0; }
/* Поля адреса, переключатель сброса и кнопка — ПОЛОСОЙ ПОД обеими колонками,
   а не третьей колонкой: в стоке это третья ячейка строки, и на месте она
   сжималась в узкий столбец с переносом каждого слова. */
#dns-service .ntable > tbody > tr > td.orderbox2 {
    grid-column: 1 / -1;
    margin-top: 0;
    padding: 16px 20px;
    text-align: left;
}
/* Полоса условий применения (адреса, сброс, кнопка) переехала из подвала
   таблицы в отдельный блок над списком наборов — селекторы работают и там,
   и там, потому что опираются на .orderbox3, а не на место в таблице. */
#dns-service .cplv-dns-apply { margin-bottom: 22px; }
#dns-service .cplv-dns-apply .wbox_content { padding: 0; }
#dns-service .orderbox3,
#dns-service .orderbox2 .orderbox3 { text-align: left !important; }
#dns-service .orderbox2 .form-group,
#dns-service .orderbox3 .checkbox { display: flex; align-items: center; gap: 10px; }
#dns-service .orderbox3 .checkbox label { margin: 0; font-size: 14px; color: var(--cplv-ink); }
#dns-service .orderbox3 .input { min-width: 220px; }
#dns-service .orderbox3 .btn { margin-left: auto; }
#dns-service .orderbox2 table,
#dns-service .orderbox2 td { display: block; width: 100%; padding: 0; border: 0; background: none; }

#dns-service .orderbox2 .pull-left { float: none; }
#dns-service .orderbox2 tr { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px; }

/* ---- серверы имён ---- */
#dns-service .cplv-dns-ns__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
    gap: 24px;
    align-items: start;
}
#dns-service .cplv-dns-ns__case + .cplv-dns-ns__case {
    margin-top: 22px;
    padding-top: 22px;
    border-top: 1px solid var(--cplv-line);
}
#dns-service .cplv-dns-ns__case-t {
    display: block;
    margin-bottom: 6px;
    font-size: 15px;
    font-weight: 600;
    color: var(--cplv-ink);
}
#dns-service .cplv-dns-ns__case-d {
    display: block;
    margin-bottom: 14px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--cplv-muted);
}
#dns-service .cplv-dns-ns__case .listi { margin-top: 4px; }
#dns-service .cplv-dns-ns__check {
    display: inline-block;
    margin-top: 10px;
    font-size: 14px;
    font-weight: 600;
}
@media (max-width: 900px) {
    #dns-service .cplv-dns-ns__grid { grid-template-columns: minmax(0, 1fr); }
}
#dns-service .listi { margin: 0; padding: 0; list-style: none; }
#dns-service .listi li {
    position: relative;
    margin: 0 0 10px;
    padding-left: 18px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--cplv-muted);
}
#dns-service .listi li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--cplv-line-strong);
}
#dns-service .checker.table td,
#dns-service .checker.table th {
    padding: 10px 14px;
    border: 0 !important;
    border-top: 1px solid var(--cplv-line) !important;
    background: none;
    color: var(--cplv-ink);
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
}
#dns-service .checker.table th {
    border-top: 0 !important;
    color: var(--cplv-muted);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}
#dns-service .checker.table tr.even { background: none; }
#dns-service .checker.table {
    border: 1px solid var(--cplv-line) !important;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    border-collapse: separate;
    overflow: hidden;
}

/* ---- кнопки внутри раздела ----
   Подпись кнопки всегда в одну строку: «Импортировать содержимое зоны»
   переносилась и кнопка вырастала по высоте. */
#dns-service .btn { white-space: nowrap; }
#dns-service center { text-align: left; }
#dns-service .wbox_content > center,
#dns-service .text-center {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--cplv-line);
    text-align: left;
}

/* ---- полоса выполнения (применение набора, импорт) ----
   ⚠️ В стоке высота полосы зависит от состояния: пока идёт работа — 16px, а на
   готовности скрипт кладёт внутрь надпись, и полоса вырастает до 19px. Из-за
   этого блок дёргался на середине и в конце (замечание владельца 01.09.2026).
   Высота теперь одна в обоих состояниях. Надпись «Готово» шла синим по
   зелёному, то есть её просто не было видно. */
#dns-service .progress {
    height: 28px;
    margin: 0 0 22px;
    padding: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    box-shadow: none;
    overflow: hidden;
}
#dns-service .progress .bar,
#dns-service .progress .progress-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 0;
    background-color: var(--cplv-accent) !important;
    background-image: none;
    color: var(--cplv-on-accent) !important;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
}
@media (prefers-reduced-motion: no-preference) {
    #dns-service .progress .bar { transition: width .2s linear; }
}
/* Кнопка «Продолжить» до готовности не работает — пусть так и выглядит. */
#dns-service .progress-btn.disabled {
    opacity: .5;
    pointer-events: none;
}

/* ---- полоса с адресами и кнопкой под набором записей ----
   ⚠️ Рамку и подложку у неё снимало общее правило «#dns-service .ntable td»:
   у него специфичность выше, чем у «#dns-service .orderbox2». Возвращаем их
   через td.orderbox2 — селектор с классом на элементе. */
#dns-service .ntable td.orderbox1,
#dns-service .ntable td.orderbox2 {
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
#dns-service .ntable td.orderbox1 { padding: 0; overflow: hidden; }
#dns-service .ntable td.orderbox2 { padding: 0; }
#dns-service .orderbox3 {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
    padding: 18px 20px !important;
    text-align: left !important;
}
#dns-service .orderbox3 > * { float: none !important; margin: 0 !important; }
/* Подпись и знак «?» — в одну строку над полем: в колонке знак уезжал на
   собственную строку и висел под подписью. */
#dns-service .orderbox3 .input {
    display: grid;
    grid-template-columns: auto auto 1fr;
    align-items: center;
    gap: 0 6px;
    min-width: 240px;
}
#dns-service .orderbox3 .input > .control-label { grid-column: 1; margin: 0; }
#dns-service .orderbox3 .input > .vtip_description { grid-column: 2; }
#dns-service .orderbox3 .input > input { grid-column: 1 / -1; margin-top: 7px; }
#dns-service .orderbox2 .checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 46px;
}
#dns-service .orderbox2 .checkbox label { margin: 0; font-size: 14px; color: var(--cplv-ink); }
#dns-service .orderbox2 .btn { margin-left: auto; }

/* ---- телефон ---- */
@media (max-width: 767px) {
    #dns-service .wbox_content { padding: 16px; }
    #dns-service .icons { padding: 16px; }
    #dns-service .icons > ul { grid-template-columns: 1fr; }
    #dns-service table.display tr { flex-wrap: wrap; padding: 14px 16px; }
    #dns-service table.display > thead { display: none; }
    #dns-service table.dns-records tr > td:nth-child(2),
    #dns-service table.dns-records tr > td:nth-child(3) { flex: 1 1 100%; }
    #dns-service table.dns-records tr > td:nth-child(4) { flex: 0 0 auto; margin-right: auto; text-align: left; }
    #dns-service .cplv-dns-head__right { width: 100%; margin-left: 0; }
    #dns-service .cplv-dns-head__right .btn { flex: 1 1 auto; }
    #dns-service .ntable > tbody > tr { grid-template-columns: minmax(0, 1fr); }
    
    #dns-service .cplv-dns-pills { overflow-x: auto; flex-wrap: nowrap; }
}

/* ---- ссылки, знак «?» и подсказка ----
   Ссылка без кнопки шла бутстраповским синим (#3891f2) — цветом, которого в
   панели нет. «Отмена» рядом с зелёной кнопкой к тому же читалась как
   случайный текст, поэтому она стала второстепенной кнопкой. */
#dns-service a:not(.btn) { color: var(--cplv-accent); }
#dns-service a:not(.btn):hover { color: var(--cplv-accent-hover); }
#dns-service .wbox_content > center > a:not(.btn),
#dns-service .text-center > a:not(.btn) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    padding: 10px 20px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
#dns-service .wbox_content > center > a:not(.btn):hover,
#dns-service .text-center > a:not(.btn):hover {
    border-color: var(--cplv-line-strong);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
}

/* ⚠️ Знак «?» в стоке — синяя картинка vtip.png: перекрасить её нельзя,
   поэтому картинку убираем и рисуем знак сами, текущим цветом. Правило не
   ограничено разделом DNS: этот знак тема ставит по всей панели. */
body .vtip_description {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    /* ⚠️ Отступ слева 22px тема держала под картинку-знак: без его снятия
       знак «?» выезжает за нарисованный кружок. */
    padding: 0 !important;
    margin-left: 6px;
    vertical-align: -4px;
    border: 1.5px solid var(--cplv-line-strong);
    border-radius: 50%;
    background: none !important;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    cursor: help;
}
body .vtip_description::before { content: "?"; }
body .vtip_description:hover { border-color: var(--cplv-accent); color: var(--cplv-accent); }

/* Подсказка у знака «?». Её рисует Bootstrap, и в стоке она синяя (#3891f2) —
   цвета, которого в панели нет. Красим в основной тон: тёмная плашка на светлой
   теме и светлая на тёмной, как у всех всплывающих подписей панели.
   ⚠️ Плашку Bootstrap вешает на <body>, вне #dns-service, поэтому и правило без
   этого префикса — оно и должно работать на всю панель. */
body .tooltip { z-index: 1080; }
body .tooltip .tooltip-inner {
    max-width: 300px;
    padding: 10px 10px;
    border-radius: var(--cplv-radius-sm);
    background-color: var(--cplv-ink);
    color: var(--cplv-bg);
    font-family: Onest, system-ui, sans-serif;
    font-size: 13px;
    line-height: 1.45;
    text-align: left;
    box-shadow: var(--cplv-shadow-hover);
}
body .tooltip.bs-tooltip-top .arrow::before,
body .tooltip.bs-tooltip-auto[x-placement^="top"] .arrow::before { border-top-color: var(--cplv-ink); }
body .tooltip.bs-tooltip-bottom .arrow::before,
body .tooltip.bs-tooltip-auto[x-placement^="bottom"] .arrow::before { border-bottom-color: var(--cplv-ink); }
body .tooltip.bs-tooltip-left .arrow::before,
body .tooltip.bs-tooltip-auto[x-placement^="left"] .arrow::before { border-left-color: var(--cplv-ink); }
body .tooltip.bs-tooltip-right .arrow::before,
body .tooltip.bs-tooltip-auto[x-placement^="right"] .arrow::before { border-right-color: var(--cplv-ink); }

/* ============================================================================
   ОБРАЩЕНИЯ: отбор по состоянию и бейдж состояния
   ============================================================================ */

/* ⚠️ Кнопки отбора «Все / Открыто / Отвечено» стояли вразброс, и между ними
   были мёртвые зоны: у пунктов темы остаётся padding 10px 30px и margin-top,
   а нажимается только сама ссылка. Клик мимо ничего не делал — со стороны это
   выглядело как «фильтр не работает» (замечание владельца 01.09.2026).
   Сам отбор исправен, проверено: «Открыто» — 1 строка, «Отвечено» — 2, «Все» — 14. */
body .section-tickets .nav-slider { position: relative; gap: 8px; }
body .section-tickets .nav-slider > li.nav-item {
    margin: 0;
    padding: 0;
    list-style: none;
}
/* Тема кладёт в список отдельный узел-ползунок под бегущую подсветку. У нас
   активную вкладку красит она сама, и ползунок остаётся лишней полосой. */
body .section-tickets .nav-slider > .slider { display: none; }

/* Состояние обращения — бейджем, тон тот же, что у точки в начале строки:
   строку читают по цвету, и подпись должна говорить то же самое. */
body .cplv-tk-state,
body .cplv-state {
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 6px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
body .cplv-tk-state--Open { color: var(--cplv-ok); }
body .cplv-tk-state--Answered { color: var(--cplv-warn); }
body .cplv-tk-state--Client-Reply { color: var(--cplv-info); }
body .cplv-tk-state--In-Progress { color: var(--cplv-teal); }
body .cplv-tk-state--Closed { color: var(--cplv-muted); }

/* ============================================================================
   СОСТОЯНИЕ СПИСКОМ: БЕЙДЖ И ВКЛАДКА ОТБОРА

   Один цвет на оба места: бейдж в строке домена и вкладка отбора над списком
   красятся из одной карты (замечание владельца 02.09.2026). Карта — ниже,
   в переменной --tone; шаблоны только выводят имя состояния, разбираться в
   тонах им не нужно.

   Тон: зелёный — работает; синий — в работе у реестра; бирюзовый — переезжает;
   жёлтый — сроки вышли; красный — выключено за неоплату; серый — закрыто;
   сиреневый — на проверке.
   ============================================================================ */
.cplv-state--Active,               .cplv-f--Active               { --tone: var(--cplv-ok); }
.cplv-state--Pending,              .cplv-f--Pending              { --tone: var(--cplv-info); }
.cplv-state--Pending-Registration, .cplv-f--Pending-Registration { --tone: var(--cplv-info); }
.cplv-state--Pending-Transfer,     .cplv-f--Pending-Transfer     { --tone: var(--cplv-teal); }
.cplv-state--Transferred-Away,     .cplv-f--Transferred-Away     { --tone: var(--cplv-teal); }
.cplv-state--Expired,              .cplv-f--Expired              { --tone: var(--cplv-warn); }
.cplv-state--Suspended,            .cplv-f--Suspended            { --tone: var(--cplv-danger); }
.cplv-state--Cancelled,            .cplv-f--Cancelled            { --tone: var(--cplv-muted); }
.cplv-state--Terminated,           .cplv-f--Terminated           { --tone: var(--cplv-muted); }
.cplv-state--Fraud,                .cplv-f--Fraud                { --tone: var(--cplv-violet); }

body .cplv-state { color: var(--tone, var(--cplv-muted)); }

/* Вкладка отбора берёт тот же тон: подпись — цветом состояния, выбранная —
   на подложке из него же и с контуром.
   ⚠️ color-mix даёт подложку прямо из currentColor, поэтому отдельные rgba
   на каждый тон и на каждую тему не нужны. Перед ним — обычная подложка:
   если color-mix не поддержан, вкладка просто останется серой. */
body .cplv-dom-filters .nav-link[class*="cplv-f--"] { color: var(--tone, var(--cplv-muted)); }
body .cplv-dom-filters .nav-link[class*="cplv-f--"]:hover {
    background: var(--cplv-line);
    background: color-mix(in srgb, currentColor 14%, transparent);
    color: var(--tone, var(--cplv-ink));
}
body .cplv-dom-filters .nav-item.active > .nav-link[class*="cplv-f--"] {
    background: var(--cplv-surface-2);
    background: color-mix(in srgb, currentColor 16%, transparent);
    color: var(--tone, var(--cplv-ink));
    box-shadow: inset 0 0 0 1px currentColor;
}

/* ---- форма нового обращения во всю ширину блока ----
   Общее правило держит содержимое формы колонкой 620 px — так удобнее читать
   длинные формы аккаунта. У обращения полей мало, и блок при этом стоял
   наполовину пустым (замечание владельца 01.09.2026): здесь ограничение снято,
   каждое поле занимает всю ширину блока.

   ⚠️ Отступ между полями подряд задан правилом из трёх классов и перебивает
   строку ниже — в сетке он сдвигал бы поля друг относительно друга. Здесь
   расстояние держит gap сетки. */
.cplv-ticket-new .cplv-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
}
.cplv-ticket-new .cplv-form > * { max-width: none; margin-top: 0; }
.cplv-ticket-new .cplv-form > .cplv-field + .cplv-field,
.cplv-ticket-new .cplv-form > .cplv-field + .fileupload,
.cplv-ticket-new .cplv-form > .cplv-field + .cplv-more { margin-top: 0; }
.cplv-ticket-new .cplv-lead { max-width: 720px; }

/* ============================================================================
   РАЗДЕЛ ДОМЕНА  (/studio/clientarea/domains/<id>/<домен>/)

   Страница домена приведена к виду страницы услуги: строка опознания, деньги
   на первом экране, вкладки вместо белой колонки слева, факты и настройки
   блоками, операции — карточками действий.

   Разметку рисуют наши шаблоны темы (services/domain_details.tpl,
   left_nav_domain.tpl, domain_actions.tpl, _cplv-msg.tpl), поэтому правила
   здесь короткие и без !important — спорить не с кем. Исключение — содержимое
   виджетов: его рисует ядро (.wbox), там селекторы за #cplv-domain.

   Макет: https://claude.ai/code/artifact/b9953481-5fb6-47a3-8ceb-ea019d040d39
   ============================================================================ */

/* ---- кнопка «Все домены» держится у правого края строки опознания ---- */
#cplv-domain .cplv-dom-back { margin-left: 10px; white-space: nowrap; }

/* ---- подпись блока: та же, что у блока действий ---- */
.cplv-box__label {
    margin-bottom: 14px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}

/* ---- IP рядом с именем сервера имён ---- */
.cplv-field__suffix { margin-left: 10px; color: var(--cplv-muted); }

/* ---- строка денег с долгом: обводка в тон, чтобы не проходили мимо ---- */
.cplv-srv-billing--due { border-color: rgba(179, 66, 58, .45); }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .cplv-srv-billing--due { border-color: rgba(224, 115, 107, .42); }
}
:root[data-theme="dark"] .cplv-srv-billing--due { border-color: rgba(224, 115, 107, .42); }

/* ---- настройки: значение и «Изменить» в одной строке ----
   Раньше блокировка и автопродление были парой «бейдж + синяя ссылка» внутри
   плитки фактов: значение читалось, а что с ним делать — нет. */
.cplv-dom-sets { padding: 22px 24px; }
.cplv-sets { list-style: none; margin: 0; padding: 0; }
.cplv-set {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 0;
    border-top: 1px solid var(--cplv-line);
}
.cplv-set:first-child { border-top: 0; padding-top: 0; }
.cplv-set:last-child { padding-bottom: 0; }
.cplv-set__text { flex: 1 1 auto; min-width: 0; }
.cplv-set__title { display: block; font-size: 15px; font-weight: 600; color: var(--cplv-ink); }
.cplv-set__desc { display: block; margin-top: 4px; font-size: 13px; line-height: 1.45; color: var(--cplv-muted); }

/* ---- факты и серверы имён ---- */
/* Факты — просто значения: рамка поля тут читалась как поле ввода, в которое
   можно печатать. У серверов имён рамка остаётся: это то, что копируют. */
.cplv-dom-facts, .cplv-dom-ns { padding: 22px 24px; }
.cplv-dom-facts .cplv-field__value {
    min-height: 0;
    padding: 0;
    border: 0;
    background: transparent;
    font-size: 15px;
    font-weight: 600;
}
.cplv-dom-ns .cplv-note { margin: 16px 0 0; }

/* ---- сообщение, которое обязано быть замеченным ----
   Знак в цветном квадрате слева, заголовок — что делать, строка — почему.
   Тон выбирает шаблон: info пояснение, warn предупреждение, danger запрет. */
.cplv-msg {
    display: flex;
    gap: 14px;
    margin: 14px 0 0;
    padding: 16px 18px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
.cplv-msg__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 38px;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-msg__icon svg { width: 20px; height: 20px; }
.cplv-msg__text { flex: 1 1 auto; min-width: 0; }
.cplv-msg__title { display: block; font-size: 15px; font-weight: 600; line-height: 1.35; color: var(--cplv-ink); }
.cplv-msg__desc { display: block; margin-top: 4px; font-size: 14px; line-height: 1.5; color: var(--cplv-muted); }
.cplv-msg__act { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }

.cplv-msg--info .cplv-msg__icon { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
.cplv-msg--ok { border-color: rgba(63, 143, 87, .42); }
.cplv-msg--ok .cplv-msg__icon { background: rgba(63, 143, 87, .12); color: var(--cplv-ok); }
.cplv-msg--warn { border-color: rgba(138, 106, 21, .42); }
.cplv-msg--warn .cplv-msg__icon { background: rgba(138, 106, 21, .12); color: var(--cplv-warn); }
.cplv-msg--danger { border-color: rgba(179, 66, 58, .45); }
.cplv-msg--danger .cplv-msg__icon { background: rgba(179, 66, 58, .12); color: var(--cplv-danger); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .cplv-msg--info .cplv-msg__icon { background: rgba(127, 182, 224, .14); }
    :root:not([data-theme="light"]) .cplv-msg--ok { border-color: rgba(156, 205, 126, .40); }
    :root:not([data-theme="light"]) .cplv-msg--ok .cplv-msg__icon { background: rgba(156, 205, 126, .14); }
    :root:not([data-theme="light"]) .cplv-msg--warn { border-color: rgba(201, 162, 39, .40); }
    :root:not([data-theme="light"]) .cplv-msg--warn .cplv-msg__icon { background: rgba(201, 162, 39, .14); }
    :root:not([data-theme="light"]) .cplv-msg--danger { border-color: rgba(224, 115, 107, .42); }
    :root:not([data-theme="light"]) .cplv-msg--danger .cplv-msg__icon { background: rgba(224, 115, 107, .14); }
}
:root[data-theme="dark"] .cplv-msg--info .cplv-msg__icon { background: rgba(127, 182, 224, .14); }
:root[data-theme="dark"] .cplv-msg--ok { border-color: rgba(156, 205, 126, .40); }
:root[data-theme="dark"] .cplv-msg--ok .cplv-msg__icon { background: rgba(156, 205, 126, .14); }
:root[data-theme="dark"] .cplv-msg--warn { border-color: rgba(201, 162, 39, .40); }
:root[data-theme="dark"] .cplv-msg--warn .cplv-msg__icon { background: rgba(201, 162, 39, .14); }
:root[data-theme="dark"] .cplv-msg--danger { border-color: rgba(224, 115, 107, .42); }
:root[data-theme="dark"] .cplv-msg--danger .cplv-msg__icon { background: rgba(224, 115, 107, .14); }

/* ---- текущий пункт в блоке «Разделы и действия» ----
   Блок стоит на всех страницах домена и работает как меню, поэтому открытый
   раздел обязан быть видно: контур цветом, подложка плашки, знак в тон. */
.cplv-actions__grid > li > a.cplv-action--on,
.cplv-actions__grid > li > a.cplv-action--on:hover {
    border-color: var(--cplv-accent);
    background: var(--cplv-surface-2);
}
.cplv-action--on .cplv-action__title { color: var(--cplv-ink); }
.cplv-action--on .cplv-action__icon {
    background: rgba(63, 143, 87, .12);
    color: var(--cplv-accent);
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .cplv-action--on .cplv-action__icon { background: rgba(156, 205, 126, .14); }
}
:root[data-theme="dark"] .cplv-action--on .cplv-action__icon { background: rgba(156, 205, 126, .14); }

/* ---- заливка карточки действия по значению ----
   Решение владельца 04.09.2026: в блоке действий цвет обязан читаться раньше
   подписи, поэтому карточка заливается тем же тоном, что и знак. У РАЗДЕЛОВ
   заливки нет — там цвет ничего не значил бы.
   Доля тона в тёмной теме выше: на тёмном полотне слабая примесь не видна. */
.cplv-action--t-accent { --cplv-tone: var(--cplv-accent); }
.cplv-action--t-info   { --cplv-tone: var(--cplv-info); }
.cplv-action--t-violet { --cplv-tone: var(--cplv-violet); }
.cplv-action--t-teal   { --cplv-tone: var(--cplv-teal); }
.cplv-action--t-rose   { --cplv-tone: var(--cplv-rose); }
.cplv-action--t-warn   { --cplv-tone: var(--cplv-warn); }
.cplv-action--t-danger { --cplv-tone: var(--cplv-danger); }
.cplv-action--t-muted  { --cplv-tone: var(--cplv-muted); }
:root { --cplv-fill: 8%; --cplv-fill-line: 34%; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) body.template_2019 { --cplv-fill: 13%; --cplv-fill-line: 42%; }
}
:root[data-theme="dark"] body.template_2019 { --cplv-fill: 13%; --cplv-fill-line: 42%; }

/* ⚠️ Селектор длиннее общего: сетку действий модуль адресует через два id
   (#lockable-vm-menu #vm-menu), и правило короче до неё не доходит.
   ⚠️ Перед color-mix стоит обычная подложка — если браузер его не понимает,
   карточка останется белой, а не прозрачной. */
body .cloud #lockable-vm-menu #vm-menu.cplv-actions__grid > li > a.cplv-action--fill,
.cplv-actions__grid > li > a.cplv-action--fill {
    background: var(--cplv-surface);
    background: color-mix(in srgb, var(--cplv-tone) var(--cplv-fill), var(--cplv-surface));
    border-color: color-mix(in srgb, var(--cplv-tone) var(--cplv-fill-line), var(--cplv-line));
}
body .cloud #lockable-vm-menu #vm-menu.cplv-actions__grid > li > a.cplv-action--fill:hover,
.cplv-actions__grid > li > a.cplv-action--fill:hover {
    background: color-mix(in srgb, var(--cplv-tone) calc(var(--cplv-fill) + 6%), var(--cplv-surface));
    border-color: color-mix(in srgb, var(--cplv-tone) calc(var(--cplv-fill-line) + 10%), var(--cplv-line));
}
body .cplv-action--fill .cplv-action__title { color: color-mix(in srgb, var(--cplv-tone) 62%, var(--cplv-ink)); }
.cplv-action--fill .cplv-action__icon { background: color-mix(in srgb, var(--cplv-tone) 18%, transparent); }

/* Блок-меню плотнее блока действий: пунктов в нём вдвое больше и стоит он на
   каждой странице раздела. */
.cplv-dom-menu { padding: 18px 20px 20px; }
/* ⚠️ auto-FILL, а не auto-fit: у услуги в блоке бывает две карточки, и
   auto-fit растягивал их во всю ширину экрана — две плашки по пол-экрана
   вместо ряда карточек. auto-fill держит ширину колонки, и ряд заполнен
   слева направо. При полном ряду (домен, 13 карточек) разницы нет. */
.cplv-dom-menu .cplv-actions__grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.cplv-dom-menu .cplv-actions__grid > li > a.cplv-action { padding: 10px 14px; gap: 10px; }
.cplv-dom-menu .cplv-action__icon { flex: 0 0 34px; width: 34px; height: 34px; }
.cplv-dom-menu .cplv-action__icon svg { width: 18px; height: 18px; }
.cplv-dom-menu .cplv-action__title { font-size: 14px; }
.cplv-dom-menu .cplv-action__desc { font-size: 12px; }

/* ---- состояния, которых в панели ещё не было ----
   Точка и бейдж «Истёк» и «Проверка заказа» рисовались серым по умолчанию:
   на списке доменов их было не отличить от закрытых. */
body .cplv-dot--Expired { background: var(--cplv-warn); }
body .cplv-dot--Fraud { background: var(--cplv-danger); }
body .badge-Expired {
    background-color: var(--cplv-surface-2) !important;
    color: var(--cplv-warn) !important;
}
body .badge-Fraud {
    background-color: var(--cplv-surface-2) !important;
    color: var(--cplv-danger) !important;
}

/* ---- содержимое виджетов раздела: блок ядра .wbox ----
   Виджеты (контакты, журнал, счета, приватность, код переноса) рисует ядро
   своей разметкой. Приводим её к нашему блоку — так же, как сделано в разделе
   DNS. */
#cplv-domain .widget { margin: 0; }
#cplv-domain .wbox {
    margin: 0 0 22px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    box-shadow: var(--cplv-shadow);
    overflow: hidden;
}
#cplv-domain .wbox_header {
    padding: 14px 24px;
    border-bottom: 1px solid var(--cplv-line);
    background: transparent;
    color: var(--cplv-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}
#cplv-domain .wbox_content { padding: 22px 24px; line-height: 1.55; }
#cplv-domain .wbox_content > br:first-child { display: none; }
#cplv-domain .wbox_content .table { margin-bottom: 0; }
#cplv-domain .wbox_content .table td { padding: 10px 10px 10px 0; border: 0; vertical-align: middle; }
#cplv-domain .wbox_content .table tr + tr td { border-top: 1px solid var(--cplv-line); }
#cplv-domain .wbox_content form + form { margin-top: 18px; }
#cplv-domain .wbox_content .btn { margin-top: 14px; }
/* ⚠️ …кроме ряда кнопок под формой: там отбивку даёт сам ряд, а лишний
   margin-top у кнопки отправки съезжал её вниз на половину — это и была
   ступенька между «Сохранить» и «Отмена». Селектор с id намеренно: правило
   выше тоже с id, и без него не перебить. */
#cplv-domain .wbox_content td[align="center"] .btn,
#cplv-domain .wbox_content > center .btn { margin-top: 0; }
#cplv-domain .wbox_content input.inp {
    width: 100%;
    max-width: 420px;
    min-height: 46px;
    padding: 10px 14px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    font-size: 15px;
}

/* ---- форма виджета домена в стоковой таблице ----
   Виджеты «Блокировка регистратора», «Приватность» и им подобные рисует ядро
   таблицей 2013 года: подпись прижата ВПРАВО в одной ячейке, поле и кнопка —
   в соседней, и всё это по центру блока. Поле с кнопкой при этом стояли
   вплотную (4 px — замечание владельца 05.09.2026).

   Таблицу разбираем на обычные блоки: подпись ВСТАЁТ НАД полем (правило 4
   спеки), ряд «поле + кнопка» получает промежуток 10. Сам select приводим к
   виду остальных полей панели: стоковый оставался белым и в тёмной теме. */
#cplv-domain .wbox_content > center { text-align: left; }
#cplv-domain .wbox_content table.checker,
#cplv-domain .wbox_content table.checker > tbody,
#cplv-domain .wbox_content table.checker > tbody > tr,
#cplv-domain .wbox_content table.checker > tbody > tr > td {
    display: block;
    width: auto;
    padding: 0;
    border: 0;
    /* ⚠️ !important: у ячейки стоит атрибут align="right", а тема ловит его
       правилом `.table td[align="right"]` с !important — без него подпись
       оставалась прижатой к правому краю блока. */
    text-align: left !important;
}
#cplv-domain .wbox_content table.checker > tbody > tr > td:first-child {
    margin-bottom: 7px;
    font-size: 14px;
    color: var(--cplv-muted);
}
#cplv-domain .wbox_content table.checker > tbody > tr > td:first-child b { font-weight: 400; }
#cplv-domain .wbox_content table.checker form {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
/* Кнопка отправки виджета: у неё класс .padded от темы, и с ним она
   вырастала до 44 — на два пункта выше кнопки панели. */
#cplv-domain .wbox_content input.btn,
#cplv-domain .wbox_content button.btn { height: 42px; min-height: 42px; padding: 0 22px; }
#cplv-domain .wbox_content select.inp {
    height: 46px;
    min-width: 200px;
    padding: 0 14px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    font-size: 15px;
}

/* ---- плашка сообщения первой в блоке ---- */
#cplv-domain .wbox_content > .cplv-msg:first-child { margin-top: 0; }

/* ---- форма контактов домена ----
   Разметку рисует ядро таблицей 2013 года: подписи прижаты вправо в узкой
   колонке, поля растянуты во всю ширину блока, строки полосатые. Меняем
   стилями, а не шаблоном: за структуру таблицы держится скрипт виджета
   (sh_contacts ходит по tbody с id `<тип>_contact` и `<тип>_preview`). */
#cplv-domain #contactinfoeditor .table { margin: 0; }
#cplv-domain #contactinfoeditor .table td {
    padding: 10px 14px 10px 0;
    border: 0;
    vertical-align: middle;
}
/* ⚠️ :not([align="center"]) — ряд кнопок под формой тоже первая ячейка в своей
   строке, и без исключения он получал ширину 210 px и выключку влево. */
#cplv-domain #contactinfoeditor .table td:first-child:not([align="center"]) {
    width: 210px;
    /* ⚠️ !important: у ячеек стоит атрибут align="right", а бутстрап темы
       описывает его правилом `.table td[align="right"]{text-align:right!important}`.
       Обычное переопределение до него не доходит. */
    text-align: left !important;
    font-size: 14px;
    font-weight: 400;
    color: var(--cplv-muted);
}
#cplv-domain #contactinfoeditor .table td:first-child:not([align="center"]) strong {
    font-size: 15px;
    font-weight: 600;
    color: var(--cplv-ink);
}
#cplv-domain #contactinfoeditor .table-striped tbody tr:nth-of-type(odd),
#cplv-domain #contactinfoeditor .table tr.even { background: transparent; }
/* ⚠️ Между группами контактов бутстрап рисует `tbody + tbody{border-top:2px
   solid #dee2e6}` — в тёмной теме это была светлая полоса во всю ширину. */
#cplv-domain #contactinfoeditor .table tbody + tbody { border-top: 1px solid var(--cplv-line); }
#cplv-domain #contactinfoeditor .form-control,
#cplv-domain #contactinfoeditor .iti { max-width: 520px; }
/* Ряд «Контакт регистранта»: переключатели и список в одну строку, с воздухом. */
#cplv-domain #contactinfoeditor .table td label { margin: 0 14px 0 6px; font-size: 14px; color: var(--cplv-ink); }
#cplv-domain #contactinfoeditor .table td input[type="radio"] { vertical-align: middle; }
#cplv-domain #contactinfoeditor .table td select.w-auto { max-width: 260px; }
#cplv-domain #contactinfoeditor .btn { margin-top: 18px; }
/* …кроме ряда кнопок: отбивку там даёт сам ряд, а лишний отступ сдвигал
   «Сохранить» вниз относительно «Отмены». */
#cplv-domain #contactinfoeditor td[align="center"] .btn { margin-top: 0; }

@media (max-width: 767px) {
    #cplv-domain #contactinfoeditor .table td { display: block; width: 100% !important; padding: 4px 0; }
    #cplv-domain #contactinfoeditor .table tr + tr { display: block; margin-top: 10px; }
    #cplv-domain #contactinfoeditor .form-control { max-width: none; }
}

/* ---- телефон ---- */
@media (max-width: 767px) {
    /* Блок «Разделы и действия» на телефоне: одна колонка карточек. */
    .cplv-dom-menu { padding: 16px; }
    .cplv-dom-facts, .cplv-dom-ns, .cplv-dom-sets { padding: 16px; }
    .cplv-set { flex-wrap: wrap; }
    .cplv-set .btn { width: 100%; text-align: center; }
    #cplv-domain .wbox_header { padding: 13px 16px; }
    #cplv-domain .wbox_content { padding: 16px; }
    #cplv-domain .cplv-dom-back { width: 100%; margin: 10px 0 0; text-align: center; }
}

/* ============================================================================
   РЯД КНОПОК ПОД ФОРМОЙ ВИДЖЕТА  (панель целиком)

   Ядро закрывает каждую форму виджета одинаково:

       <input type="submit" class="btn btn-primary" value="Сохранить">
       <span class="fs11">Или</span>
       <a class="fs11" href="…">Отмена</a>

   На экране это читалось как «Сохранить Или Отмена» — кнопка, потом два
   мелких серых слова в упор к ней, без отбивки от полей формы. «Или» лишнее:
   вторая возможность и так видна, если она выглядит второй кнопкой.

   Стало: «Или» скрыто, «Отмена» — обычная вторая кнопка, ряд отбит сверху
   линией и отступом, выключка влево (замечание владельца 02.09.2026).
   Правило общее: тем же шаблоном закрыты формы серверов имён, контактов,
   кода переноса, DNSSEC, синхронизации и записей DNS.

   ⚠️ Селектор требует, чтобы «Или» стояло НЕПОСРЕДСТВЕННО за кнопкой
   отправки: `fs11` в ядре встречается и в других местах (подписи колонок,
   ссылка «Remove»), и трогать их нельзя.
   ============================================================================ */

/* ---- «Или» убираем ---- */
input[type="submit"] + span.fs11,
button[type="submit"] + span.fs11,
.btn + span.fs11,
.btn + span.mx-2.text-muted { display: none; }

/* ---- обе кнопки одного роста и на одной линии ----
   ⚠️ Прыгали они не случайно: кнопка отправки — это <input>, он выстраивается
   по базовой линии текста, а «Отмена» — ссылка, которой мы дали inline-flex.
   Разная выключка по вертикали плюс разная высота и давали ступеньку. Поэтому
   обеим ЯВНО задаём одинаковые рост, отбивку, кегль и vertical-align.

   ⚠️ Знак на кнопке отправки — фоновой картинкой, а не ::before: у <input>
   псевдоэлементов нет. У «Отмены» знак маской, чтобы он брал цвет текста и
   работал в обеих темах. */

.wbox_content td[align="center"] > input[type="submit"],
.wbox_content td[align="center"] > button[type="submit"],
.wbox_content td[align="center"] > .btn,
.wbox_content > center input[type="submit"],
.wbox_content > center button[type="submit"],
.wbox_content > center .btn,
input[type="submit"] + span.fs11 + a,
button[type="submit"] + span.fs11 + a,
.btn + span.fs11 + a,
.btn + span.mx-2.text-muted + a {
    min-height: 44px;
    padding: 10px 20px;
    border-radius: var(--cplv-radius-sm);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.25;
    white-space: nowrap;
    vertical-align: middle;
    /* ⚠️ Обнуляем внешние отступы. Ступеньку давал не выключка, а свой
       `margin-top:14px` у кнопок внутри .wbox_content (он отбивал кнопку от
       текста в блоках без ряда): при vertical-align:middle середина считается
       по внешней рамке, и кнопка с отступом уезжала вниз на половину его. */
    margin-top: 0;
    margin-bottom: 0;
}

/* ---- знак на кнопке отправки: галочка ---- */
.wbox_content td[align="center"] > input[type="submit"],
.wbox_content td[align="center"] > button[type="submit"],
.wbox_content > center input[type="submit"],
.wbox_content > center button[type="submit"] {
    padding-left: 44px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4 4L19 7'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 17px center;
    background-size: 18px 18px;
}

/* В тёмной теме кнопка отправки светло-зелёная с тёмной подписью — знак тоже
   тёмный, иначе белая галочка тонет в заливке. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .wbox_content td[align="center"] > input[type="submit"],
    :root:not([data-theme="light"]) .wbox_content td[align="center"] > button[type="submit"],
    :root:not([data-theme="light"]) .wbox_content > center input[type="submit"],
    :root:not([data-theme="light"]) .wbox_content > center button[type="submit"] {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230f1216' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4 4L19 7'/%3E%3C/svg%3E");
    }
}
:root[data-theme="dark"] .wbox_content td[align="center"] > input[type="submit"],
:root[data-theme="dark"] .wbox_content td[align="center"] > button[type="submit"],
:root[data-theme="dark"] .wbox_content > center input[type="submit"],
:root[data-theme="dark"] .wbox_content > center button[type="submit"] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230f1216' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4 4L19 7'/%3E%3C/svg%3E");
}

/* ---- «Отмена» — вторая кнопка со знаком ---- */
input[type="submit"] + span.fs11 + a,
button[type="submit"] + span.fs11 + a,
.btn + span.fs11 + a,
.btn + span.mx-2.text-muted + a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Отбивка между кнопками — тройная против прежней: рядом стоят зелёная
       «Сохранить» и «Отмена», и в упор их легко нажать не ту (замечание
       владельца 02.09.2026). */
    margin-left: 32px;
    border: 1px solid var(--cplv-line);
    background: var(--cplv-surface);
    color: var(--cplv-ink);
    text-decoration: none;
}
input[type="submit"] + span.fs11 + a::before,
button[type="submit"] + span.fs11 + a::before,
.btn + span.fs11 + a::before,
.btn + span.mx-2.text-muted + a::before {
    content: "";
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E") center / contain no-repeat;
}
input[type="submit"] + span.fs11 + a:hover,
button[type="submit"] + span.fs11 + a:hover,
.btn + span.fs11 + a:hover,
.btn + span.mx-2.text-muted + a:hover {
    border-color: var(--cplv-line-strong);
    background: var(--cplv-bg);
    color: var(--cplv-ink);
    text-decoration: none;
}

/* ---- ряд: по центру блока, с отбивкой сверху ----
   ⚠️ !important у выключки: у ячейки стоит атрибут align="center", но бутстрап
   темы описывает его правилом с !important — обычное правило до него не доходит.
   Ряд оставляем ячейкой таблицы (не флексом): display:flex на td выбивает
   ячейку из строки и теряет colspan. Ровность даёт vertical-align выше. */
.wbox_content td[align="center"]:has(> input[type="submit"]),
.wbox_content td[align="center"]:has(> button[type="submit"]),
.wbox_content td[align="center"]:has(> .btn) {
    padding: 22px 0 8px !important;
    text-align: center !important;
    border-top: 1px solid var(--cplv-line);
    /* ⚠️ line-height:0 у СТРОКИ, а не у кнопок. Кнопки — строчные блоки, и
       `vertical-align:middle` считает середину от базовой линии родителя плюс
       половина роста буквы «х». Пока у строки есть свой межстрочный интервал,
       обе кнопки съезжают по-разному — отсюда и ступенька. Обнуляем интервал
       строки: собственный line-height у кнопок задан выше. */
    line-height: 0;
    font-size: 0;
}

/* Часть виджетов (код переноса, синхронизация) обёртывает ряд кнопок в
   <center> — приводим к тому же виду.
   ⚠️ У раздела DNS для того же случая своё правило за #dns-service — оно
   специфичнее и остаётся в силе. */
.wbox_content > center {
    display: block;
    margin-top: 22px;
    padding-top: 20px;
    border-top: 1px solid var(--cplv-line);
    text-align: center;
}
/* Здесь ряд можно сделать флексом: <center> оборачивает форму целиком, а не
   ячейку таблицы, поэтому строка не ломается. */
.wbox_content > center > form {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 32px;
    text-align: center;
}
.wbox_content > center > form input[type="submit"] + span.fs11 + a,
.wbox_content > center > form .btn + span.fs11 + a { margin-left: 0; }

/* ---- список доменов: отбор по состоянию ----
   Слева вкладки состояний с числом, справа кнопки. Вид тот же, что у
   таблеток раздела DNS: активная — заливка цветом текста, остальные —
   вложенная плашка. */
/* Ряд целиком: вкладки слева, кнопки справа.
   ⚠️ Своя разметка, а не .nav-tabs-wrapper темы: у темы этот ряд описан
   правилами с !important (`body .nav-tabs-wrapper ul:has(…){flex-wrap:wrap
   !important}`), из-за которых кнопки уезжали под вкладки. Спорить с ними
   дороже, чем поставить свой контейнер. */
.cplv-listbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}
.cplv-listbar__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    margin-left: auto;
}
/* ---- порядок списка: две кнопки без подписи ---- */
.cplv-sort { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.cplv-sort__i { display: inline-flex; }
body .cplv-sort-btn {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    justify-content: center;
    min-height: 40px;
    /* Ширина общая: у кнопок порядка два знака (предмет и стрелка), у кнопки
       отбора один, и она была уже соседних. */
    min-width: 52px;
    padding: 0 8px;
    /* ⚠️ Кнопка отбора — <button>, а соседние — ссылки: у кнопки своя рамка
       от темы, и она выглядела иначе. Ряд обязан быть одинаковым. */
    border: 0;
    -webkit-appearance: none;
    appearance: none;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    text-decoration: none;
}
body .cplv-sort-btn:hover { background: var(--cplv-line); color: var(--cplv-ink); }
body .cplv-sort__i.active .cplv-sort-btn { background: var(--cplv-ink); color: var(--cplv-bg); }
body .cplv-sort-btn .material-icons { font-size: 18px; }
body .cplv-sort-btn .sort-icon { font-size: 16px; opacity: .7; }

/* Ряд состояний — свой блок под шапкой, в одну строку. Не влезает —
   прокручивается вбок, а не переносится вразнобой. */
.cplv-filterbar { margin-bottom: 22px; }
.cplv-filterbar[hidden] { display: none; }
.cplv-dom-filters {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0;
    padding: 0;
    list-style: none;
}
.cplv-dom-filters::-webkit-scrollbar { display: none; }
.cplv-dom-filters .nav-item { flex: 0 0 auto; }
.cplv-dom-filters .nav-item { margin: 0; list-style: none; }
body .cplv-dom-filters .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 14px;
    border: 0;
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
}
body .cplv-dom-filters .nav-link:hover { background: var(--cplv-line); color: var(--cplv-ink); }
body .cplv-dom-filters .nav-item.active > .nav-link {
    background: var(--cplv-ink);
    color: var(--cplv-bg);
}
.cplv-filter-n { opacity: .65; font-variant-numeric: tabular-nums; }

/* ---- кнопка со знаком ---- */
.cplv-btn-icon { display: inline-flex; align-items: center; gap: 8px; }
.cplv-btn-icon__ic { display: inline-flex; }
.cplv-btn-icon__ic svg { width: 16px; height: 16px; }

@media (max-width: 767px) {
    /* На телефоне ряд ломается на две строки: сверху порядок и отбор,
       кнопки — отдельной строкой во всю ширину. В одну строку они не влезают
       и уводили страницу вбок. */
    .cplv-listbar { flex-wrap: wrap; }
    .cplv-listbar__actions { order: 3; width: 100%; margin-left: 0; flex-wrap: wrap; }
    /* Подпись «Массовый перенос доменов» длиннее половины экрана: разрешаем ей
       переноситься, иначе кнопка не сжимается и ряд уводит страницу вбок. */
    .cplv-listbar__actions .btn {
        flex: 1 1 150px;
        justify-content: center;
        white-space: normal;
        text-align: center;
    }
}

/* ============================================================================
   ВСПЛЫВАЮЩИЕ СООБЩЕНИЯ (PNotify)

   Панель показывает их поверх страницы: «изменения ещё не подтверждены»,
   «название домена обновлено» и т.п. В стоке это ярко-синий прямоугольник
   набора brighttheme (#3891f2) с белым текстом — единственное место в панели
   с таким цветом, и в тёмной теме он бьёт по глазам (замечание владельца
   02.09.2026).

   Стало: та же плашка, что у сообщений на страницах (.cplv-msg) — полотно
   блока, контур в тон события, текст обычным цветом. Тон задаётся один раз
   переменной --tone, дальше её берут и контур, и знак.
   ============================================================================ */
body .ui-pnotify .brighttheme-info    { --tone: var(--cplv-info); }
body .ui-pnotify .brighttheme-success { --tone: var(--cplv-ok); }
body .ui-pnotify .brighttheme-error   { --tone: var(--cplv-danger); }
body .ui-pnotify .brighttheme-notice  { --tone: var(--cplv-warn); }

/* ⚠️ !important: набор brighttheme объявляет свои цвета именно так
   (`.ui-pnotify .brighttheme.brighttheme-info{background-color:#3891f2!important}`),
   и обычное правило до него не доходит, даже более специфичное. */
body .ui-pnotify .brighttheme.ui-pnotify-container {
    padding: 14px 16px;
    border: 1px solid var(--tone, var(--cplv-line)) !important;
    border-radius: var(--cplv-radius);
    /* Подложка — полотно блока, слегка подкрашенное тоном события: ровно так
       же, как у сообщений на страницах (.cplv-msg--warn/ok/danger). Первая
       строка — запас: если браузер не понимает color-mix, останется чистое
       полотно. */
    background-color: var(--cplv-surface) !important;
    background-color: color-mix(in srgb, var(--tone, transparent) 9%, var(--cplv-surface)) !important;
    background-image: none !important;
    color: var(--cplv-ink) !important;
    box-shadow: 0 10px 30px rgba(16, 20, 28, .14);
    font-size: 14px;
    line-height: 1.5;
}
body .ui-pnotify .ui-pnotify-title {
    margin-bottom: 4px;
    color: var(--cplv-ink) !important;
    font-size: 15px;
    font-weight: 600;
}
body .ui-pnotify .ui-pnotify-text { color: var(--cplv-muted) !important; }
body .ui-pnotify .ui-pnotify-container > .ui-pnotify-text:only-child { color: var(--cplv-ink) !important; }

/* Знак и крестик — в тон события, а не белым по синему. */
body .ui-pnotify .brighttheme-icon-info::after,
body .ui-pnotify .brighttheme-icon-success::after,
body .ui-pnotify .brighttheme-icon-error::after,
body .ui-pnotify .brighttheme-icon-notice::after { color: var(--tone, var(--cplv-muted)); }
body .ui-pnotify [class^="brighttheme-icon"],
body .ui-pnotify [class*=" brighttheme-icon"],
body .ui-pnotify .brighttheme [class^="brighttheme-icon"],
body .ui-pnotify .brighttheme [class*=" brighttheme-icon"] {
    border-color: var(--tone, var(--cplv-muted)) !important;
    color: var(--tone, var(--cplv-muted)) !important;
    background-color: transparent !important;
}
body .ui-pnotify .ui-pnotify-closer,
body .ui-pnotify .ui-pnotify-sticker { color: var(--cplv-muted); opacity: .75; }
body .ui-pnotify .ui-pnotify-closer:hover,
body .ui-pnotify .ui-pnotify-sticker:hover { opacity: 1; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) body .ui-pnotify .brighttheme.ui-pnotify-container {
        box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
    }
}
:root[data-theme="dark"] body .ui-pnotify .brighttheme.ui-pnotify-container {
    box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
}

/* ============================================================================
   ПОРЯДОК КНОПОК СОЦВХОДА: GOOGLE ПЕРВОЙ, GITHUB ВТОРОЙ
   ============================================================================
   Решение владельца 05.09.2026, действует на всех экранах входа.
   Виджет HostBill ({clientwidget module="login"}) печатает кнопки в порядке
   своих модулей — GitHub, потом Google, — и порядка в нём не задать: каждый
   модуль печатает себя сам. Поэтому переставляем раскладкой.
   Опознаём кнопку по классу цвета, который проставляет сам модуль:
   .btn-red — Google, .btn-dark — GitHub.
   ⚠️ Браузер без :has() (до 2023 года) оставит порядок виджета — вёрстка при
   этом не ломается, кнопки просто идут как раньше.
   Те же три правила продублированы для страниц входа в custom/cplv-auth.css:
   тот файл подключается отдельно (страницы авторизации рисует вёрстка сайта). */
body .cplv-sso-row > * { order: 3; }
body .cplv-sso-row > *:has(.btn-red) { order: 1; }
body .cplv-sso-row > *:has(.btn-dark) { order: 2; }

/* ============================================================================
   СТРАНИЦА СЧЁТА: СОСТОЯНИЕ И ДЕЙСТВИЯ
   ============================================================================
   Просьба владельца 05.09.2026. Было: бледный бейдж у правого края строки и три
   одинаковые серые кнопки — «Вернуться к счетам», «Печать», PDF. Со счёта уходят,
   посмотрев ровно одно (оплачен или нет), а из действий нажимают печать и PDF;
   возврат к списку — навигация, он не должен спорить с ними видом. */

/* Состояние сразу за номером: заливка в цвет состояния, а не подпись на сером.
   ⚠️ Специфичность выше базовых `body .badge-*` (два класса вместо одного) и
   с !important — иначе базовое правило перекрасило бы обратно в серое. */
body h1.cplv-srv-name .cplv-inv-status {
    display: inline-block;
    margin-left: 10px;
    padding: 6px 10px;
    border-radius: 999px;
    vertical-align: 3px;      /* выравниваем по строчным буквам заголовка */
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
}
body .cplv-inv-status.badge-Paid,
body .cplv-inv-status.badge-Active { background-color: var(--cplv-ok) !important; color: #fff !important; }
body .cplv-inv-status.badge-Unpaid,
body .cplv-inv-status.badge-Pending,
body .cplv-inv-status.badge-Receiptunpaid { background-color: var(--cplv-warn) !important; color: #fff !important; }
body .cplv-inv-status.badge-Cancelled,
body .cplv-inv-status.badge-Overdue,
body .cplv-inv-status.badge-Chargeback,
body .cplv-inv-status.badge-Refunded { background-color: var(--cplv-danger) !important; color: #fff !important; }

/* Возврат к списку — ссылка со стрелкой. Кнопкой он выглядел как действие над
   счётом и стоял первым, забирая внимание у «Оплатить». */
body a.cplv-backlink {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 4px 0 0;
    background: none;
    border: 0;
    color: var(--cplv-muted);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
}
body a.cplv-backlink:hover { color: var(--cplv-ink); text-decoration: underline; }
/* Навигация слева, действия справа (просьба владельца 05.09.2026): ряд один, но
   читается на две части — «уйти» у левого края, «сделать со счётом» у правого.
   Отступ вешаем на саму ссылку, а не на полосу: .cplv-ticket__bar общая со
   страницей обращения, а .cplv-backlink есть только на счёте. */
body .cplv-ticket__bar > a.cplv-backlink { margin-right: auto; }
body a.cplv-backlink > .material-icons { font-size: 18px; line-height: 1; }

/* Печать и PDF: белая кнопка в контуре, знак — зелёным. Серые btn-secondary
   рядом с серым фоном полосы читались как выключенные. */
body .btn.cplv-inv-act {
    background-color: var(--cplv-surface) !important;
    border: 1px solid var(--cplv-line) !important;
    color: var(--cplv-ink) !important;
    box-shadow: var(--cplv-shadow);
}
body .btn.cplv-inv-act:hover {
    background-color: var(--cplv-surface-2) !important;
    border-color: var(--cplv-accent) !important;
    color: var(--cplv-ink) !important;
}
body .btn.cplv-inv-act > .material-icons { color: var(--cplv-accent); }

/* ============================================================================
   ЧУЖИЕ ОТСТУПЫ: шаг 5 у Bootstrap (DESIGN-SPEC §4, правило 10)

   Тема размечена служебными классами Bootstrap 4, и его пятая ступень — 48 px.
   Пустая полоса шире 32 читается как обрыв страницы, поэтому ступень приводится
   к потолку шкалы. Ступени 1–4 (4 · 8 · 16 · 24) в шкалу попадают и остаются.

   ⚠️ Свои правила Bootstrap помечает !important — перебить их можно только
   таким же !important И более сильным селектором, отсюда префикс body.
   ============================================================================ */
body .m-5  { margin: 32px !important; }
body .mt-5, body .my-5 { margin-top: 32px !important; }
body .mb-5, body .my-5 { margin-bottom: 32px !important; }
body .ml-5, body .mx-5 { margin-left: 32px !important; }
body .mr-5, body .mx-5 { margin-right: 32px !important; }
body .p-5  { padding: 32px !important; }
body .pt-5, body .py-5 { padding-top: 32px !important; }
body .pb-5, body .py-5 { padding-bottom: 32px !important; }
body .pl-5, body .px-5 { padding-left: 32px !important; }
body .pr-5, body .px-5 { padding-right: 32px !important; }

/* ============================================================================
   ГЕОМЕТРИЯ РАБОЧЕЙ ОБЛАСТИ И ШАГ МЕЖДУ БЛОКАМИ
   (DESIGN-SPEC §4, правила 1, 2, 7 и 10; задача E1, находки E2–E5, E11)

   Тема задаёт рабочей области свои числа:
     ≥994: margin calc(30px + 72px) auto 30px, padding 20  → под шапкой 50,
           до подвала 50;
     ≤993: margin 0 auto 20px, padding 10.
   Поле страницы по правилу 7 — 22 (на телефоне 14), полоса под шапкой и над
   подвалом — те же 22.

   ⚠️ Селектор сильнее темы намеренно: её app.css подключается ПОЗЖЕ нашего
   файла, и при равном весе побеждает она. Тема адресует узел как
   `body .body-content .section-main` — добавляем имя тега, чтобы выиграть вес.
   ============================================================================ */
/* ⚠️ flow-root обязателен: без него margin-top первого блока СХЛОПЫВАЕТСЯ с
   полем самой рабочей области (у неё сверху нет ни рамки, ни padding) — 22
   уходили наружу, и первый блок вставал вплотную к шапке. flow-root заводит
   свой контекст форматирования: поле остаётся внутри. Заодно он держит внутри
   плавающие блоки страницы машины. */
body .body-content section.section-main { display: flow-root; }

@media (min-width: 994px) {
    body .body-content section.section-main {
        /* 70 — высота фиксированной шапки. Полосу до первого блока даёт его
           собственный margin-top, поэтому padding сверху нулевой: иначе число
           складывалось бы с ним и под шапкой выходило 44. */
        margin: 70px auto 0 auto;
        padding: 0 22px 22px;
    }
}
@media (max-width: 993px) {
    body .body-content section.section-main {
        margin-bottom: 0;
        padding: 0 22px 22px;
    }
}
@media (max-width: 767px) {
    body .body-content section.section-main { padding: 0 14px 14px; }
}

/* Верхние блоки рабочей области идут через 22 — и первый от шапки, и соседи
   между собой. Тема даёт разделам свои поля (`.section-account { margin: 40px 0 }`)
   и служебные классы Bootstrap; здесь они сводятся к одному шагу.

   ⚠️ Отступ висит на КАЖДОМ верхнем блоке, а не на первом через :first-child:
   страницы начинаются со служебного <script>, и первым ребёнком оказывается он —
   исключение доставалось невидимому узлу, а первый настоящий блок уезжал вниз
   на 44. У display:none поле ничего не рисует, поэтому так правило верно всегда. */
body .body-content section.section-main > * {
    margin-top: 22px !important;
    margin-bottom: 0 !important;
}

/* Раздел темы, завёрнутый в другой блок (страница домена, услуги), несёт свои
   `margin: 40px 0` — они складывались с шагом обёртки и давали 62 до подвала.
   Шаг задаёт верхний блок, вложенному разделу поля не нужны. Селектор нарочно
   сильнее правила выше: прямых детей рабочей области он не трогает. */
body .body-content section.section-main > * .section-account {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

/* Соседние блоки страницы домена стояли вплотную и читались как один. */
#cplv-domain .cplv-box + .cplv-box { margin-top: 22px; }

/* Виджеты главной: блок пустой у нашего бренда — отступ появляется только
   тогда, когда внутри что-то отрисовалось. */
.cplv-dash-widgets { margin-top: 22px; }
.cplv-dash-widgets:not(:has(*)) { margin-top: 0; }

/* Телефон: поля блока 16 и 18 (правило 2). Часть блоков переключалась, часть
   оставалась на 22/24 — теперь правило одно на все. */
@media (max-width: 767px) {
    body .cplv-box { padding: 16px 18px; }
}

/* ============================================================================
   ДЕЙСТВИЯ В ШАПКЕ БИЛЛИНГА
   Кнопки страницы счетов стоят в одной строке с суммами, у правого края
   (просьба владельца 05.09.2026). Отдельной строки с подписью «Текущий статус
   ваших счетов и баланса» больше нет — суммы слева говорят то же самое.
   ============================================================================ */
.cplv-billing-actions,
.cplv-billing-actions #invoice_actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
@media (max-width: 767px) {
    /* На телефоне шапка складывается в колонку: действие уходит вниз и
       занимает всю ширину — по правилу мобильного макета. */
    .cplv-billing-actions { width: 100%; margin-top: 14px; }
    .cplv-billing-actions #invoice_actions { width: 100%; }
    .cplv-billing-actions .btn { width: 100%; }
}

/* ============================================================================
   ЗАПРОС НА ОТМЕНУ (/clientarea/cancel/)
   Экран решения, которое не отменить: сначала объяснение и предупреждение,
   и только потом поля. Разметка — cp-lv/services/cancelationrequest.tpl.
   ============================================================================ */
.cplv-cancel__for { margin: 10px 0 0; font-size: 15px; font-weight: 400; color: var(--cplv-muted); }
.cplv-cancel__for b { color: var(--cplv-ink); }
.cplv-cancel { padding: 22px 24px; }
.cplv-cancel__intro { margin: 0 0 18px; font-size: 15px; line-height: 1.55; color: var(--cplv-ink); max-width: 820px; }
/* Форма внутри блока: собственные поля блока уже заданы, второй раз не нужны. */
.cplv-cancel .cplv-form { padding: 0; margin-top: 22px; }
.cplv-cancel .cplv-msg { margin-top: 0; }
.cplv-cancel .cplv-form .cplv-msg { margin-top: 18px; }
.cplv-cancel__reasons { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.cplv-cancel__reason { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; cursor: pointer; }
.cplv-cancel__reason input { margin: 0; }
/* Кнопка необратимого действия шире обычной: её нажимают осознанно. */
.cplv-cancel .cplv-form__actions .btn { min-width: 220px; }
@media (max-width: 767px) {
    .cplv-cancel { padding: 16px 18px; }
    .cplv-cancel .cplv-form__actions .btn { width: 100%; min-width: 0; }
}

/* ============================================================================
   «НАЗАД К УСЛУГЕ» над открытым разделом
   Разметка — cp-lv/services/_cplv-svc-back.tpl. Ссылка приглушённая: это выход,
   а не действие страницы, и перетягивать внимание с содержимого раздела ей
   не нужно.
   ============================================================================ */
.cplv-back {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 2px 0 14px;
    padding: 6px 12px 6px 8px;
    border: 1px solid var(--cplv-line);
    border-radius: 30px;
    background: var(--cplv-surface);
    font-size: 14px;
    line-height: 1.2;
    color: var(--cplv-muted);
    text-decoration: none;
    transition: color .15s, border-color .15s;
}
.cplv-back:hover,
.cplv-back:focus {
    color: var(--cplv-ink);
    border-color: var(--cplv-line-strong);
    text-decoration: none;
}
.cplv-back svg { flex: none; }

/* ============================================================================
   РАЗДЕЛ «НАСТРОЙКА СЕРТИФИКАТА» (виджет ssl_config ядра)
   Разметка — includes/types/ssltype/widgets/ssl_config/*.tpl (копии в
   hostbill/panel-templates/core-widgets/ssl_config/). Виджет ядра рисовал голые
   <h2>/<hr>/<pre>, здесь он приведён к блокам панели.

   Главный экран — мастер запроса на сертификат: одна кнопка делает CSR и ключ,
   вторая отправляет их в биллинг. Поэтому кнопка шага крупная, а ручная вставка
   своего CSR уведена вниз под ссылку: ею пользуется меньшинство.
   ============================================================================ */
.cplv-sslbox { padding: 22px 24px; }
/* Заголовок раздела: до 11.09.2026 им была мелкая подпись блока, и шаг мастера
   начинался как будто без названия. */
.cplv-sslw__h1 {
    margin: 0 0 10px;
    font-size: 24px;
    line-height: 1.25;
    font-weight: 700;
    color: var(--cplv-ink);
}
/* ⚠️ Объяснение обязано ПЕРЕНОСИТЬСЯ. Оно печаталось одной строкой и обрезалось
   краем блока: у текста не было ни ограничения ширины в символах, ни разрешения
   рвать длинные слова. */
.cplv-sslw__intro {
    margin: 0 0 22px;
    max-width: 72ch;
    font-size: 15px;
    line-height: 1.55;
    color: var(--cplv-ink);
    white-space: normal;
    overflow-wrap: anywhere;
}
.cplv-sslw__note {
    margin: 0 0 12px;
    font-size: 14px;
    line-height: 1.5;
    color: var(--cplv-muted);
}
/* Пояснение, стоящее МЕЖДУ блоками формы (а не внутри блока), — например строка
   «поля со звёздочкой обязательны» перед группами контактов. Без отступа сверху
   оно прилипало к нижнему краю предыдущего блока: вплотную, зазор 0. */
.cplv-sslw__note--lead { margin-top: 18px; }

/* Блок с содержимым: запрос, ключ, группа полей.
   ⚠️ Подложка БЕЛАЯ, как у блоков на «Данных аккаунта». Серый фон
   (--cplv-surface-2) делал из формы набор вложенных серых коробок — в панели так
   не выглядит ни одна форма (замечание владельца 11.09.2026). */
.cplv-sslw__pane {
    margin: 18px 0 0;
    padding: 18px 20px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    background: var(--cplv-surface);
}
.cplv-sslw__pane-head {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    font-size: 15px;
    color: var(--cplv-ink);
}
.cplv-sslw__tools { display: flex; flex-wrap: wrap; gap: 8px; }
/* Кнопки в ряду инструментов узкие: это не действие страницы, а подручные
   операции над уже готовым текстом. */
.cplv-sslw__tools .btn { min-width: 0; }

/* Ключ и запрос: моноширинный текст, который копируют целиком. */
.cplv-sslw__pem {
    font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
    line-height: 1.45;
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
    /* Само поле с ключом — слегка утоплено: это единственная серая плашка,
       которую здесь оставляем, и она отделяет машинный текст от формы. */
    background: var(--cplv-surface-2);
}
.cplv-sslw__csrdata { margin-bottom: 14px; }

/* Ручная вставка своего CSR — вторичный путь, отбит линией от мастера. */
.cplv-sslw__own {
    margin-top: 26px;
    padding-top: 18px;
    border-top: 1px solid var(--cplv-line);
}
.cplv-sslw__own-link { font-size: 14px; color: var(--cplv-muted); }
.cplv-sslw__own-link:hover { color: var(--cplv-ink); }
.cplv-sslw__own-body { margin-top: 14px; }
.cplv-sslw__own #cplv-ssl-csr,
.cplv-sslw__pane + .cplv-sslw__own { margin-top: 22px; }

.cplv-sslw__dcv { margin-top: 16px; }
.cplv-sslw__check { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; }
.cplv-sslw__check input { margin: 0; }

@media (max-width: 767px) {
    .cplv-sslbox { padding: 16px 18px; }
    .cplv-sslw__pane { padding: 14px; }
    .cplv-sslw__pane-head { align-items: flex-start; flex-direction: column; }
    .cplv-form__actions .btn { width: 100%; }
}

/* --- мастер запроса на сертификат: правки 11.09.2026 --- */
/* Поле ручной вставки — во весь запрос: CSR это 15–20 строк, и в маленьком окне
   искать в нём опечатку невозможно. */
.cplv-sslw__pem--big { min-height: 340px; }
/* Кнопка отправки своего запроса — крупная и отдельной строкой внизу блока. */
.cplv-sslw__own-body .cplv-form__actions { margin-top: 18px; }
.cplv-sslw__own-body .cplv-form__actions .btn { min-width: 220px; }
.cplv-sslw__own-body .cplv-msg { margin-top: 14px; }
/* Галочка «те же данные» стоит в ряду полей и не должна получать отступ подписи. */
.cplv-sslc__check-row { display: flex; align-items: center; }
@media (max-width: 767px) {
    .cplv-sslw__h1 { font-size: 20px; }
    .cplv-sslw__pem--big { min-height: 240px; }
    .cplv-sslw__own-body .cplv-form__actions .btn { width: 100%; min-width: 0; }
}
/* Галочка «те же данные» занимает всю строку сетки: она относится ко ВСЕЙ группе
   полей ниже, а не стоит с ними в один ряд. */
.cplv-sslw__pane .cplv-fields > .cplv-sslc__check-row { grid-column: 1 / -1; }

/* ============================================================================
   ПЛАШКА ОШИБКИ ПОЛЯ (.cplv-msg--field)
   Разметка — ssl_config/conf_csr.tpl. Стоит НАД полем, к которому относится:
   читают сверху вниз, и сообщение под кнопкой человек находил уже после второго
   нажатия. От обычной .cplv-msg отличается ролью: это не предупреждение о
   последствиях, а разбор того, что введено не так, — поэтому у неё своя
   красноватая подложка из палитры, а текст даётся цветом ошибки и чуть плотнее,
   а не серым, как второстепенное пояснение.
   ============================================================================ */
.cplv-msg--field {
    gap: 12px;
    margin: 0 0 16px;
    padding: 13px 16px;
    align-items: center;
    border-color: var(--cplv-danger-line);
    background: var(--cplv-danger-bg);
}
.cplv-msg--field .cplv-msg__icon {
    flex: none;
    background: transparent;
    color: var(--cplv-danger);
}
.cplv-msg--field .cplv-msg__icon svg { width: 22px; height: 22px; }
.cplv-msg--field .cplv-msg__desc {
    margin-top: 0;
    font-size: 14.5px;
    font-weight: 500;
    line-height: 1.45;
    color: var(--cplv-danger-ink);
}

/* Поле с ошибкой: контур в тон плашки и мягкое свечение — чтобы взгляд от
   сообщения сразу попадал на ввод, который надо поправить.
   ⚠️ Селектор повторяет форму соседнего правила панели (body .cplv-form
   .form-control …): у того же веса, но оно идёт ниже по файлу и выигрывало бы
   при равной силе. Поэтому здесь тот же префикс плюс .is-invalid. */
body .cplv-form .form-control.is-invalid,
body .cplv-form textarea.form-control.is-invalid,
body .cplv-field > .form-control.is-invalid,
body .cplv-field > textarea.form-control.is-invalid,
body .cplv-form .form-control.is-invalid:focus,
body .cplv-field > .form-control.is-invalid:focus {
    border-color: var(--cplv-danger);
    background: var(--cplv-danger-bg);
    box-shadow: 0 0 0 3px var(--cplv-danger-bg);
}

/* --- кнопки мастера: со знаком, как везде в панели --- */
.cplv-sslw .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.cplv-sslw .btn .material-icons { font-size: 18px; line-height: 1; }
/* Кнопки над текстом запроса узкие и не растягиваются: это подручные операции. */
.cplv-sslw__tools .btn { min-width: 0; padding-left: 12px; padding-right: 14px; }
/* Галочка «те же данные, что в реквизитах организации» — над группой полей,
   к которой относится, с отбивкой от заголовка блока. */
.cplv-sslc__fromorg { margin: 0 0 16px; }
.cplv-sslc__geo { color: var(--cplv-warn); }
/* Блок «Указать данные сертификата» на шаге запроса — вторичный путь, как и
   ручная вставка CSR: отбит линией и свёрнут. */
.cplv-sslw__subj { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--cplv-line); }
.cplv-sslw__subj-body { margin-top: 14px; }
/* Шаг подтверждения домена: блок способа отбит от выбора, поля адресов — от
   пояснения. Ни .cplv-field, ни .cplv-fields своего верхнего отступа не имеют
   (они рассчитаны на сетку), поэтому без этого экран шёл сплошняком. */
.cplv-sslw__dcv-emails { margin-top: 16px; }
.cplv-sslw__pane > .cplv-sslw__note:last-child { margin-bottom: 0; }


/* ============================================================================
   ДОПОЛНЕНИЕ К УСЛУГЕ (страница ?cmd=cart&cat_id=addons)
   Разметка — templates/cp-lv/overrides/cart0.tpl. Страница продаёт одну услугу,
   поэтому карточка крупная: картинка, описание, цена и одно действие.
   ========================================================================== */
.cplv-addon-list { display: flex; flex-direction: column; gap: 18px; margin-top: 22px; }
.cplv-addon {
    display: grid;
    grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
    gap: 28px;
    align-items: center;
    padding: 26px 28px;
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
.cplv-addon__media img { display: block; width: 100%; height: auto; border-radius: var(--cplv-radius-sm); }
.cplv-addon__title { margin: 0 0 10px; font-size: 22px; line-height: 1.25; color: var(--cplv-ink); }
.cplv-addon__text { margin-bottom: 18px; font-size: 15px; line-height: 1.6; color: var(--cplv-ink); max-width: 68ch; }
.cplv-addon__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.cplv-addon__sum { font-size: 28px; font-weight: 700; color: var(--cplv-ink); }
.cplv-addon__per { font-size: 14px; color: var(--cplv-muted); }
.cplv-addon__cycle, .cplv-addon__apply { display: flex; flex-direction: column; gap: 6px; max-width: 380px; margin-bottom: 14px; font-size: 14px; color: var(--cplv-muted); }
.cplv-addon__for { margin: 0 0 16px; font-size: 14px; color: var(--cplv-muted); }
/* Главное действие страницы: крупная кнопка, её видно без прокрутки. */
.cplv-addon__cta { min-width: 260px; padding-top: 12px; padding-bottom: 12px; font-size: 16px; }

@media (max-width: 991px) {
    .cplv-addon { grid-template-columns: 1fr; gap: 18px; padding: 20px; }
    .cplv-addon__cta { width: 100%; min-width: 0; }
}

/* ============================================================================
   БАННЕР «ПОСТАВИМ СЕРТИФИКАТ ЗА ВАС» на странице услуги SSL.
   Разметка — templates/cp-lv/services/service_details.tpl. Показывается, только пока
   дополнение действительно можно заказать (у услуги есть доступное дополнение).
   ========================================================================== */
.cplv-svc-offer {
    display: flex;
    align-items: center;
    gap: 20px;
    margin: 0 0 18px;
    padding: 18px 22px;
    border: 1px solid var(--cplv-line);
    border-left: 4px solid var(--cplv-ok);
    border-radius: var(--cplv-radius);
    background: var(--cplv-surface);
}
.cplv-svc-offer__icon { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 50%; background: rgba(63, 143, 87, .12); color: var(--cplv-ok); }
.cplv-svc-offer__icon svg { width: 22px; height: 22px; }
.cplv-svc-offer__text { flex: 1 1 auto; min-width: 0; }
.cplv-svc-offer__title { display: block; font-weight: 600; color: var(--cplv-ink); }
.cplv-svc-offer__desc { display: block; margin-top: 2px; font-size: 14px; color: var(--cplv-muted); }
.cplv-svc-offer__btn { flex: 0 0 auto; }

@media (max-width: 767px) {
    .cplv-svc-offer { flex-direction: column; align-items: flex-start; }
    .cplv-svc-offer__btn { width: 100%; }
}


/* ============================================================================
   ПЕРЕХОД НА СЧЁТ ПОСЛЕ ОФОРМЛЕНИЯ (шаг 5, overrides/cart5.tpl)
   Экран живёт секунды: спиннер, строка, кнопка — и уход на счёт заказа.
   ========================================================================== */
.cplv-redir { max-width: 460px; margin: 12vh auto; padding: 0 20px; text-align: center; }
.cplv-redir__spin { width: 44px; height: 44px; margin: 0 auto 20px; border-radius: 50%;
    border: 3px solid var(--cplv-line); border-top-color: var(--cplv-ok);
    animation: cplv-redir-spin 900ms linear infinite; }
@keyframes cplv-redir-spin { to { transform: rotate(360deg); } }
.cplv-redir__title { margin: 0 0 8px; font-size: 18px; font-weight: 600; color: var(--cplv-ink); }
.cplv-redir__text { margin: 0 0 20px; font-size: 14px; line-height: 1.5; color: var(--cplv-muted); }
/* Текст платёжного модуля (реквизиты перевода) — мелким, он тут не главное. */
.cplv-redir__pay { margin: 0 0 20px; font-size: 13px; line-height: 1.6; color: var(--cplv-muted); }
.cplv-redir__btn { min-width: 200px; }

/* ============================================================================
   ВЫБОР СИСТЕМЫ ПРИ ПЕРЕУСТАНОВКЕ  (экран vpsdo=rebuild, шаблон
   includes/modules/Hosting/proxmox2/templates/clientarea/rebuild.tpl)

   Было: один <select> на 48 позиций, где ISO и готовые шаблоны лежали
   вперемешку. Клиент не мог понять, что одно ставится само за пять минут,
   а другое он будет ставить руками полчаса в консоли.

   ⚠️ Исходный <select> остаётся в разметке и прячется классом
   .cplv-os__fallback, который навешивает скрипт. Без JS экран работает
   как раньше — поэтому скрытие живёт здесь, а не в разметке.
   ============================================================================ */

/* ---- предупреждение об удалении данных ---- */
.cplv-os__warn {
    display: flex;
    gap: 12px;
    background: var(--cplv-danger-bg);
    border: 1px solid var(--cplv-danger-line);
    border-left-width: 3px;
    border-radius: var(--cplv-radius-sm);
    padding: 13px 15px;
    margin-bottom: 20px;
}
.cplv-os__warn-sign {
    flex: 0 0 20px;
    width: 20px; height: 20px;
    border-radius: 999px;
    background: var(--cplv-danger);
    color: #fff;
    display: grid; place-items: center;
    font-weight: 700; font-size: 13px; line-height: 1;
}
.cplv-os__warn b { display: block; color: var(--cplv-danger-ink); font-size: 14px; }
.cplv-os__warn b + span { display: block; margin-top: 3px; font-size: 13px; color: var(--cplv-ink); }

/* ---- исходный список: запасной путь без JS ---- */
.cplv-os__fallback { display: none; }

/* ---- вкладки источника ---- */
.cplv-os__tabs {
    display: flex;
    gap: 8px;
    border-bottom: 1px solid var(--cplv-line);
}
.cplv-os__tab {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 14px;
    background: none; border: 0;
    border-bottom: 2px solid transparent;
    color: var(--cplv-muted);
    font: inherit; font-size: 14px;
    cursor: pointer;
}
.cplv-os__tab:hover { color: var(--cplv-ink); }
.cplv-os__tab.is-on { color: var(--cplv-ink); border-bottom-color: var(--cplv-accent); }
.cplv-os__cnt {
    background: var(--cplv-surface-2);
    border-radius: 999px;
    padding: 1px 7px;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.cplv-os__tab.is-on .cplv-os__cnt { background: rgba(63, 143, 87, .14); color: var(--cplv-accent); }

/* ---- пояснение: свой тон на каждый сценарий ----
   Зелёный — ставится само; жёлтый — Windows, ждать дольше; синий — ручная
   установка. Цвет здесь несёт смысл, а не украшает: по нему видно, во что
   ввязываешься, ещё до чтения текста. */
.cplv-os__expl {
    display: flex; gap: 12px;
    padding: 14px 2px 16px;
    border-bottom: 1px solid var(--cplv-line);
    margin-bottom: 16px;
}
.cplv-os__expl-ic {
    flex: 0 0 32px; width: 32px; height: 32px;
    border-radius: 9px;
    display: grid; place-items: center;
}
.cplv-os__expl-ic::before { font-size: 16px; line-height: 1; }
.cplv-os__expl[data-tone="tpl"] .cplv-os__expl-ic { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
.cplv-os__expl[data-tone="tpl"] .cplv-os__expl-ic::before { content: "\26A1"; }
.cplv-os__expl[data-tone="win"] .cplv-os__expl-ic { background: rgba(138, 106, 21, .13); color: var(--cplv-warn); }
.cplv-os__expl[data-tone="win"] .cplv-os__expl-ic::before { content: "\23F3"; }
.cplv-os__expl[data-tone="iso"] .cplv-os__expl-ic { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }
.cplv-os__expl[data-tone="iso"] .cplv-os__expl-ic::before { content: "\1F5A5"; }
.cplv-os__expl-t { display: block; font-size: 14px; font-weight: 600; }
.cplv-os__expl-s { display: block; margin-top: 3px; font-size: 13px; color: var(--cplv-muted); }

/* ---- поиск и семейства ---- */
.cplv-os__toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
/* Поле поиска — ровно то же, что поле пароля: .form-control темы.
   Своя обёртка со значком лупы давала рамку в рамке, потому что у темы
   input уже со своей границей (замечание владельца 04.10.2026). */
.cplv-os__q { flex: 0 1 420px; max-width: 420px; min-width: 180px; }
.cplv-os__q::-webkit-search-cancel-button { cursor: pointer; }
.cplv-os__chips { display: flex; gap: 6px; flex-wrap: wrap; }
.cplv-os__chip {
    border: 1px solid var(--cplv-line);
    background: var(--cplv-surface);
    border-radius: 999px;
    padding: 5px 12px;
    font: inherit; font-size: 13px;
    color: var(--cplv-muted);
    cursor: pointer;
}
.cplv-os__chip:hover { border-color: var(--cplv-line-strong); color: var(--cplv-ink); }
.cplv-os__chip.is-on { background: var(--cplv-surface-2); border-color: var(--cplv-line-strong); color: var(--cplv-ink); font-weight: 600; }

/* ---- карточки систем ---- */
.cplv-os__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(226px, 1fr));
    gap: 10px;
}
.cplv-os__card {
    position: relative;
    display: flex; gap: 12px; align-items: flex-start;
    text-align: left;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    padding: 13px;
    font: inherit;
    color: var(--cplv-ink);
    cursor: pointer;
    transition: border-color .12s ease-out, box-shadow .12s ease-out;
}
.cplv-os__card:hover { border-color: var(--cplv-line-strong); box-shadow: var(--cplv-shadow); }
.cplv-os__card.is-sel { border-color: var(--cplv-accent); box-shadow: 0 0 0 2px rgba(63, 143, 87, .16); }
/* Пунктир у ISO — не украшение: контур «не сплошной» читается как «ещё не
   готовое», в отличие от залитой карточки готового образа. */
.cplv-os__card--iso { border-style: dashed; }
.cplv-os__card--iso.is-sel { border-color: var(--cplv-info); box-shadow: 0 0 0 2px rgba(47, 111, 159, .16); }

.cplv-os__logo {
    flex: 0 0 34px; width: 34px; height: 34px;
    border-radius: 9px;
    background: var(--cplv-surface-2);
    display: grid; place-items: center;
    color: var(--cplv-muted);
}
.cplv-os__logo img { width: 21px; height: 21px; display: block; }
/* Фирменный цвет системы — только на значке. Он опознаётся быстрее названия,
   поэтому цвет здесь работает как ярлык, а не как украшение. */
.cplv-os__logo--ubuntu    { color: #E95420; background: rgba(233, 84, 32, .10); }
.cplv-os__logo--debian    { color: #C70036; background: rgba(199, 0, 54, .10); }
.cplv-os__logo--almalinux { color: #0B7261; background: rgba(11, 114, 97, .10); }
.cplv-os__logo--rocky     { color: #10B981; background: rgba(16, 185, 129, .12); }
.cplv-os__logo--centos    { color: #932279; background: rgba(147, 34, 121, .10); }
.cplv-os__logo--fedora    { color: #3C6EB4; background: rgba(60, 110, 180, .12); }
.cplv-os__logo--alpine    { color: #0D597F; background: rgba(13, 89, 127, .10); }
.cplv-os__logo--arch      { color: #1793D1; background: rgba(23, 147, 209, .12); }
.cplv-os__logo--opensuse  { color: #73BA25; background: rgba(115, 186, 37, .14); }
.cplv-os__logo--kali      { color: #367BF0; background: rgba(54, 123, 240, .12); }
.cplv-os__logo--windows   { color: #0078D4; background: rgba(0, 120, 212, .12); }
.cplv-os__logo--freebsd   { color: #AB2B28; background: rgba(171, 43, 40, .10); }
.cplv-os__logo--opnsense  { color: #D94F00; background: rgba(217, 79, 0, .10); }
.cplv-os__logo--proxmox   { color: #E57000; background: rgba(229, 112, 0, .12); }
.cplv-os__logo--rescue    { color: #5c6472; background: var(--cplv-surface-2); }

.cplv-os__txt { min-width: 0; }
.cplv-os__nm { display: block; font-weight: 600; font-size: 14px; line-height: 1.3; }
.cplv-os__mt { display: block; margin-top: 2px; font-size: 12px; color: var(--cplv-muted);
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cplv-os__time { display: inline-block; margin-top: 6px; font-size: 11px; color: var(--cplv-muted);
                 background: var(--cplv-surface-2); border-radius: 999px; padding: 2px 8px;
                 font-variant-numeric: tabular-nums; }
.cplv-os__card.is-sel .cplv-os__time { background: rgba(63, 143, 87, .12); color: var(--cplv-accent); }
.cplv-os__card--iso.is-sel .cplv-os__time { background: rgba(47, 111, 159, .12); color: var(--cplv-info); }

.cplv-os__tick { position: absolute; right: 11px; top: 11px; width: 18px; height: 18px; border-radius: 999px; }
.cplv-os__card.is-sel .cplv-os__tick { background: var(--cplv-accent); }
.cplv-os__card.is-sel .cplv-os__tick::before {
    content: ""; position: absolute; left: 5px; top: 5px; width: 8px; height: 5px;
    border-left: 2px solid #fff; border-bottom: 2px solid #fff;
    transform: rotate(-45deg);
}
.cplv-os__card--iso.is-sel .cplv-os__tick { background: var(--cplv-info); }

.cplv-os__empty { margin: 18px 2px; color: var(--cplv-muted); font-size: 14px; }

/* ---- пароль и подвал ---- */
.cplv-os__pass { margin-top: 20px; }
.cplv-os__nopass {
    margin: 20px 0 0; font-size: 13px; color: var(--cplv-muted);
    border-left: 2px solid var(--cplv-info); padding: 6px 0 6px 11px;
}
.cplv-os__actions {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin-top: 22px; padding-top: 18px;
    border-top: 1px solid var(--cplv-line);
}
.cplv-os__sum { font-size: 13px; color: var(--cplv-muted); }
/* Кнопка переустановки — красная, а не фирменная зелёная: это уничтожение
   данных, и цвет должен предупреждать, а не приглашать. */
.cplv-os .cplv-os__go,
.cplv-os .cplv-os__go:hover,
.cplv-os .cplv-os__go:focus {
    background: var(--cplv-danger);
    border-color: var(--cplv-danger);
    color: #fff;
}
.cplv-os .cplv-os__go:hover { filter: brightness(.94); }

/* ============================================================================
   ОКНО ПОДТВЕРЖДЕНИЯ ПЕРЕУСТАНОВКИ
   Вместо системного confirm(): тот нельзя оформить, он не перечисляет
   последствия, и «ОК» в нём нажимается машинально. Кнопка включается только
   после ввода имени машины.
   ============================================================================ */
.cplv-osm { position: fixed; inset: 0; z-index: 1080; display: grid; place-items: center; padding: 16px; }
.cplv-osm[hidden] { display: none; }
.cplv-osm__ovl { position: absolute; inset: 0; background: rgba(8, 12, 18, .55); }
body.cplv-osm-open { overflow: hidden; }
.cplv-osm__box {
    position: relative;
    width: 100%; max-width: 460px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    background: var(--cplv-surface);
    border-radius: 14px;
    box-shadow: 0 30px 70px rgba(0, 0, 0, .4);
}
.cplv-osm__head { display: flex; gap: 14px; padding: 22px 22px 0; }
.cplv-osm__sign {
    flex: 0 0 42px; width: 42px; height: 42px;
    border-radius: 12px;
    background: var(--cplv-danger-bg);
    border: 1px solid var(--cplv-danger-line);
    color: var(--cplv-danger);
    display: grid; place-items: center;
    font-size: 21px; font-weight: 700; line-height: 1;
}
.cplv-osm__head h5 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.cplv-osm__head p { margin: 4px 0 0; font-size: 13px; color: var(--cplv-muted); }
.cplv-osm__body { padding: 16px 22px 0; }
.cplv-osm__loss {
    background: var(--cplv-danger-bg);
    border: 1px solid var(--cplv-danger-line);
    border-radius: 10px;
    padding: 13px 15px;
}
.cplv-osm__loss b { color: var(--cplv-danger-ink); font-size: 13px; }
.cplv-osm__loss ul { margin: 8px 0 0; padding-left: 18px; font-size: 13px; }
.cplv-osm__loss li { margin: 3px 0; }
.cplv-osm__what {
    margin-top: 14px;
    background: var(--cplv-surface-2);
    border-radius: 10px;
    padding: 12px 14px;
    display: flex; gap: 12px; align-items: center;
}
.cplv-osm__what .cplv-os__logo { background: var(--cplv-surface); }
.cplv-osm__nm { display: block; font-weight: 600; font-size: 14px; }
.cplv-osm__mt { display: block; margin-top: 2px; font-size: 12px; color: var(--cplv-muted); }
.cplv-osm__type { margin-top: 14px; }
.cplv-osm__type[hidden] { display: none; }
.cplv-osm__type label { display: block; margin-bottom: 7px; font-size: 13px; }
.cplv-osm__type code {
    font-family: "IBM Plex Mono", ui-monospace, monospace;
    background: var(--cplv-surface-2);
    padding: 1px 7px; border-radius: 4px; font-size: 13px;
}
.cplv-osm__type input { font-family: "IBM Plex Mono", ui-monospace, monospace; }
.cplv-osm__foot {
    display: flex; gap: 10px;
    padding: 18px 22px 22px;
    margin-top: 16px;
    border-top: 1px solid var(--cplv-line);
}
.cplv-osm__foot .btn { flex: 1; justify-content: center; text-align: center; }
.cplv-osm .cplv-osm__cancel {
    background: transparent;
    border: 1px solid var(--cplv-line-strong);
    color: var(--cplv-ink);
}
.cplv-osm .cplv-osm__ok {
    background: var(--cplv-danger);
    border-color: var(--cplv-danger);
    color: #fff;
}
.cplv-osm .cplv-osm__ok[disabled] { opacity: .45; cursor: not-allowed; }

@media (max-width: 767px) {
    .cplv-os__grid { grid-template-columns: 1fr; }
    .cplv-os__toolbar { flex-direction: column; align-items: stretch; }
    .cplv-os__q { max-width: none; flex: 1 1 auto; }
    /* min-width:0 обязателен: иначе ряд фильтров держит ширину всех чипов разом
       (на 360px это 283 при месте в 226) и выдавливает страницу вбок. */
    .cplv-os__chips { overflow-x: auto; flex-wrap: nowrap; min-width: 0; width: 100%; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
    .cplv-os__chip { flex: 0 0 auto; }
    /* Вкладок всего две, и подписи у них длинные («Ручная установка с ISO»).
       Прокручивать ряд вбок ради них неудобно — вторая вкладка пряталась за краем
       и выглядела обрезанной. На телефоне ставим их в две равные колонки и
       разрешаем перенос строки. */
    .cplv-os__tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 0; overflow: visible; }
    .cplv-os__tab { justify-content: center; text-align: center; padding: 9px 6px; gap: 6px; font-size: 13px; line-height: 1.25; white-space: normal; }
    .cplv-os__actions { flex-direction: column; align-items: stretch; }
    .cplv-os__actions .btn { width: 100%; }
    .cplv-osm__foot { flex-direction: column-reverse; }
}

/* Форма услуги в теме ограничена 720px — под поля ввода это верно, но выбор
   системы это сетка карточек, и на 720px в неё влезает две колонки вместо
   четырёх. Снимаем ограничение только здесь, а поля внутри по-прежнему узкие:
   растянутый на всю ширину ввод пароля выглядел бы нелепо. */
/* ⚠️ Перебиваем по id: у темы правило
   body .cloud #content-cloud form:has(.form-group) { max-width: 720px }
   — обычный классовый селектор его не берёт. */
body .cloud #content-cloud form#cplv-os-form,
body .cloud form#cplv-os-form { max-width: none; }
.cplv-os .cplv-os__pass .vm-password-input,
.cplv-os .cplv-os__keys .chosen-container,
.cplv-os .cplv-os__keys select { max-width: min(420px, 100%); }

/* ============================================================================
   ВЫБОР ЯЗЫКА — ШИРОКАЯ ПАНЕЛЬ (вариант 1 владельца, 04.10.2026)
   ============================================================================
   Языков 42, и выпадающий список их не вмещал: он прокручивался, а на телефоне
   вообще не показывался — там язык жил отдельным разделом левого меню, и клиент
   его не находил. Теперь это такая же широкая панель, как «Заказать», корзина и
   уведомления: тот же механизм, тот же оверлей, на телефоне — лист во весь экран.

   Числа носителей не выводим (решение владельца 04.10.2026): в макете они
   объясняли порядок, в рабочем интерфейсе это шум. Сам порядок остался — он
   задан ниже свойством order, потому что в Smarty 2 отсортировать массив нечем. */
body .cplv-wm--lang { padding-bottom: 10px; }

body .cplv-wm--lang .cplv-lang__head {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding-bottom: 10px;
}
body .cplv-lang__title { flex: 0 0 auto; }

/* Поле поиска — обычный .form-control темы, как на экране установки ОС.
   Своя обёртка со значком лупы давала рамку в рамке: у темы input уже со своей. */
body .cplv-lang__q {
    flex: 0 1 320px;
    max-width: min(320px, 100%);
    min-width: 170px;
    margin-left: auto;
    font-size: 14px;
    letter-spacing: normal;
    text-transform: none;
    font-weight: 400;
}

body .cplv-lang__sect {
    padding: 10px 32px 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}

body .cplv-lang__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
    gap: 2px 12px;
    padding: 0 32px 6px;
}
body .cplv-lang__grid--all { padding-bottom: 26px; }

body .cplv-lang__item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 9px 10px;
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
    font-size: 14px;
    line-height: 1.3;
    text-decoration: none;
}
body .cplv-lang__item:hover,
body .cplv-lang__item:focus-visible { background: var(--cplv-surface-2); color: var(--cplv-ink); text-decoration: none; }
body .cplv-lang__item.is-current { background: var(--cplv-surface-2); font-weight: 600; }

/* Флаг — картинка 21×16 с тонкой обводкой: без неё белые флаги (польский,
   японский) сливаются с карточкой. object-fit, потому что пропорции у файлов 4:3. */
body .cplv-lang__flag {
    flex: 0 0 21px;
    width: 21px;
    height: 16px;
    border-radius: 2px;
    object-fit: cover;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}
:root[data-theme="dark"] body .cplv-lang__flag,
body .cplv-lang__flag { box-shadow: 0 0 0 1px rgba(0, 0, 0, .12); }

body .cplv-lang__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body .cplv-lang__tick { margin-left: auto; font-size: 18px; color: var(--cplv-accent); }

body .cplv-lang__empty { padding: 0 32px 26px; color: var(--cplv-muted); font-size: 14px; }

/* Порядок в общем списке — по распространённости языка, а не по алфавиту
   служебных имён, в котором HostBill отдаёт массив. Smarty 2 сортировать не
   умеет, поэтому порядок живёт здесь: grid-элементам достаточно order. */
body .cplv-lang__grid--all [data-l="english"]    { order: 1; }
body .cplv-lang__grid--all [data-l="spanish"]    { order: 2; }
body .cplv-lang__grid--all [data-l="french"]     { order: 3; }
body .cplv-lang__grid--all [data-l="portuguese"] { order: 4; }
body .cplv-lang__grid--all [data-l="russian"]    { order: 5; }
body .cplv-lang__grid--all [data-l="german"]     { order: 6; }
body .cplv-lang__grid--all [data-l="turkish"]    { order: 7; }
body .cplv-lang__grid--all [data-l="italian"]    { order: 8; }
body .cplv-lang__grid--all [data-l="polish"]     { order: 9; }
body .cplv-lang__grid--all [data-l="ukrainian"]  { order: 10; }
body .cplv-lang__grid--all [data-l="uzbek"]      { order: 11; }
body .cplv-lang__grid--all [data-l="romanian"]   { order: 12; }
body .cplv-lang__grid--all [data-l="dutch"]      { order: 13; }
body .cplv-lang__grid--all [data-l="azerbaijani"]{ order: 14; }
body .cplv-lang__grid--all [data-l="kazakh"]     { order: 15; }
body .cplv-lang__grid--all [data-l="hungarian"]  { order: 16; }
body .cplv-lang__grid--all [data-l="greek"]      { order: 17; }
body .cplv-lang__grid--all [data-l="czech"]      { order: 18; }
body .cplv-lang__grid--all [data-l="swedish"]    { order: 19; }
body .cplv-lang__grid--all [data-l="serbian"]    { order: 20; }
body .cplv-lang__grid--all [data-l="bulgarian"]  { order: 21; }
body .cplv-lang__grid--all [data-l="croatian"]   { order: 22; }
body .cplv-lang__grid--all [data-l="danish"]     { order: 23; }
body .cplv-lang__grid--all [data-l="finnish"]    { order: 24; }
body .cplv-lang__grid--all [data-l="slovak"]     { order: 25; }
body .cplv-lang__grid--all [data-l="norwegian"]  { order: 26; }
body .cplv-lang__grid--all [data-l="georgian"]   { order: 27; }
body .cplv-lang__grid--all [data-l="albanian"]   { order: 28; }
body .cplv-lang__grid--all [data-l="belarusian"] { order: 29; }
body .cplv-lang__grid--all [data-l="tajik"]      { order: 30; }
body .cplv-lang__grid--all [data-l="armenian"]   { order: 31; }
body .cplv-lang__grid--all [data-l="lithuanian"] { order: 32; }
body .cplv-lang__grid--all [data-l="kyrgyz"]     { order: 33; }
body .cplv-lang__grid--all [data-l="turkmen"]    { order: 34; }
body .cplv-lang__grid--all [data-l="bosnian"]    { order: 35; }
body .cplv-lang__grid--all [data-l="latvian"]    { order: 36; }
body .cplv-lang__grid--all [data-l="slovenian"]  { order: 37; }
body .cplv-lang__grid--all [data-l="macedonian"] { order: 38; }
body .cplv-lang__grid--all [data-l="estonian"]   { order: 39; }
body .cplv-lang__grid--all [data-l="irish"]      { order: 40; }
body .cplv-lang__grid--all [data-l="maltese"]    { order: 41; }
body .cplv-lang__grid--all [data-l="icelandic"]  { order: 42; }

/* Блок «часто выбирают» — порядок владельца (04.10.2026), а не распространённость. */
body .cplv-lang__grid--top [data-l="english"]    { order: 1; }
body .cplv-lang__grid--top [data-l="russian"]    { order: 2; }
body .cplv-lang__grid--top [data-l="latvian"]    { order: 3; }
body .cplv-lang__grid--top [data-l="estonian"]   { order: 4; }
body .cplv-lang__grid--top [data-l="lithuanian"] { order: 5; }

@media (max-width: 1199px) {
    body .cplv-lang__sect, body .cplv-lang__grid, body .cplv-lang__empty { padding-left: 24px; padding-right: 24px; }
}
@media (max-width: 767px) {
    /* Лист во весь экран: одна колонка, пункты крупнее под палец, поиск —
       на всю ширину и прилипает к шапке листа. */
    body .cplv-wm--lang .cplv-lang__head { position: sticky; top: 0; z-index: 2; background: var(--cplv-surface); }
    body .cplv-lang__q { flex: 1 1 100%; max-width: none; margin-left: 0; }
    body .cplv-lang__grid { grid-template-columns: 1fr; }
    body .cplv-lang__item { padding: 11px 10px; font-size: 15px; }
}

/* ==========================================================================
   СОЗДАНИЕ МАШИНЫ В ОБЛАКЕ — экран vpsdo=createvm
   Размер машины задаётся долей свободных ресурсов пула, а не числами:
   клиент уже оплатил облако, ему важно «сколько из остатка отдать», а не цена.
   Разметку собирает createvm.tpl переносом стоковых полей — здесь только вид.
   ========================================================================== */

/* Стоковая таблица формы остаётся в DOM (её строки сетевых интерфейсов рисует
   createvm.js), но видимыми должны быть только они. */
body .cplv-cvm-on table { width: 100%; border: 0; }
/* Тема раскладывает строки таблицы флексом (.table-rw-stack), поэтому обычного
   display:none мало — нужен !important, иначе остаются пустые подписи полей,
   которые уже переехали в карточки. */
body .cplv-cvm-on table tr:not(.net) { display: none !important; }
body .cplv-cvm-on table tr.net > td:first-child { display: none !important; }
body .cplv-cvm-on table tr.net > td {
    display: block;
    padding: 0;
    border: 0;
}
body .cplv-cvm-on table .interface-config-flex {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin-bottom: 10px;
}
body .cplv-cvm-on table .interface-config-flex .form-group {
    flex: 1 1 220px;
    min-width: 0;
    margin: 0;
}
body .cplv-cvm-on table .interface-config-flex label {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--cplv-muted);
}
body .cplv-cvm-on table .range-input { display: flex; align-items: center; gap: 10px; }
body .cplv-cvm-on table .range-input input[type="range"] { flex: 1 1 auto; min-width: 0; }
body .cplv-cvm-on .input-with-slider .slider,
body .cplv-cvm-on .input-with-slider .slabel { display: none; }

.cplv-cvm { display: flex; flex-direction: column; gap: 14px; }
.cplv-cvm__body { display: flex; flex-direction: column; gap: 14px; }

.cplv-cvm__sec {
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
    padding: 16px;
}
.cplv-cvm__sec-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.cplv-cvm__sec-head h4 { margin: 0; font-size: 15px; font-weight: 650; color: var(--cplv-ink); }
.cplv-cvm__sec-ic {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; flex: 0 0 28px;
    border-radius: 8px;
    background: var(--cplv-surface-2);
    color: var(--cplv-muted);
}
.cplv-cvm__sec-ic svg { width: 16px; height: 16px; }
.cplv-cvm__sec-note { flex: 1 1 100%; font-size: 13px; color: var(--cplv-muted); }

/* ——— поля ——— */
.cplv-cvm__fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px 18px; }
.cplv-cvm__field { min-width: 0; }
.cplv-cvm__field > label {
    display: block; margin-bottom: 5px;
    font-size: 12px; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--cplv-muted);
}
.cplv-cvm__field .form-control,
.cplv-cvm__field select { width: 100%; max-width: min(420px, 100%); }
.cplv-cvm__field .vm-password-input { width: 100%; max-width: min(420px, 100%); }
.cplv-cvm__nopass { margin: 10px 0 0; font-size: 13px; color: var(--cplv-muted); }
.cplv-cvm__netnote {
    margin: -4px 0 14px;
    font-size: 13px; line-height: 1.5; color: var(--cplv-muted);
}

/* ——— плитки долей ——— */
.cplv-share__tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}
.cplv-share__tile {
    display: flex; flex-direction: column; gap: 4px;
    padding: 14px 12px 12px;
    text-align: left;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s;
}
.cplv-share__tile:hover { border-color: var(--cplv-line-strong); box-shadow: var(--cplv-shadow); }
.cplv-share__tile.is-on { border-color: var(--cplv-accent); box-shadow: 0 0 0 2px rgba(63, 143, 87, .16); }
.cplv-share__pct { font-size: 22px; font-weight: 680; line-height: 1.1; color: var(--cplv-ink); }
.cplv-share__of { font-size: 12px; color: var(--cplv-muted); }
.cplv-share__vals { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; font-size: 13px; }
.cplv-share__vals > span { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.cplv-share__vals i { font-style: normal; color: var(--cplv-muted); font-size: 12px; }
.cplv-share__vals b { font-weight: 650; color: var(--cplv-ink); font-variant-numeric: tabular-nums; }
.cplv-os__cur.is-empty .cplv-os__cur-nm { color: var(--cplv-muted); font-weight: 500; }
.cplv-share__mini {
    display: block; height: 4px; margin-top: 8px;
    background: var(--cplv-surface-2); border-radius: 999px; overflow: hidden;
}
.cplv-share__mini i { display: block; height: 100%; background: var(--cplv-line-strong); }
.cplv-share__tile.is-on .cplv-share__mini i { background: var(--cplv-accent); }

/* ——— полосы пула ——— */
.cplv-share__pool { margin-top: 16px; }
.cplv-share__pool-head {
    font-size: 12px; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--cplv-muted); margin-bottom: 8px;
}
.cplv-share__pb { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; font-size: 13px; }
.cplv-share__pb-lab { flex: 0 0 90px; color: var(--cplv-muted); }
.cplv-share__pb-bar {
    flex: 1 1 auto; min-width: 0; display: flex;
    height: 8px; border-radius: 999px; overflow: hidden;
    background: var(--cplv-surface-2);
}
.cplv-share__pb-bar i { display: block; height: 100%; }
.cplv-share__pb-bar .is-used { background: var(--cplv-line-strong); }
.cplv-share__pb-bar .is-new  { background: var(--cplv-accent); }
.cplv-share__pb-val { flex: 0 0 auto; min-width: 72px; text-align: right; font-variant-numeric: tabular-nums; color: var(--cplv-ink); }
.cplv-share__legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; font-size: 12px; color: var(--cplv-muted); }
.cplv-share__legend span { display: inline-flex; align-items: center; gap: 6px; }
.cplv-share__legend span::before {
    content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--cplv-surface-2);
}
.cplv-share__legend .is-used::before { background: var(--cplv-line-strong); }
.cplv-share__legend .is-new::before  { background: var(--cplv-accent); }

/* ——— ручной режим ——— */
.cplv-share__toggle,
.cplv-cvm__adv-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 14px; padding: 0;
    background: none; border: 0;
    font-size: 13px; font-weight: 600; color: var(--cplv-accent);
    cursor: pointer;
}
.cplv-cvm__adv-toggle { margin-top: 0; }
.cplv-share__toggle-ic {
    width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s;
}
.cplv-share__toggle.is-on .cplv-share__toggle-ic,
.cplv-cvm__adv-toggle.is-on .cplv-share__toggle-ic { transform: rotate(90deg); }

.cplv-share__manual { margin-top: 14px; display: flex; flex-direction: column; gap: 14px; }
.cplv-share__row {
    display: grid;
    grid-template-columns: 110px auto 1fr auto;
    align-items: center;
    gap: 10px 14px;
}
.cplv-share__row > label { font-size: 13px; color: var(--cplv-muted); }
.cplv-share__ctl { display: inline-flex; align-items: center; gap: 6px; }
.cplv-share__step {
    width: 32px; height: 32px; flex: 0 0 32px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--cplv-surface-2);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    font-size: 16px; line-height: 1; color: var(--cplv-ink);
    cursor: pointer;
}
.cplv-share__step:hover { border-color: var(--cplv-line-strong); }
body .cplv-share__num {
    width: 62px; height: 32px; padding: 0 8px;
    text-align: center; font-variant-numeric: tabular-nums;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-ink);
}
.cplv-share__unit { font-size: 13px; color: var(--cplv-muted); }
.cplv-share__range { width: 100%; min-width: 0; }
.cplv-share__free { font-size: 12px; color: var(--cplv-muted); white-space: nowrap; }

/* ——— свёрнутый выбор системы ——— */
.cplv-os__cur {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 12px 14px; text-align: left;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius-sm);
    cursor: pointer;
}
.cplv-os__cur:hover { border-color: var(--cplv-line-strong); }
.cplv-os__cur-logo { flex: 0 0 auto; }
.cplv-os__cur-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cplv-os__cur-nm { font-size: 14px; font-weight: 600; color: var(--cplv-ink); }
.cplv-os__cur-mt { font-size: 12px; color: var(--cplv-muted); }
.cplv-os__cur-act { flex: 0 0 auto; font-size: 13px; font-weight: 600; color: var(--cplv-accent); }
.cplv-os__pick--fold .cplv-os__ui { margin-top: 12px; }

/* ——— не хватает ресурсов ——— */
.cplv-cvm__none {
    display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap;
    padding: 18px;
    background: var(--cplv-danger-bg);
    border: 1px solid var(--cplv-danger-line);
    border-radius: var(--cplv-radius);
}
.cplv-cvm__none-sign {
    flex: 0 0 28px; width: 28px; height: 28px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--cplv-danger); color: #fff;
    font-weight: 700; line-height: 1;
}
.cplv-cvm__none-txt { flex: 1 1 260px; min-width: 0; }
.cplv-cvm__none-txt b { display: block; font-size: 15px; color: var(--cplv-danger-ink); }
.cplv-cvm__none-txt p { margin: 6px 0 0; font-size: 13px; color: var(--cplv-ink); }
.cplv-cvm__lack { margin: 8px 0 0; padding-left: 18px; font-size: 13px; color: var(--cplv-danger-ink); }
.cplv-cvm__none-go { flex: 0 0 auto; align-self: center; }

/* ——— подвал ——— */
.cplv-cvm__foot {
    display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
    padding: 14px 16px;
    background: var(--cplv-surface);
    border: 1px solid var(--cplv-line);
    border-radius: var(--cplv-radius);
}
.cplv-cvm__sum { font-size: 14px; color: var(--cplv-ink); }
body .cplv-cvm__slot-go .btn { min-width: 220px; }

@media (max-width: 767px) {
    .cplv-cvm__sec { padding: 14px 12px; }
    .cplv-share__tiles { grid-template-columns: 1fr 1fr; }
    .cplv-share__row {
        grid-template-columns: 1fr auto;
        grid-template-areas: "lab free" "ctl ctl" "rng rng";
    }
    .cplv-share__row > label { grid-area: lab; }
    .cplv-share__free { grid-area: free; text-align: right; }
    .cplv-share__ctl { grid-area: ctl; }
    .cplv-share__range { grid-area: rng; }
    .cplv-share__pb-lab { flex: 0 0 64px; font-size: 12px; }
    .cplv-share__pb-val { min-width: 60px; font-size: 12px; }
    .cplv-cvm__foot { flex-direction: column; align-items: stretch; }
    body .cplv-cvm__slot-go .btn { width: 100%; min-width: 0; }
    .cplv-cvm__none-go { width: 100%; }
}
.cplv-cvm__netips { margin: -8px 0 14px; font-size: 13px; color: var(--cplv-muted); }
.cplv-cvm__netips.is-warn { color: var(--cplv-danger-ink); }
.cplv-cvm__netips.is-warn a { font-weight: 600; }

/* Число с единицей не разрывается: «8 GB» на телефоне уезжало на две строки,
   а длинная подпись ресурса («Дисковое пространство») должна просто переноситься. */
.cplv-share__vals b { white-space: nowrap; }
.cplv-share__vals i { min-width: 0; }
.cplv-share__pb-val { white-space: nowrap; }

/* ---- новый вид экрана создания машины поверх старых правил формы ----
   Правила выше (`#create-vm-form` как карточка шириной 860 px и таблица-сетка)
   писались, когда форма была стоковой таблицей и САМА была карточкой. Теперь
   карточки — секции `.cplv-cvm__sec`, а форма только контейнер: своей рамки,
   подложки и ограничения ширины у неё быть не должно, иначе экран занимает
   половину рабочей области и выбивается из остальной панели. */
body #content-cloud #create-vm-form.cplv-cvm-on {
    max-width: none;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}
/* Строка сетевого интерфейса — единственная видимая строка таблицы, и она
   должна занимать всю карточку «Сеть», а не колонку старой сетки. */
body #content-cloud .cplv-cvm-on table.vm-create-attr tbody { display: block; }
body #content-cloud .cplv-cvm-on table.vm-create-attr tr.net { display: block; }

/* Поля ручного режима — в масштабе панели (у неё поля высотой 46 px), но число
   остаётся узким: правила формы тянут любой input[type=text] во всю ширину. */
body #content-cloud #create-vm-form.cplv-cvm-on input.cplv-share__num {
    width: 86px;
    height: 46px;
    padding: 0 10px;
    text-align: center;
}
.cplv-share__step { width: 46px; height: 46px; flex: 0 0 46px; font-size: 18px; }
/* Список систем не пришёл — объясняем, а не показываем пустоту. */
.cplv-os__unavail {
    margin: 0;
    padding: 14px 16px;
    background: var(--cplv-danger-bg);
    border: 1px solid var(--cplv-danger-line);
    border-radius: var(--cplv-radius-sm);
    color: var(--cplv-danger-ink);
    font-size: 14px;
}
