/* ---------- Шрифты ---------- */
/* Asgard Number: в наличии Regular (400) и Xbold (800).
   Логотип в макете помечен как Medium 500 — по метрикам это ровно Regular
   (ширина «Burger» 307.7px против 308.3px в эталоне), поэтому 500 отдаём
   на Regular, а 700+ на Xbold. */
@font-face {
  font-family: "Asgard";
  src: url("/app/assets/fonts/Asgard-Regular.woff2") format("woff2");
  font-weight: 400 500;
  font-display: swap;
}

@font-face {
  font-family: "Asgard";
  src: url("/app/assets/fonts/Asgard-Xbold.woff2") format("woff2");
  font-weight: 600 900;
  font-display: swap;
}

/* Asgard Number — цифровое начертание Asgard, для крупных сумм. */
@font-face {
  font-family: "Asgard Number";
  src: url("/app/assets/fonts/AsgardNumber-Regular.woff2") format("woff2");
  font-weight: 400 500;
  font-display: swap;
}

@font-face {
  font-family: "Asgard Number";
  src: url("/app/assets/fonts/AsgardNumber-Xbold.woff2") format("woff2");
  font-weight: 600 900;
  font-display: swap;
}

@font-face {
  font-family: "Neue Haas Unica";
  src: url("/app/assets/fonts/NeueHaasUnica-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Neue Haas Unica";
  src: url("/app/assets/fonts/NeueHaasUnica-Medium.woff2") format("woff2");
  font-weight: 500 700;
  font-display: swap;
}

/* ---------- Переменные ---------- */
:root {
  --bg: #E4E4E4;
  --ink: #000;
  --paper: #fff;
  --tg: #86DFFF;
  --tg-deep: #7FDFFE;

  /* Макет 440px: всё внутри масштабируется от ширины экрана */
  --w: 440;
  --h: 700;
  --backdrop: #8A8A8A;
  /* Ширина сцены и шаг сетки считаются из одного значения */
  --stage: min(100vw, 440px);
  --u: calc(var(--stage) / var(--w));
  --font-display: "Asgard", "Helvetica Neue", Arial, system-ui, sans-serif;
  --font-text: "Neue Haas Unica", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-number: "Asgard Number", "Asgard", Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--backdrop);
  font-family: var(--font-text);
  -webkit-font-smoothing: antialiased;
}

/* Макет 440x1000 по центру окна; на узких экранах прижимается к верху,
   чтобы низ не уезжал под обрез. */
body {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Экран с навигацией занимает всё окно — центрировать нечего, а от
   центрирования низ сцены уезжал вверх и панель отрывалась от края. */
body:has(.tabbar) {
  align-items: stretch;
}

/* Если окно ниже макета — прижимаем к верху, иначе низ уедет за обрез. */
@media (max-height: 700px) {
  body {
    align-items: flex-start;
  }
}

/* ---------- Экран ---------- */
.stage {
  position: relative;
  width: var(--stage);
  margin: 0 auto;
  height: 850px;
}

/* Экран с навигацией тянем на всю высоту окна: панель прибита к низу
   окна, и на короткой сцене она висела бы в фоне страницы, оторванная
   от мини-аппа. Отступа снизу у сцены быть не должно — в нём просвечивал
   бы фон страницы; запас под панель даёт сам экран. */
.stage:has(.tabbar) {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Фон экрана доходит до самого низа окна, а содержимое не уезжает под
   панель: её высота отведена внутренним отступом. */
.stage:has(.tabbar) .screen {
  min-height: 100%;
  padding-bottom: calc(135 * var(--u));
  box-sizing: border-box;
}

/* Внутри Telegram окно выше макета — тянем экран на всю его высоту. */
.is-telegram .screen {
  height: 100%;
}

/* Пока проверяем, знаком ли нам пользователь, стартовый экран не
   показываем: у своих он иначе мелькнул бы перед уходом в кабинет.
   Фон остаётся, поэтому выглядит как обычная загрузка. */
.is-checking .stage {
  visibility: hidden;
}

.screen {
  position: relative;
  width: 100%;
  /* Фиксированная высота макета: 440x1000. */
  height: calc(var(--h) * var(--u));
  margin: 0 auto;
  overflow: hidden;
  background: var(--bg);
  isolation: isolate;
}

/* ---------- Логотип ---------- */
.hero {
  margin: 0;
}

.hero__title {
  position: absolute;
  left: calc(62 * var(--u));
  top: calc(99 * var(--u));
  width: calc(315 * var(--u));
  height: calc(54 * var(--u));
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: calc(77 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

/* Значок VPN */
.badge {
  position: absolute;
  /* Увеличено в 2.95 раза от макета: «VPN» набран тем же кеглем 77px,
     что и логотип, поэтому плашка и звезда выросли пропорционально. */
  left: calc(260 * var(--u));
  top: calc(100 * var(--u));
  width: 100px;
  height: 20px;
  transform: rotate(15deg);
  z-index: 2;
}

.badge__star {
  position: absolute;
  width: 65px;
  height: 65px;
  top: -20px;
  left: 15px;
  /* Девятиконечная звезда из макета (Star 21). Заливка, обводка и белые
     блики по краю уже запечены в картинке, поэтому здесь только фон. */
  background: url("/app/assets/icons/star.png") no-repeat center / contain;
}

.hero__tagline {
  position: absolute;
  left: calc(91 * var(--u));
  top: calc(175 * var(--u));
  width: calc(259 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(25 * var(--u));
  line-height: 1.1;
  letter-spacing: -.04em;
  color: rgba(0, 0, 0, .4);
}

/* ---------- Кнопки ---------- */
.actions {
  display: contents;
}

.btn,
.tg {
  -webkit-appearance: none;
  appearance: none;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.btn {
  position: absolute;
  left: calc(44 * var(--u));
  width: calc(352 * var(--u));
  height: calc(86 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: calc(30 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(22 * var(--u));
  line-height: 1;
  text-decoration: none;
  text-align: center;
  /* Градиентная обводка из макета */
  background-origin: border-box;
  background-clip: padding-box, border-box;
  transition: transform .18s ease, filter .18s ease;
}

/* Наведение: кнопка чуть приподнимается и подсвечивается. */
@media (hover: hover) {
  .btn:hover {
    transform: translateY(calc(-2 * var(--u)));
    filter: brightness(1.08);
  }

  .btn--light:hover {
    filter: brightness(1.02);
  }

  .tg:hover {
    filter: brightness(1.05) drop-shadow(0 calc(5.47 * var(--u)) calc(4 * var(--u)) rgba(6, 118, 159, .1));
  }

  /* Круг «Добавьте фото»: слегка увеличивается и подсвечивается. */
  .avatar:hover {
    transform: scale(1.03);
    filter: brightness(1.04);
  }

  /* Кнопка «Создать профиль»: центрирование держится на translateX(-50%),
     поэтому подъём дописываем к нему, иначе кнопка прыгнет вправо. */
  .submit__btn:hover {
    transform: translateX(-50%) translateY(calc(-3 * var(--u)));
    filter: brightness(1.04);
  }
}

/* Форма готова к отправке — кнопка меняется на активный вариант. Готовность:
   на регистрации все поля заполнены И выбрано фото, на входе — только поля.
   Два background-image анимировать нельзя, поэтому активная картинка лежит
   отдельным слоем и плавно проявляется поверх обычной. Её холст 440×328
   против 605×318 у базовой, так что размеры задаём явно. */
.submit__btn::after {
  content: "";
  position: absolute;
  /* Активный холст 440x328, пилюля в нём — в точке 81;221. */
  left: calc(-81 * var(--u));
  top: calc(-221 * var(--u));
  width: calc(440 * var(--u));
  height: calc(328 * var(--u));
  background: url("/app/assets/icons/create_profile_active.png") no-repeat center / contain;
  opacity: 0;
  transition: opacity .45s ease;
  pointer-events: none;
}

.screen.is-ready .submit__btn::after {
  opacity: 1;
}

/* Базовая картинка лежит в ::before и гаснет так же плавно, как проявляется
   активная — background-image сам по себе не анимируется. */
.submit__btn::before {
  content: "";
  position: absolute;
  /* Холст PNG больше пилюли: 605x318, сама пилюля в нём — 281x72
     в точке 162;214. Отсюда сдвиги. */
  left: calc(-162 * var(--u));
  top: calc(-214 * var(--u));
  width: calc(605 * var(--u));
  height: calc(318 * var(--u));
  background: url("/app/assets/icons/create_profile.png") no-repeat center / contain;
  opacity: 1;
  transition: opacity .45s ease;
  pointer-events: none;
}

.screen.is-ready .submit__btn::before {
  opacity: 0;
}

/* Нажатие: лёгкое сжатие вместо подъёма. */
.avatar:active {
  transform: scale(.98);
}

.submit__btn:active {
  transform: translateX(-50%) scale(.985);
}

.btn:active {
  transform: scale(.985);
  filter: brightness(.97);
}

/* Центрирование держится на translateX(-50%), поэтому сжатие при нажатии
   дописываем к нему, а не заменяем — иначе кнопка прыгнет вправо. */
.tg:active {
  transform: translateX(-50%) scale(.98);
}

.btn:focus-visible,
.tg:focus-visible {
  outline: calc(3 * var(--u)) solid #2AABEE;
  outline-offset: calc(3 * var(--u));
}

.btn--dark {
  top: calc(222 * var(--u));
  color: var(--paper);
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(25 * var(--u)) calc(20 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .4),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(255, 64, 157, .6),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

.btn--light {
  top: calc(323 * var(--u));
  color: var(--ink);
  background-image:
    linear-gradient(180deg, #fff 15%, #E4E4E4 95%),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(25 * var(--u)) calc(20 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .3),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

/* ---------- Вход через телеграм ---------- */
/* Весь блок — одна картинка 237×56 (стрелка, логотип и подпись уже в ней).
   Ширина берётся из макета, высота считается по пропорции файла. */
.tg {
  position: absolute;
  /* По центру сцены: середина минус половина ширины — не зависит от того,
     как поменяется ширина картинки. */
  left: 50%;
  transform: translateX(-50%);
  top: calc(434 * var(--u));
  width: calc(237 * var(--u));
  height: calc(56 * var(--u));
  display: block;
  filter: drop-shadow(0 calc(5.47 * var(--u)) calc(4 * var(--u)) rgba(6, 118, 159, .1));
  transition: transform .18s ease;
}

.tg__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Пока проверяется подпись телеграма — кнопка приглушена и не ловит
   повторные нажатия. */
.tg.is-busy {
  opacity: .6;
  pointer-events: none;
}

/* ---------- Бургер ---------- */
.burger {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(497 * var(--u));
  bottom: 0;
  overflow: hidden;
  /* Свой контекст наложения: backdrop-filter у .burger__fade размывает
     только то, что внутри этого блока (картинку бургера), и не дотягивается
     до копирайта, который лежит выше по z-index. */
  isolation: isolate;
  z-index: 1;
}

/* Картинка шире экрана и уходит за края, как в макете. */
.burger__img {
  position: absolute;
  left: 50%;
  top: 5%;
  width: 110%;
  height: 100%;
  transform: translateX(-50%);
  object-fit: cover;
  object-position: top center;
}

/* Размытие низа — под подпись копирайта. Без затемнения: картинка бургера
   уходит в расфокус, а не в чёрный. Сам backdrop-filter применяется ко
   всему блоку сразу, поэтому плавность даёт маска — блюр набирает силу
   сверху вниз вместе с непрозрачностью маски. */
.burger__fade {
  position: absolute;
  left: 0;
  right: 0;
  /* Блок .burger уходит за нижний край экрана, поэтому bottom:0 увёл бы
     размытие за обрез — прижимаем полосу к видимому низу. */
  bottom: calc(101 * var(--u));
  height: calc(250 * var(--u));
  /* Радиус вдвое меньше прежнего: стоимость размытия растёт с радиусом,
     а под маской разница почти не видна. contain ограничивает
     перерисовку самим элементом — без него браузер на каждый кадр
     прокрутки пересобирает всё, что под полосой. */
  contain: paint;
  backdrop-filter: blur(calc(5 * var(--u)));
  -webkit-backdrop-filter: blur(calc(5 * var(--u)));
  mask: linear-gradient(180deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, .35) 40%,
      rgba(0, 0, 0, 1) 75%,
      rgba(0, 0, 0, 1) 100%);
  -webkit-mask: linear-gradient(180deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, .35) 40%,
      rgba(0, 0, 0, 1) 75%,
      rgba(0, 0, 0, 1) 100%);
  pointer-events: none;
}

/* На главной размытие идёт от самого низа блока — отступ, который нужен
   профилю, здесь задирает полосу над картинкой. */
.screen:not(.screen--profile) .burger__fade {
  bottom: 0;
}

/* ---------- Подвал ---------- */
/* Копирайт лежит поверх размытия. Одного z-index мало: backdrop-filter у
   .burger__fade захватывает в свой фон всё, что отрисовано под ним, и
   соседний футер туда попадал. Собственный слой композитора (transform +
   will-change) выводит текст из-под фильтра — он остаётся резким. */
.footer {
  position: absolute;
  left: calc(87 * var(--u));
  width: calc(265 * var(--u));
  bottom: calc(40 * var(--u));
  margin: 0;
  z-index: 2;
  transform: translateZ(0);
  will-change: transform;
}

.footer__text {
  margin: 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1.15;
  letter-spacing: -.0286em;
  color: rgba(255, 255, 255, .8);
}

/* ==================================================================
   Страница регистрации (макет 920:16949, та же сетка 440×956)
   ================================================================== */

/* ---------- Переключатель Регистрация / Вход ---------- */
.seg {
  position: absolute;
  /* Ширина контейнера в макете — по содержимому (hug), а оно разное на
     вкладках «Регистрация» и «Вход». Поэтому центрируем, а не прибиваем
     к left: иначе блок уезжает вбок и обрезается. */
  left: 50%;
  transform: translateX(-50%);
  top: calc(85 * var(--u));
  height: calc(46 * var(--u));
  display: flex;
  align-items: center;
  padding: calc(2 * var(--u)) calc(4 * var(--u));
  border-radius: calc(15 * var(--u));
  /* Обводка-градиент из макета поверх полупрозрачной заливки */
  border: calc(1 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .1)),
    linear-gradient(180deg, rgba(0, 0, 0, .05) 17%, rgba(0, 0, 0, .15) 100%);
}

.seg__item {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  height: calc(38 * var(--u));
  /* Ширина по содержимому + горизонтальный padding из макета. «Вход» ниже
     получает минимум 84px — столько ему отведено в макете. */
  padding: 0 calc(24 * var(--u));
  border: 0;
  border-radius: calc(11 * var(--u));
  background: none;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(11 * var(--u));
  line-height: 1;
  letter-spacing: -.0364em;
  text-align: center;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* Плавный переход между вкладками: цвет, фон и тень меняются не скачком. */
  transition: color .22s ease, background-image .22s ease, box-shadow .22s ease;
}

/* «Вход» в макете занимает 84px (layout_0Y57HQ) — и активным, и нет,
   иначе тёмная таблетка получается уже своей ячейки и жмётся к краю. */
.seg__item[data-tab="login"] {
  min-width: calc(84 * var(--u));
}

/* Активный сегмент — тёмная «таблетка» со стеклянной подсветкой */
.seg__item.is-active {
  color: var(--paper);
  border: calc(.5 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(180deg, rgba(0, 0, 0, .05) 17%, rgba(0, 0, 0, .15) 100%);
  box-shadow:
    0 calc(6 * var(--u)) calc(6 * var(--u)) calc(-4 * var(--u)) rgba(0, 0, 0, .3),
    inset calc(3 * var(--u)) calc(3 * var(--u)) calc(10 * var(--u)) calc(-1 * var(--u)) rgba(255, 255, 255, .8),
    inset calc(-2.5 * var(--u)) calc(-2.5 * var(--u)) calc(5 * var(--u)) calc(-1 * var(--u)) rgba(255, 255, 255, .6);
}

/* Выбранное фото затягивает круг целиком: подпись и плюс прячем. */
/* Фото выбрано: показываем картинку кругом на месте SVG-заглушки. */
.avatar.has-photo {
  height: calc(156 * var(--u));
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Аватарки на входе нет — поднимаем форму на её место (160px вверх),
   чтобы не оставалось пустоты под переключателем. */
.screen--login .field--name {
  top: calc(160 * var(--u));
}

.screen--login .field--email {
  top: calc(232 * var(--u));
}

.screen--login .field--password {
  top: calc(304 * var(--u));
}

.screen--login .submit {
  top: calc(378 * var(--u));
}

.screen--login .consent {
  top: calc(480 * var(--u));
}

.screen--login .tg--reg {
  top: calc(560 * var(--u));
}

/* ---------- Аватар ---------- */
/* Круг «Добавьте фото» целиком в SVG: градиент, обводки, подпись по дуге,
   плюс и тень. Холст 156×194 — снизу запас под тень, поэтому высота больше
   ширины, а сам круг занимает верхние 156px. */
.avatar {
  position: absolute;
  z-index: 1;
  left: calc(142 * var(--u));
  top: calc(152 * var(--u));
  width: calc(156 * var(--u));
  height: calc(194 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/add-photo.png") no-repeat center top / contain;
  cursor: pointer;
  transition: transform .2s ease, filter .2s ease;
}

/* ---------- Поля ---------- */
.reg-form {
  margin: 0;
}

.field {
  position: absolute;
  z-index: 1;
  left: calc(44 * var(--u));
  width: calc(352 * var(--u));
  height: calc(65 * var(--u));
  /* Содержимое по центру и по горизонтали, и по вертикали. */
  display: flex;
  align-items: center;
  border-radius: calc(14 * var(--u));
}

.field--name {
  top: calc(312 * var(--u));
}

.field--email {
  top: calc(384 * var(--u));
}

.field--password {
  top: calc(456 * var(--u));
  padding-right: calc(25 * var(--u));
}

/* Текст пароля не должен заезжать под глазок */
.field--password .field__input {
  padding-right: 0;
}

.field__input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  /* Высоту не тянем на 100%: тогда flex-центрирование родителя работает,
     и текст стоит ровно по вертикали поля. */
  /* Высота во всё поле + line-height равен ей: глиф встаёт ровно по центру.
     При line-height .9 текст уезжал вверх — это и был перекос. */
  height: 100%;
  padding: 0 calc(34 * var(--u));
  border: 0;
  border-radius: inherit;
  background: none;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(32 * var(--u));
  line-height: calc(65 * var(--u));
  letter-spacing: -.03em;
  text-align: center;
  color: var(--ink);
}

.field__input::placeholder {
  color: rgba(0, 0, 0, .2);
  opacity: 1;
}

.field__input:focus {
  outline: none;
}

/* Точки-маркеры по краям поля */
/* Полукруги по краям поля: половина ширины, скруглены только с одной
   стороны — плоской гранью наружу, к краю поля. */
.field__dot {
  position: absolute;
  top: calc(24 * var(--u));
  width: calc(9.5 * var(--u));
  height: calc(19 * var(--u));
  background: rgba(0, 0, 0, .2);
  pointer-events: none;
  transition: background-color .2s ease;
}

/* Поле заполнено — метки по краям чернеют. :placeholder-shown истинно, пока
   поле пустое, поэтому берём отрицание. Селектор смотрит вперёд по дереву,
   а .field__dot--left стоит ДО инпута, поэтому для него используем :has(). */
.field:has(.field__input:not(:placeholder-shown)) .field__dot {
  background: var(--ink);
}

.field__dot--left {
  left: calc(1 * var(--u));
  border-radius: 0 calc(9.5 * var(--u)) calc(9.5 * var(--u)) 0;
}

.field__dot--right {
  left: calc(341.5 * var(--u));
  border-radius: calc(9.5 * var(--u)) 0 0 calc(9.5 * var(--u));
}

/* Глазок у пароля: в макете 392/470 от экрана, поле стоит в 44/452 */
/* Кнопка-«глаз» — полуовал: вытянутая по горизонтали таблетка,
   скруглённая по половине высоты. */
.field__eye {
  position: absolute;
  z-index: 2;
  left: calc(356 * var(--u));
  top: calc(17 * var(--u));
  width: calc(36 * var(--u));
  height: calc(36 * var(--u));
  padding: 0;
  border: 0;
  /* Иконка из макета: подложка, обводка и тень уже внутри SVG. */
  background: url("/app/assets/icons/eye-off.svg") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Пароль показан — перечёркиваем глаз диагональной линией. */
/* Пароль показан — иконка из макета со «зрачком» вместо перечёркнутой. */
.field__eye.is-on {
  background-image: url("/app/assets/icons/eye-on.svg");
}

/* ---------- Кнопка «Создать профиль» ---------- */
.submit {
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  /* Форма кнопки — SVG 281×72 из макета; высота обёртки под неё.
     Стоит между паролем (низ 527) и согласием (632) — чуть выше него. */
  top: calc(530 * var(--u));
  height: calc(72 * var(--u));
  pointer-events: none;
}

/* Кнопка — вытянутый эллипс со стеклянными inset-тенями (Ellipse 1664).
   Подпись у нижней дуги, как в макете (текст на 354..575). */
/* Кнопка «Создать профиль» целиком в SVG (605×318): форма, inner-тени,
   размытая тень под ней и сам текст. Видимая часть — x 154..445, y 205..288,
   поэтому холст шире и выше кнопки; лишнее прозрачно. */
.submit__btn {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  /* Кнопка — ровно пилюля из макета (281x72); картинки-холсты лежат
     в ::before/::after и выходят за неё, не перехватывая клики. */
  top: 0;
  width: calc(281 * var(--u));
  height: calc(72 * var(--u));
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  transition: transform .2s ease, filter .2s ease;
}

/* Пока форма не готова, кнопка не реагирует на нажатия. */
.screen:not(.is-ready) .submit__btn {
  cursor: default;
  pointer-events: none;
}

/* Профиль уже создаётся — второе нажатие завело бы ещё один запрос. */
.screen.is-busy .submit__btn {
  cursor: progress;
  pointer-events: none;
  filter: grayscale(1);
}

/* ---------- Согласие ---------- */
.consent {
  position: absolute;
  z-index: 1;
  left: calc(94 * var(--u));
  top: calc(646 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

/* Причина, по которой форма не отправилась. Браузерная подсказка
   молчит про галочку согласия и не видна на десктопе. */
.form-error {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  /* Прижимаем к низу экрана: при фиксированной координате сообщение
     обрезалось нижним краем на невысоких окнах. */
  bottom: calc(10 * var(--u));
  margin: 0;
  padding: 0 calc(24 * var(--u));
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1.2;
  text-align: center;
  color: #BF2121;
}

/* Причина, по которой автовход не состоялся (стартовый экран).
   В потоке, а не absolute как .form-error: этот экран прокручивается,
   и прижатое к низу сообщение уехало бы под кнопки. */
.auth-problem {
  margin: calc(14 * var(--u)) calc(24 * var(--u)) 0;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1.25;
  text-align: center;
  color: #BF2121;
}

/* «Вы вышли из профиля» — состояние, а не сбой: тот же размер, но
   спокойный цвет, чтобы человек не искал несуществующую ошибку. */
.auth-problem--calm {
  color: rgba(0, 0, 0, .6);
}

.consent__box {
  flex: 0 0 auto;
  width: calc(25 * var(--u));
  height: calc(24 * var(--u));
  padding: 0;
  border: 0;
  /* По умолчанию — «полный» вид (как раньше при нажатии), галочка внутри
     появляется только когда согласие отмечено. */
  background: url("/app/assets/icons/check-box.svg") no-repeat center / contain;
  opacity: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: relative;
  transition: opacity .15s ease, background-image .15s ease;
}

/* Галочка отмеченного состояния. */
/* Отмечено — меняем иконку на активную (чёрный кружок с галочкой). */
.consent__box[aria-checked="true"] {
  background-image: url("/app/assets/icons/check-box-active.svg");
}

.consent__text {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(12 * var(--u));
  line-height: 1.15;
  letter-spacing: -.0337em;
  color: rgba(0, 0, 0, .2);
}

/* ---------- «Взять данные из телеграма» ---------- */
.tg--reg {
  top: calc(711 * var(--u));
  width: calc(237.9 * var(--u));
  height: calc(56.2 * var(--u));
  filter: drop-shadow(0 calc(5.47 * var(--u)) calc(6.83 * var(--u)) rgba(6, 118, 159, .15));
}

@media (prefers-reduced-motion: reduce) {

  .btn,
  .avatar,
  .submit__btn,
  .consent__box {
    transition: none;
  }
}

/* ---------- Текст по дуге (<curved-text>) ---------- */
curved-text {
  display: block;
  line-height: 0;
  pointer-events: none;
}

.curved-text__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

curved-text text {
  font-family: var(--font-display);
}

/* ==========================================================================
   Личный кабинет (account.html) — экран залогиненного пользователя.
   Макет 946:8980. Координаты и размеры — как в Figma, в единицах --u.
   ========================================================================== */

/* ---------- Карточка тарифа ---------- */
.plan {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(108 * var(--u));
  width: calc(400 * var(--u));
  height: calc(187 * var(--u));
  /* Размеры и координаты — из макета (Frame 1171277000, 400x187).
     Тариф задаётся data-plan на .plan, окончание подписки — классом is-expired. */
  border-radius: calc(45 * var(--u));
  border: calc(3 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(var(--plan-bg), var(--plan-bg)),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%, rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(31 * var(--u)) calc(21 * var(--u)) calc(-30 * var(--u)) var(--plan-shadow),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(30 * var(--u)) calc(-2.5 * var(--u)) #fff,
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) var(--plan-glow);
  overflow: hidden;
}

/* ---------- Темы тарифов ----------
   Цвета, тени и градиенты каждого тарифа взяты из макета. Значение по
   умолчанию — «Продвинутый», остальные переопределяют переменные. */
.plan,
.plan[data-plan="advanced"] {
  --plan-bg: #000;
  --plan-shadow: rgba(0, 0, 0, .3);
  --plan-glow: rgba(144, 137, 246, .6);
  --plan-accent: #fff;
  --plan-count: #000;
  --plan-stroke: #fff;
  --plan-name: linear-gradient(30deg, #F7DED7 0%, #B6C9D7 36%, #B4C2F3 70%, #E2CEEA 100%);
  --plan-fill: linear-gradient(30deg, #F7DED7 0%, #B6C9D7 36%, #B4C2F3 70%, #E2CEEA 100%);
  --plan-muted: rgba(255, 255, 255, .3);
  --plan-track: rgba(255, 255, 255, .3);
  --plan-used: #fff;
}

/* Личный — зелёная карточка. */
.plan[data-plan="personal"] {
  --plan-bg: #27E593;
  --plan-shadow: rgba(15, 160, 97, .3);
  --plan-glow: rgba(226, 246, 137, .6);
  --plan-accent: #32D890;
  --plan-count: #32D890;
  --plan-stroke: #fff;
  --plan-name: linear-gradient(32deg, #F2F2F2 0%, #D7FFA2 55%, #F2FFD5 100%);
  --plan-fill: linear-gradient(32deg, #F2F2F2 0%, #D7FFA2 55%, #F2FFD5 100%);
  --plan-muted: rgba(255, 255, 255, .6);
  --plan-track: rgba(255, 255, 255, .3);
  --plan-used: #fff;
}

/* Семья — розовая карточка. */
.plan[data-plan="family"] {
  --plan-bg: #F5197B;
  --plan-shadow: rgba(178, 6, 83, .3);
  --plan-glow: rgba(246, 188, 137, .6);
  --plan-accent: #FF2486;
  --plan-count: #FF2486;
  --plan-stroke: #fff;
  --plan-name: linear-gradient(34deg, #F2F2F2 22%, #FFD2A2 85%, #C4FFE6 100%);
  --plan-fill: linear-gradient(90deg, #F2F2F2 15%, #FFD2A2 35%, #C4FFE6 79%);
  --plan-muted: rgba(255, 255, 255, .6);
  --plan-track: rgba(255, 255, 255, .3);
  --plan-used: #fff;
}

/* Конструктор — фиолетовая карточка. */
.plan[data-plan="custom"] {
  --plan-bg: #8523C6;
  --plan-shadow: rgba(113, 19, 176, .5);
  --plan-glow: rgba(175, 255, 25, .6);
  --plan-accent: #8523C6;
  --plan-count: #8523C6;
  --plan-stroke: #fff;
  --plan-name: linear-gradient(30deg, #F7EED7 0%, #FFB3E4 36%, #EADECE 100%);
  --plan-fill: linear-gradient(90deg, #F7EED7 8%, #FFB3E4 36%, #EADECE 79%, #E5FFB4 100%);
  --plan-muted: rgba(255, 255, 255, .6);
  --plan-track: rgba(255, 255, 255, .3);
  --plan-used: #fff;
}

/* Подписка закончилась — светлая карточка, всё приглушено. */
.plan.is-expired {
  --plan-bg: #E4E4E4;
  --plan-shadow: rgba(0, 0, 0, .3);
  --plan-glow: rgba(0, 0, 0, .1);
  --plan-accent: #E4E3E3;
  --plan-count: #fff;
  --plan-stroke: #000;
  --plan-name: linear-gradient(rgba(0, 0, 0, .4), rgba(0, 0, 0, .4));
  --plan-fill: linear-gradient(rgba(0, 0, 0, .3), rgba(0, 0, 0, .3));
  --plan-muted: rgba(0, 0, 0, .4);
  --plan-track: rgba(0, 0, 0, .1);
  --plan-used: rgba(0, 0, 0, .6);
}

/* Даже погасшая карточка сохраняет отсвет своего тарифа: в макете у
   каждого из четырёх истёкших вариантов свой цвет внутренней тени. */
.plan.is-expired[data-plan="advanced"] {
  --plan-glow: rgba(137, 186, 246, .6);
}

.plan.is-expired[data-plan="personal"] {
  --plan-glow: rgba(226, 246, 137, .6);
  --plan-shadow: rgba(15, 160, 97, .3);
}

.plan.is-expired[data-plan="family"] {
  --plan-glow: rgba(245, 25, 123, .6);
  --plan-shadow: rgba(245, 25, 123, .2);
}

.plan.is-expired[data-plan="custom"] {
  --plan-glow: rgba(113, 19, 176, .6);
  --plan-shadow: rgba(113, 19, 176, .5);
}

/* ---------- Название тарифа (39px, 34;32) ---------- */
.plan__name {
  position: absolute;
  left: calc(34 * var(--u));
  /* Правка 13.10.2026 (Мария): «в названии тарифа буквы обрезаются по
     нижнему краю». Та же причина, что у .plan-card__name на экране
     тарифов (её чинили 12.10.2026): фиксированная height: 27px при
     шрифте 39px, а название красится через background-clip: text —
     градиент обрезается ровно по блоку, и хвосты «р», «у», «ц» теряют
     низ. Высоту задаём минимальной, блок растёт под строку; верх
     поднимаем на половину прибавки, чтобы текст остался на месте. */
  top: calc(26 * var(--u));
  width: calc(332 * var(--u));
  min-height: calc(39 * var(--u));
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(39 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  white-space: nowrap;
  background-image: var(--plan-name);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Строка трафика ---------- */
/* Точки-маркеры по краям (34;79 и 359;79, диаметр 7). */
.plan__dot {
  position: absolute;
  top: calc(79 * var(--u));
  width: calc(7 * var(--u));
  height: calc(7 * var(--u));
  border-radius: 50%;
  background: var(--plan-muted);
}

.plan__dot--left {
  left: calc(34 * var(--u));
}

.plan__dot--right {
  left: calc(359 * var(--u));
}

.plan__traffic-label,
.plan__traffic-used,
.plan__traffic-total {
  position: absolute;
  top: calc(77 * var(--u));
  height: calc(9 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(12 * var(--u));
  line-height: .9;
  letter-spacing: -.06em;
  color: var(--plan-muted);
}

.plan__traffic-label {
  left: calc(45 * var(--u));
  width: calc(98 * var(--u));
}

/* Израсходовано — ярче остального (в макете белым на цветной карточке). */
.plan__traffic-used {
  left: calc(297 * var(--u));
  width: calc(20 * var(--u));
  justify-content: flex-end;
  color: var(--plan-used);
}

.plan__traffic-total {
  left: calc(317 * var(--u));
  width: calc(38 * var(--u));
  justify-content: flex-end;
}

/* ---------- Полоса трафика (332x18 в 34;94, радиус 6) ---------- */
.plan__bar {
  position: absolute;
  left: calc(34 * var(--u));
  top: calc(94 * var(--u));
  width: calc(332 * var(--u));
  height: calc(18 * var(--u));
  border-radius: calc(6 * var(--u));
  background: var(--plan-track);
  overflow: hidden;
}

.plan__bar-fill {
  height: 100%;
  border-radius: inherit;
  background-image: var(--plan-fill);
}

/* ---------- Цена и дата (ряд в 36;137, промежуток 15) ----------
   Ряд упирается в кружки устройств (они начинаются с 287), поэтому
   ширину ограничиваем: «Подписка истекла» длиннее даты и иначе
   заезжает под счётчик. */
.plan__meta {
  position: absolute;
  left: calc(36 * var(--u));
  top: calc(137 * var(--u));
  max-width: calc(245 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(15 * var(--u));
}

.plan__price,
.plan__until {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 700;
  font-size: calc(18 * var(--u));
  line-height: .9;
  letter-spacing: -.06em;
  white-space: nowrap;
  /* В макете у строки нет заливки — только обводка 2px цветом фона. */
  color: transparent;
  -webkit-text-stroke: calc(1 * var(--u)) var(--plan-stroke);
  paint-order: stroke fill;
}

/* «Подписка истекла» набрана с более мягким трекингом, чем дата. */
.plan__until--note {
  letter-spacing: -.083em;
}

/* ---------- Устройства (кружки 35x35 в ряд, y=126) ----------
   Группа прижата к правому краю: сколько бы кружков ни было, последний
   стоит на месте. В макете у одного устройства счётчик начинается с
   307, у двух — с 287; разница ровно в один кружок со сдвигом. */
.plan__devices {
  position: absolute;
  top: calc(126 * var(--u));
  right: calc(33 * var(--u));
  height: calc(35 * var(--u));
  display: flex;
  align-items: center;
}

/* Кружки перекрывают друг друга и счётчик: device--1 поверх device--2,
   а тот — поверх счётчика. Порядок в разметке обратный, поэтому
   каждый следующий подтягивается влево. */
.plan__device {
  order: 1;
}

.plan__device--1 {
  order: 2;
}

/* Скрытый кружок не должен занимать место в ряду. */
.plan__device[hidden] {
  display: none;
}

/* Счётчик — белый круг с обводкой цвета тарифа. */
.plan__devices-count {
  position: relative;
  z-index: 3;
  flex: 0 0 auto;
  width: calc(35 * var(--u));
  height: calc(35 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: calc(20 * var(--u));
  border: calc(1.5 * var(--u)) solid var(--plan-accent);
  background: #fff;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.0167em;
  color: var(--plan-count);
}

/* На истёкшей карточке счётчик инвертирован: чёрный круг, белая цифра. */
.plan.is-expired .plan__devices-count {
  background: #000;
  color: #fff;
}

/* Кружки с иконками устройств; шаг 21/24 из макета даёт наложение. */
.plan__device {
  flex: 0 0 auto;
  width: calc(35 * var(--u));
  height: calc(35 * var(--u));
  margin-left: calc(-14 * var(--u));
  border-radius: calc(50 * var(--u));
  border: calc(1.5 * var(--u)) solid var(--plan-bg);
  background-image:
    radial-gradient(circle at 50% 0%,
      rgba(215, 215, 215, 1) 0%, rgba(175, 175, 175, .7) 17%,
      rgba(89, 89, 89, .9) 34%, rgba(154, 154, 154, .05) 49%);
  background-color: rgba(0, 0, 0, .5);
}

.plan.is-expired .plan__device {
  background-color: rgba(110, 110, 110, .1);
}

.plan__device--1 {
  z-index: 2;
}

.plan__device--2 {
  z-index: 1;
}

/* Сама картинка устройства поверх кружка. */
.plan__device::before {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

.plan__device--1::before {
  background-image: url("/app/assets/icons/plan-device-b.png");
}

.plan__device--2::before {
  background-image: url("/app/assets/icons/plan-device-a.png");
}

/* Бейдж «+ 150гб докуплено» поверх карточки. */
.traffic-badge {
  position: absolute;
  left: calc(135 * var(--u));
  top: calc(265 * var(--u));
  width: calc(162 * var(--u));
  height: calc(55 * var(--u));
  background: url("/app/assets/icons/traffic-badge.png") no-repeat center / contain;
  transform: rotate(-6deg);
  pointer-events: none;
}

/* ---------- Имя пользователя ---------- */
.account-user {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(79 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
}

/* Юзернейм в шапке не показываем — осталось только имя, поэтому
   display:inline (он ставил имя и ник в одну строку) больше не нужен. */
.account-user__name {
  margin: 0;
  color: var(--ink);
}

/* ---------- Кнопка «Открыть в Happ» ---------- */
.happ {
  position: absolute;
  left: 50%;
  top: calc(330 * var(--u));
  width: calc(295 * var(--u));
  height: calc(100.5 * var(--u));
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  transform: translateX(-50%);
  background: url("/app/assets/icons/happ-btn.png") no-repeat center / contain;
  cursor: pointer;
  transition: transform .2s ease, filter .2s ease;
}

/* ---------- Плитки «Тарифы» и «Трафик» ---------- */
.tiles {
  display: contents;
}

.tile {
  position: absolute;
  top: calc(475 * var(--u));
  width: calc(195 * var(--u));
  height: calc(116 * var(--u));
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  border-radius: calc(30 * var(--u));
  background: var(--paper);
  cursor: pointer;
  transition: transform .2s ease, filter .2s ease;
}

.tile--tariff {
  left: calc(20 * var(--u));
}

.tile--traffic {
  left: calc(225 * var(--u));
}

.tile__title,
.tile__hint {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
}

.tile__title {
  top: calc(55 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

.tile__hint {
  top: calc(84 * var(--u));
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(12 * var(--u));
  line-height: 1.1;
  letter-spacing: -.0167em;
  color: rgba(0, 0, 0, .4);
}

/* Розовые звёзды над плитками — декор из макета, вместе с иконкой внутри. */
.tile::before {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(-60 * var(--u));
  width: calc(127 * var(--u));
  height: calc(126 * var(--u));
  transform: translateX(-50%);
  pointer-events: none;
}

/* ВРЕМЕННО: иконка тарифов — копия трафика, нужен отдельный SVG. */
.tile--tariff::before {
  background: url("/app/assets/icons/tile-tariff.svg") no-repeat center / contain;
}

.tile--traffic::before {
  background: url("/app/assets/icons/icon-traffic.svg") no-repeat center / contain;
}

/* ---------- Инструкция ---------- */
.instruction {
  position: absolute;
  left: calc(40 * var(--u));
  top: calc(625 * var(--u));
  width: calc(355 * var(--u));
  height: calc(69 * var(--u));
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background: url("/app/assets/icons/instruction-btn.png") no-repeat left center / contain;
  cursor: pointer;
  transition: transform .2s ease, filter .2s ease;
}

/* ---------- Нижняя панель ----------
   Прибита к низу окна, а не к координате макета: страницы длиннее экрана,
   и панель, лежащая в потоке, уезжала вверх вместе с содержимым — под ней
   открывалась пустота. fixed держит её на месте при любой прокрутке. */
/* Панель не ездит со страницей — прибита к низу окна. Сцена тянется на
   всю высоту окна (см. .stage:has(.tabbar)), поэтому низ окна и низ
   мини-аппа совпадают, и панель стоит у края экрана, а не в фоне. */
/* ---------- Всплывающее уведомление ----------
   Короткое подтверждение действия (скопировали ссылку). Висит над
   панелью навигации, нажатия не перехватывает. */
.toast {
  position: fixed;
  z-index: 8;
  left: 50%;
  bottom: calc(150 * var(--u));
  margin: 0;
  padding: calc(14 * var(--u)) calc(24 * var(--u));
  max-width: calc(var(--stage) - 48 * var(--u));
  border-radius: calc(24 * var(--u));
  background: rgba(0, 0, 0, .85);
  box-shadow: 0 calc(8 * var(--u)) calc(24 * var(--u)) calc(-8 * var(--u)) rgba(0, 0, 0, .45);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.2;
  letter-spacing: -.02em;
  text-align: center;
  color: #fff;
  pointer-events: none;
  /* Появляется снизу вверх; стартовое положение — чуть ниже. */
  transform: translate(-50%, calc(12 * var(--u)));
  opacity: 0;
  transition: opacity .2s ease, transform .2s ease;
}

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

.tabbar {
  position: fixed;
  z-index: 5;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: var(--stage);
  height: calc(135 * var(--u));
  /* Правка 18.10.2026: панель без значка. В tabbar.png значок VPN с
     надписью был вшит в картинку, и свой значок не мог его перекрыть.
     tabbar-plain.png — та же панель, из неё вырезан значок и ореол. */
  background: url("/app/assets/icons/tabbar-plain.png") no-repeat center top / contain;
}

.tabbar__item {
  position: absolute;
  top: calc(30 * var(--u));
  width: calc(59 * var(--u));
  height: calc(75 * var(--u));
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background: none;
  cursor: pointer;
  transition: transform .2s ease;
}

.tabbar__item--friends {
  left: calc(113 * var(--u));
}

.tabbar__item--profile {
  left: calc(268 * var(--u));
}

/* Значок VPN: белый «цветок», внутри иконка питания. Розовая в своём
   разделе, чёрная в чужом — меняется только она (макет 1007:11841).

   Правка 18.10.2026 (Матвей: «вот так должно быть»). Раньше значок брали
   из tabbar.png и накрывали tabbar-vpn-idle.png, но в обеих картинках
   внутри нарисована надпись «VPN», а в макете там иконка питания —
   перекрытием это не лечилось. Теперь значок целиком свой: форма,
   объём и иконка собраны в SVG по макету, поэтому состояние видно
   сразу и надпись не выглядывает.

   Раздел VPN это account, devices (туда ведёт кнопка «VPN») и tariffs,
   которые открываются из devices. */
.tabbar__item--vpn {
  left: calc(166 * var(--u));
  top: calc(2 * var(--u));
  width: calc(107 * var(--u));
  height: calc(107 * var(--u));
  border-radius: 50%;
  background: url("/app/assets/icons/tabbar-vpn-off.svg") no-repeat center / contain;
}

.screen--account .tabbar__item--vpn,
.screen--devices .tabbar__item--vpn,
.screen--tariffs .tabbar__item--vpn {
  background-image: url("/app/assets/icons/tabbar-vpn-on.svg");
}

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

@media (hover: hover) {

  .happ:hover {
    transform: translateX(-50%) translateY(calc(-2 * var(--u)));
    filter: brightness(1.04);
  }

  .tile:hover,
  .instruction:hover {
    transform: translateY(calc(-2 * var(--u)));
    filter: brightness(1.04);
  }

  .tabbar__item:hover {
    transform: scale(1.06);
  }
}

/* Центрирование Happ держится на translateX(-50%) — дописываем к нему. */
.happ:active {
  transform: translateX(-50%) scale(.985);
}

.tile:active,
.instruction:active {
  transform: scale(.985);
}

.tabbar__item:active {
  transform: scale(.94);
}

@media (prefers-reduced-motion: reduce) {

  .happ,
  .tile,
  .instruction,
  .tabbar__item {
    transition: none;
  }
}

/* ==================================================================
   Экран «Выберите тариф» (макет 962:9209, сетка 440×956)
   ================================================================== */

.screen--tariffs {
  /* Экран длиннее окна: 782 = низ кнопки «К оплате» + отступ.
     Правка 15.10.2026 (Евгений, скриншот): снизу появилась панель
     разделов (ТЗ п. 8). Общее правило .stage:has(.tabbar) .screen даёт
     ей padding-bottom, но при border-box этот отступ съедал высоту
     изнутри — кнопка уезжала под панель. Тут контент размечен
     абсолютно от верха, поэтому высота считается без padding, а отступ
     прибавляется снизу: кнопка остаётся над панелью, и до неё можно
     долистать. */
  height: calc(810 * var(--u));
  box-sizing: content-box;
}

/* Правка 13.10.2026 (Мария): «на десктопе внизу серое пространство».
   Высота задана по макету, а окно браузера выше — снизу просвечивал фон
   страницы (--backdrop). Экранов с нижней панелью это не касалось: для
   них правило .stage:has(.tabbar) уже тянет сцену на всю высоту окна, а
   у тарифов и трафика панели нет. */
.stage:has(.screen--tariffs),
.stage:has(.screen--traffic) {
  min-height: 100vh;
  min-height: 100dvh;
}

.stage:has(.screen--tariffs) .screen--tariffs,
.stage:has(.screen--traffic) .screen--traffic {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Правка 17.10.2026 (Мария): «кнопку оплаты не видно на остальных
   страницах, и не всегда понятно, что надо прокрутить».

   Экраны тарифов и трафика размечены по макету 844px: кнопка стоит на
   фиксированных 696px от верха. На окне пониже (650 и меньше — обычное
   дело для вебвью с клавиатурой или на невысоком телефоне) она просто
   за кадром, а подсказки прокрутить нет. Измерено: при 650px до неё
   оставалось 43px прокрутки, при 560 — 133px.

   Прижимаем кнопку к нижнему краю окна, когда она туда не помещается.
   position: fixed не годится — сцена центрирована и уже 440px, fixed
   увёл бы кнопку за её край на десктопе (та же причина, по которой у
   .paybar выбран margin-top: auto). */
/* Правка 17.10.2026. Кнопку «К оплате» я прижимал к низу ОКНА
   (position: fixed), чтобы на невысоком экране её не приходилось искать
   прокруткой — у .screen стоит overflow: hidden, своей прокрутки нет.

   Это породило две поломки подряд: сперва из-под кнопки торчал значок
   панели разделов, потом кнопка легла прямо на карточку «Конструктор»
   (измерено: на окне 560px перекрытие 67px). Причина общая — карточки
   размечены АБСОЛЮТНО от верха экрана и за кнопкой не двигаются,
   сколько ни добавляй padding.

   Прижимать к окну больше не пытаемся: кнопка остаётся на своём месте
   в потоке, а до неё доводит прокрутка страницы (не экрана — страница
   прокручивается, высота экрана 810 больше окна). Вместо этого даём
   понять, что ниже что-то есть: на невысоком окне экран чуть
   укорачивается, и край кнопки попадает в видимую область. */
@media (max-height: 760px) {

  /* Низ кнопки — 782. Оставляем её и небольшой хвост в пределах
     прокрутки, чтобы она не оказывалась ровно у границы. */
  .screen--tariffs,
  .screen--traffic {
    height: calc(800 * var(--u));
  }
}

/* Правка 15.10.2026 (Евгений, скриншот): панель разделов накрыла кнопку
   «К оплате».

   Общее правило .stage:has(.tabbar) .screen отводит панели место
   внутренним отступом при border-box. Для экранов, размеченных
   абсолютно от верха, это не работает: отступ съедает высоту изнутри, а
   координаты элементов не сдвигаются — кнопка на 696 оказывается под
   панелью. Здесь высота считается по контенту, а отступ прибавляется
   снизу, и до кнопки можно долистать. */
.stage:has(.tabbar) .screen--tariffs {
  box-sizing: content-box;
}

/* ---------- Стрелка «назад» ---------- */
.tariffs__back {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(74 * var(--u));
  width: calc(26 * var(--u));
  height: calc(20 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/back-arrow.svg") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.tariffs__back:active {
  transform: scale(.9);
}

/* ---------- Заголовки секций ---------- */
.tariffs__title {
  position: absolute;
  left: calc(73.5 * var(--u));
  top: calc(72 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
}

.tariffs__title--period {
  left: calc(68 * var(--u));
  top: calc(592 * var(--u));
}

.tariffs__title-badge {
  flex: 0 0 auto;
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  background: url("/app/assets/icons/tariff-badge.svg") no-repeat center / contain;
}

/* У «Периода подписки» свой значок — календарь */
.tariffs__title--period .tariffs__title-badge {
  background-image: url("/app/assets/icons/period-badge.svg");
}

.tariffs__title-text {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(26 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

/* ---------- Карточки тарифов ---------- */
.plans {
  display: contents;
}

.plan-card {
  position: absolute;
  left: calc(20 * var(--u));
  width: calc(400 * var(--u));
  height: calc(86 * var(--u));
  padding: 0;
  text-align: left;
  border-radius: calc(25 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* Неактивная карточка: полупрозрачная заливка + светлая обводка-градиент */
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    /* В макете заливка 10% чёрного, но поверх #E4E4E4 карточка выходит
       почти в цвет фона — берём плотнее, чтобы читалась как на макете. */
    linear-gradient(rgba(0, 0, 0, .18), rgba(0, 0, 0, .18)),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  transition: transform .18s ease;
}

/* Порядок из макета: Личный, Продвинутый, Семья, Конструктор */
.plan-card {
  z-index: 1;
}

.plan-card.is-active {
  z-index: 2;
}

.plan-card[data-plan="personal"] {
  top: calc(113 * var(--u));
}

.plan-card[data-plan="advanced"] {
  top: calc(211 * var(--u));
}

.plan-card[data-plan="family"] {
  top: calc(309 * var(--u));
}

.plan-card[data-plan="custom"] {
  top: calc(407 * var(--u));
}

/* Пробный период (макет TrialMain). Правка 14.10.2026: правила позиции
   у карточки не было вовсе — она висела поверх заголовка. По макету
   пробный стоит ПЕРВЫМ, остальные уезжают на шаг вниз; шаг тот же
   98px, что между платными. Когда триал недоступен, карточка скрыта
   атрибутом hidden, и :has() ниже не срабатывает — платные остаются на
   своих местах. */
.plan-card[data-plan="trial"] {
  top: calc(113 * var(--u));
}

.plans:has(.plan-card[data-plan="trial"]:not([hidden])) .plan-card[data-plan="personal"] {
  top: calc(211 * var(--u));
}

.plans:has(.plan-card[data-plan="trial"]:not([hidden])) .plan-card[data-plan="advanced"] {
  top: calc(309 * var(--u));
}

.plans:has(.plan-card[data-plan="trial"]:not([hidden])) .plan-card[data-plan="family"] {
  top: calc(407 * var(--u));
}

.plans:has(.plan-card[data-plan="trial"]:not([hidden])) .plan-card[data-plan="custom"] {
  top: calc(505 * var(--u));
}

/* Карточек стало пять — период, счётчик и кнопка уезжают на тот же шаг
   98px, иначе «Период подписки» наезжает на «Конструктор», а счётчик
   «Конструктора» прячется под его же карточкой. */
.screen--tariffs.has-trial .counter {
  top: calc(568 * var(--u));
}

/* С открытым счётчиком экран и так выше (has-counter), а пятая
   карточка добавляет ещё шаг. */
.screen--tariffs.has-trial.has-counter {
  height: calc(978 * var(--u));
}

.screen--tariffs.has-trial .tariffs__title--period {
  top: calc(690 * var(--u));
}

.screen--tariffs.has-trial .periods {
  top: calc(727 * var(--u));
}

.screen--tariffs.has-trial .checkout {
  top: calc(794 * var(--u));
}

/* Выбран пробный — периода нет: он бесплатный и всегда на 3 дня.
   В макете TrialMain блок периода при этом не показывается, а кнопка
   говорит «Попробовать · 0 ₽». */
.screen--tariffs.trial-picked .tariffs__title--period,
.screen--tariffs.trial-picked .periods {
  display: none;
}

.screen--tariffs.trial-picked .checkout {
  top: calc(690 * var(--u));
}

/* Сумма в кнопке — мятная, как «бесплатно» в макете. */
.screen--tariffs.trial-picked .checkout__sum {
  background: #49F9AD;
}

/* «Попробовать» длиннее «К оплате», под которое отведены 152px, —
   уменьшаем кегль и даём больше места, иначе надпись уезжает под
   плашку с суммой. */
.screen--tariffs.trial-picked .checkout__label {
  width: calc(210 * var(--u));
  font-size: calc(23 * var(--u));
}

.plan-card:active {
  transform: scale(.99);
}

/* Выбранная карточка — чёрная, с цветной внутренней подсветкой */
.plan-card.is-active {
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(144, 137, 246, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

/* ---------- Цвет выбранной карточки по тарифу ----------
   В макете каждый тариф свой: «Личный» зелёный, «Продвинутый» чёрный,
   «Семья» розовая, «Конструктор» фиолетовый. Меняются заливка,
   цвет падающей тени и нижняя внутренняя подсветка. */

/* «Личный» — зелёный */
.plan-card[data-plan="personal"].is-active {
  background-image:
    linear-gradient(#27E593, #27E593),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(15, 165, 99, .3),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(226, 246, 137, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

/* «Семья» — розовая */
.plan-card[data-plan="family"].is-active {
  background-image:
    linear-gradient(#F5197B, #F5197B),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(143, 12, 70, .5),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(246, 188, 137, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

/* «Конструктор» — фиолетовый */
.plan-card[data-plan="custom"].is-active {
  background-image:
    linear-gradient(#8523C6, #8523C6),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(142, 35, 215, .6),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(144, 137, 246, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

.plan-card__name {
  position: absolute;
  /* Минус 2px рамки: left считается от padding-box. */
  left: calc(23 * var(--u));
  top: calc(24 * var(--u));
  /* Правка 12.10.2026 (Мария): «обрезается часть букв снизу при смене
     цвета». Была фиксированная height: 14px при шрифте 20px — обычному
     тексту это сходило, а у выбранной карточки название красится через
     background-clip: text, и градиент обрезается ровно по блоку: буквы
     с хвостами (у, р, ц) теряли низ. Высоту задаём минимальной — блок
     растёт под строку, верхняя граница остаётся на месте. */
  min-height: calc(14 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  /* Ниже 1 межстрочный интервал прижимал хвосты букв к краю блока. */
  line-height: 1.1;
  letter-spacing: -.03em;
  color: rgba(0, 0, 0, .3);
}

/* У выбранной карточки название — перламутровый градиент,
   свой для каждого тарифа */
.plan-card.is-active .plan-card__name {
  background-image: linear-gradient(30deg,
      #F7DED7 0%, #B6C9D7 36%, #B4C2F3 70%, #E2CEEA 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.plan-card[data-plan="personal"].is-active .plan-card__name {
  background-image: linear-gradient(32deg,
      #F2F2F2 0%, #D7FFA2 55%, #F2FFD5 100%);
}

.plan-card[data-plan="family"].is-active .plan-card__name {
  background-image: linear-gradient(34deg,
      #F2F2F2 22%, #FFD2A2 85%, #C4FFE6 100%);
}

.plan-card[data-plan="custom"].is-active .plan-card__name {
  background-image: linear-gradient(30deg,
      #F7EED7 0%, #FFB3E4 36%, #F3B4B5 70%, #EADECE 100%);
}

.plan-card__devices {
  position: absolute;
  left: calc(23 * var(--u));
  top: calc(49 * var(--u));
  height: calc(10 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: .9;
  letter-spacing: -.04em;
  color: rgba(0, 0, 0, .3);
}

.plan-card.is-active .plan-card__devices {
  color: rgba(255, 255, 255, .6);
}

/* Плашка с ценой справа */
.plan-card__price {
  position: absolute;
  /* left/top у absolute-потомка отсчитываются от padding-box, а координаты
     макета — от края карточки, поэтому вычитаем 2px рамки. */
  left: calc(239 * var(--u));
  top: calc(14 * var(--u));
  width: calc(144 * var(--u));
  height: calc(54 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(4 * var(--u));
  border-radius: calc(14 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(13 * var(--u));
  letter-spacing: -.03em;
  color: rgba(1, 1, 1, .3);
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    radial-gradient(51.78% 51.78% at 50% 50.03%,
      rgba(255, 255, 255, 0) 91.47%, rgba(255, 255, 255, .01) 100%),
    linear-gradient(rgba(255, 255, 255, .1), rgba(255, 255, 255, .1));
  box-shadow: inset calc(3 * var(--u)) calc(3 * var(--u)) calc(17 * var(--u)) calc(-3 * var(--u)) rgba(255, 255, 255, .8);
}

/* Кегль чуть меньше макетного: четырёхзначные суммы (и «₽» следом)
   не помещались в плашку и выпирали за её край. */
.plan-card__sum {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(17 * var(--u));
  line-height: 1;
  letter-spacing: -.0357em;
  white-space: nowrap;
}

/* Плашка выбранной карточки — тёмная, цифры белые */
.plan-card.is-active .plan-card__price {
  color: var(--paper);
  border-color: transparent;
  background-image:
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .01) 91%, rgba(255, 255, 255, 1) 100%),
    linear-gradient(rgba(255, 255, 255, .1), rgba(255, 255, 255, .1));
  box-shadow:
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .8),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(20 * var(--u)) calc(-2.5 * var(--u)) #fff,
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(20 * var(--u)) calc(-2.5 * var(--u)) #fff;
}

/* ---------- Плашки «Хит» и скидок ----------
   Скотч: форму и наклон берём из SVG-экспорта Figma как маску (у него
   рваные края в альфе), а цвет задаём здесь — экспорт Figma опирается
   на смешивание слоёв, которое браузер внутри <img> не воспроизводит.
   Надпись остаётся обычным HTML поверх плёнки. */
.pill {
  position: absolute;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.0383em;
  pointer-events: none;
}

.pill::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--pill-color);
  -webkit-mask: var(--pill-tape) no-repeat center / 100% 100%;
  mask: var(--pill-tape) no-repeat center / 100% 100%;
}

/* «Хит» — на карточке «Продвинутый», левый верхний угол.
   В отличие от скидок это готовая цветная картинка с уже напечатанной
   надписью: кладём её фоном, а не маской. Пропорции 77x52. */
.pill--hit {
  left: calc(-14 * var(--u));
  top: calc(-22 * var(--u));
  width: calc(71 * var(--u));
  height: calc(48 * var(--u));
  background: url("/app/assets/icons/hit.png") no-repeat center / contain;
  /* Надпись уже есть на картинке — HTML-текст прячем,
     но оставляем в дереве доступности. */
  font-size: 0;
  color: transparent;
  z-index: 2;
}

/* Плёнка-маска не нужна: у «Хита» своя картинка. */
.pill--hit::before {
  content: none;
}

/* Скидки над периодами. Как и «Хит» — готовые картинки с напечатанным
   процентом, поэтому HTML-текст прячем (в дереве доступности он остаётся). */
.pill--save {
  font-size: 0;
  color: transparent;
}

.pill--save::before {
  content: none;
}

.pill--save-3 {
  z-index: 2;
  left: calc(167.5 * var(--u));
  background: url("/app/assets/icons/save-31.png") no-repeat center / contain;
  top: calc(26 * var(--u));
  width: calc(55 * var(--u));
  height: calc(35 * var(--u));
}

.pill--save-12 {
  z-index: 2;
  left: calc(307.5 * var(--u));
  background: url("/app/assets/icons/save-36.png") no-repeat center / contain;
  top: calc(26 * var(--u));
  width: calc(55 * var(--u));
  height: calc(35 * var(--u));
}

/* ---------- Период подписки ---------- */
.periods {
  position: absolute;
  left: calc(19.5 * var(--u));
  top: calc(629 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(10 * var(--u));
}

.period {
  width: calc(127 * var(--u));
  height: calc(45 * var(--u));
  padding: 0;
  border: 0;
  border-radius: calc(14 * var(--u));
  background: rgba(0, 0, 0, .05);
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .3);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.period:active {
  transform: scale(.97);
}

/* Выбранный период — белая «таблетка» со стеклянной подсветкой */
.period.is-active {
  background: #000;
  color: var(--paper);
  box-shadow:
    0 calc(6 * var(--u)) calc(6 * var(--u)) calc(-4 * var(--u)) rgba(0, 0, 0, .3),
    inset calc(5 * var(--u)) calc(5 * var(--u)) calc(15 * var(--u)) calc(-2 * var(--u)) rgba(255, 255, 255, .8),
    inset calc(-2.5 * var(--u)) calc(-2.5 * var(--u)) calc(9 * var(--u)) 0 rgba(255, 255, 255, .7);
}

/* ---------- К оплате ---------- */
.checkout {
  position: absolute;
  /* НИЖЕ панели навигации (z-index 5) — и это важно.

     Правка 18.10.2026 (Мария: «к оплате не должна перекрывать значок
     vpn»). z-index: 6 здесь стоял с тех пор, когда кнопка прижималась
     к низу ОКНА (position: fixed): тогда она была отдельным слоем над
     страницей, и поднять её над панелью было осмысленно. df2ad3f
     вернул кнопку в поток, а поднятый слой остался — панель осталась
     fixed, кнопка поехала по ней и накрыла круглый значок VPN.
     Измерено: на окне 760px палец в центре значка попадал в .checkout,
     то есть значок был не нажимаем вовсе.

     Белое «облако» вокруг значка больше не наползает на кнопку: это
     лечилось прижатием к окну, которого теперь нет, — кнопка стоит в
     потоке выше панели по координате, а не по слою. */
  left: calc(21 * var(--u));
  top: calc(696 * var(--u));
  width: calc(398 * var(--u));
  height: calc(86 * var(--u));
  padding: 0;
  border-radius: calc(46.26 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(255, 64, 157, .6),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
  transition: transform .18s ease;
}

.checkout:active {
  transform: scale(.99);
}

.checkout__label {
  position: absolute;
  left: calc(30 * var(--u));
  top: calc(30 * var(--u));
  width: calc(152 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  color: var(--paper);
}

/* Розовая плашка с суммой */
.checkout__sum {
  position: absolute;
  left: calc(262 * var(--u));
  top: calc(16 * var(--u));
  width: calc(122 * var(--u));
  height: calc(54 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: calc(30 * var(--u));
  /* В макете сумма набрана Asgard Number 28px, но плашка всего 122px:
     «2 999 ₽» туда встаёт впритык, а суммы длиннее вылезали за края.
     Даём внутренние поля и не даём строке переноситься. */
  padding: 0 calc(10 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(25 * var(--u));
  line-height: 1;
  letter-spacing: -.0357em;
  white-space: nowrap;
  color: var(--ink);
  background-image:
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .01) 91%, rgba(255, 255, 255, 1) 100%),
    linear-gradient(#FF2486, #FF2486);
  box-shadow:
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .8),
    inset calc(-2.5 * var(--u)) calc(-3.25 * var(--u)) calc(7.5 * var(--u)) calc(-2.5 * var(--u)) #000,
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(30 * var(--u)) calc(-2.5 * var(--u)) #fff,
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(0, 0, 0, .2);
}

@media (prefers-reduced-motion: reduce) {

  .tariffs__back,
  .plan-card,
  .period,
  .checkout {
    transition: none;
  }
}

/* ==================================================================
   Окно оформления заказа (Group 628189 в макете 920:17368)
   Открывается по тапу на тариф. Панель 400×647 поверх затемнения.
   ================================================================== */

/* Затемнение поверх экрана (Rectangle 30188) */
.order-scrim {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 10;
  transition: opacity .22s ease, visibility .22s ease;
}

.order-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Сама панель */
.order {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(138 * var(--u));
  width: calc(400 * var(--u));
  height: calc(647 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.order-scrim.is-open .order {
  transform: none;
}

/* ---------- Шапка: эмблема, сумма, подпись ---------- */

/* Круглая эмблема (Vector, 91×91 в точке 23;32) */
.order__logo {
  position: absolute;
  left: calc(23 * var(--u));
  top: calc(32 * var(--u));
  width: calc(91 * var(--u));
  height: calc(91 * var(--u));
  background: url("/app/assets/icons/modal-logo.svg") no-repeat center / contain;
}

/* Крупная сумма (22;154, шрифт 28) */
.order__total {
  position: absolute;
  left: calc(22 * var(--u));
  top: calc(154 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-number);
  font-weight: 500;
  font-size: calc(60 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

.order__caption {
  position: absolute;
  left: calc(23 * var(--u));
  top: calc(214 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* ---------- Строки «параметр — значение» ---------- */

/* Подпись слева, значение справа; координаты — из макета */
.order__row {
  position: absolute;
  left: calc(24 * var(--u));
  height: calc(24 * var(--u));
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.order__row--plan {
  top: calc(266 * var(--u));
  width: calc(352 * var(--u));
}

.order__row--user {
  top: calc(298 * var(--u));
  width: calc(352 * var(--u));
}

.order__row--period {
  top: calc(331 * var(--u));
  width: calc(358 * var(--u));
}

.order__row--expires {
  top: calc(363 * var(--u));
  width: calc(358 * var(--u));
}

.order__row--devices {
  top: calc(396 * var(--u));
  width: calc(351 * var(--u));
}

.order__label {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.0222em;
  color: rgba(0, 0, 0, .3);
}

.order__value {
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(16 * var(--u));
  line-height: 1;
  letter-spacing: -.025em;
  color: var(--ink);
}

/* Точки-«кавычки» вокруг значений периода и даты (Ellipse 1655/1656) */
.order__value--dotted::before,
.order__value--dotted::after {
  content: "";
  flex: 0 0 auto;
  width: calc(4 * var(--u));
  height: calc(7.69 * var(--u));
  border-radius: 50%;
  background: var(--ink);
}

/* Аватар получателя — фото 18×20.65 (Group 628121) */
.order__avatar {
  flex: 0 0 auto;
  width: calc(18 * var(--u));
  height: calc(20.65 * var(--u));
  margin-right: calc(3 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, .12);
}

/* ---------- Количество устройств ----------
   В макете это не счётчик, а две круглые фишки 24×24:
   значок-бейдж (x=301) и чёрный кружок с цифрой (x=327). */
/* Фишки прибиты к координатам макета (301 и 327 от края панели),
   а не прижаты к правому краю строки. */
.order__devices {
  position: absolute;
  left: calc(315 * var(--u));
  /* 301 − 24 (левый край строки) */
  display: flex;
  align-items: center;
  gap: calc(2 * var(--u));
}

.order__devices-badge {
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  background: url("/app/assets/icons/tariff-badge.svg") no-repeat center / contain;
}

.order__count {
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ink);
  font-family: var(--font-text);
  font-weight: 700;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: var(--paper);
}

/* ---------- Разделители (Line 120/121) ---------- */
.order__line {
  position: absolute;
  left: calc(34 * var(--u));
  width: calc(332 * var(--u));
  height: calc(2 * var(--u));
  /* Line 120/121: горизонтальный градиент, гаснущий к краям. */
  background: linear-gradient(270deg,
      rgba(0, 0, 0, .05) 10%, rgba(0, 0, 0, .25) 50%, rgba(0, 0, 0, .05) 100%);
}

.order__line--top {
  top: calc(442 * var(--u));
}

.order__line--bottom {
  top: calc(518 * var(--u));
}

/* ---------- Списание с баланса ---------- */
.order__charge {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(461 * var(--u));
  width: calc(190 * var(--u));
  height: calc(35 * var(--u));
}

.order__charge-note {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(12 * var(--u));
  line-height: 1;
  letter-spacing: -.0333em;
  color: rgba(0, 0, 0, .4);
}

/* Ширина по макету (190px): длинные суммы ужимаем, а не переносим,
   иначе строка уезжает под кнопку пополнения. */
.order__charge-sum {
  position: absolute;
  left: 0;
  top: calc(25 * var(--u));
  width: calc(190 * var(--u));
  height: calc(20 * var(--u));
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(22 * var(--u));
  line-height: 1;
  letter-spacing: -.0357em;
  white-space: nowrap;
  color: var(--ink);
}

/* Текущий баланс — серый: акцент на том, сколько останется после списания. */
.order__charge-was {
  color: rgba(0, 0, 0, .3);
}

/* Кнопка пополнения баланса (Frame 1171276922).
   В макете лежит рядом с панелью: 293;596 на кадре —
   внутри панели (20;138) это 273;458, правее блока списания. */
.order__topup {
  position: absolute;
  left: calc(273 * var(--u));
  top: calc(458 * var(--u));
  width: calc(93 * var(--u));
  height: calc(42 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/order-topup.svg") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.order__topup:active {
  transform: scale(.96);
}

/* ---------- Кнопка «Оплатить» ---------- */
.order__pay {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(542 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: calc(2 * var(--u)) solid transparent;
  border-radius: calc(46.26 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(255, 64, 157, .6),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  color: var(--paper);
  transition: transform .18s ease;
}

.order__pay:active {
  transform: scale(.99);
}

/* Полоска-«ручка» вверху панели (Rectangle 30189/30190, 50×6) */
.order__grip {
  position: absolute;
  left: calc(175 * var(--u));
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  padding: 0;
  border: calc(.8 * var(--u)) solid transparent;
  border-radius: calc(10 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .1)),
    linear-gradient(180deg, rgba(0, 0, 0, .05) 0%, rgba(0, 0, 0, .2) 100%);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0, 0, 0, .35);
}

/* ------------------------------------------------------------------
   Тот же заказ, но для трафика: периода здесь нет, поэтому строк на
   одну меньше — всё ниже «Получателя» подтягиваем на её место, а панель
   и низ (линии, списание, кнопки) укорачиваем на тот же шаг.
   ------------------------------------------------------------------ */
.order--traffic {
  height: calc(614 * var(--u));
}

.order--traffic .order__row--expires {
  top: calc(331 * var(--u));
}

.order--traffic .order__row--devices {
  top: calc(363 * var(--u));
}

.order--traffic .order__line--top {
  top: calc(409 * var(--u));
}

.order--traffic .order__line--bottom {
  top: calc(485 * var(--u));
}

.order--traffic .order__charge {
  top: calc(428 * var(--u));
}

.order--traffic .order__topup {
  top: calc(425 * var(--u));
}

.order--traffic .order__pay {
  top: calc(509 * var(--u));
}

/* Объём — это три-пять цифр: круглый счётчик устройств их не вмещает,
   поэтому растягиваем кружок в пилюлю. */
.order--traffic .order__count {
  width: auto;
  min-width: calc(24 * var(--u));
  padding: 0 calc(9 * var(--u));
  border-radius: calc(12 * var(--u));
}

/* Пилюля шире кружка — сдвигаем строку левее, чтобы правый край
   остался на месте. */
.order--traffic .order__devices {
  left: auto;
  right: 0;
}

/* В строке объёма значок трафика, а не устройства */
.order--traffic .order__devices-badge {
  background-image: url("/app/assets/icons/traffic-badge-icon.svg");
}

/* ==================================================================
   Счётчик устройств (макет 3063:2744, Frame 1171276914)
   Раскрывается под карточкой «Конструктор»: панель 414x153 заходит
   под карточку, ниже — «−», текущее число и «+».
   ================================================================== */

.counter {
  position: absolute;
  left: calc(13 * var(--u));
  /* Карточка «Конструктор» занимает 407..493 — панель заводим под неё */
  top: calc(470 * var(--u));
  width: calc(414 * var(--u));
  height: calc(76 * var(--u));
  border-radius: calc(33 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(var(--paper), var(--paper)),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  z-index: 0;
}

/* ---------- Кнопки «−» и «+» ---------- */
/* Светлые пилюли со стеклянным бликом — как «+ ₽» в окне заказа */
.counter__step {
  position: absolute;
  top: calc(27 * var(--u));
  height: calc(39 * var(--u));
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(17 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* Правка 12.10.2026 (Мария): «при нажатии на плюс меняет масштаб
     туда-сюда». Два быстрых нажатия подряд вебвью принимал за
     двойной тап и зумил страницу. manipulation отключает именно
     двойной тап, обычные нажатия и прокрутку не трогает. */
  touch-action: manipulation;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    radial-gradient(120% 140% at 50% -10%,
      rgba(255, 255, 255, .95) 30%, rgba(238, 238, 238, .85) 62%, rgba(206, 206, 206, .8) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  box-shadow: 0 calc(6 * var(--u)) calc(10 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .4);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(22 * var(--u));
  line-height: 1;
  color: var(--ink);
  transition: transform .18s ease;
}

.counter__step--down {
  left: calc(11 * var(--u));
  width: calc(120 * var(--u));
}

.counter__step--up {
  left: calc(278 * var(--u));
  width: calc(121 * var(--u));
}

.counter__step:active {
  transform: scale(.96);
}

/* Недоступную границу диапазона гасим, но кнопку не прячем */
.counter__step[disabled] {
  opacity: .4;
  cursor: default;
}

/* ---------- Текущее число ---------- */
/* Полупрозрачная пилюля со значком устройства и числом */
.counter__value {
  position: absolute;
  left: calc(157 * var(--u));
  top: calc(31 * var(--u));
  height: calc(39 * var(--u));
  padding: 0 calc(15 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
  border-radius: calc(56 * var(--u));
  background: rgba(255, 255, 255, .2);
}

.counter__badge {
  width: calc(13 * var(--u));
  height: calc(19 * var(--u));
  background: url("/app/assets/icons/tariff-badge.svg") no-repeat center / contain;
}

/* Число набрано цифровым начертанием, с ведущим нулём */
.counter__num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(30 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

/* Экран вырастает, когда счётчик раскрыт */
.screen--tariffs.has-counter {
  height: calc(880 * var(--u));
}

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

/* ==================================================================
   Ползунок объёма (макет 3063:2744)
   Раскрывается под карточкой «Свой объем»: белая панель 414x216,
   карточка ложится на её верх, ниже — шкала и быстрый выбор.
   ================================================================== */

/* Панель заходит под карточку: её верх перекрыт самой карточкой,
   поэтому видна только нижняя часть со шкалой. */
.volume {
  position: absolute;
  left: calc(13 * var(--u));
  top: calc(372 * var(--u));
  width: calc(414 * var(--u));
  height: calc(145 * var(--u));
  border-radius: calc(33 * var(--u));
  background: var(--paper);
  border: calc(2 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(var(--paper), var(--paper)),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  z-index: 0;
}

/* ---------- Текущий объём ---------- */
/* Крупная цифра с точками по бокам (Frame 1171276947, 11;117) */
.volume__value {
  position: absolute;
  left: calc(11 * var(--u));
  top: calc(46 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(4 * var(--u));
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(18 * var(--u));
  line-height: 1;
  /* Точки по бокам берут currentColor — чернеют вместе с числом */
  color: var(--ink);
}

/* Объём можно не только тянуть ползунком, но и вписать руками.
   Поле должно выглядеть ровно как прежний текст: свой шрифт у input
   не наследуется, поэтому повторяем его явно. Ширина — по содержимому
   (через size в разметке ширина скачет), поэтому фиксируем под «10 000 гб». */
.volume__amount {
  width: calc(96 * var(--u));
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: center;
  -webkit-appearance: none;
  appearance: none;
  cursor: text;
}

.volume__amount:focus {
  outline: none;
  /* Подсказываем, что поле редактируется, не сдвигая соседей. */
  box-shadow: 0 calc(2 * var(--u)) 0 calc(-1 * var(--u)) rgba(132, 35, 198, .5);
}

.volume__dot {
  width: calc(7 * var(--u));
  height: calc(7 * var(--u));
  border-radius: 50%;
  background: currentColor;
}

/* ---------- Шкала ---------- */
/* Дорожка 258x26 в точке 144;109, заливка растёт слева */
.volume__track {
  position: absolute;
  left: calc(144 * var(--u));
  top: calc(38 * var(--u));
  width: calc(258 * var(--u));
  height: calc(26 * var(--u));
  border-radius: calc(4 * var(--u));
  /* Пустая часть шкалы — ровная светлая заливка. */
  background: rgba(132, 35, 198, .07);
}

/* Пройденная часть шкалы */
.volume__fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  border-radius: inherit;
  /* Вертикальные штрихи, как в макете: частая «гребёнка» цвета тарифа. */
  background-image:
    repeating-linear-gradient(90deg,
      #8423C6 0 calc(1.5 * var(--u)),
      rgba(132, 35, 198, .25) calc(1.5 * var(--u)) calc(3 * var(--u)));
  pointer-events: none;
}

/* Бегунок: тонкая палочка с треугольной «шапкой» (Group 628206, 7x40) */
.volume__handle {
  position: absolute;
  top: calc(-8 * var(--u));
  width: calc(7 * var(--u));
  height: calc(34 * var(--u));
  margin-left: calc(-3.5 * var(--u));
  pointer-events: none;
}

.volume__handle::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: calc(7 * var(--u));
  height: calc(4 * var(--u));
  background: #8423C6;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

.volume__handle::after {
  content: "";
  position: absolute;
  left: calc(2.5 * var(--u));
  top: calc(8 * var(--u));
  width: calc(2 * var(--u));
  height: calc(26 * var(--u));
  background: #8423C6;
}

/* Само поле ввода прозрачное — рисуем заливку и бегунок сами */
.volume__input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background: none;
}

.volume__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: calc(28 * var(--u));
  height: calc(40 * var(--u));
}

.volume__input::-moz-range-thumb {
  width: calc(28 * var(--u));
  height: calc(40 * var(--u));
  border: 0;
}

/* ---------- Границы шкалы ---------- */
/* Точки по краям (Ellipse 1591/1592) и подписи под ними */
.volume__edge {
  position: absolute;
  top: calc(70 * var(--u));
  width: calc(7 * var(--u));
  height: calc(7 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, .3);
}

.volume__edge--min {
  left: calc(149 * var(--u));
}

.volume__edge--max {
  left: calc(391 * var(--u));
}

.volume__limit {
  position: absolute;
  top: calc(69 * var(--u));
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(12 * var(--u));
  line-height: .9;
  letter-spacing: -.06em;
  color: rgba(0, 0, 0, .3);
}

.volume__limit--min {
  left: calc(159 * var(--u));
}

.volume__limit--max {
  left: calc(339 * var(--u));
}

/* ---------- Быстрый выбор ---------- */
/* Две кнопки 190x42 в ряд (Frame 1171276946, 13;161) */
.volume__quick {
  position: absolute;
  left: calc(13 * var(--u));
  top: calc(90 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

.volume__chip {
  width: calc(190 * var(--u));
  height: calc(42 * var(--u));
  padding: 0 calc(13 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(17 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* Та же защита от зума двойным тапом, что у счётчика устройств. */
  touch-action: manipulation;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(180deg, #F2F2F2 0%, #E4E4E4 100%),
    linear-gradient(180deg, rgba(0, 0, 0, .08) 0%, rgba(0, 0, 0, .18) 100%);
  box-shadow: 0 calc(5 * var(--u)) calc(8 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .17);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  transition: transform .18s ease;
}

.volume__chip:active {
  transform: scale(.96);
}

/* ---------- Выбранная карточка «Свой объем» ---------- */
/* В макете она фиолетовая, а не чёрная, и лежит поверх панели */
.plan-card[data-pack="custom"].is-active {
  background-image:
    linear-gradient(#8523C6, #8523C6),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(79, 11, 126, .45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(196, 137, 246, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

.plan-card[data-pack="custom"].is-active .plan-card__price {
  background-image:
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .01) 91%, rgba(255, 255, 255, 1) 100%),
    linear-gradient(#9B3FDA, #9B3FDA);
}

/* Экран вырастает, когда шкала раскрыта.

   Правка 12.10.2026 (Мария): «кнопку оплаты при выборе своего объёма
   поднять выше, она уезжает вниз». Кнопка сдвигалась с 696 на 786 —
   на 90px, хотя сама шкала занимает 372..517 и до кнопки не достаёт:
   между ними и так оставалось 179px пустоты. Оставляем небольшой
   сдвиг (40px), чтобы блок не прилипал к кнопке, и на столько же
   укорачиваем экран — иначе внизу остаётся пустая прокрутка. */
.screen--traffic.has-volume {
  height: calc(850 * var(--u));
}

/* Сдвиг действует, только пока кнопка стоит в потоке экрана.

   На невысоком окне (max-height: 760px выше по файлу) она прижимается
   к низу через position: fixed + bottom, и top там должен оставаться
   auto. Это правило лежит ПОЗЖЕ медиазапроса и весит столько же (два
   класса против одного), поэтому без ограничения оно возвращало
   top: 736 — а при fixed это отсчёт от верха ОКНА. На 600px кнопка
   уезжала за нижний край, и достать её было нельзя: у .screen
   overflow: hidden, прокрутки нет (правка 17.10.2026, Александр:
   «нет кнопки К оплате, даже если прокручиваешь вниз»). */
@media (min-height: 761px) {
  .screen--traffic.has-volume .checkout {
    top: calc(736 * var(--u));
  }
}

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

/* ==================================================================
   Успешная оплата (макет 920:16421)
   Открывается после «Оплатить»: карточка 400x289 в точке 20;496,
   звезда со «птичкой» наезжает на неё сверху.
   ================================================================== */

/* Затемнение — тот же Rectangle 30188, что и у окна заказа */
.paid-scrim {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 20;
  transition: opacity .22s ease, visibility .22s ease;
}

.paid-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Белая карточка (Rectangle 30175). Начало координат вложенных
   элементов — её левый верхний угол, поэтому звезда уходит в минус. */
.paid {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(496 * var(--u));
  width: calc(400 * var(--u));
  height: calc(289 * var(--u));
  border-radius: calc(60 * var(--u));
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.paid-scrim.is-open .paid {
  transform: none;
}

/* Белое поле карточки отдельным слоем: кнопка «На главную» светится
   розовым по краю, и обрезка держит свечение внутри скругления,
   а звезда со стикерами остаётся снаружи. */
.paid::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--paper);
}

/* ---------- Звезда с галочкой (Star 16 + Vector, 170x170 в 130;382) ---------- */
.paid__star {
  position: absolute;
  left: calc(110 * var(--u));
  top: calc(-114 * var(--u));
  width: calc(170 * var(--u));
  height: calc(170 * var(--u));
  background: url("/app/assets/icons/success-star.svg") no-repeat center / contain;
  filter: drop-shadow(0 calc(10 * var(--u)) calc(22 * var(--u)) rgba(213, 6, 72, .35));
}

/* «Птичка» (Vector, 59x53 в 186;438) — по центру звезды */
.paid__star::after {
  content: "";
  position: absolute;
  left: calc(58 * var(--u));
  top: calc(60 * var(--u));
  width: calc(54 * var(--u));
  height: calc(39 * var(--u));
  background: url("/app/assets/icons/success-check.svg") no-repeat center / contain;
}

/* ---------- Подписи-стикеры по бокам звезды ---------- */
/* Чёрный текст в белой обводке; в макете повёрнут к центру */
.paid__sticker {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.05;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--ink);
  -webkit-text-stroke: calc(5 * var(--u)) var(--paper);
  paint-order: stroke fill;
  text-shadow: 0 calc(4 * var(--u)) calc(14 * var(--u)) rgba(0, 0, 0, .14);
  white-space: nowrap;
}

/* «Спасибо!» слева (37;484 в кадре) */
.paid__sticker--thanks {
  left: calc(-7 * var(--u));
  top: calc(-12 * var(--u));
  width: calc(91 * var(--u));
  transform: rotate(-18deg);
}

/* «Успешная оплата» справа (302;477 в кадре) */
.paid__sticker--done {
  left: calc(282 * var(--u));
  top: calc(-19 * var(--u));
  width: calc(103 * var(--u));
  transform: rotate(16deg);
}

/* ---------- Сумма и подпись ---------- */

/* Крупная сумма (92;553 в кадре, шрифт 28) */
.paid__sum {
  position: absolute;
  left: calc(72 * var(--u));
  top: calc(57 * var(--u));
  width: calc(256 * var(--u));
  height: calc(42 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(60 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  text-align: center;
  color: #000;
}

/* «Можно запускать, тариф активен!» (94;614 в кадре, шрифт 23) */
.paid__note {
  position: absolute;
  left: calc(74 * var(--u));
  top: calc(118 * var(--u));
  width: calc(253 * var(--u));
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(23 * var(--u));
  line-height: 1.05;
  letter-spacing: -.02em;
  text-align: center;
  color: rgba(0, 0, 0, .4);
}

/* ---------- Кнопка «На главную» (362x85 в 39;680) ---------- */
/* Та же чёрная пилюля со светлой каймой, что и «Оплатить» */
.paid__home {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(184 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: calc(2 * var(--u)) solid transparent;
  border-radius: calc(46.26 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  /* Внешней тени нет: кнопка лежит внутри карточки и её край
     иначе пачкает нижние скругления. */
  box-shadow:
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(255, 64, 157, .6),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  color: var(--paper);
  transition: transform .18s ease;
}

.paid__home:active {
  transform: scale(.99);
}

@media (prefers-reduced-motion: reduce) {

  .order-scrim,
  .order,
  .order__topup,
  .order__pay,
  .paid-scrim,
  .paid,
  .paid__home {
    transition: none;
  }
}

/* ==================================================================
   Экран «Докупить трафик» (макет 962:9284, сетка 440×956)
   Каркас общий с экраном тарифов: те же .plan-card, .checkout,
   .tariffs__back. Здесь только отличия — розовая выбранная карточка,
   три пакета вместо четырёх и отсутствие блока периода.
   ================================================================== */

.screen--traffic {
  /* 782 = низ кнопки «К оплате» + отступ. */
  height: calc(810 * var(--u));
}

/* Заголовок: в этом макете значок стоит ПОСЛЕ текста (текст с x=64). */
.tariffs__title--traffic {
  left: calc(64 * var(--u));
}

/* Пакеты идут в три ряда: 113, 211, 309 */
.screen--traffic .plan-card:nth-of-type(1) {
  top: calc(113 * var(--u));
}

.screen--traffic .plan-card:nth-of-type(2) {
  top: calc(211 * var(--u));
}

.screen--traffic .plan-card:nth-of-type(3) {
  top: calc(309 * var(--u));
}

/* Названия пакетов набраны цифровым начертанием (Asgard Number) */
.plan-card__name--num {
  font-family: var(--font-display);
}

/* ---------- Цвет выбранного пакета ----------
   В макете «+150 гб» чёрный (как базовая карточка), «+300 гб» розовый,
   «Свой объем» фиолетовый — цвета заданы ниже по data-pack. */
.plan-card[data-pack="300"].is-active {
  background-image:
    linear-gradient(#F5197B, #F5197B),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(143, 12, 70, .5),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(246, 188, 137, .6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
}

/* На розовой карточке подписи белые, без перламутрового градиента */
.screen--traffic .plan-card.is-active .plan-card__name {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--paper);
}

.screen--traffic .plan-card.is-active .plan-card__devices {
  color: rgba(255, 255, 255, .6);
}

/* Плашка с ценой на розовой карточке — светлая, цифры белые */
/* Плашка почти прозрачная: сквозь неё виден розовый корпус карточки,
   форму держат только внутренние белые блики (значения из макета). */
.screen--traffic .plan-card.is-active .plan-card__price {
  color: var(--paper);
  background-image:
    radial-gradient(51.78% 51.78% at 50% 50.03%,
      rgba(255, 255, 255, 0) 91.47%, rgba(255, 255, 255, .01) 100%);
  box-shadow:
    inset calc(3 * var(--u)) calc(3 * var(--u)) calc(17 * var(--u)) calc(-3 * var(--u)) rgba(255, 255, 255, .8),
    inset calc(1 * var(--u)) calc(1 * var(--u)) calc(20 * var(--u)) calc(-3 * var(--u)) #fff,
    inset calc(1 * var(--u)) calc(1 * var(--u)) calc(20 * var(--u)) calc(-3 * var(--u)) #fff;
}

/* Цена в этом макете без «/ нед» — плашка уже (87–91 вместо 144) */
.screen--traffic .plan-card__price {
  left: calc(293 * var(--u));
  width: calc(91 * var(--u));
}

.screen--traffic .plan-card .plan-card__price {
  left: calc(297 * var(--u));
  width: calc(87 * var(--u));
  height: calc(54 * var(--u));
  border-radius: calc(14 * var(--u));
  /* В макете padding 32x15 — это отступы автолэйаута Figma, они задают
     размер кадра, а не поля внутри готовой плашки 87x54: как CSS-padding
     они съедают всю ширину и «537 ₽» переносится на две строки. */
  padding: 0 calc(8 * var(--u));
  white-space: nowrap;
}

/* ---------- Плашка «Выгоднее» ----------
   Готовая картинка с напечатанной надписью (как «Хит»), но крупнее
   и с другим наклоном: 119.15×74.95 при 1.14;179.17 на кадре. */
.pill--better {
  /* Пропорции берём у самой картинки (351x145 = 2.42), иначе при contain
     скотч ужимается по ширине и болтается в пустой коробке. */
  left: calc(-14 * var(--u));
  top: calc(-24 * var(--u));
  width: calc(119 * var(--u));
  height: calc(49 * var(--u));
  background: url("/app/assets/icons/tape-better.png") no-repeat center / contain;
  font-size: 0;
  color: transparent;
  z-index: 2;
}

.pill--better::before {
  content: none;
}

/* ==================================================================
   Экран «Подарить VPN» (макет 920:19222, сетка 440x956)
   ================================================================== */

.screen--friends {
  background: var(--bg);
}

/* ---------- Шапка: звезда, счётчик, формула ---------- */
/* Белое свечение снизу (Rectangle 30156, 440x274 в 0;0). */
/* Шапка растянута на весь экран: координаты вложенных блоков заданы
   от кадра 440x956. Обрезка не нужна — списка под шапкой больше нет. */
.friends__hero {
  position: absolute;
  inset: 0;
  margin: 0;
}

.friends__hero::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(274 * var(--u));
  background: radial-gradient(circle at 50% 137%,
      rgba(255, 255, 255, 0) 59%, rgba(255, 255, 255, 1) 100%);
}

/* Звезда шапки — готовая картинка из макета.
   В ней уже есть и заливка, и стеклянные блики, и обводка, и розовое
   свечение вокруг, поэтому маска, градиенты, кольцо и отдельное
   пятно-блик больше не нужны.
   Холст — во всю ширину сцены (440×477), бокс звезды в макете —
   477×477 в -19;35, то есть картинка ложится в 0;35. */
.friends__star {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}

/* Звезда в макете белая (узел 1007:11848), а start.png выгружен с розового
   варианта того же слоя. Картинку оставляем ради формы — берём её как
   маску, а красим по макету: белый радиальный градиент на #E4E4E4.

   Розовое свечение вокруг силуэта в маске тоже есть, поэтому наружу
   оно уходит тем же градиентом, что и тело, — без розового. */
.friends__star--outer {
  left: 0;
  top: calc(35 * var(--u));
  width: calc(440 * var(--u));
  height: calc(477 * var(--u));
  background:
    radial-gradient(circle at 50% 45%,
      rgba(255, 255, 255, .01) 21%, #fff 76%),
    #E4E4E4;
  -webkit-mask: url("/app/assets/icons/start.png") no-repeat center top / 100% auto;
  mask: url("/app/assets/icons/start.png") no-repeat center top / 100% auto;
  filter: drop-shadow(0 calc(14 * var(--u)) calc(22 * var(--u)) rgba(77, 77, 77, .15));
}

/* Кнопки по краям шапки (59x59 в 20;85 и 361;85). */
.friends__icon {
  position: absolute;
  z-index: 4;
  top: calc(85 * var(--u));
  width: calc(59 * var(--u));
  height: calc(59 * var(--u));
  padding: 0;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(20 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Серые стопы радиального градиента из макета сильно затемняли кнопку
     на светлом фоне — ослабляем их и поднимаем белую подложку. */
  background-image:
    radial-gradient(circle at 50% 4%,
      rgba(128, 128, 128, .01) 22%, rgba(158, 158, 158, .15) 42%, rgba(158, 158, 158, .3) 56%),
    linear-gradient(180deg, rgba(0, 0, 0, .05) 0%, rgba(0, 0, 0, .18) 100%);
  background-color: rgba(255, 255, 255, .72);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .25);
  transition: transform .18s ease;
}

.friends__icon:active {
  transform: scale(.96);
}

.friends__icon--back {
  left: calc(20 * var(--u));
}

.friends__icon--share {
  left: calc(361 * var(--u));
}

.friends__icon::before {
  content: "";
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: calc(22 * var(--u));
}

.friends__icon--back::before {
  background-image: url("/app/assets/icons/friends-back.svg");
  background-size: calc(29 * var(--u)) calc(19 * var(--u));
}

.friends__icon--share::before {
  background-image: url("/app/assets/icons/friends-share.svg");
  background-size: calc(21 * var(--u)) calc(21 * var(--u));
}

/* Подпись «Приглашено» с галочкой (Frame 628143 в 158.5;173). */
.friends__invited {
  position: absolute;
  z-index: 5;
  left: 50%;
  top: calc(173 * var(--u));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(7 * var(--u));
  transform: translateX(-50%);
}

.friends__invited-icon {
  width: calc(37 * var(--u));
  height: calc(16 * var(--u));
  background: url("/app/assets/icons/invite-mark.svg") no-repeat center / contain;
}

.friends__invited-label {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(16 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* Число приглашённых (208x56 в 116;234, Asgard Number 80). */
.friends__count {
  position: absolute;
  z-index: 5;
  left: calc(116 * var(--u));
  top: calc(234 * var(--u));
  width: calc(208 * var(--u));
  height: calc(56 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-number);
  font-weight: 800;
  font-size: calc(80 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

/* Кнопка «Подарить VPN» — готовая картинка из макета.
   В ней уже есть и значок, и надпись по дуге, и розовое свечение, поэтому
   собирать капсулу из градиентов и curved-text больше не нужно.
   Холст картинки — во всю ширину сцены (440×321), сама капсула
   занимает в нём 82..355 по x и 217..309 по y. */
.friends__arc {
  position: absolute;
  z-index: 2;
  left: 0;
  /* Верх капсулы в макете — около 473, а внутри картинки он на 217. */
  top: calc(270 * var(--u));
  /* 473 − 217 */
  width: calc(440 * var(--u));
  height: calc(321 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/gift.png") no-repeat center top / 100% auto;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* Кликабельна только сама капсула — прозрачный холст пропускает
     нажатия к тому, что лежит ниже. */
  clip-path: inset(calc(217 * var(--u)) calc(84 * var(--u)) calc(11 * var(--u)) calc(82 * var(--u)));
  transition: transform .18s ease;
}

.friends__arc:active {
  transform: scale(.97);
}

/* Формула «39 оформили = 39 мес в подарок» (131;327 и 246;327). */
/* В макете три блока стоят на своих координатах (131;329, 207;325,
   246;329), а не в ряд с зазором: при flex положение правых
   зависело бы от ширины числа слева. */
.friends__formula {
  display: contents;
}

.friends__stat {
  position: absolute;
  z-index: 4;
  top: calc(329 * var(--u));
}

.friends__stat--left {
  left: calc(131 * var(--u));
}

.friends__stat--right {
  left: calc(246 * var(--u));
}

.friends__stat {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(5 * var(--u));
  white-space: nowrap;
}

.friends__stat-value {
  display: flex;
  align-items: flex-end;
  gap: calc(2 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

.friends__stat-value b {
  font-weight: 400;
}

/* «мес» набрано мельче числа. */
.friends__stat-value i {
  font-style: normal;
  font-size: calc(14 * var(--u));
}

/* Значок «люди» после числа оформивших (Subtract, 15x9). */
.friends__stat--left .friends__stat-value::after {
  content: "";
  width: calc(15 * var(--u));
  height: calc(9 * var(--u));
  margin-bottom: calc(2 * var(--u));
  background: url("/app/assets/icons/friends-signed.svg") no-repeat center / contain;
}

.friends__stat-note {
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(12 * var(--u));
  line-height: 1;
  letter-spacing: -.0333em;
  color: rgba(0, 0, 0, .4);
}

/* Прогресс до следующей порции бонусных дней (ТЗ п. 6.1).
   Шрифт и цвет — как у подписей формулы выше, чтобы строка читалась
   её продолжением, а не отдельным сообщением. */
.friends__progress {
  position: absolute;
  z-index: 4;
  left: 0;
  top: calc(378 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(13 * var(--u));
  line-height: 1.35;
  letter-spacing: -.0333em;
  text-align: center;
  /* .6, а не .55: фон экрана #E4E4E4, и на нём .55 даёт 4.45:1 —
     чуть ниже порога читаемости 4.5:1. */
  color: rgba(0, 0, 0, .6);
}

/* Знак равенства между парами (25x28 в 207;323). */
.friends__equals {
  position: absolute;
  z-index: 4;
  left: calc(207 * var(--u));
  top: calc(325 * var(--u));
  width: calc(25 * var(--u));
  height: calc(28 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: calc(40 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: rgba(0, 0, 0, .3);
}

/* Стикер «новый друг» */
.friends__new {
  position: absolute;
  z-index: 4;
  left: calc(24 * var(--u));
  top: calc(545 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

.friends__new-avatar {
  width: calc(28 * var(--u));
  height: calc(28 * var(--u));
  border-radius: 50%;
  background: linear-gradient(180deg, #D7D7D7 0%, #9E9E9E 100%);
}

.friends__new-name {
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

.friends__new-note {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(12 * var(--u));
  line-height: 1;
  letter-spacing: -.0333em;
  color: rgba(0, 0, 0, .4);
}

/* Значок «VPN за друзей» (Group 628300, 133.1x30.76 в 153;457). */
.friends__vpn {
  position: absolute;
  z-index: 3;
  left: calc(153 * var(--u));
  top: calc(457 * var(--u));
  width: calc(133.1 * var(--u));
  height: calc(40 * var(--u));
  background: url("/app/assets/icons/friends-vpn-badges.png") no-repeat center / contain;
  filter: drop-shadow(0 calc(4 * var(--u)) calc(6 * var(--u)) rgba(196, 8, 92, .2));
}

/* Аватарки приглашённых (Group 628286, 341x150.7 в 50;582). */
.friends__faces {
  position: absolute;
  z-index: 2;
  left: calc(50 * var(--u));
  top: calc(582 * var(--u));
  width: calc(341 * var(--u));
  height: calc(150.7 * var(--u));
}

/* Кружок друга. Раньше весь ряд был одной картинкой-заглушкой с восемью
   лицами; теперь это настоящие аватарки, поэтому каждая — свой элемент.
   Позиции и размеры сняты с макета: кружки лежат в шахматном порядке,
   крупные вперемешку с мелкими. */
.friends__face {
  position: absolute;
  border-radius: 50%;
  background: #D9D9D9 no-repeat center / cover;
  box-shadow:
    0 calc(6 * var(--u)) calc(12 * var(--u)) calc(-4 * var(--u)) rgba(0,0,0,.35),
    inset 0 0 0 calc(1.5 * var(--u)) rgba(255,255,255,.5);
}

/* Слоты по макету: left/top/размер для каждой из восьми позиций.
   Порядок — как читается ряд слева направо, чтобы при одном друге
   кружок встал слева, а не в случайном месте. */
.friends__face:nth-child(1) { left: calc(48 * var(--u));  top: calc(12 * var(--u)); width: calc(78 * var(--u));  height: calc(78 * var(--u)); }
.friends__face:nth-child(2) { left: calc(112 * var(--u)); top: calc(62 * var(--u)); width: calc(92 * var(--u));  height: calc(92 * var(--u)); }
.friends__face:nth-child(3) { left: calc(160 * var(--u)); top: calc(0 * var(--u));  width: calc(62 * var(--u));  height: calc(62 * var(--u)); }
.friends__face:nth-child(4) { left: calc(222 * var(--u)); top: calc(22 * var(--u)); width: calc(74 * var(--u));  height: calc(74 * var(--u)); }
.friends__face:nth-child(5) { left: calc(288 * var(--u)); top: calc(0 * var(--u));  width: calc(58 * var(--u));  height: calc(58 * var(--u)); }
.friends__face:nth-child(6) { left: calc(286 * var(--u)); top: calc(52 * var(--u)); width: calc(88 * var(--u));  height: calc(88 * var(--u)); }
.friends__face:nth-child(7) { left: calc(18 * var(--u));  top: calc(74 * var(--u)); width: calc(58 * var(--u));  height: calc(58 * var(--u)); }
.friends__face:nth-child(8) { left: calc(212 * var(--u)); top: calc(96 * var(--u)); width: calc(50 * var(--u));  height: calc(50 * var(--u)); }

/* «+N» справа от ряда (Group 628084, 33x27 в 387;604). */
/* ---------- Активная вкладка нижней навигации (макет 1008:13407) ----------
   Панель целиком нарисована в tabbar.png, и подписи там серые. У активной
   вкладки подпись чёрная, а под значком розовое свечение, поэтому оба слоя
   дорисовываем поверх картинки.

   Подпись: 30x6 в 5;46 внутри кнопки 59x75, набрана 9px. Своя подпись
   встаёт поверх серой из картинки, поэтому под ней подложка. Панель в
   этом месте не одного цвета, а уходит от #E8E8E8 к #EDEDED — подложку
   красим тем же градиентом, иначе виден шов. */
.tabbar__item.is-active .tabbar__label {
  position: absolute;
  left: 0;
  top: calc(53 * var(--u));
  width: 100%;
  height: calc(12 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  clip-path: none;
  background: linear-gradient(180deg, #E8E8E8 0%, #EDEDED 100%);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(9 * var(--u));
  line-height: .9;
  letter-spacing: -.0333em;
  text-align: center;
  color: var(--ink);
}

/* Значок активной вкладки (макет 1008:13410) — розовый стеклянный шар
   с чёрной иконкой внутри и белым бликом снизу. Собран из десятка слоёв
   с размытиями, поэтому взят картинкой из макета, а не повторён в CSS.

   Шар в макете 39.44x40 в 9;10 от угла кнопки, но свечение выходит за
   его края, и в экспорте холст шире (190x192 при 4x). Кладём картинку
   этим холстом, отцентрировав по месту шара. */
.tabbar__item.is-active::before {
  content: "";
  position: absolute;
  left: calc(5 * var(--u));
  top: calc(6 * var(--u));
  width: calc(47.5 * var(--u));
  height: calc(48 * var(--u));
  background: url("/app/assets/icons/tab-friends-active.png") no-repeat center / contain;
  pointer-events: none;
}

/* Аватарка пользователя поверх значка вкладки. Фон ставит JS: своей
   картинки у нас нет, берём телеграмовскую из initData. Пока её нет,
   виден нарисованный в tabbar.png силуэт. */
.tabbar__avatar {
  position: absolute;
  left: calc(5 * var(--u));
  top: calc(6 * var(--u));
  width: calc(47.5 * var(--u));
  height: calc(48 * var(--u));
  border-radius: 50%;
  background: no-repeat center / cover;
  pointer-events: none;
}

/* У «Профиля» кружок остаётся серым — розовеет только подпись. */
.tabbar__item--profile.is-active::before { content: none; }

/* ---------- Поиск ---------- */
/* Поле 352x85 в 44;160 кадра — внутри панели это 24;21 */
/* Затемнение (Rectangle 30188) */
.whom-scrim {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 30;
  transition: opacity .22s ease, visibility .22s ease;
}

.whom-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Панель (Rectangle 30175, 400x751 в 20;139) */
.whom {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(139 * var(--u));
  width: calc(400 * var(--u));
  height: calc(751 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.whom-scrim.is-open .whom {
  transform: none;
}

/* Полоска-«ручка» (Rectangle 30189/30190, 50x6) */
/* Сама «ручка» уже есть на картинке заголовка, поэтому
   здесь остаётся только прозрачная зона нажатия. */
.whom__grip {
  position: absolute;
  z-index: 3;
  left: calc(175 * var(--u));
  top: calc(-16 * var(--u));
  width: calc(50 * var(--u));
  height: calc(14 * var(--u));
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Заголовок «Кому дарим» (111;122 кадра — над панелью) */
/* Шапка окна — готовая картинка 231x53: в ней уже есть
   и «ручка», и надпись, и значок подарка. Текст в разметке
   остаётся для скринридеров. */
.whom__title {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(-18 * var(--u));
  width: calc(231 * var(--u));
  height: calc(53 * var(--u));
  margin: 0;
  transform: translateX(-50%);
  background: url("/app/assets/icons/who_gift.png") no-repeat center / contain;
  font-size: 0;
  color: transparent;
}

.whom__search {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(21 * var(--u));
  width: calc(352 * var(--u));
  height: calc(85 * var(--u));
  padding: 0 calc(20 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(36 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    radial-gradient(120% 160% at 50% -20%,
      rgba(255, 255, 255, .98) 32%, rgba(240, 240, 240, .9) 64%, rgba(214, 214, 214, .85) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .22);
}

/* Лупа (Union, 21x21) — рисуем кольцом и ручкой, чтобы не тащить
   SVG с backdrop-filter, который браузеры в фоне не рисуют. */

.whom__search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  padding: 0;
  background: none;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  /* Длинная ссылка не разрывает поле — уходит в многоточие */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: rgba(0, 0, 0, .3);
}

.whom__search-input::placeholder {
  color: rgba(0, 0, 0, .3);
}

.whom__search-input:focus {
  outline: none;
}

/* ---------- Список получателей ---------- */
/* Строки 352x66 с шагом 76 — первая в 44;267 кадра */
.whom__list {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(128 * var(--u));
  width: calc(352 * var(--u));
  /* Ниже панели список не уходит: прокручиваем внутри */
  max-height: calc(600 * var(--u));
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Прокрутка остаётся, полосу прячем: в макете её нет. */
  scrollbar-width: none;
  /* Firefox */
  -ms-overflow-style: none;
  /* старый Edge */
}

/* WebKit/Blink — Safari, Chrome, телеграмовский вебвью. */
.whom__list::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Подсказка на месте списка: контактов у Telegram не спросить,
   поэтому получателя вводят вручную. Встаёт туда же, где был бы
   список, иначе всплывает потоком поверх поля поиска. */
.whom__empty {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(128 * var(--u));
  width: calc(352 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.3;
  letter-spacing: -.03em;
  color: rgba(0, 0, 0, .3);
}

.whom__row {
  position: relative;
  height: calc(70 * var(--u));
  margin-bottom: calc(10 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

/* Аватар 65x66 */
.whom__avatar {
  flex: 0 0 auto;
  width: calc(75 * var(--u));
  height: calc(76 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, .12);
}

.whom__person {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(5 * var(--u));
}

.whom__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

.whom__nick {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .3);
}

/* Переключатель-пилюля 33x27 справа (Group 628084) */
.whom__pick {
  position: relative;
  flex: 0 0 auto;
  width: calc(33 * var(--u));
  height: calc(27 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/whom-arrow.svg") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease, filter .18s ease;
}

.whom__pick:active {
  transform: scale(.94);
}

/* Выбранный получатель: пилюля подсвечивается розовым цветом экрана. */
.whom__pick[aria-checked="true"] {
  filter: brightness(.97) drop-shadow(0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(255, 36, 134, .45));
}

@media (prefers-reduced-motion: reduce) {

  .whom-scrim,
  .whom,
  .whom__pick {
    transition: none;
  }
}

/* ==================================================================
   Окно с QR-кодом (макеты 920:19976 и 920:20390)
   Второй макет — то же окно после нажатия: кнопка становится розовой
   с подписью «Скопировано».
   ================================================================== */

/* Затемнение на весь экран; окно внутри — по центру. Остальные попапы
   выезжают снизу, а этот показывают целиком: у него своя форма с выемкой
   под аватар, и от края она читается хуже. */
.qr-scrim {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  transition: opacity .22s ease, visibility .22s ease;
}

.qr-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Обёртка размером с окно: её центрирует flex, а аватар и имя, лежащие
   снаружи плашки, позиционируются от неё — иначе при центрировании они
   отрывались от окна и уезжали выше экрана. */
.qr-box {
  position: relative;
  flex: 0 0 auto;
  width: calc(398 * var(--u));
  height: calc(517 * var(--u));
}

.qr {
  /* absolute от .qr-box: дети внутри по-прежнему считаются от этого угла. */
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  /* Форма из макета (Subtract 920:20354): скруглённая плашка
     с выемкой под аватар справа сверху — обычным border-radius
     её не повторить, поэтому режем маской по SVG. */
  background: #FF2486;
  -webkit-mask: url("/app/assets/icons/qr-panel.svg") no-repeat center / 100% 100%;
  mask: url("/app/assets/icons/qr-panel.svg") no-repeat center / 100% 100%;
  isolation: isolate;
  transform: translateY(calc(16 * var(--u)));
  transition: transform .22s ease;
}

/* Белый блик по верхней кромке. Отдельным слоем: inset-тени
   самого элемента маска срезала бы. */
.qr::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  box-shadow: inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7);
  pointer-events: none;
}

.qr-scrim.is-open .qr {
  transform: none;
}

/* «Ручка» сверху — закрывает окно */
.qr__grip {
  position: absolute;
  left: calc(174 * var(--u));
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  padding: 0;
  border: 0;
  border-radius: calc(3 * var(--u));
  background: rgba(0, 0, 0, .1);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0, 0, 0, .35);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Розовый QR. Картинка выгружена вместе со свечением и потому выше
   своего бокса (314×356 против 314×314). Сам бокс оставляем квадратным,
   а свечение выпускаем наружу через ::before — иначе оно съедает подпись. */
.qr__code {
  position: absolute;
  left: calc(42.12 * var(--u));
  /* 63.12 − 21 */
  top: calc(47 * var(--u));
  /* 315 − 268 */
  width: calc(314 * var(--u));
  height: calc(314 * var(--u));
  /* Свечение выходит за бокс вниз и накрывает подпись —
     уводим весь слой под остальной текст. */
  z-index: 0;
  pointer-events: none;
}

.qr__code::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(356 * var(--u));
  /* Пока настоящий QR не пришёл — пульсирующая плашка, а не код
     из макета: он выглядел как рабочий, но вёл в никуда. */
  border-radius: calc(40 * var(--u));
  background: rgba(0, 0, 0, .12);
  animation: skeleton-pulse 1.2s ease-in-out infinite;
}

/* Пришёл настоящий код (класс ставит JS): картинку макета убираем,
   а сам QR рисуем фоном. В SVG только чёрные модули, поэтому белую
   карточку со скруглением и свечением даём здесь. */
.qr__code.has-code::before { content: none; }

.qr__code.has-code {
  /* Поля внутри белой карточки: вплотную к краю код не сканируется. */
  padding: calc(22 * var(--u));
  background-repeat: no-repeat;
  background-position: center;
  background-size: calc(100% - 44 * var(--u)) calc(100% - 44 * var(--u));
  background-color: #fff;
  border-radius: calc(40 * var(--u));
  box-shadow: 0 0 calc(60 * var(--u)) calc(10 * var(--u)) rgba(255, 255, 255, .9);
}

.qr__hint {
  position: absolute;
  z-index: 1;
  left: calc(112 * var(--u));
  /* 133 − 21 */
  top: calc(384 * var(--u));
  /* 652 − 268 */
  width: calc(175 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(17.21 * var(--u));
  line-height: 1;
  letter-spacing: -.0444em;
  color: rgba(0, 0, 0, .4);
}

/* Подпись внутри розовой карточки QR — поверх свечения. */

/* Кнопка «Скопировать» — светлая, 362×86 */
.qr__copy {
  position: absolute;
  left: calc(18 * var(--u));
  /* 39 − 21 */
  top: calc(413 * var(--u));
  /* 681 − 268 */
  width: calc(362 * var(--u));
  height: calc(86 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(9 * var(--u));
  padding: 0 calc(20 * var(--u));
  border-radius: calc(36 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    radial-gradient(circle at 50% 4%,
      rgba(255, 255, 255, .95) 22%, rgba(236, 236, 236, .95) 60%, rgba(214, 214, 214, .95) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .35);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  color: rgba(0, 0, 0, .3);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.qr__copy:active {
  transform: scale(.98);
}

/* Иконку красим маской: в макете она того же цвета, что и надпись. */
.qr__copy-icon {
  flex: 0 0 auto;
  width: calc(33 * var(--u));
  height: calc(23 * var(--u));
  background: currentColor;
  -webkit-mask: url("/app/assets/icons/copy-icon.svg") no-repeat center / contain;
  mask: url("/app/assets/icons/copy-icon.svg") no-repeat center / contain;
}

/* Второй макет (920:20390): нажали — кнопка розовая,
   надпись «Скопировано» тёмная. */
.qr__copy.is-copied {
  background-image:
    radial-gradient(circle at 50% 6%,
      rgba(255, 232, 219, .8) 0%, rgba(255, 135, 188, 1) 24%,
      rgba(255, 49, 140, 1) 55%, rgba(202, 18, 101, .9) 77%),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  color: rgba(0, 0, 0, .9);
}

@media (prefers-reduced-motion: reduce) {

  .qr-scrim,
  .qr,
  .qr__copy {
    transition: none;
  }
}

/* ---------- Окно «Все ваши друзья» (макет 920:19599) ----------
   Затемнение rgba(0,0,0,.25) и белая панель 400x751 в 20;139. */
.all-scrim {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 10;
  transition: opacity .22s ease, visibility .22s ease;
}

.all-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

.all {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(139 * var(--u));
  width: calc(400 * var(--u));
  height: calc(751 * var(--u));
  display: flex;
  flex-direction: column;
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.all-scrim.is-open .all {
  transform: none;
}

/* «Ручка» вверху панели (50x6 в 195;111 от кадра). */
.all__grip {
  flex: 0 0 auto;
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  /* Заголовок ушёл наверх, поэтому отступ под «ручкой» держим здесь. */
  margin: calc(16 * var(--u)) auto calc(20 * var(--u));
  padding: 0;
  border: 0;
  border-radius: calc(10 * var(--u));
  background: rgba(0, 0, 0, .1);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Заголовок 26px по центру. */
/* Заголовок — готовая картинка из макета (282×39).
   Сверху у картинки была своя «ручка» — срезали, чтобы не двоилась с кнопкой.
   Текст остаётся в разметке для скринридеров и aria-labelledby,
   но визуально его заменяет изображение. */
/* Заголовок вынесен НАД плашкой: лежит на её верхней кромке,
   поэтому из потока флекса убираем и позиционируем абсолютно. */
.all__title {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(-30 * var(--u));
  width: calc(282 * var(--u));
  height: calc(45 * var(--u));
  margin: 0;
  transform: translateX(-50%);
  background: url("/app/assets/icons/all_friends.png") no-repeat center / contain;
  /* Прячем сам текст, не убирая его из дерева доступности. */
  font-size: 0;
  color: transparent;
}

/* Список прокручивается внутри панели. */
/* Сетка 3 в ряд: аватар, под ним имя и статус (макет 291) */
.all__list {
  flex: 1 1 auto;
  margin: 0;
  /* Сверху — место под вынесенный заголовок. */
  padding: calc(34 * var(--u)) calc(24 * var(--u)) calc(24 * var(--u));
  list-style: none;
  display: grid;
  /* minmax(0, 1fr), а не просто 1fr: иначе колонка не может стать уже
     своего содержимого, длинное имя с nowrap распирает её, и третья
     карточка уезжает за край панели. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: min-content;
  align-content: start;
  /* По вертикали ряды стоят плотно, по горизонтали колонки не слипаются */
  gap: calc(22 * var(--u)) calc(12 * var(--u));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---------- Аватар без фото ----------
   Telegram отдаёт photo_url не всегда: фото может не быть вовсе или его
   закрывает приватность. Тогда вместо чужого лица из макета показываем
   первую букву имени. Букву кладём в data-letter, чтобы одно правило
   работало для всех аватарок разом. */
.avatar--letter {
  /* !important и у цвета: у аватарок фон задан шорткатом background,
     который иначе перетёр бы подложку и кружок остался бы прозрачным. */
  background-image: none !important;
  background-color: #C9C9C9 !important;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.avatar--letter::after {
  content: attr(data-letter);
  font-family: var(--font-display);
  font-weight: 500;
  /* Размер буквы задаётся на самом кружке — у каждой аватарки свой. */
  font-size: inherit;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  color: #fff;
}

/* Кегль под каждый размер кружка: примерно половина диаметра. */
.whom__avatar.avatar--letter { font-size: calc(28 * var(--u)); }
.all__avatar.avatar--letter { font-size: calc(26 * var(--u)); }
.friends__face.avatar--letter { font-size: calc(26 * var(--u)); }
.profile__avatar.avatar--letter { font-size: calc(60 * var(--u)); }
.ask__avatar.avatar--letter { font-size: calc(26 * var(--u)); }
.tabbar__avatar.avatar--letter { font-size: calc(18 * var(--u)); }

/* Ячейка: аватар, имя, статус — всё по центру колонки */
.all__cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(3 * var(--u));
  text-align: center;
}

.all__cell:active .all__avatar { transform: scale(.95); }

.all__avatar {
  /* 84, а не 100: в колонке ~109 единиц крупный кружок не оставлял
     места имени, и оно обрезалось на «Тест-др…». */
  width: calc(84 * var(--u));
  height: calc(84 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, .12);
}

/* Розовая звезда с галочкой на тех, кто оформил подписку.
   Висит на правом нижнем краю аватара. Координаты считаем от его
   размера (84), а не абсолютом: при прежнем top:72 значок съезжал
   на имя, когда аватар уменьшили. */
.all__check {
  position: absolute;
  left: 50%;
  top: calc(60 * var(--u));
  width: calc(28 * var(--u));
  height: calc(29 * var(--u));
  transform: translateX(calc(14 * var(--u)));
  background: url("/app/assets/icons/friends-check-star.svg") no-repeat center / contain;
}

/* Имя и статус — один блок: так пара держится вместе
   и её можно двигать целиком относительно аватара. */
.all__info {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  /* Небольшой отступ от аватара: при отрицательном margin имя
     подлезало под розовую галочку «купил подписку». */
  margin-top: calc(4 * var(--u));
}

.all__name {
  /* Длинное имя переносим на вторую строку, а не режем многоточием:
     в колонке ~109 единиц «Александра» превращалась в «Алекс…», и
     друзей было не отличить друг от друга. Дальше двух строк не
     пускаем — иначе ряды разъезжаются по высоте. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  max-width: 100%;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.1;
  letter-spacing: -.02em;
  text-align: center;
  overflow-wrap: anywhere;
  overflow: hidden;
  color: var(--ink);
}

/* Статус справа: у оплативших — розовый, у остальных приглушённый. */
.all__state {
  display: block;
  margin-top: calc(3 * var(--u));
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(10 * var(--u));
  line-height: 1;
  letter-spacing: -.05em;
  text-align: center;
  color: rgba(0, 0, 0, .4);
}

.all__state--trial {
  color: rgba(0, 0, 0, .6);
}

/* Значок «VPN за друзей» стал кнопкой — сбрасываем вид кнопки. */
.friends__vpn {
  padding: 0;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.friends__vpn:active {
  transform: scale(.96);
}

@media (prefers-reduced-motion: reduce) {

  .all,
  .all-scrim,
  .friends__vpn {
    transition: none;
  }
}

/* Скрытый блок не участвует в раскладке и не ловит клики. Без этого
   прозрачное затемнение перехватывает нажатия по всему экрану. */
[hidden] {
  display: none !important;
}

/* ==================================================================
   Попап «Бесплатный VPN за создание профиля» (макет 1007:9139)
   Белый лист с вырезом сверху: в вырез заходит розовая звезда с числом
   дней, по краям — аватар и подарок.
   ================================================================== */

.gift-scrim {
  position: absolute;
  inset: 0;
  z-index: 40;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  transition: opacity .22s ease;
}

.gift-scrim.is-open {
  opacity: 1;
}

/* Лист — SVG с уже вырезанной «ямкой» под звезду (Subtract 400x240). */
.gift {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(543 * var(--u));
  width: calc(400 * var(--u));
  height: calc(240 * var(--u));
  background: url("/app/assets/icons/gift-sheet.svg") no-repeat center / contain;
  transform: translateY(calc(20 * var(--u)));
  transition: transform .24s ease;
}

.gift-scrim.is-open .gift {
  transform: none;
}

/* ---------- Звезда с числом дней ----------
   В макете 185x185 в 128;424 на кадре — внутри листа (20;543)
   это 108;-119: звезда заходит в вырез и выступает над листом. */
.gift__star {
  position: absolute;
  left: calc(108 * var(--u));
  top: calc(-119 * var(--u));
  width: calc(185 * var(--u));
  height: calc(185 * var(--u));
  background: url("/app/assets/icons/gift-star.svg") no-repeat center / contain;
}

/* «3» и «дня» — отдельным слоем поверх звезды (189;477 → 169;-66). */
.gift__days {
  position: absolute;
  left: calc(169 * var(--u));
  top: calc(-66 * var(--u));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(5 * var(--u));
  color: var(--paper);
}

.gift__days-num {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(90 * var(--u));
  line-height: 1;
  letter-spacing: -.0111em;
}

.gift__days-word {
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  line-height: 1.1;
}

/* ---------- Аватар и подарок по краям выреза ---------- */
.gift__avatar {
  position: absolute;
  left: calc(49 * var(--u));
  /* 69 − 20 */
  top: calc(-9 * var(--u));
  /* 534 − 543 */
  width: calc(48 * var(--u));
  height: calc(49 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, .12);
  box-shadow: 0 calc(4 * var(--u)) calc(14 * var(--u)) 0 rgba(0, 0, 0, .14);
}

.gift__box {
  position: absolute;
  left: calc(310 * var(--u));
  /* 330 − 20 */
  top: calc(-21 * var(--u));
  /* 522 − 543 */
  width: calc(54.19 * var(--u));
  height: calc(54.19 * var(--u));
  background: url("/app/assets/icons/gift-box.svg") no-repeat center / contain;
}

/* ---------- Заголовок ----------
   Две строки: первая чёрная, вторая — серая (56;609 → 36;66). */
.gift__title {
  position: absolute;
  left: calc(36 * var(--u));
  top: calc(66 * var(--u));
  width: calc(328 * var(--u));
  height: calc(46 * var(--u));
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(25 * var(--u));
  line-height: 1.1;
  letter-spacing: -.03em;
  color: var(--ink);
}

.gift__title span {
  color: rgba(0, 0, 0, .3);
}

/* ---------- Кнопка «Забрать :)» ----------
   Чёрная «таблетка» со стеклянной подсветкой (39;680 → 19;137). */
.gift__take {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(137 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  border-radius: calc(46.26 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, .7) 26%,
      rgba(255, 255, 255, .3) 97%,
      rgba(255, 255, 255, .2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(255, 64, 157, .6),
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(60 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255, 255, 255, .2);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  color: var(--paper);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.gift__take:active {
  transform: scale(.98);
}

@media (prefers-reduced-motion: reduce) {

  .gift-scrim,
  .gift,
  .gift__take {
    transition: none;
  }
}

/* ==================================================================
   Наведение на экране «Ваши друзья»
   Только для мыши: на тач-устройствах :hover залипает после тапа,
   поэтому всё под @media (hover: hover). Нажатие (:active) уже
   описано у каждой кнопки — здесь добавляем промежуточное состояние.
   ================================================================== */

@media (hover: hover) {

  /* Круглые кнопки шапки (назад и QR) — чуть приподнимаются. */
  .friends__icon:hover {
    transform: scale(1.06);
    filter: brightness(1.04);
  }

  /* «Подарить VPN» и значок «VPN за друзей» — готовые картинки,
     поэтому подсвечиваем их фильтром, а не фоном. */
  .friends__arc:hover,
  .friends__vpn:hover {
    transform: scale(1.03);
    filter: brightness(1.06);
  }

  /* «Ручка» окна: расширяем зону отклика цветом, размер не трогаем —
     она узкая, масштаб был бы заметен как дрожание. */
  .qr__grip:hover,
  .whom__grip:hover,
  .all__grip:hover {
    filter: brightness(.88);
  }

  /* Кнопка «Скопировать» в окне QR. */
  .qr__copy:hover {
    transform: scale(1.01);
    filter: brightness(1.03);
  }

  /* Строка контакта в «Кому дарим» — подсветка всей строки. */
  .whom__row:hover {
    background: rgba(0, 0, 0, .04);
  }

  /* Карточка друга в списке «Все ваши друзья». */
  .all__cell:hover .all__avatar {
    transform: scale(1.05);
    filter: brightness(1.04);
  }
}

/* Плавность для тех элементов, у которых её ещё не было. */
.qr__grip,
.whom__grip,
.all__grip {
  transition: filter .18s ease;
}

.whom__row {
  transition: background .18s ease;
}

.all__cell .all__avatar {
  transition: transform .18s ease, filter .18s ease;
}

@media (prefers-reduced-motion: reduce) {

  .qr__grip,
  .whom__grip,
  .all__grip,
  .whom__row,
  .all__cell .all__avatar {
    transition: none;
  }
}

/* ==================================================================
   Пустое состояние: друзей ещё нет (макет 1007:11845)
   Счётчик и аватарки гаснут, рядом с нулём — грустный смайл.
   ================================================================== */

/* Смайл 70x51 рядом со счётчиком, отступ 7 как в макете */
.friends__sad {
  flex: 0 0 auto;
  width: calc(70 * var(--u));
  height: calc(51 * var(--u));
  margin-left: calc(7 * var(--u));
  background: url("/app/assets/icons/friends-sad.svg") no-repeat center / contain;
}

/* Ноль и смайл — бледные, как в макете */
.friends__count.is-empty {
  color: rgba(0, 0, 0, .1);
}

/* Друзей нет — ряда аватарок нет вовсе: показывать некого, а размытая
   заглушка из чужих лиц только мешала. */
.friends__faces.is-empty {
  display: none;
}

/* ==================================================================
   Экран «Профиль» (макет 960:8796, сетка 440×1305)
   Открывается по кнопке «Профиль» в нижней навигации.
   ================================================================== */

.screen--profile {
  /* Низ макета — 1153 (низ навигации), плюс запас. */
  height: calc(1165 * var(--u));
  background: var(--bg);
  overflow: hidden;
}

/* Навигация на этом экране ниже, чем на экране друзей (0;1018). */
/* Общая сцена — фиксированные 850px, а этот экран выше:
   растягиваем её под содержимое, иначе бургер и навигация уезжают под обрез. */
.stage:has(.screen--profile) {
  height: calc(1165 * var(--u));
}

/* Панель прибита к низу окна — координата по вертикали ей не нужна. */

/* ---------- Кнопки шапки (59×59 в 20;73 и 361;73) ---------- */
.profile__icon {
  position: absolute;
  top: calc(73 * var(--u));
  width: calc(59 * var(--u));
  height: calc(59 * var(--u));
  padding: 0;
  border: 0;
  background: no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.profile__icon:active { transform: scale(.94); }

/* Кнопки шапки — готовые картинки: значок и надпись уже в них.
   Холст 59×68 (выгружен в 4×: 236×272) — выше бокса на величину тени,
   поэтому тянем по ширине и даём тени выйти за край.

   Прежний tg.png лежал в 1× и на телефоне растягивался втрое: подпись
   мылило до нечитаемости. Обе кнопки выгружены заново из макета. */
.profile__icon--write {
  left: calc(20 * var(--u));
  background-image: url("/app/assets/icons/profile-write.png");
  background-size: 100% auto;
  background-position: center top;
}

.profile__icon--edit {
  left: calc(361 * var(--u));
  background-image: url("/app/assets/icons/profile-edit-btn.png");
  background-size: 100% auto;
  background-position: center top;
}

/* ---------- Аватар и дуга ---------- */
/* Заглушка из макета — уже круглая картинка с прозрачными углами, а фото
   из телеграма приходит обычным квадратом. Поэтому круг режем сами:
   border-radius + cover (не contain — тот вписывает кадр целиком и
   оставляет поля, из-за чего фото выглядело квадратным в круге).

   Сторона берётся одна: в макете блок 159.88x162.13, и на таком
   прямоугольнике 50% дали бы эллипс. */
.profile__avatar {
  position: absolute;
  left: calc(140.21 * var(--u));
  top: calc(56 * var(--u));
  width: calc(160 * var(--u));
  height: calc(160 * var(--u));
  border-radius: 50%;
  overflow: hidden;
  /* Размер и положение кадра — отдельными свойствами, а не шорткатом:
     JS подставляет фото через style.backgroundImage, и шорткат в этот
     момент сбрасывал бы cover, из-за чего фото вылезало квадратом. */
  background-color: rgba(0, 0, 0, .12);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

/* Имя: белая обводка 6.4px поверх аватара (239×34 в 100;210). */
.profile__name {
  position: absolute;
  left: calc(100 * var(--u));
  top: calc(210 * var(--u));
  width: calc(239 * var(--u));
  height: calc(34 * var(--u));
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(48 * var(--u));
  line-height: 1;
  /* Чуть шире макетных -.05em: с толстым контуром буквы иначе слипаются */
  letter-spacing: -.01em;
  text-align: center;
  /* Почти прозрачные буквы в чёрном контуре; paint-order кладёт
     контур под заливку, иначе он съедает тонкие штрихи Asgard. */
  color: rgba(255, 255, 255, .1);
  -webkit-text-stroke: calc(3 * var(--u)) var(--ink);
  paint-order: stroke fill;
}

/* ---------- Карточки «Баланс» и «Подписка» (189×126 в 26;271 и 225;271) ---------- */
.pcard {
  position: absolute;
  top: calc(271 * var(--u));
  width: calc(189 * var(--u));
  height: calc(126 * var(--u));
  border-radius: calc(32 * var(--u));
  border: calc(2.87 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
}

.pcard--balance {
  left: calc(26 * var(--u));
  background-image:
    linear-gradient(#FF2486, #FF2486),
    linear-gradient(43deg,
      rgba(255,255,255,0) 0%, rgba(255,255,255,.7) 26%,
      rgba(255,255,255,.3) 97%, rgba(255,255,255,.2) 100%);
  box-shadow:
    0 calc(29.63 * var(--u)) calc(20.07 * var(--u)) calc(-28.68 * var(--u)) rgba(208,16,102,.4),
    inset calc(2.39 * var(--u)) calc(2.39 * var(--u)) calc(15.77 * var(--u)) calc(-2.39 * var(--u)) rgba(255,255,255,.7),
    inset calc(1.19 * var(--u)) calc(1.19 * var(--u)) calc(28.68 * var(--u)) calc(-2.39 * var(--u)) #fff,
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(37.5 * var(--u)) calc(-5.5 * var(--u)) rgba(246,188,137,.7);
}

.pcard--sub {
  left: calc(225 * var(--u));
  background-image:
    linear-gradient(180deg, #fff 21%, #E4E4E4 100%),
    linear-gradient(43deg,
      rgba(255,255,255,0) 0%, rgba(255,255,255,.7) 26%,
      rgba(255,255,255,.3) 97%, rgba(255,255,255,.2) 100%);
  box-shadow:
    0 calc(29.63 * var(--u)) calc(20.07 * var(--u)) calc(-28.68 * var(--u)) rgba(0,0,0,.3),
    inset calc(2.39 * var(--u)) calc(2.39 * var(--u)) calc(15.77 * var(--u)) calc(-2.39 * var(--u)) rgba(255,255,255,.7),
    inset calc(1.19 * var(--u)) calc(1.19 * var(--u)) calc(28.68 * var(--u)) calc(-2.39 * var(--u)) #fff,
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(25 * var(--u)) calc(-5.5 * var(--u)) rgba(246,137,137,.7);
}

/* «Баланс» — подпись сверху (72×10 в 58;19 от карточки). */
.pcard__label {
  position: absolute;
  left: calc(29 * var(--u));
  top: calc(16 * var(--u));
  width: calc(72 * var(--u));
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(255, 255, 255, .6);
}

/* Сумма: крупное число и знак рубля помельче. */
.pcard__sum {
  position: absolute;
  left: 0;
  top: calc(38 * var(--u));
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(2 * var(--u));
  color: var(--paper);
}

.pcard__sum b {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(30 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
}

.pcard__sum i {
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(17 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
}

/* «Подписка» со значком wi-fi. */
.pcard__head {
  position: absolute;
  left: 0;
  top: calc(16 * var(--u));
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(5 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .5);
}

.pcard__wifi {
  width: calc(17 * var(--u));
  height: calc(10.39 * var(--u));
  background: url("/app/assets/icons/profile-wifi.svg") no-repeat center / contain;
}

/* Дата окончания — красная, в две строки. */
.pcard__expires {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(38 * var(--u));
  width: calc(135 * var(--u));
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1.25;
  letter-spacing: -.02em;
  color: rgba(255, 56, 60, .7);
}

/* Белая кнопка внутри карточки (160×40 в 14;75). */
.pcard__btn {
  position: absolute;
  left: calc(11 * var(--u));
  top: calc(75 * var(--u));
  width: calc(160 * var(--u));
  height: calc(40 * var(--u));
  padding: 0;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(15 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Светлая заливка с сероватым отливом книзу, как в макете;
     вторым слоем — градиентная кайма. */
  background-image:
    radial-gradient(120% 160% at 50% -20%,
      rgba(255,255,255,.95) 22%, rgba(226,226,226,.95) 55%, rgba(184,184,184,.95) 100%),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9,9,9,.22);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.pcard__btn:active { transform: scale(.97); }

/* ---------- Подписка с включённым автопродлением (макет 919:7477) ----------
   Оба состояния лежат в разметке, показываем нужное по data-autorenew.
   Выключено — светлая карточка «Закончится / Продлить»,
   включено — чёрная «Автопродление / Отменить». */
.pcard--sub[data-autorenew="off"] .pcard__renew,
.pcard--sub[data-autorenew="off"] .pcard__btn--cancel,
.pcard--sub[data-autorenew="on"] .pcard__expires,
.pcard--sub[data-autorenew="on"] .pcard__btn:not(.pcard__btn--cancel) {
  display: none;
}

/* Чёрный корпус с той же градиентной каймой и лиловым отливом внутри. */
.pcard--sub[data-autorenew="on"] {
  --pcard-accent: linear-gradient(30deg, #F7DED7 0%, #B6C9D7 36%, #B4C2F3 70%, #E2CEEA 100%);
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255,255,255,0) 0%, rgba(255,255,255,.7) 26%,
      rgba(255,255,255,.3) 97%, rgba(255,255,255,.2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0,0,0,.45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(144,137,246,.6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.2);
}

/* Заголовок и значок набраны светлым градиентом. */
.pcard--sub[data-autorenew="on"] .pcard__head {
  background-image: var(--pcard-accent);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Тот же значок, но залитый градиентом: сам SVG уводим в маску. */
.pcard--sub[data-autorenew="on"] .pcard__wifi {
  background: var(--pcard-accent);
  -webkit-mask: url("/app/assets/icons/profile-wifi.svg") no-repeat center / contain;
  mask: url("/app/assets/icons/profile-wifi.svg") no-repeat center / contain;
}

/* «Автопродление / дата» (137×24 в 26;41). */
/* От текста до кнопки всего 37 единиц (38 → 75). «Автопродление» плюс
   дата «13 Сентября 2027» в 137 единиц шириной не влезали в строку и
   переносились на три — три строки по 14px с интерлиньяжем 1.25 дают
   52.5 и наезжали на кнопку. Уменьшаем кегль: дата встаёт в две строки
   и укладывается в отведённое место. */
.pcard__renew {
  position: absolute;
  left: calc(23 * var(--u));
  top: calc(38 * var(--u));
  width: calc(137 * var(--u));
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(12 * var(--u));
  line-height: 1.2;
  letter-spacing: -.02em;
  color: #F4F4F4;
}

/* «Отменить» — полупрозрачное стекло вместо белой заливки. */
.pcard__btn--cancel {
  left: calc(14 * var(--u));
  padding: 0 calc(13 * var(--u));
  background-image:
    radial-gradient(circle at 50% 4%,
      rgba(158,158,158,.5) 5%, rgba(255,255,255,.3) 30%, rgba(255,255,255,.2) 50%),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  background-color: rgba(255, 255, 255, .4);
  color: #000;
}

/* ---------- Строки-заголовки разделов ---------- */
.prow {
  position: absolute;
  left: calc(30 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .3);
}

.prow--devices { top: calc(426 * var(--u)); }
.prow--pay     { top: calc(549 * var(--u)); left: calc(32 * var(--u)); }
.prow--profile { top: calc(671 * var(--u)); left: calc(169 * var(--u)); }

.prow__icon--device {
  width: calc(9 * var(--u));
  height: calc(12 * var(--u));
  background: url("/app/assets/icons/profile-device.svg") no-repeat center / contain;
}

.prow__icon--person {
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
  border-radius: 50%;
  background: url("/app/assets/icons/profile-person.svg") no-repeat center / cover;
}

.prow__icon--ruble { font-size: calc(14 * var(--u)); }

/* Счётчик «0/0» — цифровым начертанием, чёрный. */
.prow__count {
  font-family: var(--font-display);
  font-size: calc(14 * var(--u));
  color: var(--ink);
}

/* ---------- «Добавить» / «Привязать» справа ---------- */
.prow__add {
  position: absolute;
  display: flex;
  align-items: center;
  gap: calc(3 * var(--u));
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.prow__add:active { transform: scale(.95); }

.prow__add--devices { left: calc(300 * var(--u)); top: calc(425 * var(--u)); }
.prow__add--pay     { left: calc(296 * var(--u)); top: calc(547 * var(--u)); }

.prow__add-icon {
  width: calc(17 * var(--u));
  height: calc(13 * var(--u));
  background: url("/app/assets/icons/profile-plus.svg") no-repeat center / contain;
}

/* ---------- Загрузка ----------
   Пока данные идут с бэкенда, на их месте пульсируют серые плашки.
   Раньше тут стояли нули и подписи из макета — пользователь читал их
   как факт («баланс 0», «устройств 0/0»), а через секунду цифры
   менялись на настоящие. */
@keyframes skeleton-pulse {
  0%, 100% { opacity: .55; }
  50%      { opacity: .25; }
}

/* Текст прячем, на его месте — серая полоска в размер строки. */
.is-loading .skeleton {
  color: transparent !important;
  position: relative;
}

.is-loading .skeleton::after {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  height: 1em;
  border-radius: calc(6 * var(--u));
  background: currentColor;
  color: rgba(0, 0, 0, .18);
  animation: skeleton-pulse 1.2s ease-in-out infinite;
}

/* Полоска на месте списка: та же высота, что у пустой плашки. */
.pskeleton {
  height: calc(60 * var(--u));
  margin: 0 0 calc(10 * var(--u));
  border-radius: calc(18 * var(--u));
  background: rgba(0, 0, 0, .12);
  animation: skeleton-pulse 1.2s ease-in-out infinite;
}

.pskeleton[hidden] { display: none; }
/* Кружок аватара, пока не знаем, чьё фото ставить: пульсирует так же,
   как текстовые скелетоны. Раньше на его месте стояло лицо из макета. */
.avatar-slot:not(.is-ready) {
  animation: skeleton-pulse 1.2s ease-in-out infinite;
}

/* ---------- Пустые плашки (400×60) ---------- */
/* hidden должен работать: у .pempty есть display:flex, а он
   специфичнее браузерного [hidden]{display:none} — без этого
   плашка «не добавлены» висит на экране, пока грузятся данные. */
.pempty[hidden] { display: none; }

.pempty {
  position: absolute;
  left: calc(21 * var(--u));
  width: calc(400 * var(--u));
  height: calc(60 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: calc(18 * var(--u));
  background: rgba(0, 0, 0, .1);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  color: rgba(0, 0, 0, .4);
}

.pempty--devices { top: calc(454 * var(--u)); }
.pempty--pay     { top: calc(576 * var(--u)); }

/* ---------- Кнопки «Выйти» и «Удалить» ---------- */
.pbtn {
  position: absolute;
  top: calc(696 * var(--u));          /* 671 + 25 */
  height: calc(50 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(9 * var(--u));
  padding: 0 calc(13 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(18 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    radial-gradient(120% 160% at 50% -20%,
      rgba(255,255,255,.95) 22%, rgba(226,226,226,.95) 55%, rgba(184,184,184,.95) 100%),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9,9,9,.22);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(21 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.pbtn:active { transform: scale(.98); }

.pbtn--exit {
  left: calc(26 * var(--u));
  width: calc(188 * var(--u));
  color: rgba(0, 0, 0, .6);
}

.pbtn--delete {
  left: calc(225 * var(--u));
  width: calc(190 * var(--u));
  color: rgba(191, 33, 33, .6);
}

.pbtn__icon--exit {
  width: calc(19 * var(--u));
  height: calc(18 * var(--u));
  background: url("/app/assets/icons/profile-exit.svg") no-repeat center / contain;
}

.pbtn__icon--trash {
  width: calc(17 * var(--u));
  height: calc(18 * var(--u));
  background: url("/app/assets/icons/profile-trash.svg") no-repeat center / contain;
}

/* ---------- Копирайт ---------- */
.profile__copy {
  position: absolute;
  left: calc(91.5 * var(--u));        /* 26 + 65.5 */
  top: calc(771 * var(--u));          /* 671 + 100 */
  width: calc(259 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1.15;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .3);
}

/* ---------- Бургер со стикерами внизу ----------
   Это тот же блок, что на главной (.burger + .burger__img + .burger__fade):
   картинку и размытие описывать заново не нужно, здесь только положение. */
.profile__burger {
  left: calc(-9 * var(--u));
  top: calc(806 * var(--u));
  right: auto;
  bottom: auto;
  width: calc(457 * var(--u));
  height: calc(458 * var(--u));
}

@media (hover: hover) {
  .profile__icon:hover,
  .prow__add:hover {
    transform: scale(1.06);
    filter: brightness(1.04);
  }

  .pcard__btn:hover,
  .pbtn:hover {
    transform: scale(1.02);
    filter: brightness(1.03);
  }
}

@media (prefers-reduced-motion: reduce) {
  .profile__icon,
  .pcard__btn,
  .prow__add,
  .pbtn { transition: none; }
}

/* ==================================================================
   Компоненты по макету 3108:2745
   ================================================================== */

/* Демо-страница: компоненты идут в столбик, чтобы смотреть их отдельно. */
.screen--kit {
  height: auto;
  min-height: calc(var(--h) * var(--u));
  padding: calc(24 * var(--u)) 0 calc(48 * var(--u));
  background: var(--bg);
}

.kit__head {
  margin: calc(24 * var(--u)) 0 calc(12 * var(--u));
  padding: 0 calc(20 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .4);
}

/* ---------- Карточка устройства (400x355) ---------- */
.device {
  position: relative;
  width: calc(400 * var(--u));
  height: calc(355 * var(--u));
  margin: 0 auto calc(16 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
}

/* «Ручка» вверху: 50x6 в 13;110 от верха карточки. */
.device__grip {
  position: absolute;
  left: 50%;
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  margin-left: calc(-25 * var(--u));
  border-radius: calc(3 * var(--u));
  background: rgba(0, 0, 0, .1);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0, 0, 0, .35);
}

/* Круг с картинкой устройства (125x125 в 38;38). */
.device__icon {
  position: absolute;
  left: 50%;
  top: calc(38 * var(--u));
  width: calc(125 * var(--u));
  height: calc(125 * var(--u));
  margin-left: calc(-62.5 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  border-radius: 50%;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Стеклянный круг: радиальная подсветка сверху + обводка градиентом. */
  background-image:
    radial-gradient(circle at 50% 4%,
      rgba(128,128,128,.01) 22%, rgba(158,158,158,.4) 42%, rgba(158,158,158,.7) 56%),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  background-color: rgba(255, 255, 255, .7);
  box-shadow: 0 calc(6 * var(--u)) calc(10 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .22);
}

/* Сама картинка поверх круга — размеры у каждой свои, из макета. */
.device__icon::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

.device[data-dev="phone"] .device__icon::after {
  width: calc(125 * var(--u));
  height: calc(125 * var(--u));
  background-image: url("/app/assets/icons/dev-phone.png");
}

.device[data-dev="galaxy"] .device__icon::after {
  width: calc(75 * var(--u));
  height: calc(70 * var(--u));
  background-image: url("/app/assets/icons/dev-galaxy.png");
}

.device[data-dev="laptop"] .device__icon::after {
  width: calc(98 * var(--u));
  height: calc(69 * var(--u));
  background-image: url("/app/assets/icons/dev-laptop.png");
}

.device[data-dev="pc"] .device__icon::after {
  width: calc(62 * var(--u));
  height: calc(93 * var(--u));
  background-image: url("/app/assets/icons/dev-pc.png");
}

/* Название устройства (Asgard Number 25, по центру на 181). */
.device__name {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(181 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(25 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* Дата добавления (14, приглушённая, на 211). */
.device__added {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(211 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .3);
}

/* Чёрная кнопка «Скопировать ключ» (362x85 в 19;252). */
.device__copy {
  position: absolute;
  left: 50%;
  top: calc(252 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  margin-left: calc(-181 * var(--u));
  padding: 0 calc(36 * var(--u)) 0 calc(32 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(12 * var(--u));
  border: 0;
  border-radius: calc(50 * var(--u));
  background: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.device__copy:active { transform: scale(.99); }

.device__copy-text {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(18 * var(--u));
  line-height: 1;
  color: var(--paper);
}

.device__copy-icon {
  flex: 0 0 auto;
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  background: url("/app/assets/icons/copy-key.svg") no-repeat center / contain;
}

/* ---------- Плашка подписки (189x126) ---------- */
.sub {
  position: relative;
  width: calc(189 * var(--u));
  height: calc(126 * var(--u));
  margin: 0 auto calc(14 * var(--u));
  border-radius: calc(32 * var(--u));
  border: calc(2 * var(--u)) solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Фон темы + светлая обводка градиентом, как у карточек тарифов. */
  background-image:
    linear-gradient(var(--sub-bg), var(--sub-bg)),
    linear-gradient(43deg,
      rgba(255,255,255,0) 0%, rgba(255,255,255,.7) 26%,
      rgba(255,255,255,.3) 97%, rgba(255,255,255,.2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) var(--sub-shadow),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) var(--sub-glow),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.2);
}

/* Темы плашки — цвета из макета. */
.sub[data-theme="green"] {
  --sub-bg: #27E593;
  --sub-shadow: rgba(15, 150, 71, .45);
  --sub-glow: rgba(226, 247, 199, .6);
  --sub-cancel: #22C980;
  --sub-halo: rgba(39, 229, 147, .6);
  --sub-accent: linear-gradient(32deg, #F2F2F2 0%, #D7FFA2 55%, #F2FFD5 100%);
}

.sub[data-theme="pink"] {
  --sub-bg: #FF2486;
  --sub-shadow: rgba(208, 16, 102, .4);
  --sub-glow: rgba(246, 188, 137, .7);
  --sub-cancel: #DD2174;
  --sub-halo: rgba(255, 36, 134, .6);
  --sub-accent: linear-gradient(34deg, #F2F2F2 22%, #FFD2A2 85%, #C4FFE6 100%);
}

.sub[data-theme="violet"] {
  --sub-bg: #8523C6;
  --sub-shadow: rgba(132, 41, 207, .45);
  --sub-glow: rgba(144, 137, 246, .6);
  --sub-cancel: #711DAA;
  --sub-halo: rgba(133, 35, 198, .6);
  --sub-accent: linear-gradient(30deg, #F7EED7 0%, #FFB3E4 36%, #EADECE 100%);
}

.sub[data-theme="black"] {
  --sub-bg: #000;
  --sub-shadow: rgba(0, 0, 0, .45);
  --sub-glow: rgba(144, 137, 246, .6);
  --sub-cancel: #000;
  --sub-halo: rgba(158, 158, 158, .5);
  --sub-accent: linear-gradient(30deg, #F7DED7 0%, #B6C9D7 36%, #B4C2F3 70%, #E2CEEA 100%);
}

/* Заголовок «Подписка» с иконкой (ряд в 42;19). */
.sub__title {
  position: absolute;
  left: calc(42 * var(--u));
  top: calc(19 * var(--u));
  margin: 0;
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  /* Подпись набрана светлым градиентом темы. */
  background-image: var(--sub-accent);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.sub__icon {
  flex: 0 0 auto;
  width: calc(17 * var(--u));
  height: calc(10.39 * var(--u));
  border-radius: calc(6 * var(--u));
  background-image: var(--sub-accent);
}

/* «Автопродление / дата» (137x24 в 26;41). */
.sub__renew {
  position: absolute;
  left: calc(26 * var(--u));
  top: calc(41 * var(--u));
  width: calc(137 * var(--u));
  margin: 0;
  text-align: center;
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: #F4F4F4;
}

/* Кнопка «Отменить» (160x40 в 14;75). */
.sub__cancel {
  position: absolute;
  left: calc(14 * var(--u));
  top: calc(75 * var(--u));
  width: calc(160 * var(--u));
  height: calc(40 * var(--u));
  padding: 0 calc(13 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(15 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Полупрозрачное «стекло» в цвет темы. */
  background-image:
    radial-gradient(circle at 50% 4%,
      var(--sub-halo) 5%, rgba(255,255,255,.3) 30%, rgba(255,255,255,.2) 50%),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  background-color: rgba(255, 255, 255, .4);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .22);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--sub-cancel);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.sub__cancel:active { transform: scale(.97); }

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

/* ==================================================================
   Баланс (макет 919:6550)
   Шапка, карточка с суммой, итоги за период и список транзакций.
   ================================================================== */

.screen--balance {
  /* Абсолютные потомки высоту не задают, поэтому считаем её сами:
     низ списка транзакций (1016) плюс запас снизу. */
  height: calc(1060 * var(--u));
}

/* Сцена задана под 850px, а баланс длиннее: тянем её по содержимому
   и прижимаем к верху — иначе центрирование body срезает низ списка. */
.stage:has(.screen--balance) {
  height: calc(1060 * var(--u));
}

body:has(.screen--balance) {
  align-items: flex-start;
}

/* Стрелка «назад» (Vector 26x20 в 20;74) */
.balance__back {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(74 * var(--u));
  width: calc(26 * var(--u));
  height: calc(20 * var(--u));
  padding: 0;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background: url("/app/assets/icons/balance-back.svg") no-repeat center / contain;
}

/* Заголовок «Баланс» (164;75) */
.balance__title {
  position: absolute;
  left: calc(164 * var(--u));
  top: calc(75 * var(--u));
  width: calc(113 * var(--u));
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(26 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
  text-align: center;
  color: var(--ink);
}

/* ---------- Карточка с суммой (400x218 в 21;113) ---------- */
.balance__card {
  position: absolute;
  left: calc(21 * var(--u));
  top: calc(113 * var(--u));
  width: calc(400 * var(--u));
  height: calc(218 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
}

/* Сумма и знак рубля в одну строку по нижнему краю (47;31) */
.balance__sum {
  position: absolute;
  left: 0;
  top: calc(31 * var(--u));
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: calc(5 * var(--u));
  color: var(--ink);
}

.balance__amount {
  font-family: var(--font-number);
  font-weight: 800;
  font-size: calc(60 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
}

.balance__currency {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(30 * var(--u));
  line-height: 1;
  letter-spacing: -.1164em;
}

/* Подпись под суммой (132;86) */
.balance__note {
  position: absolute;
  left: 0;
  top: calc(86 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(19 * var(--u));
  line-height: 1;
  letter-spacing: -.0158em;
  text-align: center;
  color: rgba(0, 0, 0, .4);
}

/* Чёрная кнопка «Пополнить» (366x80 в 17;123 внутри карточки) */
.balance__topup {
  position: absolute;
  left: calc(17 * var(--u));
  top: calc(123 * var(--u));
  width: calc(366 * var(--u));
  height: calc(80 * var(--u));
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(9 * var(--u));
  border: calc(3 * var(--u)) solid transparent;
  border-radius: calc(50 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#000, #000),
    linear-gradient(43deg,
      rgba(255,255,255,0) 0%,
      rgba(255,255,255,.7) 26%,
      rgba(255,255,255,.3) 97%,
      rgba(255,255,255,.2) 100%);
  box-shadow:
    0 calc(32 * var(--u)) calc(22 * var(--u)) calc(-30 * var(--u)) rgba(0,0,0,.45),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.7),
    inset calc(-2.5 * var(--u)) calc(-6.25 * var(--u)) calc(17.5 * var(--u)) calc(-5.5 * var(--u)) rgba(223,223,223,.6),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.2);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(21 * var(--u));
  line-height: 1;
  color: var(--paper);
  transition: transform .18s ease;
}

.balance__topup:active { transform: scale(.99); }

/* Стрелка «вниз на полку» — в файле уже белая, перекрашивать не нужно. */
.balance__topup-icon {
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
  background: url("/app/assets/icons/topup-arrow.svg") no-repeat center / contain;
}

/* ---------- Итоги за период (54;354 и 264;354) ---------- */
.balance__stats {
  position: absolute;
  left: calc(54 * var(--u));
  top: calc(354 * var(--u));
  width: calc(340 * var(--u));
  display: flex;
  justify-content: space-between;
}

.balance__stat {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

/* Квадратный значок 27x27 с бледной заливкой */
.balance__stat-icon {
  flex: 0 0 auto;
  width: calc(27 * var(--u));
  height: calc(27 * var(--u));
  border-radius: calc(8 * var(--u));
  background: rgba(0, 0, 0, .05) no-repeat center / calc(13 * var(--u));
}

.balance__stat-icon--spent { background-image: url("/app/assets/icons/balance-spent.svg"); }
.balance__stat-icon--added { background-image: url("/app/assets/icons/balance-added.svg"); }

.balance__stat-body {
  display: flex;
  flex-direction: column;
  gap: calc(5 * var(--u));
}

/* Сумма: крупное число и знак рубля помельче */
.balance__stat-value {
  display: flex;
  align-items: flex-end;
  gap: calc(2 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--ink);
}

.balance__stat-value b {
  font-weight: 400;
  font-size: calc(28 * var(--u));
}

.balance__stat-value i {
  font-style: normal;
  font-size: calc(17 * var(--u));
}

.balance__stat-note {
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .4);
}

/* Заголовок «Транзакции» (124;443) */
.balance__heading {
  position: absolute;
  z-index: 1;
  left: calc(20 * var(--u));
  top: calc(428 * var(--u));
  width: calc(400 * var(--u));
  height: calc(48 * var(--u));
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Надпись — графика из макета: серые буквы в белой обводке. Она лежит
     на кромке карточки, поэтому своей подложки у блока нет. */
  background: url("/app/assets/icons/balance-heading.svg")
    no-repeat center / calc(214 * var(--u)) auto;
  text-indent: -9999px;
  overflow: hidden;
}

/* ---------- Список транзакций (400 в 20;452) ----------
   Белое поле идёт от заголовка до низа экрана: под ним не должно
   оставаться полосы фона, даже когда операций мало. */
.ops {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(452 * var(--u));
  bottom: 0;
  width: calc(400 * var(--u));
  padding: 0 0 calc(24 * var(--u));
  /* Скругление только сверху: низ уходит за край экрана. */
  border-radius: calc(60 * var(--u)) calc(60 * var(--u)) 0 0;
  background: var(--paper);
  overflow-y: auto;
  scrollbar-width: none;
}

.ops::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Операций ещё нет: подпись стоит по центру белого поля. */
.ops.is-empty {
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ops__empty {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(16 * var(--u));
  line-height: 1.2;
  letter-spacing: -.02em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

/* Название месяца над группой */
/* Месяц-разделитель (макет 919:7143): подпись и две полукруглые
   «скобки» 6x11 по бокам, зазор 8. */
.ops__month {
  height: calc(33 * var(--u));
  /* Первый заголовок стоит на 40 от верха карточки (макет), остальные
     отбиваются от предыдущего списка. */
  margin: calc(19 * var(--u)) 0 0;
  padding: 0 calc(24 * var(--u));
  display: flex;
  align-items: center;
  /* По левому краю, вровень со строками списка */
  justify-content: flex-start;
  gap: calc(8 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .3);
}

/* Скобки по бокам названия месяца (Ellipse 1593/1594, 6x11) */
.ops__month-mark {
  flex: 0 0 auto;
  width: calc(6 * var(--u));
  height: calc(11 * var(--u));
  background: no-repeat center / contain;
}

.ops__month-mark--left  { background-image: url("/app/assets/icons/month-cap-left.svg"); }
.ops__month-mark--right { background-image: url("/app/assets/icons/month-cap-right.svg"); }

.ops__list:last-child { margin-bottom: calc(16 * var(--u)); }

/* Первый заголовок стоит на 40 от верха карточки. */
/* Первый заголовок стоит на 40 от верха карточки (макет 919:7143). */
.ops > .ops__month:first-child { margin-top: calc(40 * var(--u)); }

.ops__list {
  margin: 0;
  padding: 0 calc(24 * var(--u));
  list-style: none;
  /* В макете строки идут вплотную: шаг 62 задаёт сама высота строки. */
  display: flex;
  flex-direction: column;
}

/* Строка операции 352x62 с разделителем снизу */
.op {
  position: relative;
  /* Макет 919:6571: строка 352×62 — значок слева, название и время
     в центре, сумма справа. */
  height: calc(62 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

/* Разделитель гаснет к краям, как в макете */
/* Значок операции в макете отсутствует. */
.op__icon {
  flex: 0 0 auto;
  width: calc(38 * var(--u));
  height: calc(38 * var(--u));
  border-radius: 50%;
  background: no-repeat center / contain;
}

.op[data-kind="sbp"] .op__icon {
  background-image: url("/app/assets/icons/op-sbp.svg");
}

.op[data-kind="card"] .op__icon {
  background-image: url("/app/assets/icons/op-card.svg");
}

.op[data-kind="crypto"] .op__icon {
  background-image: url("/app/assets/icons/op-crypto.svg");
}

.op[data-kind="stars"] .op__icon {
  background-image: url("/app/assets/icons/op-stars.svg");
}

/* Кешбэк приходит от друга — показываем его аватар */
.op[data-kind="cash"] .op__icon {
  background-color: rgba(0, 0, 0, .12);
  background-size: cover;
}

.op__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: calc(7 * var(--u));
}

.op__name {
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(15 * var(--u));
  line-height: .9;
  letter-spacing: -.0333em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Время и дата через точку */
.op__meta {
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(10 * var(--u));
  line-height: 1;
  letter-spacing: -.04em;
  color: rgba(0, 0, 0, .4);
}

.op__dot {
  width: calc(2.5 * var(--u));
  height: calc(2.5 * var(--u));
  border-radius: 50%;
  background: currentColor;
}

/* Тонкая линия под строкой, гаснущая к краям (stroke fill_B8XNWJ) */
.op:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(1 * var(--u));
  background: linear-gradient(270deg,
    rgba(0,0,0,.05) 10%, rgba(0,0,0,.25) 50%, rgba(0,0,0,.05) 100%);
}

/* Списание бледнее поступления: гаснет вся строка — значок,
   название и сумма. */
.op[data-flow="out"] .op__name,
.op[data-flow="out"] .op__sum {
  color: rgba(0, 0, 0, .25);
}

.op[data-flow="out"] .op__icon {
  opacity: .45;
}

/* Сумма операции справа */
.op__sum {
  flex: 0 0 auto;
  margin-left: auto;
  padding-left: calc(8 * var(--u));
  display: flex;
  align-items: baseline;
  gap: calc(2 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: .9;
  letter-spacing: -.0333em;
  /* В макете сумма чёрная (fill_07IPWT), приглушены только время и дата */
  color: var(--ink);
  white-space: nowrap;
}

/* Знак операции: крупнее и легче самой суммы */
.op__sign {
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: calc(25 * var(--u));
  line-height: 1;
  letter-spacing: -.14em;
}

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

/* ==================================================================
   <pay-card> — карточка привязанной карты (макет 3108:2744, 352x149)
   ================================================================== */

pay-card {
  display: block;
  width: calc(352 * var(--u));
  height: calc(149 * var(--u));
}

.paycard {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: calc(32 * var(--u));
  background: #000;
  box-shadow:
    0 calc(10 * var(--u)) calc(18 * var(--u)) calc(-30 * var(--u)) rgba(0,0,0,.3),
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(16.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.7),
    inset calc(-2.5 * var(--u)) calc(-4.25 * var(--u)) calc(7.5 * var(--u)) calc(-5.5 * var(--u)) rgba(246,137,139,.5),
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(15 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.2);
}

/* Красный вариант карты (например, Альфа-банк). */
.paycard--red { background: #F5352A; }

/* Рамка вокруг номера: два вложенных прямоугольника из макета
   (333x68 в 10;13 и 325x60 в 14;17). */
.paycard__top {
  position: absolute;
  left: calc(10 * var(--u));
  top: calc(13 * var(--u));
  width: calc(333 * var(--u));
  height: calc(68 * var(--u));
}

/* Внешняя рамка отдельным слоем: маску нельзя вешать на сам блок —
   она срезала бы номер и подпись внутри него. */
.paycard__top::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: calc(18 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  background: linear-gradient(180deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.3) 68%) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* Внутренняя рамка. */
.paycard__top::after {
  content: "";
  position: absolute;
  left: calc(4 * var(--u));
  top: calc(4 * var(--u));
  width: calc(325 * var(--u));
  height: calc(60 * var(--u));
  border-radius: calc(15 * var(--u));
  border: calc(1 * var(--u)) solid rgba(255, 255, 255, .12);
}

/* Номер карты (Asgard Number 15, трекинг 10%). */
.paycard__number {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(19 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  /* Asgard Number 15 с трекингом 10% — как в макете. */
  font-size: calc(15 * var(--u));
  line-height: 1;
  letter-spacing: .1em;
  color: #838383;
  white-space: nowrap;
}

/* Подписи под значениями — 14px, полупрозрачные белые. */
.paycard__caption {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(255, 255, 255, .3);
}

.paycard__top .paycard__caption {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(38 * var(--u));
}

/* Чип (44x30 в 282;32). */
.paycard__chip {
  position: absolute;
  left: calc(272 * var(--u));
  top: calc(19 * var(--u));
  width: calc(44 * var(--u));
  height: calc(30 * var(--u));
  border-radius: calc(5 * var(--u));
  background: url("/app/assets/icons/card-chip.png") no-repeat center / contain;
}

/* CVV (30;100) и срок действия (97;100). */
.paycard__field {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: calc(6 * var(--u));
}

.paycard__field--cvv    { left: calc(30 * var(--u)); top: calc(100 * var(--u)); }
.paycard__field--expiry { left: calc(97 * var(--u)); top: calc(100 * var(--u)); }

.paycard__value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(15 * var(--u));
  line-height: 1;
  letter-spacing: .1em;
  color: #838383;
}

/* Значок платёжной системы (93x42 в 245;92). */
.paycard__bank {
  position: absolute;
  left: calc(245 * var(--u));
  top: calc(92 * var(--u));
  width: calc(93 * var(--u));
  height: calc(42 * var(--u));
  border-radius: calc(14 * var(--u));
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* ==================================================================
   Заполненное состояние профиля (макет 955:7596)
   Списки устройств и способов оплаты. Пустые плашки прячутся,
   когда в данных что-то есть, — и наоборот.
   ================================================================== */

.plist {
  position: absolute;
  left: calc(26 * var(--u));
  width: calc(389 * var(--u));
  margin: 0;
  padding: 0;
  list-style: none;
  /* Поток, а не абсолютные координаты: при удалении строки
     остальные поднимаются сами и пустоты не остаётся. */
  display: flex;
  flex-direction: column;
}

/* ---------- Устройства (ряды с шагом 79: 454, 533, 612) ---------- */
.plist--devices { top: calc(454 * var(--u)); }

.plist--devices { gap: calc(13 * var(--u)); }

.pdev {
  flex: 0 0 auto;
  height: calc(66 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

/* Плитка с картинкой устройства (92×66). */
.pdev__icon {
  flex: 0 0 auto;
  width: calc(92 * var(--u));
  height: calc(66 * var(--u));
  border-radius: calc(14 * var(--u));
  background: no-repeat center / contain;
}

.pdev__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--u));
  min-width: 0;
}

.pdev__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(22 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Неактивное устройство — имя блёклое. */
.pdev.is-off .pdev__name { color: rgba(0, 0, 0, .3); }

.pdev__added {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: rgba(0, 0, 0, .3);
}

/* Кнопка-стрелка справа (30×30). */
.pdev__go {
  flex: 0 0 auto;
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: url("/app/assets/icons/whom-arrow.svg") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.pdev__go:active { transform: scale(.9); }

/* ---------- Способы оплаты (ряды с шагом 57: 741, 798, 855, 912) ---------- */
.plist--pay { top: calc(741 * var(--u)); }

.plist--pay { gap: calc(15 * var(--u)); }

.ppay {
  flex: 0 0 auto;
  height: calc(42 * var(--u));
  display: flex;
  align-items: center;
}

/* Цветной значок платёжной системы (93×42). */
.ppay__badge {
  flex: 0 0 auto;
  width: calc(93 * var(--u));
  height: calc(42 * var(--u));
  border-radius: calc(12 * var(--u));
  background: no-repeat center / contain;
}

/* Название/номер — от x=130, т.е. 104 от левого края ряда. */
.ppay__name {
  flex: 1 1 auto;
  margin-left: calc(11 * var(--u));
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(22 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Непривязанный способ — блёклый. */
.ppay.is-off .ppay__name { color: rgba(0, 0, 0, .3); }

/* Кружок выбора (30×30 в x=353). */
.ppay__pick {
  flex: 0 0 auto;
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  margin-right: calc(7 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/ppay-uncheck.png") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.ppay__pick {
  position: relative;
}

.ppay__pick[aria-checked="true"] {
  background-image: url("/app/assets/icons/ppay-check.png");
}

/* Белая «птичка» 12x11 по центру выбранного переключателя */
.ppay__pick[aria-checked="true"]::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(12 * var(--u));
  height: calc(11 * var(--u));
  transform: translate(-50%, -50%);
  background: url("/app/assets/icons/ppay-check.svg") no-repeat center / contain;
}

.ppay__pick:active { transform: scale(.9); }

/* Кнопка удаления (25×25 в x=390). */
.ppay__del {
  flex: 0 0 auto;
  width: calc(25 * var(--u));
  height: calc(25 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/ppay-del.png") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.ppay__del:active { transform: scale(.9); }

/* ---------- Сдвиг нижних блоков, когда списки заполнены ----------
   В пустом состоянии «Способы оплаты» на 549, а в заполненном — на 715.
   Разницу задаём модификатором на экране, чтобы не дублировать правила. */
/* Бургер и навигация встают под потоком: высоту его содержимого
   знает только браузер, поэтому её прокидывает JS в --pflow-bottom. */
.screen--profile .profile__burger { top: var(--pflow-bottom, calc(806 * var(--u))); }

@media (hover: hover) {
  .pdev__go:hover,
  .ppay__pick:hover,
  .ppay__del:hover {
    transform: scale(1.1);
    filter: brightness(1.05);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pdev__go,
  .ppay__pick,
  .ppay__del { transition: none; }
}

/* ==================================================================
   Нижняя часть профиля — поток вместо абсолютных координат.
   Раньше каждый блок стоял на своей отметке (426, 549, 671…), и после
   удаления строки на её месте оставалась дыра. Теперь блоки идут друг
   за другом и подтягиваются сами.
   ================================================================== */

.pflow {
  position: absolute;
  left: 0;
  /* Верх — там же, где раньше стоял заголовок «Устройства». */
  top: calc(426 * var(--u));
  width: calc(440 * var(--u));
  display: flex;
  flex-direction: column;
}

/* Заголовки разделов и кнопка справа от них — на одной строке. */
.pflow .prow {
  position: static;
  left: auto;
  top: auto;
  height: calc(14 * var(--u));
  margin: 0 0 calc(14 * var(--u)) calc(30 * var(--u));
}

/* «Профиль» в макете стоит по центру. */
.pflow .prow--profile {
  margin-left: 0;
  justify-content: center;
}

/* Строка заголовка растягивается на всю ширину, чтобы кнопка
   «Добавить» / «Привязать» встала у правого края той же строки. */
.pflow .prow--devices,
.pflow .prow--pay {
  margin-right: calc(25 * var(--u));
}

.pflow .prow--devices .prow__count { margin-right: auto; }
.pflow .prow--pay .prow__label     { margin-right: auto; }

/* Кнопка — обычный элемент строки, а не абсолют. */
.pflow .prow__add {
  position: static;
  left: auto;
  top: auto;
}

/* Списки и пустые плашки — обычные блоки в потоке. */
.pflow .plist {
  position: static;
  left: auto;
  top: auto;
  width: calc(389 * var(--u));
  margin: 0 auto 0 calc(26 * var(--u));
}

.pflow .pempty {
  position: static;
  left: auto;
  top: auto;
  width: calc(400 * var(--u));
  margin-left: calc(21 * var(--u));
}

/* Отступ между разделами: список → следующий заголовок. */
.pflow .plist--devices,
.pflow .pempty--devices { margin-bottom: calc(37 * var(--u)); }

.pflow .plist--pay,
.pflow .pempty--pay { margin-bottom: calc(39 * var(--u)); }

/* Пустой список не должен занимать место и давать лишний отступ. */
.pflow .plist:empty { display: none; }

/* Пара кнопок «Выйти» / «Удалить». */
.pbtns {
  display: flex;
  gap: calc(11 * var(--u));
  margin: calc(11 * var(--u)) 0 0 calc(26 * var(--u));
}

.pflow .pbtn {
  position: static;
  left: auto;
  top: auto;
}

.pflow .profile__copy {
  position: static;
  left: auto;
  top: auto;
  width: calc(259 * var(--u));
  margin: calc(25 * var(--u)) auto 0;
}

/* ==================================================================
   Об устройстве (макет 919:7184)
   Открывается по тапу на устройство: карточка 400x355 в точке 20;416
   поверх затемнения — картинка, название, дата и кнопка с ключом.
   ================================================================== */

/* Затемнение (Rectangle 30188) */
.dev-scrim {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 30;
  transition: opacity .22s ease, visibility .22s ease;
}

.dev-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Карточка (Rectangle 30175, 400x355) */
/* Окно у нижнего края экрана: страница профиля длиннее кадра
   Figma, и привязка по top оставляла панель посередине. */
.dev {
  position: absolute;
  left: 50%;
  bottom: calc(20 * var(--u));
  margin-left: calc(-200 * var(--u));
  width: calc(400 * var(--u));
  height: calc(355 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.dev-scrim.is-open .dev {
  transform: none;
}

/* «Ручка» сверху (Rectangle 30189/30190, 50x6 в 195;429 кадра) */
/* Наклейка «Об устройстве» — над левым верхним углом окна
   (в макете 36;391 при панели 20;416, то есть 16;-25 относительно неё).
   Белая обводка даёт эффект наклеенной бумажки. */
.dev__sticker {
  position: absolute;
  left: calc(16 * var(--u));
  /* Наклейка сильнее заходит на окно, чем в макете. */
  top: calc(-22 * var(--u));
  width: calc(140 * var(--u));
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  line-height: .9;
  letter-spacing: -.02em;
  color: var(--ink);
  -webkit-text-stroke: calc(6 * var(--u)) var(--paper);
  paint-order: stroke fill;
  text-shadow: 0 calc(4 * var(--u)) calc(14 * var(--u)) rgba(0, 0, 0, .14);
  transform: rotate(-8deg);
  pointer-events: none;
}

.dev__grip {
  position: absolute;
  left: calc(175 * var(--u));
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  padding: 0;
  border: calc(.8 * var(--u)) solid transparent;
  border-radius: calc(10 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(rgba(0,0,0,.1), rgba(0,0,0,.1)),
    linear-gradient(180deg, rgba(0,0,0,.05) 0%, rgba(0,0,0,.2) 100%);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0,0,0,.35);
}

/* Картинка устройства в рамке (125x125 в 157;454 кадра) */
.dev__photo {
  position: absolute;
  left: calc(137 * var(--u));
  top: calc(38 * var(--u));
  width: calc(125 * var(--u));
  height: calc(125 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(30 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    url("/app/assets/icons/devadd-photo.png"),
    linear-gradient(180deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,.3) 100%);
  background-repeat: no-repeat;
  background-position: center, center;
  background-size: cover, cover;
  box-shadow: 0 calc(6 * var(--u)) calc(10 * var(--u)) calc(-6 * var(--u)) rgba(9,9,9,.22);
}

/* Новое устройство: заглушка сама несёт рамку, тень и скругление,
   поэтому у бокса своё оформление отключаем. */
.dev.is-adding .dev__photo {
  left: calc(133 * var(--u));
  top: calc(32 * var(--u));
  width: calc(133 * var(--u));
  height: calc(135 * var(--u));
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background-image: url("/app/assets/icons/devadd-blank.svg");
  background-size: contain;
  background-position: center;
}

/* Плитка-заглушка уже стоит у .dev__photo выше — здесь только
   блёклое название: «Новое устройство» — подсказка, а не данные. */
.dev.is-adding .dev__name,
.dev.is-new .dev__name { color: rgba(0, 0, 0, .3); }

/* Стрелки перебора устройств (58x47 в 64;497 и 317;497 кадра) */
/* Круглые кнопки по краям — готовые картинки 60×49 из макета:
   в них уже и фон, и градиентная рамка, и сам значок. */
.dev__nav {
  position: absolute;
  top: calc(81 * var(--u));
  width: calc(60 * var(--u));
  height: calc(49 * var(--u));
  padding: 0;
  border: 0;
  background: no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.dev__nav--prev { left: calc(44 * var(--u)); }
.dev__nav--next { left: calc(297 * var(--u)); }

.dev__nav:active { transform: scale(.94); }

/* Стрелка внутри кнопки */

/* Слева — платформа устройства, справа — удаление (макет 919:7184) */
/* Слева — платформа устройства, справа — корзина удаления. */
/* Значок платформы подставляет JS: он зависит от устройства.
   Apple остаётся запасным — на нём вёрстка и рисовалась. */
.dev__nav--prev { background-image: url("/app/assets/icons/dev-apple.svg"); }
.dev__nav--next { background-image: url("/app/assets/icons/dev-basket.svg"); }

/* Название устройства (189x18 в 125;597 кадра) */
.dev__name {
  position: absolute;
  left: calc(61 * var(--u));
  top: calc(181 * var(--u));
  width: calc(277 * var(--u));
  margin: 0;
  /* Asgard Number 25, как в макете (style_RLLELE). */
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(25 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--ink);
}

/* Дата добавления (141x10 в 150;627 кадра) */
.dev__added {
  position: absolute;
  left: calc(130 * var(--u));
  top: calc(211 * var(--u));
  width: calc(141 * var(--u));
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

/* Кнопка «Скопировать ключ» (362x85 в 38.85;668 кадра) */
/* Кнопка «Скопировать ключ» — готовая картинка 362×85 из макета:
   в ней уже и фон, и надпись, и значок. Текст остаётся в разметке
   для скринридеров, но не рисуется. */
.dev__copy {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(252 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  border: 0;
  background: url("/app/assets/icons/copy.png") no-repeat center / contain;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  font-size: 0;
  color: transparent;
  transition: transform .18s ease;
}

/* Надпись и значок уже на картинке. */
.dev__copy-icon { display: none; }

.dev__copy:active { transform: scale(.99); }

/* Значок ключа справа от подписи */

/* После нажатия кнопка подтверждает копирование */
/* Нажали — кнопка розовеет и пишет «Скопировано».
   Картинку прячем и возвращаем текст: иначе отклика не видно. */
.dev__copy.is-copied {
  background-image: none;
  background-color: #FF2486;
  border-radius: calc(50 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(18 * var(--u));
  line-height: 1;
  color: var(--paper);
  /* Подсказка бывает длиннее «Скопировано» — ужимаем, а не обрезаем. */
  padding: 0 calc(16 * var(--u));
  text-align: center;
}

/* Сообщение без успеха (подсказка/диагностика): текст тоже должен быть
   виден, а у кнопки по умолчанию font-size:0 — надпись зашита в PNG. */
.dev__copy.is-note {
  background-image: none;
  background-color: rgba(0, 0, 0, .08);
  border-radius: calc(50 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 calc(16 * var(--u));
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(15 * var(--u));
  line-height: 1.15;
  text-align: center;
  color: rgba(0, 0, 0, .55);
}

@media (prefers-reduced-motion: reduce) {
  .dev-scrim,
  .dev,
  .dev__nav,
  .dev__copy { transition: none; }
}

/* ==================================================================
   Привязка карты (макет 952:10413). Панель 400 в 20;386.
   Карта сама служит формой: поля лежат поверх подписей.
   ================================================================== */

.bind-scrim {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 10;
  transition: opacity .22s ease, visibility .22s ease;
}

.bind-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

.bind {
  position: absolute;
  left: 50%;
  margin-left: calc(-200 * var(--u));
  bottom: calc(20 * var(--u));
  width: calc(400 * var(--u));
  padding: 0 0 calc(24 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
  /* Стикер выходит за верхний край — обрезать его нельзя. */
  overflow: visible;
}

.bind-scrim.is-open .bind { transform: none; }

/* «Ручка» 50x6 вверху панели. */
.bind__grip {
  display: block;
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  margin: calc(13 * var(--u)) auto 0;
  padding: 0;
  border: 0;
  border-radius: calc(10 * var(--u));
  background: rgba(0, 0, 0, .1);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0, 0, 0, .35);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Заголовка в макете нет — оставляем для скринридеров. */
.bind__title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Стикер «Сделать основным способом» ----------
   Лежит поверх верхнего края окна: звезда в 305.84;321 кадра и подпись
   в 272;357 — считаем от панели (20;386), поэтому уходим в минус по Y. */
.bind__primary {
  position: absolute;
  left: calc(252 * var(--u));
  top: calc(-65 * var(--u));
  z-index: 2;
  width: calc(126 * var(--u));
  height: calc(110 * var(--u));
  padding: 0;
  border: 0;
  background: none;
  /* Наклон тот же, что у стикера в окне готовой карты (.paym__primary). */
  transform: rotate(6deg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.bind__primary:active { transform: rotate(-9deg) scale(.96); }

/* Белая звезда-галочка 41x41 (Star 23 + Star 24 из макета). */
.bind__primary-star {
  position: absolute;
  left: calc(45 * var(--u));
  top: 0;
  width: calc(41 * var(--u));
  height: calc(41 * var(--u));
  background: url("/app/assets/icons/bind-star-empty.svg") no-repeat center / contain;
  filter: drop-shadow(0 calc(1 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .15));
  transition: filter .15s ease;
}

/* Выбранный способ — розовая звезда с галочкой. Белый кант рисуем
   тенями без размытия: по фигурному краю иначе выходит свечение. */
.bind__primary[aria-checked="true"] .bind__primary-star {
  background-image: url("/app/assets/icons/friends-check-star.svg");
  filter:
    drop-shadow(calc(2 * var(--u)) 0 0 #fff)
    drop-shadow(calc(-2 * var(--u)) 0 0 #fff)
    drop-shadow(0 calc(2 * var(--u)) 0 #fff)
    drop-shadow(0 calc(-2 * var(--u)) 0 #fff)
    drop-shadow(0 calc(1 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .15));
}

/* Подпись в три строки, белая обводка отделяет её от фона. */
.bind__primary-text {
  position: absolute;
  left: 0;
  top: calc(36 * var(--u));
  width: 100%;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: .9;
  letter-spacing: -.02em;
  color: var(--ink);
  -webkit-text-stroke: calc(10 * var(--u)) #fff;
  paint-order: stroke fill;
}

/* ---------- Карта 352x149 ---------- */
.bind__card {
  position: relative;
  width: calc(352 * var(--u));
  height: calc(149 * var(--u));
  margin: calc(14 * var(--u)) auto 0;
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(32 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(#fff, #fff),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  box-shadow: 0 calc(9.63 * var(--u)) calc(14 * var(--u)) calc(-28.68 * var(--u)) rgba(66, 66, 66, .15);
}

/* Рамка-прорезь под номер: точки, поле ввода и подпись лежат в ней. */
.bind__slot {
  position: absolute;
  left: calc(10 * var(--u));
  top: calc(13 * var(--u));
  width: calc(333 * var(--u));
  height: calc(68 * var(--u));
  border: calc(1 * var(--u)) solid rgba(0, 0, 0, .08);
  border-radius: calc(22 * var(--u));
}

/* Четыре группы точек — то, что видно, пока номер не введён. */
.bind__digits {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(17 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(15 * var(--u));
  line-height: 1;
  letter-spacing: .1em;
  color: #484848;
  pointer-events: none;
}

/* Золотой чип справа вверху карты. */
.bind__chip {
  position: absolute;
  right: calc(16 * var(--u));
  top: calc(16 * var(--u));
  width: calc(44 * var(--u));
  height: calc(34 * var(--u));
  background: url("/app/assets/icons/card-chip.png") no-repeat center / contain;
}

/* Подпись поля — под значением, приглушённая. */
.bind__caption {
  position: absolute;
  left: 0;
  bottom: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .3);
  pointer-events: none;
}

.bind__caption--number {
  left: calc(20 * var(--u));
  bottom: calc(16 * var(--u));
}

/* CVV и срок: заглушка сверху, подпись снизу, поле поверх. */
.bind__pair {
  position: absolute;
  bottom: calc(18 * var(--u));
  height: calc(34 * var(--u));
}

.bind__pair--cvv    { left: calc(24 * var(--u)); width: calc(70 * var(--u)); }
.bind__pair--expiry { left: calc(110 * var(--u)); width: calc(120 * var(--u)); }

.bind__dots {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(15 * var(--u));
  line-height: 1;
  letter-spacing: .1em;
  color: #484848;
  pointer-events: none;
}

/* Поля ввода прозрачны: значение видно на месте заглушки. */
.bind__input {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  left: 0;
  top: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(15 * var(--u));
  line-height: 1;
  letter-spacing: .1em;
  color: #484848;
  caret-color: #484848;
}

.bind__input:focus { outline: none; }

/* Номер занимает всю ширину прорези над точками. */
.bind__input--number {
  left: calc(20 * var(--u));
  top: calc(14 * var(--u));
  width: calc(230 * var(--u));
  height: calc(20 * var(--u));
}

.bind__input--cvv,
.bind__input--expiry {
  width: 100%;
  height: calc(18 * var(--u));
}

/* Код скрываем точками того же кегля, что и цифры: браузерный password
   рисует их крупнее и ломает строку. */
.bind__input--cvv {
  -webkit-text-security: disc;
  letter-spacing: .12em;
}

/* Пока поле пустое, под ним видно заглушку из точек. */
.bind__input:placeholder-shown { color: transparent; }

/* Кнопка «Скан» в правом нижнем углу карты. */
.bind__scan {
  position: absolute;
  right: calc(14 * var(--u));
  bottom: calc(16 * var(--u));
  height: calc(40 * var(--u));
  padding: 0 calc(13 * var(--u));
  display: flex;
  justify-content: center;
  align-items: center;
  gap: calc(5 * var(--u));
  border: calc(1 * var(--u)) solid transparent;
  border-radius: calc(15 * var(--u));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  /* Белая кнопка с серым отливом от верхнего края и градиентной каймой. */
  background-image:
    radial-gradient(circle at 50% 4%,
      rgba(255, 255, 255, .99) 22%, rgba(226, 226, 226, .95) 42%, rgba(200, 200, 200, .95) 56%),
    linear-gradient(180deg, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .3) 100%);
  box-shadow: 0 calc(9 * var(--u)) calc(6 * var(--u)) calc(-6 * var(--u)) rgba(9, 9, 9, .22);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(18 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.bind__scan:active { transform: scale(.96); }

.bind__scan-icon {
  flex: 0 0 auto;
  width: calc(18 * var(--u));
  height: calc(14 * var(--u));
  background: url("/app/assets/icons/bind-scan.svg") no-repeat center / contain;
}

/* ---------- Другие способы оплаты ---------- */
.bind__ways {
  display: flex;
  justify-content: center;
  gap: calc(10 * var(--u));
  margin: calc(18 * var(--u)) 0 0;
}

/* Кнопка — цельная картинка во всю площадь, как .paym__alt в окне карты. */
.bind__way {
  width: calc(100 * var(--u));
  height: calc(40 * var(--u));
  padding: 0;
  border: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.bind__way:active { transform: scale(.96); }

.bind__way--sbp    { background-image: url("/app/assets/icons/pay-sbp.png"); }
.bind__way--crypto { background-image: url("/app/assets/icons/pay-crypto.png"); }
.bind__way--stars  { background-image: url("/app/assets/icons/pay-stars.png"); }

/* Подпись «Данные шифруются и защищены». */
.bind__note {
  margin: calc(16 * var(--u)) 0 0;
  text-align: center;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  color: rgba(0, 0, 0, .3);
}

/* Чёрная кнопка «Привязать» 362x85. */
.bind__submit {
  display: block;
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  margin: calc(14 * var(--u)) auto 0;
  padding: 0;
  border: 0;
  border-radius: calc(50 * var(--u));
  background: var(--ink);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(26 * var(--u));
  line-height: 1;
  color: var(--paper);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease, opacity .18s ease;
}

.bind__submit:active { transform: scale(.99); }

/* Пока карта не заполнена — кнопка неактивна. */
.bind__submit:disabled {
  opacity: .35;
  cursor: default;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .bind,
  .bind-scrim,
  .bind__scan,
  .bind__way,
  .bind__submit { transition: none; }
}

/* ==================================================================
   Окно способа оплаты (макет 919:8445): открывается по тапу на карту
   ================================================================== */

.paym-scrim {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 30;
  transition: opacity .22s ease, visibility .22s ease;
}

.paym-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Панель 400x405 в 20;366. */
.paym {
  position: absolute;
  left: 50%;
  margin-left: calc(-200 * var(--u));
  bottom: calc(20 * var(--u));
  width: calc(400 * var(--u));
  height: calc(405 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
  /* Стикер выходит за верхний край — обрезать его нельзя. */
  overflow: visible;
}

.paym-scrim.is-open .paym { transform: none; }

/* «Ручка» 50x6 в 194.85;379 кадра -> внутри панели 175;13. */
.paym__grip {
  position: absolute;
  left: calc(175 * var(--u));
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  padding: 0;
  border: 0;
  border-radius: calc(10 * var(--u));
  background: rgba(0, 0, 0, .1);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0, 0, 0, .35);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ---------- Стикер «Сделать основным способом» ----------
   Тот же компонент, что и в окне привязки карты: звезда сверху, подпись
   в три строки под ней. Панели у обоих окон одинаковые (400 шириной,
   прижаты к низу), поэтому координаты совпадают один в один. */
.paym__primary {
  position: absolute;
  left: calc(252 * var(--u));
  top: calc(-65 * var(--u));
  z-index: 2;
  width: calc(126 * var(--u));
  height: calc(110 * var(--u));
  padding: 0;
  border: 0;
  background: none;
  /* Наклон: в выгрузке Figma поворота нет, но габарит группы 104.12x81.01
     с дробными сторонами выдаёт повёрнутый блок — прямой он был бы
     примерно 96x73, лишнее и набегает от наклона. */
  transform: rotate(6deg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.paym__primary:active { transform: rotate(-9deg) scale(.96); }

/* Белая звезда-галочка 41x41 (Star 23 + Star 24 из макета). */
.paym__primary-star {
  position: absolute;
  left: calc(45 * var(--u));
  top: 0;
  width: calc(41 * var(--u));
  height: calc(41 * var(--u));
  background: url("/app/assets/icons/bind-star-empty.svg") no-repeat center / contain;
  filter: drop-shadow(0 calc(1 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .15));
  transition: filter .15s ease;
}

/* Выбранный способ — розовая звезда с галочкой. Белый кант рисуем
   тенями без размытия: по фигурному краю иначе выходит свечение. */
.paym__primary[aria-checked="true"] .paym__primary-star {
  background-image: url("/app/assets/icons/friends-check-star.svg");
  filter:
    drop-shadow(calc(2 * var(--u)) 0 0 #fff)
    drop-shadow(calc(-2 * var(--u)) 0 0 #fff)
    drop-shadow(0 calc(2 * var(--u)) 0 #fff)
    drop-shadow(0 calc(-2 * var(--u)) 0 #fff)
    drop-shadow(0 calc(1 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .15));
}

/* Подпись в три строки, белая обводка отделяет её от фона. */
.paym__primary-text {
  position: absolute;
  left: 0;
  top: calc(36 * var(--u));
  width: 100%;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: .9;
  letter-spacing: -.02em;
  color: var(--ink);
  -webkit-text-stroke: calc(10 * var(--u)) #fff;
  paint-order: stroke fill;
}

/* Карта 352x149 в 44;399 кадра -> внутри панели 24;33. */
.paym__card {
  position: absolute;
  left: calc(24 * var(--u));
  top: calc(33 * var(--u));
}

/* «Или оплатите через»: 124x10 в 158;564 -> 138;198. */
.paym__or {
  position: absolute;
  left: 0;
  top: calc(194 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

/* Ряд кнопок: 40 высотой в 584 -> 218 внутри панели. */
.paym__alts {
  position: absolute;
  left: calc(30 * var(--u));
  top: calc(218 * var(--u));
  width: calc(340 * var(--u));
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.paym__alt {
  flex: 0 0 auto;
  width: calc(105 * var(--u));
  height: calc(40 * var(--u));
  padding: 0;
  border: 0;
  background-repeat: no-repeat;
  background-position: center;
  /* Картинка тянется на всю ширину кнопки, а не вписывается с полями. */
  background-size: 100% 100%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.paym__alt:active { transform: scale(.96); }

.paym__alt--sbp {
  background-image: url("/app/assets/icons/pay-sbp.png");
}

.paym__alt--crypto {
  background-image: url("/app/assets/icons/pay-crypto.png");
}

.paym__alt--stars {
  background-image: url("/app/assets/icons/pay-stars.png");
}

/* «Данные шифруются и защищены»: 211x10 в 115;647 -> 95;281. */
.paym__note {
  position: absolute;
  left: 0;
  top: calc(277 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

/* Кнопка «Привязать»: 362x85 в 38.85;668 -> 18.85;302. */
.paym__submit {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(302 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  border: 0;
  border-radius: calc(50 * var(--u));
  background: #000;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--paper);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s ease;
}

.paym__submit:active { transform: scale(.99); }

@media (prefers-reduced-motion: reduce) {

  .paym-scrim,
  .paym,
  .paym__primary,
  .paym__primary-star,
  .paym__alt,
  .paym__submit {
    transition: none;
  }
}

/* ==================================================================
   Окна-подтверждения профиля: выход, удаление, изменение данных,
   удаление карты и отмена подписки. Действие подтверждается
   слайдером «смахните», а не обычной кнопкой.
   ================================================================== */

/* Затемнение */
.ask-scrim {
  position: fixed;
  left: 50%;
  top: 0;
  width: var(--stage);
  margin-left: calc(var(--stage) / -2);
  height: 100%;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  visibility: hidden;
  z-index: 40;
  transition: opacity .22s ease, visibility .22s ease;
}

/* Удаление карты и профиля — красное свечение снизу (макет 919:9239).
   В макете это отдельный слой 440x876 с градиентом и blur(50px): красный
   копится у нижнего края, за панелью окна, а верх экрана остаётся чистым.
   Поэтому не плоская заливка, а градиент — плоская мыла весь экран. */
.ask-scrim[data-ask="card"],
.ask-scrim[data-ask="device"],
.ask-scrim[data-ask="wipe"],
.ask-scrim[data-ask="logout"],
.ask-scrim[data-ask="cancel"] {
  background:
    linear-gradient(180deg, rgba(255, 30, 30, 0) 0%, rgba(248, 60, 60, .6) 100%),
    rgba(0, 0, 0, .25);
}

.ask-scrim.is-open {
  opacity: 1;
  visibility: visible;
}

/* Панель окна */
.ask {
  position: absolute;
  /* По центру по горизонтали, как .dev: жёсткий left уводил окно влево,
     когда экран шире 440. */
  left: 50%;
  margin-left: calc(-200 * var(--u));
  /* Прижато к низу экрана, как остальные окна (.dev, .bind). */
  bottom: calc(20 * var(--u));
  width: calc(400 * var(--u));
  border-radius: calc(60 * var(--u));
  background: var(--paper);
  transform: translateY(calc(24 * var(--u))) scale(.98);
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.ask-scrim.is-open .ask {
  transform: none;
}

/* Окно с аватаром: выход, удаление профиля, изменение данных */
.ask--user {
  height: calc(492 * var(--u));
}

/* ---------- Окно-подтверждение с аватаром (.ask--confirm) ----------
   Общий вид для выхода из профиля (макет 919:10035) и удаления профиля:
   различаются только подписи, поэтому это один компонент, а тексты
   приходят из разметки и data-done.

   Панель 400x233 в 20;538 на холсте 440x956 — низ в 185 от нижнего края.
   Аватар и наклейка выходят за верхнюю границу, поэтому overflow видимый. */
.ask--confirm {
  height: calc(233 * var(--u));
  overflow: visible;
}

/* Окно с картой и окно отмены подписки */
.ask--card {
  height: calc(300 * var(--u));
}

.ask--device {
  /* Высота под карточку устройства, подсказку в две строки и слайдер:
     на 290 подсказка ложилась прямо на дорожку. */
  height: calc(330 * var(--u));
}

/* Карточка устройства в окне подтверждения: значок, имя и дата —
   тем же порядком, что в списке, чтобы узнавалось с одного взгляда. */
.ask__device {
  position: absolute;
  left: 0;
  /* Заголовок висит над кромкой окна, поэтому карточка начинается сразу
     под верхним краем, как карта в окне удаления способа оплаты. */
  top: calc(30 * var(--u));
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(8 * var(--u));
}

.ask__device-icon {
  width: calc(88 * var(--u));
  height: calc(88 * var(--u));
  border-radius: calc(24 * var(--u));
  background: no-repeat center / contain,
    linear-gradient(180deg, rgba(0, 0, 0, .06) 0%, rgba(0, 0, 0, .12) 100%);
}

.ask__device-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

.ask__device-added {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(13 * var(--u));
  line-height: 1;
  color: rgba(0, 0, 0, .4);
}

/* Подсказка стоит под карточкой, а не на месте из окна отмены. */
.ask--device .ask__hint {
  top: calc(176 * var(--u));
  /* Уже полной ширины: иначе строка «устройство отключится от VPN»
     не переносится там, где задумано. */
  left: calc(40 * var(--u));
  width: calc(320 * var(--u));
}

.ask--cancel {
  height: calc(250 * var(--u));
}

/* «Ручка» сверху — закрывает окно */
.ask__grip {
  position: absolute;
  left: calc(175 * var(--u));
  top: calc(13 * var(--u));
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  padding: 0;
  border: calc(.8 * var(--u)) solid transparent;
  border-radius: calc(10 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image:
    linear-gradient(rgba(0,0,0,.1), rgba(0,0,0,.1)),
    linear-gradient(180deg, rgba(0,0,0,.05) 0%, rgba(0,0,0,.2) 100%);
  box-shadow: 0 calc(4 * var(--u)) calc(6 * var(--u)) calc(-3 * var(--u)) rgba(0,0,0,.35);
}

/* Заголовок окна («Точно удаляем?», «Точно отменяем?») */
.ask__title {
  position: absolute;
  left: 0;
  top: calc(34 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(26 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--ink);
}

/* «Точно удаляем?» и «Точно отменяем?»: в макете это готовые надписи
   серыми буквами, поэтому подставляем их картинками, а текст оставляем
   для скринридеров. Обе сидят над верхней кромкой окна, а не внутри. */
.ask-scrim[data-ask="card"] .ask__title,
.ask-scrim[data-ask="device"] .ask__title,
.ask-scrim[data-ask="cancel"] .ask__title {
  text-indent: -9999px;
  overflow: hidden;
}

/* Надпись удаления — 285x54. */
.ask-scrim[data-ask="card"] .ask__title,
.ask-scrim[data-ask="device"] .ask__title {
  top: calc(-27 * var(--u));
  height: calc(54 * var(--u));
  background: url("/app/assets/icons/sure_delete.png")
    no-repeat center / calc(285 * var(--u)) auto;
}

/* Надпись отмены — 306x49, чуть шире и ниже предыдущей. */
.ask-scrim[data-ask="cancel"] .ask__title {
  top: calc(-24.5 * var(--u));
  height: calc(49 * var(--u));
  background: url("/app/assets/icons/sure_otmena.png")
    no-repeat center / calc(306 * var(--u)) auto;
}

/* Наклейка над окном («Выход из профиля», «Удаление профиля») */
.ask__sticker {
  position: absolute;
  left: 50%;
  top: calc(-14 * var(--u));
  transform: translateX(-50%) rotate(-4deg);
  padding: calc(6 * var(--u)) calc(14 * var(--u));
  border-radius: calc(12 * var(--u));
  background: var(--ink);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.05;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--paper);
  white-space: nowrap;
}

/* Красная плашка — только у старого вида наклейки: в .ask--confirm
   наклейка вообще без подложки. */
.ask:not(.ask--confirm) .ask__sticker--wipe { background: #BF2121; }

/* Наклейка окна-подтверждения (макет 919:10426): не плашка, а чёрный
   текст с белой обводкой 5px — она и отделяет его от фона. Стоит справа
   сверху, наполовину выходя за верхний край панели (297;515 при панели в
   20;538 → 277;-23 от её угла).

   Наклон: в выгрузке Figma поворота нет, но габарит блока 121.02x37.88
   с дробными сторонами выдаёт повёрнутый текст — две строки 16px при
   line-height .9 занимают ~29px, лишняя высота и набегает от наклона. */
.ask--confirm .ask__sticker {
  left: calc(277 * var(--u));
  top: calc(-15 * var(--u));
  width: calc(121 * var(--u));
  padding: 0;
  border-radius: 0;
  background: none;
  transform: rotate(7deg);
  font-size: calc(16 * var(--u));
  line-height: .9;
  color: var(--ink);
  /* Обводка рисуется под заливкой, иначе она съедает тонкие штрихи. */
  -webkit-text-stroke: calc(5 * var(--u)) var(--paper);
  paint-order: stroke fill;
  filter: drop-shadow(0 calc(4 * var(--u)) calc(14 * var(--u)) rgba(0, 0, 0, .14));
}

/* Значок в углу аватара */
.ask__badge {
  position: absolute;
  left: calc(232 * var(--u));
  top: calc(150 * var(--u));
  z-index: 1;
  width: calc(52 * var(--u));
  height: calc(52 * var(--u));
  border-radius: 50%;
  background: var(--paper) no-repeat center / calc(24 * var(--u));
  box-shadow: 0 calc(4 * var(--u)) calc(10 * var(--u)) calc(-4 * var(--u)) rgba(0,0,0,.3);
}

/* В окне выхода значок — пустой кружок с тонкой обводкой в левом верхнем
   углу панели (макет 919:10423, 47x47 в 43;560 → 23;22 от угла панели). */
.ask--confirm .ask__badge {
  left: calc(23 * var(--u));
  top: calc(22 * var(--u));
  width: calc(47 * var(--u));
  height: calc(47 * var(--u));
  background: none no-repeat center;
  border: calc(1 * var(--u)) solid rgba(0, 0, 0, .2);
  box-shadow: none;
}

/* Значки внутри кружка: иконка 22x21, поэтому размер задаём свой.
   Селектор с .ask--confirm — иначе правило выше перебивает фон. */
.ask__badge--exit,
.ask--confirm .ask__badge--exit {
  background-image: url("/app/assets/icons/ask-exit.svg");
  background-size: calc(22 * var(--u)) calc(21 * var(--u));
}

.ask__badge--pen,
.ask--confirm .ask__badge--pen {
  background-image: url("/app/assets/icons/ask-pen.svg");
  background-size: calc(19 * var(--u)) calc(19 * var(--u));
}

/* Удаление профиля — в кружке корзина вместо стрелки выхода (26x28). */
.ask__badge--trash,
.ask--confirm .ask__badge--trash {
  background-image: url("/app/assets/icons/ask-trash.svg");
  background-size: calc(26 * var(--u)) calc(28 * var(--u));
}

/* Аватар пользователя */
.ask__avatar {
  position: absolute;
  left: calc(125 * var(--u));
  top: calc(64 * var(--u));
  width: calc(150 * var(--u));
  height: calc(150 * var(--u));
  /* Сбросы нужны, потому что в окне правки это <button>, а не span:
     иначе браузер добавит свою рамку, фон и padding. */
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .12);
  background-size: cover;
  background-position: center;
  font: inherit;
  -webkit-tap-highlight-color: transparent;
}

/* Кликабельный только в окне правки — там он меняет фото. */
.ask--edit .ask__avatar {
  cursor: pointer;
}

/* Аватар в окне выхода (макет 919:10401): 126x126 в 157;465 — то есть
   137;-73 от угла панели, поэтому он наполовину висит над ней. Белая
   обводка и мягкая тень снизу отделяют его от фона. */
.ask--confirm .ask__avatar {
  left: calc(137 * var(--u));
  top: calc(-73 * var(--u));
  width: calc(126 * var(--u));
  height: calc(126 * var(--u));
  border: calc(.9 * var(--u)) solid rgba(255, 255, 255, .5);
  box-shadow: 0 calc(12 * var(--u)) calc(10 * var(--u)) calc(-8 * var(--u)) rgba(128, 128, 128, .3);
}

/* Белое свечение по краю: в макете это отдельный слой с радиальным
   градиентом поверх фотографии. */
.ask--confirm .ask__avatar::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, 0) 56%, rgba(255, 255, 255, 1) 100%);
  pointer-events: none;
}

/* У окна изменения данных аватар приглушён и размыт под карандаш.
   Размытие даёт backdrop-filter на затемняющем слое, а не filter на
   самом элементе: иначе вместе с фотографией размылись бы и карандаш,
   и белая обводка. */
.ask__avatar--dim::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .35);
  -webkit-backdrop-filter: blur(calc(6 * var(--u)));
  backdrop-filter: blur(calc(2 * var(--u)));
}

.ask__avatar-pen {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 1;
  width: calc(44 * var(--u));
  height: calc(44 * var(--u));
  transform: translate(-50%, -50%);
  background: url("/app/assets/icons/pen.svg") no-repeat center / contain;
  filter: brightness(0) invert(1);
}

/* Имя и ник под аватаром */
.ask__name {
  position: absolute;
  left: 0;
  top: calc(232 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(28 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--ink);
}

.ask__nick {
  position: absolute;
  left: 0;
  top: calc(268 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(16 * var(--u));
  line-height: 1;
  letter-spacing: -.0286em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

/* Имя и ник в окне выхода (макет 919:10399 и 919:10400). Имя набрано
   цифровым начертанием Asgard Number 25px, ник — 14px в 40% чёрного.
   Координаты y считаются от верха панели: 611-538 и 641-538. */
.ask--confirm .ask__name {
  top: calc(73 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(25 * var(--u));
}

.ask--confirm .ask__nick {
  top: calc(103 * var(--u));
  font-size: calc(14 * var(--u));
  color: rgba(0, 0, 0, .4);
}

/* ---------- Окно изменения данных (макет 919:10430) ----------
   Панель ниже остальных окон с аватаром: 400x233 вместо 492.
   Имя и почта — не плашки, а обычный текст по центру, как в макете:
   поля остаются полями (их правят), но выглядят как подписи. */
.ask--edit {
  height: calc(233 * var(--u));
}

.ask__input {
  position: absolute;
  left: 0;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  line-height: 1;
  text-align: center;
  color: rgba(0, 0, 0, .3);
}

.ask__input:focus { outline: none; }
.ask__input::placeholder { color: rgba(0, 0, 0, .3); }

/* Имя: Asgard Number 25px — то же начертание, что и в окне выхода. */
.ask__input--name {
  top: calc(73 * var(--u));
  height: calc(25 * var(--u));
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(25 * var(--u));
  letter-spacing: -.02em;
}

/* Почта: 14px обычным текстовым начертанием. */
.ask__input--mail {
  top: calc(100 * var(--u));
  height: calc(18 * var(--u));
  font-family: var(--font-text);
  font-weight: 400;
  font-size: calc(14 * var(--u));
  letter-spacing: -.0286em;
}

/* Аватар под карандашом приглушён сильнее, чем в окне выхода: в макете
   фотография уходит в тёмно-серый, иначе белый карандаш на ней теряется.
   Белое свечение по краю от .ask--confirm тут лишнее — оно высветляет
   как раз тот край, который должен быть притемнён. */
.ask--edit .ask__avatar::before { content: none; }

.ask--edit .ask__avatar--dim::after {
  background: rgba(0, 0, 0, .45);
}

/* Наклейка «Измените данные» стоит чуть правее и выше, чем в окне
   выхода (306.54;525.84 при панели в 20;538 → 286.54;-12.16). */
.ask--edit .ask__sticker {
  left: calc(280 * var(--u));
  top: calc(-12 * var(--u));
  width: calc(100 * var(--u));
}

/* Кнопка «Готово»: 362x85 в 19;132 от угла панели, чёрная, r50. */
.ask--edit .ask__done {
  position: absolute;
  left: calc(19 * var(--u));
  top: calc(132 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  padding: 0;
  border: none;
  border-radius: calc(50 * var(--u));
  background: #000;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: 1;
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Тексты окна отмены подписки */
.ask__note,
.ask__hint {
  position: absolute;
  left: 0;
  width: 100%;
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
  color: rgba(0, 0, 0, .4);
}

/* Окно отмены на 230px: над слайдером (он начинается со 121) остаётся
   мало места, поэтому строки стоят плотно — «Доступ сохранится до»,
   дата и подсказка укладываются в 12..118. */
.ask__note {
  top: calc(17 * var(--u));
  font-size: calc(16 * var(--u));
}

.ask__date {
  position: absolute;
  left: 0;
  top: calc(41 * var(--u));
  width: 100%;
  margin: 0;
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(34 * var(--u));
  line-height: 1;
  letter-spacing: -.03em;
  text-align: center;
  color: var(--ink);
}

.ask__hint {
  top: calc(87 * var(--u));
  font-size: calc(14 * var(--u));
}

/* Карта, которую удаляем */
.ask__card {
  position: absolute;
  left: calc(25 * var(--u));
  top: calc(25 * var(--u));
  width: calc(312 * var(--u));
  height: calc(141 * var(--u));
}

/* ---------- Слайдер «смахните» ---------- */
.swipe {
  position: absolute;
  /* Тянем шарик — выделять текст при этом не нужно. */
  -webkit-user-select: none;
  user-select: none;
  left: calc(19 * var(--u));
  bottom: calc(24 * var(--u));
  width: calc(362 * var(--u));
  height: calc(85 * var(--u));
  border-radius: calc(50 * var(--u));
  background: rgba(0, 0, 0, .1);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
}

/* Подпись по центру дорожки */
.swipe__label {
  position: absolute;
  left: calc(88 * var(--u));
  top: 50%;
  
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: 1;
  text-align: left;
  color: rgba(0, 0, 0, .2);
  pointer-events: none;
}

/* Значок у правого края — куда тянуть */
.swipe__icon {
  position: absolute;
  right: calc(26 * var(--u));
  top: 50%;
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  transform: translateY(-50%);
  background: no-repeat center / contain;
  opacity: .5;
  pointer-events: none;
}

/* Стрелка после слова «Смахните»: отдельная картинка 20x12 */
.swipe__arrow {
  display: inline-block;
  width: calc(20 * var(--u));
  height: calc(12 * var(--u));
  margin-left: calc(7 * var(--u));
  vertical-align: middle;
  background: url("/app/assets/icons/swipe-arrow.svg") no-repeat center / contain;
}

/* В макете значка справа нет — форму задаёт сама подпись. */
.swipe__icon { display: none; }

.swipe__icon--exit  { background-image: url("/app/assets/icons/profile-exit.svg"); }
.swipe__icon--trash { background-image: url("/app/assets/icons/profile-trash.svg"); }

/* ---------- Промежуточный этап свайпа (макет 919:9637) ----------
   Пока тянут, за шариком тянется красный след, шарик наливается красным,
   а подпись «Смахните» сменяется на «Удаляем...». Прогресс приходит из
   JS переменной --swipe-p (0..1). */

/* След за шариком: в макете это прямоугольник #FF3B30 с blur(40px),
   скруглённый слева. Ширину гоним от прогресса. */
.swipe__trail {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  /* 102px следа в макете при шарике, ушедшем на ~119px: держим след
     чуть короче центра шарика, чтобы край размытия жил под ним. */
  width: calc((8 + 61 + (285 - 8) * var(--swipe-p, 0)) * var(--u));
  border-radius: calc(42 * var(--u)) 0 0 calc(42 * var(--u));
  background: #FF3B30;
  /* Размытие в макете (40px) — на слое поверх фона; у нас след лежит
     внутри дорожки, и такой радиус размазывал его в бледное пятно.
     Берём вдвое меньше: мягкий край остаётся, цвет держится. */
  filter: blur(calc(20 * var(--u)));
  /* Цвет набирается быстрее хода — к середине след уже плотный, как в макете. */
  opacity: calc(var(--swipe-p, 0) * 1.8);
  pointer-events: none;
}

/* Подпись хода: лежит там же, где обычная, и проявляется вместе со следом */
.swipe__progress {
  position: absolute;
  left: calc(88 * var(--u));
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(20 * var(--u));
  line-height: 1;
  text-align: left;
  color: rgba(0, 0, 0, .3);
  opacity: 0;
  pointer-events: none;
}

.swipe__progress::after { content: attr(data-text); }

/* Как только тронули — обычная подпись гаснет, подпись хода проявляется. */
.swipe.is-moving .swipe__label,
.swipe.is-moving .swipe__arrow { opacity: 0; }
.swipe.is-moving .swipe__progress { opacity: 1; }

/* Шарик наливается красным по мере хода (радиальная заливка из макета) */
.swipe.is-moving .swipe__knob::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: calc(var(--swipe-p, 0) * 1.6);
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 59, 48, 0) 0%,
    rgba(255, 59, 48, .3) 63%,
    rgba(255, 59, 48, .6) 100%);
}

/* Свайп доведён до конца: дорожка краснеет и показывает результат.
   Подпись подставляется из data-done, шарик уезжает к правому краю. */
.swipe.is-done {
  background: #FF3B30;
  transition: background .2s ease;
}

.swipe.is-done .swipe__label,
.swipe.is-done .swipe__arrow,
.swipe.is-done .swipe__icon,
.swipe.is-done .swipe__progress,
.swipe.is-done .swipe__trail {
  opacity: 0;
}

/* При промежуточном этапе (is-moving) иконка корзины исчезает */
.swipe.is-moving .swipe__knob {
  background-image: none;
}

/* На финальном этапе красноту даёт сама дорожка — подсветка шарика лишняя. */
.swipe.is-done .swipe__knob::after { opacity: 0; }

.swipe__done {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(21 * var(--u));
  line-height: 1;
  letter-spacing: -.02em;
  text-align: center;
  color: rgba(0, 0, 0, .3);
  opacity: 0;
  transition: opacity .2s ease;
  pointer-events: none;
}

.swipe.is-done .swipe__done { opacity: 1; }

/* Значок в шарике меняется на корзину — действие произошло. */
.swipe.is-done .swipe__knob {
  /* Макет 919:12756: 77x77 в 281;4 от края дорожки. */
  left: calc(281 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  background: #fff url("/app/assets/icons/swipe-done-knob.svg") no-repeat center / calc(71 * var(--u));
  box-shadow:
    inset calc(2.5 * var(--u)) calc(2.5 * var(--u)) calc(6.5 * var(--u)) calc(-2.5 * var(--u)) rgba(255,255,255,.7),
    inset calc(-2.5 * var(--u)) calc(-3.25 * var(--u)) calc(7.5 * var(--u)) calc(-2.5 * var(--u)) #000,
    inset calc(1.25 * var(--u)) calc(1.25 * var(--u)) calc(20 * var(--u)) calc(-2.5 * var(--u)) #fff,
    inset calc(-8 * var(--u)) calc(-9.25 * var(--u)) calc(10 * var(--u)) calc(-2.5 * var(--u)) rgba(0,0,0,.2);
}

/* Шарик, который тянут */
.swipe__knob {
  position: absolute;
  left: calc(8 * var(--u));
  top: calc(8 * var(--u));
  width: calc(69 * var(--u));
  height: calc(69 * var(--u));
  border-radius: 50%;
  background: var(--paper);
  box-shadow:
    0 calc(4 * var(--u)) calc(10 * var(--u)) calc(-4 * var(--u)) rgba(0,0,0,.25),
    0 0 0 calc(1 * var(--u)) rgba(0,0,0,.06);
  cursor: grab;
  transition: left .22s cubic-bezier(.2, .8, .3, 1);
}

/* Пока тянут — за пальцем без задержки */
.swipe.is-dragging .swipe__knob {
  cursor: grabbing;
  transition: none;
}

/* ---------- Слайдер в окне выхода (макет 919:10414) ----------
   Дорожка стоит в 39;670 при панели в 20;538 — 19 от левого края и 16 от
   низа. Шарик крупнее общего: 77x77 в 5;4, со стеклянным набором теней. */
.ask--confirm .swipe {
  bottom: calc(16 * var(--u));
}

/* Цель у правого края (макет 919:11594): гнездо 77x77 в 285;4, внутри
   кольцо 71x71 с градиентной обводкой, а в кольце — значок выхода 38x38.
   Само гнездо без заливки, видно только кольцо. */
.ask--confirm .swipe::after {
  content: "";
  position: absolute;
  left: calc(285 * var(--u));
  top: calc(7 * var(--u));
  width: calc(71 * var(--u));
  height: calc(71 * var(--u));
  border-radius: 50%;
  /* Обводка-градиент снизу вверх: 25% чёрного у низа, 5% у верха.
     Внутри кольца пусто, поэтому градиент даёт не border, а вторая
     заливка в border-box, из которой padding-box вырезает середину. */
  border: calc(1.42 * var(--u)) solid transparent;
  background:
    linear-gradient(0deg, rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, .05) 100%) border-box;
  -webkit-mask:
    linear-gradient(#000 0 0) padding-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) padding-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* Значок выхода внутри кольца (38x38 по центру гнезда 77x77 в 285;4). */
.ask--confirm .swipe__exit {
  position: absolute;
  left: calc(304.5 * var(--u));
  top: calc(23.5 * var(--u));
  width: calc(38 * var(--u));
  height: calc(38 * var(--u));
  background: url("/app/assets/icons/swipe-exit.svg") no-repeat center / contain;
  pointer-events: none;
}

/* В окне удаления профиля на конце дорожки стоит корзина, а не выход.
   Картинка уже содержит кольцо целиком (77x77), поэтому отдельное
   кольцо гасим, а значок растягиваем на всё гнездо. */
.ask-scrim[data-ask="wipe"] .swipe::after { content: none; }

/* Гнездо на конце дорожки в окне удаления карты: кольцо с корзиной
   уже целиком в картинке (77x77 в 285;4). */
.ask-scrim[data-ask="card"] .swipe::after {
  content: "";
  position: absolute;
  left: calc(285 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  background: url("/app/assets/icons/swipe-target-trash.svg") no-repeat center / contain;
  pointer-events: none;
}

.ask-scrim[data-ask="card"] .swipe.is-done::after { content: none; }

/* Гнездо на конце дорожки в окне отмены подписки: кольцо со значком
   выхода целиком в картинке (77x77 в 285;4), как и в окне удаления. */
.ask-scrim[data-ask="cancel"] .swipe::after {
  content: "";
  position: absolute;
  left: calc(285 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  background: url("/app/assets/icons/swipe-target-exit.svg") no-repeat center / contain;
  pointer-events: none;
}

.ask-scrim[data-ask="cancel"] .swipe.is-done::after { content: none; }

.ask-scrim[data-ask="wipe"] .swipe__exit {
  left: calc(285 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  background-image: url("/app/assets/icons/swipe-trash-ring.svg");
}

.ask--confirm .swipe__knob {
  left: calc(5 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  box-shadow:
    0 calc(8.57 * var(--u)) calc(12.24 * var(--u)) calc(-7.34 * var(--u)) rgba(0, 0, 0, .5),
    inset calc(3.06 * var(--u)) calc(3.06 * var(--u)) calc(20.19 * var(--u)) calc(-3.06 * var(--u)) #fff,
    inset calc(-5.51 * var(--u)) calc(-3.98 * var(--u)) calc(14.07 * var(--u)) calc(-3.06 * var(--u)) rgba(0, 0, 0, .2),
    inset calc(1.53 * var(--u)) calc(1.53 * var(--u)) calc(12.24 * var(--u)) calc(-3.06 * var(--u)) #fff,
    inset calc(-4.9 * var(--u)) calc(-3.98 * var(--u)) calc(12.24 * var(--u)) calc(-3.06 * var(--u)) rgba(0, 0, 0, .2);
}

.ask--confirm .swipe__label {
  left: calc(101 * var(--u));
  font-weight: 400;
  letter-spacing: 0;
}

/* В окне удаления профиля подпись длиннее — сдвигаем левее. */
.ask-scrim[data-ask="wipe"] .swipe__label {
  left: calc(93 * var(--u));
}

/* ---------- Конечный кадр (макет 919:10820) ----------
   Свайп доведён: дорожка сплошь красная, шарик доехал до правого края и
   стал прозрачным (в макете у него пустая заливка), по центру — итог в
   две строки. Текст берётся из разметки, поэтому кадр общий для выхода
   и удаления. */
.ask--confirm .swipe.is-done .swipe__knob {
  left: calc(285 * var(--u));
  top: calc(4 * var(--u));
  width: calc(77 * var(--u));
  height: calc(77 * var(--u));
  background: none;
  box-shadow: none;
}

/* Кружок-цель растворяется: его место занял сам шарик. */
.ask--confirm .swipe.is-done::after,
.ask--confirm .swipe.is-done .swipe__exit { opacity: 0; }

/* В конечном кадре значок слева опускается на 15px и заполняется
   (макет 919:11208: 47x47 уже в 43;575, внутри квадрат 31x31). Состояние
   живёт на дорожке, поэтому дотягиваемся до значка через :has() — класса
   на самой панели JS не ставит. */
.ask--confirm:has(.swipe.is-done) .ask__badge {
  top: calc(37 * var(--u));
  transition: top .2s ease;
}

.ask--confirm:has(.swipe.is-done) .ask__badge::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(31 * var(--u));
  height: calc(31 * var(--u));
  border-radius: calc(6 * var(--u));
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, .2);
}

.ask--confirm .swipe__done {
  /* Подпись 149x34 в 107;25 — по центру дорожки, в две строки. */
  font-weight: 400;
  font-size: calc(20 * var(--u));
  line-height: 1.15;
  letter-spacing: 0;
}

/* Только для скринридеров */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .ask-scrim,
  .ask,
  .swipe__knob { transition: none; }
}

/* Лист выбора суммы пополнения (правка 12.10.2026).
   Пополнение переехало в мини-апп из бота, отдельного экрана под него
   в макете нет — показываем лист поверх баланса. Цвета и формы берём
   из существующих контролов: --ink/--paper, скруглённые пилюли. */
.topup-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
}

.topup-sheet__box {
  width: var(--stage);
  max-width: 100%;
  box-sizing: border-box;
  padding: calc(24 * var(--u)) calc(17 * var(--u))
    calc(24 * var(--u) + env(safe-area-inset-bottom, 0px));
  border-radius: calc(32 * var(--u)) calc(32 * var(--u)) 0 0;
  background: var(--paper, #fff);
}

.topup-sheet__title {
  margin: 0 0 calc(18 * var(--u));
  font-family: var(--font-display);
  font-size: calc(22 * var(--u));
  color: var(--ink, #000);
  text-align: center;
}

.topup-sheet__row {
  display: flex;
  flex-wrap: wrap;
  gap: calc(10 * var(--u));
  margin-bottom: calc(14 * var(--u));
}

.topup-sheet__amount {
  flex: 1 1 calc(45%);
  height: calc(64 * var(--u));
  border: 0;
  border-radius: calc(50 * var(--u));
  background: var(--ink, #000);
  color: var(--paper, #fff);
  font-family: var(--font-display);
  font-size: calc(20 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.topup-sheet__cancel {
  width: 100%;
  height: calc(56 * var(--u));
  border: calc(2 * var(--u)) solid var(--ink, #000);
  border-radius: calc(50 * var(--u));
  background: transparent;
  color: var(--ink, #000);
  font-family: var(--font-text);
  font-size: calc(17 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ==================================================================
   Денежная реферальная программа (ТЗ 13.10.2026, п.6.2)
   Отдельного макета нет — собрано в стиле блоков экрана «Друзья»:
   те же шрифты, скругления и подписи под числами.
   ================================================================== */
.money {
  position: absolute;
  z-index: 3;
  left: calc(20 * var(--u));
  top: calc(590 * var(--u));
  width: calc(400 * var(--u));
  padding: calc(18 * var(--u)) calc(20 * var(--u));
  border-radius: calc(32 * var(--u));
  background: var(--paper);
  box-sizing: border-box;
}

.money[hidden],
.friends__faces[hidden] {
  display: none;
}

.money__row {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.money__cell {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: calc(6 * var(--u));
  min-width: 0;
}

/* Числа — тем же шрифтом, что счётчики выше. */
.money__value {
  font-family: var(--font-number);
  font-weight: 400;
  font-size: calc(28 * var(--u));
  line-height: .9;
  letter-spacing: -.03em;
}

.money__note {
  font-size: calc(12 * var(--u));
  opacity: .55;
}

.money__history-open {
  display: block;
  width: 100%;
  margin-top: calc(14 * var(--u));
  padding: calc(6 * var(--u)) 0 0;
  background: none;
  border: 0;
  font-size: calc(13 * var(--u));
  text-decoration: underline;
  text-underline-offset: 3px;
  opacity: .7;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Возврат с выплат на бонусы днями (правка 18.10.2026, Мария: «как
   сделать, чтобы дни начислились?»). Соседствует с «Историей», поэтому
   оформлена так же — ссылкой, а не второй крупной кнопкой: главное
   действие в этом блоке одно, «Вывести». */
.money__to-days {
  display: block;
  width: 100%;
  margin-top: calc(8 * var(--u));
  padding: calc(6 * var(--u)) 0 0;
  background: none;
  border: 0;
  font-size: calc(13 * var(--u));
  text-decoration: underline;
  text-underline-offset: 3px;
  opacity: .7;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.money__to-days:disabled {
  opacity: .35;
  cursor: default;
}

/* Правка 17.10.2026 (Александр): «История плохо открывается».

   Шторка наследовала .whom-scrim — absolute с height 100% от .stage.
   На экране друзей сцена выше окна (список друзей, баланс, история),
   поэтому «низ сцены» оказывался за нижним краем экрана: открытая
   шторка уезжала вниз, и был виден только её заголовок.

   Крепим к окну: fixed + dvh, чтобы учитывалась адресная строка
   мобильного браузера. Ширину ограничиваем холстом — иначе на десктопе
   шторка растянулась бы во весь экран мимо макета. */
.money-scrim {
  position: fixed;
  left: 50%;
  top: 0;
  width: 100%;
  max-width: var(--stage);
  height: 100vh;
  height: 100dvh;
  transform: translateX(-50%);
}

.money-sheet {
  position: absolute;
  left: calc(20 * var(--u));
  right: calc(20 * var(--u));
  bottom: calc(20 * var(--u));
  /* --u считается от ШИРИНЫ холста, поэтому одной величины в --u мало:
     на широком и невысоком окне 620 единиц перерастают экран, и низ
     списка снова обрезается. Берём меньшее из макетной высоты и того,
     что реально осталось в окне за вычетом отступов. */
  max-height: min(calc(620 * var(--u)), calc(100dvh - 40 * var(--u)));
  display: flex;
  flex-direction: column;
  padding: calc(28 * var(--u)) calc(24 * var(--u)) calc(24 * var(--u));
  border-radius: calc(40 * var(--u));
  background: var(--paper);
  box-sizing: border-box;
  transform: translateY(calc(24 * var(--u)));
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}

.money-scrim.is-open .money-sheet {
  transform: none;
}

.money-sheet__close {
  position: absolute;
  top: calc(10 * var(--u));
  left: 50%;
  width: calc(50 * var(--u));
  height: calc(6 * var(--u));
  transform: translateX(-50%);
  border: 0;
  border-radius: 3px;
  background: rgba(0, 0, 0, .2);
  cursor: pointer;
  touch-action: manipulation;
}

.money-sheet__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: calc(22 * var(--u));
}

.money-sheet__total {
  margin: calc(6 * var(--u)) 0 0;
  font-size: calc(13 * var(--u));
  opacity: .6;
}

.money-sheet__body {
  margin-top: calc(6 * var(--u));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.money-sheet__empty {
  margin: calc(18 * var(--u)) 0 0;
  font-size: calc(13 * var(--u));
  opacity: .55;
}

.money-sheet__empty[hidden] {
  display: none;
}

.friends__progress[hidden] {
  display: none;
}

.money__rate {
  margin: calc(14 * var(--u)) 0 0;
  font-size: calc(13 * var(--u));
  opacity: .7;
}

.money__withdraw {
  margin-top: calc(14 * var(--u));
  width: 100%;
  height: calc(48 * var(--u));
  border: 0;
  border-radius: calc(24 * var(--u));
  background: #000;
  color: #fff;
  font-size: calc(15 * var(--u));
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Выводить нечего — кнопка не ведёт в тупик. */
.money__withdraw:disabled {
  opacity: .35;
  cursor: default;
}

.money__history {
  margin-top: calc(18 * var(--u));
}

.money__history-title {
  margin: 0 0 calc(10 * var(--u));
  font-size: calc(13 * var(--u));
  font-weight: 600;
  opacity: .6;
}

.money__history-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--u));
}

.money__history-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: calc(10 * var(--u));
  font-size: calc(13 * var(--u));
}

.money__history-item b {
  font-family: var(--font-number);
  font-weight: 400;
}

.money__history-item span {
  opacity: .5;
}

/* Выплаченное выделяем, отклонённое приглушаем. */
.money__history-item--completed b { color: #1a7f37; }
.money__history-item--rejected { opacity: .45; }

/* ================= Подписка (SubManage / Renew / Extend / Auto) =========
   Макеты этого раздела (артефакт «Burger VPN — mini app», 13.10.2026)
   свёрстаны потоком, а не по координатам: число вариантов продления
   приходит из прайса и заранее не известно. Поэтому экран здесь —
   единственный в мини-аппе, который тянется по содержимому, а шаг сетки
   --u сохраняем, чтобы размеры совпадали с остальными экранами.
   ====================================================================== */
.screen--sub {
  height: auto;
  min-height: calc(var(--h) * var(--u));
  /* Нижний отступ — под полосу «К оплате»: она прибита к низу окна и
     иначе накрыла бы последнюю карточку. */
  padding: calc(22 * var(--u)) calc(22 * var(--u)) calc(140 * var(--u));
}

/* Сцена этого раздела тянется на всю высоту окна, а не на высоту макета.
   Иначе снизу (а из-за центрирования body — и сверху) просвечивал серый
   фон страницы: окно Telegram выше 700px макета. Тот же приём уже
   применён к экранам с нижней панелью, но этот раздел под то правило не
   подходит — панели у него нет. */
.stage:has(.screen--sub) {
  height: auto;
  min-height: 100vh;
  min-height: 100dvh;
}

/* min-height: 100% здесь не работает: у сцены задана не height, а
   min-height, а процент от min-height родителя не считается — экран
   остался бы по содержимому, и снизу просвечивал бы серый фон.
   Поэтому меряем от окна, как сама сцена. */
.stage:has(.screen--sub) .screen--sub {
  min-height: 100vh;
  min-height: 100dvh;
  /* Колонка — чтобы полоса «К оплате» прижималась к низу через
     margin-top: auto. */
  display: flex;
  flex-direction: column;
}

/* ---------- Шапка: кружок «назад» и заголовок ---------- */
.pick-head {
  display: flex;
  align-items: center;
  gap: calc(14 * var(--u));
  margin: calc(16 * var(--u)) 0 calc(18 * var(--u));
}

.pick-head__back {
  width: calc(38 * var(--u));
  height: calc(38 * var(--u));
  border-radius: 50%;
  border: calc(2 * var(--u)) solid rgba(0, 0, 0, .18);
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
  /* Стрелка влево с хвостом — как в макете */
  background:
    no-repeat center / calc(17 * var(--u)) auto
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23595959' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 6l-6 6 6 6'/%3E%3Cpath d='M8 12h12'/%3E%3C/svg%3E");
}

.pick-head__back:active {
  transform: scale(.94);
}

.pick-head__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  /* 22px: «Расширить подписку» — самый длинный заголовок раздела, и на
     440px он должен уместиться в одну строку, как в макете. */
  font-size: calc(22 * var(--u));
  letter-spacing: -.03em;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- Карточка подписки ---------- */
.sub-card {
  padding: calc(18 * var(--u)) calc(20 * var(--u));
  border-radius: calc(24 * var(--u));
  background: #111;
  color: var(--paper);
  display: flex;
  flex-direction: column;
  gap: calc(7 * var(--u));
  box-shadow: 0 calc(10 * var(--u)) calc(24 * var(--u)) calc(-14 * var(--u)) rgba(0, 0, 0, .5);
}

.sub-card__big {
  margin: 0;
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
  flex-wrap: wrap;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(22 * var(--u));
  letter-spacing: -.02em;
}

/* Розовая пилюля с числом устройств */
.sub-card__dev {
  font-family: var(--font-text);
  font-weight: 700;
  font-size: calc(13 * var(--u));
  background: #FF2486;
  color: #000;
  padding: calc(4 * var(--u)) calc(10 * var(--u));
  border-radius: 999px;
  white-space: nowrap;
}

.sub-card__dev:empty {
  display: none;
}

.sub-card__row {
  margin: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: calc(10 * var(--u));
  font-size: calc(14 * var(--u));
  color: rgba(255, 255, 255, .6);
}

.sub-card__row b {
  color: var(--paper);
  font-weight: 700;
}

/* Светлый вариант карточки — блок привязки карты на экране автопродления */
.sub-card--light {
  background: var(--paper);
  color: var(--ink);
  gap: calc(10 * var(--u));
  margin-top: calc(14 * var(--u));
  box-shadow: 0 calc(8 * var(--u)) calc(20 * var(--u)) calc(-14 * var(--u)) rgba(0, 0, 0, .25);
}

.sub-card__t {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(17 * var(--u));
  letter-spacing: -.02em;
}

.sub-card__d {
  margin: 0;
  font-size: calc(14 * var(--u));
  line-height: 1.45;
  opacity: .6;
}

/* ---------- Подпись над группой ---------- */
.sublbl {
  margin: calc(22 * var(--u)) 0 calc(2 * var(--u));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(13 * var(--u));
  letter-spacing: .02em;
  opacity: .45;
}

/* ---------- Строка-действие (SubManage) ---------- */
.act-row {
  display: flex;
  align-items: center;
  gap: calc(14 * var(--u));
  width: 100%;
  padding: calc(15 * var(--u)) calc(16 * var(--u));
  margin-top: calc(10 * var(--u));
  border-radius: calc(24 * var(--u));
  background: var(--paper);
  color: var(--ink);
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
  box-shadow: 0 calc(6 * var(--u)) calc(16 * var(--u)) calc(-12 * var(--u)) rgba(0, 0, 0, .3);
}

.act-row:active {
  transform: scale(.99);
}

/* Строка автопродления на своём экране не кнопка — не жмётся */
.act-row--static:active {
  transform: none;
}

.act-row__ic {
  width: calc(40 * var(--u));
  height: calc(40 * var(--u));
  border-radius: calc(14 * var(--u));
  flex-shrink: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: calc(20 * var(--u)) auto;
}

/* Круговая стрелка — продление */
.act-row__ic--pink {
  background-color: #FF2486;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 12a8 8 0 1 1-2.3-5.7'/%3E%3Cpath d='M20 4v5h-5'/%3E%3C/svg%3E");
}

/* Телефон с плюсом — расширение */
.act-row__ic--purple {
  background-color: #C9B8FF;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='7' y='2.5' width='10' height='19' rx='3'/%3E%3Cpath d='M12 9v6M9 12h6'/%3E%3C/svg%3E");
}

/* Карта — автопродление */
.act-row__ic--mint {
  background-color: #49F9AD;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5.5' width='18' height='13' rx='3'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E");
}

.act-row__text {
  display: flex;
  flex-direction: column;
  gap: calc(3 * var(--u));
  flex: 1;
  min-width: 0;
}

.act-row__t {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(16 * var(--u));
  letter-spacing: -.02em;
}

.act-row__d {
  font-size: calc(13 * var(--u));
  opacity: .5;
  line-height: 1.3;
}

.act-row__chev {
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
  flex-shrink: 0;
  opacity: .3;
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/svg%3E");
}

.act-row__state {
  font-size: calc(13 * var(--u));
  font-weight: 600;
  opacity: .45;
  flex-shrink: 0;
  white-space: nowrap;
}

/* Данные подписки не загрузились: управлять нечем, пока мы не знаем,
   что у человека за подписка. Гасим действия, чтобы нажатие не уводило
   на экран, который посчитает цену от нулей. */
.sub-pane.is-unavailable .act-row {
  opacity: .4;
  pointer-events: none;
}

/* ---------- Вариант выбора (срок продления, способ расширения) ---------- */
.opt-list {
  display: contents;
}

.opt {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: calc(2 * var(--u)) calc(12 * var(--u));
  width: 100%;
  padding: calc(15 * var(--u)) calc(18 * var(--u));
  margin-top: calc(10 * var(--u));
  border-radius: calc(24 * var(--u));
  background: var(--paper);
  color: var(--ink);
  text-align: left;
  border: calc(2 * var(--u)) solid transparent;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
  box-shadow: 0 calc(6 * var(--u)) calc(16 * var(--u)) calc(-12 * var(--u)) rgba(0, 0, 0, .3);
}

.opt:active {
  transform: scale(.99);
}

/* Выбранный вариант обведён чёрным — как в макете SubRenew. */
.opt.is-active {
  border-color: var(--ink);
}

.opt__t {
  grid-column: 1;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(16 * var(--u));
  letter-spacing: -.02em;
}

.opt__d {
  grid-column: 1;
  font-size: calc(13 * var(--u));
  opacity: .5;
  line-height: 1.3;
}

.opt__p {
  grid-column: 2;
  grid-row: 1 / span 2;
  /* Колонкой: цена сверху, плашка со скидкой под ней — как в макете. */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: calc(6 * var(--u));
  font-family: var(--font-number);
  font-weight: 600;
  font-size: calc(19 * var(--u));
  white-space: nowrap;
}

/* Процент скидки — зелёная плашка под ценой (макет SubRenew). */
.opt__p small {
  font-family: var(--font-text);
  font-size: calc(11 * var(--u));
  font-weight: 700;
  color: #000;
  background: #49F9AD;
  padding: calc(3 * var(--u)) calc(9 * var(--u));
  border-radius: 999px;
  line-height: 1.2;
}

/* ---------- Мини-переключатель периода (внутри «С продлением») ---------- */
.mini-period {
  display: flex;
  gap: calc(6 * var(--u));
  margin-top: calc(10 * var(--u));
}

.mini-period button {
  flex: 1;
  min-height: calc(40 * var(--u));
  border-radius: calc(14 * var(--u));
  background: var(--paper);
  font-size: calc(13 * var(--u));
  font-weight: 600;
  border: calc(2 * var(--u)) solid transparent;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
}

/* Выбор здесь тот же, что у .opt — обводим чёрным, а не розовым. */
.mini-period button.is-active {
  border-color: var(--ink);
}

/* ---------- Счётчик устройств ---------- */
.stepper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(10 * var(--u));
  margin-top: calc(10 * var(--u));
  padding: calc(14 * var(--u));
  border-radius: calc(24 * var(--u));
  background: rgba(255, 255, 255, .92);
}

.stepper button {
  flex: 1;
  min-height: calc(48 * var(--u));
  border-radius: calc(16 * var(--u));
  background: linear-gradient(#fafafa, #ececec);
  box-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .12), inset 0 calc(1 * var(--u)) 0 #fff;
  font-size: calc(22 * var(--u));
  font-weight: 500;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
}

.stepper button:disabled {
  opacity: .35;
}

.stepper button:not(:disabled):active {
  transform: scale(.96);
}

.stepper__cnt {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(30 * var(--u));
  letter-spacing: -.03em;
  min-width: calc(86 * var(--u));
  text-align: center;
}

/* ---------- Тумблер автопродления ---------- */
.switch {
  width: calc(52 * var(--u));
  height: calc(32 * var(--u));
  border-radius: 999px;
  background: rgba(0, 0, 0, .14);
  flex-shrink: 0;
  padding: calc(3 * var(--u));
  display: flex;
  /* Правка 17.10.2026 (Мария: «кривоватый переключатель»): кружок сидел
     на 4px ниже середины. Размеры в --u дают дробные пиксели (52x32 при
     padding 3 и кружке 26 — это 3+26+3=32 в теории, но после округления
     выходило 28 на 23+5), и остаток уходил вниз. Выравниваем по центру
     явно: тогда перекос не зависит от округления. */
  align-items: center;
  transition: background .18s ease;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
}

.switch i {
  width: calc(26 * var(--u));
  height: calc(26 * var(--u));
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, .2);
  /* margin-left, а не transform: кружок прижимается флексом
     (см. .switch.is-on i), и анимировать надо именно отступ. */
  transition: margin-left .18s ease;
}

.switch.is-on {
  background: #49F9AD;
}

.switch.is-on i {
  /* Кружок прижимаем к правому краю самим флексом, а не сдвигом на
     вычисленное число. Любая формула промахивается: --u даёт дробные
     пиксели, дорожка округляется до 46px вместо 52, и жёсткий сдвиг в
     20px оставлял 1px справа против 5px слева. С margin-left: auto
     отступы равны при любом округлении (измерено). */
  margin-left: auto;
}

/* Пока ждём ответ сервера — тумблер неактивен */
.switch:disabled {
  opacity: .5;
}

/* ---------- Строка способа оплаты ---------- */
.card-row {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
  padding: calc(15 * var(--u)) calc(18 * var(--u));
  margin-top: calc(10 * var(--u));
  border-radius: calc(22 * var(--u));
  background: var(--paper);
  font-size: calc(14 * var(--u));
  box-shadow: 0 calc(6 * var(--u)) calc(16 * var(--u)) calc(-12 * var(--u)) rgba(0, 0, 0, .3);
}

.card-row__cc {
  width: calc(32 * var(--u));
  height: calc(22 * var(--u));
  border-radius: calc(5 * var(--u));
  background: linear-gradient(135deg, #2b2b2b, #555);
  flex-shrink: 0;
}

.card-row__x {
  margin-left: auto;
  font-size: calc(13 * var(--u));
  font-weight: 600;
  color: #FF2486;
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
}

.card-row--next {
  font-weight: 500;
}

.card-row--next b {
  margin-left: auto;
  font-family: var(--font-number);
  font-weight: 600;
}

/* ---------- Сноска ---------- */
.note {
  margin: calc(16 * var(--u)) 0 0;
  font-size: calc(13 * var(--u));
  line-height: 1.45;
  opacity: .45;
}

.note:empty {
  display: none;
}

/* ---------- Кнопки в карточке привязки ----------
   Своё имя, а не .btn: общий .btn в мини-аппе позиционируется абсолютно
   (left/width от сетки макета), и внутри потоковой карточки он вылезал
   за её края. */
.bind-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: calc(54 * var(--u));
  margin-top: calc(4 * var(--u));
  border-radius: calc(28 * var(--u));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(16 * var(--u));
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
}

.bind-btn:active {
  transform: scale(.99);
}

.bind-btn--pink {
  background: #FF2486;
  color: #000;
}

.bind-btn--white {
  background: var(--paper);
  font-family: var(--font-text);
  font-weight: 600;
  font-size: calc(15 * var(--u));
}

/* ---------- Полоса «К оплате» ---------- */
/* Правка 16.10.2026 (Евгений, скриншот «сделай отступ»): полоса «К
   оплате» прижата к низу через margin-top:auto, а auto — это ОСТАТОК
   места. Пока список короткий, зазор большой; когда контент дорастает
   до низа, остатка не остаётся и карточка упирается в кнопку.

   Отступ даём панели: он не съедается, как auto, и держится при любой
   длине списка. На самой полосе это не сделать — margin-top занят
   (auto нельзя положить в max(), правило отбрасывается целиком), а
   padding-top перебивается короткой записью padding ниже и раздул бы
   высоту кнопки. */
.sub-pane {
  margin-bottom: calc(18 * var(--u));
}

.paybar {
  /* Прижата к низу экрана: margin-top:auto в flex-колонке. Так полоса
     стоит внизу и при коротком списке, и при длинном (sticky без
     скролла не прилипал и повисал посреди экрана), и при этом остаётся
     внутри сцены шириной 440 — fixed уводил её за край на десктопе. */
  margin-top: auto;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(12 * var(--u));
  width: 100%;
  height: calc(78 * var(--u));
  padding: 0 calc(12 * var(--u)) 0 calc(28 * var(--u));
  border-radius: 999px;
  background: #111;
  color: var(--paper);
  -webkit-tap-highlight-color: transparent;
  /* Без этого Safari принимает быстрые повторные тапы за
     двойной и зумит страницу — особенно заметно на «+»/«−». */
  touch-action: manipulation;
  box-shadow: 0 calc(16 * var(--u)) calc(30 * var(--u)) calc(-18 * var(--u)) rgba(0, 0, 0, .55);
}

.paybar:active {
  transform: scale(.99);
}

.paybar__k {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: calc(22 * var(--u));
  letter-spacing: -.03em;
}

.paybar__sum {
  min-width: calc(130 * var(--u));
  height: calc(54 * var(--u));
  padding: 0 calc(18 * var(--u));
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #FF2486;
  color: #000;
  font-family: var(--font-number);
  font-weight: 600;
  font-size: calc(21 * var(--u));
}

/* ================= Мои устройства (макет Active) =======================
   Главный экран после покупки и единственный вход в управление:
   «Управлять подпиской», «Докупить трафик», «Получить конфиг» живут в
   меню устройства, а не на плитках главной.

   Экран потоковый, как раздел подписки: число устройств заранее не
   известно, по координатам макета его не разложить.
   ====================================================================== */
.screen--devices {
  height: auto;
  min-height: 100vh;
  min-height: 100dvh;
  /* Боковые поля и верх — свои; низ отдельной строкой, чтобы его не
     перебивало общее правило .stage:has(.tabbar) .screen и чтобы под
     нижней панелью оставался запас: иначе она накрывает «Добавить
     устройство». */
  padding: calc(18 * var(--u)) calc(22 * var(--u)) 0;
  padding-bottom: calc(170 * var(--u));
}

.stage:has(.screen--devices) {
  height: auto;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---------- Шапка с логотипом ---------- */
.dev-top {
  display: flex;
  justify-content: center;
  align-items: center;
  height: calc(40 * var(--u));
}

.dev-top__mark {
  display: flex;
  align-items: center;
  gap: calc(6 * var(--u));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(15 * var(--u));
  letter-spacing: -.02em;
}

.dev-top__tag {
  background: var(--ink);
  color: var(--paper);
  font-size: calc(9 * var(--u));
  letter-spacing: .04em;
  padding: calc(3 * var(--u)) calc(6 * var(--u));
  border-radius: calc(6 * var(--u));
}

/* ---------- Подпись раздела: слева название, справа значение ---------- */
.dev-sec {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: calc(10 * var(--u));
  margin: calc(22 * var(--u)) 0 calc(10 * var(--u));
}

.dev-sec__k {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(17 * var(--u));
  letter-spacing: -.02em;
}

.dev-sec__v {
  font-size: calc(13 * var(--u));
  opacity: .5;
}

.dev-sec__v--mint {
  background: #49F9AD;
  color: #000;
  opacity: 1;
  font-weight: 700;
  padding: calc(3 * var(--u)) calc(9 * var(--u));
  border-radius: 999px;
}

/* ---------- Карточка устройства ---------- */
.dev-card {
  background: #111;
  color: var(--paper);
  border-radius: calc(26 * var(--u));
  padding: calc(18 * var(--u));
  margin-bottom: calc(12 * var(--u));
  box-shadow: 0 calc(10 * var(--u)) calc(24 * var(--u)) calc(-14 * var(--u)) rgba(0, 0, 0, .5);
}

.dev-card__head {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

/* Иконка платформы: своей картинки под каждую ОС нет, рисуем силуэт
   телефона — он подходит и телефону, и планшету, и десктопу. */
.dev-card__ic {
  width: calc(36 * var(--u));
  height: calc(36 * var(--u));
  border-radius: calc(12 * var(--u));
  background: rgba(255, 255, 255, .12) no-repeat center / calc(18 * var(--u)) auto;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Crect x='7' y='2.5' width='10' height='19' rx='3'/%3E%3Cpath d='M11 18.5h2'/%3E%3C/svg%3E");
}

.dev-card__name {
  flex: 1;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(16 * var(--u));
  letter-spacing: -.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dev-card__name i {
  font-style: normal;
  opacity: .45;
}

/* Плашка тарифа */
.dev-card__chip {
  background: #FF2486;
  color: #000;
  font-size: calc(11 * var(--u));
  font-weight: 700;
  padding: calc(4 * var(--u)) calc(9 * var(--u));
  border-radius: 999px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ---------- Факты: срок и автопродление ---------- */
.dev-card__facts {
  display: flex;
  flex-direction: column;
  gap: calc(5 * var(--u));
  margin-top: calc(14 * var(--u));
  font-size: calc(13 * var(--u));
  color: rgba(255, 255, 255, .6);
}

.dev-card__facts span {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

/* Точка-маркер перед строкой */
.dev-card__facts span::before {
  content: "";
  width: calc(5 * var(--u));
  height: calc(5 * var(--u));
  border-radius: 50%;
  background: #49F9AD;
  flex-shrink: 0;
}

/* ---------- Трафик ---------- */
.dev-card__meter {
  margin-top: calc(16 * var(--u));
}

.dev-card__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: calc(10 * var(--u));
  font-size: calc(12 * var(--u));
  color: rgba(255, 255, 255, .55);
  margin-bottom: calc(6 * var(--u));
}

.dev-card__row b {
  color: var(--paper);
  font-family: var(--font-number);
  font-weight: 600;
}

.dev-card__row--second {
  margin-top: calc(14 * var(--u));
}

.dev-card__unl {
  color: #49F9AD !important;
}

.dev-card__bar {
  height: calc(8 * var(--u));
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  overflow: hidden;
}

.dev-card__bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #FFD9E8, #B9C6FF);
}

/* Безлимитная полоса залита целиком — ограничения нет. */
.dev-card__bar--unl i {
  width: 100%;
  background: linear-gradient(90deg, #49F9AD, #8BFFD0);
  opacity: .55;
}

/* ---------- Кнопка раскрытия меню ---------- */
.dev-card__toggle {
  width: 100%;
  margin-top: calc(16 * var(--u));
  padding: calc(10 * var(--u));
  border-radius: calc(16 * var(--u));
  background: rgba(255, 255, 255, .1);
  color: var(--paper);
  font-size: calc(13 * var(--u));
  font-weight: 600;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dev-card__toggle:active {
  transform: scale(.99);
}

/* ---------- Меню устройства ---------- */
.dev-menu {
  margin-top: calc(14 * var(--u));
  padding-top: calc(14 * var(--u));
  border-top: 1px solid rgba(255, 255, 255, .12);
}

.dev-menu__id {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: calc(10 * var(--u));
  font-size: calc(12 * var(--u));
  color: rgba(255, 255, 255, .5);
  margin-bottom: calc(12 * var(--u));
}

.dev-menu__id b {
  color: rgba(255, 255, 255, .8);
  font-family: var(--font-number);
  font-weight: 600;
}

/* Главное действие — розовая кнопка на всю ширину */
.dev-menu__main {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: calc(52 * var(--u));
  border-radius: calc(26 * var(--u));
  background: #FF2486;
  color: #000;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(15 * var(--u));
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dev-menu__main:active {
  transform: scale(.99);
}

.dev-menu__howto {
  display: block;
  width: 100%;
  margin-top: calc(8 * var(--u));
  padding: calc(6 * var(--u)) 0;
  background: none;
  border: 0;
  color: rgba(255, 255, 255, .7);
  font-family: var(--font-display);
  font-size: calc(13 * var(--u));
  text-decoration: underline;
  text-underline-offset: 3px;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dev-menu__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(8 * var(--u));
  margin-top: calc(8 * var(--u));
}

.dev-menu__btn {
  min-height: calc(46 * var(--u));
  border-radius: calc(16 * var(--u));
  background: rgba(255, 255, 255, .1);
  color: var(--paper);
  font-size: calc(13 * var(--u));
  font-weight: 600;
  padding: 0 calc(8 * var(--u));
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dev-menu__btn:active {
  transform: scale(.98);
}

/* «Удалить устройство» — по макету Active отличается от соседей.
   Красим текст, а не фон: кнопка остаётся в одном ряду с остальными,
   но действие читается как необратимое. */
.dev-menu__btn--danger {
  color: #FF6B8A;
}

/* ---------- Пусто ---------- */
.dev-empty {
  margin: calc(10 * var(--u)) 0 0;
  padding: calc(18 * var(--u));
  border-radius: calc(22 * var(--u));
  background: var(--paper);
  font-size: calc(14 * var(--u));
  line-height: 1.45;
  opacity: .7;
}

/* ---------- Добавить устройство ---------- */
.dev-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(10 * var(--u));
  width: 100%;
  min-height: calc(58 * var(--u));
  border-radius: calc(26 * var(--u));
  background: var(--paper);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(15 * var(--u));
  box-shadow: 0 calc(8 * var(--u)) calc(20 * var(--u)) calc(-14 * var(--u)) rgba(0, 0, 0, .3);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dev-add:active {
  transform: scale(.99);
}

.dev-add__plus {
  width: calc(22 * var(--u));
  height: calc(22 * var(--u));
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 8v8M8 12h8'/%3E%3C/svg%3E");
}

/* ================= Подтверждение пробного периода =====================
   Макет TrialConfirm. Оплаты нет, поэтому окно заказа не подходит:
   вместо суммы и способов — два условия и одна кнопка.
   ====================================================================== */
.ask--trial {
  padding: calc(30 * var(--u)) calc(24 * var(--u)) calc(26 * var(--u));
}

/* Общий .ask__title позиционирован абсолютно — он рассчитан на окно, где
   содержимое тоже разложено по координатам. Здесь содержимое потоковое,
   и абсолютный заголовок наезжал на текст условий. */
.ask--trial .ask__title {
  position: static;
  text-align: left;
  font-size: calc(24 * var(--u));
  line-height: 1.15;
}

/* Зелёная надпись над заголовком — акцент «бесплатно». */
.trial__eyebrow {
  margin: 0 0 calc(8 * var(--u));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(12 * var(--u));
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #12a36a;
}

.trial__facts {
  list-style: none;
  margin: calc(18 * var(--u)) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: calc(12 * var(--u));
}

.trial__fact {
  position: relative;
  padding-left: calc(34 * var(--u));
  font-size: calc(14 * var(--u));
  line-height: 1.45;
  opacity: .75;
}

/* Кружок со значком перед строкой */
.trial__fact::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(1 * var(--u));
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  border-radius: 50%;
  background: #49F9AD no-repeat center / calc(13 * var(--u)) auto;
}

/* Восклицательный знак — ограничения пробного периода */
.trial__fact--info::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M12 7v6'/%3E%3Cpath d='M12 17h.01'/%3E%3C/svg%3E");
}

/* Галочка — условие «один раз» */
.trial__fact--ok::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M5 12l5 5 9-10'/%3E%3C/svg%3E");
}

.trial__actions {
  display: flex;
  gap: calc(10 * var(--u));
  margin-top: calc(22 * var(--u));
}

.trial__back {
  flex: 0 0 calc(110 * var(--u));
  min-height: calc(54 * var(--u));
  border-radius: calc(28 * var(--u));
  background: #f1f1f1;
  font-size: calc(15 * var(--u));
  font-weight: 600;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Зелёная кнопка: в макете активация подчёркнуто «бесплатная», поэтому
   мятная, а не розовая как платные действия. */
.trial__go {
  flex: 1;
  min-height: calc(54 * var(--u));
  border-radius: calc(28 * var(--u));
  background: #49F9AD;
  color: #000;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(16 * var(--u));
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.trial__back:active,
.trial__go:active {
  transform: scale(.99);
}

.trial__go:disabled {
  opacity: .6;
}

/* ================= Экран входа =========================================
   Правка 15.10.2026 (Мария): «что я должна сюда ввести, я не понимаю».

   Здесь была форма «Имя / Почта / Пароль» с кнопкой «Создать профиль» —
   копия регистрации. Для входа она не годилась: имя не нужно, пароль
   нигде не хранится (ни в API, ни в модели), а кнопка отправляла на
   /api/register, то есть «Войти» регистрировало заново.

   Вместо полей — объяснение и кнопка Telegram. Экран позиционируется по
   координатам макета, поэтому блоку задаём место явно.
   ====================================================================== */
.login-note {
  position: absolute;
  left: calc(26 * var(--u));
  /* Под переключателем: он на 85 и высотой 46. */
  top: calc(160 * var(--u));
  width: calc(388 * var(--u));
  text-align: center;
}

.login-note__title {
  margin: 0 0 calc(14 * var(--u));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(26 * var(--u));
  letter-spacing: -.02em;
  line-height: 1.1;
}

.login-note__text {
  margin: 0 0 calc(12 * var(--u));
  font-size: calc(15 * var(--u));
  line-height: 1.45;
  opacity: .75;
}

.login-note__text--dim {
  opacity: .5;
}

/* Кнопка Telegram здесь — главное действие, а не запасной путь, как на
   регистрации: поднимаем её ближе к тексту. Позиционируем внутренний
   .tg; обёртке tg-button position: absolute задавать нельзя — она
   тогда перестаёт показывать кнопку. */
/* Правка 17.10.2026: выше стояла форма входа по почте, поэтому кнопка
   опустилась под неё. Это теперь второй путь, а не главный. */
.screen--login .tg {
  top: calc(470 * var(--u));
}

.login-note__error {
  position: absolute;
  left: calc(26 * var(--u));
  /* Под кнопкой Telegram (470 + её высота): выше она перекрывала текст. */
  top: calc(560 * var(--u));
  width: calc(388 * var(--u));
  text-align: center;
}

/* ---------- Вход по почте (правка 17.10.2026) ---------- */
/* Шаги занимают одно место: поле почты скрывается, поле кода встаёт на
   его координату — экран не прыгает при переходе к коду. */
.screen--login .field--email,
.screen--login .field--code {
  top: calc(160 * var(--u));
}

/* Код набирают цифрами и сверяют с письмом по одной: разрядка и центр
   делают это читаемым, моноширинный шрифт не даёт строке дёргаться. */
.field--code .field__input {
  text-align: center;
  font-family: var(--font-display), ui-monospace, monospace;
  font-size: calc(22 * var(--u));
  letter-spacing: calc(6 * var(--u));
}

/* Куда ушло письмо. Под полем, чтобы опечатка в адресе бросалась в глаза
   до того, как человек начнёт искать несуществующее письмо. */
.code-sent {
  position: absolute;
  left: calc(26 * var(--u));
  top: calc(236 * var(--u));
  width: calc(388 * var(--u));
  margin: 0;
  font-family: var(--font-text);
  font-size: calc(14 * var(--u));
  line-height: 1.35;
  text-align: center;
  opacity: .6;
  /* Длинный адрес не должен ломать раскладку */
  overflow-wrap: anywhere;
}

/* Кнопка отправки стоит ниже подписи «код отправлен на …» */
.screen--login .submit {
  top: calc(292 * var(--u));
}

.screen--login .consent {
  top: calc(400 * var(--u));
}

/* Запасные действия: выслать ещё раз и сменить почту. Ссылками, а не
   кнопками: главное действие на экране одно, и это отправка кода. */
.code-actions {
  position: absolute;
  left: calc(26 * var(--u));
  top: calc(400 * var(--u));
  width: calc(388 * var(--u));
  display: flex;
  justify-content: center;
  gap: calc(24 * var(--u));
}

.code-actions__btn {
  padding: calc(6 * var(--u)) 0;
  border: 0;
  background: none;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: calc(15 * var(--u));
  color: inherit;
  text-decoration: underline;
  text-underline-offset: calc(3 * var(--u));
  opacity: .6;
  cursor: pointer;
  transition: opacity .2s ease;
}

.code-actions__btn:hover {
  opacity: .9;
}

/* ---------- Сайт вне Telegram: вход и «3 дня бесплатно» ---------- */
/* Макет — холст 440×1000 в единицах --u. На сайте аватарки нет, а вместо пароля и
   имени — блок «3 дня бесплатно», поэтому всё стоит на своих местах, как у .screen--login. */
.screen--web .avatar {
  display: none;
}

.screen--web .field--email {
  top: calc(160 * var(--u));
}

.web-extra,
.web-tg {
  position: absolute;
  z-index: 1;
  left: calc(44 * var(--u));
  width: calc(352 * var(--u));
  margin: 0;
  text-align: center;
}

.web-extra {
  top: calc(246 * var(--u));
}

.screen--web:not(.screen--login) .submit {
  top: calc(520 * var(--u));
}

.screen--web:not(.screen--login) .consent {
  top: calc(630 * var(--u));
}

.screen--web.screen--login .submit {
  top: calc(250 * var(--u));
}

.screen--web.screen--login .web-tg {
  top: calc(370 * var(--u));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(12 * var(--u));
}

.web-extra__title {
  margin: 0;
  font-size: calc(20 * var(--u));
  font-weight: 700;
}

.web-extra__text,
.web-tg__hint {
  margin: calc(4 * var(--u)) 0 0;
  font-size: calc(14 * var(--u));
  line-height: 1.35;
  opacity: 0.6;
}

.web-extra__methods {
  display: flex;
  gap: calc(8 * var(--u));
  margin-top: calc(12 * var(--u));
}

.web-extra__methods button {
  flex: 1;
  height: calc(44 * var(--u));
  border-radius: calc(14 * var(--u));
  background: rgba(0, 0, 0, 0.08);
  font-size: calc(16 * var(--u));
  font-weight: 600;
}

.web-extra__methods button[aria-checked="true"] {
  background: #000;
  color: #fff;
}

.web-extra__consent {
  display: flex;
  align-items: flex-start;
  gap: calc(8 * var(--u));
  margin-top: calc(12 * var(--u));
  font-size: calc(13 * var(--u));
  line-height: 1.35;
  text-align: left;
}

.web-extra__consent[hidden] {
  display: none;
}

.web-extra__consent input {
  flex: none;
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
  margin-top: 1px;
}

.money__row .money__withdraw {
  flex: none;
  width: auto;
  margin-top: 0;
  padding: 0 calc(26 * var(--u));
}


/* Правка 16.10.2026 (Евгений): «закомментируй полностью вход/регистрацию,
   они не нужны, все данные из тг берутся». Внутри Telegram личность
   подтверждает подпись initData, имя и username приходят оттуда же —
   форма с почтой и паролем не нужна. Кнопки остаются для сайта
   (.is-browser), где Telegram нет и войти больше нечем. */
.is-telegram .actions {
  display: none;
}

/* «Привязать Telegram» в профиле сайта: отдельная широкая кнопка над «Выйти / Удалить» */
.pbtns--link[hidden] {
  display: none;
}

.pbtn--link {
  width: calc(388 * var(--u));
  color: rgba(0, 0, 0, 0.75);
}
