Crystal
Foundations

Motion

Crystal's animation system powered by GSAP with crystallization-aware timing.

Crystal's motion system is built on GSAP (GreenSock Animation Platform). All GSAP plugins are free since the 2025 Webflow acquisition — no license restrictions.

Available Plugins

PluginPurpose
ScrollTriggerScroll-based animation triggers
ScrollSmootherSmooth scrolling wrapper
SplitTextText splitting for character/word/line animations
DrawSVGSVG path drawing animations
MorphSVGSVG shape morphing

Crystallization-Aware Timing

Each crystallization preset defines its own motion personality:

PresetDurationEasingCharacter
Clean200msease-outBalanced, professional
Dream300msease-outSoft, flowing
Edge100msease-in-outSnappy, precise
Luxe500mseaseGraceful, refined
Bold100msback(1.275)Bouncy, energetic

Use CSS custom properties to respect the active crystallization:

.animated-element {
  transition-duration: var(--crystal-motion-duration);
  transition-timing-function: var(--crystal-motion-easing);
}

React Integration

Use the useGSAP hook for automatic cleanup:

import { useGSAP } from '@gsap/react';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

function AnimatedSection() {
  const containerRef = useRef<HTMLDivElement>(null);

  useGSAP(() => {
    gsap.from('.card', {
      y: 40,
      opacity: 0,
      stagger: 0.1,
      scrollTrigger: {
        trigger: containerRef.current,
        start: 'top 80%',
      },
    });
  }, { scope: containerRef });

  return <div ref={containerRef}>...</div>;
}

CSS Animation Utilities

Crystal provides utility classes for common animations:

<div class="animate-fade-in">Fades in with upward motion</div>
<div class="animate-scale-in">Scales in from 95%</div>
<div class="animate-shimmer">Loading shimmer effect</div>

Stagger delays for list items:

<div class="animate-fade-in stagger-1">50ms delay</div>
<div class="animate-fade-in stagger-2">100ms delay</div>
<div class="animate-fade-in stagger-3">150ms delay</div>