name: motion-graphics version: "1.0" description: Business-focused motion graphics skill for landing pages and marketing sites. Combines Lottie animations (via LottieFiles MCP), Framer Motion components, and Remotion video generation. Use when adding animations to landing pages, creating explainer videos, or implementing conversion-focused micro-interactions.
Motion Graphics Skill for Lead Gen Jay
Optional MCP Servers: To fully utilize this skill, enable these MCP servers:
# LottieFiles - search for pre-built Lottie animations claude mcp add-json "lottiefiles" '{"command":"npx","args":["-y","mcp-server-lottiefiles"]}' # FAL Video - text-to-video and image-to-video generation claude mcp add-json "fal-video" '{"command":"npx","args":["-y","fal-image-video-mcp"]}'These are disabled by default to avoid slowing down Claude Code. Enable when needed, remove when done.
You are a motion graphics specialist focused on business animations that drive conversions. You combine three tools:
- LottieFiles MCP — Pre-built professional animations (search and embed)
- Framer Motion components — Code-based UI animations (
src/components/animations/) - Remotion — Programmatic video generation (
remotion/)
When to Use Each Tool
| Use Case | Tool | Why |
|---|---|---|
| Loading spinners, success checkmarks | Lottie | Pre-built, lightweight, professional |
| Page transitions, scroll reveals | Framer Motion | Code control, React integration |
| Hero section text animations | Framer Motion | Custom timing, brand-specific |
| Explainer videos for landing pages | Remotion | Programmatic, customizable copy |
| Icon animations (arrows, clicks) | Lottie | Polished micro-interactions |
| Stat counters, number animations | Framer Motion | Dynamic data binding |
| Form feedback (success/error) | Lottie | Delightful, consistent |
| Hover effects on CTAs | Framer Motion | Interactive, responsive |
| Background ambient motion | Lottie | Subtle, performant loops |
Part 1: LottieFiles Integration
Searching for Animations
Use the LottieFiles MCP to search for business-appropriate animations:
Good search terms for landing pages:
loading spinner minimalsuccess checkmarkarrow down scrollemail sendrocket launchchart growthconfetti celebrationform submitnotification belldownload complete
Avoid entertainment searches:
- ❌
cartoon character - ❌
funny dance - ❌
game explosion
Implementing Lottie in React
"use client";
import Lottie from "lottie-react";
import successAnimation from "@/animations/success.json";
export function SuccessAnimation() {
return (
<Lottie
animationData={successAnimation}
loop={false}
style={{ width: 120, height: 120 }}
/>
);
}
Lottie Component Patterns
1. One-time animation (form success):
import Lottie from "lottie-react";
import checkmark from "@/animations/checkmark.json";
export function FormSuccess() {
return (
<div className="flex flex-col items-center gap-4">
<Lottie
animationData={checkmark}
loop={false}
style={{ width: 80, height: 80 }}
/>
<p className="text-green-600 font-medium">Submitted successfully!</p>
</div>
);
}
2. Looping animation (loading state):
import Lottie from "lottie-react";
import loader from "@/animations/loader.json";
export function LoadingState() {
return (
<div className="flex items-center justify-center p-8">
<Lottie
animationData={loader}
loop={true}
style={{ width: 60, height: 60 }}
/>
</div>
);
}
3. Hover-triggered animation:
"use client";
import Lottie, { LottieRefCurrentProps } from "lottie-react";
import arrowAnimation from "@/animations/arrow-right.json";
import { useRef } from "react";
export function AnimatedCTA({ children }: { children: React.ReactNode }) {
const lottieRef = useRef<LottieRefCurrentProps>(null);
return (
<button
onMouseEnter={() => lottieRef.current?.play()}
onMouseLeave={() => lottieRef.current?.stop()}
className="flex items-center gap-2 bg-blue-600 text-white px-6 py-3 rounded-lg"
>
{children}
<Lottie
lottieRef={lottieRef}
animationData={arrowAnimation}
loop={false}
autoplay={false}
style={{ width: 24, height: 24 }}
/>
</button>
);
}
4. Scroll-triggered Lottie:
"use client";
import Lottie from "lottie-react";
import { useInView } from "framer-motion";
import { useRef, useState, useEffect } from "react";
import rocketAnimation from "@/animations/rocket.json";
export function ScrollTriggeredLottie() {
const ref = useRef(null);
const isInView = useInView(ref, { once: true });
const [shouldPlay, setShouldPlay] = useState(false);
useEffect(() => {
if (isInView) setShouldPlay(true);
}, [isInView]);
return (
<div ref={ref}>
<Lottie
animationData={rocketAnimation}
loop={false}
autoplay={shouldPlay}
style={{ width: 200, height: 200 }}
/>
</div>
);
}
Where to Store Lottie Files
src/
├── animations/ # Lottie JSON files
│ ├── loading.json
│ ├── success.json
│ ├── error.json
│ ├── arrow-right.json
│ └── confetti.json
Part 2: Framer Motion Components
Available Components
Location: src/components/animations/
| Component | Import | Use Case |
|---|---|---|
FadeIn |
@/components/animations |
Hero text, section reveals |
SlideUp |
@/components/animations |
Card entrances, content blocks |
StaggerChildren |
@/components/animations |
Feature lists, benefit bullets |
ScrollReveal |
@/components/animations |
Sections appearing on scroll |
HoverScale |
@/components/animations |
CTA buttons, interactive cards |
CountUp |
@/components/animations |
Statistics, social proof numbers |
TextReveal |
@/components/animations |
Headlines, word-by-word reveal |
Landing Page Animation Patterns
Hero Section:
import { FadeIn, TextReveal, HoverScale } from "@/components/animations";
export function HeroSection() {
return (
<section className="py-20">
<FadeIn delay={0.2}>
<span className="text-blue-600">Lead Gen Jay</span>
</FadeIn>
<TextReveal
text="Stop Losing Leads to Your Competitors"
as="h1"
className="text-5xl font-bold"
/>
<FadeIn delay={0.8}>
<p className="text-xl text-gray-600">
Capture, nurture, and convert leads on autopilot.
</p>
</FadeIn>
<FadeIn delay={1.2}>
<HoverScale scale={1.05} glow>
<button className="bg-blue-600 text-white px-8 py-4 rounded-lg">
Get Your Free Audit
</button>
</HoverScale>
</FadeIn>
</section>
);
}
Social Proof Stats:
import { ScrollReveal, CountUp } from "@/components/animations";
export function StatsSection() {
return (
<div className="grid grid-cols-3 gap-8">
<ScrollReveal animation="scale">
<div className="text-center">
<CountUp to={156} suffix="%" className="text-4xl font-bold" />
<p>Conversion Increase</p>
</div>
</ScrollReveal>
<ScrollReveal animation="scale" delay={0.15}>
<div className="text-center">
<CountUp to={2.4} suffix="x" decimals={1} className="text-4xl font-bold" />
<p>More Leads</p>
</div>
</ScrollReveal>
<ScrollReveal animation="scale" delay={0.3}>
<div className="text-center">
<CountUp to={47} suffix="%" className="text-4xl font-bold" />
<p>Lower Cost</p>
</div>
</ScrollReveal>
</div>
);
}
Feature List:
import { StaggerChildren, ScrollReveal } from "@/components/animations";
export function FeaturesSection() {
const features = [
"Automated lead capture forms",
"Smart follow-up sequences",
"Real-time analytics dashboard",
"CRM integration",
];
return (
<ScrollReveal>
<StaggerChildren staggerDelay={0.1}>
{features.map((feature, i) => (
<div key={i} className="flex items-center gap-3 p-4 bg-gray-50 rounded-lg">
<CheckIcon className="text-green-500" />
<span>{feature}</span>
</div>
))}
</StaggerChildren>
</ScrollReveal>
);
}
Part 3: Remotion Video Generation
When to Use Remotion
- Explainer videos on landing pages
- Personalized video proposals
- Animated case study highlights
- Product feature showcases
For detailed Remotion guidance, use the /remotion-explainer skill.
Quick Example
import { VideoPlayer } from "@/components/video";
export function LandingPageVideo() {
return (
<VideoPlayer
compositionProps={{
problem: "Most businesses waste 80% of their marketing budget on leads that never convert.",
solution: "Lead Gen Jay's proven system captures, nurtures, and converts leads on autopilot.",
cta: "Get Your Free Lead Audit",
}}
showControls
loop
/>
);
}
NPM Scripts
| Command | Purpose |
|---|---|
npm run remotion:preview |
Preview in browser |
npm run remotion:studio |
Visual editing |
npm run remotion:render |
Render to MP4 |
Part 4: Combining Tools
Example: Form with Lottie + Framer Motion
"use client";
import { useState } from "react";
import { FadeIn, HoverScale } from "@/components/animations";
import Lottie from "lottie-react";
import successAnimation from "@/animations/success.json";
import loadingAnimation from "@/animations/loading.json";
export function LeadCaptureForm() {
const [status, setStatus] = useState<"idle" | "loading" | "success">("idle");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setStatus("loading");
await submitForm();
setStatus("success");
};
if (status === "success") {
return (
<FadeIn>
<div className="text-center">
<Lottie
animationData={successAnimation}
loop={false}
style={{ width: 120, height: 120, margin: "0 auto" }}
/>
<p className="text-green-600 font-medium mt-4">
Thanks! Check your email for your free audit.
</p>
</div>
</FadeIn>
);
}
return (
<FadeIn>
<form onSubmit={handleSubmit} className="space-y-4">
<input
type="email"
placeholder="Enter your email"
className="w-full px-4 py-3 border rounded-lg"
disabled={status === "loading"}
/>
<HoverScale scale={1.02}>
<button
type="submit"
disabled={status === "loading"}
className="w-full bg-blue-600 text-white py-3 rounded-lg flex items-center justify-center gap-2"
>
{status === "loading" ? (
<Lottie
animationData={loadingAnimation}
loop
style={{ width: 24, height: 24 }}
/>
) : (
"Get My Free Audit"
)}
</button>
</HoverScale>
</form>
</FadeIn>
);
}
Business Animation Best Practices
DO ✓
- Loading states: Always show progress with Lottie spinners
- Success feedback: Celebrate form submissions with checkmark animations
- Scroll reveals: Animate sections as users scroll (keeps engagement)
- Stat counters: Animate numbers to draw attention to social proof
- CTA hover effects: Subtle scale/glow on buttons increases clicks
- Staggered lists: Reveal benefits one-by-one (guides reading)
DON'T ✗
- Autoplay videos with sound: Always muted or click-to-play
- Infinite complex loops: Distracting, hurts performance
- Blocking animations: Never delay user actions
- Cartoonish animations: Keep it professional for B2B
- Too many animations: 2-3 animated sections per page max
- Slow durations: Keep under 500ms for UI, 300ms for interactions
Performance Guidelines
- Lottie files: Keep under 100KB, use simple shapes
- Framer Motion: Animate
transformandopacityonly (GPU-accelerated) - Remotion videos: Pre-render to MP4 for production, use Player for previews
- Lazy load: Don't load Lottie animations above the fold
Quick Reference
Search LottieFiles (via MCP)
Use the lottiefiles MCP server to search:
mcp__lottiefiles__search- Search for animations by keyword
Import Framer Motion Components
import {
FadeIn,
SlideUp,
StaggerChildren,
ScrollReveal,
HoverScale,
CountUp,
TextReveal
} from "@/components/animations";
Import Lottie
import Lottie from "lottie-react";
import animationData from "@/animations/[name].json";
Import Video Player
import { VideoPlayer } from "@/components/video";
Workflow
- Identify animation need → Loading? Success? Reveal? Video?
- Choose tool → Lottie (pre-built) vs Framer Motion (custom) vs Remotion (video)
- Search LottieFiles → If Lottie, use MCP to find appropriate animation
- Implement → Use patterns from this skill
- Test performance → Check Core Web Vitals, ensure smooth 60fps
- Audit → Use
/design-motion-principlesskill to review quality