/* =====================================================================
   site.css — оболочка сайта MegaDrop в стиле Brawl Stars
   ---------------------------------------------------------------------
   Витрина подогнана под ту же графику, что и сцена Mega Box: тот же
   шрифт (Lilita One через семейство "MegaBoxFont" из megabox.scene.css),
   та же обводка 0.1em с выдавкой вниз, те же кнопки-«плитки» с жёсткой
   нижней тенью и синий фон из background.mp4.

   Модалки открытия, профиль и авторизация СЮДА НЕ ВХОДЯТ — у них свои
   файлы (case.css, profile.css, auth.css) и своя тёмно-фиолетовая тема.
   ===================================================================== */

/* =====================================================================
   ШРИФТ САЙТА
   ---------------------------------------------------------------------
   Объявление переехало сюда из megabox.scene.css. Причина — загрузка:
   тот файл весит 33 КБ в сжатом виде (самый тяжёлый стиль сайта) и
   нужен только сцене открытия, поэтому в main.html он теперь грузится
   отложенно и первую отрисовку не задерживает. А шрифт нужен СРАЗУ:
   им набраны логотип, заголовки полок, названия и цены ящиков.
   site.css грузится первым и не откладывается — здесь объявлению и
   место.

   WOFF2 ПЕРВЫМ, TTF ЗАПАСНЫМ. Тот же файл, пережатый: 34 684 байта
   против 13 880, на 60 % легче. На критическом пути разница двойная —
   шрифт стоит в preload, и сервер его НЕ сжимает (в _COMPRESSIBLE у
   server/app.py только text/ и скрипты), то есть 34 КБ уходили по
   проводу как есть. Начертание совпадает попиксельно: сравнение кадра
   с «МАЛЕНЬКИЙ ЯЩИК» до и после дало 0 отличающихся пикселей из 29 700.
   Строка с ttf оставлена следом — woff2 не понимают только браузеры
   старше 2016 года.

   ДИАПАЗОН ВЕСА 400 900, А НЕ ОДНО ЗНАЧЕНИЕ. Переписывать его на
   900 900 НЕЛЬЗЯ: диапазон покрывает и 800, которым набрана сцена, и
   400, которое ещё встречается в чужих правилах, — на любом из них
   начертание берётся как есть, без синтетического жира. Полный разбор,
   почему у семейства везде просят 900, — в шапке megabox.scene.css.
   ===================================================================== */
@font-face {
  font-family: "MegaBoxFont";
  src: url("../assets/cases/megabox/fonts/lilitaone.woff2") format("woff2"),
       url("../assets/cases/megabox/fonts/lilitaone.ttf") format("truetype");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

:root{
  --bg-deep:#062a70;
  --blue-1:#2a72e6;
  --blue-2:#14459f;
  --blue-3:#0c3183;
  --blue-deep:#08245f;
  --panel:rgba(9,42,116,.62);
  --panel-line:rgba(255,255,255,.16);
  --text:#FFFFFF;
  --text-dim:#BBD6F5;
  --gold:#FFE45C;
  --green-1:#63E06E;
  --green-2:#34B747;
  --green-sh:#1C7A2E;
  --btn-blue-1:#55B8FF;
  --btn-blue-2:#2278DE;
  --btn-blue-sh:#14508F;
  --ink:#150a22;

  /* Выдавка под текст — та же стопка копий, что и в сцене: одиночная
     тень отрывается от тонких мест глифа, поэтому 10 копий с шагом
     0.0155em дают сплошную плиту на всю глубину 0.155em. */
  --extrude:
    0 0.0155em 0 var(--ink), 0 0.031em  0 var(--ink),
    0 0.0465em 0 var(--ink), 0 0.062em  0 var(--ink),
    0 0.0775em 0 var(--ink), 0 0.093em  0 var(--ink),
    0 0.1085em 0 var(--ink), 0 0.124em  0 var(--ink),
    0 0.1395em 0 var(--ink), 0 0.155em  0 var(--ink);

  /* =================================================================
     ОБВОДКА ГЛИФОВ — ТЕНЯМИ, А НЕ -webkit-text-stroke.
     -----------------------------------------------------------------
     ПОЧЕМУ НЕ ОБВОДКОЙ. Пара «-webkit-text-stroke + paint-order» рисует
     кант ровнее и дешевле — но в WebKit (Safari, то есть ВЕСЬ iPhone и
     iPad: там любой браузер поверх WebKit) элемент с любым непустым
     paint-order ТЕРЯЕТ свой text-shadow. Выдавка под буквами просто не
     печатается. Проверено на самом движке (playwright webkit, кегль
     16.8 px, DPR 3): у «НОСТАЛЬГИЯ 2019-2020» под строкой в Chrome идёт
     сплошная плита в 8 device-px, в WebKit — 3, и это не выдавка, а
     нижняя дуга самой обводки. Обводка при этом на месте, поэтому со
     стороны это читается как «текст поехал»: половина надписей с
     выдавкой, половина без. Хуже того, решение о печати тени WebKit
     принимает заново на каждую перерисовку слоя — при прокрутке выдавка
     то появляется, то пропадает, и надписи мерцают. Именно это и было
     на присланном снимке с iPhone: у «НОСТАЛЬГИЯ 2019-2020» выдавка
     осталась только под «Я» и последним «0», у остальных букв её нет.
     Обойти нельзя: тень пропадает и при paint-order одним словом
     (paint-order:stroke), и вовсе БЕЗ -webkit-text-stroke — ломает сам
     paint-order, а не обводка. Значит, от него надо уходить.

     ЧТО ВМЕСТО. Кольцо из 16 копий тени радиусом --so-r. Это то же
     построение, что даёт paint-order:stroke fill: кант нарастает
     НАРУЖУ, заливка остаётся целой (тени всегда печатаются под
     текстом). Радиус — половина прежней толщины обводки: stroke шёл по
     СЕРЕДИНЕ контура, то есть наружу уходила половина. Отсюда
     0.1em → 0.05em, 0.09em → 0.045em, 0.08em → 0.04em.
     Замер подтверждает равенство: в Chrome старый и новый набор дают
     среднее расхождение 0.27 из 255 на кегле 10, 17, 38 и 100 px.

     ПОЧЕМУ 16 КОПИЙ. Кольцо — многоугольник, между копиями остаются
     фестоны глубиной r*(1-cos(180°/N)). При N=16 это 0.019r: даже на
     кегле 100 px (r = 5 px) — 0.1 px, то есть меньше пикселя на любом
     экране. N=8 дало бы 0.076r и на крупном кегле уже читалось бы.

     КАК ПОЛЬЗОВАТЬСЯ. text-shadow:var(--so),var(--extrude) — кольцо
     идёт ПЕРВЫМ: тени печатаются в порядке списка, и выдавка должна
     лечь под кант, а не поверх. Цвет и радиус правятся на месте:
     --so-c:var(--fb-glyph-ink); --so-r:.045em;
     ================================================================= */
  --so-c:var(--ink);
  --so-r:0.05em;
  --so:
    calc(var(--so-r) *  1.000) 0 0 var(--so-c),
    calc(var(--so-r) *  0.924) calc(var(--so-r) *  0.383) 0 var(--so-c),
    calc(var(--so-r) *  0.707) calc(var(--so-r) *  0.707) 0 var(--so-c),
    calc(var(--so-r) *  0.383) calc(var(--so-r) *  0.924) 0 var(--so-c),
    0 calc(var(--so-r) *  1.000) 0 var(--so-c),
    calc(var(--so-r) * -0.383) calc(var(--so-r) *  0.924) 0 var(--so-c),
    calc(var(--so-r) * -0.707) calc(var(--so-r) *  0.707) 0 var(--so-c),
    calc(var(--so-r) * -0.924) calc(var(--so-r) *  0.383) 0 var(--so-c),
    calc(var(--so-r) * -1.000) 0 0 var(--so-c),
    calc(var(--so-r) * -0.924) calc(var(--so-r) * -0.383) 0 var(--so-c),
    calc(var(--so-r) * -0.707) calc(var(--so-r) * -0.707) 0 var(--so-c),
    calc(var(--so-r) * -0.383) calc(var(--so-r) * -0.924) 0 var(--so-c),
    0 calc(var(--so-r) * -1.000) 0 var(--so-c),
    calc(var(--so-r) *  0.383) calc(var(--so-r) * -0.924) 0 var(--so-c),
    calc(var(--so-r) *  0.707) calc(var(--so-r) * -0.707) 0 var(--so-c),
    calc(var(--so-r) *  0.924) calc(var(--so-r) * -0.383) 0 var(--so-c);
}

*{margin:0;padding:0;box-sizing:border-box}

/* =====================================================================
   АРТ НЕ УТАСКИВАЕТСЯ ОДНИМ ЖЕСТОМ
   ---------------------------------------------------------------------
   touch-callout — то самое меню «Сохранить изображение», которое iOS
   показывает на долгое нажатие; user-drag — перетаскивание мышью на
   рабочий стол. Правую кнопку над артом гасит js/page.guard.js.

   Это НЕ защита, а неудобство, и путать одно с другим не стоит: файл
   лежит по обычному адресу и достаётся «Просмотром кода», вкладкой
   «Сеть», прямой ссылкой и снимком экрана. Убирается ровно случайное
   сохранение в один жест.

   user-select здесь НЕ ставится глобально: он заодно запретил бы
   выделять текст, а на сайте есть что копировать — реквизиты перевода,
   промокод, реферальная ссылка, номер обращения в поддержку. */
img,video,canvas{
  -webkit-touch-callout:none;
  -webkit-user-drag:none;
}
html{scroll-behavior:smooth;background:var(--bg-deep)}
body{
  font-family:'Manrope',sans-serif;
  background:transparent;
  color:var(--text);
  /* ОБРЕЗКА ПО ГОРИЗОНТАЛИ — clip, А НЕ hidden.
     Разница не косметическая: overflow:hidden делает страницу
     ПРОКРУЧИВАЕМЫМ контейнером (просто с нулевой полосой), и на iOS
     Safari именно это ломает перерисовку при разведении пальцев —
     часть плиток остаётся от прежнего масштаба, и текст печатается
     поверх текста. Ровно это видно на присланном снимке с приближением.
     overflow:clip обрезает то же самое, но контейнера прокрутки не
     создаёт, и артефакт уходит.

     Строки две, и порядок важен: Safari до 16 про clip не знает и
     возьмёт hidden (там всё как было), новые браузеры — clip.
     Обрезать при этом почти нечего: замер на 320-1440 px по пяти
     экранам показал, что за правый край не выходит ничего, кроме
     фонового <video>, а его и без того режет .bg-stage. Правило
     оставлено страховкой от длинной неразрывной строки. */
  overflow-x:hidden;
  overflow-x:clip;
  /* touch-action здесь НЕ ставится: manipulation у body отнимал
     приближение по двойному тапу на всей странице. Оно возвращено, а
     задержка клика гасится точечно — только на сцене открытия ящика,
     где темп нажатий что-то значит (.sbs-root в
     css/smallbox.scene.css). */
  /* Сглаживание по субпикселям на тёмном фоне утолщает светлые буквы, и
     обводка 0.1em поверх этого превращала мелкие подписи в кашу. На
     WebKit просим серое сглаживание — буквы выходят такими, как
     нарисованы. */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  /* Safari на iPhone раздувает кегль в повёрнутом экране по своему
     усмотрению — вёрстка при этом едет, а мы её и так считаем сами. */
  -webkit-text-size-adjust:100%;
          text-size-adjust:100%;
  min-height:100vh;
}

/* =====================================================================
   ПОЛОСА ПРОКРУТКИ
   ---------------------------------------------------------------------
   Собрана из тех же материалов, что и кнопки-«плитки» витрины: тот же
   синий градиент #55B8FF → #2278DE и тот же тёмный низ #14508F, так что
   бегунок читается как ещё один элемент интерфейса, а не как деталь
   браузера.

   Скругление даёт связка прозрачной рамки и background-clip: padding-box.
   Рамка вырезает поле внутри дорожки, фон под неё не заезжает, и бегунок
   выходит «плавающей» пилюлей с воздухом по краям — обычным padding у
   ::-webkit-scrollbar этого не добиться — он его не поддерживает.

   Правило намеренно ГЛОБАЛЬНОЕ, без привязки к html: свои полосы есть у
   окна открытия ящика, профиля и авторизации, и разнобой между ними
   бросался бы в глаза сильнее, чем синий бегунок на тёмной модалке.

   Firefox рисует полосу сам и слушает только scrollbar-width/-color —
   ему отдаём те же два цвета. Градиента и скруглений он не поддерживает,
   так что там будет сплошная заливка того же синего.

   ЭТИ ДВА СВОЙСТВА СПРЯТАНЫ ЗА @supports НЕ ЗРЯ. Chrome с некоторых пор
   тоже слушает scrollbar-width, и `thin` перебивал ширину, заданную
   ниже: полоса выходила 10 px вместо 14, а прозрачная рамка в 3 px
   оставляла от бегунка 4 px. Условие отдаёт эти свойства только тем
   браузерам, где вебкитовских псевдоэлементов нет, — то есть Firefox.
   ===================================================================== */
@supports not selector(::-webkit-scrollbar){
  *{scrollbar-width:thin;scrollbar-color:#2E86E8 rgba(4,18,58,.55)}
}

::-webkit-scrollbar{width:14px;height:14px}

::-webkit-scrollbar-track{
  background:rgba(4,18,58,.55);
  border:3px solid transparent;
  background-clip:padding-box;
  border-radius:999px;
}

::-webkit-scrollbar-thumb{
  background:linear-gradient(180deg,#55B8FF 0%,#2278DE 100%);
  border:3px solid transparent;
  background-clip:padding-box;
  border-radius:999px;
  /* Тонкий светлый кант сверху и тёмный снизу — та же «объёмная плитка»,
     что у кнопок, только в миниатюре. */
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),
             inset 0 -1px 0 rgba(2,10,45,.45);
  transition:background .15s ease, box-shadow .15s ease;
}
::-webkit-scrollbar-thumb:hover{
  background:linear-gradient(180deg,#7ACCFF 0%,#3A8BEC 100%);
  background-clip:padding-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),
             inset 0 -1px 0 rgba(2,10,45,.45);
}
::-webkit-scrollbar-thumb:active{
  background:linear-gradient(180deg,#2278DE 0%,#14508F 100%);
  background-clip:padding-box;
}

/* Квадрат на пересечении полос — иначе браузер красит его белым. */
::-webkit-scrollbar-corner{background:transparent}

/* Заголовки и всё «игровое» — шрифтом сцены с обводкой. Вынесено в
   утилиту, потому что одну и ту же связку stroke + extrude просит
   десяток разных элементов. */
.bs-ink{
  font-family:"MegaBoxFont","Arial Black","Segoe UI",system-ui,sans-serif;
  font-weight:900;
  /* ТРЕКИНГ СНЯТ С РЕФЕРЕНСА, а не подобран на глаз.
     Мерить в em бесполезно: в игре другая гарнитура. Сравнимая величина
     одна — просвет между ЗАЛИВКАМИ соседних букв в долях капители.
     В референсе панели он равен 0.083-0.111 капители (медиана 0.111) у заголовка и
     0.053-0.132 (медиана 0.105) у «ПОДАРОК» — то есть буквы там стоят
     ТЕСНО, обводки местами соприкасаются, чистого фона между ними нет.
     У нашей Lilita тот же просвет даёт letter-spacing 0.04em: замер на
     канве — 0.082-0.116, медиана 0.097.
     Межсловный ОТРИЦАТЕЛЬНЫЙ: пробел Lilita относительно капители шире
     игрового, и без поправки зазор между словами выходил 0.43 капители
     против референсных 0.278-0.306. -0.09em выводит его на 0.295. */
  letter-spacing:.04em;
  word-spacing:-.09em;
  text-shadow:var(--so),var(--extrude);
  line-height:1.1;
}

/* =====================================================================
   ФОН — видео background.mp4
   ---------------------------------------------------------------------
   Слой лежит за содержимым (z-index:-1), поэтому html красится в
   запасной синий: если видео не стартовало (экономия трафика, политика
   автовоспроизведения), страница всё равно остаётся синей, а не белой.
   ===================================================================== */
/* КАДР РОЛИКА — ПОДЛОЖКОЙ ПОД ВИДЕО, А НЕ ЗАПАСНАЯ ЗАЛИВКА.
   Раньше при неигравшем ролике оставался плоский синий html, и на
   телефоне это выглядело как «фон не загрузился» — а не играет он там
   сплошь и рядом: режим энергосбережения на iPhone запрещает
   автозапуск любого видео, экономия трафика не даёт докачать файл,
   системная настройка «меньше движения» прячет его сама. Кадр весит
   12 КБ и закрывает все эти случаи разом: фон остаётся тем же, просто
   неподвижным. Видео ложится поверх, когда доедет и запустится. */
.bg-stage{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none;
  background:var(--bg-deep) url(../assets/background-poster.jpg) center/cover no-repeat;
  /* ПРИЗРАКИ ТЕКСТА В ПОДВАЛЕ — ОТСЮДА. Слой закреплён (position:fixed),
     а содержимое страницы над ним полупрозрачное (подвал залит
     градиентом с альфой, панели — тоже). Safari на iPhone такую пару
     рисует в разных слоях и, прокручивая, местами не сбрасывает старую
     плитку: на её месте остаётся прежний кадр, и поверх него печатается
     новый текст — получается двойная строка со сдвигом вверх-влево.
     Ровно это видно на присланных снимках у нижнего края.

     translateZ(0) + will-change отдают слою СВОЮ поверхность в
     композиторе явно, вместо того чтобы Safari решал это по ходу дела;
     backface-visibility гасит вторую, обратную сторону этой
     поверхности. Никакой анимации сюда не добавляется — только
     подсказка компоновщику. Расход оправдан: слой и без того
     полноэкранный и с видео внутри, то есть на своей поверхности он
     оказался бы всё равно. */
  transform:translateZ(0);
  will-change:transform;
  -webkit-backface-visibility:hidden;
          backface-visibility:hidden;}
.bg-stage video{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  min-width:100%;min-height:100%;width:auto;height:auto;
  object-fit:cover;
}
/* Виньетка: в исходном ролике центр очень светлый, и белый текст на нём
   терял контраст. Гасим края и центр по-разному. */
.bg-stage::after{
  content:"";position:absolute;inset:0;
  background:
    radial-gradient(115% 85% at 50% 32%, rgba(3,14,48,.10) 0%, rgba(3,14,48,.34) 55%, rgba(2,10,38,.72) 100%),
    linear-gradient(180deg, rgba(2,10,38,.42) 0%, rgba(2,10,38,.16) 22%, rgba(2,10,38,.30) 70%, rgba(2,10,38,.66) 100%);
}

/* ШИРИНА КОЛОНКИ. Было 1180 — подложки выходили ровно по ширине трёх
   карточек, и секция читалась как узкая полоса. Расширено до 1500: сами
   карточки при этом НЕ растут (их ширина ограничена --card-max ниже), а
   встают по центру, оставляя поля по бокам — так же, как у конкурента,
   где панель идёт почти во всю страницу, а карточки внутри мелкие. */
/* Боковое поле ТЕКУЧЕЕ, а не ступенькой в медиазапросе. На телефоне
   каждый пиксель поля отнимается у карточек — их теперь три в ряд и на
   375 px, — но резать 24 → 10 разом нельзя: на границе точки карточка
   прыгала бы в ширине. clamp ведёт поле от 24 px на широком экране к
   10 px на узком без единого скачка. Тем же приёмом заданы поля
   подложек, просветы сетки и полоса заголовка ниже. */
.wrap{max-width:1500px;margin:0 auto;padding:0 clamp(10px,2.4vw,24px);position:relative;z-index:1}

/* Запас под свисающими частями шапки. Логотип уходит ниже полосы на 1.75
   её высоты, плашка профиля с ником — на 2.4, а первая секция начинала
   страницу всего в 52 px от полосы: подложка бесплатных ящиков
   подъезжала под ник, и шапка (z-index:50) печатала его поверх панели.
   Считаем от --head-h, чтобы запас ужимался вместе с шапкой. */
main.wrap{padding-top:calc(var(--head-h) * 1.4)}

/* Потолок ширины карточки. Ровно тот размер, при котором форма уже
   выверена по референсам, — расширение панели его не трогает.
   minmax(0, …) оставляет колонке право сжаться на узком экране. */
:root{--card-max:332px}

/* =====================================================================
   ШАПКА
   ===================================================================== */
/* Шапка по референсному кадру шапки — это НЕ панель, а узкая полоса, из которой
   вниз свисают элементы правого края. Отсюда три следствия:

   1. Единственный размер здесь — --head-h, высота полосы. ВСЯ геометрия
      баланса считается от неё теми долями, что сняты с кадра (полоса в
      нём 32 px), поэтому одной правкой --head-h вся группа съезжает
      целиком и пропорции референса не плывут. Первая попытка держала
      размеры язычков в абсолютных пикселях кадра при полосе 40 вместо
      32 — рядом с более высокой полосой они выглядели мелкими.
   2. Фон полосы непрозрачный и ТОТ ЖЕ, что у язычков (--head-bg).
      Полупрозрачность дала бы двойное наложение в месте стыка и
      прочертила бы поперёк шва видимую границу.
   3. Ни border-bottom, ни тени снизу: любая линия под полосой
      перечеркнула бы свисающие язычки. В референсе край плоский. */
:root{
  --head-h:33px;
  --head-bg:#05070F;
  /* Насколько язычок выступает ниже кромки: в кадре 16 при полосе 32.
     Ровно половина — и это же радиус круглой кнопки, поэтому кнопка
     садится центром на кромку и упирается донышком в низ язычка. */
  --head-drop:calc(var(--head-h) / 2);
}

header.site-head{
  /* НЕ sticky. Полоса не прилипает к верху, а открывает страницу и
     уезжает вместе с ней — это просто верхушка сайта, и выглядеть она
     должна как на первом экране. Прилипшая, она к тому же тащила за
     собой свисающие логотип и язычки: те шли поверх карточек, и при
     прокрутке шапка читалась как рассыпавшаяся.
     position:relative оставлен ради z-index — без него свисающие части
     ушли бы ПОД содержимое страницы (у .wrap свой z-index:1). */
  position:relative;z-index:50;
  background:var(--head-bg);
}
.nav{display:flex;align-items:center;gap:26px;height:var(--head-h)}

/* БАЗОВАЯ связка «значок + слово». Ею набран и логотип в подвале,
   поэтому здесь только общее; всё, что про свисание из полосы, —
   ниже, под .site-head. Правила отсюда НЕ трогают подвал: у него
   своя разметка, старая и плоская. */
.logo{
  display:flex;align-items:center;gap:11px;
  text-decoration:none;color:var(--text);
  font-size:1.35rem;
  flex-shrink:0;
}
.logo img{width:38px;height:38px;object-fit:contain;filter:drop-shadow(0 3px 6px rgba(2,10,45,.6))}

/* ЛОГОТИП В ШАПКЕ.
   Композиция снята с кадра: там мелкое «BRAWL» капителью .38 полосы
   лежит целиком на чёрном, а крупное «STARS» — в 2.2 раза выше —
   сидит верхом на нижней кромке и уходит под неё. Знак ростом 2.25
   полосы начинается ровно на её середине, и ниже кромки оказывается
   76 % его высоты. Все эти доли и перенесены сюда; наше отличие —
   значок стоит сбоку от столбика, а не над ним.

   Слово равняется по ВЕРХУ значка, а не по центру: вся композиция
   держится на том, что «Mega» попадает на полосу, а «Drop» из неё
   свисает; по центру значка слово целиком уехало бы под полосу. Сам
   значок тоже равняется по верху строки — он вдвое выше полосы, и при
   align-items:center торчал бы ВВЕРХ за край страницы. */
.site-head .logo{
  align-items:flex-start;
  gap:calc(var(--head-h) * .2);
  align-self:flex-start;
  margin-top:calc(var(--head-h) * .5);
  /* Распорки здесь БОЛЬШЕ НЕТ. Раньше её держал margin-right:auto на
     логотипе, но теперь сразу за ним стоит плашка профиля, и авторазмер
     разогнал бы их по разным краям строки. Правую группу отжимают
     margin-left:auto на .hud и .auth-btn — ровно один из них виден в
     любой момент, так что делить свободное место между ними не выйдет. */
  position:relative;z-index:1;
}
.site-head .logo-mark{
  width:calc(var(--head-h) * 2.25);height:calc(var(--head-h) * 2.25);
  object-fit:contain;filter:drop-shadow(0 3px 6px rgba(2,10,45,.6));
  flex-shrink:0;
  /* Звезда поднята относительно столбика: выровненная с ним по верху,
     она вставала с «Mega» и «Drop» в один пояс и читалась как третья
     строка связки. Подъём разводит их по высоте — знак идёт выше слов.
     Больше .3 полосы брать нельзя: верх звезды упрётся в край страницы
     (связка и так начинается на середине полосы, то есть в 0.5). */
  margin-top:calc(var(--head-h) * -.3);
}

/* line-height ниже единицы — не опечатка: в связке из двух слов строки
   должны стоять вплотную, иначе это не логотип, а два абзаца. Своя
   строчная сетка тут и нужна, поэтому .bs-ink со своим 1.1 перебит.

   Разрядка у «Mega» подогнана так, чтобы верхнее слово вышло по ширине
   примерно как нижнее: в лежачей связке разница в ширине читалась бы
   как ошибка вёрстки, а не как приём. */
.site-head .logo-word{
  display:flex;flex-direction:column;
  line-height:.84;
  /* Столбик поднят на .15 полосы относительно значка — это не подгонка
     «на глаз», а то самое условие композиции: замер по рендеру показал,
     что без сдвига «Mega» свисает под кромку на 2.5 px, а «Drop»
     начинается на 3 px ниже неё, то есть слова просто лежат ПОД
     полосой. Сдвиг ставит «Mega» целиком на чёрное, а «Drop» — верхом
     на кромку, как «BRAWL» и «STARS» в кадре. */
  margin-top:calc(var(--head-h) * -.15);
}
.site-head .logo-top{
  font-size:calc(var(--head-h) * .52);
  letter-spacing:.3em;
  /* Разрядка добавляет пустоту и справа от последней буквы — гасим,
     иначе слово визуально уезжает влево относительно нижнего. */
  margin-right:-.3em;
  color:#fff;
}
.site-head .logo-bot{
  font-size:calc(var(--head-h) * 1.16);
  /* Золото значка: связка читается как одна марка, а не как картинка
     рядом с надписью. Заливка ПЛОСКАЯ, не градиентная: градиент по
     тексту делается через background-clip с color:transparent, а
     прозрачная заливка открывает выдавку --extrude, которая лежит
     ровно за глифом, — слово выходило чернильным, а не золотым. */
  color:var(--gold);
}

/* =====================================================================
   БАЛАНС И БАЛЛЫ — по референсному кадру шапки
   ---------------------------------------------------------------------
   Баланс — не плашки внутри шапки, а два ЯЗЫЧКА, свисающих из полосы:
   они начинаются от её верхней кромки, идут вниз одним цветом с ней
   (шва не видно) и выступают ниже края на --head-drop. Между ними
   вырез, сквозь который виден фон страницы, — по нему и читается, что
   язычков два, а не один.

   Замеры с кадра (полоса 32 px, ширина 1346 px) переведены в доли от
   --head-h — в скобках исходные пиксели:
     • выступ вниз          = .5   × полосы   (16)
     • Ø круглой кнопки     = 1    × полосы   (31) — кнопка ростом с полосу
     • минимальная ширина   = 4.375× полосы   (140)
     • вырез между язычками = .4375× полосы   (14)
     • поле слева и просвет
       между значением и кнопкой = .75 × полосы (24)
     • капитель значения    = .47  × полосы   (15)
   Плюс два правила, не выражаемых числом:
     • центр значения и центр кнопки лежат НА нижней кромке полосы,
       поэтому донышко кнопки совпадает с низом язычка, а правый край
       кнопки — с правым краем язычка (внахлёст, как было раньше, в
       референсе нет);
     • углы прямые: скруглять нечего, язычок вырезан из полосы.

   Сами кнопки больше не рисуются CSS: зелёную и синюю подменили готовые
   готовые картинки (см. .hud-act ниже).
   ===================================================================== */
.hud{
  display:flex;gap:calc(var(--head-h) * .4375);flex-shrink:0;
  /* Тянемся во всю высоту полосы (у .nav align-items:center, поэтому
     stretch приходится просить явно), а отрицательный нижний отступ
     добавляет к этой высоте выступ: у растянутого flex-элемента
     height = высота строки − отступы, то есть 40 − (−16) = 56. */
  align-self:stretch;
  margin-bottom:calc(var(--head-drop) * -1);
  /* Распорка до правого края: слева от язычков теперь стоит плашка
     профиля, и без авторазмера вся группа сползлась бы к логотипу. */
  margin-left:auto;
  position:relative;z-index:1;
}
.hud[hidden]{display:none}

.hud-pill{
  display:flex;align-items:center;justify-content:flex-end;
  column-gap:calc(var(--head-h) * .75);
  /* Верхнее поле опускает содержимое на нижнюю кромку полосы:
     (padding-top + высота язычка) / 2 = высота полосы. Справа и снизу
     полей нет вовсе: кнопка должна упираться в самый край язычка, иначе
     из-под неё торчит чёрная кромка — в референсе её нет. Прежние 2 и
     4 px стояли под ободок box-shadow, которого у кнопки больше нет. */
  padding:calc(var(--head-h) - var(--head-drop)) 0 0 calc(var(--head-h) * .75);
  min-width:calc(var(--head-h) * 4.375);
  background:var(--head-bg);
  /* Единственный скруглённый угол — нижний правый, и радиус ему не
     подобран, а выведен: кнопка вписана в этот угол вплотную (её край
     совпадает и с правым, и с нижним краем язычка), её центр стоит
     ровно в точке (право − R, низ − R), поэтому дуга радиуса R = радиус
     кнопки ложится точно на её окружность. Без него в углу оставался
     чёрный клин, торчащий из-под иконки, — в кадре его нет. */
  border-bottom-right-radius:var(--head-drop);
}
.hud-val{
  /* .47 — капитель; у lilitaone она составляет .725 кегля, отсюда .65. */
  font-size:calc(var(--head-h) * .65);color:#fff;white-space:nowrap;
  /* Знак ₽ в lilitaone.ttf отсутствует намеренно (почему и что сделано
     вместо этого — см. шапку megabox.scene.css): его рисует запасная
     гарнитура из списка .bs-ink, и именно ради неё у семейства везде
     просят вес 900. */
}

.hud-act{
  /* Ø = 2 × --head-drop = высота полосы: столько язычок и выступает,
     поэтому кнопка, сидящая центром на кромке, достаёт до его низа. */
  width:calc(var(--head-drop) * 2);height:calc(var(--head-drop) * 2);
  flex-shrink:0;border:0;cursor:pointer;border-radius:50%;padding:0;
  /* Кнопка — ГОТОВАЯ КАРТИНКА (готовые кружки «+» и «i», обрезанные
     по кругу в assets/ui/hud-add.webp и assets/ui/hud-info.webp): и круг, и обод,
     и белый знак нарисованы в ней. Поэтому здесь нет ни градиента, ни
     набранного глифа — раньше знак рисовался lilitaone со связкой
     обводка + выдавка, а круг — линейным градиентом; всё это заменила
     одна картинка, и тела у <button> больше нет.
     Картинки обрезаны ровно по силуэту и квадратные, так что
     background-size:100% 100% ставит круг в квадрат кнопки без полей —
     нижний правый угол язычка по-прежнему укрыт под окружностью. */
  background:center/100% 100% no-repeat;
  /* Ни ободка, ни «монетной» подставки снизу: и то и другое вылезало
     из-под круга на язычок и на страницу, а в кадре круг плоский. */
  box-shadow:none;
  transition:transform .09s ease, filter .14s ease;
}
/* ПЛОЩАДЬ ПОД ПАЛЕЦ БОЛЬШЕ, ЧЕМ САМА КНОПКА.
   Диаметр кружка привязан к высоте полосы шапки (см. выше), и на
   телефоне полоса 23 px — то есть «+» у баланса выходит 23x23 при
   рекомендованных для касания сорока. Увеличивать сам кружок нельзя:
   он сидит центром на кромке полосы и упирается донышком в низ язычка,
   вся геометрия группы держится на этом равенстве. Поэтому растёт не
   кнопка, а её невидимая площадь нажатия. Влево она заходит на цифры
   баланса — и это скорее плюс: в «+» целятся, тыкая в сумму. */
.hud-act{position:relative}
.hud-act::after{content:"";position:absolute;inset:-8px}
/* ДВЕ КНОПКИ В ОДНОМ ЯЗЫЧКЕ («+» и «−» у баланса) стоят вплотную, и их
   площади нажатия налезали бы друг на друга: восемь пикселей вправо от
   «+» — это восемь пикселей внутрь «−». В шве выигрывал бы тот, кто ниже
   в разметке, то есть «−», и палец, целившийся в пополнение, открывал бы
   вывод. Поэтому шов НЕ расширяется вовсе: «+» растёт влево, на цифры
   баланса (туда и тычут), «−» — вправо, в просвет шапки.

   Пара названа классами, а не выведена через :has(+ .hud-act): тот
   появился только в Safari 15.4, а сайт держит Safari 15, и на нём
   ПРАВИЛО ЦЕЛИКОМ отбрасывается как непонятое — то есть шов остался бы
   расширенным ровно там, где он опаснее всего. */
.hud-act + .hud-act::after{left:0}
.hud-add::after{right:0}
.hud-act:hover{filter:brightness(1.1)}
/* Коробка пары «+» и «−». Просвет между ними задаётся ЗДЕСЬ, а не
   вычитанием из column-gap язычка: тот меняется на каждом изломе
   адаптива (.75 → .4 → .32 от --head-h), и одна и та же отрицательная
   поправка, дававшая на десктопе законные 10 px, на телефоне сажала
   кнопки друг на друга внахлёст. Свой gap не зависит ни от одного из
   них. */
.hud-acts{
  display:flex;align-items:center;flex-shrink:0;
  gap:calc(var(--head-drop) * .3);
}
/* Нажатие сжимает кнопку, а НЕ опускает её на 2 px, как у остальных
   кнопок сайта: донышко и так стоит на нижнем крае язычка, и сдвиг вниз
   выносил бы кнопку за край — на нажатие она вылезала бы на страницу. */
.hud-act:active{transform:scale(.93)}
.hud-add {background-image:url(../assets/ui/hud-add.webp)}
/* «−» вывода. Картинка того же кроя и того же размера, что «+», только
   красная: две кнопки стоят вплотную, подписей у них нет, и различать их
   человек будет цветом раньше, чем знаком внутри. */
.hud-sub {background-image:url(../assets/ui/hud-sub.webp)}
.hud-info{background-image:url(../assets/ui/hud-info.webp)}

/* Кнопка-«плитка»: цвет задаётся тремя переменными, форма общая. */
.btn{
  --b1:var(--btn-blue-1); --b2:var(--btn-blue-2); --bs:var(--btn-blue-sh);
  --lift:5px;
  border:0;cursor:pointer;display:inline-block;
  padding:11px 22px 15px;border-radius:16px;
  font-size:1rem;color:#fff;
  background:linear-gradient(180deg,var(--b1) 0%,var(--b2) 100%);
  box-shadow:0 var(--lift) 0 var(--bs), 0 10px 14px -6px rgba(2,10,45,.6);
  transition:transform .09s ease,box-shadow .09s ease,filter .14s ease;
}
.btn:hover{filter:brightness(1.08)}
.btn:active{transform:translateY(var(--lift));box-shadow:0 0 0 var(--bs)}
.btn.green{--b1:var(--green-1);--b2:var(--green-2);--bs:var(--green-sh)}
.btn.gold{--b1:#FFD84D;--b2:#F5A524;--bs:#A96A05}

/* Кнопки «Войти» и профиля приезжают из auth.css / profile.css в
   фиолетовой теме модалок. В шапке они стоят рядом с синими плитками,
   поэтому здесь перекрашиваются под витрину. Внутренности оверлеев не
   трогаем — там фиолетовая тема на месте.
   site.css подключён ПОСЛЕ обоих файлов, так что хватает той же
   специфичности без !important. */
.auth-btn{
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;letter-spacing:.04em;  /* см. .bs-ink */
  text-shadow:var(--so),var(--extrude);
}

/* «ВОЙТИ» — ПЛАШКА ТОГО ЖЕ НАБОРА, ЧТО ПРОФИЛЬ И МЕНЮ.
   Раньше это была отдельная фигура: пилюля с радиусом 16 и своей
   высотой, висевшая на четверти полосы. Рядом с плашками, которые
   свисают из середины полосы на две её высоты, она начиналась выше их
   верха и кончалась много выше их низа, да ещё стояла прямо среди
   скошенных — в шапке это читалось как съехавшая кнопка, а не как
   отдельный акцент. Поэтому геометрия берётся у соседей целиком: тот же
   вылет (.5 полосы), та же высота (2 полосы), тот же маленький радиус
   (.15) и тот же скос 5.06°. Кнопка встаёт с ними в один рост и на одни
   кромки — верхнюю и нижнюю.

   ЦВЕТ ОСТАЁТСЯ ЗЕЛЁНЫМ, и это единственное отличие от тёмных соседей:
   «Войти» — приглашение нажать, а плашки рядом просто открывают разделы.
   Фаска сверху и утолщённый кант снизу те же, что у тёмных, только
   светлее тела — набор один, краска разная.

   ШИРИНА — минимум плашки профиля (3.35 полосы): «Войти» на неё и
   меняется после входа, и правый край шапки от этого не прыгает.
   Отдельного :hover/:active не пишем сверху старых — они переопределены
   здесь целиком, вместе со скосом (без него transform на наведении
   выпрямлял бы плашку). */
.site-head .auth-btn{
  align-self:flex-start;
  margin-top:calc(var(--head-h) * .5);
  margin-left:auto;   /* распорка до правого края, когда профиля нет */
  position:relative;z-index:1;
  display:grid;place-items:center;
  height:calc(var(--head-h) * 2);
  min-width:calc(var(--head-h) * 3.35);
  padding:0 calc(var(--head-h) * .5);
  border:2px solid var(--ink);
  border-radius:calc(var(--head-h) * .15);
  background:linear-gradient(180deg,
    var(--green-1) 0%, var(--green-1) 5%, var(--green-1) 10%,
    var(--green-2) 55%, var(--green-sh) 100%);
  box-shadow:0 2px 0 var(--ink), 0 7px 14px -6px rgba(2,10,45,.8);
  transform:skewX(-5.06deg);
  transition:filter .14s ease, transform .09s ease, box-shadow .09s ease;
}
.site-head .auth-btn:hover{filter:brightness(1.15);transform:skewX(-5.06deg)}
.site-head .auth-btn:active{
  transform:skewX(-5.06deg) translateY(2px);
  box-shadow:0 0 0 var(--ink), 0 4px 10px -6px rgba(2,10,45,.8);
}
/* Слово стоит прямо в наклонной плашке — как ник в профиле и «птичка» в
   кнопке «назад». Кегль общий для подписей шапки: .58 полосы. */
.auth-btn-name{
  font-size:calc(var(--head-h) * .58);
  color:#fff;white-space:nowrap;
  transform:skewX(5.06deg);
}

/* =====================================================================
   ПЛАШКИ ПРОФИЛЯ И МЕНЮ — по референсному кадру шапки
   ---------------------------------------------------------------------
   В кадре это НЕ кнопки поверх шапки, а две тёмные плашки, вырезанные из
   той же полосы: обе начинаются на её середине и свисают вниз — ровно
   как логотип слева и язычки баланса справа. Прежняя кнопка профиля была
   синей пилюлей с белым кантом, то есть единственным элементом шапки не
   из этого набора, — отсюда и переделка.

   ЗАМЕРЫ С КАДРА (полоса 31 px), переведены в доли --head-h:
     • верх плашки       = .5   × полосы ниже верхней кромки (16)
     • высота            = 2    × полосы (62) — у обеих одинаковая
     • ширина «меню»     = 2    × полосы (62), то есть квадрат
     • ширина профиля    = 3.35 × полосы (104), но по факту её тянет ник
     • квадрат аватара   = 1.4  × полосы (44), по центру плашки
     • три полоски       = .935 × полосы в ширину (29), .226 в толщину (7)
       при просвете      = .065 × полосы (2)
     • капитель ника     = .42  × полосы (13) → кегль .58 (у lilitaone
       капитель составляет .725 кегля)
   Цвета оттуда же: тело #343C4E, светлая фаска сверху #6B697E.

   НАКЛОН — общий для витрины 5.06° (см. --fb-skew у панелей). Замер по
   кромкам кадра дал 4.56° слева и 4.83° справа, но это съёмка с блюром и
   всего 38 строк на фит; на такой базе разница с 5.06° — меньше пикселя,
   а разнобой углов в шапке и на карточках был бы виден. Содержимое
   плашек получает обратный скос и стоит прямо — как заголовки в
   наклонных панелях ниже.
   ===================================================================== */
.profile-btn,
.ug-btn,
.nav-burger{
  --plate-h:calc(var(--head-h) * 2);
  --plate-skew:-5.06deg;
  --plate-unskew:5.06deg;
  /* Скругление и обводка сняты с кадра: кант 2 px, радиус МАЛЕНЬКИЙ.
     На глаз в кадре углы кажутся круглее, чем есть, — это блюр записи;
     по пикселям левая кромка «меню» отходит от края всего на 2 px за 2
     строки от верха, то есть радиус около 4 из 62, ~.13 полосы. Берём
     .15: ближе к замеру, чем первые .22, но не в острый угол.
     Кант непрозрачный: в референсе он чернее и тела плашки, и синего
     фона, то есть это именно обводка, а не тень под краем. */
  --plate-r:calc(var(--head-h) * .15);
  align-self:flex-start;
  margin-top:calc(var(--head-h) * .5);
  position:relative;z-index:1;
  border:0;background:none;padding:0;cursor:pointer;
}

/* Лицо плашки. Фаска — не декоративный градиент «сверху светлее», а
   замеренная полоска: подсветка держится первые .15 высоты и гаснет к
   .25, дальше идёт ровное тело и лёгкое затемнение у самого низа. */
.profile-plate,
.ug-btn-plate,
.nav-burger{
  background:linear-gradient(180deg,
    #6B697E 0%, #6B697E 5%, #55536B 10%, #3C4155 15%,
    #353C4F 26%, #343C4E 70%, #2F3747 100%);
  border:2px solid var(--ink);
  border-radius:var(--plate-r);
  /* Утолщение канта снизу — в кадре чёрная кромка внизу вдвое толще
     боковых. Мягкая тень второй строкой, как у кнопок-плиток. */
  box-shadow:0 2px 0 var(--ink), 0 7px 14px -6px rgba(2,10,45,.8);
  transform:skewX(var(--plate-skew));
  transition:filter .14s ease, transform .09s ease, box-shadow .09s ease;
}

/* ---------- ПРОФИЛЬ ---------- */
/* Кнопка сама по себе прозрачна: плашка — это .profile-plate, а ник висит
   ПОД ней на синем фоне, как в кадре. Поэтому столбик, а не строка. */
.profile-btn{
  display:inline-flex;flex-direction:column;align-items:stretch;
  /* Отрицательный: в кадре обводка ника заходит на нижнюю кромку плашки,
     а не висит под ней с зазором — связка читается как одно целое. */
  gap:calc(var(--head-h) * -.06);
}
.profile-plate{
  height:var(--plate-h);
  /* Ширину тянет ник (он и в кадре шире квадрата аватара), а минимум
     держит саму плашку узнаваемой, когда ник короткий. */
  min-width:calc(var(--head-h) * 3.35);
  display:grid;place-items:center;
}
.profile-ava{
  width:calc(var(--head-h) * 1.4);height:calc(var(--head-h) * 1.4);
  /* Квадрат со скруглением, а не круг: в кадре это именно рамка-окошко
     под картинку. Обводка та же, что у плашки, только тоньше. */
  border-radius:calc(var(--head-h) * .16);
  border:2px solid var(--ink);
  background:linear-gradient(160deg,#55B8FF,#2278DE);
  box-shadow:none;
  transform:skewX(var(--plate-unskew));   /* стоит прямо в наклонной плашке */
}
.profile-ava img{border-radius:inherit}
.profile-ava span{font-size:calc(var(--head-h) * .62)}
.profile-name{
  font-size:calc(var(--head-h) * .58);
  text-align:center;color:#fff;
  /* Ник не должен растягивать шапку: длинный обрезается многоточием.
     Потолок — 7 полос, примерно вдвое шире минимума плашки. */
  max-width:calc(var(--head-h) * 7);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transform:skewX(var(--plate-unskew));
}
/* Кнопка профиля приезжает из profile.css фиолетовой пилюлей, и её
   :hover/:active перебивают базовые правила отсюда по специфичности.
   Гасим их явно: подсветку берёт на себя плашка ниже. */
.profile-btn:hover,
.profile-btn:active{
  transform:none;background:none;box-shadow:none;border-color:transparent;
}
.profile-btn:hover .profile-plate{transform:skewX(var(--plate-skew));filter:brightness(1.22)}
.profile-btn:active .profile-plate{transform:skewX(var(--plate-skew)) translateY(2px);
  box-shadow:0 0 0 var(--ink), 0 4px 10px -6px rgba(2,10,45,.8)}

/* ---------- АПГРЕЙДЕР ----------
   Третья плашка того же набора, между аватаркой и язычками баланса.
   Собрана из уже готовых частей двух соседей, а не выдумана заново:
   столбик «плашка + подпись» и его отрицательный просвет — от профиля
   (подпись так же заходит обводкой на нижнюю кромку), поле под значком
   и его размер — от окошка аватара. Ширина плашки между квадратом меню
   (2 полосы) и профилем (3.35): её держит подпись «Апгрейд», которая
   шире значка.

   Значок — ЦВЕТНОЙ АРТ, а не белый штрих, как полоски меню и «птичка»
   назад. Это не украшение: два одинаковых квадрата подряд читались бы
   как две кнопки меню, а рисованная шестерёнка со стрелкой узнаётся
   раньше, чем читается подпись.

   УТОПЛЕННОЙ ПЛОЩАДКИ ПОД ЗНАЧКОМ БОЛЬШЕ НЕТ. Она была нужна белой
   стрелке — та без тёмного поля висела бы на теле плашки без опоры.
   У готового значка тёмный кант нарисован свой, и на площадке (гашёнка
   тела на 42 %, почти чёрная) кант сливался с ней, а сам значок
   выглядел вдавленным в колодец. Поле осталось — им задан размер и
   обратный скос, — но заливку с него сняли. */
.ug-btn{
  display:inline-flex;flex-direction:column;align-items:stretch;
  gap:calc(var(--head-h) * -.06);
}
.ug-btn-plate{
  height:var(--plate-h);
  min-width:calc(var(--head-h) * 2.6);
  display:grid;place-items:center;
}
.ug-btn-pad{
  width:calc(var(--head-h) * 1.4);height:calc(var(--head-h) * 1.4);
  display:grid;place-items:center;
  transform:skewX(var(--plate-unskew));   /* стоит прямо в наклонной плашке */
}
/* Значок — готовый арт assets/ui/upgrade-badge.png (шестерёнка с зелёной
   стрелкой). Картинка КВАДРАТНАЯ и заполнена почти целиком, поэтому
   она чуть больше своего поля (107 %): по кадру значок должен доходить
   до кромок плашки так же, как аватар в профиле. Размер задан долей
   ПОЛЯ, а не полосы: на узких экранах поле ужимается с 1.4 полосы до
   1.2 (см. медиазапросы в конце файла), и значок в долях полосы полез
   бы за края плашки. Тени две: жёсткая — та же, что была у стрелки
   (значок стоит на плашке, а не парит над ней), мягкая — вместо
   утопленной площадки, она и отделяет кант значка от тела плашки. */
.ug-btn-ico{
  width:107%;height:107%;
  background:url('../assets/ui/upgrade-badge.png') center/contain no-repeat;
  filter:drop-shadow(0 2px 0 rgba(2,10,45,.55))
         drop-shadow(0 4px 6px rgba(2,10,45,.6));
}
.ug-btn-name{
  font-size:calc(var(--head-h) * .58);
  text-align:center;color:#fff;white-space:nowrap;
  transform:skewX(var(--plate-unskew));
}
.ug-btn:hover .ug-btn-plate{transform:skewX(var(--plate-skew));filter:brightness(1.22)}
.ug-btn:hover .ug-btn-ico{filter:drop-shadow(0 2px 0 rgba(2,10,45,.55))
  drop-shadow(0 4px 6px rgba(2,10,45,.6)) brightness(1.1)}
.ug-btn:active .ug-btn-plate{transform:skewX(var(--plate-skew)) translateY(2px);
  box-shadow:0 0 0 var(--ink), 0 4px 10px -6px rgba(2,10,45,.8)}
/* Экран апгрейдера открыт — плашка притушена и подсвечена золотом, как
   активная вкладка: иначе с открытого экрана она зовёт открыть его же. */
.ug-btn.is-on .ug-btn-plate{
  filter:brightness(1.12);
  box-shadow:0 2px 0 var(--ink), 0 0 0 2px rgba(255,216,77,.55),
             0 7px 14px -6px rgba(2,10,45,.8);
}

/* ---------- КНОПКА МЕНЮ ---------- */
.nav-burger{
  width:var(--plate-h);height:var(--plate-h);   /* в кадре квадрат */
  display:grid;place-items:center;
}
/* Утопленная площадка под полосками. Она НЕ чёрная: замер даёт (32,34,37)
   против (54,59,76) у тела, то есть тело гасится примерно на 42 % — на
   сплошном чёрном полоски выглядели бы наклейкой, а не врезкой.
   Просветы между полосками и поле вокруг них — один и тот же фон этой
   площадки, поэтому обводка полосок получается замкнутой сама собой. */
.nb-bars{
  display:flex;flex-direction:column;
  gap:calc(var(--head-h) * .065);
  width:calc(var(--head-h) * 1.045);
  padding:calc(var(--head-h) * .055);
  border-radius:calc(var(--head-h) * .1);
  background:rgba(0,0,0,.42);
}
.nb-bars i{
  display:block;height:calc(var(--head-h) * .226);
  background:#fff;border-radius:calc(var(--head-h) * .03);
}
.nav-burger:hover{transform:skewX(var(--plate-skew));filter:brightness(1.22)}
.nav-burger:active{transform:skewX(var(--plate-skew)) translateY(2px);
  box-shadow:0 0 0 var(--ink), 0 4px 10px -6px rgba(2,10,45,.8)}

/* =====================================================================
   СЕКЦИИ
   ===================================================================== */
section{padding:52px 0}
/* .sec-head тут больше нет: заголовок с подписью был только у «Как это
   работает», а разделы витрины носят свой заголовок в шапке .gpanel. */

/* Плашка категории — «NOSTALGIA 2020» и «MORE CASES». Скошенная лента
   на всю ширину сетки, чтобы разделы читались как полки витрины. */
/* ПРОСВЕТ МЕЖДУ ПАНЕЛЯМИ — ОДНА ВЕЛИЧИНА НА ВСЕ СТЫКИ.
   Между бесплатными ящиками и витриной он раньше складывался из полей
   двух соседних секций (52 + 52 = 104 px), а между панелями витрины был
   свой margin 34 px — то есть стыки жили порознь и разъезжались. Теперь
   обе величины берутся из --panel-gap: 104 минус 30 % = 73 px, и тот же
   зазор стоит между «Ностальгией» и «Другими кейсами».
   Половинки на соседних секциях, потому что вертикальные поля секций не
   схлопываются — между ними padding, а не margin.

   Прежние .cat / .cat-head (подпись полки с линейкой) удалены: заголовок
   раздела теперь стоит в шапке своей панели и подпись его дублировала. */
:root{--panel-gap:73px}
#free{padding-bottom:calc(var(--panel-gap) / 2)}
#cases{padding-top:calc(var(--panel-gap) / 2)}
#caseSections > .gpanel + .gpanel{margin-top:var(--panel-gap)}

/* Эмодзи внутри .bs-ink: обводка и выдавка превращают цветной глиф в
   грязное пятно, поэтому для них оформление снимается. */
.bs-ink .no-ink{
  -webkit-text-stroke:0;text-stroke:0;text-shadow:none;
}

/* =====================================================================
   КАРТОЧКА ЯЩИКА — по референсным кадрам витрины
   ---------------------------------------------------------------------
   Оба кадра дали одну и ту же карточку 381 x 295 px, так что замеры
   независимо подтверждены дважды. Кадры скошены на 5.03° и 5.11° — те же
   5.06°, что и у остальных референсов; наклон воспроизведён так же, как
   у бесплатных ящиков: скошена рамка, содержимое стоит прямо.

   Всё в cqw — долях ШИРИНЫ КАРТОЧКИ, поэтому на любой ширине это тот же
   рисунок целиком:
     высота карточки  295 px → aspect 381/295 (77.43 %)
     тело             224 px → 58.79 %      полоса цены 70 px → 18.37 %
     обводка            3 px →  0.79 %      радиус      14 px →  3.67 %
     название: капитель 23 → 6.04 % (кегль 8.75 %), сверху 5.38 %,
               справа 2.36 %, прижато ВПРАВО — как в референсе
     цена:     капитель 33 → 8.66 % (кегль 12.55 %), по центру полосы
     арт:      высота 145 px → 38.06 %, шириной по своему пропорцию

   Цвета сняты пипеткой, оба кадра сошлись:
     тело #058CE9 → #00A0FE (сверху вниз)
     полоса цены #3C4B73     обводка #1754A7

   ЦЕНА В РУБЛЯХ, А НЕ В КРИСТАЛЛАХ. В референсе там зелёный кристалл и
   число; по заданию вместо него рубли, поэтому значок убран, осталось
   «9 ₽» / «27 ₽» / «90 ₽». Знака ₽ в lilitaone.ttf намеренно нет (см.
   megabox.scene.css) — его рисует запасная гарнитура, и на фоне соседних
   цифр это не читается как подмена, пока у семейства просят вес 900.
   ===================================================================== */
/* ТРИ КОЛОНКИ, НА ТЕЛЕФОНЕ ДВЕ. Колонка minmax(0, --card-max) не только
   не даёт карточке перерасти 332 px, но и СЖИМАЕТСЯ, когда места мало,
   поэтому в колонку сетка не разворачивается нигде. Ниже 620 px колонок
   всё же две, а не три: втроём карточка садилась на 95 px, и ящик на
   ней приходилось угадывать (см. медиазапрос в конце файла).
   Просвет вынесен в --grid-gap, потому что по нему же считается ширина
   одинокой карточки в неполном ряду. */
.bs-grid{display:grid;--grid-gap:clamp(7px,1.8vw,22px);
  grid-template-columns:repeat(3,minmax(0,var(--card-max)));
  gap:var(--grid-gap);justify-content:center}
/* Неполный ряд центрируем: «More Cases» с одной карточкой иначе жалась
   к левому краю, оставляя две трети полки пустыми. Ширина колонки при
   этом равна обычной, так что карточка не растягивается. */
/* Неполный ряд: колонок ровно по числу карточек, остальное — поля.
   Центрирование уже задано у .bs-grid. */
.bs-grid.few[data-n="1"]{grid-template-columns:minmax(0,var(--card-max))}
.bs-grid.few[data-n="2"]{grid-template-columns:repeat(2,minmax(0,var(--card-max)))}
/* Класса .cols-4 больше нет: по ТЗ ящики идут по три в ряд в любом
   разделе, независимо от его длины (см. renderSections в main.html). */

/* Ячейка — контейнер отсчёта cqw и запас под вылет скошенных углов. */
.bs-cell{container-type:inline-size}

.bs-card{
  /* Наклон НЕ здесь: он на .gpanel, карточка его наследует. Свой skew
     сложился бы с родительским и дал бы двойной. Обратный скос
     содержимого берёт --fb-unskew с той же подложки. */
  --bs-ink-line:#000E3C;

  position:relative;display:flex;flex-direction:column;
  width:100%;aspect-ratio:381/295;
  /* ОБВОДКА. Цвет снят с ВЕРХНЕЙ кромки, а не с боковой: карточка в
     референсе скошена на 5°, и боковую кромку скос размазывает по
     лишним пикселям — усреднение по ней давало ложные #1754A7. Верхняя
     кромка горизонтальна, скос по X её не трогает, и там ядро обводки
     читается чисто: #000C3A у big и #000F3F у mega, в среднем #000E3C.

     СНИЗУ ОБВОДКА ВДВОЕ ТОЛЩЕ. По профилю почти чёрная полоса внутри
     карточки занимает y=-6..-1, то есть 6 px, тогда как сверху ядро
     укладывается в 3 px (y=0..+2). Обе карточки дали одно и то же.
     Толщины в пикселях, как в референсе: наша карточка 332 против 381,
     разница 13 % — в пределах округления border-width браузером. */
  border:3px solid var(--bs-ink-line);
  border-bottom-width:6px;
  /* ТЕНЬ ЖЁСТКАЯ, БЕЗ РАЗМЫТИЯ — и только снизу.
     Прошлый вариант с блюром был ошибкой замера: боковой «ореол» в 5 px
     я снял, усредняя профиль по 150 строкам, а скос уводит боковую
     кромку на 13 px по этой высоте — она просто проехала через кадр, и
     смаз я принял за размытие. Нижняя кромка горизонтальна, скос её не
     трогает: там ровно 6 px плотной полосы (y=+0..+5) без спада, дальше
     сразу фон.
     Цвет и альфа найдены по ДВУМ кадрам сразу: у big и mega разный фон
     под тенью (rgb(22,106,254) и rgb(12,80,255)), поэтому система из
     двух уравнений решается однозначно — rgba(0,0,22,.423). Обратная
     подстановка воспроизводит оба замера с точностью до единицы. */
  box-shadow:0 6px 0 rgba(0,0,22,.423);
  border-radius:3.67cqw;overflow:hidden;
  background:#01A5FC;   /* подложка под свечение .bs-art */
  cursor:pointer;
  transition:filter .14s ease;
}
.bs-card:hover,.bs-card:focus-visible{filter:brightness(1.06)}

/* Тело: арт снизу, название абсолютом в правом верхнем углу. */
/* ФОН ТЕЛА — РАДИАЛЬНОЕ СВЕЧЕНИЕ, А НЕ ЛИНЕЙНЫЙ ГРАДИЕНТ.
   Прежний linear-gradient(#058CE9 → #00A0FE) был ошибкой замера: я снял
   его вдоль боковой кромки, а её размазывает скос 5°. По строкам, взятым
   с поправкой на скос, картина другая — фон ярче в СЕРЕДИНЕ и по
   вертикали, и по горизонтали: зелёный канал 164 у края, 206 на четверти
   ширины, 229 на трети, симметрично с обеих сторон.
   Подгонка по 9930 чистым пикселям фона обоих кадров дала эллипс
   47 % x 32 % ширины карточки (это 47 % x 54.4 % коробки тела) со
   среднеквадратичной ошибкой 7.6 из 255. Центр закрыт артом, поэтому его
   цвет получен экстраполяцией замеренного кольца t=0.5..1.0; на вид он
   почти не участвует — видно как раз кольцо.
   Спад НЕ линейный: измеренные значения идут выше прямой между центром и
   краем, поэтому кривая набрана промежуточными стопами. */
.bs-art{
  background:radial-gradient(47% 54.4% at 50% 50%,
    #9DFFFA 0%, #47E3F9 55%, #38DDFB 65%, #25CCFC 75%,
    #17BDFC 85%, #08AFFC 95%, #01A5FC 100%);
  position:relative;flex:1 1 auto;min-height:0;
  display:flex;align-items:flex-end;justify-content:center;
  padding:0 2cqw 1cqw;
}
/* РАЗМЕР АРТА. В референсе ящик 55 %W в ширину и 39 %W в высоту — он
   нарисован приплюснутым. Наши картинки почти квадратные, и при той же
   ВЫСОТЕ выходили заметно уже: 38 x 38 вместо 55 x 39. Поэтому за
   ориентир взята зрительная ПЛОЩАДЬ: корень из 55x39 = 46.3 %W — при
   квадратной картинке это та же занимаемая площадь, что у эталона.
   Поверх этого сохранено соотношение, заданное раньше вручную:
   Small на 10 % мельче Big, Mega вровень с Big, Starr Drop как была.
   У Mega Box в файле 13 % прозрачного поля по краям, поэтому её процент
   выше — он компенсирует поле, а не увеличивает ящик. */
.bs-art img{
  height:var(--bs-art-h,46.3cqw);width:auto;max-width:94%;object-fit:contain;
  transform:skewX(var(--fb-unskew));   /* стоит прямо в наклонной рамке */
  filter:drop-shadow(0 1.6cqw 2cqw rgba(3,40,95,.34));
}
.bs-art .bs-emoji{
  font-size:30cqw;line-height:1;
  transform:skewX(var(--fb-unskew));
  filter:drop-shadow(0 1.6cqw 2cqw rgba(3,40,95,.34));
}
.bs-name{
  position:absolute;top:5.38cqw;right:2.36cqw;z-index:2;
  transform:skewX(var(--fb-unskew));
  transform-origin:100% 50%;
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;font-size:8.75cqw;line-height:1;color:#fff;
  letter-spacing:.04em;word-spacing:-.09em;   /* трекинг — см. .bs-ink */
  white-space:nowrap;text-transform:uppercase;
  text-shadow:var(--so),var(--extrude);
}

/* Полоса цены. */
.bs-price{
  flex:0 0 auto;height:18.37cqw;
  display:grid;place-items:center;
  background:#3C4B73;
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;font-size:12.55cqw;line-height:1;color:#fff;
  letter-spacing:.04em;
  text-shadow:var(--so),var(--extrude);
}
.bs-price span{transform:skewX(var(--fb-unskew));display:block}

/* ---------------------------------------------------------------------
   СКИДКА НА ЯЩИК
   ---------------------------------------------------------------------
   Три метки, и каждая отвечает на свой вопрос: сколько стоило (<s> в
   полосе цены), насколько дешевле (плашка на арте) и сколько это ещё
   продлится (таймер под плашкой). Все три сидят на карточке, а не
   всплывают поверх витрины: игрок сравнивает ящики глазами по полке, и
   уводить хоть одно из чисел в сторону значит заставлять его открывать
   ящик, чтобы узнать цену.

   КЕГЕЛЬ ЦЕНЫ НЕ ТРОГАЕМ. Соблазн уменьшить его был: два числа вместо
   одного. Замер говорит обратное — «6 229 4 983 ₽» занимает 240 из 327
   доступных пикселей полосы, то есть 73 % её ширины, и на любой ширине
   экрана эта доля та же (всё в полосе задано в cqw). Мельчить цену
   действующую ради зачёркнутой незачем: старая цена и так вдвое мельче
   своим em.
   --------------------------------------------------------------------- */
.bs-card.on-sale .bs-price s{
  /* Перечёркнутое число приглушено и уменьшено — оно справка, а не цена.
     Линия своя (не text-decoration): встроенное перечёркивание браузер
     рисует по базовой линии шрифта, а MegaBoxFont сидит в строке высоко,
     и линия проходила по нижней трети цифр. */
  position:relative;font-size:.62em;opacity:.72;
  margin-right:.42em;text-decoration:none;
}
.bs-card.on-sale .bs-price s::after{
  content:"";position:absolute;left:-.06em;right:-.06em;top:47%;
  height:.1em;background:currentColor;border-radius:.05em;
}

/* Плашка «−20%» и таймер — слева, ПОД НАЗВАНИЕМ, а не в самом верхнем
   углу. Верхний угол занят: .bs-name стоит абсолютом справа, но у обоих
   акционных ящиков имя длинное («УЛЬТРАЛЕГЕНДАРНЫЙ ЯЩИК») и тянется
   почти во всю карточку — замер дал наложение плашки на буквы. Самая
   длинная строка заканчивается на 14.1cqw от верха, отсюда и отступ.
   Арт плашка при этом слегка перекрывает, и это нормально: скидка на
   ящике — наклейка на коробке, а не подпись рядом с ней.

   Обратный скос тот же, что у остальных надписей: рамка наклонена на
   5°, а числа в ней стоят прямо. */
.bs-off,.bs-left{
  position:absolute;left:3.1cqw;z-index:3;
  transform:skewX(var(--fb-unskew));transform-origin:0 50%;
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;line-height:1;white-space:nowrap;
}
.bs-off{
  top:16.5cqw;font-size:8.2cqw;color:#fff;
  padding:1.5cqw 2.4cqw 1.2cqw;border-radius:2.2cqw;
  /* Красный, а не жёлтый: жёлтый на сайте уже занят легендарной
     ступенью (RARITIES), и плашка скидки читалась бы как метка
     редкости ящика. */
  background:#E8323C;border:.75cqw solid var(--bs-ink-line);
  box-shadow:0 1.1cqw 0 rgba(0,0,22,.42);
}
/* Таймер под плашкой. Мельче её вдвое: он меняется каждую секунду, и
   крупные скачущие цифры перетягивают внимание с самого ящика. */
.bs-left{
  top:29.3cqw;font-size:5.4cqw;color:#fff;
  letter-spacing:.02em;
  text-shadow:var(--so),var(--extrude);
  font-variant-numeric:tabular-nums;
}

.bs-card[data-case="smallbox"]{--bs-art-h:42.1cqw}   /* видно 42.1 %W */
.bs-card[data-case="bigbox"]  {--bs-art-h:47.3cqw}   /* видно 46.3 %W */
.bs-card[data-case="megabox"] {--bs-art-h:53.4cqw}   /* видно 46.3 %W */

/* ЯЩИКИ РЕДКОСТИ. Их арты пришли с глухим чёрным фоном на квадрате
   384x384; фон снят, а пустое поле сверху и снизу обрезано общим кадром
   (tools/unblack_boxes.py), и кадр стал 384x335 — ящик занимает в нём
   91 % высоты против 80 % до обрезки.
   Отсюда и процент: 55 x 0.913 = 50.2 %W видимого ящика. Это на 8 %
   крупнее коробок «Ностальгии» (46.3 %W) — то самое «немного увеличить»
   из ТЗ, освободившееся после снятия фона. Выше не берём: на 56 cqw
   картинка упирается в полосу цены.
   Ультре проценты не правятся: у неё вокруг ящика идут искры, они и
   должны занимать чуть больше места — так нарисовано. */
.bs-card[data-case="rarebox"],
.bs-card[data-case="superrarebox"],
.bs-card[data-case="epicbox"],
.bs-card[data-case="mythicbox"],
.bs-card[data-case="legendarybox"],
.bs-card[data-case="ultrabox"]{--bs-art-h:55cqw}      /* видно ~50 %W */

/* ОСОБЫЕ ЯЩИКИ (Хаос, Вселенная, Судьба). Их арты пришли уже с
   прозрачным фоном и обрезаны по содержимому (tools/import_new_art.py,
   --only 3boxes), поэтому ящик занимает В КАДРЕ все 100 % высоты против
   91 % у ящиков редкости — тот же процент дал бы картинку на десятую
   крупнее соседних панелей.
   Считаем не по высоте, а по ЗРИТЕЛЬНОЙ ПЛОЩАДИ — так же, как выше для
   Small/Big/Mega: эти три ящика нарисованы заметно более приплюснутыми
   (аспект 1.32-1.35 против 1.21 у редкостей), и при равной высоте они
   выглядели бы крупнее просто за счёт ширины.
   50 x sqrt(1.33) = 57.7 %W зрительной площади — ровно столько же, что
   у Вселенной со старым артом (54.2 x 61.7 -> 57.8). То есть при
   переезде в свою панель ящик не изменил размера, а Хаос с Судьбой
   встали вровень с ним.
   В ширину это 50 x 1.33 = 66.5 %W при разрешённых max-width:94%. */
.bs-card[data-case="chaosbox"],
.bs-card[data-case="universebox"],
.bs-card[data-case="fatebox"]{--bs-art-h:50cqw}       /* видно ~57.7 %W площади */

/* «УЛЬТРАЛЕГЕНДАРНЫЙ ЯЩИК» — единственное название, которое не влезает.
   Замер на трёх ширинах: строка занимает 1.11 ширины карточки, тогда
   как следующее по длине («ЛЕГЕНДАРНЫЙ ЯЩИК») — 0.82. Отношение от
   ширины экрана не зависит: кегль задан в cqw, то есть в долях самой
   карточки, поэтому на любом размере обрезало одинаково — у карточки
   overflow:hidden, и первые буквы просто исчезали («РАЛЕГЕНДАРНЫЙ
   ЯЩИК»).
   Кегль ужат до 6.5 cqw — 0.85 ширины карточки. Запас в 15 % не лишний:
   карточка СКОШЕНА на 5.06° (скос на .gpanel, карточка его наследует),
   и её левая кромка на высоте названия уходит вправо примерно на 9 px
   относительно габарита. По голому габариту строка «влезала» уже при
   7.1 cqw, а на экране у неё срезало первую букву.

   ЧИСЛА ПЕРЕСЧИТАНЫ ПОСЛЕ ПЕРЕИМЕНОВАНИЯ. Ящик звался
   «СУПЕРЛЕГЕНДАРНЫЙ» — на букву короче, — и тех же 0.85 хватало при
   7 cqw. Новое имя шире на 6 %, и на прежнем кегле доля выросла до 0.91:
   формально строка ещё помещалась в габарит, но запас съедало почти
   весь, а тратит его скос. Кегль ужат ровно настолько, чтобы доля
   вернулась к проверенным 0.85.
   Правило именное, а не общее: ужимать заодно шесть названий, которые
   и так помещаются, значило бы чинить не то. */
.bs-card[data-case="ultrabox"] .bs-name{font-size:6.5cqw}

/* «Скоро» — карточка гасится. */
.bs-card.locked{filter:saturate(.5) brightness(.86)}
.bs-card.locked:hover{filter:saturate(.5) brightness(.92)}

/* =====================================================================
   UPGRADER
   ---------------------------------------------------------------------
   Раздел стал рабочим и переехал в собственный файл css/upgrader.css
   (разметку строит js/upgrader.ui.js). Прежние правила заглушки
   (.upg-card с «строительными» полосами, .upg-ico, .upg-badge,
   .upg-lock) удалены вместе с самой заглушкой: элементов с этими
   классами на странице больше нет.
   ===================================================================== */

/* =====================================================================
   БЕСПЛАТНЫЕ ЯЩИКИ — ПАНЕЛЬ ПО РЕФЕРЕНСУ ПАНЕЛИ
   ---------------------------------------------------------------------
   ВСЁ СНЯТО ПИПЕТКОЙ С ФАЙЛА, НЕ НА ГЛАЗ.

   Референс снят с телефона и вдобавок наклонён: панель равномерно
   сдвинута по горизонтали на 5.06° (dx/dy = -0.0885, отклонение от
   прямой не больше 0.7 px на 174 строках — это чистый shear, не
   перспектива). Перед замерами картинка распрямлена обратным сдвигом,
   иначе все вертикали врали бы на ~80 px по высоте кадра.

   Распрямлённая панель: 445 x 875 px. Отсюда пропорции ниже — каждый
   размер выражен долей ШИРИНЫ панели (cqw от ячейки), поэтому на сайте
   карточка получается тем же изображением, отмасштабированным целиком.

     обводка      4 px → 0.90%      шапка      102 px → 22.92%
     черта        2 px → 0.45%      тело       641 px → 144.04%
     радиус       4 px → 0.90%      подвал     132 px → 29.66%
     просвет 875 px + обводки 4+4 → внешняя высота 883 px
     арт ящика  312 px → 70.11%     внешняя пропорция → 445/883

   Цвета (средние по чистым областям распрямлённого файла):
     обводка #051D48   шапка #2E81F8   черта верх #1C80EA
     тело: свечение #51FAFD в центре → края #1FAAF4
     черта низ #1B7CE9   подвал #2F83FD
     «ПОДАРОК» заливка #8DE94E, обводка глифов #091B18

   «ПОДАРОК» — ЭТО ТЕКСТ, А НЕ КНОПКА. На референсе под ним сплошная
   синяя полоса подвала #2F83FD без всякой плашки: зелёные только сами
   буквы. Прежняя зелёная кнопка была моим неверным прочтением мелкого
   скриншота и убрана.

   КАРТОЧКИ НЕРАБОЧИЕ ПО ЗАДАНИЮ: ни таймера, ни обработчиков.
   ===================================================================== */
/* =====================================================================
   ПОДЛОЖКА ПОД КАРТОЧКАМИ (.gpanel) — по референсному кадру панели
   Общая для двух секций: бесплатных ящиков и хранилища.
   ---------------------------------------------------------------------
   Кадр там скошен так же, как и остальные референсы, поэтому меряно по
   распрямлённой копии. Подложка 303 px шириной, карточка внутри 265 px;
   всё, что ниже, выражено долей ШИРИНЫ КАРТОЧКИ, а не подложки: у нас
   она втрое шире (три карточки в ряд вместо колонки), и проценты от её
   ширины дали бы поля и кегль втрое крупнее нужного.
     боковое поле        19 px → 7.2 % ширины карточки
     верх → капитель     24 px → 9.1 %
     капитель заголовка  20 px → 7.5 %  (кегль 20/0.69 = 29 px → 10.9 %)
     капитель → карточка 42 px → 15.8 %

   ПОДЛОЖКА НЕ ЗАЛИВКА, А ЗАТЕМНЕНИЕ. В референсе она не перекрывает
   фон, а гасит его: рядом с ней зелёный канал фона 100 и 164, под ней —
   76 и 119, при почти неизменном синем. Решение системы из этих двух пар
   даёт альфа-смешение rgba(21,27,243,.328) — обе пары воспроизводятся
   с точностью до единиц. Поэтому здесь полупрозрачный цвет, а не сплошной:
   так подложка гасит именно то, что под ней (у нас — видеофон), как в игре.
   ===================================================================== */
.gpanel{
  /* ОТСТУП ПОД ВЫЛЕТ СКОШЕННЫХ УГЛОВ. Подложка — параллелограмм: нижний
     левый и верхний правый углы уходят за свою колонку на
     tan(5.06°)·H/2 ≈ 0.044·H. При высоте около 820 px это ~36 px, а
     боковое поле .wrap даёт только 24 — на окне 1180 нижний левый угол
     срезался и появлялась горизонтальная прокрутка. 20 px собственного
     поля закрывают разницу с запасом. Поле текучее по той же причине,
     что и у .wrap: на планшете подложка ниже (карточки мельче), вылет
     падает вдвое, и держать под него полные 20 px, отнятые у карточек,
     незачем. Ниже 620 px поле, наоборот, РАСТЁТ: там сетка в две
     колонки, бесплатные ящики встают в два ряда, и подложка снова
     высокая — расчёт в медиазапросе в конце файла. */
  margin:0 clamp(12px,2vw,20px);
  /* НАКЛОН ВСЕГО УЗЛА. Замер левой кромки панели в референсе дал
     dx/dy = -0.08853, то есть skewX(-5.06°).

     Значение подтверждено ВТОРЫМ референсом — там
     карточки «ОСОБАЯ АКЦИЯ». Линейный фит по трём левым кромкам дал
     -0.08864 / -0.08863 / -0.08847, в среднем -0.08858 (5.062°) при
     отклонении от прямой 1.3-2.3 px на 157 строках. Две независимые
     съёмки сошлись на одном угле, так что 5.06° — это и есть штатный
     наклон витрины в игре, а не артефакт конкретного кадра.
     Правые кромки в том файле мерить нельзя: их портят звёздочки
     «3x выгода», свисающие за край карточки, — фит по ним даёт ложные
     4.1° при отклонении в 31 px.
     Скос от середины по высоте (origin по умолчанию) — верх уходит
     вправо, низ влево на одинаковую величину.

     НАКЛОНЕНА ТОЛЬКО РАМКА. Заголовок, арт и «ПОДАРОК» получают
     обратный skew на ту же величину (--fb-unskew ниже) и стоят прямо.
     Математика сходится точно: родитель переводит точку (u,v) ребёнка в
     (u + k·v), обратный скос у ребёнка даёт (u − k·v) ещё до этого, и
     после подстановки остаётся чистое (u). То есть содержимое не
     деформируется вовсе, а лишь съезжает вместе с рамкой — origin по
     умолчанию (центр элемента) для этого и нужен. */
  --fb-skew:-5.06deg;
  --fb-unskew:5.06deg;
  transform:skewX(var(--fb-skew));

  position:relative;
  /* Обводка ~3 px по краю (1.1 % ширины карточки). В референсе она
     заметно темнее подложки: по левой кромке зелёный 73 против 76 у
     тела, по верхней — 54 против 63 у полосы заголовка. Полупрозрачная,
     как и сама подложка: сплошная перестала бы гаситься видеофоном и
     выбилась бы из общей плотности. */
  border:3px solid rgba(0,30,170,.40);
  border-radius:20px;
  background:rgba(21,27,243,.328);
  /* Чтобы полоса заголовка обрезалась по скруглению угла. */
  overflow:hidden;
}

/* ПОЛОСА ЗАГОЛОВКА — второй, более тёмный синий сверху.
   Замер: под ней зелёный канал 63 против 84 у тела подложки при почти
   том же синем, то есть полоса на четверть темнее. Подбор смешения дал
   rgba(55,0,230,.25) поверх подложки — воспроизводит замер в ноль.
   Высота 55 px при карточке 265 = 20.8 % ширины карточки; у нас
   карточка выходит 331 px, отсюда 69 px. */
.gpanel-head{
  /* Не height, а min-height: на телефоне заголовок раздела набран мельче,
     но длинный («НОСТАЛЬГИЯ 2019-2020») всё равно может уйти на вторую
     строку — с жёсткой высотой её срезало бы. На компьютере ничего не
     меняется: строка в 38 px с полями укладывается в те же 69. */
  min-height:clamp(40px,7.4vw,69px);
  display:grid;place-items:center;
  padding:8px clamp(10px,2.4vw,24px);
  background:rgba(55,0,230,.25);
}
.gpanel-title{
  display:block;text-align:center;margin:0;
  text-transform:uppercase;   /* на референсе «ЯЩИКИ» капсом */
  font-family:"MegaBoxFont","Arial Black","Segoe UI",system-ui,sans-serif;
  /* Нижняя ступень 1.05rem, а не прежние 1.6: на 375 px «НОСТАЛЬГИЯ
     2019-2020» в 25 px не помещалась в строку и ломалась пополам. */
  font-weight:900;font-size:clamp(1.05rem,3.9vw,2.4rem);line-height:1;
  letter-spacing:.04em;word-spacing:-.09em;   /* трекинг — см. .bs-ink */
  color:#fff;
  text-shadow:var(--so),var(--extrude);
  transform:skewX(var(--fb-unskew));   /* стоит прямо в наклонной подложке */
}

/* Поля сетки — по референсу в долях ширины карточки: от полосы до
   карточки 28/265 = 10.6 %, по бокам 19/265 = 7.2 %, снизу 22/265 =
   8.3 %. При нашей карточке 331 px это 35 / 24 / 27. */
/* Колонки и текучие поля — по тем же причинам, что у .bs-grid (там же и
   про --grid-gap, и про две колонки на телефоне). */
.free-grid{display:grid;--grid-gap:clamp(7px,1.8vw,22px);
  grid-template-columns:repeat(3,minmax(0,var(--card-max)));
  gap:var(--grid-gap);justify-content:center}
.free-grid,
.gpanel-body{padding:clamp(12px,3.4vw,35px) clamp(10px,2.4vw,24px) clamp(10px,2.6vw,27px)}

/* Ячейка — контейнер отсчёта cqw. Ничего не рисует. */
.free-cell{container-type:inline-size}

.free-card{
  --fb-ink:#051D48;        /* обводка панели */
  --fb-head:#2E81F8;       /* полоса заголовка */
  --fb-line-top:#1C80EA;   /* черта под заголовком */
  --fb-body-edge:#1FAAF4;  /* тело, края (замер по углам) */
  --fb-line-bot:#1B7CE9;   /* черта над подвалом */
  --fb-foot:#2F83FD;       /* полоса подвала */
  --fb-green:#8DE94E;      /* заливка «ПОДАРОК» */
  --fb-glyph-ink:#091B18;  /* обводка глифов */

  position:relative;display:flex;flex-direction:column;
  /* 883 = 875 px просвета между обводками + сами обводки 4+4. box-sizing
     здесь border-box, поэтому aspect-ratio задаёт ВНЕШНИЙ размер: с
     445/875 полосы не сходились и тело недобирало 1.75 % ширины. */
  width:100%;aspect-ratio:445/883;
  /* Обводка задана долей ширины, как и всё в карточке, но с полом в
     полтора пикселя: на телефоне карточка ~95 px, 0.9 % от неё — меньше
     пикселя, и браузер стирал кант до еле заметной серой нитки. */
  border:max(1.5px,.9cqw) solid var(--fb-ink);
  border-radius:max(3px,.9cqw);overflow:hidden;
  background:var(--fb-body-edge);
  /* Наклон и переменные --fb-skew/--fb-unskew живут на .free-panel:
     в референсе скошен весь узел целиком, и второй skew здесь дал бы
     двойной наклон. */
}

/* ---- полоса заголовка ---- */
.free-head{
  flex:0 0 auto;height:22.92cqw;
  display:grid;place-items:center;padding:0 3cqw;
  background:var(--fb-head);
  border-bottom:max(1px,.45cqw) solid var(--fb-line-top);
}
.free-title{
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  /* Референс: капитель 36 px при панели 445 → кегль 36/0.73 = 49.3 px
     = 11.08cqw. Наши заголовки длиннее «2 Mega Boxes!», поэтому кегль
     подрезан до влезающего в строку: «Ящик за приглашение» — 19 знаков
     против 13 у «2 Mega Boxes!». 8.6cqw — крупнейший кегль, при котором
     он держится в одну строку с запасом (замер: 303 px в просвет
     333 px). Один кегль на все три карточки. */
  font-weight:900;font-size:8.6cqw;line-height:1;color:#fff;
  white-space:nowrap;text-align:center;
  letter-spacing:.04em;word-spacing:-.09em;   /* см. .bs-ink */
  transform:skewX(var(--fb-unskew));   /* стоит прямо в наклонной рамке */
  --so-c:var(--fb-glyph-ink);
  text-shadow:var(--so),var(--extrude);
}

/* ---- тело со свечением и артом ---- */
.free-box{
  position:relative;flex:1 1 auto;min-height:0;
  display:grid;place-items:center;
  /* ФОН ТОТ ЖЕ, ЧТО У КАРТОЧЕК ВИТРИНЫ — по заданию. Замер и разбор
     свечения см. у .bs-art выше: эллипс 47 % x 54.4 % коробки, центр
     #9DFFFA, край #01A5FC, промежуточные стопы под нелинейный спад.
     Прежнее свечение, снятое с референсного кадра панели (55.4 % x 48.4 %, центр
     #51FAFD), заменено на него же. */
  background:radial-gradient(47% 54.4% at 50% 50%,
    #9DFFFA 0%, #47E3F9 55%, #38DDFB 65%, #25CCFC 75%,
    #17BDFC 85%, #08AFFC 95%, #01A5FC 100%);   /* тот же фон, что у витрины */
  border-bottom:max(1px,.45cqw) solid var(--fb-line-bot);
}
.free-emoji{position:relative;font-size:22cqw;transform:skewX(var(--fb-unskew));
  filter:drop-shadow(0 2cqw 3cqw rgba(3,40,90,.35))}
.free-box.has-art .free-emoji{display:none}
.free-img{
  position:relative;width:70.11cqw;max-height:94%;object-fit:contain;
  transform:skewX(var(--fb-unskew));   /* стоит прямо в наклонной рамке */
  filter:drop-shadow(0 2.4cqw 3.2cqw rgba(4,45,95,.34));
}

/* ---- полоса подвала с надписью ---- */
.free-foot{
  flex:0 0 auto;height:29.66cqw;
  display:grid;place-items:center;
  background:var(--fb-foot);
}
.free-btn{
  /* На референсе оптический центр надписи стоит на 10.5 px (2.36 %
     ширины) ВЫШЕ середины полосы — выносные Lilita вниз пустые, и
     строка, выровненная по центру бокса, села бы ниже. */
  transform:translateY(-2.36cqw) skewX(var(--fb-unskew));
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  /* Референс: капитель 38 px → кегль 38/0.73 = 52.1 px = 11.70cqw. */
  font-weight:900;font-size:11.70cqw;line-height:1;letter-spacing:.04em;
  text-transform:uppercase;color:var(--fb-green);
  --so-c:var(--fb-glyph-ink);
  text-shadow:var(--so),var(--extrude);
  /* Курсор задаёт css/freebox.css: карточка целиком кликабельна, а сама
     подпись — <button>, и состояний у неё три (готов, откат, условие). */
  user-select:none;
}

/* =====================================================================
   ПОДВАЛ
   ---------------------------------------------------------------------
   Плиток «Как это работает» и жёлтой плашки ежедневного бонуса здесь
   больше нет — вместе с самими разделами (см. main.html).
   ===================================================================== */
footer{
  position:relative;z-index:1;margin-top:40px;padding:40px 0 34px;
  border-top:3px solid rgba(2,12,45,.5);
  background:linear-gradient(180deg,rgba(5,22,62,.55),rgba(4,16,48,.82));
}
.foot{display:flex;justify-content:space-between;gap:26px;flex-wrap:wrap;color:var(--text-dim);font-size:.88rem}
/* Колонки ссылок. Просвет текучий: на широком экране это те же 56 px,
   что стояли инлайном в разметке, а на телефоне колонки переносятся, и
   56 px между ними превращались в пустую полосу в пол-экрана. */
.foot-cols{display:flex;gap:clamp(22px,5vw,56px);flex-wrap:wrap}
.foot h5{color:#fff;font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;margin-bottom:12px;font-weight:900}
.foot ul{list-style:none}
.foot li{margin-bottom:8px}
.foot a{color:var(--text-dim);text-decoration:none;font-weight:600}
/* ПАЛЕЦ ПОПАДАЕТ ПО ССЫЛКЕ, А НЕ МЕЖДУ ССЫЛКАМИ — ТОЛЬКО НА ТЕЛЕФОНЕ.
   Строка подвала в 12 px кегля даёт цель высотой 19 px при шаге 27 —
   вдвое меньше подушечки пальца, и «Оплата и возврат» открывалась
   «Ответственной игрой».

   Поле по 11 px сверху и снизу доводит цель до 41 px. Сохранить при
   этом прежний просвет в 8 px НЕЛЬЗЯ: тогда шаг остаётся 27, а цели по
   41 налезают друг на друга на 14 px, и нажатие в нахлёст достаётся
   соседней ссылке — то есть промах никуда не делся, только стал
   незаметен в разметке. Поэтому строки раздвинуты: шаг ровно 41,
   просвет между текстами 22. Подвал на телефоне вырастает с 255 до
   ~340 px — для подвала это допустимо, промахи дороже.

   Ссылка — блок по ширине текста, а не всей колонки: на всю ширину
   цель накрыла бы пустоту справа и налезла на соседнюю колонку.

   На широком экране правило не включается: курсор точный, а плотный
   подвал там задан намеренно. */
@media (max-width:720px){
  .foot li{margin-bottom:0}
  .foot li > a{display:inline-block;padding:11px 0}
}
/* Логотип подвала набран шрифтом сцены, и 600 от соседних ссылок ему
   доставаться не должно: у семейства просят 900 везде, где оно
   используется, — почему именно, написано у @font-face в
   megabox.scene.css. */
.foot .logo{font-weight:900}
.foot a:hover{color:#fff}
/* ОГОВОРКА ПОДВАЛА. Два абзаца: что за сервис (со ссылками на шансы,
   оферту и ответственную игру) и отказ от аффилиации с Supercell.
   Отделена от колонок линией — это не ещё одна колонка ссылок, а то,
   что обязано быть прочитано. */
.disclaimer{
  margin-top:26px;padding-top:22px;
  border-top:2px solid rgba(255,255,255,.1);
  font-size:.76rem;color:#93B4DC;max-width:88ch;line-height:1.7;font-weight:600;
}
.disclaimer p + p{margin-top:12px}
.disclaimer b{color:#DCEAFB}
.disclaimer a{color:#BBD6F5;text-decoration:underline;text-underline-offset:2px}
.disclaimer a:hover{color:#fff}
/* Отказ от аффилиации набран мельче и глуше остального: он адресован не
   игроку, а правообладателю, и отнимать внимание у строки про
   ответственную игру не должен. */
.disclaimer-fan{color:#7593BC;font-size:.72rem}

/* =====================================================================
   TOAST
   ===================================================================== */
.toast-zone{
  position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:100000;
  display:flex;flex-direction:column;gap:10px;align-items:center;pointer-events:none;
}
.toast{
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;
  font-size:1rem;color:#fff;word-spacing:.16em;
  text-shadow:var(--so),var(--extrude);
  background:linear-gradient(180deg,#2a72e6,#123a92);
  border:3px solid rgba(255,255,255,.2);
  box-shadow:0 6px 0 #07204f, 0 14px 26px -8px rgba(2,10,45,.8);
  padding:11px 22px 15px;border-radius:16px;
  animation:toast-in .22s ease, toast-out .3s ease 2.9s forwards;
}
.toast-warn{background:linear-gradient(180deg,#FFD84D,#F5A524);box-shadow:0 6px 0 #A96A05, 0 14px 26px -8px rgba(2,10,45,.8)}
.toast-success{background:linear-gradient(180deg,var(--green-1),var(--green-2));box-shadow:0 6px 0 var(--green-sh), 0 14px 26px -8px rgba(2,10,45,.8)}
@keyframes toast-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateY(14px)}}

/* =====================================================================
   NOTICE — окно, которое ждёт «ОК»
   ---------------------------------------------------------------------
   Тост живёт 3,4 секунды и уезжает сам. Для «баланс скоро появится» это
   ровно столько, сколько надо, а для блокировки аккаунта — нет: там
   длинный текст, номер обращения и адрес поддержки, которые игрок
   обязан успеть прочитать и переписать. Такие сообщения приходят ОДИН
   раз (редиректом от Google, из письма) — не успел прочитать, и повода
   показать их снова у страницы нет.

   Поэтому окно стоит по центру, гасит фон и ждёт нажатия. Разметку
   строит window.notice в main.html.

   ЦВЕТА ОТ ОКНА ВХОДА (auth.css), а не от тоста: это диалог, и выглядеть
   он должен как диалог. Жёлтой осталась кнопка и значок — тем же
   предупреждающим жёлтым, что у .toast-warn, чтобы сообщение читалось
   как предупреждение с первого взгляда.
   ===================================================================== */
.notice-backdrop{
  position:fixed;inset:0;z-index:100001;display:flex;align-items:center;justify-content:center;
  padding:20px;overflow-y:auto;
  background:
    radial-gradient(900px 600px at 50% -10%, rgba(47,131,253,.30), transparent 60%),
    rgba(3,12,40,.86);
  backdrop-filter:blur(10px);
  opacity:0;transition:opacity .22s ease;
}
.notice-backdrop.show{opacity:1}
.notice-card{
  width:min(460px,100%);padding:30px 28px 26px;border-radius:20px;text-align:center;
  background:linear-gradient(180deg,#2555bb 0%,#12327f 60%,#0c2360 100%);
  border:3px solid rgba(0,30,170,.55);
  box-shadow:0 10px 0 #07184a, 0 40px 90px -30px rgba(0,0,0,.9);
  transform:translateY(16px) scale(.98);
  transition:transform .3s cubic-bezier(.2,.9,.25,1.05);
}
.notice-backdrop.show .notice-card{transform:none}
.notice-ic{
  width:64px;height:64px;margin:0 auto 16px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:1.9rem;
  background:linear-gradient(180deg,#FFD84D,#F5A524);
  box-shadow:0 5px 0 #A96A05, 0 18px 34px -12px rgba(2,10,45,.9);
}
.notice-title{
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;font-size:1.5rem;line-height:1.1;letter-spacing:.04em;word-spacing:-.09em;
  color:#fff;-webkit-text-stroke:0.1em var(--ink);paint-order:stroke fill;
  margin-bottom:12px;
}
/* Текст сообщения — обычным шрифтом и с человеческим межстрочным: в нём
   бывают адрес поддержки и номер обращения, и их переписывают руками. */
.notice-text{
  color:var(--text-dim);font-size:.95rem;font-weight:600;line-height:1.6;
  max-width:38ch;margin:0 auto 22px;word-break:break-word;
}
.notice-ok{
  width:100%;padding:14px 22px;border:none;border-radius:16px;cursor:pointer;
  font-family:"MegaBoxFont","Arial Black",system-ui,sans-serif;
  font-weight:900;font-size:1.05rem;letter-spacing:.06em;color:#fff;
  -webkit-text-stroke:0.09em var(--ink);paint-order:stroke fill;
  background:linear-gradient(180deg,#FFD84D,#F5A524);
  box-shadow:0 6px 0 #A96A05, 0 14px 26px -8px rgba(2,10,45,.8);
  transition:filter .2s ease, transform .09s ease, box-shadow .09s ease;
}
.notice-ok:hover{filter:brightness(1.08)}
.notice-ok:active{transform:translateY(6px);box-shadow:0 0 0 #A96A05}

/* =====================================================================
   АДАПТИВ / ДОСТУПНОСТЬ
   ===================================================================== */
:focus-visible{outline:3px solid var(--gold);outline-offset:3px;border-radius:8px}

/* Ниже 800 px в строку перестают влезать логотип, оба язычка и кнопка
   профиля: при полосе 33 группе нужно ~768 px. Уменьшаем --head-h — от
   неё считается вся геометрия баланса, так что язычки, кнопки и кегль
   ужимаются одним множителем, — и снимаем язычкам минимальную ширину:
   она рассчитана на «1 234 567 ₽», а на телефоне достаточно ширины по
   содержимому. Точка своя, не общая 620: там правится сетка карточек,
   а шапка ломается раньше. Одного шага хватает до 360 px — при полосе
   40 их требовалось два. */
@media (max-width:800px){
  :root{--head-h:26px}
  .hud{gap:calc(var(--head-h) * .24)}
  /* Доли те же, что и на десктопе, но урезанные: .75 → .4 у полей и
     4.375 → 2.8 у минимальной ширины. Ровно столько, чтобы на 360 px в
     строку встали значок, оба язычка и кнопка профиля. */
  .hud-pill{
    min-width:calc(var(--head-h) * 2.8);
    padding-left:calc(var(--head-h) * .4);
    column-gap:calc(var(--head-h) * .4);
  }
}

/* Плашка профиля и кнопка меню целиком считаются от --head-h, так что
   выше их править не пришлось. Здесь снимается только МИНИМУМ ширины
   профиля: 3.35 полосы рассчитаны на ник в строку, а ниже 620 ник
   скрывается (profile.css), и от плашки остаётся квадрат аватара с
   полями. Ещё ниже приходится ужимать саму полосу: на 360 px в строку
   встают логотип, плашка, оба язычка и кнопка меню — при полосе 26 им
   нужно ~347 px против 328 доступных. */
/* ПЛАШКА АПГРЕЙДЕРА УЖИМАЕТСЯ РАНЬШЕ ВСЕХ И РАНЬШЕ ВСЕХ ЖЕ УХОДИТ.
   Строка шапки и без неё набита под завязку: логотип, плашка профиля,
   два язычка баланса и кнопка меню. Язычки рассчитаны на «1 234 567 ₽»
   (см. их замеры выше), и на таком балансе шестому элементу места нет —
   он выталкивал бы кнопку меню за обрез, а body режет overflow-x, то
   есть кнопка просто пропадала бы. Границы не выдуманы, а замерены на
   этом самом балансе:

     • строка с подписью требует 917 px → подпись снимается ниже 950, и
       плашка садится на квадрат (у профиля тот же приём: ниже 720 от
       плашки остаётся один аватар, profile.css);
     • квадрат требует 897 px → ниже 900 плашка уходит из шапки совсем.

   Раздел при этом не теряется: там же, ниже 900, в меню появляется
   пункт «Апгрейдер» (css/menu.css) — дверь остаётся ровно там, куда на
   узком экране и тянутся. */
@media (max-width:950px){
  .ug-btn-name{display:none}
  .ug-btn-plate{min-width:var(--plate-h)}
  .ug-btn-pad{width:calc(var(--head-h) * 1.2);height:calc(var(--head-h) * 1.2)}
}
@media (max-width:900px){
  .ug-btn{display:none}
}
@media (max-width:620px){
  .profile-plate{min-width:calc(var(--head-h) * 2.1)}
}
@media (max-width:470px){
  :root{--head-h:23px}
}

/* Слово логотипа снимается только здесь, у самых узких телефонов: в
   строке четыре элемента, и на 430 px ей уже не хватает ширины — низ
   уезжал за обрез, а body режет overflow-x, так что кнопка профиля
   просто пропадала бы. Раньше слово пропадало ещё на 620: старая
   лежачая связка «значок + MegaDrop» была вдвое шире нынешнего
   столбика и столько не выдерживала. */
@media (max-width:470px){
  .site-head .logo-word{display:none}
}

/* =====================================================================
   ТЕЛЕФОН: ДВА ЯЩИКА В РЯД
   ---------------------------------------------------------------------
   Сначала витрина на узком экране разворачивалась в КОЛОНКУ (главная
   вытягивалась на 3 500 px), потом — в те же три колонки, что и на
   компьютере. Три оказались перебором: на 375 px карточка садилась на
   97 px, и ящик на ней приходилось угадывать, а название с ценой
   пришлось набирать долями в полтора раза крупнее референсных, чтобы
   они хоть читались. ДВЕ колонки дают 146 px — карточка в полтора раза
   шире, и почти всё, что было сломано усадкой, чинится само.

   ЧТО ИЗ ЭТОГО СЛЕДУЕТ:

   1. ПРОПОРЦИИ ВОЗВРАЩАЮТСЯ РЕФЕРЕНСНЫЕ. Квадрат вместо лежачих
      381x295 был подпоркой под 97 px: там референсная карточка выходила
      75 px высотой, из них 18 съедала полоса цены и 5 канты — арту
      оставалась полоска в 52 px, и квадрат отдавал ему 72. При 146 px
      та же референсная пропорция даёт 113 / 27 / 81: под арт больше,
      чем выторговывал квадрат, и это при полуторной ширине. Поэтому
      здесь больше НЕ правятся ни aspect-ratio, ни доли арта: они и так
      верные.
   2. КЕГЛИ ТОЖЕ РЕФЕРЕНСНЫЕ. Все размеры внутри карточки заданы в cqw,
      то есть в долях её ширины, и с ростом карточки название само
      выходит 12.8 px вместо 8.5, цена — 18.3 вместо 12.2. Прежние
      завышенные доли (10cqw у названия, 14cqw у цены) на широкой
      карточке дали бы уже 15 и 20 px — крупнее, чем нужно, и название
      «МАЛЕНЬКИЙ ЯЩИК» упёрлось бы в левый край.
   3. КАНТЫ И ТЕНЬ — ПО МИНИМУМУ ИЗ ДОЛИ И ПИКСЕЛЯ. Референсные 3 px
      сверху и 6 снизу — это 0.9 % и 1.8 % от карточки в 332 px; на 146
      доля даёт 1.3 и 2.6 px, и кант истончается до нитки. max() держит
      пол в 2 и 3 px, но на планшетной карточке в 246 px берёт долю —
      так толщина не прыгает ступенькой на самой границе 620 px.
   4. ТРЕТЬЯ КАРТОЧКА В РЯДУ ОДНА. Разделов по три ящика у нас два
      (витрина и бесплатные), и в две колонки третья карточка остаётся
      одна в нижнем ряду. Прижатая к левому краю, она читается как
      обрыв, поэтому одинокий хвост растягивается на оба столбца и
      встаёт по центру, сохраняя ширину колонки: 100 % минус просвет,
      пополам. Ширина колонки не «примерно такая же», а ровно та же —
      отсюда и --grid-gap у сеток.
   5. НАКЛОН ОСТАЁТСЯ НА ПОДЛОЖКЕ. Прежде он переезжал отсюда на
      карточки: в одну колонку подложка вытягивалась до 1700 px, и скос
      выносил её углы на четверть ширины экрана. В два ряда подложка
      доходит до 534 px, вылет её углов — 24 px, и его закрывают поля
      (см. .gpanel ниже — их пришлось расширить). Это важнее, чем
      кажется: скос подложки сдвигает всё содержимое ОДИНАКОВО, поэтому
      просветы сетки остаются ровными, а скос на каждой карточке
      порознь сводил бы их углы вплотную.

   Плата за вторую колонку — высота: у бесплатных ящиков два ряда
   вместо одного. Поэтому карточка подарка здесь единственная, кому
   пропорции всё же правятся (см. ниже).
   ===================================================================== */
@media (max-width:620px){
  /* ---- сетка ---- */
  .bs-grid,.free-grid{
    grid-template-columns:repeat(2,minmax(0,var(--card-max)));
  }
  /* ПОДЛОЖКА ОТОДВИГАЕТСЯ ОТ КРАЁВ. Она скошена целиком, поэтому её
     углы вылетают за собственную кромку на tan(5.06°)·H/2 — тем
     дальше, чем она выше. С двумя колонками бесплатные ящики встают в
     два ряда, подложка вытянулась с 220 до 540 px, и вылет вырос с 10
     до 24 px против 22 доступных (12 своих полей плюс 10 у .wrap):
     нижний левый угол срезало, и появлялась горизонтальная прокрутка.
     Потребное поле — решение неравенства (поле .wrap + m) ≥ 0.0443·H(m),
     где H сама зависит от m через ширину карточки: 11 px на 320,
     14 на 375, 24.2 на 620. clamp ниже даёт 14 / 15.8 / 26 — с запасом
     на всех трёх и без ступеньки между ними. */
  .gpanel{margin:0 clamp(14px,4.2vw,27px)}
  /* Одинокий хвост неполного ряда — по центру, шириной в колонку.
     .few сюда не попадает: там колонок ровно по числу карточек, ряд
     полный, и span 2 нарисовал бы вторую колонку из ничего. */
  .bs-grid:not(.few)>.bs-cell:last-child:nth-child(odd),
  .free-grid>.free-cell:last-child:nth-child(odd){
    grid-column:span 2;justify-self:center;
    width:calc((100% - var(--grid-gap)) / 2);
  }

  /* ---- карточка ящика ---- */
  .bs-card{
    border-width:max(2px,.9cqw);
    border-bottom-width:max(3px,1.8cqw);
    box-shadow:0 max(3px,1.8cqw) 0 rgba(0,0,22,.423);
  }

  /* ---- карточка бесплатного ящика ---- */
  /* ЕДИНСТВЕННОЕ, ЧТО ПРИХОДИТСЯ ЖАТЬ. Референсные 445x883 — почти
     вдвое выше своей ширины: при 146 px это 290 px, а карточек три,
     то есть два ряда, и один раздел «Бесплатные ящики» занял бы под
     600 px — три четверти экрана. 445/700 оставляет ту же тройку полос
     (заголовок, арт, подпись) и садит карточку до 230 px.
     Внутренние доли при этом не трогаются: тело гибкое (flex:1 1 auto),
     оно и отдаёт срезанную высоту, а заголовок с подвалом остаются
     референсными — на 146 px это 12.6 и 17 px, читается с руки.
     Подпись при этом влезает в ОДНУ строку: самая длинная («Ящик за
     приглашение») занимает 89 из 112 px просвета на 320 px и 111 из
     139 на 375 — та же доля, что на компьютере, там 247 из 307. */
  .free-card{aspect-ratio:445/700}

  /* ---- ШАПКА: ЯЗЫЧОК БАЛЛОВ УХОДИТ В МЕНЮ ----
     Строка шапки на телефоне была ПЕРЕПОЛНЕНА, и это не мелочь вида
     «тесновато»: при входе в аккаунт кнопка меню уезжала за правый
     обрез, а body режет overflow-x — то есть на телефоне у вошедшего
     игрока меню просто не открывалось. Замер на 375 px: значок 52 +
     плашка профиля 48 + два язычка 247 + кнопка меню 46 + просветы 27 =
     420 против 355 доступных.

     Снимается язычок БАЛЛОВ, а не что-либо ещё, по трём причинам:
     баланс — единственное число в шапке, за которым стоят настоящие
     деньги; логотип и кнопка меню незаменимы; а у самих баллов уже
     есть, куда переехать. Приём в шапке не новый — ровно так же ниже
     900 px из неё уходит плашка апгрейдера (см. её медиазапрос выше),
     и раздел не теряется, а появляется строкой в меню. Здесь то же
     самое: счётчик баллов стоит первой строкой меню (js/menu.ui.js,
     оформление в css/menu.css) — за той же кнопкой, что и раньше.

     Оставшийся язычок с балансом влезает с запасом: 52 + 48 + 132 + 46
     + 21 = 299 из 355, и даже семизначная сумма не выталкивает меню. */
  .hud-pill[data-hud="points"]{display:none}

  /* ---- прочее ---- */
  /* Просветы шапки и поля язычка ужаты: освободившееся место лучше
     отдать самим плашкам, чем воздуху между ними. */
  .nav{gap:7px}
  .hud-pill{
    padding-left:calc(var(--head-h) * .32);
    column-gap:calc(var(--head-h) * .32);
  }
  /* «Войти» здесь не правится: её размеры считаются от --head-h, как у
     остальных плашек шапки, и ужимаются вместе с ними. */
  .site-head .btn{padding:9px 14px 13px;font-size:.9rem;border-radius:13px}
  /* Вертикальные просветы ужаты вместе с карточками: между двумя
     низкими панелями прежние 104 px читались как пропущенный раздел. */
  section{padding:30px 0}
  :root{--panel-gap:44px}
  footer{margin-top:22px;padding:28px 0 26px}
  .foot{gap:18px}
  .disclaimer{margin-top:20px;padding-top:18px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .bg-stage video{display:none}
}
