/* ============================================================
   05 — АНИМАЦИИ / KEYFRAMES / SCROLL-REVEAL
   ============================================================ */

/* Появление по скроллу — только при активном JS (.js на <html>) */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 36px, 0);
  transition:
    opacity 0.85s var(--ease-out),
    transform 0.85s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-in {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Hero — сразу виден */
.js .hero [data-reveal] {
  opacity: 1;
  transform: none;
  transition: none;
}

/* Горизонтальный сдвиг */
.js [data-reveal="left"]  { transform: translate3d(-48px, 0, 0); }
.js [data-reveal="right"] { transform: translate3d(48px, 0, 0); }
.js [data-reveal="left"].is-in,
.js [data-reveal="right"].is-in { transform: translate3d(0, 0, 0); }

/* Clip-reveal */
.js [data-reveal="clip"] {
  transform: none;
  clip-path: inset(0 100% 0 0);
  opacity: 1;
  transition: clip-path 1s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal="clip"].is-in { clip-path: inset(0 0 0 0); }

/* Целая секция: заголовок появляется чуть раньше сетки */
.js .section:not(.hero).is-section-in > .wrap > .section-head [data-reveal] {
  transition-duration: 0.75s;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }
}

/* --- Keyframes --- */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--red-glow); }
  50%      { box-shadow: 0 0 0 7px transparent; }
}

@keyframes spinSlow {
  to { transform: rotate(360deg); }
}

@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

.spinner { animation: spinSlow 22s linear infinite; transform-origin: center; }

.glitch-hover { position: relative; display: inline-block; }
.glitch-hover::after {
  content: attr(data-text);
  position: absolute;
  left: 0; top: 0;
  color: var(--red);
  clip-path: inset(0 0 50% 0);
  transform: translate(0, 0);
  opacity: 0;
  transition: opacity 0.12s ease;
  pointer-events: none;
}
.glitch-hover:hover::after {
  opacity: 0.9;
  animation: glitch 0.4s steps(2) infinite;
}
@keyframes glitch {
  0%   { transform: translate(-2px, -1px); }
  50%  { transform: translate(2px, 1px); }
  100% { transform: translate(-1px, 1px); }
}

.magnetic { transition: transform 0.25s var(--ease-out); }

.tilt {
  transform: perspective(900px)
             rotateX(var(--rx, 0deg))
             rotateY(var(--ry, 0deg));
  transition: transform 0.3s var(--ease-out);
  transform-style: preserve-3d;
}

.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--red), var(--rust-2));
  z-index: 1100;
  will-change: transform;
}
