/* TapVilla — общая база для трёх вариантов.
   Значения перенесены один-в-один из прототипов design_handoff_tapvilla/design/TapVilla-v*.dc.html
   Важно: НЕ ставить глобальный box-sizing:border-box — прототип считает падинги по content-box. */

html, body {
  margin: 0; padding: 0; background: #ededee; -webkit-tap-highlight-color: transparent;
  /* Запрет приближения: manipulation убирает зум двойным тапом и задержку клика 300мс,
     text-size-adjust — автоувеличение шрифтов. Щипок двумя пальцами гасит js/nozoom.js. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  overscroll-behavior: none;   /* без «оттягивания» страницы и pull-to-refresh */
}
* { -webkit-user-select: none; user-select: none; }
a { color: #6f86e8; text-decoration: none; }
a:hover { color: #93a6f2; }

/* ---------- keyframes ---------- */
@keyframes floatUp-v1 {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(.8); }
  100% { opacity: 0; transform: translate(-50%, -190%) scale(1.15); }
}
@keyframes floatUp-v2 {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(.7); }
  18%  { transform: translate(-50%, -75%) scale(1.12); }
  100% { opacity: 0; transform: translate(-50%, -215%) scale(1); }
}
@keyframes floatUp-v3 {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(.7); }
  18%  { transform: translate(-50%, -78%) scale(1.14); }
  100% { opacity: 0; transform: translate(-50%, -220%) scale(1); }
}
@keyframes spark-v2 {
  0%   { opacity: .95; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.35); }
}
@keyframes spark-v3 {
  0%   { opacity: .95; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.3); }
}
@keyframes ringPulse-v1 {
  0%, 100% { box-shadow: 0 0 44px rgba(70,96,220,.35), inset 0 0 60px rgba(0,0,0,.55); }
  50%      { box-shadow: 0 0 74px rgba(70,96,220,.55), inset 0 0 60px rgba(0,0,0,.55); }
}
@keyframes ringPulse {
  0%, 100% { box-shadow: 0 0 40px rgba(70,96,220,.32); }
  50%      { box-shadow: 0 0 78px rgba(70,96,220,.55); }
}
@keyframes goldPulse {
  0%, 100% { box-shadow: 0 0 34px rgba(240,180,41,.55); }
  50%      { box-shadow: 0 0 90px rgba(240,180,41,.95); }
}
@keyframes toastIn {
  0%   { opacity: 0; transform: translate(-50%, -18px) scale(.94); }
  12%  { opacity: 1; transform: translate(-50%, 0) scale(1); }
  82%  { opacity: 1; transform: translate(-50%, 0) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -14px) scale(.97); }
}
@keyframes shakeX {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(-2px, 1px); }
  50%      { transform: translate(2px, -1px); }
  75%      { transform: translate(-1px, -2px); }
}
@keyframes fall {
  0%   { top: -8%;  opacity: 1;  transform: rotate(0deg); }
  100% { top: 108%; opacity: .2; transform: rotate(260deg); }
}
@keyframes popIn {
  0%   { transform: translate(-50%, -50%) scale(.2);  opacity: 0; }
  55%  { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1);   opacity: 1; }
}
@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}

/* ---------- каркас ---------- */
.page {
  min-height: 100vh; min-height: 100dvh;
  display: flex; align-items: flex-start; justify-content: center;
  background: #ededee; font-family: Manrope, Helvetica, sans-serif;
}
/* На телефоне рамка занимает весь экран, на десктопе — 440×980 как в прототипе. */
.shell {
  width: min(100vw, 440px);
  height: min(100dvh, 980px);
  background: #17171a; position: relative; overflow: hidden;
  display: flex; flex-direction: column;
}

/* ---------- шапка ---------- */
.hdr {
  background: #08080a; padding: 14px 16px 16px;
  /* В полноэкранном режиме (с домашнего экрана) шапка уходит под чёлку —
     добавляем безопасную зону. В обычном браузере env() = 0, вид не меняется. */
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
  border-radius: 0 0 26px 26px; border-bottom: 2px solid #f0b429;
  box-shadow: 0 10px 40px rgba(240,180,41,.22);
  position: relative; z-index: 3;
}
.hdr-row { display: flex; align-items: center; gap: 12px; }
.rank { flex: 0 0 132px; display: flex; flex-direction: column; gap: 7px; }
.rank-top { display: flex; align-items: baseline; justify-content: space-between; gap: 4px; }
.rank-name { display: flex; align-items: center; gap: 4px; color: #fff; font-size: 15px; font-weight: 700; min-width: 0; }
/* «4 / 10» и длинные ранги («GrandMaster») не должны переносить строку —
   на 320px это ломало высоту шапки */
.rank-name > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chev { color: #6d6d76; font-size: 13px; flex: 0 0 auto; }
.rank-label { color: #fff; font-size: 13px; font-weight: 700; white-space: nowrap; flex: 0 0 auto; }
.rank-bar { height: 6px; border-radius: 99px; background: #24242a; overflow: hidden; }
.rank-fill { height: 100%; border-radius: 99px; background: linear-gradient(90deg, #8b8ffb, #5b62e8); }
.v2 .rank-fill, .v3 .rank-fill { transition: width .4s ease; }

.profit { flex: 1; display: flex; align-items: center; gap: 10px; background: #1e1e23; border: 1px solid #2c2c33; border-radius: 16px; padding: 6px 8px; }
.profit-logo { width: 34px; height: 34px; flex: 0 0 34px; border-radius: 9px; background: #2b57d6; display: grid; place-items: center; color: #fff; font-size: 17px; font-weight: 800; }
.vsep { width: 1px; height: 26px; background: #34343c; }
.profit-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.profit-cap { color: #8b8b95; font-size: 10px; letter-spacing: .2px; }
.profit-row { display: flex; align-items: center; gap: 5px; }
.coin-sm { width: 15px; height: 15px; border-radius: 50%; background: radial-gradient(circle at 34% 28%, #ffe28a, #e5a51b 68%, #b9780c); border: 1px solid #f7cd5d; }
.v1 .coin-sm { background: radial-gradient(circle at 34% 28%, #ffe28a, #e5a51c 68%, #b9780c); }
.profit-val { color: #fff; font-size: 15px; font-weight: 800; }
.info-dot { width: 15px; height: 15px; border-radius: 50%; background: #313139; color: #a9a9b3; font-size: 10px; font-weight: 800; display: grid; place-items: center; }
.gear { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 12px; background: #1e1e23; border: 1px solid #2c2c33; display: grid; place-items: center; color: #c9c9d2; font-size: 19px; cursor: pointer; }
.gear:hover { background: #26262d; }

/* Вторая правка против прототипа. Шапка там набрана из жёстких величин
   (16 + 132 + 12 + пилюля 162 + 12 + 40 + 16) и требует ровно 392px, поэтому на экране
   360px шестерёнка уезжала за край — замерено и на прототипе, и у нас: правый край
   кнопки 376.1 при ширине рамки 360. Прототип рисовался под 440px, а это версия для
   телефона, поэтому ниже 392px поджимаем отступы и блок ранга. Пропорции и кегли те же. */
@media (max-width: 391px) {
  .hdr { padding-left: 10px; padding-right: 10px; }
  .hdr-row { gap: 8px; }
  .rank { flex: 0 0 118px; min-width: 0; }
}
@media (max-width: 344px) {
  .hdr { padding-left: 8px; padding-right: 8px; }
  .hdr-row { gap: 6px; }
  .rank { flex: 0 0 92px; min-width: 0; }
  .profit { gap: 6px; padding: 6px; }
}

/* ---------- контент ---------- */
.content { flex: 1; overflow: hidden; display: flex; flex-direction: column; min-height: 0; position: relative; }
.v3 .content { z-index: 3; }

/* Разделы лежат стопкой друг на друге и переключаются прозрачностью: пока один
   гаснет, второй проявляется. Раньше это был display:none → display:flex, то есть
   мгновенная подмена, и весь экран вздрагивал вместе с меню.

   Отступы переехали с .content на сами разделы намеренно: абсолютный блок
   отсчитывает inset от ГРАНИЦЫ ПАДДИНГА родителя, поэтому, оставь мы их на
   .content, раздел лёг бы прямо на них и упёрся в края экрана. */
.tab {
  position: absolute; inset: 0; box-sizing: border-box;
  display: flex; flex-direction: column;
  padding: clamp(7px, 1.4vh, 12px) 16px 0;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(6px);
  transition: opacity .12s ease, transform .16s ease, visibility 0s linear .16s;
}
.v1 .tab, .v2 .tab { padding: clamp(8px, 1.6vh, 14px) 16px 0; }
/* Уходящий гаснет быстрее, чем проявляется приходящий (и тот ещё чуть медлит):
   иначе половину перехода на экране два текста поверх друг друга. */
.tab.on {
  opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  transition: opacity .16s ease .07s, transform .24s cubic-bezier(.22, .8, .3, 1), visibility 0s;
}
/* Кому важно, чтобы не мельтешило (и старым устройствам) — просто без перехода. */
@media (prefers-reduced-motion: reduce) {
  .tab, .tab.on { transition: none; }
}

/* баланс */
.bal { display: flex; align-items: center; justify-content: center; gap: clamp(9px, 1.6vw, 14px); margin: clamp(10px, 2.4vh, 22px) 0 clamp(6px, 1.2vh, 10px); }
.v2 .bal { flex: 0 0 auto; margin: clamp(5px, 1.5vh, 16px) 0 clamp(2px, 0.6vh, 6px); }
.v3 .bal { flex: 0 0 auto; gap: clamp(8px, 1.5vw, 13px); margin: clamp(5px, 1.4vh, 14px) 0 clamp(2px, 0.6vh, 5px); }
.coin-big {
  width: clamp(34px, 5.8vh, 54px); height: clamp(34px, 5.8vh, 54px); flex: 0 0 auto;
  border-radius: 50%; background: radial-gradient(circle at 34% 26%, #ffe58f, #e6a51b 66%, #b1710a);
  border: 2px solid #f8d264; display: grid; place-items: center; color: #8a5b06;
  font-size: clamp(17px, 2.8vh, 26px); font-weight: 800; text-shadow: 0 1px 0 rgba(255,255,255,.4);
}
.v3 .coin-big { width: clamp(32px, 5.4vh, 50px); height: clamp(32px, 5.4vh, 50px); font-size: clamp(16px, 2.6vh, 25px); }
.bal-num { color: #fff; font-size: clamp(27px, 4.5vh, 42px); font-weight: 800; letter-spacing: -.5px; }
.v3 .bal-num { font-size: clamp(26px, 4.3vh, 41px); }

/* круг */
.stage { flex: 1; display: flex; align-items: center; justify-content: center; position: relative; min-height: 0; container-type: size; }
.v2 .stage { min-height: clamp(96px, 19vh, 200px); }
.v3 .stage { min-height: clamp(96px, 19vh, 210px); }

/* Круг: в прототипе он задан height:100% + max-width, и на узком экране ширина
   упиралась в 84%, а высота нет — круг превращался в эллипс (замерено: 300.7×330
   при ширине 390). Здесь сторона считается сразу по трём ограничениям.
   и на узком экране ширина упиралась в 84%, а высота нет — круг превращался в эллипс
   (замерено на прототипе: 300.7×330 при ширине экрана 390). Здесь сторона считается
   сразу по трём ограничениям, поэтому круг остаётся кругом на любом телефоне.
   Первая строка width — запасная, для браузеров без единиц контейнера. */
.tap {
  width: min(330px, 84%); height: auto; aspect-ratio: 1; margin: 0 auto;
  width: min(330px, 84cqi, calc(100cqb - 8px));
  border-radius: 50%; padding: 4px; cursor: pointer; position: relative; transition: transform .1s ease-out;
}
.tap-ring { width: 100%; height: 100%; border-radius: 50%; padding: 9px; box-sizing: border-box; }
.v2 .tap-ring { background: linear-gradient(170deg, #7f8cf0, #3a45a8 45%, #1b2050); animation: ringPulse 3.2s ease-in-out infinite; }
.tap-core { width: 100%; height: 100%; border-radius: 50%; background: radial-gradient(circle at 50% 38%, #34428f, #1a1f4c 72%); display: grid; place-items: center; overflow: hidden; }
.villa { width: 88%; height: 88%; object-fit: contain; filter: drop-shadow(0 14px 22px rgba(0,0,0,.5)); }

.fx-layer { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
/* энергия / boost */
.energy { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; padding: clamp(6px, 1.4vh, 10px) 4px 6px; }
.v2 .energy { padding: clamp(4px, 1vh, 10px) 4px clamp(2px, 0.6vh, 6px); }
.v3 .energy { padding: clamp(4px, 1vh, 9px) 4px clamp(2px, 0.6vh, 5px); }
.energy-left { display: flex; align-items: center; gap: 12px; }
.boost { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.v3 .energy-left, .v3 .boost { gap: 11px; }
.boost:hover { opacity: .82; }
.big-emoji { font-size: clamp(21px, 3.4vh, 30px); line-height: 1; }
.v3 .big-emoji { font-size: clamp(20px, 3.2vh, 29px); }
.energy-text, .boost-title { color: #fff; font-size: clamp(17px, 2.7vh, 24px); font-weight: 800; }
.v3 .energy-text, .v3 .boost-title { font-size: clamp(16px, 2.6vh, 23px); }
.v3 .boost-title { line-height: 1.1; }
.boost-col { display: flex; flex-direction: column; }
.boost-sub { color: #7f7f89; font-size: 11px; font-weight: 700; }
.v2 .boost-sub { font-size: clamp(9.5px, 1.3vh, 11px); line-height: 1.2; }
.v3 .boost-sub { font-size: clamp(9px, 1.3vh, 11px); line-height: 1.2; }

/* вкладка Mine */

/* нижняя навигация */
.nav { flex: 0 0 auto; padding: clamp(6px, 1.2vh, 10px) 12px calc(clamp(8px, 1.6vh, 14px) + env(safe-area-inset-bottom, 0px)); }
.v3 .nav { padding: clamp(5px, 1vh, 9px) 12px calc(clamp(7px, 1.4vh, 13px) + env(safe-area-inset-bottom, 0px)); position: relative; z-index: 3; }
/* Колонки считаются по числу ячеек, а не задаются числом: раздел из меню могут
   убрать (так уехали «Бусты»), и жёсткое repeat(5) оставило бы пустую пятую
   колонку — меню выглядело бы сдвинутым влево. */
.nav-in { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; background: #232328; border-radius: 18px; padding: clamp(5px, 1vh, 8px) 6px; }
.v3 .nav-in { padding: clamp(4px, 0.9vh, 8px) 6px; }
/* Подсветка активного раздела переезжает плавно — резкая смена цвета читается
   как рывок самого меню. Геометрия при этом не меняется вовсе. */
.nav-cell { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 7px 0 5px; border-radius: 13px; cursor: pointer; position: relative; transition: background .18s ease; }
.v3 .nav-cell { gap: 4px; padding: 6px 0 4px; }
.nav-icon { font-size: 22px; line-height: 1; transition: opacity .18s ease; }
.v3 .nav-icon { font-size: clamp(18px, 2.8vh, 22px); }
.nav-label { font-size: 11.5px; font-weight: 700; transition: color .18s ease; }
.v3 .nav-label { font-size: clamp(10px, 1.5vh, 11.5px); }
.nav-dot { position: absolute; top: 5px; right: 14px; width: 8px; height: 8px; border-radius: 50%; transition: background .18s ease; }
@media (prefers-reduced-motion: reduce) {
  .nav-cell, .nav-icon, .nav-label, .nav-dot { transition: none; }
}
.v3 .nav-dot { top: 4px; right: 12px; }

/* тост (v2, v3) */
.toast-anchor { position: absolute; left: 50%; z-index: 9; pointer-events: none; }
.v2 .toast-anchor { top: 84px; }
.v3 .toast-anchor { top: 82px; z-index: 14; }
.toast {
  position: absolute; left: 0; top: 0; transform: translate(-50%, 0);
  background: #101014; color: #fff; padding: 9px 16px; border-radius: 999px;
  font-size: 13px; font-weight: 800; white-space: nowrap;
  font-family: Manrope, Helvetica, sans-serif;
  box-shadow: 0 12px 30px rgba(0,0,0,.55);
}

/* эффекты (создаются императивно, вне цикла перерисовки) */
.fx-num { position: absolute; font-weight: 800; pointer-events: none; white-space: nowrap; font-family: Manrope, Helvetica, sans-serif; }
.fx-spark { position: absolute; width: 9px; height: 9px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff2bd, #e6a51b); pointer-events: none; }
