/* ONE MOTION TOKEN SET FOR SUMA.HK (card c1791583071062024).
 *
 * Served same-origin as a plain file under public/, so the Next app
 * (app/layout.tsx links it in <head>) and the static onboarding frame
 * (public/onboarding-preview/index.html links it before base.css) load the
 * SAME bytes. It is not imported through the Next CSS pipeline because the
 * iframed frame cannot import a Next-bundled sheet. No CDN, no script.
 *
 * WHERE EVERY VALUE COMES FROM. Nothing here is a new taste; each token is a
 * curve or a beat the marketing site already uses:
 *
 *   --m-ease-out     cubic-bezier(.22,1,.36,1)   site-interactions.css transforms (.3s to .38s),
 *                                                onboarding --rise
 *   --m-ease-emph    cubic-bezier(.2,.7,.2,1)    site-interactions.css dialog open (.3s),
 *                                                legacy suma.css and onboarding base.css --ease
 *   --m-ease-swap    cubic-bezier(.22,.61,.36,1) site-interactions.css gallery slide swaps (.4s)
 *   --m-ease-colour  ease                        site-interactions.css colour (.24s ease)
 *
 *   --m-dur-press    100ms   between onboarding base.css .btn transform (.14s) and one frame
 *                            at 60 fps: a press must read in the NEXT frame
 *   --m-dur-fast     160ms   portal .sp-button (.16s)
 *   --m-dur-base     240ms   site-interactions.css colour (.24s), onboarding qhelp (240ms)
 *   --m-dur-scene    340ms   site-interactions.css transform band (.3s to .38s); a scene swap
 *   --m-stagger       50ms   one beat between siblings entering together
 *   --m-rise           6px   client-phases.css phase-in, booking-bubbles-in translateY(6px)
 *   --m-press-scale   .97    onboarding .act:active scale(.97)
 *
 * PAGE-LEVEL. Only a token whose name begins --m-dur-page may exceed 400ms;
 * test/site-motion-audit.test.mjs reads this file and fails on any other
 * duration over 400ms. They are entrances of a whole page or of the wizard's
 * finale, and the one ambient loop, never a response to a click:
 *
 *   --m-dur-page         950ms  onboarding #sheet rise (style.css), kept as it was
 *   --m-dur-page-reveal  700ms  onboarding finale reveal (index.html .finale .in 700ms)
 *   --m-dur-page-pulse  1400ms  skeleton breathe and the in-flight sweep: a LOOP, not a transition
 *
 *   --m-delay-reveal     120ms  a skeleton waits this long before it shows, so a reply that lands
 *                               inside it never flashes one (the content still fades in)
 *
 * Motion is unconditional on suma.hk (Dominic, INTEGRATION.md): there is no
 * prefers-reduced-motion branch here and none may be added. Only transform
 * and opacity animate; colour transitions on hover stay as they were.
 */
:root {
  --m-dur-press: 100ms;
  --m-dur-fast: 160ms;
  --m-dur-base: 240ms;
  --m-dur-scene: 340ms;
  --m-dur-page: 950ms;
  --m-dur-page-reveal: 700ms;
  --m-dur-page-pulse: 1400ms;
  --m-delay-reveal: 120ms;
  --m-ease-out: cubic-bezier(.22,1,.36,1);
  --m-ease-emph: cubic-bezier(.2,.7,.2,1);
  --m-ease-swap: cubic-bezier(.22,.61,.36,1);
  --m-ease-colour: ease;
  --m-stagger: 50ms;
  --m-rise: 6px;
  --m-press-scale: .97;
}

/* The shared entrance: fade and rise by --m-rise as one surface. Users run it
   with fill-mode `backwards`, never `both`, so once it ends an inline opacity
   (motion/react's exit fade) is in charge again. */
@keyframes m-rise-in {
  from { opacity: 0; transform: translateY(var(--m-rise)); }
  to { opacity: 1; transform: none; }
}
@keyframes m-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* skeleton breathe: opacity only, on the compositor */
@keyframes m-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: .55; }
}
/* the in-flight sweep under a submitting button: transform only */
@keyframes m-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
/* the done tick draws: the one non-transform/opacity property, on a 13px path */
@keyframes m-tick-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}
