Lunia DS

Getting started

Motion

Motion tokens shared by every component, with a live preview for each one. Use them as CSS variables, Tailwind classes or in TypeScript.

Use the tokens

CSS: transition: scale var(--lunia-duration-xl) var(--lunia-ease-out);

Tailwind: duration-xl ease-throw. Reduced motion: motion-reduce:transition-none.

TypeScript: the build also writes motion.ts and a motion.json file in the design token format.

Previews play in a loop.

Duration

Short for small changes, longer for size and distance. Each bar fills in its own duration.

  • duration-2xs

    --lunia-duration-2xs

    120ms

    Exit fades, tap feedback

  • duration-xs

    --lunia-duration-xs

    160ms

    Quick exits

  • duration-sm

    --lunia-duration-sm

    200ms

    Hover, color, small fades

  • duration-md

    --lunia-duration-md

    260ms

    Fade in, blur in

  • duration-lg

    --lunia-duration-lg

    320ms

    Color and rotation, chevrons

  • duration-xl

    --lunia-duration-xl

    380ms

    Move, scale, icon swap

  • duration-2xl

    --lunia-duration-2xl

    420ms

    Height and size, folds

  • duration-3xl

    --lunia-duration-3xl

    460ms

    Text morph, large folds

  • duration-4xl

    --lunia-duration-4xl

    520ms

    Thrown thumbs, arrivals

  • duration-5xl

    --lunia-duration-5xl

    640ms

    Meters, growing bars, number roll

  • duration-6xl

    --lunia-duration-6xl

    900ms

    Long number roll

  • duration-loop

    --lunia-duration-loop

    1600ms

    One cycle of a loop: breathing, sheen

Easing

ease-out is the default and ease-throw overshoots a little. The dot moves with the curve you see.

  • ease-out

    --lunia-ease-out

    cubic-bezier(0.16, 1, 0.3, 1)

    Default. Enter, move, morph

  • ease-settle

    --lunia-ease-settle

    cubic-bezier(0.23, 1, 0.32, 1)

    Surfaces that change size, panels

  • ease-throw

    --lunia-ease-throw

    cubic-bezier(0.34, 1.36, 0.64, 1)

    Small overshoot. Thumbs, pills, arrivals

  • ease-glide

    --lunia-ease-glide

    cubic-bezier(0.77, 0, 0.175, 1)

    Travel across the screen

  • ease-loop

    --lunia-ease-loop

    cubic-bezier(0.45, 0, 0.55, 1)

    Loops only

  • ease-exit

    --lunia-ease-exit

    ease-out

    Short exits

  • ease-linear

    --lunia-ease-linear

    linear

    Constant speed. Spinners, sheens, timers, caret blink

Stagger

The delay between letters, rows or steps. The cap keeps a long list from feeling slow.

  • stagger-text

    --lunia-stagger-text

    16ms

    Delay between letters

  • stagger-list

    --lunia-stagger-list

    28ms

    Delay between rows or bars

  • stagger-max

    --lunia-stagger-max

    160ms

    Longest total stagger

  • stagger-step

    --lunia-stagger-step

    50ms

    Delay between pasted items, steps and cards

Scale

How small a hidden icon gets, and how far a pressed button shrinks. Nothing scales from 0.

  • scale-swap

    --lunia-scale-swap

    0.6000000238418579

    Scale of a hidden icon in a swap

  • scale-press

    --lunia-scale-press

    0.9700000286102295

    Scale of a pressed button

Blur

A little blur hides the swap between two icons and the arrival of letters.

  • blur-swap

    --lunia-blur-swap

    3px

    Blur (px) of a hidden icon

  • blur-text

    --lunia-blur-text

    4px

    Blur (px) of entering letters and text

Distance

How far content rises, shifts or slides. Distances stay small.

  • distance-rise

    --lunia-distance-rise

    4px

    Content rises in from

  • distance-nudge

    --lunia-distance-nudge

    6px

    Panel content offset

  • distance-slide

    --lunia-distance-slide

    24px

    Step and panel slides

Choreography rules

Seven rules decide how motion is put together. Each one has a small live example, and each follows the reduce motion switch above.

  1. 1Opacity resolves before movement

    Content becomes solid first and stops moving after. The eye reads the content before it reads the path.

    Opacity 260ms, move 420ms.

  2. 2Exits are about half the entrance

    Leaving is quick and uses ease-exit. People have already decided to move on.

    In 380ms, out 200ms.

  3. 3Content waits for its container

    A panel grows first. Its content follows 60 to 120ms later, so text never sits on a moving edge.

    Panel 420ms, text starts after 90ms.

  4. 4Grow from what was touched

    A menu opens from its button, a pill grows from its place. Set the transform origin to that corner.

    Transform origin top left, 320ms.

  5. 5Never scale from 0, keep distances small

    Start at 0.6 or higher and move 4 to 24px. A shape that grows from nothing looks like it is popping in.

    Scale 0.6 to 1, rise 4px.

  6. 6State changes use transitions

    A transition can reverse in the middle. Use keyframes only to enter, to leave and for loops.

    Try the switch: click it twice quickly.

  7. 7Every motion has a reduced result

    When the user asks for less motion, the state still changes, but nothing moves.

    Turn on Reduce motion: the color changes, the box stays.