/* components.css — атомарные UI-компоненты (T02.14, premium-polish 2026-05-30).
 *
 * Используются в base.html + admin templates + макросах _macros.html.
 * Все цвета — через токены tokens.css (никаких hardcoded hex). См. STYLE_GUIDE.md.
 *
 * Контраст: текст/кнопки на --brand-ink (#00707E, 5.8:1 AA), не на --brand-primary
 * (#0AB5C5, 2.49:1 — только декор). См. audit 2026-05-30.
 */

/* ============================================================
   FOCUS-VISIBLE (a11y) — единый видимый фокус для клавиатуры
   ============================================================ */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 2px;
}
/* мышиный фокус не показываем (только клавиатурный) */
:focus:not(:focus-visible) { outline: none; }

/* ============================================================
   DISPLAY TYPOGRAPHY (feat/typography-tabs Ф1)
   Golos Text — только заголовки разделов/карточек + KPI-числа.
   body/кнопки/инпуты/.ms-prose остаются Golos (они наследуют font-family).
   Трек -0.012em (эталон mockup); элементы с собственным -0.02em (hero,
   rich-KPI) сохраняют его за счёт каскада: этот блок стоит ВЫШЕ их правил
   (.ms-hero__title — позже по порядку; rich-KPI — выше по специфичности).
   ============================================================ */
.ms-page-header__title,
.ms-card-title,
.ms-section-title,
.ms-panel-section__title,
.ms-empty__title,
.ms-hero__title,
.ms-kpi-card__value,
.ms-tile-row__title,
.ms-popover__title {
  font-family: var(--font-display);
  letter-spacing: -0.012em;
}

/* ============================================================
   СКВОЗНЫЕ БАННЕРЫ (полоса над контентом кабинета)
   ============================================================ */
/* TASK_626.2: баннеры «подтвердите почту» и impersonate были свёрстаны инлайновыми
   стилями с цветами мимо палитры бренда, причём баннер верификации показывается на
   КАЖДОЙ странице, пока почта не подтверждена. Вынесены в класс: вид задаётся в одном
   месте, а не переписывается в разметке. Кнопка внутри — обычная ms-btn ms-btn-sm. */
.ms-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: 10px var(--space-4);
  font-size: var(--text-secondary-size);
  border-bottom: 2px solid transparent;
}
.ms-notice form { margin: 0; }
.ms-notice__actions { display: flex; align-items: center; gap: var(--space-3); }
.ms-notice__link { color: var(--brand-ink); font-weight: 600; font-size: var(--text-xs); }
/* Информационный — подтверждение почты. */
.ms-notice--info { background: var(--alert-info-bg); border-bottom-color: var(--brand-ink); color: var(--graphite); }
/* Предупреждающий — режим impersonate. Кнопка выхода ghost: это escape-действие,
   а не CTA, и белое на янтарном читается без изобретения нового цвета. */
.ms-notice--warning { background: var(--alert-warning-bg); border-bottom-color: var(--warning); color: var(--alert-warning-text); }
/* NB: модификатора --fixed тут нет намеренно. Прибитая к верху окна версия нужна только
   на change_password.html, а он standalone и components.css не подключает — правило было
   бы классом с нулём потребителей, то есть ровно тем мёртвым слоем, который мы и убираем. */

/* ============================================================
   BUTTONS
   ============================================================ */
.ms-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  position: relative;
  /* TASK_626.1: без этого <a>/<summary> остаются content-box (border-box браузер даёт
     только <button>) и padding с рамкой прибавляются СВЕРХУ к min-height: ссылка-кнопка
     рендерилась 64px вместо 44px, ms-btn-sm — 46 вместо 32. Замерено на 67 ссылках из 202. */
  box-sizing: border-box;
  padding: 9px 16px;
  min-height: 44px;            /* tap-target a11y (WCAG 2.5.5 AAA) */
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--transition-fast),
              border-color var(--transition-fast),
              color var(--transition-fast),
              box-shadow var(--transition-fast),
              transform var(--transition-fast);
}
.ms-btn:active { transform: translateY(1px); }

.ms-btn-primary {
  background: var(--brand-ink);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}
.ms-btn-primary:hover { background: var(--brand-ink-hover); box-shadow: var(--shadow); }
/* TASK_627 (Р5.1, идея владельца): пока сохранять нечего — кнопка приглушена, первая правка
   её зажигает. Класс вешает settings_dirty_guard.js, а НЕ шаблон: без JS кнопка остаётся
   обычной цветной. И это только вид — кнопка не disabled, нажать можно всегда (если детект
   правки промахнётся, сохранить всё равно получится). Контраст текста на белом 5.80:1. */
.ms-btn-primary.is-idle {
  background: var(--white);
  color: var(--brand-ink);
  box-shadow: none;
  border-color: var(--brand-border-strong);
}
.ms-btn-primary.is-idle:hover { background: var(--brand-primary-light); box-shadow: var(--shadow-sm); }

.ms-btn-secondary {
  background: var(--brand-secondary);
  color: var(--white);
}
.ms-btn-secondary:hover { background: var(--brand-secondary-dark); }

.ms-btn-ghost {
  background: var(--white);
  color: var(--graphite);
  border-color: var(--graphite-30); /* TASK_503.1: рамка заметна в покое (была --gray-border);
                                       hover-сигнал остаётся за фоном --gray-mid */
}
.ms-btn-ghost:hover { background: var(--gray-mid); border-color: var(--graphite-30); }

.ms-btn-danger { background: var(--danger); color: var(--white); }
.ms-btn-danger:hover { background: var(--danger-ink); }

/* Лёгкий вариант деструктивной кнопки для списков/управления (TASK_424): не «стена
   красного» — обводка на белом. Сплошной ms-btn-danger оставляем подтверждающим диалогам. */
.ms-btn-danger-outline { background: var(--white); color: var(--danger); border-color: var(--danger); }
.ms-btn-danger-outline:hover { background: var(--danger-light); color: var(--danger-ink); border-color: var(--danger-ink); }

/* Акцент добавления (TASK_503.2): outlined-кнопка «+ Добавить …» — заметнее ghost,
   но не конкурирует с primary-CTA форм (hover НЕ заливается — фон --gray-mid). */
.ms-btn-add { background: var(--white); color: var(--brand-ink); border-color: var(--brand-ink); }
.ms-btn-add:hover { background: var(--gray-mid); color: var(--brand-ink-hover); }

/* Внешняя ссылка-кнопка (TASK_503.3): переход на чужую площадку «… ↗» — чернильный
   текст на тихой рамке --gray-border; hover подчёркивает, как у ссылок. */
.ms-btn-linkout { background: var(--white); color: var(--brand-ink); border-color: var(--gray-border); }
.ms-btn-linkout:hover { text-decoration: underline; }

.ms-btn-sm { padding: 6px 12px; min-height: 32px; font-size: var(--text-xs); }
/* TASK_590.2: на тач-устройствах мелкие кнопки дорастают до 44px (визуал на десктопе не трогаем). */
@media (pointer: coarse) { .ms-btn-sm { min-height: 44px; } }
.ms-btn-lg { padding: 12px 22px; min-height: 48px; font-size: var(--text-base); }

.ms-btn:disabled,
.ms-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
}

/* loading state — текст скрыт, крутится спиннер */
.ms-btn.is-loading { color: transparent !important; pointer-events: none; }
.ms-btn.is-loading::after {
  content: "";
  position: absolute;
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--radius-full);
  color: var(--white);
  animation: ms-spin 0.6s linear infinite;
}
.ms-btn-ghost.is-loading::after { color: var(--graphite); }
@keyframes ms-spin { to { transform: rotate(360deg); } }

/* ============================================================
   CARDS
   ============================================================ */
.ms-card,
.ms-card-lg {
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.ms-card-lg { padding: var(--space-8); }
.ms-card-flush { padding: 0; overflow: hidden; }

.ms-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.ms-card-flush .ms-card-header { padding: var(--space-5) var(--space-6) 0; margin-bottom: var(--space-4); }
.ms-card-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--graphite);
}

/* ============================================================
   PAGE HEADER (title + meta + actions) — единый паттерн вместо inline-flex
   ============================================================ */
.ms-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}
.ms-page-header__title { margin: 0; font-size: var(--text-2xl); font-weight: 700; color: var(--graphite); }
.ms-page-header__meta { margin: var(--space-1) 0 0; color: var(--graphite-60); font-size: var(--text-sm); }
.ms-page-header__actions { display: flex; gap: var(--space-2); flex-shrink: 0; }
/* TASK_308: на узком экране ряд действий ужимается и переносит кнопки (иначе flex-shrink:0 + max-content ширина = overflow, напр. карточка клиники в админке /admin/clinics/{id}). */
@media (max-width: 768px) { .ms-page-header__actions { flex-wrap: wrap; flex-shrink: 1; min-width: 0; } }

/* ============================================================
   BADGES
   ============================================================ */
.ms-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 2px;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  background: var(--gray-mid);
  color: var(--graphite-60);
  white-space: nowrap;
}
.ms-badge-danger  { background: var(--danger-light);  color: var(--danger-ink); }
.ms-badge-success { background: var(--success-light); color: var(--success-ink); }
.ms-badge-warning { background: var(--warning-light); color: var(--warning-ink); }
.ms-badge-info    { background: var(--brand-secondary-light); color: var(--brand-secondary); }
.ms-badge-count {
  margin-left: auto;
  padding: 1px 7px;
  text-transform: none;
  letter-spacing: 0;
}

/* ============================================================
   FORM CONTROLS
   ============================================================ */
.ms-form-group { margin-bottom: var(--space-5); }

/* Инлайн-лейбл с чекбоксом; not-allowed при disabled-инпуте — состояние без JS */
.ms-inline-toggle { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.ms-inline-toggle:has(input:disabled) { cursor: not-allowed; }

.ms-input,
.ms-textarea,
.ms-input-text,
input[type="text"].ms-input,
input[type="email"].ms-input,
input[type="tel"].ms-input,
input[type="search"].ms-input,
input[type="password"].ms-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  font-size: var(--text-base);   /* 16px — без iOS-zoom */
  font-family: inherit;
  color: var(--graphite);
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.ms-textarea { min-height: 96px; resize: vertical; line-height: 1.5; }

/* TASK_626.4: --graphite-60 равен цвету основного текста (near-black), поэтому подсказка
   в пустом поле была неотличима от заполненного. --graphite-30 заведён в tokens.css
   именно под «disabled, placeholder». Чёрный вторичный текст — решение владельца,
   остаётся как есть; правится только протечка на плейсхолдеры. */
.ms-input::placeholder,
.ms-textarea::placeholder { color: var(--graphite-30); }

.ms-input:focus,
.ms-textarea:focus {
  outline: none;
  border-color: var(--brand-ink);
  box-shadow: 0 0 0 3px var(--brand-primary-light);
}
.ms-input:disabled,
.ms-textarea:disabled { background: var(--gray-mid); color: var(--graphite-30); cursor: not-allowed; }

.ms-input-error,
.ms-input.ms-input-error:focus { border-color: var(--danger); }
.ms-input-error:focus { box-shadow: 0 0 0 3px var(--danger-light); }

select.ms-input { cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235F7373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 38px; }

.ms-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--graphite);
  margin-bottom: 6px;
}
.ms-label-required::after { content: " *"; color: var(--danger); }
.ms-hint,
.ms-hint-text {
  font-size: var(--text-xs);
  color: var(--graphite-60);
  margin: 6px 0 0;
  line-height: 1.4;
}
.ms-hint { margin: -8px 0 12px; max-width: 70ch; line-height: 1.55; }  /* TASK_432 (§В): мера ~130 знаков рвала читаемость под таблицей аналитики */
.ms-error-text {
  font-size: var(--text-xs);
  color: var(--danger-ink);
  margin: 6px 0 0;
  line-height: 1.4;
}

/* ============================================================
   TABLES
   ============================================================ */
.ms-table-wrap {
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow-x: auto;             /* было hidden → данные обрезались на мобиле (audit F-04) */
  -webkit-overflow-scrolling: touch;
}
/* POP — ЛОКАЛЬНОЕ усиление разделения таблицы (konfetka polish, /competitors).
   Поднимает обёртку над фоном без правки глобального .ms-table-wrap
   (общий для ~10 списков, часть пойдёт в функц-переделку → не оформляем). */
.ms-table-wrap--pop { box-shadow: var(--shadow); border-color: var(--brand-border); }
.ms-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.ms-table th,
.ms-table td { padding: 12px 16px; text-align: left; vertical-align: middle; }
.ms-table th {
  background: var(--gray-mid);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--graphite);
  border-bottom: 1px solid var(--gray-border);
  position: sticky; top: 0; z-index: var(--z-sticky);
}
.ms-table tr + tr td { border-top: 1px solid var(--gray-border); }
.ms-table tbody tr { transition: background-color var(--transition-fast); }
.ms-table tbody tr:hover { background: var(--gray-bg); }

/* Responsive: таблица → карточки на узких экранах.
 * Применяется к таблицам с классом .ms-table--cards; каждая <td> должна иметь
 * data-label="Заголовок" (рендерится перед значением). */
@media (max-width: 640px) {
  /* true block flow — иначе display:table считает min-width по колонкам и режет */
  .ms-table--cards,
  .ms-table--cards tbody { display: block; width: 100%; }
  .ms-table--cards thead { position: absolute; left: -9999px; }
  .ms-table--cards tr { display: block; padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--gray-border); }
  .ms-table--cards tr:first-child { border-top: 0; }
  /* label над значением — значение получает всю ширину (текст отзыва не режется) */
  .ms-table--cards td { display: block; padding: 5px 0; border: 0 !important;
    text-align: left; white-space: normal; word-break: break-word; }
  .ms-table--cards td::before { content: attr(data-label); display: block;
    font-size: var(--text-xs); font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.3px; color: var(--graphite-60); margin-bottom: 2px; }
}

/* TASK_559: сортируемые заголовки (клик → сорт строк) + фильтр по расстоянию (/competitors). */
.ms-thsort { border: 0; background: none; font: inherit; color: inherit; cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; gap: 3px; }
.ms-thsort:hover { text-decoration: underline; }
.ms-thsort--on { font-weight: 700; color: var(--brand-ink); }

/* ============================================================
   TABLE — COMPARE variant (раздел «Сравнения», TASK_130)
   Плотные компаунд-ячейки (значение + .ms-cmp-sub) + анти-слоп
   (docs/archive/TABS_PLAN.md): цвет = ТОЛЬКО сигнал проблемы; рейтинг — акцент весом
   (Golos «как везде») + янтарная звезда; без бейдж-пилюль. Scoped модификатор —
   НЕ трогает общий .ms-table (10+ списков с vertical-align:middle).
   ============================================================ */
.ms-table--compare td { vertical-align: top; padding: 16px 12px; }
.ms-table--compare th { padding-left: 12px; padding-right: 12px; }
.ms-table--compare td,
.ms-table--compare th { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* подпись под значением — тихая, без переноса в середине */
.ms-table--compare .ms-cmp-sub {
  display: block; margin-top: 3px; font-size: var(--text-xs);
  font-weight: 400; line-height: 1.3; color: var(--graphite-60);
}
/* рейтинг — лёгкий акцент весом (шрифт как везде); звезда янтарная (#F5A623, .ms-star-full) */
.ms-table--compare .ms-cmp-rating { font-weight: 700; font-size: 15px; color: var(--graphite); }
.ms-table--compare .ms-cmp-star { color: var(--star); font-size: 13px; margin-right: 3px; }
/* позитив — нейтрально-тёмный; негатив/SLA — единственный «красный» сигнал */
.ms-table--compare .ms-cmp-pos { color: var(--graphite); font-weight: 500; }
.ms-table--compare .ms-cmp-neg { color: var(--danger-ink); font-weight: 500; }
/* приглушённое (qr «есть», нули, прочерки) + янтарное предупреждение (нет QR) */
.ms-table--compare .ms-cmp-muted { color: var(--graphite-30); }  /* TASK_430: --graphite-30 — реально приглушённый аффорданс «нет/мало данных»; --graphite-60 схлопнут в near-black и читался как настоящее значение (исходно --gray-mid ≈невидим) */
.ms-table--compare .ms-cmp-warn { color: #B4540A; font-weight: 600; }
/* на мобиле (≤640px → карточки) компаунд-ячейка не режется nowrap'ом */
@media (max-width: 640px) {
  .ms-table--compare td,
  .ms-table--compare th { white-space: normal; }
  .ms-table--compare td { padding: 5px 0; }
}

/* Рейтинг-вид Сравнений (TASK_317) — ранг по avg_rating + подсветка своего филиала.
   Промоут из mockups/team_roles/team_rating_a.html. Только rating-вид (?view=rating). */
.rk-rank { display: inline-block; min-width: 1.7em; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }
.rk-row-you td { background: var(--gray-bg); }
.rk-row-you td:first-child { box-shadow: inset 3px 0 0 var(--graphite); }
.rk-you { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; padding: 11px 16px; border: 1px solid var(--gray-border); border-left: 3px solid var(--graphite); border-radius: var(--radius-sm); background: var(--white); }
.rk-you__name { font-weight: 600; }
.rk-you__pos { font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--graphite-60); }

/* ============================================================
   ALERTS
   ============================================================ */
.ms-alert {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin-bottom: var(--space-4);
  border: 1px solid var(--alert-info-border);
  background: var(--alert-info-bg);
  color: var(--alert-info-text);
}
.ms-alert__title { font-weight: 700; margin-bottom: 8px; }  /* TASK_432 (§В): заголовок дисклеймера был inline font-weight:600 (off-system) → класс, вес 700 как все заголовки */
.ms-alert-error   { background: var(--alert-error-bg);   color: var(--alert-error-text);   border-color: var(--alert-error-border); }
.ms-alert-success { background: var(--alert-success-bg); color: var(--alert-success-text); border-color: var(--alert-success-border); }
.ms-alert-warning { background: var(--alert-warning-bg); color: var(--alert-warning-text); border-color: var(--alert-warning-border); }

/* ============================================================
   EMPTY STATE
   ============================================================ */
.ms-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-12) var(--space-6);
  background: var(--white);
  border: 1px dashed var(--gray-border);
  border-radius: var(--radius);
}
.ms-empty--sm { padding: var(--space-8) var(--space-4); }
.ms-empty__icon {
  width: 48px; height: 48px;
  color: var(--brand-primary);
  margin-bottom: var(--space-4);
  opacity: 0.9;
}
.ms-empty--sm .ms-empty__icon { width: 36px; height: 36px; margin-bottom: var(--space-3); }
.ms-empty__title { margin: 0; font-size: var(--text-lg); font-weight: 700; color: var(--graphite); }
.ms-empty__text { margin: var(--space-2) 0 0; max-width: 42ch; color: var(--graphite-60); font-size: var(--text-sm); line-height: 1.5; }
.ms-empty__cta { margin-top: var(--space-5); display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: center; }

/* ============================================================
   KPI CARD (dashboard / reports)
   ============================================================ */
.ms-kpi-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius);
  padding: var(--space-5) var(--space-6);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}
.ms-kpi-card--link:hover {
  border-color: var(--brand-primary);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.ms-kpi-card__label {
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--graphite-60);
}
.ms-kpi-card__value {
  margin-top: var(--space-2);
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: 1.1;
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}
.ms-kpi-card__sublabel { margin-top: var(--space-1); font-size: var(--text-xs); color: var(--graphite-60); }
.ms-kpi-card__delta { margin-top: var(--space-2); font-size: var(--text-sm); font-weight: 600; }
.ms-kpi-card__delta--up { color: var(--success-ink); }
.ms-kpi-card__delta--down { color: var(--danger-ink); }
.ms-kpi-card__delta--neutral { color: var(--graphite-60); }

/* ============================================================
   STARS (рейтинг)
   ============================================================ */
.ms-stars { display: inline-flex; gap: 1px; line-height: 1; white-space: nowrap; }
.ms-star { color: var(--graphite-30); font-size: var(--text-base); }  /* TASK_432 (§В): пустая звезда была --gray-border (~1.3:1, читалась как disabled) → --graphite-30 видимее */
.ms-star-full { color: var(--star); }  /* янтарный — стандарт «звёзд», читаем на белом (токен --star, TASK_431) */
.ms-star-half { color: var(--star); opacity: 0.55; }
.ms-stars-sm .ms-star { font-size: var(--text-sm); }
.ms-stars-lg .ms-star { font-size: var(--text-xl); }

/* ============================================================
   HTMX loading affordances (свопы без feedback — audit F-15)
   ============================================================ */
.htmx-indicator { opacity: 0; transition: opacity var(--transition-fast); }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }
.htmx-request.ms-btn { color: transparent !important; pointer-events: none; }
.htmx-request.ms-btn::after {
  content: ""; position: absolute; width: 16px; height: 16px;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: var(--radius-full); color: var(--white);
  animation: ms-spin 0.6s linear infinite;
}
.ms-spinner {
  display: inline-block; width: 16px; height: 16px;
  border: 2px solid var(--gray-border); border-top-color: var(--brand-ink);
  border-radius: var(--radius-full); animation: ms-spin 0.6s linear infinite;
  vertical-align: middle;
}

/* ============================================================
   LINKS (контент-ссылки на --brand-ink, не на 2.49:1 aqua)
   ============================================================ */
.ms-link { color: var(--brand-ink); text-decoration: none; font-weight: 600; transition: color var(--transition-fast); }
.ms-link:hover { color: var(--brand-ink-hover); text-decoration: underline; }

/* ============================================================
   UTILITIES
   ============================================================ */
.ms-text-sm { font-size: var(--text-sm); }
.ms-text-xs { font-size: var(--text-xs); }
.ms-text-muted { color: var(--graphite-60); }
/* inline filter-селекты/инпуты: ширина по контенту, а не 100% (для фильтр-баров) */
.ms-input-auto { width: auto; }
.ms-mb-0 { margin-bottom: 0; }
.ms-mb-2 { margin-bottom: var(--space-2); }
.ms-mb-4 { margin-bottom: var(--space-4); }
.ms-mb-6 { margin-bottom: var(--space-6); }

/* Filter-bar — единый контейнер GET-фильтров (reviews/negative/doctors/analytics).
   Раньше дублировался inline на каждой странице (konfetka-зачистка). */
.ms-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  width: fit-content;         /* TASK_432 (§В): при 2 селектах рамка не тянется на всю ширину и не перевешивает данные */
  max-width: 100%;
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius-sm);
}

/* Узкая колонка для страниц-настроек/форм (был inline max-width:640). */
.ms-narrow { max-width: 640px; }

/* Status-banner биллинга (карточка статуса подписки; был inline max-width +
   border-left на каждой ветке).
   Баннер: фон-тинт + ведущая иконка вместо «цветной кромки» border-left
 * (анти-слоп R4 — телл «толстый бордюр с одной стороны»). Композится с .ms-card
 * (радиус/паддинг/тень оттуда); flex несёт icon-chip слева. Единственный
 * потребитель — billing/index.html. */
.ms-banner {
  max-width: 720px;
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  border: 1px solid var(--gray-border);
}
.ms-banner--brand   { background: var(--brand-primary-light); border-color: var(--brand-border); }
.ms-banner--danger  { background: var(--danger-light);        border-color: var(--alert-error-border); }
.ms-banner--success { background: var(--success-light);       border-color: var(--alert-success-border); }
.ms-banner--muted   { background: var(--gray-mid);            border-color: var(--gray-border); }

/* Очередь негатива — карточка тикета (был inline grid на каждой строке). */
.ms-neg-list { display: flex; flex-direction: column; gap: var(--space-3); }
.ms-neg-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius-sm);
}
.ms-neg-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
  font-size: 13px;
  color: var(--graphite-60);
}
.ms-neg-card__text { font-size: 14px; line-height: 1.5; margin-bottom: var(--space-3); }
.ms-neg-card__side { text-align: right; min-width: 200px; }
/* TASK_398: действия тикета — flex-группа (spacing через gap:--space-2, без инлайн margin) + звёзды рейтинга. */
.ms-neg-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: flex-end; }
.ms-neg-stars { color: var(--warning-ink); font-size: 14px; }
/* TASK_592: раскрывающиеся формы отработки (details/summary как кнопка, без триангла; CSP-safe). */
.ms-neg-disc > summary { list-style: none; cursor: pointer; display: inline-flex; }
.ms-neg-disc > summary::-webkit-details-marker { display: none; }
.ms-neg-resform { display: flex; flex-direction: column; gap: var(--space-2); align-items: stretch;
  margin-top: var(--space-2); padding: var(--space-3); background: var(--gray-mid);
  border-radius: var(--radius-sm); min-width: 220px; text-align: left; }
.ms-neg-resform__lbl { display: flex; flex-direction: column; gap: 4px; font-size: var(--text-xs);
  color: var(--graphite-60); font-weight: 600; }
.ms-neg-resform .ms-input { min-height: 44px; }
/* Содержание закрытой резолюции на карточке (когда/как/итог/причина). */
.ms-neg-reso { margin: var(--space-2) 0; font-size: var(--text-xs); color: var(--graphite-60);
  line-height: 1.5; text-align: right; }
/* TASK_595.2: SLA-бейдж очереди (было 4× inline-style) — базовый + модификаторы по срочности. */
/* Подпись под контактами пациента: «Без контакта» / «Контакт повреждён».
 * Заводится в TASK_603.3 вместо трёх одинаковых inline-стилей в том же блоке. */
.ms-neg-contact-note { font-size: 13px; color: var(--graphite-30); margin-bottom: 8px; }
.ms-neg-sla { font-size: 13px; margin-bottom: 8px; }
.ms-neg-sla--danger { color: var(--danger-ink); font-weight: 500; }
.ms-neg-sla--warn { color: var(--warning-ink); }
.ms-neg-sla--ok { color: var(--success-ink); }
/* Mobile (≤640px): двухколоночная карточка → одна колонка. Боковой блок (статус/SLA/
 * действия) разворачивается под текстом во всю ширину — иначе min-width:200px переполняет
 * вьюпорт на 390px (единственная кабинетная страница с overflow). */
@media (max-width: 640px) {
  .ms-neg-card { grid-template-columns: 1fr; }
  .ms-neg-card__side { min-width: 0; text-align: left; }
  .ms-neg-actions { justify-content: flex-start; }
}

/* ============================================================
   DESIGN KIT «konfetka» (2026-05-31) — переиспользуемые плитки.
   Подняты из одобренного POC дашборда: бренд-бордюр по периметру +
   лёгкий «волновой» градиент (рецепт лендинга .feature-item), icon-chip,
   hero-полоса, section-заголовок, list-tile. Цвета — через токены.
   ============================================================ */

/* --- ICON CHIP — тонированный квадрат с иконкой (KPI, алерты, действия) --- */
.ms-icon-chip {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  border-radius: var(--radius-sm);
  background: var(--_chip-bg, var(--brand-primary-light));
  color: var(--_chip-fg, var(--brand-ink));
}
.ms-icon-chip svg { width: 22px; height: 22px; }
.ms-icon-chip--round { border-radius: var(--radius-full); width: 40px; height: 40px; }
.ms-icon-chip--round svg { width: 20px; height: 20px; }
.ms-icon-chip--brand   { --_chip-bg: var(--brand-primary-light);   --_chip-fg: var(--brand-ink); }
.ms-icon-chip--navy    { --_chip-bg: var(--brand-secondary-light); --_chip-fg: var(--brand-secondary); }
.ms-icon-chip--amber   { --_chip-bg: var(--warning-light);         --_chip-fg: var(--warning-ink); }
.ms-icon-chip--danger  { --_chip-bg: var(--danger-light);          --_chip-fg: var(--danger-ink); }
.ms-icon-chip--success { --_chip-bg: var(--success-light);         --_chip-fg: var(--success-ink); }
.ms-icon-chip--muted   { --_chip-bg: var(--gray-mid);              --_chip-fg: var(--graphite-60); }

/* --- TILE — брендовая поверхность (бордюр + волновой градиент) --- */
.ms-tile {
  background: var(--surface-brand);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);   /* konfetka polish: --shadow-sm → --shadow (оторвать от фона) */
}
a.ms-tile, .ms-tile--link {
  display: block;
  text-decoration: none; color: inherit;
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
a.ms-tile:hover, .ms-tile--link:hover {
  box-shadow: var(--shadow-lg);   /* idle поднят до --shadow → hover на ступень выше */
  transform: translateY(-3px);
  border-color: var(--brand-border-strong);
}
/* TILE-ROW — горизонтальная компоновка: chip + тело + хвост (бейдж/стрелка) */
.ms-tile-row { display: flex; align-items: flex-start; gap: var(--space-4); padding: var(--space-5); }/* TASK_397: flex-start — иконка не плавает по центру у многострочных плиток (/help, /survey/setup) */
.ms-tile-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ms-tile-row__title { display: block; font-weight: 700; color: var(--graphite); text-wrap: balance; }
.ms-tile-row__sub { display: block; font-size: var(--text-sm); color: var(--graphite-60); }
.ms-tile-row__arrow { margin-left: auto; color: var(--graphite-30); transition: color var(--transition), transform var(--transition); }
a.ms-tile:hover .ms-tile-row__arrow,
.ms-tile--link:hover .ms-tile-row__arrow { color: var(--brand-ink); transform: translateX(3px); }
/* TILE как <button> (триггер поповера): сбросить дефолты кнопки до вида плитки. */
.ms-tile--button { font: inherit; text-align: left; width: 100%; cursor: pointer; }
/* Живое число в плитке (крупно, navy). */
.ms-tile-row__metric { font-weight: 800; color: var(--brand-secondary); font-variant-numeric: tabular-nums; }
/* «Подробнее» — affordance справа (плитка открывает поповер). */
.ms-tile-row__more { margin-left: auto; flex-shrink: 0; align-self: center; font-size: var(--text-xs); font-weight: 600; color: var(--brand-ink); white-space: nowrap; }
.ms-tile--link:hover .ms-tile-row__more { color: var(--brand-ink-hover); }
/* мета-строка карточки (напр. «4 мин · Категория» в разделе «Полезное») */
.ms-tile-row__meta { margin-top: var(--space-1); font-size: var(--text-xs); color: var(--graphite-60); }

/* --- KPI CARD — rich-вариант (icon-chip + брендовая поверхность).
   Базовый .ms-kpi-card НЕ трогаем (его использует reports/weekly.html). --- */
.ms-kpi-card--rich {
  display: flex; flex-direction: column;
  background: var(--surface-brand);
  border-color: var(--brand-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);   /* konfetka polish: поднять rich-KPI над фоном (база .ms-kpi-card НЕ трогается) */
  overflow: hidden;
}
.ms-kpi-card--rich .ms-icon-chip { margin-bottom: var(--space-4); }
.ms-kpi-card--rich .ms-kpi-card__value { font-size: var(--text-4xl); font-weight: 800; letter-spacing: -0.02em; margin-top: 2px; }
.ms-kpi-card--rich .ms-kpi-card__delta { font-weight: 700; }
.ms-kpi-card--rich.ms-kpi-card--link:hover {
  border-color: var(--brand-border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

/* --- GRID'ы плиток --- */
.ms-kpi-grid,
.ms-actions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  align-items: start;   /* TASK_397: плитки разной высоты выравниваются по верху, не растягиваются */
}

/* ── TASK_397 — Отзывы: верхний ряд = 2 KPI (число крупно) + 3 обучающие (тише). Scoped .w397-*; общий .ms-actions-grid не трогаем. ── */
.w397-group-label { margin: 0 0 var(--space-3); font-size: var(--text-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--graphite-60); }
.w397-kpi { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); margin-bottom: var(--space-6); }
.w397-kpi-tile { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-5); }
.w397-kpi-tile .ms-icon-chip { width: 48px; height: 48px; }
.w397-kpi-tile .ms-icon-chip svg { width: 24px; height: 24px; }
.w397-kpi-tile__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.w397-kpi-tile__label { font-size: var(--text-sm); font-weight: 600; color: var(--graphite); }
.w397-kpi-tile__value { font-size: var(--text-4xl); font-weight: 800; line-height: 1.05; letter-spacing: -0.02em; color: var(--brand-secondary); font-variant-numeric: tabular-nums; }
.w397-kpi-tile__unit { font-size: var(--text-xl); font-weight: 700; color: var(--brand-ink); margin-left: 2px; }
.w397-kpi-tile__sub { font-size: var(--text-sm); color: var(--graphite-60); }
.w397-kpi-tile__sub--warn { color: var(--warning-ink); font-weight: 600; }
.w397-guides { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.w397-guide { background: var(--white); border-color: var(--gray-border); box-shadow: var(--shadow-sm); padding: var(--space-4); gap: var(--space-3); align-items: center; }
.w397-guide:hover { box-shadow: var(--shadow); border-color: var(--brand-border-strong); }
.w397-guide .ms-icon-chip { width: 34px; height: 34px; }
.w397-guide .ms-icon-chip svg { width: 18px; height: 18px; }
.w397-guide .ms-tile-row__title { font-size: var(--text-sm); font-weight: 600; }
.w397-guide .ms-tile-row__sub { font-size: var(--text-xs); }
.w397-guide .ms-tile-row__more { color: var(--graphite-60); font-weight: 500; }
.w397-guide:hover .ms-tile-row__more { color: var(--brand-ink); }
@media (max-width: 900px) { .w397-kpi, .w397-guides { grid-template-columns: 1fr; } }
.ms-kpi-grid { margin-bottom: var(--space-8); }

/* --- STACK — вертикальный список плиток --- */
.ms-stack { display: flex; flex-direction: column; gap: var(--space-3); }

/* --- TABS — переключатель (напр. филиалы на /competitors) --- */
.ms-tabs {
  display: flex; flex-wrap: wrap; gap: var(--space-1);
  border-bottom: 1px solid var(--gray-border);
  margin-bottom: var(--space-6);
}
.ms-tab {
  display: inline-flex; align-items: center;
  padding: 9px 16px; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent;
  background: none; cursor: pointer;
  font-family: inherit; font-size: var(--text-sm); font-weight: 600;
  color: var(--graphite-60); text-decoration: none;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}
.ms-tab:hover { color: var(--brand-ink); }
.ms-tab--active { color: var(--brand-ink); border-bottom-color: var(--brand-ink); }

/* --- FOLDER TABS (.ms-ftabs) — папки-разделители для под-навигации раздела
   (Настройки: Профиль/Реквизиты/Площадки/Конкуренты; Сравнения: Врачи/Филиалы).
   В отличие от .ms-tabs (плоский фильтр, напр. филиалы на /competitors), активная
   вкладка вливается в панель, аква-контур огибает весь блок. Утверждён на
   mockup_settings_tabs.html (2026-06-01). Базовый вид = «заливка неактивных». --- */
.ms-ftabs { margin-bottom: var(--space-6); }
.ms-ftabs__bar {
  display: flex; gap: var(--space-1);
  position: relative; z-index: 2;
  padding: 0 0 0 var(--radius);   /* отступ слева = радиус: верхний-левый угол панели всегда открыт/скруглён */
  margin: 0;
  overflow-x: auto;               /* TASK_314: 8 табов на шкале 17px не влезают <1280 → горизонт. скролл вместо page-overflow */
  scrollbar-width: none;
}
.ms-ftabs__bar::-webkit-scrollbar { display: none; }
.ms-ftabs__bar .ms-ftab { margin-bottom: 0; }   /* в скролл-баре нет верт. overflow для клипа — шов держит панель ниже (margin-top:-1px) */
.ms-ftab {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 10px 18px;
  margin-bottom: -1px;                            /* перекрыть верхнюю границу панели */
  border: 1px solid var(--gray-border);
  border-bottom-color: var(--brand-primary);      /* низ = аква-линия контура (под неактивными табами) */
  border-radius: 3px 3px 0 0;                     /* верхние углы таба острые (3px, бренд) */
  background: var(--gray-mid);
  color: var(--graphite-60);
  font-family: inherit; font-size: var(--text-sm); font-weight: 600; line-height: 1.2;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color 160ms var(--ease-tab), color 160ms var(--ease-tab), border-color 160ms var(--ease-tab);
}
.ms-ftab:hover { background: var(--white); color: var(--brand-ink); }
.ms-ftab--active,
.ms-ftab--active:hover {
  background: var(--white);
  color: var(--brand-ink); font-weight: 600;      /* R5 — тише активный: отличие несут цвет+заливка+рамка, не вес */
  border-color: var(--brand-primary);             /* аква-рамка слева/сверху/справа */
  border-bottom-color: var(--white);              /* низ открыт: вливается в панель */
  cursor: default;
}
/* «Скоро» — непостроенная вкладка Settings 2.0: неактивный <span> (не ссылка),
   без href → не даёт 404 и не фокусируется. Таск, реализовав свой роут,
   переключит вкладку на обычную ссылку (built:true в макросе settings_tabs). */
.ms-ftab--soon {
  cursor: default; opacity: .55; pointer-events: none;
  background: var(--gray-mid); color: var(--graphite-60);
}
.ms-ftab__soon {
  margin-left: var(--space-1); padding: 0 6px; border-radius: var(--radius-sm);
  background: var(--gray-border); color: var(--graphite-60);
  font-size: 10px; font-weight: 700; line-height: 16px;
  text-transform: uppercase; letter-spacing: .04em;
}
/* Счётчик на табе (Новые [3]) — бейдж; задел под статус-табы негатива (Ф3). */
.ms-ftab__count {
  margin-left: var(--space-1); display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 18px; padding: 0 6px; border-radius: var(--radius-sm);
  background: var(--gray-border); color: var(--graphite-60);
  font-size: 11px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
}
.ms-ftab--active .ms-ftab__count { background: var(--brand-primary-light); color: var(--brand-ink); }
.ms-ftab__count--urgent { background: var(--danger-light); color: var(--danger-ink); }
/* urgent сохраняет красный даже на активном табе (иначе active-тинт перебивает по
   специфичности — а «Новые [n]» по умолчанию активный, и сигнал срочности терялся бы). */
.ms-ftab--active .ms-ftab__count--urgent { background: var(--danger-light); color: var(--danger-ink); }
.ms-ftabs__panel {
  position: relative; z-index: 1;
  margin-top: -1px;                               /* TASK_314: панель заходит на 1px под ряд табов — шов держится без margin-bottom табов (нужно для overflow-x скролла) */
  background: var(--white);
  border: 1px solid var(--brand-primary);         /* аква-контур всего блока */
  border-radius: var(--radius-md);                /* R2 — внешний контейнер крупнее табов (10) */
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
@media (max-width: 640px) {
  .ms-ftabs__bar { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; margin-bottom: 0; }
  .ms-ftabs__bar::-webkit-scrollbar { display: none; }
  .ms-ftab { margin-bottom: 0; }
}
/* .ms-doctabs (TASK_417) — переключатель раздела «Полезное» БЕЗ панели: нижняя
   аква-линия заменяет панель, активный таб «врезается» белым низом в линию. */
.ms-doctabs { border-bottom: 1px solid var(--brand-primary); }
.ms-doctabs .ms-ftabs__bar { margin-bottom: 0; }
/* Подсекция внутри .ms-ftabs__panel (напр. блок филиала) — лёгкий разделитель
   вместо вложенной карточки. */
.ms-panel-section + .ms-panel-section { margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--gray-border); }
.ms-panel-section__title { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4); font-size: var(--text-base); font-weight: 700; color: var(--brand-secondary); }
/* Внутри панели вкладок таблица — «плоская»: рамку/тень даёт сама панель
   (иначе card-in-card). overflow-x для мобилы сохраняется. */
.ms-ftabs__panel .ms-table-wrap { border: 0; box-shadow: none; border-radius: 0; }
/* TASK_428 (А5): плющим рамки-в-рамках внутри панели табов — вложенная панель, карточка «Этапы»
   (.ms-survey-agg) плоские; тикеты негатива (.ms-neg-card) → плоские с border-bottom-разделителем. */
.ms-ftabs__panel .ms-ftabs__panel,
.ms-ftabs__panel .ms-survey-agg { border: 0; box-shadow: none; padding: 0; }
.ms-ftabs__panel .ms-neg-card { border: 0; border-radius: 0; box-shadow: none; }
.ms-ftabs__panel .ms-neg-card:not(:last-child) { border-bottom: 1px solid var(--gray-border); }

/* --- TASK_379.4: вкладка «Счета и акты» (/billing) — суб-строки, шапка УПД,
   disabled-плейсхолдер, числовые ячейки. На токенах; каркас .ms-ftabs выше не трогаем. --- */
/* TASK_383.3: нейтральный pending-бейдж (оранжевый убран). Scoped-класс, глобальный
   .ms-badge-warning (competitors/admin) НЕ трогаем — только billing переходит на pending. */
.ms-badge-pending { background: var(--gray-mid); color: var(--graphite); border: 1px solid var(--gray-border); }
.fin-sub { display: block; margin-top: 2px; font-size: 11px; color: var(--graphite); font-weight: 400; white-space: nowrap; }
.fin-docnum { display: block; margin-top: 4px; font-family: var(--font-mono); font-size: 11px; color: var(--graphite); white-space: nowrap; }
/* «ещё не готово» — приглушённый disabled-аффорданс, чтобы живые PDF-ссылки доминировали */
.fin-doc__wait { color: var(--graphite-30); font-size: var(--text-xs); margin-right: 6px; }
.fin-th-sub { display: block; font-weight: 400; font-size: 11px; color: var(--graphite); text-transform: none; letter-spacing: 0; margin-top: 1px; }
/* числовые ячейки: правое выравнивание + tabular-nums из одного места (перебивает .ms-table td) */
.ms-ftabs__panel .ms-table .fin-cell--num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .ms-table--cards td.fin-cell--num { text-align: left; } }

/* --- TASK_379.5: панель «Подписка» — список филиалов + докупка из биллинга.
   На токенах; переиспользует .ms-panel-section (шапка/разделитель) и .ms-badge-*. --- */
.fin-note { margin: var(--space-3) 0 0; font-size: var(--text-sm); color: var(--graphite-60); }
.fin-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-4); padding: var(--space-4) 0; border-top: 1px solid var(--gray-border); }
.fin-row:first-of-type { border-top: 0; }
.fin-row__name { display: flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--graphite); }
.fin-row__addr { margin-top: 2px; font-size: var(--text-sm); color: var(--graphite-60); }
/* «Главный» — тихая метка, не яркая плашка */
.fin-tag { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; color: var(--graphite-60); border: 1px solid var(--gray-border); border-radius: 2px; padding: 1px 7px; }
/* статус филиала — тихая точка + подпись */
.fin-status { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; font-size: var(--text-sm); color: var(--graphite-60); }
.fin-status__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gray-border); }
.fin-status--on .fin-status__dot { background: var(--success); }
/* «+ Добавить филиал» — свёрнуто по умолчанию */
.fin-add { margin-top: var(--space-4); }
/* TASK_626.5b: правило было близнецом .act__btn — по специфичности (0,1,1) перебивало
   ms-btn-sm и держало min-height 36px + кегль 15px, т.е. шестой размер вне шкалы (замер:
   36px там, где все соседи 32px). Единственный потребитель — <summary class="ms-btn
   ms-btn-add ms-btn-sm"> в billing/index.html, он получает геометрию, вес и цвет от канона.
   Остаётся только то, чего канон для <summary> не даёт, — снятие маркера-треугольника.
   .fin-promo-inline ниже НЕ трогаем: там голый <summary> без ms-btn, правило ему нужно. */
.fin-add > summary { list-style: none; }
.fin-add > summary::-webkit-details-marker { display: none; }
.fin-add__panel { margin-top: var(--space-3); max-width: 560px; }
.fin-add__lbl { display: block; margin: var(--space-3) 0 var(--space-1); font-size: var(--text-xs); color: var(--graphite-60); }
.fin-add__row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.fin-add__num { width: 96px; box-sizing: border-box; padding: 9px 12px; font: inherit; color: var(--graphite); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); }

/* TASK_381.5: тихая ссылка «У меня есть промокод» в оплате — quiet <details> (паттерн .fin-add). */
.fin-promo-inline { margin-top: var(--space-4); }
.fin-promo-inline > summary { display: inline-flex; align-items: center; min-height: 36px; list-style: none; cursor: pointer; font-size: var(--text-sm); font-weight: 600; color: var(--brand-ink); }
.fin-promo-inline > summary::-webkit-details-marker { display: none; }
.fin-promo-inline .fin-promo-row { display: flex; gap: var(--space-2); align-items: center; margin-top: var(--space-3); }
.fin-promo-input { width: 160px; padding: 8px 10px; font: inherit; letter-spacing: 1.5px; text-transform: uppercase; border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); font-variant-numeric: tabular-nums; }
.fin-promo-inline .fin-promo-note { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--graphite-60); }
.fin-promo-inline .fin-promo-note--error { color: var(--danger); }

/* --- TASK_383.1: билд UI billing_top — шапка/чип статуса + этаж «01 Подписка» (вариант A).
   Порт из мокапа app/static/mockups/billing_top_focus.html; на токенах (белый → var(--white)).
   Канон .ms-ftabs (664+) и .fin-* 379.4/5 НЕ трогаем. .fin-promo (бонус) — в 383.5. --- */

/* шапка страницы: заголовок слева + чип статуса справа (билинг-скоуп, .ms-page-header глобален) */
.fin-pagehead { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }

/* чип статуса в строке заголовка (заменил статус-баннеры) */
.fin-active { display: inline-flex; align-items: center; gap: var(--space-2); background: var(--success-light); color: var(--success-ink); border: 1px solid var(--success); border-radius: 3px; padding: 8px 14px; font-size: var(--text-sm); font-weight: 600; white-space: nowrap; }
.fin-active svg { flex: none; }
/* нейтральный вариант — для не-оплаченных состояний (зелёный только «paid») */
.fin-active--muted { background: var(--gray-mid); color: var(--graphite); border-color: var(--gray-border); }
/* TASK_383.6: trial-чип — тот же .fin-active, но бренд-тон (подписка ещё не оплачена, не зелёный) */
.fin-trial { background: var(--brand-primary-light); color: var(--brand-ink); border-color: var(--brand-border); }
/* TASK_558: near-expiry «оплачено до» — жёлтый (≤30д) и красный (≤14д) */
.fin-active--warn { background: var(--warning-light); color: var(--warning-ink); border-color: var(--warning); }
.fin-active--danger { background: var(--danger-light); color: var(--danger-ink); border-color: var(--danger); }
@media (max-width: 620px) { .fin-active { white-space: normal; } }

/* табличные цифры — выравнивание денег */
.fin-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* эйбрау-заголовок этажа: «01 ПОДПИСКА» + тихая приписка справа (тариф) */
.fin-eyebrow { display: flex; align-items: center; gap: var(--space-3); font-family: var(--font-sans); font-size: 16px; font-weight: 700; letter-spacing: 0.2px; text-transform: uppercase; color: var(--graphite); margin: 0 0 var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--gray-border); }
.fin-eyebrow__note { margin-left: auto; font-family: var(--font-sans); letter-spacing: normal; text-transform: none; font-weight: 400; font-size: var(--text-sm); color: var(--graphite-60); }
.fin-eyebrow__note b { font-weight: 600; color: var(--graphite); font-variant-numeric: tabular-nums; }
/* выраженный 2px-разделитель + воздух между этажами панели «Подписка» */
.ms-ftabs__panel .ms-panel-section + .ms-panel-section { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 2px solid var(--gray-border); }

/* этаж 01: крупный итог слева, годовой оффер справа */
.fin-summary { display: grid; grid-template-columns: auto 1fr; gap: var(--space-8); align-items: start; }
@media (max-width: 560px) { .fin-summary { grid-template-columns: 1fr; gap: var(--space-5); } }
.fin-total__label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.6px; color: var(--graphite); }
.fin-total__amount { display: flex; align-items: baseline; gap: 6px; margin-top: var(--space-2); line-height: 1; }
.fin-total__amount b { font-size: 40px; font-weight: 700; color: var(--graphite); letter-spacing: -1px; white-space: nowrap; }
.fin-total__amount span { font-size: var(--text-base); color: var(--graphite-60); }
.fin-total__sub { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--graphite-60); }
.fin-total__sub .fin-num { color: var(--graphite); font-weight: 600; }
/* годовой оффер (правая колонка) — вертикальный стек: экономия + CTA «Перейти на год» */
.fin-meta { border-left: 1px solid var(--gray-border); padding-left: var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); justify-content: center; font-size: var(--text-sm); color: var(--graphite); }
.fin-meta b { color: var(--graphite); font-weight: 600; }
.fin-meta a { align-self: flex-start; }
@media (max-width: 560px) { .fin-meta { border-left: 0; padding-left: 0; border-top: 1px solid var(--gray-border); padding-top: var(--space-5); } }

/* переключатель периода помесячно ⇄ за год (JS billing_period.js свопит data-m/data-y) */
.fin-seg { display: inline-flex; margin-top: var(--space-4); gap: 3px; padding: 3px; background: var(--gray-mid); border: 1px solid var(--gray-border); border-radius: 3px; }
.fin-seg__opt { border: 0; background: none; font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--graphite-60); padding: 6px 12px; cursor: pointer; border-radius: 2px; display: inline-flex; align-items: center; gap: 8px; }
.fin-seg__opt--on { background: var(--white); color: var(--graphite); box-shadow: var(--shadow-sm); }
/* TASK_590.2: сегмент-переключатель периода на тач ≥44px. */
@media (pointer: coarse) { .fin-seg__opt { min-height: 44px; } }
/* строка «сегмент + подсказка» под суммой */
.fin-segline { display: flex; align-items: center; gap: 8px; }
/* TASK_383.5: промо «+2 месяца» на годовой активации — тег на опции «За год» (.fin-promo__tag).
   Показ гейтит bonus_available (зеркало сервера) в шаблоне. Контейнер-строка .fin-promo удалена в 383.6. */
.fin-promo__tag { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 700; color: var(--brand-ink); background: var(--brand-primary-light); border: 1px solid var(--brand-border); border-radius: 2px; padding: 2px 7px; white-space: nowrap; }
/* TASK_557 (§12.2): крупный бейдж скидки «−28%» на опции «За год» — заметнее, чем мелкий %
   в .fin-meta. Сплошной brand-ink (контраст-safe под белый текст) вместо light-тега +2 мес →
   считывается сразу. Острый радиус 2px (язык проекта, не пилюля). Отдельный от .fin-promo__tag. */
.fin-seg__badge { font-size: 14px; font-weight: 700; line-height: 1; color: var(--white); background: var(--brand-ink); border-radius: 2px; padding: 3px 7px; white-space: nowrap; letter-spacing: 0.2px; }
/* TASK_383.6: герой активации подписки (trial/expired) — единственный focus экрана, один primary CTA */
.act { padding: var(--space-5) var(--space-6); border: 1px solid var(--gray-border); border-left: 3px solid var(--brand-ink); border-radius: 3px; background: var(--white); }
.act__left { max-width: 640px; }
.act__what { font-size: 16px; font-weight: 700; color: var(--graphite); }
.act__sub { margin-top: 4px; font-size: var(--text-sm); color: var(--graphite); }
.act__form { margin-top: var(--space-4); }
.act__form .fin-seg { margin-top: 0; }
.act__hint { margin: var(--space-3) 0 var(--space-4); font-size: var(--text-sm); color: var(--graphite); }
.act__hint b { font-weight: 600; color: var(--graphite); }
/* TASK_626.5: .act__btn удалён — навешивался ПОВЕРХ ms-btn-primary и переопределял
   канонические 9px/16px на 12px/22px, давая пятый размер вне шкалы: две одинаковые
   кнопки «Запросить счёт» на /billing отличались боковыми полями. Нужен крупный CTA —
   есть штатный ms-btn-lg. */
.act__legal { margin-top: var(--space-3); }
/* TASK_420: степпер числа филиалов при активации */
.act__branches { margin-top: var(--space-4); }
.act__branches-label { display: block; font-size: var(--text-sm); color: var(--graphite); font-weight: 600; margin-bottom: 8px; }
.act__stepper { display: inline-flex; align-items: center; border: 1px solid var(--gray-border); border-radius: 3px; overflow: hidden; vertical-align: middle; }
.act__step { width: 40px; height: 40px; border: 0; background: var(--white); font-size: 20px; line-height: 1; cursor: pointer; color: var(--brand-ink); }
.act__step:hover:not(:disabled) { background: var(--gray-mid); }
.act__step:disabled { color: var(--graphite-30); cursor: default; }
.act__count { width: 56px; height: 40px; text-align: center; border: 0; border-left: 1px solid var(--gray-border); border-right: 1px solid var(--gray-border); font: inherit; font-weight: 700; font-size: 16px; color: var(--graphite); -moz-appearance: textfield; }
.act__count::-webkit-outer-spin-button, .act__count::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.act__branches-note { margin-top: 8px; font-size: var(--text-sm); color: var(--graphite-60); max-width: 560px; }
.act__branches-note b { color: var(--graphite); font-weight: 700; }
.act__total { margin: var(--space-3) 0 0; font-size: 15px; color: var(--graphite); }
.act__total b { font-weight: 800; }
/* сегмент-переключатель как нативные radio (значение формы) — состояние через :has(:checked), без JS */
.fin-seg__opt input[type="radio"] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.fin-seg__opt:has(input[type="radio"]:checked) { background: var(--white); color: var(--graphite); box-shadow: var(--shadow-sm); }
.fin-seg:has(input[type="radio"]) .fin-seg__opt { cursor: pointer; }
.fin-seg__opt:focus-within { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
/* автопродление: форма «Отключить» встык к тексту (без inline style в шаблоне) */
.fin-note form { display: inline; margin-left: var(--space-2); }

/* «?»-подсказка — CSS-only тултип (без JS, под CSP; /billing не .cdash) */
.hint { -webkit-appearance: none; appearance: none; position: relative; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0; border-radius: 50%; border: 1px solid var(--gray-border); background: var(--white); color: var(--graphite); font: 700 11px/1 var(--font-sans); cursor: help; vertical-align: middle; margin-left: 5px; }
.hint:hover, .hint:focus-visible { border-color: var(--brand-primary); color: var(--brand-ink); outline: none; }
.hint::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 9px); transform: translateX(-50%); width: max-content; max-width: 260px; background: var(--graphite); color: var(--white); font: 400 12px/1.45 var(--font-sans); text-align: left; padding: 8px 11px; border-radius: 3px; white-space: normal; opacity: 0; visibility: hidden; transition: opacity 120ms ease; z-index: 30; pointer-events: none; }
.hint::before { content: ''; position: absolute; left: 50%; bottom: calc(100% + 4px); transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--graphite); opacity: 0; visibility: hidden; transition: opacity 120ms ease; }
.hint:hover::after, .hint:hover::before, .hint:focus-visible::after, .hint:focus-visible::before { opacity: 1; visibility: visible; }
/* TASK_590.1: тап-раскрытие на тач (hint.js тогглит .is-open) — реюз бабла/стрелки, без нового стиля. */
.hint[data-tip].is-open::after, .hint[data-tip].is-open::before { opacity: 1; visibility: visible; }
/* вариант для «?» у правого края — тултип открывается влево, не улетает за экран */
.hint--left::after { left: auto; right: -2px; transform: none; }
.hint--left::before { left: auto; right: 4px; transform: none; }
/* TASK_403: «?» у заголовка раздела — чуть крупнее (рядом с h1) и тултип раскрывается ВНИЗ
   (заголовок у верха контента — вверх клипалось бы за край вьюпорта). */
.hint--section { width: 18px; height: 18px; font-size: 12px; margin-left: var(--space-2); vertical-align: 0.12em; }
.hint--section::after { bottom: auto; top: calc(100% + 9px); }
.hint--section::before { bottom: auto; top: calc(100% + 4px); border-top-color: transparent; border-bottom-color: var(--graphite); }
/* Визуально-скрытый текст для скринридеров (aria-describedby у help-точки) */
.ms-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* --- TASK_383.2: платёжный центр «02 К оплате» (.pc) — открытые счета строками +
   итоговая «Оплатить всё». Порт из billing_top_focus.html; токены, белый → var(--white). --- */
.pc { border: 0; border-left: 3px solid var(--brand-ink); border-radius: 3px; background: var(--white); }/* TASK_428 (А5): полный border убран, остался left-акцент. TASK_432 (§В): --graphite→--brand-ink, унифицирован с .act */
.pc-row { display: grid; grid-template-columns: 150px 1fr auto auto; gap: var(--space-3) var(--space-5); align-items: center; padding: var(--space-4) var(--space-5); }
.pc-row + .pc-row { border-top: 1px solid var(--gray-border); }
.pc-row__type { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; line-height: 1.3; }
.pc-row__type--new { color: var(--graphite); }
.pc-row__type--renew { color: var(--graphite-60); }
.pc-row__what { font-size: var(--text-sm); color: var(--graphite); font-weight: 600; }
.pc-row__meta { margin-top: 2px; font-size: var(--text-xs); color: var(--graphite-60); }
.pc-row__sum { font-size: var(--text-base); font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; text-align: right; }
.pc-row__act { display: flex; gap: var(--space-2); align-items: center; }
.pc-total { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; padding: var(--space-4) var(--space-5); border-top: 2px solid var(--graphite); background: var(--gray-mid); border-radius: 0 0 3px 3px; }
.pc-total__label { font-size: var(--text-sm); color: var(--graphite-60); }
.pc-total__sum { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.4px; }
.pc-total__act { margin-left: auto; display: flex; gap: var(--space-3); align-items: center; }
.pc-foot { padding: var(--space-3) var(--space-5); border-top: 1px solid var(--gray-border); }
.pc-foot__note { margin: 0; }
/* Стек при узкой КОНТЕНТ-области (не вьюпорте): сайдбар кабинета съедает ~350px,
   4-колоночный грид .pc-row не влезает уже при ~980px вьюпорта → строки-действия
   уезжают за панель. Порог 980 (не 760 мокапа) держит зону 760–980 без overflow. */
@media (max-width: 980px) {
  .pc-row { grid-template-columns: 1fr auto; }
  .pc-row__type { grid-column: 1 / -1; }
  .pc-row__act { grid-column: 1 / -1; justify-content: flex-end; }
  .pc-total__act { margin-left: 0; width: 100%; }
}

/* --- BRANCH FOLDER TABS (.ms-branch-tabs) — двухрядный «стек» филиалов как бар
   .ms-ftabs (ось филиала на /reviews). Раскладку рядов (передний/задний) проставляет
   JS (front/back) по data-branch-tabs, мерит offsetTop. Без JS — обычные folder-табы
   в один/несколько рядов (рабочая деградация). Утверждён на mockup_reviews_tabs_variants (0+). --- */
.ms-branch-tabs {
  display: flex; flex-wrap: wrap; gap: 0; row-gap: 4px;
  position: relative; z-index: 2;
  padding: 0 0 0 var(--radius);
  margin: 0;
}
.ms-branch-tabs .ms-ftab + .ms-ftab { margin-left: -1px; }   /* наезд: единая линия границ соседей */
/* Задний ряд — приглушён, позади; видимый размер = передний (низ = 10 + 9px наезда, 9px скрыты). */
.ms-branch-tabs .ms-ftab.is-back-row {
  z-index: 1;
  padding: 10px 18px 19px;
  background: var(--gray-border); color: var(--graphite-60);
  border-color: var(--gray-border); border-bottom-color: var(--gray-border);
}
.ms-branch-tabs .ms-ftab.is-back-row:hover { background: var(--gray-mid); color: var(--brand-ink); }
.ms-branch-tabs .ms-ftab.is-back-row.ms-ftab--active {   /* единая белая заливка активного в любом ряду */
  background: var(--white); color: var(--brand-ink); border-color: var(--brand-primary);
}
/* Передний ряд — врезается в панель, наезжает на задний сверху. */
.ms-branch-tabs .ms-ftab.is-front-row {
  position: relative; z-index: 2; margin-top: -9px;
  box-shadow: 0 -4px 8px -5px rgba(2, 63, 136, 0.16);
}

/* --- STACK TABS (.ms-stack-tabs) — двухрядный «стек» категорий раздела «Полезное».
   В отличие от .ms-branch-tabs: категории СТАТИЧНЫ → ряды задаются разметкой (макрос
   stack_tabs режет items пополам), без JS/offsetTop. Задний ряд уже, передний шире и
   врезается в панель .ms-ftabs__panel. Утверждён на polezno_full.html (вариант A +
   подъём текста). Нахлёст 18px: back padding-bottom 27 компенсирует front margin-top −18. --- */
.ms-stack-tabs { display: flex; flex-direction: column; position: relative; z-index: 2; padding-left: var(--radius); margin: 0; }
.ms-stack-tabs__row { display: flex; gap: 0; position: relative; flex-wrap: wrap; }
.ms-stack-tabs__row--back { z-index: 1; }
.ms-stack-tabs__row--front { z-index: 2; margin-top: -18px; box-shadow: 0 -3px 7px -5px rgba(2, 63, 136, 0.16); }
.ms-stab {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 12px 22px; margin-bottom: -1px;
  border: 1px solid var(--gray-border); border-bottom-color: var(--brand-primary);
  border-radius: 3px 3px 0 0; background: var(--gray-mid); color: var(--graphite);
  font-family: inherit; font-size: var(--text-base); font-weight: 600; line-height: 1.2;
  white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background-color 160ms var(--ease-tab), color 160ms var(--ease-tab), border-color 160ms var(--ease-tab);
}
.ms-stab + .ms-stab { margin-left: -1px; }
.ms-stack-tabs__row--back .ms-stab { padding-top: 7px; padding-bottom: 27px; }   /* текст приподнят над швом, высота таба та же */
.ms-stab:hover { background: var(--white); color: var(--brand-ink); }
.ms-stab--active { background: var(--white); color: var(--brand-secondary); border-color: var(--brand-primary); cursor: default; }
.ms-stack-tabs__row--front .ms-stab--active { border-bottom-color: var(--white); }
.ms-stab__count {
  margin-left: var(--space-1); display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 20px; padding: 0 7px; border-radius: var(--radius-sm);
  background: var(--gray-border); color: var(--graphite-text);
  font-size: 12px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
}
.ms-stab--active .ms-stab__count { background: var(--brand-primary-light); color: var(--brand-ink); }
/* --- Вкладки Настроек в стеке (.ms-stack-tabs--set, TASK_627 Б4/Р8). Внутри — .ms-ftab,
   а не .ms-stab: на этом классе висят замки тестов бара и плейсхолдер «Скоро».
   Три состояния, пороги замерены на живых Настройках (10 вкладок, ширина бара = ширина
   .ms-content, а она у`же вьюпорта на ~304px из-за бокового меню):
     ≥1120px  полный вид стека: кегль .ms-stab, нахлёст 18px. Ряды 681px и 765px
              против 816px бара — каждый в ОДНУ строку;
     1000…1119 тот же стек, но вкладки в каноническом кегле 15px: ряды 571px и 646px
              против 696px бара на 1000;
     641…999  НАХЛЁСТА НЕТ: ряды становятся обычными folder-табами в несколько строк
              (рабочая деградация, как у .ms-branch-tabs без JS). Причина — шов:
              margin-top −18px поднимает ряд ЦЕЛИКОМ, поэтому у завёрнутого ряда
              в панель врезается только последняя строка, а остальные вкладки висят
              выше со своей аква-линией низа. Замерено на 900px: низы переднего ряда
              [188, 235] против верха панели 233 — четыре вкладки в 45px от панели.
              Ровно тот разрыв, из-за которого у «Полезного» сделан схлоп на ≤1240px;
     ≤640px   канон проекта на мобиле: один горизонтально-скроллируемый ряд, как
              .ms-ftabs__bar. Свайпом на тач-экране вкладки достаются; мышью на
              десктопе — нет, ровно поэтому Б4 лечится именно от 641px.
   ⚠️ Инвариант при любой правке вкладок (проверять замером, тестами не ловится):
   у каждого ряда РОВНО одна строка, и низы вкладок переднего ряда совпадают с верхом
   панели. Обрезка и docOverflow этого не показывают — оба нулевые и в сломанном виде. --- */
.ms-stack-tabs--set { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.ms-stack-tabs--set::-webkit-scrollbar { display: none; }
.ms-stack-tabs--set .ms-stack-tabs__row { display: contents; }
.ms-stack-tabs--set .ms-ftab { margin-bottom: 0; }   /* в скролл-ряду нет верт. overflow для клипа — шов держит панель (margin-top:-1px) */
.ms-stack-tabs--set .ms-ftab + .ms-ftab { margin-left: -1px; }   /* наезд: единая линия границ соседей */
@media (min-width: 641px) {
  .ms-stack-tabs--set { flex-direction: column; overflow-x: visible; }
  .ms-stack-tabs--set .ms-stack-tabs__row { display: flex; row-gap: 4px; }   /* если ряд завернулся — строки не слипаются */
  .ms-stack-tabs--set .ms-ftab { padding: 12px 18px; margin-bottom: -1px; }
  /* Нахлёста нет до 1000px — см. шапку секции. Тень заднего ряда без нахлёста тоже
     не нужна: она рисует линию над рядом, к которому ничего не примыкает. */
  .ms-stack-tabs--set .ms-stack-tabs__row--front { margin-top: 0; box-shadow: none; }
  /* Активная вкладка всегда белая с аква-рамкой — в любом ряду и в любой строке (Р8.1).
     Низ здесь ЗАКРЫТ (аква): в многострочной деградации ряд не примыкает к панели, и белый
     низ читался бы как дырка в рамке вкладки, повисшей в воздухе. Открывается ниже, от 1000px. */
  .ms-stack-tabs--set .ms-ftab--active { background: var(--white); color: var(--brand-ink); border-color: var(--brand-primary); }
}
/* Стык рядов в скролл-режиме (≤640): ряды там display:contents, поэтому селектор
   `.ms-ftab + .ms-ftab` не спаривает последнюю вкладку заднего ряда с первой вкладкой
   переднего — они не соседи по дереву элементов. На этом одном стыке рамки удваивались
   до 2px (замер: зазор 0 вместо −1). Наезд задаём адресно. */
@media (max-width: 640px) {
  .ms-stack-tabs--set .ms-stack-tabs__row--front .ms-ftab:first-child { margin-left: -1px; }
}
@media (min-width: 1000px) {
  /* Ряды влезают каждый в одну строку → включаем полноценный стек: нахлёст и приглушённый
     задний ряд. Приглушение живёт ЗДЕСЬ, а не выше: в многострочной деградации оба ряда
     равноправны, и красить верхний серым значило бы врать про глубину. */
  .ms-stack-tabs--set .ms-stack-tabs__row--front { margin-top: -18px; }
  .ms-stack-tabs--set .ms-stack-tabs__row--back .ms-ftab {
    padding-top: 7px; padding-bottom: 27px;   /* текст приподнят над швом, высота таба та же */
    background: var(--gray-border); color: var(--graphite-60);
    border-color: var(--gray-border); border-bottom-color: var(--gray-border);
  }
  .ms-stack-tabs--set .ms-stack-tabs__row--back .ms-ftab:hover { background: var(--gray-mid); color: var(--brand-ink); }
  /* Р8.1: активная в заднем ряду не должна приглушаться заливкой ряда (специфичность
     (0,3,0) против (0,2,0) выше — поэтому правило повторяется здесь). Низ у неё закрыт
     аква: задний ряд с панелью не смыкается, его нижние 18px и так под передним рядом. */
  .ms-stack-tabs--set .ms-stack-tabs__row--back .ms-ftab--active {
    background: var(--white); color: var(--brand-ink); border-color: var(--brand-primary);
  }
  /* А вот активная в ПЕРЕДНЕМ ряду обязана вливаться в панель белым низом — это весь приём
     folder-tabs, у «Полезного» есть парное правило (.ms-stack-tabs__row--front .ms-stab--active).
     Правило `.ms-stack-tabs--set .ms-ftab--active` выше закрывало низ шорткатом border-color,
     и активная вкладка выглядела закрытой коробкой, поставленной на линию панели.
     Открываем ровно здесь: от 1000px ряд гарантированно в одну строку и примыкает к панели. */
  .ms-stack-tabs--set .ms-stack-tabs__row--front .ms-ftab--active { border-bottom-color: var(--white); }
}
@media (min-width: 1120px) {
  .ms-stack-tabs--set .ms-ftab { padding-left: 22px; padding-right: 22px; font-size: var(--text-base); }
}
/* Узкий/средний экран (≤1240px): передний ряд из 5 RU-вкладок не влезает и заворачивается
   (flex-wrap ломает шов) → схлоп в один горизонтально-скроллируемый ряд (канон .ms-ftabs).
   Порог 1240 подтверждён live-смоуком: ≥1241 два ряда чистые, ≤1180 передний ряд рвётся.
   Настройки (--set) из схлопа ИСКЛЮЧЕНЫ до своего порога ниже: их ряды из .ms-ftab
   короче, а схлоп в скролл со спрятанным скроллбаром — это ровно баг Б4, который тут
   и лечится. Свой порог у Настроек ниже, он замерен отдельно. */
@media (max-width: 1240px) {
  .ms-stack-tabs:not(.ms-stack-tabs--set) { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .ms-stack-tabs:not(.ms-stack-tabs--set)::-webkit-scrollbar { display: none; }
  .ms-stack-tabs:not(.ms-stack-tabs--set) .ms-stack-tabs__row { display: contents; }
  .ms-stack-tabs:not(.ms-stack-tabs--set) .ms-stack-tabs__row--front { margin-top: 0; box-shadow: none; }
  .ms-stab, .ms-stack-tabs:not(.ms-stack-tabs--set) .ms-stack-tabs__row--back .ms-stab { margin-top: 0; padding: 10px 18px; }
}

/* --- STAT-STRIP — компактная сводка-строка (гибрид «Позитив» на /reviews). --- */
.ms-stat-strip {
  display: flex; flex-wrap: wrap; gap: var(--space-6);
  margin: 0 0 var(--space-4); padding: var(--space-4) var(--space-5);
  border: 1px solid var(--gray-border); border-radius: var(--radius-md);
  background: var(--gray-mid);
}
.ms-stat-strip__num {
  font-family: var(--font-display); font-size: 22px; font-weight: 700;
  color: var(--brand-secondary); line-height: 1; letter-spacing: -0.012em;
  font-variant-numeric: tabular-nums;
}
.ms-stat-strip__lbl { display: block; margin-top: 3px; font-size: 12px; color: var(--graphite-60); }

/* центрирование спиннера в ленивом контейнере вкладки */
.ms-loading { display: flex; justify-content: center; padding: var(--space-12) 0; }

/* --- SECTION header c акцент-полоской --- */
.ms-section { margin-bottom: var(--space-6); }
.ms-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-3); }
.ms-section-title { display: flex; align-items: center; gap: var(--space-2); margin: 0; font-size: var(--text-lg); font-weight: 700; color: var(--graphite); }
.ms-section-title::before { content: ""; width: 4px; height: 18px; border-radius: var(--radius-full); background: var(--brand-ink); }
/* TASK_399: под-заголовок секции (тише блок-титула) — инверсия иерархии + 2-й цвет полоски (aqua vs navy). */
.ms-section-title--sub { font-size: var(--text-base); font-weight: 600; color: var(--graphite-60); }
.ms-section-title--sub::before { height: 14px; background: var(--brand-primary); }

/* --- HERO — приветственная полоса (фирменный aqua-градиент) --- */
.ms-hero {
  position: relative; overflow: hidden;
  border-radius: var(--radius-md);
  padding: var(--space-8);
  margin-bottom: var(--space-6);
  box-shadow: var(--shadow);
}
.ms-hero--brand {
  background: var(--hero-brand);
  border: 1px solid rgba(10, 181, 197, 0.35);
}
.ms-hero--brand::before {                  /* кольцо-«волна» (как .blog-grad на лендинге) */
  content: ""; position: absolute;
  width: 200px; height: 200px; border-radius: 50%;
  border: 26px solid rgba(255, 255, 255, 0.20);
  bottom: -80px; right: -30px; pointer-events: none;
}
.ms-hero--brand::after {                    /* мягкий белый блик для объёма */
  content: ""; position: absolute;
  right: 100px; top: -70px;
  width: 220px; height: 220px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.40) 0%, rgba(255,255,255,0) 70%);
  pointer-events: none;
}
/* navy-текст на aqua: фирменная пара, читаемо (AA), не белый (audit F-02) */
.ms-hero__title { position: relative; margin: 0; font-size: var(--text-3xl); font-weight: 800; letter-spacing: -0.02em; color: var(--brand-secondary); }
.ms-hero__subtitle { position: relative; margin: 6px 0 0; font-size: var(--text-base); font-weight: 600; color: var(--graphite); }

@media (max-width: 768px) {
  .ms-hero { padding: var(--space-6); }
  .ms-hero__title { font-size: var(--text-2xl); }
}

/* --- HERO COMPACT — для контент-страниц (Конкуренты): меньше padding,
   меньше заголовок; крупное кольцо убрано, мягкий блик — масштабированный (TASK_422).
   Объявлено ПОСЛЕ базового .ms-hero и его @media → побеждает по source-order. */
.ms-hero--compact { padding: var(--space-5) var(--space-6); }
.ms-hero--compact .ms-hero__title { font-size: var(--text-2xl); }
.ms-hero--compact .ms-hero__subtitle { margin-top: 2px; font-size: var(--text-sm); }
/* TASK_422: кольцо убрано (великовато на компакте), но мягкий блик остаётся масштабированным —
   бренд-глянец на /competitors читается как НАМЕРЕННЫЙ герой, а не плоская teal-полоса (аудит). */
.ms-hero--compact::before { display: none; }
.ms-hero--compact::after { right: 48px; top: -56px; width: 170px; height: 170px; }
@media (max-width: 768px) {
  .ms-hero--compact { padding: var(--space-4) var(--space-5); }
  .ms-hero--compact .ms-hero__title { font-size: var(--text-xl); }
}

/* --- RANK SUMMARY — сводка «ваше место», справа в строке заголовка «Рейтинг рядом».
   Локальный элемент в .ms-section-head (глобальный класс не трогаем). --- */
.ms-rank-summary {
  font-size: var(--text-sm); font-weight: 600; color: var(--graphite-60);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ms-rank-summary strong { color: var(--brand-secondary); font-weight: 800; }

/* --- INSIGHT BAR — компактная строка над таблицей: подсказка слева + чипы-поповеры справа. --- */
.ms-insight-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-3);
}
.ms-insight-bar__tip { font-size: var(--text-sm); color: var(--graphite-text); line-height: 1.4; }
.ms-insight-bar__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* --- POPOVER — нативная карточка-совет (HTML Popover API). По центру вьюпорта,
   лёгкий backdrop. Без JS. Триггеры — .ms-btn-ghost.ms-btn-sm. --- */
.ms-popover {
  max-width: min(440px, 92vw);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  background: var(--white);
  color: var(--graphite-text);
}
.ms-popover::backdrop { background: rgba(2, 25, 41, 0.35); }
.ms-popover__title { margin: 0 0 var(--space-3); font-size: var(--text-lg); font-weight: 800; color: var(--brand-secondary); }
.ms-popover__body { font-size: var(--text-sm); line-height: 1.5; }
.ms-popover__body ul { margin: 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.ms-popover__why { margin: var(--space-3) 0 0; padding-top: var(--space-3); border-top: 1px solid var(--gray-border); color: var(--graphite-60); }
.ms-popover__close { margin-top: var(--space-4); }

/* --- PROSE — типографика длинных статей (раздел «Полезное», markdown → HTML).
   Кабинетный аналог .legal-prose, на токенах. Применяется к контейнеру статьи. --- */
.ms-prose { font-size: var(--text-base); line-height: 1.7; color: var(--graphite-text); }
.ms-prose > :first-child { margin-top: 0; }
.ms-prose > :last-child { margin-bottom: 0; }
.ms-prose h2 { position: relative; font-size: var(--text-xl); font-weight: 700; color: var(--brand-secondary); margin: var(--space-10) 0 var(--space-3); line-height: 1.3; scroll-margin-top: var(--space-6); }
.ms-prose h2::before { content: ""; display: block; width: 28px; height: 3px; margin-bottom: var(--space-3); background: var(--brand-primary); border-radius: var(--radius-full); } /* TASK_416: аква-риска-эйбров у раздела (декор, не текст) */
.ms-prose > h2:first-child { margin-top: 0; }
.ms-prose h3 { font-size: var(--text-lg); font-weight: 600; color: var(--graphite); margin: var(--space-6) 0 var(--space-2); scroll-margin-top: var(--space-6); }
.ms-prose p { margin: 0 0 var(--space-4); }
.ms-prose ul, .ms-prose ol { margin: 0 0 var(--space-4); padding-left: var(--space-6); }
.ms-prose li { margin-bottom: var(--space-2); }
.ms-prose a { color: var(--brand-ink); font-weight: 600; text-decoration: underline; }
.ms-prose a:hover { color: var(--brand-ink-hover); }
.ms-prose strong { font-weight: 700; color: var(--graphite); }
.ms-prose blockquote {
  margin: var(--space-4) 0; padding: var(--space-3) var(--space-4);
  border-left: 4px solid var(--brand-ink); background: var(--brand-primary-light);
  border-radius: var(--radius-sm); color: var(--graphite-text);
}
.ms-prose blockquote p:last-child { margin-bottom: 0; }
.ms-prose table { width: 100%; border-collapse: collapse; margin: var(--space-4) 0; font-size: var(--text-sm); }
.ms-prose th, .ms-prose td { padding: var(--space-2) var(--space-3); border: 1px solid var(--gray-border); text-align: left; }
.ms-prose th { background: var(--gray-mid); font-weight: 600; }

/* === TASK_416 — «Полезное»: оглавление статьи (TOC) + editorial-индекс раздела === */

/* Читаемая колонка статьи (оглавление + prose) */
.ms-help-article { max-width: 760px; }

/* Оглавление «В этой статье» — строит help_toc.js (h2 → якоря); пусто (нет JS / <2 h2) → скрыто */
.ms-toc { margin: 0 0 var(--space-8); padding: var(--space-5) var(--space-6); background: var(--white); border: 1px solid var(--gray-border); border-radius: var(--radius-lg); }
.ms-toc:empty { display: none; }
.ms-toc__label { margin: 0 0 var(--space-3); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--graphite-60); }
.ms-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: toc; display: grid; gap: var(--space-1); }
.ms-toc__link { display: flex; gap: var(--space-3); align-items: baseline; padding: var(--space-1) 0; color: var(--graphite-text); text-decoration: none; font-weight: 600; line-height: 1.4; transition: color var(--transition); }
.ms-toc__link::before { counter-increment: toc; content: counter(toc); flex: none; min-width: 1.6em; color: var(--brand-ink); font-variant-numeric: tabular-nums; font-weight: 700; }
.ms-toc__link:hover, .ms-toc__link.is-active { color: var(--brand-ink); }

/* Editorial-индекс /help: лид «Начните отсюда» + разделы-списки строк (замена плиткам) */
.ms-lib-intro { font-size: var(--text-base); color: var(--graphite-60); margin: 0 0 var(--space-6); }
.ms-lib-nav { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-8); padding: var(--space-3) 0; border-top: 1px solid var(--gray-border); border-bottom: 1px solid var(--gray-border); }
.ms-lib-nav__link { display: inline-flex; align-items: center; gap: 6px; padding: var(--space-1) var(--space-3); font-size: var(--text-sm); font-weight: 600; color: var(--brand-ink); text-decoration: none; border-radius: var(--radius-full); transition: background var(--transition); }
.ms-lib-nav__link:hover { background: var(--brand-primary-light); }
.ms-lib-nav__n { font-size: var(--text-xs); color: var(--graphite-30); font-variant-numeric: tabular-nums; }
.ms-lib-lead { margin: 0 0 var(--space-10); }
.ms-lib-lead__title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; color: var(--graphite); margin: 0 0 var(--space-1); letter-spacing: -0.012em; }
.ms-lib-lead__hint { font-size: var(--text-sm); color: var(--graphite-60); margin: 0 0 var(--space-3); }
.ms-lib-section { margin: 0 0 var(--space-10); }
.ms-lib-section:last-child { margin-bottom: 0; }
.ms-lib-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-1); }
.ms-lib-head__title { position: relative; font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; color: var(--brand-secondary); letter-spacing: -0.012em; padding-top: var(--space-3); }
.ms-lib-head__title::before { content: ""; position: absolute; top: 0; left: 0; width: 28px; height: 3px; background: var(--brand-primary); border-radius: var(--radius-full); }
.ms-lib-head__count { flex: none; font-size: var(--text-sm); color: var(--graphite-60); font-variant-numeric: tabular-nums; }
.ms-lib-row { display: grid; grid-template-columns: 1fr auto; column-gap: var(--space-4); align-items: baseline; padding: var(--space-3); border-radius: var(--radius-md); text-decoration: none; transition: background var(--transition); }
.ms-lib-row + .ms-lib-row { border-top: 1px solid var(--gray-border); }
.ms-lib-row:hover { background: var(--brand-primary-light); }
.ms-lib-row__title { grid-column: 1; grid-row: 1; font-weight: 600; color: var(--brand-ink); }
.ms-lib-row:hover .ms-lib-row__title { color: var(--brand-ink-hover); }
.ms-lib-row__meta { grid-column: 2; grid-row: 1; font-size: var(--text-xs); color: var(--graphite-30); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ms-lib-row__dek { grid-column: 1; grid-row: 2; margin-top: 2px; font-size: var(--text-sm); color: var(--graphite-60); }
.ms-lib-row--lead .ms-lib-row__title { font-size: var(--text-lg); }
.ms-lib-badge { display: inline-block; margin-left: var(--space-2); padding: 0 var(--space-2); font-size: var(--text-xs); font-weight: 600; color: var(--brand-secondary); background: var(--brand-secondary-light); border-radius: var(--radius-sm); vertical-align: middle; }

/* === TASK_414 — Техподдержка: лента переписки тикета === */
.ms-thread { display: flex; flex-direction: column; gap: var(--space-4); }
.ms-msg { padding: var(--space-4); border: 1px solid var(--gray-border); border-radius: var(--radius-md); background: var(--white); }
.ms-msg--staff { background: var(--brand-primary-light); border-color: transparent; } /* ответ поддержки — аква-тинт */
.ms-msg__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-2); }
.ms-msg__author { font-size: var(--text-sm); font-weight: 700; color: var(--brand-secondary); }
.ms-msg--staff .ms-msg__author { color: var(--brand-ink); }
.ms-msg__date { font-size: var(--text-xs); color: var(--graphite-30); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ms-msg__body { font-size: var(--text-sm); line-height: 1.6; color: var(--graphite-text); white-space: pre-wrap; word-break: break-word; }
.ms-btn-row { display: flex; gap: var(--space-2); flex-wrap: wrap; } /* ряд кнопок (смена статуса тикета) */

/* ============================================================
   КОНКУРЕНТЫ — редизайн live-обогащения (TASK_126).
   Промоут утверждённых мок-классов (mockup_competitors.html) под ms-* нейминг.
   Данные 2ГИС — live, не хранятся.
   ============================================================ */

/* --- Слим-полоса «Ваше место»: ранг + инсайт-разрыв + действия в одну строку. --- */
.ms-place-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-6);
  padding: 13px 20px; margin: 0 0 var(--space-4);
  border: 1px solid var(--brand-border); border-radius: var(--radius-md);
  background: var(--surface-brand); box-shadow: var(--shadow-sm);
}
.ms-place-bar__rank {
  display: flex; align-items: baseline; gap: 9px;
  padding-right: var(--space-6); border-right: 1px solid var(--brand-border);
}
.ms-place-bar__rank em {
  font-style: normal; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .5px; color: var(--graphite-60);
}
.ms-place-bar__rank b {
  font-family: var(--font-display); font-size: 30px; font-weight: 800; line-height: 1;
  color: var(--brand-secondary); letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.ms-place-bar__rank b small { font-size: 14px; font-weight: 700; color: var(--graphite-60); margin-left: 5px; }
.ms-place-bar__gap { flex: 1; min-width: 220px; font-size: var(--text-sm); line-height: 1.4; color: var(--brand-secondary-dark); }
.ms-place-bar__gap b { color: var(--brand-secondary); font-weight: 700; }
.ms-place-bar__actions { display: flex; gap: var(--space-2); flex-shrink: 0; }
@media (max-width: 620px) { .ms-place-bar__rank { border-right: 0; padding-right: 0; } }

/* --- Сетка плиток-сигналов (5 шт.): метрики места + сигналы карточки. --- */
.ms-sig-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; margin: 0 0 var(--space-6); }
@media (max-width: 1080px) { .ms-sig-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px)  { .ms-sig-grid { grid-template-columns: repeat(2, 1fr); } }
/* TASK_319 F-010: на ≤400 схлопываем в 1 колонку — 1fr=minmax(auto,1fr) не сжимался
   ниже min-content карточки (.ms-sig-card__value nowrap, 20px) → +99px overflow на 375. */
@media (max-width: 400px)  { .ms-sig-grid { grid-template-columns: 1fr; } }

.ms-sig-card {
  display: flex; flex-direction: column; gap: 9px; padding: 13px 14px;
  background: var(--surface-brand); border: 1px solid var(--brand-border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast), border-color var(--transition-fast);
}
.ms-sig-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); border-color: var(--brand-border-strong); }
.ms-sig-card__top { display: flex; align-items: center; gap: 8px; }
.ms-sig-card .ms-icon-chip { width: 26px; height: 26px; flex-shrink: 0; }
.ms-sig-card .ms-icon-chip svg { width: 15px; height: 15px; }
.ms-sig-card__label {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--graphite-60);
}
.ms-sig-card__you {
  flex-shrink: 0; padding: 2px 6px; border-radius: var(--radius-full);
  background: var(--brand-primary-light); color: var(--brand-ink);
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
}
.ms-sig-card__value {
  flex-shrink: 0; font-family: var(--font-display); font-size: 20px; font-weight: 700; line-height: 1;
  color: var(--graphite); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.ms-sig-card--gap .ms-sig-card__value { color: var(--warning-ink); }
.ms-sig-card__ctx { font-size: var(--text-sm); line-height: 1.35; color: var(--graphite-60); }
.ms-sig-card__ctx b { color: var(--brand-secondary); font-weight: 700; white-space: nowrap; }
.ms-sig-bar { display: block; height: 5px; border-radius: var(--radius-full); background: var(--gray-mid); overflow: hidden; }
.ms-sig-bar i { display: block; height: 100%; border-radius: var(--radius-full); background: var(--brand-primary); }
.ms-sig-card--gap .ms-sig-bar i { background: var(--warning); }

/* --- Скелетон-загрузка (вместо голого спиннера на время live-запроса 2ГИС). --- */
.ms-skeleton {
  display: block; height: 14px; border-radius: 3px;
  background: linear-gradient(90deg, var(--gray-mid) 25%, var(--gray-border) 37%, var(--gray-mid) 63%);
  background-size: 400% 100%; animation: ms-shimmer 1.3s ease infinite;
}
@keyframes ms-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
/* Скелетон-каркас раздела на время live-запроса (полоса места + сетка плиток + строки). */
.ms-skeleton-wrap { display: flex; flex-direction: column; gap: 14px; }
.ms-skeleton--bar  { height: 48px; border-radius: var(--radius-md); }
.ms-skeleton--tile { height: 96px; border-radius: var(--radius-md); }
.ms-skeleton--row  { height: 38px; border-radius: var(--radius-sm); }

/* --- Мелкие утилиты (вынос inline-стилей из шаблонов конкурентов, konfetka-инвариант). --- */
.ms-hero__subtitle-soft { font-weight: 500; opacity: .7; }
.ms-num { text-align: right; font-variant-numeric: tabular-nums; }
.ms-ta-c { text-align: center; }
.ms-nowrap { white-space: nowrap; }
.ms-cell-muted { color: var(--graphite-60); }
.ms-cell-strong { font-weight: 700; }
.ms-row-own { background: var(--brand-primary-light); }
.ms-rec-list { margin: 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.ms-rec-list li { line-height: 1.45; }
.ms-rec-list li b { color: var(--brand-secondary); }
.ms-popover__actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); }
.ms-onboard-card { margin-top: var(--space-4); max-width: 640px; border: 0; box-shadow: none; background: var(--gray-mid); }/* TASK_404: плоско — не box-in-box в панели конкурентов (А5) */
.ms-onboard-card .ms-onboard-title { margin: 0 0 var(--space-2); font-weight: 700; color: var(--graphite); font-size: var(--text-sm); }

/* ── TASK_406 — карточка виджета для сайта: две колонки (внешний вид | установка), превью кнопки+QR, свотчи цвета, установка в 2 шага. Цвет кнопки задаёт JS через style.background. ── */
.w406-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: var(--space-6); max-width: 900px; margin-top: var(--space-5); }
@media (max-width: 860px) { .w406-grid { grid-template-columns: 1fr; gap: var(--space-5); } }
.w406-col__title { margin: 0 0 12px; font-size: var(--text-sm); font-weight: 700; color: var(--brand-secondary); }
.w406-preview { display: flex; align-items: center; gap: var(--space-5); padding: var(--space-5); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--gray-mid); }
.w406-preview__stage { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.w406-preview__cap { font-size: 12px; color: var(--graphite-30); margin: 0; }
.w406-btn { display: inline-block; padding: 12px 22px; border-radius: 10px; background: var(--brand-secondary); color: var(--white); font: 600 15px/1.2 var(--font-sans); text-decoration: none; cursor: pointer; }
.w406-qr { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.w406-qr__img { width: 76px; height: 76px; border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); display: block; }
.w406-qr__cap { font-size: 11px; color: var(--graphite-30); }
.w406-field { margin-top: var(--space-5); max-width: 360px; }
.w406-field .ms-input { width: 100%; }
.w406-swatches { display: flex; gap: 8px; margin-top: 8px; }
.w406-swatch { width: 30px; height: 30px; padding: 0; border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--_c); cursor: pointer; position: relative; transition: box-shadow var(--transition-fast), border-color var(--transition-fast); }
.w406-swatch:hover { border-color: var(--graphite-30); }
.w406-swatch--active { border-color: var(--white); box-shadow: 0 0 0 2px var(--brand-secondary); }
.w406-steps { display: flex; flex-direction: column; gap: var(--space-4); }
.w406-step { display: flex; gap: 12px; }
.w406-step__num { flex: 0 0 auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-sm); background: var(--brand-secondary); color: var(--white); font-size: 13px; font-weight: 700; line-height: 1; }
.w406-step__body { flex: 1 1 auto; min-width: 0; }
.w406-step__lead { margin: 2px 0 8px; font-size: 14px; font-weight: 600; color: var(--graphite); }
.w406-code { margin: 0; white-space: pre-wrap; word-break: break-all; background: var(--gray-mid); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); padding: 12px; font: 13px/1.5 ui-monospace, Menlo, Consolas, monospace; color: var(--graphite); overflow-x: auto; }
.w406-code__actions { display: flex; gap: 8px; margin-top: 10px; }
.w406-inv { display: flex; align-items: flex-start; gap: 8px; margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--gray-border); font-size: 13px; color: var(--graphite-60); line-height: 1.5; max-width: var(--set-w); }
.w406-inv svg { flex: 0 0 auto; margin-top: 1px; color: var(--brand-ink); }
.ms-onboard-steps { margin: 0 0 var(--space-4); padding-left: var(--space-5); color: var(--graphite-60); font-size: var(--text-sm); line-height: 1.7; }
.ms-inline-form { display: inline; margin-left: var(--space-2); }
.ms-summary { cursor: pointer; }
.ms-mt-3 { margin-top: var(--space-3); }
.ms-mt-4 { margin-top: var(--space-4); }

/* ============================================================
   QR-КОДЫ (TASK_127) — раздел /qr. Промоут из mockup_qr_section.html.
   Сегмент-контрол «Вид», сетка QR-карточек (зоны/врачи), мини в таблице,
   тип-бейдж Филиал/Врач, пустая цель красным пунктиром, легаси под details.
   ============================================================ */
/* Сегмент-контрол «Вид» Сетка/Таблица. */
.ms-segmented {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--gray-mid); border: 1px solid var(--gray-border); border-radius: var(--radius-sm);
}
.ms-segmented__btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border: 0; background: none; border-radius: 3px; cursor: pointer;
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--graphite-60);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}
.ms-segmented__btn svg { width: 16px; height: 16px; }
.ms-segmented__btn:hover { color: var(--brand-ink); }
.ms-segmented__btn.is-active { background: var(--white); color: var(--brand-ink); box-shadow: var(--shadow-sm); cursor: default; }

/* TASK_215: переключатель источника сравнения (Конкуренты). Оба сегмента
   неинтерактивны (источник один); disabled-вариант «скоро» — по образцу .ms-ftab--soon. */
.ms-cmp-source { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.ms-cmp-source__label { font-size: var(--text-sm); font-weight: 600; color: var(--graphite-30); }
.ms-segmented__btn--soon { opacity: .55; cursor: default; pointer-events: none; }
.ms-segmented__soon {
  margin-left: 6px; padding: 0 6px; border-radius: var(--radius-sm);
  background: var(--gray-border); color: var(--graphite-60);
  font-size: 10px; font-weight: 700; line-height: 16px; text-transform: uppercase; letter-spacing: .04em;
}

.qr-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-bottom: var(--space-5); }
.qr-toolbar__label { margin-right: auto; font-size: var(--text-sm); font-weight: 600; color: var(--graphite-30); }

/* «Вид» переключает только содержимое (Сетка/Таблица — обе в DOM). */
.qr-views[data-variant="grid"]  .qr-as-table { display: none; }
.qr-views[data-variant="table"] .qr-as-grid  { display: none; }

/* Фирменная полоса на кнопках раздела QR (TASK_146 Ф3) — СТРОГО scoped к .qr-views
   (ms-btn-ghost живёт в 22 шаблонах; глобально перекрасило бы весь кабинет). */
.qr-views .ms-btn-ghost { border-color: var(--brand-primary); color: var(--brand-secondary); }
.qr-views .ms-btn-ghost:hover { background: var(--brand-primary-light); border-color: var(--brand-primary-dark); }
.qr-toolbar__dl { margin-right: auto; display: inline-flex; align-items: center; gap: 6px; }

/* Блок «Приглашение оставить отзыв» (TASK_146 Ф1). */
.ms-qr-invite { align-self: stretch; text-align: left; margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--gray-border); }
.ms-qr-invite__preview { margin: 0 0 var(--space-3); line-height: 1.5; }
.ms-qr-invite .ms-qr-card__code { display: inline; word-break: break-all; }
.ms-qr-invite__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ms-qr-invite__status { margin: var(--space-2) 0 0; }
.ms-qr-invite__status:empty { display: none; }
details.ms-qr-invite > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--brand-secondary); font-size: var(--text-sm); }
details.ms-qr-invite > summary::-webkit-details-marker { display: none; }
.ms-qr-invite__hint { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-weight: 500; color: var(--graphite-30); }
.ms-qr-invite__hint::before { content: "(развернуть)"; }
details.ms-qr-invite[open] .ms-qr-invite__hint::before { content: "(свернуть)"; }
.ms-qr-invite__hint::after { content: "▾"; display: inline-block; transition: transform var(--transition-fast); }
details.ms-qr-invite[open] .ms-qr-invite__hint::after { transform: rotate(180deg); }
details.ms-qr-invite > summary + * { margin-top: var(--space-3); }


/* Сетка QR-карточек. */
.ms-qr-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-4); }
.ms-qr-card { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-5); text-align: center; }
.ms-qr-card__thumb { width: 116px; height: 116px; padding: 9px; background: var(--white); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; }
.ms-qr-card__thumb img { width: 100%; height: 100%; display: block; }
.ms-qr-card__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); justify-content: center; margin-top: auto; }
.ms-qr-card--empty { background: var(--white); border: 1px dashed var(--gray-border); box-shadow: none; }
.ms-qr-card__code { font-family: monospace; font-size: var(--text-xs); color: var(--graphite-60); }
.ms-qr-card .ms-qr-card__code { display: none; }   /* в карточке код скрыт; в таблице остаётся */
.ms-qr-card__sub-actions { display: flex; flex-wrap: wrap; gap: 6px 12px; justify-content: center; }
.ms-qr-card__sub-actions form { display: contents; }  /* кнопка-форма участвует во flex напрямую */
.ms-qr-card__sub-actions a,
.ms-qr-card__sub-actions button { background: none; border: 0; padding: 2px 0; cursor: pointer; font: inherit; font-size: var(--text-xs); color: var(--graphite-60); text-decoration: underline; }  /* a11y: было padding:0 — расширена тач-зона */
.ms-qr-card__sub-actions button.danger { color: var(--danger-ink); }
/* тип-бейдж Филиал / Врач */
.ms-qr-card__type { position: absolute; top: 10px; left: 10px; padding: 2px 9px; border-radius: var(--radius-sm); font-size: 11px; font-weight: 700; letter-spacing: .01em; }/* TASK_400: капсула→3px (язык острых радиусов) */
.ms-qr-card__type--filial { background: var(--brand-primary-light); color: var(--brand-ink); }
.ms-qr-card__type--doctor { background: var(--brand-secondary-light); color: var(--brand-secondary); }
/* зональные QR — крупнее/жирнее подпись, всегда выше врачей */
.ms-qr-card--zone .ms-tile-row__title { font-size: 16px; font-weight: 800; }

/* TASK_391 — печатные действия на карточке кода: листовка A4–A7 (по размерам),
   бейдж врача, лист наклеек, тег «Новый». Острые углы 3px/2px (язык радиусов). */
.qr-lf-lbl { font-size: 12px; font-weight: 600; color: var(--graphite-30); }
.qr-lf-sizes { display: inline-flex; gap: 3px; }
.qr-lf-sizes a {
  font-size: 11.5px; font-weight: 700; line-height: 1; padding: 5px 8px;
  color: var(--brand-secondary); background: var(--white);
  border: 1px solid var(--gray-border); border-radius: 3px; text-decoration: none;
}
.qr-lf-sizes a:hover { border-color: var(--brand-primary); }
.qr-lf-sizes a.on { background: var(--brand-secondary); color: var(--white); border-color: var(--brand-secondary); }
.ms-qr-card__actions .qr-badge { border-color: var(--brand-secondary); color: var(--brand-secondary); font-weight: 700; }  /* TASK_432 (§В): бирюзовый выбивался среди navy print-кнопок → --brand-secondary */
.qr-sticker-tag {
  margin-left: 6px; padding: 1px 6px; font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; border-radius: 2px;
  color: var(--success-ink); background: var(--success-light); border: 1px solid var(--alert-success-border);
}

/* мини-QR в таблице */
.ms-qr-mini { width: 46px; height: 46px; flex-shrink: 0; padding: 3px; background: var(--white); border: 1px solid var(--gray-border); border-radius: 3px; }
.ms-qr-mini img { width: 100%; height: 100%; display: block; }
.ms-qr-mini--empty { border-style: dashed; border-color: var(--gray-border); }
.qr-mini-actions { display: inline-flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.qr-mini-actions form { display: contents; }

/* пустая цель (нет QR) */
.qr-empty-glyph { width: 116px; height: 116px; display: flex; align-items: center; justify-content: center; color: var(--graphite-30); }
.qr-empty-glyph svg { width: 46px; height: 46px; }
.qr-empty-note { font-size: var(--text-xs); color: var(--graphite-60); }

/* группировка по филиалам в «Все» + под-сетки */
.qr-group + .qr-group { margin-top: var(--space-6); }
.qr-group__head { margin: 0; }
/* Шапка группы филиала: название слева, «Создать все» справа (TASK_146). */
.qr-group__head-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.qr-group__bulk { margin: 0 0 0 auto; }
.qr-docs { margin-top: var(--space-5); }

/* легаси (неактивные коды) */
.qr-legacy { margin-top: var(--space-5); }
.qr-legacy summary { cursor: pointer; font-size: var(--text-sm); color: var(--graphite-60); font-weight: 600; }
.qr-legacy[open] summary { margin-bottom: var(--space-3); }
.qr-legacy .ms-table td { color: var(--graphite-60); }

/* онбординг шаг-3 плитка */
.onboard-tile { margin-bottom: var(--space-4); padding-top: var(--space-3); padding-bottom: var(--space-3); }
.onboard-tile .ms-tile-row__more { color: var(--graphite-30); }
.onboard-tile .ms-icon-chip { width: 34px; height: 34px; }

/* =====================================================================
   ЖУРНАЛ АУДИТА — лента событий (TASK_137).
   Промоут утверждённых мок-классов (mockup_admin_clinic_card.html #s-journal)
   под ms-* нейминг. Аддитивно — существующее не трогаем.
   ===================================================================== */
.ms-feed { display: flex; flex-direction: column; gap: 8px; }
.ms-feed-row {
  display: flex;
  gap: 12px;
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-left: 3px solid var(--gray-mid);
  border-radius: 3px;
  padding: 10px 14px;
}
.ms-feed-row--red   { border-left-color: var(--danger-ink); }
.ms-feed-row--green { border-left-color: var(--success-ink); }
.ms-feed-row--gray  { border-left-color: var(--graphite-30); }
.ms-feed-row--amber { border-left-color: #D46B08; }  /* «молчит» — мягкий риск (TASK_138) */
/* Строка-ссылка (дашборд «Требует внимания», TASK_138) — кликабельна целиком. */
.ms-feed-row--link { text-decoration: none; color: inherit; transition: background-color 0.12s ease; }
.ms-feed-row--link:hover { background: var(--gray-mid); }
.ms-feed-row__time {
  flex: 0 0 66px;
  font-size: 12px;
  color: var(--graphite-60);
  line-height: 1.4;
}
.ms-feed-row__body { flex: 1; min-width: 0; font-size: 14px; line-height: 1.45; color: var(--graphite); }
.ms-feed-row__meta { font-size: 12px; color: var(--graphite-60); margin-top: 2px; }
.ms-feed-cat {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  border-radius: 2px;
  padding: 1px 7px;
  margin-right: 6px;
  white-space: nowrap;
}
.ms-feed-cat--money,
.ms-feed-cat--law,
.ms-feed-cat--access { background: var(--danger-light); color: var(--danger-ink); }
.ms-feed-cat--grow   { background: var(--success-light); color: var(--success-ink); }
.ms-feed-cat--ops    { background: var(--gray-mid); color: var(--graphite-60); }
.ms-feed-note { font-size: 12px; color: var(--graphite-60); margin-top: 12px; }

/* ============================================================
   КОКПИТ КАРТОЧКИ КЛИНИКИ (TASK_139) — командная полоса + bento
   Промоут из утверждённого мокапа mockup_clinic_contacts.html (v3).
   ============================================================ */
.ms-cockpit-bar {
  display: grid;
  grid-template-columns: 1.15fr 1.35fr 1.5fr;
  background: var(--brand-primary-light);
  border: 1px solid var(--brand-primary);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 14px;
}
.ms-cb-cell { padding: 13px 18px; }
.ms-cb-cell + .ms-cb-cell { border-left: 1px solid rgba(2, 63, 136, .12); }
.ms-cb-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--brand-secondary-dark);
  margin-bottom: 6px;
}
.ms-cb-strong { font-size: 16px; font-weight: 700; color: var(--brand-ink); line-height: 1.25; }
.ms-cb-sub { font-size: 12px; color: var(--brand-secondary-dark); margin-top: 4px; line-height: 1.5; }
.ms-cb-phone { font-size: 19px; font-weight: 800; color: var(--brand-ink); text-decoration: none; }
.ms-cb-callrow { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 8px; }
.ms-cb-money { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }

/* Здоровье: цветная точка + текст (анти-слоп: без пилюль).
   red — новый уровень поверх мокапа (мокап показывал green/amber). */
.ms-health { display: inline-flex; align-items: center; gap: 8px; }
.ms-health__dot { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; }
.ms-health--green .ms-health__dot { background: var(--success-ink); }
.ms-health--amber .ms-health__dot { background: #D46B08; } /* тот же amber, что .ms-feed-row--amber */
.ms-health--red .ms-health__dot { background: var(--danger-ink); }

/* Bento-сетка Обзора (2 колонки, полноширинная лента через __span2). */
.ms-ob-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.ms-ob-grid > .ms-ob-grid__span2 { grid-column: 1 / -1; }

/* KPI-плитки «Ценность для клиента». */
.ms-vtiles { display: flex; gap: 10px; flex-wrap: wrap; }
.ms-vtile { flex: 1 1 90px; }
.ms-vtile__v { font-size: 19px; font-weight: 700; color: var(--brand-ink); }
.ms-vtile__l { font-size: 11px; color: var(--graphite-60); margin-top: 2px; }
/* Тренд рейтинга (TASK_143): рост зелёный, падение красное, флэт нейтральный
   (цвет = сигнал; зелёный при равных цифрах оверселлил бы «рост»). */
.ms-vtile__delta--up { color: var(--success-ink); }
.ms-vtile__delta--down { color: var(--danger-ink); }
.ms-vtile__delta--flat { color: var(--graphite-60); }
.ms-vtile__sub { font-size: 11px; color: var(--graphite-60); margin-top: 1px; }

/* Мини-лента активности клиники (категория = цвет текста, без бейджа). */
.ms-mini-feed { display: flex; flex-direction: column; gap: 2px; }
.ms-mfeed-row {
  display: flex;
  gap: 12px;
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px solid var(--gray-border);
}
.ms-mfeed-row:last-child { border-bottom: 0; }
.ms-mfeed-time { flex: 0 0 90px; color: var(--graphite-60); font-size: 12px; }
.ms-mcat { font-weight: 700; font-size: 11px; margin-right: 6px; }
.ms-mcat--grow { color: var(--success-ink); }
.ms-mcat--money, .ms-mcat--access, .ms-mcat--law { color: var(--danger-ink); }
.ms-mcat--ops { color: var(--graphite-60); }

@media (max-width: 720px) {
  .ms-cockpit-bar { grid-template-columns: 1fr; }
  .ms-cb-cell + .ms-cb-cell { border-left: 0; border-top: 1px solid rgba(2, 63, 136, .12); }
  .ms-ob-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   REDUCED MOTION (a11y) — выключаем переходы/анимации
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
 * ГЛАВНАЯ / DASHBOARD (TASK_214) — промоут утверждённого вида V1+ (r3 «Уплотнение»).
 * Скоуп .dashb-* (перенос из app/static/mockups/cabinet/dashboard_r3_v1_rich.html).
 * Все значения на живых токенах + --text-secondary* (Волна 0). Только аддитивно.
 * ============================================================================ */
/* Сдержанный ease-out — приборный, не пружинит: «control = дорого». */
      :root { --dashb-ease: cubic-bezier(0.22, 1, 0.36, 1); }

      /* ── ХОЛСТ ДОКУМЕНТА (ДНК B2) ───────────────────────────────────────
         Печатный разворот: щедрые поля, мера, графит. Чуть шире B2 (1120),
         чтобы леджер + рейл уместились без тесноты — рейл это «оплата» за ширину. */
      .r3 {
        max-width: 1120px;
        margin: 0 auto;
        padding: var(--space-2) var(--space-2) var(--space-16);
        color: var(--graphite);
      }
      .r3 * { box-sizing: border-box; }

      /* ── МАСТХЭД издания (ДНК B2 вербатим по структуре) ──────────────────── */
      .dashb-masthead { padding-top: var(--space-6); }
      .dashb-masthead__kicker {
        display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
        font-size: var(--text-secondary-size);   /* 13px */
        font-weight: 600;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--brand-ink);
      }
      .dashb-masthead__kicker .dashb-mk-dot { color: var(--graphite-30); letter-spacing: 0; }
      .dashb-masthead__kicker .dashb-mk-week { color: var(--graphite-60); }
      .dashb-masthead__title {
        font-family: var(--font-display);
        font-size: clamp(2.4rem, 5vw, 3.4rem);
        font-weight: 800;
        line-height: 1.02;
        letter-spacing: -0.02em;
        color: var(--brand-secondary);            /* navy — «имя издания» */
        margin: 6px 0 0;
      }
      .dashb-rule {
        margin-top: var(--space-4);
        border: 0;
        border-top: 2px solid var(--brand-secondary);
        border-bottom: 1px solid var(--gray-border);
        height: 4px;
      }
      .dashb-dateline {
        display: flex; flex-wrap: wrap; align-items: baseline;
        justify-content: space-between; gap: 8px 18px;
        padding-top: var(--space-3);
        font-size: var(--text-secondary-size-lg);  /* 15px */
        color: var(--graphite);
      }
      .dashb-dateline__issue { font-weight: 600; }
      .dashb-dateline__when  { color: var(--graphite-60); font-variant-numeric: tabular-nums; }

      /* ── РАЗВОРОТ: леджер (главная колонка) + рейл «Состояние» (правая треть) ─
         ВОТ как лечится воздух: правая треть теперь не пустота за числами, а
         содержательная врезка. Леджер занимает ~62%, рейл ~38%. Рейл «липкий» —
         состояние всегда на виду, пока листаешь записи. */
      .dashb-spread {
        margin-top: var(--space-8);
        display: grid;
        grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr);
        gap: var(--space-12);
        align-items: start;
      }

      /* ── ЛЕДЖЕР ВКЛАДА СЕРВИСА — доминанта (ДНК B2) ──────────────────────── */
      .dashb-ledger__head { margin-bottom: var(--space-2); }
      .dashb-ledger__overline {
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--graphite-60);
      }
      .dashb-ledger__lead {
        font-family: var(--font-display);
        font-size: clamp(1.5rem, 2.7vw, 2rem);
        font-weight: 700;
        line-height: 1.16;
        letter-spacing: -0.015em;
        color: var(--graphite);
        text-wrap: pretty;
        margin: var(--space-2) 0 0;
        max-width: 24ch;
      }
      .dashb-ledger__lead b { font-weight: 800; color: var(--brand-secondary); }

      /* ── ЗАПИСЬ ЛЕДЖЕРА — УПЛОТНЕНА. Ключевое отличие от B2: ──────────────
         B2 был grid 1fr minmax(140px,auto) — число летело к дальнему краю.
         Здесь правая колонка ФИКСИРОВАНА (clamp ~118–148px) и стоит ВПЛОТНУЮ
         к прозе через умеренный gap: число-результат больше не отрывается в
         воздух, проза тянется шире. Воздух справа закрыт рейлом, а не пустотой. */
      .dashb-entry {
        display: grid;
        grid-template-columns: minmax(0, 1fr) clamp(118px, 14vw, 148px);
        align-items: baseline;
        gap: var(--space-3) var(--space-6);
        padding: var(--space-6) 0;
        border-top: 1px solid var(--gray-border);
      }
      .dashb-entry:first-of-type {
        border-top: 2px solid var(--brand-secondary);
        margin-top: var(--space-5);
      }
      .dashb-entry__lbl {
        display: block;
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        color: var(--brand-ink);
        margin-bottom: var(--space-2);
      }
      .dashb-entry__did {
        font-family: var(--font-display);
        font-size: clamp(1.1rem, 1.5vw, 1.35rem);
        font-weight: 700;
        line-height: 1.26;
        letter-spacing: -0.01em;
        color: var(--graphite);
        margin: 0;
        text-wrap: pretty;
        max-width: 42ch;
      }
      .dashb-entry__did b { font-weight: 800; color: var(--graphite); font-variant-numeric: tabular-nums; }
      .dashb-entry__note {
        margin: var(--space-3) 0 0;
        font-size: var(--text-secondary-size-lg);  /* 15px */
        line-height: 1.55;
        color: var(--graphite-text);
        max-width: 58ch;
      }
      .dashb-entry__note b { font-weight: 600; color: var(--graphite); font-variant-numeric: tabular-nums; }
      .dashb-entry__note a { color: var(--brand-ink); text-decoration: none; font-weight: 600; }
      .dashb-entry__note a:hover { text-decoration: underline; }

      /* правая колонка записи — число-результат вплотную, не у дальнего края */
      .dashb-entry__result {
        justify-self: end;
        text-align: right;
        white-space: nowrap;
      }
      .dashb-entry__num {
        display: flex; align-items: baseline; justify-content: flex-end; gap: 6px;
        font-family: var(--font-display);
        font-weight: 800;
        line-height: 0.95;
        letter-spacing: -0.02em;
        color: var(--graphite);
        font-variant-numeric: tabular-nums;
      }
      .dashb-entry__num--md { font-size: clamp(2rem, 3.2vw, 2.5rem); }
      .dashb-entry__star { color: #F5A623; font-size: 0.62em; line-height: 1; }
      .dashb-entry__unit {
        font-size: 0.84rem; font-weight: 700; color: var(--graphite-60);
        letter-spacing: 0;
      }
      .dashb-entry__delta {
        margin-top: var(--space-2);
        font-size: var(--text-secondary-size);
        font-weight: 700;
        color: var(--success-ink);
        font-variant-numeric: tabular-nums;
      }
      .dashb-entry__rcap {
        margin-top: var(--space-2);
        font-size: var(--text-secondary-size);
        font-weight: 500;
        color: var(--graphite-60);
        white-space: normal;
        max-width: 16ch;
        margin-left: auto;
        line-height: 1.4;
      }

      /* ── ОТКРЫТАЯ СТРОКА ЛЕДЖЕРА: «что осталось сделать» = действие ─────────
         Единственное место, где danger выпрыгивает (семантика просрочки).
         ⚠ юр-гардрейл: «успели ответить до публикации», не цензура. */
      .dashb-entry--open {
        border-top: 2px solid var(--brand-secondary);
        margin-top: var(--space-2);
        padding-top: var(--space-6);
        align-items: start;
      }
      .dashb-entry--open .dashb-entry__lbl { color: var(--danger-ink); }
      .dashb-entry--open .dashb-entry__did { font-size: clamp(1.2rem, 1.9vw, 1.5rem); max-width: 32ch; }
      /* буквица-число «6» — ровно одна на экран (журнальный приём) */
      .dashb-dropcap {
        float: left;
        font-family: var(--font-display);
        font-size: 4.4rem;
        font-weight: 800;
        line-height: 0.78;
        color: var(--danger-ink);
        margin: 4px 14px -4px 0;
        font-variant-numeric: tabular-nums;
      }
      .dashb-cta {
        display: inline-flex; align-items: center; gap: 9px;
        margin-top: var(--space-5);
        min-height: 46px;
        padding: 0 var(--space-6);
        background: var(--danger-ink);
        color: var(--white);
        font-weight: 600;
        font-size: var(--text-secondary-size-lg);
        border-radius: var(--radius-sm);
        text-decoration: none;
        box-shadow: var(--shadow-sm);
        transition: background var(--transition) var(--dashb-ease),
                    transform var(--transition) var(--dashb-ease),
                    box-shadow var(--transition) var(--dashb-ease);
      }
      .dashb-cta:hover { background: #991B1B; box-shadow: var(--shadow); }
      .dashb-cta:active { transform: scale(0.985); }
      .dashb-cta:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
      .dashb-cta__arrow { font-size: 18px; line-height: 1; transition: transform var(--transition) var(--dashb-ease); }
      .dashb-cta:hover .dashb-cta__arrow { transform: translateX(3px); }

      /* правый «счётчик» открытой записи — сколько просрочено */
      .dashb-entry--open .dashb-entry__result { padding-top: 4px; }
      .dashb-open-num {
        font-family: var(--font-display);
        font-size: clamp(2rem, 3.2vw, 2.5rem);
        font-weight: 800;
        line-height: 0.95;
        letter-spacing: -0.02em;
        color: var(--danger-ink);
        font-variant-numeric: tabular-nums;
      }
      .dashb-open-cap {
        margin-top: var(--space-2);
        font-size: var(--text-secondary-size);
        font-weight: 600;
        color: var(--danger-ink);
        white-space: nowrap;
      }

      /* =====================================================================
         РЕЙЛ «СОСТОЯНИЕ ЗА ПЕРИОД» — содержательная врезка в правой трети.
         Это и есть лекарство от воздуха: НЕ виджет, НЕ кольцо, НЕ график.
         Тихое число пульса + контекст словами + следующий шаг. Монохром
         navy/graphite, ОДИН аква-акцент на ссылке-шаге. Приборный тон.
         Липкий: состояние держится на виду, пока листаешь леджер.
         ===================================================================== */
      .dashb-rail {
        align-self: start;
        padding: var(--space-6) var(--space-6) var(--space-5);
        border: 1px solid var(--gray-border);
        border-top: 3px solid var(--brand-secondary);   /* приборная «шапка» врезки */
        border-radius: var(--radius-sm);
        background: var(--white);
      }
      .dashb-rail__overline {
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--graphite-60);
        margin: 0;
      }

      /* ПУЛЬС = тихое число рейтинга, БЕЗ кольца/дуги/спарклайна. Только тип. */
      .dashb-pulse {
        margin-top: var(--space-3);
        display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
      }
      .dashb-pulse__num {
        display: inline-flex; align-items: baseline; gap: 7px;
        font-family: var(--font-display);
        font-size: clamp(2.8rem, 4.4vw, 3.4rem);
        font-weight: 800;
        line-height: 0.92;
        letter-spacing: -0.025em;
        color: var(--graphite);
        font-variant-numeric: tabular-nums;
      }
      .dashb-pulse__star { color: #F5A623; font-size: 0.5em; line-height: 1; }
      .dashb-pulse__of {
        font-size: 1.05rem; font-weight: 700; color: var(--graphite-30);
        letter-spacing: 0;
      }
      .dashb-pulse__delta {
        display: inline-flex; align-items: baseline; gap: 4px;
        font-family: var(--font-sans);
        font-size: var(--text-secondary-size-lg);
        font-weight: 700;
        color: var(--success-ink);
        font-variant-numeric: tabular-nums;
        align-self: center;
      }
      .dashb-pulse__delta-arrow { font-size: 0.85em; }
      /* слово-диагноз под числом — пульс «контекстуализирован», не голый балл */
      .dashb-pulse__read {
        margin: var(--space-3) 0 0;
        font-size: var(--text-secondary-size-lg);
        line-height: 1.5;
        color: var(--graphite-text);
        max-width: 30ch;
      }

      /* контекст пульса — 2 строки «из чего складывается период», hairline-ряды */
      .dashb-rail__ctx { margin-top: var(--space-5); }
      .dashb-ctx {
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: baseline;
        column-gap: var(--space-4);
        padding: var(--space-3) 0;
        border-top: 1px solid var(--gray-border);
      }
      .dashb-ctx__n {
        font-family: var(--font-display);
        font-size: var(--text-xl);
        font-weight: 800;
        line-height: 1;
        color: var(--graphite);
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
      }
      .dashb-ctx__n .dashb-ctx__plus { color: var(--success-ink); font-size: 0.66em; font-weight: 700; margin-left: 3px; }
      .dashb-ctx__t {
        font-size: var(--text-secondary-size-lg);
        line-height: 1.45;
        color: var(--graphite-60);
      }
      .dashb-ctx__t b { color: var(--graphite); font-weight: 600; }

      /* V1+ · компактная сводка-список в рейле: больше метрик, та же ширина */
      .dashb-rail__stats { margin-top: var(--space-5); }
      .dashb-stat {
        display: flex; align-items: baseline; justify-content: space-between;
        gap: var(--space-4);
        padding: var(--space-2) 0;
        border-top: 1px solid var(--gray-border);
      }
      .dashb-stat__lbl { font-size: var(--text-secondary-size-lg); color: var(--graphite-60); }
      .dashb-stat__lbl--sub { padding-left: var(--space-4); color: var(--graphite-30); }
      .dashb-stat__val {
        font-weight: 700; color: var(--graphite);
        font-variant-numeric: tabular-nums; white-space: nowrap;
        font-size: var(--text-secondary-size-lg);
      }
      .dashb-stat__val .dashb-up { color: var(--success-ink); font-weight: 700; font-size: 0.85em; margin-left: 4px; }
      .dashb-stat__val--due { color: var(--danger-ink); }

      /* следующий шаг — единственный аква-акцент рейла, спокойная ссылка */
      .dashb-rail__next {
        margin-top: var(--space-5);
        padding-top: var(--space-5);
        border-top: 1px solid var(--gray-border);
      }
      .dashb-next__lbl {
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        color: var(--graphite-60);
        margin: 0 0 var(--space-2);
      }
      .dashb-next__text {
        margin: 0 0 var(--space-3);
        font-size: var(--text-secondary-size-lg);
        line-height: 1.5;
        color: var(--graphite-text);
        max-width: 32ch;
      }
      .dashb-next__text b { color: var(--graphite); font-weight: 600; font-variant-numeric: tabular-nums; }
      .dashb-next__link {
        display: inline-flex; align-items: center; gap: 6px;
        min-height: 44px;
        font-size: var(--text-secondary-size-lg);
        font-weight: 600;
        color: var(--brand-ink);
        text-decoration: none;
      }
      .dashb-next__link:hover { color: var(--brand-ink-hover); text-decoration: underline; }
      .dashb-next__link:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
      .dashb-next__arrow { transition: transform var(--transition) var(--dashb-ease); }
      .dashb-next__link:hover .dashb-next__arrow { transform: translateX(3px); }

      /* ── ПРАВАЯ КОЛОНКА = рейл «Состояние» + «Кто на виду» — заполняет низ-право ── */
      .dashb-side { min-width: 0; }
      .dashb-side-doctors {
        margin-top: var(--space-8);
        padding-top: var(--space-6);
        border-top: 1px solid var(--gray-border);
      }
      .dashb-side-doctors .dashb-col__intro { max-width: none; margin-bottom: var(--space-4); }

      /* ── НИЗ-А · ПО ФИЛИАЛАМ: горизонтальная полоса-сравнение с «разрывом» ──
         ДНК B2 — data-as-editorial, не зеркальная колонка. */
      .dashb-foot {
        margin-top: var(--space-12);
        padding-top: var(--space-8);
        border-top: 2px solid var(--brand-secondary);
      }
      .dashb-col__kicker {
        display: flex; align-items: baseline; justify-content: space-between;
        gap: 12px;
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--brand-ink);
        margin-bottom: var(--space-4);
      }
      .dashb-col__kicker a {
        font-family: var(--font-sans);
        letter-spacing: 0; text-transform: none;
        font-size: var(--text-secondary-size-lg);
        color: var(--brand-ink); text-decoration: none;
        display: inline-flex; align-items: center; gap: 5px;
        min-height: 44px; font-weight: 600;
      }
      .dashb-col__kicker a:hover { text-decoration: underline; }
      .dashb-col__kicker a .dashb-arrow { transition: transform var(--transition) var(--dashb-ease); }
      .dashb-col__kicker a:hover .dashb-arrow { transform: translateX(3px); }

      .dashb-col__intro {
        font-size: var(--text-secondary-size-lg);  /* 15px */
        line-height: 1.6;
        color: var(--graphite-text);
        margin: 0 0 var(--space-6);
        max-width: 64ch;
      }
      .dashb-col__intro b { color: var(--graphite); font-weight: 600; font-variant-numeric: tabular-nums; }

      .dashb-gap {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        align-items: center;
        gap: var(--space-6);
        padding: var(--space-2) 0 0;
      }
      .dashb-gap__pole { min-width: 0; }
      .dashb-gap__pole--lo { text-align: right; }
      .dashb-gap__name {
        font-size: var(--text-secondary-size-lg);
        font-weight: 600;
        color: var(--graphite);
      }
      .dashb-gap__rate {
        display: flex; align-items: baseline; gap: 6px;
        margin-top: 2px;
        font-family: var(--font-display);
        font-size: clamp(1.8rem, 3.2vw, 2.5rem);
        font-weight: 800;
        line-height: 1;
        letter-spacing: -0.02em;
        color: var(--graphite);
        font-variant-numeric: tabular-nums;
      }
      .dashb-gap__pole--lo .dashb-gap__rate { justify-content: flex-end; }
      .dashb-gap__star { color: #F5A623; font-size: 0.6em; line-height: 1; }
      .dashb-gap__sub {
        margin-top: var(--space-1);
        font-size: var(--text-secondary-size);
        color: var(--graphite-60);
        font-variant-numeric: tabular-nums;
      }
      .dashb-gap__sub .dashb-neg { color: var(--danger-ink); font-weight: 700; }
      .dashb-gap__mid {
        text-align: center;
        padding: 0 var(--space-2);
        border-left: 1px solid var(--gray-border);
        border-right: 1px solid var(--gray-border);
      }
      .dashb-gap__mid-lbl {
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--graphite-60);
      }
      .dashb-gap__mid-val {
        margin-top: 2px;
        font-family: var(--font-display);
        font-size: clamp(1.5rem, 2.6vw, 2rem);
        font-weight: 800;
        line-height: 1;
        color: var(--graphite);
        font-variant-numeric: tabular-nums;
      }

      /* ── ПЛАН ПО ОТЗЫВАМ · прогресс по целям переходов (TASK_305) ───────── */
      .dashb-targets { padding: var(--space-2) 0 0; }
      .dashb-target { min-width: 0; }
      .dashb-target + .dashb-target {
        margin-top: var(--space-3);
        padding-top: var(--space-3);
        border-top: 1px solid var(--gray-border);
      }
      .dashb-target__head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
      .dashb-target__plat {
        font-weight: 600;
        font-size: var(--text-secondary-size-lg);
        color: var(--graphite);
      }
      .dashb-target__branch { font-size: var(--text-secondary-size); color: var(--graphite-60); }
      .dashb-target__meta {
        margin-top: 2px;
        font-size: var(--text-secondary-size);
        color: var(--graphite-60);
        font-variant-numeric: tabular-nums;
      }
      /* Тонкий брендовый прогресс-бар (не капсула — radius 4px). */
      .dashb-target__bar {
        display: block;
        width: 100%; max-width: 360px; height: 8px;
        margin-top: var(--space-2);
        appearance: none; -webkit-appearance: none;
        border: none; border-radius: 4px; overflow: hidden;
        background: var(--gray-bg);
      }
      .dashb-target__bar::-webkit-progress-bar { background: var(--gray-bg); border-radius: 4px; }
      .dashb-target__bar::-webkit-progress-value { background: var(--brand-primary); border-radius: 4px; }
      .dashb-target__bar::-moz-progress-bar { background: var(--brand-primary); border-radius: 4px; }

      /* ── НИЗ-Б · КТО НА ВИДУ (врачи): вертикальный список НИЖЕ (ДНК B2) ──── */
      .dashb-doctors {
        margin-top: var(--space-12);
        padding-top: var(--space-8);
        border-top: 1px solid var(--gray-border);
      }
      .dashb-row {
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: baseline;
        gap: var(--space-4);
        padding: var(--space-3) 0;
      }
      .dashb-row + .dashb-row { border-top: 1px solid var(--gray-border); }
      .dashb-row__name {
        font-weight: 600;
        font-size: var(--text-secondary-size-lg);
        color: var(--graphite);
      }
      .dashb-row__sub {
        display: block; margin-top: 2px;
        font-size: var(--text-secondary-size);
        color: var(--graphite-60); font-weight: 400;
        font-variant-numeric: tabular-nums;
      }
      .dashb-row__metric {
        display: inline-flex; align-items: baseline; gap: 5px;
        white-space: nowrap; font-variant-numeric: tabular-nums;
      }
      .dashb-row__star { color: #F5A623; font-size: 13px; }
      .dashb-row__rating { font-weight: 700; font-size: var(--text-secondary-size-lg); color: var(--graphite); }

      /* ── ПОДВАЛ-ДЕЙСТВИЯ: тонкая полоса ссылок-рубрик (ДНК B2) ───────────── */
      .dashb-deck {
        margin-top: var(--space-12);
        padding-top: var(--space-5);
        border-top: 1px solid var(--gray-border);
        display: flex; flex-wrap: wrap; align-items: center;
        gap: 4px;
      }
      .dashb-deck__lbl {
        font-size: var(--text-secondary-size);
        color: var(--graphite-60);
        margin-right: var(--space-3);
        font-weight: 600;
      }
      .dashb-deck a {
        display: inline-flex; align-items: center;
        min-height: 44px;
        padding: 0 var(--space-3);
        font-size: var(--text-secondary-size-lg);
        font-weight: 600;
        color: var(--brand-ink);
        text-decoration: none;
        transition: color var(--transition) var(--dashb-ease);
      }
      .dashb-deck a:hover { color: var(--brand-ink-hover); text-decoration: underline; }
      .dashb-deck a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
      .dashb-deck__sep { color: var(--graphite-30); user-select: none; }

      /* ── EMPTY-STATE Астерии (день 0) — спокойный леджер «ещё не начато» (ДНК B2) ── */
      .dashb-demo-sep {
        margin: var(--space-16) 0 var(--space-6);
        padding-top: var(--space-5);
        border-top: 2px dashed var(--gray-border);
        font-size: var(--text-secondary-size);
        font-weight: 700;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--graphite-30);
      }
      .dashb-empty__overline {
        font-size: var(--text-secondary-size);
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--brand-ink);
      }
      .dashb-empty__lead {
        font-family: var(--font-display);
        font-size: clamp(1.5rem, 2.6vw, 2rem);
        font-weight: 700;
        line-height: 1.18;
        letter-spacing: -0.015em;
        color: var(--graphite);
        margin: var(--space-3) 0 0;
        max-width: 24ch;
      }
      .dashb-empty__text {
        margin: var(--space-4) 0 var(--space-6);
        font-size: var(--text-secondary-size-lg);
        line-height: 1.6;
        color: var(--graphite-text);
        max-width: 58ch;
      }
      .dashb-empty__cta {
        display: inline-flex; align-items: center; gap: 9px;
        min-height: 46px;
        padding: 0 var(--space-6);
        background: var(--brand-ink);
        color: var(--white);
        font-weight: 600;
        font-size: var(--text-secondary-size-lg);
        border-radius: var(--radius-sm);
        text-decoration: none;
        box-shadow: var(--shadow-sm);
        transition: background var(--transition) var(--dashb-ease), box-shadow var(--transition) var(--dashb-ease);
      }
      .dashb-empty__cta:hover { background: var(--brand-ink-hover); box-shadow: var(--shadow); }
      .dashb-empty__cta:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
      .dashb-empty__steps { list-style: none; margin: var(--space-8) 0 0; padding: 0; }
      .dashb-empty__step {
        display: grid; grid-template-columns: auto 1fr; align-items: baseline;
        column-gap: var(--space-4);
        padding: var(--space-4) 0;
        border-top: 1px solid var(--gray-border);
        font-size: var(--text-secondary-size-lg);
        font-weight: 600;
        color: var(--graphite);
      }
      .dashb-empty__num {
        font-variant-numeric: tabular-nums;
        font-weight: 800;
        font-family: var(--font-display);
        color: var(--graphite-30);
        min-width: 1.4ch;
      }
      .dashb-empty__step b { font-weight: 600; }
      .dashb-empty__hint {
        display: block; margin-top: 2px;
        font-size: var(--text-secondary-size);
        font-weight: 400; color: var(--graphite-60);
      }

      /* ── РЕСПОНСИВ ───────────────────────────────────────────────────────
         Планшет: разворот складывается — рейл уходит ПОД леджер (не вбок),
         перестаёт быть липким, разворачивается в горизонтальную ленту. */
      @media (max-width: 960px) {
        .dashb-spread { grid-template-columns: 1fr; gap: var(--space-10); }
        .dashb-rail {
          position: static;
          border-top-width: 3px;
        }
        /* на планшете контекст пульса встаёт в 2 колонки — лента, не столбик */
        .dashb-rail__ctx {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 0 var(--space-8);
        }
        .dashb-ctx:nth-child(2) { border-top: 1px solid var(--gray-border); }
      }
      @media (max-width: 720px) {
        .dashb-entry {
          grid-template-columns: 1fr;
          gap: var(--space-4);
        }
        .dashb-entry__result { justify-self: start; text-align: left; }
        .dashb-entry__num { justify-content: flex-start; }
        .dashb-entry__rcap { margin-left: 0; }
        .dashb-entry--open .dashb-entry__result { padding-top: 0; }
        .dashb-rail__ctx { grid-template-columns: 1fr; }
        .dashb-ctx:nth-child(2) { border-top: 1px solid var(--gray-border); }
      }
      @media (max-width: 560px) {
        .dashb-rail { padding-left: var(--space-5); padding-right: var(--space-5); }
        .dashb-dropcap { font-size: 3.8rem; }
        .dashb-gap { grid-template-columns: 1fr; gap: var(--space-4); text-align: left; }
        .dashb-gap__pole--lo { text-align: left; }
        .dashb-gap__pole--lo .dashb-gap__rate { justify-content: flex-start; }
        .dashb-gap__mid {
          border: 0; border-top: 1px solid var(--gray-border);
          border-bottom: 1px solid var(--gray-border);
          padding: var(--space-3) 0; text-align: left;
          display: flex; align-items: baseline; gap: 10px;
        }
        .dashb-gap__mid-val { margin-top: 0; }
        /* «Кто на виду» на узком экране: метрика не должна жаться к имени.
           Имя+sub слева растягиваются, рейтинг прижат к правому краю; multi-line
           имя ровняем по верху (а не по baseline метрики). TASK_NIGHT_02. */
        .dashb-row {
          gap: var(--space-2) var(--space-3);   /* 8px верт / 12px гориз — меньше зазор */
          align-items: start;
        }
        .dashb-row__metric { align-self: start; }
      }

      @media (prefers-reduced-motion: reduce) {
        .dashb-cta, .dashb-cta__arrow, .dashb-deck a, .dashb-next__arrow,
        .dashb-next__link, .dashb-col__kicker a .dashb-arrow, .dashb-empty__cta { transition: none; }
      }

/* ============================================================================
 * ВОЛНА 0 / ДИРЕКТИВА 2 (TASK_214) — мелкий вторичный текст: near-black + ступень.
 * Аддитивный перенос из _overrides.css. Мелко-вторичные .ms-* -> --text-secondary
 * (#1F2933, AA+) и +1 ступень размера. НЕ трогает функц. серый
 * (placeholder/disabled/select-arrow/.ms-tile-row__arrow/.ms-icon-chip--muted).
 * (.ms-cmp-muted вынесен на --graphite-30 явно — см. TASK_430 у строки объявления.)
 * Override'ы идут последними -> перебивают исходные --graphite-60 по cascade.
 * ============================================================================ */
.ms-hint,
.ms-hint-text {
  font-size: var(--text-secondary-size);
  color: var(--text-secondary);
}
.ms-text-muted { color: var(--text-secondary); }
.ms-text-xs { font-size: var(--text-secondary-size); }
.ms-page-header__meta,
.ms-tile-row__sub,
.ms-kpi-card__sublabel { color: var(--text-secondary); }
.ms-page-header__meta { font-size: var(--text-secondary-size-lg); }
.ms-tile-row__sub      { font-size: var(--text-secondary-size-lg); }
.ms-tile-row__sub--warn { color: var(--danger-ink); font-weight: 600; }  /* TASK_432 (§В): «просрочено» — сигнал, не приглушённый сабтайтл (после ВОЛНА-0 override по cascade) */
.ms-kpi-card__sublabel { font-size: var(--text-secondary-size); }
.ms-tile-row__meta { font-size: var(--text-secondary-size); color: var(--text-secondary); }
.ms-table--compare .ms-cmp-sub,
.ms-sig-card__ctx { font-size: var(--text-secondary-size); color: var(--text-secondary); }
.ms-stat-strip__lbl,
.ms-feed-row__time,
.ms-feed-row__meta,
.ms-mfeed-time { font-size: var(--text-secondary-size); color: var(--text-secondary); }
.ms-empty__text,
.ms-popover__why { color: var(--text-secondary); }
.ms-qr-card__code,
.qr-empty-note,
.qr-legacy summary { font-size: var(--text-secondary-size); color: var(--text-secondary); }

/* Директива 3 — мера прозы ≤65ch (как лендинг) */
.ms-prose p,
.ms-prose li { max-width: 65ch; }

/* Печать — near-black вторичный текст остаётся чёрным в ч/б */
@media print {
  .ms-text-muted,
  .ms-hint, .ms-hint-text,
  .ms-page-header__meta,
  .ms-tile-row__sub,
  .ms-tile-row__meta,
  .ms-kpi-card__sublabel,
  .ms-stat-strip__lbl,
  .ms-feed-row__time,
  .ms-feed-row__meta { color: var(--graphite) !important; }
}
/* ============================================================
   SETTINGS PANES (.set-*) — Settings 2.0 (промоут из mockup_settings_v2.html).
   Колонка контента = --set-w. Используются в панелях Настроек: Площадки/Конкуренты
   (TASK_185), Профиль/Клиника (187/188). Аддитивно, существующее не трогаем.
   ============================================================ */

/* TASK_627 (Б3): блочная модель слоя Настроек — третий случай подряд (после кнопок-ссылок
   и <summary> в TASK_626). Как только контейнеру блока задаётся явная ширина, к ней
   прибавляются поля и рамка: замерено — карточка width:100% с полями 24px и рамкой 2px
   перехлёстывает соседнюю колонку на 36px. Заводим один раз на контейнеры слоя, а не
   латаем по месту. Шире (весь [class^="set-"]) намеренно НЕ берём: у .set-order__btn
   28×28 есть рамка, border-box сжал бы кнопку на /survey/setup — это вне scope таска. */
.set-block, .set-subblock, .set-form, .set-reqform, .set-rows, .set-row, .nm-wrap { box-sizing: border-box; }
/* Тот же класс, четвёртый случай: у .tm-item (строка списка администраторов) стоит
   width:100% плюс поля 14px и левая рамка 3px — без border-box строка вылезает из списка
   ровно на 31px (замерено: +30 у .tm-item, +16 у .tm-item__meta на любой узкой ширине).
   Дефект существовал до пакета 2 (A/B со снятым классом карточек даёт те же числа). */
.tm-c, .tm-list, .tm-item, .tm-detail { box-sizing: border-box; }

/* Ритм блоков внутри панели (--space-7 НЕ существует — был баг слипания, см. tokens). */
.set-block + .set-block { margin-top: var(--space-8); padding-top: var(--space-8); border-top: 1px solid var(--gray-border); }

/* ============================================================
   TASK_627 пакет 2 (Р1–Р4, Р7): блок Настроек = карточка, карточки — в две колонки.
   Мокапы всех 10 вкладок согласованы владельцем 2026-07-29.

   Скоуп — ТОЛЬКО панель Настроек (.ms-ftabs__panel--set, модификатор ставит макрос
   settings_tabs). Класс .set-block живёт ещё на /survey/setup, /survey/questions,
   в аналитике филиала и на смене email — там вид не меняется.

   До правки Настройки были единственным разделом кабинета, свёрстанным плоской колонкой
   с горизонтальными линейками: у .set-block не было СВОЕГО правила вообще, только
   разделитель между блоками. Отсюда жалоба владельца «нет блоков, всё выглядит сырым».
   ============================================================ */

/* Р2. Две колонки — газетной укладкой, а не сеткой: в сетке соседи в ряду тянутся до одной
   высоты, и короткий блок стоял полупустым. Колонки укладывают блоки по фактической высоте.
   Внешняя рамка панели ОСТАЁТСЯ (решение владельца: «все должны быть в рамке»).

   Порог схлопа задан ШИРИНОЙ КОЛОНКИ, а не медиа-запросом по окну. Первая версия
   схлопывала по `@media (max-width: 900px)` — и это был тот же класс дефекта, который
   таск чинит в Р3 у .w406-grid («порог завязан на ширину ОКНА, а не карточки»): панель
   у`же вьюпорта на ~304px из-за бокового меню, поэтому на 901–1119px карточки выходили
   266–375px, и содержимое вылезало за рамку (замер на /settings: почта за правым краем
   карточки на +133px при 901, +71px при 1024, +23px при 1120) и наезжало на соседнюю.
   `columns: 420px 2` = «две колонки, но только если каждой хватает 420px»: браузер сам
   оставляет одну, когда панели мало, и порог автоматически совпадает с фактической
   геометрией при любой ширине бокового меню. Найденный замером пол — карточка ~415px. */
.ms-ftabs__panel--set { columns: 420px 2; column-gap: var(--space-4); }

/* Р1. Карточка — ровно оформление .ms-tile, а не своё: поверхность с лёгким градиентом,
   рамка 2px, тень, поля 24px. Владелец забраковал промежуточные варианты: белый фон +
   серая рамка + --shadow-sm («плоский») и рамку 1px («тонкая обводка смущает»). */
.ms-ftabs__panel--set > .set-block {
  /* box-sizing критичен: ширина 100% + поля 24px + рамка 2px без сброса дают перехлёст
     соседней колонки 36px (замерено). Сброс уже стоит на слое (Б3), здесь — причина. */
  width: 100%;
  /* Карточка — контейнер для запросов: раскладки внутри неё должны схлопываться по ЕЁ
     ширине, а не по ширине окна. Иначе повторяется дефект, который таск чинит в Р3:
     `.tm-c` схлопывалась по @media 760px и на вьюпорте 800 (карточка 442px) оставалась
     двухколоночной с деталью 94px — содержимое вылезало на +46px (замерено). */
  container-type: inline-size;
  margin: 0 0 var(--space-4);
  padding: var(--space-6);
  background: var(--surface-brand);
  border: 2px solid var(--brand-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  break-inside: avoid;
  -webkit-column-break-inside: avoid;   /* Safari до 16.4 понимает только префиксную форму */
}
/* Разделитель между блоками больше не нужен — границы несут карточки. */
.ms-ftabs__panel--set > .set-block + .set-block { margin-top: 0; padding-top: var(--space-6); border-top: none; }
/* Волосяная линия делит карточку на шапку и содержимое. */
.ms-ftabs__panel--set .set-block__title { padding-bottom: var(--space-3); border-bottom: 1px solid var(--brand-border); }
.ms-ftabs__panel--set .set-block__sub { margin-top: var(--space-3); }

/* Р5. Кнопка сохранения — в шапке карточки. Была в самом низу формы: чтобы сохранить,
   надо доскроллить до конца блока (замерено: 328px от верха карточки). В шапке она
   всегда на виду и всегда в одном месте на любой вкладке.
   Линия при этом переезжает с заголовка на строку шапки целиком — иначе она обрезается
   по ширине текста заголовка. */
.ms-ftabs__panel--set .set-block__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--brand-border);
  flex-wrap: wrap;   /* узкая карточка: кнопка уходит под заголовок, а не режет его */
}
.ms-ftabs__panel--set .set-block__head .set-block__title { padding-bottom: 0; border-bottom: 0; }
.ms-ftabs__panel--set .set-block__head > .ms-btn { flex: 0 0 auto; }

/* Р3. Блоки, чьё содержимое физически не влезает в половину (487px под контент), — на всю
   ширину. Замерено, а не на глаз: .nm-matrix имеет min-width 560px; .tm-c (список 280px +
   карточка участника) требует ~700px и в половине вылетал за карточку на 211px; .w406-grid
   держит порог схлопа на ширине ОКНА (@media 860px), а не карточки, поэтому в 535px колонки
   жались до ~230px и QR наезжал на кнопку. */
.ms-ftabs__panel--set > .set-block--wide { column-span: all; }

/* Р4. Две колонки нужны только там, где есть ЧТО в них ставить — то есть минимум два узких
   блока. Если узкий блок один (Команда, Виджет: остальные широкие) или блок вообще один
   (Площадки, Маршрутизация, Конкуренты) — колонка одна, а узкая карточка держит ширину по
   содержимому. Иначе получается ровно то, с чего таск начался: поля жмутся слева на 640px,
   справа мёртвая зона, а действие в шапке уезжает за 400px от полей.
   Селектор читается как «нет двух узких блоков подряд среди детей панели». Через
   :only-of-type делать нельзя — ломается, как только в панели появится любой другой div. */
.ms-ftabs__panel--set:not(:has(> .set-block:not(.set-block--wide) ~ .set-block:not(.set-block--wide))) { columns: auto 1; }
.ms-ftabs__panel--set:not(:has(> .set-block:not(.set-block--wide) ~ .set-block:not(.set-block--wide))) > .set-block:not(.set-block--wide) {
  max-width: calc(var(--set-w) + var(--space-6) * 2 + 4px);   /* колонка контента + поля + рамка */
}

/* ============================================================
   Р9. Свой выпадающий список (.msel) вместо нативного <select>.
   Владелец потребовал взять под контроль РАСКРЫТЫЙ перечень: у нативного select его
   рисует ОС, CSS до него не достаёт. Стрелка нативного списка к тому же нарисована
   оттенком из давно убранной палитры — отсюда ощущение «начала 2000-х».

   Механика — нативный <details> + радио внутри (идиома проекта, ср. .set-details, .fin-seg).
   Работает БЕЗ JS: перечень раскроется и выбор уйдёт в форму даже при отключённых
   скриптах. JS (msel.js) добавляет только удобство — закрыть после выбора, подставить
   значение в заголовок, закрыть по клику мимо и по Esc.
   Размер «Б» (выбран владельцем): поле 40px, текст 15px — вровень с кнопками;
   строка перечня 34px. На тач-устройствах поле дорастает до 44px.
   Промоут из mockups/select_size.html (вариант sz-m). ============================================================ */
.msel { position: relative; max-width: 320px; }
.msel > summary {
  /* box-sizing обязателен: у <summary> он не сброшен, и min-height складывается
     с отступами и рамкой (46 + 22 + 4 = 72px вместо 46). Тот же капкан, что с
     кнопками-ссылками в TASK_626 и с блочной моделью слоя .set-* (Б3). */
  box-sizing: border-box;
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  min-height: 40px; padding: 9px 13px;
  font-size: var(--text-sm); color: var(--graphite);
  border: 2px solid var(--brand-border-strong); border-radius: var(--radius-sm);
  background: var(--surface-brand);
  box-shadow: var(--shadow);
  transition: box-shadow var(--transition) ease, border-color var(--transition) ease;
}
.msel > summary::-webkit-details-marker { display: none; }
.msel > summary:hover { box-shadow: var(--shadow-lg); }
.msel > summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.msel__chev { flex: 0 0 auto; color: var(--brand-ink); transition: transform var(--transition) ease; }
.msel[open] > summary { border-color: var(--brand-ink); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.msel[open] .msel__chev { transform: rotate(180deg); }
.msel__panel {
  position: absolute; left: 0; right: 0; z-index: 5;   /* перечень всплывает поверх содержимого, как у нативного */
  margin-top: -2px; padding: 5px;
  background: var(--white);
  border: 2px solid var(--brand-ink); border-top: 0;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  box-shadow: var(--shadow-lg);
  max-height: 320px; overflow-y: auto;   /* 11 вариантов «Срока реакции» не должны уезжать за экран */
}
.msel__opt {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border-radius: 2px; cursor: pointer;
  font-size: var(--text-sm); line-height: 1.3; color: var(--graphite);
}
.msel__opt input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.msel__opt:hover { background: var(--brand-primary-light); }
.msel__opt:has(input:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.msel__tick { flex: 0 0 auto; color: var(--brand-ink); visibility: hidden; display: inline-flex; }
.msel__opt:has(input:checked) { background: var(--brand-primary-light); font-weight: 600; color: var(--brand-ink); }
.msel__opt:has(input:checked) .msel__tick { visibility: visible; }
@media (pointer: coarse) {
  .msel > summary { min-height: 44px; }
  .msel__opt { padding-top: 10px; padding-bottom: 10px; }
}

/* Р9.1. Сегменты внутри карточки Настроек — вариант «Д» (выбран владельцем 2026-07-30
   по мокапу select_pick.html, семь вариантов).

   Жалоба: «кнопки невыразительные, сливаются, не видно выбора». Причина в коде: .fin-seg
   рисовался для «Оплаты», где фон вокруг белый, и выбранный там отличался белой заливкой
   на сером контейнере. Внутри новой карточки поверхность сама светлая (--surface-brand) —
   и эта пара почти перестала различаться.

   Решение складывает два уже существующих в продукте приёма, а не заводит третий:
   рамка контейнера — аква 2px, как у активной вкладки («здесь выбирают»);
   выбранный — заливка --brand-ink с белым текстом («выбрано вот это»), контраст 5.80:1.
   Заливка аква с белым текстом сюда не годится: 2.49:1, и токен --brand-primary прямо
   подписан «НЕ под белый текст».

   Скоуп — только панель Настроек: на «Оплате» сегменты остаются прежними (деньги, в проде). */
.ms-ftabs__panel--set .fin-seg {
  background: var(--white);
  border: 2px solid var(--brand-border-strong);
  padding: 4px; gap: 4px;
}
.ms-ftabs__panel--set .fin-seg__opt { color: var(--graphite); }
.ms-ftabs__panel--set .fin-seg__opt:has(input:checked) {
  background: var(--brand-ink); color: var(--white); font-weight: 700; box-shadow: none;
}

/* Р7. Строки списка внутри карточки — тоже с объёмом, иначе на объёмной карточке они
   оставались плоскими. Тень СЛАБЕЕ, чем у карточки: строка лежит на карточке, а не парит. */
.ms-ftabs__panel--set .set-row { border-color: var(--brand-border); box-shadow: var(--shadow-sm); }
.ms-ftabs__panel--set .set-row:hover { border-color: var(--brand-border-strong); box-shadow: var(--shadow); }
/* TASK_588.2: якорь-скролл к сохранённому блоку (#blk-*) не прячет его под липкую шапку. */
.set-block[id^="blk-"] { scroll-margin-top: 72px; }
.set-block__title { margin: 0; font-size: var(--text-lg); font-weight: 700; color: var(--graphite); letter-spacing: -.011em; }
/* TASK_570: узкий числовой инпут для процентов-нормативов */
.set-input--pct { max-width: 140px; }
.set-block--lead .set-block__title { position: relative; padding-left: 14px; }
.set-block--lead .set-block__title::before { content: ''; position: absolute; left: 0; top: .16em; bottom: .16em; width: 4px; border-radius: var(--radius-sm); background: var(--brand-primary); }
.set-block__sub { margin: 6px 0 18px; font-size: var(--text-sm); color: var(--graphite-60); max-width: var(--set-w); line-height: 1.55; }
.set-subblock { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--gray-border); }
.set-subblock__title { margin: 0 0 12px; font-size: var(--text-sm); font-weight: 700; color: var(--brand-secondary); }
.set-reg__sub { margin: 0 0 12px; }
.set-reg-links { display: flex; flex-wrap: wrap; gap: 8px; }

/* key-value (Профиль: Email/Роль) */
/* TASK_308: длинный email — одно «слово» без пробелов — не даёт 1fr-колонке сжаться
   (min-width:auto) → горизонтальный overflow. minmax(0,1fr) + перенос чинит.
   TASK_627: раньше это лечение стояло только под @media (max-width: 640px), то есть по
   ширине ОКНА. Как только карточка стала у`же окна (две колонки в панели), почта полезла
   за рамку карточки на любой «широкой» ширине окна — замер: +133px при вьюпорте 901.
   Правило теперь безусловное; в узком окне остаётся только сужение метки до 120px. */
.set-kv { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 10px 16px; font-size: 14px; max-width: var(--set-w); }
.set-kv dt { color: var(--graphite-60); margin: 0; }
.set-kv dd { color: var(--graphite); margin: 0; font-weight: 500; overflow-wrap: anywhere; }
@media (max-width: 640px) { .set-kv { grid-template-columns: 120px minmax(0, 1fr); } }

/* Карточка филиала (вкладка Филиалы) */
.set-bcard__head { margin-bottom: 18px; }
.set-bcard__name { font-size: var(--text-base); font-weight: 700; color: var(--graphite); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.set-bcard__meta { font-size: var(--text-xs); color: var(--graphite-60); margin-top: 6px; line-height: 1.5; }

/* Строки-сущности (площадки) */
.set-rows { max-width: var(--set-w); }
.set-row { display: flex; align-items: center; gap: 14px; padding: 13px 15px; border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); transition: border-color var(--transition) ease; }
.set-row + .set-row { margin-top: 8px; }
.set-row__body { flex: 1 1 auto; min-width: 0; }
.set-row__name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-weight: 600; color: var(--graphite); font-size: 14px; }
.set-row__meta { font-size: 12px; color: var(--graphite-60); margin-top: 3px; line-height: 1.45; overflow-wrap: anywhere; }
.set-row__actions { display: flex; gap: 8px; flex: 0 0 auto; }
@media (max-width: 560px) {
  .set-row { flex-wrap: wrap; }
  .set-row__body { flex-basis: 100%; }
  .set-row__actions { width: 100%; justify-content: flex-end; }
}

/* Тег + статус-индикаторы (Подключено / Настраивается / Скоро) */
.set-tag { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 2px; font-size: var(--text-xs); font-weight: 600; letter-spacing: .01em; background: var(--brand-primary-light); color: var(--brand-ink); }
.set-tag--warn { background: var(--warning-light); color: var(--warning-ink); }  /* TASK_432 (§В): «Деактивирован» — оранжевый текст на aqua-фоне был latent; свой warn-фон */
.set-state { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-xs); font-weight: 600; line-height: 1.3; }
.set-state--ok { color: var(--success-ink); }
.set-state--warn { color: var(--warning-ink); }
.set-state--soon { color: var(--graphite-60); }
.set-state--warn::before, .set-state--soon::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.set-ico { flex: 0 0 auto; }
.set-plat-dot { width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; display: inline-block; }

/* Формы настроек + раскрывашка «+ Добавить» */
.set-form { max-width: var(--set-w); display: flex; flex-direction: column; gap: 16px; }
.set-form .ms-form-group { margin: 0; }
.set-details > summary { list-style: none; cursor: pointer; display: inline-block; }
.set-details > summary::-webkit-details-marker { display: none; }
.set-details[open] > summary { margin-bottom: 14px; }
.set-details--mt { margin-top: 14px; }
/* TASK_386.1: узкий селект порога перехвата + отступ формы режима под ним. */
.set-select-narrow { max-width: 320px; }
.set-form--mt { margin-top: 14px; }
/* TASK_399: реквизиты — единая ширина колонки (как .set-form, а не хардкод 560px) + липкая «Сохранить». */
.set-reqform { max-width: var(--set-w); }
.set-reqform--mt { margin-top: 14px; }
.set-sticky-save { position: sticky; bottom: 0; margin-top: 24px; padding: 12px 0; background: var(--white); }
/* TASK_400 — палитра свотчей цвета рамки листовки (значение --sw задаёт JS; здесь только раскладка+состояние). */
.ms-fsw-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-2); }
.ms-fsw { width: 30px; height: 30px; padding: 0; border: 2px solid var(--white); border-radius: var(--radius-sm); box-shadow: 0 0 0 1px var(--gray-border); background: var(--sw, var(--brand-primary)); cursor: pointer; transition: transform var(--transition-fast); }
.ms-fsw:hover { transform: scale(1.1); }
.ms-fsw[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--brand-ink); }
.ms-input-hex { max-width: 180px; }

/* TASK_389.3: живой предпросмотр вопроса опроса «как увидит пациент» (HTMX-swap по вводу). */
.sqprev { max-width: var(--set-w); margin-top: 16px; background: var(--white); border: 1px solid var(--brand-border); border-radius: var(--radius-sm); padding: 16px 18px; box-shadow: var(--shadow-sm); }
.sqprev__cap { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--graphite-30); margin-bottom: 10px; }
.sqprev__prompt { font-size: var(--text-lg); font-weight: 650; color: var(--graphite); line-height: 1.35; margin-bottom: 14px; overflow-wrap: anywhere; }
.sqprev__scale { display: flex; gap: 8px; margin-bottom: 8px; }
.sqprev__num { flex: 1; text-align: center; padding: 10px 0; border: 1px solid var(--brand-border); border-radius: var(--radius-sm); background: var(--brand-primary-light); color: var(--brand-ink); font-weight: 600; font-size: 14px; }
.sqprev__ends { display: flex; justify-content: space-between; gap: 12px; font-size: 12px; color: var(--graphite-60); }

/* Филиал-фильтр под заголовком (демотирован, не третий заголовок) */
.set-branchbar { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.set-branchbar__label { font-size: 12px; font-weight: 600; color: var(--graphite-60); }
.set-branchbar .ms-tabs { margin: 0; }

/* Режим показа площадок (радио-карточки). Живое превью пути — в .ms-jp-* ниже (TASK_395.1). */
.set-modewrap { display: flex; gap: 28px; flex-wrap: wrap; align-items: flex-start; max-width: var(--set-w); }
.set-modewrap .set-choice { grid-template-columns: 1fr; flex: 1 1 290px; gap: 8px; }
.set-choice { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: var(--set-w); }
.set-choice label { display: block; padding: 13px 15px; border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); cursor: pointer; transition: border-color var(--transition) ease, box-shadow var(--transition) ease, background var(--transition) ease; }
.set-choice label:hover { border-color: var(--brand-border-strong); }
.set-choice input { margin-right: 8px; }
.set-choice label:has(input:checked) { border-color: var(--brand-primary); box-shadow: inset 0 0 0 1px var(--brand-primary); background: var(--brand-primary-light); }
.set-choice b { display: block; font-size: var(--text-sm); color: var(--graphite); margin-bottom: 4px; }
.set-choice span { font-size: var(--text-xs); color: var(--graphite-60); line-height: 1.45; display: block; }
@media (max-width: 760px) { .set-choice { grid-template-columns: 1fr; } .set-modewrap .set-choice { flex-basis: 100%; } }
/* ============================================================
   JOURNEY PREVIEW (.ms-jp-*) — read-only фильмстрип пути пациента на /survey/setup (TASK_395.1).
   Промоут из mockups/journey_unified_preview.html (.jp-* → .ms-jp-*). Только реальные токены
   (шкала graphite схлопнута: есть лишь --graphite и --graphite-30). Заливки с белым текстом →
   --ms-jp-accent (акцент клиники, contrast-safe) с fallback --brand-ink (text-safe, НЕ аква).
   Полоса .ms-jp-strip — иллюстрация (aria-hidden). ============================================ */
.ms-jp .set-block__title { margin-bottom: 10px; }
.ms-jp .ms-insight-bar { margin-bottom: 12px; }
.ms-jp-legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: var(--text-sm); color: var(--graphite); margin: 0 0 14px; }
.ms-jp-legend b { color: var(--graphite); }
.ms-jp-legend__pos b { color: var(--success-ink); }
.ms-jp-legend__neg b { color: var(--danger-ink); }

.ms-jp-strip { display: flex; gap: 14px; overflow-x: auto; padding: 4px 2px 12px; }
.ms-jp-phone { flex: 0 0 176px; margin: 0; }
.ms-jp-phone__step { font-size: 11px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--graphite-30); margin-bottom: 7px; }
.ms-jp-phone--pos .ms-jp-phone__step { color: var(--success-ink); }
.ms-jp-phone--neg .ms-jp-phone__step { color: var(--danger-ink); }
.ms-jp-phone__screen { display: flex; flex-direction: column; min-height: 290px; padding: 14px 12px; background: var(--white); border: 1.5px solid var(--gray-border); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); }
.ms-jp-phone__brandhead { font-size: 11px; font-weight: 600; text-align: center; color: var(--graphite); padding-bottom: 9px; border-bottom: 1px solid var(--gray-border); margin-bottom: 12px; overflow-wrap: anywhere; }
.ms-jp-phone__q { font-size: 13px; font-weight: 600; text-align: center; line-height: 1.3; margin: 6px 0 10px; color: var(--graphite); }
.ms-jp-phone__q--sub { font-size: 12px; font-weight: 500; margin-top: 10px; }
.ms-jp-phone__stars { display: flex; justify-content: center; gap: 3px; color: #F5A623; margin-bottom: 8px; } /* design-lint: ignore — янтарь звёзд #F5A623, стандарт проекта (.ms-star-full/.ms-cmp-star), токена нет */
.ms-jp-phone__scale { display: flex; justify-content: center; gap: 4px; margin: 4px 0 2px; }
.ms-jp-phone__scale span { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; color: var(--graphite); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); }
.ms-jp-phone__scale .is-picked { background: var(--ms-jp-accent, var(--brand-ink)); color: var(--white); border-color: transparent; }
.ms-jp-phone__ends { display: flex; justify-content: space-between; font-size: 10px; color: var(--graphite-30); margin: 2px 2px 0; }
.ms-jp-phone__cap { font-size: 11px; text-align: center; color: var(--graphite); line-height: 1.35; margin-bottom: 9px; }
.ms-jp-phone__cap b { color: var(--graphite); }
.ms-jp-phone__cap--muted { color: var(--graphite-30); margin: auto 0; }
.ms-jp-phone__foot { margin-top: auto; padding-top: 9px; font-size: 10px; text-align: center; color: var(--graphite-30); }
.ms-jp-phone__done { margin: auto; text-align: center; }
.ms-jp-phone__done svg { color: var(--success-ink); margin-bottom: 8px; }
.ms-jp-pbtn { padding: 8px; margin-bottom: 6px; text-align: center; font-size: 12px; font-weight: 600; color: var(--graphite); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); }
.ms-jp-pbtn--primary { background: var(--ms-jp-accent, var(--brand-ink)); border-color: var(--ms-jp-accent, var(--brand-ink)); color: var(--white); }
.ms-jp-input { padding: 7px 8px; margin-bottom: 6px; font-size: 11px; color: var(--graphite-30); border: 1px solid var(--gray-border); border-radius: var(--radius-sm); }
.ms-jp-input--area { min-height: 44px; }
/* Экран 2: раскладка площадок = сохранённый режим; живой свитч по радио — CSS :has() на общем
   предке .ms-ftabs__panel (тот же паттерн, что снятый .set-modewrap:has). CSP-safe (чистый CSS). */
.ms-jp-layout { display: none; }
.ms-ftabs__panel:has(input[name="display_mode"][value="dominant"]:checked) .ms-jp-layout--dominant { display: block; }
.ms-ftabs__panel:has(input[name="display_mode"][value="single"]:checked) .ms-jp-layout--single { display: block; }
.ms-ftabs__panel:has(input[name="display_mode"][value="equal"]:checked) .ms-jp-layout--equal { display: block; }
/* TASK_394.3a: блок «показ площадок» на /survey/setup — вынос inline-стилей (перенос из destinations). */
.set-primary-group { margin-top: 16px; }
.set-primary-opt { display: flex; gap: 8px; align-items: center; margin-top: 8px; cursor: pointer; }
.set-savebtn { margin-top: 14px; }
/* TASK_394.3b: порядок площадок — стрелки ↑↓ (a11y-база) + drag (прогрессивное улучшение). */
.set-order { list-style: none; margin: 8px 0 0; padding: 0; max-width: var(--set-w); }
.set-order__row { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border: 1px solid var(--gray-border); border-radius: 3px; margin-bottom: 7px; background: var(--white); }
.set-order__row--primary { background: var(--gray-bg); }
.set-order__name { font-size: 13.5px; font-weight: 600; color: var(--graphite); }
.set-order__badge { font-size: 11px; font-weight: 600; color: var(--brand-ink); border: 1px solid var(--brand-ink); border-radius: 2px; padding: 1px 6px; }
.set-order__arrows { margin-left: auto; display: inline-flex; gap: 4px; }
.set-order__btn { width: 28px; height: 28px; display: grid; place-items: center; font-size: 14px; line-height: 1; background: var(--white); color: var(--graphite); border: 1px solid var(--gray-border); border-radius: 3px; cursor: pointer; }
.set-order__btn:hover:not(:disabled) { background: var(--gray-bg); }
.set-order__btn:disabled { opacity: 0.4; cursor: default; }
/* Drag (survey_reorder.js): курсор-хват + подсветка перетаскиваемой/целевой строки. */
.set-order--draggable .set-order__row:not(.set-order__row--primary) { cursor: grab; }
.set-order__row.is-dragging { opacity: 0.5; }
.set-order__row.is-dragover { border-color: var(--brand-primary); }

/* Переключатель еженедельного отчёта (TASK_193). Кнопка-форма (POST+303, без JS,
   CSP-safe): состояние из server-side aria-pressed, не из input:checked. ARIA toggle-button. */
.set-toggle { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: var(--text-sm); color: var(--graphite); background: none; border: none; padding: 0; font-family: inherit; text-align: left; min-height: 44px; }/* TASK_590.2: тач-таргет 44px (трек 40×22 не меняем, центрируем) */
.set-toggle__track { width: 40px; height: 22px; border-radius: var(--radius-full); background: var(--gray-border); position: relative; transition: background var(--transition) ease; flex: 0 0 auto; }/* TASK_401: --gray-mid→--gray-border — off-состояние видно (был почти невидим) */
.set-toggle__track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--white); box-shadow: var(--shadow-sm); transition: transform var(--transition) var(--ease-tab, ease); }
.set-toggle[aria-pressed="true"] .set-toggle__track { background: var(--brand-ink); }/* TASK_503.4: аква→чернила — ON контрастнее и в тон accent-color нативных чекбоксов */
.set-toggle[aria-pressed="true"] .set-toggle__track::after { transform: translateX(18px); }
.set-toggle__state { color: var(--text-secondary); }/* TASK_605: состояние тумблера словом — приглушённее подписи, но читаемо */
.set-toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: var(--radius-sm); }
/* TASK_627 (Б1): подпись и состояние — ОДИН flex-элемент .set-toggle__body. Были двумя
   детьми: на узкой ширине состояние встаёт отдельной колонкой, а подпись переносится под
   него (замер живой /settings/routing при 420px: тумблер 55px, состояние колонкой 87×54 —
   каша на самой юридически чувствительной настройке продукта). Блочный flex убирает из
   уравнения и baseline от inline-flex, из-за которой кнопка выступала за строку своего
   контейнера. Правило висит на :has(), а не на модификаторе: тумблеры без подписи
   (ячейки матрицы уведомлений, «Команда») должны остаться центрированными inline-flex. */
.set-toggle:has(.set-toggle__body) { display: flex; align-items: flex-start; }
.set-toggle:has(.set-toggle__body) .set-toggle__track { margin-top: 2px; }   /* трек — по первой строке подписи, а не по центру блока */
.set-toggle__body { flex: 1 1 auto; min-width: 0; }
/* TASK_627 (Б2): у .ms-hint отступ сверху −8px намеренный (подтягивает пояснение под поле),
   но рассчитан на ОДНОСТРОЧНОГО соседа. Там, где перед подсказкой стоит не поле, а тумблер
   с многострочной подписью или таблица-матрица, абзац въезжает в соседа — замерено на живых
   страницах: перехлёст 8px на /settings/routing (и на 1440, и на 420) и 8px на
   /settings/notifications (низ таблицы 1558 против верха абзаца 1550). Гасим минус ровно
   в этих двух случаях, сам −8px у полей не трогаем. */
form:has(.set-toggle) + .ms-hint,
.nm-wrap + .ms-hint { margin-top: var(--space-3); }
/* TASK_401 (А8): нативные чекбоксы/радио красятся брендом, а не OS-синим. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--brand-ink); }

/* Уведомления → матрица «событие × канал» (TASK_392). Одна сетка вместо weekly-тоггла
   и карточек каналов. Ячейка = set-toggle (переопределяем gap на 0 — метки нет). Узкий
   экран — горизонтальный скролл (min-width), страница по горизонтали не едет. */
.nm-wrap { overflow-x: auto; max-width: var(--set-w); }
.nm-matrix { width: 100%; border-collapse: collapse; min-width: 560px; }
.nm-matrix th, .nm-matrix td { text-align: left; padding: 0; }
.nm-matrix thead th { padding: 0 10px 12px; vertical-align: bottom; border-bottom: 1.5px solid var(--gray-border); }
.nm-matrix .nm-ch { text-align: center; }
.nm-ch__name { font-size: var(--text-sm); font-weight: 600; display: block; color: var(--graphite); }
.nm-ch__st { font-size: var(--text-xs); font-weight: 500; margin-top: 3px; display: inline-block; }
.nm-ch__st--ok { color: var(--success-ink); }
.nm-ch__st--soon { color: var(--graphite-30); }
.nm-ch__form { margin-top: 5px; }
.nm-ch__code { display: block; margin-top: 6px; font-size: var(--text-xs); font-weight: 400; color: var(--graphite-60); line-height: 1.4; }
/* TASK_631: QR привязки MAX. Белая подложка обязательна — модули чёрные, а тёмная тема
   или цветная карточка съели бы контраст и сканер перестал бы брать код. */
.nm-ch__qr { display: block; margin: 8px auto 0; width: 128px; height: 128px; background: var(--white); padding: 5px; border: 1px solid var(--gray-border); border-radius: 3px; }
.nm-ch__open { margin-top: 6px; }
.nm-matrix tbody tr { border-bottom: 1px solid var(--gray-border); }
.nm-ev { padding: 14px 14px 14px 2px; max-width: 360px; }
.nm-ev__name { font-size: var(--text-sm); font-weight: 600; display: block; color: var(--graphite); }
.nm-ev__meta { font-size: var(--text-xs); color: var(--graphite-60); margin-top: 2px; display: block; line-height: 1.35; }
.nm-cell { text-align: center; width: 96px; }
.nm-toggle { gap: 0; justify-content: center; min-height: 44px; min-width: 44px; }/* TASK_590.2: тач-таргет ячейки матрицы 44×44 */
.nm-soon { color: var(--graphite-30); font-size: var(--text-sm); }

/* Вкладка «Команда» (TASK_316) — мастер-деталь администраторов филиалов.
   Промоут из mockups/team_roles/team_komanda_c.html. SSR-выбор через ?admin= /
   ?action=invite — НЕ JS-панели (как folder_tabs). */
/* TASK_627: minmax(0,…) на обеих колонках. Было `280px 1fr`: у 1fr min-width:auto, поэтому
   содержимое детали (почта одним словом, ряды кнопок) не давало колонке сузиться, и деталь
   вылезала за границы контейнера — на «Команде» в карточке замерено +102px при 1024
   (до карточек было +48px, поля карточки вылет удвоили). Схлоп в одну колонку на ≤760px
   ниже остаётся: minmax только разрешает колонкам сжиматься, счёт колонок не меняет. */
.tm-c { display: grid; grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: 20px; align-items: start; margin-top: 4px; }
.tm-c > * { min-width: 0; }
/* Слева — компактный список администраторов */
.tm-list { border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); overflow: hidden; }
.tm-list__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--gray-border); }
.tm-list__head .ms-label { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--graphite-60); }
.tm-list__count { font-size: 12px; color: var(--graphite-60); font-weight: 500; }
.tm-item { display: block; width: 100%; text-align: left; appearance: none; background: none; border: 0; border-bottom: 1px solid var(--gray-border); border-left: 3px solid transparent; padding: 11px 14px; cursor: pointer; font-family: inherit; color: var(--graphite); text-decoration: none; transition: var(--transition); }
.tm-item:last-child { border-bottom: 0; }
.tm-item:hover { background: var(--gray-bg); }
.tm-item.is-active { background: var(--gray-bg); border-left-color: var(--graphite); }
.tm-item__name { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.tm-item__meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; font-size: 12px; color: var(--graphite-60); }
.tm-item__br { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tm-dot { flex: 0 0 auto; width: 6px; height: 6px; border-radius: var(--radius-full); background: var(--graphite-60); }
.tm-dot--on { background: var(--brand-primary); }
.tm-dot--inv { background: #C9A227; }
.tm-dot--off { background: var(--gray-mid); }
/* Справа — панель деталей */
.tm-detail { border: 1px solid var(--gray-border); border-radius: var(--radius-sm); background: var(--white); padding: 22px 24px; }
.tm-detail__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; border-bottom: 1px solid var(--gray-border); padding-bottom: 16px; margin-bottom: 18px; }
.tm-detail__name { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.012em; color: var(--graphite); }
.tm-detail__role { margin: 5px 0 0; font-size: 13px; color: var(--graphite-60); }
.tm-state { font-size: 12px; font-weight: 600; color: var(--graphite-60); display: inline-flex; align-items: center; gap: 6px; }
.tm-state--on { color: var(--graphite); }
.tm-state--inv { color: #7A5E00; }
/* Строка тумблера в детали */
.tm-switchrow { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin: 18px 0; padding: 14px 0; border-top: 1px solid var(--gray-border); border-bottom: 1px solid var(--gray-border); max-width: var(--set-w); }
.tm-switchrow__t { font-size: 14px; font-weight: 600; color: var(--graphite); }
.tm-switchrow__d { margin: 4px 0 0; font-size: 13px; color: var(--graphite-60); line-height: 1.5; max-width: 32ch; }
.tm-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.tm-empty { color: var(--graphite-60); font-size: 14px; }
@media (max-width: 760px) {
  .tm-c { grid-template-columns: 1fr; }
  .tm-list { order: 1; }
  .tm-detail { order: 2; }
}
/* TASK_627: та же раскладка, но по ширине КАРТОЧКИ (контейнер объявлен на
   .ms-ftabs__panel--set > .set-block). Мастер-деталь требует 280px списка + ~300px детали,
   то есть ~600px контента = ~660px карточки; ниже — одна колонка. Медиа-запрос выше этого
   не ловит: на вьюпорте 800 окно «широкое», а карточка 442px. */
@container (max-width: 660px) {
  .tm-c { grid-template-columns: minmax(0, 1fr); }
  .tm-list { order: 1; }
  .tm-detail { order: 2; }
}

/* ============================================================
   ВОЛНА 1 — системные компоненты ДС (promotion_queue 1.1–1.4).
   ТОЛЬКО определения классов (аддитивно): живые шаблоны НЕ переключены —
   это Волна 2 (отдельные таски). Имена новые → существующие .ms-* не задеты.
   Источник: docs/research/cabinet_design_2026-06-16/promotion_queue.md.
   ============================================================ */

/* Волна 1 (1.1): канонический .ms-summary-strip — на базе .ms-stat-strip (:793).
   Материал --surface-brand, хайрлайн-делители, __num navy (НЕ задаём font-family
   явно — наследует Golos через --font-sans, иначе ложный single-font detect).
   Потребитель — Волна 2 (billing/branches/analytics/negative/dashboard сводки). */
.ms-summary-strip {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: 0;
  margin: 0 0 var(--space-4);
  border: 1px solid var(--gray-border); border-radius: var(--radius-md);
  background: var(--surface-brand); overflow: hidden;
}
.ms-summary-strip__cell {
  flex: 1 1 0; min-width: 140px;
  padding: var(--space-4) var(--space-5);
  border-left: 1px solid var(--gray-border);   /* хайрлайн-делитель между ячейками */
}
.ms-summary-strip__cell:first-child { border-left: 0; }
.ms-summary-strip__kicker {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--graphite-60); margin-bottom: 4px;
}
.ms-summary-strip__num {
  font-size: 22px; font-weight: 700; color: var(--brand-secondary);
  line-height: 1; letter-spacing: -0.012em; font-variant-numeric: tabular-nums;
}
.ms-summary-strip__lbl { display: block; margin-top: 3px; font-size: var(--text-secondary-size); color: var(--text-secondary); }

/* Волна 1 (1.2): плоский статус-тег .ms-status (точка-маркер + sentence-case).
   ⛔ gate владельца (тег-vs-капсула) — НЕ заменяем .ms-badge, добавлен рядом
   нейтральной версией. Семантика статусов (оплачен/активен/просрочен/пробный) и
   цветовые модификаторы — за владельцем (см. promotion_queue 1.2). */
.ms-status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px; border-radius: 2px;
  font-size: var(--text-xs); font-weight: 600; text-transform: none;
  color: var(--text-secondary); background: var(--gray-mid);
}
.ms-status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--graphite-60); flex: none;
}

/* Волна 1 (1.3): .ms-focus-panel — danger-led панель (крупная цифра + CTA).
   Severity через box-shadow inset (НЕ border-left). Вариант --ok = спокойный
   brand-тон (мост к empty-state при негатив=0). Потребитель — Волна 2
   (dashboard/reviews/reports/negative). */
.ms-focus-panel {
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--gray-border); border-radius: var(--radius-md);
  box-shadow: inset 3px 0 0 var(--danger-ink);
  background: var(--white);
}
.ms-focus-panel--ok { box-shadow: inset 3px 0 0 var(--brand-secondary); }

/* Волна 1 (1.4): модификатор .ms-table--quiet-head — sentence-case th, прозрачный
   фон, нижняя граница. Глобальный .ms-table th (uppercase, :278) НЕ трогаем. */
.ms-table--quiet-head th {
  text-transform: none; letter-spacing: normal;
  background: transparent; font-weight: 600;
  border-bottom: 1px solid var(--gray-border);
}

/* ============================================================
   Панель владельца «Оценка визита по стадиям» (TASK_299.1).
   Бар-таблица: стадия · полоса · балл · тренд · число ответов.
   Без капсул (бренд-гайд); узкое место — амбер; тренд — зелёный/амбер.
   ============================================================ */
.ms-survey-agg { margin-top: var(--space-6); }
.ms-survey-agg__head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-1);
}
.ms-survey-agg__head .ms-filter-bar { margin: 0; }
.ms-survey-agg__sub {
  margin: 0 0 var(--space-4); color: var(--graphite-60); font-size: var(--text-sm); line-height: 1.5;
}
.ms-survey-agg__grid { display: flex; flex-direction: column; gap: var(--space-2); }
.ms-survey-agg__hrow,
.ms-survey-agg__row {
  display: grid;
  grid-template-columns: minmax(104px, 1.1fr) 1fr 40px 56px 62px;
  align-items: center; gap: var(--space-2);
}
.ms-survey-agg__hrow {
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--graphite-30); margin-bottom: var(--space-1);
}
.ms-survey-agg__hrow span:nth-child(3),
.ms-survey-agg__hrow span:nth-child(4),
.ms-survey-agg__hrow span:nth-child(5) { text-align: right; }
.ms-survey-agg__row { font-size: var(--text-sm); }
.ms-survey-agg__name { color: var(--graphite); }
.ms-survey-agg__bar { height: 9px; border-radius: 5px; background: var(--gray-border); overflow: hidden; }
/* TASK_393.1: двухцветная полоса доли позитива — зелёная доля 4-5★ поверх приглушённого
   негатив-фона (остаток = 1-3★). Спокойный медтон, не тревожный красный. */
.ms-survey-agg__bar--split { background: var(--danger-soft); }
.ms-survey-agg__pos { display: block; height: 100%; border-radius: 5px; background: var(--success); }
.ms-survey-agg__val { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--graphite-60); }
.ms-survey-agg__tr { text-align: right; font-size: var(--text-xs); font-weight: 600; font-variant-numeric: tabular-nums; }
.ms-survey-agg__tr--up { color: var(--success-ink); }
.ms-survey-agg__tr--down { color: var(--warning-ink); }
.ms-survey-agg__tr--flat,
.ms-survey-agg__tr--none { color: var(--graphite-30); }
.ms-survey-agg__split { text-align: right; font-size: var(--text-xs); font-variant-numeric: tabular-nums; color: var(--graphite-30); }
.ms-survey-agg__split-pos { color: var(--success-ink); font-weight: 600; }
.ms-survey-agg__split-neg { color: var(--danger-ink); font-weight: 600; }
.ms-survey-agg__row.is-low .ms-survey-agg__name { color: var(--warning-ink); font-weight: 600; }
.ms-survey-agg__note { margin: var(--space-4) 0 0; padding-top: var(--space-4);
  border-top: 1px solid var(--gray-border); font-size: var(--text-sm); color: var(--graphite-60); line-height: 1.55; }
.ms-survey-agg__empty { margin: 0; padding: var(--space-4) 0; color: var(--graphite-60); font-size: var(--text-sm); }

@media (max-width: 540px) {
  .ms-survey-agg__hrow,
  .ms-survey-agg__row { grid-template-columns: minmax(84px, 1fr) 36px 50px 58px; }
  .ms-survey-agg__bar { display: none; }
  .ms-survey-agg__hrow span:nth-child(2) { display: none; }
}

/* ===== Дропзона логотипа (.pf-*) — TASK_313: общий компонент =====
   Потребители: settings/brand.html (логотип клиники) + admin/partner_form.html (лого партнёра).
   Промоут из inline-CSS partner_form (анти-дубль). Лимиты/форматы — в шаблоне+JS. */
.pf-drop { display:flex; flex-direction:column; align-items:center; text-align:center; border:1.5px dashed var(--gray-border);
  border-radius: var(--radius); background: var(--gray-bg); padding: var(--space-8) var(--space-6); cursor:pointer;
  transition: border-color .15s ease, background-color .15s ease; }
.pf-drop:hover { border-color: var(--brand-ink); background: var(--white); }
.pf-drop.is-over { border-style:solid; border-color: var(--brand-primary); background: var(--brand-primary-light); }
.pf-drop__title { font-weight:600; font-size: var(--text-base); color: var(--graphite); margin-top: var(--space-3); }
.pf-drop__title u { color: var(--brand-ink); text-underline-offset:2px; }
.pf-drop__sub { font-size: var(--text-sm); color: var(--graphite-60); line-height:1.55; margin-top: var(--space-1); }
.pf-drop input[type=file] { display:none; }

.pf-file { display:none; align-items:center; gap: var(--space-4); border:1px solid var(--gray-border);
  border-radius: var(--radius); background: var(--white); padding: var(--space-3) var(--space-4); margin-top: var(--space-3); }
.pf-file.is-show { display:flex; }
.pf-file__thumb { width:56px; height:56px; flex:0 0 56px; border:1px solid var(--gray-border); border-radius: var(--radius-sm);
  object-fit:contain; background:var(--white); padding:5px; }
.pf-file__thumb--svg { display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:700;
  color: var(--brand-ink); background: var(--brand-primary-light); padding:0; }
.pf-file__body { flex:1 1 auto; min-width:0; }
.pf-file__name { font-weight:600; font-size: var(--text-sm); color: var(--graphite); word-break:break-all; }
.pf-file__meta { font-size: var(--text-xs); color: var(--graphite-60); margin-top:3px; }
.pf-file__meta.is-warn { color: var(--danger); font-weight:600; }
.pf-file__rm { appearance:none; border:1px solid var(--gray-border); background: var(--white); border-radius: var(--radius-sm);
  width:32px; height:32px; flex:0 0 32px; cursor:pointer; color: var(--graphite-60); font-size:18px; line-height:1; }
.pf-file__rm:hover { border-color: var(--danger); color: var(--danger); }

/* ============================================================================
 * CRM-ДАШБОРД / ГЛАВНАЯ (TASK_373) — перенос утверждённого вида + «Быстрый старт».
 * Скоуп .cdash (из app/static/mockups/dashboard_crm_*.html). Только аддитивно.
 * Токены 1-в-1 из мокапа (НЕ алиасить — значения отличаются от проектных).
 * ============================================================================ */
.cdash{
  --accent:#0AB5C5;--accent-ink:#00707E;--navy:#023F88;--accent-on:#06343a;--accent-hover:#09a3b2; /* design-lint: ignore — локальные токены дашборда, значения из утверждённого мокапа */
  --ink:#1A1A1A;--muted:#1A1A1A;--faint:#2A2E33;--border:#E2E5E7;--hair:#EDF0F3; /* design-lint: ignore */
  --bg:#EEF2F6;--panel:#fff;--panel-2:#FAFBFC;--row-hover:#FAFDFE; /* design-lint: ignore */
  --danger:#B91C1C;--danger-bg:#FEF2F2;--danger-border:#F4C6C6;--warn:#B45309;--warn-bg:#FFF7ED;--success:#15803D;--success-bg:#ECFDF3; /* design-lint: ignore */
  --tip-bg:#23292E;--neutral-seg:#8A949E;--guide:#9DA4AA;--accent-soft-bg:#E6F8FA;--accent-soft-border:#BDE8EC;--accent-tint:#F1FBFC;--alert-tint:#fff5f5; /* design-lint: ignore */
  --sh-sm:0 1px 2px rgba(16,24,40,.05),0 1px 1px rgba(16,24,40,.04);
  --sh-md:0 1px 2px rgba(16,24,40,.05),0 6px 16px -6px rgba(16,24,40,.12);
  --sh-pop:0 12px 30px -8px rgba(16,24,40,.22),0 3px 8px rgba(16,24,40,.08);
  --ease:cubic-bezier(0.23,1,0.32,1);
  display:flex;flex-direction:column;gap:16px;max-width:1240px;
  font-family:'Golos Text','Inter',system-ui,sans-serif;color:var(--ink);font-size:14px;line-height:1.45;
}
.cdash *{box-sizing:border-box}
.cdash .num{font-variant-numeric:tabular-nums}
.cdash a{color:inherit;text-decoration:none}

/* Pulse */
.cdash .pulse{background:var(--panel);border:1px solid var(--border);border-radius:3px;box-shadow:var(--sh-md);display:grid;grid-template-columns:repeat(5,1fr);overflow:hidden}
.cdash .pulse__cell{padding:15px 20px;border-right:1px solid var(--hair);position:relative}
.cdash .pulse__cell:last-child{border-right:0}
.cdash .pulse__k{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.cdash .pulse__v{font-size:28px;font-weight:800;letter-spacing:-.02em;margin-top:6px;line-height:1}
.cdash .pulse__v small{font-size:15px;font-weight:700;color:var(--faint);margin-left:2px}
.cdash .pulse__meta{font-size:12px;color:var(--muted);margin-top:6px}
.cdash .delta{font-weight:700;font-size:12px}
.cdash .delta--up{color:var(--muted)}
/* TASK_586.3: падение рейтинга печаталось со знаком минус, но красилось как рост. */
.cdash .delta--down{color:var(--danger-ink)}
/* TASK_586.1: CTA на плитке просрочки. Явное правило обязательно — .cdash a выше сбрасывает
   цвет и подчёркивание, без него ссылка неотличима от обычного текста. */
.cdash .pulse__cta{color:var(--brand-ink);font-weight:700}
.cdash .pulse__cta:hover{text-decoration:underline}
.cdash .pulse__cell--alert{background:linear-gradient(180deg,var(--panel) 0%,var(--alert-tint) 100%)}
.cdash .pulse__cell--alert .pulse__v{color:var(--danger)}
.cdash .pulse__cell--alert .pulse__k{color:var(--danger)}

/* Grid + panels */
.cdash .grid{display:grid;grid-template-columns:1.62fr 1fr;gap:16px;align-items:start}
.cdash .grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;align-items:stretch}
.cdash .col{display:flex;flex-direction:column;gap:16px;min-width:0}
.cdash .panel{background:var(--panel);border:1px solid var(--border);border-radius:3px;box-shadow:var(--sh-sm);overflow:hidden}
.cdash .panel--hero{box-shadow:var(--sh-md)}
.cdash .panel__head{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--hair)}
.cdash .panel__title{font-size:14.5px;font-weight:800;letter-spacing:-.01em}
.cdash .panel__tools{margin-left:auto;display:flex;align-items:center;gap:10px}
.cdash .panel__link{font-size:12.5px;font-weight:600;color:var(--accent-ink);display:inline-flex;align-items:center;gap:5px}
.cdash .panel__link:hover{text-decoration:underline}
.cdash .cnt{font-size:11px;font-weight:700;background:var(--hair);color:var(--muted);padding:2px 8px;border-radius:2px}

/* info-хинты «?» (#hintpop добавляется JS внутрь .cdash) */
.cdash .help{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;border:1px solid var(--border);background:var(--panel);color:var(--faint);font-family:inherit;font-size:10px;font-weight:700;line-height:1;cursor:pointer;padding:0;margin-left:6px;vertical-align:middle;text-transform:none;letter-spacing:0;transition:color 140ms var(--ease),border-color 140ms var(--ease)}
.cdash .help:hover,.cdash .help:focus-visible{color:var(--accent-ink);border-color:var(--accent);outline:none}
.cdash .hint-pop{position:fixed;max-width:264px;background:var(--tip-bg);color:var(--panel);font-size:12px;font-weight:400;line-height:1.45;padding:9px 12px;border-radius:3px;box-shadow:var(--sh-pop);opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity 140ms var(--ease),transform 140ms var(--ease);z-index:60}
.cdash .hint-pop.on{opacity:1;transform:translateY(0)}
.cdash .hint-pop::after{content:"";position:absolute;top:100%;left:var(--ax,50%);transform:translateX(-50%);border:5px solid transparent;border-top-color:var(--tip-bg)}

/* Flow chart */
.cdash .flow{padding:14px 18px 12px}
.cdash .flow__legend{display:flex;gap:10px;font-size:12px;color:var(--muted);margin:2px 0 6px}
/* TASK_585.3: пункты легенды — кнопки-тумблеры линий (сброс стилей button + состояния). */
.cdash .flow__legend .it{display:inline-flex;align-items:center;gap:6px;background:none;border:0;margin:0;padding:2px 5px;font:inherit;color:inherit;line-height:1.3;cursor:pointer;border-radius:4px}
.cdash .flow__legend .it:hover{background:var(--hair)}
.cdash .flow__legend .it:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.cdash .flow__legend .it[aria-pressed="false"]{opacity:.4}
.cdash .flow__legend .sw{width:10px;height:10px;border-radius:3px;background:var(--accent)}
.cdash .flow__legend .sw--pos{background:var(--navy)}
.cdash .flow__legend .sw--neg{background:var(--danger-ink)}
/* TASK_571: цель по доле негатива — норма (muted) / выше нормы (danger, полужирный). */
.cdash .flow__legend .flow__goal{color:var(--muted)}
.cdash .flow__legend .flow__goal--over{color:var(--danger-ink);font-weight:600}
.cdash .flowwrap{position:relative}
.cdash .flowwrap svg{display:block;width:100%;height:auto;overflow:visible;cursor:default}
.cdash .f-axis{font-size:11px;fill:var(--faint);font-family:inherit}
.cdash .f-reveal{clip-path:inset(0 100% 0 -1%);transition:clip-path 760ms var(--ease)}
.cdash .f-reveal.in{clip-path:inset(0 -2% 0 -1%)}
.cdash .f-marker{fill:var(--panel);stroke:var(--accent);stroke-width:2;transform-box:fill-box;transform-origin:center;transition:transform 140ms var(--ease)}
.cdash .f-marker.on{transform:scale(1.7)}
/* TASK_585.2: кружки Позитив/Негатив цветом линии, визуальные (не перехватывают hover). */
.cdash .f-dot{pointer-events:none}
.cdash .f-dot--pos{fill:var(--navy);opacity:.9}
.cdash .f-dot--neg{fill:var(--danger-ink);opacity:.9}
.cdash .f-guide{stroke:var(--guide);stroke-width:1.5;opacity:0;transition:opacity 120ms var(--ease)}
.cdash .f-guide.on{opacity:1}
.cdash .f-tip{position:absolute;top:0;left:0;pointer-events:none;z-index:9;background:var(--panel);border:1px solid var(--border);border-radius:3px;box-shadow:var(--sh-pop);padding:10px 12px;min-width:158px;opacity:0;transform:translateY(3px) scale(.98);transition:opacity 150ms var(--ease),transform 150ms var(--ease)}
.cdash .f-tip.on{opacity:1;transform:none}
.cdash .f-tip::after{content:"";position:absolute;left:50%;bottom:-5px;width:9px;height:9px;background:var(--panel);border-right:1px solid var(--border);border-bottom:1px solid var(--border);transform:translateX(-50%) rotate(45deg)}
.cdash .f-tip.below::after{top:-5px;bottom:auto;border:none;border-left:1px solid var(--border);border-top:1px solid var(--border)}
/* TASK_585.1: дата в шапке тултипа (раньше только в отдельном chip внизу → «дату не видно»). */
.cdash .f-tip-date{font-size:11.5px;font-weight:600;color:var(--muted);margin-bottom:6px}
.cdash .f-tip-v{font-size:20px;font-weight:800;letter-spacing:-.01em;line-height:1;margin-bottom:8px}
.cdash .f-tip-v .u{font-size:12px;font-weight:600;color:var(--muted);margin-left:4px}
.cdash .f-tip-row{display:flex;justify-content:space-between;gap:16px;font-size:12.5px;color:var(--muted);margin-top:4px}
.cdash .f-tip-row .val{color:var(--ink);font-weight:700}
.cdash .f-tip-row.sep{margin-top:7px;padding-top:7px;border-top:1px solid var(--hair)}
.cdash .f-chip{position:absolute;pointer-events:none;z-index:8;background:var(--tip-bg);color:var(--panel);font-size:11.5px;font-weight:600;padding:4px 9px;border-radius:3px;white-space:nowrap;opacity:0;transform:translate(-50%,2px);transition:opacity 130ms var(--ease),transform 130ms var(--ease)}
.cdash .f-chip.on{opacity:1;transform:translate(-50%,0)}

/* Distribution (SSR) */
.cdash .dist{padding:14px 18px 16px}
.cdash .dist__row{display:grid;grid-template-columns:36px 1fr 34px;gap:11px;align-items:center;margin-bottom:9px;font-size:13px}
.cdash .dist__row .s{font-weight:700;color:var(--ink)}
.cdash .dist__track{height:11px;background:var(--hair);border-radius:3px;overflow:hidden}
.cdash .dist__fill{display:block;height:100%;background:var(--accent);border-radius:3px}
.cdash .dist__row .c{text-align:right;color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums}
.cdash .dist__risk{display:flex;align-items:center;gap:8px;margin:1px 0 9px;font-size:11px;color:var(--faint)}
.cdash .dist__risk .ln{flex:1;height:1px;background:repeating-linear-gradient(90deg,var(--border) 0 5px,transparent 5px 9px)}

/* Routing */
.cdash .route{padding:16px 18px}
.cdash .route__bar{display:flex;height:34px;border-radius:3px;overflow:hidden;border:1px solid var(--border)}
.cdash .route__seg{display:flex;align-items:center;justify-content:center;color:var(--panel);font-weight:800;font-size:13px}
.cdash .route__seg--out{background:var(--accent);color:var(--accent-on)}
.cdash .route__seg--in{background:var(--neutral-seg);color:var(--ink)}/* TASK_396: белый на сером ~3:1 → тёмный текст */
.cdash .route__legend{display:flex;gap:18px;margin-top:13px}
.cdash .route__leg{flex:1}
.cdash .route__lk{font-size:12px;color:var(--muted);font-weight:600;display:flex;align-items:center;gap:7px}
.cdash .route__sw{width:11px;height:11px;border-radius:3px;flex:none}
.cdash .route__lv{font-size:21px;font-weight:800;letter-spacing:-.02em;margin-top:3px}
.cdash .route__lv small{font-size:12px;color:var(--faint);font-weight:700;margin-left:4px}
.cdash .route__note{margin-top:13px;padding:10px 12px;border-radius:3px;background:var(--panel-2);border:1px solid var(--hair);font-size:12px;color:var(--muted);line-height:1.4}

/* Переходы на площадки */
.cdash .src{padding:16px 18px}
.cdash .src__row{display:grid;grid-template-columns:120px 1fr 40px;gap:11px;align-items:center;margin-bottom:12px;font-size:13px}
.cdash .src__row:last-child{margin-bottom:0}
.cdash .src__n{font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cdash .src__track{height:11px;background:var(--hair);border-radius:3px;overflow:hidden}
.cdash .src__fill{display:block;height:100%;background:var(--accent);border-radius:3px}
.cdash .src__c{text-align:right;color:var(--muted);font-weight:700;font-variant-numeric:tabular-nums}
/* TASK_377 — неподключённая площадка: серым + ссылка «Вкл» → /settings/destinations */
.cdash .src__row--off .src__n{color:var(--faint);font-weight:500}
.cdash .src__row--off .src__track{background:var(--panel-2)}
.cdash .src__on{text-align:right;font-size:12px;font-weight:700;color:var(--accent-ink)}
.cdash .src__on:hover{text-decoration:underline}
.cdash .src__note{margin-top:14px;padding-top:12px;border-top:1px solid var(--hair);font-size:12.5px;color:var(--muted);line-height:1.4}
.cdash .src__note strong{color:var(--ink);font-weight:700}

/* Обращения (deals) */
.cdash .deals{width:100%;border-collapse:collapse}
.cdash .deals thead th{text-align:left;font-size:10.5px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.05em;padding:9px 18px;border-bottom:1px solid var(--hair);background:var(--panel-2)}
.cdash .deals tbody tr{border-bottom:1px solid var(--hair);cursor:pointer;transition:background 120ms var(--ease)}
.cdash .deals tbody tr:last-child{border-bottom:0}
.cdash .deals tbody tr:hover{background:var(--row-hover)}
.cdash .deals td{padding:12px 18px;vertical-align:middle}
.cdash .deal__id{font-weight:800;font-size:12.5px;color:var(--accent-ink)}
.cdash .deal__txt{font-weight:600;font-size:13.5px;color:var(--ink);line-height:1.3}
.cdash .deal__meta{font-size:12px;color:var(--muted);margin-top:4px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.cdash .deal__meta .sep{color:var(--border)}
.cdash .deal__doc{color:var(--ink);font-weight:600}
.cdash .sla{font-size:12.5px;font-weight:800;display:flex;flex-direction:column;gap:2px;line-height:1.15;text-align:right}
.cdash .sla small{font-size:10px;font-weight:600;color:var(--faint);text-transform:uppercase;letter-spacing:.04em}
.cdash .sla--over{color:var(--danger)}
.cdash .sla--soon{color:var(--ink)}
.cdash .sla--ok{color:var(--faint)}
.cdash .col-status{width:1%;white-space:nowrap}
.cdash .col-sla{width:1%;white-space:nowrap;text-align:right}
.cdash .col-act{width:1%;white-space:nowrap;text-align:right}/* TASK_398: колонка быстрого «Решено» */
.cdash .tag{display:inline-flex;align-items:center;font-size:10.5px;font-weight:700;letter-spacing:.02em;text-transform:uppercase;padding:3px 7px;border-radius:2px;border:1px solid transparent;white-space:nowrap}
.cdash .tag--over{background:var(--danger-bg);color:var(--danger);border-color:var(--danger-border)}
.cdash .tag--work{background:var(--hair);color:var(--ink);border-color:var(--border)}
.cdash .tag--done{background:var(--accent-soft-bg);color:var(--accent-ink);border-color:var(--accent-soft-border)}
.cdash .tag--rate{background:var(--panel);color:var(--accent-ink);border-color:var(--accent-soft-border);letter-spacing:0;font-weight:700}
.cdash .qs .tag{border-radius:3px}/* «Готово» в Быстром старте — под 3px блока, а не 2px статус-бейджей */

/* Rows (филиалы/врачи) + feed (последние ответы) */
.cdash .rows{padding:4px 0}
.cdash .row{display:flex;align-items:center;gap:12px;padding:11px 18px;border-bottom:1px solid var(--hair)}
.cdash .row:last-child{border-bottom:0}
.cdash .row__main{min-width:0;flex:1}
.cdash .row__name{font-weight:700;font-size:13.5px;line-height:1.2}
.cdash .row__sub{font-size:12px;color:var(--muted);margin-top:2px;display:flex;align-items:center;gap:8px}
.cdash .row__sub .sep{color:var(--border)}
.cdash .row__rate{font-weight:800;font-size:16px;letter-spacing:-.01em;display:flex;align-items:center;gap:4px;white-space:nowrap}
.cdash .minibadge{font-size:11px;font-weight:700;color:var(--muted);background:var(--hair);border:1px solid var(--border);border-radius:2px;padding:1px 6px;white-space:nowrap}
.cdash .row--gap{background:var(--panel-2)}
/* TASK_377 — «Смотреть все» футер-ссылка под списком (По филиалам/врачам) */
.cdash .rowmore{display:block;padding:9px 18px;font-size:12.5px;font-weight:600;color:var(--accent-ink);border-top:1px solid var(--hair)}
.cdash .rowmore:hover{background:var(--row-hover);text-decoration:underline}
.cdash .feed{padding:2px 0}
.cdash .feed__item{display:flex;gap:11px;padding:11px 18px;border-bottom:1px solid var(--hair)}
.cdash .feed__item:last-child{border-bottom:0}
.cdash .feed__dot{width:8px;height:8px;border-radius:2px;margin-top:6px;flex:none;background:var(--accent)}
.cdash .feed__t{font-size:13px;font-weight:600;line-height:1.35}
.cdash .feed__t b{font-weight:800;color:var(--accent-ink)}
.cdash .feed__m{font-size:11.5px;color:var(--faint);margin-top:2px}

/* Отзывы — статистика */
.cdash .rstat{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;padding:14px 18px}
.cdash .rstat__cell{padding:11px 12px;background:var(--panel);border-radius:2px}/* TASK_428 (А5): без border/shadow — не box-in-box; разделяет gap. Без перекраски. */
.cdash .rstat__v{font-size:23px;font-weight:800;letter-spacing:-.01em;line-height:1}
/* TASK_554 (§1.3): средняя оценка периода под числом. Монохром дашборда (★ не янтарь — цвет
   дашборд-звёзд supervised, см. --star). Вторичность — размером, не цветом. */
.cdash .rstat__avg{font-size:12.5px;font-weight:600;color:var(--faint);margin-top:4px;line-height:1}
.cdash .rstat__k{font-size:11px;color:var(--muted);font-weight:600;margin-top:6px;text-transform:uppercase;letter-spacing:.03em}
.cdash .rsub{padding:12px 18px 2px;font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.05em}
.cdash .rrate{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;padding:2px 18px 14px}
.cdash .rrate__cell{padding:9px 12px;background:var(--panel);border-radius:2px}/* TASK_428 (А5): без border/shadow — не box-in-box; разделяет gap */
.cdash .rrate__s{font-size:14px;font-weight:700;color:var(--ink)}
.cdash .rrate__v{font-size:20px;font-weight:800;letter-spacing:-.01em;line-height:1;margin-top:5px}
.cdash .rrate__p{font-size:11px;color:var(--muted);font-weight:600;margin-top:4px}

/* Кнопки (CTA быстрого старта) */
.cdash .btn{font-family:inherit;cursor:pointer;border:1px solid var(--border);background:var(--panel);color:var(--ink);font-weight:600;font-size:13px;padding:8px 15px;border-radius:3px;display:inline-flex;align-items:center;gap:7px;transition:all 140ms var(--ease);white-space:nowrap}
.cdash .btn:hover{background:var(--hair)}
.cdash .btn svg{stroke:currentColor}
.cdash .btn--primary{background:var(--accent);border-color:var(--accent);color:var(--accent-on);box-shadow:0 2px 8px -2px rgba(10,181,197,.5)}
.cdash .btn--primary:hover{background:var(--accent-hover);border-color:var(--accent-hover)}
.cdash .btn--primary:active{transform:scale(.98)}
.cdash .btn--sm{padding:6px 12px;font-size:12.5px}

/* Быстрый старт */
.cdash .startrow{display:grid;grid-template-columns:minmax(372px,0.92fr) 1.5fr;gap:16px;align-items:stretch}
.cdash .startrow .panel--hero{display:flex;flex-direction:column}
.cdash .startrow .flow{flex:1;display:flex;flex-direction:column;justify-content:flex-start}/* TASK_396: flex-start — убрать пустой провал над графиком */
/* TASK_390.3 / TASK_495: блок «Путь пациента» под «Пульсом» — сетка 2×6 всех 12 этапов, воронка строкой в футере. Локальные .cdash-токены. */
/* auto-fit: на узком экране две колонки этапов схлопываются в одну. */
.cdash .pjd__caprow{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:6px 12px;padding:14px 18px 0}
.cdash .pjd__cap{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin:0}
.cdash .pjd__total{font-size:13px;color:var(--muted)}
.cdash .pjd__total b{color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}
.cdash .pjd__total small{font-size:11px}
/* TASK_495.3: переключатель периода — тихие текст-кнопки, активная подчёркнута брендом (без пилюль). */
.cdash .pjd__per{display:inline-flex;gap:14px;margin-left:2px}
.cdash .pjd__perbtn{border:0;background:none;padding:0 0 2px;font:inherit;font-size:12px;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent}
.cdash .pjd__perbtn:hover{color:var(--ink)}
.cdash .pjd__perbtn--on{color:var(--ink);font-weight:700;border-bottom-color:var(--brand-primary)}
/* TASK_555: фильтр обращений по периоду (раскрытие списка) — тот же язык подчёркнутых таб-кнопок, что и период «Пути пациента». */
.cdash .tickets-filter{display:flex;flex-wrap:wrap;gap:14px;padding:14px 18px 8px;align-items:center}
/* TASK_586.8: подпись «Ранжировать по периоду» — ряд кнопок читался как фильтр «показать только». */
.cdash .tickets-filter__lbl{font-size:12px;font-weight:600;color:var(--muted);align-self:center}
.cdash .tickets-filter__btn{border:0;background:none;padding:0 0 2px;font:inherit;font-size:12px;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent}
.cdash .tickets-filter__btn:hover{color:var(--ink)}
.cdash .tickets-filter__btn.is-active{color:var(--ink);font-weight:700;border-bottom-color:var(--brand-primary)}
/* TASK_576: аффорданса «Показать телефоны» (справа) + ячейка действий строки (Позвонить + Решено). */
.cdash .tickets-filter__reveal{margin-left:auto;color:var(--ink);font-weight:600}
.cdash .deal__acts{display:flex;gap:8px;align-items:center;justify-content:flex-end}
.cdash .deal__noconsent{font-size:12px;color:var(--muted)}
.cdash .cdash-journey .pjd{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:0 24px;padding:12px 18px 8px}
.cdash .pjd__row{display:grid;grid-template-columns:126px 1fr 52px;align-items:center;gap:10px;margin-bottom:9px}
.cdash .pjd__n{font-size:13px;color:var(--ink)}
/* TASK_396: полоса «довольны/недовольны» по этапам — трек = недовольны (danger-soft), заливка = доля довольных (success). Эталон .ms-survey-agg__bar--split. */
.cdash .pjd__bar{height:8px;border-radius:3px;background:var(--danger-soft);overflow:hidden}
.cdash .pjd__bar i{display:block;height:100%;background:var(--success)}
.cdash .pjd__row--low .pjd__n{color:var(--warning-ink);font-weight:600}
.cdash .pjd__v{font-size:13px;font-weight:700;text-align:right;color:var(--ink);font-variant-numeric:tabular-nums}
/* TASK_495: этап без ответов — приглушённая строка, подпись внутри трека. */
.cdash .pjd__row--empty .pjd__n{color:var(--muted)}
.cdash .pjd__bar--na{display:flex;align-items:center;justify-content:center;height:14px;background:var(--hair)}
.cdash .pjd__bar--na em{font-style:normal;font-size:10px;line-height:1;color:var(--muted);letter-spacing:.02em}
.cdash .pjd__v--na{font-weight:500;color:var(--muted)}
/* TASK_495: этап с 1-2 ответами — приглушение (одиночный негатив не должен пугать). */
.cdash .pjd__row--thin .pjd__n{color:var(--muted)}
.cdash .pjd__row--thin .pjd__bar{opacity:.35}
.cdash .pjd__row--thin .pjd__v{color:var(--muted);font-weight:500;white-space:nowrap}
.cdash .pjd__row--thin .pjd__v small{font-size:10px;font-weight:500}
.cdash .pjd__note{font-size:12px;color:var(--muted);margin:0;padding:12px 18px 16px;border-top:1px solid var(--hair)}
.cdash .pjd__note--flow b{color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}
.cdash .pjd__note + .pjd__note--flow{border-top:0;padding-top:0;margin-top:-10px}
/* TASK_580: разрез «Сервис / Медицина» по опросу (средние 1-5, не доли) — подблок под стадиями. */
.cdash .pjd__dims{padding:10px 18px 4px;border-top:1px solid var(--hair)}
.cdash .pjd__dims .pjd__note{border-top:0;padding:6px 0 0}
/* TASK_586.7: Сервис/Медицина — средние баллы 1-5, а не доля довольных, как у этапов выше.
   Одинаковый зелёный читался как «та же метрика». Бренд-акцент разводит шкалы визуально.
   Текст берёт brand-ink: brand-primary по токен-правилу только под крупный декор. */
.cdash .pjd__dims .pjd__bar{background:var(--brand-primary-light)}
.cdash .pjd__dims .pjd__bar i{background:var(--brand-primary)}
.cdash .pjd__dims .pjd__n,.cdash .pjd__dims .pjd__v{color:var(--brand-ink)}
.cdash .qs{position:relative;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--border);border-radius:3px;box-shadow:var(--sh-md);overflow:hidden}
.cdash .qs__head{padding:15px 18px 13px 20px;border-bottom:1px solid var(--hair)}
.cdash .qs__title{font-size:15.5px;font-weight:800;letter-spacing:-.015em}
.cdash .qs__sub{font-size:12px;color:var(--muted);margin-top:3px;line-height:1.4}
.cdash .qs__sub b{color:var(--ink);font-weight:700}
.cdash .qs__meter{display:flex;align-items:center;gap:10px;margin-top:11px}
.cdash .qs__bar{flex:1;height:6px;background:var(--hair);border-radius:3px;overflow:hidden}
.cdash .qs__fill{display:block;height:100%;background:var(--accent);border-radius:3px;transition:width 600ms var(--ease)}
.cdash .qs__count{font-size:12px;font-weight:700;color:var(--ink);white-space:nowrap}
.cdash .qs__count .num{color:var(--accent-ink)}
.cdash .qs__list{list-style:none;flex:1}
.cdash .qs__step{display:flex;align-items:center;gap:11px;padding:9px 18px 9px 20px;border-bottom:1px solid var(--hair)}
.cdash .qs__step:last-child{border-bottom:0}
.cdash .qs__step.is-next{background:linear-gradient(90deg,var(--accent-tint) 0%,var(--panel) 70%)}
.cdash .qs__mark{width:22px;height:22px;border-radius:3px;flex:none;display:grid;place-items:center;font-size:11.5px;font-weight:800;font-variant-numeric:tabular-nums;border:1.5px solid var(--border);color:var(--muted);background:var(--panel)}
.cdash .qs__step.is-next .qs__mark{background:var(--navy);border-color:var(--navy);color:var(--panel)}
.cdash .qs__step.is-done .qs__mark{background:var(--accent);border-color:var(--accent);color:var(--accent-on)}
.cdash .qs__step.is-done .qs__name{color:var(--muted)}
.cdash .qs__body{flex:1;min-width:0}
.cdash .qs__name{font-size:13px;font-weight:700;line-height:1.25}
.cdash .qs__hint{font-size:11.5px;color:var(--muted);margin-top:1px;line-height:1.3}
.cdash .qs__act{flex:none}
.cdash .qs__foot{padding:9px 18px 11px 20px;border-top:1px solid var(--hair);display:flex;align-items:center;justify-content:space-between}
.cdash .qs__hintnote{font-size:11px;color:var(--faint)}
.cdash .qs__dismiss{border:0;background:transparent;color:var(--faint);font-family:inherit;font-size:12px;font-weight:600;cursor:pointer;padding:2px}
.cdash .qs__dismiss:hover{color:var(--muted);text-decoration:underline}

/* Пустые состояния (вариант C) */
.cdash .flowblank{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;padding:24px 24px 34px;text-align:center;position:relative;min-height:210px}
.cdash .flowblank__base{position:absolute;left:18px;right:18px;bottom:34px;height:1px;background:repeating-linear-gradient(90deg,var(--border) 0 6px,transparent 6px 11px)}
.cdash .flowblank__t{font-size:13px;font-weight:700;color:var(--muted)}
.cdash .flowblank__s{font-size:12px;color:var(--faint);max-width:300px;line-height:1.45}
.cdash .empty{padding:24px 18px;text-align:center}
.cdash .empty--row{padding:20px 18px}
.cdash .empty__t{font-size:13px;font-weight:700;color:var(--muted)}
.cdash .empty__s{font-size:12px;color:var(--faint);margin-top:4px;line-height:1.45}
.cdash .empty__s a{color:var(--accent-ink);font-weight:600}
/* доп. для шаблона (TASK_373.2) */
.cdash__head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:2px}
.cdash__title{font-size:18px;font-weight:800;letter-spacing:-.015em}
.cdash__crumb{font-size:12.5px;color:var(--faint)}
/* TASK_376 — чип подписки в шапке (рендерится внутри .cdash__head → токены .cdash наследуются) */
.cdash-subchip{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:600;padding:8px 16px;border-radius:3px;border:1px solid;margin-left:auto;white-space:nowrap;align-self:center}
/* TASK_427: на узких экранах чип переносится, не переполняя шапку (нет горизонтального скролла) */
@media (max-width: 540px) { .cdash-subchip { white-space: normal; margin-left: 0; } }
.cdash-subchip__ic{width:15px;height:15px;flex:none}
.cdash-subchip__ic svg{display:block;width:100%;height:100%}
.cdash-subchip__d{font-weight:500;opacity:.9}
.cdash-subchip--active{background:var(--success-bg);border-color:#CDEAD7;color:var(--success)} /* design-lint: ignore — бордер-хекс из утверждённого мокапа */
.cdash-subchip--trial{background:var(--accent-tint);border-color:var(--accent-soft-border);color:var(--accent-ink)}
.cdash-subchip--trialwarn{background:var(--warn-bg);border-color:#F2D9B0;color:var(--warn)} /* design-lint: ignore — бордер-хекс из утверждённого мокапа */
/* TASK_558: near-expiry платного периода — жёлтый (≤30д) / красный (≤14д) */
.cdash-subchip--paidwarn{background:var(--warning-light);border-color:var(--warning);color:var(--warning-ink)}
.cdash-subchip--paiddanger{background:var(--danger-light);border-color:var(--danger);color:var(--danger-ink)}
.cdash .startrow--full{grid-template-columns:1fr}
.cdash .row__star{color:var(--accent-ink)}
.cdash .qs form{display:contents}
.cdash .route__sw--out{background:var(--accent)}
.cdash .route__sw--in{background:var(--neutral-seg)}
/* TASK_377 — лид-строка под шапкой (рендерится внутри .cdash → токены наследуются) */
.cdash-lead{font-size:13px;color:var(--muted);margin:-6px 0 2px;line-height:1.5}
.cdash-lead strong{color:var(--ink);font-weight:700}
/* TASK_377 — «Быстрый переход по сервису» (owner-only, низ Главной) */
.cdash-nav{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}
.cdash-navcol{display:flex;flex-direction:column;gap:7px;min-width:0}
.cdash-navcol__h{font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.04em;padding:0 2px 2px}
.cdash-colbtn{display:flex;align-items:center;gap:9px;padding:8px 11px;border:1px solid var(--border);border-radius:3px;background:var(--panel);color:var(--ink);font-size:12.5px;font-weight:600;line-height:1.2;transition:background 140ms var(--ease)}/* TASK_432 (§В): 18 кнопок с полной aqua-обводкой перегружали — --accent→--border, аква осталась на icon-chip */
.cdash-colbtn:hover{background:var(--accent-tint)}
.cdash-colbtn__ic{display:grid;place-items:center;width:24px;height:24px;flex:none;border-radius:3px;background:var(--accent-soft-bg);color:var(--accent-ink)}
.cdash-colbtn__ic svg{width:15px;height:15px}

/* media */
@media(max-width:1120px){.cdash .grid3{grid-template-columns:1fr}.cdash .grid{grid-template-columns:1fr}.cdash .pulse{grid-template-columns:repeat(2,1fr)}.cdash .pulse__cell{border-right:0;border-bottom:1px solid var(--hair)}.cdash .pulse__cell:nth-child(odd){border-right:1px solid var(--hair)}.cdash .pulse__cell:last-child{border-right:0;border-bottom:0}.cdash .startrow{grid-template-columns:1fr}.cdash-nav{grid-template-columns:repeat(3,1fr)}}
/* TASK_396: на мобиле таблица «Обращения» не должна клиппить nowrap-колонку срока (.panel overflow:hidden) */
@media(max-width:600px){.cdash .deals thead th{padding-left:9px;padding-right:9px}.cdash .deals td{padding:10px 9px}.cdash .sla{font-size:11.5px}.cdash .tag{padding:2px 5px}}
@media(max-width:700px){.cdash-nav{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.cdash .rstat{grid-template-columns:repeat(3,1fr)}}
@media(max-width:460px){.cdash-nav{grid-template-columns:1fr}}
@media (prefers-reduced-motion: reduce){.cdash .f-reveal,.cdash .f-tip,.cdash .f-chip,.cdash .f-guide,.cdash .f-marker{transition:none}}

/* ============================================================================
 * Тост «шаг быстрого старта выполнен» (TASK_374) — глобальный оверлей кабинета,
 * НЕ внутри .cdash: рендерится в base.html на /qr, /doctors, /settings и т.д.
 * Вид 1-в-1 из утверждённого мокапа app/static/mockups/toast_demo.html.
 * Тайминг 4с (полоса + автозакрытие в quickstart_toast.js) — без inline --dur.
 * ============================================================================ */
.qstoast-wrap{position:fixed;top:18px;right:18px;z-index:var(--z-toast);display:flex;flex-direction:column;gap:10px;pointer-events:none;font-family:'Golos Text','Inter',system-ui,-apple-system,sans-serif}
.qstoast{position:relative;overflow:hidden;display:flex;align-items:flex-start;gap:12px;background:var(--brand-secondary);color:var(--white);padding:13px 14px 15px 13px;border-radius:3px;box-shadow:0 18px 44px -12px rgba(2,28,68,.5),0 5px 12px rgba(16,24,40,.18);font-size:14px;width:344px;pointer-events:auto;transform:translateX(125%);opacity:0;transition:transform .44s cubic-bezier(.22,1,.36,1),opacity .3s ease}
.qstoast.in{transform:translateX(0);opacity:1}
.qstoast.out{transform:translateX(125%);opacity:0;transition:transform .4s cubic-bezier(.4,0,1,1),opacity .4s ease}
.qstoast__ic{width:30px;height:30px;border-radius:3px;flex:none;background:var(--brand-primary);color:#063b42;display:grid;place-items:center;margin-top:1px} /* design-lint: ignore — ink на аква-чипе, значение из утверждённого мокапа */
.qstoast--done .qstoast__ic{background:#16d6c2;color:#053b39} /* design-lint: ignore — финальный «всё готово», значения из мокапа */
.qstoast__b{flex:1;min-width:0;padding-top:1px}
.qstoast__t{font-weight:700;line-height:1.3;letter-spacing:-.012em;font-size:14.5px}
.qstoast__s{font-size:12.5px;color:#b3c6e2;margin-top:3px;line-height:1.4} /* design-lint: ignore — подпись на navy, значение из мокапа */
.qstoast__x{flex:none;color:#8aa0c4;background:transparent;border:0;font-size:17px;line-height:1;cursor:pointer;padding:2px 3px;margin:-2px -2px 0 0;border-radius:3px} /* design-lint: ignore — приглушённый × на navy, значение из мокапа */
.qstoast__x:hover{color:var(--white);background:rgba(255,255,255,.12)}
.qstoast__bar{position:absolute;left:0;bottom:0;height:3px;width:100%;background:var(--brand-primary);transform-origin:left;transform:scaleX(1)}
.qstoast.in .qstoast__bar{transition:transform 4s linear;transform:scaleX(0)}
.qstoast--done{background:#053b39} /* design-lint: ignore — глубокий аква финала, значение из мокапа */
.qstoast--done .qstoast__s{color:#9fded6} /* design-lint: ignore — подпись финала, значение из мокапа */
.qstoast--done .qstoast__bar{background:#16d6c2} /* design-lint: ignore — полоса финала, значение из мокапа */
@media (prefers-reduced-motion:reduce){.qstoast,.qstoast.out{transition:opacity .2s ease}.qstoast.in .qstoast__bar{transition:none}}

/* Пагинация — единая обёртка (вынос из inline-flex reviews/negative; вид идентичен) */
.ms-pager { display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 16px; }
/* Ячейка текста отзыва — вынос inline max-width (вид идентичен) */
.ms-review-text { max-width: 400px; }

/* ============================================================
   TASK_418.4 — экран «Отчёт по репутации» (порт reports_rich_mockup)
   Лист-превью богатого PDF: letterhead + KPI + диаграммы + сравнения.
   ============================================================ */

.ms-rr-periods { display: inline-flex; gap: 6px; margin-right: 8px; }
.ms-page-header__actions.ms-rr-no-print { flex-wrap: wrap; row-gap: 8px; }

.ms-rr-sheet {
  max-width: 880px;
  background: var(--white);
  border: 1px solid var(--gray-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.ms-rr-lh {
  background: var(--brand-secondary);
  color: var(--white);
  padding: 20px 32px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
}
.ms-rr-lh__org { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.ms-rr-lh__sub {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.65);
  margin-top: 3px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}
.ms-rr-lh__period { text-align: right; font-size: 12.5px; color: rgba(255, 255, 255, 0.72); }
.ms-rr-lh__period b { display: block; font-size: 14px; color: var(--white); font-weight: 700; }

.ms-rr-body { padding: 24px 32px 28px; }

.ms-rr-sec {
  font-size: 15px;
  font-weight: 700;
  color: var(--brand-secondary);
  margin: 26px 0 10px;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 9px;
}
.ms-rr-sec::before {
  content: "";
  width: 4px;
  height: 15px;
  background: var(--brand-primary);
  border-radius: 2px;
}
.ms-rr-body > .ms-rr-sec:first-of-type { margin-top: 22px; }
.ms-rr-sub { font-size: 12.5px; color: var(--graphite-30); margin: -6px 0 12px; }
.ms-rr-empty { font-size: 13px; color: var(--graphite-30); margin: 4px 0 0; }
.ms-rr-chart svg { display: block; overflow: visible; }

.ms-rr-kpi {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.ms-rr-k {
  border: 1px solid var(--gray-border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.ms-rr-k__n { font-size: 24px; font-weight: 700; color: var(--brand-secondary); line-height: 1.05; }
.ms-rr-k__l { font-size: 12px; color: var(--graphite-60); margin-top: 6px; }
.ms-rr-k__d { font-size: 11.5px; margin-top: 4px; color: var(--graphite-30); }
.ms-rr-k__d.up { color: var(--brand-primary-dark); }
.ms-rr-k__d.down { color: var(--graphite-30); }

.ms-rr-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 26px;
}

.ms-rr-dist__row {
  display: grid;
  grid-template-columns: 26px 1fr 36px;
  gap: 10px;
  align-items: center;
  margin-bottom: 9px;
  font-size: 13px;
}
.ms-rr-dist__st { font-weight: 700; color: var(--brand-secondary); }
.ms-rr-dist__tr {
  height: 12px;
  background: var(--gray-mid);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.ms-rr-dist__fl {
  display: block;
  height: 100%;
  background: var(--brand-primary);
  border-radius: var(--radius-full);
}
.ms-rr-dist__c { text-align: right; color: var(--graphite-60); }

.ms-rr-rt__top { display: flex; justify-content: space-between; margin-bottom: 11px; }
.ms-rr-rt__n { font-size: 22px; font-weight: 700; color: var(--brand-secondary); line-height: 1; }
.ms-rr-rt__l { font-size: 12px; color: var(--graphite-60); margin-top: 5px; }
.ms-rr-rt__right { text-align: right; }
.ms-rr-rt__bar {
  display: flex;
  height: 14px;
  border-radius: var(--radius-full);
  overflow: hidden;
  background: var(--gray-mid);
}
.ms-rr-rt__bar i { height: 100%; }
.ms-rr-rt__pos { background: var(--brand-primary); }
.ms-rr-rt__neg { background: var(--graphite-30); }
.ms-rr-rt__leg {
  display: flex;
  justify-content: space-between;
  margin-top: 9px;
  font-size: 12px;
  color: var(--graphite-60);
}
.ms-rr-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: middle;
}
.ms-rr-dot--pos { background: var(--brand-primary); }
.ms-rr-dot--neg { background: var(--graphite-30); }

.ms-rr-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ms-rr-table th {
  text-align: left;
  font-weight: 600;
  color: var(--graphite-60);
  font-size: 12px;
  padding: 0 0 9px;
  border-bottom: 1px solid var(--gray-border);
}
.ms-rr-table th.r, .ms-rr-table td.r {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding-left: 10px;
}
.ms-rr-table td { padding: 10px 0; border-bottom: 1px solid var(--gray-mid); vertical-align: top; }
.ms-rr-table tr:last-child td { border-bottom: none; }
.ms-rr-table td.nm { font-weight: 600; }
.ms-rr-role { display: block; font-weight: 400; color: var(--graphite-60); font-size: 12px; margin-top: 1px; }

.ms-rr-foot {
  margin-top: 24px;
  padding-top: 14px;
  border-top: 1px solid var(--gray-border);
  font-size: 11.5px;
  color: var(--graphite-30);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

/* Зеркальные секции Главной (мокап reports_rich_mockup_v2, 505.5) */
.ms-rr-cap { font-size: 12.5px; color: var(--graphite-60); margin: 9px 2px 0; line-height: 1.5; }

/* TASK_587.4 — строка-статус рассылки отчёта (владелец видит, идёт ли письмо и куда). */
.ms-rr-sendinfo { font-size: 13px; color: var(--graphite-60); margin: 0 2px 16px; line-height: 1.5; }
.ms-rr-sendinfo a { color: var(--brand-ink); text-decoration: none; }
.ms-rr-sendinfo a:hover { text-decoration: underline; }

.ms-rr-rstat { grid-template-columns: repeat(6, 1fr); gap: 10px; }
.ms-rr-rstat .ms-rr-k { padding: 10px 8px; text-align: center; }
.ms-rr-rstat .ms-rr-k__n { font-size: 20px; }

.ms-rr-rrate { grid-template-columns: repeat(5, 1fr); gap: 10px; margin-top: 12px; }
.ms-rr-rrate .ms-rr-k { padding: 8px; text-align: center; background: var(--gray-mid); border-color: var(--gray-mid); }
.ms-rr-rrate__s { font-size: 11.5px; font-weight: 700; color: var(--brand-secondary); }
.ms-rr-rrate__n { font-size: 16px; font-weight: 700; margin-top: 2px; }
.ms-rr-rrate__p { font-size: 11px; color: var(--graphite-30); }

.ms-rr-pj-cap {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12.5px;
  color: var(--graphite-60);
  margin: -6px 0 12px;
}
.ms-rr-pj { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 26px; }
.ms-rr-pj__row {
  display: grid;
  grid-template-columns: 118px 1fr 52px;
  gap: 10px;
  align-items: center;
  font-size: 12.5px;
  min-height: 24px;
}
.ms-rr-pj__n { font-weight: 600; }
.ms-rr-pj__bar {
  display: block;
  height: 10px;
  background: var(--gray-mid);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.ms-rr-pj__bar i {
  display: block;
  height: 100%;
  background: var(--brand-primary);
  border-radius: var(--radius-full);
}
.ms-rr-pj__na { font-size: 11px; color: var(--graphite-30); }
.ms-rr-pj__v { text-align: right; color: var(--graphite-60); font-weight: 600; }
.ms-rr-pj__v small { font-weight: 400; color: var(--graphite-30); }
.ms-rr-pj__row--na .ms-rr-pj__n { color: var(--graphite-30); font-weight: 400; }
.ms-rr-pj__row--na .ms-rr-pj__v { color: var(--graphite-30); font-weight: 400; }
.ms-rr-pj__row--thin .ms-rr-pj__n { color: var(--graphite-60); font-weight: 400; }
.ms-rr-pj__row--thin .ms-rr-pj__bar { opacity: 0.35; }
.ms-rr-pj__row--low .ms-rr-pj__n { color: var(--warning-ink); font-weight: 700; }

.ms-rr-src__row {
  display: grid;
  grid-template-columns: 130px 1fr 32px;
  gap: 10px;
  align-items: center;
  margin-bottom: 9px;
  font-size: 13px;
}
.ms-rr-src__n { font-weight: 600; }

.ms-rr-tgt__row { margin-bottom: 12px; font-size: 13px; }
.ms-rr-tgt__hd { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 5px; }
.ms-rr-tgt__nm { font-weight: 600; }
.ms-rr-tgt__nm small { font-weight: 400; color: var(--graphite-60); }
.ms-rr-tgt__val { color: var(--graphite-60); }
.ms-rr-tgt__tr {
  display: block;
  height: 10px;
  background: var(--gray-mid);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.ms-rr-tgt__fl {
  display: block;
  height: 100%;
  background: var(--brand-secondary);
  border-radius: var(--radius-full);
}

@media (max-width: 680px) {
  .ms-rr-two { grid-template-columns: 1fr; }
  .ms-rr-kpi { grid-template-columns: repeat(2, 1fr); }
  .ms-rr-rstat { grid-template-columns: repeat(3, 1fr); }
  .ms-rr-rrate { grid-template-columns: repeat(5, 1fr); }
  .ms-rr-pj { grid-template-columns: 1fr; }
  .ms-rr-lh, .ms-rr-body { padding-left: 18px; padding-right: 18px; }
}

@media print {
  .ms-sidebar, .ms-sidebar__footer, .ms-rr-no-print { display: none !important; }
  .ms-main { margin-left: 0 !important; padding: 0 !important; }
  .ms-rr-sheet { box-shadow: none; border: none; max-width: none; }
  .ms-rr-lh, .ms-rr-dist__fl, .ms-rr-rt__pos, .ms-rr-rt__neg, .ms-rr-dot {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
  @page { margin: 12mm; }
}

/* TASK_627 (Р9): строка «филиал администратора + Сменить» — свой список рядом с кнопкой.
   Инлайновый flex из шаблона вынесен сюда (страж дизайн-токенов не пускает style=). */
.tm-reassign { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.tm-reassign .msel { flex: 1 1 220px; max-width: 280px; }
