← All motion systems
Motion System

Linear

Fast, precise, and physically grounded — motion that feels like a native app, never a website.

get_motion("linear")
Browse all

Motion System: Linear

Category: Project Management / Productivity Fast, precise, and physically grounded — motion that feels like a native app, never a website.

Motion Philosophy

Linear's motion is built around the feeling of a high-performance native application. Every transition should communicate speed and control. The product is used by engineers and designers who are sensitive to latency — any animation that feels slow is felt as friction, not polish. Motion earns its place only when it aids orientation or confirms an action.

The physics model is spring-based, but never playful. Springs at Linear's tuning are tight and critically damped — they reach their target quickly and stop cleanly, with no oscillation. This gives interactive elements a satisfying mechanical feel: buttons that respond to pressure, drawers that snap into place, popovers that arrive with intention. The result is motion that feels native because it behaves like the physics of real interface objects, not the bounce of a toy.

Motion must never be expressive for its own sake. Linear does not celebrate, delight, or entertain through animation. If an element is entering, it fades and slides by a small amount — just enough to give the eye a vector without drawing attention to the transition itself. If something exits, it does so quickly. The interface should feel like it is always ready, always fast.

Duration Scale

TokenValueUse
instant0msState changes with no visual transition (toggling background sync, silent status updates)
fast100msHover states, checkbox ticks, small icon transitions, tooltip appearance
default160msMost UI transitions: command menu opening, modal appearing, panel sliding
slow240msPage-level view transitions, sidebar expanding/collapsing
slower400msOnboarding coach marks, empty state illustrations entering

Easing

TokenCurveUse
ease-outcubic-bezier(0.16, 1, 0.3, 1)Elements entering the screen — decelerates sharply to rest
ease-incubic-bezier(0.7, 0, 0.84, 0)Elements exiting — accelerates quickly away
ease-in-outcubic-bezier(0.45, 0, 0.55, 1)Elements repositioning within the layout
springSee spring configsAll interactive elements: buttons, toggles, drag handles

The ease-out curve is notably aggressive — it front-loads the motion so the element appears to arrive almost instantly and merely settles into place. This is central to the native-app feel.

Spring Configs (Framer Motion / react-spring)

  • Default: stiffness: 400, damping: 30, mass: 1
  • Snappy: stiffness: 600, damping: 35, mass: 0.8
  • Tight (for micro-interactions, icon morphs): stiffness: 700, damping: 40, mass: 0.6
  • Gentle (for large panel transitions): stiffness: 250, damping: 28, mass: 1

No bouncy config exists in the Linear system. Damping ratios are always at or above critical damping.

Stagger Patterns

  • List items: 20ms between each item
  • Cards in grid: 30ms between each card
  • Command menu results: 15ms between each result
  • Children in container: 24ms delay from parent entrance

Stagger is used sparingly — primarily for list items rendering for the first time (e.g., initial load, filtered results). It is not applied to items that already exist in the DOM being rearranged.

Enter / Exit Patterns

Fade + Slide (default for panels, modals, command palette)

enter: opacity 0→1, translateY 6px→0, duration: default (160ms), ease: ease-out
exit: opacity 1→0, translateY 0→-4px, duration: fast (100ms), ease: ease-in

Scale Pop (popovers, context menus, tooltips)

enter: opacity 0→1, scale 0.97→1, duration: fast (100ms), ease: ease-out
exit: opacity 1→0, scale 1→0.97, duration: fast (100ms), ease: ease-in

Slide (command menu, right-hand detail panel)

enter: translateX 100%→0, duration: default (160ms), ease: ease-out
exit: translateX 0→100%, duration: fast (100ms), ease: ease-in

Sidebar / Left Nav Toggle

enter: translateX -100%→0, width animates with layout, duration: slow (240ms), ease: ease-out
exit: translateX 0→-100%, duration: default (160ms), ease: ease-in

Interaction States

  • Hover: Subtle background fill transition at 80ms ease-out. No scale. Icon color shifts via CSS transition, not Framer. Feels instantaneous.
  • Press/Active: scale(0.97) over 80ms with Default spring config. Releases to scale(1) on pointer-up, same spring. Communicates physical depression.
  • Focus: Focus ring appears instantly (0ms) with no transition — using CSS outline. Keyboard navigation should never be delayed by animation.
  • Drag: Dragged item scales to 1.02 and gains a shadow over 120ms ease-out. Drop targets pulse opacity 0.5→1 on 160ms ease-in-out loop while dragging over them.
  • Loading: Skeleton shimmer using CSS animation: linear gradient moving left-to-right over 1400ms, infinite, no easing. Spinners are 16px, 800ms linear rotation.

Rules

  • Respect prefers-reduced-motion. When set, collapse all durations to 0ms and disable transforms. Spring configs should resolve to their target value immediately.
  • Never animate layout properties (width, height, padding, margin) directly. Use transforms and opacity — let layout shifts use layout prop in Framer Motion so the browser optimizes composite-layer transitions.
  • Exit animations must be shorter than enter animations. The interface should clear space faster than it fills it.
  • Do not stack multiple simultaneous animations on a single element. If an item is entering, it should not also be scaling on hover until the entrance is complete.

Use this in your agent

The DesignMD MCP server returns this full motion system in one call. Combine it with design tokens using get_full_system.

get_full_system("linear")
Set up MCP →