Checklist Feature Section
Original · freefeature checklist section
Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.
npx shadcn@latest add https://webinnoventix.com/r/featx-checklist.json"use client";
import {
useState,
useRef,
useId,
type KeyboardEvent,
type ReactNode,
} from "react";
import { motion, AnimatePresence, useReducedMotion } from "motion/react";
type FeatureItem = {
title: string;
detail: string;
};
type FeatureGroup = {
id: string;
label: string;
tagline: string;
icon: ReactNode;
items: FeatureItem[];
};
function IconUsers() {
return (
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className="h-4 w-4">
<path
d="M16 19c0-2.2-2.7-4-6-4s-6 1.8-6 4M13 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm7 11c0-1.8-1.5-3.3-3.5-3.8M17.5 8.5a2.5 2.5 0 0 0 0-4"
stroke="currentColor"
strokeWidth={1.7}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function IconBolt() {
return (
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className="h-4 w-4">
<path
d="M13 3 5 13h5l-1 8 8-10h-5l1-8Z"
stroke="currentColor"
strokeWidth={1.7}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function IconShield() {
return (
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className="h-4 w-4">
<path
d="M12 3 5 6v5c0 4.4 3 7.6 7 9 4-1.4 7-4.6 7-9V6l-7-3Zm-2.5 8.5 2 2 3.5-3.5"
stroke="currentColor"
strokeWidth={1.7}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function IconChart() {
return (
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className="h-4 w-4">
<path
d="M4 20h16M7 20v-6m5 6V8m5 12v-9"
stroke="currentColor"
strokeWidth={1.7}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function IconCheck() {
return (
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" className="h-3.5 w-3.5">
<path
d="M4 10.5 8 14.5 16 5.5"
stroke="currentColor"
strokeWidth={2.6}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
const GROUPS: FeatureGroup[] = [
{
id: "collaboration",
label: "Collaboration",
tagline: "Keep every conversation, doc, and decision in one place.",
icon: <IconUsers />,
items: [
{
title: "Real-time co-editing",
detail:
"Several people edit the same doc, board, or spec at once with live cursors and inline comments.",
},
{
title: "Threaded discussions",
detail:
"Reply in context so decisions stay attached to the work instead of scrolling away in chat.",
},
{
title: "Scoped guest access",
detail:
"Invite clients and contractors into specific spaces without exposing the rest of your org.",
},
{
title: "90-day version history",
detail:
"Roll any document back to any point in the last three months with a single click.",
},
{
title: "Mentions and assignments",
detail:
"Loop in the right person and turn any comment into a tracked, owned action item.",
},
],
},
{
id: "automation",
label: "Automation",
tagline: "Let the busywork run itself while your team ships.",
icon: <IconBolt />,
items: [
{
title: "Visual workflow builder",
detail:
"Chain triggers and actions on a drag-and-drop canvas. No code, no scripting required.",
},
{
title: "300+ native integrations",
detail:
"Connect your CRM, repo, and calendar so data moves on its own instead of by copy-paste.",
},
{
title: "Scheduled runs",
detail:
"Fire recurring jobs on a cron-style schedule, down to the exact minute you choose.",
},
{
title: "Conditional branching",
detail:
"Route work automatically by status, owner, or any custom field your team defines.",
},
{
title: "Instant webhooks",
detail:
"Send and receive events in real time to keep anything you already run perfectly in sync.",
},
],
},
{
id: "security",
label: "Security",
tagline: "Enterprise-grade controls, switched on by default.",
icon: <IconShield />,
items: [
{
title: "SSO and SCIM provisioning",
detail:
"Enforce single sign-on and auto-sync members straight from your identity provider.",
},
{
title: "Granular permissions",
detail:
"Set access per space, folder, or field using inheritable, reusable role templates.",
},
{
title: "SOC 2 Type II and GDPR",
detail:
"Independently audited controls plus EU data residency for teams that need it.",
},
{
title: "Complete audit log",
detail:
"Every view, edit, and export is recorded and exportable for your security team.",
},
{
title: "Encryption everywhere",
detail:
"AES-256 at rest and TLS 1.3 in transit on every single connection, always.",
},
],
},
{
id: "insights",
label: "Insights",
tagline: "Know what's working without exporting a thing.",
icon: <IconChart />,
items: [
{
title: "Live dashboards",
detail:
"Build charts from any view and watch them redraw the moment the underlying work changes.",
},
{
title: "Custom reports",
detail:
"Slice progress by owner, sprint, or label and schedule delivery straight to inboxes.",
},
{
title: "Goal tracking",
detail:
"Tie daily tasks to quarterly objectives and let progress roll up automatically.",
},
{
title: "Workload view",
detail:
"Spot overloaded teammates and rebalance before a deadline quietly slips.",
},
{
title: "Export and open API",
detail:
"Pull raw data over REST or push it to your warehouse on a schedule you control.",
},
],
},
];
export default function FeatxChecklist() {
const reduce = useReducedMotion();
const [active, setActive] = useState(0);
const uid = useId();
const tabRefs = useRef<Array<HTMLButtonElement | null>>([]);
const activeGroup = GROUPS[active];
const handleKey = (e: KeyboardEvent<HTMLButtonElement>, i: number) => {
const count = GROUPS.length;
let next = i;
if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (i + 1) % count;
else if (e.key === "ArrowLeft" || e.key === "ArrowUp")
next = (i - 1 + count) % count;
else if (e.key === "Home") next = 0;
else if (e.key === "End") next = count - 1;
else return;
e.preventDefault();
setActive(next);
tabRefs.current[next]?.focus();
};
const listVariants = {
hidden: {},
show: { transition: { staggerChildren: reduce ? 0 : 0.045 } },
exit: { transition: { staggerChildren: 0 } },
};
const itemVariants = reduce
? { hidden: { opacity: 1 }, show: { opacity: 1 }, exit: { opacity: 1 } }
: {
hidden: { opacity: 0, y: 12 },
show: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -8 },
};
return (
<section className="relative w-full overflow-hidden bg-white py-24 sm:py-32 dark:bg-slate-950">
<style>{`
@keyframes featx-float {
0%, 100% { transform: translate3d(0, 0, 0); }
50% { transform: translate3d(0, -18px, 0); }
}
@keyframes featx-sheen {
0% { background-position: -140% 0; }
100% { background-position: 240% 0; }
}
@media (prefers-reduced-motion: reduce) {
.featx-anim { animation: none !important; }
}
`}</style>
{/* Decorative background */}
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0 overflow-hidden"
>
<div className="featx-anim absolute -left-24 -top-24 h-72 w-72 rounded-full bg-indigo-300/40 blur-3xl [animation:featx-float_11s_ease-in-out_infinite] dark:bg-indigo-600/20" />
<div className="featx-anim absolute -right-16 top-1/3 h-80 w-80 rounded-full bg-violet-300/30 blur-3xl [animation:featx-float_14s_ease-in-out_infinite] dark:bg-violet-700/20" />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,transparent_55%,white_100%)] dark:bg-[radial-gradient(circle_at_center,transparent_55%,rgb(2_6_23)_100%)]" />
</div>
<div className="relative mx-auto max-w-6xl px-6">
{/* Header */}
<div className="mx-auto max-w-2xl text-center">
<span className="inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-3 py-1 text-xs font-semibold uppercase tracking-wider text-indigo-700 dark:border-indigo-500/30 dark:bg-indigo-500/10 dark:text-indigo-300">
<span className="relative flex h-1.5 w-1.5">
<span className="featx-anim absolute inline-flex h-full w-full animate-ping rounded-full bg-indigo-500 opacity-75" />
<span className="relative inline-flex h-1.5 w-1.5 rounded-full bg-indigo-500" />
</span>
Everything included
</span>
<h2 className="mt-5 text-balance text-3xl font-bold tracking-tight text-slate-900 sm:text-4xl md:text-5xl dark:text-white">
One workspace, every capability your team needs to ship.
</h2>
<p className="mt-4 text-pretty text-base leading-relaxed text-slate-600 sm:text-lg dark:text-slate-400">
No add-ons and no surprise upgrade walls. Nimbus ships the full
toolkit on every plan. Pick a category to see exactly what lands in
your account on day one.
</p>
</div>
{/* Tabs */}
<div
role="tablist"
aria-label="Feature categories"
className="mx-auto mt-10 flex max-w-3xl flex-wrap items-center justify-center gap-2 sm:gap-3"
>
{GROUPS.map((group, i) => {
const selected = i === active;
return (
<button
key={group.id}
ref={(el) => {
tabRefs.current[i] = el;
}}
role="tab"
id={`${uid}-tab-${group.id}`}
aria-selected={selected}
aria-controls={`${uid}-panel-${group.id}`}
tabIndex={selected ? 0 : -1}
onClick={() => setActive(i)}
onKeyDown={(e) => handleKey(e, i)}
className={[
"inline-flex items-center gap-2 rounded-full border px-4 py-2 text-sm font-semibold outline-none transition-colors",
"focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950",
selected
? "border-transparent bg-slate-900 text-white shadow-sm dark:bg-white dark:text-slate-900"
: "border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400 dark:hover:border-slate-700 dark:hover:text-slate-200",
].join(" ")}
>
<span
className={
selected
? "text-indigo-300 dark:text-indigo-500"
: "text-indigo-500 dark:text-indigo-400"
}
>
{group.icon}
</span>
{group.label}
</button>
);
})}
</div>
{/* Panel */}
<div
role="tabpanel"
id={`${uid}-panel-${activeGroup.id}`}
aria-labelledby={`${uid}-tab-${activeGroup.id}`}
tabIndex={0}
className="mx-auto mt-10 max-w-4xl rounded-3xl border border-slate-200 bg-white/70 p-6 shadow-xl shadow-slate-900/5 backdrop-blur-sm outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 sm:p-8 dark:border-slate-800 dark:bg-slate-900/60 dark:shadow-black/30"
>
<div className="flex flex-col gap-2 border-b border-slate-200 pb-5 sm:flex-row sm:items-center sm:justify-between dark:border-slate-800">
<p className="text-pretty text-lg font-semibold text-slate-900 dark:text-white">
{activeGroup.tagline}
</p>
<span className="inline-flex w-max items-center gap-1.5 rounded-full bg-emerald-50 px-3 py-1 text-xs font-semibold text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-300">
<span className="text-emerald-500 dark:text-emerald-400">
<IconCheck />
</span>
{activeGroup.items.length} capabilities included
</span>
</div>
<AnimatePresence mode="wait">
<motion.ul
key={activeGroup.id}
initial="hidden"
animate="show"
exit="exit"
variants={listVariants}
className="mt-6 grid gap-x-8 gap-y-5 sm:grid-cols-2"
>
{activeGroup.items.map((item) => (
<motion.li
key={item.title}
variants={itemVariants}
className="flex gap-3.5"
>
<span className="mt-0.5 flex h-6 w-6 flex-none items-center justify-center rounded-full bg-emerald-100 text-emerald-600 ring-1 ring-inset ring-emerald-200 dark:bg-emerald-500/15 dark:text-emerald-300 dark:ring-emerald-500/25">
<IconCheck />
</span>
<div>
<h3 className="text-sm font-semibold text-slate-900 dark:text-white">
{item.title}
</h3>
<p className="mt-1 text-sm leading-relaxed text-slate-600 dark:text-slate-400">
{item.detail}
</p>
</div>
</motion.li>
))}
</motion.ul>
</AnimatePresence>
</div>
{/* Footer CTA */}
<div className="mx-auto mt-10 flex max-w-4xl flex-col items-center justify-between gap-5 rounded-2xl border border-slate-200 bg-gradient-to-r from-slate-50 to-white px-6 py-5 sm:flex-row dark:border-slate-800 dark:from-slate-900 dark:to-slate-950">
<p className="text-pretty text-center text-sm text-slate-600 sm:text-left dark:text-slate-400">
<span className="font-semibold text-slate-900 dark:text-white">
Every feature, every plan.
</span>{" "}
From your first free workspace to enterprise rollout.
</p>
<div className="flex flex-none items-center gap-3">
<a
href="#start"
className="relative overflow-hidden rounded-full bg-indigo-600 px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950"
>
<span
aria-hidden="true"
className="featx-anim pointer-events-none absolute inset-0 bg-[linear-gradient(110deg,transparent_25%,rgba(255,255,255,0.35)_50%,transparent_75%)] bg-[length:200%_100%] [animation:featx-sheen_3.5s_linear_infinite]"
/>
<span className="relative">Start free</span>
</a>
<a
href="#plans"
className="rounded-full border border-slate-300 px-5 py-2.5 text-sm font-semibold text-slate-700 transition-colors hover:border-slate-400 hover:text-slate-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-slate-700 dark:text-slate-300 dark:hover:border-slate-500 dark:hover:text-white dark:focus-visible:ring-offset-slate-950"
>
Compare plans
</a>
</div>
</div>
</div>
</section>
);
}Dependencies
Licence
Built by Web Innoventix. Free for personal and commercial use, no attribution required.
Built by Web Innoventix
Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.
Get a free quoteSimilar components
Browse all →Three Column Icon Grid
OriginalA responsive icon grid that presents six product capabilities as scannable cards, each with an inline SVG icon, title and short description.

Alternating Media Rows
OriginalThree feature rows that alternate a text column with a CSS-built visual panel, walking the reader through a plan, measure and ship story.

Bento Feature Grid
OriginalA bento-style grid mixing one large hero cell, a tall stat cell and several compact cards to give features a clear visual hierarchy.

Tabbed Feature Switcher
OriginalA tabbed feature preview that switches panels using only native radio inputs and Tailwind peer variants, so it works with no JavaScript.

Stat Backed Features
OriginalA feature layout that pairs each capability with a headline metric, so every claim is anchored to a measurable result.

Scroll-reveal bento grid
OriginalAn asymmetric bento feature grid whose cards stagger into view on scroll, lift on hover and feature an animated conic gradient border, shimmering headline, growing bar chart and a masked marquee tag strip.

Sticky scroll steps
OriginalA scroll-linked how-it-works section where a sticky panel cross-fades between steps and a progress ring plus filling timeline track advance as you scroll through the process.

Spotlight hover feature cards
OriginalA responsive feature card grid where each card follows the cursor with a radial spotlight glow, lifts and rotates its icon on hover, reveals a call to action, and sits above a scrolling logo marquee.

Animated marquee highlights band
OriginalA bold feature band with an animated gradient background, floating blurred orbs, blur-in staggered headline, two opposing marquee pill rows and shimmering stat cards.

Bordered Feature Grid (2x2)
MITA two-column grid of bordered feature cards, each pairing an outlined icon with a title and supporting copy. Clean, enterprise-leaning layout with full dark-mode support.

Outlined Feature Cards with CTA
MITA three-column feature section with heading and intro, plus blue-outlined cards that each carry an icon, description, and a circular arrow call-to-action. Fully theme-aware.

Icon-Left Feature List
MITA centered heading over a three-column feature list, each row leading with a rounded icon badge and a 'Learn More' link. Classic marketing feature block, ported with added dark variants.

