:root {
  --bg: #f2f5f8;
  --panel: #ffffff;
  --ink: #0e1726;
  --ink2: #3f4f66;
  --muted: #7789a0;
  --line: #e4e9f0;
  --line2: #eef2f7;
  --accent: #0d7c66;
  --accent2: #0a5f4e;
  --soft: #e6f4ef;
  --good: #15803d;
  --warn: #b45309;
  --crit: #be123c;
  --won-bg: #e7f4ec;
  --won-fg: #146c39;
  --work-bg: #e9f0fb;
  --work-fg: #1d4ed8;
  --off-bg: #f0f2f5;
  --off-fg: #64748b;
  --warn-bg: #fff7ed;
  --warn-line: #f3dcbd;
  --crit-bg: #fdf2f4;
  --crit-line: #f5c6d2;
  --shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 1px 3px rgba(16, 24, 40, .05);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 14px/1.5 -apple-system, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
}

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 24px 64px;
}

a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
a:hover { text-decoration: underline; }

.head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
}

.drop {
  width: 12px;
  height: 12px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  flex: none;
  box-shadow: 0 0 0 4px var(--soft);
}

h1 {
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -.01em;
  margin: 0;
}

.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 3px;
}

.head-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

.meta {
  text-align: right;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.45;
}
.meta b { color: var(--ink2); font-weight: 600; }

.user-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 12.5px;
}
.user-meta b { color: var(--ink2); font-weight: 600; }
.logout-form { display: inline-flex; margin: 0; }
/* POST-кнопка внутри строки таблицы (деактивация счёта и т.п.) */
.inline-form { display: inline-flex; margin: 0; }

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 24px;
}
.nav a {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink2);
  text-decoration: none;
}
.nav a:hover { background: var(--line2); text-decoration: none; }
.nav a[aria-current="page"] {
  background: var(--soft);
  color: var(--accent2);
}

.messages {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: grid;
  gap: 8px;
}
.msg {
  padding: 11px 16px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--panel);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink2);
  box-shadow: var(--shadow);
}
.msg.success { background: var(--won-bg); border-color: #cbe7d6; color: var(--won-fg); }
.msg.info { background: var(--work-bg); border-color: #cfdcf5; color: var(--work-fg); }
.msg.warning { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.msg.error { background: var(--crit-bg); border-color: var(--crit-line); color: var(--crit); }

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 12px;
  margin-bottom: 30px;
}
.kpi {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 15px 16px;
  box-shadow: var(--shadow);
}
.kpi .lbl {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .055em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.kpi .val {
  font-size: 25px;
  font-weight: 660;
  letter-spacing: -.02em;
  line-height: 1;
}
.kpi .val small {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  margin-left: 3px;
}
.kpi .sub { font-size: 12px; color: var(--muted); margin-top: 6px; }
.kpi.lead {
  background: linear-gradient(180deg, var(--soft), var(--panel));
  border-color: color-mix(in srgb, var(--accent) 26%, var(--line));
}
.kpi.lead .val { color: var(--accent2); }

h2 {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 26px 0 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
h2::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.panel > p { padding: 16px 18px; margin: 0; }

.scroll { overflow-x: auto; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
thead th {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: right;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--line2);
}
thead th:first-child { text-align: left; }
tbody td, tbody th {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line2);
  text-align: right;
}
tbody th { text-align: left; font-weight: 600; }
tbody tr:hover td, tbody tr:hover th {
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.strong { font-weight: 660; }
.comm { color: var(--accent2); font-weight: 600; }

tr.total th, tr.total td {
  border-top: 2px solid var(--line);
  border-bottom: none;
  font-weight: 660;
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}

tr.cancelled th, tr.cancelled td { color: var(--muted); }
tr.cancelled .strong { text-decoration: line-through; text-decoration-color: var(--muted); }

.drr { white-space: nowrap; min-width: 116px; }
.dv { font-weight: 600; font-size: 12.5px; }
.dv.good { color: var(--good); }
.dv.warn { color: var(--warn); }
.dv.crit { color: var(--crit); }
.dv.na { color: var(--muted); }

.tag {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}
.tag.won { background: var(--won-bg); color: var(--won-fg); }
.tag.work { background: var(--work-bg); color: var(--work-fg); }
.tag.off { background: var(--off-bg); color: var(--off-fg); }

.note {
  color: var(--muted);
  font-size: 12px;
  padding: 11px 16px;
  background: var(--line2);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.note b { color: var(--ink2); }
.panel .note {
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
}
p.note { margin: 0 0 20px; }
.note.crit {
  color: #9f1239;
  background: var(--crit-bg);
  border-color: var(--crit-line);
}
.note.crit b { color: #9f1239; }
.panel .note.crit { border: 0; }

.mono { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink2); }
.dim { color: var(--muted); font-weight: 400; }

.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--good);
  margin-right: 7px;
  vertical-align: middle;
}

.mb { margin-bottom: 30px; }

p.warn, span.warn, li.warn { color: var(--warn); font-weight: 600; font-size: 13px; }
p.good { color: var(--good); font-weight: 600; font-size: 13px; }

label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink2);
  margin-bottom: 4px;
}

input[type="text"],
input[type="date"],
input[type="number"],
input[type="password"],
input[type="email"],
select,
textarea {
  width: 100%;
  max-width: 380px;
  padding: 9px 12px;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  outline: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--soft);
}
input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  vertical-align: -2px;
}
textarea { min-height: 72px; resize: vertical; }

button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 9px 18px;
  font: 600 13.5px/1 inherit;
  font-family: inherit;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent2);
  border-radius: 10px;
  cursor: pointer;
}
button:hover { background: var(--accent2); }
button:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }

button.danger { background: var(--crit); border-color: #9f1239; }
button.danger:hover { background: #9f1239; }

button.ghost {
  background: transparent;
  color: var(--ink2);
  border-color: var(--line);
}
button.ghost:hover { background: var(--line2); }

button.sm { min-height: 30px; padding: 5px 12px; font-size: 12px; border-radius: 8px; }

.btn-link {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink2);
  font-size: 13.5px;
  background: var(--panel);
}
.btn-link:hover { background: var(--line2); text-decoration: none; }

.errorlist {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  color: var(--crit);
  font-size: 12.5px;
  font-weight: 600;
}
.field .errorlist { margin-top: 4px; }
form > .errorlist { margin: 0 0 12px; }

.form-panel { padding: 20px; }
.form-panel form { margin: 0; }
.form-panel .field { margin: 0 0 14px; }
.form-panel p.field { margin-top: 0; }
.form-panel .field .dim { display: block; font-size: 12px; margin-top: 3px; max-width: 380px; }
.form-panel button { margin-top: 4px; }
.form-panel form > a { margin-left: 10px; }
.form-panel .note { margin: 18px -20px -20px; }

.filter-panel { padding: 16px 20px; }
.filter-panel form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin: 0;
}
.filter-panel .field {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 140px;
}
.filter-panel input, .filter-panel select { max-width: 200px; }
.filter-panel form > a { padding-bottom: 10px; }

/* Форма прямо в ячейке таблицы («завершить членство»): раньше ширина
   поля задавалась инлайном, и на телефоне пара «дата + кнопка» не
   помещалась в карточку, растягивая её вбок. */
.inline-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
}

.inline-form input[type="date"] { max-width: 150px; }

/* Полоса величины: одна мера, длина = доля от максимума ряда. Числа
   напечатаны рядом текстом, поэтому сама полоса — подкрепление, а не
   единственный носитель смысла (aria-hidden). Цвет — та же пара
   «должны / на руках», что и у вердиктов: третьей палитры в кабинете
   заводить незачем. */
.bar {
  height: 8px;
  margin: 6px 0 0;
  border-radius: 999px;
  background: var(--line2);
  overflow: hidden;
}

.bar > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--muted-strong);
}

.bar--owed > span { background: var(--owed-fg); }
.bar--holding > span,
.bar--hold > span { background: var(--hold-fg); }
.bar--settled > span { background: var(--muted); }

/* Мера «сколько начисленного уже закрыто деньгами»: тот же элемент, но
   шкала фиксированная (0…100 %), поэтому у неё своё имя. */
.meter {
  height: 6px;
  margin: 4px 0 0;
  border-radius: 999px;
  background: var(--line2);
  overflow: hidden;
}

.meter > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* Выбор периода — ВВЕРХУ дашборда и без раскрытия: «а что было в
   прошлом месяце» спрашивают первым делом (слово владельца 31.07.2026:
   «период не выставляется в дашборде, это дико неудобно»). */
.period-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin: 0 0 22px;
  padding: 12px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}

.period-now {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink2);
}

.period-now b { font-variant-numeric: tabular-nums; }

.period-bar .presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

.period-bar .presets a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  color: var(--ink2);
}

.period-bar .presets a:hover {
  background: var(--soft);
  border-color: var(--accent);
  color: var(--accent2);
  text-decoration: none;
}

.period-bar .presets a[aria-current] {
  background: var(--soft);
  border-color: var(--accent);
  color: var(--accent2);
  font-weight: 600;
}

.period-range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
  margin-left: auto;
}

.period-range label { margin: 0; font-size: 12.5px; color: var(--muted-strong); }
.period-range input { max-width: 165px; min-height: 34px; }
.period-bar .period-fallback { flex-basis: 100%; margin: 0; }
.period-bar .errorlist { flex-basis: 100%; margin: 0; }

/* «За всё время» — выход из дефолтного окна (01.08.2026). Отделён от
   пресетов пунктиром: это не «ещё один период», а снятие отбора, и
   выглядеть как шестая равноправная кнопка он не должен. */
.period-bar .presets .preset-all { border-style: dashed; }
.period-range .period-hint {
  flex-basis: 100%;
  font-size: 12.5px;
  color: var(--muted-strong);
}

.period-picker {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 16px 20px;
  margin-bottom: 24px;
}
.period-picker form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin: 0;
}
.period-picker label { margin-bottom: 4px; }
.period-picker input { max-width: 170px; }
.period-picker .presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 12px 0 0;
}
.period-picker .presets a {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink2);
}
.period-picker .presets a:hover { background: var(--soft); border-color: var(--accent); color: var(--accent2); text-decoration: none; }
.period-picker .period-fallback { margin: 12px 0 0; }

.anomalies {
  background: var(--warn-bg);
  border-color: var(--warn-line);
}
.anomalies ul {
  list-style: none;
  margin: 0;
  padding: 6px 0;
}
.anomalies .anomaly {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 10px 20px;
}
.anomalies .anomaly + .anomaly { border-top: 1px solid var(--warn-line); }
.anomalies .anomaly .lbl { font-size: 13px; font-weight: 600; color: var(--warn); }
.anomalies .anomaly .num { color: var(--ink); }
.anomalies .note { border-top-color: var(--warn-line); background: transparent; }

.actions { padding: 20px; }
.actions .action { margin: 0; }
.actions .action + .action { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line2); }
.actions .action > .dim { display: inline-block; margin-left: 10px; font-size: 12px; }
.actions ul { margin: 6px 0 12px; padding-left: 20px; }
.actions .field { margin: 10px 0 12px; }

.drift { padding-top: 0; }
.drift > p { padding: 16px 20px 6px; margin: 0; }

.pagination {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 20px;
}
.pagination a {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink2);
  font-size: 13px;
}
.pagination a:hover { background: var(--line2); text-decoration: none; }

.login-wrap {
  max-width: 460px;
  padding-top: 8vh;
}
.login-wrap .head { border-bottom: 0; margin-bottom: 8px; }
.login-wrap .form-panel { padding: 24px; }
.login-wrap button { width: 100%; margin-top: 6px; }
.login-wrap input { max-width: none; }
.login-wrap .form-panel .note { margin: 20px -24px -24px; }

/* Выход со страницы 403: главный ход — свой кабинет, а не повторный
   вход. Кнопка во всю ширину панели — на телефоне это единственная
   цель нажатия на экране. */
.denied-actions { margin: 16px 0 0; }
.btn-home {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid var(--accent2);
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  font-size: 14px;
}
.btn-home:hover { background: var(--accent2); color: #fff; text-decoration: none; }
.btn-home:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }

@media (prefers-reduced-motion: no-preference) {
  .kpi, .panel, .period-picker { animation: rise .4s ease both; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 640px) {
  .wrap { padding: 20px 14px 48px; }
  .head { align-items: flex-start; flex-direction: column; }
  .head-right { align-items: flex-start; }
  .meta { text-align: left; }
  .kpi .val { font-size: 22px; }
  .form-panel, .filter-panel, .actions { padding: 16px; }
  .form-panel .note { margin: 16px -16px -16px; }
  .actions .action > .dim { display: block; margin: 8px 0 0; }
  .login-wrap { padding-top: 4vh; }
  .login-wrap .form-panel { padding: 18px; }
  .login-wrap .form-panel .note { margin: 16px -18px -18px; }
}

/* P6c: баланс счёта партнёра — цвет в обе стороны (плюс/минус). */
.kpi .val.pos { color: var(--good); }
.kpi .val.neg { color: var(--crit); }
td.num.pos { color: var(--good); }
td.num.neg { color: var(--crit); }

/* ===== P7c: ДДС — плитки сценариев и модалки ввода/правки ==================
   Плитки: крупные цели нажатия (мобильный ввод «на ходу»), в колонку на
   узком экране. Модалка: нативный <dialog>; открытая СЕРВЕРОМ (фолбэк
   без JS) выглядит обычной панелью — поэтому оформление одинаково и в
   модальном, и в инлайновом виде. */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 84px;
  padding: 16px 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}
.tile:hover {
  border-color: var(--accent);
  background: linear-gradient(180deg, var(--soft), var(--panel));
  text-decoration: none;
}
.tile-name { font-size: 14.5px; line-height: 1.3; }
.tile-go {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent2);
  margin-top: auto;
}

dialog.cf-modal {
  width: min(560px, calc(100vw - 32px));
  max-height: min(88vh, 900px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 10px 30px rgba(16, 24, 40, .16);
  overflow: auto;
}
dialog.cf-modal::backdrop { background: rgba(14, 23, 38, .38); }
/* Диалог, открытый СЕРВЕРОМ (фолбэк без JS): UA-стиль делает открытый
   dialog абсолютно позиционированным — он лёг бы поверх ленты. Возвращаем
   его в поток: без скриптов это просто панель с формой на своём месте. */
dialog.cf-modal[open]:not(:modal) {
  position: static;
  width: auto;
  max-width: 100%;
  max-height: none;
  margin: 0 0 24px;
}

.cf-modal-form { margin: 0; }
.cf-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
}
.cf-modal-head h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.cf-modal-close {
  font-size: 20px;
  line-height: 1;
  color: var(--muted);
  padding: 2px 6px;
}
.cf-modal-close:hover { color: var(--ink); text-decoration: none; }
.cf-modal-hint {
  margin: 0;
  padding: 12px 20px 0;
  font-size: 12.5px;
  color: var(--muted);
}
.cf-modal-body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 4px 16px;
  padding: 16px 20px;
}
.cf-modal-body .field { margin: 0 0 12px; }
.cf-modal-body .field.wide { grid-column: 1 / -1; }
.cf-modal-body input, .cf-modal-body select, .cf-modal-body textarea { max-width: none; }
.cf-modal-body .dim { display: block; font-size: 11.5px; margin-top: 3px; }
/* Способ платежа — кнопки-переключатели в строку (Django рендерит
   RadioSelect блочным div'ом со вложенными label). */
.cf-modal-body [id$="_method"] {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 2px;
}
.cf-modal-body [id$="_method"] > div { display: inline-flex; align-items: center; gap: 5px; }
.cf-modal-body [id$="_method"] label { display: inline; margin: 0; font-weight: 500; font-size: 13px; }
.cf-modal-body .errorlist { list-style: none; margin: 4px 0 0; padding: 0; }
.cf-modal-body .errorlist li { display: block; margin: 0; }
.cf-modal-form > .errorlist { margin: 12px 20px 0; }
/* Кнопка «Внести» всегда на виду: у длинных сценариев (депозит) форма
   выше окна, и без липкого подвала до неё надо было доскроллить. */
.cf-modal-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 18px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}

/* Лента: компактные строки, чтобы действия («Исправить»/«Удалить») были
   видны без горизонтального скролла — это главное, чего не хватало
   владельцу. Автор и контрагент ушли второй строкой в свои колонки. */
.cf-feed { font-size: 13px; }
.cf-feed tbody td, .cf-feed tbody th { padding: 9px 10px; }
.cf-feed .sub-line { display: block; font-size: 11px; margin-top: 2px; }
/* Действия строки — столбиком: три ссылки в ряд уезжали за край панели
   (пробе: лента на 1440px), а именно они и есть новая функциональность. */
/* Колонка действий ПРИЛИПАЕТ к правому краю: лента шире экрана на
   мобильном и на длинных комментариях — иначе «Исправить»/«Удалить»
   уезжали бы за край и находились только горизонтальным скроллом. */
.cf-feed th:last-child,
.cf-feed td:last-child {
  position: sticky;
  right: 0;
  z-index: 1;
  box-shadow: -6px 0 8px -8px rgba(16, 24, 40, .35);
}
.cf-feed thead th:last-child { background: var(--line2); }
.cf-feed tbody td:last-child { background: var(--panel); }
.cf-feed .row-actions { width: 104px; }
.cf-feed .row-actions .btn-link {
  display: flex;
  justify-content: center;
  margin: 0 0 4px;
  min-height: 26px;
  padding: 4px 8px;
  font-size: 11.5px;
  border-radius: 8px;
}
.cf-feed .row-actions .btn-link:last-child { margin-bottom: 0; }
.cf-feed .row-actions .dim { display: block; font-size: 11px; white-space: normal; text-align: left; }
.cf-feed td.comment { max-width: 190px; white-space: normal; }
.kpi .val.dim { color: var(--muted); font-size: 18px; }
.kpi .sub.warn { color: var(--warn); }

@media (max-width: 640px) {
  .tiles { grid-template-columns: 1fr; }
  dialog.cf-modal {
    width: 100vw;
    max-width: 100vw;
    max-height: 100vh;
    height: 100%;
    border-radius: 0;
    border: 0;
    margin: 0;
  }
  .cf-modal-body { grid-template-columns: 1fr; }
}

/* P7a: корректировки базы расчёта — ленточные действия в строке таблицы. */
.btn-link.sm {
  min-height: 30px;
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 8px;
}
.row-form {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 6px 0 0;
}
.row-form input[type="text"] { max-width: 180px; min-height: 30px; font-size: 12px; }
form.mt { margin-top: 18px; }
/* Скрытая подпись поля: доступность (лейбл есть, визуально не мешает). */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* P7d: раздел «Сделки» — список сделок Amo с атрибуцией и деньгами.
   Ячейки таблицы двухэтажные: главное значение сверху, уточнение
   (телефон, тег города, «было» до правки) — строкой ниже мелким. */
.sub-line {
  display: block;
  font-size: 11.5px;
  line-height: 1.35;
  margin-top: 3px;
  font-weight: 400;
}
.kpi.alarm .val { color: var(--warn); }
.kpi.alarm { border-color: var(--warn-line); }
/* Кликабельный счётчик (31.07.2026): дефолт прячет несопоставленные, и
   цифра дыры обязана быть входом в неё. Цвет не трогаем — он несёт
   смысл (тревожный/обычный), поэтому «ссылочность» показана пунктирным
   подчёркиванием, а не перекраской в синий. */
.kpi .val a {
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
}
.kpi .val a:hover,
.kpi .val a:focus-visible { text-decoration-style: solid; }
/* Пояснение над плиткой счётчиков: что именно они считают. */
.kpi-scope { margin: -4px 0 14px; max-width: 70ch; line-height: 1.5; }
/* Проблемы строки (31.07.2026): бейджи под номером сделки. Компактно и
   без заливки строки целиком — проблем у сделки бывает несколько сразу,
   и раскраска строк превратила бы таблицу в светофор. Цвет — тревожный,
   но приглушённый: это пометка «здесь разобрать», а не ошибка системы. */
.problem-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 5px;
  max-width: 190px;
}
.problem-badge {
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .01em;
  padding: 2px 6px;
  border-radius: 5px;
  white-space: nowrap;
  color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
}
/* Текстовые колонки таблицы сделок читаются слева (числовые — .num). */
table.deals td.city-cell,
table.deals td.deal-cell,
table.deals td.partner-cell { text-align: left; }
table.deals td.deal-cell { white-space: nowrap; }
table.deals td .tag { white-space: nowrap; }
/* Чекбоксы в панели фильтров: подпись рядом с квадратиком, а не над ним. */
.filter-panel .field.check {
  flex-direction: row;
  align-items: center;
  gap: 7px;
  min-width: 0;
  padding-bottom: 9px;
}
.filter-panel .field.check input { margin: 0; }

@media (max-width: 640px) {
  /* Узкий экран: панель фильтров в одну колонку, поля во всю ширину —
     иначе селект города обрезается в 140-пиксельную колонку. */
  .filter-panel form { flex-direction: column; align-items: stretch; gap: 10px; }
  .filter-panel .field { min-width: 0; }
  .filter-panel input, .filter-panel select { max-width: none; }
  .filter-panel .field.check { justify-content: flex-start; padding-bottom: 0; }
  .filter-panel form > a { padding-bottom: 0; }
  /* На узком экране таблица сделок переключается в карточки
     (mobile.css, .cards), и минимальная ширина колонок ей мешала бы:
     карточка обязана укладываться в экран, а не скроллиться вбок.
     Слово владельца 31.07.2026: «сделки в виде таблицы на мобильных
     лучше карточками, будет удобнее смотреть». */
  table.deals:not(.cards) { min-width: 720px; }
}

/* «В работе» (30.07.2026) — ОЖИДАНИЕ, а не деньги периода. Оформление
   намеренно приглушённое и пунктирное: цифру нельзя спутать с рублями
   расчёта, стоящими рядом. Ни KPI-карточка, ни таблица не используют
   акцентные «денежные» цвета. */
.kpi.pending {
  border-style: dashed;
  background: var(--panel);
}
.kpi.pending .val { color: var(--muted); }
.pending-block { margin-top: 18px; }
table.pending caption {
  caption-side: top;
  text-align: left;
  padding: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .055em;
  text-transform: uppercase;
  color: var(--muted);
}
table.pending { border: 1px dashed var(--line); border-radius: 10px; }
table.pending th[scope="row"] { text-align: left; font-weight: 600; }
table.pending td { color: var(--muted); }
table.pending tr.total td.strong { color: var(--ink); }
/* Статус сделки: РЕАЛЬНОЕ имя стадии Amo сверху, категория и воронка —
   строкой ниже. Категория осталась цветом, но не таблеткой: имена стадий
   бывают в три слова («В РАБОТЕ ПЕРЕГОВОРЫ»), и таблетка либо растягивала
   бы таблицу, либо переносилась бы уродливым блоком. Цвет несёт точка. */
table.deals td.status-cell { text-align: left; max-width: 200px; }
.status-name { font-weight: 600; }
.status-name::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: 1px;
  background: currentColor;
}
.status-name.won { color: var(--won-fg); }
.status-name.work { color: var(--work-fg); }
.status-name.off { color: var(--off-fg); }
/* ===== Кабинет Игоря: числа, произнесённые словами ========================
   Слой добавлен целиком в конец файла и ничего выше не переписывает.

   Смысловая находка раздела: знак суммы означает РАЗНОЕ. Плюс — клиника
   должна (цвет акцента, «деньги идут ко мне»), минус — на руках лежат
   чужие деньги (охра «придержано»), и это НЕ убыток, поэтому красный
   --crit здесь не используется: он занят настоящими ошибками. */

:root {
  --owed-fg: #0a5f4e;
  --owed-bg: #e9f5f1;
  --owed-line: #bfe0d6;
  --hold-fg: #7c4a12;
  --hold-bg: #fdf5e8;
  --hold-line: #ecd8b4;
  /* Объяснения — содержание раздела, а не служебная подпись: --muted
     даёт на белом 3,6:1 и не проходит WCAG AA для мелкого текста.
     Здесь 5,1:1 — читается, но по-прежнему уходит на второй план. */
  --muted-strong: #5d6f88;
}

.verdict {
  position: relative;
  padding: 26px 30px 24px;
  margin-bottom: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--muted);
  border-radius: 16px;
  box-shadow: var(--shadow);
}
.verdict--owed {
  border-left-color: var(--owed-fg);
  background: linear-gradient(105deg, var(--owed-bg), var(--panel) 62%);
}
.verdict--holding {
  border-left-color: var(--hold-fg);
  background: linear-gradient(105deg, var(--hold-bg), var(--panel) 62%);
}

.verdict-when {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted-strong);
}

.verdict h2.verdict-said {
  display: block;
  margin: 0;
  max-width: 34ch;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--ink);
}
.verdict h2.verdict-said::after { content: none; }

.verdict-figure {
  margin: 4px 0 0;
  font-size: clamp(44px, 5.2vw, 64px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.verdict--owed .verdict-figure { color: var(--owed-fg); }
.verdict--holding .verdict-figure { color: var(--hold-fg); }
.verdict-cur {
  margin-left: .12em;
  font-size: .38em;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--muted);
}

.verdict-why { margin: 12px 0 0; }
.verdict-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 18px 0 0;
}
.verdict-actions .btn-link { font-weight: 600; }

.verdict--compact { padding: 20px 24px 18px; }
.verdict--compact .verdict-figure { font-size: clamp(32px, 3.4vw, 42px); }
.verdict--compact h2.verdict-said { font-size: 17px; }

/* Пояснение — это содержание, а не мелкий шрифт под таблицей. */
.plain {
  margin: 6px 0 0;
  max-width: 68ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink2);
}
.plain b { font-weight: 650; color: var(--ink); }

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 34px;
  list-style: none;
  margin: 0 0 30px;
  padding: 14px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.facts li { display: flex; flex-direction: column; gap: 2px; }
.facts b {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.015em;
  font-variant-numeric: tabular-nums;
}
.facts span { font-size: 12px; color: var(--muted-strong); }

.attention { margin-bottom: 30px; }
.attention-list {
  display: grid;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.attention-card {
  display: grid;
  grid-template-columns: minmax(140px, 200px) minmax(0, 1fr) minmax(150px, auto);
  align-items: start;
  gap: 6px 24px;
  padding: 16px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.attention-card--critical {
  border-left-color: var(--hold-fg);
  background: linear-gradient(100deg, var(--hold-bg), var(--panel) 46%);
}

.attention-value {
  margin: 0;
  font-size: 21px;
  font-weight: 660;
  line-height: 1.2;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.attention-card--critical .attention-value { color: var(--hold-fg); }

/* Погородный счётчик — список строк, а не один длинный заголовок. */
.attention-value--split {
  display: grid;
  gap: 3px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.01em;
  list-style: none;
  padding: 0;
}

.attention-body { min-width: 0; }
.attention-body h3 {
  margin: 0;
  font-size: 14.5px;
  font-weight: 650;
  line-height: 1.3;
  color: var(--ink);
}
.attention-body .plain { margin-top: 4px; }
.attention-detail {
  margin: 7px 0 0;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--muted-strong);
}

.attention-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
.attention-side .btn-link { text-align: center; }
/* Разбор есть, но не в этом кабинете: молчание читалось бы как «нечего
   разбирать», а ссылка в чужой раздел — как 403. */
.attention-closed {
  margin: 0;
  max-width: 22ch;
  font-size: 12px;
  line-height: 1.4;
  text-align: right;
  color: var(--muted);
}

.tag.hold {
  background: var(--hold-bg);
  color: var(--hold-fg);
  box-shadow: inset 0 0 0 1px var(--hold-line);
}

.attention-foot {
  margin: 10px 0 0;
  max-width: 74ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted-strong);
}

.ledger-panel { padding: 4px 0 0; }
.ledger { list-style: none; margin: 0; padding: 0; }
.ledger-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 24px;
  padding: 15px 22px 16px;
  border-left: 3px solid transparent;
}
.ledger-row + .ledger-row { border-top: 1px solid var(--line2); }
.ledger-row--owed { border-left-color: var(--owed-line); }
.ledger-row--holding { border-left-color: var(--hold-line); }

.ledger-city {
  grid-column: 1;
  margin: 0;
  font-size: 15.5px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.ledger-amount {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  margin: 0;
  font-size: 26px;
  font-weight: 660;
  line-height: 1.1;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink2);
}
.ledger-row--owed .ledger-amount { color: var(--owed-fg); }
.ledger-row--holding .ledger-amount { color: var(--hold-fg); }

.ledger-said {
  grid-column: 1;
  margin: 3px 0 0;
  max-width: 62ch;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink2);
}
.ledger-check {
  grid-column: 1 / -1;
  margin: 8px 0 0;
}
.ledger-row .bar { grid-column: 1 / -1; }
.ledger-parts {
  grid-column: 1 / -1;
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--muted-strong);
  font-variant-numeric: tabular-nums;
}
.ledger-row--outside .ledger-city { font-weight: 600; color: var(--ink2); }
.ledger-row--outside .ledger-amount { font-size: 20px; }
.ledger-row--empty { padding: 22px; }

.ledger-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  margin: 0;
  padding: 16px 22px 18px;
  border-top: 2px solid var(--line);
  background: color-mix(in srgb, var(--accent) 4%, transparent);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink2);
}
.ledger-total b {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}

.disclosure > summary {
  cursor: pointer;
  padding: 12px 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink2);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  list-style-position: inside;
}
.disclosure > summary:hover { background: var(--line2); }
.disclosure > summary:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.disclosure[open] > summary { margin-bottom: 12px; }
.disclosure > summary .tag { margin-left: 8px; }
.disclosure > summary .dim { color: var(--muted-strong); font-weight: 400; }

.disclosure--inline > summary {
  border: 0;
  border-radius: 0;
  background: transparent;
}
.disclosure--inline + .disclosure--inline > summary { border-top: 1px solid var(--line); }
.disclosure--inline[open] > summary { margin-bottom: 0; border-bottom: 1px solid var(--line); }
.disclosure--inline > .period-picker {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.disclosure--inline > .scroll { padding: 14px 18px 0; }
.disclosure--inline > .sync-warning { margin: 0; padding: 14px 18px 0; }

.explainer {
  padding: 24px 28px 26px;
  margin-bottom: 30px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
}
.explainer-lead { margin: 0; max-width: 78ch; font-size: 15px; }
/* Нумерация здесь не украшение: это реальная последовательность —
   посчитали → подписал я → подписал Максим. Порядок несёт смысл. */
.explainer-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 22px 30px;
  margin: 24px 0 0;
  padding: 0;
  counter-reset: step;
  list-style: none;
}
.explainer-steps li {
  counter-increment: step;
  padding-top: 14px;
  border-top: 2px solid var(--soft);
}
.explainer-steps li::before {
  content: counter(step);
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--accent2);
}
.explainer-steps h3 {
  margin: 0;
  font-size: 14.5px;
  font-weight: 650;
  line-height: 1.3;
}
.explainer-steps .plain { font-size: 13.5px; }

.empty { padding: 26px 28px 28px; }
/* Панель по умолчанию раздвигает свои <p> (.panel > p): здесь абзацы —
   текст пустого состояния, а не «одинокая строка в карточке». */
.empty > p { padding: 0; }
.empty-title {
  margin: 0;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.empty .plain { max-width: 74ch; }
.form-panel button + .dim { margin-left: 12px; }

.nav-grouped {
  align-items: center;
  gap: 4px 10px;
  padding-bottom: 4px;
}
.nav-grouped .nav-group {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0 10px 0 0;
  list-style: none;
}
.nav-grouped .nav-group + .nav-group {
  padding-left: 10px;
  border-left: 1px solid var(--line);
}
.nav-grouped .nav-group--reference {
  margin-left: auto;
  padding-left: 0;
  border-left: 0;
}
.nav-grouped .nav-group--reference a {
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted-strong);
}
.nav-grouped .nav-group--reference a[aria-current="page"] {
  font-weight: 600;
  color: var(--accent2);
}

/* --- кабинет Максима: партнёры первым экраном ------------------------ */

.board { margin: 0 0 34px; }
.board > h2 { margin-top: 0; }

.facts--duo { gap: 10px 40px; }
.facts--duo b { font-size: 21px; }

.partner-cards {
  display: grid;
  gap: 10px;
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}

.partner-card {
  display: grid;
  grid-template-columns:
    minmax(0, 1.1fr) minmax(110px, auto) minmax(44px, 0.4fr)
    minmax(0, 1.5fr) auto;
  align-items: center;
  gap: 6px 24px;
  padding: 14px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}

.partner-card--owes { border-left-color: var(--hold-fg); }
.partner-card--empty { grid-template-columns: minmax(0, 1fr); color: var(--muted-strong); }
.partner-card p { margin: 0; }

.partner-card__name {
  font-size: 16px;
  font-weight: 640;
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
}

.partner-card__where { font-size: 12.5px; color: var(--muted-strong); }

.partner-card__debt {
  font-size: 20px;
  font-weight: 680;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--hold-fg);
}

.partner-card__debt--prepaid,
.partner-card__debt--clear { color: var(--muted-strong); }
.partner-card__debt-note { font-size: 11.5px; color: var(--muted-strong); }
.partner-card__last { font-size: 12.5px; line-height: 1.5; color: var(--muted-strong); }

/* Тач-цель: не меньше 44px по высоте на любом экране. */
.partner-card__go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 16px;
  border-radius: 11px;
  background: var(--soft);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 13.5px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  color: var(--accent2);
}

.partner-card__go:hover { box-shadow: inset 0 0 0 1px var(--accent); }

/* Сальдо переводов: две встречные суммы одной парой. */
.duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 28px;
  padding: 16px 20px;
}

.duo-item { display: flex; flex-direction: column; gap: 3px; margin: 0; }
.duo-label { font-size: 12.5px; color: var(--muted-strong); }

.duo-value {
  font-size: 19px;
  font-weight: 660;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.duo--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.duo-foreign {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  padding: 10px 14px;
  max-width: 74ch;
  background: var(--off-bg);
  border-radius: 11px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted-strong);
}

.duo-value.pos { color: var(--owed-fg); }
.duo-value.neg { color: var(--hold-fg); }

.duo-note {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  max-width: 74ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted-strong);
}

/* Разбор города под строкой ленты: тот же расчёт, только развёрнутый.
   Единственное место, где город появляется во второй раз, — и оно
   закрыто по умолчанию. Второй таблицы тех же городов на экране нет. */
.ledger-open {
  grid-column: 1 / -1;
  margin: 10px 0 0;
}
.ledger-open > summary {
  display: inline-block;
  cursor: pointer;
  padding: 5px 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink2);
  background: var(--line2);
  border-radius: 9px;
  list-style-position: inside;
}
.ledger-open > summary:hover { background: var(--line); }
.ledger-open > summary:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.ledger-open[open] > summary { margin-bottom: 10px; }

.breakdown {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: 14px 34px;
}
.breakdown__when {
  margin: 0 0 6px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}
.breakdown__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0;
  margin: 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.breakdown__list dt,
.breakdown__list dd {
  margin: 0;
  padding: 5px 0;
  border-top: 1px solid var(--line2);
}
.breakdown__list dt { color: var(--muted-strong); }
.breakdown__list dd { text-align: right; color: var(--ink2); }
.breakdown__list dt:first-of-type,
.breakdown__list dd:first-of-type { border-top: 0; }
.breakdown__list dt.breakdown__key,
.breakdown__list dd.breakdown__key { font-weight: 680; color: var(--ink); }
.breakdown__note {
  grid-column: 1 / -1;
  margin: 8px 0 0;
  max-width: 68ch;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted-strong);
}

/* На широком экране тот же разбор идёт таблицей: показатели строками, окна
   расчёта колонками — накопительное и периодное значение сравниваются по
   горизонтали. Раскладку телефона перевернуть средствами CSS нельзя (там
   показатели идут двумя списками, и подписи повторяются в каждом), поэтому
   раскладки две, и лишняя выключена на своей стороне порога. */
@media (min-width: 761px) {
  .breakdown { display: none; }
}
.breakdown-compare { max-width: 560px; }
.breakdown-compare__grid {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.breakdown-compare__said {
  caption-side: top;
  max-width: 64ch;
  padding: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.5;
  text-align: left;
  color: var(--ink2);
}
.breakdown-compare__corner { width: 38%; }
.breakdown-compare__grid thead th {
  padding: 0 0 8px 22px;
  background: none;
  border-bottom: 1px solid var(--line);
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;
  vertical-align: top;
}
.breakdown-compare__what {
  display: block;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted-strong);
}
.breakdown-compare__when {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  color: var(--muted-strong);
}
.breakdown-compare__caveat {
  display: block;
  font-size: 11px;
  font-weight: 500;
  font-style: italic;
  white-space: nowrap;
  color: var(--muted-strong);
}
.breakdown-compare__grid tbody th,
.breakdown-compare__grid tbody td {
  padding: 6px 0 6px 22px;
  border-bottom: 1px solid var(--line2);
  white-space: nowrap;
}
.breakdown-compare__grid tbody th {
  padding-left: 0;
  font-weight: 400;
  white-space: normal;
  color: var(--muted-strong);
}
.breakdown-compare__grid tbody td { color: var(--ink2); }
.breakdown-compare__grid th.breakdown-compare__aside,
.breakdown-compare__grid td.breakdown-compare__aside {
  border-left: 1px solid var(--line2);
  color: var(--muted-strong);
}
.breakdown-compare__grid .breakdown-compare__key th,
.breakdown-compare__grid .breakdown-compare__key td {
  font-weight: 680;
  color: var(--ink);
}
.breakdown-compare__grid .breakdown-compare__key--last th,
.breakdown-compare__grid .breakdown-compare__key--last td {
  border-top: 2px solid var(--line);
  border-bottom: 0;
}
.breakdown-compare__grid tfoot th,
.breakdown-compare__grid tfoot td {
  padding: 16px 0 0 22px;
  border-bottom: 0;
  vertical-align: top;
  text-align: right;
  font-weight: 400;
  color: var(--muted-strong);
}
.breakdown-compare__grid tfoot th {
  padding-left: 0;
  text-align: left;
  white-space: normal;
}
.breakdown-compare__hint {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--muted-strong);
}
.breakdown-compare__note {
  margin: 10px 0 0;
  max-width: 68ch;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted-strong);
}

.ledger-total--period b { font-size: 17px; font-weight: 650; color: var(--ink2); }
.ledger-total-note {
  margin: 0;
  padding: 0 22px 16px;
  max-width: 74ch;
  font-size: 12.5px;
  line-height: 1.5;
}
.section-lead {
  margin: -4px 0 14px;
  max-width: 78ch;
  font-size: 13px;
  line-height: 1.5;
}
.register-group__meta {
  margin: -4px 0 12px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

/* Итог денег периода — над погородным разрезом, крупнее карточек города:
   сумма карточек равна ему, и порядок чтения обязан это показывать. */
.money-total {
  padding: 18px 20px 17px;
  background: linear-gradient(180deg, var(--soft), var(--panel));
  border-color: color-mix(in srgb, var(--accent) 26%, var(--line));
}
.money-total .duo-value.money-total__value {
  font-size: 27px;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
  color: var(--accent2);
}

/* Деньги периода по городам: те же суммы, разложенные по строкам расчёта. */
.city-money__heading {
  margin: 18px 0 10px;
  font-size: 14px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.city-money {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 12px;
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
}
.city-money__card {
  padding: 16px 18px 15px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.city-money__name {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0 0 10px;
  font-size: 15.5px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.city-money__scheme {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
}
.city-money__sums {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  margin: 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.city-money__sums dt,
.city-money__sums dd {
  margin: 0;
  padding: 5px 0;
  border-top: 1px solid var(--line2);
}
.city-money__sums dt:first-of-type,
.city-money__sums dd:first-of-type { border-top: 0; }
.city-money__sums dt { color: var(--muted-strong); }
.city-money__sums dd { text-align: right; color: var(--ink2); }
.city-money__sums dd.city-money__lead {
  font-size: 17px;
  font-weight: 680;
  color: var(--ink);
}
.city-money__gaps-title {
  margin: 12px 0 6px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}
.city-money__gaps {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.city-money__gaps a {
  display: inline-block;
  padding: 5px 10px;
  font-size: 12.5px;
  color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: 9px;
  text-decoration: none;
}
.city-money__gaps a:hover { border-color: var(--warn); }
.city-money__gaps b { font-variant-numeric: tabular-nums; }
.city-money__clean {
  margin: 12px 0 0;
  font-size: 12.5px;
  color: var(--good);
}
.city-money__note {
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted-strong);
}

/* Пусто — это факт, а не сбой: «0 ₽» без подписи читается как ошибка. */
.duo-blank {
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
}
.duo-item--transfer .duo-value { font-variant-numeric: tabular-nums; }

/* Итог расчёта строкой, а не крупным вердиктом. */
.settlement-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 18px;
  margin: 0 0 10px;
  padding: 14px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}

.settlement-line b {
  font-size: 19px;
  font-weight: 680;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

@media (min-width: 1180px) {
  .wrap { max-width: 1240px; }
  .attention-card { gap: 6px 30px; padding: 18px 24px; }
  .ledger-row { padding: 17px 26px 18px; }
}

@media (max-width: 900px) {
  .attention-card { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .partner-card { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 16px; }
  .partner-card__last,
  .partner-card__go { grid-column: 1 / -1; }
  .attention-side { align-items: flex-start; }
  .attention-closed { max-width: none; text-align: left; }
  .nav-grouped .nav-group--reference { margin-left: 0; }
}

@media (max-width: 640px) {
  .period-bar { gap: 10px; padding: 12px 16px; }
  .period-bar .presets { width: 100%; }
  .period-bar .presets a { flex: 1 1 auto; justify-content: center; min-height: 44px; }
  /* Пары «подпись — поле» в две колонки: иначе подпись «По дату»
     уезжает в конец строки, а её поле переносится на следующую. */
  .period-range {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 8px 10px;
    width: 100%;
    margin-left: 0;
  }
  .period-range input { width: 100%; max-width: none; min-height: 44px; }
  .period-range button { grid-column: 1 / -1; width: 100%; min-height: 44px; }
  .period-range .errorlist { grid-column: 1 / -1; margin: 0; }
  .partner-card { grid-template-columns: minmax(0, 1fr); padding: 14px 16px; }
  .partner-card__money { display: flex; align-items: baseline; gap: 8px; }
  .partner-card__go { width: 100%; }
  .duo,
  .duo--four { grid-template-columns: minmax(0, 1fr); padding: 14px 16px; }
  .settlement-line { padding: 14px 16px; }
  .verdict { padding: 20px 18px; }
  .verdict h2.verdict-said { font-size: 17px; }
  .facts { gap: 10px 20px; padding: 14px 16px; }
  .ledger-row { grid-template-columns: minmax(0, 1fr); padding: 14px 16px 15px; }
  .ledger-amount { grid-column: 1; grid-row: auto; }
  .ledger-total { padding: 14px 16px; }
  .explainer { padding: 18px 16px 20px; }
  .empty { padding: 18px 16px 20px; }
  .nav-grouped .nav-group + .nav-group { border-left: 0; padding-left: 0; }
}

/* ===== Блок отбора «Сделок» и свёрнутые вспомогательные блоки ============
   Слово владельца 31.07.2026: «фильтры как-то сильно много места
   занимают». Форма из десяти полей ушла под раскрытие, а снаружи
   осталось то, ради чего на неё смотрят: чем сейчас сужен список
   (переключатель + чипы) и что это за строки (предложение словами).
   Слой самостоятельный и ничего выше не переписывает. */

.scope {
  margin: 0 0 26px;
  padding: 16px 20px 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
}

/* Переключатель «чьи сделки»: дефолт показывает сопоставленные, и это
   должно читаться с экрана, а не из выпадающего списка на девять пунктов
   (слово владельца: «несопоставленные ко мне не относятся, но их при
   желании можно будет посмотреть»). Обычные ссылки — работает без JS. */
.scope-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--line2);
  border-radius: 999px;
}
.scope-switch a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 34px;
  padding: 0 16px;
  border-radius: 999px;
  color: var(--ink2);
  font-size: 13.5px;
  font-weight: 600;
}
.scope-switch a:hover {
  background: color-mix(in srgb, var(--panel) 70%, transparent);
  text-decoration: none;
}
.scope-switch a[aria-current] {
  background: var(--panel);
  color: var(--accent2);
  box-shadow: 0 1px 2px rgba(16, 24, 40, .1), inset 0 0 0 1px var(--line);
}

.scope-said {
  margin: 12px 0 0;
  max-width: 76ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink2);
}
.scope-said b {
  color: var(--ink);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* Чипы применённого отбора: форма спрятана, поэтому условия обязаны быть
   видны снаружи — иначе короткий список выглядит как пустой месяц. Чип
   целиком ссылка «показать без этого условия». */
.scope-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}
.scope-chips a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 30px;
  padding: 0 6px 0 11px;
  border-radius: 999px;
  background: var(--soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent2);
  font-size: 12.5px;
  font-weight: 600;
}
.scope-chips a:hover {
  background: color-mix(in srgb, var(--accent) 14%, var(--panel));
  text-decoration: none;
}
.scope-chip__off {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-size: 13px;
  line-height: 1;
}

.refine { margin: 14px 0 0; }
.refine > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.refine > summary::-webkit-details-marker { display: none; }
.refine > summary::marker { content: ""; }
.refine > summary::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg) translate(-1px, -1px);
}
.refine[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.refine > summary:hover { border-color: var(--accent); color: var(--accent2); }

.refine-form {
  display: grid;
  gap: 18px;
  margin: 16px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid var(--line2);
}
/* fieldset остаётся блочным: «выехавшая» легенда во flex-контейнере
   ведёт себя по-разному в браузерах, поэтому строка полей — свой div. */
.refine-group {
  margin: 0;
  padding: 0;
  border: 0;
}
.refine-group > legend {
  padding: 0;
  margin-bottom: 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-strong);
}
.refine-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 14px;
}
.refine-row .field {
  display: flex;
  flex-direction: column;
  min-width: 150px;
}
.refine-row .field.check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding-bottom: 9px;
}
.refine-row .field.check label { margin: 0; }
.refine-row .field.check input { margin: 0; }
.refine-row input,
.refine-row select { max-width: 220px; }
.refine-hint {
  flex-basis: 100%;
  margin: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted-strong);
}
.refine-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* Длинная справка под лентой — под раскрытие: она нужна раз в месяц, а
   место занимает на каждом заходе. */
.note-fold > summary {
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  color: var(--muted-strong);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.note-fold > summary::-webkit-details-marker { display: none; }
.note-fold > summary::marker { content: ""; }
.note-fold > summary::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 8px;
  vertical-align: 2px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
}
.note-fold[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.note-fold > summary:hover { color: var(--ink2); }
.note-fold .note { border-top: 0; }

/* Полосы счётчиков: на широком экране это ровно тот же ряд плиток, что и
   раньше (display: contents), подписи полос не показываются. Смысл они
   несут на телефоне — там же и включаются. */
.kpi-band { display: contents; }
.kpi-band__title { display: none; }
/* Восемь счётчиков подряд при auto-fit оставляли одну плитку сиротой на
   второй строке. Четыре колонки дают два ровных ряда на любой ширине. */
@media (min-width: 900px) {
  .kpis--banded { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Свёрнутый выбор произвольных дат. Пресеты закрывают почти все заходы,
   а два поля с календарями занимали первый экран целиком. */
.period-pick { min-width: 0; }
.period-pick > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink2);
  font-size: 13.5px;
  cursor: pointer;
  list-style: none;
}
.period-pick > summary::-webkit-details-marker { display: none; }
.period-pick > summary::marker { content: ""; }
.period-pick > summary::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg) translate(-1px, -1px);
}
.period-pick[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.period-pick > summary:hover { border-color: var(--accent); color: var(--accent2); }
.period-pick > summary b {
  font-weight: 650;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Раскрытый выбор дат забирает свою строку целиком: иначе поля жмутся к
   пресетам и подпись «По дату» отрывается от своего поля. */
.period-pick[open] { flex: 1 1 100%; }
.period-pick > .period-range { margin: 12px 0 0; }

/* Ссылка внутри абзаца отличается от текста НЕ только цветом: контраст
   зелёного к чернилам ниже 3:1, и по цвету её не находит ни дальтоник,
   ни человек на солнце. Подчёркивание — у ссылок в потоке текста;
   кнопки, чипы и пункты меню остаются без него (там носитель смысла —
   форма элемента, а не цвет). */
.note a,
.plain a,
.warn a,
.scope-said a,
.actions a:not(.btn-link),
.form-panel .dim a,
.attention-foot a,
.duo-note a,
.ledger-said a {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* ============================================================
   Компактная подача (31.07.2026)

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

/* Строка «главное сегодня»: цифры, за которыми заходят, — до всякого
   фильтра и без плитки во всю ширину. */
.today { margin: 0 0 18px; }
.today-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.today-card {
  padding: 12px 16px 13px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.today-card--key { border-left-color: var(--accent); }
.today-card p { margin: 0; }
.today-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted-strong);
}
.today-card .today-value {
  margin-top: 2px;
  font-size: 28px;
  font-weight: 690;
  line-height: 1.15;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.today-value--off { font-size: 19px; color: var(--muted-strong); }
.today-cur { margin-left: 3px; font-size: .55em; font-weight: 600; color: var(--muted-strong); }
.today-card .today-split {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
  margin-top: 4px;
  font-size: 12px;
  color: var(--muted-strong);
}
.today-split b { font-weight: 650; color: var(--ink2); font-variant-numeric: tabular-nums; }
.today-scope {
  margin: 8px 0 0;
  max-width: 84ch;
  font-size: 12px;
  line-height: 1.5;
}

/* Пояснение, которому не нужна панель во всю ширину. */
.compact-note {
  margin: 0 0 10px;
  max-width: 84ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink2);
}
.section-lead { margin: -4px 0 12px; max-width: 88ch; font-size: 12.5px; line-height: 1.5; }

/* Две логики денег: Москва и города делёжа — своими группами со своим
   итогом, а не одной суммой (слово владельца 31.07.2026). */
.ledger-group { padding: 0; }
.ledger-group + .ledger-group { border-top: 2px solid var(--line); }
.ledger-group__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0;
  padding: 11px 22px 2px;
}
.ledger-group__name {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-strong);
}
.ledger-group__sum {
  font-size: 19px;
  font-weight: 680;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ledger-group__formula {
  margin: 0;
  padding: 0 22px 8px;
  max-width: 88ch;
  font-size: 11.5px;
  line-height: 1.45;
}
.ledger-cities { list-style: none; margin: 0; padding: 0; }
.ledger-group .ledger-row {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1px 16px;
  padding: 9px 22px 11px;
}
.ledger-group .ledger-city { grid-column: 1; grid-row: 1; }
.ledger-group .ledger-amount {
  grid-column: 2;
  grid-row: 1;
  align-self: baseline;
  font-size: 20px;
}
.ledger-group .ledger-parts { grid-column: 1 / -1; margin-top: 3px; }
/* «Разбор» под строкой города — текстовая ссылка, а не серая плашка:
   плашка на каждый город добавляла по 40 px пустого места. */
.ledger-group .ledger-open { grid-column: 1 / -1; margin: 3px 0 0; }
.ledger-group .ledger-open > summary {
  display: inline-block;
  padding: 2px 0;
  background: none;
  border-radius: 0;
  font-size: 12px;
  color: var(--accent2);
}
.ledger-group .ledger-open > summary:hover { background: none; text-decoration: underline; }
.breakdown__said { margin: 0 0 6px; font-size: 12.5px; color: var(--ink2); }

/* Группа из одного города: итог группы повторил бы строку под ним
   слово в слово — сумму несёт сама строка. */
.ledger-group--single .ledger-group__sum { display: none; }

/* Карточка бригады: имя и долг первой строкой, контекст второй,
   спарклайн, действие. Всё, что было служебными подписями под каждой
   карточкой, ушло в общий текст блока. */
.pcards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 10px;
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}
.pcard {
  padding: 12px 16px 13px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.pcard--owes { border-left-color: var(--hold-fg); }
.pcard--silent { border-left-color: var(--crit); }
.pcard--empty { color: var(--muted-strong); }
.pcard p { margin: 0; }
.pcard__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.pcard__name {
  font-size: 15.5px;
  font-weight: 645;
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.pcard__debt {
  font-size: 19px;
  font-weight: 680;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--hold-fg);
}
.pcard__debt--prepaid,
.pcard__debt--clear { color: var(--muted-strong); }
.pcard .pcard__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-top: 3px;
  font-size: 12px;
  color: var(--muted-strong);
}
.pcard__state::before { content: "·"; margin-right: 6px; }
.pcard .pcard__history { margin-top: 5px; font-size: 11.5px; line-height: 1.45; }
.pcard__history b { font-weight: 650; color: var(--ink2); }

/* Мера погашения бригады: шкала 0…100 % от её собственных начислений,
   поэтому карточку можно читать в отрыве от соседних. Прежняя полоса
   нормировалась на максимум долга в ряду, и у самого крупного должника
   она всегда была во всю ширину — читалась как «шкала сломана»
   (слово владельца 01.08.2026). Процент стоит словами следующей
   строкой, полоса — его картинка, поэтому она aria-hidden. */
.pcard .pcard__meter { margin-top: 9px; }
.pcard .pcard__closed { margin-top: 5px; font-size: 11.5px; line-height: 1.45; }
.pcard__closed b { font-weight: 650; color: var(--ink2); }
.pcard .pcard__act {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
  margin-top: 8px;
}
.pcard__act .btn-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  margin: 0;
}
.pcard__more { font-size: 11.5px; font-weight: 500; color: var(--muted-strong); }
.pcard__more:hover { color: var(--accent2); }

/* Спарклайн истории бригады: заявки и деньги по месяцам. Полосы
   считает тот же bar_width на Decimal, что и мера погашения, — второго
   механизма процентов в проекте нет. Текстовая альтернатива — в
   aria-label контейнера и строкой итогов под ним. */
.spark {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  margin-top: 6px;
  height: 30px;
}
.spark__col {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  height: 100%;
}
.spark__bars {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border-bottom: 1px solid var(--line);
}
.spark__bar {
  width: 6px;
  min-height: 1px;
  border-radius: 2px 2px 0 0;
  background: var(--line);
}
.spark__bar--deals { background: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.spark__bar--paid { background: var(--accent); }
.spark__month {
  flex: none;
  font-size: 9.5px;
  line-height: 1;
  color: var(--muted);
  white-space: nowrap;
}

/* Две логики денег под главной цифрой: Москва и города — сразу, без
   прокрутки до ленты (слово владельца 31.07.2026). */
.verdict-split {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin: 6px 0 0;
  font-size: 12.5px;
  color: var(--muted-strong);
}
.verdict-split b {
  font-weight: 660;
  color: var(--ink2);
  font-variant-numeric: tabular-nums;
}
.verdict { padding: 20px 24px 18px; }
.verdict-figure { font-size: clamp(38px, 4.4vw, 54px); }
.verdict-why { margin-top: 9px; }
.verdict-actions { margin-top: 12px; }

/* Счётчики выборки одной строкой вместо плиток во всю ширину: цифра
   слева, что она значит — рядом мелким. Плитки занимали два экрана на
   телефоне, отвечая при этом на второстепенные вопросы. */
.tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 2px 22px;
  list-style: none;
  margin: 0 0 8px;
  padding: 12px 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.tally__item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 3px 0;
  font-size: 12px;
  color: var(--muted-strong);
}
.tally__item > b {
  min-width: 2.2em;
  font-size: 17px;
  font-weight: 680;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.tally__item--alarm > b { color: var(--crit); }
.tally__item--pending > b { color: var(--muted-strong); }

/* Панель над списком: вход в отбор и сброс. На телефоне она липкая —
   фильтр нужен, когда список уже пролистан (mobile.css). */
.listbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
}
.listbar__filters {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 16px;
  background: var(--panel);
  border-radius: 11px;
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent2);
}
.listbar__filters:hover { box-shadow: inset 0 0 0 1px var(--accent); text-decoration: none; }
.listbar__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
}
.listbar__reset { font-size: 12.5px; font-weight: 500; color: var(--muted-strong); }

/* Слаг, логин и состояние партнёра одной строкой — только в карточке
   телефона. */
.part-meta { display: none; }

/* Действие внутри строки под раскрытием: форма завершения членства с
   полем даты занимала место на каждом городе каждой бригады. */
.row-fold > summary {
  display: inline-block;
  padding: 2px 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent2);
  cursor: pointer;
}

/* Партнёр, плательщик, счёт и получатель одной строкой — только в
   карточке телефона. */
.pay-meta { display: none; }

/* Банк, способ, реквизит и получатель одной строкой — только в
   карточке телефона: в таблице десктопа у каждого своя колонка. */
.acc-meta { display: none; }

/* Счёт, город, партнёр и способ одной строкой — только в карточке
   телефона: в таблице десктопа у каждого своя колонка. */
.cf-meta { display: none; }

/* Дата, город и статус одной строкой — только в карточке телефона: в
   таблице десктопа у каждого своя колонка. */
.deal-meta { display: none; }

/* Разбор сделки под раскрытием: телефоны, партнёр, начислено,
   происхождение города. В таблице десктопа те же значения стоят
   колонками, поэтому там раскрытие скрыто. */
.deal-fold { display: none; }
.deal-fold__list {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 4px 14px;
  margin: 8px 0 0;
  font-size: 12.5px;
}
.deal-fold__list dt { color: var(--muted-strong); }
.deal-fold__list dd { margin: 0; overflow-wrap: anywhere; }

/* Выезжающая панель отбора: на телефоне — снизу, на десктопе остаётся
   обычной модалкой (места там хватает, ничего не ухудшаем). */
.cf-modal.sheet { max-width: 720px; }

/* Одна строка вместо панели из двух крупных чисел: те же деньги
   раскрыты карточками городов ниже, повторять их плитками незачем. */
.money-line b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Расшифровка знака под строкой города: минус означает ДВА разных
   события, и держать это в голове владелец не обязан (его вопрос
   «что означает баланс, что минус, что плюс»). */
.ledger-mean {
  grid-column: 1 / -1;
  margin: 2px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
}
.ledger-mean a { white-space: nowrap; }

/* Разбор дыр — плотнее: пять карточек занимали пол-экрана, а читаются
   они одной строкой «сколько и что». Слово владельца: «технические
   элементы занимают много лишнего места». */
.attention { margin-bottom: 22px; }
.attention-list { gap: 8px; }
.attention-card { gap: 4px 20px; padding: 11px 16px; }
.attention-value { font-size: 18px; }
.attention-value--split { font-size: 13.5px; gap: 2px; }
.attention-body h3 { font-size: 13.5px; }
.attention-body .plain { margin-top: 2px; font-size: 12.5px; line-height: 1.45; }
.attention-side { gap: 6px; }
.attention-foot { margin-top: 8px; font-size: 12px; }

/* Знак баланса словами — один раз под лентой городов, а не в каждой
   строке: повтор одной и той же оговорки трижды владелец уже называл
   дублированием. */
.ledger-legend {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  max-width: 92ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted-strong);
}

/* Разрез итогов ленты — строкой под главной цифрой, а не плитками:
   шесть плиток занимали первый экран целиком, а читают из них одну. */
.totals-split {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin: -14px 0 22px;
  font-size: 12.5px;
  line-height: 1.5;
}
.totals-split b { color: var(--ink); font-variant-numeric: tabular-nums; }
.totals-split__note { flex-basis: 100%; color: var(--muted); }

/* Действия строки ленты: три кнопки столбиком растили строку до 90 px.
   Правка — на виду (её делают), удаление и сторно — под «ещё»: их за
   месяц бывает одна, а место они занимали в каждой строке. */
.cf-feed .row-actions {
  width: 132px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
.cf-feed .row-actions .btn-link { margin: 0; }
.row-more { display: inline-block; }
.row-more > summary {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 4px 8px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  font-size: 11.5px;
  color: var(--muted-strong);
  cursor: pointer;
  list-style: none;
}
.row-more > summary::-webkit-details-marker { display: none; }
.row-more > summary::marker { content: ""; }
.row-more > summary:hover { border-color: var(--accent); color: var(--accent2); }
.row-more__items { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }

/* Столбец статуса — пустой у действующей записи. Десять строк подряд с
   ярлыком «действует» ничего не сообщают: значимо ровно обратное, и
   сторно видно и ярлыком, и приглушённой строкой. */
.cf-feed .status-col { width: 1%; }
.cf-feed td.method-col { white-space: nowrap; font-size: 12px; }

/* Правка сделки в строке — компактной кнопкой без переноса: столбиком
   она добавляла строке 16 px, а строк на экране шесть. */
.deals td.row-actions {
  white-space: nowrap;
  vertical-align: middle;
}
.deals td.row-actions .btn-link { margin: 0; padding: 4px 8px; min-height: 26px; font-size: 11.5px; }

/* ===== Кабинет бригады: остаток как равенство ============================
   Слой добавлен целиком в конец файла и ничего выше не переписывает.

   Находка раздела: на вопрос «из чего сложился долг» отвечает не список
   и не таблица, а РАВЕНСТВО — два слагаемых и результат под чертой.
   Разъехаться с остатком счёта оно не может по построению: «зачтено» —
   это всё, что не действующее начисление, поэтому разность тождественно
   равна балансу леджера. Знак у результата не печатается: направление
   несёт слово над ним, минус читался бы вторым отрицанием. */

.sum-line {
  list-style: none;
  margin: 0;
  padding: 14px 20px 10px;
  display: grid;
  gap: 0;
}
.sum-line__row {
  display: grid;
  grid-template-columns: 1.1em minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0 12px;
  padding: 7px 0;
}
.sum-line__op {
  font-size: 16px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.sum-line__what { color: var(--ink2); line-height: 1.4; }
.sum-line__num {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.015em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.sum-line__row--result {
  margin-top: 5px;
  padding-top: 11px;
  border-top: 1px solid var(--line);
}
.sum-line__row--result .sum-line__op,
.sum-line__row--result .sum-line__what {
  color: var(--ink);
  font-weight: 600;
}
.sum-line__row--result .sum-line__num { font-size: 23px; }
.sum-line--holding .sum-line__row--result .sum-line__num { color: var(--hold-fg); }
.sum-line--owed .sum-line__row--result .sum-line__num { color: var(--owed-fg); }

.sum-line__foot { padding: 2px 20px 16px; }
.sum-line__foot .meter { margin: 0 0 8px; }
.sum-line__scope {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted-strong);
}

/* Справка кабинета бригады внутри карточки вердикта: та же плашка
   «фактов», но без собственной рамки — рамку уже дал вердикт. */
.facts--account {
  margin: 16px 0 0;
  padding: 14px 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
  gap: 10px 28px;
}

/* Помесячный ритм бригады: сколько передали и сколько она внесла.
   Полосы нормируются КАЖДАЯ по своему ряду (начисления и поступления —
   разные величины), поэтому сравнивать их между собой нельзя, и об этом
   сказано под блоком. */
.months { list-style: none; margin: 0; padding: 6px 20px 10px; }
.months__row {
  padding: 12px 0;
  border-bottom: 1px solid var(--line2);
}
.months__row:last-child { border-bottom: 0; }
.months__when {
  margin: 0;
  font-size: 14px;
  font-weight: 650;
  letter-spacing: -.01em;
}
.months__deals { margin: 1px 0 0; font-size: 12.5px; color: var(--muted-strong); }
.months__line {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0 10px;
  margin: 7px 0 0;
}
.months__what { font-size: 12.5px; color: var(--muted-strong); }
.months__num {
  justify-self: end;
  font-size: 14.5px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.months .bar {
  grid-column: 1 / -1;
  display: block;
  height: 6px;
  margin: 5px 0 0;
}

/* Микроподпись у значения в карточной раскладке телефона. На широком
   экране значение подписано ЗАГОЛОВКОМ КОЛОНКИ, и вторая подпись рядом
   была бы дублем, поэтому по умолчанию её нет вовсе. */
.d-comm__cap,
.d-price__cap,
.l-after__cap { display: none; }

/* Вердикт кабинета бригады — та же карточка, но воздуха меньше: на его
   странице она стоит первой и должна оставлять место разложению, а не
   занимать экран одна. Отдельный модификатор, а не правка .verdict:
   карточка Игоря живёт своей мерой и меняться от этого не должна. */
.verdict--brigade { padding: 20px 24px 18px; }
.verdict--brigade .verdict-figure { font-size: clamp(38px, 4.4vw, 52px); }
.verdict--brigade .verdict-why { margin-top: 8px; }
.verdict--brigade .verdict-why.dim { font-size: 12.5px; }

/* Выбор дат под своим заголовком: даты уже названы в заголовке блока,
   поэтому панель пресетов по умолчанию свёрнута — она занимала больше
   места, чем показатели, ради которых её открывают. */
.period-fold { margin: 0 0 14px; }
.period-fold > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 2px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.period-fold > summary::-webkit-details-marker { display: none; }
.period-fold > summary::marker { content: ""; }
.period-fold > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border: 2px solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) translate(-2px, -2px);
}
.period-fold[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.period-fold > .period-bar { margin-top: 8px; }

/* Знак рубля в карточной раскладке: на широком экране единица измерения
   стоит в заголовке колонки («Сумма ₽»), в карточке заголовков нет — и
   без него в списке остаются голые числа. */
.cur-cap { display: none; }

/* На широком экране равенство не растягивается во всю панель: подпись и
   число, разведённые на 900 px, перестают читаться как одна строка. */
@media (min-width: 761px) {
  .sum-line,
  .sum-line__foot { max-width: 640px; }
}

@media (min-width: 761px) {
  /* Полоса длиной в тысячу пикселей не сравнивается глазом ни с чем:
     ряд ужимается до меры, на которой видна разница между месяцами. */
  .months { max-width: 640px; }
}

/* --- 01.08.2026: честное пустое состояние, блок бригад, страница бригады --- */

/* Пустой экран без объяснения породил жалобу владельца (раздел «Заявки»
   первого числа месяца). Подсказка стоит В МЕСТЕ СПИСКА и читается как
   обычный текст, а не как ошибка: данные не потерялись, дело в датах. */
.empty-hint {
  margin: 0;
  line-height: 1.5;
  text-align: left;
}
.empty-hint a { font-weight: 600; }

/* Хвост списка бригад: блок не имеет права разъезжать дашборд, но и
   молча обрезать бригады нельзя — поэтому раскрытие с явным числом. */
.pcards-more { margin: 0 0 14px; }
.pcards-more > summary {
  cursor: pointer;
  padding: 10px 12px;
  border: 1px dashed var(--line);
  border-radius: 10px;
  color: var(--muted);
  font-size: 14px;
  min-height: 44px;
  display: flex;
  align-items: center;
}
.pcards-more > summary:hover { border-color: var(--accent); color: var(--accent2); }
.pcards-more > .pcards { margin-top: 10px; }

/* Выбывшие бригады — отдельная группа: деактивация долг не гасит. */
.pcards-group {
  margin: 18px 0 4px;
  font-size: 15px;
  color: var(--muted);
}

/* Возврат из карточки бригады в реестр. */
.crumbs { margin: 0 0 12px; font-size: 14px; }

/* Спарклайн на странице одной бригады крупнее карточного: здесь он
   основной график, а не иконка рядом с суммой. */
.spark--large { height: 96px; gap: 10px; }

.plain-list { margin: 0 0 12px; padding-left: 18px; line-height: 1.7; }

/* Плательщик и счёт получателя в истории счёта: две строки одной
   ячейки — «кто платил» ведущая, «куда пришло» пояснением. */
.l-payment__who { display: block; }
.l-payment .sub-line { display: block; font-size: 13px; }

/* --- 01.08.2026: текст для чата операторов (страница «Сделки») --- */

/* Владелец отбирает заявки с незаполненными полями Amo и кидает готовый
   текст операторам в чат. Блок свёрнут: он нужен после отбора, а не при
   каждом заходе, и место над таблицей дорогое. */
/* ГЛОБАЛЬНОЕ правило, а не часть блока ниже: `button { display: inline-flex }`
   этого файла (см. базовый блок кнопок) сильнее браузерного
   `[hidden] { display: none }`, поэтому скрытая атрибутом кнопка оставалась
   видимой ГДЕ УГОДНО в кабинете. Здесь оно потому, что здесь и понадобилось
   впервые: без него без скрипта на экране висела бы мёртвая кнопка
   копирования — ровно то, чего фолбэк должен избежать. */
button[hidden] { display: none; }

.opnote > summary .dim { font-weight: 400; }
.opnote__body { padding: 14px 16px; }
/* Пояснение и подсказка — содержание блока, а не служебная подпись:
   служебный --muted на этом фоне даёт около 2,9:1 и мелкий текст по AA
   не проходит (axe, 01.08.2026). --muted-strong заведён ровно для таких
   объяснений — второй план по весу, но читаемый. */
.opnote__lead,
.opnote__hint { color: var(--muted-strong); }
.opnote__lead { margin: 0 0 12px; line-height: 1.55; }

.opnote__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 10px;
}
.opnote__done { font-size: 12px; font-weight: 600; color: var(--good); }
/* Не сработавший буфер обмена — не успех: тот же ответ зелёным читался бы
   как «скопировано», и человек ушёл бы вставлять пустоту. */
.opnote__done--fail { color: var(--crit); }

/* Текст лежит в поле ввода намеренно: это единственный способ скопировать
   его без скрипта — выделение внутри textarea работает у всех. */
.opnote__text {
  display: block;
  width: 100%;
  /* Общий `max-width: 380px` полей ввода тут вреден: строка текста —
     полная ссылка на карточку Amo, и в узкой колонке каждая переносится
     дважды, а вставленное в чат сообщение выглядит иначе, чем на экране. */
  max-width: none;
  min-height: 200px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink2);
  font: 400 12.5px/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  resize: vertical;
}
.opnote__text:focus-visible { outline: 2px solid var(--accent2); outline-offset: 1px; }
.opnote__hint { margin: 8px 0 0; }

/* Пустой отбор — строка вместо кнопки: неактивная кнопка не объясняет,
   почему копировать нечего. */
.opnote-none {
  margin: 0 0 16px;
  line-height: 1.5;
  /* Перебивает .dim той же специфичностью, но ниже по файлу: это
     объяснение «почему копировать нечего», его читают, а не проглядывают. */
  color: var(--muted-strong);
}

/* ===== Контроль стадий (01.08.2026) ======================================
   Слой добавлен целиком в конец файла и ничего выше не переписывает.

   Смысл раздела: «6 дней при норме 2» — это ПОДПИСЬ к статусу, а не
   отдельный факт строки. Поэтому она идёт под названием стадии тем же
   блоком, мельче и приглушённо, и краснеет только при просрочке: если
   красить всегда, красный перестаёт что-либо значить.

   Своего бейджа у просрочки нет — она помечена общим .problem-badge, как
   остальные признаки проблем: второго словаря пометок в проекте нет. */

.stage-age {
  display: block;
  margin-top: 3px;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--muted);
  white-space: nowrap;
}
.stage-age--late {
  font-weight: 600;
  color: var(--warn);
}
/* В компактной строке (.deal-meta) подпись стоит В РЯД со статусом, а не
   блоком: там всё содержимое сделки уложено одной лентой. */
.deal-meta .stage-age { display: inline; margin-top: 0; }

/* ==================== Доступы (общее хранилище) ====================
   Строка на запись, а не карточка. Заходят сюда за одним движением —
   скопировать логин или пароль, — а карточка с четырьмя подписанными
   кнопками отдавала под это пол-экрана: на телефоне помещалась одна
   запись из шестнадцати.

   Три действия стоят в ПОСТОЯННЫХ колонках справа и не съезжают, когда
   у записи нет пароля или ссылки: рука запоминает место, а не читает
   подписи заново. Пустая ячейка дешевле сдвига. */
.vault-find {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
}
.vault-find input[type="search"] { max-width: 300px; }
.vault-find__all { font-size: 12.5px; }

.vault-group { margin: 0 0 20px; }
.vault-group__name {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 7px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}
.vault-group__count {
  font-size: 11px;
  letter-spacing: 0;
  color: var(--muted-strong);
  background: var(--line2);
  border-radius: 999px;
  padding: 1px 7px;
}

/* Список не растягивается на всю ширину экрана: строка из названия,
   логина и трёх кнопок на 1440 превратилась бы в редкую гребёнку, где
   глазу нечем связать левый край с правым. */
.vault-list {
  list-style: none;
  max-width: 900px;
  margin: 0;
  padding: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

.vault-line {
  --rail-slot: 34px;
  --rail-h: 36px;
  /* Сколько места справа держать под кнопки. У записи без пароля занят
     только последний слот, и название вправе занять два пустых. */
  --rail-reserve: calc(3 * var(--rail-slot) + 4px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto) auto;
  align-items: start;
  column-gap: 12px;
  padding: 4px 12px;
  border-top: 1px solid var(--line2);
}
.vault-line:first-child { border-top: 0; }
.vault-line:hover { background: color-mix(in srgb, var(--accent) 3%, transparent); }

/* Снятая с работы запись не исчезает (в ней ответ «а куда входили
   раньше»), но и не спорит за внимание с рабочими. */
.vault-line--off .vault-line__name { color: var(--muted); }

.vault-line__fold { grid-column: 1; grid-row: 1; min-width: 0; }
.vault-line__login { grid-column: 2; grid-row: 1; }
.vault-line__rail { grid-column: 3; grid-row: 1; }
.vault-line__out { grid-column: 1 / -1; grid-row: 2; }

/* Три элемента первой строки одной высоты — тогда название и логин
   стоят по центру кнопок, а раскрытое пояснение растёт вниз и ничего
   не сдвигает. */
.vault-line__head,
.vault-line__login,
.vault-line__rail { min-height: var(--rail-h); }

.vault-line__head {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
  font-size: 13.5px;
  font-weight: 620;
  color: var(--ink);
}
.vault-line__head::-webkit-details-marker { display: none; }
.vault-line__head::marker { content: ""; }
/* Уголок нарисован границами, а не иконкой: он поворачивается на
   раскрытии, и поворот рамки не тянет за собой ни спрайта, ни шрифта. */
.vault-line__head::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin: 0 2px;
  border-right: 1.7px solid var(--muted);
  border-bottom: 1.7px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform .15s ease;
}
.vault-line__fold[open] > .vault-line__head::before { transform: rotate(45deg); }
.vault-line__head:focus-visible { outline: 2px solid var(--accent2); outline-offset: -2px; border-radius: 8px; }

.vault-line__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Логин виден в строке: две записи «Директ» различают именно им.
   Скрипт делает его же кнопкой копирования — отдельной иконки «⧉ логин»
   рядом с «⧉ пароль» не будет: два одинаковых значка в ряд читаются
   хуже, чем нажатие прямо по значению. */
.vault-line__login {
  display: flex;
  align-items: center;
  max-width: 240px;
  padding: 0 6px;
  border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  color: var(--muted-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Раскрытая строка показывает логин целиком: длинный адрес почты в
   строке обрезан многоточием, и второй его копии в раскрытии нет —
   разворачивается тот же самый, там, куда человек уже смотрит. Отсюда
   же берётся ручное копирование, когда буфера обмена нет. */
.vault-line__fold[open] ~ .vault-line__login {
  overflow: visible;
  white-space: normal;
  overflow-wrap: anywhere;
}
.vault-line__login[role="button"] {
  cursor: pointer;
  text-decoration: underline dotted var(--muted);
  text-underline-offset: 4px;
}
.vault-line__login[role="button"]:hover {
  background: var(--soft);
  color: var(--accent2);
  text-decoration-color: var(--accent2);
}
.vault-line__login[role="button"]:focus-visible {
  outline: 2px solid var(--accent2);
  outline-offset: 1px;
}

.vault-line--nosecret { --rail-reserve: var(--rail-slot); }

/* Слоты постоянные, но пустой слот не должен перехватывать нажатие:
   на телефоне название заезжает под него, и тап по названию обязан
   раскрывать строку, а не упираться в невидимую пустоту. */
.vault-line__rail {
  display: grid;
  grid-template-columns: repeat(3, var(--rail-slot));
  gap: 2px;
  justify-content: end;
  pointer-events: none;
}
.vault-act,
.vault-act-form { pointer-events: auto; }
.vault-act--secret { grid-column: 1; }
.vault-act-form { grid-column: 2; display: block; margin: 0; }
.vault-act--open { grid-column: 3; }

.vault-act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: var(--rail-h);
  min-height: var(--rail-h);
  padding: 0;
  font: inherit;
  color: var(--muted-strong);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  cursor: pointer;
}
.vault-act svg { width: 18px; height: 18px; }
.vault-act:hover {
  color: var(--accent2);
  background: var(--soft);
  border-color: #cfe6dd;
  text-decoration: none;
}
.vault-act:focus-visible { outline: 2px solid var(--accent2); outline-offset: 1px; }
.vault-act[hidden] { display: none; }

.vault-line__out {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
}
/* Отступ появляется вместе с содержимым: у нетронутой строки под
   первой линией не должно быть ни пикселя пустоты. */
.vault-line__out > .vault-value:not([hidden]) { margin-bottom: 7px; }
.vault-line__status:not(:empty) {
  margin-bottom: 7px;
  font-size: 12px;
  color: var(--muted);
}

.vault-line__more {
  padding: 2px 0 10px 16px;
  font-size: 12.5px;
  color: var(--ink2);
}
.vault-line__note {
  margin: 0 0 8px;
  max-width: 70ch;
  white-space: pre-line;
}
.vault-line__facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 3px 12px;
  margin: 0 0 8px;
}
.vault-line__facts dt {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}
.vault-line__facts dd { margin: 0; }
.vault-line__edit {
  display: flex;
  gap: 16px;
  margin: 0;
  font-size: 12.5px;
}

/* Значение — моноширинным и с переносом по любому символу: логин и
   пароль читают посимвольно, и «l» против «1» должно быть видно. */
.vault-value {
  display: inline-block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  background: var(--line2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 4px 9px;
  color: var(--ink);
  overflow-wrap: anywhere;
  user-select: all;
}
.vault-value--secret { background: var(--soft); border-color: #cfe6dd; }
.vault-value[hidden] { display: none; }
/* Показанный пароль принимает фокус программно (скрипт переводит его
   туда, чтобы значение прочитали сразу), но по Tab в обход не встаёт —
   и рамку рисуем только когда фокус действительно на нём. */
.vault-value:focus { outline: 2px solid var(--accent2); outline-offset: 1px; }

.vault-foot {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 900px;
  margin-top: 24px;
}
.vault-legend {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 3px 12px;
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.vault-legend dt { font-weight: 600; color: var(--ink2); }
.vault-legend dd { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .vault-line__head::before { transition: none; }
}

/* Поиск и адрес — новые для кабинета типы полей (раздел «Доступы»).
   Базовое правило форм перечисляет типы поимённо и этих двух не знает,
   поэтому браузер рисовал бы их своим системным стилем посреди наших.
   Значения те же — одно поведение на всю форму. */
input[type="search"],
input[type="url"] {
  width: 100%;
  max-width: 380px;
  padding: 9px 12px;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  outline: none;
}

/* ===== Москва: корректировка базы прямо в строке начисления ==============
   Слово владельца 01.08.2026: «корректировки не указываются? и возможность
   отсюда добавить?». Слой дописан в конец файла и ничего выше не меняет.

   Разрез «факт зачёркнут → база рядом» рисуется теми же .dim/<s>/.strong/
   .sub-line/.tag.off, что в таблице сделок: одна сущность — один вид.
   Здесь только то, чего в тех правилах не было: столбец действия у ЭТОЙ
   таблицы (правила сделок прибиты к table.deals) и раскрытие причины. */

table.accruals td.row-actions {
  white-space: nowrap;
  vertical-align: middle;
}
table.accruals td.row-actions .btn-link {
  margin: 0;
  padding: 4px 8px;
  min-height: 26px;
  font-size: 11.5px;
}

/* Исключённая сделка: «не считается» стоит в денежной колонке вместо
   суммы. Крупный денежный кегль ей не нужен — это не деньги, а их
   отсутствие, и он спорил бы с настоящими суммами соседних строк. */
table.accruals td.money .dim {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: normal;
}

/* Ярлык «не считается» стоит в колонке чисел и обязан быть по её краю:
   .sub-line блочная (в ней двухэтажные ячейки таблицы сделок), и без
   этого пилюля растягивалась бы на всю ширину колонки заливкой. */
table.accruals td .tag.sub-line {
  display: block;
  width: fit-content;
  margin-left: auto;
}

/* Причина правки — под раскрытием: она бывает в предложение длиной, а
   колонка узкая. Пилюля раскрытия — общая .row-more (лента ДДС), здесь
   только колонка «пилюля над текстом», её край и сам текст. */
.why {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  margin-top: 5px;
}
.why__text {
  margin: 4px 0 0;
  max-width: min(34ch, 100%);
  font-size: 11.5px;
  line-height: 1.4;
  font-weight: 400;
  color: var(--muted-strong);
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ===== Журнальная сетка (.ledger) ===================================
   Ширины колонок объявлены в <colgroup> и table-layout их фиксирует.
   Без этого браузер меряет колонку по самому длинному слову: «Медион ·
   Максим Я.» разворачивал строку в три этажа, лента становилась шире
   панели, и колонка действий уезжала за правый край — то, на что
   владелец жаловался 01.08.2026. Здесь ширина задана заранее, а
   содержимое подчиняется ей: одна запись — одна строка, длинное
   значение обрезается многоточием, полный текст живёт в title. */
.ledger { table-layout: fixed; font-size: 13px; }
.ledger tbody td,
.ledger tbody th {
  padding: 9px 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.4;
}
.ledger thead th { padding: 10px 12px; }
.ledger tbody th[scope="row"] { font-weight: 600; }
.ledger .tag {
  font-size: 10px;
  padding: 1px 6px;
  vertical-align: 1px;
  white-space: nowrap;
}
/* Второй факт в ячейке — приписка В СТРОКУ, а не вторым этажом:
   «Медион · Максим Я.», «35 500 → 37 500». Этажи и были причиной
   строк по 78–145px. */
.ledger__aside {
  color: var(--muted);
  font-weight: 400;
}
.ledger__aside::before { content: " · "; }
.ledger__arrow { color: var(--muted); }
.ledger td.blank, .ledger th.blank { color: var(--muted); }

/* Рельс действий — последняя колонка фиксированной ширины. Прилипание
   (position:sticky) снято намеренно: оно спасало от горизонтальной
   прокрутки, а прокрутки больше нет, зато тень прилипшей колонки резала
   соседнюю ячейку и обрезала само слово «Действия». Рост допускается
   только вниз — когда раскрыто «ещё». */
.ledger td.row-actions {
  overflow: visible;
  text-align: right;
  white-space: nowrap;
  padding-left: 6px;
  padding-right: 10px;
  position: static;
  box-shadow: none;
}
.ledger thead th.row-actions { position: static; box-shadow: none; }
.ledger td.row-actions .btn-link {
  display: inline-flex;
  min-height: 0;
  margin: 0;
  padding: 3px 6px;
  border: 0;
  background: none;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--accent2);
}
.ledger td.row-actions .row-more > summary {
  min-height: 0;
  padding: 3px 7px;
  font-size: 11.5px;
}
/* Область нажатия 44px без роста самой кнопки: строка журнала обязана
   остаться в 40px, а палец обязан попадать (WCAG 2.5.8). */
.ledger td.row-actions .btn-link,
.ledger td.row-actions .row-more > summary { position: relative; }
.ledger td.row-actions .btn-link::after,
.ledger td.row-actions .row-more > summary::after {
  content: "";
  position: absolute;
  inset: -12px -3px;
}
.ledger .row-more[open] > summary { color: var(--accent2); }
.ledger .row-more__items { white-space: normal; justify-content: flex-end; }
.ledger__locked {
  font-size: 11px;
  color: var(--muted);
  cursor: help;
}

/* Ширины колонок лент. Проценты, а не пиксели: панель кабинета одна и
   та же на 1280 и 1440 (max-width), но пропорции переживут и смену
   этой ширины. Колонка сводной строки карточек (.c-meta) ширины не
   получает — на десктопе её ячейки скрыты, и место ей не нужно. */
.cf-feed col.c-date { width: 8%; }
.cf-feed col.c-what { width: 17%; }
.cf-feed col.c-who { width: 16%; }
.cf-feed col.c-account { width: 10%; }
.cf-feed col.c-city { width: 8%; }
.cf-feed col.c-money { width: 10%; }
.cf-feed col.c-note { width: 18.5%; }
.cf-feed col.c-actions { width: 12.5%; }

.payments col.c-date { width: 8.5%; }
.payments col.c-who { width: 19%; }
.payments col.c-got { width: 10%; }
.payments col.c-account { width: 13%; }
.payments col.c-money { width: 11%; }
.payments col.c-note { width: 27.5%; }
.payments col.c-actions { width: 11%; }

.corrections-feed col.c-deal { width: 7%; }
.corrections-feed col.c-date { width: 8%; }
.corrections-feed col.c-city { width: 10%; }
.corrections-feed col.c-status { width: 10%; }
.corrections-feed col.c-price { width: 12.5%; }
.corrections-feed col.c-comm { width: 12.5%; }
.corrections-feed col.c-why { width: 19%; }
.corrections-feed col.c-changed { width: 10%; }
.corrections-feed col.c-actions { width: 11%; }

.accounts col.c-name { width: 18%; }
.accounts col.c-bank { width: 13%; }
.accounts col.c-how { width: 14%; }
.accounts col.c-req { width: 18%; }
.accounts col.c-recipient { width: 13%; }
.accounts col.c-comment { width: 12%; }
.accounts col.c-actions { width: 12%; }

.partners-index col.c-name { width: 24%; }
.partners-index col.c-cities { width: 28%; }
.partners-index col.c-balance { width: 14%; }
.partners-index col.c-login { width: 14%; }
.partners-index col.c-actions { width: 20%; }

/* Выравнивание журнала: слева — чем запись опознаётся (дата, категория,
   бригада), справа — деньги и действия. Кабинет по умолчанию жмёт всё
   вправо, и в ленте это давало рваный левый край: глаз не мог пробежать
   столбец категорий сверху вниз, потому что каждая строка начиналась в
   своём месте. */
.ledger thead th,
.ledger tbody td,
.ledger tbody th { text-align: left; }
.ledger thead th.num,
.ledger tbody td.num,
.ledger thead th.row-actions,
.ledger tbody td.row-actions { text-align: right; }

/* Комментарий и причина — в одну строку с многоточием; полный текст в
   title. Их перенос и был вторым источником высоких строк после этажей. */
.ledger tbody td.comment,
.ledger tbody td.why-cell {
  max-width: none;
  white-space: nowrap;
}
/* Колонка действий ширину берёт из <colgroup>: собственная ширина
   пережимала сетку на пару пикселей и возвращала прокрутку. */
.ledger td.row-actions, .ledger th.row-actions { width: auto; }
/* Рельс действий не переносится: «Исправить» и «ещё» стоят в один ряд
   и ширина колонки посчитана под них. Перенос вернул бы двухэтажную
   строку — ровно то, от чего лента и уходит. */
.ledger td.row-actions { flex-wrap: nowrap; justify-content: flex-end; gap: 6px; }
.deals col.c-deal { width: 11%; }
.deals col.c-price { width: 10.5%; }
.deals col.c-date { width: 9%; }
.deals col.c-city { width: 13%; }
.deals col.c-status { width: 14%; }
.deals col.c-comm { width: 11%; }
.deals col.c-partner { width: 12%; }
.deals col.c-charge { width: 8.5%; }
.deals col.c-actions { width: 11%; }
/* Ярлыки-флажки сделки («без партнёра») и срок на стадии стоят В СТРОКУ
   с номером и статусом: столбиком они и растили строку списка. */
.ledger .problem-badges { display: inline; }
.ledger .stage-age { display: inline; margin: 0 0 0 6px; }
.ledger .sub-line { display: inline; margin: 0 0 0 6px; }

/* Сверка по городам: от 11 до 15 числовых колонок — она шире панели по
   существу, и резать набор нельзя (это аудиторский след расчёта). Вместо
   этого прилипает первая колонка: прокручивая числа вправо, видно, о
   каком городе строка. Поля ужаты — 14px с двух сторон на пятнадцати
   колонках стоили 420px ширины. */
.city-grid { font-size: 12.5px; }
.city-grid thead th { padding: 10px 8px; }
.city-grid tbody td, .city-grid tbody th { padding: 9px 8px; white-space: nowrap; }
.city-grid thead th:first-child,
.city-grid tbody th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 2;
  text-align: left;
  box-shadow: 6px 0 8px -8px rgba(16, 24, 40, .35);
}
.city-grid thead th:first-child { background: var(--line2); }
.city-grid tbody th[scope="row"] { background: var(--panel); }
.city-grid tbody tr.total th[scope="row"] { background: var(--soft); }
/* Заголовки сверки переносятся в две строки — «Мне поступило ₽» и
   «База: «Комиссия» −₽» в одну строку стоили 280px ширины на двоих.
   Высоту СТРОК это не трогает: переносится только шапка. */
.city-grid thead th { white-space: normal; line-height: 1.25; }
.city-grid thead th:first-child { white-space: nowrap; }
.sources col.c-source { width: 26%; }
.sources col.c-state { width: 20%; }
.sources col.c-when { width: 18%; }
.sources col.c-done { width: 12%; }
.sources col.c-failed { width: 12%; }
.sources col.c-error { width: 12%; }
