/* ============================================================ движение
   Всё плавное, но не мельтешит: анимации короткие, а бесконечные — только
   там, где не отвлекают. Кто выключил анимации в системе, тот видит статику. */

/* появление блоков при прокрутке */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s cubic-bezier(.2, .7, .2, 1), transform .7s cubic-bezier(.2, .7, .2, 1);
  will-change: opacity, transform;
}
.reveal.seen { opacity: 1; transform: none; }

/* карточки в ряду выходят по очереди */
.reveal.d1 { transition-delay: .07s; }
.reveal.d2 { transition-delay: .14s; }
.reveal.d3 { transition-delay: .21s; }
.reveal.d4 { transition-delay: .28s; }
.reveal.d5 { transition-delay: .35s; }
.reveal.d6 { transition-delay: .42s; }

/* фон медленно дышит — страница перестаёт быть мёртвой картинкой */
body::before { animation: drift 26s ease-in-out infinite alternate; }
@keyframes drift {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(-1.5%, 1.5%, 0) scale(1.06); }
  100% { transform: translate3d(1.5%, -1%, 0) scale(1.02); }
}

/* первый экран въезжает сам */
.hero .badge { animation: rise .7s .05s both cubic-bezier(.2, .7, .2, 1); }
.hero h1 { animation: rise .8s .12s both cubic-bezier(.2, .7, .2, 1); }
.hero .lead { animation: rise .8s .2s both cubic-bezier(.2, .7, .2, 1); }
.hero-actions { animation: rise .8s .28s both cubic-bezier(.2, .7, .2, 1); }
@keyframes rise {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

/* градиент в заголовке переливается */
h1 .grad {
  background-size: 220% 100%;
  animation: flow 9s ease-in-out infinite;
}
@keyframes flow {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

/* кнопка наливается светом от курсора */
.btn { position: relative; overflow: hidden; }
.btn::before {
  content: "";
  position: absolute;
  left: var(--mx, 50%); top: var(--my, 50%);
  width: 0; height: 0;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .35), transparent 70%);
  transform: translate(-50%, -50%);
  transition: width .5s, height .5s, opacity .5s;
  opacity: 0;
}
.btn:hover::before { width: 260px; height: 260px; opacity: 1; }

/* карточки мягко откликаются на курсор */
.feature, .stat, .step {
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), border-color .25s, box-shadow .35s;
}
.feature:hover { box-shadow: 0 22px 50px rgba(0, 0, 0, .45); }

/* цифры набегают — считает скрипт, тут только ровная ширина знаков */
.stat .value { font-variant-numeric: tabular-nums; transition: color .3s; }
.stat:hover .value { color: var(--accent); }

/* ============================================================ иконки */
.feature .icon {
  background: linear-gradient(135deg, rgba(91, 140, 255, .22), rgba(160, 107, 255, .22));
  width: 52px; height: 52px; border-radius: 15px;
  transition: transform .4s cubic-bezier(.2, .7, .2, 1), background .3s;
}
.feature:hover .icon {
  transform: translateY(-3px) rotate(-4deg) scale(1.06);
  background: linear-gradient(135deg, rgba(91, 140, 255, .34), rgba(160, 107, 255, .34));
}

.ic { width: 26px; height: 26px; display: block; overflow: visible; }
.ic path, .ic circle, .ic rect, .ic line, .ic polyline {
  stroke: var(--text);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

/* карточка: строка имени печатается заново */
.ic-card .writeline { stroke-dasharray: 22; stroke-dashoffset: 0; }
.feature:hover .ic-card .writeline { animation: writeline 1.6s ease-in-out infinite; }
@keyframes writeline {
  0% { stroke-dashoffset: 22; }
  55% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 0; opacity: .3; }
}

/* чат: три точки набора текста */
.ic-chat .dot { fill: var(--text); stroke: none; opacity: .35; }
.feature:hover .ic-chat .dot1 { animation: typing 1.1s infinite; }
.feature:hover .ic-chat .dot2 { animation: typing 1.1s .18s infinite; }
.feature:hover .ic-chat .dot3 { animation: typing 1.1s .36s infinite; }
@keyframes typing {
  0%, 60%, 100% { opacity: .3; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-1.5px); }
}

/* монеты: блик пробегает по стопке */
.ic-coins .shine { stroke: #fff; stroke-width: 2.6; opacity: 0; }
.feature:hover .ic-coins .shine { animation: shine 1.7s ease-in-out infinite; }
@keyframes shine {
  0% { transform: translateX(-8px); opacity: 0; }
  40% { opacity: .85; }
  100% { transform: translateX(8px); opacity: 0; }
}

/* телефон: волны связи расходятся */
.ic-phone .wave { opacity: 0; transform-origin: 18px 6px; }
.feature:hover .ic-phone .wave1 { animation: wave 1.7s infinite; }
.feature:hover .ic-phone .wave2 { animation: wave 1.7s .4s infinite; }
@keyframes wave {
  0% { opacity: 0; transform: scale(.5); }
  35% { opacity: .9; }
  100% { opacity: 0; transform: scale(1.2); }
}

/* щит: галочка дорисовывается */
.ic-shield .check { stroke-dasharray: 14; stroke-dashoffset: 14; }
.feature:hover .ic-shield .check { animation: draw .6s .1s forwards ease-out; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* сон: буквы Z всплывают */
.ic-sleep .z { opacity: 0; }
.feature:hover .ic-sleep .z1 { animation: floatz 1.9s infinite; }
.feature:hover .ic-sleep .z2 { animation: floatz 1.9s .65s infinite; }
@keyframes floatz {
  0% { opacity: 0; transform: translateY(2px) scale(.8); }
  35% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-5px) scale(1.05); }
}

/* номер шага подпрыгивает под курсором */
.step:hover .num { animation: bump .5s ease-out; }
@keyframes bump {
  0% { transform: scale(1); }
  45% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* ракета лаунчера парит */
.rocket { display: inline-block; animation: hoverup 3.4s ease-in-out infinite; }
@keyframes hoverup {
  0%, 100% { transform: translateY(0) rotate(0); }
  50% { transform: translateY(-8px) rotate(-6deg); }
}

/* ============================================================ окна и страницы */
.modal { transform: translateY(18px) scale(.96); transition: transform .3s cubic-bezier(.2, .8, .25, 1); }
.overlay { transition: opacity .25s; }

/* смена страницы: не рывок, а переход */
.page-in { animation: pagein .45s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes pagein {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* поля формы отзываются на фокус */
input, select { transition: border-color .2s, background .2s, box-shadow .2s, transform .2s; }
input:focus, select:focus { transform: translateY(-1px); }

/* ошибка в форме даёт понять, что она новая */
.message.show.bad { animation: shake .45s cubic-bezier(.36, .07, .19, .97); }
.message.show.good { animation: rise .4s both; }
@keyframes shake {
  10%, 90% { transform: translateX(-1.5px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-5px); }
  40%, 60% { transform: translateX(5px); }
}

/* строки в админке появляются лесенкой */
#admin-rows tr { animation: rise .4s both; }
#admin-rows tr:nth-child(1) { animation-delay: .02s; }
#admin-rows tr:nth-child(2) { animation-delay: .06s; }
#admin-rows tr:nth-child(3) { animation-delay: .1s; }
#admin-rows tr:nth-child(4) { animation-delay: .14s; }
#admin-rows tr:nth-child(n+5) { animation-delay: .18s; }

/* пока цифры не пришли — мягкое мерцание вместо прочерков */
.loading {
  background: linear-gradient(90deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .12), rgba(255, 255, 255, .05));
  background-size: 220% 100%;
  animation: sweep 1.4s infinite;
  border-radius: 8px;
  color: transparent !important;
}
@keyframes sweep {
  0% { background-position: 120% 0; }
  100% { background-position: -20% 0; }
}

/* кнопка в работе: полоска бежит по низу */
.btn.busy { pointer-events: none; opacity: .75; }
.btn.busy::after {
  content: "";
  position: absolute; left: 0; bottom: 0; height: 2px; width: 40%;
  background: rgba(255, 255, 255, .8);
  animation: slide 1s linear infinite;
}
@keyframes slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* ============================================================ уважение к настройкам */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001s !important;
  }
  .reveal { opacity: 1; transform: none; }
  /* эмблемы фракций рисуем сразу, без прочерчивания линий */
  .faction .emblem svg > * { stroke-dashoffset: 0; }
}
