Skip to main content
A Singapore Government Agency Website
MOT-2L2 · recommendedhybridMotion

Motion values come from the declared motion token set — durations and easings are never hardcoded in component code

Fails when: a raw duration (350ms, 0.4s) or cubic-bezier literal in component code where the token set exists · a surface that animates but declares no motion token set · the narrative tier (--motion-story) used on interface or task UI

Status: proposed. This control is not ratified. It is recorded here so its shape is reviewable, and it carries an accepted gap in the catalogue for exactly that reason: the harness does not enforce a rule a design lead has not ratified. No check enforces it, and none may while its status is proposed.

Requirement

Where a product declares a motion token set, every duration and easing in component code resolves to a token from it — --motion-* and --ease-*, or their declared code mirror. Raw millisecond values and cubic-bezier literals appear only in the token definitions themselves.

A surface that animates at all is expected to have a declared token set to animate from. The narrative motion tier (--motion-story) is for narrative surfaces and is not used on interface or task UI.

Rationale

Motion is the last part of a design system to get tokens, and the first to drift without them. Hardcoded durations spread by copy-paste, so a system ends up with 200ms, 220ms, and 250ms doing the same job, and no way to retune the feel of a product except by finding every literal. Tokens make motion a system property rather than a per-component decision, in the same way TOK-1 makes colour one.

The boundary with MOT-1: MOT-1 bounds where motion may run and how long it may last; MOT-2 bounds where the values come from. A duration can be token-sourced and still be too long for a task flow, which is MOT-1's finding, not this one's.

Why this is hybrid

Static-check half. A raw ms, s, or cubic-bezier literal in component code is a literal, and separating it from the token definitions is a matter of knowing which file declares the set. That half is mechanical.

Judgment half. Whether a surface should have declared a token set, and whether a given surface is narrative or interface — the boundary the --motion-story condition turns on — are readings the evaluator makes.

Neither half runs today. The control is unratified, so no script implements either half, and the catalogue records that as its accepted gap rather than as pending work. Ratification is a design-lead decision and is tracked separately from any check build.

Passes when

  • Every duration and easing in component code resolves to a declared motion token.
  • Raw values appear only where the token set is defined.
  • The narrative tier is used only on narrative surfaces.

Fails when

  • A raw duration or cubic-bezier literal sits in component code while a token set exists.
  • A surface animates but declares no motion token set.
  • --motion-story drives motion on interface or task UI.

Evaluator guidance

While this control is proposed, findings are advisory: record them, and do not block on them.

Flag:

  • Raw motion literals in component code where a token set is declared.
  • Animated surfaces with no declared token set.
  • Narrative-tier motion on task UI.

Do not flag:

  • The token definitions themselves, which are where raw values belong.
  • Products with no declared motion token set at all — the control grades N/A rather than failing, and standing up a token set is design work, not a finding.
  • Durations that are token-sourced but feel wrong for the flow — that is MOT-1.
  • A recorded rationale for a deliberate raw value — this is an L2 control with waiver: rationale.

Also available as Markdown · catalog.yaml