/* us-motion.css — the site's motion system (RELEASE-BRIEF.md §11), paired with
   us-motion.js. Injected by release/build.mjs into every static page; the React
   application carries the same rules inline (demo/deploy/motion.js).

   The script decides, before first paint, which of these classes <html> gets:
     us-motion-on      animations run (default, or US_MOTION='force')
     us-motion-static  prefers-reduced-motion is on and US_MOTION='respect':
                       final states only, no transitions
     us-motion-force   US_MOTION='force': the reveal rules carry !important so a
                       page's own "@media (prefers-reduced-motion) * {transition:none}"
                       cannot freeze them (that is exactly what the flag is for)
   Nothing here applies without the script: a page whose JS never runs shows its
   content as is.

   Hooks (attributes, no classes to add by hand):
     data-reveal            fade + 8 px up when the element enters the viewport
     data-reveal="120"      the same, with an explicit delay in ms (group stagger)
     data-countup           the first number inside counts up from 0, once
     svg.us-thread > path   the red thread draws with the scroll (dasharray set by JS)
     .us-lift               hover/focus: −2 px, soft shadow, 160 ms
   Only `opacity` and `translate` are touched (never `transform`, never the
   element's own opacity value), so positioned or faded elements keep their styles. */

/* ── reveal ──────────────────────────────────────────────────────────────── */
html.us-motion-on [data-reveal]:not(.in){opacity:0;translate:0 8px}
html.us-motion-on [data-reveal].in:not(.us-done){
  transition:opacity .5s cubic-bezier(.22,.61,.36,1),translate .5s cubic-bezier(.22,.61,.36,1);
}
html.us-motion-force [data-reveal]:not(.in){opacity:0!important;translate:0 8px!important}
html.us-motion-force [data-reveal].in:not(.us-done){
  transition:opacity .5s cubic-bezier(.22,.61,.36,1),translate .5s cubic-bezier(.22,.61,.36,1)!important;
  animation:none!important;
}

/* ── page load: the site header comes in once per session ───────────────── */
html.us-intro-pending .us-site-header,html.us-intro-pending #root>header{opacity:0}
html.us-motion-on .us-intro:not(.in){opacity:0;translate:0 -6px}
html.us-motion-on .us-intro.in{
  transition:opacity .4s cubic-bezier(.22,.61,.36,1),translate .4s cubic-bezier(.22,.61,.36,1);
}
html.us-motion-force .us-intro:not(.in){opacity:0!important;translate:0 -6px!important}
html.us-motion-force .us-intro.in{
  transition:opacity .4s cubic-bezier(.22,.61,.36,1),translate .4s cubic-bezier(.22,.61,.36,1)!important;
}

/* ── the red thread ──────────────────────────────────────────────────────── */
/* hidden until the script has measured the path and set its dash, so the page
   never flashes the fully drawn line before the first frame */
html.us-motion-on svg.us-thread path:not([data-thread-track]):not(.us-thread-ready){visibility:hidden}
html.us-motion-force svg.us-thread path:not([data-thread-track]){transition:none!important}
svg.us-thread path[data-thread-track]{opacity:.13}

/* ── hover / focus micro ─────────────────────────────────────────────────── */
.us-lift{
  transition:translate .16s cubic-bezier(.22,.61,.36,1),box-shadow .16s cubic-bezier(.22,.61,.36,1),
             color .16s cubic-bezier(.22,.61,.36,1),border-color .16s cubic-bezier(.22,.61,.36,1),
             background-color .16s cubic-bezier(.22,.61,.36,1);
}
html.us-motion-force .us-lift{
  transition:translate .16s cubic-bezier(.22,.61,.36,1),box-shadow .16s cubic-bezier(.22,.61,.36,1),
             color .16s cubic-bezier(.22,.61,.36,1),border-color .16s cubic-bezier(.22,.61,.36,1),
             background-color .16s cubic-bezier(.22,.61,.36,1)!important;
}
html.us-motion-on .us-lift:hover,html.us-motion-on .us-lift:focus-visible{
  translate:0 -2px;box-shadow:0 12px 28px -14px rgba(24,36,48,.35);
}
html.us-motion-static .us-lift:hover,html.us-motion-static .us-lift:focus-visible{
  translate:none;box-shadow:0 12px 28px -14px rgba(24,36,48,.35);
}
