/* ============================================================================
   Кабинет MoneyFlow — язык «Раскладка».
   Модульная сетка: важное занимает больше места и читается первым.
   Светлый фон, скруглённые плитки, крупные числа моноширинным шрифтом.
   Акцент один — мшисто-зелёный; палитра — в tokens.css.
   ============================================================================ */

@import url('/assets/css/fonts.css');

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.55 'Golos', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-family: 'Onest', sans-serif; letter-spacing: -0.025em; line-height: 1.2; font-weight: 700; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.05rem; }
h3 { font-size: 0.95rem; }

p { margin: 0 0 1em; }
a { color: var(--volt); }

.muted { color: var(--muted); }
.small { font-size: 0.86rem; }
.neg { color: var(--coral); }
.r { text-align: right; }
.c { text-align: center; }

/* ---------------------------------------------------------------- шапка */

.top {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  flex-wrap: wrap;
  padding: 1rem clamp(1rem, 3vw, 1.75rem);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.035em;
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}

.brand-mark {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: var(--volt);
  color: #fff;
  font-size: 0.9rem;
}

.nav { display: flex; gap: 0.2rem; flex-wrap: wrap; }

.nav a {
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.93rem;
}

.nav a:hover { background: #e7ecf1; color: var(--ink); }
.nav a.on { background: var(--ink); color: #fff; }

.logout button {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--muted);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  font: 400 0.9rem 'Onest', sans-serif;
  cursor: pointer;
}

.logout button:hover { border-color: var(--ink); color: var(--ink); }

/* Нижняя панель — «касса с кнопкой ＋» (выбор Александра): три раздела, клавиша
   записи траты посередине, остальное под «Ещё». На десктопе скрыта, пилюли
   остаются; отступ снизу держит body.with-tabbar. */
.tabbar { display: none; }

@media (max-width: 620px) {
  .with-tabbar .nav { display: none; }

  .tabbar {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    background: var(--card);
    border-top: 1px solid var(--line);
    padding: 0.45rem 0.3rem calc(0.45rem + env(safe-area-inset-bottom));
  }

  .tabbar .tab {
    display: grid; justify-items: center; gap: 3px;
    color: var(--muted); text-decoration: none;
    font-size: 0.6rem; letter-spacing: 0.01em;
  }

  .tabbar svg {
    width: 22px; height: 22px;
    stroke: currentColor; fill: none;
    stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  }

  .tabbar .tab.on { color: var(--volt); font-weight: 600; }

  /* Оба всплывающих блока — details; сама ячейка сетки остаётся обычной. */
  .tab-pop { position: static; }
  .tab-pop > summary { list-style: none; cursor: pointer; }
  .tab-pop > summary::-webkit-details-marker { display: none; }
  .tab-pop > summary:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; border-radius: 8px; }

  /* Клавиша записи выступает над панелью — как кнопка выдачи чека на кассе. */
  .tab-plus {
    position: absolute; left: 50%; top: -22px; transform: translateX(-50%);
    width: 54px; height: 54px; border-radius: 50%;
    background: var(--volt); color: #fff;
    display: grid; place-items: center;
    border: 4px solid var(--bg);
    box-shadow: 0 8px 18px -6px rgba(15, 110, 82, .6);
    font: 300 1.7rem/1 'Onest', sans-serif;
  }
  .tab-plus span { margin-top: -2px; }

  .tabbar .pop {
    position: absolute; bottom: calc(100% + 0.55rem); z-index: 41;
    background: var(--card); border-radius: 16px; padding: 0.75rem;
    box-shadow: 0 22px 44px -20px rgba(13, 19, 24, .55);
  }

  .tab-more .pop { right: 0.6rem; min-width: 10.5rem; padding: 0.4rem; display: grid; gap: 2px; }

  /* Бланк новой траты — отдельный экран, а не окошко над клавишей: окошко
     накрывало саму клавишу, и закрыть его пальцем было некуда. */
  .blank-sheet {
    position: fixed; inset: 0; z-index: 60;
    background: var(--bg); padding: 0.8rem 0.75rem calc(1.2rem + env(safe-area-inset-bottom));
    overflow-y: auto;
  }
  body:has(.tab-add[open]) { overflow: hidden; }

  .blank-top {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 0.7rem;
    font: 400 0.62rem/1 'JetBrains', monospace; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--muted);
  }
  .blank-x {
    width: 34px; height: 34px; border-radius: 50%; background: var(--card);
    display: grid; place-items: center; color: var(--muted); text-decoration: none;
    font-size: 0.95rem; border: 1px solid var(--line);
  }
  .blank-x:hover { color: var(--ink); border-color: var(--ink); }

  /* Селектор с классом бланка — иначе общее правило input[type=text] возвращает
     полю рамку и фон, и сумма перестаёт быть суммой на бумаге. */
  .blank-sheet input.blank-sum {
    width: 100%; text-align: center; background: none; color: var(--ink);
    border: 0; border-bottom: 2px solid var(--line); border-radius: 0;
    font: 500 1.9rem/1.1 'JetBrains', monospace; font-variant-numeric: tabular-nums;
    padding: 0.5rem 0 0.55rem; margin-bottom: 1rem;
  }
  .blank-sheet input.blank-sum:focus { outline: none; border-bottom-color: var(--volt); }
  .blank-sheet input.blank-sum::placeholder { color: #c2ccd4; }

  .blank-fields { display: grid; gap: 0.6rem; margin-bottom: 1rem; }
  .blank-field { display: grid; gap: 0.25rem; }
  /* [hidden] в UA-стилях проигрывает авторскому display:grid выше — без этого
     правила поле «Какой долг» остаётся видимым, хотя JS уже поставил hidden. */
  .blank-field[hidden] { display: none; }
  .blank-field > span {
    font: 400 0.6rem/1 'JetBrains', monospace; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--muted);
  }
  .blank-field input, .blank-field select {
    width: 100%; font: 500 0.95rem 'Golos', sans-serif; color: var(--ink);
    padding: 0.6rem 0.7rem; border: 1px solid var(--line); border-radius: var(--r-sm);
    background: #fafbfc;
  }
  .quick-go {
    width: 100%; border: 0; border-radius: var(--r-sm);
    background: var(--volt); color: #fff; padding: 0.7rem;
    font: 700 0.75rem/1 'JetBrains', monospace; letter-spacing: 0.08em;
    text-transform: uppercase; cursor: pointer;
  }
  .quick-go:active { background: var(--volt-dark); }

  /* Остаток выбранной корзины — под чеком, чтобы было видно, из чего тратишь. */
  .blank-left {
    background: var(--card); border-radius: var(--r-sm);
    padding: 0.7rem 0.75rem 0.75rem; margin-top: 0.9rem;
    font: 400 0.78rem/1.4 'JetBrains', monospace; color: var(--ink);
  }
  .blank-left-row { display: flex; justify-content: space-between; gap: 0.6rem; }
  .blank-left-row .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .blank-left-row .val { white-space: nowrap; font-variant-numeric: tabular-nums; }
  .blank-track { height: 5px; border-radius: 3px; background: #eceff2; overflow: hidden; margin-top: 0.45rem; }
  .blank-track i { display: block; height: 100%; }
  .blank-left-note { color: var(--muted); font-size: 0.66rem; margin-top: 0.4rem; }

  .pop-links a {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.6rem 0.7rem; border-radius: 10px;
    color: var(--ink); text-decoration: none; font-size: 0.92rem;
  }
  .pop-links a.on { background: var(--volt-soft); color: var(--volt); font-weight: 600; }

  body.with-tabbar { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
}

/* ---------------------------------------------------------------- каркас */

.wrap { max-width: 1200px; margin: 0 auto; padding: 0.25rem clamp(1rem, 3vw, 1.75rem) 3rem; }

.card {
  background: var(--card);
  border-radius: var(--r);
  padding: 1.5rem;
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}

.card-narrow { max-width: 430px; margin-inline: auto; }

/* Плитка поддержки — тише остальных: приглушённый фон, ни одного акцентного цвета. */
.support-tile {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
  background: #fbfbfd;
}

.support-tile p {
  margin: 0;
  flex: 1 1 16rem;
}

.support-tile .linklike {
  color: #8a8f9c;
  font-size: 0.85rem;
}

.grid-2 {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
}

@media (max-width: 940px) { .grid-2 { grid-template-columns: minmax(0, 1fr); } }

/* Сетка обзора — «пульт и лента» (выбор Александра): слева то, чем управляешь,
   справа лента чеков в их собственной ширине 460px.

   minmax(0, 1fr), а не 1fr: чек состоит из nowrap-строк и по max-content распирает
   трек — страница уезжает вбок вместе с fixed-панелью.
   Порядок блоков в разметке не меняется, поэтому на телефоне лента остаётся прежней. */
.bento { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }

/* Колонки — отдельные контейнеры, а не общая сетка блоков: в общей сетке строки
   выравниваются по самому высокому соседу, и под низкой плашкой зияла дыра
   высотой с чек. Так каждая колонка укладывается плотно и независимо. */
/* minmax(0, 1fr) обязателен и здесь: без него колонка растягивается по
   max-content чека и уносит страницу вбок на телефоне. */
.bento-col { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; align-content: start; min-width: 0; }

@media (min-width: 1001px) {
  .bento { grid-template-columns: minmax(0, 1fr) 460px; align-items: start; }
}

.bento > * { margin-bottom: 0; }
/* Чек внутри бенто-сетки: отступ ленты ему не нужен, ячейка и так с зазором.
   width: 100% обязателен — `margin-inline: auto` у ленты переключает элемент
   сетки на fit-content, и чек вылезает за свой трек, утаскивая страницу вбок. */
.bento .cheque-feed { width: 100%; }
.bento .cheque { margin-bottom: 0; }
.span-2 { grid-column: span 2; }
.span-4 { grid-column: span 4; }
@media (max-width: 1000px) { .span-4 { grid-column: span 2; } }
@media (max-width: 620px) { .span-2, .span-4 { grid-column: span 1; } }

/* Главная плитка с ответом «сколько можно потратить» */
.headline {
  background: var(--ink);
  color: #fff;
  border-radius: var(--r);
  padding: 1.75rem;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1.25rem;
}

.headline .k { font-size: 0.8rem; color: #9aa3b2; }
.headline .big {
  font-family: 'JetBrains', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: clamp(2.2rem, 5vw, 3.2rem);
  letter-spacing: -0.05em;
  line-height: 1;
  margin: 0.6rem 0 0;
}
.headline .of { color: #9aa3b2; font-size: 0.9rem; margin: 0.55rem 0 0; }
/* Дневной лимит: подпись серая, цифра белая моно — вторая по важности после суммы. */
.headline .hd-pace { color: #9aa3b2; font-size: 0.9rem; margin: 0.35rem 0 0; }
.headline .hd-pace b {
  font: 500 1rem/1 'JetBrains', monospace;
  font-variant-numeric: tabular-nums;
  color: #fff;
  white-space: nowrap;
}

/* Сумма и прогноз в одной строке; полоса ниже — остаток со светофором. */
.hd-split { display: flex; align-items: flex-end; justify-content: space-between; gap: 0.9rem; }
.hd-split .big { font-size: clamp(1.7rem, 6vw, 2.4rem); white-space: nowrap; }
/* Подпись сверху, дата снизу — читается одной фразой: «хватит до 07.09». */
.hd-days { text-align: right; flex: none; }
.hd-days .n { display: block; margin-top: 0.25rem; font: 500 1.35rem/1 'JetBrains', monospace; color: #6fc3a3; }
.hd-days .c {
  display: block; color: #9aa3b2;
  font: 400 0.6rem/1.3 'JetBrains', monospace; letter-spacing: 0.06em; text-transform: uppercase;
}

.hd-scale { margin-top: 1.1rem; }
.hd-track { height: 8px; border-radius: 5px; background: #1c2731; overflow: hidden; }
.hd-track i { display: block; height: 100%; border-radius: 5px; }
/* Три равные трети шкалы: зелёная, жёлтая, красная. Тона светлее кабинетных —
   --volt и --coral на тёмном фоне глохнут (та же история, что была у .spark). */
.hd-track i.zone-high { background: #6fc3a3; }
.hd-track i.zone-mid { background: #e0a44a; }
.hd-track i.zone-low { background: #e0685e; }
.hd-scale-cap {
  display: flex; justify-content: space-between; gap: 0.6rem; margin-top: 0.45rem;
  font: 400 0.62rem/1 'JetBrains', monospace; color: #9aa3b2;
  letter-spacing: 0.05em; text-transform: uppercase;
}

/* Плитка показателя */
.k { font-size: 0.8rem; color: var(--muted); }
.v {
  font-family: 'JetBrains', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: 1.6rem;
  letter-spacing: -0.035em;
  margin-top: 0.4rem;
}

/* ---------------------------------------------------------------- формы */

.field { margin-bottom: 0.9rem; }
.field label { display: block; font-size: 0.83rem; color: var(--muted); margin-bottom: 0.3rem; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], select {
  width: 100%;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #fafbfc;
  color: var(--ink);
  font: 400 1rem 'Golos', sans-serif;
}

input:focus-visible, select:focus-visible { outline: 2px solid var(--volt); outline-offset: -1px; }

.sum-input { font: 500 1.4rem 'JetBrains', monospace; letter-spacing: -0.03em; }

.field-row, .row-form { display: flex; gap: 0.7rem; flex-wrap: wrap; align-items: flex-end; }
.row-form .field { margin-bottom: 0; }
.grow { flex: 1 1 180px; }
/* Селектор с именем тега — иначе правило input[type=...] { width:100% } перебивает класс. */
input.w-full, .w-full { width: 100%; }
input.w-num, .w-num { width: 96px; }

.actions { display: flex; gap: 0.6rem; margin-top: 1.1rem; flex-wrap: wrap; }

.btn {
  padding: 0.75rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--ink);
  font: 500 0.95rem 'Onest', sans-serif;
  cursor: pointer;
}

.btn:hover { border-color: var(--ink); }

.btn-primary {
  background: var(--volt);
  border-color: var(--volt);
  color: #fff;
  font-weight: 600;
}

.btn-primary:hover { background: var(--volt-dark); border-color: var(--volt-dark); }

.link-btn {
  border: 0; background: none; color: var(--muted);
  cursor: pointer; font: inherit; padding: 2px 6px; border-radius: 6px;
}
.link-btn:hover { color: var(--coral); background: #fdeeeb; }

/* ------------------------------ «Корзины» (страница): ведомость, вариант 1.
   Имя .bucket-row занято плиткой обзора — здесь свой префикс .bucket-edit.
   Подписи «перенос» и «архив» стоят в шапке столбцов и печатаются один раз,
   строка — один этаж. На десктопе две колонки, на телефоне одна. */

.bucket-head {
  display: grid;
  grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
  column-gap: 2.2rem;
  margin-top: 0.9rem;
}
.bucket-head-set {
  display: grid;
  grid-template-columns: 1fr 5.5rem 5.5rem 4.4rem;
  gap: 0.5rem;
  padding: 0 0.5rem 0.5rem;
  font: 400 0.64rem/1 'JetBrains', monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.bucket-head-set span:not(:first-child) { text-align: center; }

/* Колонки заполняются сверху вниз (1…5 слева, 6…9 справа) — порядок читается
   как список, а не змейкой; высоту колонки задаёт --rows из шаблона. */
.bucket-list {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
  grid-template-rows: repeat(var(--rows, 1), auto);
  column-gap: 2.2rem;
}

.bucket-edit {
  display: grid;
  grid-template-columns: 1fr 5.5rem 5.5rem 4.4rem;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.5rem;
  padding: 0.28rem 0.5rem;
  border-top: 1px solid var(--line);
}
.bucket-edit:hover { background: #fafbfc; }

.bucket-name { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.bucket-dot { width: 10px; height: 10px; border-radius: 4px; flex: none; }

/* Селектор с именем тега — иначе общее правило input[type=text] вернёт рамку и фон. */
input.bucket-title {
  border-color: transparent;
  background: transparent;
  border-radius: 9px;
  padding: 0.35rem 0.5rem;
  font: 400 0.98rem 'Golos', sans-serif;
}
input.bucket-title:hover { border-color: var(--line); background: #fafbfc; }
input.bucket-title:focus-visible { background: #fafbfc; }

.bucket-cell { display: flex; justify-content: center; }
/* Тумблер в ведомости мельче общего: строка держится на высоте 40px. */
.bucket-edit .switch .tr { width: 32px; height: 18px; }
.bucket-edit .switch .tr::after { width: 14px; height: 14px; margin: 2px; }
.bucket-edit .switch input:checked + .tr::after { transform: translateX(14px); }
.bucket-edit .updown { justify-content: flex-end; }
.bucket-edit .updown button { width: 28px; height: 28px; font-size: 0.8rem; }

@media (max-width: 620px) {
  /* Одна колонка, подписи возвращаются к тумблерам, кнопки — снова под палец. */
  .bucket-head { display: none; }
  .bucket-list { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
  .bucket-edit { grid-template-columns: auto auto 1fr; gap: 0.35rem 0.9rem; padding: 0.55rem 0.5rem; }
  .bucket-name { grid-column: 1 / -1; }
  .bucket-cell { justify-content: flex-start; }
  .bucket-cell::after { content: attr(data-label); font-size: 0.78rem; color: var(--muted); margin-left: 0.45rem; }
  .bucket-edit .updown { justify-self: end; }
  .bucket-edit .updown button { width: 34px; height: 34px; }
}

/* Тумблер: настоящий чекбокс прозрачен поверх нарисованного переключателя. */
.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; cursor: pointer; margin: 0; }
.switch .tr { width: 40px; height: 24px; border-radius: 999px; background: #d5dce2; transition: background .15s; flex: none; }
.switch .tr::after {
  content: ''; display: block; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; margin: 3px; transition: transform .15s;
  box-shadow: 0 1px 2px rgba(13,19,24,.25);
}
.switch input:checked + .tr { background: var(--volt); }
.switch input:checked + .tr::after { transform: translateX(16px); }
.switch input:focus-visible + .tr { outline: 2px solid var(--volt); outline-offset: 2px; }
/* Тумблер с подписью вне списка корзин — «Настройки». */
.lbl-switch { display: flex; align-items: center; gap: 0.45rem; font-size: 0.85rem; color: var(--muted); }

.updown { display: inline-flex; gap: 4px; }
.updown button {
  width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--card); color: var(--ink); cursor: pointer; font-size: 0.9rem; line-height: 1;
}
.updown button:hover { border-color: var(--ink); }

/* ---------------------------------------------------------------- таблицы */

.tbl { width: 100%; border-collapse: collapse; font-size: 0.94rem; }
.tbl th, .tbl td { padding: 0.62rem 0.6rem; border-bottom: 1px solid var(--line); text-align: left; }
/* Выравнивание по классу должно перебивать общее правило ячеек таблицы. */
.tbl th.c, .tbl td.c { text-align: center; }
.tbl th.r, .tbl td.r { text-align: right; }
.tbl th:first-child, .tbl td:first-child { padding-left: 0; }
.tbl th:last-child, .tbl td:last-child { padding-right: 0; }
.tbl thead th {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); font-weight: 600;
}
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tfoot th { border-top: 1px solid var(--line); border-bottom: 0; padding-top: 0.8rem; }
.tbl .r, .tbl .num { font-family: 'JetBrains', monospace; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- правила квитанцией

   Правила показаны чеком: сверху пришло, ниже построчно куда разошлось, внизу
   двойная черта и равенство «разложено = пришло». Поля внутри строки намеренно
   без рамок-«кирпичей» — строка должна читаться, а не заполняться.
   Форма ленты взята из макета «Квитанция», цвета — кабинетные. */

.rules-head { margin: 0.5rem 0 1.1rem; }
.rules-head h1 { margin-bottom: 0.35rem; }
.rules-head p { margin: 0; max-width: 62ch; }

.rules-lay {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 18px;
  align-items: start;
}

@media (max-width: 940px) { .rules-lay { grid-template-columns: minmax(0, 1fr); } }

.rules-side .card { margin-bottom: 14px; }
.rules-side .card:last-child { margin-bottom: 0; }

/* ---- лента ---- */

.receipt {
  position: relative;
  background: var(--card);
  padding: 2rem clamp(1rem, 3vw, 2rem) 2.4rem;
  box-shadow: var(--shadow);
  --tooth: 11px;
  /* Слои маски складываются, поэтому у каждого своя высота: сплошной слой
     середины иначе перекрыл бы вырезы и зубцов не было бы видно. */
  -webkit-mask:
    radial-gradient(circle var(--tooth) at 50% 0, #0000 98%, #000) 50% 0 / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    radial-gradient(circle var(--tooth) at 50% 100%, #0000 98%, #000) 50% 100% / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    linear-gradient(#000, #000) 50% 50% / 100% calc(100% - var(--tooth) * 2) no-repeat;
  mask:
    radial-gradient(circle var(--tooth) at 50% 0, #0000 98%, #000) 50% 0 / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    radial-gradient(circle var(--tooth) at 50% 100%, #0000 98%, #000) 50% 100% / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    linear-gradient(#000, #000) 50% 50% / 100% calc(100% - var(--tooth) * 2) no-repeat;
}

.r-head { text-align: center; margin-bottom: 1.3rem; }

.r-kind {
  display: block;
  font-family: 'JetBrains', monospace;
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

input.r-name {
  width: 100%;
  margin-top: 0.35rem;
  text-align: center;
  border-color: transparent;
  background: transparent;
  font: 700 1.15rem 'Onest', sans-serif;
  letter-spacing: -0.02em;
  padding: 0.3rem 0.5rem;
}

input.r-name:hover { border-color: var(--line); background: #fafbfc; }
input.r-name:focus-visible { background: #fafbfc; }

.r-gross {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.7rem 0;
  border-top: 1px solid var(--ink);
  border-bottom: 1px dashed var(--line);
  margin-bottom: 1.2rem;
}

.r-gross label { font-size: 0.86rem; color: var(--muted); margin-right: auto; }

.r-gross input {
  width: 165px;
  text-align: right;
  border-color: transparent;
  background: transparent;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  font: 600 1.25rem 'JetBrains', monospace;
  font-variant-numeric: tabular-nums;
  padding: 0.1rem 0.3rem;
}

.r-gross input:hover { background: #fafbfc; }
.r-unit { font-size: 0.84rem; color: var(--muted); }

.r-sect { margin-bottom: 1.2rem; }

.r-band {
  font-family: 'JetBrains', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.4rem;
}

.r-rest {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0.6rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--line);
  font-size: 0.87rem;
  color: var(--muted);
}

.r-rest b { margin-left: auto; color: var(--ink); }

.r-total {
  display: flex;
  align-items: baseline;
  margin: 1.3rem 0 0;
  padding-top: 0.7rem;
  border-top: 3px double var(--ink);
}

.r-total span {
  font-family: 'JetBrains', monospace;
  font-size: 0.76rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.r-total b { margin-left: auto; font-size: 1.15rem; font-weight: 700; }
.r-total.bad b { color: var(--coral); }

.r-fine { margin: 1.1rem 0 0; font-size: 0.84rem; color: var(--muted); }

.r-fine select {
  width: auto;
  padding: 0.25rem 1.5rem 0.25rem 0.4rem;
  font-size: 0.84rem;
  border-radius: 8px;
}

/* Штамп: правки есть, но ещё не записаны. */
.stamp {
  position: absolute;
  right: clamp(0.6rem, 3vw, 1.6rem);
  top: 3.4rem;
  transform: rotate(-11deg) scale(0.94);
  border: 2.5px solid var(--coral);
  color: var(--coral);
  border-radius: 8px;
  padding: 0.22rem 0.55rem;
  font: 700 0.74rem 'JetBrains', monospace;
  letter-spacing: 0.14em;
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: none;
}

.receipt.dirty .stamp { opacity: .85; transform: rotate(-11deg) scale(1); }

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

/* ---- строка квитанции ---- */

.rule {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  padding: 0.45rem 0;
  font-size: 0.94rem;
}

.rule-off { opacity: .5; }

.rule-on { display: inline-flex; align-items: center; position: relative; flex: none; }
.rule-on input { position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0; }

/* Пин цвета корзины он же переключатель ступени: погасший пин = ступень выключена. */
.rule-on .pin {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--pin, var(--muted));
  box-shadow: 0 0 0 3px transparent;
}

.rule-on input:not(:checked) + .pin { background: none; box-shadow: inset 0 0 0 1.5px var(--line); }
.rule-on input:focus-visible + .pin { box-shadow: 0 0 0 3px #d7e8e1; }

.rule-arrow { color: var(--muted); }

.rule input.rule-num {
  width: 58px;
  padding: 0.25rem 0.4rem;
  text-align: right;
  font: 500 0.92rem 'JetBrains', monospace;
  border-color: transparent;
  background: #eef1f4;
  border-radius: 7px;
}

.rule input.rule-num:hover { border-color: var(--line); }
.rule input.rule-fixed { width: 104px; }

.rule select.rule-base,
.rule select.rule-bucket {
  width: auto;
  max-width: 100%;
  padding: 0.25rem 1.15rem 0.25rem 0.35rem;
  font-size: 0.9rem;
  border-color: transparent;
  background-color: transparent;
  border-radius: 7px;
  /* Своя стрелка вместо нативной: та рисуется поверх текста и съедает
     последнюю букву, сколько бы ширины список ни получил. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.35rem center;
  background-size: 9px 6px;
}

.rule select.rule-base:hover,
.rule select.rule-bucket:hover { border-color: var(--line); background-color: #fafbfc; }

.rule input.rule-newbucket {
  width: 150px;
  padding: 0.25rem 0.45rem;
  font-size: 0.88rem;
  border-radius: 7px;
}

/* Выноска точками — глаз ведут от ступени к сумме, как в бумажном чеке. */
.rule-dots {
  flex: 1 1 40px;
  min-width: 20px;
  border-bottom: 1px dotted #c9ced2;
  transform: translateY(-3px);
}

.rule-res {
  font-family: 'JetBrains', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  white-space: nowrap;
}

/* Название ступени — подпись под строкой: в истории нужно, в чтении чека мешает. */
.rule input.rule-title {
  flex: 1 1 100%;
  order: 9;
  margin-left: 1.1rem;
  padding: 0.15rem 0.4rem;
  font-size: 0.82rem;
  color: var(--muted);
  background: transparent;
  border-color: transparent;
  border-radius: 7px;
}

.rule input.rule-title:hover { border-color: var(--line); background: #fafbfc; }
.rule input.rule-title:focus-visible { color: var(--ink); background: #fafbfc; }

.rule-sum { margin: 0.7rem 0 0; font-size: 0.85rem; color: var(--muted); text-align: center; }
.rule-sum.ok { color: var(--mint); }
.rule-sum.bad { color: var(--coral); }

/* Дельта к сохранённому плану: без неё непонятно, стало больше или меньше. */
.rule-delta {
  font-family: 'JetBrains', monospace;
  font-size: 0.78rem;
  font-weight: 500;
  padding: 0.05rem 0.3rem;
  border-radius: 6px;
}

.rule-delta.up { color: #05614a; background: #e7f8f2; }
.rule-delta.down { color: #a3341f; background: #fdeeeb; }

.rule-off-mark { color: var(--muted); font-size: 0.85rem; font-family: 'Onest', sans-serif; }

/* Короткая вспышка, чтобы взгляд поймал изменившееся число. */
@keyframes rule-flash {
  from { background: #d7e8e1; }
  to { background: transparent; }
}

.rule-flash { animation: rule-flash .6s ease-out; border-radius: 7px; }

@media (prefers-reduced-motion: reduce) {
  .rule-flash { animation: none; }
}

/* Сводка «что изменится, если сохранить» */
.diff {
  background: #eef5f2;
  border: 1px solid #d3e4dc;
  border-radius: var(--r-sm);
  padding: 0.95rem 1.1rem;
  margin-bottom: 1.3rem;
}

.diff-head { font-size: 0.86rem; color: var(--muted); margin-bottom: 0.6rem; }

.diff-list { display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; font-size: 0.92rem; }

.diff-item b {
  font-family: 'JetBrains', monospace;
  font-weight: 500;
  margin-left: 0.25rem;
}

.diff-item b.up { color: #05614a; }
.diff-item b.down { color: #a3341f; }

.diff-reset { margin-top: 0.7rem; color: var(--volt); }
.diff-reset:hover { color: var(--volt-dark); background: transparent; }

@media (max-width: 620px) {
  .rule { gap: 0.4rem 0.35rem; }
  .rule-dots { flex-basis: 100%; display: none; }
  .rule-res { margin-left: auto; }
  .rule input.rule-title { margin-left: 0; }
}
.tbl-alloc { margin-top: 1.1rem; }
.leftover th { color: var(--amber); }
.plus { color: var(--mint); }

/* ---------------------------------------------------------------- корзины */

.bucket-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.35rem 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
}
.bucket-row:last-child { border-bottom: 0; padding-bottom: 0; }
.bucket-row .name { display: flex; align-items: center; gap: 0.55rem; font-size: 0.95rem; }
.bucket-row .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.bucket-row .left {
  text-align: right; font-family: 'JetBrains', monospace;
  font-variant-numeric: tabular-nums; font-weight: 500;
}
.bucket-row .track {
  grid-column: 1 / -1; height: 5px; border-radius: 3px; background: #edf1f4; overflow: hidden;
}
.bucket-row .track i { display: block; height: 100%; border-radius: 3px; }
.bucket-row .meta {
  grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 1rem;
  font-family: 'JetBrains', monospace; font-size: 0.76rem; color: var(--muted);
}

/* Полоса раскладки поступления */
/* Полоса долей внутри чека раскладки. */
.split-bar { display: flex; gap: 3px; height: 28px; border-radius: 8px; overflow: hidden; margin: 0.2rem 0 0.75rem; }
.split-bar i {
  display: grid; place-items: center; color: #fff;
  font: 500 0.74rem 'JetBrains', monospace; min-width: 0;
}
/* ---------------------------------------------------------------- прочее */

.flash {
  padding: 0.85rem 1.15rem; border-radius: var(--r-sm); margin-bottom: 14px;
  background: #e7f8f2; color: #05614a; font-size: 0.95rem;
}
.flash-err { background: #fdeeeb; color: #a3341f; }
.flash ul { margin: 0.4rem 0 0; padding-left: 1.1rem; }

/* Полоса-напоминание: тише ошибки, заметнее обычного текста. */
.flash-note {
  background: #fff8e6;
  border-color: #f3dfa8;
  color: #6b5514;
}

/* Кнопка внутри текста, выглядящая ссылкой: форма нужна из-за CSRF-токена. */
.linklike {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.warn {
  color: #8a5a06; background: #fdf4e3; padding: 0.7rem 1rem;
  border-radius: var(--r-sm); font-size: 0.86rem; margin-top: 0.8rem;
}
.warn-dot { color: var(--amber); }

.stats { display: flex; gap: 1.8rem; flex-wrap: wrap; margin-top: 1.2rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.stat { display: flex; flex-direction: column; }
.stat-label { font-size: 0.78rem; color: var(--muted); }
.stat-value { font-family: 'JetBrains', monospace; font-size: 1.1rem; font-weight: 500; letter-spacing: -0.02em; }

/* Готовые схемы — набор бланков: выбор одним нажатием, без списка карточек. */
.blanks { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 1rem 0 0.4rem; }

.blank {
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 999px;
  padding: 0.4rem 0.85rem;
  font: 500 0.87rem 'Onest', sans-serif;
  color: var(--ink);
  cursor: pointer;
}

.blank:hover { border-color: var(--ink); }
.blank[aria-current="true"] { background: var(--ink); border-color: var(--ink); color: #fff; }

.dl { display: grid; grid-template-columns: minmax(140px, auto) minmax(0, 1fr); gap: 0.5rem 1.4rem; margin: 0; }
.dl dt { font-weight: 600; }
/* minmax(0,1fr) + перенос: длинная почта не распирает сетку за край карточки. */
.dl dd { margin: 0; overflow-wrap: anywhere; }
/* На узком экране список складывается в стопку: подпись мелкая сверху, значение
   целиком под ней — почта помещается в одну строку (выбор Александра, вариант A). */
@media (max-width: 620px) {
  .dl { grid-template-columns: 1fr; gap: 0; }
  .dl dt { font-weight: 500; font-size: 0.83rem; color: var(--muted); margin-bottom: 0.15rem; }
  .dl dd { margin-bottom: 1rem; }
  .dl dd:last-child { margin-bottom: 0; }
}

/* Чек-атом .cheque* живёт в tokens.css — общий для кабинета, витрины и блога. */

.code-line code {
  background: #edf1f4; padding: 0.5rem 0.85rem; border-radius: 8px;
  display: inline-block; font-family: 'JetBrains', monospace;
}

/* ---------------------------------------------------------------- привязка Telegram

   Блок объясняет две вещи, которых раньше на странице не было: какому боту писать
   и что он умеет. Второе показано куском переписки, а не списком команд, — так
   понятно ещё до привязки.                                                        */

.bot-row {
  display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap;
  padding: 0.85rem 1rem; margin-bottom: 1rem;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: #fafbfc;
}

.bot-ava {
  width: 42px; height: 42px; border-radius: 12px; flex: none;
  display: grid; place-items: center; background: #29a9ea; color: #fff;
}

.bot-id { display: flex; flex-direction: column; margin-right: auto; }
.bot-name { font-weight: 600; }
.bot-sub { color: var(--muted); font-size: 0.85rem; }

.btn-tg {
  display: inline-flex; align-items: center; gap: 0.5rem; white-space: nowrap;
  padding: 0.75rem 1.35rem; border: 1px solid var(--volt); border-radius: var(--r-sm);
  background: var(--volt); color: #fff; text-decoration: none;
  font: 600 0.95rem 'Onest', sans-serif;
}

.btn-tg:hover { background: var(--volt-dark); border-color: var(--volt-dark); }

.btn-ghost {
  display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap;
  padding: 0.55rem 0.9rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink); text-decoration: none;
  font: 500 0.88rem 'Onest', sans-serif; cursor: pointer;
}

.btn-ghost:hover { border-color: var(--ink); }

.linked-badge {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.35rem 0.8rem; border-radius: 999px;
  background: #e6f6f0; color: #0a7d5c; font-size: 0.88rem;
}

.fallback {
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
  color: var(--muted); font-size: 0.87rem;
}

.fallback code, .chat-note code {
  background: #edf1f4; padding: 0.2rem 0.45rem; border-radius: 6px;
  color: var(--ink); font-family: 'JetBrains', monospace; font-size: 0.85em;
}

.chat {
  display: grid; gap: 0.5rem; padding: 0.9rem;
  background: #e7ecf1; border-radius: var(--r-sm); font-size: 0.88rem;
}

.msg { max-width: 82%; margin: 0; padding: 0.5rem 0.75rem; border-radius: 14px; line-height: 1.4; }
.msg.me { justify-self: end; background: var(--volt); color: #fff; border-bottom-right-radius: 5px; }
.msg.bot { justify-self: start; background: var(--card); border-bottom-left-radius: 5px; }

.chat-btns { display: flex; gap: 0.35rem; flex-wrap: wrap; margin-top: 0.4rem; }
.chat-btns span { background: #eaeef2; border-radius: 8px; padding: 0.28rem 0.55rem; font-size: 0.8rem; }

.chat-note { margin-top: 0.8rem; color: var(--muted); font-size: 0.87rem; }

.mono { font-family: 'JetBrains', monospace; }

.foot { padding: 1.5rem; text-align: center; color: var(--muted); font-size: 0.86rem; }

.calc-busy { opacity: .5; }

/* Подсказки «почему так»: свёрнуты по умолчанию, чтобы не шуметь на странице правил. */
.why { margin: 0.7rem 0 0; }
.why summary { cursor: pointer; color: var(--muted); font-size: 0.88rem; list-style: none; }
.why summary::-webkit-details-marker { display: none; }
.why summary::before { content: '?'; display: inline-grid; place-items: center; width: 16px; height: 16px; margin-right: 0.45rem; border-radius: 50%; background: var(--muted); color: #fff; font-size: 0.62rem; vertical-align: -2px; }
.why[open] summary { margin-bottom: 0.5rem; }
.why p { margin: 0; max-width: 60ch; color: var(--muted); font-size: 0.88rem; }

:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ------------------------------------------- развороты-селекты (единый стиль)
   Нативный select скрыт, но остаётся в форме; разметку строит app.js. */

.dd-hidden { display: none; }
.dd { position: relative; }

.dd summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 0.62rem 0.85rem; background: #fafbfc; font-weight: 500;
}

.dd summary::-webkit-details-marker { display: none; }
.dd summary:focus-visible { outline: 2px solid var(--volt); outline-offset: -1px; }
.dd summary .arr { color: var(--muted); }
.dd[open] summary { border-color: var(--volt); }

.dd-menu {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 30;
  width: max-content; min-width: 100%; max-width: min(340px, 90vw);
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 14px 30px -18px rgba(13, 19, 24, .4);
  padding: 0.4rem; display: grid; gap: 2px;
  max-height: 60vh; overflow: auto;
}

.dd-menu button {
  display: flex; align-items: center; gap: 0.6rem;
  border: 0; background: none; border-radius: 10px; padding: 0.55rem 0.7rem;
  cursor: pointer; text-align: left;
  font: 500 0.92rem 'Golos', sans-serif; color: var(--ink);
}

.dd-menu button:hover { background: var(--volt-soft); }
.dd-menu button.on { background: var(--volt); color: #fff; }
.dd-menu button.accent { color: var(--volt); font-weight: 600; border-top: 1px dashed var(--line); border-radius: 0 0 10px 10px; margin-top: 2px; }
.dd-menu .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.dd-menu .f { margin-left: auto; font: 400 0.72rem 'JetBrains', monospace; color: var(--muted); white-space: nowrap; padding-left: 0.6rem; }
.dd-menu button.on .f { color: rgba(255, 255, 255, .75); }

/* В строке-фразе «Правил» разворот — слово с пунктиром, не кнопка. */
.dd-inline { display: inline-block; vertical-align: baseline; }
.dd-inline summary {
  border: 0; background: none; padding: 0.1rem 0.15rem; border-radius: 7px;
  font-size: 0.9rem; font-weight: 500; color: var(--volt);
  display: inline-flex; gap: 0.3rem;
}
.dd-inline summary .dd-cur { border-bottom: 1px dashed var(--volt); }
.dd-inline .dd-menu { min-width: 0; max-width: min(320px, 86vw); }

/* --------------------------------------------- «Долги»: ведомость и прогрессия.
   Строка того же строя, что на «Корзинах», но вместо тумблеров — цифры,
   а полоса под строкой тает: заполнение = сколько ОСТАЛОСЬ выплатить. */

.debt-x { max-width: 430px; margin: 1.2rem auto 1.6rem; }

.debt-head, .debt-row {
  display: grid;
  grid-template-columns: 1fr 9rem 8rem 5rem;
  align-items: center;
  gap: 0.5rem;
}
.debt-head {
  font: 400 0.64rem/1 'JetBrains', monospace;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
  padding: 0 0.5rem 0.5rem;
}
.debt-head span:not(:first-child) { text-align: right; }

/* Строка — это summary: нажатие раскрывает под ней панель правки. */
.debt-item { border-top: 1px solid var(--line); }
.debt-item > summary { list-style: none; cursor: pointer; }
.debt-item > summary::-webkit-details-marker { display: none; }
.debt-item > summary:focus-visible { outline: 2px solid var(--volt); outline-offset: -2px; border-radius: 10px; }

.debt-row { padding: 0.5rem; }
.debt-row:hover { background: #fafbfc; }
.debt-item[open] > .debt-row { background: #fafbfc; }
/* Карандаш проявляется на строке, а у раскрытой становится крестиком-намёком. */
.debt-pen { margin-left: 0.45rem; color: var(--line); font-size: 0.8rem; }
.debt-item > summary:hover .debt-pen { color: var(--muted); }
.debt-item[open] .debt-pen { color: var(--volt); }

.debt-edit { padding: 0.2rem 0.5rem 1.1rem; }
.debt-edit .actions { margin-top: 0.9rem; align-items: center; }
.debt-name { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.debt-dot { width: 10px; height: 10px; border-radius: 4px; flex: none; }
.debt-title { display: grid; gap: 0.1rem; min-width: 0; }
.debt-title b { font-weight: 400; }
.debt-title small { color: var(--muted); font-size: 0.74rem; }
.debt-num {
  text-align: right; font: 400 0.95rem 'JetBrains', monospace; font-variant-numeric: tabular-nums;
}
.debt-num small { display: block; color: var(--muted); font-size: 0.7rem; font-family: 'Golos', sans-serif; }
.debt-when { text-align: right; font: 400 0.85rem 'JetBrains', monospace; color: var(--muted); }
.debt-bar { grid-column: 1 / -1; height: 6px; border-radius: 4px; background: #edf0f3; overflow: hidden; margin-top: 0.2rem; }
.debt-bar i { display: block; height: 100%; border-radius: 4px; }

.debt-closed { margin-top: 1rem; font-size: 0.9rem; }
.debt-closed summary { cursor: pointer; color: var(--muted); }
.debt-closed-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.4rem 0.5rem; color: var(--muted); }

.debt-edit-tools { display: flex; align-items: center; gap: 0.9rem; margin-top: 1.1rem; }

/* График прогрессии. Одна серия — легенды нет, её называет заголовок. */
.debt-chart { margin: 1.6rem 0 0; }
.debt-chart figcaption {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.7rem; margin-bottom: 0.4rem;
}
.debt-chart figcaption b { font-weight: 500; }
.debt-chart figcaption span { font: 400 0.72rem 'JetBrains', monospace; color: var(--muted); }
.debt-chart svg { display: block; width: 100%; height: auto; }
.dc-grid { stroke: #e6eaee; stroke-width: 1; }
.dc-axis { fill: #8a97a3; font: 400 10px 'JetBrains', monospace; }
.dc-fact { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dc-plan { fill: none; stroke-width: 2; stroke-dasharray: 3 5; opacity: .5; stroke-linecap: round; }
.dc-dot { fill: var(--dc); stroke: #fff; stroke-width: 2; }
.dc-dot-plan { fill: #fff; stroke: var(--dc); }

@media (max-width: 620px) {
  /* Шрифт в единицах viewBox: на узком экране 10px превращались в нечитаемые пять. */
  .dc-axis { font-size: 15px; }
  .debt-head { display: none; }
  .debt-row { grid-template-columns: 1fr auto; gap: 0.3rem 0.8rem; }
  .debt-edit .field-row { gap: 0.5rem; }
  .debt-name { grid-column: 1 / -1; }
  .debt-num { text-align: left; }
  .debt-num:last-of-type { text-align: right; }
  .debt-when { grid-column: 2; }
}

/* Плитка долгов на «Обзоре»: те же цифры, что на странице, только короче. */
.debt-tile .v { margin: 0.5rem 0 0; }
.debt-tile .debt-bar { margin-top: 0.9rem; height: 8px; }
.debt-tile-cap {
  display: flex; justify-content: space-between; gap: 0.6rem; margin-top: 0.45rem;
  font: 400 0.62rem/1 'JetBrains', monospace; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted);
}

/* ------------------------------------ Разворот «Настройки» в шапке кабинета.
   Ежедневное (Обзор, Поступления, Траты) осталось пилюлями, редкое — здесь.
   Живёт внутри .nav, поэтому на телефоне его скрывает то же правило, а роль
   меню играет «Ещё» в нижней панели. */

.nav-dd { position: relative; }
.nav-dd > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.45rem 0.9rem; border-radius: 999px;
  color: var(--muted); font-size: 0.93rem;
}
.nav-dd > summary::-webkit-details-marker { display: none; }
.nav-dd > summary:hover { background: #e7ecf1; color: var(--ink); }
.nav-dd > summary:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }
.nav-dd > summary svg {
  width: 17px; height: 17px; stroke: currentColor; fill: none;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.nav-dd > summary .arr { font-size: 0.7rem; }
/* Открытый разворот и активный раздел внутри него подсвечены одинаково —
   человек видит, что нужная страница «лежит» здесь. */
.nav-dd.on > summary, .nav-dd[open] > summary { background: var(--ink); color: #fff; }

.nav-dd-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 40;
  width: max-content; min-width: 17rem; max-width: min(22rem, 90vw);
  background: var(--card); border-radius: 16px; padding: 0.5rem;
  box-shadow: 0 1px 2px rgba(13, 19, 24, .06), 0 22px 44px -20px rgba(13, 19, 24, .5);
  display: grid; gap: 2px;
}

/* Селектор с .nav — иначе общее правило .nav a вернёт пилюлю. */
.nav .nav-dd-menu a {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.55rem 0.7rem; border-radius: 12px;
  color: var(--ink); text-decoration: none; font-size: 1rem;
}
.nav .nav-dd-menu a:hover { background: var(--volt-soft); }
.nav .nav-dd-menu a.on { background: var(--volt-soft); }
.nav-dd-menu .i svg {
  width: 22px; height: 22px; stroke: var(--volt); fill: none;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.nav-dd-menu .i { display: flex; padding-top: 2px; }
.nav-dd-menu b { display: block; font: 700 0.98rem 'Onest', sans-serif; letter-spacing: -0.01em; }
.nav-dd-menu small { color: var(--muted); font-size: 0.82rem; }
.nav-dd-menu .sep { height: 1px; background: var(--line); margin: 0.35rem 0.5rem; }

/* ------------------------------ Админка «/admin»: таблица пользователей —
   «Сетка» (выбор Александра из пяти показанных вариантов, site/preview/admin-table-*.html):
   видимые границы каждой ячейки, узкая строка, даты моно-шрифтом, клик по
   заголовку сортирует (JS — app.js, блок «Сортировка таблиц по клику на шапку»).
   Обёртка со своим скроллом — таблица не должна распирать страницу на телефоне. */
.admin-table-wrap { overflow-x: auto; margin-top: 0.8rem; border-radius: 10px; border: 1px solid var(--line); }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; background: var(--card); }
.admin-table th {
  text-align: left; font: 600 0.7rem 'JetBrains', monospace; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); padding: 0.45rem 0.65rem; border: 1px solid var(--line); background: #f6f7f8;
  white-space: nowrap;
}
.admin-table th[data-key] { cursor: pointer; user-select: none; }
.admin-table th[data-key]:hover { color: var(--ink); background: #eef1f3; }
.admin-table th .arrow { display: inline-block; width: 0.8em; opacity: 0.5; }
.admin-table th[data-dir="asc"] .arrow::after { content: '▲'; }
.admin-table th[data-dir="desc"] .arrow::after { content: '▼'; }
.admin-table th[data-dir] { color: var(--ink); background: #e9edf0; }
.admin-table th[data-dir] .arrow { opacity: 1; color: var(--volt); }
.admin-table td {
  padding: 0.3rem 0.65rem; border: 1px solid var(--line);
  text-align: left; white-space: nowrap; vertical-align: middle;
}
.admin-table tbody tr:hover td { background: #fafbfc; }
.admin-table .mono { font-family: 'JetBrains', monospace; font-size: 0.8rem; color: var(--muted); }
.admin-table .badge { display: inline-block; font-size: 0.72rem; padding: 0.06rem 0.45rem; border-radius: 4px; font-weight: 600; }
.admin-table .badge.role-user { background: #eef1f3; color: var(--muted); }
.admin-table .badge.role-admin { background: var(--volt-soft); color: var(--volt); }
.admin-table .badge.status-active { background: var(--volt-soft); color: var(--volt); }
.admin-table .badge.status-blocked { background: #fdeeeb; color: var(--coral); }
.admin-actions { display: flex; gap: 0.3rem; align-items: center; }
.admin-btn {
  padding: 0.12rem 0.45rem; border: 1px solid var(--line); border-radius: 6px;
  background: var(--card); color: var(--ink); font: 500 0.71rem 'Golos', sans-serif;
  cursor: pointer; white-space: nowrap;
}
.admin-btn:hover { border-color: var(--ink); }
.admin-btn.danger { border-color: var(--coral); color: var(--coral); background: #fdeeeb; }
.admin-btn.danger:hover { background: var(--coral); color: #fff; }
.admin-btn.confirm { border-color: var(--volt); color: var(--volt); background: var(--volt-soft); }
.admin-btn.confirm:hover { background: var(--volt); color: #fff; }
.budget-icon { width: 19px; height: 19px; display: block; }
.budget-icon path, .budget-icon circle { fill: none; stroke: var(--muted); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.budget-icon.shared { width: 26px; }

.channel-icon { width: 19px; height: 19px; display: block; }
.channel-icon path { fill: none; stroke: var(--muted); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.channel-icon.on path { stroke: var(--volt); }

/* ------------------------------ Сводка «Регистрации» — плитки + полосы
   (выбор Александра из пяти показанных вариантов, site/preview/admin-summary-*.html).
   Плитки и блок источников на паре var(--paper) — карточка вокруг уже белая
   (var(--card)), без этого контраста плитки слились бы с фоном. */
.admin-summary { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.1fr); gap: 12px; margin-top: 0.9rem; }
@media (max-width: 800px) { .admin-summary { grid-template-columns: minmax(0,1fr); } }
.admin-metrics { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 10px; }
.admin-metric { background: var(--paper); border-radius: 14px; padding: 1rem 1.1rem; }
.admin-metric .n { font: 700 1.9rem/1 'JetBrains', monospace; letter-spacing: -0.02em; }
.admin-metric .l { color: var(--muted); font-size: 0.8rem; margin-top: 0.4rem; }
.admin-metric.hi .n { color: var(--volt); }
.admin-sources { background: var(--paper); border-radius: 14px; padding: 1rem 1.2rem; }
.admin-sources h2 { font-size: 0.9rem; margin: 0 0 0.8rem; color: var(--muted); font-weight: 600; }
.admin-bar-row { display: flex; justify-content: space-between; gap: 0.6rem; font-size: 0.87rem; margin-bottom: 0.2rem; }
.admin-bar-row b { font-family: 'JetBrains'; font-weight: 600; }
.admin-bar-track { height: 6px; border-radius: 4px; background: #e7eaec; overflow: hidden; margin-bottom: 0.6rem; }
.admin-bar-track:last-child { margin-bottom: 0; }
.admin-bar-fill { height: 100%; border-radius: 4px; }
.admin-pages { display: flex; gap: 0.4rem; margin-top: 0.8rem; }
.admin-pages a { color: var(--muted); text-decoration: none; padding: 2px 6px; border-radius: 6px; }
.admin-pages a.on { background: var(--volt-soft); color: var(--volt); font-weight: 600; }

/* Блок с QR на странице приложения: код и подпись рядом, на узком экране —
   друг под другом. Телефону QR не нужен, но и не мешает: адрес рядом. */
.install-qr {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  margin: 16px 0; padding: 14px; border: 1px solid var(--line); border-radius: var(--r-sm);
}
.install-qr img { flex: none; display: block; }
.install-qr p { margin: 0 0 4px; }
