/* fx.css – система движения игры «Первый заказ». Подключать ПОСЛЕ game.css и render.css.
   Анимируются только transform и opacity. Бесконечные эффекты выключаются в html.low и при reduced-motion. */

/* ================= ТОКЕНЫ ================= */
:root{
  --fx-tap:90ms;--fx-fast:140ms;--fx-base:240ms;--fx-slow:420ms;--fx-xslow:700ms;--fx-stagger:60ms;
  --fx-out:cubic-bezier(.2,.8,.2,1);
  --fx-in:cubic-bezier(.5,0,.9,.4);
  --fx-inout:cubic-bezier(.65,0,.35,1);
  --fx-spring:cubic-bezier(.34,1.56,.64,1);
  --fx-snap:cubic-bezier(.2,1.5,.4,1);
}

/* ================= СЛУЖЕБНЫЕ СЛОИ ================= */
.fx-canvas{position:fixed;left:0;top:0;width:100vw;height:100vh;pointer-events:none;z-index:97;visibility:hidden}
.fx-ghost{position:fixed;z-index:2;pointer-events:none;margin:0;will-change:transform,opacity}
.fx-ghost *{animation:none!important;transition:none!important}
.fx-fly{position:fixed;margin:0;z-index:96;pointer-events:none;will-change:transform,opacity}
.fx-vig{position:fixed;inset:0;pointer-events:none;z-index:96;opacity:0;background:radial-gradient(ellipse at center,transparent 52%,rgba(74,222,155,.34) 100%)}
.fx-vig[data-k="bad"]{background:radial-gradient(ellipse at center,transparent 52%,rgba(255,107,122,.36) 100%)}
.fx-vig[data-k="gold"]{background:radial-gradient(ellipse at center,transparent 45%,rgba(255,211,110,.4) 100%)}
.fx-flash{position:fixed;inset:0;pointer-events:none;z-index:96;opacity:0;background:radial-gradient(circle at 50% 40%,#fff 0,rgba(255,240,210,.7) 35%,rgba(255,211,110,0) 75%)}

/* ================= КЛЮЧЕВЫЕ КАДРЫ ================= */
@keyframes fxScrIn{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}
@keyframes fxFade{from{opacity:0}to{opacity:1}}
@keyframes fxRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes fxPop{0%{opacity:0;transform:scale(.5)}60%{opacity:1;transform:scale(1.1)}100%{opacity:1;transform:none}}
@keyframes fxPopIn{0%{opacity:0;transform:translateY(8px) scale(.9)}100%{opacity:1;transform:none}}
@keyframes fxNudgeIn{0%{opacity:0;transform:none}20%{opacity:1;transform:translateX(-7px)}40%{transform:translateX(6px)}60%{transform:translateX(-3px)}80%{transform:translateX(1px)}100%{opacity:1;transform:none}}
@keyframes fxGood{0%{transform:scale(1)}30%{transform:scale(1.035)}60%{transform:scale(.99)}100%{transform:scale(1)}}
@keyframes fxBad{20%{transform:translateX(-5px)}40%{transform:translateX(4px)}60%{transform:translateX(-2px)}80%{transform:translateX(1px)}}
@keyframes fxMsgIn{from{opacity:0;transform:translate(-10px,8px) scale(.86)}to{opacity:1;transform:none}}
@keyframes fxMsgOut{from{opacity:0;transform:translate(12px,10px) scale(.86)}to{opacity:1;transform:none}}
@keyframes fxNotif{0%{opacity:0;transform:translateY(-22px) scale(.92)}60%{opacity:1;transform:translateY(3px) scale(1.01)}100%{opacity:1;transform:none}}
@keyframes fxWiggle{0%{transform:scale(.6)}40%{transform:scale(1.15) rotate(-10deg)}60%{transform:rotate(8deg)}80%{transform:rotate(-4deg)}100%{transform:none}}
@keyframes fxHop{0%{opacity:0;transform:translateY(8px) scale(.7)}40%{opacity:1;transform:translateY(-10px) scale(1.06)}62%{transform:translateY(0) scale(1.1,.9)}80%{transform:translateY(-3px) scale(.97,1.03)}100%{opacity:1;transform:none}}
@keyframes fxAlert{0%{opacity:0;transform:scale(.7)}30%{opacity:1;transform:scale(1.1) rotate(-8deg)}50%{transform:rotate(7deg)}70%{transform:rotate(-4deg)}100%{opacity:1;transform:none}}
@keyframes fxSag{0%{opacity:0;transform:translateY(-4px)}50%{opacity:1;transform:translateY(3px) scale(1.03,.97)}100%{opacity:1;transform:none}}
@keyframes fxTilt{0%{opacity:0;transform:rotate(0)}40%{opacity:1;transform:rotate(-7deg)}70%{transform:rotate(3deg)}100%{opacity:1;transform:none}}
@keyframes fxBobIn{0%{opacity:0;transform:scale(.6) rotate(-6deg)}60%{opacity:1;transform:scale(1.08) rotate(2deg)}100%{opacity:1;transform:none}}
@keyframes fxSheen{0%,58%{transform:translateX(-130%) skewX(-18deg)}100%{transform:translateX(340%) skewX(-18deg)}}
@keyframes fxSweep{from{transform:translateX(-110%)}to{transform:translateX(110%)}}
@keyframes fxBreathe{0%,100%{transform:none}50%{transform:scale(1.025)}}
@keyframes fxReady{0%{transform:scale(.96)}55%{transform:scale(1.04)}100%{transform:none}}
@keyframes fxGrowX{from{transform:scaleX(0)}to{transform:none}}
@keyframes fxPing{0%{transform:scale(1);opacity:.7}100%{transform:scale(3);opacity:0}}
@keyframes fxBar{0%,100%{transform:none}50%{transform:scaleY(1.7)}}
@keyframes fxPulse{0%,100%{transform:none}50%{transform:scale(1.09)}}
@keyframes fxBlink{0%,49%{opacity:1}50%,100%{opacity:0}}
@keyframes fxHint{0%{opacity:0;transform:scale(.96)}30%{opacity:1;transform:scale(1.02)}100%{opacity:0;transform:scale(1.07)}}
@keyframes fxSpin{to{transform:rotate(360deg)}}
@keyframes fxXp{0%{opacity:0;transform:translateY(12px) scale(.5)}18%{opacity:1;transform:translateY(-4px) scale(1.28)}30%{transform:translateY(-8px) scale(1)}100%{opacity:0;transform:translateY(-80px) scale(.9)}}
@keyframes fxPunchText{0%{opacity:0;transform:scale(.4)}60%{opacity:1;transform:scale(1.25)}100%{opacity:1;transform:none}}
@keyframes fxLogo{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(4deg) translateY(-4px)}}

/* ================= ПЕРЕХОД ЭКРАНОВ ================= */
/* новый экран въезжает снизу с лёгким масштабом; старый уходит копией (FX.leave) */
.screen{animation:fxScrIn var(--fx-slow) var(--fx-out) 40ms both}
.modal .mw{animation:fxRise var(--fx-slow) var(--fx-out) both}

/* ================= КНОПКИ ================= */
/* главный призыв дышит и ловит блик; кнопка, ставшая доступной, «оживает» */
#bStart,#bCont,#toFin{position:relative;overflow:hidden}
#bStart{animation:fxBreathe 2.6s ease-in-out 1s infinite}
#bStart::after,#bCont::after,#toFin::after{content:'';position:absolute;top:0;bottom:0;left:0;width:42%;pointer-events:none;background:linear-gradient(100deg,transparent,rgba(255,255,255,.5),transparent);transform:translateX(-130%) skewX(-18deg);animation:fxSheen 3.6s var(--fx-inout) 1.4s infinite}
#fGo:not([disabled]),#chk:not([disabled]),#chkGo:not([disabled]),#asm:not([disabled]){animation:fxReady .5s var(--fx-spring)}

/* ================= ВАРИАНТЫ ОТВЕТА ================= */
.opt.good,.scam.ok,.mt.ok{animation:fxGood .5s var(--fx-out)}
.opt.bad,.scam.miss{animation:fxBad .42s var(--fx-out)}
.verdict.ok{animation:fxPopIn .45s var(--fx-spring) both}
.verdict.no{animation:fxNudgeIn .5s var(--fx-out) both}
/* подсветка правильного после ошибки (FX.hint) */
.fx-hint{position:relative}
.fx-hint::before{content:'';position:absolute;inset:-4px;border-radius:inherit;border:2px solid var(--green,#4ADE9B);pointer-events:none;animation:fxHint 1.2s var(--fx-out) 2 both}
.numz{display:inline-block}
.numz.hit{animation:fxPop .5s var(--fx-spring) both}

/* ================= XP, УРОВЕНЬ, КОШЕЛЁК ================= */
.fx .xp{animation:fxXp 1.3s var(--fx-out) forwards;text-shadow:0 0 18px rgba(255,211,110,.55),0 4px 20px rgba(0,0,0,.5)}
.hud .hxp b{transform-origin:left center;position:relative;overflow:hidden}
.hud .hxp b.fx-sheen::after,.lvlchip::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.7) 50%,transparent 70%);transform:translateX(-110%);animation:fxSweep .9s var(--fx-inout) .25s both}
.lvlchip{overflow:hidden}
.lvlchip b{display:block;animation:fxPunchText .6s var(--fx-spring) .12s both}
.bank .bi{animation:fxWiggle .6s var(--fx-out) .35s both}
.bank .bs{display:inline-block}

/* ================= БОБ ================= */
.bob .bav{animation:fxBobIn .5s var(--fx-spring) .08s both}
.bob .bav.mood-happy,.bob .bav.mood-proud{animation:fxHop .7s var(--fx-out) .08s both}
.bob .bav.mood-alert{animation:fxAlert .6s var(--fx-out) .08s both}
.bob .bav.mood-soft{animation:fxSag .8s var(--fx-out) .08s both}
.bob .bav.mood-think{animation:fxTilt 1s var(--fx-out) .08s both}

/* ================= СООБЩЕНИЯ, УВЕДОМЛЕНИЯ, ГОЛОСОВЫЕ ================= */
.m.in{transform-origin:0 100%;animation:fxMsgIn .42s var(--fx-spring) both}
.m.out{transform-origin:100% 100%;animation:fxMsgOut .38s var(--fx-spring) both}
.m.sys{animation:fxFade .3s ease-out both}
.mrow>img,.mrow>.mav0{animation:fxPop .4s var(--fx-spring) both}
.notif{animation:fxNotif .55s var(--fx-snap) both}
.notif .ni,.pushn .ni{animation:fxWiggle .6s var(--fx-out) .25s both}
.m.in .voice .vw i{transform-origin:50% 50%;animation:fxBar .7s ease-in-out 2}
.m.in .voice .vw i:nth-child(3n+2){animation-delay:.08s}
.m.in .voice .vw i:nth-child(3n){animation-delay:.16s}
.voice .vp{animation:fxPulse 1.6s ease-in-out .4s 3}
.pvav{animation:fxPop .5s var(--fx-spring) .15s both}
.attach{animation:fxPopIn .5s var(--fx-spring) .15s both}
.attach .ath{animation:fxPop .5s var(--fx-spring) .3s both}

/* ================= СПИСКИ И ШАГИ ================= */
.chatlist .ch{animation:fxRise .45s var(--fx-out) both}
.chatlist .ch:nth-child(2){animation-delay:.07s}.chatlist .ch:nth-child(3){animation-delay:.14s}.chatlist .ch:nth-child(4){animation-delay:.21s}
.ch .cn{animation:fxPop .5s var(--fx-spring) .35s both}
.title-scr>*{animation:fxRise .6s var(--fx-out) both}
.title-scr>*:nth-child(2){animation-delay:.08s}.title-scr>*:nth-child(3){animation-delay:.16s}.title-scr>*:nth-child(4){animation-delay:.24s}
.title-scr>*:nth-child(5){animation-delay:.32s}.title-scr>*:nth-child(6){animation-delay:.4s}.title-scr>*:nth-child(7){animation-delay:.48s}
.logo .lb{animation:fxLogo 5s ease-in-out infinite}
.progress-dots i.on{transform-origin:left center;animation:fxGrowX .6s var(--fx-out) .2s both}
.ws-steps div.on i{animation:fxPop .5s var(--fx-spring) .15s both}
.ws-tabs button .dotn{animation:fxPop .4s var(--fx-spring) both}
.ws-tabs button .dotn::after{content:'';position:absolute;inset:0;border-radius:50%;background:var(--pink,#FF7EB6);animation:fxPing 1.4s var(--fx-out) infinite}

/* ================= НЕЙРОСЕТЬ: ОЖИДАНИЕ И ОТВЕТ ================= */
#think{animation:fxRise .35s var(--fx-out) both}
#thl{display:inline-block}
.thbar b{position:relative;overflow:hidden}
.thbar b::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);transform:translateX(-110%);animation:fxSweep 1.1s linear infinite}
.ai-m.ai.fx-ai-new{position:relative;overflow:hidden}
.ai-m.ai.fx-ai-new::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(110deg,transparent 30%,rgba(139,124,255,.22) 50%,transparent 70%);transform:translateX(-110%);animation:fxSweep 1.1s var(--fx-inout) .15s both}
.fx-typing::after{content:'▍';display:inline-block;margin-left:1px;color:#8B7CFF;animation:fxBlink .7s steps(1) infinite}
.pv-time{animation:fxPopIn .5s var(--fx-spring) both}
.pv-tip{animation:fxNudgeIn .5s var(--fx-out) both}

/* ================= СБОРКА, ОТЗЫВ, ЗНАЧКИ ================= */
.assemble{animation:fxFade .25s ease-out both}
.assemble .ac{animation:fxPopIn .45s var(--fx-spring) both}
.assemble .al{animation:fxPulse 1.2s ease-in-out infinite}
#asx{display:block}
.review{animation:fxPopIn .5s var(--fx-spring) .1s both}
.stars.fx-stars i{animation:none}
.bdg.on span{display:inline-block}
.fx-shine{position:relative;overflow:hidden}
.fx-shine::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(100deg,transparent 30%,rgba(255,236,170,.45) 50%,transparent 70%);transform:translateX(-110%);animation:fxSweep 1s var(--fx-inout) .1s both}

/* ================= ФИНАЛ ================= */
.fin-hero.fx-halo{position:relative;isolation:isolate}
.fin-hero.fx-halo::before{content:'';position:absolute;left:50%;top:-30px;width:190px;height:190px;margin-left:-95px;border-radius:50%;z-index:-1;pointer-events:none;
  background:repeating-conic-gradient(from 0deg,rgba(255,211,110,.3) 0 8deg,transparent 8deg 24deg);
  -webkit-mask:radial-gradient(circle,#000 22%,transparent 70%);mask:radial-gradient(circle,#000 22%,transparent 70%);
  animation:fxSpin 16s linear infinite,fxFade .8s ease-out .3s both}

/* ================= СЛАБЫЕ ТЕЛЕФОНЫ ================= */
.low .fx-ghost,.low .fx-fly{display:none}
.low .screen{animation:fxFade .22s ease-out both}
.low .modal .mw,.low .chatlist .ch,.low .title-scr>*{animation:fxFade .25s ease-out both}
.low #bStart,.low .logo .lb,.low .assemble .al,.low .m.in .voice .vw i,.low .voice .vp,.low .thbar b::after,.low .ws-tabs button .dotn::after,.low .fx-typing::after{animation:none}
.low #bStart::after,.low #bCont::after,.low #toFin::after,.low .fin-hero.fx-halo::before,.low .hud .hxp b.fx-sheen::after{display:none}

/* ================= МЕНЬШЕ ДВИЖЕНИЯ ================= */
@media (prefers-reduced-motion: reduce){
  .fx-canvas,.fx-ghost,.fx-fly,.fx-flash{display:none!important}
  #bStart,.logo .lb,.assemble .al,.m.in .voice .vw i,.voice .vp,.thbar b::after,.ws-tabs button .dotn::after,.fx-typing::after,.fin-hero.fx-halo::before,.fx-hint::before{animation:none!important}
  #bStart::after,#bCont::after,#toFin::after,.fin-hero.fx-halo::before{display:none!important}
  .fx-hint::before{opacity:1}
}
