/* Motion system. JS (js/motion.js) adds .js-motion to <html>, .visible to each .reveal on first view
   and .motion-paused to [data-ambient] blocks that are off screen. Without JS everything is simply visible. */

/* ── Scroll reveal ────────────────────────────────────────────────────────────
   <div class="reveal">                      rises and fades in
   data-reveal="fade|left|right|scale|clip"  other entrances
   data-reveal="lines"                       for a heading block: its h1/h2 rises line by line, other children follow
   style="--i:2" or a parent [data-stagger]  delays an item by 2 steps
   Entrances are animations with a backwards fill: once they end, the element is back to its own
   styles, so `transform` and `transition` stay free for hover effects. */
.js-motion .reveal:not(.visible) { opacity:0; }
.js-motion .reveal.visible { animation:reveal-up var(--t-slow) var(--ease) calc(var(--i,0) * 90ms) backwards; }
.js-motion .reveal.visible[data-reveal="fade"] { animation-name:reveal-fade; }
.js-motion .reveal.visible[data-reveal="left"] { animation-name:reveal-left; }
.js-motion .reveal.visible[data-reveal="right"] { animation-name:reveal-right; }
.js-motion .reveal.visible[data-reveal="scale"] { animation-name:reveal-scale; }
.js-motion .reveal.visible[data-reveal="clip"] { animation-name:reveal-clip; animation-duration:1.1s; animation-timing-function:var(--ease-in-out); }
@keyframes reveal-up { from { opacity:0; transform:translateY(26px); } }
@keyframes reveal-fade { from { opacity:0; } }
@keyframes reveal-left { from { opacity:0; transform:translateX(-34px); } }
@keyframes reveal-right { from { opacity:0; transform:translateX(34px); } }
@keyframes reveal-scale { from { opacity:0; transform:scale(.955); } }
@keyframes reveal-clip { from { clip-path:inset(0 0 100% 0); } to { clip-path:inset(0); } }

[data-stagger]>:nth-child(2) { --i:1; } [data-stagger]>:nth-child(3) { --i:2; } [data-stagger]>:nth-child(4) { --i:3; }
[data-stagger]>:nth-child(5) { --i:4; } [data-stagger]>:nth-child(6) { --i:5; } [data-stagger]>:nth-child(7) { --i:6; } [data-stagger]>:nth-child(8) { --i:7; }

/* Heading blocks: the title is written in line by line (JS wraps each line of the h1/h2 in .line > .line-inner). */
.line { display:block; overflow:hidden; padding:.14em .2em .2em; margin:-.14em -.2em -.2em; }
.line-inner { display:block; }
.js-motion .reveal[data-reveal="lines"]:not(.visible) { opacity:1; }
.js-motion .reveal[data-reveal="lines"]:not(.visible)>* { opacity:0; }
.js-motion .reveal[data-reveal="lines"].visible { animation:none; }
.js-motion .reveal[data-reveal="lines"].visible>:not(h1,h2) { animation:reveal-up var(--t-slow) var(--ease) calc(var(--n,0) * 130ms) backwards; }
.js-motion .reveal[data-reveal="lines"].visible>:nth-child(2) { --n:1; }
.js-motion .reveal[data-reveal="lines"].visible>:nth-child(3) { --n:3; }
.js-motion .reveal[data-reveal="lines"].visible>:nth-child(n+4) { --n:4; }
.js-motion .reveal[data-reveal="lines"].visible .line-inner { animation:line-rise 1s var(--ease) calc(120ms + var(--line,0) * 130ms) backwards; }
@keyframes line-rise { from { transform:translateY(112%); } }

/* ── Ambient loops ─────────────────────────────────────────────────────────── */
@keyframes spin { to { transform:rotate(360deg); } }
@keyframes breathe { 0%,100% { opacity:.65; } 50% { opacity:1; } }
.motion-paused,.motion-paused *,.motion-paused::before,.motion-paused::after,.motion-paused *::before,.motion-paused *::after { animation-play-state:paused !important; }

/* ── View transitions ──────────────────────────────────────────────────────────
   Only named elements morph (viewTransition() in js/motion.js); the page itself is not cross-faded. */
:root { view-transition-name:none; }
::view-transition-group(*) { animation-duration:.42s; animation-timing-function:var(--ease); }
::view-transition-old(*),::view-transition-new(*) { animation-duration:.3s; }

@media (prefers-reduced-motion:reduce) {
  *,*::before,*::after { animation:none !important; transition:none !important; }
}

/* Фоновая вкладка не расходует кадры на декоративные циклы. */
.page-paused,.page-paused *,.page-paused::before,.page-paused::after,.page-paused *::before,.page-paused *::after { animation-play-state:paused !important; }
/* На сенсорных устройствах убраны полноэкранные фильтры и параллакс. */
@media (hover:none), (max-width:767px) {
  body::after { display:none; }
  .site-dialog::backdrop { backdrop-filter:none; }
  .character-glow { filter:none; }
  .hero-art img { transform:none; transition:none; }
  .community-art img { animation:none !important; }
}
