{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "how-it-works-3",
  "title": "Clickable Horizontal Stepper",
  "description": "Interactive how it works stepper with clickable steps along a progress line that fills to the active step, stacking vertically on mobile.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "badge"
  ],
  "files": [
    {
      "path": "registry/blocks/how-it-works/3/how-it-works-block.tsx",
      "content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { cn } from \"@/lib/utils\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\n/** Props a call site may pass through to an icon. */\ntype IconProps = { className?: string; size?: number | string }\n\nconst steps = [\n  {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"UserPlus\"\n        tabler=\"IconUserPlus\"\n        hugeicons=\"UserAddIcon\"\n        phosphor=\"UserPlus\"\n        remixicon=\"RiUserAddLine\"\n        {...p}\n      />\n    ),\n    title: \"Create your account\",\n    copy: \"Sign up in under two minutes, no card required to get started.\",\n  },\n  {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Palette\"\n        tabler=\"IconPalette\"\n        hugeicons=\"PaintBoardIcon\"\n        phosphor=\"Palette\"\n        remixicon=\"RiPaletteLine\"\n        {...p}\n      />\n    ),\n    title: \"Customize your space\",\n    copy: \"Pick a template and tune Acme to match how your team already works.\",\n  },\n  {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Users\"\n        tabler=\"IconUsersGroup\"\n        hugeicons=\"UserGroupIcon\"\n        phosphor=\"UsersThree\"\n        remixicon=\"RiTeamLine\"\n        {...p}\n      />\n    ),\n    title: \"Invite your team\",\n    copy: \"Send role-based invites in bulk and let colleagues join in one click.\",\n  },\n  {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Rocket\"\n        tabler=\"IconRocket\"\n        hugeicons=\"RocketIcon\"\n        phosphor=\"Rocket\"\n        remixicon=\"RiRocketLine\"\n        {...p}\n      />\n    ),\n    title: \"Ship with confidence\",\n    copy: \"Run automated checks and deploy knowing Acme has your back.\",\n  },\n]\n\nexport default function HowItWorksBlock() {\n  const [active, setActive] = useState(0)\n  // Fill the connector up to the centre of the active circle so the segment\n  // from the left edge is already drawn once the first step is active.\n  const progress = ((active + 0.5) / steps.length) * 100\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-muted/30 px-6 py-16 text-foreground\">\n      <div className=\"mx-auto w-full max-w-4xl\">\n        <div className=\"mb-12 text-center\">\n          <Badge variant=\"outline\" className=\"mb-4\">\n            How it works\n          </Badge>\n          <h2 className=\"font-heading text-3xl font-bold tracking-tight sm:text-4xl\">\n            Up and running in four steps\n          </h2>\n          <p className=\"mx-auto mt-3 max-w-xl text-muted-foreground\">\n            Go from sign-up to full team collaboration without a single support\n            ticket.\n          </p>\n        </div>\n\n        <ol\n          className={cn(\"relative flex flex-col gap-8\", \"md:flex-row md:gap-0\")}\n        >\n          <div\n            className=\"absolute top-0 left-[1.25rem] hidden h-full w-px bg-border md:top-5 md:left-0 md:h-px md:w-full\"\n            aria-hidden=\"true\"\n          />\n          <div\n            className=\"absolute top-0 left-[1.25rem] hidden w-px bg-primary transition-all duration-500 md:top-5 md:left-0 md:h-px md:w-auto\"\n            style={{ height: `${progress}%` }}\n            aria-hidden=\"true\"\n          />\n          <div\n            className=\"absolute top-5 left-0 hidden h-px bg-primary transition-all duration-500 md:block\"\n            style={{ width: `${progress}%` }}\n            aria-hidden=\"true\"\n          />\n\n          {steps.map(({ icon: Icon, title, copy }, index) => {\n            const isDone = index <= active\n            const isCurrent = index === active\n            return (\n              <li\n                key={title}\n                className=\"relative flex flex-1 gap-4 md:flex-col md:items-center md:gap-0 md:px-3 md:text-center\"\n              >\n                <button\n                  type=\"button\"\n                  onClick={() => setActive(index)}\n                  aria-current={isCurrent ? \"step\" : undefined}\n                  className={cn(\n                    \"z-10 flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-full border p-0 transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:outline-none\",\n                    isDone\n                      ? \"border-primary bg-primary text-primary-foreground\"\n                      : \"border-border bg-background text-muted-foreground hover:bg-muted\",\n                    isCurrent &&\n                      \"ring-2 ring-primary ring-offset-2 ring-offset-background\"\n                  )}\n                >\n                  {isDone ? (\n                    <IconPlaceholder\n                      lucide=\"Check\"\n                      tabler=\"IconCheck\"\n                      hugeicons=\"Tick02Icon\"\n                      phosphor=\"Check\"\n                      remixicon=\"RiCheckLine\"\n                      className=\"size-4\"\n                      aria-hidden=\"true\"\n                    />\n                  ) : (\n                    <Icon className=\"size-4\" aria-hidden=\"true\" />\n                  )}\n                  <span className=\"sr-only\">{title}</span>\n                </button>\n\n                <div className=\"md:mt-4\">\n                  <h3\n                    className={cn(\n                      \"mt-0.5 font-heading text-sm font-semibold transition-colors\",\n                      isCurrent || isDone\n                        ? \"text-foreground\"\n                        : \"text-muted-foreground\"\n                    )}\n                  >\n                    {title}\n                  </h3>\n                  <p className=\"mt-1.5 text-sm text-muted-foreground md:mx-auto md:max-w-[16rem]\">\n                    {copy}\n                  </p>\n                </div>\n              </li>\n            )\n          })}\n        </ol>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/how-it-works-3.tsx"
    }
  ],
  "meta": {
    "height": "444px",
    "tier": "free"
  },
  "categories": [
    "how-it-works"
  ],
  "type": "registry:block"
}