← FeaturesOpen in v0
Features 05 — Toolkit Grid
Centered indexed header over a hairline grid of six quantified capabilities with quiet icon-square hover states, set on an interactive shader flow field masked to the header zone, revealed with per-cell stagger.
$ npx shadcn@latest add @ludusvibe/features-05Code
Installed to components/sections/features-05.tsx — it's yours to edit.
"use client"
import * as React from "react"
import { motion } from "motion/react"
import {
BarChart3,
BellRing,
FlaskConical,
MonitorPlay,
Plug,
ShieldCheck,
} from "lucide-react"
import { buttonVariants } from "@/components/ui/button"
import { ShaderBackground } from "@/components/ludus/shader-background"
import { fadeUp, stagger, viewport } from "@/lib/motion"
import { cn } from "@/lib/utils"
type Feature = {
icon: React.ComponentType<{ className?: string }>
title: string
description: string
}
export type Features05Props = {
index?: string
label?: string
title?: React.ReactNode
description?: string
/** Exactly six capabilities — one quantified line each. */
features?: Feature[]
/** Small centered link under the grid. Pass `null` to hide it. */
link?: { label: string; href: string } | null
/** Heading element — use "h1" when this is the page's main heading. */
as?: "h1" | "h2"
className?: string
}
const defaultFeatures: Feature[] = [
{
icon: MonitorPlay,
title: "Session replays",
description: "50,000 replays a month included on every plan.",
},
{
icon: BellRing,
title: "Alerts in Slack",
description: "Funnel drop-offs reach your channel in under 60 seconds.",
},
{
icon: FlaskConical,
title: "A/B testing",
description: "Ship experiments in minutes, called at 95% significance.",
},
{
icon: BarChart3,
title: "Funnel analytics",
description: "Every step tracked; queries answer in under 400ms.",
},
{
icon: Plug,
title: "Integrations",
description: "One-line snippet plus 40+ native connections.",
},
{
icon: ShieldCheck,
title: "Privacy built in",
description: "SOC 2 Type II, GDPR-ready, EU data residency.",
},
]
export function Features05({
index = "03",
label = "Toolkit",
title = "Everything a revenue team needs. Nothing it doesn't.",
description = "Six capabilities, one snippet — Lumen replaces the four tools your funnel data is currently scattered across.",
features = defaultFeatures,
link = { label: "Explore the full toolkit →", href: "#" },
as: Heading = "h2",
className,
}: Features05Props) {
return (
<section className={cn("relative overflow-hidden bg-background", className)}>
<ShaderBackground
interactive
intensity={0.2}
className="[mask-image:linear-gradient(to_bottom,black,transparent_45%)]"
/>
<motion.div
initial="hidden"
whileInView="visible"
viewport={viewport}
variants={stagger(0.06)}
className="relative mx-auto max-w-6xl px-6 py-20 md:py-28"
>
{/* Centered header zone */}
<div className="text-center">
<motion.p
variants={fadeUp}
className="text-xs tracking-[0.2em] text-muted-foreground uppercase"
>
<span className="text-primary">{index}</span> — {label}
</motion.p>
<motion.div variants={fadeUp}>
<Heading className="mx-auto mt-4 max-w-[24ch] text-3xl font-medium tracking-tight text-balance md:text-4xl">
{title}
</Heading>
</motion.div>
<motion.p
variants={fadeUp}
className="mx-auto mt-4 max-w-[52ch] text-pretty text-muted-foreground"
>
{description}
</motion.p>
</div>
{/* Hairline capability grid */}
<div className="mt-16 grid gap-px border bg-border sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature, i) => (
<motion.div
key={feature.title}
variants={fadeUp}
custom={i * 0.05}
className="group bg-background p-6 transition-colors hover:bg-muted/40 md:p-8"
>
<span
aria-hidden
className="flex size-10 items-center justify-center border transition-colors group-hover:border-primary/50"
>
<feature.icon className="size-5 text-primary" />
</span>
<h3 className="mt-6 font-medium">{feature.title}</h3>
<p className="mt-2 text-sm text-pretty text-muted-foreground">
{feature.description}
</p>
</motion.div>
))}
</div>
{link && (
<motion.div variants={fadeUp} className="mt-8 text-center">
<a
href={link.href}
className={cn(buttonVariants({ variant: "link", size: "sm" }))}
>
{link.label}
</a>
</motion.div>
)}
</motion.div>
</section>
)
}