# MotionScale

> The shared motion scale made visible: the same distance travelled on each duration token and each easing, with a Replay button.

## Facts

- **Product**: Crew OS and Max
- **Family**: Motion
- **Kind**: Showcase page (tokens and patterns)
- **Source**: `: app/transitions.css`
- **Live preview**: /design/components/motion-scale/preview.html
- **Page**: /design/components/motion-scale

## Guidelines

**Durations**: `--duration-stagger` 40ms, `-micro` 80, `-quick` 150 (closes, tooltips), `-fast` 250 (opens), `-medium` 350, `-slow` 400 (panels), `-very-slow` 500 (emphasis). **Easings**: `--ease-smooth-out` `cubic-bezier(0.22, 1, 0.36, 1)` for anything entering or moving; `--ease-bounce` `cubic-bezier(0.34, 1.36, 0.64, 1)` for badges popping in; `--ease-bounce-strong` `cubic-bezier(0.34, 3.85, 0.64, 1)`; `--ease-linear` for loops; agent surfaces and public-site reveals use `cubic-bezier(0.16, 1, 0.3, 1)`.

**Use** the tokens, never literal values: `transition: transform var(--duration-fast) var(--ease-smooth-out)`, or in Tailwind `duration-(--acc-chevron) ease-(--acc-ease)`. Radix overlays animate with keyframes on `scale` and `opacity`. Under reduced motion every duration collapses to 0.01ms.

## Example

```html
<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
var DUR = [["--duration-stagger", 40], ["--duration-micro", 80], ["--duration-quick", 150], ["--duration-fast", 250], ["--duration-medium", 350], ["--duration-slow", 400], ["--duration-very-slow", 500]];
var EASE = [["--ease-smooth-out", "cubic-bezier(0.22, 1, 0.36, 1)", "opens, panels, moves"], ["--ease-bounce", "cubic-bezier(0.34, 1.36, 0.64, 1)", "badges popping in"], ["--ease-bounce-strong", "cubic-bezier(0.34, 3.85, 0.64, 1)", "bouncy hover-out"], ["--ease-linear", "linear", "shimmer, spinners"], ["agent surfaces", "cubic-bezier(0.16, 1, 0.3, 1)", "chat, Ask Max, reveals"]];
function Track(label, meta, style, on) {
  return h("div", { className: "grid grid-cols-[180px_1fr_170px] items-center gap-3" },
    h("code", { className: "font-mono text-xs" }, label),
    h("div", { className: "relative h-5 rounded-full bg-muted" },
      h("span", { className: "absolute top-0.5 size-4 rounded-full bg-primary", style: Object.assign({ left: on ? "calc(100% - 18px)" : "2px" }, style) })),
    h("span", { className: "text-xs text-muted-foreground" }, meta));
}
function App() {
  var s = React.useState(false), on = s[0];
  React.useEffect(function () { var t = setTimeout(function () { s[1](true); }, 300); return function () { clearTimeout(t); }; }, []);
  return h("div", { className: "grid gap-4" },
    h("div", { className: "flex items-center justify-between" },
      h("p", { className: "text-sm text-muted-foreground" }, "Same distance, different clocks. Reference the tokens: transition: transform var(--duration-fast) var(--ease-smooth-out)."),
      h(DC.Button, { size: "sm", variant: "outline", onClick: function () { s[1](!on); } }, "Replay")),
    h("div", { className: "grid gap-2" }, DUR.map(function (d) {
      return h("div", { key: d[0] }, Track(d[0], d[1] + "ms · smooth-out", { transition: "left var(" + d[0] + ") var(--ease-smooth-out)" }, on));
    })),
    h("div", { className: "grid gap-2 pt-2" }, EASE.map(function (e) {
      return h("div", { key: e[0] }, Track(e[0], e[2], { transition: "left 900ms " + e[1] }, on));
    })));
}
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>
```

## More in Motion

- [ActionFocusSession](/design/components/action-focus-session.md): The focus timebox for one task in the actions cockpit: a live billable clock with approve, start, pause, run and done, and a burst of sparkles on completion.
- [CardResize](/design/components/card-resize.md): A container that tweens its width and height when its content changes (`.t-resize`).
- [ChapterScrubber](/design/components/chapter-scrubber.md): A rail of ticks, one per chapter, that swell like a dock under the pointer, with a card previewing the hovered chapter.
- [ContainerScroll](/design/components/container-scroll.md): A hero block where a device-like frame starts tilted back in 3D and straightens as the page scrolls, with the title drifting up.
- [FeatureSlideshow](/design/components/feature-slideshow.md): A step-by-step feature explainer: an accordion of steps on the left that advances on a timer, a progress line on the open step, and a large media slot on the right.
- [FirstBentoAnimation](/design/components/first-bento-animation.md): A self-playing chat vignette for the bento grid: a user asks for a meeting slot, the Digital Crew avatar shows typing dots, then the reply streams in as a `Reasoning` block.
- [FourthBentoAnimation](/design/components/fourth-bento-animation.md): A scheduling vignette for the bento grid: a week ruler, three task bars that spring into place, and a time cursor that follows the pointer.
- [HyperText](/design/components/hyper-text.md): A monospaced, uppercase text effect: letters scramble through random characters, then lock in from left to right.
- [InfiniteSlider](/design/components/infinite-slider.md): A JavaScript-driven endless strip (Framer Motion) that renders its children twice and slides them in a loop, optionally slowing on hover.
- [JoyfulTaskCheckbox](/design/components/joyful-task-checkbox.md): A task checkbox with a small, restrained completion moment: one soft bloom, two sparks, then stillness.
- [Lottie](/design/components/lottie.md): The lottie-react player, exported as-is, for the Lottie animations that ship with Crew OS (`animations/*.json`).
- [Marquee](/design/components/marquee.md): An endless CSS scroll of repeated content, horizontal or vertical, speed set with two CSS variables.
- [NumberFlowCounter](/design/components/number-flow-counter.md): A small dark pill that shows one number at a time and rolls its digits to the next value every two seconds (NumberFlow).
- [OrbitingCircles](/design/components/orbiting-circles.md): Places its children on a circular orbit around the centre of the parent and spins them, with an optional faint ring for the path.
- [ShimmerText](/design/components/shimmer-text.md): A status line with a light band sweeping across its glyphs — Max's "Thinking…" and live tool lines (`.t-shimmer`).
- [SignatureGradient](/design/components/signature-gradient.md): The signature Digital Crew gradient — indigo → pink → amber (`dc-andre`, `dc-camille`, `dc-amber`) — in its four forms.
- [SkeletonReveal](/design/components/skeleton-reveal.md): A skeleton that cross-blurs into the loaded content, so the swap reads as one motion (`.t-skel`).
- [StreamingText](/design/components/streaming-text.md): Streamed words resolving through a soft cross-blur, one after another (`.t-stream-w` → `.is-in`).
- [ThirdBentoAnimation](/design/components/third-bento-animation.md): An insight vignette for the bento grid: a smooth area line draws itself, a dot pulses at its midpoint and a dark pill above it ticks through values.
- [UniboxMotion](/design/components/unibox-motion.md): The Unibox's shared motion vocabulary: every surface moves on the same few springs, so the whole inbox feels like one physical material.
