/* ============================================================
   Motion — shared keyframes. Durations/easings live in spacing.css
   with the rest of the scalar tokens.

   These MUST ship with the system: components reference them by name, so a
   consumer that only links styles.css still gets working animation. Do not
   redefine them per page.
   ============================================================ */

/* Indeterminate spinner — Button loading, SearchField loading, sync + delete
   phases. `canbake-spin` is the same animation under the older name. */
@keyframes tt-spin { to { transform: rotate(360deg); } }
@keyframes canbake-spin { to { transform: rotate(360deg); } }

/* Scrim fade-in behind Modal / ConfirmDialog / drawer. */
@keyframes tt-modal-scrim { from { opacity: 0; } to { opacity: 1; } }

/* Skeleton — a slow opacity breath, NOT a travelling shimmer. A shimmer reads
   as progress the app cannot actually report. */
@keyframes tt-skeleton { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

@media (prefers-reduced-motion: reduce) {
  /* Spinners stop rotating; the accompanying label still says what's happening.
     Skeletons hold at rest opacity rather than pulsing. */
  [style*="tt-spin"], [style*="canbake-spin"] { animation: none !important; }
  [style*="tt-skeleton"] { animation: none !important; opacity: 1 !important; }
}
