/* Карточка клиента — вёрстка по макету `docs/designe/SellSaver Admin —
   Клиент`. Здесь только геометрия и композиция экрана: токены (`--panel`,
   `--sunken`, `--rowline`, `--text` и прочие) и шрифты (`InterPanel`,
   `PTSerifPanel`) объявлены в `admin.css`, обе темы работают через них —
   своих цветов файл не заводит. */

.clientcard { display: flex; flex-direction: column; gap: var(--sp-gutter); }

/* ── Шапка ─────────────────────────────────────────────────────────────── */

.clientcard__head { display: flex; align-items: center; gap: var(--sp-block); flex-wrap: wrap; }

/* Аватар-инициалы: человека в списке из полусотни карточек опознают по нему
   раньше, чем прочитан адрес. Круг, а не плитка, — плитками в панели
   обозначены маркетплейсы, и вторая их разновидность путала бы. */
.clientcard__avatar { width: 46px; height: 46px; flex: 0 0 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--avatar); color: var(--text2);
  font-size: var(--fs-lead); font-weight: 700; letter-spacing: .02em; }

.clientcard__title { flex: 1; min-width: 280px; display: flex;
  flex-direction: column; gap: var(--sp-tight); }
/* Гарнитуру, кегль и вес имени задаёт общий `h1` панели (`admin.css`) — тот
   же, что у имени магазина. Здесь остаётся только раскладка: номер записи
   стоит в одну строку с именем по общей базовой линии. */
.clientcard__title h1 { display: flex; align-items: baseline; gap: var(--sp-item);
  flex-wrap: wrap; }

/* Номер записи мельче имени и приглушён: его сверяют с обращением, но читают
   вторым — крупный он спорил бы с именем за внимание. */
.clientcard__id { font-family: "InterPanel", system-ui, sans-serif; font-size: var(--fs-row);
  font-weight: 500; color: var(--muted3); }

.clientcard__sub { display: flex; align-items: center; gap: var(--sp-item); flex-wrap: wrap;
  font-size: var(--fs-body); color: var(--muted2); }

.clientcard__badges { display: flex; align-items: center; gap: var(--sp-item); flex-wrap: wrap; }

/* Полоса вкладок карточки — общий `.adm-tabs`, тот же, что у записи с
   дочерними разделами, и без единой местной правки: зазор до шапки и до
   содержимого задаёт `gap` стека `.clientcard`. Своего правила здесь нет
   намеренно — с него и начинается расхождение переключателей. */

/* ── Встроенный список ─────────────────────────────────────────────────── */

/* Секция вокруг чужого списка (`admin/_embedded_list.html`). Своей таблицы у
   неё нет — только заголовок, ссылка на полноценный экран и объяснение
   пустоты; всё остальное рисуют общие фрагменты списка.

   Сама секция — сетка `adm-list-layout` (таблица + колонка действий), поэтому
   колонкой выкладывается КАРТОЧКА внутри неё, а не секция: раскладку в
   столбец здесь ставить нельзя, иначе колонка действий снова упадёт под
   таблицу во всю ширину. */
.adm-embed__card { display: flex; flex-direction: column; min-width: 0; }
.adm-embed .adm-card__head { display: flex; align-items: center;
  justify-content: space-between; gap: var(--sp-row); }

/* Подпись под пустой таблицей: «пустое ≠ ноль» — строка объясняет, что
   означает пустота именно здесь, а не оставляет оператора гадать. */
.adm-embed__hint { padding: 0 var(--sp-gutter) var(--sp-block); font-size: var(--fs-body); color: var(--muted2); }

/* ── Обзор: тревоги ────────────────────────────────────────────────────── */

/* Плашка на повод, только при поводе. Две цветовые оси не смешиваются:
   янтарь — «требует решения», красный — «уже сломано», нейтральная — просто
   информация (заявка на вывод). */
.clientcard__alerts { display: flex; flex-direction: column; gap: var(--sp-item); }
.clientcard__alert { display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-block); padding: var(--sp-row) var(--sp-block); border-radius: 13px; font-size: var(--fs-row);
  font-weight: 600; border: 1px solid var(--border2); background: var(--panel);
  color: var(--text2); }
.clientcard__alert-text { flex: 1; min-width: 0; }
.clientcard__alert-link { flex: 0 0 auto; font-size: var(--fs-body); font-weight: 500;
  color: inherit; text-decoration: underline; text-underline-offset: 2px;
  white-space: nowrap; }
.clientcard__alert--err { color: var(--err); background: rgba(241, 98, 111, .08);
  border-color: rgba(241, 98, 111, .24); }
.clientcard__alert--warn { color: var(--warn); background: rgba(241, 163, 59, .08);
  border-color: rgba(241, 163, 59, .24); }
.clientcard__alert--info { color: var(--link); background: rgba(127, 168, 232, .08);
  border-color: rgba(127, 168, 232, .22); }

/* ── Обзор: ряд KPI ────────────────────────────────────────────────────── */

.clientcard__kpi { display: grid; gap: var(--sp-gutter);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.clientcard__tile { padding: var(--sp-block) var(--sp-block); border-radius: var(--radius-card);
  background: var(--panel); border: 1px solid var(--border); }
/* Плитка — та же, что у KPI карточки магазина (`.shopcard__kpi-*`) и обзора:
   подпись микрокеглем с трекингом, число `--fs-metric`, примечание ремаркой.
   Своих значений блок больше не заводит. */
.clientcard__tile-label { font-size: var(--fs-micro); letter-spacing: .12em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4);
  margin-bottom: var(--sp-item); }
.clientcard__tile-value { font-size: var(--fs-metric); font-weight: 600;
  letter-spacing: -.03em; line-height: 1; color: var(--text); }
.clientcard__tile-value.is-err { color: var(--err); }
.clientcard__tile-value.is-warn { color: var(--warn); }
.clientcard__tile-note { margin-top: var(--sp-snug); font-size: var(--fs-hint); color: var(--muted3); }

/* ── Взаиморасчёты: весы и подписи (Обзор + Кошелёк) ───────────────────── */

/* Блок ОДИН на карточку и включается двумя вкладками одним и тем же фрагментом
   (`admin/_client_settlement.html`), поэтому и правила здесь одни. Фон, рамку и
   отступы даёт `.adm-card`, расстояние до соседних блоков — `gap` колонки
   `.clientcard`; своей отбивки блок не заводит ни на одной из вкладок. */
.clientcard__scales-empty { font-size: var(--fs-row); color: var(--muted3); }
.clientcard__scales-empty b { color: var(--text2); font-weight: 600; }

/* Подписи сторон — над своими концами полосы, лицом к центру. */
.clientcard__scales-heads { display: flex; justify-content: space-between;
  align-items: baseline; gap: var(--sp-block); }
.clientcard__scales-head { display: flex; align-items: baseline; gap: var(--sp-item);
  min-width: 0; }
.clientcard__scales-head.is-right { flex-direction: row-reverse; }
.clientcard__scales-title { font-size: var(--fs-micro); letter-spacing: .12em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4); }
.clientcard__scales-sum { font-size: var(--fs-lead); font-weight: 600;
  letter-spacing: -.02em; color: var(--text2);
  font-variant-numeric: tabular-nums; }
.clientcard__scales-sum.is-in { color: var(--green); }

/* Полоса растёт от центральной оси в обе стороны: левая половина прижата к оси
   справа, правая — слева. Длины сравниваются от ОДНОЙ точки, а не от разных
   краёв экрана, ради чего весы и нарисованы. */
.clientcard__scales-bar { display: grid; align-items: center; margin-top: var(--sp-item);
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); }
.clientcard__scales-side { display: flex; gap: var(--sp-tight); height: 14px; }
.clientcard__scales-side:first-child { flex-direction: row-reverse; }
.clientcard__scales-seg { border-radius: 4px; min-width: 3px; }
.clientcard__scales-axis { width: 1px; height: 22px; margin: 0 var(--sp-snug);
  background: var(--border2); }

/* Цвета — по смыслу, не по красоте: пришедшее к нам зелёное (`--brand`, тот же
   оттенок, что у купленной корзины баланса); выплаченное приглушённое — это
   свершившийся факт, внимания не требующий; долг янтарный — та же ось
   «требует решения», что во всей панели. Красным долг не красится: он норма
   работающей партнёрской программы, а не поломка. */
.clientcard__scales-seg.is-income { background: var(--brand); }
.clientcard__scales-seg.is-payouts { background: var(--muted2); }
.clientcard__scales-seg.is-debt { background: var(--warn); }

/* Подписи — колонками с цветной чертой слева, как легенда полосы состава
   баланса: черта связывает подпись с сегментом, не тратя строки на кружки. */
.clientcard__scales-legend { display: grid; gap: var(--sp-block); margin-top: var(--sp-block);
  grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) {
  .clientcard__scales-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .clientcard__scales-legend { grid-template-columns: minmax(0, 1fr); }
}
.clientcard__scales-item { padding-left: var(--sp-row); border-left: 2px solid var(--faint);
  min-width: 0; }
.clientcard__scales-item.is-income { border-left-color: var(--brand); }
.clientcard__scales-item.is-payouts { border-left-color: var(--muted2); }
.clientcard__scales-item.is-debt { border-left-color: var(--warn); }
.clientcard__scales-item.is-ok { border-left-color: var(--brand); }
.clientcard__scales-item.is-err { border-left-color: var(--err); }
/* Ноль — «этого ещё не было», а не значимая величина: подпись приглушается
   целиком, чтобы не спорить за внимание с непустыми. */
.clientcard__scales-item.is-zero { border-left-color: var(--faint); }
.clientcard__scales-label { font-size: var(--fs-hint); color: var(--muted2); }
.clientcard__scales-value { margin-top: var(--sp-tight); font-size: var(--fs-lead);
  font-weight: 600; letter-spacing: -.02em; color: var(--text);
  font-variant-numeric: tabular-nums; }
.clientcard__scales-item.is-zero .clientcard__scales-value { color: var(--muted3); }
.clientcard__scales-item.is-debt .clientcard__scales-value { color: var(--warn); }
.clientcard__scales-item.is-err .clientcard__scales-value { color: var(--err); }
/* Токены — под рублями и мельче их: это та же величина в служебной единице,
   её читают вторым взглядом, когда сверяют курс. */
.clientcard__scales-tokens { margin-top: var(--sp-hair); font-size: var(--fs-body);
  color: var(--muted2); font-variant-numeric: tabular-nums; }
.clientcard__scales-item.is-zero .clientcard__scales-tokens { color: var(--muted3); }
.clientcard__scales-hint { margin-top: var(--sp-tight); font-size: var(--fs-hint);
  color: var(--muted4); line-height: 1.4; }
/* Итог отделён линией, а не цветом: это не четвёртая часть полосы, а её
   вывод — разность двух сумм, места на шкале у неё нет. */
.clientcard__scales-net { padding-left: var(--sp-block); border-left-width: 1px; }
/* Оговорка под подписями: почему долг меньше начисленного. Отделена линией во
   всю ширину — она относится ко всему блоку, а не к четвёртой колонке. */
.clientcard__scales-foot { margin-top: var(--sp-block); padding-top: var(--sp-row);
  border-top: 1px solid var(--rowline); font-size: var(--fs-hint);
  color: var(--muted3); }

/* ── Обзор: платежи по месяцам ─────────────────────────────────────────── */

/* Столбец = оплаченные платежи за свой день или месяц (шаг выбирает длина
   окна). Возврат — тонкая засечка ПОВЕРХ, а не вычет: вычтенный внутри, он
   превратил бы «заплатил, потом вернули» в «заплатил меньше», и повод для
   разбора исчез бы.

   Зазор считает сервер по числу столбцов (`payments_chart`): у года по дням их
   365, и постоянные 4px съели бы всю ширину. Медиазапросом это не выражается —
   зазор зависит от данных, а не от экрана. `position: relative` держит
   подсказку: она позиционируется внутри ряда. */
/* Поле графика — то же, что у расхода выше: базовая линия и две линии сетки
   фоном (верх и середина). Окно без платежей выглядит как график с нулями, а
   не как несработавшая отрисовка. */
.clientcard__paybars { position: relative; display: flex; align-items: flex-end;
  gap: var(--pay-gap, var(--sp-tight)); height: 132px;
  border-bottom: 1px solid var(--rowline);
  background-image: linear-gradient(var(--rowline), var(--rowline)),
                    linear-gradient(var(--rowline), var(--rowline));
  background-size: 100% 1px, 100% 1px;
  background-position: 0 0, 0 50%;
  background-repeat: no-repeat; }
.clientcard__paybar { position: relative; flex: 1 1 0; min-width: 0;
  height: 100%; display: flex; align-items: flex-end;
  border-radius: 5px 5px 0 0; }

/* Засечка нулевого слота — два пикселя у дна, ПОД заливкой: у месяца с
   платежами её не видно, у пустого она и есть ответ «денег в этом месяце не
   приходило». Цвет нейтральный, а не цвет данных: серая засечка и зелёный
   столбец — разные сущности. Минимальная высота столбца с деньгами поднята
   (`panel_money.MIN_BAR`), чтобы он был заметно выше засечки. */
.clientcard__paybar::before { content: ""; position: absolute;
  left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px;
  background: var(--faint); z-index: 0; }
.clientcard__paybar-fill { position: relative; z-index: 1; width: 100%;
  border-radius: 5px 5px 0 0; background: var(--brand); }
/* Незакончённый столбец штрихуется, иначе его провал читается как падение
   выручки, а не как «период ещё идёт». */
.clientcard__paybar.is-current .clientcard__paybar-fill {
  background: repeating-linear-gradient(135deg, var(--brand) 0 3px,
    transparent 3px 6px), var(--sunken); }
.clientcard__paybar-refund { position: absolute; left: 0; bottom: 0; width: 100%;
  border-radius: 5px 5px 0 0; background: var(--err); opacity: .85; }

/* Наведение — тот же жест, что у графика расхода: подложка во всю высоту слота
   под наведённым столбцом и приглушение остальных, чтобы подсказка читалась
   вместе со своим столбцом, а не поверх одинаково ярких соседей. Пометки
   ставит скрипт; без него график остаётся обычным. */
/* Подсветка — сменой цвета той же дорожки, а не фоном столбца: дорожка лежит
   поверх фона, и покрашенный фон под ней просто не был бы виден. */
/* Подложка наведения — отдельный слой поверх засечки и шире столбца на
   полузазора, как у графика расхода: слот наведённого периода смыкается с
   соседними. Красить саму засечку нельзя — она в два пикселя высотой, и
   наводиться было бы не на что. */
.clientcard__paybar::after { content: ""; position: absolute;
  top: 0; bottom: 0; left: calc(var(--pay-gap, 4px) / -2);
  right: calc(var(--pay-gap, 4px) / -2);
  border-radius: 7px; background: var(--hover2); opacity: 0; z-index: 0; }
.clientcard__paybar.is-hot::after { opacity: 1; }
.clientcard__paybars.is-hovered .clientcard__paybar-fill { opacity: .45; }
.clientcard__paybars.is-hovered .clientcard__paybar.is-hot
  .clientcard__paybar-fill { opacity: 1; }

/* Ось: у месяцев подпись под каждым столбцом, у дней — три засечки по краям и
   в середине (`is-sparse`), иначе они сливаются в серую полосу. */
.clientcard__payaxis { display: flex; gap: var(--pay-gap, var(--sp-tight)); margin-top: var(--sp-snug);
  font-size: var(--fs-eyebrow); color: var(--muted4); }
.clientcard__payaxis span { flex: 1 1 0; text-align: center; }
.clientcard__payaxis.is-sparse { justify-content: space-between; }
.clientcard__payaxis.is-sparse span:first-child { text-align: left; }
.clientcard__payaxis.is-sparse span:last-child { text-align: right; }

/* Подвал: слева сумма окна (то, что видно на графике), справа — итог за всё
   время. Две величины отвечают на разные вопросы, и ставить их рядом без
   разделения значило бы предлагать сравнить несравнимое. */
.clientcard__payfoot { display: flex; align-items: baseline; flex-wrap: wrap;
  gap: var(--sp-item); margin-top: var(--sp-row); padding-top: var(--sp-item);
  border-top: 1px solid var(--rowline); font-size: var(--fs-hint);
  color: var(--muted4); }
.clientcard__payfoot-main { font-size: var(--fs-lead); font-weight: 600;
  letter-spacing: -.02em; color: var(--text);
  font-variant-numeric: tabular-nums; }
.clientcard__payfoot-main span { font-size: var(--fs-hint); font-weight: 400;
  letter-spacing: 0; color: var(--muted4); }
.clientcard__payfoot-lead { flex: 1 1 auto; }
.clientcard__payfoot-back { color: var(--err); }

/* ── Обзор: две колонки ────────────────────────────────────────────────── */

/* Правая колонка уезжает под левую на узком экране: горизонтальной прокрутки
   у страницы не бывает ни при какой ширине от 1280 px. */
.clientcard__cols { display: grid; gap: var(--sp-gutter); grid-template-columns: minmax(0, 1fr) 340px;
  align-items: start; }
@media (max-width: 1660px) { .clientcard__cols { grid-template-columns: minmax(0, 1fr); } }
.clientcard__main, .clientcard__side { display: flex; flex-direction: column; gap: var(--sp-gutter);
  min-width: 0; }
/* Пояснение под заголовком блока — та же ремарка, что `.shopcard__hint`. */
.clientcard__sub-note { font-size: var(--fs-hint); color: var(--muted3); margin-top: var(--sp-hair); }
/* Ссылка «Все магазины →», кнопка правки и сегмент периода уходят к правому
   краю шапки — как ремарка и кнопка в шапке панели магазина. */
.clientcard .adm-card__head > a,
.clientcard .adm-card__head > .adm-btn,
.clientcard .adm-card__head > .adm-seg { margin-left: auto; }
.clientcard .adm-card__head > .adm-btn { flex: 0 0 auto; }
.clientcard .adm-card__head > a { font-size: var(--fs-body); }
/* Надзаголовок группы внутри блока («По операциям», «Списания») — ступень
   надзаголовка, та же, что у шапки таблицы и `.adm-page__eyebrow`. */
.clientcard__block-title { font-size: var(--fs-eyebrow); letter-spacing: .1em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4);
  margin: var(--sp-block) 0 var(--sp-item); }

/* ── Обзор: «Профиль» и «Доступ и права» ───────────────────────────────── */

/* ДВА самостоятельных блока рядом НАД графиком, а не одна карточка «Профиль
   и доступ» с двумя группами внутри (разделены 2026-08-16) и не две карточки
   в правой колонке (перенесены оттуда 2026-08-16: столбиком это были
   четырнадцать строк «подпись — значение», и колонка вытягивалась вдвое выше
   графика).

   Ряд, а не два блока друг под другом: рядом они занимают ровно ту же высоту,
   что занимала общая полоса, и график расхода остаётся над сгибом. Доли и
   точка перелома те же, что у `.clientcard__burn`, чтобы соседние блоки
   ломались одновременно, а не по очереди; зазор — тот же, что между блоками
   левой колонки (`.clientcard__main`), иначе ряд читался бы теснее, чем всё
   вокруг него. Вертикальной линии между ними больше нет: границу проводят
   сами рамки карточек. */
.clientcard__facts { display: grid; gap: var(--sp-gutter);
  grid-template-columns: minmax(0, 1.55fr) minmax(240px, 1fr); }
@media (max-width: 1240px) {
  .clientcard__facts { grid-template-columns: minmax(0, 1fr); }
}
/* Отступы тела — как у `.clientcard__burn-side`: соседние блоки колонки
   обязаны начинать содержимое на одной вертикали. */
.clientcard__facts-body { padding: var(--sp-block) var(--sp-gutter) var(--sp-block); min-width: 0; }

/* Ячейки укладываются по ширине сами: при 1.55 доли их влезает четыре, в
   узком блоке — две. Фиксированное число колонок оставляло бы либо дыру
   справа, либо обрезанный email. */
.clientcard__facts-grid { display: grid; gap: var(--sp-row) var(--sp-section);
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
/* Подпись над значением, как в плитке KPI: пара в строку («Email — …») при
   нескольких колонках заставляет глаз искать, где кончается подпись. */
.clientcard__fact { min-width: 0; }
.clientcard__fact-label { font-size: var(--fs-micro); letter-spacing: .12em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4);
  margin-bottom: var(--sp-tight); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
/* Значение в одну строку с многоточием: длинный email не имеет права
   растянуть ячейку и сломать ряд — целиком он есть в подсказке. */
.clientcard__fact-value { font-size: var(--fs-row); color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Тон значения — те же две оси, что во всей панели: янтарь «требует решения»
   (почта не подтверждена, зависшая смена адреса), красный «уже сломано»
   (вход закрыт). Синий — просто примечательно (служебные полномочия), серый
   — обычное состояние флага и незаполненное поле: они не должны спорить за
   внимание с тем, что от них отличается. */
.clientcard__fact-value.is-warn { color: var(--warn); }
.clientcard__fact-value.is-err { color: var(--err); }
.clientcard__fact-value.is-info { color: var(--link); }
.clientcard__fact-value.is-muted { color: var(--muted4); }

/* ── Обзор: график расхода ─────────────────────────────────────────────── */

/* Раскладка макета: слева график, справа обе разбивки столбцом, между ними
   вертикальная линия. Разбивки ПОД графиком (как было до 2026-08-16)
   вытягивали блок почти на два экрана. Ширины из макета: график занимает
   1.55 доли, колонка разбивок — минимум 240px. */
.clientcard__burn { display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(240px, 1fr); }
.clientcard__burn-chart { padding: var(--sp-block) var(--sp-gutter) var(--sp-block); border-right: 1px solid var(--line); }
.clientcard__burn-side { padding: var(--sp-block) var(--sp-gutter) var(--sp-block); min-width: 0; }
/* Узкий экран: колонки встают друг под друга, и вертикальная линия между
   ними превращается в горизонтальную — иначе она висит сбоку у пустоты. */
@media (max-width: 1240px) {
  .clientcard__burn { grid-template-columns: minmax(0, 1fr); }
  .clientcard__burn-chart { border-right: 0; border-bottom: 1px solid var(--line); }
}

/* Столбец дня — ЗАПУСКИ, поделённые на платные (заливка) и бесплатные
   (штриховка). Почему не токены — см. `panel_burn._segments`: бесплатный
   запуск стоит ноль и в шкале токенов не существует вовсе.

   Штриховка, а не второй цвет: цветовые оси панели заняты смыслом (янтарь —
   «требует решения», красный — «сломано»), и бесплатный запуск — ни то ни
   другое. Заливка задана переменной, потому что тот же рисунок повторяет
   образец в легенде, и два его экземпляра обязаны совпадать. */
.clientcard { --burn-free: repeating-linear-gradient(45deg,
  var(--track), var(--track) 3px, var(--border4) 3px, var(--border4) 6px); }
/* Обёртка нужна подсказке: она позиционируется абсолютно относительно
   области графика, а не страницы. */
.clientcard__chart { position: relative; }
/* Зазор приходит переменной от сервера (`panel_burn._bar_gap`): у «Года» дней
   365, и постоянные 3px съели бы всю ширину графика — столбцы упёрлись бы в
   `min-width` и полезли за край блока. */
/* Поле графика: базовая линия внизу и две линии сетки — по верху и по
   середине. Без них окно без запусков — пустое место, неотличимое от
   несработавшей отрисовки; с ними видно и поле, и половину шкалы. Линии
   рисуются фоном, а не узлами: лишние узлы в ряду из трёхсот столбцов стоили
   бы больше, чем весят.

   Тот же приём и те же токены — у графика платежей ниже: два графика на одном
   экране обязаны говорить одним языком. */
.clientcard__bars { display: flex; align-items: flex-end; height: 210px;
  gap: var(--burn-gap, var(--sp-tight));
  border-bottom: 1px solid var(--rowline);
  background-image: linear-gradient(var(--rowline), var(--rowline)),
                    linear-gradient(var(--rowline), var(--rowline));
  background-size: 100% 1px, 100% 1px;
  background-position: 0 0, 0 50%;
  background-repeat: no-repeat; }
.clientcard__bar { flex: 1; min-width: 1px; display: flex; flex-direction: column;
  justify-content: flex-end; gap: var(--sp-hair); height: 100%; cursor: crosshair;
  position: relative; }

/* Выделение столбца — ровно то же, что на графике магазина
   (`.shopcard__chart-band` + приглушение остальных): подложка во всю высоту
   слота и прозрачность у прочих столбцов. Приглушением, а не подсветкой
   активного: осветление работает только на тёмной теме, а прозрачность
   читается на обеих. Здесь подложка — псевдоэлемент самого столбца, а не
   отдельный слой: столбец тут настоящий элемент (на графике магазина
   рисует SVG, и слой позиционирует скрипт), и второй узел ради сходства кода
   был бы выдумкой.

   Подложка лежит ПОД сегментами (`z-index`), иначе непрозрачная заливка
   закрывала бы ровно то, на что указывает. Слот расширен на половину зазора
   в каждую сторону — так подложки соседних дней смыкаются, как на графике
   магазина, где слот дня непрерывен. */
/* Засечка нулевого слота — два пикселя у самого дна, ПОД заливкой столбца: у
   дня с запусками её просто не видно, у пустого она и есть ответ «здесь ничего
   не запускали». Сплошная дорожка во всю высоту, которая стояла тут раньше,
   превращала поле в серое полотно и топила в нём сами столбцы.

   Цвет нейтральный (`--faint`), а не цвет данных: серая засечка и зелёный
   столбец — разные сущности, и путать их нельзя даже на минимальной высоте. */
.clientcard__bar::before { content: ""; position: absolute;
  left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px;
  background: var(--faint); z-index: 0; }
/* Подложка наведения — отдельным слоем поверх дорожки и по-прежнему шире её на
   полузазора: слот наведённого дня обязан смыкаться с соседними, как на
   графике магазина, а постоянная дорожка — наоборот, оставлять между днями
   просвет, иначе она перестаёт показывать деление по дням. */
.clientcard__bar::after { content: ""; position: absolute;
  top: 0; bottom: 0; left: calc(var(--burn-gap, 3px) / -2);
  right: calc(var(--burn-gap, 3px) / -2);
  border-radius: 7px; background: var(--hover2); opacity: 0; z-index: 0; }
.clientcard__bar.is-hot::after { opacity: 1; }
.clientcard__bar-free, .clientcard__bar-paid { position: relative; z-index: 1;
  transition: opacity .12s ease; }
.clientcard__bars.is-hovered .clientcard__bar-free,
.clientcard__bars.is-hovered .clientcard__bar-paid { opacity: .38; }
.clientcard__bar.is-hot .clientcard__bar-free,
.clientcard__bar.is-hot .clientcard__bar-paid { opacity: 1; }

.clientcard__bar-free { background: var(--burn-free); border-radius: 3px 3px 0 0; }
.clientcard__bar-paid { background: var(--brand); }
/* Скругление достаётся верхнему сегменту: у столбца без бесплатных запусков
   это платный, иначе оно оказалось бы на стыке двух заливок. */
.clientcard__bar-paid.is-top { border-radius: 3px 3px 0 0; }

/* Метки покупок — засечки НАД столбцами, на той же оси времени. Треугольник
   вершиной вниз: он указывает на день, а кружок или квадрат просто висели бы
   рядом. Цвет — `--info`, тот же, что у заработанных токенов в диаграмме
   баланса: это про деньги клиента, а не про его расход. */
.clientcard__buys { position: relative; height: 12px; margin-bottom: var(--sp-tight); }
.clientcard__buy { position: absolute; top: 2px; width: 0; height: 0;
  transform: translateX(-50%); cursor: help;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 7px solid var(--info); }

/* Три засечки вместо подписи каждому столбцу: при 90 днях подписи сливаются
   в серую полосу. Точную дату называет подсказка столбца. */
.clientcard__axis { display: flex; justify-content: space-between; padding-top: var(--sp-item);
  font-size: var(--fs-hint); color: var(--muted4); font-variant-numeric: tabular-nums; }
.clientcard__legend { display: flex; align-items: center; gap: var(--sp-block); flex-wrap: wrap;
  padding-top: var(--sp-row); font-size: var(--fs-body); color: var(--text2); }
.clientcard__legend > span { display: inline-flex; align-items: center; gap: var(--sp-snug); }
.clientcard__swatch { width: 13px; height: 8px; flex: 0 0 13px; border-radius: 2px;
  background: var(--brand); }
.clientcard__swatch--free { background: var(--burn-free); }
.clientcard__legend-note { margin-left: auto; color: var(--muted2); }

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

/* Два числа под легендой: темп и ритм покупок. Ряд, а не строки: их
   сравнивают друг с другом («тратит всё так же, а покупать перестал»), и
   столбиком это сравнение распадается. Разделены линией сверху — они не
   часть легенды, а отдельный вывод из тех же данных. */
.clientcard__signals { display: flex; gap: var(--sp-section); flex-wrap: wrap; margin-top: var(--sp-row);
  padding-top: var(--sp-row); border-top: 1px solid var(--rowline); }
.clientcard__signal { display: flex; align-items: baseline; gap: var(--sp-item); min-width: 0;
  font-size: var(--fs-body); }
.clientcard__signal-label { font-size: var(--fs-eyebrow); letter-spacing: .1em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4); }
.clientcard__signal-value { font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.clientcard__signal-note { color: var(--muted3); min-width: 0; }
/* Янтарь — «требует решения»: темп просел или клиент молчит дольше
   собственного ритма покупок. Рост и ровный ход в подсветке не нуждаются. */
.clientcard__signal.is-warn .clientcard__signal-value,
.clientcard__signal.is-warn .clientcard__signal-note { color: var(--warn); }

/* Строка разбивки: подпись, число запусков, точечная выноска до суммы и
   полоса доли под ней. Выноска, а не колонки сетки: подписи операций и имена
   магазинов разной длины, и в сетке суммы двух списков вставали по разным
   вертикалям — глазу приходилось искать столбец заново в каждом списке. */
.clientcard__burn-group + .clientcard__burn-group { margin-top: var(--sp-block);
  padding-top: var(--sp-block); border-top: 1px solid var(--line); }
.clientcard__bar-row { padding: var(--sp-snug) 0; }
.clientcard__bar-line { display: flex; align-items: baseline; gap: var(--sp-item);
  font-size: var(--fs-body); }
.clientcard__bar-label { min-width: 0; color: var(--text2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.clientcard__bar-runs { flex: 0 0 auto; font-size: var(--fs-hint);
  color: var(--muted4); font-variant-numeric: tabular-nums; }
.clientcard__bar-lead { flex: 1; min-width: 12px;
  border-bottom: 1px dotted var(--border2); }
.clientcard__bar-sum { flex: 0 0 auto; font-weight: 500; color: var(--text);
  font-variant-numeric: tabular-nums; }
/* Ноль здесь — бесплатная операция, а не сбой: приглушаем, чтобы строка не
   читалась наравне с настоящими списаниями. */
.clientcard__bar-sum.is-zero { font-weight: 400; color: var(--muted4); }
.clientcard__bar-track { height: 3px; margin-top: var(--sp-tight); border-radius: 2px;
  background: var(--track); overflow: hidden; }
.clientcard__bar-fill { display: block; height: 100%; background: var(--brand); }
/* Магазины — другой оттенок: два списка стоят столбиком друг под другом, и
   одна заливка на оба читалась бы как один продолжающийся рейтинг. */
.clientcard__bar-fill--shop { background: var(--link); }
.clientcard__bar-fill.is-ok { background: var(--brand); }
.clientcard__bar-fill.is-warn { background: var(--warn); }
.clientcard__bar-fill.is-err { background: var(--err); }

/* ── Кошелёк: диаграмма баланса ────────────────────────────────────────── */

/* Раскладка макета: слева состав баланса, справа колонка плиток шириной
   300px. На узком экране плитки уезжают под состав — сжимать их некуда,
   внутри числа. */
.clientcard__balance { display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--sp-section); }
@media (max-width: 1100px) {
  .clientcard__balance { grid-template-columns: minmax(0, 1fr); }
}
.clientcard__balance-main { min-width: 0; }
.clientcard__balance-head { display: flex; align-items: baseline; gap: var(--sp-row);
  flex-wrap: wrap; }
/* Надзаголовок «Всего токенов» — общий `.clientcard__block-title`, но без
   верхнего отступа: он открывает блок, а не отделяет группу внутри него. */
.clientcard__balance-head .clientcard__block-title { margin: 0; }
.clientcard__balance-note { font-size: var(--fs-hint); color: var(--muted3); }
/* Единственное число на вкладке, которое читают через всю комнату, — оно и
   крупнее всей остальной шкалы. Своя ступень тут не заводится: это `h1`
   экрана по величине, только цифрами интерфейсного шрифта. */
.clientcard__balance-total { margin-top: var(--sp-snug); font-size: var(--fs-display);
  font-weight: 600; letter-spacing: -.035em; line-height: 1.05; color: var(--text);
  font-variant-numeric: tabular-nums; }
.clientcard__balance-total.is-err { color: var(--err); }

/* Полоса состава: сегменты в ряд, разделены зазором, у каждого своё
   скругление — это не одна шкала с делениями, а три величины рядом. */
.clientcard__balance-bar { display: flex; gap: var(--sp-tight); height: 14px; margin-top: var(--sp-block); }
.clientcard__balance-seg { border-radius: 4px; min-width: 3px; }

/* Подписи — три колонки под полосой, каждая с цветной чертой слева: она и
   связывает подпись с её сегментом. Кружки или квадратики легенды тут не
   нужны — черта делает это, не занимая строки. */
.clientcard__balance-legend { display: grid; gap: var(--sp-block); margin-top: var(--sp-block);
  grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 720px) {
  .clientcard__balance-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.clientcard__balance-item { padding-left: var(--sp-row); border-left: 2px solid var(--faint); }
.clientcard__balance-label { display: flex; align-items: baseline; gap: var(--sp-snug);
  font-size: var(--fs-hint); color: var(--muted2); }
.clientcard__balance-label span { font-size: var(--fs-eyebrow); color: var(--muted4);
  font-variant-numeric: tabular-nums; }
.clientcard__balance-value { margin-top: var(--sp-tight); font-size: var(--fs-lead);
  font-weight: 600; letter-spacing: -.02em; color: var(--text);
  font-variant-numeric: tabular-nums; }
.clientcard__balance-value.is-err { color: var(--err); }
.clientcard__balance-value.is-zero { color: var(--muted3); }
.clientcard__balance-hint { margin-top: var(--sp-tight); font-size: var(--fs-hint);
  color: var(--muted4); line-height: 1.4; }

/* Цвет корзины — КАТЕГОРИЯ, а не состояние: янтарный у бонусных не значит
   «требует решения», он лишь отличает корзину от соседней, ровно как
   фирменные цвета отличают маркетплейсы. Оттенки — категорийные токены
   `--bucket-*` из `admin.css`, одинаковые в обеих темах: текстовые
   `--warn`/`--info` в светлой теме темнеют ради контраста на белом, и полоса
   уходила бы в оливковый. Своих значений блок не заводит. */
.clientcard__balance-seg.is-bonus { background: var(--bucket-bonus); }
.clientcard__balance-seg.is-purchased { background: var(--bucket-purchased); }
.clientcard__balance-seg.is-earned { background: var(--bucket-earned); }
.clientcard__balance-item.is-bonus { border-left-color: var(--bucket-bonus); }
.clientcard__balance-item.is-purchased { border-left-color: var(--bucket-purchased); }
.clientcard__balance-item.is-earned { border-left-color: var(--bucket-earned); }

/* Плитки справа: утопленные, чтобы читаться как справка сбоку, а не как
   четвёртая, пятая и шестая корзины. */
.clientcard__balance-meta { display: flex; flex-direction: column; gap: var(--sp-item); }
.clientcard__meta-tile { padding: var(--sp-row) var(--sp-block); border-radius: 12px;
  background: var(--sunken); border: 1px solid var(--border2); }
.clientcard__meta-head { display: flex; align-items: baseline;
  justify-content: space-between; gap: var(--sp-item); font-size: var(--fs-body);
  color: var(--muted2); }
.clientcard__meta-value { font-size: var(--fs-lead); font-weight: 600;
  color: var(--text); font-variant-numeric: tabular-nums; }
.clientcard__meta-value.is-ok { color: var(--green); }
.clientcard__meta-value.is-warn { color: var(--warn); }
.clientcard__meta-value.is-err { color: var(--err); }
.clientcard__meta-value.is-zero { color: var(--muted3); }
.clientcard__meta-tile .clientcard__bar-track { margin-top: var(--sp-item); }
.clientcard__meta-tile .clientcard__balance-hint { margin-top: var(--sp-snug); }

/* Стилей блока «Взаиморасчёты» здесь больше нет: своей вёрстки у него на
   «Кошельке» не осталось — вкладка включает ТОТ ЖЕ фрагмент, что и «Обзор»
   (`admin/_client_settlement.html`), а его правила стоят выше, в разделе
   весов. Прежние `.clientcard__earn*` рисовали второй вариант того же блока —
   таблицу без полосы, — и две вкладки одной карточки показывали одни и те же
   суммы по-разному (сведены 2026-08-16, решение владельца). */

/* ── Обзор: строки блоков ──────────────────────────────────────────────── */

.clientcard__rows { display: flex; flex-direction: column; gap: var(--sp-item); }
.clientcard__row { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-row); font-size: var(--fs-row); }
.clientcard__row-label { color: var(--muted2); }
.clientcard__row-value { color: var(--text); text-align: right; overflow: hidden;
  text-overflow: ellipsis; }
.clientcard__row-hint { display: block; font-size: var(--fs-hint); color: var(--muted3); }
.clientcard__note { margin-top: var(--sp-item); padding: var(--sp-item) var(--sp-row); border-radius: 11px;
  font-size: var(--fs-body); background: var(--sunken); color: var(--muted); }
.clientcard__note--err { color: var(--err); background: rgba(241, 98, 111, .08); }
.clientcard__note--warn { color: var(--warn); background: rgba(241, 163, 59, .08); }

/* Стилей блоков «Магазины» и «Деньги: последнее» здесь больше нет: сами
   блоки сняты с «Обзора» 2026-08-16 — они целиком повторяли одноимённые
   вкладки. Плитка маркетплейса и строки списков живут теперь только там, где
   их рисуют встроенные списки разделов. */

/* ── Обзор: столбец действий ───────────────────────────────────────────── */

/* Тот же язык, что блок «Действия» карточки магазина (`shop-detail.css`):
   строка = подпись, состояние под ней, кнопка запуска справа; строки
   разделены линиями, без рамки вокруг каждой.

   Классы свои, а не общие с карточкой магазина: там строка знает про ДЕНЬГИ
   (тариф операции, хватает ли токенов владельцу), здесь денег нет вовсе —
   есть право оператора и применимость действия к записи. Общий CSS заставил
   бы один из двух экранов притворяться другим; то же решение принято для
   блока действий списка (`admin.css`). */
.clientcard__acts { display: flex; flex-direction: column; margin: 0; }
.clientcard__act { position: relative; display: flex; align-items: center; gap: var(--sp-row);
  padding: var(--sp-row) var(--sp-gutter); border-bottom: 1px solid var(--rowline);
  transition: background .14s ease; }
.clientcard__act:last-child { border-bottom: none; }
.clientcard__act:hover { background: var(--hover); }
/* Полоса слева — ПРЕПЯТСТВИЕ: запустить нельзя (нет права либо запись не
   подходит). У обычной строки её нет вовсе — иначе весь столбец расчерчен и
   цвет перестаёт что-либо значить. Опасность полосой не передаётся: она про
   последствие запуска, а не про невозможность. */
.clientcard__act::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2.5px; background: transparent; }
.clientcard__act.is-blocked::before { background: var(--faint); }

.clientcard__act-body { flex: 1; min-width: 0; }
/* Название ужимается многоточием, а не переносится: имя действия — ярлык, а
   не предложение, и в две строки оно превращает столбец в лестницу. Полное —
   в подсказке строки. */
.clientcard__act-label { font-size: var(--fs-row); font-weight: 500; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Состояние, в отличие от карточки магазина, переносится. Там во второй
   строке стоит короткое слово («Доступна», «Не хватает токенов») и её обрезка
   ничего не стоит; здесь у неприменимого действия там ПРИЧИНА отказа целым
   предложением — единственное, ради чего строка осталась на экране, и
   многоточие после трёх слов оставило бы её без смысла. Ровная высота строк
   приносится в жертву осознанно: сравнивать в этом столбце нечего, цифр в нём
   нет. */
.clientcard__act-state { margin-top: var(--sp-tight); font-size: var(--fs-hint); font-weight: 500;
  line-height: 1.45; color: var(--green); }
/* Запустить нельзя — строка тускнеет целиком: иначе она читается как рабочая,
   у которой просто потерялась кнопка. */
.clientcard__act.is-blocked .clientcard__act-label { color: var(--muted3);
  font-weight: 400; }
.clientcard__act.is-blocked .clientcard__act-state { color: var(--muted4); }

/* Кнопка своя, а не `.adm-btn`: геометрия совпадает с кнопкой запуска в
   карточке магазина — один жест на двух соседних экранах обязан выглядеть
   одинаково. Зелёная сплошная — обычное действие, красный контур — опасное.
   Ось цвета здесь свободна (платности у действий над клиентом нет), поэтому
   её занимает опасность; в карточке магазина она занята тарифом, и там
   опасность показывает только диалог подтверждения. */
.clientcard__act-run { flex: 0 0 auto; font: inherit; font-size: var(--fs-body); font-weight: 600;
  padding: var(--sp-snug) var(--sp-row); border-radius: 9px; cursor: pointer; white-space: nowrap;
  background: var(--brand); border: 1px solid var(--brand); color: var(--on-brand);
  transition: filter .16s ease, background .16s ease; }
.clientcard__act-run:hover { filter: brightness(1.08); }
.clientcard__act-run:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.clientcard__act-run.is-danger { background: rgba(241, 98, 111, .12);
  border-color: rgba(241, 98, 111, .32); color: var(--err); }
.clientcard__act-run.is-danger:hover { background: rgba(241, 98, 111, .18); }

/* Подпись-ремарка в шапке блока уходит к правому краю — как «списываются с
   владельца» в карточке магазина. */
.clientcard__head-hint { margin-left: auto; font-size: var(--fs-hint); color: var(--muted3); }

/* ── Обзор: опасная зона ───────────────────────────────────────────────── */

/* Опасная зона выглядит одинаково на обеих карточках: красная рамка, красная
   шапка, красный заголовок (`.shopcard__panel--danger`). До этого на карточке
   клиента красной была только рамка, и блок читался спокойнее, чем он есть. */
/* Опасная зона — общая с карточкой магазина (`.adm-danger*`/`.adm-cascade*`
   в `admin.css`). Своих правил у неё здесь больше нет: каскад фразой через
   запятую («магазины — 1 платежи — 0 …») заменён той же сеткой счётчиков,
   что у магазина, — решает тут количество, а во фразе числа тонут между
   подписями. */

/* ── Вкладка «Магазины»: место под финансовый блок ─────────────────────── */

/* Сам блок — общий с карточкой магазина (`.shopcard__fin*`, `shop-detail.css`),
   здесь только место, куда он приезжает вторым запросом, и заглушка на время
   ожидания. Своей вёрстки дашборда у карточки клиента больше нет: пока их было
   две, одни и те же цифры показывались двумя разными способами. */
.clientfin__slot { min-height: 80px; }
.clientfin__skeleton { padding: var(--sp-section) var(--sp-gutter); border-radius: var(--radius-card);
  background: var(--panel); border: 1px solid var(--border);
  font-size: var(--fs-row); color: var(--muted3); }
/* Сетка плиток вкладок «Кошелёк» и «Партнёрка» — к финансовому блоку
   отношения не имеет, имя осталось историческим. */
.clientfin__kpi { display: grid; gap: var(--sp-gutter);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.clientcard__bar-fill.is-income { background: var(--ok); }

/* ── Сегменты вкладок ──────────────────────────────────────────────────── */

/* Своих отступов полоса сегментов не носит: она стоит прямым ребёнком стека
   вкладки (`.clientcard`), и зазор до соседей задаёт его `gap`. Пока отступ
   был здесь, он складывался с зазором стека, и сегменты стояли от таблицы
   дальше, чем блоки друг от друга. */
.clientcard__row-value.is-warn { color: var(--warn); }
.clientcard__row-value.is-err { color: var(--err); }

/* Строки «подпись — значение» в широких блоках (шапки «Кошелька» и
   «Партнёрки») — сеткой в две колонки, а не распоркой во всю ширину: при
   ширине карточки в 1200 px метка и значение расходились по краям экрана и
   переставали читаться как пара. */
.adm-card__body > .clientcard__rows { max-width: 720px; }
.adm-card__body > .clientcard__rows .clientcard__row {
  display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: var(--sp-block); }
.adm-card__body > .clientcard__rows .clientcard__row-value { text-align: left; }

/* ── Партнёрка: уровень и код ──────────────────────────────────────────── */

/* Слева путь до следующей ставки, справа код. Двумя строками «подпись —
   значение» это выглядело как справка, хотя главный вопрос блока —
   «далеко ли клиенту до повышенной ставки», и он требует шкалы, а не числа.
   Колонка кода отделена линией тем же приёмом, что группы в полосе фактов
   «Обзора»: это один блок с двумя частями, а не два блока подряд. */
.clientcard__lvl { display: grid; gap: var(--sp-section); align-items: start;
  grid-template-columns: minmax(0, 1fr) 260px; }
@media (max-width: 900px) {
  .clientcard__lvl { grid-template-columns: minmax(0, 1fr); }
}
.clientcard__lvl-main { min-width: 0; }
.clientcard__lvl-head { display: flex; align-items: baseline; gap: var(--sp-row);
  flex-wrap: wrap; }
.clientcard__lvl-head .clientcard__block-title { margin: 0; }
/* Название уровня — величина того же порядка, что значение KPI: его читают
   первым во всей вкладке. Ставка рядом мельче: она следствие уровня, а не
   вторая независимая величина. */
.clientcard__lvl-title { display: flex; align-items: baseline; gap: var(--sp-item);
  flex-wrap: wrap; margin-top: var(--sp-snug); font-size: var(--fs-metric); font-weight: 600;
  letter-spacing: -.03em; line-height: 1; color: var(--text); }
.clientcard__lvl-title.is-muted { color: var(--muted3); }
.clientcard__lvl-rate { font-size: var(--fs-lead); font-weight: 600;
  letter-spacing: -.02em; color: var(--green); }

/* Шкала — путь ОТ порога текущего уровня ДО порога следующего, а не «сколько
   платящих всего»: у неё ровно один вопрос, и полная полоса значит «порог
   взят», а не «рефералов много». */
.clientcard__lvl-track { height: 8px; margin-top: var(--sp-block); border-radius: 5px;
  background: var(--track); overflow: hidden; }
.clientcard__lvl-fill { display: block; height: 100%; border-radius: 5px;
  background: var(--brand); }
.clientcard__lvl-scale { display: flex; align-items: baseline;
  justify-content: space-between; gap: var(--sp-row); margin-top: var(--sp-snug);
  font-size: var(--fs-hint); color: var(--muted4); }
/* Что именно осталось до повышения — по центру шкалы, между её концами: это
   вывод из полосы, а не третья подпись оси. */
.clientcard__lvl-note { flex: 1; min-width: 0; text-align: center;
  color: var(--muted2); }

.clientcard__lvl-code { padding-left: var(--sp-section); border-left: 1px solid var(--line);
  min-width: 0; }
@media (max-width: 900px) {
  .clientcard__lvl-code { padding: var(--sp-block) 0 0; border-left: 0;
    border-top: 1px solid var(--line); }
}
/* Подпись группы и кнопка правки — одной строкой, кнопка справа: тот же приём,
   что у групп полосы фактов «Обзора» (`.clientcard__facts-head`). Надзаголовок
   отдаёт свои отступы строке, иначе кнопка встаёт выше подписи. */
.clientcard__lvl-codehead { display: flex; align-items: center; gap: var(--sp-item);
  margin-bottom: var(--sp-item); }
.clientcard__lvl-codehead .clientcard__block-title { margin: 0; }
.clientcard__lvl-codehead .adm-btn { margin-left: auto; flex: 0 0 auto; }
/* Код — общий `.adm-copy` (моноширинный, с отметкой «скопировано»), но
   размером с то, что диктуют по телефону: он же и кнопка копирования.
   Собственного поведения не заводит — второй копирующий элемент разошёлся бы
   с первым. */
.clientcard__code { font-size: var(--fs-lead); font-weight: 600;
  letter-spacing: .04em; color: var(--text); background: var(--sunken);
  border: 1px solid var(--border2); border-radius: 10px;
  padding: var(--sp-snug) var(--sp-row); margin: 0; }
.clientcard__code:hover { background: var(--hover); }
.clientcard__lvl-hint { margin-top: var(--sp-item); font-size: var(--fs-hint);
  color: var(--muted3); line-height: 1.45; }

/* ── Партнёрка: воронка ────────────────────────────────────────────────── */

/* Ступени сверху вниз, ширина полосы — доля от приглашённых. Строкой
   «приглашено 40 → активировали 8 (20 %) → платят 1 (3 %)» те же числа
   приходилось сравнивать в уме. */
.clientcard__funnel { display: flex; flex-direction: column; gap: var(--sp-block); }
.clientcard__step { min-width: 0; }
.clientcard__step-head { display: flex; align-items: baseline; gap: var(--sp-item); }
.clientcard__step-label { font-size: var(--fs-eyebrow); letter-spacing: .1em;
  font-weight: 600; text-transform: uppercase; color: var(--muted4); }
.clientcard__step-value { font-size: var(--fs-lead); font-weight: 600;
  letter-spacing: -.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.clientcard__step-percent { font-size: var(--fs-hint); color: var(--muted3);
  font-variant-numeric: tabular-nums; }
.clientcard__step-track { height: 10px; margin-top: var(--sp-snug); border-radius: 6px;
  background: var(--track); overflow: hidden; }
.clientcard__step-fill { display: block; height: 100%; border-radius: 6px;
  background: var(--faint); }
/* Цвет ступени — градация «холодно → тепло → деньги»: серый переход по
   ссылке, синяя активация (тот же оттенок, что у заработанной корзины
   баланса), зелёная оплата — тот же зелёный, что у пришедших к нам денег на
   весах взаиморасчёта. Оси «требует решения» и «сломано» здесь свободны:
   решать оператору по воронке нечего. */
.clientcard__step.is-invited .clientcard__step-fill { background: var(--muted2); }
.clientcard__step.is-activated .clientcard__step-fill { background: var(--bucket-earned); }
.clientcard__step.is-paying .clientcard__step-fill { background: var(--brand); }
.clientcard__step-note { margin-top: var(--sp-snug); font-size: var(--fs-hint);
  color: var(--muted3); }

/* ── Партнёрка: деньги ─────────────────────────────────────────────────── */

/* Блок целиком собран классами «Баланса кошелька» (`clientcard__balance*`):
   вопрос «из чего сложилась сумма» там и здесь один, и двух разных ответов
   на него в одной карточке быть не должно. Своего тут — только рубли рядом с
   крупной суммой и цвета трёх стадий комиссии. */
.clientcard__balance-rub { margin-left: var(--sp-item); font-size: var(--fs-lead);
  font-weight: 600; letter-spacing: -.02em; color: var(--muted2); }

/* Стадия — КАТЕГОРИЯ, а не состояние: отменённая комиссия не красится
   красным («уже сломано»), поздний чарджбэк — штатное событие программы.
   Зачисленное зелёное (деньги дошли), созревающее синее (тот же оттенок, что
   у заработанной корзины), отменённое приглушённое — свершившийся факт,
   внимания не требующий. Оттенки категорийные (`--bucket-*`, одинаковы в
   обеих темах): текстовые `--warn`/`--info` в светлой теме темнеют ради
   контраста на белом, и полоса ушла бы в оливковый. */
.clientcard__balance-seg.is-paid { background: var(--brand); }
.clientcard__balance-seg.is-pending { background: var(--bucket-earned); }
.clientcard__balance-seg.is-canceled { background: var(--muted2); }
.clientcard__balance-item.is-paid { border-left-color: var(--brand); }
.clientcard__balance-item.is-pending { border-left-color: var(--bucket-earned); }
.clientcard__balance-item.is-canceled { border-left-color: var(--muted2); }

/* ── Партнёрка: признаки накрутки ──────────────────────────────────────── */

/* Плитки KPI, а не строки «подпись — значение»: спокойный сигнал приглушён,
   тревожный горит, и глаз находит нужный, не перечитывая все четыре. Тон
   значения — общие `is-warn`/`is-err` плитки: янтарь «требует решения»
   (адреса повторяются, поток мёртвый), красный «уже сломано» (самоприглашение,
   заморозка по фроду). */
.clientcard__sigs { margin-top: var(--sp-row); }

