/* ============================================================
   ZamaCards — мини-приложение.
   Ни одного хардкод-хекса: всё через var(--*) из tokens.css.
   Ни одного правила «если тема тёмная»: разница между темами
   уже разведена токенами.
   ============================================================ */

html,
body {
  height: 100%;
  overscroll-behavior-y: none;
}

body {
  -webkit-tap-highlight-color: transparent;
  text-rendering: optimizeLegibility;
}

/* Полоса прокрутки. Прячем совсем: в WebKit на macOS полоса рисуется системой
   поверх контента, и ::-webkit-scrollbar её не берёт — сузить не выходит,
   только убрать через scrollbar-width. Индикатор здесь и не нужен: мини-апп
   листают пальцем, а на десктопе прокрутка и так очевидна по движению. */
html,
body,
* {
  scrollbar-width: none;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar,
::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

/* ---------- Каркас экрана ---------------------------------- */

#app {
  position: relative;
  z-index: 1;
  /* Каркас прибит к полной высоте вьюпорта, а не к содержимому: на десктопе
     (Telegram Desktop, движок WebKitGTK) окно мини-аппа само подстраивает
     высоту под страницу, и динамическая 100dvh замыкала петлю — окно → dvh →
     содержимое → размер окна, отсюда прыганье при открытии. Якорь в стабильную
     высоту, которую Telegram знает сам (--tg-viewport-stable-height), а без
     неё — в 100dvh, и только если и той нет (старые WebKit) — в 100vh. */
  min-height: 100vh;
  min-height: var(--tg-viewport-stable-height, 100dvh);
  display: flex;
  flex-direction: column;

  /* Сколько занято снизу: системная зона плюс таб-бар, если он показан */
  --bottom-gap: var(--safe-bottom);
}

#app[data-tabs='1'] {
  --bottom-gap: calc(var(--tabbar-h) + var(--safe-bottom));
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  animation: screen-in var(--duration-slow) var(--ease-in-out);
}

/*
  Корень экрана — обычный <div> с шапкой, телом и кнопками. Без этого правила
  он остаётся высотой по контенту: .body { flex: 1 } растягивать нечего,
  .actions { margin-top: auto } некуда двигать, и на коротких экранах кнопка
  повисала сразу под текстом посреди пустоты вместо низа.
*/
.screen > * {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.screen--back { animation: screen-back var(--duration-slow) var(--ease-in-out); }

@keyframes screen-in {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}

@keyframes screen-back {
  from { opacity: 0; transform: translateX(-16px); }
  to   { opacity: 1; transform: none; }
}

/*
  Переключение вкладки — не углубление в стек, а переход вбок между равными
  разделами. Боковой сдвиг здесь врал бы про иерархию, поэтому раздел
  проявляется и чуть подаётся вверх: движение мягче и не спорит с пилюлей,
  которая в это же время едет по доку.
*/
.screen--tab { animation: screen-tab var(--duration-slow) var(--ease-out); }

@keyframes screen-tab {
  from { opacity: 0; transform: translateY(8px) scale(0.994); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Плита и лист ------------------------------------
   Каждый экран начинается с плиты --color-plate: на главной на ней баланс,
   на остальных — заголовок. Три грани одного тона с разной светлотой по
   одной диагонали (сверху-справа вниз-влево). У «Полночи» плита темнее
   кнопки, у цветных палитр это цвет действия. Лист с содержимым наезжает
   на плиту скруглением. Шапку Telegram tg.js красит в цвет плиты, поэтому
   плита и шапка читаются одним куском.
   Облик и решения: docs/design/BRAND.md.
   ------------------------------------------------------------ */

.top {
  position: relative;
  padding: var(--space-1) var(--screen-padding) 40px;
  background: var(--color-plate);
  color: var(--color-text-on-plate);
  overflow: hidden;
  isolation: isolate;
}

.facet {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.facet--1 { background: var(--color-plate-facet-1); clip-path: polygon(0 0, 58% 0, 26% 100%, 0 100%); }
.facet--2 { background: var(--color-plate-facet-2); clip-path: polygon(72% 0, 100% 0, 100% 58%); }
.facet--3 { background: var(--color-plate-facet-1); opacity: 0.55; clip-path: polygon(60% 0, 66% 0, 34% 100%, 28% 100%); }

/* Скелетон на плите — её же чернилами: грунт листа горел бы на ней
   светлой плашкой, пока грузится баланс. */
.top .skel { background: color-mix(in srgb, var(--color-text-on-plate) 12%, transparent); }

.top__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 48px;
}

/* Кнопки на плите: аватар, поддержка, «назад» в браузере. Цвет — чернила плиты. */
.top__ava,
.top__btn {
  display: grid;
  place-items: center;
  width: var(--tap-target);
  height: var(--tap-target);
  padding: 0;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: color-mix(in srgb, var(--color-text-on-plate) 84%, transparent);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out);
}

.top__btn svg { width: 22px; height: 22px; }

.top__ava:active,
.top__btn:active { background: color-mix(in srgb, var(--color-text-on-plate) 12%, transparent); }

.ttl { padding: var(--space-2) 0 var(--space-1); }

.ttl__t {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

.ttl__s {
  display: block;
  margin-top: 2px;
  font-size: var(--text-sm);
  color: color-mix(in srgb, var(--color-text-on-plate) 80%, transparent);
}

/* Лист. Наезжает на плиту скруглением; тень — токен темы: в светлых видна,
   в тёмных почти нет, как и задумано. */
.body {
  position: relative;
  flex: 1;
  margin-top: calc(-1 * var(--sheet-overlap));
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  background: var(--color-bg);
  box-shadow: var(--shadow-sheet);
  padding: var(--space-5) var(--screen-padding) calc(var(--bottom-gap) + var(--space-6));
}

/* Экран-состояние: ждём платёж, выпускаем карту, не получилось. Контента мало,
   и прижатый к шапке блок с пустотой под ним читается как обрывок страницы.
   Ставим его по центру свободной высоты — между шапкой и кнопками. */
.body--center {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/*
  Кнопка действия — в потоке, а не fixed. Fixed перекрывала итоговые суммы
  на коротких экранах: контент кончался под ней. Sticky прижимает её к низу,
  пока есть куда скроллить, и никогда не наезжает на текст.
*/
.actions {
  position: sticky;
  bottom: calc(var(--bottom-gap) + var(--space-3));
  z-index: var(--z-nav);
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3) var(--screen-padding) 0;
  margin-top: auto;
  background: linear-gradient(180deg, transparent, var(--color-bg) 40%);
}

.actions::after {
  content: '';
  display: block;
  height: var(--space-3);
}

.actions--inline {
  position: static;
  margin-top: 0;
  padding: var(--space-6) 0 0;
  background: none;
}

.actions--inline::after { display: none; }

/* ---------- Нижняя навигация -------------------------------- */

/*
  Внешний слой не ловит тапы (pointer-events: none) — он нужен только ради
  градиента, которым контент гасится под доком. Тапы принимает сам док.
*/
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-nav);
  display: flex;
  justify-content: center;
  padding: var(--space-2) var(--screen-padding) calc(var(--safe-bottom) + var(--space-3));
  pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--color-bg) 55%);
}

.tabbar__dock {
  pointer-events: auto;
  display: flex;
  gap: var(--space-1);
  width: 100%;
  max-width: 420px;
  padding: var(--space-1);
  border-radius: var(--radius-xl);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
  box-shadow: var(--shadow-modal);
}

/*
  Подпись есть только у текущего раздела. Четыре иконки с подписями под каждой
  давали слишком плотный низ; куда я нажал — и так видно по заливке. Название
  остаётся в разметке для чтения с экрана через aria-label кнопки.
*/
.tab {
  /* Ширины анимируются через flex-grow: у активного 1.8125, у остальных 1.
     На доке 320px это ровно 116px и 64px — размеры из макета. */
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 var(--space-1);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--duration-normal) var(--ease-out),
              background-color var(--duration-normal) var(--ease-out),
              flex-grow var(--duration-slow) var(--ease-in-out),
              padding var(--duration-slow) var(--ease-in-out);
}

.tab__ico { display: flex; }
.tab__ico svg { width: 22px; height: 22px; }

/* Подпись прячется шириной, а не display: none — display не анимируется,
   и подпись появлялась рывком в уже разъехавшейся пилюле. */
.tab__label {
  max-width: 0;
  margin-left: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-width var(--duration-slow) var(--ease-in-out),
              margin-left var(--duration-slow) var(--ease-in-out),
              opacity var(--duration-fast) var(--ease-out);
}

.tab:active:not([aria-current='page']) { background: var(--color-surface-2); }

.tab[aria-current='page'] {
  flex-grow: 1.8125;
  padding: 0 var(--space-4);
  color: var(--color-accent);
  background: var(--color-accent-bg);
}

.tab[aria-current='page'] .tab__label {
  max-width: 8rem;
  margin-left: var(--space-2);
  opacity: 1;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  /* 16px по бокам, а не 20: на кнопке в половину экрана (360px) те четыре
     лишних пикселя с каждой стороны и съедали место у подписи. */
  padding: 0 var(--space-4);
  /* Кнопка — flex-элемент, а он по умолчанию не сжимается уже содержимого
     и вылезает за сетку. Разрешаем сжиматься и переносить подпись. */
  min-width: 0;
  text-wrap: balance;
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-2);
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  text-align: center;
  transition: background-color var(--duration-instant) var(--ease-out),
              transform var(--duration-instant) var(--ease-out);
}

.btn:active:not(:disabled) { transform: scale(0.98); }

.btn--primary {
  background: var(--color-primary);
  color: var(--color-text-on-primary);
  /* Кнопку опознаёт подпись: у «Полночи» в ночи заливка к фону 2.01, и это
     сознательное исключение (COLORS.md, п. 3). Граница — тонкая кромка
     в тон карточек, а не контур. */
  border-color: var(--color-border);
}

.btn--primary:active:not(:disabled) { background: var(--color-primary-press); }

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--color-text-2);
}

.btn--danger {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.btn:disabled {
  background: var(--color-surface-2);
  color: var(--color-text-disabled);
  border-color: var(--color-border-subtle);
}

.btn--primary:disabled { background: var(--color-surface-2); }
.btn--wide { width: 100%; }
.btn--busy { pointer-events: none; }

/* Ширина кнопки при загрузке не меняется — иначе она прыгает */
.btn__spinner {
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: spin 700ms linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-target);
  height: var(--tap-target);
  flex: 0 0 var(--tap-target);
  border-radius: var(--radius-md);
  border: none;
  background: transparent;
  color: var(--color-text-2);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out);
}

.icon-btn:active { background: var(--color-surface-2); }
.icon-btn svg { width: 22px; height: 22px; }

/* ---------- Типографика и деньги ---------------------------- */

.eyebrow {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-3);
}

.section { margin-top: var(--space-6); }

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

.section__title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.link {
  border: none;
  background: none;
  padding: 0;
  color: var(--color-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

/* Текстовая ссылка как самостоятельное действие («Ввести вручную», «Открыть»):
   строка текста в 18px — не тач-цель. Растягиваем область нажатия до минимума,
   а отрицательные поля возвращают сам текст на линию соседнего контента. */
.link--tap {
  min-height: var(--tap-target);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  margin-left: calc(-1 * var(--space-2));
  margin-right: calc(-1 * var(--space-2));
}

.muted { color: var(--color-text-2); }
.dim   { color: var(--color-text-3); font-size: var(--text-sm); }

.note {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--color-text-2);
}

.money {
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-tight);
}

.money__cents,
.money__cur {
  font-size: 0.55em;
  font-weight: var(--weight-semibold);
  color: var(--color-text-2);
  letter-spacing: 0;
}

/* ---------- Баланс на плите --------------------------------- */

/* Высота фиксирована: на плите живут и баланс карты, и надпись у плитки
   «выпустить ещё». Без общей высоты плита прыгала при листании колоды. */
.bal {
  position: relative;
  display: grid;
  align-content: center;
  min-height: 132px;
  text-align: center;
  padding: var(--space-3) 0 var(--space-5);
}

.bal__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: color-mix(in srgb, var(--color-text-on-plate) 84%, transparent);
}

/* Глаз прячет сумму. Тач-цель шире рисунка: кнопка 28, иконка 18. */
.eye {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.eye svg { width: 18px; height: 18px; }
.eye__off { display: none; }
.is-hidden .eye__on { display: none; }
.is-hidden .eye__off { display: block; }

/* Самое крупное на экране */
.bal__num {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-4xl);
  font-weight: var(--weight-extra);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-on-plate);
  white-space: nowrap;
}

/*
  Общее правило уводит копейки и знак валюты в 0.55em — в списке операций это
  верно, а на сорокачетырёхпунктовой сумме давало 24-й кегль: «$» читался как
  обрубок. У баланса рост полный, разница держится цветом. Правило точечное.
*/
.bal__num .money__cents,
.bal__num .money__cur {
  font-size: 1em;
  font-weight: inherit;
  letter-spacing: inherit;
  color: color-mix(in srgb, var(--color-text-on-plate) 72%, transparent);
}

/* Рублёвый эквивалент — ответ на «это сколько в рублях», сразу под суммой */
.bal__rub {
  margin-top: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--color-text-on-plate) 84%, transparent);
}

.bal__rub .money__cents,
.bal__rub .money__cur { font-size: 1em; font-weight: inherit; color: inherit; }

.bal__mask { display: none; }
.is-hidden .bal__val { display: none; }
.is-hidden .bal__mask { display: inline; }

.bal__status { margin-top: var(--space-2); }

/* Листнули колоду — баланс на плите меняется проявлением, а не подменой
   в кадре. 180 мс: заметно, что это другая карта, и не тормозит палец. */
@keyframes bal-swap {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.bal--swap > * { animation: bal-swap var(--duration-normal) var(--ease-out); }

/* Оффер на плите, когда карты нет */
.hero {
  padding: var(--space-2) var(--space-1) var(--space-5);
  text-align: center;
}

.hero__t {
  margin: 0;
  font-size: var(--text-2xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

.hero__s {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: color-mix(in srgb, var(--color-text-on-plate) 82%, transparent);
  text-wrap: balance;
}

/* ---------- Быстрые действия: плитки под картой -------------- */

.quick {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* Плитка целиком: иконка и подпись внутри. 12px, а не 11: на трёх плитках
   «Заморозить» помещается в строку, а на четырёх — только на 11. */
.quick__btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 68px;
  min-width: 0;
  padding: 0 var(--space-1);
  border: var(--border-width) solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  background: var(--color-surface-1);
  color: var(--color-text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              transform var(--duration-instant) var(--ease-out);
}

.quick__btn:active {
  background: var(--color-surface-2);
  transform: scale(0.96);
}

.quick__ring { display: grid; place-items: center; }
.quick__ring svg { width: 22px; height: 22px; }

/* Знак СБП уже, чем квадратные иконки (20.79 × 24), поэтому ширину не задаём —
   иначе он растянется. Высота на 2px больше: цветной знак рядом со
   штриховыми иначе читается мельче. */
.quick__sbp { display: flex; }
.quick__sbp svg { width: auto; height: 24px; }

.quick__btn:disabled { opacity: 0.4; pointer-events: none; }

/* Акцентный — только «Пополнить». Заливки нет: зелёный сегмент знака СБП
   сливался бы с primary. Акцент несёт цветной знак и яркая подпись. */
.quick__btn--accent { color: var(--color-text); border-color: var(--color-border-strong); }

/* ---------- Виртуальная карта ------------------------------- */

/*
  Пластик — тёмный камень в тон темы. Собственных цветов нет: заливка
  --card-stone, грани --card-stone-1/2, печать — чернила --card-ink с
  прозрачностью на месте. Карта тёмная во всех темах: на светлом листе она
  главный предмет экрана, как чёрная карта на жёлтом в референсе, на тёмном
  её держат грани и кромка. Гряды, водяной знак и блики сняты: фактуру
  дают грани.
*/
.plastic {
  position: relative;
  aspect-ratio: 1.586;
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  isolation: isolate;
  background: var(--card-stone);
  color: var(--card-ink);
  border: var(--border-width) solid var(--card-edge);
  /* Тонкий блик по верхней кромке: предмет, а не плашка */
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--card-ink) 12%, transparent);
}

/* Тень видна только в светлых темах — в тёмных её нет, так и задумано */
.plastic:not(.plastic--mini):not(.plastic--teaser) {
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--card-ink) 12%, transparent),
              var(--shadow-modal);
}

.plastic--frozen::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--card-frozen);
}

/* Грани: две плоскости и кромка по той же диагонали, что грани плиты.
   Штрих кромки не масштабируется вместе с растянутым SVG. */
.plastic__facets {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.plastic__facets svg { width: 100%; height: 100%; display: block; }
.plastic__facet-1 { fill: var(--card-stone-1); }
.plastic__facet-2 { fill: var(--card-stone-2); }

.plastic__edge {
  stroke: color-mix(in srgb, var(--card-ink) 16%, transparent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.plastic__top {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.plastic__logo { width: 30px; height: 30px; }
/* Знак на пластике — теми же чернилами, что печать: второй цвет на камне лишний */
.plastic__logo path { fill: color-mix(in srgb, var(--card-ink) 92%, transparent); }

.plastic__virtual {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.16em;
  color: color-mix(in srgb, var(--card-ink) 68%, transparent);
}

/*
  Номер набирается в одну строку всегда. На узких экранах (320) шестнадцать
  знаков не влезали 22-м кеглем и ломались пополам — карта переставала быть
  картой. Кегль привязан к ширине экрана: пластик тянется по ней же, так что
  номер занимает одну и ту же долю карты на любом телефоне.
*/
.plastic__num {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  white-space: nowrap;
  font-size: clamp(16px, 5.6vw, var(--text-xl));
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--card-ink) 92%, transparent);
}

/* Номер-призрак, пока карта не выпущена: обязан читаться как «здесь пока пусто» */
.plastic__num--ghost { color: color-mix(in srgb, var(--card-ink) 55%, transparent); }

.plastic__mid { position: relative; z-index: 1; }
.plastic__mid .plastic__chip { margin-bottom: var(--space-3); }

/*
  Чип. У виртуальной карты его физически нет — это витринная условность,
  принятая владельцем осознанно: без чипа пластик читался как пустой
  прямоугольник. Золотой во всех темах: у настоящих карт он такой.
*/
.plastic__chip {
  position: relative;
  display: block;
  flex: 0 0 auto;
  width: 38px;
  height: 28px;
  border-radius: var(--radius-sm);
  background: var(--card-chip);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25);
}

/* Две насечки контактной площадки — без них чип выглядит наклейкой */
.plastic__chip::after {
  content: '';
  position: absolute;
  inset: 5px 4px;
  border-left: var(--border-width) solid rgba(0, 0, 0, 0.35);
  border-right: var(--border-width) solid rgba(0, 0, 0, 0.35);
}

.plastic__foot {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
}

.plastic__field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.plastic__field--right { align-items: flex-end; text-align: right; }

.plastic__cap {
  font-size: 8px;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--card-ink) 70%, transparent);
}

.plastic__name {
  max-width: 55vw;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: 0.03em;
  color: color-mix(in srgb, var(--card-ink) 78%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Срок и знак сети стоят в ряд, знак — по центру блока со сроком */
.plastic__right {
  display: flex;
  align-items: center;
  gap: 9px;
}

.plastic__date {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--card-ink) 85%, transparent);
}

.plastic__net {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--card-ink) 78%, transparent);
}

/* Знак платёжной системы. Задаём только высоту — ширину считает viewBox (1.55),
   иначе круги превращаются в овалы. 21px — рост прописной у соседнего слова
   VIRTUAL: знак встаёт с датой в один оптический ряд и не перевешивает её. */
.plastic__net-mark { display: flex; }
.plastic__net-mark .plastic__mark { width: auto; height: 21px; }

/*
  Словесный знак Visa. Настоящий логотип набран собственным шрифтом платёжной
  системы — это чужой товарный знак, файла у нас нет. Здесь его форма собрана
  шрифтом карты: жирное начертание с наклоном 8°, как в оригинале.
*/
.plastic__net--visa {
  display: inline-block;
  font-size: 17px;
  font-weight: var(--weight-extra);
  letter-spacing: 0.01em;
  color: color-mix(in srgb, var(--card-ink) 95%, transparent);
  transform: skewX(-8deg);
}

/* Плашка в списках: только знак */
.plastic--mini {
  width: 52px;
  aspect-ratio: 1.586;
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  flex: 0 0 auto;
  justify-content: flex-start;
}

.plastic--mini .plastic__logo { width: 15px; height: 15px; }

/* Карта-витрина в оффере на пустой главной: тот же пластик мельче, с наклоном */
.plastic--teaser {
  width: 116px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
}

.plastic--teaser .plastic__logo { width: 18px; height: 18px; }
.plastic--teaser .plastic__virtual { font-size: 8px; }
.plastic--teaser .plastic__chip { width: 24px; height: 17px; border-radius: 4px; }
.plastic--teaser .plastic__mid .plastic__chip { margin-bottom: 6px; }
.plastic--teaser .plastic__num { font-size: 11px; letter-spacing: 0.04em; }
.plastic--teaser .plastic__cap { font-size: 6px; }
.plastic--teaser .plastic__name,
.plastic--teaser .plastic__date { font-size: 8px; }
/* На витрине нижняя строка (владелец, срок, сеть) не помещается по высоте
   и резалась пополам — на 116px она всё равно не читалась. Чип и номер
   опускаются вниз сами: justify-content: space-between. */
.plastic--teaser .plastic__foot { display: none; }

/* Полноширинная карта-кнопка на главной */
.card-tap {
  position: relative;
  display: block;
  width: 100%;
  /* Кнопка по умолчанию центрирует текст, и номер карты уезжал в середину
     вместо левого края. Карта внутри неё — обычный блок, выравнивание своё. */
  text-align: left;
  padding: 0;
  border: none;
  background: none;
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: transform var(--duration-instant) var(--ease-out);
}

.card-tap:active { transform: scale(0.99); }

/* ---------- Переворот карты и её оборот ---------------------
   Реквизиты показываются на самом пластике: там, куда человек и так смотрит.
   Переворот — 250 мс, потолок Telegram; двигаются только transform и opacity.
   ------------------------------------------------------------ */

.card-flip {
  perspective: 1400px;
  cursor: pointer;
}

.card-flip__inner {
  position: relative;
  transform-style: preserve-3d;
  transition: transform var(--duration-slow) var(--ease-in-out);
}

.card-flip--open .card-flip__inner { transform: rotateY(180deg); }

/* Грань, отвёрнутая от зрителя, не должна просвечивать сквозь пластик.
   Свойство нужно и на самом пластике: у него свой контекст наложения,
   и в WebKit без этого сквозь карту видно зеркальную изнанку. */
.card-flip__face,
.card-flip__face > .plastic {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.card-flip__face--back {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
}

/* Пока карта лицом вверх, оборот не ловит нажатия — иначе невидимые кнопки
   копирования перехватывают тап по пластику. */
.card-flip:not(.card-flip--open) .card-flip__face--back { pointer-events: none; }
.card-flip--open .card-flip__face--front { pointer-events: none; }

/* Открытая карта не должна ужиматься под пальцем: тап по ней теперь копирует
   поле, а не «нажимает карту целиком». */
.card-flip--open:active { transform: none; }

/* Высота задана лицевой стороной (ISO-пропорция), и оборот обязан уложиться
   в неё ровно: у пластика overflow: hidden, вылезший отсчёт просто обрежется.
   Поэтому здесь всё считано под 360 — полоса 38, три строки по 32, отсчёт. */
.plastic--back {
  height: 100%;
  justify-content: flex-start;
  gap: 0;
  padding: 0 0 var(--space-3);
}

/* Магнитная лента. Не плашка во всю ширину: жёсткий прямоугольник поперёк
   карты выглядел как незагрузившийся блок. Лента растворяется у краёв, а
   читается за счёт кромок — блик сверху, тень снизу. Именно они держат её
   на тёмном пластике, где чёрное на чёрном само по себе не видно. */
.cardback__stripe {
  display: block;
  height: 38px;
  margin-top: var(--space-3);
  background: var(--card-stripe);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--card-ink) 20%, transparent),
              inset 0 -1px 0 color-mix(in srgb, var(--card-ink) 10%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 13%, #000 87%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 13%, #000 87%, transparent 100%);
}

.cardback__rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-4) 0;
}

.cardback__pair { display: flex; gap: var(--space-2); }
.cardback__pair .cardback__row { flex: 1; }

.cardback__row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  width: 100%;
  min-height: 32px;
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--card-ink);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}

.cardback__row:active {
  background: color-mix(in srgb, var(--card-ink) 12%, transparent);
}

/* Скопировано — короткая обводка вместо тоста: тост перекрыл бы саму карту. */
.cardback__row--copied {
  border-color: color-mix(in srgb, var(--card-ink) 34%, transparent);
  background: color-mix(in srgb, var(--card-ink) 10%, transparent);
}

.cardback__key {
  flex: 0 0 auto;
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--card-ink) 60%, transparent);
}

.cardback__val {
  flex: 1;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--card-ink) 95%, transparent);
}

/* 16px, не 18: на 360 восемнадцатый кегль с разрядкой переносил номер пополам */
.cardback__row--pan .cardback__val {
  font-size: var(--text-base);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.cardback__copy {
  flex: 0 0 auto;
  color: color-mix(in srgb, var(--card-ink) 55%, transparent);
}

.cardback__copy svg { width: 15px; height: 15px; display: block; }

/* Держатель — не поле, а вход в «Данные для оплаты»: у него слабая подложка
   и кромка, чтобы строка читалась как кнопка, а стрелка не терялась среди
   иконок копирования. Цвет берётся из печати карты, поэтому работает во
   всех темах и на любом пластике. */
.cardback__row--more {
  background: color-mix(in srgb, var(--card-ink) 8%, transparent);
  border-color: color-mix(in srgb, var(--card-ink) 16%, transparent);
}

.cardback__row--more .cardback__copy {
  color: color-mix(in srgb, var(--card-ink) 80%, transparent);
}

/* Отсчёт до автоскрытия — по нижнему краю карты, как строка состояния. */
.cardback__timer {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: auto;
  padding: 0 var(--space-5) 0 var(--space-4);
  font-size: var(--text-2xs);
  color: color-mix(in srgb, var(--card-ink) 62%, transparent);
}

.cardback__timer svg { width: 13px; height: 13px; flex: 0 0 13px; }
.cardback__left { font-variant-numeric: tabular-nums; }

.cardback__track {
  flex: 1;
  height: 2px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--card-ink) 22%, transparent);
  overflow: hidden;
}

.cardback__bar {
  display: block;
  height: 100%;
  width: 100%;
  background: color-mix(in srgb, var(--card-ink) 70%, transparent);
  transform-origin: left;
  transition: transform 1s linear;
}

.cardback__load { padding: var(--space-4) var(--space-5); }

.cardback__error {
  padding: 0 var(--space-5);
  font-size: var(--text-sm);
  color: var(--card-ink);
}

.cardback__hint {
  padding: 0 var(--space-5);
  font-size: var(--text-xs);
  color: color-mix(in srgb, var(--card-ink) 60%, transparent);
}

/* Пластик стоит первым на листе и на главной, и на экране карты */
.card-tap--flush { margin-top: 0; }

.card-tap__status {
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

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

   Ширина карты — ровно ширина листа, а сосед виден узкой полоской в
   `--deck-peek`. Так получается из-за того, что полоска берётся из зазора
   между картами, а не из ширины самой карты: карта стоит по тем же полям,
   что и всё остальное на экране, и первая карта не съезжает — центрировать
   её больше не нужно, она и так на месте. Прежние 86% ширины давали кусок
   чужой карты сбоку и перекошенный экран на первой карте.
   ------------------------------------------------------------ */

.deck {
  /* Сколько видно соседней карты. Это подсказка «здесь можно листать»,
     а не вторая карта на экране: всё, что толще, читается как обрезок. */
  --deck-peek: 8px;

  display: flex;
  gap: var(--deck-peek);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--screen-padding);
  scrollbar-width: none;
  /* Выходим за поля листа: колода едет от края экрана до края */
  margin: 0 calc(var(--screen-padding) * -1);
  padding: 0 var(--screen-padding);
}

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

.deck__item {
  flex: 0 0 100%;
  min-width: 0;
  scroll-snap-align: center;
  /* Сосед чуть приглушён: на полоске в восемь пикселей разница почти не
     видна, зато при листании карта «выходит на свет» — это и подсказывает,
     какая из них сейчас в руках. Сильнее гасить нельзя: на тёмной теме
     полоска пропала бы совсем, а вместе с ней и намёк, что колода листается. */
  opacity: 0.7;
  transition: opacity var(--duration-slow) var(--ease-out);
}

.deck__item.is-on { opacity: 1; }

/* Точки — единственный статичный признак того, сколько всего карт.
   Последняя, у плитки выпуска, полая: она про действие, а не про карту. */
.deck__dots {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* Активная точка вытягивается в пилюлю, а не просто меняет цвет: положение
   в колоде читается краем глаза, без пересчёта кружков. */
.deck__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  transition: width var(--duration-normal) var(--ease-out),
              background-color var(--duration-normal) var(--ease-out),
              box-shadow var(--duration-normal) var(--ease-out);
}

.deck__dot.is-on { width: 18px; background: var(--color-text); }
.deck__dot--add { background: none; box-shadow: inset 0 0 0 1.5px var(--color-border-strong); }
.deck__dot--add.is-on { background: none; box-shadow: inset 0 0 0 1.5px var(--color-text); }

.deck__add {
  width: 100%;
  aspect-ratio: 1.586;
  /* Пунктир того же радиуса, что у пластика: плитка стоит в одном ряду
     с картами и не выбивается формой. */
  border-radius: var(--radius-card);
  border: var(--border-width) dashed var(--color-border-strong);
  background: transparent;
  color: var(--color-text-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  transition: transform var(--duration-instant) var(--ease-out);
}

.deck__add:active { transform: scale(0.99); }
.deck__plus { display: grid; place-items: center; }
.deck__add svg { width: 24px; height: 24px; }
.deck__addtitle { color: var(--color-text); }
.deck__addsub { font-size: var(--text-xs); font-weight: var(--weight-regular); }

/* ---------- Карточки списка --------------------------------- */

.tile {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out);
}

.tile:active { background: var(--color-surface-2); }
.tile + .tile { margin-top: var(--space-3); }

/* Плитка-справка (какую карту пополняем): не кнопка, не нажимается. */
.tile--static { cursor: default; }
.tile--static:active { background: var(--color-surface-1); }

.tile__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.tile__grow { flex: 1; min-width: 0; }

.tile__title {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Рядом с чипом статуса места мало — подпись обрезаем, а не ломаем строку */
.tile__sub {
  font-size: var(--text-sm);
  color: var(--color-text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tile__amount {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---------- Чипы статусов ----------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

.chip svg { width: 12px; height: 12px; }

.chip--success { background: var(--color-success-bg); color: var(--color-success); }
.chip--warning { background: var(--color-warning-bg); color: var(--color-warning); }
.chip--info    { background: var(--color-info-bg);    color: var(--color-info); }
.chip--danger  { background: var(--color-danger-bg);  color: var(--color-danger); }

/* ---------- Поля -------------------------------------------- */

.field { display: block; margin-top: var(--space-4); }

.field__label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-2);
}

.field__input {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border-strong);
  background: var(--color-surface-2);
  color: var(--color-text);
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
}

.field__input:focus-visible { border-color: var(--color-accent-glow); }
.field--error .field__input { border-color: var(--color-danger); }

.field__error {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-danger);
}

/* Подсказка под полем — не ошибка: человек ничего не сделал не так
   («Telegram не передал номер»), красить её красным было бы нечестно. */
.field__hint {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-3);
}
.field__hint:empty { display: none; }

.presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.preset {
  min-height: var(--tap-target);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  color: var(--color-text-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.preset[aria-pressed='true'] {
  background: var(--color-accent-bg);
  border-color: var(--color-accent-glow);
  color: var(--color-text);
}

/* ---------- Выбор варианта ---------------------------------- */

.option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  color: var(--color-text);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}

.option + .option { margin-top: var(--space-3); }

.option[aria-pressed='true'] {
  border-color: var(--color-accent-glow);
  background: var(--color-surface-2);
}

.option__mark {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  border-radius: var(--radius-full);
  border: 2px solid var(--color-border-strong);
}

.option[aria-pressed='true'] .option__mark {
  border-color: var(--color-accent-glow);
  background: var(--color-accent-glow);
  box-shadow: inset 0 0 0 4px var(--color-surface-2);
}

.option__art {
  width: 44px;
  height: 28px;
  flex: 0 0 44px;
  border-radius: var(--radius-sm);
  border: var(--border-width) solid var(--card-edge);
}

/* Вариант, который срабатывает сразу по тапу (выбор шлюза оплаты): вместо
   отметки — шеврон, иначе строка обещает выбор, а не переход. */
.option__grow { flex: 1; min-width: 0; }

.option__title {
  display: block;
  font-weight: 600;
}

.option__sub {
  display: block;
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--color-text-2);
}

.option__go {
  flex: 0 0 auto;
  color: var(--color-text-3);
}

.option__go svg { width: 18px; height: 18px; display: block; }

/* ---------- Строки «итого» ---------------------------------- */

.summary {
  margin-top: var(--space-6);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
}

.summary__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--color-text-2);
}

.summary__row b {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
}

.summary__row--total {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-border-subtle);
  font-size: var(--text-base);
  color: var(--color-text);
}

.summary__row--total b { font-size: var(--text-xl); }

/* Пояснение под подписью строки («требование банка…»): тише и мельче,
   чтобы не спорить с суммой справа. */
.summary__hint {
  display: block;
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--color-text-3);
}

/* ---------- Остаток на счёте ZamaCards ---------------------- */

/* Тихая плитка на главной: появляется только когда остаток не нулевой.
   Без цвета состояния — это не предупреждение и не успех, а справка
   с одним действием. */
.leftover {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
}

.leftover__text { flex: 1; min-width: 0; }

.leftover__title {
  font-size: var(--text-sm);
  color: var(--color-text-2);
  font-variant-numeric: tabular-nums;
}

.leftover__sub {
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--color-text-3);
}

.leftover .link--tap { flex: 0 0 auto; white-space: nowrap; }

/* Долг — тот же блок, но это уже про деньги, которые человек должен нам.
   Красным кромка и сумма: не тревога на весь экран, но и не справка. */
.leftover--debt {
  border-color: color-mix(in srgb, var(--color-danger) 45%, var(--color-border));
  background: var(--color-danger-bg);
}

.leftover--debt .leftover__title { color: var(--color-danger); font-weight: var(--weight-semibold); }

/* ---------- Что нельзя оплачивать и согласие ----------------- */
/*
  Запрет не наш — он в условиях банка-партнёра, а отказ по такой оплате
  стоит комиссии, которая ложится на владельца карты. Поэтому блок стоит
  до покупки и на самой карте, а не только в правилах: там его прочтут
  уже после первого списания.
*/
.rules {
  margin-top: var(--space-5);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
}

.rules__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
}

.rules__list {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-2);
}

.rules__hint {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--color-text-3);
}

.rules__more { margin-top: var(--space-2); }
.rules__more .link { font-size: var(--text-xs); }

/* Согласие перед оплатой. Мелкое и тихое: это не решение, а ссылка на то,
   где решение расписано целиком. */
.legal {
  margin: var(--space-4) 0 0;
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--color-text-3);
  text-align: center;
}

.legal .link { font-size: inherit; }

/* ---------- Реквизиты --------------------------------------- */

.secret {
  margin-top: var(--space-3);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  overflow: hidden;
}

.secret__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-4);
  background: transparent;
  border: none;
  border-bottom: var(--border-width) solid var(--color-border-subtle);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

.secret__row:last-child { border-bottom: none; }
.secret__row:active { background: var(--color-surface-2); }
/* Подтверждение копирования — на самой строке: поля списывают подряд,
   и тост перекрыл бы следующее. */
.secret__row--copied { background: var(--color-surface-2); }

.secret__key {
  display: block;
  font-size: var(--text-xs);
  line-height: 1.3;
  color: var(--color-text-2);
}

.secret__val {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  font-variant-numeric: tabular-nums;
  line-height: 1.35;
  letter-spacing: 0.06em;
  /* Адрес длиннее номера карты — пусть переносится, а не уезжает под иконку. */
  overflow-wrap: anywhere;
}

/* Подпись над второй группой строк (адрес). Такая же, как у ключа строки,
   но стоит снаружи блока, чтобы группа читалась как отдельная. */
.secret__label {
  margin: var(--space-4) var(--space-1) 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--color-text-2);
}

/* Адрес — слова, а не цифры: моноширинный здесь только мешает переносу. */
.secret__val--text {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  letter-spacing: 0;
}

.secret__copy { color: var(--color-text-3); flex: 0 0 auto; }
.secret__copy svg { width: 18px; height: 18px; display: block; }

/* ---------- Пусто, ошибка, партнёр недоступен --------------- */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-8) var(--space-4);
}

.empty__art {
  width: 56px;
  height: 56px;
  color: var(--color-text-3);
}

.empty__art svg { width: 100%; height: 100%; }

.empty__title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  text-wrap: balance;
}

.empty__text {
  margin: 0;
  max-width: 30ch;
  font-size: var(--text-sm);
  color: var(--color-text-2);
  text-wrap: balance;
}

.banner {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  font-size: var(--text-sm);
  color: var(--color-text-2);
}

.banner svg { width: 20px; height: 20px; flex: 0 0 20px; margin-top: 2px; }

/* Два действия в баннере счёта — «Открыть» и «Скрыть» — одной строкой.
   У ссылок отрицательные поля под тач-цель, поэтому зазор даёт gap, а не
   поля самих ссылок. */
.banner__acts { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.banner--warning { background: var(--color-warning-bg); color: var(--color-warning); border-color: transparent; }
.banner--danger  { background: var(--color-danger-bg);  color: var(--color-danger);  border-color: transparent; }
.banner--info    { background: var(--color-info-bg);    color: var(--color-info);    border-color: transparent; }

/* ---------- Скелетоны --------------------------------------- */

.skel {
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
  animation: skel 1.4s var(--ease-in-out) infinite;
}

@keyframes skel {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.skel--line { height: 14px; }
.skel--title { height: 44px; width: 62%; border-radius: var(--radius-md); }
.skel--tile { height: 76px; border-radius: var(--radius-lg); margin-top: var(--space-3); }
.skel--plastic { aspect-ratio: 1.586; border-radius: var(--radius-card); }
.skel--chip { height: 92px; border-radius: var(--radius-lg); }

/* ---------- Прогресс выпуска -------------------------------- */

.steps { margin-top: var(--space-6); display: grid; gap: var(--space-4); }

.step {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  font-size: var(--text-sm);
  color: var(--color-text-3);
}

.step__dot {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  border-radius: var(--radius-full);
  border: 2px solid var(--color-border-strong);
  display: grid;
  place-items: center;
}

.step__dot svg { width: 12px; height: 12px; }

.step--active { color: var(--color-text); }
.step--active .step__dot { border-color: var(--color-accent-glow); }

.step--done { color: var(--color-text-2); }
.step--done .step__dot {
  border-color: var(--color-accent-glow);
  background: var(--color-accent-glow);
  color: var(--color-text-on-primary);
}

/* ---------- Шит --------------------------------------------- */

.veil {
  position: fixed;
  inset: 0;
  z-index: var(--z-veil);
  background: var(--gradient-veil);
  opacity: 0;
  animation: veil-in var(--duration-slow) var(--ease-out) forwards;
}

@keyframes veil-in { to { opacity: 1; } }

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-sheet);
  /* Запасной 100vh на WebKit без dvh — как у каркаса выше */
  max-height: 86vh;
  max-height: 86dvh;
  overflow-y: auto;
  padding: var(--space-3) var(--screen-padding) calc(var(--safe-bottom) + var(--space-6));
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--color-surface-3);
  box-shadow: var(--shadow-sheet);
  transform: translateY(100%);
  animation: sheet-in var(--duration-slow) var(--ease-in-out) forwards;
}

@keyframes sheet-in { to { transform: none; } }

.sheet--closing { animation: sheet-out var(--duration-slow) var(--ease-in-out) forwards; }
@keyframes sheet-out { to { transform: translateY(100%); } }

.sheet__grip {
  width: 36px;
  height: 4px;
  margin: 0 auto var(--space-4);
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
}

.sheet__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

/* ---------- Тост -------------------------------------------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--safe-bottom) + var(--tabbar-h) + var(--space-4));
  z-index: var(--z-toast);
  transform: translate(-50%, 12px);
  opacity: 0;
  max-width: calc(100% - var(--space-8));
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-3);
  color: var(--color-text);
  font-size: var(--text-sm);
  text-align: center;
  animation: toast-in var(--duration-normal) var(--ease-out) forwards;
}

@keyframes toast-in { to { transform: translate(-50%, 0); opacity: 1; } }

.toast--closing { animation: toast-out var(--duration-normal) var(--ease-out) forwards; }
@keyframes toast-out { to { transform: translate(-50%, 12px); opacity: 0; } }

/* ---------- Списки операций и истории ----------------------- */

.rows { margin-top: var(--space-2); }

.row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: var(--border-width) solid var(--color-border-subtle);
}

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

/* Строка-кнопка: операция по карте открывает саму карту. Выглядит ровно как
   обычная строка — интерактивность выдаёт только отклик на нажатие. */
.row--tap {
  width: 100%;
  border-top: 0;
  border-left: 0;
  border-right: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.row--tap:active { opacity: 0.6; }

.row__icon {
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border-radius: var(--radius-md);
  display: grid;
  place-items: center;
  background: var(--color-surface-2);
  color: var(--color-text-2);
}

.row__icon svg { width: 18px; height: 18px; }
.row__icon--in { background: var(--color-money-in-bg); color: var(--color-money-in); }
.row__icon--out { background: var(--color-surface-2); color: var(--color-text-2); }
.row__icon--bad { background: var(--color-danger-bg); color: var(--color-danger); }

.row__grow { flex: 1; min-width: 0; }

.row__title {
  font-size: var(--text-base);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row__sub { font-size: var(--text-xs); color: var(--color-text-2); }

.row__amount {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.row__amount--in  { color: var(--color-money-in); }
.row__amount--out { color: var(--color-money-out); }
.row__amount--bad { color: var(--color-text-3); text-decoration: line-through; }

.day {
  margin: var(--space-5) 0 var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-3);
}

/* ---------- Фильтры ----------------------------------------- */

.filters {
  display: flex;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  overflow-x: auto;
  padding-bottom: var(--space-1);
  scrollbar-width: none;
}

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

.filter {
  flex: 0 0 auto;
  min-height: var(--tap-target);
  padding: 0 var(--space-4);
  border-radius: var(--radius-full);
  border: var(--border-width) solid var(--color-border);
  background: transparent;
  color: var(--color-text-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.filter[aria-pressed='true'] {
  background: var(--color-surface-2);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

/* Чип из одного знака («₽», «$») сам по себе уже, чем палец: ширину
   дотягиваем до тач-цели, иначе по нему промахиваются. */
.filter--currency {
  min-width: var(--tap-target);
  text-align: center;
}

/* Светлая или тёмная: иконка и слово в одной строке. */
.filter--mode {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.filter--mode svg {
  width: 16px;
  height: 16px;
}

/* Палитра Telegram сама решает, светло ей или темно: переключать нечего. */
.filter--mode:disabled {
  color: var(--color-text-disabled);
  cursor: default;
}

/* ---------- Профиль и настройки ----------------------------- */

.list {
  margin-top: var(--space-3);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  overflow: hidden;
}

.list__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 52px;
  padding: var(--space-3) var(--space-4);
  background: transparent;
  border: none;
  border-bottom: var(--border-width) solid var(--color-border-subtle);
  color: var(--color-text);
  font-size: var(--text-base);
  text-align: left;
  cursor: pointer;
}

.list__item:last-child { border-bottom: none; }
.list__item:active { background: var(--color-surface-2); }
.list__item svg { width: 20px; height: 20px; color: var(--color-text-3); flex: 0 0 20px; }
.list__value { color: var(--color-text-2); font-size: var(--text-sm); }

/* Плита профиля: аватар, имя, ник */
.prof {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--space-2) 0 var(--space-5);
}

.prof__ava { margin-bottom: var(--space-2); }
.prof__name { font-size: var(--text-xl); font-weight: var(--weight-bold); }
.prof__user { font-size: var(--text-sm); color: color-mix(in srgb, var(--color-text-on-plate) 75%, transparent); }

/* Аватар: буква имени на подложке в тон текста вокруг, картинка поверх, когда доедет */
.ava {
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  overflow: hidden;
  font-weight: var(--weight-bold);
  background: color-mix(in srgb, currentColor 18%, transparent);
}

.ava__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/*
  Образцы палитр. Каждый несёт data-theme палитры и data-mode выбранного
  режима, а токены берёт из них же: плита — --color-plate, карта —
  --card-stone, грунт — --color-bg. Превью собирается из тех же цветов, что
  и сама тема, без единого хекса, и показывает её в том режиме, который
  человек выбрал выше. Кольцо выбранного — на рамке снаружи образца.
  Сетка, а не карусель: все семь видны сразу, ничего не уезжает за край.
*/
.themes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.theme {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-text-2);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.theme__frame {
  display: block;
  width: 100%;
  border-radius: 15px;
  border: var(--border-width) solid var(--color-border);
  transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

.theme[aria-pressed='true'] { color: var(--color-text); }

.theme[aria-pressed='true'] .theme__frame {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

.theme__pic {
  position: relative;
  display: block;
  aspect-ratio: 84 / 132;
  border-radius: 14px;
  overflow: hidden;
  background: var(--color-bg);
}

.theme__pic::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  background: var(--color-plate);
}

.theme__bar {
  position: absolute;
  left: 26%;
  right: 26%;
  top: 15%;
  height: 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--color-text-on-plate) 72%, transparent);
}

/* Кромка — та же, что у пластика: у «Полночи» карта и плита одного цвета,
   и без неё образец карты сливался с плитой. */
.theme__card {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 33%;
  height: 28%;
  border-radius: 6px;
  border: var(--border-width) solid var(--card-edge);
  background: var(--card-stone);
}

.theme__line {
  position: absolute;
  left: 12%;
  right: 30%;
  top: 67%;
  height: 7px;
  border-radius: 4px;
  background: var(--color-surface-2);
}

.theme__line + .theme__line { top: 78%; right: 46%; }

/* ---------- Онбординг --------------------------------------- */

.intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-top: var(--space-2);
}

.intro__art {
  width: 76%;
  max-width: 260px;
  transform: rotate(-7deg);
  animation: card-in 420ms var(--ease-out) both;
}

@keyframes card-in {
  from { opacity: 0; transform: rotate(-7deg) translateY(14px); }
  to   { opacity: 1; transform: rotate(-7deg); }
}

.intro__title {
  margin: var(--space-8) 0 0;
  font-size: var(--text-2xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

.intro__lead {
  margin: var(--space-3) 0 0;
  max-width: 32ch;
  color: var(--color-text-2);
  line-height: var(--leading-normal);
}

.perks {
  width: 100%;
  margin-top: var(--space-8);
  display: grid;
  gap: var(--space-4);
  text-align: left;
}

.perk {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.perk__ring {
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border-radius: var(--radius-md);
  display: grid;
  place-items: center;
  background: var(--color-surface-1);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-accent);
}

.perk__ring svg { width: 20px; height: 20px; }
.perk__title { font-weight: var(--weight-semibold); }
.perk__text { font-size: var(--text-sm); color: var(--color-text-2); line-height: var(--leading-snug); }

/* ---------- Мелочи ------------------------------------------ */

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }

.center { text-align: center; }
.hidden { display: none !important; }

.brand-mark { width: 28px; height: 28px; flex: 0 0 28px; }
.brand-mark path { fill: var(--color-logo); }

.wordmark {
  font-size: var(--text-lg);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Лесенка появления списка: не больше шести шагов, дальше глаз не считывает */
.stagger > *:nth-child(1) { animation-delay: 0ms; }
.stagger > *:nth-child(2) { animation-delay: 30ms; }
.stagger > *:nth-child(3) { animation-delay: 60ms; }
.stagger > *:nth-child(4) { animation-delay: 90ms; }
.stagger > *:nth-child(5) { animation-delay: 120ms; }
.stagger > *:nth-child(6) { animation-delay: 150ms; }

.stagger > * { animation: rise var(--duration-normal) var(--ease-out) both; }

@keyframes rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Лента курсов ------------------------------------ */

/* Одна строка под быстрыми действиями: доллар, евро, время. Курс здесь
   справка, а не блок — владелец выбрал из трёх вариантов самый тихий. */
.rs {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
  padding: 10px var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
  font-size: var(--text-sm);
}

.rs > .skel { flex: 1; }

.rs__item {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-family: var(--font-mono);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--color-text);
}

.rs__item b { font-weight: var(--weight-bold); color: var(--color-text-2); }

/* Направление несёт стрелка + цвет, не только цвет */
.rs__item i { font-style: normal; font-size: 10px; }
.rs__up { color: var(--color-success); }
.rs__down { color: var(--color-danger); }

.rs__stamp {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--color-text-3);
  white-space: nowrap;
}

/* ---------- Оффер, когда карты нет ---------------------------- */

/* Текст слева, наклонённая карта-витрина справа — как блок карты в референсе.
   Кнопка называет всю сумму списания: витрина и экран заказа сходятся в цифре. */
.offer {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 118px;
  gap: var(--space-3) var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-card);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
  overflow: hidden;
}

.offer__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  min-width: 0;
}

.offer__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: -0.01em;
  line-height: var(--leading-tight);
}

.offer__sub {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--color-text-2);
  text-wrap: pretty;
}

.offer__rate {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.offer__rate-sub {
  display: block;
  margin-top: 2px;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--color-text-3);
}

/* Кнопка в узкой колонке: 14px и поля 12, иначе сумма не помещается */
.offer .btn {
  min-height: var(--tap-target);
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
}

.offer__art {
  position: relative;
  align-self: center;
  min-height: 150px;
}

/* Наклон небольшой, чтобы карта целиком осталась внутри блока, а не резалась краем */
.offer__art .plastic {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%) perspective(800px) rotateY(-16deg) rotateZ(-6deg);
  box-shadow: var(--shadow-modal);
}

/* Три шага — настоящая последовательность, поэтому пронумерованы */
.steps {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
}

.steps li {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
  font-size: var(--text-xs);
  line-height: 1.3;
  color: var(--color-text-2);
}

.steps b {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  background: var(--color-accent-bg);
  color: var(--color-accent);
  font-size: var(--text-xs);
}

/* ---------- Оплата по СБП ----------------------------------- */

/* Знак СБП на кнопке. Он уже, чем квадратные иконки, поэтому ширину не
   задаём — иначе растянется; высота чуть меньше строки, чтобы не спорить
   с суммой в подписи. Цвета у знака свои: это чужой товарный знак. */
.btn__sbp { display: flex; flex: 0 0 auto; }
.btn__sbp svg { width: auto; height: 20px; display: block; }

/* Сумма к оплате — самое крупное на экране ожидания: человек сверяет её
   с тем, что видит в приложении банка. */
.pay__total {
  margin-top: var(--space-1);
  font-size: var(--text-3xl);
  font-weight: var(--weight-extra);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
  color: var(--color-balance);
}

/* Номер платежа — моно: его диктуют в поддержку, и 0/O там путать нельзя. */
.pay__id {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
}

/* ---------- Коды подтверждения (3DS) ------------------------ */

.otp {
  margin-top: var(--space-3);
  border-radius: var(--radius-lg);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface-1);
  overflow: hidden;
}

.otp__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 56px;
  padding: var(--space-3) var(--space-4);
  background: transparent;
  border: none;
  border-bottom: var(--border-width) solid var(--color-border-subtle);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

.otp__row:last-child { border-bottom: none; }
.otp__row:active { background: var(--color-surface-2); }

/* Код крупный и моноширинный: его переписывают в чужую форму, и 1/l, 0/O
   должны различаться с одного взгляда. Разрядка — чтобы цифры не слипались. */
.otp__code {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
}

.otp__time {
  flex: 1;
  font-size: var(--text-xs);
  color: var(--color-text-3);
  text-align: right;
}

.otp__copy { color: var(--color-text-3); flex: 0 0 auto; }
.otp__copy svg { width: 18px; height: 18px; display: block; }

/* ---------- Загрузочный экран ------------------------------- */

.splash {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  background: var(--color-bg);
  background-image: var(--gradient-ambient);
  transition: opacity var(--duration-slow) var(--ease-out);
}

.splash--gone { opacity: 0; pointer-events: none; }

.splash__mark {
  width: 64px;
  height: 64px;
  animation: splash-pulse 1400ms var(--ease-in-out) infinite;
}

.splash__mark path { fill: var(--color-logo); }

/* Словесный знак — одним цветом: «Cards» больше не подкрашивается */
.splash__word {
  font-size: var(--text-2xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  color: var(--color-logo-wordmark);
}

.splash__dots { display: flex; gap: var(--space-2); }

.splash__dots span {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-text-3);
  animation: splash-dot 1200ms var(--ease-in-out) infinite;
}

.splash__dots span:nth-child(2) { animation-delay: 150ms; }
.splash__dots span:nth-child(3) { animation-delay: 300ms; }

@keyframes splash-pulse {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50%      { transform: scale(1.06); opacity: 1; }
}

@keyframes splash-dot {
  0%, 100% { opacity: 0.3; transform: translateY(0); }
  50%      { opacity: 1; transform: translateY(-3px); }
}

/* ---------- Меньше движения --------------------------------- */

/*
  Анимации не выключаем, а сжимаем до нуля: часть из них через fill-mode
  доводит элемент до конечного состояния (шторка, ступенчатое появление).
  С `animation: none` шторка осталась бы за нижним краем экрана.
*/
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Экран карты ------------------------------------- */

/* Под пластиком: сколько на карте и кто держатель; чип только у исключений */
.crow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.crow__t {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

.crow__s { font-size: var(--text-sm); color: var(--color-text-3); }

/* ---------- Пополнение --------------------------------------- */

/* Что будет с деньгами, если не сработает: строка под итогом, всегда видна */
.guar {
  margin: var(--space-3) 0 0;
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  color: var(--color-text-3);
}

/* Переключатель валюты — сегментированный контрол, а не пилюли в ряд */
.filters--seg {
  display: inline-flex;
  gap: var(--space-1);
  margin: var(--space-4) 0 0;
  padding: 3px;
  border-radius: var(--radius-full);
  background: var(--color-surface-2);
  overflow: visible;
}

.filters--seg .filter {
  min-height: 32px;
  min-width: 48px;
  padding: 0 var(--space-3);
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text-2);
}

.filters--seg .filter[aria-pressed='true'] {
  background: var(--color-surface-1);
  color: var(--color-text);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.18);
}

/* ---------- Из чего складывается цена карты ------------------ */

/* Две ячейки: сама карта и то, что останется на её балансе. Вторая —
   единственный акцент блока: именно её люди не замечали и думали, что
   карта стоит 20 $. Стоит на витрине, в заказе и на экране оплаты. */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.split__cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border-subtle);
  background: var(--color-surface-1);
}

.split__cap { font-size: var(--text-xs); color: var(--color-text-2); }

.split__val {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.split__sub { font-size: var(--text-xs); color: var(--color-text-3); }

.split__cell--on {
  background: var(--color-accent-bg);
  border-color: var(--color-accent);
}

.split__cell--on .split__cap { color: var(--color-text); }
.split__cell--on .split__val { color: var(--color-accent); }

/* В оффере блок и кнопка идут на всю ширину под текстом и картой */
.offer .split,
.offer .btn { grid-column: 1 / -1; }
.offer .split { margin-top: 0; }
