Motion

Motion is intentionally subtle. Transitions use CSS with consistent duration tokens. Scroll-triggered reveals use IntersectionObserver.

Duration tokens

TokenValueUsage
--duration-fast150msLink colors, sidebar hover
--duration-default200msButtons, cards, general transitions
--duration-slow300msComplex state changes
--easing-defaulteaseAll standard transitions

Scroll reveal

Elements with the .reveal class fade in and slide up when they enter the viewport.

.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

Triggered via IntersectionObserver:

const observer = new IntersectionObserver(
  entries => entries.forEach(e => {
    if (e.isIntersecting) e.target.classList.add('visible');
  }),
  { threshold: 0.1, rootMargin: '0px 0px -60px 0px' }
);
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));

Hover transitions

Standard pattern for all interactive elements:

transition: background var(--duration-default) var(--easing-default),
            box-shadow var(--duration-default) var(--easing-default);

Hover patterns by element

ElementTransition propertyDuration
Linkscolor--duration-fast (150ms)
Buttonsbackground, box-shadow--duration-default (200ms)
Cardsbox-shadow--duration-default (200ms)
Product cardsbox-shadow, transform--duration-default (200ms)
Iconscolor--duration-fast (150ms)

The testimonials carousel uses a cubic-bezier easing for smooth sliding:

transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);

Card focus transitions:

transition: opacity 0.4s ease, transform 0.4s ease;

Terminal animation

Used in the Helm terminal showcase. Lines appear sequentially with staggered delays:

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* Cursor blink */
animation: blink 1s step-end infinite;

/* Line entrance: 100ms stagger per line */
opacity: 0 -> 1;
transform: translateY(4px) -> translateY(0);
transition: 0.3s ease;

Reduced motion

The design system does not currently include a prefers-reduced-motion media query. All animations are CSS-based and short duration (under 600ms).