Tendoo Design

Motion

Define the animation principles, easing curves, and transition tokens that enhance user experience through thoughtful motion.

Motion

Motion helps bring the Tendoo interface to life. It guides users, enhances feedback, and adds delight — all without getting in the way. Our motion system uses consistent tokens and principles to ensure motion is meaningful, accessible, and performant.

Why motion matters

  • Provides visual feedback and spatial awareness.
  • Guides attention and supports interaction.
  • Reinforces brand personality through consistent expression.

Motion tokens

Our motion tokens define a shared language for timing and easing across all components. Use these to ensure smooth and consistent interactions.

Durations

TokenValueUse cases
motion.duration.xs75msInstant feedback (e.g., toggle, switch, button group)
motion.duration.sm150msHover, press, small UI transitions (e.g., chip, badge)
motion.duration.md250msModals, drawers, dropdowns, tooltips
motion.duration.lg400msPage transitions, image viewers, masonry layout
motion.duration.xl600msCarousel slides, timeline scrolls, skeleton loaders

Easings

TokenCurveUse cases
motion.easing.linearcubic-bezier(0, 0, 1, 1)Progress bars, sliders
motion.easing.standardcubic-bezier(0.4, 0, 0.2, 1)Default easing for UI transitions
motion.easing.incubic-bezier(0.4, 0, 1, 1)Entering elements (e.g., dialogs, dropdowns)
motion.easing.outcubic-bezier(0, 0, 0.2, 1)Exiting elements (e.g., tooltips, toasts)
motion.easing.elasticcubic-bezier(0.34, 1.56, 0.64, 1)Playful or attention-grabbing elements (e.g., rating, snackbar)
// motion.tokens.ts
export const motion = {
  duration: {
    xs: "75ms",
    sm: "150ms",
    md: "250ms",
    lg: "400ms",
    xl: "600ms",
  },
  easing: {
    linear: "cubic-bezier(0, 0, 1, 1)",
    standard: "cubic-bezier(0.4, 0, 0.2, 1)",
    in: "cubic-bezier(0.4, 0, 1, 1)",
    out: "cubic-bezier(0, 0, 0.2, 1)",
    elastic: "cubic-bezier(0.34, 1.56, 0.64, 1)",
  },
};

Component examples

Here’s how these tokens are typically applied across your components:

ComponentDuration tokenEasing token
accordionduration.mdeasing.standard
alert-dialogduration.mdeasing.in / out
aspect-ratio
audio-playerduration.smeasing.out
avatarduration.smeasing.standard
badgeduration.xseasing.standard
breadcrumbduration.xseasing.standard
buttonduration.smeasing.out
button-groupduration.smeasing.out
calendarduration.mdeasing.standard
cardduration.smeasing.standard
carouselduration.xleasing.standard
chartduration.lgeasing.linear
checkboxduration.smeasing.out
chipduration.smeasing.out
code-blockduration.xseasing.standard
collapsibleduration.mdeasing.standard
color-pickerduration.smeasing.out
comboboxduration.mdeasing.in / out
commandduration.smeasing.out
context-menuduration.mdeasing.out
data-tableduration.mdeasing.standard
date-pickerduration.mdeasing.standard
dialogduration.mdeasing.in / out
drawerduration.lgeasing.in / out
dropdown-menuduration.mdeasing.in / out
empty-stateduration.lgeasing.out
error-boundaryduration.mdeasing.out
file-uploadduration.mdeasing.standard
image-galleryduration.lgeasing.out
image-viewerduration.lgeasing.out
inputduration.smeasing.standard
input-otpduration.smeasing.out
json-viewerduration.smeasing.standard
kbdduration.xseasing.out
labelduration.xseasing.standard
linkduration.xseasing.out
list-groupduration.smeasing.standard
loaderduration.lgeasing.linear
mapduration.lgeasing.out
masonry-gridduration.lgeasing.out
menubarduration.mdeasing.standard
metricduration.smeasing.linear
navigation-menuduration.mdeasing.in / out
notificationduration.smeasing.elastic
paginationduration.smeasing.standard
popoverduration.mdeasing.in / out
progressduration.mdeasing.linear
radio-groupduration.smeasing.out
range-sliderduration.smeasing.standard
ratingduration.smeasing.elastic
resizableduration.mdeasing.standard
scroll-areaduration.lgeasing.standard
selectduration.mdeasing.in / out
separator
sheetduration.lgeasing.in / out
skeletonduration.lgeasing.linear
snackbarduration.smeasing.elastic
spinnerduration.lgeasing.linear
stepperduration.mdeasing.standard
switchduration.smeasing.out
tabduration.mdeasing.standard
tableduration.mdeasing.standard
tagduration.smeasing.out
text-editorduration.mdeasing.standard
textareaduration.smeasing.standard
time-pickerduration.mdeasing.in / out
timelineduration.xleasing.standard
toastduration.smeasing.elastic
toggleduration.smeasing.out
toggle-groupduration.smeasing.out
tooltipduration.smeasing.out
tree-viewduration.mdeasing.standard
video-playerduration.mdeasing.standard

Usage guidelines

  • Use motion sparingly to support usability, not distract from it.
  • Apply consistent duration and easing based on context.
  • Avoid overly fast or slow transitions — use tokens to maintain rhythm.
  • Always respect user preferences via prefers-reduced-motion.

Accessibility best practices

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

Examples

Button hover

<button className="transition-transform duration-fast ease-in-out hover:scale-105">
  Hover Me
</button>
.modal-enter {
  opacity: 0;
  transform: translateY(16px);
}
.modal-enter-active {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 200ms var(--motion-easing-ease-out), transform 200ms var(--motion-easing-ease-out);
}

Motion enhances experience when done with purpose. Use tokens, stay subtle, and let transitions support — not steal — the user's attention.