/* Дизайн-система панелей ЛайфСтатс (кабинет партнёра и админка).
   Токены взяты из _ds дизайн-макета — менять только вместе с макетом. */
/* ===== Токены дизайн-системы (из _ds, не менять произвольно) ===== */
:root{
  --ls-bg:#F6F6F7; --ls-bg-soft:#EFEFF1; --ls-surface:#FFFFFF; --ls-surface-alt:#FAFAFB;
  --ls-dark:#0A0A0A; --ls-dark-soft:#1C1D21;
  --ls-ink:#000000; --ls-ink-1:#1D1D1F; --ls-ink-muted:#6E6E73; --ls-ink-faint:#87888E;
  --ls-accent:#1D5BE0; --ls-accent-hover:#1747B4; --ls-accent-soft:#EAF0FE; --ls-accent-on-dark:#8FB0F5;
  /* Статусные пары «текст + подложка»: тон выбирается по смыслу, не по цвету. */
  --ls-ok:#157F45;      --ls-ok-bg:#E8F5EE;
  --ls-wait:#7A5A12;    --ls-wait-bg:#F5F1E6;
  --ls-err:#A32A2A;     --ls-err-bg:#FBECEA;
  --ls-neutral:#6E6E73; --ls-neutral-bg:#F0F0F3;
  --ls-danger:var(--ls-err);
  /* Серии графиков: акцент — партнёрское, серые — прямое и фон. */
  --ls-data-1:#1D5BE0; --ls-data-2:#8E96A6; --ls-data-3:#B7BDC9;
  --ls-hairline:#F0F0F3; --ls-border:#E6E6EA; --ls-border-strong:#D5D5DB;
  --on-dark-70:rgba(255,255,255,.7); --on-dark-50:rgba(255,255,255,.5);
  --font-sans:-apple-system,BlinkMacSystemFont,"SF Pro Display","Inter Tight",Inter,system-ui,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,monospace;
  --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-8:32px;
  --r-sm:12px; --r-md:16px; --r-lg:20px; --r-xl:24px; --r-pill:999px;
  --r-card:20px; --r-field:14px;
  --sh-card:0 1px 1px rgba(0,0,0,.03),0 8px 24px rgba(0,0,0,.05);
  --sh-nav:0 1px 2px rgba(0,0,0,.04),0 4px 12px rgba(0,0,0,.06);
  --sh-dialog:0 40px 120px rgba(0,0,0,.3);
  --ease-out:cubic-bezier(.2,.7,.2,1);
}
*{box-sizing:border-box}
/* display:flex у элемента перебивает атрибут hidden — гасим их явно,
   иначе «скрытые» бейджи и модалки остаются на экране. */
[hidden]{display:none !important}
/* В макете 700-го начертания нет нигде: всё выделенное набрано 600, 800 остаётся
   только логотипу. Заголовки и <b> без своего font-weight получают от браузера
   bold=700, поэтому гасим его на уровне тегов — любое правило с классом всё равно
   перебьёт это по специфичности, так что явные веса компонентов не пострадают. */
h1,h2,h3,h4,b,strong{font-weight:600}
html,body{margin:0;padding:0;touch-action:manipulation;-webkit-text-size-adjust:100%}
body{
  background:var(--ls-bg); color:var(--ls-ink-1);
  font-family:var(--font-sans); font-size:15px; line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
button{font-family:inherit}
button:active{transform:scale(.975);transition:transform 120ms}
:focus-visible{outline:2px solid var(--ls-accent);outline-offset:2px}
a{color:var(--ls-accent)}
.nums{font-variant-numeric:tabular-nums}

/* ===== ВХОД ===== */
.auth{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.auth__card{width:100%;max-width:400px;background:var(--ls-surface);border-radius:var(--r-xl);padding:36px 32px;box-shadow:var(--sh-card)}
.auth__logo{display:flex;align-items:center;gap:10px;margin-bottom:28px}

/* ===== Тёмный вход (админка) =====
   В макете вход в админку — чёрный экран без карточки; в кабинете партнёра
   он остаётся светлым, поэтому тема включается отдельным классом. */
.auth--dark{background:var(--ls-dark)}
.auth--dark .auth__card{background:transparent;box-shadow:none;padding:0}
.auth--dark .auth__logo{color:#fff}
.auth--dark .auth__logo b{color:#fff;font-size:15px;font-weight:600}
.auth--dark .auth__logo i{color:var(--ls-accent-on-dark);font-size:17px;font-weight:800;letter-spacing:-.04em}
.auth__tag{display:none}
.auth--dark .auth__tag{display:inline-flex;align-items:center;height:20px;padding:0 8px;margin-left:2px;
  border-radius:var(--r-pill);background:rgba(255,255,255,.1);color:rgba(255,255,255,.55);
  font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase}
.auth--dark .auth__title{color:#fff;font-size:30px;margin-bottom:24px}
.auth--dark .field__label{color:rgba(255,255,255,.55)}
.auth--dark .field__label i{color:rgba(255,255,255,.4) !important}
.auth--dark .field__input{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.14);color:#fff}
.auth--dark .field__input::placeholder{color:rgba(255,255,255,.35)}
.auth--dark .field__input:focus{border-color:var(--ls-accent-on-dark);box-shadow:0 0 0 3px rgba(143,176,245,.18)}
.auth--dark .btn--light:hover{background:#eceef2}
.auth--dark .btn--ghost{border-color:rgba(255,255,255,.18);color:#fff}
.auth--dark .auth__err{color:#FF8A7A}
.auth--dark .sub{color:rgba(255,255,255,.55)}
.auth__logo b{font-size:19px;letter-spacing:-.02em}
.auth__logo i{font-style:italic;color:var(--ls-accent);font-weight:700}
.auth__title{margin:0 0 6px;font-size:26px;line-height:1.12;letter-spacing:-.025em;color:var(--ls-ink)}
.auth__sub{margin:0 0 26px;color:var(--ls-ink-muted);font-size:15px}
.field{display:block;margin-bottom:16px}
.field__label{display:block;font-size:13px;color:var(--ls-ink-muted);margin-bottom:7px}
.field__input{
  width:100%;height:44px;padding:0 14px;border:1px solid var(--ls-border-strong);border-radius:var(--r-sm);
  background:var(--ls-surface);color:var(--ls-ink-1);font-family:inherit;font-size:16px;
  transition:border-color .15s,box-shadow .15s;
}
.field__input:focus{outline:none;border-color:var(--ls-accent);box-shadow:0 0 0 3px var(--ls-accent-soft)}
/* Поле, которое не пропустили. Красную рамку держим и в фокусе: иначе стоит
   вернуть курсор в поле — и признак ошибки исчезает, хотя ошибка осталась. */
.field__input--err{border-color:var(--ls-err)}
.field__input--err:focus{border-color:var(--ls-err);box-shadow:0 0 0 3px rgba(163,42,42,.15)}
/* Ошибка окна ask прижата к полю. Резерв высоты в .auth__err нужен форме входа,
   где текст появляется на месте, а в диалоге он рисовал пустой зазор до кнопок. */
#ask-err{margin:6px 0 0;font-size:13px;min-height:0}
#ask-err:empty{display:none}
/* На тёмном входе поле остаётся крупным: там оно единственный объект экрана. */
.auth--dark .field__input{height:48px}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:52px;padding:0 22px;border:0;border-radius:var(--r-pill);
  font-size:15px;font-weight:600;cursor:pointer;transition:background .15s,opacity .15s;
}
.btn--primary{background:var(--ls-accent);color:#fff}
.btn--primary:hover{background:var(--ls-accent-hover)}
.btn--block{width:100%}
.btn--light{background:#fff;color:var(--ls-ink)}
.btn--ghost{background:transparent;border:1px solid var(--ls-border-strong);color:var(--ls-ink-1)}
/* Тёмная кнопка — главное действие раздела (в макете так выглядит «Пригласить»). */
.btn--dark{height:36px;padding:0 16px;font-size:13px;background:var(--ls-dark);color:#fff}
.btn--dark:hover{background:var(--ls-dark-soft)}
/* Необратимое действие — красная кнопка, как в подтверждениях макета. */
.btn--danger{background:var(--ls-err);color:#fff}
.btn--danger:hover{background:#8d2323}
.btn--danger-ghost{background:var(--ls-surface);border:1px solid var(--ls-err);color:var(--ls-err)}
.btn--danger-ghost:hover{background:var(--ls-err-bg)}
/* «Выйти» на экране «Ещё»: по макету это серая пилюля с красной подписью, а не
   обводная кнопка. Правило по id, а не через новый модификатор: такая кнопка в
   панели одна, а height обязателен — базовый .btn задаёт 52px вместо 44. */
#btn-exit-2{height:44px;border:0;background:var(--ls-bg-soft);color:var(--ls-err)}
#btn-exit-2:hover{background:#E5E5E8}
.btn[disabled]{opacity:.5;cursor:not-allowed}
.auth__err{margin:14px 0 0;color:var(--ls-danger);font-size:14px;min-height:20px}

/* ===== КАРКАС ===== */
.app{display:none;min-height:100vh}
.app.is-on{display:flex}
.side{
  position:sticky;top:0;align-self:flex-start;height:100vh;width:240px;flex:none;
  background:var(--ls-surface);border-right:1px solid var(--ls-hairline);
  display:flex;flex-direction:column;padding:24px 16px;
}
/* Тёмная навигация админки (в кабинете партнёра панель светлая).
   Мобильные правила для этого же класса лежат ниже, в медиазапросе. */
.side--dark{background:var(--ls-dark);border-right-color:transparent}
.side--dark .side__logo b{color:#fff}
.side--dark .side__mark{color:#fff}
.side--dark .side__logo i{color:var(--ls-accent-on-dark)}
.side--dark .side__logo:hover b{color:var(--ls-accent-on-dark)}
.side--dark .side__sub{display:block;
  font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:rgba(255,255,255,.4)}
.side--dark .side__group{color:var(--on-dark-50)}
.side--dark .nav__item{position:relative;color:var(--on-dark-70)}
.side--dark .nav__item svg{color:rgba(255,255,255,.45)}
.side--dark .nav__item:hover{background:rgba(255,255,255,.06);color:#fff}
.side--dark .nav__item.is-on{background:rgba(255,255,255,.1);color:#fff;font-weight:600}
.side--dark .nav__item.is-on svg{color:var(--ls-accent-on-dark)}
/* Полоска слева у активного пункта — она же метка «ты здесь». */
.side--dark .nav__item.is-on::before{content:"";position:absolute;left:-16px;top:6px;bottom:6px;
  width:3px;border-radius:0 3px 3px 0;background:var(--ls-accent)}
/* Колокольчик переехал в шапку — в панели он был бы вторым таким же. */
.side--dark .side__bell{display:none}
.side--dark .side__user{background:var(--ls-dark-soft);padding:12px;gap:12px}
.side--dark .side__user:hover{background:#232327}
.side--dark .side__handle{color:#fff}
.side--dark .side__role{color:var(--on-dark-50)}
.side--dark .ava{background:rgba(255,255,255,.12);color:#fff}
.side--dark .side__foot{gap:0}
/* Выход — иконка в углу карточки пользователя, а не отдельная красная строка. */
.side--dark .side__exit{position:absolute;right:10px;top:50%;transform:translateY(-50%);
  width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;
  color:var(--on-dark-50)}
.side--dark .side__exit .lbl{display:none}
.side--dark .side__exit:hover{background:rgba(255,255,255,.08);color:#fff}
.side--dark .side__foot{position:relative}

/* Заголовок раздела нужен только в мобильной шапке. */
.side__page{display:none;min-width:0;flex:1}
.side__sub{display:none}
.side__logo{display:flex;align-items:center;gap:10px;padding:0 10px;margin-bottom:28px;
  border:0;background:transparent;text-align:left;color:inherit;cursor:pointer;font-family:inherit}
.side__logo:hover b{color:var(--ls-accent)}
/* Знак и слово: «ЛайфСтатс Partners» одной строкой по базовой линии,
   под ней — роль. Размеры взяты из макета. */
.side__mark{flex:none;color:var(--ls-accent)}
.side__word{display:flex;flex-direction:column;min-width:0}
.side__row{display:flex;align-items:baseline;gap:5px;line-height:1.1}
.side__logo b{font-size:14px;font-weight:600;letter-spacing:0;line-height:1.1}
.side__logo i{font-size:16px;font-weight:800;font-style:italic;letter-spacing:-.04em;color:var(--ls-accent)}
.nav{display:flex;flex-direction:column;gap:2px}
.nav__item{
  display:flex;align-items:center;gap:12px;height:44px;padding:0 12px;border:0;
  border-radius:var(--r-sm);background:transparent;color:var(--ls-ink-1);
  font-size:15px;font-weight:500;text-align:left;cursor:pointer;transition:background .15s;
}
.nav__item:hover{background:var(--ls-bg-soft)}
.nav__item.is-on{background:var(--ls-accent-soft);color:var(--ls-accent);font-weight:600}
.nav__item svg{flex:none;opacity:.9}
/* Цифра в кружке: line-height:1 убирает лишний интерлиньяж, а padding сверху
   опускает цифру на место — у шрифта под базовой линией пустой выносной
   элемент, из-за которого число зрительно уезжает вверх. */
.nav__badge,.side__bell-n{min-width:20px;height:20px;padding:2px 6px 0;border-radius:var(--r-pill);
  background:var(--ls-accent);color:#fff;font-size:12px;font-weight:600;line-height:1;
  display:flex;align-items:center;justify-content:center;font-variant-numeric:tabular-nums}
.nav__badge{margin-left:auto}
.side__foot{margin-top:auto;display:flex;flex-direction:column;gap:4px}
.side__user{display:flex;align-items:center;gap:10px;padding:10px;border-radius:var(--r-sm);text-decoration:none;color:inherit}
.side__user:hover{background:var(--ls-bg-soft)}
.ava{width:36px;height:36px;flex:none;border-radius:var(--r-pill);background:var(--ls-accent-soft);
  color:var(--ls-accent);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600}
/* Фото партнёра поверх инициалов: пока картинка грузится или если не
   загрузилась, в кружке остаются буквы. */
.ava,.prof-ava{position:relative;overflow:hidden}
.ava > img,.prof-ava > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit}
.side__handle{display:block;font-weight:600;font-size:14px;line-height:1.2}
.side__role{display:block;font-size:12px;color:var(--ls-ink-faint)}
.side__exit{border:0;background:none;color:var(--ls-danger);font-size:14px;text-align:left;padding:8px 10px;cursor:pointer;border-radius:var(--r-sm)}
.side__exit:hover{background:rgba(200,40,40,.06)}

.main{flex:1;min-width:0;padding:32px 28px 100px}
.page__title{margin:0 0 22px;font-size:34px;line-height:1.06;letter-spacing:-.03em;color:var(--ls-ink)}

/* ===== Период ===== */
/* ===== Верхняя панель =====
   Растягиваем на всю ширину main отрицательными полями — так шапка липнет к
   верху и идёт от края до края, не переделывая раскладку страницы. */
.topbar{
  position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:20px;
  height:64px;margin:-32px -28px 24px;padding:0 28px;
  background:var(--ls-surface);box-shadow:var(--sh-nav);
}
.topbar__t{min-width:0;flex:1}
.topbar__eye{display:block;font-size:11px;font-weight:600;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ls-ink-faint);line-height:1.2}
/* font-weight задаём явно: это <h1>, без него браузер ставит 700, а в макете 600. */
.topbar__h{margin:1px 0 0;font-size:18px;font-weight:600;line-height:1.15;letter-spacing:-.02em;color:var(--ls-ink)}
/* Поиск: кнопка, а не поле — открывает диалог, поэтому и выглядит как цель для клика. */
.search{
  display:flex;align-items:center;gap:10px;width:min(380px,34vw);height:40px;padding:0 14px;
  border:0;border-radius:var(--r-pill);background:var(--ls-bg-soft);
  color:var(--ls-ink-faint);font-size:14px;font-family:inherit;cursor:pointer;transition:.15s;
}
.search:hover{background:#E7E7EA}
@media (min-width:1181px){ .search{cursor:text} }
/* На десктопе поле ввода живёт прямо в шапке, подпись-заглушка нужна только
   телефону, где поиск открывается шторкой. */
.search-wrap{position:relative}
.search__txt{display:none;flex:1;text-align:left;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.search__inp{flex:1;min-width:0;border:0;background:none;font:inherit;font-size:14px;color:var(--ls-ink-1)}
.search__inp::placeholder{color:var(--ls-ink-faint)}
.search__inp::-webkit-search-cancel-button{display:none}
.search__inp:focus,.search__inp:focus-visible{outline:none}
.search:focus-within{background:var(--ls-surface);box-shadow:0 0 0 2px var(--ls-accent-soft)}
/* Выпадающий список результатов под полем. */
.search__menu{
  position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:40;max-height:60vh;overflow:auto;
  padding:8px;border-radius:var(--r-md);background:var(--ls-surface);box-shadow:var(--sh-card),0 12px 32px rgba(0,0,0,.12);
}
.search__menu .sr__item{width:100%}
.search kbd{
  font:inherit;font-size:12px;padding:2px 6px;border-radius:6px;
  background:var(--ls-surface);color:var(--ls-ink-faint);box-shadow:var(--sh-card)
}
.topbar__bell{
  position:relative;flex:none;width:40px;height:40px;display:flex;align-items:center;justify-content:center;
  border:0;border-radius:var(--r-pill);background:transparent;color:var(--ls-ink-1);cursor:pointer;transition:.15s;
}
.topbar__bell:hover{background:var(--ls-neutral-bg)}
/* Точка непрочитанного — не число: в шапке важен факт, счёт виден в шторке. */
.topbar__dot{position:absolute;top:9px;right:10px;width:8px;height:8px;border-radius:50%;
  background:var(--ls-accent);border:2px solid var(--ls-surface)}
.topbar__ava{width:36px;height:36px;flex:none}
/* Между планшетом и десктопом поиск съедал место у заголовка — оставляем
   только иконку, подпись возвращается на широком экране. */
@media (max-width:1180px){
  .search{width:auto;min-width:44px;padding:0 12px}
  .search__txt,.search kbd,.search__inp{display:none}
  .search__menu{width:320px;left:auto}
}

.periods{display:inline-flex;gap:2px;background:var(--ls-surface);border-radius:var(--r-pill);padding:3px;margin-bottom:22px;box-shadow:var(--sh-card)}
.periods button{
  flex:1;height:30px;padding:0 10px;border:0;border-radius:var(--r-pill);background:transparent;
  color:var(--ls-ink-muted);font-size:12px;font-weight:500;white-space:nowrap;cursor:pointer;transition:.15s;
}
.periods button:hover{color:var(--ls-ink-1)}
.periods button.is-on{background:var(--ls-dark);color:#fff;font-weight:600}

/* ===== Карточки ===== */
.grid{display:grid;gap:16px;margin-bottom:16px}
.grid--top{grid-template-columns:minmax(0,1.6fr) minmax(0,1fr) minmax(0,1fr)}
.card{background:var(--ls-surface);border-radius:var(--r-lg);padding:22px;box-shadow:var(--sh-card)}
/* Карточка-список: таблица идёт от края до края, поэтому полей у карточки нет.
   Всё, что не таблица (подписи, пагинация), получает поля само. */
.card--table{padding:0;overflow:hidden}
.card--table > div > .tbl{margin:0}
.card--table > div > p,
.card--table > div > .pager,
.card--table > div > .empty{margin-left:22px;margin-right:22px}
.card--table > div > p:first-child{padding-top:18px}
.card--table > div > .pager{padding-bottom:18px}
/* На телефоне список карточками — ему поля нужны. */
@media (max-width:860px){ .card--table > div > .mlist{padding:6px 16px 14px} }
.card--dark{background:var(--ls-dark);color:#fff;display:flex;flex-direction:column;justify-content:space-between;position:relative;overflow:hidden}
/* Синее свечение в правом верхнем углу: круг 200x200, уходящий за край.
   closest-side даёт ровный спад до нуля ровно на радиусе 100px; промежуточный
   стоп здесь не нужен — именно он создавал плотное ядро с резким плечом,
   из-за которого подсветка читалась отдельным пятном. */
.card--dark::after{content:"";position:absolute;right:-50px;top:-60px;width:200px;height:200px;
  border-radius:999px;
  background:radial-gradient(closest-side,rgba(29,91,224,.35),transparent);
  pointer-events:none}
.card--dark > *{position:relative;z-index:1}
/* Спарклайн — в правом нижнем углу; текст рядом ограничен, чтобы не пересекались. */
/* Переключатель «Выручка / Прибыль» в тёмной карточке обзора. */
.kpi__head{display:flex;align-items:center;justify-content:space-between;gap:12px;position:relative;z-index:2}
.kpi__head .eyebrow{min-width:0;margin-bottom:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kswitch{display:flex;align-items:center;gap:8px;flex:none}
.kswitch__l{font-size:12px;font-weight:600;color:var(--on-dark-50);transition:color .15s}
.kswitch__l.is-on{color:#fff}
.kswitch__l:first-child{display:none}
.kswitch__t{position:relative;width:38px;height:22px;flex:none;padding:2px;border:0;border-radius:var(--r-pill);
  background:rgba(255,255,255,.18);cursor:pointer;display:flex;align-items:center;transition:background .18s}
.kswitch__t i{display:block;width:18px;height:18px;border-radius:var(--r-pill);background:#fff;
  transition:transform .18s var(--ease-out)}
.kswitch__t.is-on{background:var(--ls-accent)}
.kswitch__t.is-on i{transform:translateX(16px)}
/* На средних ширинах карточка узкая: подпись у тумблера уступает место
   эйбрау, режим и так назван слева. */
@media (min-width:861px) and (max-width:1360px){ .kswitch__l{display:none} }
@media (max-width:860px){
  .kswitch__l{font-size:11px}
  .kswitch__t::after{content:'';position:absolute;inset:-9px -8px}
}

.spark{position:absolute;right:22px;bottom:24px;width:40%;max-width:150px;height:34px;z-index:1;
  pointer-events:none;display:block;transition:opacity .4s var(--ease-out)}
/* Линия проявляется слева направо: карточка оживает, а не появляется готовой. */
.spark svg{display:block;width:100%;height:100%;overflow:visible;
  animation:spark-reveal .6s var(--ease-out)}
.spark__line{fill:none;stroke:var(--ls-accent-on-dark);stroke-width:2;stroke-linecap:round;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.spark__area{fill:url(#spark-grad)}
/* Прошлый день — тонкой линией под текущим: с ним сравнивает дельта. */
.spark__ref{fill:none;stroke:rgba(255,255,255,.26);stroke-width:1.5;stroke-linecap:round;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.spark__g0{stop-color:var(--ls-accent-on-dark);stop-opacity:.42}
.spark__g1{stop-color:var(--ls-accent-on-dark);stop-opacity:0}
/* Точка — отдельным элементом поверх: растянутый svg сделал бы из круга овал. */
.spark__dot{position:absolute;width:7px;height:7px;border-radius:50%;background:var(--ls-accent-on-dark);
  box-shadow:0 0 0 2px rgba(0,0,0,.45);transform:translate(-50%,-50%);
  animation:spark-in .3s var(--ease-out) .45s backwards}
@keyframes spark-reveal{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes spark-in{from{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .spark,.spark svg,.spark__dot{transition:none;animation:none}
}
.card--dark .sub{max-width:56%}
/* На тёмном рост отмечаем акцентом: зелёный там читается как «системный». */
.card--dark .up,.card--dark .down{color:var(--ls-accent-on-dark)}
.eyebrow{font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--ls-ink-faint);margin:0 0 10px}
.card--dark .eyebrow{color:var(--on-dark-50)}
/* Шапка карточки настроек: заголовок предложением, а не эйбрау — мелкий
   разрядженный uppercase в макете отдан подписям KPI и шапкам таблиц. */
.card__title{margin:0;font-size:16px;font-weight:600;color:var(--ls-ink-1)}
.card__desc{margin:2px 0 18px;font-size:13px;color:var(--ls-ink-muted)}
.big{font-size:40px;font-weight:600;letter-spacing:-.03em;line-height:1.05;margin:0}
.card--dark .big{margin-bottom:18px}
.sub{margin:8px 0 0;font-size:14px;color:var(--ls-ink-muted)}
.card--dark .sub{color:var(--on-dark-50);text-align:center;margin-top:12px}
/* В KPI-карточке обзора подпись — это дельта к прошлому периоду: в макете вся
   фраза акцентная и прижата влево, а не «цветное число плюс серый хвост». */
.card--dark.kpi .sub{color:var(--ls-accent-on-dark);text-align:left}
.stat3 .card--dark.kpi .sub{color:var(--on-dark-50)}
.hint{display:flex;align-items:center;gap:7px;margin:0 0 18px;font-size:13px;color:var(--ls-ink-faint)}
.up{color:var(--ls-ok)}
.delta{display:inline-flex;align-items:baseline;gap:3px}
.delta > i{font-style:normal}
.delta.up > i::before{content:'↑'}
.delta.down > i::before{content:'↓'}
.delta.same > i::before{content:''}
.down{color:var(--ls-danger)}

/* Процент */
.pct__row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap}
.pct__val{font-size:34px;font-weight:600;letter-spacing:-.03em}
.pct__of{font-size:15px;color:var(--ls-ink-muted);font-weight:400;margin-left:8px}
.pct__count{font-size:15px;font-weight:600}
.pct__bar{height:8px;border-radius:var(--r-pill);background:var(--ls-bg-soft);margin:16px 0 8px;overflow:hidden}
.pct__fill{height:100%;border-radius:var(--r-pill);background:var(--ls-accent);transition:width .5s var(--ease-out)}
.pct__scale{display:flex;justify-content:space-between;font-size:13px;color:var(--ls-ink-faint)}
.pct__scale b{color:var(--ls-accent);font-weight:600}
.pct__next{margin:10px 0 0;font-size:14px;color:var(--ls-ink-muted)}

/* График */
.chart__head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:18px}
.chart__title{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em}
.chart__sub{margin:4px 0 0;font-size:14px;color:var(--ls-ink-muted)}
.legend{display:flex;gap:16px;font-size:13px;color:var(--ls-ink-muted);white-space:nowrap}
.legend i{display:inline-block;width:14px;height:3px;border-radius:2px;margin-right:6px;vertical-align:middle}
.chart__box{height:260px}
.metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-top:20px;padding-top:20px;border-top:1px solid var(--ls-hairline)}
.metric b{display:block;font-size:26px;font-weight:600;letter-spacing:-.02em}
.metric span{font-size:13px;color:var(--ls-ink-muted)}
.metric em{font-style:normal;font-size:13px;margin-left:6px}

/* Пустое состояние */
.empty{padding:40px 20px;text-align:center;color:var(--ls-ink-muted)}
.empty b{display:block;color:var(--ls-ink-1);font-size:17px;margin-bottom:6px}


/* ===== Списки и чипы ===== */
.chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
.chip{height:34px;padding:0 14px;border:1px solid var(--ls-border);border-radius:var(--r-pill);
  background:var(--ls-surface);color:var(--ls-ink-1);font-size:13px;font-weight:600;cursor:pointer;transition:.15s}
.chip:hover{border-color:var(--ls-border-strong)}
.chip.is-on{background:var(--ls-dark);border-color:var(--ls-dark);color:#fff;font-weight:600}

/* ===== Шапка списка: фильтры слева, «показано N из M» справа ===== */
.list-head{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.list-head .chips,.list-head .periods,.list-head .periods-row{margin-bottom:0}
.list-head .periods-row{flex:none;width:auto}
#w-kpi .periods-row{margin-bottom:0}
.list-head .periods-row .periods{flex:none;max-width:none}
/* Действие раздела прижато вправо, вплотную к счётчику: в макете это кнопка в
   конце строки фильтров, а не ещё один фильтр слева. Свободное место отдаём
   кнопке и снимаем auto со счётчика — два margin-left:auto поделили бы место
   пополам и кнопка встала бы посередине. Пока кнопка скрыта от оператора
   ([hidden]), правило не срабатывает и правый край держит сам счётчик. */
.list-head > .btn{margin-left:auto;height:36px;padding:0 16px;font-size:13px}
.list-head > .btn:not([hidden]) + .list-head__count{margin-left:0}
.list-head__count{margin-left:auto;font-size:13px;color:var(--ls-ink-muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.list-head__count b,.eyebrow b,.sub b,.top-eye b,#top-eye b,#page-eye b,#ad-count b,#t-pay-sub b{
  font-weight:inherit;font-size:inherit;letter-spacing:inherit}
/* На «Администраторах» слева фильтров нет: кнопка и счётчик стоят парой
   справа, как в макете, а не разъезжаются по краям экрана. */
.list-head--end{justify-content:flex-end;gap:8px}
.list-head--end .list-head__count{margin-left:0}

/* ===== Ячейка «человек»: аватар, имя, подпись ===== */
.cell-user{display:flex;align-items:center;gap:10px;min-width:0}
.cell-user .ava{width:30px;height:30px;font-size:11px}
/* Ник — 14px/500: разметка использует тег <b>, унаследованные 700 делают его
   заметно тяжелее макета. Подпись 12px и с прижатой строкой — иначе она берёт
   body{line-height:1.55}, ячейка вырастает и строка не влезает в макетные 52px.
   Кегль задаём scoped-правилом: базовый .row__s остаётся 13px, его же использует
   подпись «ступени · N продаж» и курс/хэш в выплатах. */
.cell-user b{display:block;font-size:14px;font-weight:500;line-height:1.25}
.cell-user .row__s{margin-top:1px;font-size:12px;line-height:1.25}

/* ===== Возврат к списку ===== */
.crumb{display:inline-flex;align-items:center;gap:6px;margin:0 0 16px;padding:6px 12px 6px 8px;
  border:0;border-radius:var(--r-pill);background:transparent;color:var(--ls-ink-muted);
  font:inherit;font-size:14px;cursor:pointer}
.crumb:hover{background:var(--ls-neutral-bg);color:var(--ls-ink-1)}

/* ===== Шапка карточки партнёра ===== */
.pcard{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:16px}
.pcard__ava{width:56px;height:56px;flex:none;font-size:18px}
.pcard__main{flex:1;min-width:220px}
.pcard__title{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* font-weight обязателен: ресета для h1-h6 в файле нет, и без него h2 берёт
   браузерный bold 700 — ник выходит заметно жирнее макетного semibold. */
.pcard__title h2{margin:0;font-size:24px;font-weight:600;letter-spacing:-.03em;line-height:1.1}
/* Мета-строка в макете разделена гэпом, а не точками, поэтому промежуток
   крупнее кегля: 13px текста и 14px между группами. */
.pcard__meta{margin:8px 0 0;display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  font-size:13px;color:var(--ls-ink-muted)}
.pcard__meta code{font-family:var(--font-mono);font-size:13px;background:var(--ls-neutral-bg);
  padding:2px 8px;border-radius:8px;color:var(--ls-ink-1)}
.pcard__acts{display:flex;gap:8px;flex-wrap:wrap}
/* В шапке карточки это главные действия по партнёру, а не мелкие операции в
   строке таблицы, поэтому кнопки крупнее и полужирные — как в макете.
   Точечно на .pcard__acts: общий .mini-btn поедет в таблицах и в «Действиях». */
.pcard__acts .mini-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;
  font-size:14px;font-weight:600}
/* Обводка отдельным правилом: в общем селекторе она перебила бы по
   специфичности красную рамку «Заблокировать». */
.pcard__acts .mini-btn:not(.mini-btn--danger){border-color:var(--ls-border-strong)}
/* Чип «процент» — тот же тон, что у акцентных статусов. */
.chip-val{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 12px;
  border-radius:var(--r-pill);background:var(--ls-accent-soft);color:var(--ls-accent);
  font-size:13px;font-weight:600}
/* Тот же чип, но кликабельный: правка процента прямо из шапки карточки. */
.chip-val--edit{border:0;font-family:inherit;cursor:pointer}
.chip-val--edit:hover{background:#dbe6fd}
.chip-val--edit svg{opacity:.65}
/* Пустое место под промокод: пунктирная рамка вместо заливки — так видно, что
   значения ещё нет, а не что оно пустое. */
.chip-val--add{background:transparent;border:1px dashed var(--ls-accent);
  font-family:inherit;cursor:pointer}
.chip-val--add:hover{background:var(--ls-accent-soft)}

/* Выбор промокода партнёру: строка-переключатель с точкой-радио слева. */
.promo-opt{display:flex;align-items:center;gap:12px;width:100%;padding:14px 16px;margin-bottom:8px;
  border:1.5px solid var(--ls-border);border-radius:var(--r-md);background:var(--ls-surface);
  font-family:inherit;text-align:left;color:inherit;cursor:pointer;transition:.15s}
.promo-opt:hover{border-color:var(--ls-border-strong)}
.promo-opt.is-on{border-color:var(--ls-accent);background:var(--ls-accent-soft)}
.promo-opt__dot{width:20px;height:20px;flex:none;border-radius:50%;border:2px solid var(--ls-border-strong);
  position:relative}
.promo-opt.is-on .promo-opt__dot{border-color:var(--ls-accent)}
.promo-opt.is-on .promo-opt__dot::after{content:'';position:absolute;inset:3px;border-radius:50%;
  background:var(--ls-accent)}
.promo-opt__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.promo-opt__main b{font-size:15px}
/* Занятый код показываем, но берём его нельзя: так видно, что код существует и
   почему он недоступен, — иначе владелец искал бы пропажу в списке. */
.promo-opt.is-busy{opacity:.55;cursor:not-allowed;background:var(--ls-bg-soft)}
.promo-opt.is-busy:hover{border-color:var(--ls-border)}
/* На телефоне чип-кнопка выше: 28px мало для пальца. */
@media (max-width:860px){ .chip-val--edit{height:34px} }
.pc-acts{display:flex;gap:8px;flex-wrap:wrap}
.note-text{margin:0;padding:14px 16px;border-radius:var(--r-md);background:var(--ls-surface-alt);
  border:1px solid var(--ls-border-soft,var(--ls-hairline));font-size:15px;line-height:1.5}
/* Заметка как запись в истории: текст и подпись «когда · кто». */
.notes{display:flex;flex-direction:column;gap:8px}
/* Радиус 14px — из макета: он между токенами --r-sm 12 и --r-md 16, поэтому
   задан числом. Пузырь заметки мельче карточки: это запись, а не блок. */
.note-item{padding:12px 14px;border-radius:14px;background:var(--ls-surface-alt)}
.note-item__t{margin:0;font-size:14px;line-height:1.45;overflow-wrap:anywhere}
.note-item__m{margin:6px 0 0;font-size:12px;color:var(--ls-ink-faint)}

/* ===== Несохранённые правки =====
   Карточка настроек, в которой что-то поменяли, обводится акцентом, а кнопка
   сохранения становится основной — чтобы уйти со страницы и потерять правки
   было трудно. */
.card.is-dirty{box-shadow:var(--sh-card),0 0 0 1.5px var(--ls-accent)}
.card.is-dirty .btn--ghost{background:var(--ls-accent);border-color:var(--ls-accent);color:#fff}
.dirty-note{display:none;align-items:center;gap:6px;margin:10px 0 0;font-size:13px;color:var(--ls-accent)}
.card.is-dirty .dirty-note{display:flex}
.dirty-note::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}

/* ===== Пагинация ===== */
.pager{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding-top:18px;margin-top:4px;
  border-top:1px solid var(--ls-hairline)}
.pager__lbl{font-size:14px;color:var(--ls-ink-muted)}
.pager__sizes{display:inline-flex;gap:2px;background:var(--ls-neutral-bg);border-radius:var(--r-pill);padding:4px}
.pager__sizes button{height:30px;min-width:42px;padding:0 10px;border:0;border-radius:var(--r-pill);
  background:transparent;color:var(--ls-ink-muted);font:inherit;font-size:13px;cursor:pointer}
.pager__sizes button.is-on{background:var(--ls-surface);color:var(--ls-ink-1);font-weight:600;box-shadow:var(--sh-card)}
.pager__pages{display:flex;align-items:center;gap:6px;margin-left:auto}
.pager__pages button{width:34px;height:34px;border:0;border-radius:var(--r-pill);background:transparent;
  color:var(--ls-ink-1);font:inherit;font-size:14px;cursor:pointer}
.pager__pages button:hover{background:var(--ls-neutral-bg)}
.pager__pages button.is-on{background:var(--ls-dark);color:#fff;font-weight:600}
.pager__gap{color:var(--ls-ink-faint);padding:0 2px}
.stat3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin-bottom:16px}
.stat3 .card{padding:18px 20px}
.stat3 b{display:block;font-size:28px;font-weight:600;letter-spacing:-.025em;margin-top:4px}
/* Тёмная карточка в тройке — подпись слева и акцентом, как у выручки на обзоре. */
.stat3 .card--dark .sub{text-align:left;max-width:none;color:var(--ls-accent-on-dark)}

.rows{display:flex;flex-direction:column}
.row{display:flex;align-items:center;gap:14px;padding:16px 0;border-top:1px solid var(--ls-hairline)}
.row:first-child{border-top:0}
.row__ico{width:40px;height:40px;flex:none;border-radius:var(--r-sm);background:var(--ls-bg-soft)}
/* Ссылка-кнопка в шапке карточки: «Все», «Открыть» — переход, а не действие. */
.link-btn{border:0;background:none;padding:0;font:inherit;font-size:14px;font-weight:500;
  color:var(--ls-accent);cursor:pointer}
.link-btn:hover{color:var(--ls-accent-hover)}
/* На телефоне ссылка-кнопка должна оставаться удобной целью для пальца —
   растим область нажатия отрицательными полями, вид при этом не меняется. */
@media (max-width:860px){
  .link-btn{padding:10px 8px;margin:-10px -8px}
  .chips--sm .chip{height:36px;padding:0 14px}
  .pager__sizes button{height:36px;min-width:48px}
  .pager__pages button{width:40px;height:40px}
  /* Макетные 30px — про десктоп и мышь; пальцу нужна цель побольше. */
  .tbl .mini-btn{height:36px}
}
.row__main{flex:1;min-width:0}
.row__t{font-weight:600;font-size:15px}
.row__s{display:block;font-size:13px;color:var(--ls-ink-muted);margin-top:2px}
.row__r{text-align:right;white-space:nowrap}
.row__sum{font-weight:600;font-size:16px}
.badge{display:inline-flex;align-items:center;gap:6px;margin-top:6px;padding:4px 10px;border-radius:var(--r-pill);font-size:12px;font-weight:600}
.badge i{width:6px;height:6px;border-radius:50%;background:currentColor}
/* Пять тонов из макета. Тон выбирается по смыслу статуса, а не по цвету:
   ok — состоялось, wait — ждёт человека, err — сорвалось, accent — в работе,
   neutral — закрыто и больше ничего не требует. */
.badge--ok{background:var(--ls-ok-bg);color:var(--ls-ok)}
.badge--wait{background:var(--ls-wait-bg);color:var(--ls-wait)}
.badge--err{background:var(--ls-err-bg);color:var(--ls-err)}
.badge--accent{background:var(--ls-accent-soft);color:var(--ls-accent)}
.badge--neutral{background:var(--ls-neutral-bg);color:var(--ls-neutral)}
/* Прежние имена — синонимы тонов, чтобы не переписывать всю разметку разом. */
.badge--check{background:var(--ls-wait-bg);color:var(--ls-wait)}
.badge--stop{background:var(--ls-err-bg);color:var(--ls-err)}
.badge--paid{background:var(--ls-neutral-bg);color:var(--ls-neutral)}
/* Фиксированная ширина — колонка статуса не «гуляет» между разными по длине
   словами (заявка/принята/отклонена и т.п.). Только там, где явно нужна ровная
   сетка — не навязываем всем бейджам в проекте (у части бейджей ширина по
   контенту осознанно, например тег «наш трафик»). */
.badge--fixed{width:124px;justify-content:center}
@media (max-width:860px){ .badge--fixed{width:108px} }

/* Промо */
.grid--2{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
/* График и панель рядом с ним — пропорция из макета. */
.grid--chart{display:grid;gap:16px;margin-bottom:16px;grid-template-columns:minmax(0,8fr) minmax(0,4fr)}
.link-box{display:flex;gap:8px;align-items:center;background:var(--ls-bg-soft);border-radius:var(--r-sm);padding:6px 6px 6px 14px;margin:12px 0 16px}
.link-box input{flex:1;min-width:0;border:0;background:transparent;font-family:inherit;font-size:15px;color:var(--ls-ink-1)}
.link-box input:focus{outline:none}
.link-box button{height:40px;padding:0 16px;border:0;border-radius:var(--r-sm);background:var(--ls-surface);
  color:var(--ls-accent);font-size:14px;font-weight:600;cursor:pointer}
.mini3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;padding-top:16px;border-top:1px solid var(--ls-hairline)}
.mini3 b{display:block;font-size:22px;font-weight:600;letter-spacing:-.02em}
.mini3 span{font-size:13px;color:var(--ls-ink-muted)}
.card--dark .mini3{border-top-color:rgba(255,255,255,.14)}
.card--dark .mini3 span{color:var(--on-dark-50)}

/* ===== Выплаты: карты, лимиты, разбивка ===== */
.block-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.linkish{border:0;background:none;padding:0;font-family:inherit;font-size:14px;font-weight:600;
  color:var(--ls-accent);cursor:pointer}
.linkish--danger{color:var(--ls-danger)}
/* Строка «присылать на телефон» в шторке уведомлений: отделена подложкой,
   чтобы не читалась как первое уведомление в списке. */
.push-row{display:flex;align-items:center;gap:12px;margin:0 0 12px;padding:12px 14px;
  border-radius:var(--r-sm);background:var(--ls-bg-soft)}
.push-row__main{flex:1;min-width:0}
.push-row__main b{font-size:14px;font-weight:600}
.push-row .btn{flex:none}
.linkish[disabled]{color:var(--ls-ink-faint);cursor:default}
.linkish[disabled]:active{transform:none}

/* Поле суммы со знаком рубля справа */
.amount{position:relative;display:block}
.amount input{padding-right:38px;font-size:20px;font-weight:600;font-variant-numeric:tabular-nums}
.amount i{position:absolute;right:16px;top:50%;transform:translateY(-50%);font-style:normal;color:var(--ls-ink-faint)}
.amount__row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-top:8px}

/* ===== Магазин: цены, промокоды, почты, письмо =====
   Общий слой для четырёх разделов из макета. Всё модификаторами: базовые
   .btn/.field/.tbl обслуживают ещё и кабинет партнёра, их трогать нельзя. */
.shop{display:flex;flex-direction:column;gap:16px;max-width:760px}
.shop--wide{max-width:none}
.shop-sub{margin:6px 0 0;font-size:14px;line-height:1.45;color:var(--ls-ink-muted)}
.shop-acts{display:flex;gap:10px;flex-wrap:wrap;margin-top:20px}
/* Строка журнала: кто и когда правил — остаётся на экране, в отличие от тоста. */
.shop-log{margin:12px 0 0;font-size:12px;color:var(--ls-ink-faint)}
.shop-card h3{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em}
/* Кнопка раздела: 44 против базовых 52 — так в макете магазина. */
.btn--44{height:44px;padding:0 20px;font-size:15px}
.btn--44.btn--ghost{padding:0 16px}
/* Выключенная главная кнопка в макете не полупрозрачная, а серая. */
.btn--primary[disabled],.btn--dark[disabled]{background:var(--ls-bg-soft);color:var(--ls-ink-faint);opacity:1}
/* Числовое поле с суффиксом внутри строки списка (цена, лимит, процент). */
.amount--field{position:relative;display:inline-block;flex:none}
.amount--field input{width:132px;height:42px;padding:0 30px 0 14px;text-align:right;
  border:1px solid var(--ls-border-strong);border-radius:var(--r-sm);background:var(--ls-surface);
  font-family:inherit;font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ls-ink-1)}
.amount--field input:focus{outline:0;border-color:var(--ls-accent);box-shadow:0 0 0 3px var(--ls-accent-soft)}
.amount--field input[readonly]{background:var(--ls-bg-soft);color:var(--ls-ink-muted);cursor:default}
.amount--field i{position:absolute;right:12px;top:50%;transform:translateY(-50%);line-height:20px;
  font-style:normal;font-size:15px;color:var(--ls-ink-faint);pointer-events:none}
.amount--wide input{width:100%}
.amount--unit input{padding-right:48px}
/* Список товаров с ценами: не таблица — пары «название · поле». */
.pricelist{margin-top:16px;border-top:1px solid var(--ls-hairline)}
.priceline{display:flex;align-items:center;justify-content:space-between;gap:12px;
  min-height:60px;padding:8px 0;border-bottom:1px solid var(--ls-hairline)}
.priceline__name{display:flex;flex-direction:column;gap:2px;min-width:0;font-size:15px;font-weight:500}
.priceline__was{font-size:12px;font-weight:400;color:var(--ls-accent)}
/* Пара «подпись + поле» в карточках правил: в макете ряд 1fr 180px. */
.setrow{display:grid;grid-template-columns:minmax(0,1fr) 180px;gap:20px;align-items:center;
  padding:12px 0;border-bottom:1px solid var(--ls-hairline)}
.setrow__k{font-size:14px;font-weight:500}
.setrow__hint{display:block;margin-top:2px;font-size:12px;line-height:1.4;color:var(--ls-ink-muted);font-weight:400}
@media (max-width:860px){
  .shop{gap:12px}
  .setrow{grid-template-columns:minmax(0,1fr);gap:8px}
  .setrow .amount--field input{width:100%}
}

/* Форма магазина: ряд полей с подписями, на телефоне — столбик. */
.form-grid{display:grid;grid-template-columns:1.1fr 1.4fr 1fr 1fr auto;gap:12px;align-items:end;margin-top:14px}
.fgroup{display:block;min-width:0}
.fgroup__k{display:block;margin-bottom:6px;font-size:13px;color:var(--ls-ink-muted)}
.fld{width:100%;height:44px;padding:0 14px;border:1px solid var(--ls-border-strong);
  border-radius:var(--r-sm);background:var(--ls-surface);font-family:inherit;font-size:15px;
  color:var(--ls-ink-1)}
.fld:focus{outline:0;border-color:var(--ls-accent);box-shadow:0 0 0 3px var(--ls-accent-soft)}
.fld--mono{font-family:var(--font-mono);font-weight:600;text-transform:uppercase}
/* Селект под тем же полем: свой шеврон вместо системного. */
.fld--sel{appearance:none;-webkit-appearance:none;padding-right:36px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none' stroke='%236E6E73' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M6 8.5l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center}
/* Сегмент-контрол «Процент / Рубли»: белая таблетка в серой дорожке. */
.segf{display:flex;gap:2px;height:44px;padding:3px;border-radius:var(--r-sm);background:var(--ls-bg-soft)}
.segf button{flex:1;min-width:0;border:0;border-radius:10px;background:transparent;
  color:var(--ls-ink-muted);font-family:inherit;font-size:14px;font-weight:600;cursor:pointer;transition:.15s}
.segf button.is-on{background:var(--ls-surface);color:var(--ls-ink-1);box-shadow:var(--sh-card)}
/* Поле формы с суффиксом — 44px, значение слева. */
.amount--tall{display:block}
.amount--tall input{width:100%;height:44px;padding:0 32px 0 14px;text-align:left;font-weight:400}
.amount--tall i{top:50%;transform:translateY(-50%)}
@media (max-width:1180px){
  .form-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .form-grid > .btn{grid-column:1 / -1}
}
@media (max-width:860px){ .form-grid{grid-template-columns:minmax(0,1fr)} }

/* Промокоды: таблица на большом экране, карточки на телефоне. */
.tbl.tbl--promos tbody tr{height:56px}
.tbl--promos th:nth-child(1),.tbl--promos td:nth-child(1){width:20%}
.tbl--promos th:nth-child(2),.tbl--promos td:nth-child(2){width:26%}
.tbl--promos th:nth-child(3),.tbl--promos td:nth-child(3){width:12%}
.tbl--promos th:nth-child(4),.tbl--promos td:nth-child(4){width:12%}
.tbl--promos th:nth-child(5),.tbl--promos td:nth-child(5){width:14%}
.tbl--mails th:nth-child(1),.tbl--mails td:nth-child(1){width:12%}
.tbl--mails th:nth-child(2),.tbl--mails td:nth-child(2){width:28%}
.tbl--mails th:nth-child(3),.tbl--mails td:nth-child(3){width:26%}
.tbl--mails th:nth-child(4),.tbl--mails td:nth-child(4){width:14%}
.tbl--mails th:nth-child(5),.tbl--mails td:nth-child(5){width:10%}
.tbl td.promo-code{font-family:var(--font-mono);font-size:15px;font-weight:600}
.tbl--promos tr.is-off .promo-code,.tbl--promos tr.is-off td{color:var(--ls-ink-faint)}
.promolist{padding:4px 16px}
.promorow{display:flex;flex-direction:column;gap:10px;padding:14px 0;
  border-top:1px solid var(--ls-hairline)}
.promorow:first-child{border-top:0}
.promorow__top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.promorow__code{font-family:var(--font-mono);font-size:16px;font-weight:600}
.promorow.is-off .promorow__code{color:var(--ls-ink-faint)}
.promorow__mid{display:flex;justify-content:space-between;gap:10px;font-size:13px;color:var(--ls-ink-muted)}
.promorow__num{font-weight:600;color:var(--ls-ink-1);font-variant-numeric:tabular-nums;white-space:nowrap}
.promorow__acts{display:flex;gap:8px}
.promorow__acts .mini-btn{flex:1;height:40px;font-size:14px;font-weight:600}
.promorow .badge{flex:none;width:100px;height:22px;padding:0;justify-content:center;font-size:11px}

/* Шапка раздела над карточкой: слева метрика, справа фильтр и выгрузка. */
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-bottom:16px}
.sec-head__num{display:block;margin-top:2px;font-size:26px;font-weight:600;
  letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.sec-head__acts{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.sec-head .periods{margin-bottom:0;overflow-x:auto;scrollbar-width:none}
.sec-head .periods::-webkit-scrollbar{display:none}
.sec-head .periods button{flex:0 0 auto;white-space:nowrap}
.sec-head .btn--dark{height:36px;text-decoration:none}
.mail-cell{font-family:var(--font-mono);font-size:13px;overflow-wrap:anywhere}
/* В футере почт вместо выбора размера страницы — счётчик, как в макете. */
.pager__shown{font-size:13px;color:var(--ls-ink-muted);font-variant-numeric:tabular-nums}
#ml-box .pager__lbl,#ml-box .pager__sizes{display:none}
@media (max-width:860px){
  .sec-head{align-items:stretch}
  .sec-head__acts{width:100%;flex-direction:column;align-items:stretch}
  .sec-head__acts .periods{width:100%;min-width:0}
  /* На телефоне чипам самим есть где расти — растягиваем их на всю пилюлю,
     как на Обзоре, а не оставляем по ширине текста с пустым хвостом справа. */
  .sec-head .periods button{flex:1 1 0;min-width:0}
  .sec-head .btn--dark{height:44px;width:100%;flex:none}
  .mlist .mail-cell{font-size:12px}
  #ml-box .mrow__t{font-family:var(--font-mono);font-size:14px}
}

/* Письмо покупателю: слева редактор, справа предпросмотр. */
.letter-intro{max-width:900px;margin:0 0 16px;font-size:14px;line-height:1.45;color:var(--ls-ink-muted)}
.code-chip{font-family:var(--font-mono);font-size:13px;background:var(--ls-bg-soft);
  padding:1px 6px;border-radius:6px}
.split.letter-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}
@media (max-width:1100px){ .split.letter-split{grid-template-columns:minmax(0,1fr)} }
.letter-edit{display:flex;flex-direction:column;gap:14px}
.letter-lab{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}
.letter-len{font-size:12px;color:var(--ls-ink-faint)}
.letter-area{height:auto;padding:12px 14px;background:var(--ls-surface-alt);
  font-family:var(--font-mono);font-size:12.5px;line-height:1.55;resize:vertical}
.letter-test{padding-top:14px;border-top:1px solid var(--ls-hairline)}
.letter-test__row{display:flex;gap:8px;flex-wrap:wrap}
.letter-test__row .fld{flex:1;min-width:180px}
.letter-test__row .btn{white-space:nowrap}
/* Предпросмотр: письмо в рамке на странице-подложке, как в почтовом клиенте. */
.mailview{margin-top:14px;border:1px solid var(--ls-border);border-radius:var(--r-md);
  overflow:hidden;background:var(--ls-bg)}
.mailview__subj{padding:12px 16px;background:var(--ls-surface);border-bottom:1px solid var(--ls-hairline)}
.mailview__subj b{display:block;margin-top:4px;font-size:15px;font-weight:600}
.mailview__body{padding:16px;display:flex;flex-direction:column;gap:12px}
.mailview__brand{display:flex;align-items:center;gap:8px;padding:12px 16px;
  background:var(--ls-surface);border-radius:14px;font-size:15px;font-weight:600}
.mailview__card{padding:20px 18px;background:var(--ls-surface);border-radius:14px;
  font-size:14px;line-height:1.5}
/* Ширину и масштаб письма подбираем по фактическому размеру колонки. */
.mailview__frame{position:relative;width:100%;overflow:hidden;border-radius:14px;
  background:var(--ls-surface)}
.mailview__frame iframe{display:block;width:100%;border:0;transform-origin:top left}
.mailview__foot{margin:0;padding:4px 0;font-size:12px;color:var(--ls-ink-faint);text-align:center}
@media (max-width:860px){
  .split.letter-split{grid-template-columns:minmax(0,1fr);gap:12px}
}

/* Выбор карты/кошелька в форме заявки */
.pick{display:flex;align-items:center;gap:10px;width:100%;margin-top:8px;padding:0 16px;height:56px;
  border:1px solid var(--ls-border);border-radius:var(--r-sm);background:var(--ls-surface);
  font-family:inherit;font-size:15px;color:var(--ls-ink-1);cursor:pointer;text-align:left}
.pick i{width:18px;height:18px;flex:none;border-radius:50%;border:1.5px solid var(--ls-border-strong)}
.pick.is-on{border-color:var(--ls-accent);background:var(--ls-accent-soft)}
.pick.is-on i{border-color:var(--ls-accent);border-width:5px}
.pick b{font-weight:600}
.pick span{margin-left:auto;font-size:13px;color:var(--ls-ink-muted)}

.split-box{margin-top:14px;padding:14px 16px;background:var(--ls-bg-soft);border-radius:var(--r-sm)}
.split-row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-top:6px}
.split-row span{font-size:13px;color:var(--ls-ink-muted)}

/* Карточка способа выплаты */
.pm{display:flex;align-items:flex-start;gap:14px;padding:16px 0;border-top:1px solid var(--ls-hairline)}
.pm:first-of-type{border-top:0}
.pm__ico{width:44px;height:30px;flex:none;border-radius:6px;display:flex;align-items:center;justify-content:center;
  font-size:9px;font-weight:600;letter-spacing:.04em;color:#fff}
.pm__ico--card{background:#0F5132}
.pm__ico--usdt{background:#159C7B}
.pm__main{flex:1;min-width:0}
.pm__t{font-weight:600;font-size:15px}
.pm__acts{display:flex;gap:14px;flex:none;padding-top:2px}
.tag{display:inline-block;margin-left:6px;padding:2px 8px;border-radius:var(--r-pill);
  background:var(--ls-accent-soft);color:var(--ls-accent);font-size:12px;font-weight:600;vertical-align:1px}

.lim{margin-top:10px}
.lim__t{display:flex;justify-content:space-between;gap:12px;font-size:13px;color:var(--ls-ink-muted)}
.lim--hot{color:#8A6410}
.lim__bar{height:5px;margin-top:6px;border-radius:var(--r-pill);background:var(--ls-bg-soft);overflow:hidden}
.lim__bar i{display:block;height:100%;border-radius:var(--r-pill);background:#8A6410}

.row__ico--paid{background:rgba(27,138,75,.10);color:var(--ls-ok)}
.row__ico--rejected{background:rgba(163,42,42,.10);color:var(--ls-danger)}
.row__ico--paid,.row__ico--rejected{display:flex;align-items:center;justify-content:center;font-size:16px}

/* ===== Модальное окно ===== */
.ov{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;
  padding:20px;background:rgba(10,10,10,.35);backdrop-filter:blur(2px)}
/* display:flex перебивает атрибут hidden — гасим окно явно. */
.ov[hidden]{display:none}
.ov__card{position:relative;width:100%;max-width:440px;max-height:90vh;overflow:auto;background:var(--ls-surface);
  border-radius:var(--r-xl);padding:28px;box-shadow:var(--sh-dialog);
  animation:dlg-in .26s var(--ease-out)}
@keyframes dlg-in{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:none}}

/* ===== Окна на телефоне =====
   По макету это шторка снизу с ручкой: до кнопок в нижней части экрана легче
   дотянуться, а центрированное окно на узком экране выглядит чужеродно. */
@media (max-width:860px){
  .ov{align-items:flex-end;padding:0}
  .ov--top{align-items:flex-end;padding-top:0}
  .ov__card,.ov__card--sheet,.ov__card--cal,.ov__card--app,.ov__card--search{
    max-width:none;max-height:92dvh;padding:26px 20px 24px;
    border-radius:24px 24px 0 0;animation:sheet-up .28s cubic-bezier(.32,.72,0,1);
  }
  /* Ручка — подсказка, что шторку можно смахнуть вниз. */
  .ov__card::before{content:"";position:absolute;top:10px;left:50%;transform:translateX(-50%);
    width:36px;height:4px;border-radius:2px;background:var(--ls-border-strong)}
  .ov{z-index:60}
  .ov__card,.ov__card--sheet,.ov__card--cal,.ov__card--app,.ov__card--search{
    padding-bottom:calc(24px + var(--nav-h, 62px))}
  .ov__foot{flex-direction:column-reverse;gap:8px}
  .ov__foot .btn{flex:0 0 auto;width:100%;min-height:52px}
}
@keyframes sheet-up{from{transform:translateY(100%)}to{transform:none}}
/* Уход окна: на большом экране — растворяется, на телефоне — уезжает вниз. */
.ov.is-closing{animation:ov-out .18s ease forwards}
.ov.is-closing .ov__card{animation:dlg-out .18s var(--ease-out) forwards}
@keyframes ov-out{to{opacity:0}}
@keyframes dlg-out{to{opacity:0;transform:scale(.97)}}
@media (max-width:860px){
  .ov.is-closing .ov__card{animation:sheet-down .2s cubic-bezier(.32,.72,0,1) forwards}
}
@keyframes sheet-down{to{transform:translateY(100%)}}
@media (prefers-reduced-motion:reduce){
  .ov.is-closing,.ov.is-closing .ov__card{animation:none}
}

/* ===== Потянуть вниз — обновить =====
   Кружок выезжает из-под шапки: стрелка — «отпусти», вращение — «обновляю».
   На десктопе жеста нет, поэтому и индикатора тоже. */
.ptr{position:fixed;top:calc(var(--head-h, 60px) + 6px);left:50%;z-index:30;
  display:none;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:var(--r-pill);background:var(--ls-surface);color:var(--ls-ink-muted);
  box-shadow:var(--sh-nav);opacity:0;transform:translateX(-50%);pointer-events:none}
@media (max-width:860px){ .ptr{display:flex} }
.ptr svg{transition:transform .2s var(--ease-out)}
.ptr.is-ready{color:var(--ls-accent)}
.ptr.is-ready svg{transform:rotate(180deg)}
.ptr.is-busy svg{display:none}
.ptr.is-busy::after{content:"";width:16px;height:16px;border:2px solid var(--ls-border-strong);
  border-top-color:var(--ls-accent);border-radius:var(--r-pill);animation:ptr-spin .7s linear infinite}
@keyframes ptr-spin{to{transform:rotate(360deg)}}
.ov__title{margin:0 0 16px;font-size:22px;font-weight:600;letter-spacing:-.025em}
.ov__foot{display:flex;gap:10px;margin-top:20px}
.ov__foot .btn{flex:1}
.tabs{display:flex;gap:2px;padding:3px;border-radius:var(--r-pill);background:var(--ls-bg-soft);margin-bottom:16px}
.tabs button{flex:1;height:38px;border:0;border-radius:var(--r-pill);background:transparent;
  color:var(--ls-ink-muted);font-family:inherit;font-size:14px;font-weight:600;cursor:pointer}
.tabs button.is-on{background:var(--ls-surface);color:var(--ls-ink-1);box-shadow:0 1px 3px rgba(0,0,0,.08)}
.tabs--pill{background:transparent;padding:0;gap:6px}
.tabs--pill button{height:40px;border:1px solid var(--ls-border);background:var(--ls-surface);font-size:13px}
.tabs--pill button.is-on{background:var(--ls-dark);border-color:var(--ls-dark);color:#fff;box-shadow:none}
.mono{font-family:var(--font-mono);font-size:14px}
.ov__card--sheet{max-width:520px;padding:24px}

/* ===== Календарь периода ===== */
.ov__card--cal{max-width:420px;padding:24px}
/* ===== Разбор заявки =====
   Слева тёмная карточка «кто пришёл», справа анкета и решение: так в макете,
   и так решение принимается быстрее, чем по строке таблицы. */
.ov__card--app{max-width:720px}
.appcard{display:grid;grid-template-columns:220px minmax(0,1fr);gap:20px}
.appcard__side{display:flex;flex-direction:column;align-items:flex-start;gap:14px;
  padding:20px;border-radius:18px;background:var(--ls-dark)}
.appcard__ava{width:52px;height:52px;font-size:17px;background:rgba(255,255,255,.12);color:#fff}
.appcard__name{font-size:20px;font-weight:600;letter-spacing:-.02em;line-height:1.2;
  color:#fff;overflow-wrap:anywhere}
.appcard__nick{margin-top:2px;font-size:14px;color:var(--ls-accent-on-dark);overflow-wrap:anywhere}
.appcard__meta{margin-top:6px;font-size:12px;color:var(--on-dark-50)}
/* Ссылка прижата к низу карточки — как в макете, независимо от длины имени. */
.appcard__link{margin-top:auto;font-size:13px;font-weight:600;
  color:var(--ls-accent-on-dark);text-decoration:none}
.appcard__link:hover{text-decoration:underline}
.appcard__main{display:flex;flex-direction:column;gap:14px}
.appstats,.appcontacts{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}
.appstat{padding:12px 14px;border-radius:14px;background:var(--ls-surface-alt)}
.appstat__k{display:block;font-size:11px;font-weight:600;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ls-ink-faint)}
.appstat__v{display:block;margin-top:4px;font-size:20px;font-weight:600}
.appcard__topic{margin:4px 0 0;font-size:15px;line-height:1.5}
.appcard__val{margin:4px 0 0;font-size:14px}
.appcard__val--brk{word-break:break-all}
.appcard__log{margin:0;font-size:12px;color:var(--ls-ink-faint)}
/* Решение — ряд равных кнопок внизу правой колонки, и на телефоне тоже. */
.appcard__acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:auto}
.appcard__acts .btn{flex:1;height:44px;padding:0 16px}
.appcard__acts--stack{flex-direction:column}
.appcard__acts--stack .btn{width:100%}
@media (max-width:860px){
  .appcard{grid-template-columns:minmax(0,1fr)}
  .appcard__acts .btn{flex:1 1 0;width:auto;min-height:44px}
}

/* ===== Массовые действия над списком =====
   Появляется только когда что-то выделено — иначе это лишняя полоса.
   Плавающая тёмная пилюля, а не полоса в потоке: она не расталкивает таблицу
   при появлении и остаётся под рукой, до какой бы строки ни долистали список.
   Сдвиг на половину сайдбара (240px) центрирует её по колонке контента. */
.bulkbar{position:fixed;left:calc(50% + 120px);bottom:24px;transform:translateX(-50%);z-index:5;
  display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;margin:0;
  padding:8px 8px 8px 18px;border-radius:var(--r-pill);background:var(--ls-dark);
  /* значение --sh-float из дизайн-системы, отдельного токена в файле нет */
  box-shadow:0 2px 8px rgba(0,0,0,.04),0 24px 64px rgba(0,0,0,.10);
  animation:bulk-up .22s var(--ease-out)}
@keyframes bulk-up{from{opacity:0;transform:translate(-50%,16px)}to{opacity:1;transform:translate(-50%,0)}}
.bulkbar__n{font-weight:600;font-size:14px;color:#fff;margin-right:6px;font-variant-numeric:tabular-nums}
.bulkbar__sum{font-size:13px;color:rgba(255,255,255,.55)}
.bulkbar .mini-btn{height:36px;padding:0 14px;border:0;background:#fff;color:var(--ls-dark);font-size:13px;font-weight:600}
.bulkbar .mini-btn--danger{background:transparent;color:#FF8A7A}
.bulkbar .link-btn{color:rgba(255,255,255,.7);font-size:13px}
.bulkbar .link-btn:hover{color:#fff}
/* На телефоне пилюля разворачивается в полосу над нижним меню. Геометрия — в
   конце файла, в блоке «Массовые действия на телефоне»: там же резервируется
   место под полосу в прокрутке списка. */
/* Чекбокс строки: свой, чтобы совпадал с обводками и радиусами системы. */
/* Реквизиты в карточке выплаты: пункт — значение, значение копируется. */
.reqs{border-top:1px solid var(--ls-hairline)}
.reqrow{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--ls-hairline);font-size:14px}
.reqrow__k{flex:none;color:var(--ls-ink-muted)}
.reqrow__v{font-weight:500;text-align:right;overflow-wrap:break-word;min-width:0}
.reqrow .copycell{font-weight:500;text-align:right;min-width:0}
.copycell{max-width:100%;margin:-2px -6px;padding:2px 6px;border:0;border-radius:8px;
  background:transparent;font-family:var(--font-mono);font-size:13px;line-height:1.45;color:inherit;
  text-align:left;word-break:break-all;cursor:pointer;transition:background .15s}
@media (hover:hover){ .copycell:hover{background:var(--ls-bg-soft)} }
.copycell:active{background:var(--ls-bg-soft)}
.mlist .copycell{font-size:12px;white-space:normal;overflow-wrap:break-word}
.mlist .row__s:has(.copycell){white-space:normal;overflow:visible;text-overflow:clip}
.tickbox{width:20px;height:20px;flex:none;border:1.5px solid var(--ls-border-strong);border-radius:6px;
  background:var(--ls-surface);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}
.tickbox.is-on{background:var(--ls-accent);border-color:var(--ls-accent)}
.tickbox svg{opacity:0;color:#fff}
.tickbox.is-on svg{opacity:1}
.tbl tr.is-picked td{background:var(--ls-accent-soft)}

/* ===== Список карточками (телефон) =====
   На узком экране таблица нечитаема даже с прокруткой: в макете 390 списки
   собраны строками-карточками. Рисуем оба варианта, показываем нужный. */
.mlist{display:none}
/* Отрицательные поля ровно гасят padding:16px у .mlist, поэтому разделитель
   идёт от края до края карточки, а содержимое остаётся в 16px — как в макете. */
.mrow{
  display:flex;align-items:center;gap:12px;width:calc(100% + 32px);padding:14px 16px;margin:0 -16px;
  border:0;border-top:1px solid var(--ls-hairline);background:none;
  font:inherit;text-align:left;color:inherit;cursor:pointer;
}
.mlist .mrow:first-child{border-top:0}
/* Строка с собственным действием: содержимое сверху, кнопка во всю ширину снизу. */
.mrow--act{display:block;cursor:default}
.mrow__row{display:flex;align-items:center;gap:12px;width:100%}
.mrow__act{
  display:block;width:100%;height:44px;margin-top:12px;border:0;border-radius:var(--r-pill);
  background:var(--ls-accent);color:#fff;font:inherit;font-size:15px;font-weight:600;cursor:pointer;
}
.mrow__act:hover{background:var(--ls-accent-hover)}
/* Колонка строки: заголовок, подпись и примечание идут с одинаковым шагом 3px,
   поэтому свои margin-top потомкам не нужны. */
.mrow__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
/* Подпись строки — ровно одна строка с многоточием: иначе длинный текст
   разгоняет высоту строки с 70px до 90px и список теряет ритм. Скоуп .mlist
   обязателен — глобальный .row__s обслуживает и ячейки десктопных таблиц. */
.mlist .row__s{font-size:12px;margin-top:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Имя переносим, а не режем многоточием: ник партнёра и почту покупателя
   надо видеть целиком — по ним и опознают строку. */
.mrow__t{display:block;font-size:15px;font-weight:500;line-height:1.25;overflow-wrap:anywhere}
.mrow__right{display:flex;flex-direction:column;align-items:flex-end;gap:5px;flex:none;text-align:right}
.mrow__sum{font-size:15px;font-weight:600;white-space:nowrap}
/* Отступ примечанию даёт gap:3px у .mrow__main — свой margin-top дал бы 6px. */
.mrow__note{display:block;font-size:11px;line-height:1.35;color:var(--ls-err);margin-top:0}
/* Аватар в мобильной строке — 38px по макету. Скоуп обязателен: базовый .ava
   (36px) стоит в сайдбаре, .cell-user .ava (30px) — в десктопной таблице. */
.mlist .ava{width:38px;height:38px;font-size:12px}
/* Чип в строке списка по ширине текста: фиксированные 108px из макета оставляли
   пустоту справа от короткого статуса и зря отжимали имя партнёра в две строки.
   Правый край всё равно ровный — колонка прижата к нему. */
.mrow .badge{flex:none;height:22px;padding:0 10px;justify-content:center;gap:5px;font-size:11px;margin-top:0}
@media (max-width:860px){
  .mlist{display:block}
  .mlist + .tbl,.has-mlist .tbl{display:none}
  .has-mlist{overflow-x:visible}
}

/* ===== Тосты =====
   Короткое сообщение о результате действия. Заменяют системный alert: он
   блокирует страницу и выглядит чужеродно рядом с остальным интерфейсом. */
.toasts{position:fixed;top:80px;right:28px;z-index:80;
  display:flex;flex-direction:column;gap:8px;align-items:flex-end;pointer-events:none;max-width:min(92vw,440px)}
.toast{
  pointer-events:auto;max-width:100%;display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:12px 8px 12px 18px;border-radius:var(--r-pill);
  background:var(--ls-dark);color:#fff;font-size:14px;line-height:1.4;text-align:left;
  box-shadow:0 12px 32px rgba(0,0,0,.25);animation:toast-in .22s var(--ease-out);
}
/* Кнопка справа убирает тост руками: длинное сообщение (логин с паролем после
   одобрения заявки) иначе висит поверх экрана, пока не истечёт таймер. */
.toast__x{flex:none;height:28px;padding:0 12px;border:0;border-radius:var(--r-pill);
  background:rgba(255,255,255,.1);color:var(--ls-accent-on-dark);
  font:inherit;font-size:13px;font-weight:600;cursor:pointer}
/* Зелёного тоста в макете нет — успех показывается тем же тёмным, поэтому
   .toast--ok убран. Красный оставлен намеренно, это осознанное отступление:
   ошибку надо отличать с одного взгляда. */
.toast--err{background:var(--ls-err)}
@keyframes toast-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
/* На телефоне тост уходит вниз, но выше панели разделов. Вырез учитываем
   отдельно: сама панель тоже сдвинута на safe-area, иначе тост наедет на неё.
   Полосу массовых действий тоже объезжаем: она живёт на том же месте. */
@media (max-width:860px){ .toasts{top:auto;bottom:calc(76px + env(safe-area-inset-bottom,0px) + var(--bulkbar-h, 0px));left:16px;right:16px;align-items:stretch;max-width:none} }

/* ===== Поиск =====
   Окно прижато к верху: список результатов растёт вниз и не прыгает под курсором. */
.ov--top{align-items:flex-start;padding-top:12vh}
.ov__card--search{max-width:560px;padding:0;overflow:hidden}
.sr__head{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--ls-border);
  color:var(--ls-ink-faint)}
.sr__inp{flex:1;min-width:0;border:0;background:none;font:inherit;font-size:16px;color:var(--ls-ink-1)}
.sr__inp::placeholder{color:var(--ls-ink-faint)}
.sr__head kbd{font:inherit;font-size:12px;padding:2px 6px;border-radius:6px;
  background:var(--ls-neutral-bg);color:var(--ls-ink-muted)}
.sr__list{max-height:52vh;overflow:auto;padding:8px}
.sr__item{display:flex;align-items:center;gap:12px;width:100%;padding:10px 12px;border:0;border-radius:var(--r-sm);
  background:none;font:inherit;text-align:left;cursor:pointer}
.sr__item:hover,.sr__item.is-on{background:var(--ls-accent-soft)}
.sr__item b{display:block;font-size:15px;font-weight:600}
.sr__kind{margin-left:auto;font-size:12px;color:var(--ls-ink-faint);white-space:nowrap}
.sr__empty{padding:26px 20px;text-align:center;color:var(--ls-ink-faint);font-size:14px}
.cal__head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}
.cal__title{font-size:17px;font-weight:600}
.cal__nav{width:36px;height:36px;flex:none;border:0;border-radius:50%;background:var(--ls-bg-soft);
  color:var(--ls-ink-1);font-size:18px;line-height:1;cursor:pointer}
.cal__nav:hover{background:var(--ls-border)}
.cal__week,.cal__grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:2px}
.cal__week span{text-align:center;font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ls-ink-faint);padding-bottom:8px}
.cal__d{height:44px;border:0;border-radius:var(--r-sm);background:transparent;
  font-family:inherit;font-size:15px;color:var(--ls-ink-1);cursor:pointer;font-variant-numeric:tabular-nums}
@media (hover:hover){ .cal__d:hover:not([disabled]){background:var(--ls-bg-soft)} }
.cal__d[disabled]{color:var(--ls-ink-faint);opacity:.45;cursor:default}
.cal__d.is-in{background:var(--ls-accent-soft);color:var(--ls-accent)}
.cal__d.is-edge{background:var(--ls-dark);color:#fff;font-weight:600}
.cal__sum{margin:16px 0 0;text-align:center;font-size:14px;color:var(--ls-ink-muted)}
/* Произвольный период — отдельная пилюля рядом с готовыми периодами:
   в макете это самостоятельная кнопка, а не шестой пункт переключателя. */
.periods-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:22px}
.periods-row .periods{margin-bottom:0;flex:1;max-width:420px}
/* Календарь — такой же пункт переключателя, только с иконкой вместо слова. */
.periods__cal{
  display:flex;align-items:center;justify-content:center;gap:6px;flex:none;
  width:38px;height:30px;padding:0;
  border:0;border-radius:var(--r-pill);background:transparent;
  color:var(--ls-ink-muted);font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;
  transition:.15s;
}
/* Рамки у кнопки нет — состояние показываем только заливкой и цветом текста,
   иначе border-color в ховере и .is-on остаётся мёртвым объявлением. */
.periods__cal:hover{color:var(--ls-ink-1)}
.periods__cal.is-on{background:var(--ls-dark);color:#fff;font-weight:600}
/* С выбранным диапазоном показываем даты — кнопка растёт под текст. */
.periods__cal.is-on{width:auto;padding:0 12px}

/* ===== Уведомления ===== */
.side__bell{display:flex;align-items:center;gap:10px;width:100%;height:40px;padding:0 12px;margin-bottom:8px;
  border:0;border-radius:var(--r-sm);background:transparent;color:var(--ls-ink-muted);
  font-family:inherit;font-size:14px;cursor:pointer;text-align:left}
.side__bell:hover{background:var(--ls-bg-soft);color:var(--ls-ink-1)}
.side__bell svg{flex:none}
.side__bell-n{margin-left:auto}
.note{display:flex;align-items:flex-start;gap:12px;width:100%;padding:14px 8px;border:0;border-top:1px solid var(--ls-hairline);
  background:none;font:inherit;text-align:left;color:inherit;border-radius:var(--r-sm)}
button.note{cursor:pointer}
button.note:hover{background:var(--ls-surface-alt)}
.note:first-child{border-top:0}
.note__ico{width:36px;height:36px;flex:none;border-radius:50%;background:var(--ls-bg-soft);color:var(--ls-ink-muted);
  display:flex;align-items:center;justify-content:center;font-size:15px}
/* Тон кружка — по смыслу события, а не по «прочитано». Ошибку видно сразу. */
.note__ico--accent{background:var(--ls-accent-soft);color:var(--ls-accent)}
.note__ico--ok{background:var(--ls-ok-bg);color:var(--ls-ok)}
.note__ico--err{background:var(--ls-err-bg);color:var(--ls-err)}
.note__main{flex:1;min-width:0}
.note__t{font-size:15px;line-height:1.4}
.note--new .note__t{font-weight:600}
.note__dot{width:8px;height:8px;flex:none;margin-top:6px;border-radius:50%;background:var(--ls-accent)}
@media (max-width:520px){ .pm{flex-wrap:wrap} .pm__acts{width:100%;padding-left:58px} }

/* Модалки на телефоне — нижний шит, а не окно по центру экрана. */
@media (max-width:860px){
  .ov{align-items:flex-end;padding:0}
  .ov__card{max-width:none;width:100%;max-height:85vh;border-radius:20px 20px 0 0;
    padding-top:30px;position:relative}
  .ov__card::before{content:'';position:absolute;top:10px;left:50%;transform:translateX(-50%);
    width:36px;height:4px;border-radius:var(--r-pill);background:var(--ls-border-strong)}
}

/* Выплаты */
.seg{display:flex;gap:8px;margin:6px 0 16px}
/* Выбор из двух — капсула 44px с плотной рамкой, как единственный аналогичный
   компонент выбора в макете; 48px с радиусом поля читались как поле ввода. */
.seg button{flex:1;min-width:0;height:44px;border:1px solid var(--ls-border-strong);border-radius:var(--r-pill);
  background:var(--ls-surface);color:var(--ls-ink-1);font-size:15px;font-weight:600;cursor:pointer}
.seg button.is-on{border-color:var(--ls-accent);background:var(--ls-accent-soft);color:var(--ls-accent)}
/* Вариант выбора карточкой: название и пояснение в две строки, как в макете
   у выбора роли. Базовый .seg остаётся однострочным — он в настройках. */
.seg--stack button{height:44px;padding:0 14px;text-align:left;font-size:14px}
.seg--stack b{display:block;font-weight:600}
.seg--stack i{display:block;font-style:normal;font-size:11px;font-weight:400;opacity:.7}
.ok-note{color:var(--ls-ok);font-size:14px;margin:10px 0 0}
/* На телефоне тройка показателей идёт парами, а тёмная карточка — во всю
   ширину: столбиком они съедали весь первый экран. */
@media (max-width:860px){
  .chart__head:has(.legend){flex-direction:column;align-items:flex-start;gap:8px}
  .grid--2{grid-template-columns:minmax(0,1fr)} .grid--chart{grid-template-columns:minmax(0,1fr)}
  .stat3{grid-template-columns:minmax(0,1fr)}
  .stat3 .card{padding:18px 20px} .stat3 b{font-size:26px}
  .mini3{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }

/* ===== Адаптив ===== */
@media (max-width:1100px){ .grid--top{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} .grid--top .card--dark{grid-column:1/-1} }
@media (max-width:860px){
  .app.is-on{flex-direction:column}
  /* На телефоне контекст и уведомления живут в тёмной полосе .side — вторая
     шапка была бы дублем. */
  .topbar{display:none}
  /* Ширину задаём явно: без неё панель растягивалась по содержимому и уезжала
     за экран, утаскивая вбок всю страницу вместо того, чтобы скроллиться самой. */
  .side{position:static;width:100%;max-width:100%;min-width:0;height:auto;
    flex-direction:row;align-items:center;gap:12px;
    border-right:0;border-bottom:1px solid var(--ls-hairline);padding:12px 16px;overflow-x:auto}
  .side__logo{margin:0;flex:none}
  .nav{flex-direction:row;gap:6px}
  .nav__item{height:38px;white-space:nowrap;padding:0 12px}
  /* Подпись прячем только там, где у пункта есть иконка: в админке иконок нет,
     и без текста меню превратилось бы в ряд пустых кнопок. */
  .nav__item svg + .lbl{display:none}
  .side__foot{margin:0 0 0 auto;flex-direction:row;align-items:center;flex:none}
  .side .side__user .side__handle,.side .side__user .side__role{display:none}
  body{overscroll-behavior-y:contain}
  .list-head__count{margin-left:0}
  /* iOS увеличивает страницу, если кегль поля меньше 16px — из-за этого при
     вводе хэша транзакции экран «прыгал». Держим 16 у всех полей ввода. */
  .field__input,.field__input.mono,.fld,.mini-inp,.amount--field input,
  .letter-area,.note-inp,.sr__inp,.search__inp{font-size:16px}
  /* Действия в карточке партнёра — одним рядом: подписи для этого укорочены. */
  .pcard__acts{flex-wrap:nowrap;width:100%}
  .pcard__acts .mini-btn{flex:1 1 0;min-width:0;padding:0 6px;font-size:13px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;text-align:center}
  /* Вкладки карточки занимают всю ширину блока и не прокручиваются вбок. */
  #pc-tabs{display:flex;width:100%;overflow-x:visible}
  #pc-tabs .chip{flex:1;min-width:0;padding:0 6px}
  .list-head > .btn{width:100%;margin-left:0;height:44px;font-size:15px;order:1}
  .list-head__count{order:2;width:100%}
  .main{padding:20px 16px 48px;min-width:0}
  /* Таблицы шире экрана: пусть прокручивается сама карточка, а не страница.
     Иначе любой список уводил всю админку вбок. */
  .card{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* Тёмной карточке прокрутка не нужна и вредна: её свечение — круг, нарочно
     выходящий за правый край на 50px, и он должен обрезаться, а не тянуть за
     собой полосу прокрутки. Таблиц внутри такой карточки не бывает. */
  .card--dark{overflow:hidden}
  .tbl{min-width:max-content}
  .page__title{font-size:26px}
  .grid--top{grid-template-columns:minmax(0,1fr)}
  .metrics{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  /* Пилюля занимает всю ширину. Обычные фильтры делят её поровну;
     для главного #periods ниже есть поправка на разную длину подписей. */
  .periods{display:flex;width:100%;max-width:100%}
  /* Кегль не переопределяем: 12px из базового правила — макетный и на телефоне. */
  /* Макетные 30px рассчитаны на мышь: пальцу нужна цель повыше. */
  .periods button{flex:1 1 0;min-width:0;height:36px;white-space:nowrap;padding:0 6px}
  /* На главном фильтре пункты не равны по длине: «Сегодня» нужно больше
     места, чем «Всё». auto-basis даёт тексту симметричные поля вместо
     одинаковых тесных сегментов. */
  #periods button[data-p]{flex:1 1 auto;padding-left:8px;padding-right:8px}
  #periods .periods__cal{flex:0 0 40px;padding-left:0;padding-right:0}
  #periods .periods__cal.is-on{flex:0 1 auto;padding-left:10px;padding-right:10px}
  .periods__cal{height:40px}
  .periods__cal.is-on svg{display:none}

  /* ===== Кабинет партнёра: шапка сверху, разделы снизу =====
     Пунктов всего четыре, поэтому им место в нижней панели, как в приложении, —
     полоса с прокруткой вбок на телефоне неудобна. В админке разделов дюжина,
     там остаётся прокручиваемая полоса выше. */
  /* У шапки transform НЕ ставим: он делает её containing block, и нижняя
     панель разделов (position:fixed внутри неё) прилипает к шапке вместо
     низа экрана. Слой composited нужен только самой панели — см. .nav ниже. */
  .side--tabs{position:fixed;top:0;left:0;right:0;width:auto;height:60px;padding:0 12px 0 16px;
    display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
    grid-template-areas:'page logo bell';
    align-items:center;gap:8px;
    overflow:visible;z-index:20;backface-visibility:hidden}
  .side--tabs .side__logo b{font-size:16px}
  .side--tabs .side__logo br{display:none}
  .side--tabs .side__logo i{margin-left:6px}
  .side--tabs .nav{position:fixed;left:0;right:0;bottom:0;justify-content:space-around;gap:0;
    background:var(--ls-surface);border-top:1px solid var(--ls-hairline);
    padding:6px 4px calc(6px + env(safe-area-inset-bottom,0px));z-index:20;
    /* Собственный слой композитора: без него при инерционной прокрутке панель
       перерисовывается вместе со страницей, отстаёт и сквозь неё видно контент.
       Своих fixed-потомков у панели нет, поэтому transform здесь безопасен. */
    transform:translateZ(0);backface-visibility:hidden;will-change:transform}
  /* Фартук под панелью: в Safari при инерционной прокрутке панель на мгновение
     отстаёт от нижнего края, и в зазоре просвечивает страница. Продолжаем её
     фон вниз за пределы экрана — тогда в зазоре виден тот же фон. */
  .side--tabs .nav::after{content:'';position:absolute;left:0;right:0;top:100%;height:120px;
    background:var(--ls-surface);pointer-events:none}
  .side--tabs .nav__item{flex:1;flex-direction:column;justify-content:center;gap:3px;
    height:auto;padding:6px 2px;font-size:11px;text-align:center;border-radius:var(--r-sm)}
  .side--tabs .nav__item svg + .lbl{display:block}
  /* Иконка таба крупнее сайдбарной — 22 по макету против 18 в разметке. Штрих
     ужимаем до 1.35: viewBox 18 растягивается до 22, и штатные 1.6 дали бы
     почти 2px, заметно жирнее макета. */
  .side--tabs .nav__item svg{width:22px;height:22px;stroke-width:1.35}
  /* Подпись таба в админке — 10/600 у всех вкладок, активность передаётся
     только цветом. Скоуплено на .side--dark: в кабинете партнёра нижняя
     панель светлая и по своему макету там 11/500. */
  .side--dark .nav__item{gap:4px;font-size:10px;font-weight:600}
  .side--tabs .nav__item.is-on{background:transparent}
  .side--tabs .side__foot{grid-area:bell;justify-self:end;gap:4px}
  /* На узком экране таблицы прокручиваются вбок, а не сжимаются в кашу: до
     карточного вида списков (как в макете 390) руки ещё не дошли. */
  .tbl{min-width:600px}
  /* В мобильной шапке уведомления снова нужны: шапки с поиском здесь нет. */
  .side--dark .side__bell{display:flex}
  .side--dark .side__sub{display:none}
  .side--tabs .side__bell{grid-area:bell;justify-self:end;width:40px;height:40px;justify-content:center;padding:0;margin:0;position:relative}
  .side--tabs .side__bell .lbl{display:none}
  /* В шапке телефона нужен факт непрочитанного, а не счёт: точка 8×8, как в макете.
     Само число пользователь видит, открыв шторку уведомлений. */
  .side--tabs .side__bell-n{position:absolute;top:9px;right:10px;width:8px;height:8px;
    min-width:0;padding:0;margin:0;font-size:0;line-height:0;overflow:hidden;
    border:2px solid var(--ls-surface)}
  /* Кольцо вокруг точки — цветом шапки: у админки она тёмная, у кабинета светлая. */
  .side--dark .side__bell-n{border-color:var(--ls-dark)}
  .side--tabs .side__user{padding:0}
  .side--tabs .side__exit{padding:8px 6px;font-size:13px}
  /* Содержимое не должно уезжать под обе панели. */
  /* ===== Прокручивается контент, а не документ =====
     В Safari прокрутка страницы прячет панель браузера, высота вьюпорта на ходу
     меняется, и нижнее меню с position:fixed отстаёт от края — под ним мелькает
     сайт. Когда скроллится внутренний контейнер, высота вьюпорта постоянна, и
     меню стоит намертво (шапка сверху потому и не «плавала»). */
  html,body{height:100%;overflow:hidden}
  .app.is-on{height:100vh;height:100dvh;overflow:hidden}
  /* ===== Скроллер живёт РОВНО между шапкой и меню =====
     Раньше .main тянулся на всю высоту экрана, а меню лежало поверх него
     (position:fixed), и низ контента приходилось выталкивать из-под меню
     паддингом и спейсерами. На iOS это не работало: при инерционной прокрутке
     и отскоке visual viewport и высота 100dvh расходятся, и Safari возвращал
     контент под меню — низ последней карточки было не достать.

     Теперь скроллер сам fixed и прибит к тем же краям, что и панели: снизу —
     к верхней границе меню, сверху — под шапку. Область прокрутки физически
     заканчивается там, где начинается меню, поэтому уехать под него контенту
     просто некуда, сколько бы ни менялся вьюпорт. Спейсеры и scroll-padding
     после этого не нужны — их роль выполняет сама геометрия. */
  .side--tabs ~ .main{
    position:fixed;top:var(--head-h, 60px);left:0;right:0;
    /* Пока JS не измерил меню, держим запас по штатной высоте: меньше него
       панель не бывает даже без safe area. */
    bottom:max(var(--nav-h, 0px), calc(56px + env(safe-area-inset-bottom, 0px)));
    overflow-y:auto;overscroll-behavior-y:contain;
    padding:14px 16px 24px;margin:0}

  /* Админка: разделов дюжина, в панель влезает пять — четыре основных и «Ещё».
     Остальные открываются оттуда списком. */
  .side--dark .nav__item:not([data-tab]){display:none}
  .side--dark .side__group{display:none}
  /* Бейдж таба вдвое мельче сайдбарного (16 против 20) и сдвинут вправо от
     центра иконки — иначе кружок закрывает её правую половину. margin-left:0
     обязателен: он гасит auto из базового .nav__badge. */
  .side--dark .nav__badge{position:absolute;top:2px;left:calc(50% + 6px);margin-left:0;
    min-width:16px;height:16px;padding:1px 4px 0;font-size:10px}

  /* Тёмные панели админки — как в макете. */
  .side--dark{background:var(--ls-dark);border-bottom-color:transparent}
  /* Логотип в шапке телефона: тот же знак и подпись, что на десктопе,
     только мельче. Роль («админ») там не нужна — её место занимает раздел. */
  .side--dark .side__logo{display:flex;grid-area:logo;justify-self:center;align-items:center;
    gap:4px;height:44px;padding:0 6px;margin:0}
  .side--dark .side__logo .side__sub{display:none}
  .auth--dark .auth__tag{display:none}
  .side--dark .side__mark{width:18px;height:17px}
  .side--dark .side__logo b{display:none}
  .side--dark .side__logo i{font-size:14px}
  .side--dark .side__page{display:block;grid-area:page;color:#fff;min-width:0}
  .side--dark .side__page i{display:none}
  .side--dark .side__page b{font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* В макете тёмная полоса сплошная — светлый хайрлайн отрезал её верх.
     Именно transparent, а не border:0: рамка держит высоту полосы. */
  .side--dark .nav{background:var(--ls-dark);border-top-color:transparent}
  .side--dark .nav::after{background:var(--ls-dark)}
  .side--dark .nav__item{color:var(--on-dark-50)}
  .side--dark .nav__item.is-on{color:#fff;background:transparent;font-weight:600}
  /* Полоска слева — метка бокового меню; в таб-баре она торчит поверх иконки. */
  .side--dark .nav__item.is-on::before{display:none}
  .side--dark .nav__item.is-on svg{color:#fff}
  .side--dark .side__bell{color:var(--on-dark-70)}
  .side--dark .side__user,.side--dark .side__exit{display:none}
  .side--dark ~ .main .page__title{display:none}

  /* Заголовок раздела в шапке телефона. */
  .side__page i{display:block;font-style:normal;font-size:11px;font-weight:600;
    letter-spacing:.07em;text-transform:uppercase;color:var(--on-dark-50)}
  /* font-weight задаём явно: у тега <b> по умолчанию 700, а в макете 600 —
     без этого заголовок останется заметно жирнее оригинала. */
  .side__page b{display:block;font-size:18px;font-weight:600;margin-top:1px;
    line-height:1.15;letter-spacing:-.02em;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
/* Пятый пункт нижней панели нужен только на телефоне. */
.nav__item--more{display:none}
@media (max-width:860px){ .side--tabs .nav__item--more{display:flex} }

/* Хвост-заглушка под последней карточкой больше не нужна: скроллер теперь
   заканчивается у верхней границы меню, и выталкивать контент из-под неё нечем.
   Правило держим на случай, если элемент остался в чьей-то разметке. */
.mobile-scroll-tail{display:none}

/* Список разделов в «Ещё» */
/* Карточку списка почти лишаем полей: строка сама держит высоту 60px, а обычные
   22px карточки разгоняли шаг до 69px и список выглядел разреженным. Через :has,
   чтобы не заводить класс-модификатор ради единственной карточки экрана. */
.card:has(> .rows#more-box){padding:4px 16px}
.more-row{display:flex;align-items:center;gap:12px;width:100%;min-height:60px;padding:10px 0;border:0;
  border-top:1px solid var(--ls-hairline);background:transparent;font-family:inherit;
  text-align:left;color:inherit;cursor:pointer}
.more-row:first-child{border-top:0}
/* Подложка иконки строки — круг 36px: общий токен радиуса даёт скруглённый
   квадрат, а список «Ещё» в макете единственный, где иконки круглые. */
.more-row__ico{width:36px;height:36px;flex:none;border-radius:var(--r-pill);background:var(--ls-bg-soft);
  color:var(--ls-ink-muted);display:flex;align-items:center;justify-content:center}
.more-row__go{flex:none;color:var(--ls-ink-faint);font-size:20px;line-height:1}
.more-row:hover .more-row__ico{background:var(--ls-accent-soft);color:var(--ls-accent)}

/* Знак вопроса у карточки процента */
.help-btn{width:24px;height:24px;flex:none;border:1px solid var(--ls-border);border-radius:50%;
  background:transparent;color:var(--ls-ink-faint);font-size:13px;line-height:1;cursor:pointer}
.help-btn:hover{border-color:var(--ls-accent);color:var(--ls-accent)}

/* Лестница ступеней: столбик на ступень, отметка «ты здесь» на текущей */
.ladder{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:8px;align-items:end;margin-top:18px}
.ladder__col{display:flex;flex-direction:column;align-items:center;gap:6px;min-height:150px;justify-content:flex-end}
.ladder__col b{font-size:15px;font-weight:600;color:var(--ls-ink-muted);font-variant-numeric:tabular-nums}
.ladder__col b.is-you{color:var(--ls-accent)}
.ladder__bar{position:relative;width:100%;border-radius:10px 10px 4px 4px;background:var(--ls-bg-soft)}
.ladder__bar.is-you{background:var(--ls-accent)}
.ladder__bar i{position:absolute;left:50%;top:-8px;transform:translate(-50%,-100%);white-space:nowrap;
  height:20px;padding:0 8px;border-radius:var(--r-pill);background:var(--ls-dark);color:#fff;
  font-size:11px;font-style:normal;font-weight:600;display:inline-flex;align-items:center}
.ladder__col em{font-style:normal;font-size:12px;line-height:1.3;text-align:center;color:var(--ls-ink-muted)}
.pv-now{margin-top:18px;padding:12px 14px;border-radius:var(--r-sm);background:var(--ls-bg-soft)}

/* Прокручиваемый список внутри карточки: полосу прячем, чтобы не спорила
   с оформлением — что блок листается, видно по обрезанной строке. */
.scroll-y{overflow-y:auto;scrollbar-width:none;overscroll-behavior:contain}
.scroll-y::-webkit-scrollbar{display:none}

/* ===== A/B-тест цен на ссылке ===== */
/* Таблица этапов шире обычной шторки — окно раздвигаем. Два класса в
   селекторе: инлайн-стили админки грузятся после panel.css и перебили бы один. */
.ov__card.ab-card{max-width:760px}
.ab-hint{font-size:13px;line-height:1.45;color:var(--ls-ink-muted);margin:10px 0 0;text-align:left}
.ab-quota{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:16px 0 4px;font-size:14px;font-weight:600}
.ab-quota .mini-inp{width:110px}
.ab-scroll{overflow-x:auto;margin-top:12px;-webkit-overflow-scrolling:touch}
.ab-tbl{min-width:560px}
.ab-tbl .ab-inp{width:84px}
.ab-tbl .row__s{display:block}
.ab-best{color:var(--ls-ok);font-weight:700}
.ab-win td{background:var(--ls-ok-bg)}
.ab-prev{margin:22px 0 0}
.ab-bar{height:6px;border-radius:var(--r-pill);background:var(--ls-bg-soft);margin:12px 0 4px;overflow:hidden}
.ab-bar i{display:block;height:100%;background:var(--ls-accent);border-radius:inherit}
#ab-add{margin-top:10px}
/* Идущий тест видно прямо в таблице ссылок. */
.mini-btn--on{border-color:var(--ls-accent);color:var(--ls-accent)}

/* ===== Ссылки: фильтр по партнёру, поиск и сортировка столбцов ===== */
.l-tools{flex-wrap:wrap}
.l-tools .field__input{width:auto;height:40px;font-size:14px}
.l-tools__sel{min-width:220px}
.l-tools__q{min-width:240px}
/* Заголовок-кнопка выглядит как обычный заголовок столбца, но нажимается и
   доступен с клавиатуры. Стрелка у неактивного столбца бледная — просто
   намёк, что по нему можно сортировать. */
.th-sort{display:inline-flex;align-items:center;gap:4px;padding:0;border:0;background:none;cursor:pointer;
  font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;white-space:nowrap}
.th-sort:hover,.th-sort.is-on{color:var(--ls-ink-1)}
.th-sort__ic{font-size:12px;line-height:1;opacity:.35;text-transform:none;letter-spacing:0}
.th-sort.is-on .th-sort__ic{opacity:1;color:var(--ls-accent)}
.th-sort:focus-visible{outline:2px solid var(--ls-accent);outline-offset:2px;border-radius:4px}
@media (max-width:720px){
  /* 16px — меньше iOS увеличивает страницу при фокусе на поле. */
  .l-tools .field__input{flex:1 1 100%;min-width:0;width:100%;height:44px;font-size:16px}
}

/* ===== Массовые действия на телефоне =====
   Пилюля превращается в шторку над нижним меню. Высота ограничена и при
   переполнении прокручивается внутри: у ссылок действий много, и раньше полоса
   вырастала на треть экрана и накрывала карточки. Под меню она больше не уезжает —
   отступ считается от его измеренной высоты (--nav-h) с запасом на safe area. */
@media (max-width:860px){
  .bulkbar{left:12px;right:12px;width:auto;transform:none;border-radius:20px;
    bottom:calc(max(var(--nav-h, 0px), calc(56px + env(safe-area-inset-bottom, 0px))) + 10px);
    justify-content:flex-start;align-items:center;gap:8px;padding:10px 12px;
    max-height:min(56vh, 320px);overflow-y:auto;overscroll-behavior:contain;
    animation:bulk-up-m .22s var(--ease-out)}
  .bulkbar .mini-btn{height:40px}
  /* Место под полосу в прокрутке: последняя карточка списка должна оставаться
     доступной, а не прятаться за шторкой. */
  .side--tabs ~ .main[data-bulkbar]{padding-bottom:calc(var(--bulkbar-h, 0px) + 20px)}
}
@keyframes bulk-up-m{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}

/* ===== Тёмная тема админки =====
   Включается атрибутом data-scheme="dark" на <html>. Его ставит только админка
   (скрипт в <head> admin-v2.html: выбор «Авто / Светлая / Тёмная», «Авто» —
   по системе). Кабинет партнёра атрибут не ставит и остаётся светлым.
   Меняем токены, а поверх — только те места, где цвет задан литералом или
   где «тёмная» плашка (--ls-dark) на тёмном фоне перестала бы читаться. */
html[data-scheme="dark"]{
  color-scheme:dark;
  --ls-bg:#0E0F12; --ls-bg-soft:#1C1D22; --ls-surface:#16171B; --ls-surface-alt:#1B1C21;
  --ls-dark:#050506; --ls-dark-soft:#1C1D21;
  --ls-ink:#FFFFFF; --ls-ink-1:#E8E8EB; --ls-ink-muted:#A0A0A8; --ls-ink-faint:#7C7D85;
  --ls-accent:#5687F2; --ls-accent-hover:#7AA1F6; --ls-accent-soft:#18233D; --ls-accent-on-dark:#8FB0F5;
  --ls-ok:#4FC28A;      --ls-ok-bg:#13271D;
  --ls-wait:#D8B25E;    --ls-wait-bg:#2A2417;
  --ls-err:#F0877C;     --ls-err-bg:#2F1A18;
  --ls-neutral:#A0A0A8; --ls-neutral-bg:#222329;
  --ls-data-1:#5687F2; --ls-data-2:#7A8294; --ls-data-3:#4A505C;
  --ls-hairline:#222328; --ls-border:#2B2C32; --ls-border-strong:#3A3B42;
  --sh-card:0 0 0 1px rgba(255,255,255,.05),0 8px 24px rgba(0,0,0,.35);
  --sh-nav:0 1px 0 rgba(255,255,255,.05),0 4px 12px rgba(0,0,0,.35);
  --sh-dialog:0 40px 120px rgba(0,0,0,.7);
}
html[data-scheme="dark"] body{background:var(--ls-bg);color:var(--ls-ink-1)}
/* Выбранные пилюли и тёмные кнопки: на тёмном фоне чёрная плашка теряется — инвертируем */
html[data-scheme="dark"] .btn--dark,
html[data-scheme="dark"] .periods button.is-on,
html[data-scheme="dark"] .periods__cal.is-on,
html[data-scheme="dark"] .chip.is-on,
html[data-scheme="dark"] #pc-tabs .chip.is-on,
html[data-scheme="dark"] .pager__pages button.is-on,
html[data-scheme="dark"] .tabs--pill button.is-on,
html[data-scheme="dark"] .cal__d.is-edge,
html[data-scheme="dark"] .ladder__bar i{background:#ECECEF;border-color:#ECECEF;color:#0A0A0A}
html[data-scheme="dark"] .btn--dark:hover{background:#FFFFFF}
html[data-scheme="dark"] .btn--danger{color:#0A0A0A}
html[data-scheme="dark"] .btn--danger:hover{background:#F6A39A}
/* Тёмные карточки и плашки остаются тёмными, но получают контур, чтобы не слиться с фоном */
html[data-scheme="dark"] .card--dark,
html[data-scheme="dark"] .appcard__side,
html[data-scheme="dark"] .bulkbar,
html[data-scheme="dark"] .prices-preview,
html[data-scheme="dark"] .pay-summary{box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
html[data-scheme="dark"] .side--dark{border-right:1px solid rgba(255,255,255,.06)}
/* Наведения и подложки, заданные литералами */
html[data-scheme="dark"] #btn-exit-2:hover,
html[data-scheme="dark"] .search:hover{background:#25262C}
html[data-scheme="dark"] .chip-val--edit:hover{background:#22305A}
html[data-scheme="dark"] .side__exit:hover{background:rgba(240,135,124,.1)}
html[data-scheme="dark"] .lim--hot{color:var(--ls-wait)}
html[data-scheme="dark"] .lim__bar i{background:var(--ls-wait)}
html[data-scheme="dark"] .row__ico--paid{background:var(--ls-ok-bg)}
html[data-scheme="dark"] .row__ico--rejected{background:var(--ls-err-bg)}
html[data-scheme="dark"] .ov{background:rgba(0,0,0,.6)}
/* Стили, которые живут в <style> админки */
html[data-scheme="dark"] .order-channel{background:#22252C;color:#A9B3C4}
html[data-scheme="dark"] .order-channel--telegram{background:var(--ls-accent-soft);color:var(--ls-accent-hover)}
html[data-scheme="dark"] .tile:hover{background:var(--ls-surface-alt)}
html[data-scheme="dark"] .tbl tr:hover td{background:rgba(255,255,255,.025)}
html[data-scheme="dark"] #p-box .tbl tr.partner-owner td,
html[data-scheme="dark"] #p-box .mrow[data-owner="1"]{background:rgba(86,135,242,.08)}
html[data-scheme="dark"] #p-box .tbl tr.partner-owner:hover td{background:rgba(86,135,242,.12)}
html[data-scheme="dark"] .link-route .link-destination[data-destination="telegram"],
html[data-scheme="dark"] .link-route .link-destination[data-destination="telegram_webapp"]{border-color:#2A3A63}
html[data-scheme="dark"] .settings-status[data-ready="true"]{background:var(--ls-accent-soft)}
/* Превью письма и QR оставляем светлыми: письмо у получателя белое, QR должен читаться сканером */
html[data-scheme="dark"] .mail-prev{border-color:var(--ls-border)}
/* Переключатель темы: внизу тёмного меню админки и на экране «Ещё» на телефоне */
.theme-sw{display:flex;gap:2px;padding:3px;margin:0 0 10px;border-radius:var(--r-pill);background:rgba(255,255,255,.06)}
.theme-sw button{flex:1;height:30px;min-width:0;padding:0 6px;border:0;border-radius:var(--r-pill);background:transparent;
  color:var(--on-dark-50);font-family:inherit;font-size:12px;font-weight:500;cursor:pointer;transition:background .15s,color .15s}
.theme-sw button:hover{color:#fff}
.theme-sw button[aria-pressed="true"]{background:rgba(255,255,255,.14);color:#fff;font-weight:600}
.theme-sw--card{margin:16px 0 0;background:var(--ls-bg-soft)}
.theme-sw--card button{height:36px;font-size:13px;color:var(--ls-ink-muted)}
.theme-sw--card button:hover{color:var(--ls-ink-1)}
.theme-sw--card button[aria-pressed="true"]{background:var(--ls-surface);color:var(--ls-ink-1);box-shadow:0 1px 3px rgba(0,0,0,.08)}
@media (max-width:860px){ .side .theme-sw{display:none} }
/* Меню админки длиннее экрана ноутбука (~900 px): низ с темой, профилем и «Выйти»
   уезжал за край. Даём панели прокрутку — только на десктопе, где она колонкой. */
@media (min-width:861px){ .side--dark{overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.15) transparent} }
