:root {
  --sidebar-w: 250px;
  --brand: #2563eb;
  --brand-dark: #1d4ed8;
  --bg: #f5f7fb;
  --card-radius: 14px;
  --shadow: 0 1px 3px rgba(16, 24, 40, .06), 0 1px 2px rgba(16, 24, 40, .04);
  --shadow-lg: 0 8px 24px rgba(16, 24, 40, .10);
  /* Фирменный акцент страницы входа: золото логотипа CRM95. */
  --accent: #c9a227;
}
/* СТРАНИЦА ВБОК НЕ ЕЗДИТ.

   Правила не было вовсе: я думал, что оно есть, но находил поиском
   чужое — от боковой панели. Строка представлений с прокруткой утащила
   за собой весь экран (18.08.2026).

   Прокрутка вбок разрешена только там, где задана нарочно: таблицы,
   полосы кнопок. Страница целиком стоит на месте. */
html, body { max-width: 100%; overflow-x: hidden; }

body { background: var(--bg); font-family: "Inter", "Segoe UI", system-ui, sans-serif; }

/* Sidebar */
.sidebar {
  position: fixed; inset: 0 auto 0 0; width: var(--sidebar-w);
  background: #0f172a; color: #cbd5e1; padding: 1rem .75rem;
  display: flex; flex-direction: column; z-index: 1030; overflow-y: auto;
  /* Вбок панель не ездит: прокрутка только вверх-вниз. Прежде правила
     не было — длинный пункт растягивал её, и меню качалось под пальцем
     (замечание владельца). */
  overflow-x: hidden;
}
.sidebar .brand {
  color: #fff; font-weight: 700; font-size: 1.1rem; text-decoration: none;
  display: flex; align-items: center; gap: .6rem; padding: .5rem .75rem 1rem;
}
.sidebar .brand i { color: #60a5fa; font-size: 1.4rem; }
.sidebar .nav-link {
  color: #94a3b8; border-radius: 10px; padding: .6rem .85rem; margin-bottom: .15rem;
  display: flex; align-items: center; gap: .7rem; font-size: .93rem;
  transition: background .15s, color .15s;
}
.sidebar .nav-link i { font-size: 1.05rem; width: 20px; text-align: center;
  flex-shrink: 0; }
/* «График платежей» — самое длинное название: при узкой панели оно
   переносится, а не растягивает её. */
.sidebar .nav-link { min-width: 0; }
.sidebar .nav-link:hover { background: rgba(255,255,255,.06); color: #e2e8f0; }
.sidebar .nav-link.active { background: var(--brand); color: #fff; }
.sidebar .nav-link .badge { margin-left: auto; }

/* Layout */
.main { margin-left: var(--sidebar-w); min-height: 100vh; display: flex; flex-direction: column; }
.topbar {
  background: #fff; border-bottom: 1px solid #e5e9f2; padding: .7rem 1.5rem;
  display: flex; align-items: center; gap: 1rem; position: sticky; top: 0; z-index: 1020;
}
.topbar .search-box { max-width: 440px; flex: 1; }
.topbar .search-box .form-control { border-radius: 10px; background: #f1f4f9; border-color: transparent; }
.topbar .search-box .form-control:focus { background: #fff; border-color: var(--brand); box-shadow: 0 0 0 .2rem rgba(37,99,235,.12); }
.content { padding: 1.5rem; flex: 1; }

/* Cards */
.card { border: none; border-radius: var(--card-radius); box-shadow: var(--shadow); }
.card:hover.card-hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); transition: all .18s; }
.kpi-card { display: flex; align-items: center; gap: 1rem; padding: 1.15rem 1.25rem; }
.kpi-icon {
  width: 52px; height: 52px; border-radius: 13px; display: flex;
  align-items: center; justify-content: center; font-size: 1.4rem; flex-shrink: 0;
}
.kpi-value { font-size: 1.55rem; font-weight: 700; line-height: 1.15; }
.kpi-label { font-size: .82rem; color: #64748b; }
.bg-soft-primary { background: #e0eaff; color: var(--brand); }
.bg-soft-success { background: #dcfce7; color: #16a34a; }
.bg-soft-danger  { background: #fee2e2; color: #dc2626; }
.bg-soft-warning { background: #fef3c7; color: #d97706; }
.bg-soft-info    { background: #cffafe; color: #0891b2; }

/* Tables */
.table-card .table { margin: 0; }
.table thead th {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .04em;
  color: #64748b; border-bottom: 1px solid #e5e9f2; background: #f8fafc; padding: .7rem 1rem;
}
.table tbody td { padding: .75rem 1rem; vertical-align: middle; font-size: .92rem; }
.table tbody tr { transition: background .12s; }
.table tbody tr:hover { background: #f6f9ff; }
.row-overdue { background: #fff1f1 !important; }
.row-overdue:hover { background: #ffe4e4 !important; }

/* Badges & buttons */
.badge-status { border-radius: 999px; padding: .38em .8em; font-size: .78rem; font-weight: 600; }
.btn { border-radius: 10px; }
.btn-lg { border-radius: 12px; }
.btn-icon { display: inline-flex; align-items: center; gap: .45rem; }
.btn-light-action {
  background: #fff; border: 1px solid #e5e9f2; color: #475569;
  /* 38px вместо 34: рядом с этими кнопками стоит удаление, и промах
     обходится дороже сэкономленного места. На телефоне ниже — 44px. */
  width: 38px; height: 38px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; padding: 0;
}
.btn-light-action:hover { border-color: var(--brand); color: var(--brand); }
.btn-light-action.danger:hover { border-color: #dc2626; color: #dc2626; }

/* Page header */
.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; flex-wrap: wrap; gap: .75rem; }
.page-header h1 { font-size: 1.35rem; font-weight: 700; margin: 0; }
.page-header .subtitle { color: #64748b; font-size: .88rem; }

/* Detail tabs */
.nav-pills-card .nav-link { border-radius: 10px; color: #475569; font-size: .92rem; }
.nav-pills-card .nav-link.active { background: var(--brand); }

/* Toasts */
.toast-container { z-index: 2000; }
.toast { border-radius: 12px; box-shadow: var(--shadow-lg); }

/* Forms */
.form-control, .form-select { border-radius: 10px; }
.form-control:focus, .form-select:focus { border-color: var(--brand); box-shadow: 0 0 0 .2rem rgba(37,99,235,.12); }
.form-label { font-size: .85rem; font-weight: 600; color: #475569; }

/* Login */
/* ── Вход ──────────────────────────────────────────────────────────
   Две части: тёмная панель с рассказом о системе и карточка входа.
   На телефоне панель убирается — там важна форма, а не рассказ. */
.login-page { min-height: 100vh; display: flex; }
.login-side {
  width: 40%; background: #0f172a; color: #cbd5e1;
  padding: 3rem 2.5rem; display: flex; flex-direction: column;
  position: relative; overflow: hidden;
}
/* Едва заметный узор: фон не должен спорить с текстом. */
.login-side::before {
  content: ""; position: absolute; inset: 0; opacity: .06;
  background-image:
    radial-gradient(circle at 20% 15%, #fff 1px, transparent 1px),
    radial-gradient(circle at 70% 40%, #fff 1px, transparent 1px);
  background-size: 60px 60px;
}
.login-side > * { position: relative; }
.login-logo { display: flex; align-items: center; gap: .9rem; margin-bottom: 2.5rem; }
.login-logo-mark {
  width: 56px; height: 56px; border: 2px solid var(--accent);
  border-radius: 14px; display: flex; align-items: center;
  justify-content: center; color: var(--accent); font-size: 1.6rem;
}
.login-logo-name { font-size: 1.9rem; font-weight: 700; color: #fff; line-height: 1; }
.login-logo-name span { color: var(--accent); }
.login-logo-sub { font-size: .78rem; color: var(--accent); letter-spacing: .08em; margin-top: .25rem; }
.login-side h1 { color: #fff; font-size: 1.75rem; line-height: 1.3; margin: 0 0 1rem; font-weight: 700; }
.login-lead { color: #94a3b8; font-size: .95rem; line-height: 1.6; margin: 0 0 1.5rem; }
.login-rule { width: 56px; height: 3px; background: var(--accent); border-radius: 2px; margin-bottom: 1.75rem; }
.login-feature { display: flex; gap: .9rem; margin-bottom: 1.15rem; }
.login-feature i { color: var(--accent); font-size: 1.15rem; margin-top: .15rem; }
.login-feature b { color: #fff; font-weight: 600; font-size: .95rem; display: block; }
.login-feature small { color: #94a3b8; font-size: .83rem; line-height: 1.45; display: block; margin-top: .15rem; }

.login-main { width: 60%; display: flex; flex-direction: column; padding: 1.5rem; }
.login-center { flex: 1; display: flex; align-items: center; justify-content: center; }
.login-card { width: 100%; max-width: 480px; border-radius: var(--card-radius); padding: 2.5rem; }
.login-foot {
  display: flex; justify-content: center; gap: 1.5rem; flex-wrap: wrap;
  color: #64748b; font-size: .82rem; padding: 1rem 0;
}
.login-foot a { color: #64748b; text-decoration: none; }

/* Поле с значком слева и кнопкой показа пароля справа. */
.login-field { position: relative; margin-bottom: 1.1rem; }
.login-field .field-icon {
  position: absolute; left: .9rem; top: 50%; transform: translateY(-50%);
  color: #64748b; font-size: 1rem; pointer-events: none;
}
.login-field .form-control { height: 48px; padding-left: 2.75rem; padding-right: 2.75rem; }
.login-field .peek {
  position: absolute; right: .9rem; top: 50%; transform: translateY(-50%);
  color: #64748b; background: none; border: 0; cursor: pointer; font-size: 1rem;
}

@media (max-width: 991.98px) {
  .login-side { display: none; }
  .login-main { width: 100%; }
  .login-card { box-shadow: none; padding: 1.5rem; }
  .login-center { align-items: flex-start; padding-top: 1rem; }
}

/* Info list */
.info-row { display: flex; padding: .5rem 0; border-bottom: 1px dashed #eef1f6; font-size: .93rem; }
.info-row:last-child { border-bottom: none; }
.info-row .label { width: 190px; color: #64748b; flex-shrink: 0; }

@media (max-width: 991.98px) {
  .sidebar { transform: translateX(-100%); transition: transform .2s; }
  .sidebar.open { transform: none; }
  .main { margin-left: 0; }
}
@media print { .sidebar, .topbar, .no-print { display: none !important; } .main { margin: 0; } }

/* ═══════════════════════════════════════════════════════════════════════
   Форма создания договора
   Полоса шагов сверху + постоянная сводка справа. Это не мастер: все
   разделы видны сразу, полоса лишь показывает прогресс и служит навигацией —
   менеджер оформляет десятки договоров в день, и лишние переходы замедляют.
   ═══════════════════════════════════════════════════════════════════════ */
.steprail{
  position:sticky;top:57px;z-index:1019;background:#fff;border-bottom:1px solid var(--line,#e5e9f2);
  padding:.7rem 1.5rem;margin:-1.5rem -1.5rem 1.25rem;display:flex;align-items:center;
  gap:.25rem;overflow-x:auto;
}
.step{display:flex;align-items:center;gap:.55rem;padding:.4rem .8rem;border-radius:10px;
  color:#64748b;font-size:.88rem;white-space:nowrap;border:none;background:none;
  transition:background .15s,color .15s;}
.step:hover{background:#f1f5f9;color:#334155;}
.step-num{width:24px;height:24px;border-radius:50%;background:#e2e8f0;color:#64748b;
  display:grid;place-items:center;font-size:.78rem;font-weight:700;flex-shrink:0;
  transition:background .18s,color .18s;}
.step.active{color:var(--brand);font-weight:600;}
.step.active .step-num{background:var(--brand);color:#fff;}
.step.done{color:#166534;}
.step.done .step-num{background:#16a34a;color:#fff;}
.step-sep{width:20px;height:1px;background:#e5e9f2;flex-shrink:0;}

.builder{display:grid;grid-template-columns:minmax(0,1fr) 352px;gap:1.25rem;align-items:start;}
.summary-col{position:sticky;top:126px;}

.section{margin-bottom:1.1rem;scroll-margin-top:126px;}
.section-head{display:flex;align-items:center;gap:.6rem;margin-bottom:.6rem;}
.section-head .n{width:26px;height:26px;border-radius:8px;background:#e0eaff;color:var(--brand);
  display:grid;place-items:center;font-size:.8rem;font-weight:700;flex-shrink:0;}
.section-head h2{font-size:1rem;font-weight:700;margin:0;}
.section-head .hint{font-size:.82rem;color:#64748b;margin-left:auto;}

.client-card{display:flex;gap:1rem;align-items:flex-start;padding:1rem 1.15rem;
  border:1px solid #e5e9f2;border-radius:12px;background:#fbfcfe;}
.client-avatar{width:46px;height:46px;border-radius:12px;background:#e0eaff;color:var(--brand);
  display:grid;place-items:center;font-weight:700;font-size:1.05rem;flex-shrink:0;}
.client-facts{display:flex;flex-wrap:wrap;gap:.35rem .9rem;font-size:.85rem;color:#64748b;}
.client-facts b{color:#0f172a;font-weight:600;}

.goods{width:100%;border-collapse:separate;border-spacing:0;}
.goods thead th{font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;color:#64748b;
  background:#f8fafc;padding:.55rem .6rem;border-bottom:1px solid #e5e9f2;font-weight:600;}
.goods tbody td{padding:.35rem .4rem;border-bottom:1px solid #f1f5f9;vertical-align:middle;}
.goods .form-control{border-radius:8px;font-size:.9rem;padding:.4rem .55rem;}
.goods input[type=number]{text-align:right;font-variant-numeric:tabular-nums;}
.goods .cell-total{text-align:right;font-weight:600;font-variant-numeric:tabular-nums;
  font-size:.92rem;padding-right:.7rem;white-space:nowrap;}
.goods tfoot td{padding:.7rem .6rem;font-weight:600;border-top:2px solid #e5e9f2;}

.sum-head{padding:1rem 1.15rem .8rem;border-bottom:1px solid #e5e9f2;}
.sum-body{padding:.85rem 1.15rem;}
.sum-row{display:flex;justify-content:space-between;gap:1rem;padding:.32rem 0;font-size:.89rem;}
.sum-row .k{color:#64748b;}
.sum-row .v{font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap;}
.sum-row.big{padding:.6rem 0;}
.sum-row.big .v{font-size:1.28rem;font-weight:700;color:var(--brand);}
.sum-div{height:1px;background:#e5e9f2;margin:.55rem 0;}
.sum-profit{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:10px;
  padding:.6rem .8rem;margin-top:.6rem;}
.sum-profit .v{color:#16a34a;}
/* Убыток не прячем: менеджер должен видеть, что продаёт ниже закупки */
.sum-profit.loss{background:#fef2f2;border-color:#fecaca;}
.sum-profit.loss .v{color:#dc2626;}

.sched{max-height:260px;overflow-y:auto;}
.sched table{width:100%;font-size:.87rem;}
.sched th{position:sticky;top:0;background:#f8fafc;color:#64748b;font-size:.72rem;
  text-transform:uppercase;letter-spacing:.04em;padding:.5rem .8rem;font-weight:600;}
.sched td{padding:.42rem .8rem;border-bottom:1px solid #f1f5f9;font-variant-numeric:tabular-nums;}
.sched td:last-child{text-align:right;font-weight:600;}

.actionbar{position:sticky;bottom:0;background:#fff;border-top:1px solid #e5e9f2;
  padding:.75rem 1.5rem;margin:1rem -1.5rem -1.5rem;display:flex;gap:.6rem;
  align-items:center;flex-wrap:wrap;z-index:1015;box-shadow:0 -2px 12px rgba(16,24,40,.05);}
.empty{padding:1.5rem;text-align:center;color:#64748b;font-size:.9rem;
  border:1px dashed #e5e9f2;border-radius:12px;}

@media (max-width:1279.98px){
  .builder{grid-template-columns:1fr;}
  .summary-col{position:static;}
}
@media (max-width:991.98px){
  .steprail{top:0;padding:.6rem .75rem;margin:-1.5rem -1.5rem 1rem;gap:.15rem;}
  .step{padding:.35rem .5rem;font-size:.8rem;}
  .step-sep{width:10px;}
  .summary-col,.section{scroll-margin-top:70px;}
}
/* Телефон: таблица товаров превращается в карточки —
   семь колонок с полями ввода на узком экране нечитаемы */
@media (max-width:767.98px){
  .goods thead{display:none;}
  .goods,.goods tbody,.goods tfoot,.goods tr,.goods td{display:block;width:100%;}
  /* Без боковых отступов: с ними карточка товара уже соседних блоков и
     выглядит смещённой внутрь. */
  .goods tbody tr{border:1px solid #e5e9f2;border-radius:12px;padding:.6rem .7rem;
    margin:0 0 .6rem;position:relative;background:#fff;}
  .goods tbody td{border:none;padding:.25rem 0;display:flex;align-items:center;
    gap:.6rem;}
  /* Доля вместо пикселей — как в остальных карточках: иначе колонка
     значений начинается в разных разделах по-разному. */
  .goods tbody td::before{content:attr(data-label);flex:0 0 42%;max-width:42%;
    font-size:.8rem;color:#64748b;}
  /* Поле занимает остаток строки и сжимается. Без min-width:0 flex-элемент
     не становится уже своего содержимого, и ширина начинает зависеть от
     введённого значения. */
  .goods tbody td>*{flex:1 1 0;min-width:0;max-width:100%;}
  .goods tbody td .form-control{width:auto!important;max-width:100%;}
  .goods tbody td.cell-total{justify-content:space-between;text-align:left;
    padding-top:.5rem;margin-top:.35rem;border-top:1px dashed #e5e9f2;}
  /* Кнопка удаления — последней строкой карточки, прижата вправо.
     Прижатие к углу абсолютом накрывало поле «Наименование» и вылезало за
     рамку: положение зависело от высоты первой строки, а её не угадать. */
  .goods tbody td.td-del{
    justify-content:flex-end;padding-top:.5rem;margin-top:.3rem;
    border-top:1px dashed #e5e9f2;
  }
  .goods tbody td.td-del::before{content:none;}
  /* Кнопка не растягивается на всю строку: общее правило для содержимого
     ячейки задаёт flex:1, а здесь нужен размер по кнопке. */
  .goods tbody td.td-del>*{
    flex:0 0 auto;
    /* Иконка-ссылка сама по себе меньше пальца, а удаление — необратимо */
    min-width:44px;min-height:44px;
    display:inline-flex;align-items:center;justify-content:center;
  }
  .goods tfoot tr{padding:.7rem;border-top:2px solid #e5e9f2;}
  .goods tfoot td{display:flex;justify-content:space-between;padding:.25rem 0;border:none;}
  .goods tfoot td:empty{display:none;}
  .goods tfoot td[colspan]{justify-content:flex-start;margin-bottom:.4rem;}
  .mobile-total{display:flex !important;}
}
@media (min-width:768px){ .mobile-total{display:none !important;} }

/* Поле, распознанное неточно: значение подставлено, но его нужно сверить
   с документом. Не ошибка — предупреждение, поэтому жёлтый, а не красный. */
.ocr-uncertain{border-color:#f59e0b !important;background:#fffbeb;}
.ocr-uncertain:focus{box-shadow:0 0 0 .2rem rgba(245,158,11,.15) !important;}

/* ═══════════════════════════════════════════════════════════════════════
   Карточка показателя как точка входа в раздел.

   Внешний вид не меняется: размеры, цвета и отступы прежние. Добавлен
   только отклик на действие — курсор, лёгкий подъём (он уже был у
   .card-hover) и вдавливание при нажатии.

   Вдавливание нужно ради телефона: наведения там не существует, и без
   отклика карточка выглядит неинтерактивной. На касание же реагирует.
   ═══════════════════════════════════════════════════════════════════════ */
.kpi-link{display:block;text-decoration:none;color:inherit;}
.kpi-link:hover{text-decoration:none;color:inherit;}
.kpi-link .kpi-card{transition:box-shadow .18s,transform .18s;}
.kpi-link:active .kpi-card{transform:translateY(0) scale(.985);}
/* Клавиатурная навигация: рамка по фокусу, иначе переход вслепую. */
.kpi-link:focus-visible{outline:none;}
.kpi-link:focus-visible .kpi-card{
  box-shadow:0 0 0 3px rgba(37,99,235,.35), var(--shadow-lg);
}

/* Плашка применённого фильтра над таблицей. Без неё человек видит
   неполный список и решает, что данные пропали. */
.filter-note{
  display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
  background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;
  padding:.55rem .85rem;font-size:.88rem;color:#1e40af;margin-bottom:.75rem;
}
.filter-note .btn-close{font-size:.65rem;margin-left:auto;}

/* Карточка прибыли с переключателем периода.
   Ряд выравнивается по высоте, чтобы карточка с кнопками не выбивалась. */
.kpi-card{height:100%;}
.kpi-profit .kpi-periods .btn{
  padding:.1rem .45rem;font-size:.72rem;line-height:1.3;border-radius:6px;
}
.kpi-profit-link{text-decoration:none;color:inherit;display:inline-block;}
.kpi-profit-link:hover .kpi-value{text-decoration:underline;}
.min-w-0{min-width:0;}

/* Страница прав сотрудника. Разрешение и подпись — одна цель нажатия:
   попадать в маленький квадрат чекбокса на телефоне неудобно. */
.perm-item{
  display:flex;align-items:flex-start;gap:.6rem;cursor:pointer;
  padding:.5rem .7rem;border:1px solid var(--border);border-radius:9px;
  transition:background .15s,border-color .15s;
}
.perm-item:hover{background:#f8fafc;border-color:#cbd5e1;}
.perm-item input{margin-top:.15rem;flex-shrink:0;}
.perm-item input:disabled{opacity:.55;}
.perm-item:has(input:checked){background:#f0f9ff;border-color:#bae6fd;}
.perm-group + .perm-group{border-top:1px solid var(--border);padding-top:1rem;}

/* ═══════════════════════════════════════════════════════════════════════
   Мобильная навигация
   ═══════════════════════════════════════════════════════════════════════ */

/* Нижняя панель. Пять зон нажатия по всей ширине — попасть пальцем можно
   не глядя, в отличие от кнопки меню в углу экрана. */
.bottom-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1035;
  display: flex; background: #fff;
  border-top: 1px solid #e5e9f2;
  /* Отступ снизу двумя правилами: первое работает везде, второе добавляет
     полосу жестов там, где браузер сообщает её размер. Функция max() для
     этого не годится — её понимают не все встроенные браузеры, и тогда
     отступ не появляется вовсе, а подписи упираются в скруглённый край. */
  padding-bottom: 12px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -2px 12px rgba(10, 46, 56, .06);
}
.bottom-nav-item {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px;
  /* 60px: рекомендуемый минимум зоны нажатия 44px плюс место под подпись */
  min-height: 60px; padding: 8px 2px 6px;
  background: none; border: none;
  color: #64748b; text-decoration: none;
  /* 0.68rem — это 11 пикселей, подписи читались с трудом */
  font-size: .75rem; line-height: 1.15;
}
.bottom-nav-item i { font-size: 1.3rem; }
.bottom-nav-item span {
  max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.bottom-nav-item.active { color: var(--brand); }
.bottom-nav-item.active i { transform: translateY(-1px); }

/* Затемнение под выдвинутым меню */
.sidebar-backdrop {
  position: fixed; inset: 0; z-index: 1039;
  background: rgba(10, 46, 56, .45);
}

@media (max-width: 991.98px) {
  .sidebar { z-index: 1040; }
  /* Содержимое не должно уезжать под нижнюю панель */
  .content {
    padding-bottom: 96px;
    padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  }
}
@media (min-width: 992px) {
  .sidebar-backdrop { display: none; }
}

/* Зоны нажатия на телефоне: 34px — частые промахи, а рядом стоит удаление */
@media (max-width: 767.98px) {
  .btn-light-action { width: 44px; height: 44px; }
  .table td, .table th { padding-top: .6rem; padding-bottom: .6rem; }
}

/* Полоса обновления приложения. Над нижней панелью, чтобы её не закрывала. */
.pwa-update-bar {
  position: fixed; left: 12px; right: 12px; z-index: 1050;
  bottom: 96px;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; padding: .7rem .9rem;
  background: #0A2E38; color: #fff;
  border-radius: 12px; font-size: .9rem;
  box-shadow: 0 6px 20px rgba(10, 46, 56, .25);
}
@media (min-width: 992px) {
  .pwa-update-bar { left: auto; right: 20px; bottom: 20px; max-width: 380px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Таблицы на телефоне: карточки вместо строк
   ═══════════════════════════════════════════════════════════════════════
   Горизонтальная прокрутка для таблицы из девяти колонок бесполезна:
   прокрутив до «Остатка», человек уже не видит, чей это договор. Поэтому
   ключевые списки на узком экране разворачиваются в карточки, где у каждого
   значения есть подпись из data-label.

   Работает только на таблицах с классом .table-cards, у которых ячейки
   размечены data-label. Остальные таблицы остаются с прокруткой — для
   служебных списков этого достаточно. */
@media (max-width: 767.98px) {
  .table-cards thead { display: none; }
  .table-cards, .table-cards tbody, .table-cards tr, .table-cards td {
    display: block; width: 100%;
  }
  .table-cards tbody tr {
    border: 1px solid #e5e9f2; border-radius: 12px;
    padding: .7rem .85rem; margin-bottom: .7rem; background: #fff;
    position: relative;
  }
  .table-cards tbody tr.row-overdue { border-color: #fca5a5; background: #fff7f7; }
  .table-cards tbody td {
    border: none; padding: .3rem 0;
    display: flex; align-items: center; gap: .6rem;
    text-align: left !important;
  }
  .table-cards tbody td::before {
    content: attr(data-label);
    flex: 0 0 42%; max-width: 42%;
    color: #64748b; font-size: .8rem;
  }
  /* Значение занимает остаток строки после подписи и сжимается.
     flex вместо width: подпись уже забрала 42%, и width:100% дал бы в сумме
     142% — содержимое вылезало за карточку. min-width:0 обязателен: без него
     flex-элемент не становится уже своего содержимого. */
  .table-cards tbody td > * {
    flex: 1 1 0; min-width: 0; max-width: 100%;
  }
  /* ЗНАЧКИ НЕ СЖИМАЮТСЯ ПОД ТЕКСТ.

     Общее правило выше делит место между всеми элементами ячейки
     поровну: значок «новое» получал половину и обрезался до «нов»
     (снимок владельца 20.08.2026).

     Значок короткий и должен быть виден целиком — место делит текст
     рядом с ним. */
  .table-cards tbody td > .badge {
    flex: 0 0 auto;
    max-width: none;
  }

  /* Поля ввода и списки: width:auto в разметке рассчитан на таблицу, где
     колонка широкая. В карточке ширину задаёт flex. */
  .table-cards tbody td .form-select,
  .table-cards tbody td .form-control,
  .table-cards tbody td select,
  .table-cards tbody td input,
  .table-cards tbody td textarea {
    width: auto !important; max-width: 100%;
  }
  /* Длинные значения без пробелов (адрес одной строкой, длинный email) */
  .table-cards tbody td { overflow-wrap: anywhere; }
  /* Первая ячейка — заголовок карточки: подпись ей не нужна, ширина вся. */
  .table-cards tbody td.cell-title {
    padding-bottom: .5rem; margin-bottom: .35rem;
    border-bottom: 1px dashed #e5e9f2;
    font-weight: 600; font-size: 1rem;
    display: block; word-break: break-word;
  }
  .table-cards tbody td.cell-title::before { content: none; }
  /* Кнопки действий — последней строкой карточки, прижаты вправо.
     Прижатие к правому верхнему углу абсолютом выглядит компактнее, но
     накрывает собой ФИО: длину имени в CSS не узнать, а запас под кнопки
     срабатывает не во всех браузерах. Отдельная строка надёжна везде. */
  .table-cards tbody td.cell-actions {
    justify-content: flex-end; gap: .35rem;
    padding-top: .55rem; margin-top: .35rem;
    border-top: 1px dashed #e5e9f2;
  }
  .table-cards tbody td.cell-actions::before { content: none; }
  .table-cards tbody td:empty { display: none; }
  /* Строка «ничего не найдено» остаётся строкой */
  .table-cards tbody td[colspan] { text-align: center !important; }
  .table-cards tbody td[colspan]::before { content: none; }
  /* Обёртка прокрутки на телефоне не нужна и мешает тени карточек */
  .table-responsive:has(.table-cards) { overflow: visible; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Вкладки настроек на телефоне
   ═══════════════════════════════════════════════════════════════════════
   Восемь вкладок в одну строку не влезают и переносятся вразброс: ширина
   каждой зависит от длины подписи, и получается рваная лестница. На узком
   экране вкладки становятся сеткой одинаковых кнопок — всё видно сразу,
   ничего не прыгает, зона нажатия у каждой не меньше 44px. */
@media (max-width: 767.98px) {
  /* Раскладка на flex, а не grid: результат тот же, но flex понимают и
     старые движки — встроенный браузер приложения может оказаться любым. */
  .nav-tabs {
    display: flex; flex-wrap: wrap;
    gap: .45rem;
    border-bottom: none;
    margin-bottom: 1rem;
  }
  .nav-tabs .nav-item {
    flex: 1 1 calc(50% - .25rem);
    min-width: 0; max-width: calc(50% - .25rem);
  }
  .nav-tabs .nav-link {
    width: 100%; min-height: 46px;
    display: flex; align-items: center; gap: .45rem;
    padding: .5rem .65rem;
    border: 1px solid #e5e9f2; border-radius: 10px;
    background: #fff; color: #475569;
    font-size: .85rem; line-height: 1.15;
    text-align: left;
    /* Длинная подпись обрезается многоточием, а не ломает сетку */
    overflow: hidden;
  }
  .nav-tabs .nav-link i { flex: 0 0 auto; font-size: 1rem; }
  .nav-tabs .nav-link.active {
    background: var(--brand); border-color: var(--brand); color: #fff;
  }
  /* Одна вкладка в последнем ряду занимает всю ширину — так ряд не выглядит
     обрубленным */
  .nav-tabs .nav-item:last-child:nth-child(odd) {
    flex-basis: 100%; max-width: 100%;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Поиск в шапке на телефоне
   ═══════════════════════════════════════════════════════════════════════
   Поле во всю ширину съедает шапку, а подсказка в нём всё равно обрезается
   на середине слова. На узком экране поле скрыто, вместо него кнопка; по
   нажатию поле раскрывается на всю ширину шапки. */
@media (max-width: 767.98px) {
  .search-box { display: none; }
  .topbar.search-open .search-box {
    display: block; flex: 1 1 auto; min-width: 0;
  }
  /* Пока поиск раскрыт, шапка уступает ему ВСЁ: и меню, и кнопку
     поиска, и колокольчик. Поле должно быть широким — иначе подсказка
     обрезается на середине слова, а запрос не виден целиком.

     Прятать меню было опасно, пока свернуть поиск было нечем. Теперь
     он сворачивается касанием мимо поля и клавишей отмены — выход
     есть, и место можно отдать полю. */
  .topbar.search-open #sidebarToggle,
  .topbar.search-open #searchToggle,
  /* !important здесь необходим: у правой области есть класс d-flex, а
     он задан в Bootstrap с высшим приоритетом — без этого колокольчик
     оставался на месте и отнимал у поля треть ширины. */
  .topbar.search-open .ms-auto { display: none !important; }
}

/* Крупные суммы в карточках: «1 100 127.80 ₽» на узком экране переносило
   знак рубля на отдельную строку — выглядит как ошибка вывода. Уменьшение
   шрифта на телефоне даёт числу поместиться целиком. */
@media (max-width: 575.98px) {
  .kpi-value {
    font-size: 1.3rem;
    /* Длинное число не должно ломаться посреди разряда */
    overflow-wrap: normal; word-break: keep-all;
  }
}
@media (max-width: 389.98px) {
  .kpi-value { font-size: 1.15rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Кнопка сохранения в длинных формах
   ═══════════════════════════════════════════════════════════════════════
   В форме с десятком полей кнопка уезжает за пределы экрана, и её ищут
   прокруткой. На телефоне она закрепляется у нижнего края — как в форме
   договора, где такая панель уже была.

   Только на узком экране: на компьютере вся форма видна целиком, и
   закреплённая полоса лишь занимала бы место. */
@media (max-width: 767.98px) {
  .form-actions-sticky {
    position: sticky;
    /* Над нижней панелью навигации, иначе она перекроет кнопку */
    bottom: 84px;
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));
    background: #fff;
    border-top: 1px solid #e5e9f2;
    padding: .7rem 0;
    margin-top: 1rem;
    z-index: 1010;
  }
  .form-actions-sticky .btn { min-height: 46px; }
  /* Кнопки делят строку: «Сохранить» шире, «Отмена» по содержимому */
  .form-actions-sticky .btn:first-child { flex: 1 1 auto; }
}

/* Характеристики товара из каталога — под строкой в форме договора.
   Менеджер видит, что уйдёт в документ, до создания договора. */
.goods .cell-details {
  font-size: .8rem;
  color: #64748b;
  padding-top: .2rem;
}
@media (min-width: 768px) {
  /* На широком экране — отдельной строкой во всю ширину таблицы */
  .goods tbody tr .cell-details {
    display: table-cell;
  }
}

/* Выбор цвета товара. Кружками, а не списком: глазами цвет ищется быстрее,
   чем читается. */
.color-pick { cursor: pointer; margin: 0; }
.color-pick input { position: absolute; opacity: 0; width: 0; height: 0; }
.color-dot {
  display: inline-block;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 2px solid #e5e7eb;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06);
  transition: transform .12s, border-color .12s;
}
.color-dot-empty {
  display: inline-flex; align-items: center; justify-content: center;
  color: #9ca3af; font-size: .8rem; background: #fff;
}
/* Выбранный обводится тёмным: на светлых цветах галочка внутри неразличима */
.color-pick input:checked + .color-dot {
  border-color: #111827;
  transform: scale(1.12);
}
.color-pick input:focus-visible + .color-dot {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}
/* В списке товаров — маленький, перед названием */
.color-dot-sm { width: 12px; height: 12px; border-width: 1px; }

/* На телефоне тринадцать кружков в ряд не влезают: делаем их мельче, чтобы
   ряд не рвался посередине и выбор оставался обозримым. */
@media (max-width: 575.98px) {
  .color-dot { width: 24px; height: 24px; }
  .color-dot-empty { font-size: .7rem; }
}

/* Снимок товара. Квадрат с сохранением пропорций: у карточек снимки разной
   формы, и без выравнивания плитка ломается. */
.product-photo {
  width: 120px; height: 120px; flex: none;
  object-fit: cover; border-radius: 12px;
  border: 1px solid var(--line, #e5e9f2); background: #fff;
}
/* Без снимка — цветной знак с первой буквой. Он же показывает цвет товара,
   так что два одинаковых названия различимы и здесь. */
.product-photo-empty {
  display: grid; place-items: center;
  color: #fff; font-size: 42px; font-weight: 700;
  border: 0;
}

/* Снимок в списке товаров: мелкий, но узнаваемый. */
.thumb {
  width: 28px; height: 28px; border-radius: 6px;
  object-fit: cover; border: 1px solid var(--line, #e5e9f2);
}

/* Сводка смены: итоговая строка отделяется линией, а не жирностью — суммы
   и без того выделены, и второй приём сделал бы таблицу пёстрой. */
.cash-summary td { padding: .45rem .25rem; border: 0; }
.cash-summary .cash-total td {
  border-top: 1px solid var(--line, #e5e9f2);
  padding-top: .7rem;
}

/* Полоса состояния смены. Тонкая: она информирует, а не требует внимания —
   криком на каждой странице она стала бы шумом, который перестают замечать. */
.shift-bar {
  display: flex; align-items: center; gap: .55rem;
  padding: .5rem .85rem; margin-bottom: 1rem;
  border-radius: 10px; font-size: .875rem;
  border: 1px solid transparent;
}
.shift-bar i { font-size: .6rem; }
.shift-bar.open {
  background: #f0fdf4; border-color: #bbf7d0; color: #166534;
}
.shift-bar.closed {
  background: #fffbeb; border-color: #fde68a; color: #92400e;
}
@media (max-width: 575.98px) {
  /* На телефоне сумма уходит под текст: в одну строку они не влезают, а
     обрезанное число хуже, чем перенесённое. */
  .shift-bar { flex-wrap: wrap; }
  .shift-bar .ms-auto { margin-left: 0 !important; width: 100%; }
}

/* ── Окно выбора товара ────────────────────────────────────────────── */
.picker .modal-body { padding: 0; }
.picker-search { flex: 1 1 260px; min-width: 0; max-width: 420px; }

.picker-chips {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .6rem 1rem; border-bottom: 1px solid var(--line, #e5e9f2);
}
.picker-chips .chip {
  border: 1px solid var(--line, #e5e9f2); background: #fff;
  border-radius: 999px; padding: .3rem .75rem;
  font-size: .78rem; font-weight: 600; color: #64748b;
}
.picker-chips .chip[aria-pressed="true"] {
  background: #eff6ff; border-color: #bfdbfe; color: var(--brand-dark, #1d4ed8);
}
.picker-count { font-size: .78rem; color: #64748b; }

.picker-body { display: flex; min-height: 0; }
.picker-cats {
  width: 190px; flex: none; padding: .6rem;
  border-right: 1px solid var(--line, #e5e9f2); overflow-y: auto;
}
.picker-cat {
  display: flex; justify-content: space-between; gap: .5rem; width: 100%;
  border: 0; background: transparent; text-align: left; color: #0f172a;
  padding: .45rem .6rem; border-radius: 8px; font-size: .82rem;
}
.picker-cat[aria-pressed="true"] {
  background: #eff6ff; color: var(--brand-dark, #1d4ed8); font-weight: 600;
}
.picker-cat span:last-child { color: #94a3b8; font-size: .75rem; }

.picker-goods { flex: 1 1 auto; overflow-y: auto; padding: .75rem; }

.picker-tiles {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
}
.picker-tile {
  border: 1px solid var(--line, #e5e9f2); border-radius: 12px;
  padding: .6rem; display: flex; flex-direction: column; gap: .4rem;
  text-align: left; background: #fff; width: 100%;
}
.picker-tile:hover { border-color: #cbd5e1; }
.picker-tile:disabled { opacity: .55; }
.picker-tile-photo {
  height: 84px; border-radius: 9px; object-fit: cover; width: 100%;
  background: #f1f5f9;
}
.picker-tile-mark {
  height: 84px; border-radius: 9px; display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: 1.4rem; background: #94a3b8;
}
.picker-tile-name { font-size: .82rem; font-weight: 600; line-height: 1.3; }
.picker-tile-meta { font-size: .72rem; color: #64748b; }
.picker-tile-price { font-weight: 700; font-size: .88rem; margin-top: auto; }
.picker-empty { padding: 2rem 1rem; text-align: center; color: #64748b; }

@media (max-width: 767.98px) {
  /* Категории полосой сверху: колонка в 190 точек съедает половину
     экрана телефона, а без категорий каталог не осмотреть. */
  .picker-body { flex-direction: column; }
  .picker-cats {
    width: 100%; border-right: 0;
    border-bottom: 1px solid var(--line, #e5e9f2);
    display: flex; gap: .35rem; overflow-x: auto; padding: .5rem;
  }
  .picker-cat { width: auto; white-space: nowrap; }
  .picker-cat span:last-child { display: none; }
}

/* Правка остатка в списке. Узкая: в строке она соседствует с ценой и
   названием, и широкое поле сдвинуло бы их за край экрана. */
.stock-edit {
  display: inline-flex; align-items: center;
  border: 1px solid var(--line, #e5e9f2); border-radius: 8px;
  overflow: hidden; background: #fff;
}
.stock-edit .stock-step {
  border: 0; background: #fff; width: 28px; height: 30px;
  color: #64748b; font-size: .95rem; line-height: 1;
}
.stock-edit .stock-step:hover { background: #f1f5f9; color: #0f172a; }
.stock-edit .stock-value {
  width: 48px; border: 0; text-align: center; font-weight: 600;
  font-size: .85rem; padding: 0;
}
.stock-edit .stock-value:focus { outline: none; background: #eff6ff; }
/* Сохранено — короткая вспышка вместо сообщения: их было бы десяток за
   минуту работы с привозом. */
.stock-edit.saved { border-color: #86efac; background: #f0fdf4; }
.stock-edit.failed { border-color: #fca5a5; }

/* Характеристики товара под его названием. Мельче и приглушённее: это
   пояснение к строке, а не самостоятельные данные — иначе они спорят с
   названием за внимание. */
.goods .cell-details {
  font-size: .75rem;
  line-height: 1.35;
  color: #64748b;
  margin-top: .3rem;
  padding-left: .15rem;
}

/* Таблица товаров: числовые столбцы держат заданную ширину, название
   забирает остаток. Без этого браузер растягивает название на пол-таблицы,
   а цифры жмутся к краю. */
.goods { table-layout: fixed; width: 100%; }
/* Специфичность та же, что у правила выше: иначе оно перебьёт выравнивание,
   и с характеристиками под названием поля съедут вниз относительно текста. */
.goods tbody td { vertical-align: top; }
.goods tbody td.cell-total { padding-top: .75rem; }

@media (max-width: 575.98px) {
  /* Характеристики на телефоне занимают отдельную строку под полем.

     Ячейка названия здесь — строка с подписью слева и полем справа, и
     характеристики делили это место с полем: обоим доставалось по трети
     ширины, и «Марка: Айфон · Модель: Макс» ломалось на четыре строки в
     углу. */
  .goods tbody td:first-child { flex-wrap: wrap; }
  .goods tbody td .cell-details {
    flex: 1 1 100%;
    max-width: 100%;
    /* Выравнивается с полем, а не с подписью: так видно, что это пояснение
       к названию, а не отдельное свойство строки. */
    margin-left: calc(42% + .6rem);
    margin-top: .25rem;
  }
}

/* Подписи в подвале таблицы товаров не переносятся: «Себестоимость»
   попадает в столбец наценки шириной под сотню точек и ломалась пополам,
   утаскивая за собой числа. */
.goods tfoot td { white-space: nowrap; }
.goods tfoot td.text-end { font-size: .72rem; padding-right: .35rem; }

/* Добавленный товар в окне выбора: остаётся видимым, но выбрать его снова
   нельзя. Исчезновение сбивало — менеджер искал глазами то, что только что
   видел. */
.picker-tile.added {
  border-color: #86efac;
  background: #f0fdf4;
  opacity: 1;
}
.picker-tile.added:disabled { opacity: 1; }
.picker-added {
  display: block;
  font-size: .7rem;
  font-weight: 700;
  color: #16a34a;
  margin-bottom: .1rem;
}

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

   Свой список виден под полем, строка целиком нажимается пальцем. */
.suggest-list {
  position: absolute;
  z-index: 1080;          /* выше окна: иначе список прячется под его краем */
  left: 0;
  right: 0;
  top: calc(100% + 2px);
  max-height: 15rem;
  overflow-y: auto;
  background: #fff;
  border: 1px solid #dbe2ef;
  border-radius: .5rem;
  box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
}

.suggest-item {
  display: block;
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  /* Высота под палец: строка в 30 точек на телефоне промахивается. */
  padding: .6rem .75rem;
  font-size: .9rem;
  line-height: 1.25;
}

.suggest-item + .suggest-item {
  border-top: 1px solid #f1f4f9;
}

.suggest-item:hover,
.suggest-item.marked {
  background: #eef4ff;
}

.suggest-title {
  display: block;
  font-weight: 600;
  color: #0f172a;
}

/* Остаток показывается сразу: менеджер выбирает договор, зная, сколько по
   нему осталось, а не открывая карточку. */
.suggest-note {
  display: block;
  font-size: .78rem;
  color: #64748b;
}

/* Предупреждение в строке подсказки: просрочка у договора в быстром
   платеже. Красным — чтобы менеджер увидел долг, не открывая договор. */
.suggest-alert {
  display: block;
  font-size: .78rem;
  color: #dc3545;
}

/* Очередной платёж по графику под полем суммы — в обоих окнах платежа:
   быстром и в карточке договора. */
.payment-due {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-top: .5rem;
  padding: .45rem .65rem;
  border-radius: 10px;
  background: #eef4ff;
  color: #1d4ed8;
  font-size: .85rem;
}

/* Подсказки общего поиска: шапка перекрывает содержимое страницы, поэтому
   список должен лежать выше неё. */
.topbar .suggest-list {
  z-index: 1090;
}

/* Кнопка поиска: без неё на телефоне непонятно, как искать — клавиша ввода
   есть не на всякой клавиатуре. */
.topbar .search-box .btn {
  border-radius: 0 10px 10px 0;
  border-color: transparent;
  background: #f1f4f9;
}

.topbar .search-box .btn:hover {
  background: #e6ebf5;
}

/* ── Недоступная выгрузка ─────────────────────────────────────────────
   Кнопка не прячется, а гаснет: препятствие устранимо — включить второй
   фактор, дождаться суток, обратиться в поддержку. Спрятать её значило бы
   оставить человека в неведении.

   Пояснения под кнопкой нет: строка была шире её самой, и ряд выглядел
   неровно. Причина приходит при наведении и по нажатию. */
.btn-locked {
  /* Не disabled: по такой кнопке нельзя нажать, а нам нужно показать
     причину по нажатию на телефоне, где наводить нечем. */
  opacity: .6;
  cursor: help;
}

.btn-locked:hover {
  opacity: .8;
}



/* ── Строки предварительного графика ──────────────────────────────────
   График в форме рисуется строками, а не таблицей: колонок всего две, и
   таблица ради них — лишняя разметка.

   Стили .sched td сюда не подходят — они для карточки договора, где
   график и правда таблица. */
.sched-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: .42rem .8rem;
  font-size: .87rem;
  border-bottom: 1px solid #f1f5f9;
  /* Цифры одной ширины: суммы в столбик читаются, а не пляшут. */
  font-variant-numeric: tabular-nums;
}

.sched-row:last-child {
  border-bottom: 0;
}

/* Сумма справа и заметнее даты: смотрят прежде всего на неё. */
.sched-row > span:last-child {
  font-weight: 600;
  white-space: nowrap;
}

/* ── Полоса «требует внимания» ────────────────────────────────────────
   Просрочка стоит первой и во всю ширину: это единственное на главной,
   что требует действия сегодня. Остальные плитки — сведения, которые
   смотрят мельком.

   Когда просрочки нет, полосы не бывает вовсе: пустая тревога приучает не
   обращать на неё внимания. */
/* Обычное положение дел — янтарное. Красная тревога, горящая всегда,
   перестаёт быть тревогой: при рассрочке просрочка — рабочее состояние, и
   через неделю глаз перестаёт её замечать.

   Красным полоса станет, когда появится сравнение с обычным: следующим
   шагом. */
.alert-overdue {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.15rem;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: var(--card-radius);
  text-decoration: none;
  color: inherit;
  transition: background .15s, border-color .15s;
}

.alert-overdue:hover {
  background: #fef3c7;
  border-color: #fcd34d;
}

.alert-overdue-icon {
  flex: 0 0 46px;
  height: 46px;
  border-radius: 13px;
  background: #fef3c7;
  color: #d97706;
  display: grid;
  place-items: center;
  font-size: 1.35rem;
}

.alert-overdue-value {
  font-size: 1.15rem;
  font-weight: 700;
  color: #92400e;
  line-height: 1.25;
}

.alert-overdue-note {
  font-size: .84rem;
  color: #a16207;
  opacity: .9;
  margin-top: .15rem;
}

.alert-overdue-arrow {
  color: #d97706;
  opacity: .5;
  font-size: 1.1rem;
}

/* На телефоне стрелка лишняя: вся полоса и так нажимается пальцем. */
@media (max-width: 575px) {
  .alert-overdue-arrow { display: none; }
  .alert-overdue { padding: .85rem 1rem; gap: .8rem; }
  .alert-overdue-value { font-size: 1.05rem; }
}

/* ── Приём платежа ───────────────────────────────────────────────────
   Самое частое действие дня, и цвет у него свой.

   Не btn-primary: тот стоит в семидесяти восьми местах по всем страницам.
   Не синий: синим заняты вкладки меню, подсветка полей и значки плиток —
   кнопка того же цвета сливалась с ними. */
.btn-take-payment {
  background: #0f766e;
  border: 0;
  color: #fff;
}

.btn-take-payment:hover,
.btn-take-payment:focus {
  background: #115e59;
  color: #fff;
}

/* Второстепенные рядом с ней: обводка в тот же цвет.
   Белое на светло-сером теряет край — кнопки выглядели частью подложки.
   Обводка связывает их с главной в один ряд, но заливки нет, и главная
   остаётся заметнее. */
.btn-outline-take {
  background: #fff;
  border: 1px solid #99f6e4;
  color: #0f766e;
}

.btn-outline-take:hover,
.btn-outline-take:focus {
  background: #f0fdfa;
  border-color: #5eead4;
  color: #115e59;
}

/* Просрочек нет — зелёная полоса на том же месте.
   Место на экране не плавает, а достижение отмечено: для рассрочки полное
   отсутствие просрочки — новость редкая и заслуженная. */
.alert-overdue.clean {
  background: #f0fdf4;
  border-color: #bbf7d0;
  cursor: default;
}

.alert-overdue.clean:hover {
  background: #f0fdf4;
  border-color: #bbf7d0;
}

.alert-overdue.clean .alert-overdue-icon {
  background: #dcfce7;
  color: #16a34a;
}

.alert-overdue.clean .alert-overdue-value { color: #166534; }
.alert-overdue.clean .alert-overdue-note { color: #15803d; }

/* ── Кнопки действий на главной ───────────────────────────────────────
   На большом экране — по содержимому: места хватает, и кнопка во всю
   ширину выглядит нелепо. */
.dashboard-actions {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
}

/* На телефоне — сетка в две колонки, главная кнопка во всю ширину.

   Делить на три нельзя: выходит по три-четыре знака на строку, надписи
   ломаются, кнопки выглядят огрызками. По содержимому — тоже: третья не
   помещается и переносится одна, ряд выглядит сломанным.

   Две пополам держат ширину и остаются читаемыми. */
@media (max-width: 767px) {
  .dashboard-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  /* Внести платёж — самое частое действие дня, ему вся строка. */
  .dashboard-actions .btn:first-child {
    grid-column: 1 / -1;
  }

  .dashboard-actions .btn {
    justify-content: center;
    text-align: center;
    min-width: 0;
  }
}

/* Строка «показать ещё» в предварительном графике: выглядит как строка
   графика, ведёт себя как кнопка. Прежде здесь была надпись с
   многоточием — она обещала действие, которого не было. */
.sched-more {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}
.sched-more:hover { background: rgba(0, 0, 0, .03); }



.sidebar .nav-divider {
  height: 1px;
  background: #1e2d45;
  margin: .35rem .85rem;
}

/* Карточка «Все разделы»: перечень внутри виден до нажатия — человек
   понимает, за чем туда идти. */
.sidebar .nav-more {
  display: flex;
  align-items: center;
  gap: .75rem;
  /* Ширину карточка не тянет: её содержимое ужимается, а не раздвигает
     панель. Без этого круглый значок и две строки текста вылезали за
     250 px, и панель начинала ездить вбок. */
  min-width: 0;
  background: #16233a;
  border-radius: 10px;
  padding: .6rem .7rem;
  margin: 0 .1rem .15rem;
  color: #cbd5e1;
  text-decoration: none;
}
.sidebar .nav-more:hover { background: #1b2b45; color: #fff; }

.sidebar .nav-more .round {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid #2c3f5d;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; font-size: 1rem;
}
.sidebar .nav-more .name { display: block; font-size: .93rem; }
.sidebar .nav-more .hint {
  display: block; font-size: .74rem; color: #64748b; line-height: 1.3;
  /* Перечень переносится на вторую строку, а не обрезается многоточием
     (замечание владельца): человек должен видеть, что внутри, целиком.
     Ширину панели это не ломает — перенос идёт по словам. */
  white-space: normal; overflow-wrap: anywhere;
}
.sidebar .nav-more .chev {
  margin-left: auto; color: #64748b; font-size: .8rem;
  transition: transform .15s;
}
.sidebar .nav-more.open .chev,
.sidebar .nav-more[aria-expanded="true"] .chev { transform: rotate(90deg); }

/* Вложенные пункты — с отступом, чтобы читались как содержимое
   карточки, а не как отдельная группа. */
.sidebar #navMore .nav-link { padding-left: 1.6rem; font-size: .9rem; }

/* Фиолетовый для кассы: своего класса в наборе нет, а кошелёк на
   эталоне именно такой. */
.sidebar .text-purple { color: #a855f7; }

/* ── Кто вошёл: внизу панели ──────────────────────────────────────
   Имя и роль под рукой: человек видит, под кем работает, а не гадает.
   Ведёт в настройки — там пароль и второй фактор. */
.sidebar .nav-user {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem .7rem; margin: 0 .1rem;
  border-radius: 10px; color: #cbd5e1; text-decoration: none;
  min-width: 0;
}
.sidebar .nav-user:hover { background: rgba(255,255,255,.06); color: #fff; }
.sidebar .nav-user.active { background: var(--brand); color: #fff; }

.sidebar .nav-user .avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: #1e3a8a; color: #bfdbfe; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.sidebar .nav-user .name {
  display: block; font-size: .93rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar .nav-user .role { display: block; font-size: .74rem; color: #64748b; }
.sidebar .nav-user.active .role { color: #dbeafe; }
.sidebar .nav-user .chev { margin-left: auto; color: #64748b; font-size: .8rem; }

/* Выход красным: единственное необратимое действие в меню. */
.sidebar .nav-logout { color: #f87171; }
.sidebar .nav-logout:hover { color: #fca5a5; background: rgba(248,113,113,.08); }

/* Части внутри профиля компании: работа, реквизиты, правила.

   Реквизиты — лишь одна из частей, а не весь профиль (замечание
   владельца). Прежде всё шло единым списком, и часовой пояс стоял
   рядом с расчётным счётом. */
.settings-part {
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #64748b;
  font-weight: 600;
  margin: 1.6rem 0 .75rem;
  padding-bottom: .4rem;
  border-bottom: 1px solid #eef1f5;
}
.settings-part:first-of-type { margin-top: 0; }

/* ═══════════════════════════════════════════════════════════════════
   Главная страница — утверждённый вид (Design Baseline 0.1).

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

/* Приветствие: типографикой, без карточки и значка — оно несёт одну
   строку сведений. */
.dash-hello {
  display: flex; align-items: flex-start; gap: .5rem;
  margin: 0 2px 1.25rem;
}
.dash-hello h1 {
  font-size: 1.25rem; font-weight: 600; letter-spacing: -.02em; margin: 0;
}
.dash-hello p { font-size: .8125rem; color: #98a2b3; margin: .2rem 0 0; }

/* Заголовок раздела: обычным кеглем, а не мелкими прописными — те
   теряются на экране. */
.dash-section {
  font-size: .95rem; font-weight: 600; margin: 0 2px .55rem;
}

/* ── панель показателей ── */
.kpi-panel {
  background: #fff; border: 1px solid #eaecf0; border-radius: var(--card-radius);
  overflow: hidden;
}
.kpi-lead {
  display: block; padding: 1rem 1rem .9rem; text-decoration: none; color: inherit;
}
.kpi-lead:hover { background: #fcfcfd; color: inherit; }
.kpi-lead-top {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
}
.kpi-lead-label { font-size: .8125rem; color: #475467; }
.kpi-lead-value {
  font-size: 1.75rem; font-weight: 600; letter-spacing: -.03em;
  line-height: 1.1; margin-top: .3rem;
}
.kpi-lead-delta {
  font-size: .78rem; margin-top: .3rem; display: flex; align-items: center;
  gap: .25rem; color: #98a2b3;
}
/* Рост долга — предупреждение, снижение — хорошо. Цвет не единственный
   признак: рядом стрелка. */
.kpi-lead-delta.up { color: #f79009; }
.kpi-lead-delta.down { color: #12b76a; }

.kpi-row { display: grid; grid-template-columns: repeat(3, 1fr);
           border-top: 1px solid #eaecf0; }
.kpi-cell {
  padding: .8rem .7rem .85rem; text-decoration: none; color: inherit;
  display: block; min-width: 0;
}
.kpi-cell + .kpi-cell { border-left: 1px solid #f2f4f7; }
.kpi-cell:hover { background: #fcfcfd; color: inherit; }
.kpi-cell-label {
  display: block; font-size: .7rem; color: #98a2b3; line-height: 1.25;
  margin-bottom: .3rem;
}
.kpi-cell-value {
  display: block; font-size: 1.05rem; font-weight: 600; letter-spacing: -.02em;
  line-height: 1.15;
}
.kpi-cell-note { display: block; font-size: .68rem; color: #98a2b3;
                 margin-top: .15rem; }
/* Состояние не только цветом: точка плюс слово. */
.kpi-cell-flag {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .68rem; color: #12b76a; margin-top: .15rem;
}
.kpi-cell-flag i { width: 5px; height: 5px; border-radius: 50%;
                   background: currentColor; }

/* ── статус платежей ── полоса слева, а не заливка */
.dash-status {
  display: flex; align-items: center; gap: .7rem;
  background: #fff; border: 1px solid #eaecf0; border-left: 3px solid #12b76a;
  border-radius: var(--card-radius); padding: .8rem .9rem;
  text-decoration: none; color: inherit;
}
.dash-status.bad { border-left-color: #f04438; }
.dash-status:hover { color: inherit; background: #fcfcfd; }
.dash-status > i:first-child { font-size: 1.15rem; color: #12b76a; }
.dash-status.bad > i:first-child { color: #f04438; }
.dash-status-title { display: block; font-size: .9rem; font-weight: 600; }
.dash-status-note { display: block; font-size: .78rem; color: #98a2b3; }
.dash-status-go { color: #98a2b3; font-size: .8rem; }

/* ── денежные средства ── */
.dash-cash {
  display: flex; align-items: center; gap: .7rem;
  background: #fff; border: 1px solid #eaecf0; border-radius: var(--card-radius);
  padding: .85rem 1rem; text-decoration: none; color: inherit;
}
.dash-cash:hover { background: #fcfcfd; color: inherit; }
.dash-cash-label { display: block; font-size: .875rem; }
.dash-cash-note { display: block; font-size: .72rem; color: #98a2b3; }
.dash-cash-value { font-size: 1.15rem; font-weight: 600; letter-spacing: -.02em; }

/* ── ближайшие платежи ── единый список */
.dash-due {
  display: flex; align-items: center; gap: .7rem; padding: .65rem 0;
  text-decoration: none; color: inherit; border-top: 1px solid #f2f4f7;
}
.dash-due:first-of-type { border-top: 0; }
.dash-due:hover { color: inherit; }
.dash-due-date {
  width: 38px; flex-shrink: 0; text-align: center; line-height: 1.05;
}
.dash-due-date b { display: block; font-size: .95rem; font-weight: 600; }
.dash-due-date span { font-size: .65rem; color: #98a2b3; }
.dash-due-mid { flex: 1; min-width: 0; }
/* Длинное ФИО обрезается многоточием: строка не должна растягивать
   страницу вбок. */
.dash-due-who {
  display: block; font-size: .85rem; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-due-what { display: block; font-size: .72rem; color: #98a2b3; }
.dash-due-sum { text-align: right; flex-shrink: 0; }
.dash-due-sum b { display: block; font-size: .85rem; font-weight: 600; }
.dash-due-sum span { font-size: .7rem; }
.dash-due-sum .today { color: var(--brand); }
.dash-due-sum .later { color: #98a2b3; }

/* ── действия одной панелью ── */
.dash-actions {
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: #fff; border: 1px solid #eaecf0; border-radius: var(--card-radius);
  overflow: hidden;
}
.dash-action {
  border: 0; background: transparent; box-shadow: none; border-radius: 0;
  padding: .85rem .3rem .8rem;
  display: flex; flex-direction: column; align-items: center; gap: .45rem;
  text-decoration: none; color: #101828; font: inherit; cursor: pointer;
  width: 100%;
}
.dash-action + .dash-action { border-left: 1px solid #f2f4f7; }
.dash-action:hover { background: #fcfcfd; }
.dash-action > i { font-size: 1.3rem; }
/* 13 px посчитаны: при трёх в ряд на экране 360 px под надпись
   остаётся 89, а «Новый договор» шрифтом 15 занимает 99. */
.dash-action .caption {
  font-size: .8125rem; font-weight: 500; line-height: 1.2; text-align: center;
}

/* ── Финансовый результат: список, а не карточка с одним числом ──
   Утверждённый вид (Design Baseline 0.1): получено → закупочная
   стоимость → расходы → итог. Прежде показывалось одно число, и
   человек не мог сойтись с ним из «получено». */
.fin-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: .35rem 0; font-size: .875rem;
}
.fin-key { color: #475467; }
.fin-val { font-variant-numeric: tabular-nums; }
.fin-val.minus { color: #475467; }

.fin-total {
  display: flex; justify-content: space-between; align-items: baseline;
  border-top: 1px solid #eaecf0; margin-top: .5rem; padding-top: .7rem;
  text-decoration: none; color: inherit;
}
.fin-total:hover { color: inherit; }
.fin-total-key { font-size: .875rem; font-weight: 500; }
.fin-total-val {
  font-size: 1.4rem; font-weight: 600; letter-spacing: -.02em; color: #12b76a;
}
.fin-total-val.text-danger { color: #f04438 !important; }

/* Незаведённые расходы — не ошибка, а незаполненность: янтарным. */
.fin-hint { display: block; font-size: .72rem; color: #b45309; margin-top: .4rem; }

/* Легенда графика: два ряда, которые не складываются — пришедшее и
   должное. Подписи обязательны: по цвету одному их не различить. */
.flow-legend {
  display: flex; gap: 1rem; font-size: .75rem; color: #98a2b3;
  margin-bottom: .6rem;
}
.flow-legend .dot {
  width: 8px; height: 8px; border-radius: 2px; display: inline-block;
  margin-right: .3rem; vertical-align: 0;
}
.flow-legend .dot.got { background: #12b76a; }
.flow-legend .dot.wait { background: #2563eb; }

/* Должники: вместо даты — сколько дней просрочено. Число само по себе
   тревожно, цвет лишь усиливает. */
.dash-due-date.overdue b { color: #f04438; }
.dash-due-date.overdue span { font-size: .6rem; }

/* ── Панель покупателей ──
   Две пары: сколько всего и в каком они состоянии. Четыре отдельные
   карточки читались бы как четыре равнозначных числа. */
.clients-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; padding: 1rem 1rem .9rem;
}
.clients-total { text-decoration: none; color: inherit; display: block; }
.clients-total:hover { color: inherit; }
.clients-value {
  display: block; font-size: 1.75rem; font-weight: 600;
  letter-spacing: -.03em; line-height: 1.05;
}
.clients-label { display: block; font-size: .78rem; color: #98a2b3; }

.clients-new { text-align: right; }
.clients-new .clients-label { margin-bottom: .25rem; }
/* Синим только число: цвет — акцент, а не заливка строки. */
.clients-new-line {
  display: block; font-size: .78rem; color: #98a2b3; line-height: 1.5;
}
.clients-new-line b { color: var(--brand); font-weight: 600; }

/* В ряду покупателей ячеек две, а не три: сетка задаётся здесь, чтобы
   не спорить с панелью показателей выше. */
.kpi-panel .kpi-row:has(.kpi-cell:nth-child(2):last-child) {
  grid-template-columns: 1fr 1fr;
}

/* Кнопка настройки главной: неброская — редкое действие, не рабочее.
   Проявляется при наведении, но всегда нажимаема: 40 px область. */
.dash-setup {
  flex-shrink: 0; width: 40px; height: 40px; margin-top: -4px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px; color: #98a2b3; text-decoration: none;
}
.dash-setup:hover { background: #f2f4f7; color: #475467; }

/* ── Настройка главной ── */
.layout-list { list-style: none; margin: 0; padding: 0; }
.layout-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .7rem .25rem; border-bottom: 1px solid #f2f4f7;
}
.layout-row:last-child { border-bottom: 0; }
.layout-note { font-size: .72rem; color: #98a2b3; margin-left: .35rem; }
.layout-move { margin-left: auto; display: flex; gap: .25rem; }
.layout-move .btn { width: 34px; }

/* Внутренний контроль: та же полоса, что статус платежей, но янтарная —
   это не беда с деньгами покупателя, а повод разобраться с действиями
   сотрудников. Красный оставлен просрочке. */
.dash-status.control { border-left-color: #f79009; }
.dash-status.control > i:first-child { color: #f79009; }

/* Колокольчик отклонений: спокойный, счётчик янтарный. Красный оставлен
   просрочке — там деньги покупателя, здесь повод разобраться. */
.topbar-bell {
  position: relative; width: 40px; height: 40px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #475467; text-decoration: none; border-radius: 10px;
}
.topbar-bell:hover { background: #f2f4f7; color: #101828; }
.topbar-bell .badge-count {
  position: absolute; top: 4px; right: 3px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 9px; border: 2px solid #fff;
  background: #f79009; color: #fff; font-size: .62rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
/* Срочные — красным: их разбирают сегодня. */
.topbar-bell .badge-count.urgent { background: #f04438; }


/* ═══════════════════════════════════════════════════════════════════
   Главная на широком экране.

   Страница делалась под телефон, и на мониторе те же размеры выглядят
   мелко: строка растягивается на всю ширину, а кегль остаётся
   телефонным (замечание владельца).

   Здесь только размеры и раскладка — состав и порядок блоков те же,
   иначе настройка компании на разных экранах давала бы разное.
   ═══════════════════════════════════════════════════════════════════ */
@media (min-width: 768px) {
  .dash-hello h1 { font-size: 1.5rem; }
  .dash-hello p { font-size: .9375rem; }
  .dash-section { font-size: 1.0625rem; margin-bottom: .7rem; }

  /* Показатели: главное число крупнее, подписи читаемее. */
  .kpi-lead { padding: 1.35rem 1.35rem 1.2rem; }
  .kpi-lead-label { font-size: .9375rem; }
  .kpi-lead-value { font-size: 2.25rem; }
  .kpi-lead-delta { font-size: .875rem; }

  .kpi-cell { padding: 1.1rem 1.1rem 1.15rem; }
  .kpi-cell-label { font-size: .8125rem; }
  .kpi-cell-value { font-size: 1.375rem; }
  .kpi-cell-note, .kpi-cell-flag { font-size: .8125rem; }

  /* Действия: значок и надпись крупнее — на мониторе по ним попадают
     мышью, а не пальцем, но читать всё равно надо. */
  .dash-action { padding: 1.15rem .5rem 1.05rem; gap: .6rem; }
  .dash-action > i { font-size: 1.6rem; }
  .dash-action .caption { font-size: .9375rem; }

  .dash-status { padding: 1rem 1.15rem; }
  .dash-status-title { font-size: 1.0625rem; }
  .dash-status-note { font-size: .875rem; }
  .dash-status > i:first-child { font-size: 1.4rem; }

  .dash-cash { padding: 1.1rem 1.25rem; }
  .dash-cash-label { font-size: 1rem; }
  .dash-cash-note { font-size: .8125rem; }
  .dash-cash-value { font-size: 1.5rem; }

  .clients-top { padding: 1.35rem 1.35rem 1.2rem; }
  .clients-value { font-size: 2.25rem; }
  .clients-lab { font-size: .875rem; }
  .clients-line { font-size: .875rem; }

  .fin-row { font-size: 1rem; padding: .45rem 0; }
  .fin-total-key { font-size: 1rem; }
  .fin-total-val { font-size: 1.75rem; }
  .fin-hint { font-size: .8125rem; }

  .dash-due { padding: .85rem 0; }
  .dash-due-date { width: 48px; }
  .dash-due-date b { font-size: 1.125rem; }
  .dash-due-date span { font-size: .75rem; }
  .dash-due-who { font-size: 1rem; }
  .dash-due-what { font-size: .8125rem; }
  .dash-due-sum b { font-size: 1rem; }
  .dash-due-sum span { font-size: .8125rem; }

  .flow-legend { font-size: .875rem; }
}

/* На мониторе страница в одну колонку оставляет половину экрана пустой.
   Списки и график встают парами — читать сверху вниз всё так же, но
   прокрутки вдвое меньше. */
@media (min-width: 1200px) {
  .dash-hello h1 { font-size: 1.625rem; }
  .kpi-lead-value { font-size: 2.5rem; }
  .clients-value { font-size: 2.5rem; }
  .fin-total-val { font-size: 2rem; }
}

/* Ширина содержимого на мониторе. Без ограничения строка тянется на
   весь экран: показатель слева, число справа — глазу приходится
   проходить полметра. Читать удобно при ширине около тысячи точек. */
@media (min-width: 1400px) {
  .content { max-width: 1200px; }
}

/* ── Главная на мониторе: две колонки ──
   Слева то, что смотрят: показатели, деньги, графики. Справа то, по
   чему действуют: статус, ближайшие платежи, должники.

   Одна колонка на широком экране оставляла половину пустой, а всё
   содержимое уходило вниз на две прокрутки. */
.dash-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}
.dash-col { min-width: 0; }

/* Ниже 1024 точек мониторный вид не показывается вовсе — там отдаётся
   телефонная разметка. Правило на случай узкого окна: пока браузер не
   сообщил новую ширину, страница остаётся мониторной, и две колонки по
   трёхсот точек были бы нечитаемы. */
@media (max-width: 1023.98px) {
  .dash-columns { grid-template-columns: minmax(0, 1fr); }
}

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

   Здесь только кегль и поля: разметка, разбиение и подписи те же. */
@media (min-width: 1024px) {
  .table thead th { font-size: .8125rem; padding: .85rem 1.1rem; }
  .table tbody td { font-size: 1rem; padding: .9rem 1.1rem; }
  .cell-title { font-size: 1rem; }
  .cell-sub { font-size: .8125rem; }
}

/* ── Фон на мониторе ──
   На телефоне #f5f7fb достаточно: экран узкий, карточки занимают почти
   всю ширину, и граница видна. На мониторе они отличались от фона на
   три ступени и сливались с ним (замечание владельца).

   Меняется ТОЛЬКО на широком экране: на телефоне прежний фон верен, а
   более тёмный делал бы страницу мрачной. */
@media (min-width: 1024px) {
  body { background: #f0f2f6; }
}

/* Денежные средства: ссылка действия вместо числа, когда его нет. */
.dash-cash-link {
  flex-shrink: 0; font-size: .875rem; font-weight: 500; color: var(--brand);
}
/* Закрытая смена — янтарным: это не беда, а положение дел, которое
   мешает принять наличные. Красный оставлен просрочке. */
.dash-cash.closed { border-left: 3px solid #f79009; }
.dash-cash.closed .dash-cash-label { color: #b45309; }

/* ── Полоса состояния договора ──
   Менеджер считал, что «Сформировать договор» завершает оформление, и
   не понимал, почему платежи не принимаются. Полоса говорит это прямо
   и показывает один следующий шаг. */
.contract-next {
  display: flex; align-items: flex-start; gap: .75rem;
  background: #fff; border: 1px solid #eaecf0;
  border-left: 3px solid #f79009; border-radius: var(--card-radius);
  padding: .9rem 1rem; text-decoration: none; color: inherit;
}
.contract-next:hover { color: inherit; background: #fcfcfd; }
.contract-next > i:first-child { font-size: 1.15rem; color: #f79009; }
.contract-next.done { border-left-color: #12b76a; }
.contract-next.done > i:first-child { color: #12b76a; }
.contract-next-title { display: block; font-size: .95rem; font-weight: 600; }
.contract-next-note { display: block; font-size: .8125rem; color: #475467;
                      margin-top: .1rem; }

/* Метки шагов: где человек и сколько осталось. */
.contract-steps { display: flex; gap: .35rem; margin-top: .5rem;
                  flex-wrap: wrap; }
.contract-step {
  font-size: .72rem; padding: .15rem .55rem; border-radius: 20px;
  background: #f2f4f7; color: #98a2b3;
}
.contract-step.done { background: #dcfae6; color: #067647; }
.contract-step.now { background: #fef0c7; color: #b54708; font-weight: 600; }

/* Подсказка об упрощённом оформлении — мелко и неброско: это редкий
   выбор, а не рабочее действие. */
.contract-next-hint {
  display: inline-block; margin-top: .5rem; font-size: .75rem;
  color: #98a2b3; text-decoration: none;
}
.contract-next-hint:hover { color: var(--brand); }

/* Перечень подстановок бланка: в две колонки на широком экране —
   тридцать четыре строки столбцом читаются тяжело. */
.placeholder-list {
  list-style: none; margin: 0; padding: 0;
  font-size: .8125rem; line-height: 1.9;
}
.placeholder-list code { font-size: .78rem; }
@media (min-width: 768px) {
  .placeholder-list { columns: 2; column-gap: 2rem; }
  .placeholder-list li { break-inside: avoid; }
}

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

   Применяется ТОЛЬКО к сортировке и столбцам на странице договоров:
   новый приём вводится на одном месте, прочие меню не тронуты. */
.sheet-wrap { position: relative; display: inline-block; }

.sheet {
  display: none;
  position: absolute; right: 0; top: calc(100% + .35rem); z-index: 1030;
  min-width: 15rem; max-width: calc(100vw - 2rem);
  background: #fff; border: 1px solid #e5e9f2; border-radius: 10px;
  box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
  padding: .35rem;
}
.sheet-open .sheet { display: block; }

.sheet-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: .4rem .6rem .5rem; border-bottom: 1px solid #e5e9f2;
  margin-bottom: .35rem; font-weight: 600; font-size: .95rem;
}
.sheet-head [data-sheet-close] {
  border: none; background: none; color: #6b7280; font-size: .85rem;
  cursor: pointer; border-radius: 8px;
  /* Не меньше 44 точек: рядом другие пункты, и промах закроет не то. */
  min-width: 44px; min-height: 44px; margin: -.3rem -.4rem -.3rem 0;
}
.sheet-head [data-sheet-close]:hover { background: #f3f5f9; color: #111827; }

.sheet-title {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  color: #6b7280; padding: .4rem .6rem .3rem; font-weight: 600;
}
.sheet a, .sheet label {
  display: flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: .45rem .6rem; border-radius: 7px;
  font-size: .875rem; color: #374151; text-decoration: none; cursor: pointer;
}
.sheet a:hover, .sheet label:hover { background: #f3f5f9; }
.sheet a.on { color: #2563eb; font-weight: 600; }
.sheet a.on::after { content: "✓"; margin-left: auto; font-size: .8rem; }
.sheet input[type="checkbox"] { accent-color: #2563eb; width: 18px; height: 18px; }
.sheet .divider { height: 1px; background: #e5e9f2; margin: .3rem 0; }

@media (max-width: 767.98px) {
  /* Панель выезжает снизу на всю ширину. Затемнение позади: нажатие
     мимо закрывает — так ведут себя все нижние панели. */
  .sheet-open::before {
    content: ""; position: fixed; inset: 0; z-index: 1039;
    background: rgba(16, 24, 40, .35);
  }
  .sheet {
    position: fixed; left: 0; right: 0; top: auto;
    min-width: 0; max-width: none; width: 100%;
    border: none; border-radius: 16px 16px 0 0;
    box-shadow: 0 -8px 32px rgba(16, 24, 40, .18);

    /* ПАНЕЛЬ ВЫШЕ НИЖНЕЙ НАВИГАЦИИ.
       ═══════════════════════════════════════════════════════════════
       Навигация CRM95 стоит внизу с z-index 1035 и занимает не меньше
       72 точек. Панель с 1030 пряталась под ней: «По задолженности» и
       «По дате окончания» было не выбрать пальцем.

       Поднимаем панель выше и отодвигаем от низа на высоту навигации,
       чтобы она не перекрывала пункты. */
    z-index: 1040;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));

    /* ВЫСОТА С ОГЛЯДКОЙ НА НАВИГАЦИЮ.
       Прежде стояло 70vh — от всего окна, без учёта того, что снизу
       72 точки заняты. Панель уходила под навигацию нижними пунктами.

       Теперь: высота окна минус навигация, минус вырез, минус запас
       сверху, чтобы было видно затемнение и понятно, что панель
       поверх. */
    max-height: calc(100vh - 72px - env(safe-area-inset-bottom, 0px) - 4rem);

    /* Прокрутка ВНУТРИ панели: страница под ней заперта, а содержимое
       листается пальцем. */
    overflow-y: auto; -webkit-overflow-scrolling: touch;

    /* Запас снизу: без него последний пункт упирается в край, и палец
       попадает по краю панели, а не по ссылке. */
    padding: .5rem .5rem 1.25rem;
  }

  /* Затемнение тоже выше навигации: иначе она остаётся яркой поверх
     затемнённой страницы и выглядит доступной, хотя нажатие закроет
     панель. */
  .sheet-open::before { z-index: 1039; }
  .sheet-head::before {
    content: ""; position: absolute; top: .35rem; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: 2px; background: #d7dbe3;
  }
  /* Заголовок с кнопкой «Закрыть» ОСТАЁТСЯ НА ВИДУ при прокрутке:
     прокрутив список столбцов вниз, человек не должен искать, чем
     закрыть панель. */
  .sheet-head {
    position: sticky; top: 0; z-index: 1;
    padding-top: .9rem; background: #fff;
  }
}

/* Страница не едет под панелью: положение запоминается и
   восстанавливается при закрытии. */
body.sheet-locked {
  position: fixed; left: 0; right: 0; width: 100%; overflow: hidden;
}

/* ═══════════════════════════════════════════════════════════════════
   Карточка договора на телефоне
   ═══════════════════════════════════════════════════════════════════
   ВСЁ ЛОКАЛЬНО ДЛЯ ДОГОВОРОВ. Общий механизм .table-cards не тронут:
   он применяется в 62 разметках, и правка задела бы все.

   Правила висят на #contractsTable — другие таблицы их не видят. */

/* Состояние точкой, по образцу макета: значок заменён кружком, цвет
   говорит о состоянии, а слово читается целиком. */
#contractsTable .st {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .875rem; white-space: nowrap;
}
#contractsTable .st::before { content: "●"; font-size: .7rem; }
#contractsTable .st-active::before { color: #16a34a; }
#contractsTable .st-draft::before,
#contractsTable .st-ready::before,
#contractsTable .st-generated::before,
#contractsTable .st-awaiting::before,
#contractsTable .st-signed::before { color: #9aa3af; }
#contractsTable .st-closed::before { color: #9aa3af; }
#contractsTable .st-cancelled::before,
#contractsTable .st-terminated::before,
#contractsTable .st-archived::before { color: #4b5563; }
/* Просрочка — красным: менеджеру важнее увидеть её сразу, чем то, что
   договор формально действует (решение владельца 18.08.2026). */
#contractsTable .st-overdue::before { color: #b42318; }

/* ПРОСРОЧКА — ОТДЕЛЬНЫЙ ПРИЗНАК, а не второе состояние: договор при
   ней остаётся действующим, просрочен платёж. */
#contractsTable .flag-overdue {
  display: inline-block; margin-left: .4rem;
  padding: .05rem .4rem; border-radius: 5px;
  background: #fef3f2; color: #b42318;
  font-size: .72rem; font-weight: 600; white-space: nowrap;
}

/* Менеджер и дата окончания — только в карточке. На широком экране
   столбцов и так девять, добавлять два значило бы сжать остальные. */
#contractsTable .only-card { display: none; }

@media (max-width: 767.98px) {
  /* Порог тот же, что у общего механизма: 767.98px. Своего не
     заводится — иначе карточки договоров переключались бы не там, где
     все прочие. */
  #contractsTable .only-card { display: flex; }

  /* Номер договора крупнее прочего: с него начинают чтение карточки, и
     по нему открывают договор. */
  #contractsTable tbody .cell-title a {
    font-size: 1rem; display: inline-flex; align-items: center;
    min-height: 44px;
  }

  /* Задолженность отделена от суммы: это разные числа, и путать их
     дорого. */
  #contractsTable tbody td[data-label="Остаток"] > * { color: #b42318; }

  /* Просрочка переносится на свою строку, если не помещается рядом с
     состоянием: рвать её пополам нельзя. */
  /* ПОМЕТКА ПРОСРОЧКИ — СВОЕЙ СТРОКОЙ ПОД СОСТОЯНИЕМ.

     Ячейка карточки устроена в две колонки: подпись слева, значение
     справа. Пометка не помещалась рядом с «Действует» и вылезала за
     край карточки (замечание владельца 18.08.2026).

     Разрешаем перенос и отдаём пометке всю ширину значения — тогда она
     встаёт под состоянием, а не режется краем. */
  #contractsTable tbody td[data-label="Статус"] {
    flex-wrap: wrap; row-gap: .3rem;
  }
  /* СТРОКУ ЗАНИМАЕТ ОБЁРТКА, а не сама пометка.

     Прежде пометке задавалось «flex: 1 0 100%», и красный фон
     растягивался на всю ширину карточки — выходила полоса (замечание
     владельца 18.08.2026).

     Теперь всю ширину берёт пустая обёртка, а пометка внутри неё
     остаётся по ширине слов. */
  #contractsTable tbody td[data-label="Статус"] .overdue-line {
    flex: 1 0 100%;
    margin-left: 42%;
  }
  /* ПОДЛОЖКИ В КАРТОЧКЕ НЕТ (решение владельца 18.08.2026).

     Красный текст на белом читается сам по себе, а плашка только
     шумит: в строке и так есть красный кружок у «Просрочен».

     В таблице на широком экране подложка остаётся — там строки идут
     плотно, и пометке нужен свой вид. */
  #contractsTable tbody td[data-label="Статус"] .flag-overdue {
    margin-left: 0;
    background: none;
    padding: 0;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Верхняя панель договоров на телефоне
   ═══════════════════════════════════════════════════════════════════
   Прежде представления переносились на четыре строки, а «Фильтры»
   стояли отдельно от сортировки и столбцов. До первого договора
   приходилось прокручивать полторы высоты экрана.

   ВСЁ ЛОКАЛЬНО ДЛЯ ДОГОВОРОВ: правила висят на .views-row и
   .tools-row — эти имена есть только на странице договоров. Глобальные
   компоненты не тронуты. */

/* На широком экране представления переносятся, как было: там места
   довольно, и прокрутка была бы лишней.

   Класс flex-wrap снят с разметки — в Bootstrap у него «!important», и
   правило для телефона его не перебивало. Задаём перенос сами. */
@media (min-width: 768px) {
  #contractsPage .views-row { flex-wrap: wrap; }
}

@media (max-width: 767.98px) {

  /* ПРЕДСТАВЛЕНИЯ — ОДНА СТРОКА С ПРОКРУТКОЙ.

     Перенос отменяется: кнопки либо помещаются, либо уезжают за край,
     откуда их достают свайпом. Ни одна не рвётся пополам. */
  #contractsPage .views-row {
    flex-wrap: nowrap;
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    /* Полосу прокрутки прячем: она занимает место и на телефоне не
       нужна — там прокручивают пальцем. */
    scrollbar-width: none;
    /* Отступ снизу, чтобы кнопки не липли к следующему ряду. */
    padding-bottom: .15rem; margin-bottom: .5rem;
  }
  #contractsPage .views-row::-webkit-scrollbar { display: none; }

  /* Кнопка представления — единый элемент: не сжимается и не переносит
     текст. Иначе «Расторгнутые» рвётся пополам. */
  #contractsPage .views-row > a {
    flex: 0 0 auto; white-space: nowrap;
    /* Зона нажатия не меньше 44 точек. */
    min-height: 44px; display: inline-flex; align-items: center;
  }

  /* ИНСТРУМЕНТЫ — ОДИН РЯД.

     Три кнопки одного назначения не должны стоять на разных уровнях.
     На 320 точках они помещаются: по 100 точек на каждую. */
  #contractsPage .tools-row {
    flex-wrap: nowrap; align-items: flex-start;
    overflow-x: auto; scrollbar-width: none;
  }
  #contractsPage .tools-row::-webkit-scrollbar { display: none; }
  #contractsPage .tools-row > * { flex: 0 0 auto; }

  /* ПРОКРУТКА — ТОЛЬКО ДЛЯ КНОПОК. Раскрытая панель фильтров не должна
     ни уезжать со свайпом ряда, ни резаться его краем (дефект пойман
     владельцем 19.08.2026: свайп по ряду утаскивал панель, подписи
     полей срезались слева).

     Устройство: опорой панели назначается сама страница (позиция ниже),
     а не что-либо внутри прокручиваемого ряда, поэтому панель выходит
     из-под прокрутки и её обрезки по правилам CSS о вложенном overflow.
     Правило действует на ВЕСЬ телефонный диапазон — прежде жило только
     до 400 точек, и между 401 и 767 панель оставалась внутри ряда. */
  #contractsPage { position: relative; }
  #contractsPage .tools-row > details { position: static; }
  #contractsPage .tools-row > details > form {
    position: absolute; left: 0; right: 0; z-index: 5;
    margin-top: .5rem;
  }

  #contractsPage .tools-row .btn,
  #contractsPage .tools-row summary {
    white-space: nowrap; min-height: 44px;
    display: inline-flex; align-items: center; gap: .35rem;
    /* Отступы поуже обычных: три кнопки должны уместиться на 320. */
    padding-left: .6rem; padding-right: .6rem;
  }
}

/* На самых узких экранах убираем значки: слова «Фильтры», «Сортировка»,
   «Столбцы» понятны и без них, а три кнопки со значками не помещаются
   в 320 точек — считано: 376 против доступных 300.

   Прокрутка ряда осталась бы запасным путём, но кнопка, уехавшая за
   край, читается как «её нет». */
@media (max-width: 400px) {
  #contractsPage .tools-row .btn i,
  #contractsPage .tools-row summary i { display: none; }
  #contractsPage .tools-row .btn,
  #contractsPage .tools-row summary {
    padding-left: .5rem; padding-right: .5rem;
  }

  /* Позиционирование раскрытой панели переехало в общий телефонный
     блок выше (≤767.98): оно нужно на всём телефонном диапазоне, а не
     только до 400 точек (дефект 19.08.2026). */

  /* Применённые условия — своей строкой, с переносом: их бывает шесть,
     и в одну строку они не встанут. */
  #contractsPage .applied-row { flex-wrap: wrap; }
}

/* ═══════════════════════════════════════════════════════════════════
   Объяснение финансового результата
   ═══════════════════════════════════════════════════════════════════
   «Покрытие стоимости товара» отвечает на вопрос, но не на все: почему
   вообще часть, а не вся стоимость. Для этого — раскрываемое
   объяснение (решение владельца 21.08.2026).

   Свёрнуто по умолчанию: большинству довольно строки под итогом. */

/* Подписи частей: «Факт за период» и «Прогноз».

   Без них две суммы прибыли подряд сливаются в одну кучу, и человек не
   понимает, какая уже в кассе, а какая только ожидается. */
.fin-part {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: #6b7280; font-weight: 600; margin: .25rem 0 .5rem;
}

/* «ПРОГНОЗ» ДОЛЖЕН ЧИТАТЬСЯ КАК ПОДПИСЬ ЧАСТИ.
   На снимке владельца 21.08.2026 он выглядел обычной строкой: подписи
   заголовков в блоке крупнее, и мелкая подпись рядом с ними терялась.
   Прибавлен отступ сверху — часть отделяется от предыдущей. */
.fin-forecast .fin-part { margin-top: 0; }

/* Прогноз отделён чертой и приглушён: это не деньги в кассе, а
   обещание, и выглядеть как факт он не должен. */
.fin-forecast {
  margin-top: 1rem; padding-top: .9rem; border-top: 1px solid #e5e9f2;
}
.fin-forecast .fin-val {
  color: #4b5563; font-weight: 600; font-size: 1.05rem;
}
/* ПОДПИСЬ В ДВЕ СТРОКИ, СУММА — НА ВЕРХНЕЙ.

   «Ожидаемая прибыль по действующим договорам» в одну строку не
   помещается. Перенос нужен, но сумма должна остаться напротив первой
   строки: иначе взгляд ищет её внизу, где пусто. */
.fin-forecast .fin-row { align-items: flex-start; }
.fin-forecast .fin-key { line-height: 1.35; }

/* Строка пояснения под итогом. */
.fin-note {
  color: #6b7280; font-size: .8125rem;
  margin-top: .5rem; padding-top: .5rem;
  border-top: 1px dashed #e5e9f2;
}

/* Значок подсказки: знак, а не эмодзи — он одинаков на всех
   устройствах и не зависит от набора значков системы. */
.hint-mark {
  /* flex вместо inline-flex: у кнопки внутри строки высота line-height
     перебивала заданную, и круг выходил прямоугольником (снимок
     владельца 21.08.2026). */
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: 20px; min-width: 20px; height: 20px; line-height: 1;
  border-radius: 50%;
  border: 1px solid #e5e9f2; background: none; color: #6b7280;
  font-size: .7rem; font-weight: 700; cursor: pointer;
  vertical-align: middle; margin-left: .35rem; padding: 0;
}
.hint-mark:hover { border-color: #2563eb; color: #2563eb; }

.explain {
  background: #fbfcfe; border: 1px solid #e5e9f2; border-radius: 12px;
  padding: 1rem; margin-top: .75rem;
}
.explain h4 { margin: 0 0 .75rem; font-size: .95rem; }
.explain-line {
  display: flex; justify-content: space-between;
  padding: .3rem 0; gap: 1rem;
}
.explain-sub { margin: .5rem 0 .25rem; color: #6b7280; font-size: .8125rem; }
/* Черта слева показывает, что это части одной суммы, а не отдельные
   строки расчёта. */
.explain-inner { padding-left: .9rem; border-left: 2px solid #e5e9f2; }
.explain-final {
  margin-top: .75rem; padding-top: .75rem;
  border-top: 1px solid #e5e9f2;
  color: #6b7280; font-size: .8125rem; line-height: 1.5;
}
.explain .earned { color: #16a34a; font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════
   Сотрудники платформы: карточки вместо таблицы
   ═══════════════════════════════════════════════════════════════════
   Прежде страница была таблицей с кнопками в каждой строке: на
   телефоне она разъезжалась, а роли путались с действиями — две
   подписи «Роли» подряд (замечание владельца 21.08.2026).

   Теперь карточка отвечает на четыре вопроса: кто это, какая почта,
   работает ли доступ, какие роли. Управление — отдельным экраном.

   ВСЁ ЛОКАЛЬНО: правила висят на #staffPage. */

#staffPage .staff-search { display: flex; gap: .5rem; }
#staffPage .staff-search input { max-width: 22rem; }

#staffPage .person-card {
  display: flex; gap: .85rem; align-items: flex-start;
  background: #fff; border-radius: 16px; padding: 1rem;
  margin-bottom: .75rem; text-decoration: none; color: inherit;
  box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
  /* Вся карточка нажимается — значит она должна быть удобной для
     пальца целиком, а не только ссылкой внутри. */
  min-height: 120px;
}
#staffPage .person-card:hover { background: #fbfcfe; }

/* Буква вместо снимка: снимков у сотрудников платформы нет, а пустой
   кружок выглядел бы недоделкой. */
#staffPage .person-avatar {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%;
  background: #eef2ff; color: #2563eb;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1.05rem;
}
#staffPage .person-avatar.off { background: #f3f4f6; color: #9aa3af; }

#staffPage .person-body { flex: 1; min-width: 0; }

#staffPage .person-name {
  font-weight: 600; font-size: 1.02rem; line-height: 1.3;
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
}

/* Почта обрезается, имя переносится: по имени узнают человека, а
   полная почта видна в карточке сотрудника. */
#staffPage .person-mail {
  color: #6b7280; font-size: .8125rem; margin: .1rem 0 .6rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

#staffPage .person-state {
  display: flex; align-items: center; gap: .4rem;
  font-size: .875rem; margin-bottom: .6rem;
}
#staffPage .person-state::before { content: "●"; font-size: .7rem; }
#staffPage .person-state.active { color: #16a34a; }
#staffPage .person-state.off { color: #9aa3af; }
#staffPage .person-state.waiting { color: #d97706; }
#staffPage .person-state.waiting::before { content: "◷"; }

#staffPage .person-roles { display: flex; flex-wrap: wrap; gap: .3rem; }
#staffPage .person-role {
  border: 1px solid #e5e9f2; border-radius: 8px;
  padding: .15rem .5rem; font-size: .75rem; color: #4b5563;
  background: #fbfcfe;
}
#staffPage .person-role.more { color: #9aa3af; }

/* Метка «это вы» — сведения, а не действие: потому бледная. */
#staffPage .person-me {
  background: #eef2ff; color: #2563eb; border-radius: 6px;
  padding: .05rem .4rem; font-size: .68rem; font-weight: 600;
}

/* Стрелка подсказывает, что карточка открывается; нажимается вся. */
#staffPage .person-chev {
  color: #9aa3af; align-self: center; flex: 0 0 auto; font-size: 1.2rem;
}

@media (max-width: 767.98px) {
  #staffPage .staff-search { flex-wrap: nowrap; }
  #staffPage .staff-search input { max-width: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   Форма обращения в поддержку
   ═══════════════════════════════════════════════════════════════════
   Прежде форма лежала в белой карточке, а в ней белые поля: границы
   сливались, и всё выглядело тяжёлым (замечание владельца 22.08.2026).

   Теперь: фон страницы → заголовок → группы → поля → закреплённое
   действие. Поля белые НА СЕРОМ, и границы видны сами.

   ВСЁ ЛОКАЛЬНО: правила висят на #supportForm. */

#supportForm .form-back {
  display: inline-flex; align-items: center; gap: .35rem;
  color: #6b7280; text-decoration: none; font-size: .875rem;
  /* Область нажатия для пальца: ссылка мелкая, а промахнуться легко. */
  min-height: 44px;
}
#supportForm .form-back:hover { color: #2563eb; }

#supportForm .form-title { font-size: 1.35rem; margin: 0 0 1.25rem; }

#supportForm .form-group { margin-bottom: 1.5rem; }
#supportForm .form-group-title {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: #6b7280; font-weight: 600; margin: 0 .15rem .6rem;
}
#supportForm .form-group-note {
  color: #6b7280; font-size: .8125rem; margin: -.35rem .15rem .6rem;
}

#supportForm .form-field { margin-bottom: .9rem; }
#supportForm .form-field label {
  display: block; color: #4b5563; font-size: .8125rem;
  margin-bottom: .3rem; padding-left: .15rem;
}
#supportForm .form-field .form-control,
#supportForm .form-field .form-select {
  border-radius: 12px; padding: .7rem .85rem; font-size: .95rem;
  /* Поле на телефоне должно быть удобным для пальца. */
  min-height: 48px;
}
#supportForm .form-field textarea.form-control {
  min-height: 120px; line-height: 1.45;
}
/* ОШИБКА ПОЛЯ.
   Под своим полем, а не общей строкой сверху: с общей человек ищет,
   к чему она относится, — особенно когда полей четыре. */
#supportForm .form-field.has-error .form-control,
#supportForm .form-field.has-error .form-select {
  border-color: #f0a3a3; background: #fffafa;
}
#supportForm .form-error {
  color: #b42318; font-size: .8125rem; margin-top: .3rem;
  padding-left: .15rem;
}

#supportForm .form-hint {
  color: #6b7280; font-size: .8125rem; margin-top: .35rem;
  padding-left: .15rem;
}

/* ЗАКРЕПЛЁННОЕ ДЕЙСТВИЕ.

   sticky, а не fixed: fixed вырывает кнопку из страницы и накрывает
   нижнее меню. sticky держит её НАД меню и не мешает прокрутке.

   Отступ снизу равен высоте нижнего меню плюс безопасная область —
   то же число, что у нижней панели (см. правку 18.08.2026, когда
   пункты уходили под навигацию). */
#supportForm .form-footer {
  position: sticky;
  bottom: calc(72px + env(safe-area-inset-bottom));
  margin: 1.5rem -1rem 0; padding: .85rem 1rem;
  background: #fff; border-top: 1px solid #e5e9f2;
  box-shadow: 0 -2px 8px rgba(16, 24, 40, .06);
  z-index: 5;
}
#supportForm .form-footer .btn {
  width: 100%; border-radius: 12px; padding: .85rem;
  font-size: 1rem; font-weight: 600; min-height: 52px;
}

/* На широком экране нижнего меню нет — кнопка прижимается к низу
   окна, а не висит над пустотой. */
@media (min-width: 768px) {
  #supportForm .form-footer {
    position: static; margin: 1.5rem 0 0; padding: 1rem 0 0;
    background: none; box-shadow: none;
  }
  #supportForm .form-footer .btn { width: auto; min-width: 14rem; }
}

/* Крестик у вложения: заметный, но не громкий.
   «btn-sm» к btn-close не применяется — в Bootstrap такого сочетания
   нет, и крестик выходил еле видным (замечание владельца 22.08.2026). */
.attach-remove {
  --bs-btn-close-opacity: .5;
  width: .75rem; height: .75rem; padding: .4rem;
  flex: 0 0 auto;
}
.attach-remove:hover { --bs-btn-close-opacity: 1; }

/* Выбранные файлы: список с крестиками до отправки.
   Поле выбора показывает лишь «2 файла» и не даёт ни убрать один, ни
   добавить третий (замечание владельца 22.08.2026). */
.chosen-files { margin-top: .5rem; }
.chosen-file {
  display: flex; align-items: center; gap: .5rem;
  background: #fff; border: 1px solid #e5e9f2; border-radius: 10px;
  padding: .5rem .7rem; margin-bottom: .4rem; font-size: .875rem;
}
.chosen-file .name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chosen-file .size { color: #6b7280; font-size: .8125rem; }

/* ═══════════════════════════════════════════════════════════════════
   Карточка договора: остаток долга главным числом
   ═══════════════════════════════════════════════════════════════════
   Прежде он стоял в ряду одинаковых карточек и весил столько же,
   сколько первый взнос (решение владельца 22.08.2026). А открывают
   договор именно ради него. */

.contract-money { padding: 1.15rem 1rem; }
.contract-money-cap {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: #6b7280; font-weight: 600; margin-bottom: .4rem;
}
.contract-money-sum { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.contract-money-note { color: #6b7280; font-size: .8125rem; }

/* Ход оплаты: «26 000» без доли непонятно — много это или мало. */
.contract-bar {
  height: 8px; background: #eef1f6; border-radius: 4px;
  overflow: hidden; margin: .9rem 0 .5rem;
}
.contract-bar span {
  display: block; height: 100%; background: #16a34a; border-radius: 4px;
}
/* Просрочка меняет цвет полосы: состояние в шапке видно не сразу, а
   полоса рядом с суммой. */
.contract-bar.late span { background: #b42318; }

/* Справочные числа: спокойные строки, а не карточки наравне с
   остатком долга. Прежде их было четыре одинакового веса, и остаток
   терялся среди них. */
.contract-facts { padding: .35rem 1rem; }
.contract-fact {
  display: flex; align-items: baseline; gap: 1rem;
  padding: .7rem 0; border-bottom: 1px solid #f1f4f9;
}
.contract-fact:last-child { border-bottom: 0; }
.contract-fact .k { color: #6b7280; flex: 1; }
.contract-fact .v { font-weight: 600; text-align: right; }

@media (max-width: 575.98px) {
  .contract-money-sum { font-size: 1.75rem; }
}
