{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "product-tour",
  "type": "registry:component",
  "title": "Product tour",
  "description": "A React product tour with a clickable list of steps beside a detail panel that fades in for the active step, plus back and next buttons that stop at the ends.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "https://ui.minidev.pro/r/button.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/product-tour.tsx",
      "type": "registry:ui",
      "target": "components/ui/product-tour.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\n/** ProductTour — a step list beside a stage that fades to the selected step, with Back and Next. */\n\ntype TourStep = { title: string; body: string }\n\n// Onboarding steps for a new Lumen workspace.\nconst SAMPLE_STEPS: TourStep[] = [\n  { title: \"Connect your bank\", body: \"Link Northwind's accounts once. Transactions sync every hour and match to invoices automatically.\" },\n  { title: \"Send your first invoice\", body: \"Pick a customer, add line items and Lumen handles the numbering, tax and reminders.\" },\n  { title: \"Invite the team\", body: \"Add Maya, Theo and Priya with roles, so approvals and payouts never wait on one person.\" },\n  { title: \"Close the month\", body: \"Reconcile in one pass, export to your ledger and lock the period.\" },\n]\n\ntype ProductTourProps = {\n  steps?: TourStep[]\n  className?: string\n}\n\nfunction ProductTour({\n  steps = SAMPLE_STEPS,\n  className,\n}: ProductTourProps) {\n  const reduce = useReducedMotion()\n  const [active, setActive] = React.useState(0)\n  return (\n    <div data-slot=\"product-tour\" data-tier=\"premium\" className={cn(\"grid gap-6 rounded-2xl border border-border bg-surface p-6 lg:grid-cols-2\", className)}>\n      <div className=\"space-y-2\">\n        {steps.map((s, i) => (\n          <button\n            key={s.title}\n            type=\"button\"\n            aria-current={i === active ? \"step\" : undefined}\n            onClick={() => setActive(i)}\n            className={cn(\n              \"w-full rounded-xl border px-4 py-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-accent\",\n              i === active ? \"border-accent/40 bg-accent/5\" : \"border-border hover:border-fg-subtle\"\n            )}\n          >\n            <p className=\"text-sm font-medium text-fg\">{s.title}</p>\n            <p className=\"mt-1 text-xs text-fg-muted\">{s.body}</p>\n          </button>\n        ))}\n      </div>\n      <motion.div\n        key={active}\n        initial={reduce ? false : { opacity: 0, y: 8 }}\n        animate={{ opacity: 1, y: 0 }}\n        className=\"flex min-h-64 flex-col justify-between rounded-xl border border-border bg-sunken p-6\"\n      >\n        <div>\n          <p className=\"text-xs text-fg-muted\">Step {active + 1}/{steps.length}</p>\n          <h3 className=\"mt-2 text-xl font-medium tracking-[-0.014em] text-fg\">{steps[active]?.title}</h3>\n          <p className=\"mt-2 text-sm text-fg-muted\">{steps[active]?.body}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button variant=\"outline\" size=\"sm\" disabled={active === 0} onClick={() => setActive((a) => Math.max(0, a - 1))}>Back</Button>\n          <Button size=\"sm\" disabled={active === steps.length - 1} onClick={() => setActive((a) => Math.min(steps.length - 1, a + 1))}>Next</Button>\n        </div>\n      </motion.div>\n    </div>\n  )\n}\nexport { ProductTour }\nexport type { ProductTourProps, TourStep }\n"
    }
  ]
}
