/* =====================================================================
   megabox.scene.css — визуальный слой Mega Box поверх штатной сцены
   ---------------------------------------------------------------------
   Все классы с префиксом .mbx- и живут ВНУТРИ .sbs-root, не задевая
   классическую сцену. Слои фона (.mbx-layer) стоят между .sbs-bg и
   лучами; убрали активный слой — вернулся классический вид.
   ===================================================================== */

/* Шрифт интерфейса — Lilita One (кириллическая версия). Имя семейства
   намеренно осталось прежним: по нему уже размечены все надписи сцены,
   и подмена файла не тянет за собой правки в стилях.

   В присланном файле не было Ё и ё — единственных букв, которых не
   хватало на весь проект («ЗВЁЗДНАЯ СИЛА»). Они добавлены прямо в
   шрифт: точки умляута взяты из готовых Ë/ë, отцентрованы по Е/е и
   поставлены на ту же высоту над буквой. Ширины совпадают с Е/е, так
   что текст не разъезжается.

   ЗНАК РУБЛЯ (U+20BD) В ШРИФТЕ НАМЕРЕННО ОТСУТСТВУЕТ. Сцена набрана
   деньгами — «+2,56₽» на ленте, «0₽ / 25₽» на полосе, итог в баннере, —
   и рубль во всех этих строках рисует ЗАПАСНАЯ гарнитура из списка
   ниже. Так и задумано, дорисовывать знак в файл НЕ НУЖНО: такая
   попытка была дважды (вторая — 2026-08-03) и оба раза откатывалась.

   Причина в обводке. Сцена печатает суммы с -webkit-text-stroke в
   0.1em, а она съедает по 50 единиц с каждой стороны любого штриха и
   любого просвета. У «Р» этого шрифта чаша опускается до 198-й
   единицы, то есть занимает почти всё место, где у рубля должна стоять
   перекладина. Арифметика не сходится ни при какой раскладке: чтобы
   просвет над перекладиной и хвост стойки под ней ПЕРЕЖИЛИ обводку,
   каждому нужно больше 100 единиц, плюс сама перекладина — итого свыше
   340 при доступных 198. На кегле 13 px глиф ещё читался, на 24 и 42
   перекладина сливалась с чашей в сплошную плиту. Обойти это можно,
   только поджав чашу вверх, — но тогда у неё самой просвет становится
   меньше 100 единиц и затягивается уже он.

   ЧТО СДЕЛАНО ВМЕСТО ЭТОГО: у семейства везде просят font-weight 900.
   Для самой Lilita это пустая просьба — @font-face (в site.css) объявляет
   диапазон 400 900, начертание берётся как есть, синтетического жира
   нет (проверено замером: строка «МАЛЕНЬКИЙ ЯЩИК 9 ₽» на 400 и на 900
   даёт ровно 540 px). А вот ЗАПАСНОМУ шрифту 900 достаётся чёрное
   начертание вместо обычного — и рубль встаёт в один вес с цифрами.

   ЗАЧЕМ ЭТО ПОНАДОБИЛОСЬ. Прежде вес просили 400, и на Windows подмены
   было не видно: там запасной — «Arial Black», у него одно начертание и
   оно тяжёлое. Но НА iPhone «Arial Black» не установлен, стопка
   доезжала до system-ui, и рядом с плотными цифрами Lilita вставал
   тонкий системный ₽ — прайс «9 ₽» на телефоне выглядел сломанным. При
   весе 900 то же место рисует SF Pro Black, на Android — Roboto Black.

   Заметно, что рубль набран другой гарнитурой, только если искать
   специально: у чёрных начертаний тот же характер и та же плотность.

   Прежний megabox.ttf (Nougat) остался в папке, но больше не
   подключён — вернуть можно одной строкой ниже. */
/* ЕДИНАЯ ТИПОГРАФИКА ПО ЗАМЕРАМ РЕФЕРЕНСА.
   Замеры сняты с кадра «x 175» и приведены к высоте прописной (cap),
   чтобы не зависеть от разрешения записи:
     обводка наружу  5 px при cap 60  = 0.083 cap
     от верха глифа  4 px при cap 60  = 0.067 cap
     вниз до конца тени 14 px         = 0.233 cap
   У Lilita One cap = 0.73em, а -webkit-text-stroke идёт ПО СЕРЕДИНЕ
   контура — наружу выходит половина. Отсюда:
     обводка  0.083 · 0.73 · 2 ≈ 0.1em
     тень     0.155em вниз, жёсткая, без блюра — и НЕ одной копией,
              а сплошной выдавкой (--mbx-extrude в smallbox.scene.css:
              одиночный сдвиг отрывался от тонких мест глифа)
   Тень подобрана по остатку: 0.17em давала снизу 0.256 cap вместо
   0.233 — лишние ~2 px, которые читались как «толстая нижняя кромка».
   Разница именно в тени, а не в обводке: сверху и с боков контур
   совпал с референсом с первого раза.
   Прежние 0.045em / 0.11em давали вдвое более тонкий контур, чем в
   оригинале: на синем фоне текст выглядел плоским и «терял» края.
   Заголовки экранов сюда НЕ входят: под буквой через 3 px уже чистый
   фон — ни обводки, ни тени (см. .mbx-title).
   Те же 0.1em/0.155em продублированы в smallbox.scene.css у счётчика. */
/* ПОЧЕМУ ЗДЕСЬ ДИАПАЗОН ВЕСОВ, А НЕ ПРОСТО ССЫЛКА НА ФАЙЛ.

   В lilitaone.ttf ровно одно начертание, usWeightClass = 400. Без
   дескриптора font-weight браузер считает, что в семействе
   «MegaBoxFont» есть только вес 400. А вся сцена набрана
   font-weight: 800 — двадцать правил в этом файле и в
   smallbox.scene.css. Подходящего начертания нет, и Chrome включает
   СИНТЕТИЧЕСКИЙ жир: размазывает контур по горизонтали сам.

   Именно это делало заголовки «раздутыми»: у «О» и «Е» затягивало
   внутренние просветы, углы «М» скруглялись, буквы толстели и
   слипались. В Photoshop тот же файл выглядел нормально, потому что
   там подмены веса не происходит.

   Диапазон 400–900 говорит браузеру, что это начертание покрывает все
   веса. Любой font-weight из сцены попадает в него, синтез
   отключается — и текст рисуется ровно так, как нарисован шрифт.
   Правки в самих правилах при этом не нужны: font-weight: 800
   остаётся на месте и работает корректно. */
/* @font-face ПЕРЕЕХАЛ В site.css.
   Причина — загрузка: этот файл (33 КБ в сжатом виде, самый тяжёлый
   стиль сайта) нужен только сцене открытия, и в main.html он теперь
   грузится отложенно, не задерживая первую отрисовку. А объявление
   шрифта нужно СРАЗУ: им набраны логотип, полки и цены на главной.
   Разбор веса 400 900 и подмены начертания — там же, у объявления. */

.sbs-root .mbx-layer,
.sbs-root .mbx-layer .mbx-bg { position: absolute; inset: 0; pointer-events: none; }
.mbx-layer .mbx-bg { opacity: 0; }
.mbx-layer .mbx-bg.is-live { opacity: 1; }

/* ---------- фоны сцен ---------- */
.mbx-bg-box     { background: radial-gradient(115% 90% at 50% 42%, #0d3f8f 0%, #071f4e 72%, #051536 100%); }
.mbx-bg-coins   { background: radial-gradient(115% 90% at 50% 45%, #1b62d8 0%, #0b3d9e 78%, #082e7c 100%); }
.mbx-bg-points  { background: radial-gradient(120% 95% at 50% 46%, #1053c4 0%, #082a70 80%); }
.mbx-bg-passive { background: radial-gradient(120% 95% at 50% 46%, #2a63d4 0%, #123c9c 85%); }

.mbx-bg .mbx-pat {
  position: absolute; inset: 0;
  background-repeat: no-repeat; background-position: 50% 50%; background-size: cover;
}
.mbx-bg-box   .mbx-pat { filter: brightness(.52) saturate(1.15); }
.mbx-bg-coins .mbx-pat { filter: brightness(1.04); }

/* Готовый фон экрана «ящик ещё НЕ открыт» (box_background.png). В нём
   уже и градиент, и узор из черепов, поэтому затемнение, нужное голой
   эмблеме, снимается, а виньетка становится мягче: иначе картинка
   гасится дважды и синий уходит в чёрный. */
.mbx-bg-box.has-art .mbx-pat { filter: none; }
.mbx-bg-box.has-art .mbx-vig {
  background: radial-gradient(125% 105% at 50% 48%, rgba(0,0,0,0) 62%, rgba(2,8,30,.34) 100%);
}

/* Фон бонусного экрана. Картинка ставится из манифеста (megabox.bonus),
   поэтому здесь только поведение слоя: заливка-подложка на случай
   незагруженной картинки и медленное вращение для лучей удвоителей. */
.mbx-bg-bonus { background: var(--mbx-bonus-fallback, #1b62d8); }
.mbx-bg-bonus .mbx-vig {
  background: radial-gradient(125% 105% at 50% 48%, rgba(0,0,0,0) 60%, rgba(0,0,0,.30) 100%);
}
/* Вращающийся фон (лучи удвоителей).

   БАГ, который здесь чинится: слой раздували процентным inset'ом
   (-45 %), то есть до 190 % ШИРИНЫ и 190 % ВЫСОТЫ экрана. На широком
   мониторе 190 % высоты меньше диагонали кадра, и стоило анимации
   доехать примерно до 30°, как углы переставали накрываться — по краям
   вылезала подложка косыми клиньями. Чем шире экран, тем заметнее.

   Правильный размер вращающегося слоя — КВАДРАТ со стороной не меньше
   ДИАГОНАЛИ кадра: только он накрывает экран при ЛЮБОМ угле.

   Сторона задаётся дважды, по возрастанию точности:
     1) min(142vmax, 100vw + 100vh) — работает везде. Сумма сторон не
        меньше диагонали (неравенство треугольника), а 142vmax (√2·vmax)
        подрезает её на вытянутых экранах, где сумма сильно избыточна.
     2) hypot(100vw, 100vh) — ТОЧНАЯ диагональ там, где браузер умеет
        hypot(). Квадрат получается минимально возможным, и картинка не
        раздувается сверх нужного: центральное свечение остаётся такого
        же размера, как на референсе. Браузер без hypot() просто
        пропустит эти строки и останется на варианте (1).
   Ради этого запаса значение и повторяется целиком, а не заводится в
   custom property: невалидная var() обнулила бы ширину вместо отката. */
.mbx-bg-bonus .mbx-pat.is-spin {
  inset: auto; left: 50%; top: 50%;
  width:       min(142vmax, calc(100vw + 100vh));
  height:      min(142vmax, calc(100vw + 100vh));
  margin-left: calc(min(142vmax, calc(100vw + 100vh)) / -2);
  margin-top:  calc(min(142vmax, calc(100vw + 100vh)) / -2);
  width:       hypot(100vw, 100vh);
  height:      hypot(100vw, 100vh);
  margin-left: calc(hypot(100vw, 100vh) / -2);
  margin-top:  calc(hypot(100vw, 100vh) / -2);
  animation-name: mbxBgSpin;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes mbxBgSpin { to { transform: rotate(360deg); } }

.mbx-bg .mbx-vig {
  position: absolute; inset: 0;
  background: radial-gradient(120% 100% at 50% 48%, rgba(0,0,0,0) 55%, rgba(2,8,30,.55) 100%);
}
.mbx-rays {
  position: absolute; inset: -25%;
  background: repeating-conic-gradient(from 8deg,
      rgba(255,255,255,.075) 0deg 6.5deg, rgba(255,255,255,0) 6.5deg 15deg);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 62%);
          mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 62%);
}
/* =====================================================================
   Коробка
   ===================================================================== */
.mbx-boxrig {
  --mbx-box-y: -160%; --mbx-box-rot: -7deg; --mbx-box-sx: 1; --mbx-box-sy: 1;
  position: absolute; left: 50%; top: 54%;
  /* Ящик ровно того же видимого размера, что и стопка монет, которая
     падает следом. Считать по ширине РАМОК нельзя: у обеих картинок своё
     прозрачное поле, и одинаковые рамки дали бы разный рисунок. Взяты
     непрозрачные доли самих файлов —

       coins_stack.png  видимая часть 0.824 ширины файла, рамка 67vmin
       box_closed.png   видимая часть 0.863 ширины файла

     отсюда 67 x 0.824 / 0.863 = 64vmin, и обе картинки выходят шириной
     55.2vmin. Потолок в px снят намеренно: у монет его нет, и с ним на
     большом экране ящик отставал бы от них тем сильнее, чем шире окно. */
  width: 64vmin;
  transform: translate(-50%, -50%)
             translateY(var(--mbx-box-y))
             rotate(var(--mbx-box-rot))
             scale(var(--mbx-box-sx), var(--mbx-box-sy));
  will-change: transform, filter;
}
.mbx-boxrig img { display: block; width: 100%; height: auto; -webkit-user-drag: none; }
/* ЗАКРЫТАЯ КОРОБКА ОБЯЗАНА ПРОПАДАТЬ, КОГДА УЛЕТАЕТ КРЫШКА.
   Сцена прячет её атрибутом hidden, но правило выше (класс + тег)
   сильнее браузерного [hidden] { display: none } — и коробка
   продолжала рисоваться ПОД половинками. В прорези между улетевшей
   крышкой и низом вместо тёмной щели со светом виднелась целая вторая
   коробка: раскрытие читалось как задвоение картинки. По той же
   причине во время падения поверх закрытой коробки лежали обе
   половинки — незаметно, потому что вместе они складываются в неё же.

   Прячем ВИДИМОСТЬЮ, а не display: закрытая коробка — единственная
   картинка рига в потоке, и от неё считается его высота. С display:none
   риг схлопнулся бы в нулевую высоту, а он центрируется по себе
   (translate(-50%,-50%)) — половинки прыгнули бы вниз на пол-коробки
   ровно в момент раскрытия. */
.mbx-boxrig img[hidden] { visibility: hidden; }
.mbx-box-base, .mbx-box-lid { position: absolute; left: 0; top: 0; will-change: transform; }
.mbx-halo {
  position: absolute; left: 50%; top: 50%;
  width: 260%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, #a8dcff 0%, #35a7ff 22%, rgba(53,167,255,0) 68%);
  opacity: 0; filter: blur(2px); pointer-events: none;
  z-index: -1;
}
/* Приглушённый вариант сияния — когда фон-картинка уже даёт подсвет. */
.mbx-boxrig.has-bgart .mbx-halo {
  width: 210%;
  background: radial-gradient(circle, rgba(168,220,255,.5) 0%,
      rgba(53,167,255,.3) 24%, rgba(53,167,255,0) 66%);
}
.mbx-openlight {
  position: absolute; left: 50%; top: 30%;
  width: 70%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, #ffffff 0%, #bfeaff 30%, rgba(191,234,255,0) 70%);
  opacity: 0; pointer-events: none;
}

/* =====================================================================
   Общая типографика наград
   ===================================================================== */
.mbx-title {
  /* Замеры экрана монет по кадру записи (кадр 1920x888):
       «МОНЕТЫ» капитель 62 px = 7.0 % высоты → кегль 9.7vmin,
                центр строки на 18.2 % высоты
     Прежние 7vmin с потолком 66 px давали капитель 45 px — в полтора
     раза мельче эталона. */
  position: absolute; left: 50%; top: 18.2%;
  transform: translate(-50%, -50%);
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: min(9.7vmin, 10.5vw);
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  font-weight: 800; letter-spacing: .015em; color: #fff;
  /* ЗАГОЛОВКИ ЭКРАНОВ НАГРАД — БЕЗ ОБВОДКИ.
     Проверено по кадрам записи: у «ОЧКИ СИЛЫ» и «УДВОИТЕЛЬ ЖЕТОНОВ»
     самый тёмный пиксель между буквами — это фон, контура там нет,
     только мягкая тень вниз. Обводка остаётся у всего остального:
     чисел наград, ленты «+N», полосы, счётчика, заголовков итога.
     Толстый контур здесь ещё и слипался: Lilita уже Nougat, и соседние
     буквы смыкались обводками в сплошную кашу.

     Отмена задана ЯВНО, а не отсутствием свойства: text-shadow
     наследуется, и любая тень, поставленная контейнеру сцены, иначе
     протекла бы в заголовок. Чистая белая заливка — и ничего больше. */
  text-shadow: none;
  -webkit-text-stroke: 0;
          text-stroke: 0;
  white-space: nowrap;
  animation: mbxTitleIn 190ms cubic-bezier(.2,.9,.3,1.3) both;
}
.mbx-title.is-dim { color: #eaf3ff; }
@keyframes mbxTitleIn {
  0%   { transform: translate(-50%,-50%) scale(.4);  opacity: 0; }
  70%  { transform: translate(-50%,-50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%,-50%) scale(1);   opacity: 1; }
}

/* =====================================================================
   Монеты
   ===================================================================== */
/* position:fixed, как у экранов очков и бонусов: иначе проценты внутри
   считаются от .sbs-stagearea, а она занимает лишь 78 % кадра — весь
   блок съезжал вниз примерно на 7 % высоты. Тряска и зум камеры при
   этом сохраняются: контейнером для fixed служит .sbs-camera, у неё
   есть transform. */
.mbx-coins, .mbx-points, .mbx-sp { position: fixed; inset: 0; }
.mbx-coins-rig {
  /* Стопка на записи: 503x363 px, то есть 56.6 % высоты кадра по
     ширине, центр на 50.9 %. В файле непрозрачная часть занимает
     84.5 % высоты картинки, поэтому рамка чуть крупнее самой стопки. */
  position: absolute; left: 50%; top: 50.9%;
  width: 67vmin;
  margin-left: -33.5vmin;
  margin-top: calc(67vmin / 1.376 / -2);
  transform: scale(0);
  transform-origin: 50% 50%;
  will-change: transform;
}
.mbx-coins-rig img { display: block; width: 100%; height: auto; }
/* Тень на «полу» под монетами.

   Параметры сняты пиксельно с референсного кадра (шоп Brawl Stars) и
   пересчитаны в проценты от рамки .mbx-coins-rig, то есть от самой
   картинки coins_stack.png (2432x1728). Что было измерено на референсе:

     • затемнение фона в ядре тени — РОВНОЕ, без градиента внутри:
       зелёный канал x0.765, синий x0.853 от чистого фона. Именно это
       даёт rgba(0,20,86,.30) поверх здешнего синего;
     • контур половинной плотности: слева 12.5 % ширины кадра, справа
       98.4 %, снизу 95 % высоты, самая широкая часть на 83.6 %;
     • край размыт примерно на 8 px референса = 0.9vmin здешней рамки.

   Отсюда и вся геометрия ниже. Заливка СПЛОШНАЯ, а мягкость даёт
   только blur(): у радиального градиента спад начинался слишком рано,
   и видимая полоса под стопками (а это как раз нижняя кромка эллипса)
   выцветала вдвое против референса — тень читалась как дымка.

   Прошлая версия не читалась ещё и по другой причине: при bottom:7 %
   и height:12 % эллипс сидел на 87 % высоты кадра, то есть целиком за
   монетами (непрозрачная часть картинки кончается на 90.7 %), наружу
   выходила только кромка. Теперь центр ниже, а сам эллипс шире стопок,
   поэтому тень видна и слева, и справа от них — как на референсе.

   Проценты, не px: рамка задана в vmin и тень должна масштабироваться
   вместе с ней. */
.mbx-coins-shadow {
  position: absolute; left: 53.5%; top: 83.6%;
  width: 91%; height: 22.8%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(0, 20, 86, .25);
  filter: blur(0.2vmin);
  z-index: -1;
}

/* ---------- искры/блёстки вокруг стопки монет ---------- */
.mbx-sparkles { position: absolute; inset: -8% -6%; pointer-events: none; z-index: 2; }
.mbx-spark {
  position: absolute;
  width: var(--s, 22px); height: var(--s, 22px);
  background: #fff;
  /* четырёхлучевая «звёздочка»-блик */
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
  filter: drop-shadow(0 0 6px rgba(190,230,255,.9));
  opacity: 0;
  transform: translate(-50%, -50%) scale(.2) rotate(0deg);
  animation: mbxSpark var(--dur, 1600ms) ease-in-out var(--delay, 0ms) infinite;
}
@keyframes mbxSpark {
  0%, 100% { opacity: 0; transform: translate(-50%,-50%) scale(.2) rotate(-25deg); }
  45%      { opacity: 1; transform: translate(-50%,-50%) scale(1) rotate(0deg); }
  70%      { opacity: .55; transform: translate(-50%,-50%) scale(.78) rotate(12deg); }
}
/* раскладка блёсток вокруг стопки: позиция, размер, тайминги — у каждой свои */
.mbx-spark:nth-child(1) { left: 12%; top: 30%; --s: 30px; --dur: 1500ms; --delay: 0ms; }
.mbx-spark:nth-child(2) { left: 86%; top: 22%; --s: 24px; --dur: 1700ms; --delay: 380ms; }
.mbx-spark:nth-child(3) { left: 70%; top: 8%;  --s: 18px; --dur: 1400ms; --delay: 720ms; }
.mbx-spark:nth-child(4) { left: 6%;  top: 66%; --s: 22px; --dur: 1650ms; --delay: 540ms; }
.mbx-spark:nth-child(5) { left: 94%; top: 60%; --s: 26px; --dur: 1550ms; --delay: 900ms; }
.mbx-spark:nth-child(6) { left: 44%; top: 4%;  --s: 16px; --dur: 1800ms; --delay: 1200ms; }
.mbx-spark:nth-child(7) { left: 30%; top: 88%; --s: 20px; --dur: 1600ms; --delay: 1050ms; }
.mbx-spark:nth-child(8) { left: 80%; top: 84%; --s: 17px; --dur: 1500ms; --delay: 260ms; }
.mbx-amount {
  /* «x 175»: капитель 63 px = 7.1 % высоты → кегль 9.9vmin,
     центр строки на 79.5 %. Было 6.2vmin с потолком 58 px. */
  position: absolute; left: 50%; top: 79.5%;
  transform: translate(-50%, -50%);
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: min(9.9vmin, 10.7vw);
  font-weight: 800; letter-spacing: .01em; color: #fff;
  --so-c:#150a22;
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  white-space: nowrap;
  animation: mbxTitleIn 190ms cubic-bezier(.2,.9,.3,1.3) both;
}

/* =====================================================================
   ОЧКИ СИЛЫ — покадровая копия оригинала (2019–2020)
   ---------------------------------------------------------------------
   Все размеры и позиции сняты с записи и пересчитаны в vmin/проценты от
   ЭКРАНА. Эталонный кадр — 1920×888, то есть vmin эталона = 888:

     заголовок    кегль 74 px  → 8.33vmin,  центр строки на 25.0 % высоты
     портрет      241×255 px   → 27.1×28.7vmin, центр на 45.4 %
     лента        216 px шир.  → 24.3vmin, тело 68 px, с хвостом 92 px
     полоса       294×60 px    → 33.1×6.8vmin, верх на 74.9 %
     иконка очков 72 px        → 8.1vmin
     подпись      кегль 39 px  → 4.4vmin, центр на 84.2 %

   position:fixed — чтобы проценты считались от экрана, а не от
   .sbs-stagearea (та занимает лишь 78 % кадра). Тряска и зум камеры
   сохраняются: контейнером для fixed-потомков служит .sbs-camera,
   у которой есть transform. Тот же приём, что на бонусных экранах.
   ===================================================================== */
.mbx-pp { position: fixed; inset: 0; pointer-events: none; }

/* Фон переливается синий → магента → фиолет: цвета ставит JS покадрово
   в переменные --mbx-pp-c (центр) и --mbx-pp-e (край). */
.mbx-bg-points {
  background: radial-gradient(circle at 50% 45.4%,
      var(--mbx-pp-c, #6858FE) 0%, var(--mbx-pp-e, #5324B3) 88%);
}
/* ---------- фон экрана очков силы ----------
   Замеры по кадру записи (центр карточки на 45.4 % высоты кадра):

     радиус  130 px → rgb(184,154,254)   ← белый подсвет под карточкой
             190 px → rgb(144,130,253)
             280 px → rgb(112,101,255)
             420 px → rgb( 95, 70,223)
             640 px → rgb( 85, 41,186)
             780 px → rgb( 83, 36,179)   ← ровный фиолетовый фон

   То есть под карточкой не просто чуть светлее — там отдельное белое
   свечение, гаснущее примерно к 40 vmin. Раньше его не было вовсе, и
   экран выходил плоским.

   Лучи: размах на записи 40–70 уровней яркости — около половины
   локальной яркости фона. Прежние .22 давали размах ~4 уровня, то есть
   были в дюжину раз бледнее нужного. */
.mbx-bg-points .mbx-glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 45.4%,
      rgba(255,255,255,.50) 0,
      rgba(255,255,255,.38) 18vmin,
      rgba(255,255,255,.20) 26vmin,
      rgba(255,255,255,.07) 38vmin,
      rgba(255,255,255,0)   55vmin);
  /* дышит вокруг карточки, а не вокруг центра экрана */
  transform-origin: 50% 45.4%;
  animation: mbxPpGlow 4.6s ease-in-out infinite;
}
@keyframes mbxPpGlow {
  0%, 100% { opacity: .84; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.05); }
}

/* Лучи ярче и медленно вращаются. Квадрат со стороной в диагональ —
   по той же причине, что у фона удвоителей и итога: слой меньше
   диагонали при повороте перестаёт накрывать углы. Центр совмещён с
   центром карточки (45.4 % высоты), чтобы лучи сходились за ней. */
.mbx-bg-points .mbx-rays {
  opacity: 1;
  inset: auto; left: 50%; top: 45.4%;
  width:       min(142vmax, calc(100vw + 100vh));
  height:      min(142vmax, calc(100vw + 100vh));
  margin-left: calc(min(142vmax, calc(100vw + 100vh)) / -2);
  margin-top:  calc(min(142vmax, calc(100vw + 100vh)) / -2);
  width:       hypot(100vw, 100vh);
  height:      hypot(100vw, 100vh);
  margin-left: calc(hypot(100vw, 100vh) / -2);
  margin-top:  calc(hypot(100vw, 100vh) / -2);
  /* Контраст лучей на записи — около 6 % от яркости фона (замерено по
     дуге радиусом 380 и 470 px, с вычетом радиального градиента).
     Жёсткие клинья с резкой границей давали под 50 % и выглядели как
     полосатый зонт, поэтому переход мягкий, а пик всего .04. */
  background: repeating-conic-gradient(from 7deg,
      rgba(255,255,255,0)    0deg,
      rgba(255,255,255,.02)  6deg,
      rgba(255,255,255,.02)  9deg,
      rgba(255,255,255,0)   15deg);
  -webkit-mask-image: none; mask-image: none;
  animation: mbxSumRays 60s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .mbx-bg-points .mbx-rays, .mbx-bg-points .mbx-glow { animation: none; }
}

/* Заголовок рисуется ПОВЕРХ стека. По раскладке он и так не пересекается
   с портретом, но на пике подлёта карта подступает к строке вплотную, а
   при других пропорциях экрана кегль и позиции считаются от разных
   сторон кадра. Явный порядок слоёв гарантирует, что текст не уйдёт под
   картинку ни при каком размере окна. */
.mbx-pp-title {
  z-index: 2;
  position: absolute; left: 50%; top: 25%;
  /* 25 % — ЦЕНТР строки на записи, поэтому центрируем и по вертикали:
     без translateY заголовок садится на 5 % ниже и лезет на портрет. */
  transform: translate(-50%, -50%);
  transform-origin: 50% 50%;
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: min(8.33vmin, 9vw);
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  font-weight: 800; letter-spacing: .015em; color: #fff;
  /* без обводки и без тени — см. пояснение у .mbx-title.
     Отмена явная по той же причине: text-shadow наследуется. */
  text-shadow: none;
  -webkit-text-stroke: 0;
          text-stroke: 0;
  white-space: nowrap;
  will-change: transform;
}

/* Портрет и лента — единый блок: лента растёт из-под портрета вплотную.
   Стек привязан ВЕРХОМ портрета (31.1 % высоты кадра), а не своим
   центром: центр стека гуляет вместе с лентой, и портрет уезжал бы
   вверх на заголовок. Ширина стека = ширина портрета, лента уже его —
   как в оригинале. */
.mbx-pp-stack {
  z-index: 1;
  position: absolute; left: 50%; top: 31.1%;
  transform: translateX(-50%);
  width: 27.1vmin;
  display: flex; flex-direction: column; align-items: center;
}

/* ---------- портрет / карта ----------
   Карта ВСЕГДА в потоке: подлёт делается только через transform, чтобы
   её центр гарантированно совпадал с центром портрета (45.4 % высоты) и
   рост шёл именно оттуда. */
.mbx-pp-card {
  position: relative;
  width: 100%; height: 28.7vmin;
  background: #16204a;
  border: 0.62vmin solid #fff;               /* белая рамка оригинала */
  box-shadow: 0 0 0 0.36vmin rgba(6,10,30,.85);
  overflow: hidden; opacity: 0;
  transform-origin: 50% 50%;
  will-change: transform, filter, opacity;
  box-sizing: border-box;
}
.mbx-pp-card.is-open { opacity: 1; transform: none; }
.mbx-pp-card img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Розовая заливка карты до раскрытия. Отдельного арта рубашки в
   оригинале нет — это тот же портрет под сплошной заливкой. */
.mbx-pp-cardtint {
  position: absolute; inset: 0;
  mix-blend-mode: multiply;
  background: #FF3EC8;
}

/* ---------- лента «+N» ----------
   Все размеры сняты с полного кадра записи (высота игрового кадра
   887 px = 100 vmin), сабпиксельно, по середине перехода цвета:

     лента        214.8×95.5 px  → 24.22×10.77vmin, верх вплотную к карте
     тело ленты   63.7 из 95.5   → шеврон начинается на 64.7 %
                  (в разметке 64.7 %, на снимке замер даёт 66.7 % —
                  замер берёт середину растушёвки края, она на ~2 px ниже)
     цвет         rgb(149,0,200) — РОВНЫЙ, без градиента
     тень         НЕПРОЗРАЧНО-ЧЁРНАЯ (на кадре под ней ровно 0,0,0),
                  ниже на 7.7 px, повторяет шеврон, вбок не смещена.
                  В разметке 0.96vmin, а не 0.87: drop-shadow съедает
                  примерно полпикселя на растушёвку сверху и снизу, и
                  на снимке 0.87vmin меряются как 7.0 px вместо 7.7
     «+16»        капитель 46 px → кегль 65 px ≈ 7.35vmin
     значок       розовый пятак Ø 50 px → 5.64vmin (элемент равен ПЯТАКУ,
                  чёрная обводка арта вылезает за него — см. has-ptico),
                  зазор пятак↔краска надписи 19 px
     поля         слева до краски «+» 31 px, справа до пятака 15 px —
                  группа стоит НЕ по центру ленты, а на 8 px правее

   ПОЧЕМУ ЛЕНТА ИЗ ДВУХ УЗЛОВ. Тень раньше стояла фильтром на том же
   элементе, что и clip-path, и не рисовалась вовсе: по спецификации
   filter применяется ДО клипа, то есть clip-path срезает готовую тень
   ровно по контуру ленты — за её пределами не остаётся ничего. Поэтому
   шеврон режется на внутреннем .mbx-pp-ribbonbody, а drop-shadow висит
   на внешнем .mbx-pp-ribbon: фильтр работает по альфе уже обрезанного
   потомка и повторяет шеврон сам. ::after не годится по той же причине,
   по какой не годился раньше, — его тоже срезал бы клип. */
.mbx-pp-ribbon {
  position: relative;
  display: flex;                 /* обёртка облегает тело ленты */
  margin-top: 0;
  filter: drop-shadow(0 0.96vmin 0 #000);
  transform: scaleY(0); transform-origin: 50% 0;
  opacity: 0; will-change: transform;
}
.mbx-pp-ribbon.is-in { opacity: 1; }

.mbx-pp-ribbonbody {
  /* Ширина НЕ фиксированная. В оригинале в ленте стоит «+16», у нас —
     денежная строка вдвое длиннее, и на референсной ширине она не
     живёт. Лента растёт под содержимое от референсных 24.22vmin и
     упирается в ширину портрета: лента шире карточки читалась бы уже
     как другой элемент, а не как та же лента с длинным числом.
     Что не влезло и в этот предел, добирает кегль — см. .mbx-pp-add. */
  width: max-content;
  min-width: 24.22vmin;
  max-width: 27.1vmin;
  height: 10.77vmin;
  /* прямоугольник с вырезом-шевроном снизу, как в оригинале */
  clip-path: polygon(0 0, 100% 0, 100% 64.7%, 50% 100%, 0 64.7%);
  background: #9500C8;
  /* «+N» центрируется в ТЕЛЕ ленты (верхние 65 %), а не во всей высоте:
     иначе надпись съезжает на хвост-шеврон. */
  display: flex; align-items: center; justify-content: center;
  gap: 1.86vmin;
  /* Процентный padding считается от ШИРИНЫ, поэтому отступы заданы в
     vmin. Снизу 2.11vmin сдвигают центр содержимого на 38.4 px от верха
     ленты — ровно туда, где стоит «+16» на записи. Слева и справа поля
     разные, и это не описка: на записи группа «сумма + значок» стоит на
     8 px правее середины ленты. Пока строка короткая, поля работают
     ровно как на кадре; когда лента упирается в свой предел, они
     становятся её фактическими полями. */
  box-sizing: border-box;
  padding: 0 1.69vmin 2.11vmin 3.21vmin;
}

.mbx-pp-add {
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  /* Кегль оригинала — 7.35vmin (капитель «+16» на записи 46 px). Под
     ним стоит короткое «+16»; у нас в ленте денежная строка вдвое
     шире. Сначала под неё растёт САМА ЛЕНТА (см. .mbx-pp-ribbon), и
     только то, что не влезло и в её предел, добирается кеглем — так
     короткие суммы читаются ровно как оригинал, а длинные ужимаются
     настолько, насколько действительно нужно, а не вдвое, как раньше.

     Ужимается ТОЛЬКО надпись: значок обязан остаться референсных
     5.64vmin, иначе с него пропадают чёрная обводка и тень — на мелком
     пятаке их просто не видно.

     Свободную ширину считает rewardPoints() (fitAdd) уже по факту
     разложенной ленты. Значение ниже — стартовое и одновременно
     верхняя граница. */
  font-size: 7.35vmin;
  font-weight: 800; color: #fff; line-height: 1;
  --so-c:#150a22;
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  opacity: 0; white-space: nowrap;
}

/* На записи пятак стоит на 3.5 px ВЫШЕ середины надписи, а не вровень с
   ней: игра центрует значок вместе с его нижней тенью, а тень занимает
   у арта 23 px из 179 по высоте. У нас элементом сделан сам пятак —
   иначе он вышел бы мельче, чем на полосе прогресса (см. has-ptico), —
   поэтому тот же сдвиг ставится руками. relative + top разложение не
   трогают: поля и ширина ленты остаются те же. */
.mbx-pp-ribbonbody .mbx-pp-ico { top: -0.39vmin; }

/* ---------- значок очков силы: розовый круг с молнией ---------- */
.mbx-pp-ico {
  flex: 0 0 auto; display: block;
  width: 5.64vmin; height: 5.64vmin;    /* розовый пятак Ø 50 px на кадре */
  border-radius: 50%;
  background:
    /* блик */
    radial-gradient(circle at 32% 28%, rgba(255,255,255,.55) 0 14%, rgba(255,255,255,0) 15%),
    radial-gradient(circle at 68% 74%, rgba(255,255,255,.28) 0 11%, rgba(255,255,255,0) 12%),
    linear-gradient(180deg, #ff7ae0 0%, #f52bae 60%, #d81295 100%);
  box-shadow: 0 0 0 0.32vmin #14061c;
  position: relative;
}
/* молния внутри круга */
.mbx-pp-ico::before {
  content: ''; position: absolute; inset: 22%;
  background: #fff;
  clip-path: polygon(58% 0%, 18% 54%, 44% 54%, 34% 100%, 82% 42%, 52% 42%);
  filter: drop-shadow(0 0 1px rgba(20,6,28,.8));
}

/* Готовый арт значка (megabox.images.point_icon). Путь кладёт сцена в
   --mbx-pt-ico на корень, отсюда его получают все три значка сразу:
   лента «+N», полоса прогресса и баннер итога.

   ПОЧЕМУ КАРТИНКА В ::before, А НЕ ФОНОМ САМОГО ЭЛЕМЕНТА. В файле
   165×179, но сам розовый пятак — 149×148 со смещением (8, 8): вокруг
   чёрная обводка, снизу ещё и тень. Фон обрезается по краю элемента,
   поэтому фоном пришлось бы уменьшать пятак, чтобы влезли обводка и
   тень, — и значок стал бы мельче полосы. Вместо этого элемент
   остаётся РОВНО размером пятака (все vmin в разметке ниже считаны от
   него), а картинка вылезает за его границы на долю обводки и тени.
   Проценты — прямое отношение файла к пятаку: 165/149, 179/148,
   −8/149, −8/148. Заменишь арт с другими полями — поправь их. */
.sbs-root.has-ptico .mbx-pp-ico {
  background: none;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;
}
.sbs-root.has-ptico .mbx-pp-ico::before {
  inset: auto;                       /* снимаем inset: 22% процедурной молнии */
  left: -5.37%; top: -5.41%;
  width: 110.74%; height: 120.95%;
  background: var(--mbx-pt-ico) 50% 50% / 100% 100% no-repeat;
  clip-path: none;
  filter: none;
}

/* ---------- полоса прогресса ----------
   Замеры того же кадра (100 vmin = 887 px):

     значок       пятак Ø 62 px      → 7vmin, верх блока на 75.2 % высоты
     полоса       тело 279×49 px      → 31.45×5.55vmin, обводка 0.5vmin
                  (снизу вдвое толще: та же обводка, сдвинутая вниз)
     скос правого края 15.4°          → skewX(−15deg)
     заливка      РОВНЫЙ rgb(253,127,254), без градиента
     жёлоб        rgb(52,1,34) сверху → rgb(91,0,52) снизу
     «16/20»      капитель 24 px      → кегль 34 px ≈ 3.8vmin
     кромка       33 px белого + мягкий переход, выступает за фронт
                  заливки на 13 px (1.47vmin)                          */
.mbx-pp-barwrap {
  /* 75.2 % — верх ЗНАЧКА: он выше полосы, поэтому по нему и якорь.
     Полоса центрируется относительно значка сама (align-items:center). */
  position: absolute; left: 50%; top: 75.2%;
  transform: translateX(-50%);
  display: flex; align-items: center;
  opacity: 0;
}
.mbx-pp-barwrap.is-in { animation: mbxPpBarIn 130ms cubic-bezier(.2,.9,.3,1.3) both; }
@keyframes mbxPpBarIn {
  0%   { opacity: 0; transform: translateX(-50%) scale(.5); }
  70%  { opacity: 1; transform: translateX(-50%) scale(1.07); }
  100% { opacity: 1; transform: translateX(-50%) scale(1); }
}
/* Значок сидит НА полосе, перекрывая её левый край. */
.mbx-pp-barico {
  width: 7vmin; height: 7vmin;
  margin-right: -0.9vmin;
  position: relative; z-index: 2;
}
/* Сама полоса — параллелограмм: правый край завален влево на 15°,
   как в оригинале. Скос делает transform, поэтому содержимое
   (текст, заливка) выпрямляется обратно.

   Обводка — двумя тенями: ровное кольцо 0.5vmin плюс такое же кольцо,
   сдвинутое вниз. На записи низ полосы заметно толще верха, и это не
   размытая тень, а именно вторая чёрная кромка. */
.mbx-pp-bar {
  position: relative;
  width: 31.45vmin; height: 5.55vmin;
  transform: skewX(-15deg);
  background: linear-gradient(180deg, #340122 0%, #3A0025 38%, #5B0034 100%);
  box-shadow: 0 0 0 0.5vmin #0A0410,
              0 0.3vmin 0 0.5vmin #0A0410,
              0 0.7vmin 0.7vmin rgba(6,2,20,.4);
  overflow: hidden;
}
.mbx-pp-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: #FD7FFE;
}
.mbx-pp-barwrap.is-full .mbx-pp-fill {
  background: #3CEE28;
}
/* Раскалённый фронт заливки. На записи это НЕ узкая полоска, а белый
   блок в 33 px с мягким переходом из розового перед ним, и он выступает
   за границу заливки на 13 px — поэтому right отрицательный, а
   max-width считается с той же добавкой: на короткой заливке кромка
   сжимается вместе с ней и не вылезает влево обрубком. */
.mbx-pp-edge {
  position: absolute; right: -1.47vmin; top: 0; bottom: 0;
  width: 7.2vmin;
  max-width: calc(100% + 1.47vmin);
  background: linear-gradient(90deg,
      rgba(255,255,255,0) 0%,
      rgba(255,255,255,.5) 34%,
      #fff 62%, #fff 100%);
  opacity: 0; transition: opacity 90ms linear;
}
/* Кромка и искры горят, только пока полоса считает (+ короткий выбег).
   Загораются МГНОВЕННО (на записи они есть уже в первом кадре полосы) и
   гаснут плавно — отсюда transition только в погашенном состоянии. */
.mbx-pp-barwrap.is-hot .mbx-pp-edge { opacity: 1; transition: none; }

/* Искры у фронта: короткий крюк с лезвием сверху и две параллельные
   чёрточки снизу-слева. Живут в barwrap, а не в полосе, — та режет всё
   по своим краям (overflow:hidden), а искры на записи выходят за них.
   Смещения посчитаны от фронта заливки на СЕРЕДИНЕ высоты полосы,
   поэтому в них уже заложен скос. */
.mbx-pp-spark {
  position: absolute; left: 0; top: 50%;
  width: 0; height: 0; z-index: 3; pointer-events: none;
  opacity: 0; transition: opacity 90ms linear;
}
.mbx-pp-barwrap.is-hot .mbx-pp-spark { opacity: 1; transition: none; }
.mbx-pp-spark b {
  position: absolute; display: block;
  background: #fff; border-radius: 0.18vmin;
}
.mbx-pp-spark b:nth-child(1) { left: -0.9vmin;  top: -4.5vmin; width: 1.15vmin; height: .8vmin; }
.mbx-pp-spark b:nth-child(2) { left:  0.35vmin; top: -5.2vmin; width: 2.3vmin;  height: .85vmin; transform: rotate(-46deg); }
.mbx-pp-spark b:nth-child(3) { left: -3.6vmin;  top:  2.9vmin; width: 2.2vmin;  height: .85vmin; transform: rotate(-42deg); }
.mbx-pp-spark b:nth-child(4) { left: -2.1vmin;  top:  3.3vmin; width: 1.7vmin;  height: .8vmin;  transform: rotate(-42deg); }

.mbx-pp-bartext {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  transform: skewX(15deg);                 /* компенсация скоса полосы */
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  /* Кегль оригинала — 3.8vmin (капитель «16/20» на записи 24 px). Как и
     в ленте, реальная строка длиннее («24,14₽ / 24,14₽» против «16/20»),
     поэтому размер подгоняется под неё в rewardPoints() (fitText).
     Перенос запрещён: строка обязана остаться одной, иначе она вылезет
     за скошенные края полосы. */
  font-size: 3.8vmin;
  white-space: nowrap;
  font-weight: 800; color: #fff; letter-spacing: .02em;
  --so-c:#150a22;
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  font-variant-numeric: tabular-nums;
}
.mbx-pp-bartext span { display: block; }

/* ---------- «Разблокировано улучшение!» ---------- */
.mbx-pp-levelup {
  position: absolute; left: 50%; top: 84.2%;
  transform: translate(-50%, -50%) scale(.6);
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: min(3.87vmin, 4.3vw);
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  font-weight: 800; color: #fff; white-space: nowrap;
  --so-c:#150a22;
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  opacity: 0;
}
.mbx-pp-levelup.is-on { animation: mbxPpLvl 180ms cubic-bezier(.2,.9,.3,1.35) both; }
@keyframes mbxPpLvl {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.6); }
  65%  { opacity: 1; transform: translate(-50%,-50%) scale(1.1); }
  100% { opacity: 1; transform: translate(-50%,-50%) scale(1); }
}

/* =====================================================================
   ЗВЁЗДНАЯ СИЛА («пассивка») — экран выпадения
   ---------------------------------------------------------------------
   Снято с референсного кадра 1280×720. В отличие от остальных
   экранов Mega Box этот НЕ размечен в vmin: композиция прижата к обоим
   краям кадра (звезда начинается на 25-м пикселе слева, панель кончается
   на 27-м справа), то есть привязана к КАДРУ целиком, а не к его высоте.
   Поэтому кадр референса вписывается в окно как есть:

     --u = один референсный пиксель = min(100vw/1280, 100vh/720)

   а .mbx-sp-frame — прямоугольник ровно 1280×720 таких пикселей,
   отцентрованный в окне. Внутри него все координаты записаны в ПРОЦЕНТАХ
   кадра, то есть один к одному с замерами: 35.43 % ширины — это буквально
   x = 453.5 на референсе. На 16:9 совпадение точное, на других пропорциях
   экран получает поля, а раскладка не плывёт.

   ЗАМЕРЫ (пиксели кадра 1280×720, по 50-процентному переходу цвета):

     звезда (без тени)  x 25…327.6   y 222…529.2   ⇒ 303.4 × 307
     «НИТА»             капитель  y 126…154,  центр всех строк x = 854
     «ЗВЁЗДНАЯ СИЛА»    капитель  y 187…245
     название силы      капитель  y 266…298
     панель (внешняя)   x 453.5…1253.8  y 320.3…513.7,  рамка 6
     портрет в панели   до x = 651 (дальше начинается текст)
     описание           капитель 24, шаг строк 42, центр x = 949.4
     цвета              фон-заливка панели #131A7B, рамка ≈ #131120,
                        голубой текст ≈ #5AEBFF, числа ≈ #17D22A

   Капитель Lilita One = 0.701em, поэтому кегль = замер / 0.701. И ещё
   одно следствие тех же метрик (ascent 923, descent −220): при
   line-height: 1 середина капители попадает на 0.501 высоты строки, то
   есть практически в центр строки. Значит строку можно ставить по ЦЕНТРУ
   КАПИТЕЛИ обычным translateY(-50%) — что здесь и сделано, и поэтому
   кегль можно менять, не пересчитывая координаты.

   ТИПОГРАФИКА. На этом экране у текста НЕТ ни чёрной обводки, ни
   выдавленной тени, которыми набраны остальные экраны сцены: в кадре
   белый заголовок лежит на синем чистой заливкой, а под буквами видно
   лишь узкое мягкое затемнение (2–3 px). Поэтому здесь свои правила, а
   не общие .mbx-title / --mbx-extrude.
   ===================================================================== */
.mbx-sp {
  position: fixed; inset: 0; pointer-events: none;
  display: grid; place-items: center;
  /* 100vw/1280 = 0.078125vw;  100vh/720 = 0.13888889vh */
  --u: min(0.078125vw, 0.13888889vh);
  --sp-cyan:   #5AEBFF;   /* название силы и текст описания */
  --sp-green:  #17D22A;   /* числовые значения в описании */
  --sp-ink:    #131120;   /* рамка панели */
  --sp-panel:  #131A7B;   /* заливка панели */
  --sp-shadow: 0 calc(2 * var(--u)) calc(3 * var(--u)) rgba(4, 8, 40, .55);
}
.mbx-sp-frame {
  position: relative;
  width: calc(1280 * var(--u)); height: calc(720 * var(--u));
}

/* ---------- звезда ----------
   Ширина считается по ПОЛНОЙ картинке, а не по самой звезде: в файле
   снизу запечена мягкая тень (звезда занимает 870×882 из 871×910), и
   если подогнать под замер всю картинку, звезда выйдет мельче кадра.
   303.4 = 303 × 871/870, отсюда 23.703 % ширины кадра. */
.mbx-sp-badge {
  position: absolute; top: 52.847%; left: 50%;
  width: 23.703%;
  transform: translate(-50%, -50%) scale(.1);
  opacity: 0;
  /* Уезд влево — тем же движением, каким текст въезжает справа. */
  transition: left 300ms cubic-bezier(.25,.9,.3,1.1);
  will-change: transform, opacity, left;
}
.mbx-sp-badge img { display: block; width: 100%; height: auto; }
.mbx-sp-badge.is-in { animation: mbxSpPopIn 130ms cubic-bezier(.2,.9,.3,1.3) both; }
.mbx-sp.is-final .mbx-sp-badge { left: 13.805%; }
@keyframes mbxSpPopIn {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.2); }
  65%  { opacity: 1; transform: translate(-50%,-50%) scale(1.12); }
  100% { opacity: 1; transform: translate(-50%,-50%) scale(1); }
}

/* Кольцо-волна, разлетающаяся от звезды сразу после её появления.
   Восьмиугольник звезды повторяется скруглением, а не картинкой. */
.mbx-sp-ring {
  position: absolute; inset: 0;
  border-radius: 26%;
  border: calc(5 * var(--u)) solid #7FE9FF;
  box-shadow: 0 0 calc(20 * var(--u)) #7FE9FF, inset 0 0 calc(20 * var(--u)) #7FE9FF;
  opacity: 0; pointer-events: none;
}
.mbx-sp-ring.is-out { animation: mbxSpRing 320ms cubic-bezier(.1,.7,.3,1) both; }
@keyframes mbxSpRing {
  0%   { transform: scale(.92); opacity: .95; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* Блик по звезде. Маска — сама иконка (путь ставит сцена в
   --mbx-sp-mask), поэтому светлая полоса идёт ПО ЗВЕЗДЕ, а не по
   невидимому квадрату вокруг неё: без маски overflow: hidden давал бы
   прямоугольный засвет в прозрачных углах. */
.mbx-sp-gleam {
  position: absolute; inset: 0;
  background: linear-gradient(115deg,
      rgba(255,255,255,0) 38%, rgba(255,255,240,.95) 50%, rgba(255,255,255,0) 62%);
  opacity: 0; transform: translateX(-130%);
  mix-blend-mode: screen;
  -webkit-mask-image: var(--mbx-sp-mask, none);
          mask-image: var(--mbx-sp-mask, none);
  -webkit-mask-size: 100% 100%;    mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;  mask-repeat: no-repeat;
}
.mbx-sp-gleam.is-sweep { animation: mbxSpGleam 240ms linear both; }
@keyframes mbxSpGleam {
  0%   { transform: translateX(-130%); opacity: 1; }
  85%  { transform: translateX(96%);   opacity: 1; }
  100% { transform: translateX(130%);  opacity: 0; }
}

/* ---------- цена под звездой ----------
   ЕДИНСТВЕННОЕ, чего нет в референсе. Стоит под иконкой и набрана ровно
   как сумма на экране монет (.mbx-amount): белым, с чёрной обводкой и
   выдавленной тенью сцены. Это осознанное исключение из «на этом экране
   обводок нет» — суммы во всём Mega Box выглядят одинаково, и цена
   звёздной силы не должна быть единственной набранной иначе.

   Значение берётся из wallet награды (value: 600 в
   economy/config/boxes.yaml), своей арифметики у экрана нет — разойтись
   с балансом и RTP он не может. */
.mbx-sp-price {
  position: absolute; top: 78.61%; left: 13.805%;
  transform: translate(-50%, -50%);
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: calc(44 * var(--u)); line-height: 1; white-space: nowrap;
  font-weight:900; letter-spacing: .01em; color: #fff;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  opacity: 0;
}
.mbx-sp-price.is-in { animation: mbxSpPop 260ms cubic-bezier(.2,.9,.3,1.25) both; }
@keyframes mbxSpPop {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.55); }
  70%  { opacity: 1; transform: translate(-50%,-50%) scale(1.08); }
  100% { opacity: 1; transform: translate(-50%,-50%) scale(1); }
}

/* ---------- въезд справа ----------
   Заголовки и панель выезжают ОДНИМ куском и одновременно с уездом
   звезды влево, как в оригинале. Слой заголовков накрывает весь кадр
   (inset: 0) не для красоты: как только на нём появляется transform, он
   становится системой отсчёта для своих absolute-детей, и без inset: 0
   проценты строк считались бы от блока нулевого размера.
   Сдвиг задан в референсных пикселях, а не в процентах: у заголовков и
   у панели разная ширина, а уехать за правый край кадра должны оба. */
.mbx-sp-titles { position: absolute; inset: 0; opacity: 0; will-change: transform, opacity; }
.mbx-sp-card   { opacity: 0; will-change: transform, opacity; }
.mbx-sp.is-final .mbx-sp-titles,
.mbx-sp.is-final .mbx-sp-card { opacity: 1; }
.mbx-sp-titles.is-in,
.mbx-sp-card.is-in { animation: mbxSpSlideIn 300ms cubic-bezier(.2,.9,.3,1.15) both; }
@keyframes mbxSpSlideIn {
  0%   { transform: translateX(calc(830 * var(--u))); opacity: 0; }
  70%  { transform: translateX(calc(-10 * var(--u))); opacity: 1; }
  100% { transform: translateX(0);                    opacity: 1; }
}

/* ---------- конечное состояние ----------
   Держится КЛАССОМ, а не доигравшей анимацией. Так и должно быть по
   механике сцены: касание в любой момент означает «сразу финал», и
   settleNow() ставит is-settled. Но это же и страховка: пока экран стоит
   на animation-fill-mode: both, вся раскладка зависит от того, что
   анимация ДОИГРАЛА. Стоит браузеру её не запустить — а в неотрисованной
   вкладке или панели предпросмотра это ровно так и бывает, — и в силе
   остаётся кадр 0 %: звезда размером в пятую часть, панель за правым
   краем. Класс снимает анимацию и задаёт покой напрямую. */
.mbx-sp.is-settled .mbx-sp-badge,
.mbx-sp.is-settled .mbx-sp-titles,
.mbx-sp.is-settled .mbx-sp-card,
.mbx-sp.is-settled .mbx-sp-price { animation: none; opacity: 1; }
/* Переход left тоже снимается: касание в этой сцене везде значит «сразу
   финал», а не «доехать красиво». Штатный вызов settleNow() приходит
   позже конца переезда, так что в обычном темпе снимать нечего. */
.mbx-sp.is-settled .mbx-sp-badge {
  transform: translate(-50%, -50%); transition: none; left: 13.805%;
}
.mbx-sp.is-settled .mbx-sp-titles,
.mbx-sp.is-settled .mbx-sp-card  { transform: none; }
.mbx-sp.is-settled .mbx-sp-ring,
.mbx-sp.is-settled .mbx-sp-gleam { animation: none; opacity: 0; }

.mbx-sp-kicker,
.mbx-sp-title,
.mbx-sp-name {
  position: absolute; left: 66.719%;
  transform: translate(-50%, -50%);
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-weight:900; line-height: 1; white-space: nowrap;
  text-shadow: var(--sp-shadow);
}
/* Трекинг положительный: при кегле, дающем замеренную капитель, набор в
   кадре ШИРЕ, чем даёт шрифт вплотную. Пустота от трекинга добавляется
   и СПРАВА от последней буквы, поэтому строку уводит влево на половину
   добавки — это и компенсирует margin-left. */
.mbx-sp-kicker { top: 19.444%; font-size: calc(41.4 * var(--u));
  letter-spacing: .05em;  margin-left: .025em;  color: #fff; }
.mbx-sp-title  { top: 30.000%; font-size: calc(83.1 * var(--u));
  letter-spacing: .0426em; margin-left: .0213em; color: #fff; }
.mbx-sp-name   { top: 39.167%; font-size: calc(47.1 * var(--u));
  letter-spacing: .027em; margin-left: .0135em; color: var(--sp-cyan); }

/* ---------- панель с портретом и описанием ---------- */
.mbx-sp-card {
  position: absolute;
  left: 35.430%; top: 44.486%; width: 62.523%; height: 26.861%;
  box-sizing: border-box;
  display: flex; align-items: stretch;
  border: calc(6 * var(--u)) solid var(--sp-ink);
  background: var(--sp-panel);
  overflow: hidden;
  box-shadow: 0 calc(3 * var(--u)) calc(6 * var(--u)) rgba(3, 6, 40, .42);
}

/* Портрет владельца силы. Занимает левую четверть панели (до x = 651,
   откуда начинается текстовое поле) и подрезан её краями — в кадре у
   Ниты обрезаны и макушка, и подбородок.

   МАСШТАБ СЧИТАЕТСЯ ПО ВЫСОТЕ, а не по cover. Все шесть вырезок сняты
   вплотную к голове (непрозрачная область = весь холст), но в разных
   пропорциях: Шелли — квадрат 806×806, Брок — 474×401, Мортис —
   555×401. cover тянул бы каждую до ширины колонки, и голова у широких
   вырезок выходила бы мельче, чем у квадратных. Высота 130 % даёт
   голову крупнее панели — как в референсе, где она обрезана и сверху, и
   снизу.

   ПРАВЫЙ КРАЙ РАСТВОРЯЕТСЯ. В кадре силуэт Ниты кончается ВНУТРИ панели
   сам, не доходя до текста: у оригинала вырезка нарисована под эту
   панель. Наши вырезки шире колонки, и обрезка дала бы на этом месте
   бритвенно-ровную вертикаль, которой в кадре нет. Поэтому последние
   10 % колонки уходят в прозрачность — арт растворяется в заливке
   панели, как в референсе, а не упирается в линию. Расширить колонку
   вместо этого нельзя: её правый край — это и есть левый край
   текстового поля, а его положение замерено по кадру. */
.mbx-sp-portrait {
  position: relative; flex: 0 0 24.29%; align-self: stretch; overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, #000 90%, transparent 100%);
          mask-image: linear-gradient(to right, #000 90%, transparent 100%);
}
.mbx-sp-portrait img {
  position: absolute; left: 50%; top: 50%; display: block;
  height: 108%; width: auto; max-width: none;
  transform: translate(-50%, -50%);
}

/* Описание силы. Кегль 33.8 и шаг строк 42 — прямо с кадра; текст
   центрован и по горизонтали, и по вертикали внутри панели.

   ПОЧЕМУ КЕГЛЬ ПОДГОНЯЕТСЯ СКРИПТОМ. В кадре описание Ниты укладывается
   в три строки, и панель построена под них. Наши описания длиннее: у
   Шелли и Спайка при референсном кегле выходит четыре строки — четвёртая
   ещё влезает (4 × 42 = 168 при 181 внутренней высоты), пятая уже нет.
   Растить панель нельзя, её размер и есть замер, поэтому кегль
   уменьшается ровно настолько, чтобы текст поместился (fitDesc() в
   js/megabox.scene.js). Где хватает референсного — там он и стоит, и
   экран совпадает с кадром буква в букву. */
.mbx-sp-desc {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.mbx-sp-desc p {
  margin: 0; text-align: center;
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-weight:900;
  font-size:   calc(var(--sp-desc, 33.8) * var(--u));
  line-height: calc(var(--sp-desc, 33.8) * 1.2426 * var(--u));
  color: var(--sp-cyan);
  text-shadow: var(--sp-shadow);
}
/* Числовые значения — зелёным, как в кадре. */
.mbx-sp-desc b { font-weight: inherit; color: var(--sp-green); }

/* Фон экрана. Готовое полотно (star_power_background.png) — это ВЕСЬ
   кадр целиком: в нём уже и синева, и звёзды, и лёгкое затемнение к
   правому краю. Поэтому у него снимаются и фильтр узора, и виньетка —
   в референсе звёзды одинаково читаются до самых углов. */
.mbx-bg-passive.has-art .mbx-pat { filter: none; }
.mbx-bg-passive.has-art .mbx-vig { background: none; }

/* =====================================================================
   БОНУСЫ — удвоители / гемы / билеты
   ---------------------------------------------------------------------
   Раскладка снята с референса и одинакова для всех трёх:

       БОНУС!          ← kicker, мелко (у гемов его нет)
       ЗАГОЛОВОК       ← крупно, центр блока на 24 % высоты экрана
         [ арт ]       ← центр на 53.5 %
        +400 / x 3     ← число, центр на 78 %

   position:fixed — НЕ для того, чтобы вырваться из сцены, а чтобы
   считать проценты от ЭКРАНА, а не от .sbs-stagearea (та занимает лишь
   78 % кадра, и все отметки уехали бы вниз). Тряска и зум камеры при
   этом сохраняются: у .sbs-camera есть transform, поэтому именно она
   служит контейнером для fixed-потомков.
   ===================================================================== */
.mbx-bonus { position: fixed; inset: 0; pointer-events: none; }

.mbx-bonus-head {
  position: absolute; left: 50%; top: 24%;
  transform: translate(-50%, -50%) scale(1);
  text-align: center; width: 96%;
}
.mbx-bonus-head.is-in { animation: mbxHeadIn 200ms cubic-bezier(.2,.9,.3,1.3) both; }
@keyframes mbxHeadIn {
  0%   { transform: translate(-50%,-50%) scale(.4);  opacity: 0; }
  70%  { transform: translate(-50%,-50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%,-50%) scale(1);   opacity: 1; }
}

/* Мелкая надпись «БОНУС!» над заголовком. Та же обводка, что у
   заголовков сцены, только тоньше — иначе на малом кегле контур
   съедает буквы. */
.mbx-kicker {
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(16px, min(4.4vmin, 5vw), 42px);
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  font-weight: 800; letter-spacing: .015em; color: #fff;
  line-height: 1.1; margin-bottom: .1em;
  /* без обводки — как и крупный заголовок под ним, см. .mbx-title */
  white-space: nowrap;
}

/* Заголовок берёт оформление .mbx-title, но живёт внутри блока-шапки:
   собственное позиционирование и въезд ему не нужны — анимируется вся
   шапка целиком, чтобы «БОНУС!» и заголовок выехали одним куском. */
.mbx-bonus-title {
  position: static; transform: none; animation: none;
  font-size: clamp(22px, min(7.4vmin, 8.4vw), 70px);
  line-height: 1.06;
}

.mbx-bonus-art {
  position: absolute; left: 50%; top: 53.5%;
  width: min(44vmin, 400px); aspect-ratio: 1;
  transform: translate(-50%, -50%) scale(0);
  opacity: 0; will-change: transform, opacity;
}
.mbx-bonus-art img {
  width: 100%; height: 100%; object-fit: contain;
  display: block; -webkit-user-drag: none;
}
/* Пружинный выход и затем еле заметное «дыхание» — предмет в оригинале
   не замирает намертво, а чуть пульсирует, пока ждёт касания. */
.mbx-bonus-art.is-in {
  animation: mbxBonusPop 260ms cubic-bezier(.2,.9,.28,1.35) both,
             mbxBonusIdle 2400ms ease-in-out 260ms infinite;
}
@keyframes mbxBonusPop {
  0%   { transform: translate(-50%,-50%) scale(.15) rotate(-9deg); opacity: 0; }
  55%  { transform: translate(-50%,-50%) scale(1.18) rotate(2.5deg); opacity: 1; }
  78%  { transform: translate(-50%,-50%) scale(.95) rotate(-1deg); opacity: 1; }
  100% { transform: translate(-50%,-50%) scale(1) rotate(0deg); opacity: 1; }
}
@keyframes mbxBonusIdle {
  0%, 100% { transform: translate(-50%,-50%) scale(1); }
  50%      { transform: translate(-50%,-50%) scale(1.035); }
}

/* --mbx-amt-k — множитель кегля из манифеста (amountScale), ставится в
   rewardBonus(). 1 = вровень с заголовком (гемы, билеты), 1.35 = крупнее
   заголовка, как «+400» у удвоителей в оригинале. */
.mbx-bonus-amount {
  --mbx-amt-k: 1;
  position: absolute; left: 50%; top: 78%;
  transform: translate(-50%, -50%) scale(.3);
  opacity: 0;
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(24px, min(calc(7.6vmin * var(--mbx-amt-k)),
                             calc(8.6vw  * var(--mbx-amt-k))), 96px);
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  font-weight: 800; letter-spacing: .01em; color: #fff;
  --so-c:#150a22;
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.mbx-bonus-amount.is-in { animation: mbxAmountIn 200ms cubic-bezier(.2,.9,.3,1.35) both; }
@keyframes mbxAmountIn {
  0%   { transform: translate(-50%,-50%) scale(.3);  opacity: 0; }
  65%  { transform: translate(-50%,-50%) scale(1.14); opacity: 1; }
  100% { transform: translate(-50%,-50%) scale(1);   opacity: 1; }
}

/* =====================================================================
   ИТОГ ОТКРЫТИЯ — «ПОЛУЧЕНО:» из оригинала
   ---------------------------------------------------------------------
   Снято по двум кадрам оригинала: 1863×1282 (только обычные награды) и
   1275×826 (обычные + «БОНУСНЫЕ ПРЕДМЕТЫ:»). Кадры сняты в разных
   пропорциях окна, и это дало главный вывод о раскладке:

     карточка   178 px при ширине 1863  →  9.55 % ШИРИНЫ кадра
     карточка   122 px при ширине 1275  →  9.57 % ШИРИНЫ кадра

   Совпадение до третьего знака по ширине и заметный разброс по высоте
   означают, что ряд наград привязан к ШИРИНЕ экрана, а не к высоте.
   Поэтому базовая величина всего экрана — --cw (ширина карточки), и от
   неё же считается всё остальное, вплоть до кегля заголовков. Потолок
   в 17vmin нужен только сверхшироким окнам, где 9.55vw уже не влезает
   по высоте.

   Замеры кадра 1863×1282, W = ширина карточки = 178 px:

     карточка         178 × 207 px            → 1 W × 1.163 W
     клин под бойцом  ещё 28 px вниз          → 0.157 W
     зазор в ряду     15 px                   → 0.084 W
     белая рамка      4.5 px                  → 0.025 W
     тёмный контур    3 px внутри белой       → 0.017 W
     нижняя губа      +2.8 px белого снизу    → 0.028 W (у клина её нет)
     «ПОЛУЧЕНО:»      капитель 37.5 px        → кегль 0.303 W
     «БОНУСНЫЕ …»     капитель 21/26 от него  → кегль 0.245 W
     число на плашке  капитель 30 px          → кегль 0.235 W
     плашка очков     верх на 137.5 px от верха содержимого → 0.772 W
     пятак очков      Ø 53 px, левое поле 21 px

   Фон — эллиптический радиальный градиент; стопы взяты прямо с кадра
   (профиль по строке через центр), поэтому их шесть, а не два: у CSS
   интерполяция линейная, и двумя стопами середина уходит светлее
   оригинала на добрые 20 единиц зелёного.
   ===================================================================== */
.mbx-bg-sum {
  background: radial-gradient(46% 61% at 50% 53%,
      #00C3FF 0%, #00B1FB 22%, #008EFF 43%,
      #005BE6 65%, #0047D9 79%, #0035D3 100%);
}
.mbx-bg-sum .mbx-vig {
  background: radial-gradient(125% 105% at 50% 50%, rgba(0,0,0,0) 66%, rgba(0,18,60,.28) 100%);
}
/* Лучи на кадре едва читаются — это не «звезда» экрана наград, а лёгкая
   фактура поверх градиента. Отсюда и опорность в .16 → .07: при прежней
   яркости они рисовали на фоне итога полосы, которых в оригинале нет.

   Размер слоя — квадрат со стороной в диагональ кадра, по той же
   причине и тем же способом, что у вращающегося фона удвоителей: слой
   меньше диагонали при повороте перестаёт накрывать углы. Подробности —
   в комментарии к .mbx-bg-bonus .mbx-pat.is-spin выше. */
.mbx-bg-sum .mbx-rays {
  opacity: 1;
  inset: auto; left: 50%; top: 50%;
  width:       min(142vmax, calc(100vw + 100vh));
  height:      min(142vmax, calc(100vw + 100vh));
  margin-left: calc(min(142vmax, calc(100vw + 100vh)) / -2);
  margin-top:  calc(min(142vmax, calc(100vw + 100vh)) / -2);
  width:       hypot(100vw, 100vh);
  height:      hypot(100vw, 100vh);
  margin-left: calc(hypot(100vw, 100vh) / -2);
  margin-top:  calc(hypot(100vw, 100vh) / -2);
  background: repeating-conic-gradient(from 4deg,
      rgba(255,255,255,.07) 0deg 5deg, rgba(255,255,255,0) 5deg 13deg);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 58%);
          mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 58%);
  animation: mbxSumRays var(--mbx-sum-spin, 48s) linear infinite;
}
@keyframes mbxSumRays { to { transform: rotate(360deg); } }

/* Дыхание центрального свечения — отдельным слоем, чтобы не мешать
   вращению лучей их же трансформом. */
.mbx-bg-sum .mbx-glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(58% 62% at 50% 53%,
      rgba(255,255,255,.10) 0%, rgba(255,255,255,0) 70%);
  animation: mbxSumGlow 5.2s ease-in-out infinite;
}
@keyframes mbxSumGlow {
  0%, 100% { opacity: .45; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.09); }
}

@media (prefers-reduced-motion: reduce) {
  .mbx-bg-sum .mbx-rays, .mbx-bg-sum .mbx-glow { animation: none; }
}

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

   Экран делится на ДВА яруса с фиксированной долей высоты, и это не
   украшательство: наши органы управления (сумма, «ПРОДАТЬ», «ЗАБРАТЬ»)
   обязаны стоять на одном и том же месте независимо от того, выпала
   бонусная секция или нет. Если сложить всё в один центрированный
   столбец, лишний ряд карточек сдвигал бы кнопки вниз на четверть
   экрана — и игрок промахивался бы по «ПРОДАТЬ», привыкнув к прошлому
   открытию. Верхний ярус центрирует награды внутри себя (ровно как
   оригинал центрирует их в кадре), нижний держит панель.
   --------------------------------------------------------------------- */
.sbs-root .mbx-sum {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  --cw: clamp(52px, min(9.55vw, 17vmin), 220px);
  /* производные от ширины карточки — см. таблицу замеров выше */
  --c-h:    calc(var(--cw) * 1.163);   /* прямоугольная часть        */
  --c-v:    calc(var(--cw) * 0.157);   /* клин под карточкой бойца   */
  --c-fr:   calc(var(--cw) * 0.025);   /* белая рамка                */
  --c-lip:  calc(var(--cw) * 0.028);   /* добавка белого снизу       */
  --c-dk:   calc(var(--cw) * 0.017);   /* тёмный контур внутри белой */
  --c-gap:  calc(var(--cw) * 0.084);   /* зазор между карточками     */
  /* Плашка очков силы: высота строки и диаметр пятака. На кадре пятак
     занимает всю строку (0.29 W при кегле числа 0.235 W), но там число
     двузначное. У нас в строке стоит сумма в ₽, она вчетверо длиннее, и
     пятак прежнего размера съедал место, которого и так не хватает, —
     да и рядом с ужатым числом выглядел непропорционально крупным. */
  --pp-row: calc(var(--cw) * 0.30);    /* высота строки в плашке     */
  --pp-ico: calc(var(--cw) * 0.235);   /* сам пятак                  */
  --pp-top: calc((var(--c-h) - var(--cw) * .772 - var(--c-fr)
                  - var(--cw) * .022 - var(--pp-row)) / 2);
  --c-ink:  #16101f;
  /* Обводка и выдавка НЕ переопределяются: и то и другое приходит из
     .sbs-root (0.1em по --mbx-ink плюс десятислойная --mbx-extrude до
     0.155em) и одинаково для всех надписей Mega Box — цены на выпадении,
     «+N» на ленте, числа на итоге. Свой, более короткий вариант тут
     когда-то стоял ради буквального совпадения с кадром, но разъезжался
     с остальными экранами. */
  background: none; border: 0; box-shadow: none;
  max-height: none;
  opacity: 0; transform: scale(.94);
  transition: opacity 180ms ease, transform 180ms cubic-bezier(.2,.9,.3,1.2);
  pointer-events: auto;
}
.sbs-root .mbx-sum.is-in { opacity: 1; transform: scale(1); }

.mbx-sum-top {
  flex: 0 0 74%;
  display: flex; flex-direction: column; align-items: center;
  /* safe center: если наград столько, что ярус переполнен, обычный
     center режет ВЕРХ — «ПОЛУЧЕНО:» уезжает за край и его не
     отскроллить. safe center в этом случае прижимает к началу.
     Первая строка — запасной вариант для браузеров без safe. */
  justify-content: center;
  justify-content: safe center;
  padding: calc(var(--cw) * .1) 2vw 0;
  overflow: auto;
}

/* ---------- заголовки секций ---------- */
.mbx-sum-h, .mbx-sum-h2 {
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-weight:900; white-space: nowrap;
  line-height: 1;
  /* Разрядка снята с кадра поглазурно: ink-ширина «ПОЛУЧЕНО:» там 294 px
     при капители 38, у Lilita без разрядки выходит 280. Ширины самих
     букв совпадают до пикселя — расходятся только боковые поля, и
     недостающие 14 px раскладываются на 8 межбуквенных зазоров. */
  letter-spacing: .062em;
  /* пробел Lilita (0.188em) вдвое уже, чем нужно: на записи межсловный
     зазор равен 0.56 высоты капители, добавка выводит его на 0.54 */
  word-spacing: .16em;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude);
}
/* Ни один из двух заголовков не белый: на обоих кадрах «ПОЛУЧЕНО:»
   залито светлой бирюзой, а «БОНУСНЫЕ ПРЕДМЕТЫ:» — бледно-жёлтым. */
.mbx-sum-h  { font-size: calc(var(--cw) * .303); color: #7BE9F3; }
.mbx-sum-h2 { font-size: calc(var(--cw) * .245); color: #EEF182; }

/* Отступы под заголовками сняты с кадров: от нижнего края НАДПИСИ до
   верха карточек 0.234 W у «ПОЛУЧЕНО:» и столько же долей своего кегля у
   бонусного. Из этого вычтена высота строки под капителью и выдавка:
   общая выдавка сцены (0.155em) длиннее той, что на кадре (0.10em), и
   без поправки заголовок сел бы к карточкам ближе, чем в оригинале. */
.mbx-sum-h  { margin: 0 0 calc(var(--cw) * .170); }
.mbx-sum-h2 { margin: calc(var(--cw) * .308) 0 calc(var(--cw) * .171); }

/* ---------- ряд карточек ---------- */
.mbx-sum-row {
  display: flex; flex-wrap: wrap; justify-content: center;
  /* верх у всех карточек общий, а низ — нет: клин карточки бойца
     свисает ниже прямоугольных соседей. Поэтому flex-start, а не
     stretch: иначе монеты растянулись бы до высоты клина. */
  align-items: flex-start;
  gap: var(--c-gap);
  max-width: 100%;
}

/* ---------------------------------------------------------------------
   КАРТОЧКА НАГРАДЫ

   Три вложенных слоя с ОДНИМ И ТЕМ ЖЕ clip-path — это единственный
   способ дать белой рамке и тёмному контуру повторить клин карточки
   бойца. border так не умеет: clip-path срезал бы его вместе с фоном.

   Одинаковый полигон на всех трёх слоях законен, хотя каждый следующий
   слой меньше на толщину рамки. Проверено арифметикой: параллельный
   перенос рёбер клина внутрь на 0.025 W переносит «плечо» с 88.10 % на
   88.16 %, а остриё — на 99.91 %. Погрешность в четверть пикселя при
   ширине карточки 178 px, то есть меньше сглаживания.

   Внешний тёмный ореол сделан drop-shadow'ом, а не четвёртым слоем:
   он не должен участвовать в раскладке, иначе зазор между карточками
   пришлось бы уменьшать на его толщину.
   --------------------------------------------------------------------- */
/* Слот — то, что кликается, и то, что двигается при выборе. Карточка
   внутри него может быть обрезана по клину (см. .mbx-sc-pp), а слот —
   нет, поэтому галочка выбора лежит именно здесь: внутри карточки её
   срезало бы тем же clip-path. */
.mbx-sc-slot {
  position: relative; flex: 0 0 auto;
  width: var(--cw); cursor: pointer;
  transition: transform 160ms cubic-bezier(.2,.9,.3,1.4);
}
.mbx-sc {
  position: relative;
  width: 100%; height: var(--c-h);
  box-sizing: border-box;
  padding: var(--c-fr) var(--c-fr) calc(var(--c-fr) + var(--c-lip));
  background: #fff;
  filter: drop-shadow(0 0 calc(var(--cw) * .016) rgba(2,10,45,.6));
}
.mbx-sc-fr {
  width: 100%; height: 100%; box-sizing: border-box;
  padding: var(--c-dk);
  background: var(--c-ink);
}
.mbx-sc-bd {
  position: relative;
  width: 100%; height: 100%;
  overflow: hidden;
  background: #10193a;
}
/* Арт карточки — ЦЕЛОЕ полотно (файлы get_*.png нарисованы под
   всю карточку: свой фон, свой рисунок, своя цветная полоса снизу),
   поэтому cover, а не contain. */
.mbx-sc-art {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%;
  display: block;
}

/* Число на карточке. Отступ проверен по кадру напрямую: там низ капители
   стоит на 84.9 % высоты карточки. При .113 W выходило 81.2 % — число
   заметно висело над цветной полосой вместо того, чтобы лежать на ней. */
.mbx-sc-n {
  position: absolute; left: 2%; right: 2%;
  bottom: calc(var(--cw) * .07);
  text-align: center; line-height: 1;
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: calc(var(--cw) * .235);
  font-weight:900; color: #fff;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude);
  white-space: nowrap;
}
/* Суммы в ₽ длиннее игровых «318» и на узкой карточке не помещаются.
   Ужимает их сцена (fitText): она ставит --fit, а не правит font-size,
   чтобы обводка и выдавка, заданные в em, ужимались вместе с текстом и
   не толстели относительно букв. */
.mbx-sc-n > span,
.mbx-sc-cap > span,
.mbx-sc-banner > span {
  display: inline-block;
  transform: scale(var(--fit, 1));
  transform-origin: 50% 100%;
}

/* ---------- карточка бойца: клин + фиолетовая плашка ---------- */
.mbx-sc-pp {
  height: calc(var(--c-h) + var(--c-v));
  /* у клина нижней губы нет — на кадре белая рамка вдоль скосов ровно
     такая же, как по бокам */
  padding: var(--c-fr);
  clip-path: polygon(0 0, 100% 0, 100% 88.1%, 50% 100%, 0 88.1%);
}
.mbx-sc-pp .mbx-sc-fr,
.mbx-sc-pp .mbx-sc-bd {
  clip-path: polygon(0 0, 100% 0, 100% 88.1%, 50% 100%, 0 88.1%);
}
/* Портрет обрезается сверху: в файле бойца снизу впечатана плашка с
   именем (см. images.brawlers в манифесте), а на итоге имени нет.
   object-position прижимает картинку к верху, и плашка уходит за
   нижнюю границу окна портрета. */
.mbx-sc-face {
  position: absolute; left: -9%; top: 0;
  /* width обязателен: у абсолютно позиционированного <img> auto-ширина
     берётся из СОБСТВЕННЫХ пропорций картинки и заданной высоты, а не
     из пары left/right (CSS 2.1, 10.3.8). Без него портрет 466×494
     сжимался бы в 89 px вместо 112 и вылезала бы плашка с именем. */
  /* 118 % ширины со сдвигом влево — не украшательство: у файлов бойцов
     по краю идёт чёрная рамка со скруглёнными углами (это карточка
     целиком, см. images.brawlers в манифесте), а в оригинале портрет
     лежит в окне встык. Наезд на 9 % с каждой стороны срезает рамку
     вместе с углами; по вертикали то же делает object-position, он же
     уводит вниз за край окна плашку с именем. */
  width: 118%; height: calc(var(--cw) * .772);
  object-fit: cover; object-position: 50% 30%;
  display: block;
}
.mbx-sc-banner {
  position: absolute; left: 0; right: 0; bottom: 0;
  top: calc(var(--cw) * .772);
  border-top: calc(var(--cw) * .022) solid var(--c-ink);
  background: #B423FE;
  display: flex; align-items: flex-start;
  /* На кадре левое поле до края пятака — 0.142 W. У нас оно 0.12 W, и
     это единственная уступка в геометрии карточки: место справа от
     пятака занимает не двузначное число оригинала, а сумма вида
     «12,09 ₽», и каждая сотая доля W там на счету (см. кегль ниже). */
  gap: calc(var(--cw) * .025);
  padding: 0 0 0 calc(var(--cw) * .12);
}
/* Пятак и число выровнены по середине ПРЯМОУГОЛЬНОЙ части плашки —
   клин в расчёт не идёт, иначе оба уехали бы вниз вслед за остриём.
   Отсюда фиксированная высота строки вместо центрирования по флексу. */
.mbx-sc-banner > * { margin-top: var(--pp-top); }
/* Пятак мельче строки, поэтому к общему отступу добавляется половина
   разницы — так его центр совпадает с центром числа. */
.mbx-sc-banner .mbx-pp-ico {
  width: var(--pp-ico); height: var(--pp-ico);
  margin-top: calc(var(--pp-top) + (var(--pp-row) - var(--pp-ico)) / 2);
}
/* Кегль числа в плашке МЕНЬШЕ, чем на кадре (.235 W), и это вынужденно.
   Замеры реальных ширин при .235 W (доли ширины карточки):

     «14» из оригинала   0.237 W      место справа от пятака   0.39 W
     «0,4 ₽»             0.524 W
     «4,25 ₽»            0.622 W
     «12,09 ₽»           0.736 W

   Двузначное число оригинала занимает чуть больше половины свободного
   места, а наша сумма — вдвое больше, чем его есть. При .20 W типичная
   сумма не дотягивает совсем немного, и остаток добирает общий на весь
   ряд множитель из fitAll (см. megabox.scene.js): ряд ужимается целиком
   и потому остаётся однородным. Оставить кегль кадра (.235 W) значило бы
   ужимать сильнее — до 0.65 вместо 0.77, то есть отдать больше, чем
   выигрывается. */
.mbx-sc-banner > span {
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-size: calc(var(--cw) * .20);
  font-weight:900; color: #fff; line-height: var(--pp-row);
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude);
  white-space: nowrap;
  transform-origin: 0 50%;
}

/* ---------------------------------------------------------------------
   ПРЕДМЕТ — карточка, которой в оригинале нет
   ---------------------------------------------------------------------
   В Brawl Stars из ящика не выпадает ничего продаваемого, поэтому
   образца для этой карточки в кадрах нет. Собрана из тех же деталей,
   что и остальные: та же рамка, тот же контур, тот же кегль числа.
   Отличает её только заливка по редкости и имя над суммой.
   --------------------------------------------------------------------- */
.mbx-sc-item { --li: #7f8db3; }
.mbx-sc-item .mbx-sc-bd {
  background:
    radial-gradient(90% 62% at 50% 34%, color-mix(in srgb, var(--li) 62%, #ffffff) 0%,
                                        color-mix(in srgb, var(--li) 88%, #000000) 72%),
    var(--li);
}
.mbx-sc-item.sbs-r-rare { --li: #21B8D6; }
.mbx-sc-item.sbs-r-super_rare { --li: #3E7BE0; }
.mbx-sc-item.sbs-r-epic { --li: #9333EA; }
.mbx-sc-item.sbs-r-mythic { --li: #E11D48; }
.mbx-sc-item.sbs-r-legendary { --li: #F59E0B; }
.mbx-sc-item.sbs-r-star_power { --li: #EAB308; }

/* Арт предмета — маленькая иконка, а не полотно: contain и поле сверху,
   чтобы под ней остались две строки подписи. */
/* width/height обязаны быть заданы явно, а не выведены из inset: у
   абсолютно позиционированной КАРТИНКИ auto-размер берётся из её
   собственных пикселей (CSS 2.1, 10.3.8), и арт 2048×2048 лёг бы на
   карточку в натуральную величину, накрыв её целиком. */
.mbx-sc-item .mbx-sc-art {
  inset: 5% auto auto 8%;
  width: 84%; height: 45%;
  object-fit: contain;
  filter: drop-shadow(0 calc(var(--cw) * .012) 0 rgba(6,10,30,.45));
}
/* Карточка без подписи (звёздная сила): строки имени нет, и арт
   разворачивается на её высоту. Низ поднят до 70 % — прямо над верхом
   капители суммы: она стоит на .07 W от низа кеглем .235 W, то есть при
   высоте карточки 1.163 W её верх приходится на 73.8 %. */
.mbx-sc-item.mbx-sc-noname .mbx-sc-art {
  inset: 4% auto auto 6%;
  width: 88%; height: 66%;
}
/* Имя стоит НАД суммой, а не под ней: сумму ищут глазами первой, и
   нижнее место — её. Отступ считается так, чтобы строка имени села
   ровно над строкой суммы: .07 W (низ суммы) + .235 W (её кегль) +
   зазор. */
.mbx-sc-cap {
  position: absolute; left: 4%; right: 4%;
  bottom: calc(var(--cw) * .332);
  text-align: center; line-height: 1;
  font-family: "MegaBoxFont", "Arial Black", "Segoe UI", system-ui, sans-serif;
  font-weight:900;
  font-size: calc(var(--cw) * .115);
  color: #fff;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   ВЫБОР «ОСТАВИТЬ СЕБЕ»
   ---------------------------------------------------------------------
   Отмечается ЛЮБАЯ награда, а не только предмет: в инвентарь уходят и
   монеты, и очки силы, и бонусы (см. claimAll в js/smallbox.logic.js).

   Отмеченная карточка приподнимается, белая рамка становится зелёной со
   свечением, а в углу появляется галочка. Три независимых признака
   (положение, цвет, значок) — потому что одного цвета мало: на золотой
   карточке монет и на легендарном арте зелёная рамка потерялась бы в
   самом рисунке, а сдвиг и галочка читаются на любой заливке.
   --------------------------------------------------------------------- */
.mbx-sc-slot:hover { transform: translateY(calc(var(--cw) * -.02)); }
.mbx-sc-slot.is-keep { transform: translateY(calc(var(--cw) * -.055)) scale(1.045); }
.mbx-sc-slot.is-keep .mbx-sc {
  background: #4BE86A;
  filter: drop-shadow(0 0 calc(var(--cw) * .07) rgba(75,232,106,.95))
          drop-shadow(0 0 calc(var(--cw) * .16) rgba(75,232,106,.55))
          drop-shadow(0 calc(var(--cw) * .035) calc(var(--cw) * .035) rgba(2,10,45,.55));
}
.mbx-sc-slot.is-keep .mbx-sc-fr { background: #10381a; }
.mbx-sc { transition: background-color 160ms ease, filter 160ms ease; }

/* Галочка. Лежит в слоте, НАД карточкой, но ВНУТРИ её габарита: зазор
   между карточками 0.084 W, и значок, вынесенный за угол, наезжал бы на
   соседа — глазу непонятно, которая из двух карточек отмечена. */
.mbx-sc-tag {
  position: absolute; z-index: 2;
  top: calc(var(--cw) * .03); right: calc(var(--cw) * .03);
  width: calc(var(--cw) * .26); height: calc(var(--cw) * .26);
  border-radius: 50%;
  background: linear-gradient(180deg, #74F58C 0%, #2BC24A 100%);
  box-shadow: 0 0 0 calc(var(--cw) * .022) var(--c-ink);
  display: grid; place-items: center;
  opacity: 0; transform: scale(.4);
  transition: opacity 140ms ease, transform 160ms cubic-bezier(.2,.9,.3,1.6);
  pointer-events: none;
}
.mbx-sc-tag::before {
  content: ''; display: block;
  width: 46%; height: 26%;
  border-left: calc(var(--cw) * .035) solid #fff;
  border-bottom: calc(var(--cw) * .035) solid #fff;
  transform: rotate(-45deg) translate(6%, -22%);
}
.mbx-sc-slot.is-keep .mbx-sc-tag { opacity: 1; transform: scale(1); }

/* ---------------------------------------------------------------------
   НИЖНЯЯ ПАНЕЛЬ — целиком наша, оригиналу неизвестна
   --------------------------------------------------------------------- */
.mbx-sum-ctl {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: calc(var(--cw) * .10);
  padding: 0 2vw calc(var(--cw) * .12);
}
.mbx-sum-total {
  font-family: "MegaBoxFont", "Arial Black", system-ui, sans-serif;
  font-weight:900;
  font-size: calc(var(--cw) * .175); color: #CFE9FF;
  letter-spacing: .02em; word-spacing: .16em; line-height: 1;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude);
  white-space: nowrap;
}
.mbx-sum-total b { color: #FFE45C; font-weight: 400; }

/* Кнопки стоят в одной строке, подписи — под своей кнопкой, поэтому
   каждая пара завёрнута в свой столбец, а не разложена в общий грид.
   Столбцы выровнены по НИЗУ: кнопки разной высоты, и при выравнивании
   по верху подписи под ними разъехались бы по вертикали. */
.mbx-sum-acts {
  display: flex; align-items: flex-end; justify-content: center;
  gap: calc(var(--cw) * .18);
}
.mbx-sum-act { display: flex; flex-direction: column; align-items: center; gap: calc(var(--cw) * .07); }

.mbx-btn {
  position: relative;
  border: 0; cursor: pointer; display: block;
  border-radius: calc(var(--cw) * .09);
  font-family: "MegaBoxFont", "Arial Black", system-ui, sans-serif;
  font-weight:900; color: #fff; line-height: 1;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  white-space: nowrap;
  transition: transform 90ms ease, box-shadow 90ms ease, filter 140ms ease;
}
.mbx-btn:hover { filter: brightness(1.08); }
.mbx-btn:active { transform: translateY(var(--btn-lift)); box-shadow: none; }

/* «ПРОДАТЬ» — главное действие, поэтому она крупнее и зелёная. */
/* Обе кнопки одного размера и одной формы — различает их только цвет.

   Место под приписку «кроме N» зарезервировано нижним полем, а сама она
   позиционируется абсолютно. Если бы приписка занимала строку в потоке,
   кнопка на первой же отмеченной награде подрастала бы, и вместе с ней
   прыгала бы вся панель — то есть ровно то, чего экран обязан избегать.
   Пустая приписка есть и у «Забрать»: без неё низ у кнопок разошёлся бы
   на высоту этой строки. */
.mbx-btn-sell, .mbx-btn-keep {
  --btn-lift: calc(var(--cw) * .035);
  padding: calc(var(--cw) * .105) calc(var(--cw) * .3) calc(var(--cw) * .19);
  font-size: calc(var(--cw) * .245);
}
.mbx-btn-sell {
  background: linear-gradient(180deg, #63E06E 0%, #34B747 100%);
  box-shadow: 0 var(--btn-lift) 0 #1C7A2E,
              0 calc(var(--cw) * .07) calc(var(--cw) * .07) rgba(2,10,45,.45);
}
.mbx-btn-keep {
  background: linear-gradient(180deg, #55B8FF 0%, #2278DE 100%);
  box-shadow: 0 var(--btn-lift) 0 #14508F,
              0 calc(var(--cw) * .07) calc(var(--cw) * .07) rgba(2,10,45,.45);
}
/* «кроме 2» — приписка внутри кнопки, строкой под словом. */
.mbx-btn-sub {
  position: absolute; left: 0; right: 0;
  bottom: calc(var(--cw) * .055);
  font-size: .44em; color: #DFFFE2; text-align: center;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
}

.mbx-sum-note {
  font-family: "MegaBoxFont", "Arial Black", system-ui, sans-serif;
  font-weight:900;
  font-size: calc(var(--cw) * .118); line-height: 1.15;
  color: #CFE3F7; text-align: center; word-spacing: .16em;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  max-width: calc(var(--cw) * 2.3);
}
.mbx-sum-note b { color: #8CF59B; font-weight: 400; }

/* Подсказка оформлена плашкой-таблеткой с пятаком «i» — так она сделана
   в оригинале (соотношения сняты с референсного кадра, где плашка
   786x73 px при кегле 31 px).

   Все размеры плашки заданы в em, то есть в долях СВОЕГО кегля, а не в
   долях --cw, как остальной экран. Причина: пятак и поля обязаны
   держаться за букву. Строка тут единственная на экране, которая может
   перенестись (длинная фраза, узкий телефон), и на переносе плашка
   растёт по тексту — доли --cw оставили бы кружок прежним, и он повис
   бы сбоку от двухстрочного текста серединой в пустоте.
     высота     2.353em      пятак        1.822em
     поле слева 0.596em      зазор до текста 0.565em
     поле справа 0.968em  (справа больше: слева поле меряется до круга,
                           а круг сам по себе оптически «поджимает» край)

   Заливка — не свой цвет, а чёрный в 11.5 %. В оригинале плашка ровно
   на столько темнее фона в ЛЮБОЙ своей точке (замер сверху и снизу
   плашки даёт один и тот же множитель 0.885), а фон экрана —
   вертикальный градиент: сплошной цвет разошёлся бы с ним либо
   поверху, либо понизу. */
.mbx-sum-hint {
  display: flex; align-items: center; justify-content: center;
  gap: .565em;
  min-height: 2.353em;
  max-width: 92%;
  padding: .3em .968em .3em .596em;
  border-radius: 999px;
  background: rgba(0, 0, 0, .115);

  font-family: "MegaBoxFont", "Arial Black", system-ui, sans-serif;
  font-weight:900;
  font-size: calc(var(--cw) * .118); line-height: 1.15;
  color: #EAF5FF; text-align: center; word-spacing: .16em;
  --so-c:var(--mbx-ink, #150a22);
  text-shadow:var(--so), var(--mbx-extrude, 0 0.155em 0 #150a22);
  margin-top: calc(var(--cw) * .04);
}
/* Пятак. Кружок нарисован во всю картинку, поэтому contain, а не cover:
   при cover круг обрезался бы по краям на любом отклонении от квадрата. */
.mbx-hint-ico {
  flex: 0 0 auto;
  width: 1.822em; height: 1.822em;
  background: url("../assets/cases/megabox/images/info_icon.webp") center / contain no-repeat;
}
/* Нечего оставлять себе — подсказка врала бы. Гасится visibility, а не
   display: панель обязана сохранять высоту, иначе кнопки подпрыгнут
   относительно прошлого открытия. */
.mbx-sum.no-items .mbx-sum-hint { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .sbs-root .mbx-sum { transition: none; }
  .mbx-sc-slot, .mbx-sc, .mbx-sc-tag { transition: none; }
}

/* быстрый режим сцены сжимает и наши one-shot анимации */
.sbs-root.is-fast .mbx-sp-badge.is-in,
.sbs-root.is-fast .mbx-sp-titles.is-in,
.sbs-root.is-fast .mbx-sp-card.is-in,
.sbs-root.is-fast .mbx-sp-price.is-in,
.sbs-root.is-fast .mbx-bonus-head.is-in,
.sbs-root.is-fast .mbx-bonus-amount.is-in { animation-duration: 90ms; }
/* Переезд звезды влево — не анимация, а переход, поэтому сжимается
   отдельно. Иначе в ускорении текст успевал бы въехать раньше, чем
   звезда освободит центр. */
.sbs-root.is-fast .mbx-sp-badge { transition-duration: 90ms; }
/* у арта две анимации: сжимаем только пружину, «дыхание» оставляем как есть */
.sbs-root.is-fast .mbx-bonus-art.is-in { animation-duration: 90ms, 2400ms; }

@media (prefers-reduced-motion: reduce) {
  .mbx-title, .mbx-amount,
  .mbx-sp-ring.is-out, .mbx-sp-gleam.is-sweep,
  .mbx-sp-badge.is-in, .mbx-sp-titles.is-in,
  .mbx-sp-card.is-in, .mbx-sp-price.is-in,
  .mbx-bonus-head.is-in, .mbx-bonus-amount.is-in { animation-duration: 1ms; }
  .mbx-sp-badge { transition: none; }
  .mbx-bonus-art.is-in { animation: mbxBonusPop 1ms both; }
  .mbx-bg-bonus .mbx-pat.is-spin { animation: none; }
}
