/* Анимации главной и простых страниц (логика — fx.js). Класс .fx на <html> ставит инлайн-скрипт в <head>,
   если пользователь не просил уменьшить движение; без него страница выглядит как раньше. */

@keyframes fx-rise {
  from { opacity: 0; translate: 0 18px; }
  to { opacity: 1; translate: none; }
}
@keyframes fx-blur-in {
  from { opacity: 0; filter: blur(12px); transform: translateY(-10px); }
  to { opacity: 1; filter: blur(0); transform: none; }
}
@keyframes fx-shine {
  0% { background-position: 150% 0; }
  60%, 100% { background-position: -50% 0; }
}
@keyframes fx-aurora {
  0% { transform: translate(-6%, -4%) scale(1); }
  50% { transform: translate(5%, 6%) scale(1.15); }
  100% { transform: translate(-6%, -4%) scale(1); }
}
@keyframes fx-spin { to { --fx-angle: 360deg; } }
@property --fx-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }

/* ---------- hero: фон ---------- */
.fx body { overflow-x: clip; }
.fx .hero { position: relative; isolation: isolate; }
.fx-field {
  position: absolute;
  inset: -64px -50vw 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  mask-image: linear-gradient(to bottom, #000 55%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
}
.fx-field canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.fx-field::before,
.fx-field::after {
  content: "";
  position: absolute;
  width: 60vmax;
  height: 60vmax;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.16;
  animation: fx-aurora 18s ease-in-out infinite;
}
.fx-field::before { left: 30%; top: -30vmax; background: radial-gradient(circle, #d4c24f, transparent 65%); }
.fx-field::after {
  left: 55%; top: -20vmax; background: radial-gradient(circle, #6f8f3a, transparent 65%);
  animation-duration: 24s; animation-direction: reverse; opacity: 0.12;
}

/* ---------- hero: текст ---------- */
.fx .hero h1 .fx-word { display: inline-block; animation: fx-blur-in 0.8s cubic-bezier(.2,.7,.2,1) both; }
.fx .hero h1 .wiki { display: inline-block; animation: fx-blur-in 0.8s 0.35s cubic-bezier(.2,.7,.2,1) both; }
.fx .hero h1 .wiki.fx-shiny {
  background: linear-gradient(110deg, var(--accent) 40%, #fff6c4 50%, var(--accent) 60%) 0 0 / 250% 100% repeat-x;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: fx-shine 5s 0.4s ease-in-out infinite;
}
.fx .hero .lede { animation: fx-rise 0.8s 0.55s both; }
.fx .hero .chips { animation: fx-rise 0.8s 0.7s both; }
.fx .hero .tile:not([hidden]) { animation: fx-rise 0.6s calc(0.8s + var(--fx-i, 0) * 90ms) cubic-bezier(.2,.7,.2,1) both; }
.fx .hero.fx-ready .tile:not([hidden]) { animation-delay: calc(var(--fx-i, 0) * 70ms); }

/* ---------- чипы ---------- */
.fx .chip { transition: background 0.25s, color 0.25s, border-color 0.25s, transform 0.2s; }
.fx .chip:active { transform: scale(0.96); }

/* ---------- карточки: свет под курсором и наклон ---------- */
.fx .tile {
  position: relative;
  overflow: hidden;
  transform: perspective(900px) rotateX(var(--fx-rx, 0deg)) rotateY(var(--fx-ry, 0deg));
  transition: border-color 0.2s, background 0.2s, transform 0.25s ease-out, box-shadow 0.25s;
}
.fx .tile::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(420px circle at var(--fx-mx, 50%) var(--fx-my, 50%), rgba(212, 194, 79, 0.13), transparent 45%);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}
.fx .tile:hover::before { opacity: 1; }
.fx .tile:hover { box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(212, 194, 79, 0.15); }
.fx .tile > * { position: relative; }
.fx .tile-head svg { transition: color 0.2s, transform 0.3s cubic-bezier(.3,1.6,.5,1); }
.fx .tile:hover .tile-head svg { transform: scale(1.15) rotate(-6deg); }
.fx .tile-badge {
  background-image: linear-gradient(110deg, transparent 35%, rgba(255, 255, 255, 0.65) 50%, transparent 65%);
  background-size: 250% 100%;
  background-repeat: no-repeat;
  animation: fx-shine 3.5s 1.5s ease-in-out infinite;
}

/* ---------- появление при прокрутке ---------- */
.fx-io .fx-reveal { opacity: 0; translate: 0 22px; transition: opacity 0.7s ease, translate 0.7s cubic-bezier(.2,.7,.2,1); transition-delay: calc(var(--fx-i, 0) * 60ms); }
.fx-io .fx-reveal.is-in { opacity: 1; translate: none; }
.fx-io .pt-item.is-past.fx-reveal.is-in { opacity: 0.62; }

/* ---------- ближайший плейтест: светящаяся рамка ---------- */
.fx .next-playtest { position: relative; isolation: isolate; }
.fx .next-playtest::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--fx-angle), transparent 0 70%, var(--accent) 85%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: fx-spin 6s linear infinite;
  pointer-events: none;
}

/* ---------- 404 ---------- */
@keyframes fx-glitch {
  0%, 92%, 100% { transform: none; text-shadow: none; }
  93% { transform: translate(-3px, 1px); text-shadow: 3px 0 #c8553d, -3px 0 #6fb0c8; }
  95% { transform: translate(3px, -1px); text-shadow: -3px 0 #c8553d, 3px 0 #6fb0c8; }
  97% { transform: translate(-1px, 0); text-shadow: 1px 0 #c8553d; }
}
.fx .nf-code { animation: fx-glitch 3.5s infinite; }
.fx .nf h1, .fx .nf .muted, .fx .nf .row { animation: fx-rise 0.7s both; }
.fx .nf .muted { animation-delay: 0.1s; }
.fx .nf .row { animation-delay: 0.2s; }

@media (prefers-reduced-motion: reduce) {
  .fx *, .fx *::before, .fx *::after { animation: none !important; transition: none !important; }
  .fx-field { display: none; }
  .fx-io .fx-reveal { opacity: 1; translate: none; }
}
