/* =============================================================================
   合流 MergePad · motion.css — keyframes + reduced motion (spec §2.8)
   Durations: --t-1 120ms (hover, press, exits) · --t-2 180ms (tabs, popovers, scrim) · --t-3 240ms (progress,
   modal/sheet/toast enter, value flash). Ambient loops: live-dot ping, ticker, skeleton shimmer, flywheel packets,
   hero ribbons — all stop under prefers-reduced-motion and while the page is hidden (html.page-hidden).
   ============================================================================= */
@keyframes ping    { 0% { transform: scale(.6); opacity: .8; } 80%, 100% { transform: scale(1.6); opacity: 0; } }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes spin    { to { transform: rotate(360deg); } }
@keyframes halo    { 0% { transform: scale(.5); opacity: 1; } 70%, 100% { transform: scale(1.6); opacity: 0; } }
@keyframes toast-in     { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes toast-in-top { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes route-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes tape     { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes packet   { from { stroke-dashoffset: 1424; } to { stroke-dashoffset: 0; } }

.ticker-track.is-moving { animation: tape var(--tape-dur, 60s) linear infinite; }
.ticker:hover .ticker-track, .ticker:focus-within .ticker-track, .ticker.is-paused .ticker-track { animation-play-state: paused; }
.packet { stroke-dasharray: 24 1400; animation: packet 3600ms linear infinite; }

/* hidden tab: park every ambient loop */
.page-hidden .skel, .page-hidden .ticker-track, .page-hidden .packet, .page-hidden .pill.ph-1 .dot::after, .page-hidden .curve .pulse { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important;
    transition-duration: 1ms !important; scroll-behavior: auto !important;
  }
  /* opacity fades may stay short but visible */
  .pop, .scrim, .tooltip, .toast, .modal { transition-property: opacity !important; transition-duration: var(--t-1) !important; transform: none !important; }
  .modal { transform: translate(-50%, -50%) !important; }
  .modal.is-top { transform: translate(-50%, 0) !important; }
  .live-dot::after, .pill.ph-1 .dot::after, .curve .pulse, .packet { display: none; animation: none !important; }
  .skel { animation: none !important; background: var(--bg-3); }
  .ticker-track.is-moving { animation: none !important; }
  .ticker-view { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .ticker-pause { display: none; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 760px) {
  .modal, .modal.md, .modal.is-top { transform: none !important; }
}
