Duration tokens

Five named durations from micro-interaction to deliberate emphasis. Hover a row to preview the actual speed of that duration.

instant--dv-motion-duration-instant50ms
Focus rings, micro-feedback
fast--dv-motion-duration-fast100ms
Hover states, border-color, input focus
normal--dv-motion-duration-normal200ms
Standard transitions — buttons, tabs, accordion
slow--dv-motion-duration-slow400ms
Structural movement — burger, progress bars
deliberate--dv-motion-duration-deliberate700ms
Emphasis, large orchestrated shifts
/* Duration tokens */
--dv-motion-duration-instant:     50ms;
--dv-motion-duration-fast:       100ms;
--dv-motion-duration-normal:     200ms;
--dv-motion-duration-slow:       400ms;
--dv-motion-duration-deliberate: 700ms;

/* Usage */
transition: background var(--dv-motion-duration-normal) var(--dv-motion-ease-standard);

Easing tokens

Enter and exit use different curves — things decelerate into place and accelerate away, following natural physics. Hover each card to feel the curve; hover off to feel the reverse.

standard
Default for most transitions — balanced in both directions
enter
Elements entering the screen — accelerates quickly then decelerates to a stop
exit
Elements leaving the screen — starts slow, accelerates away
spring
Modals, drawers — overshoots and settles back, physically-based feel with no JS
/* Easing tokens */
--dv-motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* general movement */
--dv-motion-ease-enter:    cubic-bezier(0, 0, 0.2, 1);   /* decelerates in  */
--dv-motion-ease-exit:     cubic-bezier(0.4, 0, 1, 1);   /* accelerates out */
--dv-motion-ease-spring:   linear(0, 0.009, 0.035 2.1%, …, 1); /* spring, no JS */

/* Usage — enter animations use ease-enter */
animation: dv-slide-up-in var(--dv-motion-duration-normal) var(--dv-motion-ease-enter) forwards;

Keyframe library

Named @keyframes for component enter and exit animations. All consume the motion tokens so the whole feel can be tuned from one place. Hover each card to play the animation.

dv-fade-in
opacity: 0 → 1
Overlays, tooltips, reveal
dv-fade-out
opacity: 1 → 0
Dismissal, exit
dv-slide-up
opacity + translate(0, 8px) → 0
Bottom sheets, toasts (enter)
dv-slide-down
opacity + translate(0, -8px) → 0
Dropdowns, top sheets (enter)
dv-scale-in
opacity + scale(0.95) → 1
Menus, Select dropdown (enter)
dv-pop-in
opacity + scale(0.90) → 1
Popover, emphasis (enter)
dv-slide-up-in
opacity + translateY(8px) → 0
Drawer bottom, Modal, Notification
dv-slide-down-in
opacity + translateY(-8px) → 0
Drawer top
dv-slide-left-in
opacity + translateX(8px) → 0
Drawer right
dv-slide-right-in
opacity + translateX(-8px) → 0
Drawer left
/* Utility keyframes — compose with motion tokens */
@keyframes dv-fade-in    { from { opacity: 0 } }
@keyframes dv-fade-out   { to   { opacity: 0 } }
@keyframes dv-slide-up   { from { opacity: 0; translate: 0  8px } }
@keyframes dv-slide-down { from { opacity: 0; translate: 0 -8px } }
@keyframes dv-scale-in   { from { opacity: 0; scale: 0.95 } }
@keyframes dv-pop-in     { from { opacity: 0; scale: 0.92 } }

/* Plus slide-left-in, slide-right-in, slide-up-in, slide-down-in */
/* for Drawer, Modal, and Notification enter animations. */

/* Usage */
.my-panel[data-open] {
  animation: dv-slide-up var(--dv-motion-duration-normal) var(--dv-motion-ease-enter) forwards;
}

Reduced motion

All component transitions and enter/exit animations are gated behind @media (prefers-reduced-motion: reduce). Users who request reduced motion see instant state changes with no transition or animation — all existing component classes are covered.

@media (prefers-reduced-motion: reduce) {
  /* transitions → none on all interactive components */
  .dv-button, .dv-tab, .dv-nav-link, /* … */ {
    transition: none;
  }
  /* animations → none on all animated components */
  .dv-transition[data-mounted], .dv-notification,
  .dv-drawer[data-position] .dv-drawer-content, /* … */ {
    animation: none;
  }
}

Customising motion

Override tokens at :root to restyle all motion globally, or scope overrides to a specific element subtree.

/* Slow everything down globally */
:root {
  --dv-motion-duration-normal: 350ms;
  --dv-motion-ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* Speed up a specific section */
.dashboard {
  --dv-motion-duration-normal: 120ms;
  --dv-motion-duration-slow: 200ms;
}

/* Override the Transition component defaults */
.dv-transition {
  --dv-transition-duration: var(--dv-motion-duration-slow);
  --dv-transition-easing: var(--dv-motion-ease-spring);
}

CSS Variable Reference

TokenValueUsed by
--dv-motion-duration-instant50msFocus rings, micro-feedback
--dv-motion-duration-fast100msHover states, border-color, input focus
--dv-motion-duration-normal200msStandard transitions — buttons, tabs, accordion
--dv-motion-duration-slow400msStructural movement — burger, progress bars
--dv-motion-duration-deliberate700msEmphasis, large orchestrated shifts
--dv-motion-ease-standardcubic-bezier(0.4, 0, 0.2, 1)Default for most transitions — balanced in both directions
--dv-motion-ease-entercubic-bezier(0, 0, 0.2, 1)Elements entering the screen — accelerates quickly then decelerates to a stop
--dv-motion-ease-exitcubic-bezier(0.4, 0, 1, 1)Elements leaving the screen — starts slow, accelerates away
--dv-motion-ease-springlinear(…)Modals, drawers — overshoots and settles back, physically-based feel with no JS
--dv-accordion-transitionnormal + standardAccordion chevron rotation
--dv-burger-transitionslowBurger line animation
--dv-shell-transitionnormalAppShell navbar/aside slide