Skip to content
System

Motion

One curve, three durations, and the hover, focus and entrance recipes that come out of them.

Duration is chosen by what the user is doing, not by taste. If they are pressing, 120 ms. If the pointer or the focus is on it, 200 ms. If something appears, 480 ms. If what appears is a large surface, 720 ms. The four bands share one curve, nothing bounces, and everything stops under prefers-reduced-motion. Below you have the hover, pressed, focus, entrance and countup recipes.

One single curve

cubic-bezier(0.19, 1, 0.22, 1): with the control points at (0.19, 1) and (0.22, 1), the start is fast and most of the time goes into braking. Buttons, panels, entrances and re-tinting by prop all use this curve. There is no second one.

cubic-bezier(0.19, 1, 0.22, 1)
0.19, 1 0.22, 1 time → progress

Live demos

The arc-enter entrance: a fade with 4 px of travel and a 40 ms delay between items. It is the same one this whole manual uses.
Live
200
ms · standard transition
Primary action

Interaction recipes

Hover or focus to replay the entrance.
1240
Attendees
87
NPS
Metrics count from zero to the value in 600 ms; under reduced-motion the final number is there already.

Motion tokens

TokenValueUse
--arc-duration-press120msPress acknowledgement (:active)
--arc-duration-fast200msHover, focus, state change, exits
--arc-duration480msAn element appearing: dialog, callout, popover
--arc-duration-slow720msLarge surface and scroll entrance
--arc-easecubic-bezier(0.19, 1, 0.22, 1)The brand's single curve

CSS examples

motion-tokens.css
/* Transición estándar de la marca */
.button {
  transition:
    background var(--arc-duration, 480ms) var(--arc-ease, cubic-bezier(0.19, 1, 0.22, 1)),
    color var(--arc-duration, 480ms) var(--arc-ease, cubic-bezier(0.19, 1, 0.22, 1)),
    transform var(--arc-duration, 480ms) var(--arc-ease, cubic-bezier(0.19, 1, 0.22, 1));
}

/* Aparición al montar */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.panel {
  animation: fade-in var(--arc-duration, 480ms) var(--arc-ease, cubic-bezier(0.19, 1, 0.22, 1));
}

/* Respeta reduced-motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

Prohibited

  • No bounce, no elastic. If a gesture needs emphasis, give it more duration.
  • What you see a hundred times a day does not animate: a keyboard action opens at once. What you see dozens of times —hover, moving down a list— takes the shortest band that works.
  • Running text does not move with parallax. To give a block depth, move the background image and leave the text still.
  • Neither video nor audio starts on its own without a visible control: the reader presses play.
  • No transforms that shift the layout. Animate transform and opacity, which do not reflow the page.