/* Компоненты интерфейса. */

/* ---------- Плитка направления (слой 3) ---------- */

.domain-tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  padding: var(--gap-lg);
  min-height: 190px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: left;
  /* Цвет плитки берётся из данных направления: тот же, что и внутри него.
   * Свет идёт из верхнего левого угла — так плитка читается как вход в
   * цветную среду, а не как серая карточка.
   *
   * Цвет держится по всей плитке, а не только вверху. Раньше низ уходил
   * в подложку направления — почти в чёрный, — и на чёрной прихожей
   * нижняя половина плитки просто растворялась в фоне: оставался
   * светящийся угол непонятной формы. Теперь самая тёмная точка плитки
   * всё ещё заметно фиолетовая. */
  border: 1px solid color-mix(in oklab, var(--tile-accent) 30%, transparent);
  /* Подложка плоским цветом под градиентами.
     Оба градиента полупрозрачные, и без неё сквозь плитку просвечивал
     бы фон экрана — на белой прихожей верх плитки выцветал в сиреневую
     дымку, а вместе с ним пропадал и текст на нём. */
  background-color: color-mix(in oklab, var(--tile-accent) 20%, var(--tile-surface));
  background-image:
    radial-gradient(125% 115% at 8% -10%,
      color-mix(in oklab, var(--tile-accent) 78%, transparent) 0%,
      transparent 68%),
    linear-gradient(158deg,
      color-mix(in oklab, var(--tile-accent) 52%, var(--tile-surface)) 0%,
      color-mix(in oklab, var(--tile-accent) 20%, var(--tile-surface)) 76%);
  /* Плитка — кусочек той среды, в которую ведёт, и она тёмная в любом
     случае. Поэтому чернила здесь свои, а не из темы экрана: на белой
     прихожей общий тёмный текст на тёмной плитке исчезал. */
  --text:       var(--cream);
  --text-dim:   rgba(250, 216, 206, .62);
  --text-faint: rgba(250, 216, 206, .45);
  color: var(--text);
  transition: transform .38s var(--ease-soft), border-color .3s var(--ease);
}

.domain-tile:hover { transform: translateY(-3px); border-color: var(--tile-accent); }
.domain-tile:active { transform: scale(.99); }

/* Плитка монохромного направления.
 *
 * Формула выше строит подложку из акцента, и это работает, пока акцент
 * цветной. У «Личных данных» он почти белый — по общей формуле плитка
 * вышла бы светлым пятном, и самым ярким местом главного экрана
 * оказалась бы подложка, а не то, что на ней написано.
 *
 * Поэтому здесь свет еле заметный, а плитка остаётся угольной — того же
 * цвета, что и разделы, в которые она ведёт. Правило цепляется за
 * выбранный набор, а не за направление: монохром теперь можно поставить
 * любому из трёх, и плитка должна темнеть вместе со средой. */
.domain-tile[data-theme="mono"] {
  /* Рамка заметнее, чем у цветной соседки: на чёрном фоне угольная
     плитка отличается от него на несколько процентов яркости, и без
     кромки от неё остаётся только текст, висящий в пустоте. */
  border-color: rgba(255, 255, 255, .2);
  background-color: #121215;
  background-image:
    radial-gradient(125% 115% at 8% -10%, rgba(255, 255, 255, .10) 0%, transparent 64%),
    linear-gradient(160deg, #1a1a1f 0%, #101013 74%);
}

.domain-tile[data-theme="mono"]:hover { border-color: rgba(255, 255, 255, .38); }

.domain-tile__icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: var(--tile-accent);
  color: var(--on-accent);
}

.domain-tile__icon svg { width: 24px; height: 24px; }

.domain-tile__title { font-size: 23px; font-weight: 700; letter-spacing: -.02em; }
.domain-tile__sub { font-size: 13.5px; color: var(--text-dim); margin-top: 5px; }

/* Разделы-подсказки: сколько влезло в строку, столько и видно.
 *
 * Вторая строка обрезается намеренно. Это не список, а намёк на то, что
 * внутри; перенос одного слова вниз растил карточку на целую строку ради
 * четвёртого пункта, который человек всё равно прочитает, войдя. На
 * широком экране влезают все. */
.domain-tile__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: var(--gap);
  max-height: 25px;
  overflow: hidden;
}

.domain-tile__tag {
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 100px;
  background: rgba(255, 255, 255, .06);
  color: var(--text-dim);
}

/* ---------- Карточка ---------- */

/* Карточка поднята светом изнутри, а не рамкой: заливка в --card несёт
   блик в левом верхнем углу. Рамка оставлена волосяной — только чтобы
   край не растворялся в фоне, а не чтобы очерчивать. */
.card {
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  padding: 18px;
}

.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-sm);
  margin-bottom: var(--gap);
}

/* ---------- Карточка счёта: свайп на телефоне, стрелки на компьютере ---------- */

.account-deck { position: relative; }

.account-deck__viewport {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  display: flex;
  gap: var(--gap);
  padding-bottom: 4px;
}

.account-deck__viewport::-webkit-scrollbar { display: none; }

.account-card {
  scroll-snap-align: center;
  flex: 0 0 100%;
  border-radius: var(--r-lg);
  padding: var(--gap-lg);
  border: 1px solid var(--line);
  background:
    radial-gradient(130% 120% at 88% 4%, var(--accent-soft) 0%, transparent 58%),
    var(--card);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.account-card__top { display: flex; align-items: flex-start; justify-content: space-between; }
.account-card__title { font-size: 14px; font-weight: 600; }
.account-card__meta { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

.account-card__chip {
  font-size: 11px;
  padding: 4px 9px;
  border-radius: 100px;
  background: rgba(255, 255, 255, .07);
  color: var(--text-dim);
}

.account-card__amount {
  /* Крупная сумма набирается основным шрифтом, а не моноширинным.
   * Моноширинный нужен там, где числа стоят колонкой и не должны
   * прыгать при обновлении — в списках операций. Здесь число одно, а
   * каждая цифра сидит в своей широкой ячейке, и сумма расползается на
   * три строки, хотя знаков в ней не так много. Табличные цифры
   * остаются: одинаковая ширина у них есть и без моноширинного шрифта.
   */
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  /* На узком экране кегль падает сам: длинная сумма в одну строку
   * читается лучше, чем крупная, но переломанная на три. */
  font-size: clamp(23px, 7.4vw, 33px);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1.15;
}

/* Раздвоение баланса: появляется только когда по счёту были долги */
.account-card__split {
  display: flex;
  gap: var(--gap-lg);
  padding-top: var(--gap-sm);
  border-top: 1px dashed var(--line);
}

.account-card__split-item { display: flex; flex-direction: column; gap: 2px; }
.account-card__split-value { font-size: 15px; font-weight: 600; }

/* Четыре действия. На узком экране в один ряд не влезают подписи, поэтому
   там сетка ломается на два ряда по две — кнопки остаются крупными. */
.account-card__actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap-sm); }

@media (max-width: 560px) {
  .account-card__actions { grid-template-columns: repeat(2, 1fr); }
}

.action-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 6px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line-soft);
  font-size: 12.5px;
  font-weight: 550;
  min-height: 44px;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}

.action-btn svg { width: 18px; height: 18px; }
.action-btn:hover { background: rgba(255, 255, 255, .09); border-color: var(--accent); }
.action-btn--plus svg { color: var(--plus); }
.action-btn--minus svg { color: var(--minus); }
.action-btn--debt svg { color: var(--warn); }
.action-btn--move svg { color: var(--accent); }

/* Счёт-источник в окне перевода: он не выбирается, поэтому и выглядит
   не полем ввода, а строкой — иначе в него пытаются печатать. */
.transfer-from {
  padding: 11px 14px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .04);
  border: 1px dashed var(--line);
  font-size: 14px;
  font-weight: 550;
  color: var(--text-dim);
}

/* Точки-индикаторы и стрелки */
.account-deck__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-sm);
  margin-top: var(--gap-sm);
}

.account-deck__dots { display: flex; gap: 6px; }

.account-deck__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--line);
  transition: background .2s var(--ease), width .2s var(--ease);
}

.account-deck__dot.is-active { background: var(--accent); width: 18px; border-radius: 3px; }

.account-deck__arrow {
  display: grid;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  place-items: center;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--text-dim);
}

.account-deck__arrow:hover { color: var(--text); border-color: var(--accent); }

/* Стрелки есть и на телефоне.
 *
 * Раньше они прятались: считалось, что на телефоне свайпают. Но свайп
 * ничем не обозначен — о нём знает только тот, кто его уже нашёл, а
 * точки под карточкой показывают, что счетов несколько, и не говорят,
 * как переключить. Свайп остался, стрелки к нему добавлены. */
.account-deck__arrow svg { width: 17px; height: 17px; }

/* ---------- Списки операций и должников ---------- */

.list { display: flex; flex-direction: column; }

.list__row {
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  padding: 11px 0;
  border-bottom: 1px solid var(--line-soft);
}

.list__row:last-child { border-bottom: none; }

.list__icon {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  flex-shrink: 0;
  font-size: 14px;
  font-weight: 650;
}

.list__body { flex: 1; min-width: 0; }
.list__title { font-size: 14px; font-weight: 550; }
.list__sub { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

/* Текст записи в списке: показываем целиком, поэтому переносим по
   строкам и сохраняем авторские переводы строк. Цвет чуть светлее
   служебной строки — это то, ради чего в список и заглядывают. */
.list__sub--full {
  color: var(--text-dim);
  white-space: pre-wrap;
  line-height: 1.55;
  margin-top: 4px;
}

/* Строка, которая растёт под текст: значок и три точки прижимаем к
   верху, иначе на длинной заметке они уезжают на середину. */
.list__row--top { align-items: flex-start; }
.list__row--top .list__icon,
.list__row--top .check { margin-top: 1px; }
.list__value { font-size: 14.5px; font-weight: 620; white-space: nowrap; }

.badge {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 100px;
  font-weight: 600;
}

.badge--ok { background: var(--plus-soft); color: var(--plus); }
.badge--warn { background: var(--warn-soft); color: var(--warn); }

.empty {
  padding: var(--gap-lg) var(--gap);
  text-align: center;
  color: var(--text-faint);
  font-size: 13px;
}

/* ---------- Кнопки ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 18px;
  border-radius: var(--r-sm);
  font-weight: 600;
  font-size: 14px;
  min-height: 44px;
  transition: opacity .18s var(--ease), background .18s var(--ease);
}

/* Главная кнопка светится цветом направления. Свечение, а не тень:
   на тёмном фоне тень не видна, а свет отделяет кнопку от карточки. */
.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--glow);
}
.btn--primary:hover { opacity: .88; }
.btn--ghost { background: var(--card); border: 1px solid var(--line); }
.btn--ghost:hover { border-color: var(--accent); }
.btn--icon { padding: 9px; min-height: 38px; width: 38px; border-radius: 50%; }

/* Значок внутри кнопки.
 *
 * Своего правила у него не было: в Chrome он растягивался по кнопке и
 * выглядел правильно, а в Safari схлопывался в ноль. Задаём размер явно —
 * тогда обе кнопки, «плюс» и «назад», выглядят одинаково в любом браузере.
 * flex-shrink нужен, чтобы длинная подпись рядом не сплющила значок. */
.btn svg { width: 18px; height: 18px; flex-shrink: 0; }
.btn--icon svg { width: 20px; height: 20px; }

/* Плитка значка в списке заполняется целиком — так было и так остаётся. */
.list__icon svg { width: 100%; height: 100%; }

/* ---------- Модальное окно ---------- */

.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  align-items: flex-end;
  justify-content: center;
  background: rgba(5, 4, 9, .68);
  backdrop-filter: blur(4px);
}

.modal.is-open { display: flex; }

.modal__box {
  width: 100%;
  max-width: 460px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: var(--gap-lg);
  max-height: 92vh;
  overflow-y: auto;
  animation: slide-up .3s var(--ease);
}

/* Шапка модального окна прижата к содержимому.
 *
 * Общее правило для карточек — отбивать заголовок на var(--gap), и на
 * плотной карточке это верно. В модальном окне к нему прибавляется
 * отступ самого окна и отступ первого блока, и между названием счёта и
 * его суммой набегала пустая полоса в полсотни пикселей: на телефоне
 * сумма уезжала к середине экрана, а список операций — под сгиб.
 */
.modal__box .card__head { margin-bottom: 10px; }

/* На телефоне окно и так во весь экран по ширине — широкие поля по
 * краям здесь только съедают место под содержимое. */
@media (max-width: 560px) {
  .modal__box { padding: 18px 16px 20px; }
}

@keyframes slide-up {
  from { transform: translateY(28px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

@media (min-width: 900px) {
  .modal { align-items: center; }
  .modal__box { border-radius: var(--r-lg); animation: none; }
}

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--gap); }
.field__label { font-size: 12.5px; color: var(--text-dim); font-weight: 550; }

/* Незаполненное обязательное поле. Подсвечиваем само поле, а не только
   пишем внизу: так видно, куда именно возвращаться. */
.field--bad input,
.field--bad select { border-color: var(--minus); }
.field--bad .field__label { color: var(--minus); }

.seg { display: flex; gap: 6px; }

.seg__item {
  flex: 1;
  padding: 10px;
  border-radius: var(--r-sm);
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 13px;
  font-weight: 550;
  min-height: 44px;
}

.seg__item.is-active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* ---------- Дневник прогресса ---------- */

/* Рекорд читается как одно число с хвостом, а не как три отдельных:
   крупный вес, мелкая единица, повторения рядом. */
.record { display: flex; align-items: baseline; gap: 3px; white-space: nowrap; }
.record__weight { font-size: 19px; font-weight: 800; letter-spacing: -.03em; }
.record__unit { font-size: 11px; color: var(--text-faint); }
.record__reps { font-size: 14px; font-weight: 600; color: var(--text-dim); margin-left: 3px; }

/* Вложенная карточка: тренировка внутри списка тренировок. Отличается
   от внешней на один тон, без второй рамки — иначе получается коробка
   в коробке. */
.card--inset {
  background: var(--surface-soft, rgba(255, 255, 255, .035));
  border: 1px solid var(--line-soft);
  padding: var(--gap);
}

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

/* Три колонки: что делали, с чем, и что дальше. Заголовок и строки
   держат одну сетку, поэтому «Было» и «Дальше» стоят друг под другом. */
.plan__head,
.plan__row {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1.3fr);
  gap: var(--gap-sm);
  align-items: baseline;
}

.plan__head {
  margin-top: var(--gap);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.plan__row { padding: 9px 0; border-bottom: 1px solid var(--line-soft); }
.plan__row:last-child { border-bottom: 0; padding-bottom: 0; }

.plan__name { font-size: 13.5px; font-weight: 550; }
.plan__was { font-size: 13px; color: var(--text-dim); }
.plan__next { display: flex; flex-direction: column; gap: 1px; }
.plan__weight { font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.plan__next.is-up .plan__weight { color: var(--plus); }
.plan__why { font-size: 11px; color: var(--text-faint); line-height: 1.35; }

/* На телефоне три колонки не помещаются: подписи съезжают в две строки,
   и таблица перестаёт читаться. Разворачиваем в столбик с подписями. */
@media (max-width: 560px) {
  .plan__head { display: none; }
  .plan__row { grid-template-columns: 1fr; gap: 3px; padding: 11px 0; }
  .plan__was::before { content: 'было: '; color: var(--text-faint); }
  .plan__next { flex-direction: row; align-items: baseline; gap: 8px; flex-wrap: wrap; }
  .plan__weight::before { content: 'дальше: '; font-weight: 400; color: var(--text-faint); }
}

/* ---------- Прочее ---------- */

.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-sm); }

.stat {
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  padding: var(--gap);
}

.stat__value { font-size: 19px; font-weight: 700; margin-top: 5px; }

.bars { display: flex; align-items: stretch; gap: 7px; height: 128px; }

/* Колонка тянется на всю высоту, столбик прижат к низу — только так
 * процентная высота столбика имеет от чего считаться. */
.bars__col {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 7px;
}

.bars__bar {
  width: 100%;
  border-radius: 5px 5px 2px 2px;
  background: var(--accent);
  opacity: .82;
  min-height: 3px;
  transition: height .45s var(--ease);
}

.bars__label { font-size: 10.5px; color: var(--text-faint); }

.chips { display: flex; gap: 6px; flex-wrap: wrap; }

.chip {
  font-size: 12px;
  padding: 6px 11px;
  border-radius: 100px;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--text-dim);
}

.chip.is-active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-h) + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px)) + 34px);
  transform: translateX(-50%) translateY(14px);
  z-index: 70;
  padding: 12px 18px;
  border-radius: 100px;
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 13.5px;
  font-weight: 550;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

.toast.is-shown { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (min-width: 900px) {
  .toast { bottom: 26px; }
}

/* Где внизу висит панель, тост поднимается над ней: иначе «+250 мл»
   ложится ровно на кнопку, которой это и нажали. */
[data-area="nutrition"] .toast { margin-bottom: 66px; }

/* ---------- Полоса отмены ----------
 *
 * Живёт там же, где всплывающая подсказка, но выше неё и с кнопкой:
 * подсказку читают, полосу — нажимают. Ширина ограничена, чтобы на
 * компьютере она не растягивалась через весь экран и «Отменить» не
 * оказывалось в противоположном углу от того места, куда человек
 * только что нажал.
 */
.undo {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-h) + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px)) + 34px);
  transform: translateX(-50%);
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 14px;
  width: calc(100% - 32px);
  max-width: 420px;
  padding: 11px 12px 11px 16px;
  border-radius: 16px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
  animation: undo-in .22s var(--ease);
}

@keyframes undo-in {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.undo__text {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.undo__button {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 8px 12px;
  border: 0;
  border-radius: 100px;
  background: var(--accent-soft, var(--bg-soft));
  color: var(--accent);
  font-size: 13.5px;
  font-weight: 650;
  cursor: pointer;
}

/* Счётчик — не украшение: он отвечает на вопрос «сколько у меня ещё
 * времени», который человек задаёт ровно в эту секунду. */
.undo__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 100px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}

@media (min-width: 900px) {
  .undo { bottom: 26px; }
}

/* ---------- Вкладки внутри раздела ---------- */

.tabs {
  display: flex;
  gap: 6px;
  margin-bottom: var(--gap);
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.tabs::-webkit-scrollbar { display: none; }

.tabs__item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  border-radius: 100px;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 550;
  white-space: nowrap;
  min-height: 44px;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}

.tabs__item svg { width: 16px; height: 16px; }

/* Обёртка значка не сжимается.
 *
 * Значок лежит в span, а span — сжимаемый элемент флекса. У текста есть
 * минимальная ширина (слово), у картинки её нет, поэтому при нехватке
 * места флекс сожмёт именно значок, и сожмёт до нуля.
 *
 * Вкладки на узком экране прячут значок намеренно (см. медиазапрос ниже),
 * это не тот случай. Правило здесь ради нижнего бара и бокового меню: там
 * значок обязан пережить и длинное название раздела, и узкий телефон. */
.tabs__item > span:first-child,
.tabbar__item > span:first-child,
.sidebar__item > span:first-child { flex-shrink: 0; }
.tabs__item:hover { color: var(--text); border-color: var(--accent); }

.tabs__item.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

/* ---------- Отметка о выполнении ---------- */

.check {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 2px solid var(--line);
  display: grid;
  place-items: center;
  color: var(--on-accent);
  transition: background .18s var(--ease), border-color .18s var(--ease);
}

.check svg { width: 14px; height: 14px; }
.check:hover { border-color: var(--accent); }
.check.is-done { background: var(--accent); border-color: var(--accent); }

/* Выполненное не прячем, но приглушаем: видно, что сделано, и не мешает */
.list__row.is-done .list__title {
  color: var(--text-faint);
  text-decoration: line-through;
}

/* ---------- Кнопка настроек записи ---------- */

.row-menu {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--text-faint);
  opacity: 0;
  transition: opacity .18s var(--ease), color .18s var(--ease),
              background .18s var(--ease);
}

.row-menu svg { width: 18px; height: 18px; }
.list__row:hover .row-menu { opacity: 1; }
.row-menu:hover { color: var(--text); background: var(--card-hover); }

/* На телефоне мыши нет, наводить нечем — точки видны всегда,
   и дополнительно работает долгое нажатие по строке */
@media (hover: none) {
  .row-menu { opacity: .6; }
}

/* ---------- Ползунок ---------- */

.switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: 12px 0;
  border-top: 1px solid var(--line-soft);
  margin-top: var(--gap-xs);
}

.toggle {
  width: 50px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 100px;
  background: var(--line);
  padding: 3px;
  display: flex;
  transition: background .2s var(--ease);
}

.toggle__knob {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #fff;
  transition: transform .2s var(--ease);
}

.toggle.is-on { background: var(--accent); }
.toggle.is-on .toggle__knob { transform: translateX(20px); }

/* ---------- Дни недели ---------- */

.weekdays { display: flex; gap: 6px; }

.weekday {
  flex: 1;
  min-width: 0;
  height: 44px;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 600;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}

.weekday.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

textarea {
  font-family: inherit;
  min-height: 44px;
}

/* ---------- Календарь ---------- */

.cal__week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  /* Тот же зазор, что и у сетки чисел: без него шапка и числа стоят в
     разных колонках — «ПН» над одним днём, «ВС» над соседним. */
  gap: 2px;
  margin-bottom: 6px;
}

.cal__weekday {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 6px;
}

.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

/* Клетка дня — просто место под число и точки. Кружок рисуется вокруг
   самого числа, а не вокруг всей клетки: на широком экране клетка почти
   в сто пикселей, и заливка на всю её ширину превращалась в блин, внутри
   которого болталась крошечная цифра. */
.cal__day {
  aspect-ratio: 1;
  /* min-height здесь стоять не может. Вместе с aspect-ratio он задаёт и
     минимальную ШИРИНУ: сорок четыре пикселя на клетку — это триста
     двадцать на семь колонок, и на телефоне сетка вылезала за карточку,
     унося правый столбец за край экрана. Ширину теперь определяет сама
     колонка (1fr), высоту — пропорция; на узком экране клетка выходит
     около сорока двух пикселей, и палец в неё попадает. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  color: var(--text);
  background: none;
  transition: color .16s var(--ease);
}

.cal__day:hover .cal__num { background: var(--card-hover); }

/* Дни соседних месяцев на месте, но приглушены: сетка не разъезжается,
   и видно, что неделя началась раньше */
.cal__day.is-faded { color: var(--text-faint); opacity: .45; }

/* Сегодняшний день выделен цветом, выбранный — заливкой. Так видно оба
   сразу, даже когда это разные дни */
.cal__day.is-today { color: var(--accent); font-weight: 700; }

.cal__day.is-selected { color: var(--on-accent); }

.cal__day.is-selected .cal__num {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 650;
}

.cal__day.is-selected.is-today .cal__num { color: var(--on-accent); }

/* Число в кружке: размер кружка фиксированный, шрифт под него — цифра
   заполняет кружок, но не распирает его. */
.cal__num {
  /* Кружок не шире клетки: на узких экранах клетка ужимается, и
     фиксированные 34 пикселя распирали бы её изнутри. */
  width: min(34px, 100%);
  height: min(34px, 100%);
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
  transition: background .16s var(--ease), color .16s var(--ease);
}

.cal__dots { display: flex; gap: 3px; height: 5px; }

.cal__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* Точки cal__dot--repeat здесь больше нет: повторяющиеся дела в сетке
   не отмечаются вовсе (почему — в calendar.js, функция cell). */

.cal__day.is-selected .cal__dot { background: var(--on-accent); }

/* На узком экране три вкладки с иконками не помещаются и уезжают за
   край. Иконка здесь украшение, название — суть, поэтому прячем иконку. */
@media (max-width: 480px) {
  .tabs__item { padding: 9px 12px; font-size: 13px; }
  .tabs__item svg { display: none; }
}

/* ---------- Питание ---------- */

/* Полоска прогресса: белки, жиры, углеводы, вода */
.bar {
  height: 7px;
  border-radius: 100px;
  background: var(--line);
  overflow: hidden;
}

.bar__fill {
  height: 100%;
  border-radius: 100px;
  transition: width .4s var(--ease);
}

/* Кольцо калорий: цифра внутри, чтобы не искать её глазами рядом */
.ring {
  position: relative;
  width: 92px;
  height: 92px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
}

.ring svg { position: absolute; inset: 0; }

.ring__label {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.02em;
}

/* Три поля в ряд: белки, жиры, углеводы или возраст, рост, вес */
.macro-inputs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.macro-inputs .field { margin-bottom: var(--gap-sm); }
.macro-inputs input { padding: 11px 9px; }

/* ---------- Просмотр чужих записей ---------- */

/* Полоса сверху: чьи это записи и как выйти. Висит поверх экрана и не
   уезжает при прокрутке — иначе через полминуты чтения человек уже не
   помнит, что смотрит чужое, и удивляется пропавшим кнопкам. */
.guestbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  min-height: 46px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px max(12px, env(safe-area-inset-left, 0px));
  padding-top: calc(8px + max(env(safe-area-inset-top, 0px), var(--tg-safe-top, 0px)));
  background: var(--accent-soft);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(14px);
  font-size: 13px;
}

.guestbar__icon { display: grid; color: var(--accent); }
.guestbar__icon svg { width: 18px; height: 18px; }
.guestbar__text { flex: 1; min-width: 0; }
.guestbar__exit { padding: 7px 14px; min-height: 34px; flex: none; }

/* Содержимое опускается под полосу — иначе она ложится на заголовок. */
[data-guest] .workspace__main { padding-top: 52px; }

/* ---------- Нижняя панель питания ---------- */

/* Плавает над нижним баром, поверх содержимого. Не в потоке страницы:
   еду записывают из любого места экрана, а кнопка в шапке уезжает вверх
   на первом же движении пальца.

   Ширина ограничена: на компьютере панель во весь экран выглядела бы
   полосой управления самолётом, а не двумя кнопками. */
.quickbar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--tabbar-h)
               + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px))
               + 26px);
  z-index: 25;
  width: min(calc(100% - 24px), 520px);
  display: flex;
  align-items: center;
  gap: 8px;
}

.quickbar__meal,
.quickbar__water {
  min-height: 52px;
  border-radius: 100px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 650;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Тень, а не свечение: панель лежит поверх карточек, и ей нужен вес,
     иначе она читается как нарисованная на них. */
  box-shadow: 0 14px 34px -12px rgba(0, 0, 0, .75);
  transition: transform .2s var(--ease-soft), filter .2s var(--ease);
}

.quickbar__meal {
  flex: 1;
  min-width: 0;
  gap: 8px;
  font-size: 14.5px;
  padding: 0 16px;
}

.quickbar__meal:active,
.quickbar__water:active { transform: scale(.97); }

.quickbar__meal:hover,
.quickbar__water:hover { filter: brightness(1.06); }

.quickbar__plus svg { width: 20px; height: 20px; }

/* Вода — кружками по краям. Тише, чем еда: воду записывают чаще, но
   ошибиться в ней не страшно, а главная кнопка на экране одна. */
.quickbar__water {
  width: 52px;
  flex: none;
  gap: 1px;
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--line);
}

.quickbar__drop svg { width: 17px; height: 17px; }
.quickbar__sign svg { width: 13px; height: 13px; }
.quickbar__drop { display: grid; color: var(--accent); }
.quickbar__sign { display: grid; }

/* На компьютере нижнего бара нет — панель опускается к самому краю. И
   съезжает вправо на половину бокового меню: «по центру окна» здесь
   значит «левее центра колонки, в которую человек смотрит». */
@media (min-width: 900px) {
  .quickbar {
    bottom: 24px;
    left: calc(50% + var(--sidebar-w) / 2);
  }
}

/* ---------- Состав блюда ---------- */

/* Список продуктов в форме приёма пищи. Строка — название, вес и
   кнопка «убрать»; под ней калории с БЖУ, по нажатию превращающиеся в
   поля. Числа продукта нужны редко, поэтому по умолчанию они текст, а
   не три инпута: иначе список из шести продуктов занимал бы экран. */
.ingredients__row {
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
}

.ingredients__row:last-child { border-bottom: none; }

.ingredients__top {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* min-width нужен обоим: без него длинное название растягивает строку и
   выдавливает кнопку за край карточки. */
.ingredients__name { flex: 1; min-width: 0; }

.ingredients__grams {
  width: 72px;
  flex: none;
  text-align: right;
}

.ingredients__unit { font-size: 12.5px; }

.ingredients__line {
  display: block;
  width: 100%;
  text-align: left;
  padding: 4px 0 0;
  font-size: 11.5px;
  color: var(--text-faint);
  line-height: 1.5;
}

.ingredients__line:hover { color: var(--text-dim); }

.ingredients__row .macro-inputs { margin-top: 6px; }

.ingredients__sum {
  font-size: 13px;
  font-weight: 600;
  margin: 10px 0 var(--gap);
}

.field__hint {
  font-size: 11.5px;
  color: var(--text-faint);
  line-height: 1.5;
  margin-top: 5px;
}

/* Итог расчёта в настройках: считается на лету, пока человек вводит */
.preview {
  margin-top: var(--gap);
  padding: var(--gap);
  border-radius: var(--r-md);
  background: var(--accent-soft);
  border: 1px solid var(--line);
}

/* Время приёма таблетки: нажал — отметил, что выпил */
.time-chip {
  padding: 6px 10px;
  border-radius: 100px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text-dim);
  font-size: 11.5px;
  font-weight: 600;
  min-height: 32px;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}

.time-chip:hover { border-color: var(--accent); }

.time-chip.is-taken {
  background: var(--plus);
  border-color: var(--plus);
  color: var(--on-accent);
}

.time-edit { display: flex; align-items: center; gap: 4px; }
.time-edit input { width: 110px; }

/* ---------- график веса ---------- */

/* Контейнер нужен позиционированный: линия под курсором и подсказка
   лежат поверх svg и двигаются в его координатах. */
.chart {
  position: relative;
  margin-top: 4px;
  user-select: none;
}

.chart svg { display: block; overflow: visible; }

/* Вертикальная линия под курсором: тонкая и приглушённая — она помогает
   попасть глазом в точку, а не спорит с данными. */
.chart__cursor {
  position: absolute;
  top: 16px;
  bottom: 26px;
  width: 1px;
  background: var(--text-faint);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}

.chart__tip {
  position: absolute;
  top: -2px;
  transform: translateX(-50%);
  padding: 6px 10px;
  border-radius: 9px;
  background: var(--card-hover);
  border: 1px solid var(--line);
  font-size: 12px;
  font-weight: 550;
  color: var(--text);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
  box-shadow: 0 10px 24px -14px rgba(0, 0, 0, .9);
}

/* Две линии на графике — значит нужна подпись, что есть что: по цвету
   одному человек угадывать не должен. */
.legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 11.5px;
  color: var(--text-faint);
}

.legend__item { display: inline-flex; align-items: center; gap: 6px; }

.legend__line {
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

.legend__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--text-faint);
}

/* ---------- фото прогресса ---------- */

.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--gap-sm);
  margin-top: 4px;
}

.photo {
  position: relative;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--card-hover);
  cursor: pointer;
  aspect-ratio: 3 / 4;
}

.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo:hover { border-color: var(--accent); }

/* Дата поверх снимка — на подложке, иначе на светлом фото её не видно */
.photo__date {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 14px 8px 6px;
  font-size: 11px;
  color: #fff;
  text-align: left;
  background: linear-gradient(to top, rgba(0, 0, 0, .72), transparent);
}

.compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap-sm);
}

.compare img {
  width: 100%;
  border-radius: var(--r-md);
  display: block;
}

.compare__label {
  margin-top: 6px;
  text-align: center;
  font-size: 12px;
  color: var(--text-faint);
}

/* ---------- Длинный текст ---------- */

/* Человек может вписать в заметку тысячу букв без единого пробела —
   и без этих правил такая строка уезжает за край карточки и тянет за
   собой всю страницу. Перенос разрешаем в любом месте: лучше некрасивый
   разрыв слова, чем текст, уходящий за экран. */
.h1,
.h2,
.list__title,
.list__sub,
.list__body,
.field__hint,
.empty,
.preview,
.account-card__title,
.account-card__meta,
.note-text {
  overflow-wrap: anywhere;
  min-width: 0;
}

/* Свойство переноса наследуется, поэтому вешать его на карточку целиком
   нельзя: тогда рвались бы и короткие слова в заголовках. Карточке нужно
   только одно — не раздуваться от содержимого. */
.card, .list__row, .account-card { min-width: 0; }

/* Суммы справа не переносим: разорванное число читается как два числа */
.list__value { white-space: nowrap; text-align: right; }

/* Многострочный текст заметки внутри карточки */
.note-text {
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.6;
  white-space: pre-wrap;
}

/* Счётчик символов под полем ввода */
.field__count {
  font-size: 11px;
  color: var(--text-faint);
  text-align: right;
  margin-top: 4px;
}

.field__count.is-over { color: var(--minus); }

textarea {
  min-height: 110px;
  resize: vertical;
  font-family: inherit;
  line-height: 1.55;
}

/* Фото блюда в списке — вместо иконки */
.meal-thumb {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  object-fit: cover;
  flex-shrink: 0;
}

/* Строка-ссылка в списке: ведёт в другой раздел, а не отмечается здесь.
   Приглушена, чтобы не читалась как ещё одно дело на сегодня. */
.link-row .list__title { color: var(--text-dim); font-weight: 500; }
.link-row:hover .list__title { color: var(--text); }
.link-row .list__icon { background: var(--card-hover); color: var(--text-faint); }

/* ---------- Заглушка «скоро» ---------- */

.soon {
  padding: var(--gap-lg) var(--gap);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.soon__mark {
  width: 56px;
  height: 56px;
  border-radius: 18px;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  margin-bottom: var(--gap);
}

.soon__mark svg { width: 26px; height: 26px; }

.soon__title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.01em;
}

.soon__text {
  margin-top: 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-faint);
  max-width: 420px;
}

/* На широком экране клетка дня растягивается до сотни с лишним пикселей,
   и месяц занимает весь экран — список дня уезжает вниз. Квадратные
   клетки нужны на телефоне, где ширина маленькая; на компьютере хватает
   фиксированной высоты. */
@media (min-width: 700px) {
  .cal__day { aspect-ratio: auto; height: 62px; }
}

/* ---------- Спорт: подходы, отдых, стрелки ---------- */

/* Строка подхода: номер, что было в прошлый раз, вес, повторения,
   галочка. Всё в один ряд — вводить приходится одной рукой, стоя. */
.set-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  padding: 9px 10px;
}

/* Отмеченный подход подсвечен рамкой, а не заливкой: заливка спорила бы
   с полями ввода, которые внутри него же и остаются */
.set-row.is-done { border-color: color-mix(in oklab, var(--plus) 55%, transparent); }

.set-num {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--card);
  color: var(--text-dim);
  font-size: 11.5px;
  font-weight: 700;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

/* Прошлый результат — подсказка, а не данные: держим её тусклой, чтобы
   не путалась с тем, что человек вводит сейчас */
.set-ghost {
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-faint);
  width: 66px;
  flex-shrink: 0;
}

.set-field { flex: 1; min-width: 0; }

.set-field input {
  width: 100%;
  padding: 8px 6px;
  text-align: center;
  font-family: var(--font-num);
  font-size: 14px;
}

.set-unit {
  font-size: 10px;
  color: var(--text-faint);
  text-align: center;
  margin-top: 3px;
}

.set-check {
  width: 34px;
  height: 34px;
  min-width: 34px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: none;
  display: grid;
  place-items: center;
  color: transparent;
  flex-shrink: 0;
}

.set-check svg { width: 16px; height: 16px; }

.set-check.is-done {
  background: var(--plus);
  border-color: var(--plus);
  color: var(--on-accent);
}

/* Таймер отдыха. Липнет к низу экрана: руки заняты штангой, тянуться
   к нему прокруткой неудобно. */
.rest {
  position: sticky;
  bottom: calc(var(--tabbar-h) + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px)) + 28px);
  margin-top: var(--gap);
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  text-align: center;
  box-shadow: var(--shadow);
  z-index: 20;
}

.rest__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.rest__time {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -.02em;
  margin: 4px 0 10px;
}

.rest__bar {
  height: 5px;
  border-radius: 100px;
  background: rgba(255, 255, 255, .10);
  overflow: hidden;
  margin-bottom: 10px;
}

.rest__fill {
  height: 100%;
  border-radius: 100px;
  background: var(--accent);
  transition: width .25s linear;
}

.rest__skip {
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text-dim);
  background: none;
  border: none;
}

.rest__skip:hover { color: var(--text); }

/* Стрелка в конце строки: намёк, что строка ведёт дальше */
.chev {
  color: var(--text-faint);
  flex-shrink: 0;
  display: grid;
  place-items: center;
}

.chev svg { width: 17px; height: 17px; }

@media (min-width: 900px) {
  .rest { bottom: 16px; }
}

/* Разминочный подход: буква вместо номера и приглушённый вид — он
   сделан, но в тоннаж и рекорды не идёт, и это должно быть видно. */
.set-num.is-warmup {
  background: var(--warn-soft);
  color: var(--warn);
  border: 1px solid color-mix(in oklab, var(--warn) 45%, transparent);
}

.set-row.is-done .set-num.is-warmup { opacity: .9; }

/* Кнопки правки отсчёта: рядом с «пропустить», но тише его — основное
   действие всё-таки закончить отдых, а не крутить время. */
.rest__step {
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text-dim);
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 6px 12px;
  min-height: 34px;
}

.rest__step:hover { color: var(--text); border-color: var(--accent); }

/* Точки тренировок в сетке месяца. Сделанная — акцентом раздела,
   запланированная — контуром: намерение и факт не должны выглядеть
   одинаково, иначе неделя вперёд читается как уже прожитая. */
.cal__dot--workout { background: var(--plus); }

.cal__dot--planned {
  background: none;
  border: 1.5px solid var(--accent);
  /* Рамка не должна раздувать точку: соседние заливные точки того же
     размера, и разнобой в один пиксель здесь виден */
  box-sizing: border-box;
}

/* На выбранном дне фон становится акцентным, и контурная точка на нём
   пропадает — там она тоже заливная, но чужого цвета */
.cal__day.is-selected .cal__dot--planned {
  background: var(--on-accent);
  border-color: var(--on-accent);
}

/* ───────────────────────────── Вход ─────────────────────────────
 *
 * Экран, который видит тот, кого сервер не признал за своего: открыл
 * приложение по адресу, минуя бота. Раньше такого экрана не было —
 * потому что не было и вопроса: сервер пускал любого.
 *
 * Поверх всего, а не вместо экранов: он появляется до того, как
 * приложение вообще успело что-то нарисовать.
 */
.gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gap-lg, 20px);
  background: var(--bg);
}

.gate__box {
  width: 100%;
  max-width: 340px;
  padding: 26px 22px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-raised);
  text-align: center;
}

.gate__title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 10px;
}

.gate__text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-dim);
  margin-bottom: 20px;
}

.gate__input {
  width: 100%;
  height: 46px;
  margin-bottom: 10px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  text-align: center;
  letter-spacing: 4px;
}

.gate__input:focus {
  outline: none;
  border-color: var(--accent);
}

/* 46 пикселей, а не «сколько получится»: в кнопку должен попадать
   палец, а не только курсор. */
.gate__button {
  width: 100%;
  height: 46px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.gate__error {
  min-height: 18px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--minus);
}

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

.acc-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.acc-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: var(--bg-soft, var(--card));
  text-align: left;
  cursor: pointer;
  transition: border-color .15s var(--ease), transform .15s var(--ease);
}

.acc-tile:hover { border-color: var(--accent); }
.acc-tile:active { transform: scale(.985); }

.acc-tile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-bottom: 8px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
}

.acc-tile__icon svg { width: 15px; height: 15px; }

.acc-tile__title {
  font-size: 13.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.acc-tile__sum {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
}

/* Банк и последние цифры — то, по чему карту узнают. Мельче суммы:
   сумму читают, подпись сверяют. */
.acc-tile__meta {
  font-size: 11px;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Круг долей ---------- */

.donut-box {
  display: flex;
  align-items: center;
  gap: var(--gap);
  flex-wrap: wrap;
  margin-top: var(--gap);
}

.donut {
  position: relative;
  flex: none;
  line-height: 0;
}

/* Итог в середине кольца: сумма и её состав читаются одним взглядом,
   без перевода глаз к подписи сбоку. */
.donut__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.2;
  pointer-events: none;
}

.donut__sum { font-size: 17px; font-weight: 700; }

.donut__label {
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.donut__legend {
  flex: 1;
  min-width: 160px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.donut__row { display: flex; align-items: center; gap: 8px; }

.donut__dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
}

.donut__name {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.donut__value {
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* На узком экране кольцо встаёт над легендой и центрируется: рядом они
   помещаются только на планшете и шире. */
@media (max-width: 420px) {
  .donut-box { flex-direction: column; }
  .donut__legend { width: 100%; }
}

/* ---------- Подвал главного экрана ----------
 *
 * «Мои данные» и «Конфиденциальность». Мелко и приглушённо: это не то,
 * ради чего открывают приложение, но и прятать их нельзя — право забрать
 * или стереть свои записи стоит ровно столько, сколько стоит найти
 * кнопку.
 */
.app-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: var(--gap-lg, 24px);
}

.app-foot__link {
  font-size: 12px;
  color: var(--text-faint);
  background: none;
  border: 0;
  padding: 4px;
  cursor: pointer;
  text-decoration: none;
  transition: color .15s var(--ease);
}

.app-foot__link:hover { color: var(--text-dim); text-decoration: underline; }
.app-foot__dot { color: var(--text-faint); font-size: 12px; }

/* ======================================================================
   Характер разделов
   ======================================================================

   Цвета живут в tokens.css. Здесь то, что цветом не выражается: как
   лежит свет на карточке, насколько крупно набраны суммы, чем карточка
   отделена от фона.

   Правило прежнее: любой цвет берётся из токена. Ни одного литерала —
   иначе при следующей смене палитры эти правила останутся от старой.
   ---------------------------------------------------------------------- */

/* ---------- Личные данные: монохром ---------- */

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

/* Карточка счёта — ровная плашка. Никаких бликов по кромке и никакого
   свечения: они читались как неон и спорили с цифрами, ради которых
   человек сюда и пришёл. Карточка отделяется от фона тем, что чуть
   светлее его, и тонкой рамкой. */
[data-area="finance"] .acc-tile {
  background: var(--card);
  border-color: var(--line-soft);
  border-radius: 16px;
  padding: 15px 15px 13px;
}

[data-area="finance"] .acc-tile:hover {
  background: var(--card-hover);
  border-color: var(--line);
}

/* Значок счёта на нейтральной подложке: акцент здесь почти белый, и
   круг под ним получился бы ярче самой суммы. */
[data-area="finance"] .acc-tile__icon {
  background: rgba(255, 255, 255, .07);
  color: var(--text-dim);
}

/* Сумма — главное на карточке. В сиреневых разделах цифры живут наравне
   с подписями, здесь они крупнее и плотнее: на экране балансов человек
   считывает числа, а названия счетов узнаёт боковым зрением. */
/* Сумма — главное на карточке, но не любой ценой: на «₴232 904.00» и
   узком телефоне двадцать пикселей ломали число на две строки, и оно
   переставало читаться как одно. Размер тянется за шириной карточки и
   упирается в потолок. */
[data-area="finance"] .acc-tile__sum {
  font-size: clamp(15px, 4.6vw, 19px);
  font-weight: 700;
  letter-spacing: -.03em;
  white-space: nowrap;
}

[data-area="finance"] .acc-tile__title {
  color: var(--text-dim);
  font-size: 12.5px;
}

/* Карточки — та же матовая подложка во всех разделах направления. */
[data-domain="pim"] .card,
[data-theme="mono"] .card {
  background: var(--card);
  border-color: var(--line-soft);
}

/* ---------- Тело и здоровье: мягкий свет ---------- */

/* Карточка лежит на фоне, а не нарисована на нём: тень вниз и волосяной
   свет по верхней кромке. Свечения по-прежнему нет — тень затемняет.
   Кольцо и круг долей остаются без всякой тени: у линии графика не может
   быть физического веса, и подсветка под ней читалась как витрина. */
[data-domain="sport"] .card,
[data-domain="health"] .card,
[data-domain="community"] .card {
  box-shadow: var(--shadow-soft), var(--edge);
}

[data-domain="sport"] .ring,
[data-domain="sport"] .donut,
[data-domain="health"] .ring,
[data-domain="health"] .donut {
  box-shadow: none;
  filter: none;
}

/* Главная карточка раздела.
 *
 * Одна на экран: та, ради которой человек его и открыл. В «Теле и
 * здоровье» это остаток калорий на сегодня, и он получает подложку
 * цвета направления — свет ложится из левого верхнего угла и гаснет к
 * правому нижнему, как на настоящей плашке.
 *
 * В финансах такого нет намеренно: там главное — сумма в шапке, и
 * цветная плашка под ней спорила бы с цифрами.
 */
[data-domain="health"] .card--hero {
  /* Плашка приглушённо-фиолетовая и ровная. Градиент здесь был первым,
     что бросалось в глаза, — а главное на карточке цифра, а не подложка
     под ней. Тень при этом глубже, чем у соседей: это первая карточка
     экрана, и она должна лежать выше остальных. */
  background: var(--accent-soft);
  border-color: var(--line);
  box-shadow: var(--shadow), var(--edge);
}

/* Ничего не светится: личные данные и всюду, где выбран монохром.
 *
 * Свечение приходит из общих правил — у кнопок, колец и активных
 * вкладок. В цветной среде оно уместно, на угольной превращает экран в
 * витрину. Гасим одним местом, а не выискивая каждое правило.
 *
 * Направление и набор оба в списке: в «Личных данных» это правило
 * держится с любым цветом (там считают деньги, и лишний свет спорит с
 * цифрами), а монохром гасит свет и в двух других направлениях. */
[data-domain="pim"] .btn--primary,
[data-domain="pim"] .ring,
[data-domain="pim"] .donut,
[data-domain="pim"] .tabbar__item.is-active,
[data-theme="mono"] .btn--primary,
[data-theme="mono"] .ring,
[data-theme="mono"] .donut,
[data-theme="mono"] .tabbar__item.is-active {
  box-shadow: none;
  filter: none;
}

/* А карточкам вес возвращаем: тень вниз плюс волосяная светлая кромка.
   Это не свечение — тень здесь затемняет фон под карточкой. */
[data-domain="pim"] .card,
[data-domain="pim"] .acc-tile,
[data-theme="mono"] .card,
[data-theme="mono"] .acc-tile {
  box-shadow: var(--shadow-soft), var(--edge);
}

/* Строка-предупреждение.
 *
 * Одна фраза о том, что стоит заметить, но что не является ошибкой:
 * два дела на один час, например. Поэтому янтарная, а не красная —
 * человека не в чем упрекнуть, ему просто показывают то, чего он мог
 * не заметить, заводя дела в разные дни и разные экраны. */
.warn-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--gap);
  padding: 9px 12px;
  border-radius: var(--r-sm);
  background: var(--warn-soft);
  border: 1px solid color-mix(in oklab, var(--warn) 32%, transparent);
  color: var(--warn);
  font-size: 12.5px;
  line-height: 1.45;
}

.warn-line__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.warn-line__icon svg { width: 15px; height: 15px; }

/* ---------- Экран подписки ---------- */

/* Поверх всего: это не окно, которое закрывают крестиком, а состояние
   приложения. Закрыть его можно двумя способами — оплатить или уйти
   смотреть свои записи; обе двери на экране есть. */
.paywall {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: max(16px, env(safe-area-inset-left, 0px));
  padding-top: calc(16px + max(env(safe-area-inset-top, 0px), var(--tg-safe-top, 0px)));
  padding-bottom: calc(16px + max(env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px)));
  background: var(--bg);
  overflow-y: auto;
}

.paywall__box {
  width: 100%;
  max-width: 460px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.paywall__lead { font-size: 13.5px; line-height: 1.6; }

.paywall__gives {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 6px 0 2px;
}

.paywall__give {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  font-size: 13px;
}

.paywall__give span { font-size: 12.5px; line-height: 1.5; }

.paywall__price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
  font-size: 17px;
}

.paywall__price span { font-size: 13px; }

.paywall__actions { display: flex; gap: 8px; margin-top: 4px; }
.paywall__buy { flex: 1; }

.paywall__note { font-size: 12px; line-height: 1.6; margin-top: 2px; }

.paywall__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}

/* Пока экран подписки открыт, приложение под ним не прокручивается. */
[data-paywall] body { overflow: hidden; }

/* ---------- Плитки тренировок ---------- */

/* Две в ряд: названия короткие («Спина 1»), а тап должен попадать пальцем
   без прицеливания — отсюда и высота, и крупный шрифт заголовка. */
.wtiles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.wtile {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  overflow: hidden;
}

.wtile__go {
  display: block;
  width: 100%;
  min-height: 104px;
  padding: 14px 34px 12px 14px;
  text-align: left;
  background: none;
  border: none;
}

.wtile:hover { border-color: var(--accent); }

.wtile__title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}

.wtile__note {
  margin-top: 4px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.35;
}

.wtile__meta {
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--accent);
}

/* Точки в углу: всё, что не «начать», живёт здесь — чтобы промах пальцем
   не открывал редактор вместо зала. */
.wtile__more {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text-dim);
}

.wtile__more:hover { background: var(--card-hover); color: var(--text); }
.wtile__more svg { width: 16px; height: 16px; }

/* Идущая тренировка — карточка с цветной кромкой: её видно с любой
   вкладки, и ни с чем другим она не спутается. */
.card--live { border-color: var(--accent); }

.card--tap { display: block; text-align: left; }
.card--tap:hover { border-color: var(--accent); }

/* Ответ помощника: текст абзацами, как письмо, а не как таблица. */
.review {
  margin-top: var(--gap);
  padding-top: var(--gap-sm);
  border-top: 1px solid var(--line);
}

.review__text {
  font-size: 13.5px;
  line-height: 1.65;
  white-space: pre-wrap;
}
