Framer Motion — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Framer Motion (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Deliver meaningful UI motion that improves clarity and feedback without degrading accessibility or performance.
npm i framer-motionframer-motion and use motion.* wrappers selectively.useReducedMotion and reduced-motion variants.import { motion } from 'framer-motion'
const list = {
hidden: {},
show: {
transition: { staggerChildren: 0.06, delayChildren: 0.04 },
},
}
const item = {
hidden: { opacity: 0, y: 8 },
show: { opacity: 1, y: 0, transition: { duration: 0.2 } },
}
export function StaggeredList({ items }: { items: string[] }) {
return (
<motion.ul initial="hidden" animate="show" variants={list} className="space-y-2">
{items.map((label) => (
<motion.li key={label} variants={item} className="rounded border p-3">
{label}
</motion.li>
))}
</motion.ul>
)
}import { AnimatePresence, motion } from 'framer-motion'
export function Toast({ open, message }: { open: boolean; message: string }) {
return (
<AnimatePresence mode="wait">
{open ? (
<motion.div
key="toast"
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 8 }}
transition={{ duration: 0.18 }}
className="rounded-md bg-slate-900 px-4 py-2 text-white"
>
{message}
</motion.div>
) : null}
</AnimatePresence>
)
}// components/PageTransition.tsx
'use client'
import { usePathname } from 'next/navigation'
import { useEffect, useRef, type ReactNode } from 'react'
export function PageTransition({ children }: { children: ReactNode }) {
const pathname = usePathname()
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
const el = ref.current
if (!el) return
el.style.animation = 'none'
void el.offsetHeight // force reflow to restart animation
el.style.animation = ''
}, [pathname])
return (
<div ref={ref} className="animate-fade-up">
{children}
</div>
)
}This approach re-triggers a CSS animation on route change without needing the Framer Motion overhead for every page. Use Framer Motion AnimatePresence when you need exit animations across pages.
<motion.button
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.97 }}
transition={{ type: 'spring', stiffness: 400, damping: 17 }}
className="btn-primary"
>
Run skill
</motion.button>import { motion, LayoutGroup } from 'framer-motion'
// Wrap the list in LayoutGroup; add layoutId to the selected indicator
<LayoutGroup>
{items.map((item) => (
<div key={item.id} className="relative">
{selected === item.id && (
<motion.div
layoutId="selection"
className="absolute inset-0 rounded-lg bg-primary/10"
transition={{ type: 'spring', bounce: 0.2, duration: 0.4 }}
/>
)}
<button onClick={() => setSelected(item.id)}>{item.label}</button>
</div>
))}
</LayoutGroup>import { useReducedMotion } from 'framer-motion'
function AnimatedCard({ children }: { children: React.ReactNode }) {
const reduce = useReducedMotion()
return (
<motion.div
initial={{ opacity: 0, y: reduce ? 0 : 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: reduce ? 0.01 : 0.22 }}
>
{children}
</motion.div>
)
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.