/* LaporBug shared motion — quiet, editorial. Used by the public pages.
   Hidden states only apply under html.js (added by motion.js), so content is
   never held hostage by a failed script. prefers-reduced-motion kills all. */

@keyframes mRise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

/* one-shot entrance: add .rise (+ .d1/.d2/.d3 for stagger) */
html.js .rise { opacity: 0; animation: mRise .65s cubic-bezier(.2, .7, .2, 1) forwards; }
html.js .rise.d1 { animation-delay: .12s; }
html.js .rise.d2 { animation-delay: .24s; }
html.js .rise.d3 { animation-delay: .38s; }

/* scroll reveal: .reveal + (--d for stagger); motion.js adds .in */
html.js .reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity .6s cubic-bezier(.2, .7, .2, 1), transform .6s cubic-bezier(.2, .7, .2, 1);
  transition-delay: var(--d, 0s);
}
html.js .reveal.in { opacity: 1; transform: translateY(0); }

/* generic hover lift for cards/buttons that opt in via .lift */
.lift { transition: transform .2s ease, box-shadow .2s ease; }
.lift:hover { transform: translateY(-3px); box-shadow: 0 3px 8px rgba(30,32,28,.06), 0 14px 34px rgba(30,32,28,.09); }
.lift:active { transform: translateY(-1px); }

@media (prefers-reduced-motion: reduce) {
  html.js .rise, html.js .reveal {
    animation: none; transition: none; opacity: 1; transform: none;
  }
  .lift { transition: none; }
  .lift:hover { transform: none; }
}
