content /
Features Grid
3-column feature grid (responsive: 2-col tablet, 1-col mobile). Icon, bold title, description per card. Section header above. Staggered entrance animation.
Preview
Source
tsx
"use client";
import { motion } from "framer-motion";
import {
Zap,
Shield,
BarChart3,
Globe,
Layers,
Headphones,
} from "lucide-react";
const features = [
{
icon: Zap,
title: "Lightning fast",
description:
"Sub-100ms response times globally. Our edge infrastructure ensures your users never wait.",
color: "text-amber-500",
bg: "bg-amber-500/10",
},
{
icon: Shield,
title: "Enterprise security",
description:
"SOC 2 Type II certified, end-to-end encryption, and granular permission controls out of the box.",
color: "text-emerald-500",
bg: "bg-emerald-500/10",
},
{
icon: BarChart3,
title: "Advanced analytics",
description:
"Real-time dashboards with the metrics that matter. Drill down from cohorts to individual sessions.",
color: "text-blue-500",
bg: "bg-blue-500/10",
},
{
icon: Globe,
title: "Global CDN",
description:
"Deployed across 50+ regions worldwide. Your content is always close to your customers.",
color: "text-violet-500",
bg: "bg-violet-500/10",
},
{
icon: Layers,
title: "Seamless integrations",
description:
"Connect with 200+ tools you already use. From Slack to Salesforce, setup takes minutes.",
color: "text-rose-500",
bg: "bg-rose-500/10",
},
{
icon: Headphones,
title: "24/7 support",
description:
"Dedicated success team available around the clock. Average response time under 2 minutes.",
color: "text-cyan-500",
bg: "bg-cyan-500/10",
},
];
const containerVariants = {
hidden: {},
visible: { transition: { staggerChildren: 0.1 } },
};
const cardVariants = {
hidden: { opacity: 0, y: 24 },
visible: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeOut" } },
};
export default function FeaturesGrid() {
return (
<section className="py-20 sm:py-28 bg-background">
<div className="container mx-auto px-6">
{/* Section header */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-80px" }}
transition={{ duration: 0.6, ease: "easeOut" }}
className="text-center max-w-2xl mx-auto mb-14"
>
<span className="text-sm font-semibold uppercase tracking-widest text-primary">
Why teams choose us
</span>
<h2 className="mt-3 text-3xl sm:text-4xl lg:text-5xl font-extrabold tracking-tight text-foreground">
Built for modern teams,
<br />
ready for enterprise scale
</h2>
<p className="mt-4 text-lg text-muted-foreground leading-relaxed">
Everything you need to move fast without breaking things. Powerful
enough for your biggest challenges, simple enough for your whole team.
</p>
</motion.div>
{/* Feature cards grid */}
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-60px" }}
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"
>
{features.map((feature) => {
const Icon = feature.icon;
return (
<motion.div
key={feature.title}
variants={cardVariants}
className="group relative bg-card border border-border rounded-2xl p-6 hover:border-primary/30 hover:shadow-lg transition-all duration-300"
>
<div className={`inline-flex p-3 rounded-xl ${feature.bg} mb-4`}>
<Icon className={`w-6 h-6 ${feature.color}`} />
</div>
<h3 className="text-lg font-bold text-foreground mb-2">
{feature.title}
</h3>
<p className="text-muted-foreground leading-relaxed text-sm">
{feature.description}
</p>
</motion.div>
);
})}
</motion.div>
</div>
</section>
);
} Claude Code Instructions
CLI Install
npx innovations add features-gridWhere to use it
Place this section directly below your hero, above any testimonials or social proof sections.
In Astro (src/pages/index.astro):
import FeaturesGrid from '../components/innovations/content/features-grid';
<FeaturesGrid client:visible />
In Next.js (app/page.tsx):
import FeaturesGrid from '@/components/innovations/content/features-grid';
// Add after the hero section
Edit the features array at the top of the component to change icons (from lucide-react), titles, descriptions, and accent colors. Each feature uses a color + bg pair — the bg should be the color at /10 opacity (e.g., text-amber-500 + bg-amber-500/10).