{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "features-tabs",
  "title": "Tabbed product tour",
  "description": "Product tour with animated tabs; each tab pairs short copy and a checklist with a Tailwind-built app mock.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://velora.colorlib.com/r/animated-tabs.json",
    "https://velora.colorlib.com/r/blur-fade.json"
  ],
  "files": [
    {
      "path": "src/components/blocks/features-tabs.tsx",
      "content": "import {\n  ArrowRightIcon,\n  ChartColumnIcon,\n  CheckIcon,\n  CircleCheckIcon,\n  GitPullRequestIcon,\n  KanbanIcon,\n  LoaderCircleIcon,\n  RocketIcon,\n} from \"lucide-react\";\n\nimport { AnimatedTabs } from \"@/components/velora/animated-tabs\";\nimport { BlurFade } from \"@/components/velora/blur-fade\";\nimport { cn } from \"@/lib/utils\";\n\nconst HEADING = {\n  eyebrow: \"Product tour\",\n  title: \"From idea to impact, without switching tabs\",\n  description:\n    \"Plan the work, review the code, ship the release and measure the result — all in the same calm workspace.\",\n};\n\nconst TOUR = [\n  {\n    value: \"plan\",\n    label: \"Plan\",\n    cta: \"Explore planning\",\n    icon: KanbanIcon,\n    title: \"Roadmaps that stay honest\",\n    description:\n      \"Break goals into projects and issues, then drag them across the board. Priorities and estimates roll up automatically.\",\n    points: [\"Boards, lists and timelines\", \"Cycles with automatic rollover\", \"Linked docs and specs\"],\n    mock: PlanMock,\n  },\n  {\n    value: \"build\",\n    label: \"Build\",\n    cta: \"Explore code review\",\n    icon: GitPullRequestIcon,\n    title: \"Reviews in the flow of work\",\n    description:\n      \"Pull requests link to their issues, so reviewers get the full context and the issue moves itself when the code merges.\",\n    points: [\"Branch names generated for you\", \"Inline diffs with comments\", \"Status checks on every issue\"],\n    mock: BuildMock,\n  },\n  {\n    value: \"ship\",\n    label: \"Ship\",\n    cta: \"Explore releases\",\n    icon: RocketIcon,\n    title: \"Releases without the checklist\",\n    description:\n      \"Promote builds from preview to production with one click. Acme writes the changelog from what actually shipped.\",\n    points: [\"Preview links for every change\", \"Staged rollouts and instant rollback\", \"Auto-drafted release notes\"],\n    mock: ShipMock,\n  },\n  {\n    value: \"measure\",\n    label: \"Measure\",\n    cta: \"Explore insights\",\n    icon: ChartColumnIcon,\n    title: \"Know what moved the needle\",\n    description:\n      \"Tie every release to adoption and revenue. Dashboards update live and share with a link — no exports.\",\n    points: [\"Adoption per feature\", \"Cycle time and throughput\", \"Shareable live dashboards\"],\n    mock: MeasureMock,\n  },\n];\n\n/**\n * Product tour: animated tabs, each pairing short copy and a checklist with\n * a Tailwind-built mock of the product. Edit TOUR to change the steps.\n */\nexport function FeaturesTabs() {\n  return (\n    <section className=\"px-6 py-24 sm:py-32 lg:px-8\">\n      <div className=\"mx-auto max-w-6xl\">\n        <BlurFade>\n          <div className=\"mx-auto max-w-2xl text-center\">\n            <p className=\"text-sm font-semibold text-primary\">{HEADING.eyebrow}</p>\n            <h2 className=\"mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl\">\n              {HEADING.title}\n            </h2>\n            <p className=\"mt-5 text-lg text-pretty text-muted-foreground\">\n              {HEADING.description}\n            </p>\n          </div>\n        </BlurFade>\n\n        <BlurFade delay={0.1}>\n          <AnimatedTabs\n            className=\"mt-12 gap-8\"\n            listClassName=\"self-center\"\n            tabs={TOUR.map(({ value, label, icon: Icon, mock: Mock, ...copy }) => ({\n              value,\n              title: (\n                <span className=\"flex items-center gap-2\">\n                  <Icon aria-hidden className=\"hidden size-4 sm:block\" />\n                  {label}\n                </span>\n              ),\n              content: (\n                <div className=\"grid h-full gap-8 p-6 sm:p-8 lg:grid-cols-5 lg:items-center lg:gap-12 lg:p-10\">\n                  <div className=\"lg:col-span-2\">\n                    <h3 className=\"text-2xl font-semibold tracking-tight\">{copy.title}</h3>\n                    <p className=\"mt-3 text-pretty text-muted-foreground\">{copy.description}</p>\n                    <ul className=\"mt-6 space-y-3 text-sm\">\n                      {copy.points.map((point) => (\n                        <li key={point} className=\"flex items-center gap-3\">\n                          <span className=\"grid size-5 shrink-0 place-items-center rounded-full bg-primary/10 text-primary\">\n                            <CheckIcon aria-hidden className=\"size-3\" />\n                          </span>\n                          {point}\n                        </li>\n                      ))}\n                    </ul>\n                    <a\n                      href=\"#\"\n                      className=\"mt-8 inline-flex items-center gap-1 rounded-sm text-sm font-medium text-primary hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n                    >\n                      {copy.cta}\n                      <ArrowRightIcon aria-hidden className=\"size-4\" />\n                    </a>\n                  </div>\n                  <div\n                    aria-hidden\n                    className=\"relative overflow-hidden rounded-xl border bg-muted/40 p-3 sm:p-5 lg:col-span-3\"\n                  >\n                    <div className=\"absolute -top-24 -right-24 size-64 rounded-full bg-brand/10 blur-3xl\" />\n                    <div className=\"relative\">\n                      <Mock />\n                    </div>\n                  </div>\n                </div>\n              ),\n            }))}\n          />\n        </BlurFade>\n      </div>\n    </section>\n  );\n}\n\n/* ---------- Mock UIs (decorative, built with Tailwind) ---------- */\n\nfunction Avatar({ initials, className }: { initials: string; className?: string }) {\n  return (\n    <span\n      className={cn(\n        \"grid size-5 place-items-center rounded-full bg-gradient-to-br from-brand-from to-brand-to text-[9px] font-semibold text-brand-foreground ring-2 ring-card\",\n        className\n      )}\n    >\n      {initials}\n    </span>\n  );\n}\n\nfunction PlanMock() {\n  const columns = [\n    {\n      name: \"Backlog\",\n      count: 8,\n      cards: [\n        { title: \"Usage-based billing\", tag: \"Billing\" },\n        { title: \"Dark mode for email\", tag: \"Design\" },\n        { title: \"Audit log export\", tag: \"Security\" },\n      ],\n    },\n    {\n      name: \"In progress\",\n      count: 3,\n      cards: [\n        { title: \"Onboarding checklist\", tag: \"Growth\", active: true },\n        { title: \"Search v2 ranking\", tag: \"Core\" },\n        { title: \"Mobile quick capture\", tag: \"Mobile\" },\n      ],\n    },\n    {\n      name: \"Done\",\n      count: 21,\n      cards: [\n        { title: \"SSO for all plans\", tag: \"Security\" },\n        { title: \"Faster board loads\", tag: \"Perf\" },\n        { title: \"Guest access\", tag: \"Growth\" },\n      ],\n    },\n  ];\n  return (\n    <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n      {columns.map((col, c) => (\n        <div key={col.name} className={cn(\"space-y-2\", c === 2 && \"hidden sm:block\")}>\n          <div className=\"flex items-center gap-2 px-1 text-xs font-medium\">\n            <span\n              className={cn(\n                \"size-2 rounded-full\",\n                c === 0 && \"bg-muted-foreground/40\",\n                c === 1 && \"bg-brand\",\n                c === 2 && \"bg-emerald-500\"\n              )}\n            />\n            {col.name}\n            <span className=\"text-muted-foreground\">{col.count}</span>\n          </div>\n          {col.cards.map((card, i) => (\n            <div\n              key={card.title}\n              className={cn(\n                \"rounded-lg border bg-card p-3 shadow-sm\",\n                \"active\" in card && \"border-primary/40 shadow-md ring-2 shadow-primary/10 ring-primary/15\"\n              )}\n            >\n              <p className=\"text-xs font-medium\">{card.title}</p>\n              <div className=\"mt-3 flex items-center justify-between\">\n                <span className=\"rounded-md bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n                  {card.tag}\n                </span>\n                <Avatar initials={[\"MK\", \"JL\", \"AR\"][(c + i) % 3]} />\n              </div>\n            </div>\n          ))}\n        </div>\n      ))}\n    </div>\n  );\n}\n\nfunction BuildMock() {\n  const lines = [\n    { type: \" \", text: \"export function Checklist({ steps }) {\" },\n    { type: \"-\", text: \"  const done = steps.filter((s) => s.done);\" },\n    { type: \"+\", text: \"  const done = useMemo(\" },\n    { type: \"+\", text: \"    () => steps.filter((s) => s.done),\" },\n    { type: \"+\", text: \"    [steps]\" },\n    { type: \"+\", text: \"  );\" },\n    { type: \" \", text: \"  return <Progress value={done.length} />;\" },\n  ];\n  return (\n    <div className=\"overflow-hidden rounded-lg border bg-card shadow-sm\">\n      <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2 border-b px-4 py-3\">\n        <GitPullRequestIcon className=\"size-4 text-primary\" />\n        <p className=\"text-sm font-medium\">Memoize onboarding progress</p>\n        <span className=\"rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary\">\n          ACME-128\n        </span>\n        <span className=\"ml-auto flex -space-x-1\">\n          <Avatar initials=\"JL\" />\n          <Avatar initials=\"AR\" />\n        </span>\n      </div>\n      <div className=\"overflow-hidden py-2 font-mono text-[11px] leading-6\">\n        {lines.map((line, i) => (\n          <div\n            key={i}\n            className={cn(\n              \"flex gap-3 px-4 whitespace-pre\",\n              line.type === \"+\" && \"bg-emerald-500/10\",\n              line.type === \"-\" && \"bg-red-500/10\"\n            )}\n          >\n            <span className=\"w-4 shrink-0 text-right text-muted-foreground/60\">{i + 41}</span>\n            <span\n              className={cn(\n                \"w-2 shrink-0\",\n                line.type === \"+\" && \"text-emerald-600 dark:text-emerald-400\",\n                line.type === \"-\" && \"text-red-600 dark:text-red-400\"\n              )}\n            >\n              {line.type}\n            </span>\n            <span className=\"overflow-hidden text-ellipsis\">{line.text}</span>\n          </div>\n        ))}\n      </div>\n      <div className=\"flex items-center gap-2 border-t px-4 py-3 text-xs text-muted-foreground\">\n        <CircleCheckIcon className=\"size-4 text-emerald-500\" />\n        All checks passed\n        <span className=\"ml-auto rounded-md bg-primary px-2.5 py-1 font-medium text-primary-foreground\">\n          Merge\n        </span>\n      </div>\n    </div>\n  );\n}\n\nfunction ShipMock() {\n  const stages = [\n    { name: \"Preview\", detail: \"pr-128.acme.app\", state: \"done\" },\n    { name: \"Staging\", detail: \"Smoke tests · 42 passed\", state: \"done\" },\n    { name: \"Production\", detail: \"Rolling out to 60% of traffic\", state: \"running\" },\n  ];\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"rounded-lg border bg-card p-4 shadow-sm\">\n        <div className=\"flex items-center justify-between text-xs\">\n          <span className=\"font-medium\">Release v2.14.0</span>\n          <span className=\"text-muted-foreground\">Started 3 min ago</span>\n        </div>\n        <ol className=\"mt-4 space-y-4\">\n          {stages.map((stage) => (\n            <li key={stage.name} className=\"flex items-center gap-3\">\n              {stage.state === \"done\" ? (\n                <CircleCheckIcon className=\"size-5 shrink-0 text-emerald-500\" />\n              ) : (\n                <LoaderCircleIcon className=\"size-5 shrink-0 text-primary motion-safe:animate-spin\" />\n              )}\n              <div className=\"min-w-0 flex-1\">\n                <p className=\"text-sm font-medium\">{stage.name}</p>\n                <p className=\"truncate text-xs text-muted-foreground\">{stage.detail}</p>\n              </div>\n              {stage.state === \"running\" && (\n                <div className=\"hidden h-1.5 w-24 overflow-hidden rounded-full bg-muted sm:block\">\n                  <div className=\"h-full w-3/5 rounded-full bg-gradient-to-r from-brand-from to-brand-to\" />\n                </div>\n              )}\n            </li>\n          ))}\n        </ol>\n      </div>\n      <div className=\"rounded-lg border bg-card p-4 shadow-sm\">\n        <p className=\"text-xs font-medium text-muted-foreground\">Drafted release notes</p>\n        <ul className=\"mt-2 space-y-1.5 text-xs\">\n          <li>\n            <span className=\"font-medium text-primary\">New</span> Onboarding checklist for new workspaces\n          </li>\n          <li>\n            <span className=\"font-medium text-primary\">Improved</span> Boards load 2× faster\n          </li>\n          <li>\n            <span className=\"font-medium text-primary\">Fixed</span> Timezone drift in cycle reports\n          </li>\n        </ul>\n      </div>\n    </div>\n  );\n}\n\nfunction MeasureMock() {\n  const kpis = [\n    { label: \"Adoption\", value: \"68%\", delta: \"+9%\" },\n    { label: \"Cycle time\", value: \"2.4d\", delta: \"−18%\" },\n    { label: \"Shipped\", value: \"142\", delta: \"+23\" },\n  ];\n  const bars = [32, 45, 38, 52, 48, 61, 58, 70, 66, 78, 74, 88];\n  return (\n    <div className=\"space-y-3\">\n      <div className=\"grid grid-cols-3 gap-3\">\n        {kpis.map((kpi) => (\n          <div key={kpi.label} className=\"rounded-lg border bg-card p-3 shadow-sm\">\n            <p className=\"truncate text-[11px] text-muted-foreground\">{kpi.label}</p>\n            <p className=\"mt-1 text-lg font-semibold tracking-tight\">{kpi.value}</p>\n            <p className=\"text-[11px] font-medium text-emerald-600 dark:text-emerald-400\">{kpi.delta}</p>\n          </div>\n        ))}\n      </div>\n      <div className=\"rounded-lg border bg-card p-4 shadow-sm\">\n        <div className=\"flex items-center justify-between text-xs\">\n          <span className=\"font-medium\">Weekly active teams</span>\n          <span className=\"text-muted-foreground\">Last 12 weeks</span>\n        </div>\n        <div className=\"mt-4 flex h-28 items-end gap-1.5\">\n          {bars.map((v, i) => (\n            <div\n              key={i}\n              style={{ height: `${v}%` }}\n              className={cn(\n                \"flex-1 rounded-t-sm\",\n                i === bars.length - 1\n                  ? \"bg-gradient-to-t from-brand-from to-brand-to\"\n                  : \"bg-primary/20\"\n              )}\n            />\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/blocks/features-tabs.tsx"
    }
  ],
  "categories": [
    "feature-sections"
  ],
  "type": "registry:block"
}