/* Reduced motion, for the whole of Fractal. Source: packages/appearance/motion.css,
   copied into every app by scripts/sync-appearance.mjs (npm run appearance:sync).

   Kevin, 4 November 2026: "look at accessibility in relation to motion,
   applies to the whole app". Two things ask for calm, and either is enough:

   - the person's own choice, Settings → Appearance → Motion, which every app's
     appearance.mjs writes on <html data-motion="reduce">, before the first
     paint where an app has a bootstrap script;
   - the device's reduced-motion setting, for a page that hasn't said yet
     (Agent and To-do until React runs). <html data-motion="full"> means the
     page has looked and the person wants motion, so that one wins.

   What it does: every animation and transition finishes at once, in its end
   state, so nothing slides, pulses, spins up or fades; smooth scrolling jumps.
   Nothing is hidden by it: an element that animates in still arrives, and one
   that animates out still goes. Spinners are the exception. They say something
   is happening, so they keep turning, slowly.

   The canvases, psych's ground, the mascots and xterm's cursor are drawn by
   script, which asks reducedMotion() in appearance.mjs and listens for
   "fractal-motion-change". */

@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="full"]) *,
  html:not([data-motion="full"]) *::before,
  html:not([data-motion="full"]) *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  html:not([data-motion="full"]) .animate-spin,
  html:not([data-motion="full"]) .pv-stages li[data-step="active"]::before,
  html:not([data-motion="full"]) .pv-step[data-result="running"]::before,
  html:not([data-motion="full"]) [data-motion-essential],
  html:not([data-motion="full"]) [data-motion-essential]::before {
    animation-duration: 2.4s !important;
    animation-iteration-count: infinite !important;
  }
}

html[data-motion="reduce"] *,
html[data-motion="reduce"] *::before,
html[data-motion="reduce"] *::after {
  animation-duration: 0.01ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  transition-delay: 0s !important;
  scroll-behavior: auto !important;
}

/* A spinner, slower: Tailwind's animate-spin, the preview's steps in Code, and
   anything marked data-motion-essential. */
html[data-motion="reduce"] .animate-spin,
html[data-motion="reduce"] .pv-stages li[data-step="active"]::before,
html[data-motion="reduce"] .pv-step[data-result="running"]::before,
html[data-motion="reduce"] [data-motion-essential],
html[data-motion="reduce"] [data-motion-essential]::before {
  animation-duration: 2.4s !important;
  animation-iteration-count: infinite !important;
}
