heroes /
Grid Product Preview Hero
Split hero with text on the left and a grid of 6 product UI preview cards on the right. Screenshot-style cards with gradient fills simulate app screenshots.
Preview
Source
tsx
"use client";
import { motion } from "framer-motion";
import { ArrowRight, LayoutGrid } from "lucide-react";
import { Button } from "@/components/ui/button";
const previewCards = [
{
gradient: "from-violet-500 via-purple-500 to-indigo-600",
label: "Analytics",
bars: [60, 85, 45, 90, 70],
},
{
gradient: "from-sky-400 via-cyan-400 to-teal-500",
label: "Dashboard",
bars: [40, 65, 80, 55, 75],
},
{
gradient: "from-rose-400 via-pink-500 to-fuchsia-600",
label: "Reports",
bars: [75, 50, 90, 65, 40],
},
{
gradient: "from-amber-400 via-orange-400 to-red-500",
label: "Campaigns",
bars: [50, 80, 60, 70, 85],
},
{
gradient: "from-emerald-400 via-green-500 to-teal-600",
label: "Revenue",
bars: [85, 60, 75, 90, 55],
},
{
gradient: "from-blue-500 via-indigo-500 to-violet-600",
label: "Users",
bars: [65, 90, 55, 80, 70],
},
];
export default function GridPreviewHero() {
return (
<section className="relative min-h-screen flex items-center overflow-hidden bg-background">
<div className="container mx-auto px-6 py-20 grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
{/* Left: Text */}
<motion.div
initial={{ opacity: 0, x: -30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.65, ease: "easeOut" }}
className="flex flex-col gap-6"
>
<span className="inline-flex items-center gap-2 text-xs font-semibold uppercase tracking-widest text-primary bg-primary/10 border border-primary/20 rounded-full px-4 py-2 w-fit">
<LayoutGrid className="w-3.5 h-3.5" />
6 powerful modules
</span>
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-extrabold tracking-tight text-foreground leading-[1.08]">
Every tool your
<br />
team needs,
<br />
<span className="bg-gradient-to-r from-primary to-violet-500 bg-clip-text text-transparent">
in one place.
</span>
</h1>
<p className="text-lg text-muted-foreground max-w-md leading-relaxed">
Analytics, reporting, campaign management, and revenue tracking —
all connected in a single, intuitive workspace. No more tab-switching.
</p>
<div className="flex flex-col sm:flex-row gap-3 pt-2">
<Button size="lg" className="gap-2 text-base">
Explore the platform
<ArrowRight className="w-4 h-4" />
</Button>
<Button size="lg" variant="outline" className="text-base">
View pricing
</Button>
</div>
<div className="flex items-center gap-6 pt-2 text-sm text-muted-foreground">
<div className="flex flex-col">
<span className="text-2xl font-bold text-foreground">200+</span>
<span>Integrations</span>
</div>
<div className="w-px h-10 bg-border" />
<div className="flex flex-col">
<span className="text-2xl font-bold text-foreground">99.9%</span>
<span>Uptime SLA</span>
</div>
<div className="w-px h-10 bg-border" />
<div className="flex flex-col">
<span className="text-2xl font-bold text-foreground">SOC 2</span>
<span>Certified</span>
</div>
</div>
</motion.div>
{/* Right: Product preview grid */}
<motion.div
initial={{ opacity: 0, x: 30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.65, ease: "easeOut", delay: 0.15 }}
className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-2 xl:grid-cols-3 gap-3"
>
{previewCards.map((card, i) => (
<motion.div
key={i}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 + i * 0.08 }}
className="relative rounded-xl overflow-hidden border border-border bg-card shadow-sm hover:shadow-md transition-shadow group"
>
{/* Gradient header */}
<div className={`h-24 bg-gradient-to-br ${card.gradient} p-3 relative`}>
{/* Mini bar chart sim */}
<div className="absolute bottom-2 left-3 right-3 flex items-end gap-0.5 h-12">
{card.bars.map((h, j) => (
<div
key={j}
className="flex-1 bg-white/30 rounded-sm group-hover:bg-white/40 transition-colors"
style={{ height: `${h}%` }}
/>
))}
</div>
</div>
{/* Label */}
<div className="p-3">
<p className="text-xs font-semibold text-foreground">{card.label}</p>
<p className="text-xs text-muted-foreground mt-0.5">Live data</p>
</div>
</motion.div>
))}
</motion.div>
</div>
</section>
);
} Claude Code Instructions
CLI Install
npx innovations add grid-previewWhere to use it
Place as the main hero section on your SaaS or product landing page.
In Astro (src/pages/index.astro):
import GridPreviewHero from '../components/innovations/heroes/grid-preview';
<GridPreviewHero client:load />
In Next.js (app/page.tsx):
import GridPreviewHero from '@/components/innovations/heroes/grid-preview';
// Use as the first section in the page return
The previewCards array at the top of the component controls the grid. Each card has a gradient, label, and bar chart data. Swap the gradient classes and labels to reflect your actual product modules or features.