/* Entrance animations (T095).
 * Elements carrying [data-zx-anim] start invisible; src/frontend/lib/animations.ts adds .zx-animated
 * when they scroll into view. Once the animation has ended, .zx-anim-done drops the animation so that
 * the element's own transform/opacity rules apply again. */
[data-zx-anim] {
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-timing-function: ease-out;
  animation-delay: var(--zx-anim-delay, 0ms);
}
/* Hidden only until the element scrolls into view. Once animated, the keyframes (fill-mode: both) and then
 * the element's own rules decide the opacity, so an Opacity setting on the element is never overridden. */
[data-zx-anim]:not(.zx-animated) {
  opacity: 0;
}
[data-zx-anim][data-zx-anim-duration='slow'] {
  animation-duration: 2s;
}
[data-zx-anim][data-zx-anim-duration='fast'] {
  animation-duration: 0.5s;
}
.zx-animated.zx-anim-done[data-zx-anim] {
  animation-name: none;
}

.zx-animated[data-zx-anim='fadeIn'] { animation-name: zx-fadeIn; }
.zx-animated[data-zx-anim='fadeInUp'] { animation-name: zx-fadeInUp; }
.zx-animated[data-zx-anim='fadeInDown'] { animation-name: zx-fadeInDown; }
.zx-animated[data-zx-anim='fadeInLeft'] { animation-name: zx-fadeInLeft; }
.zx-animated[data-zx-anim='fadeInRight'] { animation-name: zx-fadeInRight; }
.zx-animated[data-zx-anim='zoomIn'] { animation-name: zx-zoomIn; }
.zx-animated[data-zx-anim='slideInUp'] { animation-name: zx-slideInUp; }
.zx-animated[data-zx-anim='slideInLeft'] { animation-name: zx-slideInLeft; }
.zx-animated[data-zx-anim='bounceIn'] { animation-name: zx-bounceIn; animation-duration: 0.9s; animation-timing-function: ease-in-out; }
.zx-animated[data-zx-anim='rotateIn'] { animation-name: zx-rotateIn; transform-origin: center; }

@keyframes zx-fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes zx-fadeInUp {
  from { opacity: 0; transform: translate3d(0, 40px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes zx-fadeInDown {
  from { opacity: 0; transform: translate3d(0, -40px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes zx-fadeInLeft {
  from { opacity: 0; transform: translate3d(-40px, 0, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes zx-fadeInRight {
  from { opacity: 0; transform: translate3d(40px, 0, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes zx-zoomIn {
  from { opacity: 0; transform: scale3d(0.6, 0.6, 0.6); }
  60% { opacity: 1; }
  to { opacity: 1; transform: scale3d(1, 1, 1); }
}
@keyframes zx-slideInUp {
  from { transform: translate3d(0, 100%, 0); }
  to { transform: translate3d(0, 0, 0); }
}
@keyframes zx-slideInLeft {
  from { transform: translate3d(-100%, 0, 0); }
  to { transform: translate3d(0, 0, 0); }
}
@keyframes zx-bounceIn {
  0% { opacity: 0; transform: scale3d(0.3, 0.3, 0.3); }
  20% { transform: scale3d(1.1, 1.1, 1.1); }
  40% { transform: scale3d(0.9, 0.9, 0.9); }
  60% { opacity: 1; transform: scale3d(1.03, 1.03, 1.03); }
  80% { transform: scale3d(0.97, 0.97, 0.97); }
  to { opacity: 1; transform: scale3d(1, 1, 1); }
}
@keyframes zx-rotateIn {
  from { opacity: 0; transform: rotate3d(0, 0, 1, -90deg); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  [data-zx-anim] {
    animation: none !important;
  }
  [data-zx-anim]:not(.zx-animated) {
    opacity: revert;
  }
}
