/*
 * animations.css — keyframes and the reveal utilities (spec 12).
 * Every animation uses transform/opacity only, so it stays on the compositor.
 * Under prefers-reduced-motion everything is effectively switched off and any
 * content that depends on an animation is forced to its final state.
 */

@keyframes bp-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes bp-fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

@keyframes bp-menu-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}

@keyframes bp-toast-in {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

@keyframes bp-toast-out {
  to { opacity: 0; transform: translateY(12px); }
}

@keyframes bp-spin {
  to { transform: rotate(360deg); }
}

@keyframes bp-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@keyframes bp-pulse {
  0% { transform: scale(1); opacity: .55; }
  70% { transform: scale(1.45); opacity: 0; }
  100% { transform: scale(1.45); opacity: 0; }
}

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

@keyframes bp-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}

/* Page load fade of <main> */
main#main {
  animation: bp-fade-in var(--dur-base) var(--ease);
}

/* Scroll reveal: the pending class is added by js/core/reveal.js, so content is
   visible when JavaScript does not run at all. */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal] {
    transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  }

  [data-reveal].reveal-pending {
    opacity: 0;
    transform: translateY(16px);
  }

  [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
  }
}

/* Staggered children, used by the hero headline (spec 12). */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal-stagger] > * {
    animation: bp-fade-up var(--dur-slow) var(--ease) backwards;
  }

  [data-reveal-stagger] > *:nth-child(1) { animation-delay: 80ms; }
  [data-reveal-stagger] > *:nth-child(2) { animation-delay: 180ms; }
  [data-reveal-stagger] > *:nth-child(3) { animation-delay: 280ms; }
  [data-reveal-stagger] > *:nth-child(4) { animation-delay: 380ms; }
  [data-reveal-stagger] > *:nth-child(5) { animation-delay: 480ms; }
}

/* Decorative hero bolt: draws itself once, then keeps the drawn state. */
@media (prefers-reduced-motion: no-preference) {
  .hero__bolt-path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: bp-draw 900ms var(--ease) 200ms forwards;
  }

  .hero__float {
    animation: bp-float 3.2s var(--ease) infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Anything that relies on an animation to reach a visible state is forced
     straight to that state. */
  [data-reveal],
  [data-reveal].reveal-pending,
  [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
  }

  [data-reveal-stagger] > * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .hero__bolt-path {
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
  }

  .fab::before {
    animation: none !important;
    opacity: 0 !important;
  }

  .skeleton::after {
    animation: none !important;
  }
}
