/* Оформление мини-аппа. Токены — в tokens.css (синхронизируются с
 * дизайн-системой в claude.ai/design через DesignSync).
 *
 * Направление: спокойное и тёплое. Цвет живёт тинтом на плитке, а не
 * заливкой; опознавательный знак — точка в полную силу плюс название.
 * Название есть у каждой плитки и каждой строки всегда: именно оно, а не
 * цвет, несёт смысл. Это принципиально — приглушённая палитра не даёт
 * достаточного перцептивного расстояния между оттенками, и цвет в
 * одиночку смысл нести не может.
 */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

body {
  margin: 0 auto; max-width: 480px;
  padding: calc(var(--safe-top-px) + var(--gap-3)) var(--gap-4)
           calc(var(--safe-bottom-px) + var(--tabbar) + var(--gap-6));
  background: var(--bg); color: var(--text);
  font: var(--t-body); -webkit-font-smoothing: antialiased;
}

h2 {
  font: var(--t-caps); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--muted);
  margin: var(--gap-6) 0 var(--gap-3);
  display: flex; justify-content: space-between; align-items: baseline;
}
h2 button { background: none; border: 0; color: var(--link); cursor: pointer;
            font: var(--t-small); text-transform: none; letter-spacing: 0; }

/* ── Шапка месяца ────────────────────────────────────────────────── */
.top { display: flex; align-items: center; justify-content: space-between;
       padding: var(--gap-1) 0 var(--gap-5); }
.top .label { font: var(--t-title); }
.top button { width: 34px; height: 34px; border: 1px solid var(--line);
              border-radius: 50%; background: none; color: var(--text);
              font-size: 16px; cursor: pointer; }
.top button:disabled { opacity: .3; }

/* ── Главное число ───────────────────────────────────────────────── */
.hero .cap { font: var(--t-meta); color: var(--muted); }
.hero .val { font: var(--t-hero); letter-spacing: var(--track-hero);
             font-variant-numeric: var(--num); margin-top: var(--gap-1); }

/* ── Полоска года ────────────────────────────────────────────────── */
/* Монохромная намеренно: год — это контекст, а не главный герой экрана.
 * Цветные столбцы конкурировали бы с категориями за внимание. */
.spark { display: flex; align-items: flex-end; gap: 3px; height: 44px;
         margin: var(--gap-4) 0 var(--gap-1); }
.spark button { flex: 1; border: 0; padding: 0; background: var(--brand);
                opacity: .22; border-radius: 3px; min-height: 3px;
                cursor: pointer; transition: opacity .15s; }
.spark button.sel { opacity: 1; }
.spark-cap { font: var(--t-small); color: var(--muted);
             display: flex; justify-content: space-between; }

/* ── Плитки категорий ────────────────────────────────────────────── */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-2); }
.tile { border-radius: 18px; padding: var(--gap-4); min-height: 100px;
        display: flex; flex-direction: column; justify-content: space-between;
        cursor: pointer; border: 0; text-align: left; font: inherit;
        color: var(--text); }
/* Ведущая плитка — самая насыщенная, текст на ней светлый. */
.tile.lead, .tile.lead .pct { color: var(--on-fill-1); }
.tile.lead .pct { opacity: .72; }
.tile.big { grid-column: span 2; }
.tile .name { font: var(--t-meta); min-width: 0; overflow: hidden;
              text-overflow: ellipsis; white-space: nowrap; opacity: .85; }
/* Суммы не переносим: в узбекских сумах значение вчетверо длиннее
   рублёвого и разваливалось на две строки, растягивая плитку. */
.tile .sum { font: 700 22px/1.1 var(--font); letter-spacing: -.02em;
             font-variant-numeric: var(--num); white-space: nowrap;
             overflow: hidden; text-overflow: ellipsis; }
.tile.long .sum { font-size: 17px; }
.tile .pct { font: var(--t-small); color: var(--muted); }

/* ── Полный список категорий ─────────────────────────────────────── */
.crow { display: flex; align-items: center; gap: var(--gap-3);
        padding: var(--gap-3) 0; cursor: pointer; }
.crow + .crow { border-top: 1px solid var(--line); }
.crow .body { flex: 1; min-width: 0; }
.crow .line { display: flex; justify-content: space-between; gap: var(--gap-3);
              align-items: baseline; }
.crow .nm { min-width: 0; overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; }
.crow .sm { font: var(--t-strong); font-variant-numeric: var(--num);
            white-space: nowrap; }
/* Доля показана длиной полосы одного тона — сравнивать проще, чем цифры. */
.crow .track { height: 4px; border-radius: 2px; background: var(--surface);
               margin-top: 7px; overflow: hidden; }
.crow .track i { display: block; height: 100%; background: var(--brand);
                 border-radius: 2px; opacity: .8; }
.crow .pc { font: var(--t-small); color: var(--muted); width: 4ch;
            text-align: right; flex: none; }

/* ── Лента операций ──────────────────────────────────────────────── */
.op { display: flex; align-items: center; gap: var(--gap-3);
      padding: 11px 0; border-bottom: 1px solid var(--line); }
.op .who { flex: 1; min-width: 0; }
.op .title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op .meta { font: var(--t-small); color: var(--muted); margin-top: 1px; }
.op .amt { font: var(--t-strong); font-variant-numeric: var(--num);
           white-space: nowrap; }
.op .amt.plus { color: var(--good); }

/* ── Полоса состояния синхронизации ──────────────────────────────── */
/* Показывается только когда что-то не так. Пока данные доходят —
 * пользователя не трогаем вовсе. */
.notice { display: flex; align-items: center; gap: var(--gap-3);
          padding: var(--gap-3) var(--gap-4); border-radius: var(--radius-sm);
          background: color-mix(in oklab, var(--warning) 14%, var(--bg));
          margin-bottom: var(--gap-4); font: var(--t-meta); }
.notice.bad { background: color-mix(in oklab, var(--critical) 14%, var(--bg)); }
.notice .txt { flex: 1; }
.notice button { border: 0; border-radius: 8px; padding: 7px 12px;
                 background: var(--text); color: var(--bg);
                 font: var(--t-small); font-weight: 600; cursor: pointer;
                 white-space: nowrap; }
.notice button:disabled { opacity: .5; }

/* ── Кнопки и служебное ──────────────────────────────────────────── */
.btn { width: 100%; padding: var(--gap-3); border: 1px solid var(--line);
       border-radius: var(--radius-sm); background: none; color: var(--text);
       font: var(--t-body); cursor: pointer; margin-top: var(--gap-3); }
.msg { padding: var(--gap-6) var(--gap-4); text-align: center; color: var(--muted); }
.msg.err { color: var(--critical); }
.empty { color: var(--muted); padding: var(--gap-4) 0; }
.foot { margin-top: var(--gap-6); padding-top: var(--gap-4);
        border-top: 1px solid var(--line); font: var(--t-small);
        color: var(--muted); display: flex; justify-content: space-between;
        align-items: center; gap: var(--gap-3); }
.foot button { background: none; border: 0; color: var(--link);
               font: var(--t-small); cursor: pointer; }

/* ── Меню ────────────────────────────────────────────────────────── */
/* Плавающая капсула, а не панель во всю ширину: она не делит экран
 * линией и не отъедает угол в угол, а активный раздел читается пилюлей,
 * не полагаясь на один лишь цвет подписи. */
.tabbar {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 50;
  bottom: calc(var(--safe-bottom-px) + var(--gap-3));
  display: flex; gap: 2px; padding: 5px;
  background: var(--menu-bg); border-radius: 999px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .22);
  max-width: calc(100% - var(--gap-5));
}
.tabbar button {
  border: 0; background: none; cursor: pointer; white-space: nowrap;
  padding: 9px 15px; border-radius: 999px;
  color: var(--menu-ink); font: var(--t-small);
  transition: background .15s, color .15s;
}
.tabbar button.on { background: var(--menu-on-bg); color: var(--menu-on-ink);
                    font-weight: 600; }

/* ── Экран входа в банк ──────────────────────────────────────────── */
.auth { position: fixed; inset: 0; z-index: 100; background: var(--bg);
        display: flex; flex-direction: column; justify-content: center;
        padding: calc(var(--safe-top-px) + var(--gap-5)) var(--gap-5)
                 calc(var(--safe-bottom-px) + var(--gap-5)); }
.auth .card { width: 100%; max-width: 420px; margin: 0 auto; }
.auth .step { font: var(--t-small); color: var(--muted); margin-bottom: var(--gap-2); }
.auth h3 { margin: 0 0 var(--gap-1); font: 700 24px/1.15 var(--font);
           letter-spacing: -.02em; }
.auth p { margin: 0 0 var(--gap-5); font: var(--t-meta); color: var(--muted); }
.auth input { width: 100%; padding: var(--gap-3); border-radius: var(--radius-sm);
              font-size: 16px; border: 1px solid var(--line);
              background: var(--surface); color: var(--text); }
.auth input:focus { outline: 2px solid var(--text); outline-offset: -1px; }
.auth .row { display: flex; gap: var(--gap-2); margin-top: var(--gap-3); }
.auth .row button { flex: 1; padding: var(--gap-3); border: 0;
                    border-radius: var(--radius-sm); font: var(--t-body);
                    font-weight: 600; cursor: pointer;
                    background: var(--text); color: var(--bg); }
.auth .row button.ghost { background: none; border: 1px solid var(--line);
                          color: var(--muted); font-weight: 400; }
.auth .err { color: var(--critical); font: var(--t-meta); margin-top: var(--gap-3); }
.auth .spin { width: 22px; height: 22px; margin-bottom: var(--gap-4);
              border: 2px solid var(--line); border-top-color: var(--text);
              border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Управление категориями и продавцами ─────────────────────────── */
.seg { display: flex; gap: 2px; padding: 3px; border-radius: 999px;
       background: var(--surface); margin-bottom: var(--gap-4); }
.seg button { flex: 1; border: 0; background: none; cursor: pointer;
              padding: 8px; border-radius: 999px; color: var(--muted);
              font: var(--t-meta); }
.seg button.on { background: var(--brand); color: #fff; font-weight: 600; }

.crow .sub { font: var(--t-small); color: var(--muted); margin-top: 3px; }
.crow .sub b { color: var(--text); font-weight: 600; }
.badge { font: var(--t-small); color: var(--brand); border: 1px solid var(--brand);
         border-radius: 5px; padding: 0 5px; margin-left: 6px; opacity: .8; }

/* Кнопки действий в строке: мелкие, чтобы не спорить с содержимым. */
.mini { border: 1px solid var(--line); background: none; color: var(--muted);
        border-radius: 999px; padding: 5px 11px; font: var(--t-small);
        cursor: pointer; white-space: nowrap; flex: none; }
.mini.set { border-color: var(--brand); color: var(--brand); }
.mini.danger { border-color: var(--critical); color: var(--critical); }
.mini:disabled { opacity: .4; }

/* Выбор категории — чипы прямо под строкой продавца: на телефоне это
   быстрее модального окна и не теряет контекст. */
.picker { display: flex; flex-wrap: wrap; gap: 6px;
          padding: 0 0 var(--gap-3); }
.chip { border: 1px solid var(--line); background: var(--surface);
        color: var(--text); border-radius: 999px; padding: 7px 12px;
        font: var(--t-small); cursor: pointer; }
.chip.on { background: var(--brand); color: #fff; border-color: var(--brand); }

/* Список действий раскрывается под строкой и не перерисовывает экран:
   полный render() уводил список в начало, и продавца приходилось искать
   заново после каждой правки. */
.picker[hidden] { display: none; }
.chip.danger { border-color: var(--critical); color: var(--critical); }
.chip:disabled { opacity: .45; }
.sub .err { color: var(--critical); }

/* Возврат из отфильтрованной ленты. Переход на другую вкладку без выхода
   был тупиком: непонятно, как вернуться к списку, откуда провалился. */
.top button.back { width: auto; padding: 0 12px; border-radius: 999px;
                   font: var(--t-meta); color: var(--muted); }
.top .label .period { display: block; font: var(--t-small); color: var(--muted);
                      font-weight: 400; margin-top: 1px; }

/* Вид категории — цветом кнопки: трата нейтральна, доход зелёный,
   перевод приглушён. Подпись есть всегда, цвет только подкрепляет. */
.mini.kind-income { border-color: var(--good); color: var(--good); }
.mini.kind-transfer { opacity: .6; }

/* Выбор категории прямо под операцией. Раскрывается на месте и не
   перерисовывает экран: перерисовка сбрасывала прокрутку, и нужную
   операцию приходилось искать заново. */
.op { cursor: pointer; }
.picker-cap { font: var(--t-small); color: var(--muted); padding: 0 0 var(--gap-2); }
.picker .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.picker { padding: var(--gap-3) 0; border-bottom: 1px solid var(--line); }
.chip.new { border-style: dashed; color: var(--muted); }

/* Правка категории под строкой: место есть и для поля, и для выбора вида
   кнопками. Раньше вид спрашивался текстом, и опечатка молча не делала
   ничего. */
.editor { padding: var(--gap-3) 0 var(--gap-4); border-bottom: 1px solid var(--line); }
.edit-name { width: 100%; padding: 10px var(--gap-3); border-radius: var(--radius-sm);
             border: 1px solid var(--line); background: var(--surface);
             color: var(--text); font: var(--t-body); margin-bottom: var(--gap-2); }
.edit-name:focus { outline: 2px solid var(--brand); outline-offset: -1px; }
.editor .row { display: flex; gap: var(--gap-2); margin-top: var(--gap-3); }
.editor .row button { flex: 1; padding: 10px; border: 0; border-radius: var(--radius-sm);
                      background: var(--brand); color: #fff; font: var(--t-meta);
                      font-weight: 600; cursor: pointer; }
.editor .row button.ghost { background: none; border: 1px solid var(--line);
                            color: var(--muted); font-weight: 400; }
.editor .row button.danger { color: var(--critical); border-color: var(--critical); }

/* Период на ленте переключается тапом по заголовку: месяц или вся
   история. Заголовок оформлен кнопкой — тонкой галочки рядом с обычным
   текстом было почти не видно, и что он нажимается, никто не догадывался. */
.top .label.tappable, .top .period.tappable {
  cursor: pointer; border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 12px; display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface);
}
.top .period.tappable { font: var(--t-small); padding: 3px 9px; margin-top: 3px; }
.top .label .caret { font-size: 10px; opacity: .85; }
