{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "features-steps",
  "title": "Numbered steps",
  "description": "How-it-works section with four numbered steps on a gradient connector line, each with a small UI visual.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://velora.colorlib.com/r/avatar-circles.json",
    "https://velora.colorlib.com/r/blur-fade.json",
    "https://velora.colorlib.com/r/border-beam.json",
    "https://velora.colorlib.com/r/number-ticker.json"
  ],
  "files": [
    {
      "path": "src/components/blocks/features-steps.tsx",
      "content": "import {\n  CalendarIcon,\n  CircleCheckIcon,\n  CloudIcon,\n  DatabaseIcon,\n  FileTextIcon,\n  MailIcon,\n  MessageSquareIcon,\n} from \"lucide-react\";\n\nimport { AvatarCircles } from \"@/components/velora/avatar-circles\";\nimport { BlurFade } from \"@/components/velora/blur-fade\";\nimport { BorderBeam } from \"@/components/velora/border-beam\";\nimport { NumberTicker } from \"@/components/velora/number-ticker\";\nimport { cn } from \"@/lib/utils\";\n\nconst HEADING = {\n  eyebrow: \"How it works\",\n  title: \"Up and running in an afternoon\",\n  description:\n    \"No migration project, no consultants. Most teams go from sign-up to their first release in under a day.\",\n};\n\nconst STEPS = [\n  {\n    title: \"Connect your tools\",\n    description: \"Link your repo, inbox and calendar with one-click OAuth. Nothing to install.\",\n    visual: ConnectVisual,\n  },\n  {\n    title: \"Import your work\",\n    description: \"Bring issues, docs and history across from your old tracker in minutes.\",\n    visual: ImportVisual,\n  },\n  {\n    title: \"Invite your team\",\n    description: \"Add teammates by email or SSO. Roles and permissions are set up for you.\",\n    visual: InviteVisual,\n  },\n  {\n    title: \"Ship with confidence\",\n    description: \"Plan, review and release from one place, with every change tracked end to end.\",\n    visual: ShipVisual,\n  },\n];\n\n/**\n * \"How it works\" in four numbered steps joined by a gradient connector —\n * vertical on small screens, horizontal from `lg`. Each step carries a small\n * Tailwind-built visual; edit STEPS to change them.\n */\nexport function FeaturesSteps() {\n  return (\n    <section className=\"px-6 py-24 sm:py-32 lg:px-8\">\n      <div className=\"mx-auto max-w-7xl\">\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        <ol className=\"mx-auto mt-16 grid max-w-xl gap-12 sm:mt-20 lg:max-w-none lg:grid-cols-4 lg:gap-8\">\n          {STEPS.map(({ title, description, visual: Visual }, i) => (\n            <li key={title} className=\"relative grid grid-cols-[2.5rem_1fr] gap-x-5 lg:grid-cols-1 lg:gap-y-6\">\n              {i < STEPS.length - 1 && (\n                <span\n                  aria-hidden\n                  className=\"absolute top-12 -bottom-10 left-5 w-px -translate-x-1/2 bg-gradient-to-b from-brand-from/70 to-brand-to/30 lg:top-5 lg:-right-4 lg:bottom-auto lg:left-14 lg:h-px lg:w-auto lg:translate-x-0 lg:bg-gradient-to-r\"\n                />\n              )}\n              <BlurFade delay={0.1 * i}>\n                <span className=\"relative grid size-10 place-items-center rounded-full border bg-background text-sm font-semibold shadow-sm\">\n                  <span className=\"absolute inset-0 rounded-full bg-gradient-to-br from-brand-from/15 to-brand-to/15\" />\n                  <span className=\"relative bg-gradient-to-br from-brand-from to-brand-to bg-clip-text text-transparent\">\n                    {String(i + 1).padStart(2, \"0\")}\n                  </span>\n                </span>\n              </BlurFade>\n              <BlurFade delay={0.1 * i + 0.05} className=\"flex flex-col gap-6\">\n                <div aria-hidden className={cn(\"relative h-36 overflow-hidden rounded-xl border bg-card p-4 shadow-sm\", i === STEPS.length - 1 && \"border-primary/30\")}>\n                  <Visual />\n                  {i === STEPS.length - 1 && <BorderBeam size={80} duration={8} />}\n                </div>\n                <div>\n                  <h3 className=\"text-lg font-semibold tracking-tight\">{title}</h3>\n                  <p className=\"mt-2 text-sm leading-relaxed text-pretty text-muted-foreground\">\n                    {description}\n                  </p>\n                </div>\n              </BlurFade>\n            </li>\n          ))}\n        </ol>\n      </div>\n    </section>\n  );\n}\n\n/* ---------- Step visuals (decorative) ---------- */\n\nfunction ConnectVisual() {\n  const apps = [\n    { icon: DatabaseIcon, name: \"Database\", on: true },\n    { icon: MailIcon, name: \"Mail\", on: true },\n    { icon: CalendarIcon, name: \"Calendar\", on: false },\n  ];\n  return (\n    <div className=\"flex h-full flex-col justify-center gap-2\">\n      {apps.map(({ icon: Icon, name, on }) => (\n        <div key={name} className=\"flex items-center gap-2.5 text-xs\">\n          <span className=\"grid size-6 place-items-center rounded-md border bg-muted/60\">\n            <Icon className=\"size-3.5 text-muted-foreground\" />\n          </span>\n          <span className=\"font-medium\">{name}</span>\n          <span\n            className={cn(\n              \"ml-auto rounded-full px-2 py-0.5 text-[10px] font-medium\",\n              on ? \"bg-primary/10 text-primary\" : \"border text-muted-foreground\"\n            )}\n          >\n            {on ? \"Connected\" : \"Connect\"}\n          </span>\n        </div>\n      ))}\n    </div>\n  );\n}\n\nfunction ImportVisual() {\n  return (\n    <div className=\"flex h-full flex-col justify-center gap-3\">\n      <div className=\"flex items-baseline justify-between text-xs\">\n        <span className=\"font-medium\">Importing issues</span>\n        <span className=\"text-muted-foreground tabular-nums\">\n          <NumberTicker value={1284} /> / 1,780\n        </span>\n      </div>\n      <div className=\"h-1.5 overflow-hidden rounded-full bg-muted\">\n        <div className=\"h-full w-[72%] rounded-full bg-gradient-to-r from-brand-from to-brand-to\" />\n      </div>\n      <div className=\"flex flex-wrap gap-1.5\">\n        {[\n          { icon: FileTextIcon, label: \"Docs\" },\n          { icon: MessageSquareIcon, label: \"Comments\" },\n          { icon: CloudIcon, label: \"Files\" },\n        ].map(({ icon: Icon, label }) => (\n          <span\n            key={label}\n            className=\"inline-flex items-center gap-1 rounded-md border bg-muted/50 px-1.5 py-0.5 text-[10px] text-muted-foreground\"\n          >\n            <Icon className=\"size-3\" />\n            {label}\n          </span>\n        ))}\n      </div>\n    </div>\n  );\n}\n\nfunction InviteVisual() {\n  return (\n    <div className=\"flex h-full flex-col justify-center gap-3\">\n      <AvatarCircles\n        people={[\"Maya Kim\", \"Jon Lee\", \"Ana Ruiz\", \"Sam Obi\"]}\n        extra={12}\n      />\n      <div className=\"flex items-center gap-2 rounded-lg border bg-background px-2.5 py-1.5 text-xs\">\n        <span className=\"truncate text-muted-foreground\">dev@northwind.io</span>\n        <span className=\"ml-auto shrink-0 rounded-md bg-primary px-2 py-0.5 text-[10px] font-medium text-primary-foreground\">\n          Invite\n        </span>\n      </div>\n    </div>\n  );\n}\n\nfunction ShipVisual() {\n  const heights = [30, 42, 36, 55, 48, 66, 60, 78, 90];\n  return (\n    <div className=\"flex h-full flex-col justify-between\">\n      <div className=\"flex items-center gap-2 text-xs\">\n        <CircleCheckIcon className=\"size-4 text-emerald-500\" />\n        <span className=\"font-medium\">v2.14 is live</span>\n        <span className=\"ml-auto text-[10px] text-muted-foreground\">just now</span>\n      </div>\n      <div className=\"flex h-16 items-end gap-1\">\n        {heights.map((v, i) => (\n          <div\n            key={i}\n            style={{ height: `${v}%` }}\n            className={cn(\n              \"flex-1 rounded-t-sm\",\n              i === heights.length - 1 ? \"bg-gradient-to-t from-brand-from to-brand-to\" : \"bg-primary/15\"\n            )}\n          />\n        ))}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/blocks/features-steps.tsx"
    }
  ],
  "categories": [
    "feature-sections"
  ],
  "type": "registry:block"
}