/* Single elements: hidden until revealed */
.js [data-animate] {
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity, filter;
}

/* Groups: hide ONLY direct children so the container itself never disappears */
.js [data-animate-group] > * {
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity, filter;
}

/* Duration variable (can override via data-duration or inline) */
:root { --anim-dur: 700ms; }

/* Initial offsets for known animations (apply when data-animate is set) */
[data-animate="fade-up"]    { transform: translateY(30px); }
[data-animate="fade-down"]  { transform: translateY(-30px); }
[data-animate="fade-left"]  { transform: translateX(30px); }
[data-animate="fade-right"] { transform: translateX(-30px); }
[data-animate="zoom-in"]    { transform: scale(0.96); }
[data-animate="blur-in"]    { filter: blur(6px); }

/* When playing */
[data-animate].in {
  visibility: visible;
  animation-duration: var(--anim-dur);
  animation-fill-mode: both;
  animation-timing-function: cubic-bezier(.22,.61,.36,1);
}

/* Map types to keyframes (all keyframes fade 0→1 for smoothness) */
[data-animate="fade-up"].in    { animation-name: anim-fade-up; }
[data-animate="fade-down"].in  { animation-name: anim-fade-down; }
[data-animate="fade-left"].in  { animation-name: anim-fade-left; }
[data-animate="fade-right"].in { animation-name: anim-fade-right; }
[data-animate="zoom-in"].in    { animation-name: anim-zoom-in; }
[data-animate="blur-in"].in    { animation-name: anim-blur-in; }

@keyframes anim-fade-up   { from { opacity:0; transform:translateY(18px);} to { opacity:1; transform:translateY(0);} }
@keyframes anim-fade-down { from { opacity:0; transform:translateY(-18px);}to { opacity:1; transform:translateY(0);} }
@keyframes anim-fade-left { from { opacity:0; transform:translateX(18px);} to { opacity:1; transform:translateX(0);} }
@keyframes anim-fade-right{ from { opacity:0; transform:translateX(-18px);}to { opacity:1; transform:translateX(0);} }
@keyframes anim-zoom-in   { from { opacity:0; transform:scale(0.96);}      to { opacity:1; transform:scale(1);} }
@keyframes anim-blur-in   { from { opacity:0; filter:blur(6px);}            to { opacity:1; filter:blur(0);} }

@media (prefers-reduced-motion: reduce) {
  [data-animate], [data-animate-group] > * {
    opacity: 1; visibility: visible; transform: none; filter: none; animation: none !important;
  }
}