/* Стили кабинета — дизайн-язык витрины (шрифт TT Positive, тёмная палитра). */
/* Фирменный шрифт TT Positive (локально, WOFF2). */
@font-face { font-family: "TT Positive"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/TT_Positive_Regular.woff2") format("woff2"); }
@font-face { font-family: "TT Positive"; font-style: normal; font-weight: 500; font-display: swap; src: url("/fonts/TT_Positive_Medium.woff2") format("woff2"); }
@font-face { font-family: "TT Positive"; font-style: normal; font-weight: 600; font-display: swap; src: url("/fonts/TT_Positive_DemiBold.woff2") format("woff2"); }
@font-face { font-family: "TT Positive"; font-style: normal; font-weight: 700; font-display: swap; src: url("/fonts/TT_Positive_Bold.woff2") format("woff2"); }
@font-face { font-family: "TT Positive"; font-style: normal; font-weight: 800; font-display: swap; src: url("/fonts/TT_Positive_ExtraBold.woff2") format("woff2"); }

/* Переменные — БУКВАЛЬНО те же значения, что в client/frontend/css/styles.css (:root), чтобы
   любой переиспользуемый класс (сайдбар, badge, timeline, fp-*…) давал ИДЕНТИЧНЫЙ результат —
   а не «похожий» на других значениях переменных с теми же именами. */
:root {
  /* Шрифт экрана входа (общий блок .login-*): фирменный, как у body. */
  --login-font: "TT Positive", -apple-system, "Segoe UI", Roboto, Ubuntu, sans-serif;
  --bg: #08090b;
  --bg-2: #0d0e11;
  --sheet-bg: #1a1c23;
  --surface: #121419;
  --surface-2: #171a21;
  --surface-3: #1d222a;
  --border: #2a2f38;
  --border-2: #343b46;
  --text: #f4f5f8;
  --muted: #a4a8b8;
  --muted-2: #767c8c;
  --accent: #2f6fff;
  --accent-2: #7ea7ff;
  --green: #6cbf2c;
  --green-2: #98de56;
  --yellow: #ff9f1a;
  --orange: #ff7a1f;
  --red: #ff364f;
  --red-2: #ff002b;
  --na: #5b616e;
  --radius: 12px;
  --shadow: 0 18px 50px rgba(0,0,0,.45);
  --panel-w: 468px;
  --dd-anim: .16s;
  --dd-gap: 12px;
  --scrollbar-size: 6px;
  --scrollbar-thumb: rgba(120,150,190,.25);
  --scrollbar-thumb-hover: rgba(120,150,190,.5);
  /* 4-ступенчатая шкала «реализуемости» (уровень злоумышленника): опаснее/меньше → краснее,
     безопаснее/больше → синее. Та же палитра, что на витрине (`.ue-level`). */
  --lvl-basic: #ff5a6e;
  --lvl-medium: #ff7a1f;
  --lvl-advanced: #7db0ff;
  --lvl-expert: #4f8eff;
  /* Единая палитра важности уязвимостей (`.sev-cell`/`.sev-dot`) — те же значения, что на
     витрине (обновлены вместе с редизайном таблиц уязвимостей/Киберразведки 2026-07-09). */
  --sev-critical: #ff1420;
  --sev-high: #ff3838;
  --sev-medium: #ff9f2e;
  --sev-low: #79b0ff;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg); color: var(--text);
  font-family: "TT Positive", -apple-system, "Segoe UI", Roboto, Ubuntu, sans-serif;
  font-size: 14px; line-height: 1.45; -webkit-font-smoothing: antialiased;
}
#app { height: 100%; }

/* Единый тонкий тёмный скролл во всём приложении — БУКВАЛЬНО как на витрине (см. её styles.css
   за подробным обоснованием): WebKit по умолчанию рисует грубый светлый скроллбар. */
html { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
*::-webkit-scrollbar { width: var(--scrollbar-size); height: var(--scrollbar-size); }
*::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb); border-radius: var(--scrollbar-size);
  border: 2px solid transparent; background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }
*::-webkit-scrollbar-track { background: transparent; }

/* --- Вход: ЕДИНЫЙ вид во всех трёх сервисах ---
   Блок правил .login-* повторён ДОСЛОВНО в трёх файлах: client/frontend/css/styles.css,
   cabinet/frontend/css/styles.css и server/frontend/css/styles.css. Общего CSS у фронтендов
   нет (у каждого свой origin), поэтому правка здесь = правка во всех трёх. Палитра — свои
   переменные блока (ниже, с префиксом --login-*): имена остальных переменных :root у server
   другие. Объявлены на :root, а не на .login-wrap — `.login-error` используется и вне экрана
   входа (окно смены пароля кабинета). */
:root {
  --login-card-bg: #121419;              /* фон карточки */
  --login-card-border: #2a2f38;          /* рамка карточки */
  --login-input-bg: #171a21;             /* фон поля */
  --login-input-border: #343b46;         /* рамка поля */
  --login-accent: #2f6fff;               /* кнопка, рамка поля в фокусе */
  --login-accent-hover: #3f7bff;         /* кнопка под курсором */
  --login-on-accent: #ffffff;            /* текст на кнопке */
  --login-invalid: #ff364f;              /* рамка поля с ошибкой (.field-invalid) */
  --login-error: #ff97a6;                /* текст ошибки */
  --login-notice: #6cbf2c;               /* текст успеха */
  --login-shadow: 0 18px 50px rgba(0,0,0,.45);
  /* Шрифт экрана входа — НЕ здесь: --login-font задаёт каждый styles.css рядом со своим
     @font-face (у инсталляций разные фирменные шрифты). */
}
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: var(--bg);
  font-family: var(--login-font);
  line-height: 1.45;
}
.login-form {
  width: 360px; max-width: 100%; background: var(--login-card-bg);
  border: 1px solid var(--login-card-border); border-radius: 16px; padding: 34px 30px;
  display: flex; flex-direction: column; gap: 12px; box-shadow: var(--login-shadow);
}
.login-logo-img { display: block; margin: 0 auto 4px; border-radius: 11px; }
.login-title { margin: 0; text-align: center; font-size: 28px; font-weight: 800; line-height: 1.2; color: var(--text); }
.login-sub { margin: 0 0 8px; text-align: center; color: var(--muted); font-size: 14px; }
.login-form input {
  width: 100%; margin: 0; background: var(--login-input-bg);
  border: 1px solid var(--login-input-border); border-radius: 10px; padding: 11px 13px;
  font: inherit; font-size: 14px; color: var(--text); outline: none;
}
.login-form input::placeholder { color: var(--muted); }
.login-form input:focus { border-color: var(--login-accent); }
/* Поле, отклонённое сервером (applyFieldErrors) — селектор сильнее базового правила поля. */
.login-form input.field-invalid { border-color: var(--login-invalid); }
.login-submit {
  width: 100%; margin-top: 8px; padding: 12px; border: none; border-radius: 10px;
  background: var(--login-accent); color: var(--login-on-accent); font: inherit;
  font-size: 15px; font-weight: 600; cursor: pointer;
}
.login-submit:hover { background: var(--login-accent-hover); }
.login-submit:disabled { opacity: .6; cursor: default; }
/* Ошибка и успех («пароль установлен — войдите»): видимость задаёт ТОЛЬКО текст —
   пустой блок места не занимает. */
.login-error { color: var(--login-error); font-size: 13px; }
.login-notice { color: var(--login-notice); font-size: 13px; }
.login-error:empty, .login-notice:empty { display: none; }
/* --- конец общего блока входа --- */
/* Переключатель языка в углу экрана входа (у «/review» языка нет — там этого правила нет). */
.login-lang { position: fixed; top: 20px; right: 20px; }

/* Комментарий модератора к заявке (под текстом заявки в таблице «Заявки»). */
.sub-review { color: var(--muted); font-size: 13px; margin-top: 4px; padding-left: 8px;
  border-left: 2px solid var(--border); white-space: pre-wrap; word-break: break-word; }

/* --- Поля и кнопки --- */
.field {
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 10px; padding: 10px 12px; font-size: 14px; outline: none; font-family: inherit;
}
.field:focus { border-color: var(--accent); }
.field-sm { padding: 8px 11px; border-radius: 9px; }
/* Поля смены пароля — строго построчно (колонка), на всю ширину модалки (иначе .field
   инлайновые и встают в ряд). */
.pw-form { display: flex; flex-direction: column; gap: 10px; }
.pw-form .field { width: 100%; }
/* Нативный <select> под тёмную палитру: убираем OS-хром и рисуем свою «шеврон»-каретку
   (data-URI SVG — фон, без скрипта, CSP не нарушается); список опций тоже тёмный (Chromium
   уважает цвета на <option>). Иначе селект выбивался из дизайн-языка (светлый OS-дропдаун). */
select.field {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  cursor: pointer; padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%23a4a8b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 12px 8px;
}
select.field:hover { border-color: var(--border-2); }
select.field:focus {
  /* Каретка перекрашивается в акцент на фокусе (тот же цвет, что рамка). */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%237ea7ff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
select.field option { background: var(--surface-2); color: var(--text); }
/* Подсветка поля с ошибкой валидации (сервер вернул 422 по конкретному полю формы). */
.field-invalid { border-color: #ff364f; }
.field-error-msg { color: #ff97a6; font-size: 12px; margin: 2px 0 6px; }
.btn {
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  border-radius: 10px; padding: 9px 15px; cursor: pointer; font-size: 14px; font-family: inherit;
  transition: background .14s, border-color .14s, color .14s;
  outline: none; /* браузер иначе рисует свой дефолтный focus-ring (виден после клика — кнопка
    получает фокус) — тёмный контур поверх скруглённой кнопки. Заменён на border-color ниже,
    как у .field/.cp-info-ico: видимо только для клавиатурной навигации (:focus-visible). */
}
.btn:hover, .btn:focus-visible { border-color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: #4880ff; }
.btn-primary:disabled { opacity: .55; cursor: default; }
/* «Недоступна, но с подсказкой почему» (напр. «+ Новое испытание» при уже активном периоде) —
   НЕ нативный `[disabled]`: в Chrome/WebKit отключённый элемент не получает события наведения
   вовсе, поэтому ни курсор, ни кастомная подсказка (attachReqTip) не сработали бы. Это просто
   вид + курсор «?» (принятое обозначение «наведи — узнаешь, почему нельзя»); клика не бывает,
   т.к. обработчик клика для этого состояния просто не вешается (см. вызывающий код). Отменяем
   акцентную подсветку hover обычной кнопки — иначе выглядело бы интерактивно. */
.btn-disabled-tip, .btn-disabled-tip:hover { opacity: .55; cursor: help; border-color: var(--border); }
.btn-primary.btn-disabled-tip, .btn-primary.btn-disabled-tip:hover { background: var(--accent); }
.btn-ghost { background: transparent; }
.btn-sm { padding: 6px 11px; font-size: 13px; }
.btn-xs { padding: 3px 8px; font-size: 12px; }
/* Текстовая «опасная» кнопка (напр. «Удалить недопустимое событие») — обычная ghost-кнопка,
   только текст/рамка красные при наведении, без отдельной заливки: сама кнопка не должна
   выглядеть тревожно ПОСТОЯННО (список событий не должен пестреть красным) — только на явном
   намерении навести курсор. Подтверждение необратимого действия — window.confirm(), см. вызывающий код. */
.btn-danger-text { color: var(--muted); }
.btn-danger-text:hover { color: var(--red); border-color: var(--red); }

/* --- Раскладка: рейка-меню — БУКВАЛЬНО те же классы/значения, что .sidebar на витрине
   (client/frontend/css/styles.css), включая «жидкое стекло» (backdrop-filter). Кабинет-
   специфичные добавления — `.rail-company` (имя компании аккаунта второй строкой бренда; на витрине его нет —
   там нет единой «своей» компании) и `.nav-badge` (счётчик активных элементов) — встроены в
   ту же геометрию (46px-плитки), не расходясь с остальной рейкой. */
html, body { overflow-x: hidden; } /* ничего не должно вызывать горизонтальный скролл страницы */
.app-shell { display: block; height: 100%; --rail-w: 78px; }
.main {
  display: flex; flex-direction: column; height: 100%; min-width: 0;
  margin-left: var(--rail-w);
}
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: var(--rail-w); z-index: 1200;
  background: rgba(13,17,26,.34);
  -webkit-backdrop-filter: blur(13px) saturate(1.3);
  backdrop-filter: blur(13px) saturate(1.3);
  border-right: 1px solid rgba(255,255,255,.08); display: flex; flex-direction: column;
  padding: 18px 8px; overflow: hidden; white-space: nowrap;
  transition: width .24s cubic-bezier(.4,0,.2,1), box-shadow .24s;
}
.app-shell.nav-open .sidebar { width: 272px; box-shadow: 14px 0 40px rgba(0,0,0,.5); }
.nav-backdrop {
  position: fixed; inset: 0; background: rgba(4,7,13,.55); z-index: 1100;
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s;
  backdrop-filter: blur(2px);
}
.app-shell.nav-open .nav-backdrop { opacity: 1; visibility: visible; }

.sidebar-brand {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 11px; padding: 4px 8px 12px; font-weight: 800; font-size: 20px;
}
.rail-logo { display: block; border-radius: 12px; flex: 0 0 auto; }
/* Бренд в ДВЕ строки, как в «/review» («Cibo» / «Management»): «Кабинет» + имя компании
   аккаунта. Отдельной строкой ПОД брендом имя занимало высоту и в свёрнутой рейке — отступ
   от логотипа до первой иконки выходил больше шага между иконками. */
.brand-text { display: flex; flex-direction: column; line-height: 1.05; min-width: 0;
  max-width: 0; opacity: 0; overflow: hidden; transition: max-width .24s, opacity .16s; }
.app-shell.nav-open .brand-text { max-width: 180px; opacity: 1; }
/* Своя высота строки: унаследованная от бренда 1.05 при overflow:hidden срезала низ
   у «у/р/д/щ». */
.rail-company { color: var(--muted); font-size: 12.5px; font-weight: 500; line-height: 1.35;
  margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sidebar-nav { display: flex; flex-direction: column; gap: 8px; }
.nav-item {
  display: flex; align-items: center; justify-content: flex-start; gap: 14px;
  padding: 6px 8px; border-radius: 14px; color: var(--muted); text-decoration: none;
  font-size: 15px; font-weight: 600; transition: background .15s, color .15s; position: relative;
}
/* Наведение на пункты рейки убрано намеренно (без hover-подсветки/сдвига). */
.app-shell.nav-open .nav-item.active { color: #fff; background: rgba(47,111,255,.10); }
.nav-item.active { color: #fff; }

.nav-ico {
  flex: 0 0 auto; width: 46px; height: 46px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 13px;
  background: var(--surface-2); border: 1px solid var(--border-2);
  color: var(--muted); transition: background .15s, border-color .15s,
    color .15s, box-shadow .15s, transform .15s; position: relative;
}
.nav-ico svg { width: 24px; height: 24px; }
.nav-item.active .nav-ico {
  color: #fff; border-color: transparent;
  background: linear-gradient(135deg, var(--accent), #6c4bff);
  box-shadow: 0 5px 16px rgba(47,111,255,.45);
}

.nav-label { max-width: 0; opacity: 0; overflow: hidden; transition: max-width .24s, opacity .16s; }
.app-shell.nav-open .nav-label { max-width: 180px; opacity: 1; flex: 1 1 auto; }
/* Бейдж числа активных элементов (уязвимости/утечки/КИ) — кабинет-специфичное добавление (на
   витрине его нет): на иконке в свёрнутом виде, у правого края строки в раскрытом. */
.nav-badge { display: none; }
.nav-badge.show {
  display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
  padding: 0 4px; border-radius: 9px; background: var(--red); color: #fff; font-size: 11px; font-weight: 700;
  position: absolute; top: -4px; right: -4px; box-shadow: 0 0 0 2px rgba(13,17,26,.9);
}
.app-shell.nav-open .nav-badge.show {
  position: static; box-shadow: none; margin-left: auto;
}

.nav-toggle {
  display: flex; align-items: center; justify-content: flex-start; gap: 14px;
  margin-top: auto; margin-bottom: 8px; padding: 6px 8px; border: none;
  background: transparent; cursor: pointer; color: var(--muted);
  font: inherit; font-size: 15px; font-weight: 600; text-align: left;
  opacity: 0; transition: opacity .2s, color .15s;
}
.sidebar:hover .nav-toggle, .nav-toggle:focus-visible { opacity: 1; outline: none; }
.nav-toggle:hover { color: var(--text); }
.nav-toggle-ico {
  flex: 0 0 auto; width: 46px; height: 46px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 13px;
  background: var(--surface-2); border: 1px solid var(--border-2);
  transition: border-color .15s, color .15s, background .15s;
}
/* Наведение на плитку иконки «Свернуть» убрано намеренно (без hover-подсветки иконок рейки). */
.nav-toggle-ico svg { width: 20px; height: 20px;
  transition: transform .26s cubic-bezier(.4,0,.2,1); }
.app-shell.nav-open .nav-toggle-ico svg { transform: rotate(180deg); }

.sidebar-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border); }

/* --- Кнопка аккаунта внизу рейки (аватар-инициал + email/роль, открывает accountMenu) — тот же
   геометрический язык, что у .nav-item (46px-плитка слева, лейбл раскрывается вместе с рейкой),
   но плитка КРУГЛАЯ (аватар, не иконка-раздел) и с градиентом «активного» акцента — отличает
   аккаунт от обычных пунктов навигации, современнее прежней плоской «плашки с почтой в рамке». */
.acct-btn {
  display: flex; align-items: center; justify-content: flex-start; gap: 14px; width: 100%;
  padding: 6px 8px; border: none; border-radius: 14px; background: transparent; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 600; text-align: left; color: var(--muted);
  transition: background .15s, color .15s;
}
.acct-btn:hover, .acct-btn[aria-expanded="true"] { background: rgba(255,255,255,.06); color: var(--text); }
.acct-avatar {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent), #6c4bff); color: #fff;
  font-size: 17px; font-weight: 800; letter-spacing: .02em;
}
.acct-info { min-width: 0; max-width: 0; opacity: 0; overflow: hidden;
  display: flex; flex-direction: column; gap: 1px; transition: max-width .24s, opacity .16s; }
.app-shell.nav-open .acct-info { max-width: 168px; opacity: 1; flex: 1 1 auto; }
.acct-email { font-size: 13px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-role { font-size: 11.5px; color: var(--muted); }
.acct-caret { flex: 0 0 auto; max-width: 0; opacity: 0; overflow: hidden;
  color: var(--muted-2); font-size: 12px; transition: max-width .24s, opacity .16s; }
.app-shell.nav-open .acct-caret { max-width: 14px; opacity: 1; }

/* Меню аккаунта — портал в body (рейка сама `overflow:hidden`, локальная панель обрезалась бы
   её краем), раскрывается ВВЕРХ от кнопки (та внизу экрана). Анимация — те же dd-in/dd-out
   keyframes, что у .ms-panel (см. ниже), другая точка отсчёта transform-origin (снизу, не сверху). */
.acct-menu {
  position: fixed; z-index: 1300; min-width: 220px; max-width: 280px;
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 14px;
  box-shadow: 0 18px 40px rgba(0,0,0,.5); padding: 8px; transform-origin: bottom left;
}
.acct-menu-head { padding: 8px 10px 10px; margin-bottom: 6px; border-bottom: 1px solid var(--border); }
.acct-menu-email { font-size: 13.5px; font-weight: 700; color: var(--text); word-break: break-all; }
.acct-menu-role { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* Переключатель языка (js/app.js languageSwitch): сегментированная группа кнопок с кодом
   языка. Один элемент в двух местах — в меню аккаунта (.acct-lang) и в углу экрана входа
   (.login-lang-switch). Тот же вид, что на витрине. */
.lang-switch { display: inline-flex; gap: 2px; padding: 2px; border-radius: 9px;
  background: var(--surface-2); border: 1px solid var(--border); }
.lang-btn {
  border: none; background: transparent; border-radius: 7px; cursor: pointer;
  color: var(--muted); font: inherit; font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em; padding: 4px 9px; transition: background .12s, color .12s;
}
.lang-btn:hover { color: var(--text); }
.lang-btn.is-active { background: var(--surface); color: var(--text); }
.acct-menu-lang { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 6px 10px 8px; margin-bottom: 6px; border-bottom: 1px solid var(--border); }
.acct-menu-lang-cap { font-size: 12.5px; color: var(--muted); }
.acct-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px;
  border: none; border-radius: 10px; background: transparent; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 600; color: var(--text); text-align: left;
}
.acct-menu-item:hover, .acct-menu-item:focus-visible { background: var(--surface-2); outline: none; }
.acct-menu-item--danger:hover { color: #ff6b6b; }
.acct-menu-ico { flex: 0 0 auto; width: 18px; height: 18px; display: inline-flex; color: var(--muted); }
.acct-menu-ico svg { width: 18px; height: 18px; }

.view-root { flex: 1; padding: 22px 24px; overflow-y: auto; overflow-x: hidden; min-height: 0;
  min-width: 0; display: flex; flex-direction: column; }

/* --- Заголовки --- */
.sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 22px; }
.sec-title { margin: 0; font-size: 25px; font-weight: 800; }
.sec-sub { color: var(--muted); font-size: 14px; margin-top: 2px; }
.sec-sub-full { margin-top: 4px; font-size: 13px; line-height: 1.35; }
.hint { color: var(--muted); font-size: 13px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; margin-bottom: 16px; }

/* --- Блоки/панели — ЛАКОНИЧНО, без фона/рамки-«карточки» (как секции .fp-sec/.cp-sec
   правой панели на витрине): разделитель — тонкая верхняя линия, а не заливка суsurface.
   Внутренние мини-плитки (.metric/.ct-col/.rel-card/.kzi-grp…) свою заливку surface-2
   сохраняют — это тот же приём, что у .panel-stats .stat на витрине (внешняя секция плоская,
   внутренние чипы — с лёгкой глубиной). Используется на страницах, где секции идут ВНУТРИ уже
   оформленной карточки (Заявки) или узкой боковой панели — там рамка на каждой секции была бы
   лишней. */
.panel-block { padding: 16px 0; margin-bottom: 0; border-top: 1px solid var(--border); }
.panel-block:first-child { border-top: none; padding-top: 0; }
.block-title { font-size: 15px; margin: 0 0 12px; font-weight: 600; }

/* --- Дашборд: каждый ВЕРХНЕУРОВНЕВЫЙ раздел — самостоятельная карточка со скруглённой рамкой
   со всех сторон, а не просто верхняя линия-разделитель (та обрывалась «голым» левым/правым
   краем на широком дашборде без обрамления — выглядело как грубо обрезанные границы). Скопом
   через `.dash > .panel-block` — не трогает `.panel-block` на других страницах (Заявки), где
   секции лежат уже внутри своей рамки. Кибериспытания и Профиль компании — свой отдельный
   `.ct-page`/`.ct-block` (см. ниже), .dash там не используется. */
.dash { display: flex; flex-direction: column; gap: 14px; }
.dash > .panel-block {
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
  padding: 16px 18px; margin: 0;
}
.dash > .panel-block:first-child { border-top: 1px solid var(--border); padding-top: 16px; }
/* `.collapse` САМА без отступов (padding:0) — иначе `:hover` на .collapse-head подсвечивал бы
   только вписанную в инсет часть, оставляя тёмную кайму по бокам до скруглённых краёв карточки
   (некрасиво). Инсет вместо этого — у head/body напрямую (см. ниже), так что подсветка при
   наведении заливает ВСЮ ширину карточки, от края до края, вплоть до её скруглённых углов. */
.dash > .panel-block.collapse, .dash > .panel-block.collapse:first-child { padding: 0; }
.dash > .panel-block.collapse > .collapse-head { padding: 16px 18px; border-radius: var(--radius) var(--radius) 0 0; }
.dash > .panel-block.collapse > .collapse-body > .collapse-inner { padding: 6px 18px 18px; }
/* Кнопка «+ Заявка на изменение» первым элементом в теле блока дашборда (Кзи/события/активы/
   подрядчики) — отступ снизу отделяет её от списка блока. */
.dash-block-action { margin-bottom: 12px; }

/* --- Дашборд: hero объединён со статистикой в ОДИН всегда раскрытый ряд — Киберустойчивость
   → 3 карточки статистики. Счётчики активных уязвимостей/находок сюда не дублируются — они уже
   видны бейджем в рейке разделов. --- */
.hero { display: flex; gap: 22px; align-items: stretch; }
/* Карточки статистики (donut/гистограмма) делят оставшееся место поровну. */
.hero > .stat-card { flex: 1 1 0; min-width: 0; }

/* Информационная иконка рядом с числом киберустойчивости — по наведению показывает формулу
   рейтинга и использованные значения (Кзи, Кнс, N, результат), ТОЧНО как на витрине. */
.cp-info { position: relative; display: inline-flex; align-items: center; flex-shrink: 0; }
.cp-info-ico { width: 18px; height: 18px; border-radius: 50%; cursor: help;
  border: 1px solid var(--border-2); color: var(--muted); background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; font-style: italic; font-family: Georgia, "Times", serif;
  transition: color .14s, border-color .14s; }
.cp-info-ico:hover, .cp-info-ico:focus-visible { color: var(--text); border-color: var(--accent); outline: none; }
/* left:0 (не right:0) — Киберустойчивость теперь ПЕРВЫЙ (левый) элемент hero-ряда, попап должен
   раскрываться ВПРАВО, иначе вылезает за левый край (под рейку) и обрезается. */
.cp-info-pop { position: absolute; top: calc(100% + 8px); left: 0; z-index: 6; width: 258px;
  padding: 11px 13px; border-radius: 10px; background: rgba(16,20,30,.97);
  border: 1px solid var(--border-2); box-shadow: 0 14px 34px rgba(0,0,0,.55);
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity var(--dd-anim) ease, transform var(--dd-anim) ease, visibility 0s linear var(--dd-anim); }
.cp-info:hover .cp-info-pop, .cp-info-ico:focus-visible + .cp-info-pop {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.cp-info-title { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 7px; letter-spacing: .01em; }
.cp-info-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 11.5px; color: var(--muted); padding: 3px 0; }
.cp-info-row + .cp-info-row { border-top: 1px solid rgba(255,255,255,.05); }
.cp-info-row b { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* --- Дашборд: статистика (диаграммы), см. app.js statCards/donutChart/monthHistogram —
   карточки теперь ЧАСТЬ hero-ряда (.hero > .stat-card, см. выше), не отдельная сетка. Мягкий
   диагональный градиент фона + чуть большее скругление (var(--radius), как у внешних карточек
   дашборда) вместо плоской заливки — менее «плоский», более современный вид. */
.stat-card {
  background: linear-gradient(165deg, var(--surface-2), var(--surface));
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; transition: border-color .16s;
}
.stat-card:hover { border-color: var(--border-2); }
.stat-title { font-size: 12.5px; color: var(--muted); font-weight: 600; text-align: center; }
/* Кольцевая (donut) диаграмма — СОВРЕМЕННЫЙ вид: заливка `.donut-ring` — conic-gradient
   (задаётся из JS инлайн-стилем, см. donutChart), цвета сегментов ПЕРЕТЕКАЮТ друг в друга без
   резкой границы (одноточечные цвета-стопы). Кольцо вырезано CSS `mask` — надёжнее, чем красить
   «дыру» под цвет фона карточки (не завязано на совпадение цветов). Курсор — «?»: по
   наведению/фокусу всплывает легенда цветов (attachDonutTip), как и .cp-info/.kzi-req.has-tip.
   Лёгкая тень под кольцом (drop-shadow, следует форме — не box-shadow прямоугольника) добавляет
   глубины; на hover/focus кольцо чуть светлеет — обратная связь, что оно интерактивно. */
.donut-wrap {
  position: relative; display: inline-flex; cursor: help; border-radius: 50%;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, .38));
}
.donut-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.donut-wrap:hover .donut-ring, .donut-wrap:focus-visible .donut-ring { filter: brightness(1.12); }
/* Радиус дыры = DONUT_SIZE/2 − DONUT_THICKNESS = 116/2 − 15 = 43px (app.js) — синхронно вручную.
   Стопы НЕ в одной точке (42px/44px, не 43px/43px) — узкая зона растушёвки нужна, чтобы GPU
   сглаживал маску: единственная точка перехода давала видимые тёмные/ступенчатые пиксели по
   внутреннему краю кольца (жёсткий срез без антиалиасинга) — это и было артефактом. */
.donut-ring {
  position: relative; width: 116px; height: 116px; border-radius: 50%;
  -webkit-mask: radial-gradient(circle, transparent 42px, #000 44px);
  mask: radial-gradient(circle, transparent 42px, #000 44px);
  transition: filter .16s;
}
.donut-center {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; gap: 1px;
}
.donut-center-num { font-size: 20px; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.donut-center-lbl { font-size: 10.5px; color: var(--muted); }
/* Легенда донат-диаграммы (всплывает в .req-tip-pop, см. общий стиль подсказки) — по цветной
   точке + подписи + числу на сегмент. */
.legend-tip-title { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 7px; letter-spacing: .01em; }
.legend-tip-row { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--muted); padding: 3px 0; }
.legend-tip-row + .legend-tip-row { border-top: 1px solid rgba(255,255,255,.05); }
.legend-tip-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.legend-tip-lbl { flex: 1 1 auto; }
.legend-tip-val { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* Гистограмма обнаружений по месяцам — столбец из 2 сегментов (уязвимости/находки), высота —
   px из JS (HIST_BAR_MAX_H=84 в app.js), не проценты. Высота контейнера здесь = HIST_BAR_MAX_H +
   запас под подпись месяца (gap 6 + ~13px текста) — синхронно с app.js константой вручную. */
.hist-chart { display: flex; align-items: flex-end; gap: 10px; height: 116px; width: 100%; }
/* cursor:help — по наведению/фокусу всплывает стильная легенда (attachLegendTip), как и у
   донат-диаграмм, вместо нативного title. Подсказка вешается на ВЕСЬ столбец (см. app.js), а
   не только на .hist-bar — у месяца без записей bar пустой (нулевая высота). */
.hist-col {
  display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1 1 auto;
  cursor: help; border-radius: 6px;
}
.hist-col:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* column (не reverse): в DOM-порядке находки идут ПЕРВЫМ дочерним элементом (см. app.js
   monthHistogram) — при обычном column-направлении это кладёт находки СВЕРХУ, а уязвимости
   вторым элементом — снизу, у самой базовой линии столбца. */
.hist-bar {
  width: 100%; max-width: 26px; display: flex; flex-direction: column;
  border-radius: 3px 3px 0 0; overflow: hidden; background: var(--surface-3);
}
.hist-seg { width: 100%; }
.hist-seg--vuln { background: var(--accent); }
.hist-seg--intel { background: var(--orange); }
.hist-lbl { font-size: 10.5px; color: var(--muted); }

/* --- Кзи-полоса вклада групп --- */
.kzi-metric-bar { display: flex; height: 12px; border-radius: 7px; overflow: hidden; background: var(--surface-2); margin-bottom: 14px; border: 1px solid var(--border); }
.kzi-seg { height: 100%; }

/* --- Разбивки --- */
.breakdown { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-bottom: 8px; }
.bd-item { display: flex; align-items: center; gap: 8px; }
.bd-label { color: var(--muted); }
.bd-count { font-weight: 700; }
.chip { display: inline-flex; align-items: center; gap: 6px; }
.chip-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: 0 0 auto; }

/* --- Связанные компании --- */
.rel-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.rel-card { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; position: relative; overflow: hidden; }
.rel-name { font-weight: 600; overflow-wrap: anywhere; word-break: break-word; }
.rel-sub { color: var(--muted); font-size: 12px; margin-top: 2px; overflow-wrap: anywhere; word-break: break-word; }

/* --- События --- */
.event-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.event-list li { display: flex; align-items: center; gap: 9px; }
.dot-alert { width: 9px; height: 9px; border-radius: 50%; background: var(--red); display: inline-block; box-shadow: 0 0 0 3px rgba(255,54,79,.18); }
.dot-ok { width: 9px; height: 9px; border-radius: 50%; background: var(--na); display: inline-block; }

/* --- Таблицы (стиль витрины: БЕЗ рамки-«карточки» — лаконично встроены в фон страницы) ---
   Витрина не держит нигде «коробочную» таблицу — все её собственные списки (Компании/
   Уязвимости/Киберразведка) идут в full-bleed «листовом» режиме без border/shadow вокруг
   table-box, поэтому здесь тот же приём — единственный (не под условным .view-root--sheet). */
.table-host { min-height: 40px; overflow: auto; max-width: 100%; }
.grid { width: 100%; border-collapse: collapse; font-size: 14px; }
.grid th {
  text-align: left; padding: 11px 18px; color: var(--muted); font-weight: 700;
  border-bottom: 1px solid var(--border-2); position: sticky; top: 0;
  background: var(--surface-2); white-space: nowrap; text-transform: uppercase;
  font-size: 11px; letter-spacing: .05em;
}
.grid td {
  text-align: left; padding: 11px 18px; border-bottom: 1px solid var(--border);
  max-width: 320px; overflow-wrap: anywhere; word-break: break-word;
}
.grid tbody tr:last-child td { border-bottom: none; }
/* Заглушка пустой таблицы (ctEmptyRow): строка на всю ширину под видимой шапкой столбцов —
   вертикально центрированная иконка «пусто» + пояснение, вместо голого обрезанного тела. */
.grid-empty-row:hover { background: transparent; }
.grid-empty-cell { padding: 0 !important; border-bottom: none !important; max-width: none; }
.grid-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 34px 18px; color: var(--muted); font-size: 13.5px; text-align: center;
}
.grid-empty-ico { width: 30px; height: 30px; color: var(--muted-2); opacity: .7; }
/* Растягиваемые столбцы (util.resizableColumns) — ТОЧНО как на витрине: ручка у правой
   границы шапки столбца, th уже sticky/positioned → ручка позиционируется относительно него. */
.grid th.col-resizable { padding-right: 20px; } /* место под ручку, чтобы не легла на текст */
.col-resizer { position: absolute; top: 0; right: 0; width: 9px; height: 100%;
  cursor: col-resize; user-select: none; touch-action: none; z-index: 3; }
.col-resizer::before { content: ""; position: absolute; top: 22%; bottom: 22%; right: 3px;
  width: 2px; border-radius: 2px; background: rgba(255,255,255,.14); transition: background .12s; }
.col-resizer:hover::before, .col-resizer.is-dragging::before { background: var(--accent); }
.grid--resizable th, .grid--resizable td { overflow: hidden; text-overflow: ellipsis; }
.row-click { cursor: pointer; transition: background .12s; }
.row-click:hover { background: var(--surface-2); box-shadow: inset 3px 0 0 var(--accent); }
.muted { color: var(--muted); padding: 10px 2px; }

/* Список с фильтрами (Уязвимости/Утечки) — «лист» в край, шапка (заголовок+фильтры) единым
   куском над таблицей — БУКВАЛЬНО те же классы/значения, что sheet-list-head/sheet-filters на
   витрине (макет company1.png: крупный полужирный светло-серый заголовок #c5c7d3, приглушённый
   серо-голубой счётчик #8b93ad, фильтры-«таблетки»). */
.view-root--sheet { padding: 0; overflow: hidden; }
/* Единый фон всей секции (голова + таблица), как на витрине — иначе у шапки с фильтрами и
   у таблицы под ней получаются РАЗНЫЕ оттенки (была видна граница между ними). */
.sheet-section { flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column;
  background: var(--sheet-bg); transition: padding-right .28s cubic-bezier(.32,.72,0,1); }
/* Открытая карточка уязвимости/находки СЖИМАЕТ лист (а не перекрывает его) — таблица
   переформатируется левее панели, столбцы не уходят под неё. ТОЧНО как #app-screen.has-panel
   на витрине. */
.app-shell.has-panel .sheet-section { padding-right: var(--panel-w); }
@media (prefers-reduced-motion: reduce) { .sheet-section { transition: none; } }
.sheet-list-head { flex-shrink: 0; padding: 16px 20px; background: var(--sheet-bg); }
.sheet-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 15px; }
.sheet-heading { margin: 0; font-size: 27px; font-weight: 700; color: #c5c7d3; letter-spacing: .01em; }
.sheet-heading .sheet-count { margin-left: 10px; color: #8b93ad; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Заголовок вкладки Кибериспытания (`.ct-title`, вне `.sheet-list-head`) — тот же `.sheet-heading`,
   но со своим отступом снизу (как у `.sec-head` на остальных страницах — тот же ритм). Заголовки
   РАЗДЕЛОВ-карточек (`.ct-block`, `sheet-heading--card`) — намеренно МЕНЬШЕ и другого цвета
   (обычный `--text`, не приглушённый сине-серый #c5c7d3), чтобы не выглядеть как заголовок
   вкладки — визуальная иерархия «вкладка → раздел» должна читаться с первого взгляда. */
.ct-title { margin: 0 0 22px; }
.sheet-heading--card { font-size: 17px; color: var(--text); }
.sheet-filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* Кнопка «Сбросить фильтры» — приглушённая текстовая «таблетка», акцент на наведении. */
.filter-reset { font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  background: transparent; border: 1px solid var(--border-2); border-radius: 10px;
  padding: 9px 14px; color: var(--muted); transition: color .15s, border-color .15s; white-space: nowrap; }
.filter-reset:hover { color: var(--accent-2); border-color: var(--accent); }

/* --- Мультиселект (множественный фильтр с поиском) — ТОТ ЖЕ компонент/классы, что на
   витрине (js/multiselect.js скопирован как есть, IM.multiselect). Важность/статус на
   вкладках «Уязвимости»/«Утечки» — динамические фасеты (см. renderVulners/renderIntel). --- */
.ms { position: relative; display: inline-block; }
.ms-button {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  min-width: 160px; max-width: 240px; font: inherit; font-size: 14px; font-weight: 500;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px;
  padding: 11px 14px; color: var(--text); transition: border-color .15s, box-shadow .15s;
}
.ms.open .ms-button, .ms-button.has-sel { border-color: var(--accent); }
.ms.open .ms-button { box-shadow: 0 0 0 3px rgba(47,111,255,.18); }
.ms-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.ms-button.has-sel .ms-label { color: var(--accent-2); font-weight: 600; }
.ms-caret { color: var(--muted-2); font-size: 12px; }
.ms-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  min-width: 240px; max-width: 320px;
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0,0,0,.45); padding: 8px; overflow: hidden;
}
.ms-panel--right { left: auto; right: 0; }
.ms-search-wrap { margin-bottom: 6px; }
.ms-search {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 14px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px;
  padding: 9px 11px; color: var(--text);
}
.ms-search:focus { outline: none; border-color: var(--accent); }
.ms-list { max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.ms-opt { display: flex; align-items: center; gap: 9px; cursor: pointer; padding: 8px 9px; border-radius: 8px; font-size: 14px; color: var(--text); }
.ms-opt:hover, .ms-opt:focus { background: var(--surface-2); outline: none; }
.ms-opt.sel { background: rgba(47,111,255,.12); }
.ms-opt-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-check {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 5px; border: 1px solid var(--border-2);
  display: flex; align-items: center; justify-content: center; font-size: 12px; color: #fff;
}
.ms-check.on { background: var(--accent); border-color: var(--accent); }
.ms-empty { padding: 10px; color: var(--muted); font-size: 13px; text-align: center; }
/* Внутри «листа» — плоская приглушённая «таблетка» (как на витрине), а не заметная плашка.
   Тот же вид — и внутри карточек `.ct-block` (Кибериспытания, см. ниже), не только на
   полностраничных `.view-root--sheet` (Уязвимости/Утечки). */
.view-root--sheet .sheet-filters .ms-button, .ct-block .sheet-filters .ms-button {
  min-width: 0; max-width: none; padding: 9px 16px; border-radius: 10px;
  background: rgba(255,255,255,.03); border: 1px solid var(--border-2); color: var(--muted);
  font-weight: 500; box-shadow: none;
}
.view-root--sheet .sheet-filters .ms-button:hover, .ct-block .sheet-filters .ms-button:hover {
  color: var(--text); border-color: var(--muted-2); background: rgba(255,255,255,.06);
}
.view-root--sheet .sheet-filters .ms.open .ms-button,
.view-root--sheet .sheet-filters .ms-button.has-sel,
.ct-block .sheet-filters .ms.open .ms-button,
.ct-block .sheet-filters .ms-button.has-sel {
  color: var(--accent-2); border-color: var(--accent); background: rgba(47,111,255,.12);
}
.view-root--sheet .sheet-filters .ms-button.has-sel .ms-label,
.ct-block .sheet-filters .ms-button.has-sel .ms-label { color: var(--accent-2); }
.view-root--sheet .sheet-filters .ms-caret, .ct-block .sheet-filters .ms-caret { display: none; }

/* Анимации выпадающих панелей мультиселекта (`util.dropdownAnimateOpen/Close`). */
@keyframes dd-in {
  from { opacity: 0; transform: translateY(-6px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes dd-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-6px) scale(.98); }
}
.ms-panel { transform-origin: top center; }
.ms-panel.dd-opening, .acct-menu.dd-opening { animation: dd-in var(--dd-anim) cubic-bezier(.4,0,.2,1); }
.ms-panel.dd-closing, .acct-menu.dd-closing { animation: dd-out var(--dd-anim) cubic-bezier(.4,0,.2,1) both; }
@media (prefers-reduced-motion: reduce) {
  .ms-panel.dd-opening, .ms-panel.dd-closing,
  .acct-menu.dd-opening, .acct-menu.dd-closing { animation-duration: .001s; }
}

.view-root--sheet .sheet-section .table-host { flex: 1; min-height: 0; }
.view-root--sheet .grid th { background: var(--sheet-bg); }
.view-root--sheet .grid th:first-child, .view-root--sheet .grid td:first-child { padding-left: 20px; }
.view-root--sheet .grid th:last-child, .view-root--sheet .grid td:last-child { padding-right: 20px; }
.small { font-size: 12px; }

/* Кибериспытания и Профиль компании — общий фон ВСЕЙ страницы тонирован ТЕМ ЖЕ `--sheet-bg`, что
   заливает `.view-root--sheet` на Уязвимостях/Утечках (не только фон отдельных таблиц/карточек —
   общий тон страницы должен совпадать с остальными «листами»). Полноэкранный flush-режим
   `.view-root--sheet` тут не подходит (он расчитан на ОДНУ таблицу на весь экран,
   `overflow:hidden`) — здесь несколько разделов друг под другом с обычными отступами страницы,
   поэтому фон применяется отдельным модификатором `.view-root--tint` (см. TINT_PATHS в app.js). */
.view-root--tint { background: var(--sheet-bg); }

/* Разделы страницы (Кибериспытания: сводка участия + периоды + реализованные события; Профиль:
   общие сведения + недопустимые события + Кзи + активы) — ЯВНО РАЗДЕЛЁННЫЕ карточки на этом общем
   тонированном фоне: зазор `.ct-page{gap}` — видимое разделение, а не тонкая линия. Сама карточка
   `--surface-2` — на полтона глубже фона-канвы, тот же приём, что у мини-плиток `.ct-col`/
   `.rel-card` внутри плоских секций `.panel-block` (снаружи плоско, «чипы» чуть глубже). */
.ct-page { display: flex; flex-direction: column; gap: 16px; }
.ct-block { background: var(--surface-2); border: 1px solid var(--border-2); border-radius: var(--radius); }
/* Сводка участия/Кзи/активы переиспользуют `collapsible()` (та же `.collapse.panel-block`, что на
   дашборде) — здесь её базовый фон/рамка-разделитель не нужны (карточку уже даёт `.ct-block`
   снаружи). У `.ct-block` НЕТ overflow:hidden (см. комментарий у .table-host ниже — иначе
   выпадающий фильтр обрезался бы), поэтому скругление шапки НЕ подхватывается автоматически
   формой карточки — приходится скруглять её саму, ПО СОСТОЯНИЮ (см. `is-open` в collapsible()):
   свёрнута (шапка = вся видимая карточка) → скруглены ВСЕ четыре угла; раскрыта (тело продолжается
   ниже) → скруглены только верхние, нижние подхватывает `.collapse-body`. Без этого при наведении
   на СВЁРНУТУЮ карточку подсветка `.collapse-head:hover` показывала квадратные нижние углы поверх
   скруглённых углов `.ct-block`. */
.ct-block > .collapse.panel-block { border: none; background: transparent; padding: 0; margin: 0; }
.ct-block > .collapse.panel-block > .collapse-head { padding: 18px 20px; border-radius: var(--radius); }
.ct-block > .collapse.panel-block > .collapse-head.is-open { border-radius: var(--radius) var(--radius) 0 0; }
.ct-block > .collapse.panel-block > .collapse-body > .collapse-inner { padding: 6px 20px 18px; }
.ct-block > .collapse.panel-block > .collapse-body.is-open { border-radius: 0 0 var(--radius) var(--radius); }
/* Раздел-список с таблицей (периоды / реализованные события) — заголовок+фильтры+таблица внутри
   своей карточки; шапка таблицы (`.grid th`) — того же оттенка `--surface-2`, что и сама карточка,
   для бесшовного вида. НЕТ overflow:hidden на карточке (только у `.table-host` — своя ОГРАНИЧЕННАЯ
   высота/скролл, чтобы `position:sticky` у `th` не прилипал к верху ВСЕЙ страницы и не наезжал
   на раздел ниже): иначе выпадающая панель фильтра (`.ms-panel`) при короткой таблице обрезалась
   бы нижней границей карточки вместо того чтобы свободно всплывать поверх неё. */
.ct-block .sheet-list-head { padding: 18px 20px 14px; background: transparent; }
.ct-block .table-host { max-height: 420px; }
.ct-block .grid th:first-child, .ct-block .grid td:first-child { padding-left: 20px; }
.ct-block .grid th:last-child, .ct-block .grid td:last-child { padding-right: 20px; }
/* Раздел-список БЕЗ таблицы (Общие сведения/Недопустимые события на Профиле) — та же шапка
   `sheetHead`, но тело произвольное (не `<table>`): боковой отступ (20px) — тот же, что у ячеек
   таблицы выше, для одинакового выравнивания контента по обеим сторонам карточки. */
.ct-block-body { padding: 0 20px 18px; }

/* --- Профиль --- */
/* flex-start (не center) + min-width:0 на значении — длинное неразрывное значение (контакты,
   ИНН, e-mail) переносится по словам ВНУТРИ строки вместо распирания панели вширь. */
.kv { display: flex; gap: 12px; align-items: flex-start; padding: 7px 0; border-bottom: 1px dashed var(--border); }
.kv:last-child { border-bottom: none; }
.kv-key { width: 210px; flex: 0 0 210px; color: var(--muted); }
.kv-val { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.asset-list { margin: 0 0 10px; padding-left: 18px; }
.asset-list li { padding: 4px 0; }
.asset-kind { display: inline-block; font-size: 11px; text-transform: uppercase; color: var(--muted); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; margin-right: 6px; }

/* Недопустимые события в профиле (создание/правка/удаление — ТОЛЬКО заявкой, см. eventsBlock/
   openEventChangeForm в app.js; список ниже — read-only сводка). */
.ev-title { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.ev-crit { color: var(--muted); font-size: 12px; margin-left: auto; white-space: nowrap; }
/* li.ev-item ломает общий `.event-list li { display:flex }` — строка и форма редактирования
   должны идти одна ПОД другой, а не в одном ряду. */
.event-list li.ev-item { display: block; }
.ev-row { display: flex; align-items: center; gap: 9px; }
.ev-in { width: 100%; }
.ev-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted-2); font-weight: 600; margin: 6px 0 3px; }
.ev-label:first-child { margin-top: 0; }
/* Список карточек событий в заявке (openEventChangeForm) — каждая карточка ОБОСОБЛЕНА своей
   рамкой+скруглением+фоном и отделена ЗАЗОРОМ от соседних (не строка общей таблицы с тонкой
   линией-разделителем, как раньше): поле события (title+description+критерии) многострочное, и
   на линии-разделителе несколько карточек подряд сливались в нечитаемую стену полей. */
.ev-card-list { display: flex; flex-direction: column; gap: 10px; }
/* Кнопка «+ Добавить событие» шла сразу за последней карточкой без зазора (0px — карточки/кнопка
   просто блочно стоят друг под другом) — визуально прилипала к рамке блока над ней. */
.ev-add-btn { margin-top: 10px; }
.ev-edit-form {
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--surface-2);
}
/* Шапка карточки — затенённая полоса с номером-бейджем, ТЕМ ЖЕ приёмом, что заголовок группы
   показателей Кзи (`.kzi-pick-grp`): бейдж и контрастный фон сразу дают понять, где кончаются поля
   одного события и начинаются поля следующего, даже при беглом скролле. */
.ev-card-head { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--surface-3); }
.ev-card-num {
  flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--surface);
  color: var(--muted-2); font-size: 10.5px; font-weight: 700; display: inline-flex;
  align-items: center; justify-content: center;
}
.ev-card-fields { padding: 10px 12px 12px; }
/* Реально изменённая/новая карточка подсвечивается — ТОТ ЖЕ приём и цвет, что `.kzi-pick.is-changed`,
   но на шапке (не на всей карточке), чтобы не спорить с фоном текстовых полей внутри. */
.ev-edit-form.is-changed { box-shadow: inset 3px 0 0 var(--accent); }
.ev-edit-form.is-changed .ev-card-head { background: rgba(47, 111, 255, .22); }
.ev-label-title {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 700; color: var(--text); font-size: 12.5px;
}
/* Пометка СУЩЕСТВУЮЩЕГО события на удаление (иконка-корзина, toggle) — тот же приём и те же
   цвета, что у `.asset-del-btn`/`.asset-pick.is-removed` (сетевые активы), отдельные классы
   только из-за разной родительской структуры карточки. */
.ev-del-btn {
  flex: 0 0 auto; width: 26px; height: 26px; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 7px; border: none; background: transparent;
  color: var(--muted-2); cursor: pointer;
}
.ev-del-btn:hover { color: #ff6b6b; background: var(--surface); }
.ev-del-btn.is-active { color: #ff6b6b; }
.ev-remove-notice { display: none; color: #ff8a8a; padding: 8px 10px 10px; font-size: 12.5px; }
.ev-edit-form.is-removed { box-shadow: inset 3px 0 0 #ff6b6b; }
.ev-edit-form.is-removed .ev-card-head { background: rgba(255, 107, 107, .2); }
.ev-edit-form.is-removed .ev-card-fields { display: none; }
.ev-edit-form.is-removed .ev-remove-notice { display: block; }
.ev-edit-form.is-removed .ev-label-title { text-decoration: line-through; color: var(--muted); }
/* Компактный вариант `collapsible()` для «Критериев реализации» внутри карточки события — базовая
   `.collapse-head` (16px отступы, как у самостоятельных секций дашборда) слишком крупная для тесной
   карточки внутри и без того компактной формы. `border-top:none` снимает базовую линию-разделитель
   `.panel-block` (унаследованную от общего `.collapse.panel-block`) — внутри и без того тесной
   карточки она рисовалась ПОСЕРЕДИНЕ полей (между «Описание» и «Критерии»), не доходя до скруглённых
   краёв самой карточки — выглядело как случайный неровный обрыв, а не осмысленная граница. */
.ev-crit-collapse.collapse.panel-block { border-top: none; }
.ev-crit-collapse .collapse-head { padding: 8px 0; font-size: 12.5px; }
.ev-crit-collapse .collapse-inner { padding: 2px 0 6px; }
.ev-crit-collapse .collapse-title { font-weight: 600; font-size: 12px; color: var(--muted-2); }
.ev-crit-collapse .collapse-val { font-size: 12px; }
/* Список критериев — КАЖДОЕ поле (название/описание) на СВОЕЙ строке, а не бок о бок: рядом друг с
   другом в узкой раскрывающейся карточке они не помещались (текст обрезался/не читался). Каждый
   критерий — СВОЯ рамка+внутренний отступ (`.crit-item`): без неё поля растягивались во всю ширину
   раскрытого списка вплотную к его краям (единственной границей были рамки самих полей ввода,
   прижатые прямо к краю) — не было ни отступа, ни визуальной рамки самого пункта списка. Подписи
   `.ev-label` над каждым полем — иначе после заполнения (плейсхолдер пропадает) обе строки —
   Критерий и Описание — выглядят одинаковыми безымянными полями. Кружок-номер — тот же приём, что
   у самих карточек событий (`.ev-card-num`), чтобы визуально не путать соседние критерии. */
.crit-list { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 8px; }
.crit-item {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 10px 10px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
}
/* Номер-бейдж делит строку с подписью «Критерий» (не пустует один на отдельной строке). */
.crit-item-head { display: flex; align-items: center; gap: 7px; }
.crit-num {
  flex: none; width: 16px; height: 16px; border-radius: 50%; background: var(--surface-3);
  color: var(--muted-2); font-size: 9.5px; font-weight: 700; display: inline-flex;
  align-items: center; justify-content: center;
}
.crit-label { margin: 0; }
.crit-rm { margin-left: auto; }
.crit-in { width: 100%; }

/* --- Detail-панель уязвимости/находки — ТОЧНО стиль правой панели компании на витрине
   (`.panel` в client/frontend/css/styles.css): полупрозрачное «жидкое стекло» + блюр, БЕЗ
   тёмного оверлея-подложки (витрина тоже не даёт один — закрытие только кнопкой ✕/«Назад»). */
.detail-panel {
  position: fixed; top: 0; right: 0; height: 100%; width: var(--panel-w); max-width: 100vw;
  display: flex; flex-direction: column;
  background: rgba(12,16,26,.66);
  -webkit-backdrop-filter: blur(13px) saturate(1.25);
  backdrop-filter: blur(13px) saturate(1.25);
  border-left: 1px solid rgba(255,255,255,.08);
  padding: 24px 24px 0; overflow-y: auto; overflow-x: hidden;
  box-shadow: -18px 0 50px rgba(0,0,0,.42); z-index: 41;
  scrollbar-gutter: stable;
}
/* Кнопка закрытия — как .panel-close на витрине: плитка в правом верхнем углу. */
.panel-close {
  position: absolute; top: 18px; right: 18px; background: var(--surface-2);
  border: 1px solid var(--border-2); color: var(--text); border-radius: 10px;
  width: 36px; height: 36px; cursor: pointer; font-size: 15px; z-index: 1;
}
.panel-close:hover { border-color: var(--accent); }

/* Важность — ОБЫЧНЫЙ текст + цветной МАРКЕР-точка (единая палитра --sev-*), НЕ бейдж-«таблетка»
   (так теперь и в таблице, и в карточке — ТОЧНО как на витрине). */
.sev-cell { display: inline-flex; align-items: center; gap: 7px; }
.sev-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.sev-dot--low { background: var(--sev-low); }
.sev-dot--medium { background: var(--sev-medium); }
.sev-dot--high { background: var(--sev-high); }
.sev-dot--critical { background: var(--sev-critical); }

/* Карточка (fp-* — те же классы/вёрстка, что «карточка находки» на витрине). */
.fp-name { margin: 0 34px 12px 0; font-size: 20px; font-weight: 700; line-height: 1.22;
  color: var(--text); overflow-wrap: anywhere; word-break: break-word; }
.fp-fields { display: flex; flex-direction: column; gap: 13px; margin: 14px 0 16px; }
.fp-flabel { color: var(--muted-2); font-size: 13px; }
.fp-fval { color: var(--text); font-size: 15px; font-weight: 600; margin-top: 3px;
  overflow-wrap: anywhere; word-break: break-word; }
.fp-sec { padding: 15px 0; border-top: 1px solid var(--border); }
.fp-sec-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  font-size: 12px; color: var(--muted); font-weight: 700; margin-bottom: 10px; }
.fp-desc { white-space: pre-wrap; line-height: 1.6; font-size: 14px; color: var(--text);
  overflow-wrap: anywhere; word-break: break-word; }

/* Иконки статусов (окрашены по статусу) — заменяют цветную точку-чип в таймлайне и бейдж в
   шапке карточки/таблице. */
.fp-si { width: 17px; height: 17px; flex-shrink: 0; }
.fp-si--new { color: #b7c4e3; }
.fp-si--in_work { color: var(--accent-2); }
.fp-si--mitigated { color: var(--green); }
.fp-si--closed { color: var(--green-2); }
/* Отменённая уязвимость — красный крестик, не нейтральный серый: «Отменена»/«Отклонена» — тот же
   негативный, а не нейтральный исход, что и отклонённая заявка (см. `.fp-si--rejected` ниже,
   которая переиспользует ЭТУ ЖЕ форму иконки «запрет» и теперь совпадает с ней и по цвету). */
.fp-si--cancelled { color: var(--red); }
.fp-si--rejected { color: var(--red); }

/* Статус-чип в шапке карточки (иконка + подпись, read-only на вид — без заливки-«таблетки»),
   ТОЧНО как на витрине. Смена статуса в кабинете — отдельно, в секции «Обработка» ниже. */
.fp-status { position: relative; margin: 0 0 6px; }
.fp-status-btn { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px;
  border-radius: 10px; border: 1px solid var(--border-2); background: var(--surface-2);
  color: var(--text); font-family: inherit; font-size: 14px; font-weight: 600; }
.fp-status-btn.is-static { cursor: default; }
/* Цвет статуса красит подпись ТОЛЬКО у статичного чипа в шапке карточки (.fp-status-btn).
   В дропдауне выбора статуса (.ss-*) подпись — нейтральным цветом текста; статус там различают
   по иконке (она окрашивается сама по своему `fp-si--<status>`), а не по цвету шрифта. */
.fp-status-btn.st-new { color: #c6d0e6; }
.fp-status-btn.st-in_work { color: var(--accent-2); }
.fp-status-btn.st-mitigated { color: var(--green); }
.fp-status-btn.st-closed { color: var(--green-2); }
.fp-status-btn.st-cancelled { color: var(--red); }

/* --- Кастомный одиночный дропдаун статуса (statusSelect) — вместо нативного <select> --- */
.ss { position: relative; display: inline-block; }
.ss-btn {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer; min-width: 180px;
  font: inherit; font-size: 14px; font-weight: 600; background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 10px; padding: 9px 14px; color: var(--text);
  transition: border-color .15s, box-shadow .15s;
}
.ss.open .ss-btn { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(47,111,255,.18); }
.ss-btn:hover { border-color: var(--accent); }
.ss-lbl { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-ico { display: inline-flex; flex-shrink: 0; }
.ss-caret { flex-shrink: 0; color: var(--muted-2); font-size: 12px; transition: transform .16s; }
.ss.open .ss-caret { transform: rotate(180deg); }
.ss-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50; min-width: 100%;
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0,0,0,.45); padding: 6px;
}
.ss-list { display: flex; flex-direction: column; gap: 2px; }
.ss-opt {
  display: flex; align-items: center; gap: 9px; cursor: pointer; padding: 9px 10px;
  border-radius: 8px; font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap;
}
.ss-opt:hover, .ss-opt:focus { background: var(--surface-2); outline: none; }
.ss-opt.sel { background: rgba(47,111,255,.12); }
.ss-opt-text { flex: 1; }

/* Таблица: статус ПЕРВЫМ столбцом — иконка + подпись, БЕЗ бейджа-«таблетки» (как на витрине). */
.it-status { display: flex; align-items: center; gap: 8px; min-width: 0; }
.it-status .fp-si { width: 17px; height: 17px; flex-shrink: 0; }
.it-status-lbl { color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Плотная таблица (Уязвимости/Утечки — макет «Киберразведки» витрины): строки ближе друг к
   другу, в одну линию, без переноса. */
.grid--dense th { padding: 8px 16px; text-transform: none; font-size: 12px; letter-spacing: 0; }
.grid--dense td { padding: 6px 16px; white-space: nowrap; font-size: 13.5px; }

/* Обработка (смена статуса, кабинет-специфично — на витрине статус находки read-only). */
.editor-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.note-field { width: 100%; resize: vertical; margin-bottom: 8px; }
/* Поле заметки, обязательное для статуса «Митигирована» — акцентная рамка-подсказка. */
.note-field--required { border-color: var(--accent); }
.note-field--required::placeholder { color: var(--accent-2); }
.editor-msg { color: #ff97a6; font-size: 13px; min-height: 16px; }

/* История статусов — таймлайн с ИКОНКАМИ статуса (не цветной точкой), ТОЧНО как на витрине:
   узел-кружок на соединительной линии + иконка/подпись/время в теле записи. */
.fp-tl-list { list-style: none; padding: 0; margin: 4px 0 0; }
.fp-tl { position: relative; display: flex; gap: 14px; padding: 0 0 18px; }
.fp-tl-node { position: relative; z-index: 1; margin-top: 3px; width: 16px; height: 16px;
  flex-shrink: 0; border-radius: 50%; border: 2px solid var(--accent); background: var(--surface); }
.fp-tl:not(:last-child)::before { content: ""; position: absolute; left: 7px; top: 16px;
  bottom: 0; width: 2px; background: var(--border-2); }
/* min-width:0 — тело записи должно сжиматься вместе со строкой (не выходить за панель), а не
   растягивать её под длинную заметку/источник. */
.fp-tl-body { flex: 1 1 auto; min-width: 0; }
.fp-tl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fp-tl-lbl { font-size: 14px; font-weight: 600; color: var(--text); }
.fp-tl-cur { font-size: 11px; font-weight: 600; color: var(--accent-2); padding: 1px 8px;
  border-radius: 6px; background: rgba(47,111,255,.14); }
.fp-tl-time { font-size: 13px; color: var(--muted); margin-top: 3px; }
.fp-tl-delta { font-size: 12px; margin-top: 2px; color: var(--muted); }
.fp-tl-note { font-size: 13px; margin-top: 4px; padding-left: 8px; border-left: 2px solid var(--border);
  color: var(--text); white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere; }

.error-box { color: #ff97a6; background: rgba(255,54,79,.08); border: 1px solid rgba(255,54,79,.3); border-radius: 10px; padding: 12px 14px; }

/* --- Герой: штриховой граф security_score — прежний плоский дизайн (был до score-hero),
   стоит СПРАВА от метрик в .hero (см. renderDashboard). --- */
.hero-score { flex: 0 0 250px; }
.hero-score-cap { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; }
.hero-score-num { font-size: 56px; font-weight: 800; line-height: 1.05; }
.hero-score-lvl { font-weight: 700; margin-bottom: 14px; }
.hero-steps { height: 62px; }
.score-steps { width: 100%; height: 100%; display: block; }

/* --- Кибериспытания --- */
.ct-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.ct-col { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.ct-col-cap { color: var(--muted); font-size: 12px; }
.ct-col-val { font-size: 20px; font-weight: 800; margin-top: 2px; }
/* --- Сворачиваемая секция (Кзи) --- */
/* Без бокового отступа — как у соседних .panel-block (заголовки/списки начинаются от левого
   края секции); раньше было padding 0 20px и блок Кзи визуально «уезжал» вправо относительно
   остальных блоков дашборда/профиля. */
.collapse { padding: 0; overflow: hidden; }
.collapse-head { width: 100%; display: flex; align-items: center; gap: 12px; background: transparent; border: none; color: var(--text); padding: 16px 0; cursor: pointer; font-family: inherit; font-size: 15px; text-align: left; border-radius: 8px; }
/* var(--border), не surface-2: на дашборде .collapse теперь сама карточка с фоном surface (см.
   `.dash > .panel-block`) — разница surface→surface-2 слишком мала (почти незаметна), из-за чего
   подсветка казалась «неполной»/пятнами. border даёт заметный ровный контраст на любом фоне. */
.collapse-head:hover { background: var(--border); }
.collapse-title { font-weight: 600; }
.collapse-val { font-weight: 800; }
.collapse-chev { margin-left: auto; transition: transform .16s; color: var(--muted); font-size: 18px; }
.collapse-chev.is-open { transform: rotate(90deg); }
/* padding-top 6px (не 0) — зазор между шапкой и телом ТОЛЬКО когда тело раскрыто (при
   display:none зазор не рендерится, лишнего места в свёрнутом виде не добавляет): без него
   подсветка шапки при наведении вплотную упиралась в верхнюю границу первого элемента тела
   (ue-card и т.п.) — визуально накладывалась на неё. */
/* Плавный спойлер: max-height (JS ставит scrollHeight/0). Свёрнутый — РОВНО 0 высоты (max-height:0
   + overflow:hidden + border-box), никакой полосы под шапкой. Содержимое (padding) — в .collapse-inner. */
.collapse-body { max-height: 0; overflow: hidden; transition: max-height .24s ease; }
.collapse-inner { padding: 6px 0 18px; opacity: 0; transition: opacity .2s ease; }
.collapse-body.is-open > .collapse-inner { opacity: 1; }

/* --- Кзи-разложение (витринный стиль) --- */
.kzi-method { font-size: 12px; margin-bottom: 12px; }
.kzi-grp-list { display: flex; flex-direction: column; gap: 10px; }
.kzi-grp { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.kzi-grp.is-reset { opacity: .65; }
/* Столбцом (не строкой): полоса прогресса (kzi-grp-bar-wrap) — ВТОРОЙ ребёнок кнопки, не
   отдельный сосед — иначе подсветка :hover покрывала только строку заголовка, а полоса под ней
   оставалась тёмной (подсвечена только часть блока). Горизонтальный инсет (13px) — на самой
   кнопке, поэтому фон :hover заливает её ПОЛНОСТЬЮ, от края до края, включая полосу. */
.kzi-grp-head { width: 100%; display: flex; flex-direction: column; background: transparent; border: none; color: var(--text); padding: 0 13px; cursor: pointer; font-family: inherit; text-align: left; }
.kzi-grp-head:hover { background: var(--border); }
.kzi-grp-head-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; }
.kzi-grp-name { font-weight: 600; }
/* Маркер группы: внутри есть авто-занулённый условием показатель (уязвимости/утечка). */
.kzi-grp-flag { flex: 0 0 auto; width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 11px; font-weight: 800; color: #16130c; background: var(--orange); }
.kzi-grp-chip { margin-left: auto; font-size: 12px; color: var(--muted); border: 1px solid var(--border); border-radius: 6px; padding: 1px 7px; }
.kzi-grp-chev { color: var(--muted); transition: transform .16s; font-size: 16px; }
.kzi-grp-chev.is-open { transform: rotate(90deg); }
.kzi-grp-bar-wrap { padding: 0 0 8px; }
.kzi-grp-bar { height: 6px; background: rgba(255,255,255,.07); border-radius: 4px; overflow: hidden; }
.kzi-grp-bar-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--green), var(--accent-2)); }
.kzi-grp-body { display: none; padding: 2px 13px 12px; }
.kzi-grp-body.is-open { display: block; }
.kzi-req-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.kzi-req { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.kzi-req-num { color: var(--muted); font-size: 12px; width: 34px; flex: 0 0 34px; }
/* Минималистичный SVG-маркер БЕЗ фона (галочка/крест/слэш), центрован flex'ом — как на витрине
   (см. kziMarkIcon). Цвет — по состоянию строки. */
.kzi-req-mark { flex: 0 0 14px; width: 14px; height: 14px; display: inline-flex;
  align-items: center; justify-content: center; }
.kzi-mark-ico { width: 14px; height: 14px; display: block; }
.kzi-req.is-met .kzi-req-mark { color: var(--green); }
.kzi-req.not-met .kzi-req-mark { color: var(--red); }
.kzi-req.not-met .kzi-req-name { color: var(--muted); }
.kzi-req.is-reset .kzi-req-mark { color: var(--orange); }
.kzi-req.is-reset .kzi-req-name { color: var(--orange); }
.kzi-req-name { flex: 1 1 auto; }
/* Пометка авто-зануления показателя условием компании (незакрытые уязвимости / утечка УЗ). */
.kzi-req-flag { flex: 0 0 100%; margin-left: 42px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .02em; text-transform: uppercase; color: var(--orange); }
/* Есть полное описание (отличается от краткого имени) — курсор меняется на «?», чтобы было
   понятно, что по наведению раскроется полный текст (attachReqTip в app.js), ТОЧНО как на
   витрине (client's .kzi-req.has-tip). */
.kzi-req.has-tip { cursor: help; }
/* Подсказка полного текста показателя — портируется в body и позиционируется fixed из JS
   (attachReqTip): всегда поверх остального контента, не обрезается overflow'ом группы/карточки. */
.req-tip-pop { position: fixed; z-index: 1400; box-sizing: border-box;
  padding: 9px 12px; border-radius: 9px; background: rgba(16, 20, 30, .98);
  border: 1px solid var(--border-2); box-shadow: 0 16px 38px rgba(0, 0, 0, .6);
  font-size: 11.5px; line-height: 1.45; color: var(--text);
  opacity: 0; transform: translateY(-3px); pointer-events: none;
  transition: opacity .14s ease, transform .14s ease; }
.req-tip-pop.is-on { opacity: 1; transform: none; }
/* Компактная подсказка (короткий текст, напр. маркер активных) — по содержимому, в одну строку,
   чуть крупнее и жирнее для читаемости; не растягивается на всю REQ_TIP_MAX_W. */
.req-tip-pop--compact { width: auto; max-width: 240px; white-space: nowrap;
  padding: 7px 11px; font-size: 12.5px; font-weight: 600; }
@media (prefers-reduced-motion: reduce) {
  .req-tip-pop { transition: opacity .14s ease; }
}

/* --- Иконки сетевых активов --- */
.asset-list { list-style: none; padding-left: 0; }
.asset-item { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.asset-ico { flex: 0 0 auto; }
.asset-ico--domain { color: var(--accent-2); }
.asset-ico--ip { color: #7db0ff; }
.asset-val { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }

/* --- Списки уязвимостей/утечек на дашборде --- */
.dash-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dash-row { display: flex; align-items: center; gap: 12px; padding: 9px 8px; border-bottom: 1px solid var(--border); border-radius: 8px; cursor: pointer; }
.dash-row:last-child { border-bottom: none; }
.dash-row:hover { background: var(--surface-2); }
.dash-title { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-type { color: var(--muted); font-size: 12px; white-space: nowrap; }
.dash-more { display: inline-block; margin-top: 10px; color: var(--accent-2); text-decoration: none; font-size: 13px; }
.dash-more:hover { text-decoration: underline; }

/* --- Метка даты закрытия реализации НС --- */
.ev-closed { font-size: 12px; color: var(--muted); white-space: nowrap; margin-left: auto; }

/* Графический маркер активных — иконка-предупреждение (треугольник с «!») СРАЗУ после общего
   счётчика секции (Уязвимости / Утечки / Недопустимые события), яркая (красная). Число активных —
   красивой подсказкой по наведению (attachReqTip → .req-tip-pop). */
.active-marker {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  margin-left: 6px; color: var(--red); cursor: help; vertical-align: middle;
}
.active-marker .warn-tri-ico { display: block; }

/* --- Карточки недопустимых событий (дашборд) — ТЕ ЖЕ классы/цвета, что .ue-card на витрине,
   с критериями реализации (было скрыто) и уровнем реализации по 4-ступенчатой шкале --lvl-*. */
.ue-list { display: flex; flex-direction: column; gap: 10px; }
.ue-card { background: var(--surface-2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; }
.ue-card.is-active { border-color: rgba(255,54,79,.42); }
.ue-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.ue-title { font-weight: 700; font-size: 14px; color: var(--text); }
.ue-active { flex-shrink: 0; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  color: #ff7a8c; border: 1px solid rgba(255,54,79,.5); background: rgba(255,54,79,.14); white-space: nowrap; }
.ue-realized { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.ue-level { flex-shrink: 0; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  white-space: nowrap; border: 1px solid var(--border-2); background: var(--surface-3); color: var(--muted); }
.ue-level.lvl-basic { color: var(--lvl-basic); border-color: rgba(255,46,84,.5); background: rgba(255,46,84,.13); }
.ue-level.lvl-medium { color: var(--lvl-medium); border-color: rgba(255,138,30,.5); background: rgba(255,138,30,.12); }
.ue-level.lvl-advanced { color: var(--lvl-advanced); border-color: rgba(91,157,255,.5); background: rgba(91,157,255,.12); }
.ue-level.lvl-expert { color: var(--lvl-expert); border-color: rgba(47,128,255,.5); background: rgba(47,128,255,.14); }
.ue-desc { color: var(--muted); font-size: 13px; margin-top: 8px; line-height: 1.5; }
.ue-crit-label { color: var(--muted-2); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; margin-top: 12px; }
.ue-crits { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ue-crit { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 8px; padding: 8px 10px; }
.ue-crit-title { display: block; font-size: 13px; font-weight: 600; color: var(--text); }
.ue-crit-desc { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.45; }

@media (max-width: 820px) {
  .hero { flex-direction: column; align-items: stretch; }
  .hero-score, .hero > .stat-card { flex-basis: auto; width: 100%; }
  .ct-grid { grid-template-columns: 1fr; }
  .kv-key { width: 150px; flex-basis: 150px; }
}

/* Вложения заявок кабинета: список ссылок на PDF + загрузка нового файла. */
.sub-atts { margin-top: 6px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sub-att {
  display: inline-block; max-width: 220px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; padding: 2px 8px; border: 1px solid var(--border, #2a3550);
  border-radius: 6px; font-size: 12px; text-decoration: none; color: var(--text, #f4f5f8);
}
.sub-att:hover { border-color: var(--accent, #4c8bf5); }
.sub-att-item { display: inline-flex; align-items: center; gap: 2px; }
.sub-att-del {
  background: none; border: none; color: var(--muted-2, #767c8c); cursor: pointer;
  font-size: 11px; padding: 2px 4px; border-radius: 4px; line-height: 1;
}
.sub-att-del:hover { color: #ff6b6b; background: var(--surface-3, #1d222a); }
.sub-att-add { font-size: 12px; cursor: pointer; opacity: 0.85; }
.sub-att-add:hover { opacity: 1; }
.sub-att-input { display: none; }

/* ===== Модалка (создание заявки Кзи) ===== */
.modal-overlay {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center;
  justify-content: center; padding: 24px; background: rgba(0, 0, 0, 0.62);
}
.modal-card {
  display: flex; flex-direction: column; width: 640px; max-width: 100%;
  max-height: 88vh; background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 12px; overflow: hidden; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
/* Широкая модалка (форма подрядчиков): все поля ряда добавления умещаются в одну строку. */
.modal-card--wide { width: 960px; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.modal-title { font-size: 15px; font-weight: 600; color: var(--text); }
.modal-x {
  background: none; border: none; color: var(--muted); font-size: 15px; cursor: pointer;
  padding: 4px 8px; border-radius: 6px;
}
.modal-x:hover { color: var(--text); background: var(--surface-3); }
.modal-body { padding: 16px 18px; overflow-y: auto; }
.modal-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 14px;
  padding: 12px 18px; border-top: 1px solid var(--border); background: var(--surface-2);
}

/* ===== Форма выбора показателей Кзи ===== */
/* Кнопка создания заявки выровнена по левому краю блока и отделена линией сверху. */
.kzi-submit-bar {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  display: flex; justify-content: flex-start;
}
.kzi-form-hint { color: var(--muted); font-size: 12.5px; margin-bottom: 12px; }
.kzi-form-section-t {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted-2); margin: 14px 0 8px;
}
.kzi-pick-list { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
/* Заголовок раздела методики (номер + название) внутри таблицы показателей. */
.kzi-pick-grp {
  padding: 6px 10px; font-size: 12px; font-weight: 600; color: var(--accent-2);
  background: var(--surface-3); border-bottom: 1px solid var(--border);
}
/* Строка показателя: № | название | чекбокс. Вся строка — кликабельный <label> (клик где угодно
   переключает чекбокс). Полное описание — во всплывающей подсказке по наведению (.has-tip). */
.kzi-pick {
  display: grid; grid-template-columns: 44px 1fr auto; align-items: center; gap: 10px;
  padding: 7px 10px; border-bottom: 1px solid var(--border); cursor: pointer;
}
.kzi-pick:hover { background: var(--surface-2); }
.kzi-pick:last-child { border-bottom: none; }
/* Изменённый показатель подсвечивается (target ≠ current). */
.kzi-pick.is-changed { background: rgba(47, 111, 255, 0.12); box-shadow: inset 3px 0 0 var(--accent); }
.kzi-pick-num { color: var(--muted-2); font-size: 12px; font-variant-numeric: tabular-nums; }
.kzi-pick-name { color: var(--text); font-size: 13px; overflow: hidden; text-overflow: ellipsis; }
.kzi-pick-cur { color: var(--muted-2); font-size: 11px; white-space: nowrap; }
/* Чекбокс целевого значения показателя (checked = «выполнен»). */
.kzi-chk { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px; color: var(--muted); flex: none; }
.kzi-chk input { cursor: pointer; }
.kzi-seg { display: inline-flex; border: 1px solid var(--border-2); border-radius: 6px; overflow: hidden; flex: none; }
.kzi-seg-b {
  background: var(--surface-2); border: none; color: var(--muted); font-size: 12px;
  padding: 4px 10px; cursor: pointer;
}
.kzi-seg-b + .kzi-seg-b { border-left: 1px solid var(--border-2); }
.kzi-seg-b.active { background: var(--accent); color: #fff; }
.kzi-file-input { display: none; }
.kzi-file-pick { display: inline-block; }
.kzi-files { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.kzi-file {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 5px 9px; border: 1px solid var(--border); border-radius: 6px; font-size: 12.5px;
}
.kzi-file-name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1 1 auto; min-width: 0; }
.kzi-file-del {
  background: none; border: none; color: var(--muted-2); cursor: pointer; font-size: 12px;
  padding: 2px 6px; border-radius: 4px; line-height: 1; flex: none;
}
.kzi-file-del:hover { color: #ff6b6b; background: var(--surface-3); }
.kzi-form-count { color: var(--muted); font-size: 12.5px; margin-right: auto; }

/* In-app уведомление (toast) — заменяет native alert. */
.im-toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%) translateY(12px);
  background: var(--surface-3); color: var(--text); border: 1px solid var(--border-2);
  padding: 10px 16px; border-radius: 8px; font-size: 13px; z-index: 300; max-width: 90vw;
  opacity: 0; pointer-events: none; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.45);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.im-toast.is-on { opacity: 1; transform: translateX(-50%) translateY(0); }
.im-toast.is-error { border-color: #ff6b6b; color: #ffd7d7; }

/* ===== Форма изменения сетевых активов ===== */
/* Строка текущего актива с чекбоксом «удалить»; помеченная — подсвечивается (зачёркнута). */
.asset-pick {
  display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 10px;
  padding: 7px 10px; border-bottom: 1px solid var(--border); cursor: pointer;
}
.asset-pick:last-child { border-bottom: none; }
.asset-pick:hover { background: var(--surface-2); }
.asset-pick-val { color: var(--text); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Подрядчик в форме заявки: нет колонки-иконки вида → 2 колонки (название | кнопка), чтобы
   длинное название не «зажималось» в узкую иконочную колонку (было: сетка на 3 колонки).
   Строка не кликабельна (клик только по корзине) → курсор по умолчанию, а на названии —
   «help» (есть всплывающая подсказка по компании). */
.asset-pick--company { grid-template-columns: 1fr auto; cursor: default; }
.asset-pick--company .asset-pick-val { cursor: help; }
/* Шапка секции формы с кнопкой справа (напр. «Текущие активы» + «Удалить все»). */
.form-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* Кнопка-иконка «удалить» (корзина): серая, становится красной при пометке на удаление. */
.asset-del-btn {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  background: none; border: none; color: var(--muted-2); cursor: pointer;
  padding: 4px; border-radius: 6px; line-height: 0;
}
.asset-del-btn:hover { color: #ff6b6b; background: var(--surface-3); }
.asset-del-btn.is-active { color: #ff6b6b; }
.asset-pick.is-removed { background: rgba(255, 107, 107, 0.12); box-shadow: inset 3px 0 0 #ff6b6b; }
.asset-pick.is-removed .asset-pick-val { text-decoration: line-through; color: var(--muted); }
/* Многострочное поле добавления активов (одна строка = один актив), моноширинное для ровных
   столбцов IP/подсетей; вид определяется автоматически по значению. */
.asset-textarea { width: 100%; resize: vertical; min-height: 92px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.5; }
/* Строка добавления подрядчика: ИНН + название + отрасль + регион + кнопка (перенос на узком экране). */
.link-add-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
.link-add-row .field { flex: 1 1 140px; min-width: 0; }
.link-add-row--opt { margin-top: 8px; }
/* Поле ИНН с выпадающим списком автодополнения (позиционируем меню под инпутом). */
.inn-typeahead { position: relative; flex: 1 1 150px; min-width: 0; }
.inn-typeahead .field { width: 100%; }
/* Плавающее меню автодополнения ИНН: position:fixed (координаты ставит JS floatMenu) — выводит
   список ПОВЕРХ окна заявки, не обрезаясь его overflow (containing block = вьюпорт). */
.inn-menu {
  position: fixed; z-index: 1300;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  max-height: 240px; overflow-y: auto; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.inn-opt { padding: 7px 10px; cursor: pointer; border-bottom: 1px solid var(--border); }
.inn-opt:last-child { border-bottom: none; }
.inn-opt:hover { background: var(--surface-3); }
.inn-opt-name { font-size: 13px; color: var(--text); }
.inn-opt-sub { font-size: 11px; color: var(--muted); margin-top: 1px; }
.inn-opt.is-dup { cursor: default; opacity: 0.5; }
.inn-opt.is-dup:hover { background: none; }
.inn-opt--new { color: #57b894; font-size: 13px; }
/* Поле, заблокированное подстановкой существующей компании (данные не редактируются). */
.field.is-locked { opacity: 0.6; cursor: not-allowed; }
/* Комбобокс региона (поле с поиском + выпадающий список, как фильтры таблиц). */
.combo { position: relative; flex: 1 1 150px; min-width: 0; }
.combo .field { width: 100%; }
.combo-menu {
  position: fixed; z-index: 1300;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  max-height: 220px; overflow-y: auto; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.combo-opt { padding: 7px 10px; cursor: pointer; font-size: 13px; color: var(--text);
  border-bottom: 1px solid var(--border); }
.combo-opt:last-child { border-bottom: none; }
.combo-opt:hover { background: var(--surface-3); }
.combo-opt.is-sel { color: var(--accent); font-weight: 600; }
.combo-empty { padding: 7px 10px; font-size: 12px; color: var(--muted-2); }
/* Распознанный актив/подрядчик в превью добавлений — подсвечен (зелёная рамка/полоса). */
.kzi-file.is-added { border-color: #57b894; box-shadow: inset 3px 0 0 #57b894; }
/* Нераспознанная/повторяющаяся строка (отчёт под превью добавлений) — красная полоса. */
.kzi-file.is-error { border-color: #ff6b6b; box-shadow: inset 3px 0 0 #ff6b6b; }
/* Маркер-предупреждение (новая компания / расхождение данных) — детали во всплывашке по наведению. */
.link-warn-mark {
  flex: none; margin-left: auto; cursor: help; color: #e0b050; font-size: 14px; line-height: 1;
  padding: 2px 4px; border-radius: 6px;
}
.link-warn-mark:hover, .link-warn-mark:focus { background: rgba(230, 180, 80, 0.16); outline: none; }
/* Запись добавления с предупреждением (новая / расхождение / без региона) — янтарный акцент слева. */
.kzi-file.is-added.has-warn { border-color: #e0b050; box-shadow: inset 3px 0 0 #e0b050; }
/* Запись, БЛОКИРУЮЩАЯ отправку — КРАСНАЯ: невалидная (импорт не прошёл проверку) ИЛИ без региона
   (регион обязателен, пока не выбран — заявку отправить нельзя). Чинить кликом/выбором или удалить. */
.kzi-file.is-added.is-invalid, .kzi-file.is-added.is-blocking {
  border-color: #ff6b6b; box-shadow: inset 3px 0 0 #ff6b6b; background: rgba(255, 107, 107, 0.07);
}
.link-err-text { flex: none; margin-left: auto; font-size: 12px; color: #ff8a8a; white-space: nowrap; }
/* Название добавленной компании кликабельно — клик возвращает её в форму на редактирование. */
.link-file-name { cursor: pointer; }
.link-file-name:hover { text-decoration: underline; color: var(--accent); }
/* Кнопка с иконкой (иконка + подпись рядом) — экспорт/импорт CSV. */
.btn-icon { display: inline-flex; align-items: center; gap: 6px; }
.btn-ico { flex: none; }
/* Тулбар CSV сверху формы: экспорт + импорт рядом. */
.link-csv-bar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
/* Инлайн-комбобокс региона для импортированной строки с нераспознанным регионом (блокирует
   отправку → красная подпись, как и подсветка строки). */
.link-region-need { flex: none; font-size: 12px; color: #ff8a8a; white-space: nowrap; }
.combo.link-region-fix { flex: 0 1 200px; min-width: 140px; }
.combo.link-region-fix .field { padding: 5px 8px; font-size: 12px; }

/* Наглядное описание заявки в списке «Заявки». */
.sub-desc { display: flex; flex-direction: column; gap: 2px; }
.sub-desc-line { font-size: 13px; color: var(--text); }
.sub-desc-line.is-add { color: #57b894; }
.sub-desc-line.is-del { color: #ff8a8a; }

/* Кастомная всплывающая подсказка (js/tooltip.js) — вместо системного native title.
   Портирована с витрины (client/frontend); тот же вид/поведение. */
.im-tip { position: fixed; z-index: 9999; pointer-events: none; max-width: 320px;
  padding: 6px 10px; border-radius: 8px; font-size: 12.5px; line-height: 1.4;
  color: #eaf0fb; background: rgba(16,22,36,.97); border: 1px solid rgba(120,150,190,.32);
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.im-tip[hidden] { display: none; }
