/* ==================================================================
   «По рукам» · сброс, фон, типографика, элементы управления
   ================================================================== */

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  border: 0;
  outline: 0;
  -webkit-tap-highlight-color: transparent;
}

html,
body {
  height: 100%;
}

html {
  /* Никогда не «резиновый» шрифт: суммы и даты должны быть предсказуемы. */
  -webkit-text-size-adjust: 100%;
}

body {
  font: var(--t-body);
  color: var(--txt);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Вырезы и «дом» на iPhone: контент не должен под них уезжать. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
    env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ==================================================================
   Фон
   ==================================================================

   Отдельным фиксированным слоем, а не свойством body, по двум причинам:
   background-attachment: fixed на iOS не работает вовсе, а зерно нужно
   наложить режимом смешивания — на body это задело бы весь текст.
   ================================================================== */

.mesh {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--bg-image);
  background-attachment: scroll;
  pointer-events: none;
}

/* Плёночное зерно: единственный «декор», который есть на референсе.
   Тайл нарисован фильтром SVG в data-URI — это дешевле, чем держать
   фильтр в дереве документа, и не требует лишнего файла. */
.mesh::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

/* На светлом зерно видно через multiply, на тёмном — через overlay:
   overlay на светлом почти не читается, multiply на тёмном съедает
   градиент в грязь. */
body[data-surface='app'] .mesh::after {
  mix-blend-mode: multiply;
  opacity: 0.34;
}

body[data-surface='auth'] .mesh::after {
  mix-blend-mode: overlay;
  opacity: 0.5;
}

/* ==================================================================
   Типографика
   ================================================================== */

h1,
.display {
  font: var(--t-display);
  letter-spacing: var(--track-display);
  text-wrap: balance;
}

h2 {
  font: var(--t-h1);
  letter-spacing: -0.022em;
  text-wrap: balance;
}

h3 {
  font: var(--t-h2);
  letter-spacing: -0.012em;
}

/* Акцентная строка заголовка — как на референсах: одна строка синим. */
.hl {
  color: var(--accent);
}

.sub {
  font: var(--t-sub);
  color: var(--txt-2);
  max-width: 34ch;
}

.tiny {
  font: var(--t-tiny);
  letter-spacing: var(--track-tiny);
  text-transform: uppercase;
  color: var(--txt-3);
}

.muted {
  color: var(--txt-2);
}

.amount {
  font: var(--t-amount);
  letter-spacing: -0.03em;
  /* Цифры в колонку: суммы сторон стоят рядом и должны совпадать по ширине. */
  font-variant-numeric: tabular-nums;
}

.nums {
  font-variant-numeric: tabular-nums;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

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

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

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: var(--tap);
  padding: 0 var(--s5);
  border-radius: var(--r-pill);
  font: 600 16px / 1 var(--font);
  cursor: pointer;
  user-select: none;
  transition: transform var(--fast) var(--ease), opacity var(--fast) var(--ease),
    background-color var(--fast) var(--ease);
}

.btn:active {
  transform: scale(0.985);
}

/* Главное действие экрана. Ровно одно на экран — это правило, а не стиль. */
.btn-cta {
  background: var(--cta-bg);
  color: var(--cta-txt);
  width: 100%;
}

/**
 * Заблокированная кнопка не должна выглядеть поломкой.
 *
 * Прозрачная белая пилюля на градиенте читается как «кнопка не
 * дорисовалась». Поэтому вместо прозрачности подменяем заливку на
 * стеклянную: видно, что действие пока недоступно, и видно, что так
 * и задумано.
 */
.btn[disabled] {
  cursor: not-allowed;
}

.btn-cta[disabled] {
  background: var(--glass-2);
  color: var(--txt-3);
}

.btn-ghost {
  background: var(--glass);
  color: var(--glass-txt);
}

/*
 * Опасное действие — красной кнопкой, а не надписью.
 *
 * «Отменить сделку» и «Отменить подпись» были `.btn-plain`, то есть
 * выглядели как ссылка. Человек попросил сделать их кнопками и красными:
 * отмена — необратимое действие, и его вид должен об этом говорить.
 */
.btn-danger {
  background: var(--bad);
  color: #ffffff;
}

.btn-danger:hover {
  background: #b5271b;
}

.btn-plain {
  min-height: auto;
  padding: var(--s2) var(--s3);
  font: var(--t-sub);
  color: var(--txt-2);
  border-radius: var(--r-sm);
}

.btn-plain:hover {
  color: var(--txt);
}

/* Рамка фокуса — единственное исключение из «никаких обводок».
   На десктопе клавиатура основной способ ввода, и без видимого фокуса
   форму не пройти. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* ==================================================================
   Поля
   ================================================================== */

.field {
  display: grid;
  gap: var(--s2);
}

.field > label {
  font: var(--t-tiny);
  letter-spacing: var(--track-tiny);
  text-transform: uppercase;
  color: var(--txt-3);
}

.input {
  min-height: var(--tap);
  padding: 0 var(--s4);
  border-radius: var(--r-md);
  background: var(--glass);
  color: var(--glass-txt);
  font: 500 17px / 1 var(--font);
  transition: background-color var(--fast) var(--ease);
}

.input::placeholder {
  color: var(--txt-3);
}

.input:focus {
  background: var(--glass-2);
}

/*
 * Поле рядом с кнопкой в одной строке.
 *
 * Своя ширина у <input> — двадцать знаков, и одного min-width: 0 мало:
 * сетка выше считает свой минимум по содержимому и растягивается под эти
 * двадцать знаков вместе со всеми соседними карточками. Поэтому ширину
 * обнуляем явно, а размер полю даёт flex.
 *
 * Это не мелочь вёрстки: из-за такой строки в переписке весь экран сделки
 * уезжал по горизонтали на ширине 375 — вместе с суммами и подписью.
 */
.row-field {
  display: flex;
  gap: var(--s2);
  align-items: center;
}

.row-field > .input,
.row-field > .field {
  flex: 1 1 0;
  width: 0;
  min-width: 0;
}

/* Суммы и телефоны — цифрами в колонку и крупнее: их перечитывают. */
.input-nums {
  font: 600 20px / 1 var(--font);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

textarea.input {
  min-height: 140px;
  padding: var(--s4);
  line-height: 1.5;
  resize: vertical;
}

/* Галочка соглашения: сама галочка мелкая, но нажимать надо по всей строке. */
.check {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: var(--s3);
  align-items: start;
  min-height: var(--tap);
  padding: var(--s3) 0;
  cursor: pointer;
  font: var(--t-sub);
  color: var(--txt-2);
}

.check input {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ==================================================================
   Карточки
   ================================================================== */

/*
 * Атрибут hidden обязан прятать.
 *
 * Своего правила не было, а браузерное `[hidden] { display: none }` идёт с
 * нулевой специфичностью — любое `display` в наших классах его перебивало.
 * У `.btn` он `flex`, поэтому кнопка «Показать ещё» висела на экране, где
 * показывать больше нечего, а «Все сделки» на главной — при шести сделках
 * из шести. Ставится hidden из кода в пяти местах, и ни одно не работало.
 */
[hidden] {
  display: none !important;
}

.card {
  background: var(--glass);
  color: var(--glass-txt);
  border-radius: var(--r-card);
  padding: var(--s5);
  box-shadow: var(--shadow-card);
}

.card-tight {
  padding: var(--s4);
  border-radius: var(--r-md);
}

/* Иконка в синем скруглённом квадрате — прямо с референса. */
.badge {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 13px;
  background: var(--blue);
  color: #fff;
  font: 700 15px / 1 var(--font);
  flex: 0 0 auto;
}

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

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: var(--s1) var(--s2);
  border-radius: var(--r-sm);
  font: var(--t-tiny);
  letter-spacing: var(--track-tiny);
  text-transform: uppercase;
}

.pill-good {
  background: var(--good-soft);
  color: var(--good);
}

.pill-bad {
  background: var(--bad-soft);
  color: var(--bad);
}

.pill-wait {
  background: var(--wait-soft);
  color: var(--wait);
}

/* ==================================================================
   Экраны и переходы
   ================================================================== */

#screen {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  animation: appear var(--norm) var(--ease) both;
}

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

/* Полоса загрузки на время, пока экран ещё не смонтирован. */
.booting {
  flex: 1;
  display: grid;
  place-items: center;
  color: var(--txt-3);
  font: var(--t-sub);
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

/* Скрыто для глаз, но доступно программе чтения с экрана. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
