/* ═══════════════════════════════════════════════════
   PresentationCG v2 — SLIDE TRANSITIONS (8 штук)
   Управляются через data-transition на <html> или <section>
   engine.js добавляет классы .is-active / .is-prev / .is-next
   и .tr-entering / .tr-leaving
   ═══════════════════════════════════════════════════ */

/* ── Длительность перехода ── */
:root {
  --tr-duration: 0.6s;
  --tr-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ═══ 1. CROSSFADE ═══ */

[data-transition="crossfade"] .slide.tr-entering {
  animation: tr-crossfade-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="crossfade"] .slide.tr-leaving {
  animation: tr-crossfade-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-crossfade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes tr-crossfade-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* ═══ 2. SLIDE-LEFT ═══ */

[data-transition="slide-left"] .slide.tr-entering {
  animation: tr-slide-left-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="slide-left"] .slide.tr-leaving {
  animation: tr-slide-left-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-slide-left-in {
  from { opacity: 0; transform: translateX(100%); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes tr-slide-left-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(-30%); }
}

/* Обратное направление (← назад) */
[data-transition="slide-left"] .slide.tr-entering-reverse {
  animation: tr-slide-right-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="slide-left"] .slide.tr-leaving-reverse {
  animation: tr-slide-right-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-slide-right-in {
  from { opacity: 0; transform: translateX(-100%); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes tr-slide-right-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(30%); }
}

/* ═══ 3. BLUR-WIPE ═══ */

[data-transition="blur-wipe"] .slide.tr-entering {
  animation: tr-blur-wipe-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="blur-wipe"] .slide.tr-leaving {
  animation: tr-blur-wipe-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-blur-wipe-in {
  from {
    opacity: 0;
    filter: blur(20px);
    clip-path: inset(0 100% 0 0);
  }
  to {
    opacity: 1;
    filter: blur(0);
    clip-path: inset(0 0 0 0);
  }
}
@keyframes tr-blur-wipe-out {
  from {
    opacity: 1;
    filter: blur(0);
    clip-path: inset(0 0 0 0);
  }
  to {
    opacity: 0;
    filter: blur(20px);
    clip-path: inset(0 0 0 100%);
  }
}

/* ═══ 4. 3D-FLIP ═══ */

[data-transition="3d-flip"] {
  perspective: 1200px;
}
[data-transition="3d-flip"] .slide {
  backface-visibility: hidden;
}
[data-transition="3d-flip"] .slide.tr-entering {
  animation: tr-3d-flip-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="3d-flip"] .slide.tr-leaving {
  animation: tr-3d-flip-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-3d-flip-in {
  from {
    opacity: 0;
    transform: rotateY(90deg) scale(0.9);
  }
  to {
    opacity: 1;
    transform: rotateY(0) scale(1);
  }
}
@keyframes tr-3d-flip-out {
  from {
    opacity: 1;
    transform: rotateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: rotateY(-90deg) scale(0.9);
  }
}

/* ═══ 5. MORPH (View Transitions API fallback) ═══ */
/* Современные браузеры (Chrome 111+) используют нативный
   View Transitions через engine.js → document.startViewTransition().
   Этот CSS — fallback для остальных. */

::view-transition-old(slide-content) {
  animation: tr-morph-out var(--tr-duration) var(--tr-ease) both;
}
::view-transition-new(slide-content) {
  animation: tr-morph-in var(--tr-duration) var(--tr-ease) both;
}

@keyframes tr-morph-in {
  from { opacity: 0; transform: scale(0.94); filter: blur(4px); }
  to   { opacity: 1; transform: scale(1);    filter: blur(0); }
}
@keyframes tr-morph-out {
  from { opacity: 1; transform: scale(1);    filter: blur(0); }
  to   { opacity: 0; transform: scale(1.06); filter: blur(4px); }
}

/* Fallback для браузеров без View Transitions */
[data-transition="morph"] .slide.tr-entering {
  animation: tr-morph-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="morph"] .slide.tr-leaving {
  animation: tr-morph-out var(--tr-duration) var(--tr-ease) forwards;
}

/* ═══ 6. GLITCH ═══ */

[data-transition="glitch"] .slide.tr-entering {
  animation:
    tr-glitch-in 0.15s steps(3) 3,
    tr-crossfade-in 0.3s var(--tr-ease) 0.45s forwards;
  opacity: 0;
}
[data-transition="glitch"] .slide.tr-leaving {
  animation:
    tr-glitch-out 0.15s steps(3) 3 forwards;
}

@keyframes tr-glitch-in {
  0%   { clip-path: inset(0 0 80% 0); transform: translate(4px, -2px);  opacity: 0.7; }
  33%  { clip-path: inset(30% 0 40% 0); transform: translate(-3px, 2px); opacity: 0.5; }
  66%  { clip-path: inset(60% 0 10% 0); transform: translate(2px, -1px); opacity: 0.8; }
  100% { clip-path: inset(0);           transform: translate(0);         opacity: 1; }
}
@keyframes tr-glitch-out {
  0%   { clip-path: inset(0);           transform: translate(0);         opacity: 1; }
  33%  { clip-path: inset(20% 0 50% 0); transform: translate(-4px, 1px); opacity: 0.6; filter: hue-rotate(90deg); }
  66%  { clip-path: inset(50% 0 20% 0); transform: translate(3px, -2px); opacity: 0.3; filter: hue-rotate(180deg); }
  100% { clip-path: inset(0 0 100% 0);  transform: translate(0);         opacity: 0; filter: hue-rotate(0); }
}

/* ═══ 7. WIPE (горизонтальный clip-path) ═══ */

[data-transition="wipe"] .slide.tr-entering {
  animation: tr-wipe-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="wipe"] .slide.tr-leaving {
  animation: tr-wipe-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-wipe-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes tr-wipe-out {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 0 0 100%); }
}

/* ═══ 8. DISSOLVE (шум через pseudo-элемент) ═══ */
/* Настоящий noise-шейдер — через effects.js (canvas).
   Этот CSS — визуальное приближение через gradient-noise. */

[data-transition="dissolve"] .slide.tr-entering {
  animation: tr-dissolve-in var(--tr-duration) var(--tr-ease) forwards;
}
[data-transition="dissolve"] .slide.tr-leaving {
  position: relative;
  animation: tr-dissolve-out var(--tr-duration) var(--tr-ease) forwards;
}

@keyframes tr-dissolve-in {
  from {
    opacity: 0;
    filter: contrast(2) brightness(0.5);
  }
  40% {
    opacity: 0.6;
    filter: contrast(1.5) brightness(0.8);
  }
  to {
    opacity: 1;
    filter: contrast(1) brightness(1);
  }
}
@keyframes tr-dissolve-out {
  from {
    opacity: 1;
    filter: contrast(1) brightness(1);
  }
  60% {
    opacity: 0.5;
    filter: contrast(1.8) brightness(0.6);
  }
  to {
    opacity: 0;
    filter: contrast(2.5) brightness(0.3);
  }
}