/* ============================================================================
   Stars TMA — juice.css
   AAA game-juice библиотека дофаминовых анимаций. Цель: 120fps, залипание.
   ПРАВИЛА ДВИЖКА:
     • Анимируем ТОЛЬКО transform / opacity / filter — никаких width/top/left.
     • will-change вешаем точечно и снимаем после (см. комментарии).
     • Все тяжёлые эффекты глушатся в prefers-reduced-motion (низ файла).
   Использует переменные из style.css: --gold #ffd24a, --gold2 #ffb020, --spring.
   ========================================================================== */

:root{
  /* Кривые движения. --spring уже есть в style.css, дублируем родню сюда. */
  --ease-out: cubic-bezier(.22, 1, .36, 1);      /* появление — резкий старт, мягкий стоп */
  --ease-in:  cubic-bezier(.55, 0, .68, .35);    /* исчезновение */
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);  /* упругий перелёт (overshoot) */
  --rarity: var(--gold);                          /* цвет редкости по умолчанию (переопределяется на элементе) */
}

/* ============================================================================
   0. Базовый слой производительности
   Всё, что живёт постоянно, поднимаем на GPU-композит-слой.
   ========================================================================== */
.gpu{ transform: translateZ(0); backface-visibility: hidden; }


/* ============================================================================
   1. IDLE-ДЫХАНИЕ КЕЙСОВ
   Кейс никогда не стоит мёртвым: медленно всплывает и чуть дышит масштабом.
   Разные фазы (.breath--a/b/c) — чтобы сетка кейсов не пульсировала в унисон.
   Вешать: .case-card → .breath (+ опц. .breath--b / .breath--c)
   ========================================================================== */
@keyframes breath{
  0%,100%{ transform: translate3d(0,0,0) scale(1); }
  50%    { transform: translate3d(0,-5px,0) scale(1.018); }
}
.breath{
  animation: breath 3.6s ease-in-out infinite;
  will-change: transform;
}
/* Сдвиг фазы — чтобы соседние кейсы «дышали» вразнобой */
.breath--b{ animation-delay: -1.2s; animation-duration: 4.1s; }
.breath--c{ animation-delay: -2.4s; animation-duration: 3.2s; }
/* Пауза при наведении/удержании — элемент замирает под вниманием игрока */
.breath:active{ animation-play-state: paused; }


/* ============================================================================
   2. ПУЛЬСИРУЮЩЕЕ ЗОЛОТОЕ СВЕЧЕНИЕ (легендарки)
   Двойной box-shadow: плотное ядро + мягкое гало. Пульс дыханием яркости.
   Для картинок/иконок используем .legend-glow--img (drop-shadow вместо box).
   Вешать: легендарный .case-card / .inv-item → .legend-glow
   ========================================================================== */
@keyframes legendPulse{
  0%,100%{
    box-shadow: 0 0 0 1px rgba(255,210,74,.55),
                0 0 12px 2px rgba(255,210,74,.45),
                0 0 32px 6px rgba(255,176,32,.25);
  }
  50%{
    box-shadow: 0 0 0 1px rgba(255,210,74,.9),
                0 0 22px 6px rgba(255,210,74,.7),
                0 0 54px 14px rgba(255,176,32,.45);
  }
}
.legend-glow{
  animation: legendPulse 2s ease-in-out infinite;
  will-change: box-shadow;
  border-radius: inherit;
}
/* Вариант для прозрачных PNG-иконок: свечение по контуру, а не по коробке */
@keyframes legendPulseImg{
  0%,100%{ filter: drop-shadow(0 0 4px rgba(255,210,74,.5)) drop-shadow(0 0 10px rgba(255,176,32,.35)); }
  50%    { filter: drop-shadow(0 0 9px rgba(255,210,74,.9)) drop-shadow(0 0 22px rgba(255,176,32,.6)); }
}
.legend-glow--img{
  animation: legendPulseImg 2s ease-in-out infinite;
  will-change: filter;
}


/* ============================================================================
   3. SHIMMER-БЛИК
   Диагональный световой блик пробегает по поверхности (кнопки, карточки).
   Реализация через ::after с translateX — нулевой layout-cost.
   Требует у родителя position:relative и overflow:hidden.
   Вешать: .btn.gold / премиум .case-card → .shimmer
   Разовый блик по событию: добавить класс .shimmer--once (снять по animationend).
   ========================================================================== */
.shimmer{ position: relative; overflow: hidden; }
.shimmer::after{
  content:"";
  position:absolute;
  top:-50%; left:-60%;
  width:40%; height:200%;
  background: linear-gradient(
    100deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.35) 45%,
    rgba(255,255,255,.55) 50%,
    rgba(255,255,255,0) 100%
  );
  transform: translateX(0) rotate(8deg);
  animation: shimmerMove 3.4s ease-in-out infinite;
  will-change: transform;
  pointer-events:none;
}
@keyframes shimmerMove{
  /* Долгая пауза + быстрый пробег — блик как «случайный» отблеск, не мигалка */
  0%,   62%{ transform: translateX(0)     rotate(8deg); }
  78%,100% { transform: translateX(420%)  rotate(8deg); }
}
/* Разовый пробег (по клику/выпадению) — короче и без паузы */
.shimmer--once::after{ animation: shimmerMove .8s var(--ease-out) 1; }


/* ============================================================================
   4. ПРУЖИННОЕ ПОЯВЛЕНИЕ
   Элемент влетает с перелётом (overshoot) через --spring.
   Вешать: модалки, карточки, кнопки при монтировании → .spring-in
   Каскад в списках: обернуть .stagger, детям задать --i (или .s1..s8).
   ========================================================================== */
@keyframes springIn{
  0%  { opacity:0; transform: translate3d(0,14px,0) scale(.86); }
  60% { opacity:1; }
  100%{ opacity:1; transform: translate3d(0,0,0) scale(1); }
}
.spring-in{
  animation: springIn .42s var(--spring) both;
  will-change: transform, opacity;
}
/* Появление «из глубины» — для крупных вау-карточек */
@keyframes popScale{
  0%  { opacity:0; transform: scale(.4); }
  100%{ opacity:1; transform: scale(1); }
}
.pop-in{ animation: popScale .5s var(--ease-back) both; will-change: transform, opacity; }

/* Каскадное появление сетки/списка (stagger 55мс на элемент) */
.stagger > *{ animation: springIn .42s var(--spring) both; }
.stagger > *{ animation-delay: calc(var(--i, 0) * 55ms); }
/* Готовые слоты, если не хочется inline-переменной --i */
.stagger > *:nth-child(1){ --i:0 } .stagger > *:nth-child(2){ --i:1 }
.stagger > *:nth-child(3){ --i:2 } .stagger > *:nth-child(4){ --i:3 }
.stagger > *:nth-child(5){ --i:4 } .stagger > *:nth-child(6){ --i:5 }
.stagger > *:nth-child(7){ --i:6 } .stagger > *:nth-child(8){ --i:7 }


/* ============================================================================
   5. ТРЯСКА ЭКРАНА
   Экспоненциально затухающий шейк. Вешать на корневой контейнер приложения.
   .shake-sm — добыча/мелкий отклик, .shake-lg — момент выигрыша.
   Снимать класс по animationend, иначе не сработает повторно.
   Вешать: #app / .screen → .shake-sm | .shake-lg
   ========================================================================== */
@keyframes shakeSm{
  0%{transform:translate3d(0,0,0)} 20%{transform:translate3d(-2px,1px,0)}
  40%{transform:translate3d(2px,-1px,0)} 60%{transform:translate3d(-1px,1px,0)}
  80%{transform:translate3d(1px,0,0)} 100%{transform:translate3d(0,0,0)}
}
@keyframes shakeLg{
  0%{transform:translate3d(0,0,0) rotate(0)}
  10%{transform:translate3d(-7px,4px,0) rotate(-.6deg)}
  25%{transform:translate3d(6px,-5px,0) rotate(.5deg)}
  40%{transform:translate3d(-5px,3px,0) rotate(-.4deg)}
  55%{transform:translate3d(4px,-2px,0) rotate(.3deg)}
  70%{transform:translate3d(-2px,1px,0) rotate(-.15deg)}
  85%{transform:translate3d(1px,-1px,0) rotate(0)}
  100%{transform:translate3d(0,0,0) rotate(0)}
}
.shake-sm{ animation: shakeSm .18s ease-out both; will-change: transform; }
.shake-lg{ animation: shakeLg .5s cubic-bezier(.36,.07,.19,.97) both; will-change: transform; }


/* ============================================================================
   6. RARITY-ВСПЫШКА
   Радиальный флеш цвета редкости в момент выпадения приза. Overlay поверх карточки.
   Цвет задаётся переменной --rarity на самом элементе (по умолчанию золото).
   Готовые модификаторы редкости ниже.
   Вешать: overlay-div внутри .win-card → .rarity-flash (+ .rarity-flash--legendary и т.п.)
   ========================================================================== */
@keyframes rarityFlash{
  0%  { opacity:0; transform: scale(.2); }
  15% { opacity:1; }
  100%{ opacity:0; transform: scale(2.4); }
}
.rarity-flash{
  position:absolute; inset:0; margin:auto;
  width:60%; aspect-ratio:1; border-radius:50%;
  background: radial-gradient(circle,
    var(--rarity) 0%,
    color-mix(in srgb, var(--rarity) 40%, transparent) 40%,
    transparent 70%);
  mix-blend-mode: screen;
  pointer-events:none;
  animation: rarityFlash .7s var(--ease-out) 1 both;
  will-change: transform, opacity;
}
/* Палитра редкости — переопределяем --rarity */
.rarity-flash--common   { --rarity:#9aa7bd; }
.rarity-flash--rare     { --rarity:#4aa3ff; }
.rarity-flash--epic     { --rarity:#b45cff; }
.rarity-flash--legendary{ --rarity:var(--gold); }
.rarity-flash--mythic   { --rarity:#ff5c7a; }


/* ============================================================================
   7. ПЛАВАЮЩИЕ ЧАСТИЦЫ-ИСКРЫ (CSS-only)
   Фон модалки выигрыша: искры медленно всплывают и гаснут.
   Контейнер .sparks, до 16 искр .spark с индивидуальными --x/--d/--s.
   Реализация одним keyframes + переменные — минимум нод, ноль JS.
   Вешать: фон .win-modal → .sparks с детьми <i class="spark s1..s16">
   ========================================================================== */
.sparks{ position:absolute; inset:0; overflow:hidden; pointer-events:none; border-radius:inherit; }
.spark{
  position:absolute; bottom:-8px; left:var(--x,50%);
  width:6px; height:6px; border-radius:50%;
  background: radial-gradient(circle, var(--gold) 0%, var(--gold2) 55%, transparent 70%);
  opacity:0;
  transform: translateZ(0);
  animation: sparkRise var(--d,6s) linear var(--delay,0s) infinite;
  will-change: transform, opacity;
}
@keyframes sparkRise{
  0%  { opacity:0; transform: translate3d(0, 0, 0) scale(var(--s,1)); }
  10% { opacity:1; }
  70% { opacity:.9; }
  100%{ opacity:0; transform: translate3d(var(--drift,0px), -120%, 0) scale(calc(var(--s,1) * .3)); }
}
/* Готовые пресеты положения/скорости искр (разброс по X, длительности, дрейф) */
.spark.s1 {--x:8%;  --d:5.5s; --delay:.0s; --s:1.1; --drift:12px}
.spark.s2 {--x:18%; --d:7.0s; --delay:.8s; --s:.8;  --drift:-8px}
.spark.s3 {--x:27%; --d:6.2s; --delay:1.6s;--s:1.3; --drift:16px}
.spark.s4 {--x:35%; --d:5.0s; --delay:.4s; --s:.7;  --drift:-14px}
.spark.s5 {--x:44%; --d:7.8s; --delay:2.1s;--s:1.0; --drift:6px}
.spark.s6 {--x:52%; --d:6.6s; --delay:1.1s;--s:1.2; --drift:-10px}
.spark.s7 {--x:60%; --d:5.3s; --delay:.6s; --s:.9;  --drift:14px}
.spark.s8 {--x:68%; --d:7.2s; --delay:1.9s;--s:1.1; --drift:-6px}
.spark.s9 {--x:76%; --d:6.0s; --delay:.2s; --s:.8;  --drift:10px}
.spark.s10{--x:84%; --d:5.7s; --delay:2.4s;--s:1.3; --drift:-16px}
.spark.s11{--x:92%; --d:7.5s; --delay:1.3s;--s:.9;  --drift:8px}
.spark.s12{--x:13%; --d:6.8s; --delay:2.8s;--s:1.0; --drift:-12px}
.spark.s13{--x:40%; --d:5.9s; --delay:3.2s;--s:.7;  --drift:18px}
.spark.s14{--x:57%; --d:7.1s; --delay:.9s; --s:1.2; --drift:-4px}
.spark.s15{--x:72%; --d:6.4s; --delay:3.6s;--s:.85; --drift:12px}
.spark.s16{--x:88%; --d:5.4s; --delay:1.7s;--s:1.05;--drift:-9px}


/* ============================================================================
   8. COUNT-UP (тик цифры)
   Счётчик валюты не прыгает — цифры «докручиваются» (число меняет JS),
   а сам блок делает upbeat-подскок при получении: .count-up добавить на кадр.
   Отдельный .digit-roll — для перекатывания одной цифры (opacity+translateY).
   Вешать: .balance / .wc-val → .count-up (на момент прибавки, снять по animationend)
   ========================================================================== */
@keyframes countPop{
  0%  { transform: scale(1); }
  35% { transform: scale(1.18); color: var(--gold); }
  100%{ transform: scale(1); }
}
.count-up{
  display:inline-block;
  animation: countPop .3s var(--ease-back) 1;
  will-change: transform;
}
/* Перекат одной цифры (для посимвольного счётчика): старая уезжает вверх, новая въезжает */
@keyframes digitRollIn{
  0%  { opacity:0; transform: translateY(60%); }
  100%{ opacity:1; transform: translateY(0); }
}
.digit-roll{ display:inline-block; animation: digitRollIn .22s var(--ease-out) both; will-change: transform, opacity; }


/* ============================================================================
   9. RIPPLE / PRESS
   Мгновенный тактильный отклик на тап (закон отклика ≤100мс).
   .press — сжатие с упругим возвратом (вешать на любую кнопку/карточку).
   .ripple — контейнер, .ripple-wave — волна из точки касания
             (координаты через --rx/--ry ставит JS в pointerdown).
   Вешать: .btn / .case-card → .press ; для волны — .ripple + вставка .ripple-wave
   ========================================================================== */
.press{ transition: transform .12s var(--ease-back); }
.press:active{ transform: scale(.95); }

.ripple{ position:relative; overflow:hidden; }
.ripple-wave{
  position:absolute; left:var(--rx,50%); top:var(--ry,50%);
  width:12px; height:12px; margin:-6px 0 0 -6px; border-radius:50%;
  background: radial-gradient(circle, rgba(255,255,255,.45), rgba(255,255,255,0) 70%);
  transform: scale(0); opacity:.8;
  pointer-events:none;
  animation: rippleWave .5s var(--ease-out) 1 forwards;
  will-change: transform, opacity;
}
@keyframes rippleWave{
  0%  { transform: scale(0);  opacity:.8; }
  100%{ transform: scale(18); opacity:0; }
}

/* Микро-«вздох» важной кнопки раз в ~8с — предвкушение без назойливости.
   Вешать: главная CTA (.btn.gold, кнопка спина) → .breathe-cta */
@keyframes breatheCta{
  0%,88%,100%{ transform: scale(1); }
  94%        { transform: scale(1.03); }
}
.breathe-cta{ animation: breatheCta 8s ease-in-out infinite; will-change: transform; }


/* ============================================================================
   10. ДОСТУПНОСТЬ — prefers-reduced-motion
   Глушим всё тяжёлое/бесконечное. Оставляем мгновенный press-отклик,
   чтобы интерфейс не ощущался «мёртвым» даже в щадящем режиме.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  .breath, .breath--b, .breath--c,
  .legend-glow, .legend-glow--img,
  .shimmer::after, .shimmer--once::after,
  .sparks .spark,
  .breathe-cta{
    animation: none !important;
  }
  .spring-in, .pop-in, .stagger > *,
  .rarity-flash, .count-up, .digit-roll,
  .shake-sm, .shake-lg, .ripple-wave{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
  /* Статичное мягкое свечение вместо пульса — легендарка всё ещё выделена */
  .legend-glow{ box-shadow: 0 0 14px 3px rgba(255,210,74,.5) !important; }
  /* press оставляем — это мгновенный тактильный отклик, не «движение» */
}
