Browse all of Kata

Motion

Source docs/design/foundations/motion.mdMarkdown

On this page

What moves, how far, how fast, and who opts out.

Part of the Konjo design language. The laws in the spine apply here unless this chapter contradicts them.

Konjo is an app people open sweaty, one-handed, with forty seconds before class. Motion earns its place by making a change legible — where something came from, what replaced what. It never earns its place by being pleasant.

The durations, and what each is for

Read the numbers from the token tables; this is what they mean.

Token Use
instant A press state. Colour and opacity only — this is below the threshold where anyone perceives a transition.
quick A chip selecting, a checkbox, a small in-place change.
base The default. A sheet's backdrop, a row expanding, a tab's content cross-fading.
enter Something arriving: a sheet rising, a toast dropping in.
exit Something leaving. Deliberately faster than enter — waiting for a thing you already dismissed is the most irritating motion in any app.
slow Reserved. A deliberate reveal where the delay carries meaning.

Nothing exceeds 400ms except one celebration. The promotion certificate is the single place the app is allowed to take its time, because the moment is the point.

What is allowed to move

  • Things entering and leaving the screen. Sheets, toasts, banners, list items on first load.
  • Things changing size in place. An accordion, a "show more".
  • State on a control. Press, selection, focus.
  • Determinate progress. A bar that fills as something completes.

What is not

  • Content that is already on screen and did not change. No entrance animation on scroll, no stagger down a list the user is halfway through.
  • Anything decorative. Pulsing, floating, breathing, drifting. A dojo app is not a screensaver.
  • Anything that delays an action. If a tap has a result, the result is not gated behind an animation finishing.
  • Parallax and auto-playing carousels. Both are vestibular triggers and neither has ever helped anyone find a class.
  • Loading spinners under one second. See states — the flash is worse than the wait.

How it should feel

  • Enter with easing out, exit with easing in. Things arriving decelerate into place; things leaving accelerate away. The reverse reads as broken.
  • One thing moves at a time. If a sheet is rising, the content behind it holds still.
  • Motion has a direction and it means something. A sheet comes from the bottom because that is where it goes back to. A push comes from the trailing edge because back returns there. Arbitrary directions teach nothing.
  • Distance is small. 8–24pt of travel reads as motion; 200pt reads as a journey. The exception is a surface genuinely entering from off-screen.
  • Interruptible. A person who taps again mid-animation gets the new thing, not a queue.

Reduced motion

This is not optional and it is currently mostly missing — 14 of the 19 files that animate ignore the setting. Use useReducedMotion() from react-native-reanimated; ListFadeIn, ReflectPill, WizardProgressBar and WizardScaffold already do it correctly.

Reduced motion replaces movement, it does not delete it:

Normally Reduced
Slide in from the edge Cross-fade in place
Spring / scale Instant state change
Progress counting up Jump to the value
Scrolling to the first invalid field Jump to it — focus still moves, nothing is lost
Certificate reveal The same certificate, presented statically

Full rationale in accessibility.

The test

Watch the screen once at normal speed. If you noticed the animation, it is too long, too far, or should not be there. Then turn reduce motion on and watch again: everything you needed to understand should still be there.