@font-face {
    font-family: "Mulish";
    src: url("../fonts/mulish-400.3bd18e89443f.woff") format("woff");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Mulish";
    src: url("../fonts/mulish-500.c9b9f4e18569.woff") format("woff");
    font-style: normal;
    font-weight: 500;
    font-display: swap;
}

@font-face {
    font-family: "Mulish";
    src: url("../fonts/mulish-600.6b8460f69284.woff") format("woff");
    font-style: normal;
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: "Mulish";
    src: url("../fonts/mulish-700.e3c18cc7c415.woff") format("woff");
    font-style: normal;
    font-weight: 700;
    font-display: swap;
}

:root {
    --ink: #0b1623;
    --panel-dark: #0e1c2b;
    --steel-1: #2a3e54;
    --steel-2: #4c667a;
    --steel-3: #8ea1b4;
    --mist: #d9e0e7;
    --paper: #f4f6f8;
    --white: #ffffff;
    --line-soft: #e8edf1;
    /* Поверхности и линия, на которые ссылались блоки распределения,
       карточка контакта и пояснение к показателям. Величины не были
       объявлены, и правила с ними браузер отбрасывал целиком: блок
       оставался без фона и без рамки. */
    --surface: var(--white);
    --surface-2: #fafbfd;
    --line: var(--line-soft);
    --positive: #2f6f58;
    --positive-soft: #e7f1ec;
    --negative: #9b4242;
    --negative-soft: #f5eaea;
    --radius-small: 8px;
    --radius: 12px;
    --shadow-card: 0 8px 24px rgba(11, 22, 35, 0.045);
    --shadow-float: 0 12px 32px rgba(11, 22, 35, 0.09);
    --space-1: 8px;
    --space-2: 16px;
    --space-3: 24px;
    --space-4: 32px;
    --space-5: 40px;
    --content-max: 1680px;
    --sidebar-w: 252px;
    --fs-micro: 12px;
    --fs-meta: 12px;
    --fs-sm: 13px;
    --fs-base: 14px;
    --fs-lead: 15px;
    --fs-card: 16px;
    --fs-section: 20px;
    --fs-block: 24px;
    --fs-page: 26px;
    --lh-tight: 1.25;
    --lh-normal: 1.5;
    --lh-relaxed: 1.6;
    --shell-h: 100dvh;
}

* { box-sizing: border-box; }
html { min-height: 100%; background: var(--paper); }

body {
    min-height: 100vh;
    margin: 0;
    color: var(--ink);
    background: var(--paper);
    font-family: "Mulish", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.5;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--info, #2c5c86); outline-offset: 3px; }

.skip-link {
    position: fixed;
    z-index: 1000;
    top: 12px;
    left: 12px;
    padding: 10px 14px;
    border-radius: var(--radius-small);
    color: var(--white);
    background: var(--ink);
    transform: translateY(-160%);
}
.skip-link:focus, .skip-link:focus-visible { transform: translateY(0); outline: 3px solid #ffffff; outline-offset: 2px; }

/* Приложение занимает ровно окно. Прокручиваются колонки внутри, а не
   документ: иначе рабочая область уезжает вниз, а меню остаётся висеть
   отдельно приклеенным элементом. */
body.app { height: var(--shell-h); overflow: hidden; }
.app-shell {
    height: var(--shell-h);
    display: grid;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    overflow: hidden;
}
.sidebar {
    height: 100%;
    min-height: 0;
    /* Горизонтальные отступы живут на внутренних блоках: подсветка пункта
       должна отступать от края и от полосы прокрутки, а не упираться в них. */
    padding: 0;
    color: var(--mist);
    background: var(--ink);
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    overflow: hidden;
}
.link-button {
    min-height: 32px;
    margin-left: -8px;
    padding: 4px 8px;
    border: 0;
    border-radius: 4px;
    color: var(--steel-2);
    background: transparent;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    text-align: left;
}
.link-button { color: #b9c6d3; }
.link-button:hover { color: var(--white); background: rgba(255, 255, 255, 0.06); }

.content {
    min-width: 0;
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    padding: 40px clamp(24px, 3vw, 56px) 64px;
}
.content:focus { outline: none; }
.page-frame { width: 100%; max-width: var(--content-max); margin: 0 auto; }
.topbar {
    min-height: 72px;
    margin-bottom: 24px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 32px;
}
.topbar h1 {
    margin: 6px 0 0;
    /* Кегль объявлен ниже одним правилом: здесь он считался от ширины окна. */
    font-weight: 700;
    line-height: 1.16;
    letter-spacing: -0.03em;
}
.topbar-actions {
    min-height: 48px;
    padding-top: 2px;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 8px;
}
.eyebrow {
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 16px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}
.button {
    min-height: 44px;
    padding: 10px 18px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    color: var(--ink);
    background: var(--white);
    box-shadow: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 700;
    line-height: 22px;
    text-align: center;
    transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
}
.button:hover { border-color: var(--steel-3); background: var(--paper); }
.button.primary { color: var(--white); border-color: var(--ink); background: var(--ink); }
.button.primary:hover { border-color: var(--steel-1); background: var(--steel-1); box-shadow: var(--shadow-float); }
.button.danger { color: var(--white); border-color: var(--negative); background: var(--negative); }
.button.danger:hover { border-color: #813535; background: #813535; box-shadow: 0 10px 24px rgba(155, 66, 66, 0.2); }
.button.ghost { background: transparent; }
.button.full { width: 100%; }
.button.small { min-height: 36px; padding: 6px 12px; font-size: 12px; line-height: 20px; }
.action-cluster { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px; }
.action-cluster form { margin: 0; display: flex; }
.messages { margin-bottom: 24px; display: grid; gap: 8px; }
.message {
    padding: 12px 16px;
    border: 1px solid #c9dfd4;
    border-radius: var(--radius-small);
    color: var(--positive);
    background: var(--positive-soft);
    font-size: 14px;
}

.panel, .metric-card, .account-card {
    border: 1px solid var(--mist);
    border-radius: var(--radius);
    background: var(--white);
    box-shadow: var(--shadow-card);
}
.panel { overflow: hidden; }
.panel.narrow { max-width: 680px; padding: 32px; }
.panel-head {
    min-height: 84px;
    padding: 20px 24px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Заголовок и действие переносятся, когда в строку не помещаются:
       иначе действие выдавливается за край панели. */
    flex-wrap: wrap;
    gap: var(--space-1) 24px;
}
.panel-head > *:first-child { min-width: 0; }
.panel-head h2 {
    margin: 4px 0 0;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.015em;
}
.panel-head > a:not(.button) {
    flex: 0 0 auto;
    padding: 8px 0;
    color: var(--steel-2);
    font-size: 13px;
    font-weight: 700;
}
.panel-head > a:not(.button):hover { color: var(--ink); }

.metric-grid, .finance-metric-grid, .dashboard-grid, .finance-layout {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 24px;
}
.metric-grid, .finance-metric-grid { margin-bottom: 24px; }
.metric-grid .metric-card { grid-column: span 3; }
/* Карточка показателя раскладывается общей сеткой: доли из двенадцати
   давали в финансах свою ширину и свой промежуток, отличные от
   остального продукта. */
.metric-card {
    min-height: 164px;
    padding: 24px;
    display: flex;
    flex-direction: column;
}
.metric-card span { color: var(--steel-2); font-size: 13px; font-weight: 600; line-height: 20px; }
.metric-card strong {
    margin: auto 0 4px;
    font-size: clamp(20px, 2vw, 24px);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
}
.metric-card small { color: var(--steel-2); font-size: 12px; line-height: 18px; }
.metric-card.finance { color: var(--white); border-color: var(--ink); background: var(--ink); }
.metric-card.finance span, .metric-card.finance small { color: rgba(217, 224, 231, 0.78); }
.result-card { position: relative; }
.result-card::before {
    content: "";
    position: absolute;
    top: 20px;
    bottom: 20px;
    left: -1px;
    width: 4px;
    border-radius: 0 2px 2px 0;
    background: var(--positive);
}
.result-card.negative::before { background: var(--negative); }
.masked { letter-spacing: 0.08em; filter: blur(3px); user-select: none; }
.dashboard-grid > .panel:first-child { grid-column: span 8; }
.dashboard-grid > .panel:last-child { grid-column: span 4; }

.table-wrap { width: 100%; overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
th {
    padding: 12px 20px;
    color: var(--steel-2);
    border-bottom: 1px solid var(--line-soft);
    background: #fafbfd;
    font-size: 11px;
    font-weight: 700;
    line-height: 16px;
    letter-spacing: 0.08em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}
td {
    padding: 16px 20px;
    border-bottom: 1px solid var(--line-soft);
    font-size: 14px;
    line-height: 20px;
    vertical-align: middle;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:not(:has(.empty)):hover { background: #fafbfd; }
td a, td strong { color: var(--ink); font-weight: 700; }
td small { margin-top: 4px; color: var(--steel-2); display: block; font-size: 12px; line-height: 18px; }
.badge {
    min-height: 26px;
    padding: 4px 10px;
    border-radius: 999px;
    color: var(--steel-1);
    background: #e9eef2;
    display: inline-flex;
    align-items: center;
    font-size: 12px;
    font-weight: 700;
    line-height: 18px;
}
/* Поле пустой ячейки объявлено ниже одним правилом: здесь стояло 32 с той же
   пометкой важности, и два «важных» правила спорили друг с другом. */
.empty { color: var(--steel-2); text-align: center; }
.table-empty { height: 220px; }
.empty-content {
    max-width: 440px;
    margin: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.empty-content strong { color: var(--ink); font-size: 15px; font-weight: 700; }
.empty-content span { max-width: 380px; color: var(--steel-2); font-size: 13px; line-height: 20px; }
.empty-content .button { margin-top: 8px; }

.task-list { display: grid; }
.task-item { min-height: 72px; padding: 16px 22px; border-bottom: 1px solid var(--line-soft); display: grid; gap: 4px; }
.task-item:last-child { border-bottom: 0; }
.task-item:hover { background: #fafbfd; }
.task-item span { font-size: 14px; font-weight: 700; }
.task-item small { color: var(--steel-2); font-size: 12px; }
.task-item.row { grid-template-columns: 1fr auto; align-items: center; }
.task-item.row > div:last-child { display: flex; align-items: center; gap: 12px; }
.task-item.row .link-button { color: var(--steel-2); }

.filter-tabs, .deal-tabs, .finance-nav { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: thin; }
.filter-tabs, .deal-tabs { margin-bottom: 20px; }
.filter-tabs a, .deal-tabs a {
    min-height: 44px;
    padding: 10px 16px;
    border-radius: var(--radius-small);
    color: var(--steel-2);
    display: inline-flex;
    align-items: center;
    font-size: 14px;
    font-weight: 700;
    white-space: nowrap;
}
.filter-tabs a:hover, .deal-tabs a:hover { color: var(--ink); background: var(--white); }
.filter-tabs a.active, .deal-tabs a.active { color: var(--white); background: var(--ink); }
.deal-hero {
    min-height: 148px;
    margin-bottom: 20px;
    padding: 28px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 32px;
}
.deal-hero h2 { margin: 12px 0 6px; font-size: 24px; line-height: 1.25; }
.deal-hero p { margin: 0; color: var(--steel-2); }
.deal-hero dl { margin: 0; display: flex; gap: 40px; }
.deal-hero dl div { min-width: 130px; }
.deal-hero dt {
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.deal-hero dd { margin: 6px 0 0; font-size: 15px; font-weight: 700; }
.restricted { padding: 56px 32px; text-align: center; }
.restricted strong { display: block; font-size: 20px; }
.restricted p { color: var(--steel-2); }

.search-form { padding: 20px 24px; border-bottom: 1px solid var(--line-soft); display: flex; gap: 12px; }
.search-form input { flex: 1; min-width: 180px; }
.form-panel { max-width: 820px; padding: 32px; }
.stack-form { display: grid; gap: 20px; }
.stack-form p, .field { margin: 0; display: grid; gap: 8px; }
.stack-form label { color: var(--steel-1); font-size: 13px; font-weight: 700; }
.field > small { color: var(--steel-2); font-size: 12px; }
.form-control, .stack-form input, .stack-form select, .stack-form textarea, .search-form input, .login-form input {
    width: 100%;
    /* Высота поля равна высоте кнопки: рядом они стоят в одном ряду и
       обязаны совпадать. Прежние 46 пикселей были сильнее объявленной
       величины, потому что min-height берёт верх над height. */
    min-height: var(--field-h, 40px);
    padding: 10px 12px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    outline: none;
    color: var(--ink);
    background: var(--white);
    font-size: 14px;
    transition: border-color 160ms ease, box-shadow 160ms ease;
}
.stack-form textarea { min-height: 120px; resize: vertical; }
.stack-form input[type="checkbox"] {
    width: 18px;
    min-height: 18px;
    padding: 0;
    border-radius: 4px;
    accent-color: var(--ink);
}
.form-control:focus, .stack-form input:focus, .stack-form select:focus, .stack-form textarea:focus, .search-form input:focus, .login-form input:focus {
    border-color: var(--steel-2);
    box-shadow: 0 0 0 3px rgba(76, 102, 122, 0.14);
}
.form-actions { margin-top: 4px; display: flex; gap: 12px; }
.errorlist, .form-error {
    margin: 0;
    padding: 10px 12px;
    border-radius: var(--radius-small);
    color: #7e3030;
    background: var(--negative-soft);
    list-style: none;
    font-size: 13px;
}
.muted, .toolbar-note { color: var(--steel-2); }

.finance-nav { margin: -4px 0 24px; padding-bottom: 2px; }
.finance-nav a {
    min-height: 44px;
    padding: 10px 16px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    color: var(--steel-2);
    background: rgba(255, 255, 255, 0.76);
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    font-size: 14px;
    font-weight: 700;
    white-space: nowrap;
}
.finance-nav a:hover { color: var(--ink); border-color: var(--steel-3); background: var(--white); }
.finance-nav a.active { color: var(--white); border-color: var(--ink); background: var(--ink); }
.finance-toolbar {
    min-height: 52px;
    margin-bottom: 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.toolbar-note { font-size: 13px; line-height: 20px; }
.filter-toolbar { justify-content: flex-start; flex-wrap: wrap; }
.filter-toolbar .month-switcher { margin-right: auto; }
.form-control.compact { width: auto; min-width: 180px; }
.filter-check {
    min-height: var(--field-h, 40px);
    padding: 0 14px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--white);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--steel-1);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.filter-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--ink); }
.month-switcher {
    min-height: 46px;
    padding: 4px;
    border: 1px solid var(--mist);
    border-radius: 12px;
    background: var(--white);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.month-switcher a {
    width: 38px;
    height: 38px;
    border-radius: 8px;
    color: var(--steel-2);
    display: grid;
    place-items: center;
    font-size: 16px;
    font-weight: 700;
}
.month-switcher a:hover { color: var(--ink); background: var(--paper); }
.month-switcher strong {
    min-width: 152px;
    padding: 0 8px;
    font-size: 14px;
    font-weight: 700;
    text-align: center;
    text-transform: capitalize;
}
.finance-main-panel { min-width: 0; grid-column: span 8; }
.finance-side { min-width: 0; grid-column: span 4; display: grid; align-content: start; gap: 24px; }
.amount-cell { font-weight: 700; white-space: nowrap; }
.value-negative { color: var(--negative) !important; }
.value-positive { color: var(--positive) !important; }
.account-list, .payment-list { display: grid; }
.account-item, .payment-item {
    min-height: 72px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.account-item:last-child, .payment-item:last-child { border-bottom: 0; }
.account-item:hover, .payment-item:hover { background: #fafbfd; }
.account-item span, .payment-item span { min-width: 0; }
.account-item strong, .payment-item strong {
    overflow: hidden;
    display: block;
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
    line-height: 20px;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.account-item small, .payment-item small { margin-top: 2px; color: var(--steel-2); display: block; font-size: 12px; line-height: 18px; }
.account-item b, .payment-item b {
    flex: 0 0 auto;
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.payment-item.overdue { box-shadow: inset 4px 0 var(--negative); }
.side-empty { min-height: 166px; display: grid; place-items: center; }
.side-empty .empty-content { gap: 4px; }
.status-actual { color: var(--positive); background: var(--positive-soft); }
.status-cancelled { color: #7e3030; background: var(--negative-soft); }
.bank-review-callout {
    min-height: 74px;
    margin: -4px 0 24px;
    padding: 16px 20px;
    border: 1px solid #d9cda8;
    border-radius: var(--radius);
    background: #fbf8ee;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    transition: border-color 160ms ease, box-shadow 160ms ease;
}
.bank-review-callout:hover { border-color: #b8a66d; box-shadow: var(--shadow-card); }
.bank-review-callout strong, .bank-review-callout small { display: block; }
.bank-review-callout strong { font-size: 14px; }
.bank-review-callout small { margin-top: 2px; color: var(--steel-2); font-size: 12px; }
.bank-review-callout b {
    min-width: 34px;
    height: 34px;
    padding: 0 8px;
    border-radius: 12px;
    color: var(--white);
    background: var(--ink);
    display: grid;
    place-items: center;
    font-size: 13px;
}

.sr-only {
    position: absolute;
    /* Без этого подпись встаёт там, где оказалась по горизонтали, и
       растягивает страницу вбок на ширину прокручиваемой ленты. */
    left: 0;
    top: 0;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.mail-readonly-badge {
    min-height: 44px;
    padding: 10px 14px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    color: var(--steel-2);
    background: rgba(255, 255, 255, 0.72);
    display: inline-flex;
    align-items: center;
    font-size: 13px;
    font-weight: 700;
}
.mailbox-grid {
    margin-bottom: 24px;
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 24px;
}
.mailbox-card {
    min-width: 0;
    min-height: 164px;
    padding: 20px;
    border: 1px solid var(--mist);
    border-radius: var(--radius);
    background: var(--white);
    box-shadow: var(--shadow-card);
    grid-column: span 4;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}
.mailbox-card:hover { border-color: var(--steel-3); box-shadow: var(--shadow-float); transform: translateY(-1px); }
.mailbox-card.active { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink), var(--shadow-card); }
.mailbox-card-head { width: 100%; margin-bottom: 14px; display: flex; align-items: center; justify-content: space-between; }
.mailbox-avatar, .mail-avatar {
    border-radius: 50%;
    color: var(--white);
    background: var(--ink);
    display: grid;
    place-items: center;
    font-weight: 700;
}
.mailbox-avatar { width: 36px; height: 36px; font-size: 13px; }
.mailbox-card > strong { max-width: 100%; overflow: hidden; font-size: 16px; line-height: 22px; text-overflow: ellipsis; white-space: nowrap; }
.mailbox-card > span { max-width: 100%; margin-top: 2px; overflow: hidden; color: var(--steel-2); font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
.mailbox-card > small { margin-top: auto; padding-top: 12px; color: var(--steel-2); font-size: 12px; }
.sync-indicator { width: 10px; height: 10px; border-radius: 50%; background: var(--steel-3); box-shadow: 0 0 0 4px #eef2f5; }
.sync-indicator.ok { background: var(--positive); box-shadow: 0 0 0 4px var(--positive-soft); }
.sync-indicator.error { background: var(--negative); box-shadow: 0 0 0 4px var(--negative-soft); }
.mail-tabs { margin-bottom: 20px; }
.mail-panel { min-width: 0; }
.mail-panel-head { min-height: 80px; }
.mail-search {
    padding: 16px 20px;
    border-bottom: 1px solid var(--line-soft);
    background: #fafbfd;
    display: flex;
    align-items: center;
    gap: 10px;
}
.mail-search-field { min-width: 220px; flex: 1; }
.mail-list { display: grid; }
.mail-row {
    min-width: 0;
    min-height: 96px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line-soft);
    display: grid;
    grid-template-columns: 44px minmax(170px, 0.8fr) minmax(260px, 1.8fr) minmax(210px, 0.9fr);
    align-items: center;
    gap: 16px;
    transition: background-color 160ms ease;
}
.mail-row:last-child { border-bottom: 0; }
.mail-row:hover { background: #fafbfd; }
.mail-avatar { width: 40px; height: 40px; font-size: 14px; }
.mail-correspondent, .mail-summary, .mail-row-meta { min-width: 0; }
.mail-correspondent strong, .mail-summary strong {
    overflow: hidden;
    display: block;
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
    line-height: 20px;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mail-correspondent small, .mail-summary small {
    margin-top: 2px;
    overflow: hidden;
    display: block;
    color: var(--steel-2);
    font-size: 12px;
    line-height: 18px;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mail-row-meta { display: grid; justify-items: end; gap: 8px; }
.mail-row-meta time { color: var(--steel-2); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mail-badges, .mail-source-badges { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 4px; }
.badge.outgoing { color: #385a75; background: #e7eef4; }
.mailbox-badge { color: var(--steel-2); background: var(--paper); }
.mail-empty { border: 0; }
.pagination {
    min-height: 72px;
    padding: 14px 20px;
    border-top: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
}
.pagination span { color: var(--steel-2); font-size: 13px; }
.mail-detail-layout {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
    gap: 24px;
}
.mail-detail { min-width: 0; grid-column: span 8; }
.mail-detail-head {
    min-height: 170px;
    padding: 28px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 28px;
}
.mail-detail-title { min-width: 0; }
.mail-detail-title h2 { margin: 14px 0 8px; font-size: clamp(20px, 2vw, 24px); line-height: 1.25; letter-spacing: -0.025em; overflow-wrap: anywhere; }
.mail-detail-title time { color: var(--steel-2); font-size: 13px; }
.mail-source-badges { max-width: 280px; }
.mail-headers {
    margin: 0;
    padding: 24px 28px;
    border-bottom: 1px solid var(--line-soft);
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 32px;
}
.mail-headers div { min-width: 0; }
.mail-headers dt { margin-bottom: 4px; color: var(--steel-2); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.mail-headers dd { margin: 0; color: var(--ink); font-size: 13px; font-weight: 600; line-height: 20px; overflow-wrap: anywhere; }
.mail-headers dd span { color: var(--steel-2); display: block; font-weight: 400; }
.mail-body {
    min-height: 280px;
    padding: 32px 28px 48px;
    color: #17283a;
    font-family: "Mulish", system-ui, sans-serif;
    font-size: 15px;
    line-height: 1.75;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}
.mail-attachments { padding: 24px 28px 28px; border-top: 1px solid var(--line-soft); }
.mail-attachments h3 { margin: 0 0 14px; font-size: 15px; }
.attachment-list { display: grid; gap: 8px; }
.attachment-item { min-width: 0; padding: 12px 14px; border: 1px solid var(--line-soft); border-radius: var(--radius-small); background: #fafbfd; }
.attachment-item span { overflow: hidden; display: block; font-size: 13px; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.attachment-item small { margin-top: 2px; color: var(--steel-2); display: block; font-size: 11px; }
.mail-context { min-width: 0; grid-column: span 4; display: grid; gap: 16px; }
.mail-context-body { padding: 20px; display: grid; gap: 20px; }
.mail-context-body div { display: grid; gap: 4px; }
.mail-context-body small { color: var(--steel-2); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.mail-context-body strong, .mail-context-body a { font-size: 14px; font-weight: 700; }
.mail-context-body a:hover { text-decoration: underline; }
.mail-safety-note { margin: 0; padding: 0 4px; color: var(--steel-2); font-size: 12px; line-height: 19px; }

.account-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.account-card {
    min-height: 310px;
    padding: 24px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    transition: border-color 160ms ease, box-shadow 160ms ease;
}
.account-card:hover { border-color: var(--steel-3); box-shadow: var(--shadow-float); }
.account-card-badges { min-height: 27px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.badge.bank-readonly { color: var(--positive); background: var(--positive-soft); }
.account-card h2 { margin: 18px 0 4px; font-size: 20px; line-height: 1.35; }
.bank-account-mask { color: var(--steel-2); font-size: 12px; font-weight: 700; letter-spacing: 0.02em; }
.account-balance-block { width: 100%; margin-top: auto; padding-top: 22px; }
.account-balance-block small { color: var(--steel-2); display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.account-balance-block strong {
    margin-top: 4px;
    color: var(--ink);
    display: block;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}
.account-card > small { margin-top: 8px; color: var(--steel-2); font-size: 12px; line-height: 18px; }
.bank-sync-meta {
    width: 100%;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--line-soft);
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 18px;
}
.bank-sync-meta span { min-width: 0; }
.bank-sync-meta small, .bank-sync-meta b { display: block; }
.bank-sync-meta small { color: var(--steel-2); font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; }
.bank-sync-meta b { margin-top: 4px; overflow: hidden; font-size: 12px; line-height: 17px; text-overflow: ellipsis; white-space: nowrap; }
.bank-sync-meta em { grid-column: 1 / -1; color: var(--negative); font-size: 11px; font-style: normal; font-weight: 700; }
.bank-sync-meta.error { border-top-color: #e7caca; }
.account-card.inactive { opacity: 0.58; }
.empty-state { min-height: 260px; padding: 48px 32px; grid-column: 1 / -1; text-align: center; }
.empty-state h2 { margin: 0; font-size: 20px; }
.empty-state p { max-width: 620px; margin: 10px auto 22px; color: var(--steel-2); line-height: 1.6; }

.login-body { padding: 32px; background: var(--ink); display: grid; place-items: center; }
.login-panel {
    width: min(1040px, 100%);
    min-height: 620px;
    padding: 48px;
    border: 1px solid rgba(217, 224, 231, 0.2);
    border-radius: 12px;
    color: var(--white);
    background: var(--panel-dark);
    box-shadow: 0 32px 80px rgba(0, 0, 0, 0.28);
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    grid-template-rows: auto 1fr auto;
    gap: 40px 88px;
}
.login-brand { grid-column: 1 / -1; }
.login-brand img { display: block; width: 196px; height: auto; filter: brightness(0) invert(1); }
.login-copy { align-self: center; }
.login-copy .eyebrow { color: var(--steel-2); }
.login-copy h1 {
    max-width: 520px;
    margin: 14px 0 18px;
    font-size: clamp(30px, 5vw, 40px);
    font-weight: 700;
    line-height: 1.03;
    letter-spacing: -0.045em;
}
.login-copy p { max-width: 500px; margin: 0; color: rgba(217, 224, 231, 0.76); line-height: 1.7; }
.login-form {
    align-self: center;
    padding: 32px;
    border-radius: var(--radius);
    color: var(--ink);
    background: var(--paper);
    display: grid;
    gap: 10px;
}
.login-form label { margin-top: 8px; color: var(--steel-1); font-size: 13px; font-weight: 700; }
.login-form .button { margin-top: 12px; }
.security-note { margin: 0; color: rgba(217, 224, 231, 0.56); grid-column: 1 / -1; font-size: 12px; }

@media (max-width: 1180px) {

    .dashboard-grid > .panel:first-child, .dashboard-grid > .panel:last-child, .finance-main-panel, .finance-side { grid-column: 1 / -1; }
    .account-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .login-panel { gap: 40px; }
    .mail-row { grid-template-columns: 40px minmax(160px, 0.8fr) minmax(240px, 1.6fr); }
    .mail-row-meta { grid-column: 2 / -1; grid-row: 2; justify-items: start; }
    .mail-badges { justify-content: flex-start; }
    .mail-detail, .mail-context { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
    /* На узком экране приложение снова становится обычной страницей: держать
       две прокручиваемые колонки в 375 px негде. */
    body.app { height: auto; overflow: visible; }
    .app-shell { height: auto; grid-template-columns: 1fr; overflow: visible; }
    .sidebar { height: auto; display: block; padding: 20px; overflow: visible; }
    .sidebar > .nav { overflow: visible; }
    .content { height: auto; overflow: visible; }
    .brand img { width: 150px; }
    .nav { margin-top: 20px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .nav a { text-align: center; justify-content: center; }
    .nav a::before { display: none; }
    .sidebar-foot { display: none; }
    .content { padding: 28px 20px 48px; }
    .login-panel { min-height: auto; padding: 36px; grid-template-columns: 1fr; gap: 32px; }
    .login-brand, .security-note { grid-column: 1; }
    .mailbox-grid { gap: 14px; }
    .mailbox-card { grid-column: span 6; }
}

@media (max-width: 640px) {
    body { font-size: 14px; }
    .sidebar { padding: 18px 16px; }
    .nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .content { padding: 24px 14px 40px; }
    .topbar { min-height: auto; margin-bottom: 20px; flex-direction: column; gap: 18px; }
    .topbar-actions, .topbar-actions .button { width: 100%; }
    .metric-grid, .finance-metric-grid, .dashboard-grid, .finance-layout { gap: 14px; }

    .metric-card { min-height: 148px; padding: 20px; }
    .panel-head { min-height: 76px; padding: 18px 20px; align-items: flex-start; }
    .panel-head h2 { font-size: 16px; }
    .finance-toolbar { align-items: stretch; flex-direction: column; }
    .toolbar-note { max-width: 340px; }
    .filter-toolbar .month-switcher { margin-right: 0; }
    .form-control.compact, .month-switcher, .filter-check { width: 100%; }
    .month-switcher strong { flex: 1; }
    .search-form { padding: 16px; flex-direction: column; }
    .deal-hero { padding: 22px; align-items: flex-start; flex-direction: column; }
    .deal-hero dl { width: 100%; gap: 20px; }
    .deal-hero dl div { flex: 1; min-width: 0; }
    .account-grid { grid-template-columns: 1fr; gap: 14px; }
    .form-panel, .panel.narrow { padding: 22px; }
    .form-actions { flex-direction: column; }
    .form-actions .button { width: 100%; }
    .login-body { padding: 12px; }
    .login-panel { padding: 26px 20px; border-radius: 12px; }
    .login-copy h1 { font-size: 30px; }
    .login-form { padding: 22px; }
    .mailbox-card { grid-column: 1 / -1; min-height: 150px; }
    .mail-search { padding: 14px; align-items: stretch; flex-direction: column; }
    .mail-search-field, .mail-search .form-control.compact, .mail-search .button { width: 100%; }
    .mail-row { padding: 16px; grid-template-columns: 36px minmax(0, 1fr); gap: 10px 12px; }
    .mail-avatar { width: 36px; height: 36px; }
    .mail-summary, .mail-row-meta { grid-column: 2; }
    .mail-row-meta { grid-row: auto; justify-items: start; }
    .mail-badges { justify-content: flex-start; }
    .mail-detail-head { min-height: auto; padding: 22px; flex-direction: column; }
    .mail-source-badges { max-width: none; justify-content: flex-start; }
    .mail-headers { padding: 20px 22px; grid-template-columns: 1fr; }
    .mail-body { min-height: 220px; padding: 24px 22px 36px; font-size: 14px; }
    .mail-attachments { padding: 20px 22px 22px; }
}

/* Unified workspace: target data model, documents and safe outreach preview. */
:root {
    --warning: #8a6823;
    --warning-soft: #fbf5e6;
}


.workspace-subtitle {
    max-width: 980px;
    margin: -14px 0 24px;
    color: var(--steel-2);
    font-size: 15px;
    line-height: 1.65;
}
.workspace-tabs {
    margin: -4px 0 24px;
    padding-bottom: 2px;
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: thin;
}
.workspace-tabs a {
    min-height: 40px;
    padding: 8px 12px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    color: var(--steel-2);
    background: rgba(255, 255, 255, 0.68);
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}
.workspace-tabs a:hover { color: var(--ink); border-color: var(--steel-3); background: var(--white); }
.workspace-tabs a.active { color: var(--white); border-color: var(--ink); background: var(--ink); }

.workspace-notice {
    min-height: 70px;
    margin-bottom: 24px;
    padding: 14px 16px;
    border: 1px solid #c9dfd4;
    border-radius: var(--radius);
    color: var(--positive);
    background: var(--positive-soft);
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr);
    align-items: center;
    gap: 14px;
    font-size: 13px;
}
/* Внутри уведомления стоит предложение, а не метка: прописные и
   разрядка делали из него плакат, который тяжело читать. */
.workspace-notice strong { font-size: 12px; }
.workspace-notice.warning { color: #644b19; border-color: #dfd0a5; background: var(--warning-soft); }
.workspace-notice code { padding: 2px 4px; border-radius: 4px; background: rgba(255,255,255,.62); font-size: 11px; }
.import-upload-panel { margin-bottom: 24px; }.import-step { padding: 24px 24px 18px; display: flex; align-items: center; gap: 14px; }.import-step > span, .import-flow span { width: 34px; height: 34px; flex: 0 0 auto; border-radius: 50%; color: var(--white); background: var(--ink); display: grid; place-items: center; font-size: 12px; font-weight: 700; }.import-step strong, .import-step small { display: block; }.import-step small { margin-top: 2px; color: var(--steel-2); font-size: 12px; }.import-upload-form { padding: 16px 24px 24px; border-top: 1px solid var(--line-soft); display: flex; align-items: center; gap: 12px; }.import-upload-form .form-control { min-width: 0; flex: 1; }.import-flow { margin-bottom: 24px; display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }.import-flow article { min-height: 106px; padding: var(--space-2); border: 1px solid var(--mist); border-radius: var(--radius); background: rgba(255,255,255,.65); display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; column-gap: 12px; }.import-flow span { grid-row: span 2; }.import-flow strong { align-self: end; font-size: 14px; }.import-flow small { align-self: start; margin-top: 2px; color: var(--steel-2); font-size: 12px; }.import-summary { margin-bottom: 18px; padding: 16px 18px; border: 1px solid #c9dfd4; border-radius: var(--radius); background: var(--positive-soft); display: flex; justify-content: space-between; gap: 16px; }.import-summary span { color: #386c58; font-size: 13px; }.import-campaign-grid { display: grid; gap: 14px; }.import-campaign-card { min-height: 144px; padding: 24px; display: flex; align-items: center; justify-content: space-between; gap: 20px; }.import-campaign-card h2 { margin: 4px 0 6px; font-size: 20px; }.import-campaign-card p { margin: 0; color: var(--steel-2); font-size: 13px; }.import-config-layout { display: grid; grid-template-columns: minmax(340px, .82fr) minmax(480px, 1.18fr); gap: 24px; align-items: start; }.import-config-form { overflow: visible; }.import-preview-panel { min-height: 700px; }.import-preview-panel iframe { width: 100%; height: 610px; border: 0; background: #fff; }
.outreach-ops-grid { margin-bottom: 24px; display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(320px, .9fr); gap: 24px; }.outreach-chart-panel { min-height: 320px; }.chart-legend { display: flex; gap: 12px; color: var(--steel-2); font-size: 11px; font-weight: 700; }.chart-legend i { width: 8px; height: 8px; margin-right: 4px; border-radius: 50%; display: inline-block; }.outreach-bars { height: 190px; padding: 18px 24px 20px; display: grid; grid-template-columns: repeat(7, 1fr); align-items: end; gap: 12px; }.outreach-bars article { height: 100%; display: grid; grid-template-rows: 1fr auto; gap: 8px; text-align: center; }.outreach-bars .bars { min-height: 0; border-bottom: 1px solid var(--line-soft); display: flex; align-items: end; justify-content: center; gap: 4px; }.outreach-bars i { width: 14px; min-height: 4px; border-radius: 4px 4px 0 0; display: block; }.queue { background: #8b72d8; }.sent { background: #72c99b; }.outreach-bars small { color: var(--steel-2); font-size: 11px; }.outreach-capacity .workspace-kv { padding: 14px 24px 24px; }.outreach-routes { margin-bottom: 24px; }.route-grid { padding: 22px 24px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }.route-grid article { padding: 16px; border: 1px solid var(--line-soft); border-radius: var(--radius-small); background: #fafbfd; }.route-grid strong, .route-grid span { display: block; }.route-grid strong { font-size: 13px; }.route-grid span, .outreach-routes p { margin: 4px 24px 0; color: var(--steel-2); font-size: 12px; }.outreach-routes p { margin: 0; padding: 0 24px 22px; }

.workspace-metrics .metric-card { min-height: 142px; }
.workspace-quick-grid { margin: -4px 0 24px; display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 14px; }
.workspace-quick-card {
    min-height: 102px;
    padding: 16px 18px;
    border: 1px solid var(--mist);
    border-radius: var(--radius);
    background: rgba(255,255,255,.7);
    display: grid;
    grid-template-columns: 1fr auto;
    align-content: center;
    gap: 2px 14px;
    transition: border-color 160ms ease, background-color 160ms ease, transform 160ms ease;
}
.workspace-quick-card:hover { border-color: var(--steel-3); background: var(--white); transform: translateY(-1px); }
.workspace-quick-card span { color: var(--steel-1); font-size: 13px; font-weight: 700; }
.workspace-quick-card strong { grid-row: span 2; font-size: 24px; letter-spacing: -.03em; }
.workspace-quick-card small { color: var(--steel-2); font-size: 11px; }
.workspace-quick-card.attention { border-color: #dfd0a5; background: var(--warning-soft); }
.workspace-table-panel { min-width: 0; }
.workspace-filter {
    min-height: 76px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--line-soft);
    background: #fafbfd;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.workspace-search { min-width: 220px; flex: 1 1 320px; }
.workspace-filter label:not(.workspace-search) { flex: 0 1 auto; }
/* min-width removed in 101E: it forced a scrollbar inside every list panel. */
.workspace-table tbody tr { transition: background-color 140ms ease; }
/* Название переносится, а не обрезается: по «Оспаривания · кроме тех, кому
   уже писали; б…» нужную запись среди соседних не выбрать. Место в строке
   есть — владелец указывал на это прямо. */
.workspace-primary-link { display: inline-block; max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.workspace-cell-main { font-weight: 600; }
.workspace-badge.positive { color: var(--positive); background: var(--positive-soft); }
.workspace-badge.negative { color: #7e3030; background: var(--negative-soft); }
.workspace-badge.warning { color: #725417; background: var(--warning-soft); }
.workspace-badge.muted { color: var(--steel-1); background: #e9eef2; }

.workspace-hero {
    min-height: 190px;
    margin-bottom: 24px;
    padding: 28px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 36px;
}
.workspace-hero > div:first-child { min-width: 0; max-width: 820px; }
.workspace-hero h2 { margin: 14px 0 6px; font-size: var(--fs-section); line-height: 1.25; letter-spacing: -0.025em; }
.workspace-hero p { max-width: 800px; margin: 0; color: var(--steel-2); }
.workspace-hero dl { min-width: 420px; margin: 0; display: grid; grid-template-columns: repeat(3, minmax(110px, 1fr)); gap: 24px; }
.workspace-hero dt, .workspace-kv dt { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.workspace-hero dd { margin: 6px 0 0; font-size: 14px; font-weight: 700; overflow-wrap: anywhere; }
.workspace-hero dd a, .workspace-kv dd a { text-decoration: underline; text-decoration-color: var(--mist); text-underline-offset: 3px; }

.workspace-detail-grid {
    margin-bottom: 24px;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* Карточки в ряду держат одну высоту: прижатие к верху давало
       соседние блоки разной длины, и ряд рассыпался. */
    align-items: stretch;
    gap: 24px;
}
.workspace-card { min-width: 0; }
.workspace-card .panel-head { min-height: 76px; }
.workspace-span-2 { grid-column: 1 / -1; }
.workspace-card-body { min-height: 150px; padding: 24px; }
.workspace-card-body > strong { display: block; font-size: 16px; }
.workspace-card-body p { color: var(--steel-2); }
.workspace-list { display: grid; }
.workspace-list > article, .workspace-list > a > article {
    min-height: 74px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
}
.workspace-list > article:last-child, .workspace-list > a:last-child > article { border-bottom: 0; }
.workspace-list > a > article:hover { background: #fafbfd; }
.workspace-list article > div { min-width: 0; }
.workspace-list article strong, .workspace-list article span { display: block; }
.workspace-list article strong { font-size: 14px; }
.workspace-list article div > span { margin-top: 2px; color: var(--steel-2); font-size: 12px; }
.workspace-list article > small { flex: 0 0 auto; color: var(--steel-2); font-size: 12px; text-align: right; }
.workspace-empty { margin: 0; padding: 30px 24px; color: var(--steel-2); font-size: 13px; text-align: center; }

.workspace-timeline-panel { margin-bottom: 24px; }
.workspace-timeline { padding: 8px 24px 20px; display: grid; }
/* Время и событие — две дорожки. Раньше время лежало поверх, а под него
   отводились 170 пикселей отступа: при увеличении дата выходила за полосу
   и наезжала на текст события. */
.workspace-timeline article {
    min-height: 76px;
    padding: 18px 0;
    border-bottom: 1px solid var(--line-soft);
    display: grid;
    grid-template-columns: minmax(max-content, 150px) minmax(0, 1fr);
    gap: var(--space-2);
    align-items: start;
}
.workspace-timeline article:last-child { border-bottom: 0; }
.workspace-timeline time { color: var(--steel-2); font-size: 12px; font-variant-numeric: tabular-nums; }
.workspace-timeline article > :not(time) { grid-column: 2; }
.workspace-timeline strong, .workspace-timeline span { display: block; }
.workspace-timeline strong { font-size: 14px; }
.workspace-timeline span { margin-top: 2px; color: var(--steel-2); font-size: 12px; }
.workspace-timeline p { margin: 8px 0 0; color: var(--steel-2); font-size: 13px; }

.workspace-stage-panel { margin-bottom: 24px; padding: 8px; }
.lead-pipeline, .document-flow { display: grid; grid-template-columns: repeat(7, minmax(110px, 1fr)); gap: 4px; overflow-x: auto; }
.lead-pipeline span, .document-flow span { min-height: 54px; padding: 10px 12px; border-radius: 8px; color: var(--steel-2); background: var(--paper); display: grid; place-items: center; font-size: 11px; font-weight: 700; text-align: center; }
.lead-pipeline span.active, .document-flow span.active { color: var(--white); background: var(--ink); }
.document-flow { margin-bottom: 24px; grid-template-columns: repeat(6, minmax(130px, 1fr)); }
.document-flow span { border: 1px solid var(--mist); background: var(--white); }
.document-flow span.done { color: var(--positive); border-color: #c9dfd4; background: var(--positive-soft); }

.workspace-kv { margin: 0; padding: 8px 24px 20px; display: grid; }
.workspace-kv > div { min-width: 0; padding: 14px 0; border-bottom: 1px solid var(--line-soft); display: grid; grid-template-columns: 155px minmax(0, 1fr); gap: 20px; }
.workspace-kv > div:last-child { border-bottom: 0; }
.workspace-kv dd { min-width: 0; margin: 0; font-size: 13px; font-weight: 700; overflow-wrap: anywhere; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px !important; }
.source-steps { margin: 0; padding: 12px 24px 24px 48px; color: var(--steel-1); }
.source-steps li { padding: 6px 0 6px 4px; font-size: 13px; }

.preview-layout { display: grid; grid-template-columns: 380px minmax(0, 1fr); align-items: start; gap: 24px; }
.preview-controls { min-width: 0; }
.message-preview { min-width: 0; }
.message-preview-head { min-height: 70px; padding: 16px 22px; border-bottom: 1px solid var(--line-soft); display: flex; align-items: center; justify-content: space-between; }
.message-preview-head small { color: var(--steel-2); }
.message-preview > dl { margin: 0; padding: 18px 24px; border-bottom: 1px solid var(--line-soft); display: grid; gap: 8px; }
.message-preview > dl > div { display: grid; grid-template-columns: 70px minmax(0,1fr); gap: 14px; }
.message-preview dt { color: var(--steel-2); font-size: 11px; font-weight: 700; text-transform: uppercase; }
.message-preview dd { margin: 0; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.message-preview-body { min-height: 330px; padding: 30px 28px; color: #17283a; font-size: 14px; line-height: 1.75; }

.fact-grid { padding: 22px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.fact-card { min-width: 0; padding: 18px; border: 1px solid var(--line-soft); border-radius: 8px; background: #fafbfd; }
.fact-card.confirmed { border-color: #c9dfd4; background: #f4f9f6; }
.fact-card.rejected { border-color: #e7caca; background: #fcf7f7; }
.fact-card-head { display: flex; align-items: center; justify-content: space-between; }
.fact-card-head > small { color: var(--steel-2); font-weight: 700; }
.fact-card h3 { margin: 16px 0 4px; color: var(--steel-2); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.fact-card > strong { overflow-wrap: anywhere; display: block; font-size: 16px; }
.fact-card p { min-height: 42px; margin: 12px 0; color: var(--steel-2); font-size: 12px; line-height: 1.55; }
.fact-card > small { color: var(--steel-2); font-size: 11px; }
.document-text-panel { margin-bottom: 24px; }
.document-text { max-height: 520px; padding: 28px; color: #27394b; background: #fafbfd; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.75; overflow: auto; }

.settings-flags { margin-bottom: 24px; display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 18px; }
.setting-card { min-height: 230px; padding: 20px; }
/* Заголовок карточки настройки — одна роль и одна ступень шкалы.
   В разметке он встречался тремя разными способами. */
.setting-card h2, .setting-card h3 {
    margin: 16px 0 8px;
    font-size: var(--fs-card);
    font-weight: 700;
}
.setting-card p { margin: 0; color: var(--steel-2); font-size: 12px; line-height: 1.6; }
.setting-card code { margin-top: 20px; color: var(--steel-2); display: block; font-size: 11px; overflow-wrap: anywhere; }

@media (max-width: 1280px) {
    .workspace-hero { align-items: flex-start; flex-direction: column; }
    .workspace-hero dl { width: 100%; min-width: 0; }
    .fact-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .settings-flags { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .workspace-quick-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
}

@media (max-width: 900px) {
    .sidebar { overflow: visible; }
    .workspace-detail-grid, .preview-layout { grid-template-columns: 1fr; }
    .workspace-span-2 { grid-column: 1; }
    .preview-controls, .message-preview { grid-column: 1; }
}

@media (max-width: 640px) {
    .workspace-subtitle { margin-top: -8px; }
    .workspace-notice { grid-template-columns: 1fr; gap: 4px; }
    .workspace-filter { align-items: stretch; flex-direction: column; }
    .workspace-search, .workspace-filter label, .workspace-filter .form-control, .workspace-filter .button { width: 100%; min-width: 0; }
    .workspace-hero { min-height: auto; padding: 22px; }
    .workspace-hero dl { grid-template-columns: 1fr; gap: 16px; }
    .workspace-detail-grid { gap: 14px; }
    .workspace-list > article, .workspace-list > a > article { align-items: flex-start; flex-direction: column; gap: 8px; }
    .workspace-list article > small { text-align: left; }
    .workspace-timeline article { padding-left: 0; padding-top: 44px; }
    .workspace-timeline time { top: 18px; }
    .workspace-kv > div { grid-template-columns: 1fr; gap: 4px; }
    .fact-grid, .settings-flags { grid-template-columns: 1fr; }
    .workspace-quick-grid { grid-template-columns: 1fr; }
    .fact-grid { padding: 14px; }
    .message-preview-body { padding: 22px; }
}

/* Mail and client workspace refinements. Kept together so responsive rules stay consistent. */
.mailbox-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.mailbox-card { grid-column: auto; }
.mailbox-card-status { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.mailbox-card-foot {
    width: 100%;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.mailbox-card-foot small { color: var(--steel-2); font-size: 11px; line-height: 17px; }
.mailbox-card-foot small:last-child { text-align: right; }
.unread-counter {
    min-height: 24px;
    padding: 2px 8px;
    border-radius: 999px;
    color: var(--positive);
    background: var(--positive-soft);
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    white-space: nowrap;
}
.unread-counter.large { min-height: 30px; padding: 4px 10px; font-size: 12px; }
.mail-panel-stats { max-width: 560px; display: flex; align-items: center; justify-content: flex-end; gap: 12px; text-align: right; }
.mail-filter-bar {
    min-height: 72px;
    padding: 12px 20px;
    border-bottom: 1px solid var(--line-soft);
    background: #fafbfd;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
}
/* Папки ящика: тот же ряд вкладок, что у направления писем, но выше и
   постоянный — папка не фильтр, а место, где письмо лежит. */
.mail-folder-tabs {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 12px 16px 0; margin: 0;
}
.mail-folder-tabs a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px; border-radius: 999px;
    font-size: 13px; font-weight: 700; color: var(--steel-2); text-decoration: none;
    border: 1px solid var(--line-soft); white-space: nowrap;
}
.mail-folder-tabs a:hover { color: var(--ink); background: var(--paper); }
.mail-folder-tabs a.active { color: var(--white); background: var(--ink); border-color: var(--ink); }
.mail-folder-tabs a span { font-variant-numeric: tabular-nums; }

.mail-direction-tabs {
    padding: 4px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: var(--white);
    display: flex;
    align-items: center;
    gap: 2px;
}
.mail-direction-tabs a {
    min-height: 38px;
    padding: 8px 12px;
    border-radius: 8px;
    color: var(--steel-2);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
}
.mail-direction-tabs a:hover { color: var(--ink); background: var(--paper); }
.mail-direction-tabs a.active { color: var(--white); background: var(--ink); }
.mail-direction-tabs a > span {
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    color: var(--steel-1);
    background: var(--paper);
    display: inline-grid;
    place-items: center;
    font-size: 11px;
}
.mail-direction-tabs a.active > span { color: var(--ink); background: var(--white); }
.mail-search { min-width: min(460px, 46%); padding: 0; border: 0; background: transparent; }
.mail-search-field { min-width: 180px; }
.mail-row { grid-template-columns: 44px minmax(250px, 1.05fr) minmax(260px, 1.45fr) minmax(215px, 0.8fr); }
.mail-row:hover { background: #f7f9fb; }
.mail-row.unread { background: #f3f8f5; box-shadow: inset 4px 0 var(--positive); }
.mail-row.unread:hover { background: #edf5f0; }
.mail-avatar-wrap { position: relative; width: 40px; height: 40px; display: block; }
.unread-dot {
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 12px;
    height: 12px;
    border: 2px solid var(--white);
    border-radius: 50%;
    background: var(--positive);
}
.mail-route, .mail-summary, .mail-row-meta { min-width: 0; }
.mail-route { display: grid; gap: 6px; }
.mail-route-line { min-width: 0; display: grid; grid-template-columns: 42px minmax(0, 1fr); align-items: baseline; gap: 8px; }
.mail-route-line b { color: var(--steel-2); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.mail-route-line strong, .mail-route-line small, .mail-summary strong {
    overflow: hidden;
    display: block;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mail-route-line strong, .mail-summary strong { color: var(--ink); font-size: 14px; font-weight: 700; line-height: 20px; }
.mail-route-line small { color: var(--steel-2); font-size: 12px; line-height: 18px; }
.mail-summary small { margin-top: 4px; }
.badge.new { color: var(--positive); background: var(--positive-soft); }
.mail-header-primary { padding-left: 14px; border-left: 3px solid var(--ink); }
.mail-client-candidates { padding: 16px; display: grid; gap: 10px; }
.mail-client-candidate {
    min-width: 0;
    padding: 16px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-small);
    background: #fafbfd;
    display: grid;
    gap: 14px;
}
.mail-client-candidate > div:first-child { min-width: 0; display: grid; gap: 2px; }
.mail-client-candidate strong, .mail-client-candidate small { overflow: hidden; display: block; text-overflow: ellipsis; white-space: nowrap; }
.mail-client-candidate strong { font-size: 14px; }
.mail-client-candidate small { color: var(--steel-2); font-size: 12px; }
.mail-client-candidate form { margin: 0; }
.candidate-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

.context-notice {
    margin-bottom: 20px;
    padding: 18px 20px;
    border: 1px solid #c9dfd4;
    border-radius: var(--radius);
    color: var(--positive);
    background: var(--positive-soft);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: baseline;
    gap: 2px 14px;
}
.context-notice .eyebrow { color: #2d6650; grid-row: span 2; }
.context-notice strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.context-notice > span:last-child { color: #386c58; font-size: 13px; }
.client-form { max-width: 1180px; margin: 0 auto; display: grid; gap: 20px; }
/* Поле формы по шагу отступов: 28 пикселей не было ни одной ступенью. */
.form-section { padding: 0 var(--space-3) var(--space-3); overflow: visible; }
.form-section-head {
    min-height: 104px;
    margin: 0 -28px 26px;
    padding: 22px 28px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    gap: 18px;
}
.section-number {
    width: 42px;
    height: 42px;
    flex: 0 0 auto;
    border-radius: 50%;
    color: var(--white);
    background: var(--ink);
    display: grid;
    place-items: center;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
}
.form-section-head h2 { margin: 0 0 2px; font-size: 20px; line-height: 26px; }
.form-section-head p { margin: 0; color: var(--steel-2); font-size: 13px; line-height: 20px; }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 24px; }
.form-grid.form-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid .field { min-width: 0; margin: 0; display: grid; align-content: start; gap: 6px; }
.form-grid .field-wide { grid-column: 1 / -1; }
.form-grid label { color: var(--steel-1); font-size: 13px; font-weight: 700; }
.form-grid textarea.form-control { min-height: 86px; resize: vertical; }
.form-grid .field > small { color: var(--steel-2); font-size: 11px; line-height: 17px; }
.form-grid .has-error .form-control { border-color: var(--negative); }
.form-grid .errorlist { margin-top: 2px; }
.form-subhead {
    margin: 28px 0 16px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.form-section-head + .form-subhead { margin-top: -4px; padding-top: 0; border-top: 0; }
/* Полоса действий формы больше не липнет к низу окна. Она держалась поверх
   содержимого и при увеличении масштаба накрывала поля: на 125% это были
   «Ответственный» и пояснение к наименованию, на 150% — «Полное
   наименование». Действие и содержимое не делят одно место: полоса стоит
   последней в потоке формы, как и положено завершению.

   Вид панели сохранён: тень и рамка по-прежнему отделяют её от полей. */
.sticky-form-actions {
    min-height: 76px;
    padding: 14px 16px 14px 22px;
    border: 1px solid var(--mist);
    border-radius: var(--radius);
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 14px 40px rgba(11, 22, 35, 0.13);
    backdrop-filter: blur(14px);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
}
.sticky-form-actions > span { color: var(--steel-2); font-size: 12px; }
.sticky-form-actions .form-actions { margin: 0; }

.clients-panel { min-width: 0; }
.client-search { background: #fafbfd; }
/* Ширину задаёт раскладка колонок, а не жёсткий минимум таблицы. */
.table-primary-link { display: inline-block; max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.client-status-active { color: var(--positive); background: var(--positive-soft); }
.client-status-prospect { color: #385a75; background: #e7eef4; }
.client-status-archived { color: var(--steel-2); background: #e9eef2; }
.deal-count {
    min-width: 32px;
    height: 32px;
    border-radius: 50%;
    color: var(--ink);
    background: var(--paper);
    display: inline-grid;
    place-items: center;
    font-size: 12px;
    font-weight: 700;
}
.client-profile {
    width: min(100%, 1280px);
    margin: 0 auto;
}
.client-profile-topbar {
    width: min(100%, 1280px);
    margin-left: auto;
    margin-right: auto;
}
.client-actions-menu { position: relative; flex: 0 0 auto; }
.client-actions-menu > summary { list-style: none; }
.client-actions-menu > summary::-webkit-details-marker { display: none; }
.client-actions-trigger {
    width: 46px;
    padding-inline: 10px;
    background: var(--white);
}
.client-actions-menu[open] .client-actions-trigger { border-color: var(--steel-3); background: var(--white); }
.client-actions-dots { position: relative; top: -2px; letter-spacing: 2px; font-size: var(--fs-micro); line-height: 1; }
.client-actions-popover {
    position: absolute;
    z-index: 30;
    top: calc(100% + 9px);
    right: 0;
    width: 218px;
    padding: 8px;
    border: 1px solid var(--mist);
    border-radius: 12px;
    background: var(--white);
    box-shadow: var(--shadow-float);
    display: grid;
    gap: 4px;
}
.client-actions-popover::before {
    content: "";
    position: absolute;
    top: -5px;
    right: 18px;
    width: 9px;
    height: 9px;
    border-top: 1px solid var(--mist);
    border-left: 1px solid var(--mist);
    background: var(--white);
    transform: rotate(45deg);
}
.client-actions-popover > span {
    padding: 6px 10px 4px;
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.client-delete-link {
    min-height: 40px;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--negative);
    display: flex;
    align-items: center;
    font-size: 13px;
    font-weight: 700;
}
.client-delete-link:hover { background: var(--negative-soft); }
.client-hero {
    position: relative;
    min-height: 344px;
    margin-bottom: 24px;
    padding: 38px clamp(24px, 5vw, 72px) 34px;
    overflow: hidden;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 22px;
    text-align: center;
}
.client-hero::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 5px;
    background: linear-gradient(90deg, var(--ink), #5d7488 52%, var(--ink));
}
.client-monogram {
    width: 68px;
    height: 68px;
    border: 6px solid #edf1f4;
    border-radius: 50%;
    color: var(--white);
    background: var(--ink);
    box-shadow: 0 10px 24px rgba(11, 22, 35, 0.18);
    display: grid;
    place-items: center;
    font-size: 20px;
    font-weight: 800;
    line-height: 1;
}
.client-hero-main { min-width: 0; max-width: 850px; }
.client-hero-badges { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 6px; }
.client-hero h2 {
    margin: 12px 0 6px;
    font-size: clamp(24px, 3vw, 30px);
    line-height: 1.15;
    letter-spacing: -0.035em;
    overflow-wrap: anywhere;
}
.client-hero p { margin: 0; color: var(--steel-2); font-size: 14px; line-height: 1.55; overflow-wrap: anywhere; }
.client-hero-meta {
    width: min(100%, 900px);
    margin: 2px 0 0;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: #fafbfd;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.client-hero-meta > div {
    min-width: 0;
    min-height: 78px;
    padding: 14px 20px;
    display: grid;
    place-content: center;
    gap: 6px;
}
.client-hero-meta > div + div { border-left: 1px solid var(--line-soft); }
.client-hero dt,
.client-data-grid dt {
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}
.client-hero dd { margin: 0; font-size: 13px; font-weight: 700; line-height: 1.45; overflow-wrap: anywhere; }
.client-detail-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: stretch;
    gap: 24px;
}
.client-detail-card {
    min-width: 0;
    grid-column: span 6;
    display: flex;
    flex-direction: column;
}
.client-detail-wide { grid-column: 1 / -1; }
.client-card-head {
    position: relative;
    min-height: 126px;
    padding: 24px 28px;
    border-bottom: 1px solid var(--line-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}
.client-card-head > div { min-width: 0; max-width: 680px; }
.client-card-head h2 { margin: 4px 0 0; font-size: 16px; line-height: 1.3; letter-spacing: -0.015em; }
.client-card-head p { margin: 6px 0 0; color: var(--steel-2); font-size: 12px; line-height: 1.5; }
/* Заголовок с действием: содержимое и кнопка — соседи в одной строке, а не
   слой поверх слоя. Раньше кнопка вынималась из потока и лежала на тексте, а
   место под неё держал жёсткий отступ в 190 пикселей: при увеличении масштаба
   кнопка выходила за него и накрывала заголовок.

   Ширину забирает содержимое, кнопка своей не отдаёт. Когда в строку они не
   помещаются, кнопка переходит на строку ниже — вниз, а не поверх. */
.client-card-head.has-action {
    padding-inline: 28px;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.client-card-head.has-action > div { flex: 1 1 260px; }
.client-card-head.has-action > .button { flex: 0 0 auto; }
.client-data-grid {
    flex: 1;
    margin: 0;
    padding: 24px;
    display: grid;
    gap: 12px;
}
.requisites-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.address-grid { grid-template-columns: 1fr; }
.bank-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.client-data-grid > div {
    min-width: 0;
    min-height: 96px;
    padding: 18px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: #fafbfd;
    display: grid;
    place-content: center;
    gap: 6px;
    text-align: center;
}
.client-data-grid .data-wide { grid-column: 1 / -1; }
.client-data-grid dd { margin: 0; font-size: 14px; font-weight: 700; line-height: 1.55; overflow-wrap: anywhere; }
.client-channel-grid {
    padding: 24px;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}
.client-channel-card {
    min-width: 0;
    min-height: 104px;
    padding: 18px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: #fafbfd;
    display: grid;
    place-content: center;
    gap: 8px;
    text-align: center;
}
.client-channel-card > span {
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}
.client-channel-card a,
.client-channel-card strong { font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.client-contacts-section { padding: 0 24px 24px; border-top: 1px solid var(--line-soft); }
.client-subsection-title {
    min-height: 74px;
    padding: 16px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 2px;
    text-align: center;
}
.client-subsection-title > span { font-size: 13px; font-weight: 800; }
.client-subsection-title > small { color: var(--steel-2); font-size: 11px; }
.contact-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    align-items: stretch;
    gap: 12px;
}
.contact-person-card {
    min-width: 0;
    min-height: 184px;
    padding: 20px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 10px;
    text-align: center;
    transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.contact-person-card:hover {
    border-color: #b7c3cc;
    box-shadow: 0 10px 24px rgba(11, 22, 35, 0.08);
    transform: translateY(-2px);
}
.contact-avatar {
    width: 48px;
    height: 48px;
    flex: 0 0 auto;
    border: 4px solid #edf1f4;
    border-radius: 50%;
    color: var(--white);
    background: var(--ink);
    display: grid;
    place-items: center;
    font-size: 13px;
    font-weight: 800;
}
.contact-person-info { min-width: 0; max-width: 100%; }
.contact-person-info strong,
.contact-person-info small { display: block; overflow-wrap: anywhere; }
.contact-person-info strong { font-size: 13px; line-height: 1.5; }
.contact-person-info small { margin-top: 2px; color: var(--steel-2); font-size: 11px; line-height: 1.45; }
.contact-empty { grid-column: 1 / -1; min-height: 138px; border: 1px dashed #c9d2d9; border-radius: 12px; background: #fafbfd; }
.compact-empty {
    min-height: 118px;
    padding: 24px;
    color: var(--steel-2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 4px;
    font-size: 12px;
    line-height: 1.5;
    text-align: center;
}
.compact-empty strong { color: var(--ink); font-size: 13px; }
.deal-card-list {
    flex: 1;
    padding: 24px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    align-content: start;
    gap: 12px;
}
.deal-client-card {
    min-width: 0;
    min-height: 126px;
    padding: 18px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: #fafbfd;
    display: grid;
    place-content: center;
    gap: 4px;
    text-align: center;
    transition: border-color 0.18s ease, background 0.18s ease;
}
.deal-client-card:hover { border-color: #b7c3cc; background: var(--white); }
.deal-client-card strong { font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
.deal-client-card span,
.deal-client-card small { color: var(--steel-2); font-size: 11px; line-height: 1.45; }
.client-notes {
    flex: 1;
    min-height: 174px;
    margin: 24px;
    padding: 24px;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    color: var(--steel-1);
    background: #fafbfd;
    font-size: 14px;
    line-height: 1.75;
    overflow-wrap: anywhere;
}
.client-notes.is-empty { color: var(--steel-2); display: grid; place-items: center; text-align: center; }
.client-delete-shell {
    width: min(100%, 760px);
    margin: 0 auto;
}
.client-delete-panel {
    min-height: 530px;
    padding: clamp(32px, 6vw, 58px);
    display: flex;
    align-items: center;
    flex-direction: column;
    text-align: center;
}
.client-delete-icon {
    width: 64px;
    height: 64px;
    margin-bottom: 18px;
    border: 6px solid #fbf4f4;
    border-radius: 50%;
    color: var(--white);
    background: var(--negative);
    box-shadow: 0 10px 24px rgba(155, 66, 66, 0.16);
    display: grid;
    place-items: center;
    font-size: 24px;
    font-weight: 800;
}
.client-delete-panel h2 {
    max-width: 620px;
    margin: 8px 0 8px;
    font-size: clamp(25px, 3vw, 32px);
    line-height: 1.24;
    letter-spacing: -0.025em;
    overflow-wrap: anywhere;
}
.client-delete-lead { max-width: 590px; margin: 0; color: var(--steel-2); font-size: 14px; line-height: 1.65; }
.client-delete-impact {
    width: 100%;
    margin: 28px 0 0;
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    background: #fafbfd;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.client-delete-impact > div {
    min-height: 86px;
    padding: 16px;
    display: grid;
    place-content: center;
    gap: 4px;
}
.client-delete-impact > div + div { border-left: 1px solid var(--line-soft); }
.client-delete-impact dt { color: var(--steel-2); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.client-delete-impact dd { margin: 0; font-size: 16px; font-weight: 800; }
.client-delete-warning,
.client-delete-blocked {
    width: 100%;
    margin-top: 18px;
    padding: 14px 16px;
    border: 1px solid #ead0d0;
    border-radius: 8px;
    color: #7e3030;
    background: var(--negative-soft);
    font-size: 12px;
    line-height: 1.55;
}
.client-delete-blocked { display: grid; gap: 4px; }
.client-delete-blocked strong { font-size: 13px; }
.client-delete-actions { margin-top: 22px; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 10px; }

@media (max-width: 1180px) {
    .mail-filter-bar { align-items: stretch; flex-direction: column; }
    .mail-direction-tabs { width: max-content; max-width: 100%; overflow-x: auto; }
    .mail-search { width: 100%; min-width: 0; }
    .mail-row { grid-template-columns: 40px minmax(220px, 0.9fr) minmax(240px, 1.4fr); }
    /* Отдельная величина отступа больше не нужна: место под действие держит дорожка. */
}

@media (max-width: 900px) {
    .form-grid.form-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .client-detail-grid { grid-template-columns: 1fr; gap: 16px; }
    .client-detail-card { grid-column: 1 / -1; }
    .requisites-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
    .action-cluster { width: 100%; justify-content: stretch; }
    .action-cluster > a, .action-cluster > form, .action-cluster > form .button { flex: 1; }
    .topbar-actions .client-actions-trigger { width: 46px; }
    .mailbox-grid { grid-template-columns: 1fr; }
    .mailbox-card { grid-column: auto; }
    .mail-panel-head { align-items: flex-start; flex-direction: column; gap: 10px; }
    .mail-panel-stats { align-items: flex-start; flex-direction: column; text-align: left; }
    .mail-filter-bar { padding: 12px 14px; }
    .mail-direction-tabs { width: 100%; }
    .mail-direction-tabs a { flex: 1 0 auto; justify-content: center; }
    .mail-search { padding: 0; align-items: stretch; flex-direction: column; }
    .mail-route { grid-column: 2; }
    .candidate-actions { align-items: stretch; flex-direction: column; }
    .candidate-actions form, .candidate-actions .button { width: 100%; }
    .context-notice { grid-template-columns: 1fr; }
    .context-notice .eyebrow { grid-row: auto; }
    .form-section { padding: 0 18px 20px; }
    .form-section-head { min-height: 92px; margin: 0 -18px 20px; padding: 18px; align-items: flex-start; }
    .section-number { width: 36px; height: 36px; }
    .form-grid, .form-grid.form-grid-3 { grid-template-columns: 1fr; gap: 16px; }
    .sticky-form-actions { padding: 16px; align-items: stretch; flex-direction: column; }
    .sticky-form-actions .form-actions { width: 100%; }
    .client-search { padding: 14px; }
    .client-hero { min-height: auto; padding: 30px 18px 20px; gap: 18px; }
    .client-monogram { width: 60px; height: 60px; font-size: 20px; }
    .client-hero h2 { font-size: 24px; }
    .client-hero-meta { grid-template-columns: 1fr; }
    .client-hero-meta > div { min-height: 68px; padding: 12px 16px; }
    .client-hero-meta > div + div { border-top: 1px solid var(--line-soft); border-left: 0; }
    .client-card-head { min-height: 116px; padding: 22px 18px; }
    /* Узкий экран: содержимое и действие всегда друг под другом. */
    .client-card-head.has-action { padding: 22px 18px; flex-direction: column; gap: 14px; }
    .client-card-head.has-action > div { flex: 0 1 auto; }
    .client-data-grid,
    .requisites-grid,
    .bank-grid,
    .client-channel-grid { padding: 16px; grid-template-columns: 1fr; }
    .client-data-grid .data-wide { grid-column: auto; }
    .client-contacts-section { padding: 0 16px 16px; }
    .contact-card-grid,
    .deal-card-list { grid-template-columns: 1fr; }
    .deal-card-list { padding: 16px; }
    .client-notes { min-height: 150px; margin: 16px; padding: 20px; }
    .client-delete-panel { min-height: auto; padding: 30px 18px; }
    .client-delete-impact { grid-template-columns: 1fr; }
    .client-delete-impact > div { min-height: 68px; }
    .client-delete-impact > div + div { border-top: 1px solid var(--line-soft); border-left: 0; }
    .client-delete-actions { width: 100%; align-items: stretch; flex-direction: column; }
    .client-delete-actions .button { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; }
}

/* ==========================================================================
   101D — semantic accents, mail workspace, finance UI
   Extends the existing SABEKS palette; it does not replace it.
   ========================================================================== */

:root {
    /* Semantic accents. Green already meant "done", so "new/unread" and
       "needs attention" get their own hues instead of borrowing it. */
    --info: #2c5a86;
    --info-soft: #eaf1f8;
    --warning: #8a6320;
    --warning-soft: #fbf2e2;
    --neutral: #55677a;
    --neutral-soft: #eef1f4;

    /* Control rhythm: one height for every inline control. */
    /* Высота элемента управления одна на все ряды фильтров. Раньше их было
       три: 38 здесь, 40 в наборе величин и 46 у полей. */
    --control-h: 40px;
    --control-h-small: 32px;
    --space-05: 4px;
}

/* --- badges: colour is a hint, the text carries the meaning --------------- */
.badge.workspace-badge.warning { background: var(--warning-soft); color: var(--warning); }
.badge.workspace-badge.info { background: var(--info-soft); color: var(--info); }
.badge.workspace-badge.negative { background: var(--negative-soft); color: var(--negative); }
.badge.workspace-badge.muted { background: var(--neutral-soft); color: var(--neutral); }

/* --- unread mail: several signals at once, none of them loud ------------- */
.mail-row.unread {
    background: var(--info-soft);
    box-shadow: inset 4px 0 var(--info);
}
.mail-row.unread:hover { background: #e2ecf6; }
.mail-row.unread .mail-correspondent strong,
.mail-row.unread .mail-summary strong,
.mail-row.unread .mail-subject { font-weight: 700; color: var(--ink); }
.mail-row.unread .badge.new {
    background: var(--info);
    color: var(--white);
    font-weight: 600;
}
.unread-dot { background: var(--info); }
.unread-counter, .unread-counter.large { background: var(--info-soft); color: var(--info); }

/* --- bulk selection ------------------------------------------------------ */
.mail-row-wrap { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: stretch; }
.mail-row-wrap > .mail-row { min-width: 0; }
.mail-select-cell {
    display: flex;
    align-items: center;
    padding: 0 var(--space-1) 0 var(--space-2);
    border-bottom: 1px solid var(--line-soft);
    background: inherit;
}
.mail-row-wrap.unread .mail-select-cell { box-shadow: inset 4px 0 var(--info); }
.mail-select-cell input { width: 16px; height: 16px; cursor: pointer; }
.mail-bulk-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding: var(--space-1) var(--space-2);
    background: var(--neutral-soft);
    border-bottom: 1px solid var(--line-soft);
}
.mail-bulk-all { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
.mail-bulk-count { font-size: 13px; color: var(--steel-2); font-variant-numeric: tabular-nums; }
.mail-bulk-actions { margin-left: auto; display: flex; gap: var(--space-1); }

/* --- consistent inline controls ------------------------------------------ */
.inline-form { display: inline-flex; }
.button.small {
    min-height: var(--control-h-small);
    padding: 0 12px;
    font-size: 13px;
}
.button[disabled] { opacity: 0.6; cursor: progress; }

/* --- workspace hints and empty states ------------------------------------ */
.workspace-hint {
    margin: var(--space-1) 0 0;
    font-size: 13px;
    color: var(--steel-2);
}
.workspace-empty { color: var(--steel-2); font-size: 13px; }

/* --- finance -------------------------------------------------------------- */
.finance-activity-note {
    font-size: 13px;
    color: var(--steel-2);
    background: var(--info-soft);
    border-radius: var(--radius-small);
    padding: var(--space-1) var(--space-2);
}
.partner-wallet-card { border-left: 3px solid var(--info); }

/* --- email preview -------------------------------------------------------- */
.preview-toolbar { display: flex; gap: var(--space-1); flex-wrap: wrap; align-items: center; margin-bottom: var(--space-2); }
.preview-frame-wrap { display: flex; justify-content: center; background: var(--neutral-soft); padding: var(--space-2); border-radius: var(--radius); }
.preview-frame-wrap.dark { background: #1b2430; }
.preview-frame { width: 100%; max-width: 720px; height: 70vh; border: 1px solid var(--line-soft); border-radius: var(--radius-small); background: var(--white); }
.preview-frame.mobile { max-width: 390px; }

/* --- focus visibility ----------------------------------------------------- */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--info);
    outline-offset: 2px;
}

/* ==========================================================================
   101E — product pass: alert semantics, help, breadcrumbs, table fit
   ========================================================================== */

/* --- alerts: an error must never look like a success ---------------------- */
.message { border-color: #c6d3de; color: #24384c; background: var(--info-soft); }
.message.success { border-color: #c9dfd4; color: var(--positive); background: var(--positive-soft); }
.message.info    { border-color: #c6d3de; color: #24384c; background: var(--info-soft); }
.message.warning { border-color: #dfd0a5; color: #6b4f18; background: var(--warning-soft); }
.message.error   { border-color: #e0bcbc; color: #7d3030; background: var(--negative-soft); }
/* Состояние различается не только цветом: у каждого свой знак. Знаки — из
   общего набора, а не из шрифта: юникодные «i», «✓», «⚠», «✕» рисуются
   каждым начертанием по-своему, и рядом друг с другом выглядели разной
   толщины и на разной базовой линии. Цвет берётся от роли сообщения. */
:root {
    --icon-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3.5 8.5 6.5 11.5 12.5 4.5'/></svg>");
    --icon-warning: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2.6 14.6 13.4H1.4Z'/><path d='M8 6.6v3.1'/><path d='M8 11.9v.01'/></svg>");
    --icon-error: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M4.5 4.5 11.5 11.5'/><path d='M11.5 4.5 4.5 11.5'/></svg>");
    --icon-info: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='8' r='5.75'/><path d='M8 7.2v4'/><path d='M8 4.7v.01'/></svg>");
}
.message::before {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: 0 0 auto;
    margin-right: 8px;
    background-color: currentColor;
    -webkit-mask: var(--icon-info) center / contain no-repeat;
    mask: var(--icon-info) center / contain no-repeat;
}
.message.success::before {
    -webkit-mask-image: var(--icon-check);
    mask-image: var(--icon-check);
}
.message.warning::before {
    -webkit-mask-image: var(--icon-warning);
    mask-image: var(--icon-warning);
}
.message.error::before {
    -webkit-mask-image: var(--icon-error);
    mask-image: var(--icon-error);
}
/* Знак и текст стоят на одной линии: пока знак был буквой, их равняла
   базовая линия шрифта, а у коробки со значком её нет. */
.message { display: flex; align-items: flex-start; gap: 0; }
.message::before { margin-top: 1px; }

.workspace-notice.error { color: #7d3030; border-color: #e0bcbc; background: var(--negative-soft); }
.workspace-notice.info  { color: #24384c; border-color: #c6d3de; background: var(--info-soft); }
.workspace-notice.positive { border-color: var(--positive); background: var(--positive-soft); }

/* --- integration status strip -------------------------------------------- */
.sync-status {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--steel-2);
}
.sync-status .dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.sync-status.ok .dot { background: var(--positive); }
.sync-status.stale .dot { background: var(--warning); }
.sync-status.error .dot { background: var(--negative); }
.sync-status.running .dot { background: var(--info); }

/* --- breadcrumbs ---------------------------------------------------------- */
.breadcrumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 var(--space-1);
    font-size: 12px;
    color: var(--steel-2);
}
.breadcrumbs a { color: var(--steel-2); text-decoration: none; }
.breadcrumbs a:hover { color: var(--ink); text-decoration: underline; }
.breadcrumbs .sep { color: var(--steel-2); }
.breadcrumbs [aria-current="page"] { color: var(--ink); font-weight: 600; }

/* --- help: a compact action instead of a permanent banner ----------------- */
.help-toggle {
    width: var(--control-h);
    height: var(--control-h);
    padding: 0;
    border-radius: 50%;
    font-weight: 700;
    line-height: 1;
}
.help-panel {
    margin-bottom: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--mist);
    border-left: 3px solid var(--info);
    border-radius: var(--radius);
    background: var(--white);
}
.help-panel h2, .help-panel h3 { margin: 0 0 var(--space-1); font-size: var(--fs-lead); }
.help-panel dl { margin: 0; display: grid; gap: 10px; }
.help-panel dt { font-size: 13px; font-weight: 700; color: var(--ink); }
.help-panel dd { margin: 2px 0 0; font-size: 13px; color: var(--steel-2); line-height: 1.55; max-width: 78ch; }
.help-panel[hidden] { display: none; }

/* inline micro-help next to a metric or a term */
.hint-mark {
    display: inline-grid;
    place-items: center;
    width: 16px;
    height: 16px;
    margin-left: 4px;
    border-radius: 50%;
    border: 1px solid var(--steel-3);
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    cursor: help;
    vertical-align: middle;
}

/* --- metric cards become entry points, not dead ends ---------------------- */
.metric-card.linked { transition: border-color .12s ease, box-shadow .12s ease; }
.metric-card.linked:hover { border-color: var(--info); box-shadow: var(--shadow-float); }
.metric-card .metric-link { font-size: 12px; font-weight: 600; color: var(--info); text-decoration: none; }
.metric-card .metric-link:hover { text-decoration: underline; }

/* --- tables must fit the viewport ---------------------------------------- */
.table-wrap { width: 100%; overflow-x: auto; }
.data-table { width: 100%; table-layout: fixed; border-collapse: collapse; }
.data-table th, .data-table td {
    overflow-wrap: anywhere;
    word-break: normal;
    vertical-align: top;
}
.data-table td.numeric, .data-table th.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.workspace-cell-main { display: block; overflow-wrap: anywhere; }
.workspace-cell-sub { display: block; margin-top: 2px; color: var(--steel-2); font-size: 12px; overflow-wrap: anywhere; }

/* --- cards: text must never touch the border ------------------------------ */
.partner-wallet-card .metric-list { padding: var(--space-2) var(--space-3) var(--space-3); }
.metric-list { margin: 0; display: grid; gap: 10px; }
.metric-list > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.metric-list dt { color: var(--steel-2); font-size: 13px; }
.metric-list dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }

/* --- внешние ссылки -------------------------------------------------------
   Здесь стоял юникодный символ «↗». Он берётся из шрифта, а шрифт рисует его
   произвольно: другой наклон, другая толщина, другая базовая линия. Значок
   объявлен в наборе ниже. */

/* --- filter bar ----------------------------------------------------------- */
.filter-row { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: flex-end; }
.filter-row .form-control, .filter-row select, .filter-row input { min-height: var(--control-h); }
.filter-range { display: flex; align-items: center; gap: 6px; }
.filter-range input { width: 120px; }
.report-section { margin-bottom: 20px; }
.report-empty { padding: var(--space-2) var(--space-3) var(--space-3); }
.report-note { padding: 0 var(--space-3) var(--space-2); }
.report-sub { padding-left: 28px; color: var(--steel-2); }

/* ==========================================================================
   101E — operational lists must fit the viewport
   The old min-width forced a scrollbar inside every panel; instead the table
   now shares the available width and long values wrap.
   ========================================================================== */
.workspace-table {
    min-width: 0;
    width: 100%;
    table-layout: fixed;
}
.workspace-table th,
.workspace-table td {
    overflow-wrap: anywhere;
    word-break: normal;
    vertical-align: top;
}
.workspace-primary-link {
    display: block;
    max-width: none;
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
}
.workspace-cell-main { display: block; overflow-wrap: anywhere; }

/* Priority: the name gets the room, counters and statuses stay compact. */
.workspace-table th:first-child, .workspace-table td:first-child { width: 26%; }
.workspace-table th:nth-child(2), .workspace-table td:nth-child(2) { width: 16%; }
.workspace-table th:nth-child(3), .workspace-table td:nth-child(3) { width: 10%; }
.workspace-table th:nth-child(4), .workspace-table td:nth-child(4) { width: 16%; }
.workspace-table th:nth-child(5), .workspace-table td:nth-child(5) { width: 17%; }
.workspace-table th:nth-child(6), .workspace-table td:nth-child(6) { width: 15%; }
.workspace-table th:nth-child(7), .workspace-table td:nth-child(7) { width: 12%; }

/* Numbers read faster right-aligned and in tabular figures. */
.workspace-table td.numeric, .workspace-table th.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The wrapper keeps scrolling only as a last resort on very narrow screens. */
.table-wrap { overflow-x: auto; }
@media (min-width: 1100px) {
    .table-wrap { overflow-x: visible; }
}

/* --- review workflow ------------------------------------------------------ */
.review-layout { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(320px, .8fr); gap: var(--space-3); align-items: start; }
/* Раскладка «работа слева, справка справа» перестраивается на той же
   ступени, что и такая же раскладка в рассылках: боковая колонка в
   обеих занимает 320-340 пикселей, и раньше 1180 главной уже тесно. */
@media (max-width: 1180px) { .review-layout { grid-template-columns: minmax(0, 1fr); } }
.review-form { padding: var(--space-2) var(--space-3) var(--space-3); display: grid; gap: var(--space-2); }
.review-option { display: grid; grid-template-columns: auto minmax(0,1fr); gap: 10px; align-items: start; padding: 12px 14px; border: 1px solid var(--mist); border-radius: var(--radius-small); cursor: pointer; }
.review-option:hover { border-color: var(--info); background: var(--info-soft); }
.review-option input { margin-top: 2px; }
.review-option strong { display: block; font-size: 14px; }
.review-option small { display: block; margin-top: 2px; color: var(--steel-2); font-size: 12px; line-height: 1.5; }
.review-field { display: grid; gap: 4px; }
.review-field > span { font-size: 12px; font-weight: 600; color: var(--steel-2); }
.review-technical { margin: 0 var(--space-3) var(--space-3); }
.review-technical summary { cursor: pointer; font-size: 13px; color: var(--steel-2); }
.review-technical dl { margin-top: 10px; }
/* ==========================================================================
   101F — СИСТЕМА КОМПОНЕНТОВ

   Слой заменяет разрозненные правки отдельных страниц. Принцип: одинаковое
   действие выглядит одинаково везде, а не «похоже». Ниже описаны только
   компоненты; страничных исключений здесь нет намеренно - если экрану нужен
   особый вид, значит нужен новый компонент, а не локальный патч.
   ========================================================================== */

:root {
    /* Геометрия элементов управления. Одна высота на все кнопки, поля и
       селекторы: раньше соседние кнопки отличались на несколько пикселей и
       строка выглядела неровной. */
    --btn-h: 40px;
    /* Мелкая кнопка одной высоты во всём интерфейсе. Тридцать шесть —
       высота, которую требует соседство с полем копирования и с которой
       кнопка была описана изначально. */
    --btn-h-sm: 36px;
    --btn-radius: 8px;
    --btn-pad-x: 16px;
    --btn-pad-x-sm: 10px;
    --btn-font: 14px;
    --btn-font-sm: 13px;
    --btn-gap: 8px;
    --icon-size: 16px;

    /* Плотность. Крупная карточка оправдана только объёмом содержимого. */
    --card-pad: 20px;
    --card-pad-tight: 14px 16px;
    --kpi-min-h: 116px;
}

/* --------------------------------------------------------------------------
   1. КНОПКИ
   Шесть ролей, одна геометрия. Роль задаёт смысл, а не размер.
   -------------------------------------------------------------------------- */
.button,
a.button,
button.button {
    min-height: var(--btn-h);
    height: var(--btn-h);
    padding: 0 var(--btn-pad-x);
    gap: var(--btn-gap);
    border-radius: var(--btn-radius);
    font-size: var(--btn-font);
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Основное действие страницы. На экране оно должно быть одно. */
.button.primary { color: var(--white); border-color: var(--ink); background: var(--ink); }
.button.primary:hover { border-color: var(--steel-1); background: var(--steel-1); box-shadow: var(--shadow-float); }

/* Обычное действие. Вид по умолчанию. */
.button.secondary { color: var(--ink); border-color: var(--mist); background: var(--white); }
.button.secondary:hover { border-color: var(--steel-3); background: var(--paper); }

/* Второстепенное действие: без рамки, чтобы не спорить с основным. */
.button.ghost { border-color: transparent; background: transparent; color: var(--steel-2); }
.button.ghost:hover { border-color: var(--mist); background: var(--paper); color: var(--ink); }

/* Необратимое действие. */
.button.danger { color: var(--white); border-color: var(--negative); background: var(--negative); }

/* Переход на внешний сайт. Стрелка - часть системы иконок, а не случайный
   символ: раньше здесь стоял произвольный юникод, и владелец назвал его кривым. */
.button.external { padding-right: 12px; }
.button.external::after {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: none;
    background-color: currentColor;
    opacity: .7;
    -webkit-mask: var(--icon-external) center / contain no-repeat;
    mask: var(--icon-external) center / contain no-repeat;
}

/* Кнопка-иконка: строго квадратная, поэтому не выбивается из строки. */
.button.icon {
    width: var(--btn-h);
    padding: 0;
    flex: none;
}
.button.icon.small { width: var(--btn-h-sm); }

.button.small {
    min-height: var(--btn-h-sm);
    height: var(--btn-h-sm);
    padding: 0 var(--btn-pad-x-sm);
    font-size: var(--btn-font-sm);
}
.button[disabled], .button.is-disabled {
    opacity: .5;
    cursor: not-allowed;
    box-shadow: none;
}
.button:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   НАБОР ЗНАЧКОВ

   Одна сетка 16×16, одна обводка 1,5, скруглённые концы и соединения. Значки
   рисуются масками: цвет берётся у роли кнопки или у текста рядом, поэтому
   один и тот же значок не приходится заводить в трёх цветах.

   Оптическая величина у всех одна — 16 px. Раньше тот же значок ставили
   12, 13 и 14 пикселями в разных местах, и он выглядел то тонким, то жирным.
   -------------------------------------------------------------------------- */
:root {
    --icon-external: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M12.5 9.5V12A1.5 1.5 0 0 1 11 13.5H4A1.5 1.5 0 0 1 2.5 12V5A1.5 1.5 0 0 1 4 3.5h2.5'/><path d='M13.5 6.5v-4h-4'/><path d='M7.5 8.5 13.5 2.5'/></svg>");
    /* Второй знак вопроса удалён: правило, которое им пользовалось,
       ниже перебивалось общим. */
    --icon-copy: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='2.5' y='5.5' width='8' height='8' rx='1.6'/><path d='M5.5 5.5V4A1.5 1.5 0 0 1 7 2.5h5A1.5 1.5 0 0 1 13.5 4v5A1.5 1.5 0 0 1 12 10.5h-1.5'/></svg>");
    --icon-back: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M13.5 8H3'/><path d='M7.5 3.5 3 8l4.5 4.5'/></svg>");
}

/* Группа действий в шапке страницы: одинаковый ритм и перенос без «лесенки». */
.topbar-actions {
    display: flex;
    align-items: center;
    gap: var(--btn-gap);
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* --------------------------------------------------------------------------
   2. СПРАВКА
   Прежний круглый «?» висел в углу и выглядел случайным объектом. Теперь это
   обычное второстепенное действие в шапке, в одном ряду с остальными.
   -------------------------------------------------------------------------- */
.button.help-toggle {
    width: auto;
    height: var(--btn-h);
    /* Поля и начертание — общие для ряда. Своя величина делала кнопку
       уже соседних, хотя стоит она с ними в одном ряду и значит то же
       самое: второстепенное действие раздела. */
    padding: 0 var(--btn-pad-x);
    border-radius: var(--btn-radius);
    border-color: var(--mist);
    background: var(--white);
    color: var(--steel-2);
}
.button.help-toggle::before {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: none;
    background-color: currentColor;
    -webkit-mask: var(--icon-question) center / contain no-repeat;
    mask: var(--icon-question) center / contain no-repeat;
}
.button.help-toggle:hover { color: var(--ink); border-color: var(--steel-3); }
.button.help-toggle[aria-expanded="true"] {
    color: var(--info);
    border-color: var(--info);
    background: var(--info-soft);
}

.help-panel {
    margin-bottom: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--mist);
    border-left: 3px solid var(--info);
    border-radius: var(--radius);
    background: var(--white);
}
.help-panel h2, .help-panel h3 { margin: 0 0 4px; font-size: var(--fs-card); }
.help-panel .help-lead {
    margin: 0 0 var(--space-2);
    max-width: 80ch;
    color: var(--steel-2);
    font-size: 13px;
    line-height: 1.6;
}
.help-panel dl {
    margin: 0;
    display: grid;
    gap: var(--space-2);
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.help-panel dt { font-size: 13px; font-weight: 700; color: var(--ink); }
.help-panel dd { margin: 2px 0 0; font-size: 13px; color: var(--steel-2); line-height: 1.55; }
.help-panel .help-foot {
    margin: var(--space-2) 0 0;
    padding-top: var(--space-2);
    border-top: 1px solid var(--line-soft);
    font-size: 12px;
    color: var(--steel-2);
}

/* Микро-подсказка у термина или показателя. */
.hint-mark {
    display: inline-grid;
    place-items: center;
    width: 15px;
    height: 15px;
    margin-left: 4px;
    border-radius: 50%;
    border: 1px solid var(--steel-3);
    color: var(--steel-2);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    cursor: help;
    vertical-align: middle;
}
.hint-mark:hover { border-color: var(--info); color: var(--info); }

/* --------------------------------------------------------------------------
   3. КАРТОЧКИ ПОКАЗАТЕЛЕЙ
   Одинаковая геометрия и общая базовая линия: карточки в одном ряду больше не
   «пляшут». Показатель-агрегат обязан открывать свой состав.
   -------------------------------------------------------------------------- */
.metric-grid, .workspace-metrics, .finance-metric-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--space-2);
    margin-bottom: var(--space-3);
    align-items: stretch;
}
.metric-grid .metric-card, .workspace-metrics .metric-card { grid-column: auto; }

.metric-card {
    min-height: var(--kpi-min-h);
    padding: var(--card-pad);
    display: grid;
    /* Три ряда фиксированного назначения: подпись, число, пояснение. Именно
       это выравнивает числа соседних карточек по одной линии. */
    grid-template-rows: auto 1fr auto;
    gap: 2px;
    background: var(--white);
}
.metric-card > span {
    display: flex;
    align-items: center;
    min-height: 20px;
    color: var(--steel-2);
    font-size: 13px;
    font-weight: 600;
    line-height: 20px;
}
.metric-card > strong {
    margin: 0;
    align-self: end;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.03em;
    font-variant-numeric: tabular-nums;
}
.metric-card > small {
    min-height: 18px;
    color: var(--steel-2);
    font-size: 12px;
    line-height: 18px;
}

/* Кликабельная карточка: вся площадь - ссылка, отдельной надписи
   «Посмотреть →» больше нет, она только добавляла шум. */
a.metric-card, .metric-card.linked {
    text-decoration: none;
    color: inherit;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
a.metric-card:hover, .metric-card.linked:hover {
    border-color: var(--info);
    box-shadow: var(--shadow-float);
}
a.metric-card:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
a.metric-card::after {
    content: "";
    grid-row: 1;
    justify-self: end;
    align-self: center;
    width: 12px; height: 12px;
    background-color: var(--steel-3);
    -webkit-mask: var(--icon-external) center / contain no-repeat;
    mask: var(--icon-external) center / contain no-repeat;
    opacity: 0;
    transition: opacity .12s ease;
}
a.metric-card:hover::after { opacity: .6; }
.metric-card > span { grid-row: 1; grid-column: 1; }
a.metric-card { grid-template-columns: minmax(0, 1fr) auto; }
a.metric-card > strong, a.metric-card > small { grid-column: 1 / -1; }

.metric-card.attention { border-color: #e2c489; background: var(--warning-soft); }
.metric-card.attention > strong { color: var(--warning); }

/* --------------------------------------------------------------------------
   4. СЧЁТЧИКИ И ПОСТРАНИЧНАЯ НАВИГАЦИЯ
   Пользователь не должен считать строки глазами.
   -------------------------------------------------------------------------- */
.listing-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding: 10px var(--space-3);
    border-bottom: 1px solid var(--line-soft);
    background: var(--paper);
    font-size: 13px;
    color: var(--steel-2);
}
.listing-count { font-variant-numeric: tabular-nums; }
.listing-count strong { color: var(--ink); font-weight: 700; }
.listing-size { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.listing-size span { font-size: 12px; }
.listing-size a {
    padding: 2px 8px;
    border-radius: 4px;
    color: var(--steel-2);
    font-variant-numeric: tabular-nums;
}
.listing-size a:hover { background: var(--mist); color: var(--ink); }
.listing-size a.current { background: var(--ink); color: var(--white); font-weight: 700; }

.pagination {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid var(--line-soft);
}
.pagination .page-link {
    min-width: var(--btn-h-sm);
    height: var(--btn-h-sm);
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--mist);
    border-radius: 4px;
    background: var(--white);
    color: var(--ink);
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.pagination .page-link:hover { border-color: var(--steel-3); background: var(--paper); }
.pagination .page-link.current {
    border-color: var(--ink);
    background: var(--ink);
    color: var(--white);
    pointer-events: none;
}
.pagination .page-gap { padding: 0 4px; color: var(--steel-2); }
.pagination .page-position { margin-left: auto; font-size: 12px; color: var(--steel-2); }

/* --------------------------------------------------------------------------
   5. ЧИПЫ ФИЛЬТРА
   После перехода из показателя пользователь видит, почему список именно такой,
   и может снять любое условие по отдельности.
   -------------------------------------------------------------------------- */
.filter-chips {
    display: flex;
    align-items: center;
    gap: var(--btn-gap);
    flex-wrap: wrap;
    padding: 10px var(--space-3);
    border-bottom: 1px solid var(--line-soft);
    background: var(--info-soft);
}
.filter-chips .chips-label { font-size: 12px; font-weight: 700; color: var(--info); }
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: var(--btn-h-sm);
    padding: 0 6px 0 10px;
    border: 1px solid #c3d6e8;
    border-radius: 999px;
    background: var(--white);
    font-size: 12px;
    color: var(--ink);
}
.chip b { font-weight: 700; }
.chip .chip-remove {
    display: inline-grid;
    place-items: center;
    width: 18px; height: 18px;
    border-radius: 50%;
    color: var(--steel-2);
    font-size: 14px;
    line-height: 1;
}
.chip .chip-remove:hover { background: var(--mist); color: var(--ink); }
/* «Сбросить всё» — такое же действие, как и остальные в ряду, и цель
   нажатия у него та же. Строчка текста без высоты давала около
   восемнадцати пикселей при объявленном пороге тридцать шесть. */
.filter-chips .chips-reset {
    margin-left: auto;
    min-height: var(--btn-h-sm);
    padding: 0 8px;
    border-radius: var(--radius-small);
    display: inline-flex;
    align-items: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--info);
}
.filter-chips .chips-reset:hover { text-decoration: underline; background: var(--white); }
.filter-chips .chips-reset:active { background: var(--mist); }

/* --------------------------------------------------------------------------
   6. ПУСТЫЕ СОСТОЯНИЯ
   Пустой раздел не должен занимать пол-экрана.
   -------------------------------------------------------------------------- */
.empty { padding: var(--space-3) !important; }
.empty-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
}
.empty-content strong { font-size: 14px; font-weight: 700; color: var(--ink); }
.empty-content span { max-width: 46ch; color: var(--steel-2); font-size: 13px; line-height: 1.5; }
.empty-content .button { margin-top: 10px; }
tr.table-empty td { border-bottom: 0; }

/* --------------------------------------------------------------------------
   7. ТАБЛИЦЫ
   Горизонтальная прокрутка в рабочих списках запрещена. Колонки получают
   приоритет: главное видно всегда, второстепенное сжимается и переносится.
   -------------------------------------------------------------------------- */
.workspace-table-panel { min-width: 0; overflow: visible; }
.table-wrap { width: 100%; overflow-x: visible; }

.workspace-table {
    width: 100%;
    min-width: 0;
    table-layout: fixed;
    border-collapse: collapse;
}
.workspace-table th, .workspace-table td {
    padding: 12px var(--space-2);
    overflow-wrap: anywhere;
    word-break: normal;
    vertical-align: top;
}
.workspace-table th {
    font-size: 12px;
    font-weight: 700;
    color: var(--steel-2);
    text-align: left;
    white-space: normal;
}
.workspace-table td small {
    display: block;
    margin-top: 2px;
    color: var(--steel-2);
    font-size: 12px;
    line-height: 1.45;
}

/* Ширины по приоритету задаются классом на таблице, а не порядковым номером
   колонки: раньше шестая колонка любой таблицы получала одну и ту же ширину
   независимо от содержимого. */
.workspace-table col.col-wide { width: 24%; }
.workspace-table col.col-mid { width: 16%; }
.workspace-table col.col-narrow { width: 10%; }
.workspace-table col.col-status { width: 13%; }

.workspace-table td.amount-cell, .workspace-table th.amount-cell {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Второстепенные колонки уходят по очереди, а не ломают строку. Ступени
   привязаны к реальным устройствам: 1440 - рабочий монитор, 1280 - небольшой
   ноутбук, 1024 - планшет вертикально. Самая расходная колонка помечается
   optional-wide и исчезает первой. */
@media (max-width: 1439.98px) {
    .workspace-table col.optional-wide, .workspace-table th.optional-wide,
    .workspace-table td.optional-wide { display: none; }
}
@media (max-width: 1279.98px) {
    .workspace-table .col-optional, .workspace-table th.optional, .workspace-table td.optional { display: none; }
}
@media (max-width: 1023.98px) {
    .workspace-table .col-optional-2, .workspace-table th.optional-2, .workspace-table td.optional-2 { display: none; }
}

/* --------------------------------------------------------------------------
   8. ЗНАЧКИ СОСТОЯНИЙ
   -------------------------------------------------------------------------- */
.badge.workspace-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.badge.workspace-badge.positive { background: var(--positive-soft); color: var(--positive); }
.badge.workspace-badge.warning { background: var(--warning-soft); color: var(--warning); }
.badge.workspace-badge.info { background: var(--info-soft); color: var(--info); }
.badge.workspace-badge.negative { background: var(--negative-soft); color: var(--negative); }
.badge.workspace-badge.muted { background: var(--neutral-soft); color: var(--neutral); }

/* --------------------------------------------------------------------------
   9. КАРТОЧКА ПРОВЕРКИ
   Главное исправление: видно, кого именно подтверждает пользователь.
   -------------------------------------------------------------------------- */
.party-card {
    display: grid;
    gap: 4px;
    padding: 14px 16px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--white);
}
.party-card + .party-card { margin-top: var(--space-1); }
.party-card .party-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.party-card .party-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; color: var(--steel-2); }
.party-card .party-meta b { color: var(--ink); font-variant-numeric: tabular-nums; }
.party-card .party-why { font-size: 12px; color: var(--steel-2); line-height: 1.5; }
.party-card.is-addressee { border-color: #bcd4bf; background: #f6fbf7; }
.party-card.not-addressee { background: var(--paper); }
.party-card .party-blocker {
    margin-top: 4px;
    padding: 6px 10px;
    border-radius: 4px;
    background: var(--warning-soft);
    color: var(--warning);
    font-size: 12px;
    font-weight: 600;
}

/* Выбор адресата радио-карточками: пользователь выбирает лицо, а не абстракцию. */
.choice-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 12px;
    align-items: start;
    padding: 14px 16px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    cursor: pointer;
    background: var(--white);
}
.choice-card + .choice-card { margin-top: var(--space-1); }
.choice-card:hover { border-color: var(--info); background: var(--info-soft); }
.choice-card input { margin-top: 2px; width: 16px; height: 16px; }
.choice-card:has(input:checked) { border-color: var(--info); background: var(--info-soft); box-shadow: inset 0 0 0 1px var(--info); }
.choice-card .choice-title { display: block; font-size: 14px; font-weight: 700; color: var(--ink); }
.choice-card .choice-sub { display: block; margin-top: 2px; font-size: 13px; color: var(--steel-2); }
.choice-card .choice-effect {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--steel-2);
    line-height: 1.5;
}
.choice-card .choice-effect b { color: var(--ink); font-weight: 600; }

.publication-text {
    max-height: 320px;
    overflow-y: auto;
    padding: var(--space-2);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-small);
    background: var(--paper);
    font-size: 13px;
    line-height: 1.65;
    white-space: pre-wrap;
}

/* --------------------------------------------------------------------------
   10. КОПИРОВАНИЕ ИДЕНТИФИКАТОРА
   Нужно там, где внешний сайт не принимает прямую ссылку (КАД).
   -------------------------------------------------------------------------- */
/* Значение с действием, а не поле ввода: рамка обещала редактирование,
   которого нет, и не давала кнопке-значку её 36 пикселей. */
.copy-field {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    height: var(--btn-h-sm);
    padding: 0;
    border: 0;
    background: transparent;
}
.copy-field code {
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}
.copy-field .copy-button {
    display: inline-grid;
    place-items: center;
    /* Своего поля у кнопки не было, и браузер подставлял собственное. */
    padding: 0;
    width: var(--btn-h-sm);
    height: var(--btn-h-sm);
    border: 0;
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
}
.copy-field .copy-button::before {
    content: "";
    width: var(--icon-size); height: var(--icon-size);
    background-color: var(--steel-2);
    -webkit-mask: var(--icon-copy) center / contain no-repeat;
    mask: var(--icon-copy) center / contain no-repeat;
}
.copy-field .copy-button:hover { background: var(--mist); }
.copy-field.copied code { color: var(--positive); }
.copy-field.copied::after { content: "скопировано"; font-size: var(--fs-micro); color: var(--positive); padding-left: 2px; }

/* --------------------------------------------------------------------------
   11. ШАПКА СТРАНИЦЫ
   -------------------------------------------------------------------------- */
.topbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}
.topbar h1 { margin: 2px 0 0; line-height: 1.2; letter-spacing: -.02em; }
.workspace-subtitle {
    margin: calc(var(--space-3) * -1 + 4px) 0 var(--space-3);
    max-width: 92ch;
    color: var(--steel-2);
    font-size: 14px;
    line-height: 1.55;
}
.context-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--steel-2);
}
.context-back:hover { color: var(--ink); }
/* Стрелка возврата — значок из набора, а не символ «←» из шрифта. */
.context-back::before {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--icon-back) center / contain no-repeat;
    mask: var(--icon-back) center / contain no-repeat;
}

/* --------------------------------------------------------------------------
   12. РАЗДЕЛЫ И ГРУППЫ
   -------------------------------------------------------------------------- */
.section-intro {
    margin: 0 0 var(--space-2);
    display: grid;
    gap: 2px;
}
.section-intro h2 { margin: 0; font-size: 16px; }
.section-intro p { margin: 0; color: var(--steel-2); font-size: 13px; line-height: 1.55; }

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-2);
    align-items: stretch;
}
.card-grid > * { min-width: 0; }

/* Шаги мастера создания кампании. */
.wizard-steps { display: grid; gap: var(--space-1); counter-reset: step; }
.wizard-step {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    gap: 12px;
    align-items: center;
    padding: 12px 16px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--white);
}
.wizard-step::before {
    counter-increment: step;
    content: counter(step);
    display: grid;
    place-items: center;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: var(--neutral-soft);
    color: var(--steel-2);
    font-size: 13px;
    font-weight: 700;
}
/* Пройденный шаг: галочка рисуется фоном поверх заливки кружка — маска
   съела бы саму заливку. Цвет задан в рисунке. */
.wizard-step.done::before {
    content: "";
    background-color: var(--positive-soft);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%232f6f58' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3.5 8.5 6.5 11.5 12.5 4.5'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 16px 16px;
}
.wizard-step.current { border-color: var(--info); background: var(--info-soft); }
.wizard-step.current::before { background: var(--info); color: var(--white); }
.wizard-step .step-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.wizard-step .step-sub { display: block; margin-top: 2px; font-size: 12px; color: var(--steel-2); }
.wizard-step.blocked { opacity: .6; }

/* --------------------------------------------------------------------------
   13. ПЛОТНОСТЬ
   Крупная карточка только там, где есть содержимое.
   -------------------------------------------------------------------------- */
.panel { overflow: visible; }
.panel-head { padding: var(--space-2) var(--space-3); }
.panel-head h2 { font-size: 16px; }
.workspace-card .workspace-kv { padding: 0 var(--space-3) var(--space-3); }
.workspace-list article { padding: 12px var(--space-3); }
.setting-card { padding: var(--card-pad); }

/* Ни одна рабочая витрина не выезжает за пределы окна. */
.page-frame, .content, .workspace-table-panel, .panel { max-width: 100%; }



/* --- обзор: смысловые группы вместо плоского набора карточек --------------- */
.dashboard-group { margin-bottom: var(--space-4); }
.dashboard-group .metric-grid { margin-bottom: 0; }
.dashboard-group + .dashboard-group { margin-top: 0; }
.section-intro h2 { font-size: 15px; font-weight: 700; letter-spacing: .01em; }
.section-intro p { max-width: 90ch; }


/* --- карточка субъекта ------------------------------------------------------
   Шапка отвечает «кто это», а не повторяет имя. Разделы именованные, переход
   по ним - обычные якоря: работает без скриптов и переживает перезагрузку. */
.subject-header { padding: var(--card-pad); margin-bottom: var(--space-2); background: var(--white); }
.subject-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--space-2); }
.subject-facts {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: var(--space-2);
}
.subject-facts > div { min-width: 0; }
.subject-facts dt { color: var(--steel-2); font-size: 12px; font-weight: 600; }
.subject-facts dd {
    margin: 2px 0 0;
    font-size: 15px;
    font-weight: 600;
    overflow-wrap: anywhere;
    font-variant-numeric: tabular-nums;
}

.subject-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: var(--space-3);
}
.subject-nav a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: var(--btn-h-sm);
    padding: 0 12px;
    border: 1px solid var(--mist);
    border-radius: 999px;
    background: var(--white);
    color: var(--steel-2);
    font-size: 13px;
    font-weight: 600;
}
.subject-nav a:hover { border-color: var(--info); color: var(--ink); }
.subject-nav a b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Якорь не должен прятать заголовок раздела под верхнюю кромку. */
.workspace-card[id] { scroll-margin-top: var(--space-3); }

/* ==========================================================================
   101F, ДОПОЛНЕНИЕ B — исправления после осмотра владельцем
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. БОКОВОЕ МЕНЮ
   Меню обрывалось на высоте окна: нижние пункты становились недоступны, потому
   что прокручивалась страница, а не само меню. Теперь меню занимает всю высоту
   окна и прокручивается внутри себя, а логотип и подпись пользователя
   закреплены по краям.
   -------------------------------------------------------------------------- */

/* На планшете и телефоне меню стоит сверху и высота там действительно
   дефицитна. На настольном экране ритм от высоты не зависит. */
@media (max-width: 1023.98px) and (max-height: 700px) {
    .sidebar > .sidebar-foot { padding-top: var(--space-1); padding-bottom: var(--space-1); }
}

/* --------------------------------------------------------------------------
   2. ЗНАЧОК СПРАВКИ
   Текстовый символ «?» имел непредсказуемую базовую линию и визуально
   заваливался. Заменён на один SVG-компонент фиксированного размера,
   центрированный геометрически, а не по шрифту.
   -------------------------------------------------------------------------- */
:root {
    /* Один рисунок, одна обводка — как у остальных значков набора. */
    --icon-question: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='8' r='5.75'/><path d='M6.4 6.5c0-1 .8-1.7 1.8-1.7s1.7.7 1.7 1.6c0 1.3-1.7 1.4-1.7 2.7'/><path d='M8.2 11.6v.01'/></svg>");
}

.hint-mark {
    /* Кружок рисуется иконкой целиком: рамка плюс текст давали разное
       оптическое положение в разных шрифтовых контекстах. */
    display: inline-block;
    width: 20px;
    height: 20px;
    margin: 0 0 0 6px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    background-color: var(--steel-3);
    -webkit-mask: var(--icon-question) center / 16px 16px no-repeat;
    mask: var(--icon-question) center / 16px 16px no-repeat;
    font-size: 0;
    line-height: 0;
    color: transparent;
    cursor: help;
    /* Выравнивание по середине строки текста, а не по базовой линии. */
    vertical-align: -4px;
    transition: background-color .12s ease;
}
.hint-mark:hover { background-color: var(--info); }

/* Тот же компонент в кнопке «О разделе». */
.button.help-toggle::before {
    -webkit-mask: var(--icon-question) center / 16px 16px no-repeat;
    mask: var(--icon-question) center / 16px 16px no-repeat;
}

/* --------------------------------------------------------------------------
   3. ВЫПАДАЮЩИЕ СПИСКИ
   Системная стрелка прижималась к правой границе. Один компонент на всю CRM.
   -------------------------------------------------------------------------- */
:root {
    /* Галочка списка рисуется фоном, а не маской: цвет задаётся в самом
       рисунке. */
    --icon-chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1.4 1.6 6 6.2l4.6-4.6' fill='none' stroke='%234c667a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
select.form-control,
select.form-control.compact,
.workspace-filter select,
.form-field select {
    -webkit-appearance: none;
    appearance: none;
    padding-right: 40px;
    background-image: var(--icon-chevron);
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 8px;
    background-color: var(--white);
    cursor: pointer;
}
select.form-control::-ms-expand { display: none; }
select.form-control:focus { background-image: var(--icon-chevron); }

/* --------------------------------------------------------------------------
   4. РИТМ ОТСТУПОВ
   Между блоками местами не хватало воздуха. Одна шкала на всю систему.
   -------------------------------------------------------------------------- */
:root {
    --space-05: 4px;
    --space-1: 8px;
    --space-15: 12px;
    --space-2: 16px;
    --space-3: 24px;
    --space-4: 32px;
    --space-5: 40px;
    --space-6: 48px;
}
.page-frame > .topbar { margin-bottom: var(--space-4); }
.workspace-subtitle { margin-bottom: var(--space-4); }
.dashboard-group { margin-bottom: var(--space-5); }
.dashboard-group .section-intro { margin-bottom: var(--space-2); }
.panel + .panel,
.panel + .workspace-detail-grid,
.workspace-detail-grid + .panel { margin-top: var(--space-3); }
.metric-grid, .workspace-metrics, .finance-metric-grid { gap: var(--space-2); margin-bottom: var(--space-4); }
/* Поля шапки симметричны по вертикали: при 24 сверху и 16 снизу
   содержимое, выровненное по центру, смещалось на четыре пикселя
   вверх относительно оптического центра шапки. */
.panel-head { padding: var(--space-2) var(--space-3); }
.workspace-card .workspace-kv { padding: 0 var(--space-3) var(--space-3); }
.report-empty { padding: 0 var(--space-3) var(--space-3); }
.report-note { padding: 0 var(--space-3) var(--space-3); }
.workspace-tabs { margin-bottom: var(--space-3); }
.workspace-notice { margin-bottom: var(--space-3); }

/* --------------------------------------------------------------------------
   5. ТАБЛИЦЫ: ШИРИНА ПО СОДЕРЖИМОМУ
   Колонка «Исполнитель» была так узка, что «Не назначена» переносилось почти
   по буквам, а короткий «Приоритет» занимал лишнее место. Ширина задаётся
   смыслом колонки, а не её порядковым номером.
   -------------------------------------------------------------------------- */
.workspace-table { table-layout: fixed; }

/* Русские слова не разрываются посередине. Переносим по словам; длинные
   идентификаторы без пробелов ломаются только там, где иначе не помещаются. */
/* Перенос разрешён и внутри слова. «По словам» звучит бережнее, но у такого
   переноса есть следствие: столбец не может стать уже своего самого длинного
   значения. Адрес почты пробелов не содержит, и таблица в колонке вдвое уже
   начинала прокручиваться вбок вместо того, чтобы сжаться. Внутри слова
   браузер режет только тогда, когда иначе не помещается. */
.workspace-table td,
.workspace-table th { overflow-wrap: anywhere; word-break: normal; hyphens: none; }
.workspace-table td.amount-cell,
.workspace-table th.amount-cell { white-space: nowrap; }
.workspace-cell-main { overflow-wrap: break-word; word-break: normal; }
.workspace-primary-link { overflow-wrap: break-word; word-break: normal; }

/* Семантические классы ширины. Порядковых правил больше нет. */
.workspace-table col.w-name { width: auto; }
.workspace-table col.w-object { width: 18%; }
.workspace-table col.w-person { width: 170px; }
.workspace-table col.w-priority { width: 104px; }
.workspace-table col.w-date { width: 160px; }
.workspace-table col.w-origin { width: 128px; }
.workspace-table col.w-status { width: 116px; }
.workspace-table col.w-count { width: 92px; }
.workspace-table col.w-money { width: 150px; }
.workspace-table col.w-ident { width: 168px; }
.workspace-table col.w-contact { width: 20%; }
.workspace-table col.w-badge { width: 150px; }

/* Ячейки с короткими значениями не должны переносить их вовсе. */
.workspace-table td.nowrap { white-space: nowrap; }

/* Старые правила по номеру колонки отменяются: они назначали одну и ту же
   ширину шестой колонке любой таблицы независимо от содержимого. */
.workspace-table th:first-child, .workspace-table td:first-child,
.workspace-table th:nth-child(2), .workspace-table td:nth-child(2),
.workspace-table th:nth-child(3), .workspace-table td:nth-child(3),
.workspace-table th:nth-child(4), .workspace-table td:nth-child(4),
.workspace-table th:nth-child(5), .workspace-table td:nth-child(5),
.workspace-table th:nth-child(6), .workspace-table td:nth-child(6),
.workspace-table th:nth-child(7), .workspace-table td:nth-child(7) { width: auto; }

/* На узком экране таблица становится карточками: ломать русский текст по
   буквам ради сохранения колонок недопустимо. */
@media (max-width: 767.98px) {
    .workspace-table, .workspace-table tbody, .workspace-table tr, .workspace-table td {
        display: block;
        width: auto;
    }
    .workspace-table thead { display: none; }
    .workspace-table colgroup { display: none; }
    .workspace-table tr {
        padding: var(--space-2);
        border: 1px solid var(--mist);
        border-radius: var(--radius-small);
        background: var(--white);
    }
    .workspace-table tr + tr { margin-top: var(--space-1); }
    .workspace-table td { padding: 2px 0; border: 0; }
    .workspace-table td.amount-cell { text-align: left; }
    .workspace-table td.optional, .workspace-table td.optional-2 { display: block; }
    .workspace-table tr.table-empty { padding: 0; }
}

/* --------------------------------------------------------------------------
   6. ШАПКА СТРАНИЦЫ
   Крошки, подпись системы, заголовок и возврат стояли слишком плотно и
   читались как один блок.
   -------------------------------------------------------------------------- */
.topbar .breadcrumbs { margin-bottom: var(--space-1); }
.topbar .context-back { margin: 0 0 var(--space-1); }
.topbar .eyebrow { display: block; margin-bottom: 2px; }
.topbar h1 { margin-top: 0; }
/* U6, замечание 4: «Назад» — одна кнопка, всегда над путём. Прежде она
   пряталась при наличии крошек, и её роль брала стрелка внутри пути — та
   стояла на разных ступенях и читалась украшением. Теперь кнопка стоит
   первой строкой шапки, а путь показывает только путь. */
.topbar .context-back + .breadcrumbs { margin-top: 0; }


/* --- обзор: короткий предпросмотр работы вместо полной очереди ------------- */
.inbox-preview { padding: 0 var(--space-3) var(--space-3); display: grid; gap: var(--space-1); }
.inbox-row {
    display: grid;
    gap: 4px;
    padding: 10px 12px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-small);
    background: var(--white);
    color: inherit;
}
.inbox-row:hover { border-color: var(--info); background: var(--info-soft); }
.inbox-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.inbox-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; font-size: 12px; color: var(--steel-2); }
.inbox-about { overflow-wrap: break-word; }
.inbox-due.overdue { color: var(--negative); font-weight: 600; }

/* --- настройка обзора ------------------------------------------------------ */
.group-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-2); }
.group-move { display: inline-flex; gap: 4px; }
.group-move .button { width: 28px; height: 28px; padding: 0; }
.widget-choices { display: grid; gap: 6px; }
.widget-choice { display: grid; grid-template-columns: auto minmax(0,1fr); gap: 10px; align-items: start; padding: 8px 10px; border: 1px solid var(--line-soft); border-radius: var(--radius-small); cursor: pointer; }
.widget-choice:hover { border-color: var(--info); background: var(--info-soft); }
.widget-choice input { margin-top: 2px; width: 16px; height: 16px; }
.widget-choice b { display: block; font-size: 13px; font-weight: 600; color: var(--ink); }
.widget-choice small { display: block; margin-top: 2px; font-size: 12px; color: var(--steel-2); }


/* --- тестовая отправка: чьи данные и кому уйдёт ---------------------------- */
.test-summary {
    display: grid;
    grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
    gap: var(--space-2);
    align-items: center;
    padding: var(--space-2);
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--paper);
}
.test-summary > div { min-width: 0; display: grid; gap: 2px; }
.test-summary .test-label { font-size: 11px; font-weight: 700; color: var(--steel-2); }
.test-summary strong { font-size: 14px; overflow-wrap: break-word; }
.test-summary small { font-size: 12px; color: var(--steel-2); overflow-wrap: break-word; }
.test-summary .test-arrow { font-size: 20px; color: var(--steel-2); text-align: center; }
@media (max-width: 720px) {
    .test-summary { grid-template-columns: minmax(0,1fr); }
    .test-summary .test-arrow { transform: rotate(90deg); }
}


/* ==========================================================================
   101G — ЕДИНАЯ СИСТЕМА ИНТЕРФЕЙСА

   Раздел появился после измерения всех production-страниц: 22 разных сочетания
   размера и начертания шрифта, формы, вылезающие за контейнер на 273 px,
   карточки разной высоты в одном ряду, таблицы с равными долями колонок и
   переносами по одному слову. Это не набор заплаток по страницам: здесь
   описаны роли элементов, а страницы этими ролями пользуются.

   Порядок раздела: поверхности → типографика → кнопки → поля → таблицы →
   карточки → состояния → адаптив.
   ========================================================================== */

:root {
    /* Отступы страницы. Один набор на все разделы, чтобы карточки в разных
       местах начинались на одной линии. */
    --gutter: clamp(16px, 2.2vw, 40px);
    --card-pad: var(--space-3);
    --btn-h: 40px;
    --btn-h-sm: 36px;
    --field-h: 40px;
    --info: #2c5c86;
    --info-soft: #e8f0f7;
    --neutral-soft: #eef1f4;
}

/* --------------------------------------------------------------------------
   1. НИЧТО НЕ ВЫЛЕЗАЕТ ЗА СВОЙ КОНТЕЙНЕР

   Причина почти всех горизонтальных вылетов одна: элемент внутри grid/flex по
   умолчанию не может стать уже своего содержимого. Длинный адрес почты,
   message-id или полное наименование организации растягивали панель, и вместе
   с ней уезжала вся страница.
   -------------------------------------------------------------------------- */
.app-shell :where(div, section, article, aside, header, footer, form, dl, dd,
                  ul, ol, li, p, label, fieldset) { min-width: 0; }

.app-shell :where(p, span, strong, small, b, em, dd, dt, td, th, li, a, h1, h2, h3, h4) {
    /* Русский текст нельзя резать по буквам: переносим по словам, а слишком
       длинный идентификатор — где придётся, но только его. */
    overflow-wrap: break-word;
    word-break: normal;
    hyphens: none;
}
.app-shell :where(code, .mono, .copy-field code, .message-id, .token-value) {
    overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   2. ТИПОГРАФИКА ПО РОЛЯМ
   -------------------------------------------------------------------------- */
body { font-size: var(--fs-base); line-height: var(--lh-normal); }

/* Кегль заголовка страницы берётся со шкалы, а не считается от ширины окна.
   Плавная величина давала 27 px на 1440 и 24,4 на 1280 — размеры, которых в
   наборе нет, и заголовок оказывался чуть разным на каждом экране. Две
   U8: ступень одна на все ширины и та же, что у заголовка экрана в разделе
   «Рассылки» (--fs-page, 26 px). Прежде их было две — 24 и 30 на широком, —
   и ни одна не совпадала с разделом. */
.topbar h1 {
    font-size: var(--fs-page);
    font-weight: 700;
    line-height: var(--lh-tight);
    letter-spacing: -0.02em;
}
.topbar .eyebrow,
.eyebrow {
    display: block;
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 16px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.panel-head h2 { font-size: var(--fs-card); font-weight: 700; line-height: var(--lh-tight); }
.workspace-subtitle { font-size: var(--fs-lead); line-height: var(--lh-relaxed); color: var(--steel-2); }
.workspace-kv dt, .workspace-hero dt, .subject-facts dt {
    font-size: var(--fs-micro);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--steel-2);
}
.workspace-kv dd, .workspace-hero dd { font-size: var(--fs-base); line-height: var(--lh-normal); }
small, .form-hint, .workspace-hint { font-size: var(--fs-meta); line-height: 1.45; }
.workspace-hint { color: var(--steel-2); }

/* Деловые наименования не пишутся капслоком: длинная строка прописными
   читается заметно хуже и выглядит техническим дампом. */
.business-name, .workspace-primary-link, .party-name, .subject-title {
    text-transform: none;
    font-variant-caps: normal;
}

/* --------------------------------------------------------------------------
   3. КНОПКИ: ШЕСТЬ РОЛЕЙ, ОДНА ГЕОМЕТРИЯ
   -------------------------------------------------------------------------- */
.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--btn-h);
    min-height: var(--btn-h);
    padding: 0 16px;
    /* Кнопка без роли всё равно кнопка: на белой панели прозрачная рамка
       не давала ей ни границы, ни формы. Роли задают свой цвет рамки
       ниже и это правило перекрывают. */
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    font-size: var(--fs-sm);
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}
.button.small { height: var(--btn-h-sm); min-height: var(--btn-h-sm); padding: 0 12px; font-size: var(--fs-meta); }
.button.primary { color: var(--white); background: var(--ink); border-color: var(--ink); }
.button.primary:hover { background: var(--steel-1); border-color: var(--steel-1); }
.button.secondary { color: var(--ink); background: var(--white); border-color: var(--mist); }
.button.secondary:hover { border-color: var(--steel-3); background: var(--paper); }
.button.ghost { color: var(--steel-2); background: transparent; border-color: transparent; }
.button.ghost:hover { color: var(--ink); background: var(--neutral-soft); }
.button.danger { color: var(--white); background: var(--negative); border-color: var(--negative); }
.button.danger:hover { filter: brightness(1.08); }
.button[disabled], .button.is-disabled {
    opacity: 1;
    color: var(--steel-3);
    background: var(--neutral-soft);
    border-color: var(--line-soft);
    cursor: not-allowed;
}
.button:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

/* Внешний переход помечается одним значком, а не разными символами в разных
   разделах: ЕФРСБ и КАД должны выглядеть одинаково. */
.button.external::after,
a.external:not(.button)::after {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: 0 0 auto;
    background: currentColor;
    -webkit-mask: var(--icon-external) center / var(--icon-size) var(--icon-size) no-repeat;
    mask: var(--icon-external) center / var(--icon-size) var(--icon-size) no-repeat;
}
/* Ссылка без вида кнопки помечается тем же значком: «Открыть КАД» в списке
   и «Открыть КАД» кнопкой — одно и то же действие. */
a.external:not(.button) { display: inline-flex; align-items: center; gap: 4px; }
:root {
    /* Второй рисунок тех же двух значков удалён: набор объявляется один раз.
       Пока их было два, внешняя ссылка выглядела по-разному в шапке и в списке. */
}

/* Панель действий: одинаковые промежутки и перенос без прилипания к краю. */
.topbar-actions, .form-actions, .workspace-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
}
.form-actions { margin-top: var(--space-3); }

/* --------------------------------------------------------------------------
   4. ПОЛЯ ВВОДА
   -------------------------------------------------------------------------- */
.form-control {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    height: var(--field-h);
    padding: 0 12px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--white);
    color: var(--ink);
    font-size: var(--fs-base);
    line-height: 1.4;
}
textarea.form-control { height: auto; min-height: 96px; padding: 10px 12px; resize: vertical; }
select.form-control {
    appearance: none;
    -webkit-appearance: none;
    /* Своя стрелка: системная в разных браузерах прижимается к краю и
       выглядит по-разному. Отступ справа рассчитан под значок. */
    padding-right: 38px;
    background-image: var(--icon-chevron);
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px 16px;
}
.form-control:focus-visible { outline: 2px solid var(--info); outline-offset: 1px; border-color: var(--steel-2); }
.form-control::placeholder { color: var(--steel-2); }
.form-control[disabled], .form-control[readonly] { background: var(--paper); color: var(--steel-2); }

/* Поля одного ряда начинаются с одной линии. Поле — сетка из подписи,
   управления и пояснения; у соседа по ряду пояснения может не быть, и его
   ряды растягивались на высоту соседа: подпись занимала две строки вместо
   одной, а поле ввода уезжало на 12 пикселей ниже. Ряды прижимаются к верху.
   Раньше это было исправлено только для .field в .form-grid — .form-field,
   на котором собраны все формы продукта, правило не покрывало. */
.form-field, .field { display: grid; gap: 6px; min-width: 0; align-content: start; }
/* Поле даты имеет собственную минимальную ширину и в узкой колонке не
   сжимается: без этого пара полей выталкивает форму за пределы экрана.
   Правило общее — узкие колонки есть не только в рассылках. */
.form-field .form-control, .field .form-control { min-width: 0; max-width: 100%; }
.form-field > span, .field > label, .form-label {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--steel-1);
}
.form-hint, .form-field > small, .field > small { color: var(--steel-2); }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-2) var(--space-2); }
.form-grid > * { min-width: 0; }
.form-field-check { display: flex; align-items: flex-start; gap: 10px; }
.form-field-check input { margin-top: 2px; width: 16px; height: 16px; flex: 0 0 auto; }

/* Строка фильтра списка: поля и кнопка одной высоты. */
.workspace-filter { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
.workspace-filter .form-control, .workspace-filter .button { height: var(--field-h); }
.workspace-filter label { min-width: 0; }
.workspace-search { flex: 1 1 260px; }

/* --------------------------------------------------------------------------
   5. ТАБЛИЦЫ

   Колонка получает ширину по смыслу содержимого. Там, где вид ещё не задал
   раскладку, таблица считает ширину сама (table-layout: auto) — это заметно
   лучше равных долей, из-за которых «Не назначена» переносилось по слогам.
   -------------------------------------------------------------------------- */
.workspace-table, .data-table { width: 100%; table-layout: auto; border-collapse: collapse; }
.workspace-table:has(colgroup) { table-layout: fixed; }
/* Финансовая таблица набирается так же, как справочная: своей плотности
   у неё не было, и она падала на общее правило 12 на 20. */
.workspace-table th, .data-table th, .finance-table th {
    padding: 10px var(--space-2);
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 16px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid var(--line-soft);
}
.workspace-table td, .data-table td, .finance-table td {
    padding: 12px var(--space-2);
    font-size: var(--fs-sm);
    line-height: 1.45;
    vertical-align: top;
    border-bottom: 1px solid var(--line-soft);
}
.workspace-table tbody tr:last-child td, .data-table tbody tr:last-child td { border-bottom: 0; }
.workspace-table td small, .data-table td small {
    display: block;
    margin-top: 2px;
    color: var(--steel-2);
    font-size: var(--fs-meta);
}
/* Деньги и счётчики — вправо, цифры одной ширины: столбец читается сверху вниз. */
.workspace-table .amount-cell, .data-table .amount-cell,
.workspace-table th.amount-cell, .data-table th.amount-cell,
.num, td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Короткие значения не должны рваться на строки. */
.nowrap, td.nowrap { white-space: nowrap; }

.workspace-table col.w-name { width: auto; }
.workspace-table col.w-object { width: 17%; }
.workspace-table col.w-person { width: 168px; }
.workspace-table col.w-priority { width: 96px; }
.workspace-table col.w-date { width: 132px; }
.workspace-table col.w-origin { width: 132px; }
.workspace-table col.w-status { width: 124px; }
.workspace-table col.w-count { width: 84px; }
.workspace-table col.w-money { width: 136px; }
.workspace-table col.w-ident { width: 160px; }
.workspace-table col.w-contact { width: 22%; }
.workspace-table col.w-badge { width: 148px; }
.workspace-table col.w-service { width: 200px; }
.workspace-table col.w-stage { width: 150px; }
.workspace-table col.w-mode { width: 116px; }
.workspace-table col.w-actions { width: 120px; }
.workspace-table col.w-email { width: 24%; }
.workspace-table col.w-reason { width: 22%; }

/* Ячейки, где перенос по одному слову недопустим. */
.workspace-table td.w-person, .workspace-table td.w-status,
.workspace-table td.w-priority, .workspace-table td.w-origin,
.workspace-table td.w-mode { overflow-wrap: normal; }

.table-wrap { width: 100%; }

/* --------------------------------------------------------------------------
   6. КАРТОЧКИ ПОКАЗАТЕЛЕЙ

   В одном ряду карточки одного типа обязаны быть одной высоты, а значение —
   стоять на одной линии. Раньше высоты расходились на 20 px, и ряд «плыл».
   -------------------------------------------------------------------------- */
.metric-grid, .workspace-metrics, .finance-metric-grid { align-items: stretch; }
.metric-card {
    height: 100%;
    min-height: 0;
    padding: var(--space-2) var(--space-3);
    display: grid;
    grid-template-rows: auto 1fr auto;
    gap: 6px;
    align-content: start;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    background: var(--white);
}
.metric-card > span {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--steel-2);
    font-size: var(--fs-meta);
    font-weight: 600;
    line-height: 1.35;
}
.metric-card > strong {
    align-self: start;
    font-size: var(--fs-block);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}
.metric-card > small { color: var(--steel-2); font-size: var(--fs-meta); line-height: 1.4; }
a.metric-card { transition: border-color 140ms ease, box-shadow 140ms ease; }
a.metric-card:hover { border-color: var(--steel-3); box-shadow: var(--shadow-card); }
a.metric-card:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   7. СОСТОЯНИЯ: ЗНАЧЕНИЕ, А НЕ РАЗНООБРАЗИЕ

   Цвет означает состояние. Пять ролей, больше нет.
   -------------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 100%;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: var(--fs-meta);
    font-weight: 700;
    line-height: 17px;
    white-space: nowrap;
    color: var(--steel-1);
    background: var(--neutral-soft);
}
.badge.positive, .badge.success { color: var(--positive); background: var(--positive-soft); }
.badge.warning { color: var(--warning); background: var(--warning-soft); }
.badge.negative, .badge.danger { color: var(--negative); background: var(--negative-soft); }
.badge.info { color: var(--info); background: var(--info-soft); }
.badge.muted, .badge.neutral { color: var(--steel-2); background: var(--neutral-soft); }

.tone-warning { color: var(--warning); }
.tone-negative { color: var(--negative); }
.tone-positive { color: var(--positive); }

/* Пустой раздел объясняет, что здесь будет, и предлагает действие. */
.empty-content {
    padding: var(--space-5) var(--space-3);
    display: grid;
    justify-items: center;
    gap: 8px;
    text-align: center;
}
.empty-content strong { font-size: var(--fs-card); font-weight: 700; }
.empty-content span { max-width: 52ch; color: var(--steel-2); font-size: var(--fs-sm); }
.empty-content .button { margin-top: 6px; }

/* --------------------------------------------------------------------------
   8. ШАПКА СТРАНИЦЫ

   Брендовая строка, путь по разделам и заголовок не должны сливаться в кашу.
   -------------------------------------------------------------------------- */
.topbar { align-items: flex-start; gap: var(--space-3); }
.topbar > div:first-child { display: grid; gap: 4px; min-width: 0; }
.breadcrumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 2px;
    color: var(--steel-2);
    font-size: var(--fs-meta);
    font-weight: 600;
}
.breadcrumbs a:hover { color: var(--ink); text-decoration: underline; }
.breadcrumbs .sep { color: var(--steel-2); }
/* Стрелка и подпись — одно действие, поэтому они лежат в одной строке
   и подчёркиваются вместе. */
.context-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--steel-2);
    font-size: var(--fs-meta);
    font-weight: 600;
}
.context-back:hover { color: var(--ink); }

/* --------------------------------------------------------------------------
   9. АДАПТИВ: ОТ ТЕЛЕФОНА ДО БОЛЬШОГО ЭКРАНА

   Ступени выбраны по реальным устройствам, а не по круглым числам:
     до 480   — телефон вертикально
     480-767  — телефон горизонтально, крупный телефон
     768-1023 — планшет вертикально
     1024-1279— планшет горизонтально, небольшой ноутбук
     1280-1919— рабочий монитор
     от 1920  — большой монитор
   Приложение остаётся двухколонным, начиная с планшета горизонтально.
   -------------------------------------------------------------------------- */
@media (min-width: 1920px) {
    .page-frame { max-width: 1720px; }
}

@media (max-width: 1279.98px) {
    :root { --sidebar-w: 216px; }
    .content { padding: var(--space-3) var(--gutter) var(--space-5); }
}

@media (max-width: 1023.98px) {
    /* Планшет вертикально и уже: две прокручиваемые колонки не помещаются,
       приложение становится обычной страницей с меню сверху. */
    body.app { height: auto; overflow: visible; }
    .app-shell { height: auto; grid-template-columns: 1fr; overflow: visible; }
    .sidebar {
        position: sticky;
        top: 0;
        z-index: 20;
        height: auto;
        display: block;
        padding: var(--space-2) var(--gutter);
        overflow: visible;
    }
    .content { height: auto; overflow: visible; padding: var(--space-3) var(--gutter) var(--space-5); }
    .sidebar-foot { display: none; }
}

@media (max-width: 767.98px) {
    .nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .topbar { flex-direction: column; gap: var(--space-2); }
    .topbar-actions { width: 100%; }
    .topbar-actions .button { flex: 1 1 auto; }
    .form-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 479.98px) {
    .nav { grid-template-columns: minmax(0, 1fr); }
    .metric-card { padding: var(--space-2); }
    .content { padding: var(--space-2) var(--space-2) var(--space-4); }
}

/* Телефон горизонтально: высоты мало, шапка не должна съедать экран.
   Ширина в условии обязательна: без неё правило срабатывало и в невысоком
   настольном окне — например, при масштабе 200%. */
@media (max-width: 1023.98px) and (max-height: 520px) and (orientation: landscape) {
    .topbar { min-height: auto; }
    .topbar h1 { font-size: var(--fs-section); }
    .sidebar { padding-top: var(--space-1); padding-bottom: var(--space-1); }
}

/* Указатель без наведения (тач): состояние не может держаться только на hover. */
@media (hover: none) and (pointer: coarse) {
    .button, .nav a, .metric-card, .page-link { -webkit-tap-highlight-color: rgba(44, 92, 134, .12); }
    .button, .page-link, .chip-remove { min-height: var(--btn-h); }
}


/* --------------------------------------------------------------------------
   101G, уточнения после второго прогона измерений
   -------------------------------------------------------------------------- */

/* Заголовок колонки может перенестись: при фиксированной раскладке запрет
   переноса делал минимальную ширину таблицы больше окна и выталкивал страницу
   вбок. Заголовки короткие, вторая строка ничего не ломает. */
.workspace-table th, .data-table th { white-space: normal; }

/* Строка фильтра: поле поиска, выпадающие списки и кнопка — одной высоты.
   Разница в 6 px читается как небрежность. */
.workspace-filter :where(.form-control, .button, button, input, select) {
    height: var(--field-h);
    min-height: var(--field-h);
}
.workspace-filter label { display: flex; align-items: center; }

/* Значок состояния не растягивает ячейку: длинная подпись переносится. */
.badge.workspace-badge, .badge {
    max-width: 100%;
    white-space: normal;
    text-align: left;
}

/* Карточки показателей в одном ряду — одной высоты. Раньше высота зависела от
   длины подписи, и ряд «плыл». */
.metric-grid, .finance-metric-grid, .workspace-metrics { align-items: stretch; }
.metric-grid > *, .finance-metric-grid > *, .workspace-metrics > * { height: 100%; }

/* Карточки счетов: содержимое разной длины не должно менять высоту карточки. */
.account-grid { align-items: stretch; }
.account-card { height: 100%; display: flex; flex-direction: column; }
.account-card .account-balance-block { margin-top: auto; }

/* Почта: тема и адрес — длинные строки без пробелов, они растягивали строку
   списка. Показываем не более двух строк, остальное — в карточке письма. */
.mail-correspondent strong, .mail-summary strong, .mail-summary span, .mail-summary small {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}
.mail-row { min-width: 0; }

/* Финансовые панели: таблица внутри панели не расширяет саму панель. */
.finance-main-panel, .finance-side, .finance-layout > * { min-width: 0; }
.finance-main-panel table, .finance-side table { width: 100%; table-layout: fixed; }

/* Деньги во всех финансовых таблицах — вправо и моноширинными цифрами. */
.finance-main-panel td:last-child, .finance-side td:last-child,
.data-table td.money, .data-table th.money {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* Расход и доход различаются знаком и цветом, а не только положением. */
.amount-negative, td .negative-amount { color: var(--negative); }
.amount-positive, td .positive-amount { color: var(--positive); }

/* Пары «показатель — значение» не выталкивают карточку. */
.metric-list, .metric-list > div { min-width: 0; }
.metric-list dd { overflow-wrap: anywhere; }

/* Карточка задачи: сведения о ситуации не должны расширять панель. */
.party-card { min-width: 0; }
.party-card > span { min-width: 0; overflow-wrap: break-word; }
.party-meta { display: flex; flex-wrap: wrap; gap: 4px var(--space-2); min-width: 0; }


/* --------------------------------------------------------------------------
   101G, третий прогон: скрытие колонок, выравнивание карточек, деньги
   -------------------------------------------------------------------------- */

/* Скрыть колонку одним `display:none` на `col` недостаточно: при фиксированной
   раскладке браузер всё равно резервирует объявленную ширину, и оставшимся
   колонкам достаётся по три пикселя. Ширина обнуляется явно. */
@media (max-width: 1439.98px) {
    .workspace-table col.optional-wide { width: 0; visibility: collapse; }
}
@media (max-width: 1279.98px) {
    .workspace-table col.optional { width: 0; visibility: collapse; }
}
@media (max-width: 1023.98px) {
    .workspace-table col.optional-2 { width: 0; visibility: collapse; }
}

/* Числовая ячейка выравнивается вправо, но перенос ей не запрещён: в этой же
   колонке иногда стоит пояснение, и запрет переноса выталкивал таблицу. */
.workspace-table td.amount-cell, .data-table td.amount-cell { white-space: normal; }
.workspace-table td.amount-cell small, .data-table td.amount-cell small { text-align: right; }

/* Карточки одного ряда тянутся на всю высоту ряда. */
.metric-grid > *, .finance-metric-grid > *, .workspace-metrics > *,
.account-grid > * { align-self: stretch; }

/* Почта: длинная тема и длинный адрес не растягивают строку списка. */
.mail-route strong, .mail-route small, .mail-summary strong, .mail-summary small {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}
.mail-route, .mail-summary, .mail-row-meta, .mail-avatar-wrap { min-width: 0; }

/* Список клиентов пользуется общей раскладкой колонок. */
.client-table { width: 100%; table-layout: fixed; }
.client-table col.w-name { width: auto; }
.client-table col.w-status { width: 124px; }
.client-table col.w-ident { width: 160px; }
.client-table col.w-contact { width: 22%; }
.client-table col.w-person { width: 168px; }
.client-table col.w-count { width: 84px; }
.client-table td, .client-table th { overflow-wrap: break-word; }

/* Показатели рассылки: подпись в одной строке с числом не должна менять
   высоту карточки от длины текста. */
.workspace-quick-card, .route-grid article { min-height: 0; height: 100%; }


/* --------------------------------------------------------------------------
   101G, четвёртый прогон: плотность меню, ширина колонок, высота карточек
   -------------------------------------------------------------------------- */

/* Боковое меню целиком помещается на экране высотой 900 px и не требует
   прокрутки: 18 пунктов в трёх группах — обычный размер рабочего меню, и
   листать его ради «Настроек» неудобно. Прокрутка остаётся как страховка для
   низких окон. */

/* Заголовок колонки не должен рваться пополам: «ПРИОРИТЕТ» набран прописными
   с разрядкой, и 96 px ему не хватало. */
.workspace-table th, .data-table th { letter-spacing: 0.04em; }
.workspace-table col.w-priority { width: 116px; }
.workspace-table col.w-status { width: 132px; }
.workspace-table col.w-date { width: 128px; }
.workspace-table col.w-mode { width: 124px; }

/* Пояснение под основным значением занимает не больше двух строк: иначе одна
   длинная причина растягивает строку списка на пол-экрана. */
.workspace-table td small, .data-table td small, .client-table td small {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Все карточки показателей одной высоты, включая разные ряды. */
.metric-grid, .finance-metric-grid, .workspace-metrics { grid-auto-rows: 1fr; }

/* Дата и время в списке не переносятся: «31.08.2026 12:10» в две строки
   читается как две разные даты. */
.workspace-table td.w-date, .workspace-table td.w-date strong,
.client-table td time, .workspace-table time { white-space: nowrap; }

/* --------------------------------------------------------------------------
   101G, пятый прогон: группы в рабочей витрине и плотность меню
   -------------------------------------------------------------------------- */

/* Заголовок группы в таблице: смысловая граница, а не ещё одна строка данных. */
.workspace-table tr.table-group td {
    padding: var(--space-3) var(--space-2) 6px;
    border-bottom: 1px solid var(--line-soft);
    background: transparent;
}
.workspace-table tr.table-group:first-child td { padding-top: var(--space-1); }
.table-group-title {
    color: var(--ink);
    font-size: var(--fs-sm);
    font-weight: 700;
    letter-spacing: 0.01em;
}
.table-group-hint { margin-left: 8px; color: var(--steel-2); font-size: var(--fs-meta); }
@media (max-width: 767.98px) {
    .workspace-table tr.table-group { padding: 0; border: 0; background: transparent; }
    .workspace-table tr.table-group td { padding: var(--space-2) 0 4px; }
}

/* Меню должно помещаться целиком на экране высотой 900 px: листать список ради
   «Настроек» на обычном ноутбуке неудобно. Прокрутка остаётся страховкой для
   более низких окон. */

/* --------------------------------------------------------------------------
   101G, шестой прогон: предпросмотр работы, меню, панели
   -------------------------------------------------------------------------- */

/* Предпросмотр работы на обзоре — одна строка на запись. Прежние карточки в
   две строки занимали первый экран целиком, и показатели, ради которых обзор
   существует, начинались только со второго. */
.inbox-preview { gap: 2px; }
.inbox-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    min-height: 36px;
    padding: 6px 12px;
    border: 0;
    border-radius: var(--radius-small);
}
.inbox-row + .inbox-row { border-top: 1px solid var(--line-soft); border-radius: 0; }
.inbox-title {
    min-width: 0;
    flex: 1 1 auto;
    font-size: var(--fs-sm);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.inbox-meta { flex: 0 0 auto; gap: 6px 10px; font-size: var(--fs-meta); }
.inbox-about { max-width: 30ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel-link { color: var(--steel-2); font-size: var(--fs-meta); font-weight: 600; }
.panel-link:hover { color: var(--ink); text-decoration: underline; }
@media (max-width: 767.98px) {
    .inbox-row { flex-direction: column; align-items: flex-start; gap: 2px; }
    .inbox-title { white-space: normal; }
    .inbox-about { max-width: 100%; }
}

/* Меню помещается целиком на экране 900 px. */

/* --------------------------------------------------------------------------
   101G, седьмой прогон: поля, почта, длинные значения
   -------------------------------------------------------------------------- */

/* Поле формы внутри сетки не может быть уже своего содержимого без явного
   разрешения: выпадающий список с длинными наименованиями расширял ячейку
   сетки на несколько пикселей и сдвигал соседнюю колонку. */
.app-shell :where(select, input, textarea, button) { min-width: 0; max-width: 100%; }
.form-field, .field { min-width: 0; }
.form-field > span { min-width: 0; overflow-wrap: break-word; }

/* Почта: тема, адрес и имя ящика — длинные строки без пробелов. */
.mail-row :where(strong, small, span, b),
.mailbox-card :where(strong, small, span) { overflow-wrap: anywhere; min-width: 0; }
.mail-detail-title h2, .mail-headers dd { overflow-wrap: anywhere; }

/* Список источников: подпись под значением не расширяет ячейку. */
.workspace-table td small { max-width: 100%; overflow-wrap: break-word; }

/* Карточки счетов одной высоты в ряду независимо от числа реквизитов. */
.account-grid { grid-auto-rows: 1fr; }

/* --------------------------------------------------------------------------
   101G, восьмой прогон: ступень скрытия колонок и ширины в очереди
   -------------------------------------------------------------------------- */

/* 1440 — самая распространённая ширина рабочего монитора, и именно на ней
   самая широкая таблица упиралась в предел: главная колонка «Адресат»
   схлопывалась в ноль. Ступень сдвинута так, чтобы расходные колонки уходили
   уже на 1440, а не только ниже. */
@media (max-width: 1599.98px) {
    .workspace-table col.optional-wide, .workspace-table th.optional-wide,
    .workspace-table td.optional-wide { display: none; width: 0; visibility: collapse; }
}

/* Проценты в фиксированной раскладке считаются от ширины таблицы и легко дают
   в сумме больше ста: ширины заданы в пикселях, чтобы поведение было
   предсказуемым на любом экране. */
.workspace-table col.w-contact { width: 210px; }
.workspace-table col.w-object { width: 176px; }
.workspace-table col.w-email { width: 230px; }
.workspace-table col.w-reason { width: 220px; }
.workspace-table col.w-service { width: 180px; }

/* Почта: служебные отчёты доставки приходят одной длинной строкой без
   пробелов — она не должна растягивать список писем. */
.mail-row strong, .mail-row small, .mail-row span { word-break: break-word; }
.mail-summary, .mail-route { overflow: hidden; }

/* Подпись под значением в списке источников не расширяет ячейку. */
.workspace-table td small, .data-table td small { display: block; max-width: 100%; }

/* --------------------------------------------------------------------------
   101G, девятый прогон: планшеты и телефоны

   Измерение на 768-1180 показало общую причину: ширины колонок заданы в
   пикселях и не уменьшаются вместе с окном. На планшете сумма объявленных
   ширин превышала рабочую область, колонки сжимались, и заголовки вылезали за
   свои ячейки. Ширины должны быть ступенчатыми, как и всё остальное.
   -------------------------------------------------------------------------- */

@media (max-width: 1279.98px) {
    .workspace-table th, .data-table th, .finance-table th,
    .workspace-table td, .data-table td, .finance-table td { padding-left: 12px; padding-right: 12px; }
    .workspace-table col.w-person { width: 140px; }
    .workspace-table col.w-priority { width: 96px; }
    .workspace-table col.w-date { width: 108px; }
    .workspace-table col.w-origin { width: 108px; }
    .workspace-table col.w-status { width: 108px; }
    .workspace-table col.w-count { width: 68px; }
    .workspace-table col.w-money { width: 116px; }
    .workspace-table col.w-ident { width: 132px; }
    .workspace-table col.w-badge { width: 120px; }
    .workspace-table col.w-contact { width: 170px; }
    .workspace-table col.w-object { width: 140px; }
    .workspace-table col.w-service { width: 148px; }
    .workspace-table col.w-stage { width: 120px; }
    .workspace-table col.w-mode { width: 104px; }
    .workspace-table col.w-email { width: 180px; }
    .workspace-table col.w-reason { width: 170px; }
    .client-table col.w-contact { width: 170px; }
    .client-table col.w-person { width: 140px; }
    .client-table col.w-status { width: 108px; }
    .client-table col.w-ident { width: 132px; }
}

@media (max-width: 1023.98px) {
    .workspace-table th, .data-table th, .finance-table th,
    .workspace-table td, .data-table td, .finance-table td { padding-left: 10px; padding-right: 10px; }
    .workspace-table col.w-person { width: 124px; }
    .workspace-table col.w-priority { width: 88px; }
    .workspace-table col.w-date { width: 96px; }
    .workspace-table col.w-status { width: 100px; }
    .workspace-table col.w-money { width: 104px; }
    .workspace-table col.w-badge { width: 108px; }
    .workspace-table col.w-contact { width: 150px; }
}

/* Заголовок колонки не обязан помещаться в одну строку: перенос лучше, чем
   выезд за ячейку. */
.workspace-table th, .data-table th { word-break: normal; overflow-wrap: break-word; }
/* Ячейка переносится по тем же правилам, что и её заголовок: иначе в одном
   столбце подпись рвётся по словам, а значение — посреди слова. */
.data-table td { word-break: normal; overflow-wrap: break-word; }
/* Адресам, кодам и ссылкам резкий перенос по-прежнему нужен: неразрывный
   набор символов иначе распирает колонку. */
.data-table td :where(code, .mono, a[href^="mailto"], a[href^="http"]) {
    overflow-wrap: anywhere;
}

/* Таблицы, которые не превращаются в карточки — отчёты финансов, справочные
   таблицы карточек, — на узком экране прокручиваются внутри своей области.
   На рабочем мониторе такой прокрутки нет: там таблица помещается целиком. */
@media (max-width: 1023.98px) {
    .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .data-table { min-width: 560px; }
}
@media (max-width: 767.98px) {
    /* Списки рабочей области уже стали карточками — им прокрутка не нужна. */
    .workspace-table-panel .table-wrap { overflow-x: visible; }
    .workspace-table { min-width: 0; }
    .data-table { min-width: 480px; }
}

/* Финансовые отчёты на телефоне тоже прокручиваются внутри себя. */
@media (max-width: 1023.98px) {
    .finance-main-panel table, .finance-side table,
    .finance-table, .client-table { min-width: 560px; }
    .finance-main-panel .table-wrap, .finance-side .table-wrap { overflow-x: auto; }
}

/* --------------------------------------------------------------------------
   101G, десятый прогон: заголовки таблиц, значки, узкие экраны
   -------------------------------------------------------------------------- */

/* Заголовок колонки перестаёт быть капслоком.

   Причина не только в читаемости, хотя и в ней тоже: русские заголовки длинные
   («СВЯЗАННЫЙ ОБЪЕКТ», «ПРИОРИТЕТ»), а прописные с разрядкой шире строчных
   примерно на пятнадцать процентов. Именно поэтому заголовки вылезали за свои
   ячейки на планшете. Обычный регистр решает и то, и другое. */
.workspace-table th, .data-table th, .client-table th {
    text-transform: none;
    letter-spacing: 0;
    font-size: var(--fs-meta);
    font-weight: 700;
    color: var(--steel-2);
}

/* Значок состояния переносится по словам и не растягивает колонку.
   «Коммерческая работа» в колонке шириной 120 px обязана стать двумя строками,
   а не выехать за край. */
.badge, .badge.workspace-badge {
    display: inline-flex;
    flex-wrap: wrap;
    min-width: 0;
    max-width: 100%;
    white-space: normal;
    overflow-wrap: break-word;
    text-align: left;
}

/* Почта на телефоне: одна колонка. Базовое правило задавало минимальные
   ширины в пикселях и переопределяло прежнюю адаптацию, из-за чего список
   писем выталкивал страницу на 58 px. */
@media (max-width: 1023.98px) {
    .mail-row { grid-template-columns: 40px minmax(0, 1fr) minmax(0, 1.2fr); }
    .mail-row-meta { grid-column: 2 / -1; grid-row: 2; justify-items: start; }
}
@media (max-width: 767.98px) {
    .mail-row { grid-template-columns: 36px minmax(0, 1fr); gap: 8px 10px; }
    .mail-route, .mail-summary, .mail-row-meta { grid-column: 2; grid-row: auto; }
}

/* Плиточные наборы карточек на телефоне — в одну колонку. */
@media (max-width: 767.98px) {
    .card-grid, .route-grid, .workspace-quick-grid, .settings-flags, .fact-grid,
    .import-flow, .outreach-ops-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Таблицы финансовой сводки на телефоне прокручиваются внутри панели. */
@media (max-width: 767.98px) {
    .panel table:not(.workspace-table):not(.client-table) { min-width: 480px; }
    .panel .table-wrap { overflow-x: auto; }
}

/* --------------------------------------------------------------------------
   101G, одиннадцатый прогон: правильное скрытие колонки

   Ошибка предыдущего захода. Колонку прятали тремя способами сразу:
   `display:none` у ячеек, `display:none` у `col`, плюс `visibility:collapse`
   и `width:0` у того же `col`. В результате колонка схлопывалась, но из
   раскладки не исчезала — и ширины съезжали на одну позицию: «Исполнитель»
   получал ширину скрытой колонки, то есть ноль, а «Приоритет» — ширину
   «Исполнителя». Проверено измерением: «Задача» 195 px и «Исполнитель» 0 px
   вместо 335 и 140.

   Правильный способ ровно один: `display:none` у ячеек и у `col`. Тогда
   браузер убирает колонку из раскладки целиком, и оставшиеся получают свои
   объявленные ширины.
   -------------------------------------------------------------------------- */
@media (max-width: 1599.98px) {
    .workspace-table col.optional-wide, .client-table col.optional-wide {
        display: none;
        width: auto;
        visibility: visible;
    }
}
@media (max-width: 1279.98px) {
    .workspace-table col.optional, .client-table col.optional {
        display: none;
        width: auto;
        visibility: visible;
    }
}
@media (max-width: 1023.98px) {
    .workspace-table col.optional-2, .client-table col.optional-2 {
        display: none;
        width: auto;
        visibility: visible;
    }
}

/* --------------------------------------------------------------------------
   101G, двенадцатый прогон: остаточные вылеты в единицы пикселей
   -------------------------------------------------------------------------- */

/* Значок состояния внутри таблицы: длинное слово («Коммерческая») не влезает в
   узкую колонку целиком. Внутри значка перенос допустим — это метка, а не
   деловой текст, и разорванное слово там читается нормально. */
.workspace-table .badge, .data-table .badge, .client-table .badge {
    overflow-wrap: anywhere;
    font-size: var(--fs-micro);
    line-height: 15px;
}

/* Числовая колонка не должна быть уже своего заголовка. */
.workspace-table col.w-count { width: 84px; }
@media (max-width: 1279.98px) { .workspace-table col.w-count { width: 76px; } }

/* Финансовые отчёты: заголовок переносится, значение не растягивает таблицу. */
.finance-main-panel table th, .finance-side table th,
.finance-main-panel table td, .finance-side table td {
    white-space: normal;
    overflow-wrap: break-word;
}
.finance-main-panel table, .finance-side table { min-width: 0; }
@media (max-width: 1023.98px) {
    .finance-main-panel table, .finance-side table { min-width: 560px; }
}

/* --------------------------------------------------------------------------
   101G, тринадцатый прогон: финансовые таблицы
   -------------------------------------------------------------------------- */

/* Раскладка по смыслу: наименование статьи широкое, деньги узкие и справа.
   Без раскладки шесть колонок делили ширину поровну, и «Вывод средств
   собственнику» ломался посреди слова. */
.finance-table { width: 100%; table-layout: auto; }
.finance-table:has(colgroup) { table-layout: fixed; }
.finance-table col.w-name { width: auto; }
.finance-table col.w-money { width: 132px; }
.finance-table col.w-count { width: 104px; }
.finance-table col.w-date { width: 116px; }
.finance-table col.w-status { width: 120px; }

/* Деньги — вправо, цифры одной ширины, знак читается сразу. */
/* Вправо уходит числовое, а не всё, кроме первого столбца. По счёту под
   прежнее правило попадали «Тип», «Направление» и «Комментарий»: подпись
   у правого края, значения под ней — у левого. */
.finance-table .amount-cell, .finance-table th.num,
.finance-table th.amount-cell, .finance-table td.amount-cell {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.finance-table th:first-child, .finance-table td:first-child { text-align: left; }
.finance-table td.amount-cell { white-space: nowrap; }
.finance-table .value-negative, .finance-table .amount-negative { color: var(--negative); }

/* Наименование статьи переносится по словам, а не по буквам. */
.finance-table td:first-child { overflow-wrap: break-word; word-break: normal; }
.finance-table td:first-child small { display: block; margin-top: 2px; color: var(--steel-2); }

/* Итоговая строка отделяется от обычных. */
.finance-table tfoot td, .finance-table tr.total td, .finance-table tr.subtotal td {
    border-top: 2px solid var(--mist);
    font-weight: 700;
}

@media (max-width: 1279.98px) {
    .finance-table col.w-money { width: 112px; }
    .finance-table col.w-count { width: 88px; }
}

/* --------------------------------------------------------------------------
   101G, четырнадцатый прогон: ширины в финансовых таблицах
   -------------------------------------------------------------------------- */

/* Денежная колонка в панели на две трети ширины: 132 px было много, из-за
   этого наименованию статьи оставалось 82 px. */
.finance-table col.w-money { width: 116px; }
@media (max-width: 1439.98px) { .finance-table col.w-money { width: 108px; } }
@media (max-width: 1279.98px) { .finance-table col.w-money { width: 100px; } }

/* Подпись под суммой отклонения выравнивается по правому краю вместе с ней. */
.finance-table td.amount-cell small { display: block; text-align: right; color: var(--steel-2); }

/* Раскладка колонок в финансовых таблицах: наименование операции широкое,
   служебные поля средние, сумма узкая и неразрывная. */
.finance-table col.w-service { width: 170px; }
.finance-table col.w-reason { width: 220px; }
.finance-table col.w-name { width: auto; }
@media (max-width: 1279.98px) {
    .finance-table col.w-service { width: 140px; }
    .finance-table col.w-reason { width: 180px; }
}

/* --------------------------------------------------------------------------
   101G: флажки, переключатели и выбор файла
   -------------------------------------------------------------------------- */

/* Флажок не текстовое поле: ни высоты 40 px, ни рамки, ни внутренних отступов
   ему не нужно. Именно из-за этого форма вылезала за свою сетку. */
.form-check {
    width: 18px;
    height: 18px;
    min-width: 0;
    margin: 0;
    padding: 0;
    accent-color: var(--ink);
    cursor: pointer;
}
input[type="radio"].form-check { border-radius: 50%; }

/* Поле с флажком: подпись справа от него, а не над ним. */
.form-field:has(> .form-check) {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 10px;
}
.form-field:has(> .form-check) > .form-check { grid-row: 1; grid-column: 1; }
.form-field:has(> .form-check) > .form-label { grid-row: 1; grid-column: 2; }
.form-field:has(> .form-check) > small { grid-column: 2; }

/* Выбор файла — обычная высота поля, но без внутреннего отступа текста. */
.form-file {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    min-height: var(--field-h, 40px);
    padding: 8px 12px;
    border: 1px dashed var(--mist);
    border-radius: var(--radius-small);
    background: var(--paper);
    font-size: var(--fs-sm);
}

/* Бюджет: заголовки «Утверждённый план» и «Текущий прогноз» не помещались в
   денежную колонку. Колонки плана шире денежных. */
.finance-table col.w-plan { width: 170px; }

/* --------------------------------------------------------------------------
   101G: ступень «optional» сдвигается на 1366

   Измерение на 1280 показало общий сбой: расходные колонки уходили только ниже
   1280, а на самом 1280 рабочая область равна примерно 1008 px, и широкие
   таблицы в неё не помещались. 1366 — распространённая ширина ноутбука, и
   именно на ней таблица должна начать упрощаться.
   -------------------------------------------------------------------------- */
@media (max-width: 1365.98px) {
    .workspace-table .col-optional, .workspace-table th.optional, .workspace-table td.optional,
    .client-table th.optional, .client-table td.optional { display: none; }
    .workspace-table col.optional, .client-table col.optional {
        display: none;
        width: auto;
        visibility: visible;
    }
}

/* Список клиентов пользуется теми же ступенями. */
@media (max-width: 1023.98px) {
    .client-table th.optional-2, .client-table td.optional-2 { display: none; }
    .client-table col.optional-2 { display: none; width: auto; visibility: visible; }
}

/* Карточка показателя с длинной подписью не расширяет ряд. */
.metric-card > span { min-width: 0; overflow-wrap: break-word; }
.metric-card > strong { min-width: 0; overflow-wrap: anywhere; }

/* --------------------------------------------------------------------------
   101G: границы ступеней включают сами распространённые ширины

   1366 и 1280 — это реальные ширины экранов, а не «что-то между ступенями».
   Граница `max-width: 1365.98px` оставляла ровно 1366 на широкой раскладке, и
   на самом массовом ноутбуке таблица снова не помещалась. Границы включают
   свои значения.
   -------------------------------------------------------------------------- */
@media (max-width: 1600px) {
    .workspace-table th.optional-wide, .workspace-table td.optional-wide { display: none; }
    .workspace-table col.optional-wide { display: none; width: auto; visibility: visible; }
}
@media (max-width: 1366px) {
    .workspace-table th.optional, .workspace-table td.optional,
    .client-table th.optional, .client-table td.optional { display: none; }
    .workspace-table col.optional, .client-table col.optional {
        display: none; width: auto; visibility: visible;
    }
}
@media (max-width: 1024px) {
    .workspace-table th.optional-2, .workspace-table td.optional-2,
    .client-table th.optional-2, .client-table td.optional-2 { display: none; }
    .workspace-table col.optional-2, .client-table col.optional-2 {
        display: none; width: auto; visibility: visible;
    }
}

/* Карточный режим строки: ширина перестала быть ограничением, и
   второстепенные столбцы возвращаются. Правило обязано стоять после
   ступеней 1366 и 1024 — раньше них оно перебивалось и не работало. */
@media (max-width: 767.98px) {
    .workspace-table td.optional,
    .workspace-table td.optional-2 { display: block; }
}

/* Минимальные ширины из прежней вёрстки не должны распирать узкий экран. */
@media (max-width: 767.98px) {
    .workspace-hero dl { min-width: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .search-form input, .mail-search-field, .workspace-search,
    .form-control.compact { min-width: 0; }
    .deal-hero dl div { min-width: 0; }
}

/* --------------------------------------------------------------------------
   101G: телефон — панель действий почты и справочные таблицы
   -------------------------------------------------------------------------- */

/* Панель массовых действий в почте: две кнопки в строку не помещаются на
   360 px и выталкивали страницу на 58 px. Переносим и растягиваем. */
.mail-bulk-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); min-width: 0; }
@media (max-width: 767.98px) {
    .mail-bulk-actions { width: 100%; }
    .mail-bulk-actions .button { flex: 1 1 160px; }
    .mail-toolbar, .mail-bulk-bar { flex-wrap: wrap; gap: var(--space-1); }
}

/* Справочная таблица внутри карточки на телефоне прокручивается внутри своей
   области — превращать её в карточки нельзя, там сопоставление колонок и есть
   содержание. */
@media (max-width: 767.98px) {
    .workspace-card .table-wrap, .panel .table-wrap { overflow-x: auto; }
    .data-table { min-width: 460px; }
}

/* --------------------------------------------------------------------------
   101G: список записей внутри карточки на телефоне
   -------------------------------------------------------------------------- */

/* `.workspace-list` — строка «название + пояснение + действие» в одну линию.
   На 360 px наименование и кнопка не помещаются рядом, и строка выталкивала
   страницу. На телефоне строка становится вертикальной. */
.workspace-list article { min-width: 0; }
.workspace-list article > div { min-width: 0; }
.workspace-list article strong, .workspace-list article span { overflow-wrap: anywhere; }
@media (max-width: 767.98px) {
    .workspace-list article {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-1);
    }
    .workspace-list article .button { width: 100%; }
}

/* --------------------------------------------------------------------------
   101G: заголовок колонки — во всех таблицах без исключения

   Правило было записано через перечисление классов, и таблицы финансов в него
   не попали: «Отклонение» осталось прописными и разорвалось на «ОТКЛОНЕН ИЕ».
   Правило должно относиться к заголовку таблицы как таковому.
   -------------------------------------------------------------------------- */
.app-shell table th {
    text-transform: none;
    letter-spacing: 0;
    font-size: var(--fs-meta);
    font-weight: 700;
    line-height: 16px;
    color: var(--steel-2);
    text-align: left;
    white-space: normal;
    word-break: normal;
    overflow-wrap: break-word;
}
.app-shell table th.amount-cell, .app-shell .finance-table th.num { text-align: right; }

/* Пояснение под значением в таблице — не более двух строк. Правило было
   отменено более поздним `display: block`, и длинная причина снова растягивала
   строку списка на три строки. */
.workspace-table td small, .data-table td small, .client-table td small {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-width: 100%;
}
/* Подпись под суммой — одна строка и по правому краю. */
.workspace-table td.amount-cell small, .finance-table td.amount-cell small {
    -webkit-line-clamp: 1;
    text-align: right;
}


/* ==========================================================================
   МЕНЮ (101H)

   Прежние правила меню накапливались слоями и с каждым разом ужимали пункты,
   чтобы восемнадцать строк уместились в 900 px. Влезло, но читать стало
   нельзя. Здесь один компонент и один принятый размен: воздух важнее того,
   чтобы всё влезло без прокрутки.

   Что решено:
     - высота пункта 40 px, между пунктами 2 px, между группами 24 px;
     - группа отделена и линией, и надзаголовком — одного надзаголовка мало;
     - подсветка пункта отступает от края меню и от полосы прокрутки;
     - полоса прокрутки не видна, пока курсор не в меню, но место под неё
       зарезервировано: содержимое не дёргается;
     - название пункта не переносится никогда;
     - счётчик работы справа от пункта: красный, когда требуется человек.
   ========================================================================== */

:root {
    /* Точечные акценты. Цвет означает состояние, а не украшает. */
    --accent-attention: #C1442E;   /* требуется человек */
    --nav-w: 264px;
    --nav-item-h: 36px;
    --nav-inset: 12px;
}

.app-shell { grid-template-columns: var(--nav-w) minmax(0, 1fr); }

/* --- логотип --------------------------------------------------------------- */
.brand {
    min-height: 56px;
    padding: 16px var(--space-3) 10px;
    display: flex;
    align-items: center;
}
.login-brand { min-height: 44px; display: flex; align-items: center; }
.brand img { display: block; width: 156px; height: auto; filter: brightness(0) invert(1); }

/* --- область навигации ----------------------------------------------------- */
.sidebar > .nav {
    min-height: 0;
    padding: 2px var(--nav-inset) 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: grid;
    align-content: start;
    gap: 20px;
    /* Место под полосу прокрутки занято всегда — иначе при появлении полосы
       все пункты сдвигаются влево. */
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
    transition: scrollbar-color 180ms ease;
}
.sidebar:hover > .nav,
.sidebar > .nav:focus-within {
    scrollbar-color: rgba(217, 224, 231, .28) transparent;
}
.sidebar > .nav::-webkit-scrollbar { width: 8px; }
.sidebar > .nav::-webkit-scrollbar-track { background: transparent; }
.sidebar > .nav::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: 999px;
    background-clip: content-box;
    background-color: transparent;
    transition: background-color 180ms ease;
}
.sidebar:hover > .nav::-webkit-scrollbar-thumb,
.sidebar > .nav:focus-within::-webkit-scrollbar-thumb {
    background-color: rgba(217, 224, 231, .28);
}
.sidebar > .nav::-webkit-scrollbar-thumb:hover { background-color: rgba(217, 224, 231, .44); }

/* --- группа ---------------------------------------------------------------- */
.nav-group { display: grid; gap: 2px; }
.nav-group + .nav-group {
    padding-top: 18px;
    border-top: 1px solid rgba(217, 224, 231, .10);
}
.nav-group h2 {
    margin: 0 0 6px;
    padding: 0 12px;
    /* Надзаголовок группы меню: при 0,40 контраст к тёмной панели 3,2
       при норме 4,5 для десяти пикселей. */
    color: rgba(217, 224, 231, .62);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 14px;
    letter-spacing: .14em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- пункт ----------------------------------------------------------------- */
.nav a {
    position: relative;
    min-height: var(--nav-item-h);
    padding: 0 12px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    color: rgba(217, 224, 231, .78);
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
    /* Название раздела не переносится: «Проект ы» — не название. */
    white-space: nowrap;
    transition: color 160ms ease, background-color 160ms ease;
}
.nav a > span:first-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nav a::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -6px;
    width: 3px;
    height: 0;
    border-radius: 0 2px 2px 0;
    background: var(--white);
    transform: translateY(-50%);
    transition: height 160ms ease;
}
.nav a:hover { color: var(--white); background: rgba(255, 255, 255, .07); }
/* Фокус в тёмном меню виден отчётливо (UIUX-068): прежняя обводка
   rgba(217,224,231,.55) на тёмном фоне почти терялась. Белая обводка и
   подсветка фона пункта — два признака, а не один оттенок. */
.nav a:focus-visible { outline: 3px solid #ffffff; outline-offset: -3px; background: rgba(255, 255, 255, .14); color: #ffffff; }
.sidebar .brand:focus-visible, .sidebar-foot .link-button:focus-visible { outline: 3px solid #ffffff; outline-offset: 2px; }
.nav a.active {
    color: var(--white);
    font-weight: 600;
    background: var(--steel-1);
}
.nav a.active::before { height: 20px; }

/* --- счётчик работы -------------------------------------------------------- */
.nav-count {
    flex: 0 0 auto;
    min-width: 24px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .10);
    color: rgba(217, 224, 231, .88);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.nav a.active .nav-count { background: rgba(255, 255, 255, .18); color: var(--white); }
/* Красный означает одно: без человека это не сдвинется. Правило подсветки
   выбранного пункта стоит по специфичности выше, поэтому на выбранном разделе
   красный пропадал вместе со смыслом — здесь он назван так же точно. */
.nav-count.attention,
.nav a.active .nav-count.attention { background: var(--accent-attention); color: var(--white); }

/* --- подпись пользователя -------------------------------------------------- */
.sidebar-foot {
    margin-top: auto;
    padding: 12px var(--space-3) 14px;
    border-top: 1px solid rgba(217, 224, 231, .12);
    display: grid;
    gap: 2px;
    font-size: 13px;
}
.sidebar-foot span { color: var(--white); font-weight: 600; }
.sidebar-foot small { color: rgba(217, 224, 231, .60); font-size: 12px; }
.version-label { margin-top: 6px; color: rgba(217, 224, 231, .34) !important; font-size: var(--fs-micro) !important; }
.sidebar-foot .link-button { margin-top: 6px; margin-left: -8px; }

/* --- меню сверху на планшете и телефоне ------------------------------------ */
@media (max-width: 1023.98px) {
    /* Меню уходит наверх: колонка под него больше не нужна. */
    .app-shell { grid-template-columns: minmax(0, 1fr); }
    .sidebar { padding: 0; }
    .brand { padding: 12px var(--gutter) 8px; min-height: 0; }
    .sidebar > .nav {
        padding: 0 var(--gutter) 12px;
        overflow: visible;
    }
}
@media (hover: none) and (pointer: coarse) {
    /* На касании полосу прокрутки не «наводят» — показываем сразу. */
    .sidebar > .nav { scrollbar-color: rgba(217, 224, 231, .28) transparent; }
    .nav a { min-height: 44px; }
}


/* Меню длиннее экрана — это нормально. Ненормально, когда об этом никак не
   сказано: затемнение внизу показывает, что список продолжается. Оно лежит
   поверх меню и не перехватывает нажатия. */
.app-shell > .sidebar { position: relative; }
.app-shell > .sidebar::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 96px;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(11, 22, 35, 0) 0%, rgba(11, 22, 35, .92) 76%);
    opacity: .9;
}
/* Подпись пользователя лежит на непрозрачном фоне и затемнением не портится. */
.sidebar > .sidebar-foot { position: relative; z-index: 1; background: var(--ink); }
@media (max-width: 1023.98px) {
    .app-shell > .sidebar::after { display: none; }
}

/* --------------------------------------------------------------------------
   101H: поведение текста по типу колонки

   Класс типа теперь есть и на ячейке, поэтому правило пишется один раз и
   действует во всех таблицах сразу.
   -------------------------------------------------------------------------- */
.workspace-table td.w-date, .workspace-table th.w-date,
.workspace-table td.w-priority, .workspace-table th.w-priority,
.workspace-table td.w-count, .workspace-table th.w-count,
.workspace-table td.w-money, .workspace-table th.w-money,
.workspace-table td.w-mode, .workspace-table th.w-mode,
.client-table td.w-date, .client-table td.w-count {
    white-space: nowrap;
}
/* Подпись под датой может переноситься: там бывает пояснение. */
.workspace-table td.w-date small, .workspace-table td.w-money small { white-space: normal; }

/* Имя человека переносится по словам, но не по буквам: «Не назначена» должно
   остаться одной строкой, если ширины хватает. */
.workspace-table td.w-person, .workspace-table td.w-status { overflow-wrap: normal; }
.workspace-table col.w-origin { width: 140px; }
@media (max-width: 1279.98px) { .workspace-table col.w-origin { width: 116px; } }

/* --------------------------------------------------------------------------
   101H: числовая колонка

   Заголовок «На проверке» не помещался в 84 px и переносился, а подпись под
   числом обрезалась посреди слова. Подписи убраны там, где они повторяли
   заголовок; колонка стала чуть шире, чтобы заголовок вставал в одну строку.
   -------------------------------------------------------------------------- */
.workspace-table col.w-count { width: 104px; }
@media (max-width: 1439.98px) { .workspace-table col.w-count { width: 96px; } }
@media (max-width: 1279.98px) { .workspace-table col.w-count { width: 88px; } }

/* Число в такой колонке крупнее подписи и стоит по правому краю: столбец
   читается сверху вниз одним взглядом. */
.workspace-table td.w-count strong, .workspace-table td.w-money strong {
    font-size: var(--fs-base);
    font-variant-numeric: tabular-nums;
}
.workspace-table td.w-count, .workspace-table th.w-count { text-align: right; }

/* --------------------------------------------------------------------------
   101H: компактная полоса показателей и блок первоисточника
   -------------------------------------------------------------------------- */

/* Полоса показателей: то же содержание, вчетверо меньше высоты. Применяется,
   когда показателей больше восьми — крупные карточки в таком количестве
   закрывают собой список. */
.metric-grid.is-dense {
    grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
    gap: 8px;
    margin-bottom: var(--space-3);
}
.metric-grid.is-dense .metric-card {
    grid-column: auto;
    min-height: 0;
    padding: 10px 14px;
    grid-template-rows: auto auto auto;
    gap: 2px;
    border-radius: var(--radius-small);
}
.metric-grid.is-dense .metric-card > span {
    font-size: var(--fs-micro);
    line-height: 15px;
    /* Подпись не длиннее двух строк: иначе ряд снова разъезжается. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.metric-grid.is-dense .metric-card > strong { font-size: var(--fs-section); line-height: 1.15; }
.metric-grid.is-dense .metric-card > small {
    font-size: var(--fs-micro);
    line-height: 15px;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.metric-grid.is-dense .hint-mark { transform: scale(.86); }

/* --------------------------------------------------------------------------
   Первоисточник: номер дела и переход

   На скриншоте владельца поле с номером дела разъезжалось: значок копирования
   уходил под номер, а кнопка «Открыть КАД» стояла другой высоты. Причина —
   поле переносило содержимое внутри себя, а высоты кнопки и поля брались из
   разных величин.
   -------------------------------------------------------------------------- */
.action-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    min-width: 0;
}
.copy-field {
    flex: 0 0 auto;
    flex-wrap: nowrap;
    white-space: nowrap;
}
.copy-field code { white-space: nowrap; overflow-wrap: normal; font-size: var(--fs-meta); }
.copy-field .copy-button { flex: 0 0 auto; }
/* Рядом с полем стоят маленькие кнопки — высоты обязаны совпадать. */
.action-cluster .button.small, .action-cluster .copy-field { height: var(--btn-h-sm); }

/* Карточка первоисточника: заголовок, пояснение и действие — одна геометрия
   и для публикации ЕФРСБ, и для судебного дела. */
.workspace-list article {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    min-width: 0;
}
.workspace-list article > div:first-child { min-width: 0; display: grid; gap: 2px; }
.workspace-list article strong { font-size: var(--fs-base); font-weight: 600; }
.workspace-list article span { color: var(--steel-2); font-size: var(--fs-meta); }

/* --------------------------------------------------------------------------
   101H: выравнивание внутри карточки показателя

   Карточки были одной высоты, но числа стояли на разных уровнях: там, где
   подпись занимала две строки, значение уезжало вниз. Ряд читается сверху вниз
   только тогда, когда числа лежат на одной линии, поэтому область подписи
   получает постоянную высоту.
   -------------------------------------------------------------------------- */
.metric-card > span {
    display: block;
    min-height: 34px;
    align-content: start;
}
.metric-card > span .hint-mark { float: none; display: inline-block; vertical-align: -2px; margin-left: 4px; }
.metric-card { grid-template-rows: auto auto 1fr; align-items: start; }
.metric-card > strong { align-self: start; }
.metric-card > small { align-self: end; }

.metric-grid.is-dense .metric-card > span { min-height: 30px; }
.metric-grid.is-dense .metric-card > small { -webkit-line-clamp: 2; }

/* Колонка режима и числовые колонки: заголовок должен вставать в одну строку. */
.workspace-table col.w-mode { width: 140px; }
.workspace-table col.w-count { width: 112px; }
@media (max-width: 1439.98px) {
    .workspace-table col.w-mode { width: 124px; }
    .workspace-table col.w-count { width: 100px; }
}

/* Поле поиска в строке фильтров шире выпадающих списков: ищут чаще, чем
   фильтруют. */
.workspace-search { flex: 2 1 320px; }

/* --------------------------------------------------------------------------
   101H: вертикальный ритм страницы

   Измерение показало на одной странице промежутки 12, 24, 28, 32 и 40 px между
   верхнеуровневыми блоками. Причина: каждый блок сам решал, сколько отступить
   снизу. Расстояние между блоками — свойство страницы, а не блока, поэтому
   собственные отступы обнуляются, а промежуток задаётся один раз.
   -------------------------------------------------------------------------- */
.page-frame > * { margin-bottom: 0; }
.page-frame > * + * { margin-top: var(--space-3); }
/* Шапка стоит отдельно: между ней и содержимым воздуха больше. */
.page-frame > .topbar { margin-bottom: 0; }
.page-frame > .topbar + * { margin-top: var(--space-4); }
/* Вводный абзац принадлежит заголовку и прижимается к нему. */
.page-frame > .topbar + .workspace-subtitle { margin-top: calc(var(--space-3) * -1 + 4px); }
.workspace-subtitle { margin: 0; max-width: 90ch; }
.workspace-tabs, .workspace-notice, .metric-grid, .workspace-metrics,
.dashboard-group, .filter-chips { margin-bottom: 0; }
.panel + .panel,
.panel + .workspace-detail-grid,
.workspace-detail-grid + .panel { margin-top: var(--space-3); }
.dashboard-group { margin-bottom: 0; }
.page-frame > .dashboard-group + .dashboard-group { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   101H: минимальная цель нажатия

   Значок копирования 26 px и крестик у чипа фильтра 18 px — по такому попадают
   не с первого раза. Тридцать два пикселя — нижняя граница для мыши,
   сорок четыре — для касания.
   -------------------------------------------------------------------------- */
/* Отдельная кнопка-значок: цель нажатия 36 px — нижняя граница принятого
   диапазона 36–40. Сам значок при этом 16 px и не растёт вместе с целью. */
.copy-field .copy-button { width: var(--btn-h-sm); height: var(--btn-h-sm); }
/* Высоту ряда задаёт сама кнопка-значок. */
/* Высоту задаёт сама кнопка: отдельное правило для группы не нужно. */
.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; }
.chip-remove {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    line-height: 1;
}
.chip-remove:hover { background: rgba(11, 22, 35, .08); }
@media (hover: none) and (pointer: coarse) {
    .copy-field .copy-button, .chip-remove { min-width: 44px; min-height: 44px; }
    .chip-remove { width: 32px; height: 32px; }
}

/* Пояснение внутри карточки отступает от её края так же, как остальной текст. */
.workspace-card > .workspace-hint,
.panel > .workspace-hint { padding: 0 var(--space-3) var(--space-2); }

/* Крестик у чипа фильтра был 18 px — по такому не попадают с первого раза.
   Правило записано с тем же весом, что и прежнее, и стоит после него. */
.chip .chip-remove {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    line-height: 1;
    font-size: var(--fs-sm);
}
@media (hover: none) and (pointer: coarse) {
    .chip .chip-remove { width: 32px; height: 32px; }
}

/* Область подписи в карточке показателя фиксированной высоты: числа в ряду
   обязаны стоять на одной линии, иначе ряд не читается сверху вниз. */
.metric-card > span { height: 34px; min-height: 34px; overflow: hidden; }
.metric-grid.is-dense .metric-card > span { height: 30px; min-height: 30px; }

/* Колонка «Проекты» в списке клиентов была 84 px, и заголовок вставал в две
   строки, задирая всю шапку. Ширина числовых колонок одна на всю систему. */
.client-table col.w-count { width: 112px; }
@media (max-width: 1279.98px) { .client-table col.w-count { width: 96px; } }

/* --------------------------------------------------------------------------
   101H: отступ текста внутри карточки задаётся полем, а не внутренним отступом

   Внутренний отступ сдвигает текст, но сам блок по-прежнему начинается от края
   карточки: при проверке геометрии это неотличимо от прижатого к краю текста, а
   при выделении текст выглядит приклеенным к рамке. Поле сдвигает блок целиком.
   -------------------------------------------------------------------------- */
.workspace-card > .workspace-hint,
.panel > .workspace-hint,
.workspace-card > .workspace-empty,
.panel > .workspace-empty {
    margin: 0 var(--space-3) var(--space-2);
    padding: 0;
}
.workspace-card > .workspace-hint:first-child,
.panel > .workspace-hint:first-child { margin-top: var(--space-2); }

/* Крестик у чипа фильтра — вспомогательное действие внутри чипа, но попадать
   по нему нужно с первого раза. */
.chip { min-height: 32px; }
.chip .chip-remove { width: 28px; height: 28px; }

/* --------------------------------------------------------------------------
   101H: две ступени ритма и ни одной случайной

   Измерение на обзоре дало 0 / 24 / 24 / 24 / 32 / 32 / 32. Ноль — это
   подзаголовок, прижатый к заголовку вплотную: отрицательный отступ съел
   промежуток целиком. А блок предпросмотра между смысловыми группами отбивался
   на 24, тогда как сами группы — на 32.

   Ступеней ровно две: 24 между блоками одного уровня и 32 вокруг именованной
   группы. Подзаголовок к заголовку не относится к промежуткам между блоками —
   это одна пара, и между ними 8.
   -------------------------------------------------------------------------- */
.page-frame > .topbar + .workspace-subtitle { margin-top: 8px; }
.page-frame > .dashboard-group + *,
.page-frame > * + .dashboard-group { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   101H: запрет переноса относится к значению, а не к заголовку

   Запрет переноса был выписан и для `th`. Значение в такой колонке действительно
   рвать нельзя — «31.08.2026 12:10» в две строки читается как две даты, — а вот
   заголовок «Ближайшее событие» обязан переноситься, иначе он вылезает из
   ячейки. Разные задачи, разные правила.
   -------------------------------------------------------------------------- */
.workspace-table th.w-date, .workspace-table th.w-priority,
.workspace-table th.w-count, .workspace-table th.w-money,
.workspace-table th.w-mode { white-space: normal; }

/* Дата со временем занимает больше, чем просто дата. */
.workspace-table col.w-date { width: 144px; }
@media (max-width: 1439.98px) { .workspace-table col.w-date { width: 136px; } }
@media (max-width: 1279.98px) { .workspace-table col.w-date { width: 124px; } }

/* Боковая колонка финансов не расширяет свою сетку. */
.finance-layout > *, .finance-side > * { min-width: 0; }
.finance-side { min-width: 0; }

/* --------------------------------------------------------------------------
   101H: строка счёта в боковой панели финансов

   Название счёта «Точка Владислава · •••• 9811» шире отведённых 197 px, и
   строка расширяла всю панель на несколько пикселей. Название сокращается
   многоточием, остаток по счёту остаётся целым: сумму обрезать нельзя.
   -------------------------------------------------------------------------- */
.account-item { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); min-width: 0; }
.account-item > span { min-width: 0; display: grid; gap: 2px; }
.account-item strong, .account-item small {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.account-item > b {
    flex: 0 0 auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.account-list { min-width: 0; overflow: hidden; }

/* На телефоне длинная подпись кнопки не помещается в одну строку и выталкивает
   форму. Запрет переноса здесь не нужен: рядом нет соседей, с которыми кнопка
   должна выравниваться по высоте. */
@media (max-width: 479.98px) {
    .button {
        height: auto;
        min-height: var(--btn-h);
        padding: 8px 14px;
        white-space: normal;
        text-align: center;
        line-height: 1.25;
    }
}

/* --------------------------------------------------------------------------
   101H: последние измеренные расхождения
   -------------------------------------------------------------------------- */

/* Дата со временем на планшете горизонтально не влезала в 124 px. */
@media (max-width: 1279.98px) { .workspace-table col.w-date { width: 132px; } }

/* Финансовая таблица в прокручиваемой области: минимальная ширина должна быть
   не меньше суммы объявленных колонок, иначе название статьи схлопывается в
   58 px, хотя места хватает — просто оно отдано соседям. */
@media (max-width: 1023.98px) {
    .finance-table { min-width: 760px; }
    .data-table { min-width: 640px; }
}

/* На телефоне длинное слово в подписи кнопки переносится: рвать слово хуже,
   чем вытолкнуть форму, но здесь другого места нет. */
@media (max-width: 479.98px) {
    .button { overflow-wrap: anywhere; }
}

/* --------------------------------------------------------------------------
   101H: границы ступеней включают сами значения

   1024, 768 и 480 — это ширины реальных устройств, а не «что-то между
   ступенями». Граница `max-width: 1023.98px` оставляла ровно 1024 на широкой
   раскладке: на планшете горизонтально таблица считала себя настольной, и
   колонка «Категория» схлопывалась в 58 px при том, что места хватало.

   Здесь ступени переписаны включительно, а список клиентов получает те же
   карточки строк, что и остальные списки: своей таблицей он не отличается.
   -------------------------------------------------------------------------- */
@media (max-width: 1024px) {
    .finance-table { min-width: 780px; }
    .data-table { min-width: 760px; }
    .finance-main-panel table, .finance-side table { min-width: 720px; }
    .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .workspace-table-panel .table-wrap { overflow-x: visible; }
}

@media (max-width: 767.98px) {
    /* Список клиентов — такой же список, как остальные: на телефоне строка
       становится карточкой, а не сжимается до 35 px на колонку. */
    .client-table, .client-table tbody, .client-table tr, .client-table td {
        display: block;
        width: auto;
        min-width: 0;
    }
    .client-table thead, .client-table colgroup { display: none; }
    .client-table tr {
        padding: var(--space-2);
        border: 1px solid var(--mist);
        border-radius: var(--radius-small);
        background: var(--white);
    }
    .client-table tr + tr { margin-top: var(--space-1); }
    .client-table td { padding: 2px 0; border: 0; }
    .client-table td.optional, .client-table td.optional-2 { display: block; }
    .clients-panel .table-wrap { overflow-x: visible; }
    .workspace-table { min-width: 0; }
    .data-table { min-width: 560px; }
    .finance-table { min-width: 640px; }
}

/* Список клиентов на телефоне стал карточками строк — минимальная ширина
   таблицы, оставшаяся от прежней раскладки, больше не нужна и выталкивала
   страницу на 122 px. */
@media (max-width: 767.98px) {
    .client-table, .clients-panel table { min-width: 0; }
}


/* ==========================================================================
   МЕНЮ НА ТЕЛЕФОНЕ И ПЛАНШЕТЕ (101H)

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

   Список ссылок один и тот же на всех размерах — меняется только способ его
   показать. Второго меню в разметке нет.
   ========================================================================== */

/* На широком экране полосы и затемнения не существует. */
.app-bar, .menu-scrim { display: none; }

@media (max-width: 1024px) {
    /* Оболочка снова обычная страница, но меню лежит поверх неё. */
    .app-shell { grid-template-columns: minmax(0, 1fr); }

    .app-bar {
        position: sticky;
        top: 0;
        /* Полоса выше панели: кнопка закрытия обязана оставаться доступной. */
        z-index: 70;
        display: flex;
        align-items: center;
        gap: var(--space-2);
        height: 56px;
        padding: 0 12px 0 8px;
        background: var(--ink);
        color: var(--mist);
    }
    .app-bar-brand { display: flex; align-items: center; margin-right: auto; }
    .app-bar-brand img { width: 132px; height: auto; filter: brightness(0) invert(1); }
    .app-bar-count {
        min-width: 28px;
        height: 24px;
        padding: 0 8px;
        border-radius: 999px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: rgba(255, 255, 255, .12);
        color: var(--white);
        font-size: var(--fs-meta);
        font-weight: 700;
        font-variant-numeric: tabular-nums;
    }
    .app-bar-count.attention { background: var(--accent-attention); }

    /* Кнопка бургера: три полосы, которые складываются в крестик. */
    .burger {
        width: 44px;
        height: 44px;
        padding: 0;
        flex: 0 0 auto;
        display: grid;
        place-items: center;
        border: 0;
        border-radius: 8px;
        background: transparent;
        cursor: pointer;
    }
    .burger:hover { background: rgba(255, 255, 255, .08); }
    .burger:focus-visible { outline: 2px solid rgba(217, 224, 231, .6); outline-offset: -2px; }
    .burger-lines, .burger-lines::before, .burger-lines::after {
        content: "";
        display: block;
        width: 20px;
        height: 2px;
        border-radius: 2px;
        background: var(--mist);
        transition: transform 180ms ease, opacity 120ms ease;
    }
    .burger-lines { position: relative; }
    .burger-lines::before { position: absolute; top: -6px; }
    .burger-lines::after { position: absolute; top: 6px; }
    body[data-menu-open] .burger-lines { background: transparent; }
    body[data-menu-open] .burger-lines::before { transform: translateY(6px) rotate(45deg); }
    body[data-menu-open] .burger-lines::after { transform: translateY(-6px) rotate(-45deg); }

    /* Выездная панель. Вес селектора совпадает с тем, которым объявлено
       затемнение внизу меню, иначе позиция не переопределится. */
    .app-shell > .sidebar {
        position: fixed;
        /* Панель начинается под полосой: кнопка бургера остаётся на месте и
           работает как крестик, отдельный элемент закрытия не нужен. */
        top: 56px;
        left: 0;
        z-index: 60;
        width: min(304px, 86vw);
        height: calc(100dvh - 56px);
        max-height: calc(100dvh - 56px);
        padding: 0;
        display: grid;
        grid-template-rows: auto minmax(0, 1fr) auto;
        overflow: hidden;
        transform: translateX(-100%);
        transition: transform 220ms ease;
        box-shadow: none;
    }
    body[data-menu-open] .app-shell > .sidebar {
        transform: translateX(0);
        box-shadow: 0 0 48px rgba(11, 22, 35, .45);
    }
    /* Одна колонка: в панели шириной 304 px две колонки дают обрезанные
       подписи вида «Ответы адрес…». Вес селектора совпадает с прежним
       правилом раскладки, иначе оно не переопределится. */
    .app-shell > .sidebar > .nav {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
        padding: 12px var(--nav-inset) 16px;
        overflow-y: auto;
    }
    /* Логотип уже стоит в полосе — второй раз он не нужен. */
    .app-shell > .sidebar > .brand { display: none; }
    .nav-group + .nav-group { padding-top: 18px; border-top: 1px solid rgba(217, 224, 231, .10); }
    .nav-group h2 { padding: 0 12px; text-align: left; }
    .nav a { justify-content: space-between; text-align: left; min-height: 44px; }
    .sidebar-foot { display: grid; }
    .brand { min-height: 56px; padding: 16px var(--space-3) 10px; }

    .menu-scrim {
        position: fixed;
        inset: 56px 0 0;
        z-index: 50;
        display: block;
        background: rgba(11, 22, 35, .5);
    }
    .menu-scrim[hidden] { display: none; }

    /* Пока панель открыта, страница под ней не прокручивается. */
    body[data-menu-open] { overflow: hidden; }

    /* Затемнение снизу меню на узком экране не нужно: панель и так во всю
       высоту, а поверх неё лежит подпись пользователя. */
    .app-shell > .sidebar::after { display: none; }

    .content { height: auto; overflow: visible; padding: var(--space-3) var(--gutter) var(--space-5); }
}

/* Тем, кто просил уменьшить анимацию, панель показывается без движения. */
@media (prefers-reduced-motion: reduce) {
    .sidebar, .burger-lines, .burger-lines::before, .burger-lines::after { transition: none; }
}

/* --------------------------------------------------------------------------
   101G: показатель-часть

   Две одинаковые карточки рядом — «Открыто 47» и «Не назначено 47» — читались
   как 94 задачи. Подпись «из 47» говорит про отношение, а приглушённый фон и
   более лёгкое число не дают взгляду складывать карточки в общую сумму.
   -------------------------------------------------------------------------- */
.metric-card.is-part {
    background: var(--paper);
    border-color: var(--line-soft);
}
.metric-card.is-part > strong { font-weight: 700; }
.metric-of {
    margin-left: 6px;
    color: var(--steel-2);
    font-size: var(--fs-meta);
    font-style: normal;
    font-weight: 600;
    letter-spacing: 0;
    white-space: nowrap;
}
.metric-grid.is-dense .metric-of { font-size: var(--fs-micro); margin-left: 4px; }
a.metric-card.is-part:hover { background: var(--white); }

/* --------------------------------------------------------------------------
   101G: меню на невысоком экране

   На 1280×720 — распространённое разрешение ноутбука — под срез уходило девять
   пунктов из восемнадцати. Восемнадцать пунктов с комфортными отступами в окно
   высотой 720 px не помещаются в принципе, поэтому здесь два решения сразу:
   ужать шаг на невысоких экранах и всегда показывать текущий раздел.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   101G: плотность строки списка

   Медиана высоты строки была 99–118 px: на экран помещалось шесть записей.
   Высоту задавало пояснение, занимавшее две строки в каждой ячейке. Пояснение
   вторично — одной строки достаточно, полный текст доступен подсказкой.
   Две строки остаются там, где пояснение и есть содержание колонки.
   -------------------------------------------------------------------------- */
.workspace-table td, .client-table td { padding-top: 10px; padding-bottom: 10px; }
/* Пояснение занимает две строки: одна строка была объявлена выше, но
   перебита более поздним правилом и никогда не действовала. */

/* Основное значение в строке — не больше двух строк: длинное наименование
   организации не должно растягивать строку на пол-экрана. */
.workspace-table td .workspace-cell-main,
.workspace-table td .workspace-primary-link,
.client-table td .table-primary-link {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   101G: список на телефоне начинается с записей, а не с настроек

   Измерение на 390 px: показатели 1357 px, фильтры 685 px, первая строка
   таблицы на отметке 2485 px. Раздел открывают ради записей.
   -------------------------------------------------------------------------- */

/* Блок фильтров: на широком экране заголовка нет и блок всегда раскрыт. */
.filter-disclosure > summary { display: none; }
.filter-disclosure { border: 0; }

@media (max-width: 767.98px) {
    .filter-disclosure > summary {
        display: flex;
        align-items: center;
        gap: 8px;
        min-height: 44px;
        margin: 0 var(--space-2);
        padding: 0 12px;
        border: 1px solid var(--mist);
        border-radius: var(--radius-small);
        background: var(--white);
        color: var(--ink);
        font-size: var(--fs-sm);
        font-weight: 600;
        cursor: pointer;
        list-style: none;
    }
    .filter-disclosure > summary::-webkit-details-marker { display: none; }
    .filter-disclosure > summary::after {
        content: "";
        width: 16px;
        height: 16px;
        margin-left: auto;
        background: var(--icon-chevron) center / 16px 16px no-repeat;
        transition: transform 160ms ease;
    }
    .filter-disclosure[open] > summary::after { transform: rotate(180deg); }
    .filter-disclosure[open] > summary { margin-bottom: var(--space-1); }

    /* Показатели — одна прокручиваемая строка, а не два экрана карточек. */
    .metric-grid, .workspace-metrics, .metric-grid.is-dense {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 8px;
        padding-bottom: 4px;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
    }
    .metric-grid > *, .workspace-metrics > * {
        flex: 0 0 auto;
        width: 168px;
        scroll-snap-align: start;
        min-height: 0;
        padding: 10px 12px;
    }
    .metric-card > strong { font-size: var(--fs-section); }
    .metric-card > span { height: 30px; min-height: 30px; font-size: var(--fs-micro); }
    .metric-card > small { font-size: var(--fs-micro); -webkit-line-clamp: 1; }
    .metric-of { font-size: var(--fs-micro); }
}

/* Граница ступени — 767.98, а не 768: у продукта телефонная ступень объявлена
   именно так, и шесть блоков с «768» срабатывали ровно на ширине 768, когда
   остальная телефонная раскладка ещё не включилась. На этой ширине шапка
   таблицы оставалась видимой и выровненной вправо, а ячейки уже уезжали влево.
   Ту же ошибку продукт разбирал на границе 1023. */

/* Полоса показателей на телефоне — строка карточек одной высоты. При переходе
   на flex выравнивание по высоте потерялось, и карточки в строке разъехались. */
@media (max-width: 767.98px) {
    .metric-grid, .workspace-metrics, .metric-grid.is-dense { align-items: stretch; }
    .metric-grid > *, .workspace-metrics > * { height: auto; align-self: stretch; }
}

/* В карточном виде строки денежная ячейка выравнивается влево целиком: и
   значение, и подпись. Правое выравнивание нужно колонке, а в карточке
   колонки нет. */
@media (max-width: 767.98px) {
    .workspace-table td.amount-cell,
    .workspace-table td.amount-cell small,
    .workspace-table td.w-count,
    .workspace-table td small { text-align: left; }
}

/* --------------------------------------------------------------------------
   101G: пояснение под значением — две строки, но плотные

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

   Возвращаем две строки, но с плотным межстрочным расстоянием: короткая
   подпись помещается целиком, а строка списка вырастает незначительно.
   -------------------------------------------------------------------------- */
.workspace-table td small, .data-table td small, .client-table td small {
    -webkit-line-clamp: 2;
    line-height: 1.3;
}
/* Дата и число — подпись там всегда короткая, второй строки не требуется. */
.workspace-table td.w-date small, .workspace-table td.w-count small { -webkit-line-clamp: 1; }

/* --------------------------------------------------------------------------
   101G: пять показателей должны помещаться в один ряд

   При минимальной ширине карточки 210 px на рабочем мониторе (1440) в ряд
   влезало четыре карточки, и пятая — «Закрыто» — уходила на отдельную строку
   одна. Получался пустой прямоугольник в половину экрана и ложное впечатление,
   что этот показатель чем-то отличается от остальных.

   Подписи показателей короткие, 172 px им достаточно: на 1440 помещается пять
   карточек, на 1280 — тоже пять. Растягивает их всё та же доля свободного
   места, поэтому на широком мониторе карточки не мельчают.
   -------------------------------------------------------------------------- */
.metric-grid, .workspace-metrics, .finance-metric-grid {
    grid-template-columns: repeat(auto-fit, minmax(172px, 1fr));
}

/* --------------------------------------------------------------------------
   101G: распределение по одной величине — один блок, а не пять карточек

   P0…P4 — пять диапазонов коммерческого приоритета. Пятью равными карточками
   они занимали половину блока показателей базы субъектов и читались как пять
   независимых величин: взгляд начинал их складывать.

   Здесь это одна шкала. Требования владельца: сразу видно распределение; P0
   заметнее остальных, но без светофора; числа кликабельны так же, как были
   карточки; на телефоне блок не превращается в пять больших карточек.
   -------------------------------------------------------------------------- */
.distribution {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px var(--card-pad);
    margin-bottom: var(--space-3);
}
.distribution-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.distribution-title {
    font-size: var(--fs-meta);
    font-weight: 600;
    color: var(--steel-2);
}
.distribution-hint { font-size: var(--fs-micro); color: var(--steel-2); }

.distribution-scale {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 8px;
}
.distribution-cell {
    display: grid;
    /* Четыре ряда постоянного назначения: код, число, шкала, диапазон.
       Именно это держит числа соседних делений на одной линии. */
    grid-template-rows: auto auto auto auto;
    gap: 2px;
    padding: 8px 10px;
    border: 1px solid transparent;
    border-radius: var(--radius-small);
    background: var(--surface-2);
    text-decoration: none;
    color: inherit;
    min-width: 0;
    transition: border-color .12s ease, background .12s ease;
}
.distribution-cell:hover { border-color: var(--info); background: var(--surface); }
.distribution-cell:focus-visible {
    outline: 3px solid rgba(44, 90, 134, .35);
    outline-offset: 2px;
}
.distribution-code {
    font-size: var(--fs-micro);
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--steel-2);
}
.distribution-value {
    font-size: var(--fs-section);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.distribution-bar {
    display: block;
    height: 4px;
    border-radius: 2px;
    background: var(--line);
    overflow: hidden;
}
.distribution-bar i {
    display: block;
    height: 100%;
    border-radius: 2px;
    background: var(--steel-3);
    min-width: 2px;
}
.distribution-range {
    font-size: var(--fs-micro);
    line-height: 15px;
    color: var(--steel-3);
    /* Диапазон — вторая строка максимум: иначе деления разъезжаются по высоте. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Верхний класс заметнее соседних — плотностью и одним акцентом, а не
   заливкой: светофор из пяти цветов превратил бы шкалу в украшение. */
.distribution-cell.is-top { background: var(--surface); border-color: var(--line); }
.distribution-cell.is-top .distribution-code { color: var(--ink); }
.distribution-cell.is-top .distribution-value { font-weight: 700; }
.distribution-cell.is-top .distribution-bar i { background: var(--info); }

/* Планшет: пять делений в ряд остаются читаемыми, диапазон убирается —
   он есть в подсказке и на широком экране. */
@media (max-width: 900px) {
    .distribution-range { display: none; }
    .distribution-scale { gap: 6px; }
    .distribution-cell { padding: 8px; }
}

/* Телефон: не пять больших карточек, а компактная строка делений.
   Ряд остаётся одним — распределение читается целиком, без прокрутки. */
@media (max-width: 560px) {
    .distribution { padding: 10px 12px; }
    .distribution-scale { gap: 4px; }
    .distribution-cell {
        padding: 6px 4px;
        justify-items: center;
        text-align: center;
    }
    .distribution-value { font-size: var(--fs-base); }
}

/* --------------------------------------------------------------------------
   101G, вторая редакция: распределение — сегментная шкала

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

   Здесь доля класса равна доле его сегмента. Оттенки — одна шкала от тёмного
   к светлому, а не пять разных цветов: светофор из пяти сигналов превратил бы
   распределение в украшение. Верхний класс — самый тёмный и единственный, у
   которого значение выделено начертанием.
   -------------------------------------------------------------------------- */
.distribution-scale {
    display: flex;
    gap: 2px;
    height: 10px;
    margin-bottom: 10px;
}
.distribution-segment {
    display: block;
    min-width: 3px;
    border-radius: 2px;
    background: var(--steel-3);
    transition: opacity .12s ease;
}
.distribution-segment:hover { opacity: .75; }
.distribution-segment:focus-visible {
    outline: 3px solid rgba(44, 90, 134, .35);
    outline-offset: 2px;
}

/* Одна шкала оттенков: чем выше класс, тем плотнее заливка. */
.tone-p0 { background: #24455f; }
.tone-p1 { background: #3d6a8c; }
.tone-p2 { background: #6a90ad; }
.tone-p3 { background: #a3b9c9; }
.tone-p4 { background: #d6dee5; }

.distribution-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
}
.distribution-key {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 2px 6px;
    margin-left: -6px;
    border-radius: var(--radius-small);
    text-decoration: none;
    color: inherit;
    min-width: 0;
}
.distribution-key:hover { background: var(--surface-2); }
.distribution-key:focus-visible {
    outline: 3px solid rgba(44, 90, 134, .35);
    outline-offset: 1px;
}
.distribution-dot {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    flex: 0 0 auto;
    align-self: center;
}
.distribution-key .distribution-code {
    font-size: var(--fs-micro);
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--steel-2);
}
.distribution-key .distribution-value {
    font-size: var(--fs-base);
    font-variant-numeric: tabular-nums;
}
.distribution-key .distribution-range {
    font-size: var(--fs-micro);
    color: var(--steel-2);
    white-space: nowrap;
}
/* Верхний класс заметнее соседних начертанием, а не цветом. */
.distribution-key.is-top .distribution-code { color: var(--ink); }
.distribution-key.is-top .distribution-value { font-weight: 700; }

/* Планшет и телефон: шкала остаётся целой, из подписи уходит диапазон —
   он есть в подсказке. Пятью карточками блок не становится ни на одном
   размере: это одна строка значений, которая переносится. */
@media (max-width: 900px) {
    .distribution-legend { gap: 4px 12px; }
    .distribution-key .distribution-range { display: none; }
}
@media (max-width: 560px) {
    .distribution { padding: 10px 12px; }
    .distribution-scale { height: 8px; }
    .distribution-legend { gap: 2px 10px; }
    .distribution-key { padding: 2px 4px; margin-left: -4px; }
}

/* --------------------------------------------------------------------------
   101G: строка о пересечении показателей

   Карточки базы субъектов описывают одни и те же лица с разных сторон:
   275 + 27 + 219 + 493 даёт 1570 при 958 субъектах. Пока об этом не сказано,
   числа рядом читаются как части одного целого.

   Строка ставится под полосой показателей и оформлена как пояснение, а не как
   предупреждение: это норма устройства данных, а не проблема.
   -------------------------------------------------------------------------- */
.metrics-note {
    margin: -8px 0 var(--space-3);
    padding: 8px 12px;
    border-left: 2px solid var(--line);
    color: var(--steel-2);
    font-size: var(--fs-micro);
    line-height: 1.45;
    max-width: 88ch;
}

/* --------------------------------------------------------------------------
   ФАЗА 0: карточка проверяемого контакта

   Прежняя форма просила «подтвердить контакт», не показывая, какой именно
   адрес проверяется: блок с известными сведениями вычислялся, но в разметку
   не попадал. Теперь каждый найденный адрес — отдельная карточка со всем, на
   что человек опирается, и с решением по этому адресу, а не по лицу целиком.
   -------------------------------------------------------------------------- */
.contact-card {
    display: block;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    padding: var(--card-pad);
    margin-bottom: var(--space-2);
}
/* Адрес, из-за которого запись попала на проверку, выделен планкой слева:
   остальные показаны потому, что решение нужно и по ним. */
.contact-card.is-target { border-left: 3px solid var(--info); }

.contact-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 10px;
}
.contact-value {
    font-size: var(--fs-card);
    font-weight: 600;
    word-break: break-all;
}
.contact-kind { font-size: var(--fs-micro); color: var(--steel-2); }
.contact-flag {
    font-size: var(--fs-micro);
    color: var(--info);
    border: 1px solid var(--info);
    border-radius: var(--radius-small);
    padding: 2px 6px;
}

.contact-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 6px 16px;
    margin: 0 0 12px;
}
.contact-facts > div { display: flex; gap: 6px; align-items: baseline; min-width: 0; }
.contact-facts dt { color: var(--steel-2); font-size: var(--fs-micro); flex: 0 0 auto; }
.contact-facts dd { margin: 0; font-size: var(--fs-meta); min-width: 0; word-break: break-word; }

.contact-decision { border-top: 1px solid var(--line); padding-top: 10px; }
.contact-decision-title {
    display: block;
    font-size: var(--fs-micro);
    color: var(--steel-2);
    margin-bottom: 6px;
}
/* Компактный вариант карточки выбора: решений пять, и они повторяются для
   каждого адреса — обычная высота превратила бы страницу в простыню. */
.choice-card.compact { padding: 6px 10px; margin-bottom: 4px; }
.choice-card.compact .choice-title { font-size: var(--fs-meta); font-weight: 600; }
.choice-card.compact .choice-effect { font-size: var(--fs-micro); }

.add-contact { margin-top: var(--space-3); }
.add-contact > summary {
    cursor: pointer;
    font-size: var(--fs-meta);
    font-weight: 600;
    color: var(--info);
    padding: 8px 0;
}
.add-contact[open] > summary { margin-bottom: 8px; }

@media (max-width: 560px) {
    .contact-facts { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Вертикальный ритм меню

   Замер прежнего состояния: от логотипа до заголовка «Работа» — 2 px, а от
   этого заголовка до его же пунктов — 8 px. То есть заголовок был вчетверо
   ближе к логотипу, чем к своей группе, и читался как часть логотипа. У двух
   других групп над заголовком было 38 px: один и тот же элемент жил по трём
   разным правилам.

   Закон близости требует обратного: расстояние НАД заголовком должно заметно
   превышать расстояние ПОД ним, тогда заголовок принадлежит своей группе, а не
   тому, что стоит выше. Ритм задан на шаге 4/8:

       логотип -> заголовок      32 px   (24 у логотипа + 8 у области)
       заголовок -> первый пункт  8 px
       пункт -> пункт             4 px
       группа -> черта           24 px
       черта -> заголовок        24 px

   Над заголовком всегда 24-32 px, под ним 8 px — отношение 3:1. Промежуток
   между пунктами вдвое меньше отступа под заголовком, поэтому пункты читаются
   как одна группа, а не как отдельные строки.
   -------------------------------------------------------------------------- */
:root {
    /* Ритм меню. Одни и те же величины на любом настольном экране и при любом
       масштабе браузера. Высота окна на них не влияет: если меню не помещается,
       оно листается. */
    --nav-logo-gap: 24px;    /* логотип → надзаголовок группы */
    --nav-section-gap: 8px;  /* надзаголовок → первый пункт */
    --nav-group-gap: 24px;   /* воздух с каждой стороны черты между группами */
    --nav-item-gap: 4px;     /* пункт → пункт */
}

.brand {
    /* Логотип — другой уровень иерархии, ему нужен собственный воздух снизу. */
    padding: 16px var(--space-3) var(--nav-logo-gap);
    min-height: 0;
}

.sidebar > .nav {
    /* Собственного отступа сверху нет: расстояние до надзаголовка задаёт
       логотип одной величиной, а не два блока сразу. */
    padding-top: 0;
    /* Воздух над чертой, разделяющей группы. */
    gap: var(--nav-group-gap);
}

.nav-group { gap: var(--nav-item-gap); }

/* Воздух под чертой равен воздуху над ней: черта принадлежит обеим группам. */
.nav-group + .nav-group {
    padding-top: var(--nav-group-gap);
}

.nav-group h2 {
    /* Полное расстояние до первого пункта — --nav-section-gap: собственный отступ
       заголовка плюс промежуток сетки, который действует и здесь. */
    margin: 0 0 calc(var(--nav-section-gap) - var(--nav-item-gap));
}

/* Сжатия меню по высоте окна больше нет. Здесь стояли четыре блока,
   менявшие отступы логотипа, промежутки групп и высоту пункта на
   высотах 860, 800, 740 и 680 пикселей. Полезная высота ноутбука 1366×768 —
   около 660, у 1440×900 — около 800, у 1920×1080 — около 980. Поэтому на
   ноутбуке срабатывали все четыре, на 1440×900 — два, на 1920×1080 — ни
   одного: ритм меню оказывался разным на каждом экране, а на ноутбуке
   отступ под логотипом падал с 24 до 8 пикселей — слово «РАБОТА» прилипало
   к логотипу.

   Меню, которое не помещается по высоте, листается: область навигации
   объявлена прокручиваемой, а логотип и подпись пользователя закреплены
   по краям сетки. Это честнее сжатия: пункт не теряет цель нажатия. */

/* --------------------------------------------------------------------------
   Заголовок группы меню — по нижней ступени шкалы

   Он был 10 px: единственный размер во всём интерфейсе вне принятой шкалы,
   и при этом набран прописными, разрежённо и приглушённым цветом. Такое
   сочетание читается хуже всего, а 10 px — ниже разумного предела для
   служебной подписи. Ставим 11 px, нижнюю ступень шкалы.
   -------------------------------------------------------------------------- */
.nav-group h2 { font-size: var(--fs-micro); line-height: 16px; }

/* MAILING-UI-101R:BEGIN */

/* ==========================================================================
   101R. Раздел «Рассылки»: воронка пригодности, стадии кампании, матрица
   тестов, письмо и его разбор.

   Новых цветов не вводится — используются токены палитры. Компоненты
   рассчитаны на 320, 390, 768, 1024 и 1440 px: широкие блоки перестраиваются
   в одну колонку, широкая таблица матрицы прокручивается внутри своего
   контейнера и за пределы окна страницу не выталкивает.
   ========================================================================== */

/* --- Два столбца: работа слева, справочное справа ------------------------ */
.detail-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--space-3);
    align-items: start;
}
.detail-main, .detail-side { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }

/* --- Конструктор аудитории ---------------------------------------------- */
.builder {
    display: grid;
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
}
.builder-preview { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.builder-form { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); }
.builder-block { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.builder-block legend {
    padding: 0 0 var(--space-1);
    color: var(--ink);
    font-size: var(--fs-sm);
    font-weight: 700;
}
/* Ряд действий формы в продукте один — .form-actions; своего у раздела нет. */

/* Собственных описаний подписи, пояснения и ошибки у раздела нет: они
   называлась общими именами и меняли вид форм во всём продукте.
   Собственного описания поля тоже нет: оно называлось общим именем и
   меняло формы во всём продукте. Раздел берёт объявленный образец. */
.field.has-error .form-control { border-color: var(--negative); }
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-1); }

.field-check { display: flex; align-items: flex-start; gap: 8px; min-height: 44px; }
.field.field-check { flex-direction: row; align-items: flex-start; }
/* Флажок отстоит от подписи так же, как во всех остальных местах файла. */
.field-check > input { margin-top: 2px; flex: 0 0 auto; }
.field-check span { color: var(--ink); font-size: var(--fs-sm); line-height: 20px; }
.field-check span small { display: block; color: var(--steel-2); font-size: var(--fs-meta); }
.field-choice ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-1); }
.field-choice li label { display: flex; align-items: center; gap: 6px; min-height: 44px; font-size: var(--fs-sm); }
.priority-choice ul { flex-direction: column; gap: 0; }
.field-choice > div.form-check {
    width: auto; height: auto; min-width: 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: var(--space-1);
}
.field-choice > div.form-check > div { min-width: 0; }
.field-choice label {
    display: flex; align-items: center; gap: 6px;
    min-height: 44px; color: var(--ink); font-size: var(--fs-sm); cursor: pointer;
}
.priority-choice > div.form-check { flex-direction: column; gap: 0; }

.preview-placeholder { padding: var(--space-4); }

/* --- Воронка пригодности ------------------------------------------------- */
.funnel { background: var(--white); border: 1px solid var(--line-soft); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: var(--space-3); }
.funnel-head h3 { margin: 0 0 4px; font-size: var(--fs-lead); }
.funnel-head p { margin: 0 0 var(--space-2); color: var(--steel-2); font-size: var(--fs-meta); line-height: 18px; }
.funnel-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; counter-reset: none; }
.funnel-step .funnel-link {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "label value" "hint value";
    gap: 0 var(--space-2);
    align-items: center;
    padding: 10px 12px;
    border-radius: var(--radius-small);
    border-left: 3px solid var(--mist);
    background: var(--paper);
    color: inherit;
    text-decoration: none;
    min-height: 44px;
}
a.funnel-link:hover { background: var(--white); border-left-color: var(--steel-2); box-shadow: var(--shadow-card); }
.funnel-label { grid-area: label; color: var(--ink); font-size: var(--fs-sm); font-weight: 600; }
.funnel-hint { grid-area: hint; color: var(--steel-2); font-size: var(--fs-meta); line-height: 17px; }
.funnel-value { grid-area: value; font-size: var(--fs-section); font-weight: 700; font-variant-numeric: tabular-nums; }
.funnel-step.is-stage .funnel-link { border-left-color: var(--steel-1); background: var(--white); border-top: 1px solid var(--line-soft); border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.funnel-step.is-loss .funnel-value { color: var(--steel-2); font-size: var(--fs-card); }
.funnel-step.is-final .funnel-link { border-left-color: var(--positive); background: var(--positive-soft); margin-top: var(--space-1); }
.funnel-step.is-final .funnel-value { color: var(--positive); font-size: var(--fs-block); }
.funnel-note { margin: var(--space-2) 0 0; color: var(--steel-2); font-size: var(--fs-meta); line-height: 18px; }

/* --- Исходы отбора ------------------------------------------------------- */
.outcome-tabs { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 var(--space-3) var(--space-2); }
.outcome-tabs a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 12px; min-height: 44px;
    border: 1px solid var(--line-soft); border-radius: var(--radius-small);
    color: var(--steel-2); font-size: var(--fs-meta); font-weight: 600; text-decoration: none;
}
.outcome-tabs a b { color: var(--ink); font-variant-numeric: tabular-nums; }
.outcome-tabs a:hover { border-color: var(--steel-3); }
.outcome-tabs a.active { color: var(--white); border-color: var(--ink); background: var(--ink); }
.outcome-tabs a.active b { color: var(--white); }

/* --- Стадии кампании ----------------------------------------------------- */
.stage-list { list-style: none; margin: 0; padding: 0; }
.stage {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) auto;
    gap: var(--space-2);
    align-items: center;
    padding: 12px var(--space-3);
    border-top: 1px solid var(--line-soft);
}
.stage:first-child { border-top: 0; }
.stage-number {
    display: grid; place-items: center;
    width: 28px; height: 28px; border-radius: 50%;
    border: 1px solid var(--mist); color: var(--steel-2);
    font-size: var(--fs-meta); font-weight: 700;
}
.stage-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stage-body strong { font-size: var(--fs-sm); }
.stage-body small { color: var(--steel-2); font-size: var(--fs-meta); line-height: 18px; }
.stage-mark { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.stage.is-done .stage-number { color: var(--white); border-color: var(--positive); background: var(--positive); }
.stage.is-done .stage-mark { color: var(--positive); }
.stage.is-current { background: var(--paper); }
.stage.is-current .stage-number { color: var(--white); border-color: var(--ink); background: var(--ink); }
.stage.is-current .stage-mark { color: var(--ink); }
/* Заблокированная стадия отличается меткой, а не выцветшим текстом:
   пояснение и так набрано приглушённым тоном, и гасить его ещё сильнее
   значило бы сделать нечитаемым то, что как раз и надо прочесть. */
.stage.is-blocked .stage-mark { color: var(--warning); }
.stage.is-blocked .stage-number { border-color: var(--warning); color: var(--warning); }

/* --- Линия процесса ------------------------------------------------------ */
.process-line { list-style: none; margin: 0; padding: 0 var(--space-3) var(--space-2); display: flex; flex-wrap: wrap; gap: var(--space-1); }
.process-line li { display: flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid var(--line-soft); border-radius: 999px; }
.process-number { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; }
.process-label { color: var(--steel-1); font-size: var(--fs-meta); font-weight: 600; }

/* --- Карточки услуг ------------------------------------------------------ */
.service-card { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-2); border: 1px solid var(--line-soft); border-radius: var(--radius-small); }
.service-short { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.service-card h3 { margin: 2px 0 0; font-size: var(--fs-sm); }
/* Действие прижато к низу карточки: иначе в ряду кнопки встают на разной
   высоте, потому что текст над ними разной длины. Тот же приём принят
   для денежных счетов и почтовых ящиков. */
.service-card > .button, .service-card > form { margin-top: auto; }
.service-facts { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.service-facts > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-1); }
.service-facts dt { color: var(--steel-2); font-size: var(--fs-meta); }
.service-facts dd { margin: 0; font-size: var(--fs-sm); font-weight: 700; font-variant-numeric: tabular-nums; }
.service-facts .is-final dd { color: var(--positive); font-size: var(--fs-card); }
.service-note { margin: 0; color: var(--steel-2); font-size: var(--fs-meta); line-height: 18px; }

/* --- Списки фактов и боковые списки -------------------------------------- */
.workspace-kv.is-narrow dd {
    font-weight: 600; font-variant-numeric: tabular-nums;
    text-align: right; overflow-wrap: anywhere;
}

.side-list { list-style: none; margin: 0; padding: 0 var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); }
.side-list li { display: flex; flex-direction: column; gap: 2px; padding: 8px 0; border-top: 1px solid var(--line-soft); }
.side-list li:first-child { border-top: 0; }
.side-list a { display: flex; justify-content: space-between; gap: var(--space-1); color: inherit; text-decoration: none; min-height: 24px; }
.side-list a strong { font-size: var(--fs-sm); font-weight: 600; }
.side-list a span { color: var(--steel-2); font-size: var(--fs-meta); white-space: nowrap; }
.side-list a:hover strong { color: var(--steel-1); text-decoration: underline; }
.side-list small { color: var(--steel-2); font-size: var(--fs-meta); line-height: 17px; }
.side-list .side-empty { color: var(--steel-2); font-size: var(--fs-meta); }
/* Имя совпало с обёрткой крупного пустого состояния продукта, и
   однострочная подпись в боковом списке вырастала в блок на 166
   пикселей с текстом по центру. */
.side-list > .side-empty { min-height: 0; align-items: normal; place-items: start; }

.panel-note { color: var(--steel-2); font-size: var(--fs-meta); }
/* Форма раздела описана только внутри его двухколоночной раскладки:
   под общим именем она задавала свой промежуток и свои поля всем формам
   продукта. Все шесть форм раздела лежат внутри .detail-columns. */
.detail-columns .stack-form { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) var(--space-3); }
.detail-columns .inline-form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.detail-columns .panel > form:not(.stack-form):not(.inline-form) {
    display: flex; flex-direction: column; align-items: flex-start;
    gap: var(--space-1); padding: 0 var(--space-3) var(--space-3);
}

/* --- Письмо и разбор подстановок ----------------------------------------- */
.letter-subject, .letter-greeting { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2) var(--space-3); border-top: 1px solid var(--line-soft); }
.letter-field { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.letter-subject strong { font-size: var(--fs-lead); }
.letter-greeting small { color: var(--steel-2); font-size: var(--fs-meta); }
.letter-greeting small.is-warning { color: var(--warning); }
.letter-body {
    margin: 0; padding: var(--space-3);
    border-top: 1px solid var(--line-soft);
    background: var(--paper);
    color: var(--ink);
    font-family: inherit; font-size: var(--fs-sm); line-height: 22px;
    white-space: pre-wrap; word-break: break-word;
    overflow-x: auto;
}
.letter-body.is-source { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-meta); }
.letter-dataset { padding: 0 var(--space-3) var(--space-2); }
.letter-dataset summary { min-height: 44px; display: flex; align-items: center; color: var(--steel-2); font-size: var(--fs-meta); font-weight: 600; cursor: pointer; }

.check-list { list-style: none; margin: 0; padding: var(--space-2) var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: 8px; }
.check { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 8px; align-items: start; font-size: var(--fs-sm); line-height: 20px; }
.check-mark { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; font-size: var(--fs-micro); font-weight: 700; }
.check.is-ok .check-mark { color: var(--positive); background: var(--positive-soft); }
.check.is-warning .check-mark { color: var(--warning); background: var(--warning-soft); }
.check.is-note .check-mark { color: var(--steel-2); background: var(--mist); }
.check-ok { margin: 0; padding: var(--space-2) var(--space-3) var(--space-3); color: var(--positive); font-size: var(--fs-sm); }

/* --- Матрица тестов ------------------------------------------------------ */
.workspace-table.matrix th[scope="row"] { text-align: left; vertical-align: top; }
.matrix-cell { vertical-align: top; }
.matrix-cell small { display: block; color: var(--steel-2); font-size: var(--fs-micro); line-height: 16px; }
.matrix-cell small.is-warning { color: var(--warning); }
.matrix-order { font-variant-numeric: tabular-nums; }
.inbox-choice { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.inbox-choice legend { padding: 0 0 4px; color: var(--steel-2); font-size: var(--fs-meta); font-weight: 600; }
.inbox-choice legend i { color: var(--steel-2); font-style: normal; font-weight: 500; }

/* --- Показатели и срезы аналитики ---------------------------------------- */

.slice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-2); padding: 0 var(--space-3) var(--space-3); }
.slice { border: 1px solid var(--line-soft); border-radius: var(--radius-small); padding: var(--space-2); }
.slice h3 { margin: 0 0 var(--space-1); font-size: var(--fs-sm); }
.slice ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.slice li { display: flex; justify-content: space-between; gap: var(--space-1); font-size: var(--fs-meta); }
.slice li strong { font-variant-numeric: tabular-nums; }
.slice-label { color: var(--steel-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slice-empty { color: var(--steel-2); }

/* --- Внутренний ряд вкладок ---------------------------------------------- */
.workspace-subtabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 var(--space-3); }
.workspace-subtabs a {
    display: inline-flex; align-items: center; min-height: 44px; padding: 8px 14px;
    border-radius: var(--radius-small);
    color: var(--steel-2); font-size: var(--fs-sm); font-weight: 600; text-decoration: none;
}
.workspace-subtabs a:hover { background: var(--paper); color: var(--ink); }
/* Выбранная вкладка помечается так же, как в ряду над ней: белым по
   тёмному. Серая заливка объясняла тот же выбор вторым способом. */
.workspace-subtabs a.active { color: var(--white); border-color: var(--ink); background: var(--ink); }

/* Уведомление «к сведению» держит свой цвет: прежнее правило гасило его
   до фона страницы, и оно переставало читаться как уведомление. */

/* --- Перестроение на узких экранах --------------------------------------- */
@media (max-width: 1180px) {
    .detail-columns { grid-template-columns: minmax(0, 1fr); }
    .builder { grid-template-columns: minmax(0, 1fr); }
}

/* Ниже 420 px пара полей в строке не помещается физически: два поля по 150 px
   с промежутком и отступами шире экрана телефона. Строка становится столбцом. */
/* Общая ступень узкого экрана: пара полей в строку и ряд вкладок ужимаются
   там же, где это делает остальной продукт, а не на своих 420 и 380. */
@media (max-width: 479.98px) {
    .field-row { grid-template-columns: minmax(0, 1fr); }
    .workspace-subtabs a { padding: 8px 10px; font-size: var(--fs-meta); }
}

@media (max-width: 640px) {
    .funnel, .builder-form { padding: var(--space-2); }
    .funnel-step .funnel-link { grid-template-columns: minmax(0, 1fr) auto; padding: 10px; }
    .funnel-value { font-size: var(--fs-card); }
    .funnel-step.is-final .funnel-value { font-size: var(--fs-section); }
    .stage { grid-template-columns: 28px minmax(0, 1fr); grid-template-areas: "number body" "mark mark"; }
    .stage-number { grid-area: number; }
    .stage-body { grid-area: body; }
    .stage-mark { grid-area: mark; }
    .slice-grid { padding-left: var(--space-2); padding-right: var(--space-2); }
    .outcome-tabs, .process-line { padding-left: var(--space-2); padding-right: var(--space-2); }
    .workspace-kv.is-narrow, .fact-list, .side-list, .detail-columns .stack-form, .check-list,
    .letter-body { padding-left: var(--space-2); padding-right: var(--space-2); }
}

/* На 320 px таблица матрицы шире окна по существу: она прокручивается внутри
   своего контейнера, а страница горизонтально не едет. */


/* --- Широкая таблица не выталкивает страницу ------------------------------ */
/* Правило .table-wrap { overflow-x: visible } из общего слоя на узком экране
   отдавало таблице с фиксированными колонками право двигать всю страницу вбок.
   Управляемая прокрутка таблицы внутри своего блока допустима, горизонтальный
   сдвиг окна — нет. */
/* Своей ступени здесь нет: прокрутка таблицы внутри блока и запрет
   сдвига окна объявлены общими правилами, а граница 1023 исключала
   саму ширину 1024 — ошибку продукт уже разбирал и переписал
   на включительные границы. */
/* MAILING-UI-101R:END */


/* --------------------------------------------------------------------------
   Панели внутри сетки

   Расстояние между ними задаёт промежуток сетки. Отступ соседа сверху здесь
   лишний: первая карточка ряда его не получает, остальные получают, и ряд
   выходит разной длины. В колонке тот же отступ складывается с промежутком.
   -------------------------------------------------------------------------- */
.card-grid > .panel + .panel,
.import-config-layout > .panel + .panel,
.mail-context > .panel + .panel,
.client-form > .panel + .panel,
.review-layout > .panel + .panel,
.detail-main > .panel + .panel,
.detail-side > .panel + .panel,
.finance-side > .panel + .panel,
.workspace-detail-grid > .panel + .panel { margin-top: 0; }


/* --------------------------------------------------------------------------
   Шапка числового столбца

   Общее описание шапки объявлено позже и прижимает подпись влево, из-за чего
   цифры и их название расходятся по разным краям. Здесь это перекрывается
   только для столбцов, отмеченных как числовые.
   -------------------------------------------------------------------------- */
.app-shell table th.num,
.workspace-table th.num,
.data-table th.num,
.client-table th.num { text-align: right; }


/* --------------------------------------------------------------------------
   Первый столбец финансовой таблицы

   Правило «ячейка перед денежной уходит вправо» писалось для подписи рядом с
   суммой, но срабатывает и на первом столбце: название статьи оказывается
   прижато к правому краю. Это текст, и читают его слева.
   -------------------------------------------------------------------------- */
.app-shell .finance-table th:first-child,
.app-shell .finance-table td:first-child { text-align: left; }


/* --------------------------------------------------------------------------
   Второй круг оформления
   -------------------------------------------------------------------------- */

/* Многострочное поле высотой не ограничено: в него пишут абзац, а не строку. */
.stack-form textarea, .search-form textarea, textarea.form-control {
    height: auto;
    min-height: 96px;
}

/* Строка списка открывается по нажатию — значит, отзывается на наведение.
   Без отклика единственный признак ссылки — курсор, а его замечают не сразу. */
.workspace-table tbody tr:has(a):hover,
.data-table tbody tr:has(a):hover,
.client-table tbody tr:has(a):hover,
.finance-table tbody tr:has(a):hover { background: var(--paper); }

/* Подзаголовок раздела — проза, и мера строки у неё своя. По ширине колонки
   выходило около 108 знаков: глаз теряет начало следующей строки. */
.workspace-subtitle { max-width: 66ch; }

/* Технический блок на уровне страницы держит общий левый край. Боковой
   отступ нужен ему только внутри карточки. */
.page-frame > .review-technical { margin-left: 0; margin-right: 0; }


/* --------------------------------------------------------------------------
   Нажатие, цели и мелочи после разбора оформления
   -------------------------------------------------------------------------- */

/* Состояние нажатия не было объявлено нигде: между наведением и появлением
   результата человек не получал никакого ответа на само нажатие. */
.button:active,
button:active,
.link-button:active,
.chip-remove:active,
.pagination .page-link:active { transform: translateY(1px); }
.button.primary:active { background: var(--steel-1); border-color: var(--steel-1); }
.button.secondary:active, .button:active { background: var(--paper); }

/* На касании крестик чипа просили 44 пикселя внутри чипа высотой 36: он
   не помещался и распирал сам чип. Растёт чип, а не знак внутри него. */
@media (hover: none) and (pointer: coarse) {
    .chip { min-height: 44px; }
    .chip .chip-remove { width: 32px; height: 32px; min-width: 0; min-height: 0; }
}

/* В карточной раскладке строки заголовков столбцов нет, и выравнивать
   число вправо не к чему. */
@media (max-width: 767.98px) {
    .client-table td.num, .workspace-table td.num { text-align: left; }
}

/* Группа выбора: обёртка в fieldset нужна, чтобы вопрос читался вместе со
   своими вариантами. Стандартную рамку браузера при этом снимаем. */
.choice-group { margin: 0; padding: 0; border: 0; display: grid; gap: var(--space-1); }
.choice-group > legend { padding: 0; }

/* Ряд карточек, где вместо числа стоит слово или дата: величина набирается
   на ступень мельче, иначе строка не помещается и ломает ряд. Отклонение
   задаётся один раз на ряд, а не на каждой карточке в разметке. */
.metric-grid.is-textual .metric-card > strong { font-size: var(--fs-section); }

/* Карточка предела: подпись, величина и пояснение. Прежде их ритм задавался
   прямо в разметке, и одна и та же карточка на четырёх страницах выглядела
   по-разному. */
.setting-card-label {
    margin: 0;
    color: var(--steel-2);
    font-size: var(--fs-sm);
    font-weight: 600;
}
.setting-card-value {
    display: block;
    margin: 6px 0;
    font-size: var(--fs-section);
    font-weight: 700;
}
.setting-card-now { margin: 0; font-size: var(--fs-sm); }
.setting-card .workspace-hint { margin: 0 0 6px; }

/* Пояснительная проза не растягивается на всю ширину колонки: строка от ста
   до ста семидесяти знаков не читается — глаз теряет начало следующей.
   Мера задаётся в знаках и потому не зависит от кегля и ширины окна. */
.metrics-note,
.funnel-note,
.finance-activity-note,
.workspace-hint,
.section-intro p,
.panel > .workspace-hint { max-width: 74ch; }

/* Карточка показателя — система отсчёта для того, что вынесено из её потока. */
.metric-card { position: relative; }

/* Отступы и кегль, которые прежде стояли прямо в разметке. Значения те же,
   но теперь их можно поправить в одном месте, а не в девяти. */
.filter-row { margin-bottom: var(--space-3); }
.inline-form { margin: 0; }
.form-actions.is-spaced { margin-top: var(--space-3); }
.copy-field.is-inline { margin-left: var(--space-1); }
.button.is-inline { margin-left: 6px; }
.settings-group-title { margin: 0; font-size: var(--fs-lead); }

/* --------------------------------------------------------------------------
   Таблицы раздела «Рассылки» в узкой колонке

   Рабочий список вбок не прокручивается — правило продукта. Две таблицы
   раздела его нарушали: список выбора шаблона растягивался по самому
   длинному названию, а адрес и наименование не переносились вовсе.
   -------------------------------------------------------------------------- */
.detail-columns .form-control.compact { min-width: 0; max-width: 100%; }
.detail-columns .workspace-table td { overflow-wrap: break-word; word-break: normal; }
.detail-columns .workspace-table td :where(a[href^="mailto"], code, .mono) {
    overflow-wrap: anywhere;
}
.detail-columns .workspace-table th { white-space: normal; }

/* Сетка карточек внутри панели отступает от её краёв так же, как остальное
   вложенное содержимое. Раньше для этого заводилась вторая сетка. */
.panel > .card-grid { padding: 0 var(--space-3) var(--space-3); }

/* Узкий режим пар «подпись — значение»: в колонке 340 пикселей подпись
   шириной 155 оставляет значению слишком мало, поэтому колонки делятся
   долями, а строки не разделяются линиями — иначе блок читается тяжелее
   самой справки. */
.workspace-kv.is-narrow { padding: var(--space-2) var(--space-3) var(--space-3); }
.workspace-kv.is-narrow > div {
    grid-template-columns: minmax(0, 40%) minmax(0, 60%);
    gap: var(--space-1);
    padding: 4px 0;
    border-bottom: 0;
}
/* Значение ключевого показателя выделяется цветом, как и раньше. */
.metric-card.is-key > strong { color: var(--positive); }

/* --------------------------------------------------------------------------
   ВОЗВРАТ В ПУТИ ПО РАЗДЕЛАМ

   Путь «База субъектов / Абраамян Ваган Норайрович» — это и есть возврат:
   предпоследняя ступень всегда ведёт туда, откуда пришли. Раньше она
   выглядела как обычная надпись, а отдельную ссылку «К базе субъектов»
   рядом прятали, чтобы не дублировать. Получалось, что возврата на экране
   нет вовсе.

   Теперь предпоследняя ступень получает значок возврата и подчёркивается
   вместе с ним: стрелка и название читаются как одно действие, а не как
   украшение перед текстом.
   -------------------------------------------------------------------------- */
.breadcrumbs .crumb-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--ink);
}
.breadcrumbs .crumb-back::before {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--icon-back) center / contain no-repeat;
    mask: var(--icon-back) center / contain no-repeat;
}
.breadcrumbs .crumb-back:hover { color: var(--ink); text-decoration: underline; }

/* --------------------------------------------------------------------------
   ССЫЛКИ ПОД НАЗВАНИЕМ СИТУАЦИИ

   Публикация в ЕФРСБ и номер дела — разные предметы, и они больше не
   склеиваются в одну строку. Публикация — ссылка со значком внешнего
   перехода; номер дела — значение с копированием, потому что картотека
   прямой ссылки на карточку дела не даёт.
   -------------------------------------------------------------------------- */
.cell-refs {
    margin-top: 4px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px var(--space-2);
    color: var(--steel-2);
    font-size: var(--fs-meta);
}
.cell-refs > a { color: var(--info); }
.cell-refs > a:hover { text-decoration: underline; }
.case-ref { display: inline-flex; align-items: center; gap: 6px; }

/* Вид источника. Официальная публикация помечается «Первоисточник», ручная
   находка — «Ручной поиск»: называть их одним словом было бы неправдой. */
.source-kind {
    justify-self: start;
    padding: 2px 8px;
    border: 1px solid var(--line-soft);
    border-radius: 999px;
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 16px;
}
.workspace-list article .source-kind { color: var(--steel-2); font-size: var(--fs-micro); }
.source-kind.is-primary { color: var(--info); border-color: var(--info); }
.workspace-list article .source-kind.is-primary { color: var(--info); }

/* --------------------------------------------------------------------------
   КОНТАКТЫ: ДВЕ НЕЗАВИСИМЫЕ ГРУППЫ

   Одна таблица на почту и телефон не масштабируется: как только у лица
   появляется второй телефон и третий адрес, её приходится читать построчно.
   Группы разделены заголовком и живут каждая своей длиной.
   -------------------------------------------------------------------------- */
.contact-group + .contact-group { border-top: 1px solid var(--line-soft); }
.contact-group-head {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3) 0;
}
.contact-group-head h3 {
    margin: 0;
    font-size: var(--fs-sm);
    font-weight: 700;
}
/* Число записей стоит рядом с названием группы, а не в отдельной колонке. */
.contact-group-count {
    min-width: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--neutral-soft, var(--paper));
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.contact-group-foot { padding: 0 var(--space-3) var(--space-2); }
.contact-group > .workspace-empty { padding: var(--space-2) var(--space-3); text-align: left; }

/* Состав полей будущего добавления: свёрнут по умолчанию, чтобы не занимать
   место у сведений, которые уже есть. */
.contact-add { border-top: 1px solid var(--line-soft); }
.contact-add > summary {
    padding: var(--space-2) var(--space-3);
    color: var(--steel-2);
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
}
.contact-add > summary:hover { color: var(--ink); }
.contact-add-body {
    padding: 0 var(--space-3) var(--space-3);
    display: grid;
    gap: var(--space-2);
}

/* --------------------------------------------------------------------------
   ТАБЛИЦА НЕ ШИРЕ БЛОКА, В КОТОРОМ СТОИТ

   Минимальные ширины таблиц рассчитаны на таблицу во всю ширину страницы.
   В колонке вдвое уже они заставляли прокручивать блок вбок там, где хватило
   бы переноса текста: на «Источниках данных» справочник из двух столбцов
   требовал 760 пикселей в колонке шириной 475.
   -------------------------------------------------------------------------- */
.workspace-detail-grid .data-table,
.workspace-detail-grid .finance-table,
.workspace-detail-grid .client-table,
.detail-columns .data-table,
.detail-columns .finance-table { min-width: 0; }

/* Заголовок числового столбца переносится, а число — нет. Запрет переноса
   нужен значению: «102 000 ₽» нельзя рвать на две строки. Заголовку он не
   нужен, и из-за него «Отклонение» вылезало из своей колонки и добавляло
   финансовой таблице восемь пикселей прокрутки. */
.workspace-table th.num, .data-table th.num, .client-table th.num,
.data-table th.numeric, .workspace-table th.numeric,
.data-table th.money, .finance-table th.num,
th.amount-cell { white-space: normal; }

/* Запрет переноса нужен самому числу: «1 265 258,70 ₽» нельзя рвать на две
   строки. Пояснению под ним он не нужен, и из-за него «исполнено 0,0%»
   вылезало из последней колонки финансовой таблицы на восемь пикселей и
   заставляло блок прокручиваться вбок. */
.finance-table td.amount-cell small,
.finance-table td.num small,
.workspace-table td.num small,
.data-table td.num small,
.data-table td.numeric small { white-space: normal; }

/* Обязательное поле помечается одинаково во всём продукте. В разделе рассылок
   стояло курсивное слово «обязательно», в остальных — звёздочка: два способа
   сказать одно и то же на соседних экранах. Осталась звёздочка, у неё есть
   подсказка при наведении, и она набирается прямым начертанием — курсив у
   одиночного знака читается как случайность. */
.req {
    margin-left: 2px;
    color: var(--negative);
    font-style: normal;
    font-weight: 700;
}

/* --------------------------------------------------------------------------
   СТРЕЛКИ И ОТМЕТКИ — ИЗ ОБЩЕГО НАБОРА

   Здесь стояли последние юникодные символы, работавшие значками: «←» и «→»
   у переключателя месяца, «↑» и «↓» у перестановки показателя, «✓», «!» и
   «?» у отметки проверки, «→» между блоками на экране тестов. Шрифт рисует
   их по-своему, и рядом с настоящими значками они выглядели чужими.
   -------------------------------------------------------------------------- */
:root {
    --icon-arrow-left: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M13 8H3.5'/><path d='M7.5 3.5 3 8l4.5 4.5'/></svg>");
    --icon-arrow-right: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3 8h9.5'/><path d='M8.5 3.5 13 8l-4.5 4.5'/></svg>");
    --icon-arrow-up: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M8 13V3.5'/><path d='M3.5 8 8 3.5 12.5 8'/></svg>");
    --icon-arrow-down: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3v9.5'/><path d='M3.5 8 8 12.5 12.5 8'/></svg>");
}
.step-back::before, .step-next::before,
.step-up::before, .step-down::before,
.test-arrow::before {
    content: "";
    display: block;
    width: var(--icon-size);
    height: var(--icon-size);
    background-color: currentColor;
    -webkit-mask: var(--icon-arrow-left) center / contain no-repeat;
    mask: var(--icon-arrow-left) center / contain no-repeat;
}
.step-next::before, .test-arrow::before {
    -webkit-mask-image: var(--icon-arrow-right);
    mask-image: var(--icon-arrow-right);
}
.step-up::before {
    -webkit-mask-image: var(--icon-arrow-up);
    mask-image: var(--icon-arrow-up);
}
.step-down::before {
    -webkit-mask-image: var(--icon-arrow-down);
    mask-image: var(--icon-arrow-down);
}
.test-arrow { display: grid; place-items: center; color: var(--steel-3); }

/* Отметка проверки: тот же кружок, но знак внутри — значок, а не буква. */
.check-mark::before {
    content: "";
    display: block;
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask: var(--icon-info) center / contain no-repeat;
    mask: var(--icon-info) center / contain no-repeat;
}
.check-mark.is-ok::before {
    -webkit-mask-image: var(--icon-check);
    mask-image: var(--icon-check);
}
.check-mark.is-warning::before {
    -webkit-mask-image: var(--icon-warning);
    mask-image: var(--icon-warning);
}

/* --------------------------------------------------------------------------
   ТАБЛИЦА В КОЛОНКЕ ВДВОЕ УЖЕ

   Ширины столбцов объявляются заранее для таблицы во всю ширину страницы.
   В половинной колонке их сумма перестаёт помещаться: на «Аудитории» это
   664 пикселя при колонке 639, и первый столбец схлопывался в ноль, а блок
   прокручивался вбок. В таких колонках ширину считает содержимое.
   -------------------------------------------------------------------------- */
/* Режим заданных ширин сохраняется — в нём таблица не может стать шире своего
   места. Снимаются сами пиксельные величины: они рассчитаны на таблицу во всю
   ширину страницы. Столбцы делят колонку поровну, содержимое переносится
   внутри своего столбца. Столбцы, которые прячутся на узких экранах, не
   трогаются: у них ширина ноль, и это способ скрытия, а не величина. */
.detail-columns .workspace-table > colgroup > col:not(.optional):not(.optional-2):not(.optional-wide),
.builder .workspace-table > colgroup > col:not(.optional):not(.optional-2):not(.optional-wide),
.workspace-detail-grid .workspace-table > colgroup > col:not(.optional):not(.optional-2):not(.optional-wide) {
    width: auto;
}

/* Кнопка меню: собственного поля у неё нет, браузер подставлял свой пиксель. */
.burger { padding: 0; }

/* Поле-флажок в ряду с обычными полями: подпись у него справа от самого флажка,
   а не над ним, поэтому флажок оказывался на строке подписи соседа, а не на
   строке его поля ввода. Выравнивание по середине ряда ставит их на одну линию. */
.form-grid > .form-field:has(> input[type="checkbox"]),
.form-grid > .field:has(> input[type="checkbox"]) { align-self: center; }

/* Перенос внутри слова доходит до самого значения. Ячейка его уже разрешает,
   но значение лежит в отдельном элементе, по которому позже попадает общее
   правило «переносить только по словам». Прямое правило сильнее наследования,
   поэтому здесь оно объявляется явно и для содержимого ячейки. */
.workspace-table td :where(strong, span, small, a, code, b, em),
.workspace-table th :where(strong, span, small, a, code, b, em),
.data-table td :where(strong, span, small, a, code, b, em),
.finance-table td :where(strong, span, small, a, code, b, em) { overflow-wrap: anywhere; }

/* MAILING-GOLIVE-105:BEGIN */
/* ==========================================================================
   105. Рассылки перед первой рабочей отправкой — визуальный контракт владельца.

   Ни одно значение раздела не обрезается многоточием; таблицы выровнены по
   левому краю, включая суммы; интервал между секциями один; линий без
   назначения нет; настройка вынесена из ряда этапов. Новых цветов нет —
   только токены палитры.
   ========================================================================== */

/* --- Второстепенная вкладка раздела ------------------------------------- */
/* Ряд вкладок отвечает на вопрос «где я в работе», поэтому в нём стоят
   только этапы. Настройка этапом не является: она отодвинута к краю ряда и
   помечена шестерёнкой. Маршрут прежний, вкладка видна. */
:root { --icon-gear: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='8' r='2.25'/><path d='M8 1.5v1.6M8 12.9v1.6M14.5 8h-1.6M3.1 8H1.5M12.6 3.4l-1.1 1.1M4.5 11.5l-1.1 1.1M12.6 12.6l-1.1-1.1M4.5 4.5L3.4 3.4'/></svg>"); }
.workspace-tabs a.is-secondary { margin-left: auto; gap: 6px; color: var(--steel-2); }
.workspace-tabs a.is-secondary::before {
    content: "";
    width: var(--icon-size);
    height: var(--icon-size);
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--icon-gear) center / contain no-repeat;
    mask: var(--icon-gear) center / contain no-repeat;
}
.workspace-tabs a.is-secondary:hover { color: var(--ink); }
.workspace-tabs a.is-secondary.active { color: var(--white); }
@media (max-width: 767.98px) {
    .workspace-tabs a.is-secondary { margin-left: 0; }
}

/* --- Закон таблиц --------------------------------------------------------- */
/* Значение не обрезается: обрезанная услуга, фамилия или причина перестаёт
   быть значением. Длинное значение переносится. Выравнивание — по левому
   краю, включая денежные: в рабочих списках суммы читают построчно вместе с
   названием, и левый край держит строку целой. */
.workspace-table td, .workspace-table th,
.data-table td, .data-table th,
.client-table td, .client-table th {
    text-overflow: clip;
    white-space: normal;
    text-align: left;
}
.workspace-table td :where(strong, span, small, a, code, b, em),
.data-table td :where(strong, span, small, a, code, b, em),
.client-table td :where(strong, span, small, a, code, b, em) {
    text-overflow: clip;
    white-space: normal;
}
/* Денежное значение не рвётся посередине: «1 265 258,70 ₽» — одно число. */
.workspace-table td.amount-cell, .workspace-table th.amount-cell,
.workspace-table td.num, .workspace-table th.num,
.data-table td.numeric, .data-table th.numeric,
.data-table td.money, .data-table th.money,
.client-table td.num, .client-table th.num {
    text-align: left;
    font-variant-numeric: tabular-nums;
}
.workspace-table td.amount-cell > strong,
.workspace-table td.num > strong { white-space: nowrap; }
/* Шапка числового столбца шла вправо более сильным правилом общего слоя:
   число и его название расходились по разным краям. */
.app-shell .workspace-table th.num,
.app-shell .workspace-table td.num,
.app-shell .data-table th.num,
.app-shell .client-table th.num { text-align: left; }
/* Ссылка в таблице — тоже значение: обрезать её нельзя. */
.table-primary-link, .workspace-primary-link {
    max-width: none;
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
}

/* --- Ни одного многоточия в разделе -------------------------------------- */
/* Подписи карточек показателей, боковых списков и срезов аналитики
   переносятся, а не прячутся. Само число по-прежнему не рвётся. */
.metric-card > span, .metric-card > small {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
}
.side-list a span { white-space: normal; text-align: right; }
.slice-label { white-space: normal; overflow: visible; text-overflow: clip; }
.workspace-notice strong, .workspace-notice span { overflow-wrap: anywhere; }

/* --- Единый интервал секций ---------------------------------------------- */
/* Карточки внутри панели не прилипают к линии шапки: после разделителя —
   интервал не меньше строки. Показатели внутри панели держат её поля. */
.panel-head + .card-grid { padding-top: var(--space-2); }
.panel > .metric-grid, .panel > .workspace-metrics {
    padding: var(--space-2) var(--space-3) 0;
    margin-bottom: var(--space-2);
}
.panel > .funnel-note, .panel > p.form-hint, .panel > .check-ok + .form-hint {
    margin: 0;
    padding: 0 var(--space-3) var(--space-3);
}
.panel > form:not(.stack-form):not(.inline-form):not(.launch-form) {
    padding: 0 var(--space-3) var(--space-3);
}
.panel > .button { margin: 0 var(--space-3) var(--space-3); }

/* --- Обзор: три блока по трём вопросам ----------------------------------- */
.overview-block { margin-bottom: var(--space-4); }
.overview-block-title {
    margin: 0 0 var(--space-2);
    color: var(--steel-2);
    font-size: var(--fs-micro);
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.overview-block-line {
    margin: 0 0 var(--space-2);
    display: flex;
    flex-wrap: wrap;
    gap: 4px var(--space-2);
    color: var(--ink);
    font-size: var(--fs-sm);
}
.overview-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* --- Путь кампании: живые шаги ------------------------------------------ */
/* Каждый шаг кликабелен, показывает состояние и причину одной фразой.
   Заблокированный шаг отличается меткой, а не выцветшим текстом. */
.flow-steps { list-style: none; margin: 0; padding: 0; }
.flow-step { border-top: 1px solid var(--line-soft); }
.flow-step:first-child { border-top: 0; }
.flow-step-link {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) auto;
    gap: var(--space-2);
    align-items: center;
    min-height: 56px;
    padding: 12px var(--space-3);
    color: inherit;
    text-decoration: none;
}
.flow-step-link:hover { background: var(--paper); }
.flow-step-number {
    display: grid; place-items: center;
    width: 28px; height: 28px; border-radius: 50%;
    border: 1px solid var(--mist); color: var(--steel-2);
    font-size: var(--fs-meta); font-weight: 700;
}
.flow-step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.flow-step-body strong { font-size: var(--fs-sm); }
.flow-step-body small { color: var(--steel-2); font-size: var(--fs-meta); line-height: 18px; }
.flow-step-mark { color: var(--steel-2); font-size: var(--fs-micro); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.flow-step.is-done .flow-step-number { color: var(--white); border-color: var(--positive); background: var(--positive); }
.flow-step.is-done .flow-step-mark { color: var(--positive); }
.flow-step.is-current .flow-step-link { background: var(--paper); }
.flow-step.is-current .flow-step-number { color: var(--white); border-color: var(--ink); background: var(--ink); }
.flow-step.is-current .flow-step-mark { color: var(--ink); }
.flow-step.is-blocked .flow-step-mark { color: var(--warning); }
.flow-step.is-blocked .flow-step-number { border-color: var(--warning); color: var(--warning); }
@media (max-width: 640px) {
    .flow-step-link { grid-template-columns: 28px minmax(0, 1fr); }
    .flow-step-mark { grid-column: 2; }
}

/* --- Запуск ---------------------------------------------------------------- */
.launch-form { display: grid; gap: var(--space-2); padding: 0 var(--space-3) var(--space-3); }
.launch-form > .field { max-width: 280px; }
.launch-form > .workspace-kv.is-narrow { padding: 0; }
.launch-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.launch-reason { margin: 0; max-width: 74ch; color: var(--steel-2); font-size: var(--fs-meta); }

/* --- Уведомление с действиями -------------------------------------------- */
.workspace-notice .notice-actions {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}
.workspace-notice .notice-actions form { margin: 0; }

/* --- Список фактов: карточка карантина, письмо, пакет -------------------- */
/* Имя стояло в разметке без описания, и список рисовался браузером по
   умолчанию — подпись над значением, с полями словаря. */
.fact-list { margin: 0; padding: 0 var(--space-3) var(--space-2); display: grid; }
.fact-list > div {
    display: grid;
    grid-template-columns: minmax(0, 38%) minmax(0, 62%);
    gap: 2px var(--space-2);
    padding: 8px 0;
    border-top: 1px solid var(--line-soft);
}
.fact-list > div:first-child { border-top: 0; }
.fact-list dt { color: var(--steel-2); font-size: var(--fs-meta); }
.fact-list dd { margin: 0; font-size: var(--fs-sm); font-weight: 600; overflow-wrap: anywhere; }
.fact-list.compact > div { padding: 6px 0; }
@media (max-width: 479.98px) {
    .fact-list > div { grid-template-columns: minmax(0, 1fr); }
}

/* --- Предпросмотр письма: как его увидит адресат ------------------------ */
.letter-for {
    display: flex; flex-direction: column; gap: 2px;
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid var(--line-soft);
}
.letter-for strong { font-size: var(--fs-lead); }
.letter-for span { color: var(--steel-2); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.letter-modes { display: flex; gap: 4px; padding: var(--space-2) var(--space-3) 0; }
.letter-mode {
    min-height: var(--btn-h-sm);
    padding: 6px 12px;
    border: 1px solid var(--mist);
    border-radius: var(--radius-small);
    background: var(--white);
    color: var(--steel-2);
    font-size: var(--fs-meta);
    font-weight: 700;
    cursor: pointer;
}
.letter-mode:hover { color: var(--ink); border-color: var(--steel-3); }
.letter-mode.is-active { color: var(--white); border-color: var(--ink); background: var(--ink); }

/* Пресет периода, который сейчас стоит в полях. Кнопка не «выбрана навсегда»:
   стоит человеку поправить дату руками, признак снимается, и рядом появляется
   «Произвольный период». */
.u-choice .btn[aria-pressed="true"] { color: var(--white); border-color: var(--ink); background: var(--ink); }
.letter-frame { padding: var(--space-2) var(--space-3) var(--space-3); }
.letter-frame iframe {
    display: block;
    width: 100%;
    height: 640px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-small);
    background: #fff;
}
.letter-modes + .letter-body, .letter-frame + .letter-body { border-top: 0; margin: 0 var(--space-3) var(--space-3); border: 1px solid var(--line-soft); border-radius: var(--radius-small); }
.variant-nav {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: var(--space-2);
    margin-bottom: var(--space-3);
}
.variant-nav .step-back, .variant-nav .step-next { display: inline-flex; align-items: center; gap: 6px; }
.variant-position { font-size: var(--fs-sm); }

/* --- Отбор аудитории: период и предпросмотр допуска ---------------------- */
.date-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.admission-rest { margin: 0; padding: 0 var(--space-3); color: var(--steel-2); font-size: var(--fs-meta); }
.builder-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); padding: var(--space-2) var(--space-3) var(--space-3); }

/* --- Действия с объектом: удалить или архивировать ------------------------ */
.object-actions { display: flex; flex-direction: column; gap: var(--space-1); padding: 0 var(--space-3) var(--space-3); }
.object-actions > .form-hint { margin: 0; max-width: 74ch; }
.object-actions form { margin: 0; }
.object-actions .button-row { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* --- Служебное свёрнуто --------------------------------------------------- */
.service-details > summary {
    min-height: 44px;
    display: flex; align-items: center;
    padding: var(--space-2) var(--space-3);
    color: var(--steel-2);
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
}
.service-details > summary:hover { color: var(--ink); }
.service-details[open] > summary { border-bottom: 1px solid var(--line-soft); }
/* MAILING-GOLIVE-105:END */

/* === MAILING-GOLIVE-106: сведение backend №10 и UI №3 ========================= */
/* Заголовок столбца не рвётся посреди слова: «Израсходов/ано» — дефект. */
.workspace-table th { overflow-wrap: normal; word-break: normal; hyphens: manual; }
.workspace-table col.w-count { width: 112px; }
/* Управление идущими рассылками над очередью. */
.controls-panel { display: grid; gap: 10px; padding: 14px 18px; }
.control-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.control-body { display: grid; gap: 2px; min-width: 0; }
.control-body small { color: var(--steel-2); }
.control-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.control-actions form { margin: 0; }
/* Отправители карточками. */
.sender-card .service-facts dd { text-align: right; overflow-wrap: anywhere; }
.sender-toggle { margin-top: 12px; }
/* Запуск: причина недоступной кнопки — фразой, а не кодом. */
.launch-reason { margin: 8px 0 0; color: var(--warning); font-size: 14px; }
.launch-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* Пять шагов пути кампании: ссылка на свой блок, отметка состояния. */
.flow-step-link { display: grid; grid-template-columns: 28px 1fr auto; gap: 10px; align-items: center; color: inherit; text-decoration: none; }
.flow-step-mark { font-size: 12px; color: var(--steel-2); white-space: nowrap; }
.button-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.button-row form { margin: 0; }
.field-check small { display: block; color: var(--steel-2); font-weight: 400; }

/* === MAILING-GOLIVE-106b: закон владельца — ничего не обрезается ============ */
/* Значение в строке списка показывается целиком: длинное название переносится
   на столько строк, сколько нужно; двухстрочного среза и «…» нет. */
.app-shell .workspace-table td .workspace-cell-main,
.app-shell .workspace-table td .workspace-primary-link,
.app-shell .client-table td .table-primary-link,
.app-shell .workspace-table td small,
.app-shell .workspace-table td.amount-cell small {
    display: block; -webkit-line-clamp: unset; -webkit-box-orient: initial;
    overflow: visible; max-height: none; max-width: none;
    white-space: normal; text-overflow: clip;
}
/* Подпись карточки показателя — вся, а не одна-две строки. */
.app-shell .metric-card > small, .app-shell .metric-card > span,
.app-shell .metric-grid.is-dense .metric-card > small,
.app-shell .metric-grid.is-dense .metric-card > span {
    display: block; -webkit-line-clamp: unset; overflow: visible; max-height: none;
}
/* Бейдж — слово или короткая фраза; посреди слова не рвётся. */
.app-shell .badge, .app-shell .workspace-badge { white-space: nowrap; overflow-wrap: normal; word-break: normal; }
/* Заголовок столбца не переносится посреди слова, числовой тоже. */
.app-shell .workspace-table th, .app-shell .workspace-table th.num,
.app-shell .workspace-table th :where(strong, span, small, a, code, b, em) {
    overflow-wrap: normal !important; word-break: keep-all !important; hyphens: manual;
}
.workspace-table col.w-count { width: 128px; }
.workspace-table col.w-date { width: 140px; }
/* Пределы: три числовых столбца одной ширины, подпись под числом целиком. */
.workspace-table col.w-limit { width: 150px; }
/* Единый карантин: восемь столбцов долями — при 1366 все на месте. */
.workspace-table col.w-q-subject { width: 20%; }
.workspace-table col.w-q-contact { width: 14%; }
.workspace-table col.w-q-status { width: 10%; }
.workspace-table col.w-q-reason { width: 18%; }
.workspace-table col.w-q-service { width: 10%; }
.workspace-table col.w-q-source { width: 9%; }
.workspace-table col.w-q-date { width: 9%; }
.workspace-table col.w-q-action { width: 10%; }
/* Кнопка на всю ширину панели не выходит за её край. */
.app-shell .panel > .button.full { display: block; box-sizing: border-box; width: auto; margin: 0 var(--space-3) var(--space-3); }
/* Таблица вариантов на карточке кампании: выбор шаблона занимает свою строку. */
.variants-table col.w-variant { width: 26%; }
.variants-table col.w-template { width: auto; }
.variants-table col.w-check { width: 170px; }
.variants-table col.w-actions { width: 96px; }
.variants-table .inline-form { display: grid; gap: 6px; }
.variants-table .inline-form select { width: 100%; max-width: none; }

/* === MAILING-GOLIVE-106c: узкие столбцы без переносов посреди слова ========= */
/* Бейдж переносится только по пробелу: «Нужна / проверка» допустимо,
   «Заблокирован / о» — нет. */
.app-shell .badge, .app-shell .workspace-badge { white-space: normal; overflow-wrap: normal; word-break: keep-all; }
/* Единый карантин: доли столбцов под 1366 и перенос только по словам. */
.workspace-table col.w-q-subject { width: 18%; }
.workspace-table col.w-q-contact { width: 13%; }
.workspace-table col.w-q-status { width: 12%; }
.workspace-table col.w-q-reason { width: 17%; }
.workspace-table col.w-q-service { width: 9%; }
.workspace-table col.w-q-source { width: 10%; }
.workspace-table col.w-q-date { width: 10%; }
.workspace-table col.w-q-action { width: 11%; }
.app-shell .workspace-table td.w-q-status, .app-shell .workspace-table td.w-q-service,
.app-shell .workspace-table td.w-q-source, .app-shell .workspace-table td.w-q-date,
.app-shell .workspace-table td.w-q-action,
.app-shell .workspace-table td.w-q-status :where(strong, span, small, a, b),
.app-shell .workspace-table td.w-q-service :where(strong, span, small, a, b),
.app-shell .workspace-table td.w-q-source :where(strong, span, small, a, b),
.app-shell .workspace-table td.w-q-date :where(strong, span, small, a, b),
.app-shell .workspace-table td.w-q-action :where(strong, span, small, a, b) {
    overflow-wrap: normal; word-break: keep-all; hyphens: manual;
}
.app-shell .workspace-table td.w-q-date .workspace-cell-main { white-space: nowrap; }
/* Таблица вариантов на карточке кампании: пять столбцов в узкой колонке. */
.variants-table col.w-variant { width: 24%; }
.variants-table col.w-count { width: 84px; }
.variants-table col.w-check { width: 132px; }
.variants-table col.w-actions { width: 84px; }
.variants-table td { overflow-wrap: normal; word-break: keep-all; }
.variants-table .inline-form select, .variants-table .form-control.compact { width: 100%; min-width: 0; max-width: none; }
/* Кнопка во всю ширину панели переносит длинную подпись, а не режет её. */
.app-shell .button.full { white-space: normal; height: auto; min-height: var(--btn-h, 40px); line-height: 1.25; padding-top: 8px; padding-bottom: 8px; }

/* --- W4. Карточка маршрута обращения ------------------------------------ */
.route-tally { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.route-tally-item { font-size: 13px; color: var(--text-muted); white-space: nowrap; }
.route-tally-item.allowed strong { color: var(--ok, #2f7a4d); }
.route-tally-item.review strong { color: var(--warning, #a2701a); }
.route-tally-item.blocked strong { color: var(--danger, #a33); }

.route-cards { display: grid; gap: var(--space-3); padding: var(--space-3); }
.route-card {
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-2, 8px);
    padding: var(--space-3);
    background: var(--surface, #fff);
}
.route-card-head { display: flex; flex-direction: column; gap: 4px; }
.route-card-title { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.route-email { font-size: 16px; word-break: break-all; }
.route-reason { margin: 0; color: var(--text-muted); font-size: 13px; }

.route-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-2) var(--space-3);
    margin: var(--space-3) 0 0;
}
.route-facts > div { min-width: 0; }
.route-facts dt { font-size: 12px; color: var(--text-muted); margin: 0; }
.route-facts dd { margin: 2px 0 0; font-size: 14px; word-break: break-word; }
.route-fact-wide { grid-column: 1 / -1; }

.route-hard { margin-top: var(--space-3); }
.route-hard ul { margin: var(--space-2) 0 0; padding-left: 1.1rem; }
.route-hard li { margin-bottom: 4px; }

.route-editor, .route-evidence, .route-history { margin-top: var(--space-3); }
.route-editor > summary, .route-evidence > summary, .route-history > summary {
    cursor: pointer; font-size: 13px; color: var(--text-muted);
}
.route-form { margin-top: var(--space-3); }
.route-form .field-wide { grid-column: 1 / -1; }
.route-form-foot {
    display: flex; align-items: center; justify-content: flex-end;
    gap: var(--space-3); margin-top: var(--space-3); flex-wrap: wrap;
}
.route-form-foot small { color: var(--text-muted); }

@media (max-width: 900px) {
    .route-facts { grid-template-columns: 1fr; }
}


/* Контакты, найденные человеком: форма стоит в шапке блока «Контакты» и
   читается как одно действие, а не как анкета. */
.manual-contact-form {
    margin: 0 0 var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    background: rgba(255, 255, 255, .6);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.manual-contact-fields {
    display: grid;
    grid-template-columns: minmax(120px, .6fr) minmax(200px, 1.4fr) minmax(180px, 1fr) auto;
    gap: 10px;
    align-items: center;
}
.manual-contact-fields .form-control { width: 100%; min-width: 0; }
/* U6, замечание 35: у поля видимая подпись над ним. Подсказка внутри поля
   пропадает при вводе, и человек перестаёт видеть, что он заполняет. */
.manual-contact-fields { align-items: end; }
.manual-contact-field { display: grid; gap: 4px; min-width: 0; }
.manual-contact-label { color: var(--steel-2); font-size: 12px; line-height: 16px; }
.subject-visibility .manual-contact-field { min-width: 240px; }
.manual-contact-hint { color: var(--steel-2); font-size: 12px; line-height: 18px; }

/* Решение о видимости записи: причина обязательна, поэтому поле стоит рядом
   с кнопкой, а не прячется за вторым экраном. */
.subject-visibility {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--line-soft);
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}
.subject-visibility .form-control { flex: 1; min-width: 220px; }

@media (max-width: 720px) {
    .manual-contact-fields { grid-template-columns: 1fr; }
    .manual-contact-fields .button, .subject-visibility .button { width: 100%; }
}

/* ==== rel10 slot K6: лид из ответа на рассылку — ниже этой строки ====
   Шаг 8 px (UI_GUIDELINES «Сетка и размеры»), только цвета палитры и
   существующие метки; фокус — общий :focus-visible. */
.lead-reply + .lead-reply { border-top: 1px solid var(--line-soft); }
.lead-reply.is-open { box-shadow: inset 4px 0 0 var(--warning); }
.lead-reply-body { padding: 0 24px 8px; }
.lead-reply-text { max-height: none; overflow: visible; font-size: 14px; line-height: 1.6; color: var(--ink); }
.lead-reply-text.is-collapsed { max-height: 160px; overflow: hidden; -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent); }
.lead-expand { margin-top: 8px; min-height: 44px; padding-inline: 8px; color: var(--steel-1); font-weight: 600; }
.lead-muted { color: var(--steel-2); font-weight: 400; }
.lead-num { font-variant-numeric: tabular-nums; }
.lead-links { padding: 0 24px 16px; }
.lead-triage { display: grid; gap: 16px; padding: 16px 24px 24px; border-top: 1px solid var(--line-soft); }
.lead-triage .workspace-hint { margin: 0; }
.lead-decisions { flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.lead-stage-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px; }
.lead-stage-form .review-field { min-width: 240px; }
.lead-situations { padding: 0 24px 24px; }
.lead-situations .lead-col-date { width: 136px; }
.lead-situations .lead-col-amount { width: 152px; }
.lead-menu-item {
    width: 100%; min-height: 44px; padding: 8px; border: 0; border-radius: 8px;
    background: transparent; color: var(--ink); font: inherit; font-size: 14px; font-weight: 600;
    text-align: left; cursor: pointer;
}
.lead-menu-item:hover { background: var(--paper); }
/* Кнопки разбора ответа (фрагмент _reply_decisions.html) на страницах без UX V2. */
.reply-decisions { display: flex; flex-wrap: wrap; gap: 8px; }
.button.secondary.reply-decision-danger { color: var(--negative); border-color: var(--negative); }
.button.secondary.reply-decision-danger:hover { background: var(--negative-soft); }
.ux2 .reply-decisions { display: flex; flex-wrap: wrap; gap: 8px; }
/* K12: под кнопками разбора — видимая причина недоступной «Это лид» и раскрытие
   «Что делает каждое решение» (щелчок и клавиатура, не только наведение). Шаг 8 px. */
.reply-decide { display: grid; gap: 8px; justify-items: start; }
.reply-decide-reason { margin: 0; font-size: 13px; color: var(--steel-2); }
.reply-hints { font-size: 13px; color: var(--steel-2); }
.reply-hints > summary { min-height: 32px; display: inline-flex; align-items: center; cursor: pointer; font-weight: 600; color: var(--steel-1); }
.reply-hints > summary:focus-visible { outline: 2px solid var(--steel-1); outline-offset: 2px; border-radius: 4px; }
.reply-hints dl { display: grid; gap: 8px; margin: 8px 0 0; }
.reply-hints dl > div { display: grid; grid-template-columns: minmax(96px, max-content) minmax(0, 1fr); gap: 8px 16px; }
.reply-hints dt { font-weight: 600; color: var(--ink); }
.reply-hints dd { margin: 0; }
.ux2 .reply-decide-reason, .ux2 .reply-hints { color: var(--u-muted); }
.ux2 .reply-hints > summary { color: var(--u-ink); }
.ux2 .reply-hints dt { color: var(--u-ink); }
/* K12: подсказки решений лида — тем же раскрытием под кнопками. */
.lead-hints { font-size: 13px; color: var(--steel-2); }
.lead-hints > summary { min-height: 44px; display: inline-flex; align-items: center; cursor: pointer; font-weight: 600; color: var(--steel-1); }
.lead-hints > summary:focus-visible { outline: 2px solid var(--steel-1); outline-offset: 2px; border-radius: 4px; }
.lead-hints dl { display: grid; gap: 8px; margin: 0; }
.lead-hints dl > div { display: grid; grid-template-columns: minmax(120px, max-content) minmax(0, 1fr); gap: 8px 16px; }
.lead-hints dt { font-weight: 600; color: var(--ink); }
.lead-hints dd { margin: 0; }

/* ==== rel10 slot K20: карточка лида (проверка V5, п. 33) ==== */
/* Шапка: общий .workspace-hero держит min-height 190 px и прижимает содержимое
   к низу — над чипом стадии оставалось ~60 px пустоты. У лида шапка по
   содержимому, выравнивание по верху, отступы — сетка 8. */
.workspace-hero.lead-hero { min-height: 0; padding: 24px; align-items: flex-start; gap: 32px; }
.workspace-hero.lead-hero h2 { margin: 8px 0 4px; }
.workspace-hero.lead-hero dl { gap: 16px 24px; }
/* Стадии: кегль 11 px и перенос в две строки. Кегль 13, одна строка там, где
   место есть; ряд переносится целыми кнопками, а не буквами. */
.lead-stage-panel .lead-pipeline { grid-template-columns: repeat(auto-fit, minmax(136px, 1fr)); overflow-x: visible; gap: 8px; }
.lead-stage-panel .lead-pipeline span { min-height: 44px; padding: 8px 12px; font-size: 13px; line-height: 1.3; font-weight: 600; }
/* «Ждёт решения» называет чип в шапке ответа; полоса слева была вторым признаком
   того же. Остаётся один — чип. */
.lead-reply.is-open { box-shadow: none; }
/* Основание лида: подписи и значения — той же сеткой, что «Наше письмо». */
.lead-basis .workspace-kv { margin-top: 8px; }
.lead-basis > p { margin: 4px 0 0; }
/* Подсказка отбора «Обращения» в «Субъектах» (K20, п. 19). */
.workspace-filter-hint { margin: 8px 0 0; max-width: 88ch; font-size: 13px; line-height: 1.45; color: var(--steel-2); }

/* Выбор лица поиском (поле субъекта в формах лида, задачи, дела, документа).
   Обёртка — span внутри label поля: подписью её не оформляем. */
.form-field > .subject-lookup, .u-form-field > .subject-lookup, .subject-lookup {
    position: relative; display: grid; gap: 6px; min-width: 0;
    font-size: inherit; font-weight: 400; color: inherit;
}
.subject-lookup select[multiple] { min-height: 88px; }
.subject-lookup-results {
    position: absolute; z-index: 20; top: calc(var(--field-h, 40px) + 2px); left: 0; right: 0;
    display: grid; max-height: 320px; overflow-y: auto; padding: 4px;
    background: var(--surface, #fff); border: 1px solid var(--steel-3); border-radius: var(--radius-small, 8px);
    box-shadow: var(--shadow-float);
}
.subject-lookup-results[hidden] { display: none; }
.subject-lookup-option {
    display: grid; gap: 2px; width: 100%; min-height: 44px; padding: 8px 12px; text-align: left;
    background: none; border: 0; border-radius: 6px; font: inherit; color: var(--ink); cursor: pointer;
}
.subject-lookup-option small { color: var(--steel-2); font-size: 12px; }
.subject-lookup-option:hover, .subject-lookup-option:focus-visible { background: var(--paper); outline-offset: -2px; }
.subject-lookup-note { padding: 8px 12px; font-size: 13px; color: var(--steel-2); }
.subject-lookup-create { justify-self: start; font-size: 13px; font-weight: 600; }
