{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "roadmap-4",
  "title": "Quarterly Roadmap Columns",
  "description": "Product roadmap laid out as four quarterly columns of feature cards, each with a category and a color coded shipped, in progress, or planned status.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "badge"
  ],
  "files": [
    {
      "path": "registry/blocks/roadmap/4/roadmap-block.tsx",
      "content": "import { Badge } from \"@/components/ui/badge\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\nimport type * as React from \"react\"\n\n/** Props a call site may pass through to an icon. */\ntype IconProps = { className?: string; size?: number | string }\n\n/** An icon held in data and rendered later, e.g. `<item.icon className=\"size-4\" />`. */\ntype IconRenderer = (props: IconProps) => React.ReactNode\n\ntype Status = \"Shipped\" | \"In Progress\" | \"Planned\"\n\ntype Item = {\n  title: string\n  description: string\n  category: string\n  status: Status\n}\n\ntype Quarter = {\n  label: string\n  period: string\n  items: Item[]\n}\n\nconst statusMeta: Record<Status, { icon: IconRenderer; className: string }> = {\n  Shipped: {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Check\"\n        tabler=\"IconCheck\"\n        hugeicons=\"Tick02Icon\"\n        phosphor=\"Check\"\n        remixicon=\"RiCheckLine\"\n        {...p}\n      />\n    ),\n    className: \"text-success\",\n  },\n  \"In Progress\": {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"LoaderCircle\"\n        tabler=\"IconLoader2\"\n        hugeicons=\"Loading03Icon\"\n        phosphor=\"Spinner\"\n        remixicon=\"RiLoader4Line\"\n        {...p}\n      />\n    ),\n    className: \"text-warning\",\n  },\n  Planned: {\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Clock\"\n        tabler=\"IconClock\"\n        hugeicons=\"TimeIcon\"\n        phosphor=\"Clock\"\n        remixicon=\"RiTimeLine\"\n        {...p}\n      />\n    ),\n    className: \"text-muted-foreground\",\n  },\n}\n\nconst quarters: Quarter[] = [\n  {\n    label: \"Q1\",\n    period: \"Jan – Mar\",\n    items: [\n      {\n        title: \"Saved Views\",\n        description: \"Pin filtered lists to the sidebar and share them.\",\n        category: \"Core\",\n        status: \"Shipped\",\n      },\n      {\n        title: \"Dark Theme\",\n        description: \"A full dark palette that follows the system setting.\",\n        category: \"Design\",\n        status: \"Shipped\",\n      },\n    ],\n  },\n  {\n    label: \"Q2\",\n    period: \"Apr – Jun\",\n    items: [\n      {\n        title: \"Audit Log\",\n        description: \"An exportable record of every workspace action.\",\n        category: \"Security\",\n        status: \"Shipped\",\n      },\n      {\n        title: \"Team Roles\",\n        description: \"Granular owner, editor, and viewer permissions.\",\n        category: \"Core\",\n        status: \"Shipped\",\n      },\n    ],\n  },\n  {\n    label: \"Q3\",\n    period: \"Jul – Sep\",\n    items: [\n      {\n        title: \"Public API v2\",\n        description: \"A faster REST API with typed SDKs and webhooks.\",\n        category: \"Platform\",\n        status: \"In Progress\",\n      },\n      {\n        title: \"Mobile App\",\n        description: \"Native iOS and Android apps for on-the-go access.\",\n        category: \"Apps\",\n        status: \"In Progress\",\n      },\n      {\n        title: \"Slack Integration\",\n        description: \"Post updates and create items straight from Slack.\",\n        category: \"Integrations\",\n        status: \"Planned\",\n      },\n    ],\n  },\n  {\n    label: \"Q4\",\n    period: \"Oct – Dec\",\n    items: [\n      {\n        title: \"Custom Dashboards\",\n        description: \"Build your own views from any metric in the workspace.\",\n        category: \"Analytics\",\n        status: \"Planned\",\n      },\n      {\n        title: \"SSO and SCIM\",\n        description: \"Enterprise sign-on with automated user provisioning.\",\n        category: \"Security\",\n        status: \"Planned\",\n      },\n    ],\n  },\n]\n\nfunction RoadmapItem({ item }: { item: Item }) {\n  const meta = statusMeta[item.status]\n  return (\n    <div className=\"flex flex-col gap-2 rounded-lg border border-border bg-background p-3.5\">\n      <div className=\"flex items-center justify-between gap-2\">\n        <Badge>{item.category}</Badge>\n        <meta.icon\n          className={\"size-4 shrink-0 \" + meta.className}\n          aria-hidden=\"true\"\n        />\n      </div>\n      <p className=\"text-sm font-medium text-pretty\">{item.title}</p>\n      <p className=\"text-xs text-pretty text-muted-foreground\">\n        {item.description}\n      </p>\n      <span className={\"mt-0.5 text-xs font-medium \" + meta.className}>\n        {item.status}\n      </span>\n    </div>\n  )\n}\n\nfunction QuarterColumn({ quarter }: { quarter: Quarter }) {\n  return (\n    <div className=\"flex min-w-64 flex-1 flex-col gap-3 sm:min-w-0\">\n      <div className=\"border-b border-border pb-3\">\n        <h3 className=\"font-heading text-sm font-semibold\">\n          {quarter.label} 2026\n        </h3>\n        <p className=\"text-xs text-muted-foreground\">{quarter.period}</p>\n      </div>\n      <div className=\"flex flex-col gap-3\">\n        {quarter.items.map((item) => (\n          <RoadmapItem key={item.title} item={item} />\n        ))}\n      </div>\n    </div>\n  )\n}\n\nexport default function RoadmapBlock() {\n  return (\n    <section className=\"flex min-h-svh w-full justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"w-full max-w-5xl\">\n        <div className=\"mb-8 flex flex-col items-start\">\n          <Badge variant=\"secondary\">Roadmap</Badge>\n          <h2 className=\"mt-4 font-heading text-2xl font-bold tracking-tight text-balance sm:text-3xl\">\n            What We Are Building In 2026\n          </h2>\n          <p className=\"mt-2 text-pretty text-muted-foreground\">\n            A quarter-by-quarter look at what has shipped and what is coming\n            next.\n          </p>\n        </div>\n        <div className=\"flex gap-4 overflow-x-auto pb-2 sm:grid sm:grid-cols-2 sm:overflow-visible lg:grid-cols-4\">\n          {quarters.map((quarter) => (\n            <QuarterColumn key={quarter.label} quarter={quarter} />\n          ))}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/roadmap-4.tsx"
    }
  ],
  "cssVars": {
    "light": {
      "success": "oklch(0.432 0.095 166.913)",
      "warning": "oklch(0.473 0.137 46.201)"
    },
    "dark": {
      "success": "oklch(0.765 0.177 163.223)",
      "warning": "oklch(0.828 0.189 84.429)"
    }
  },
  "meta": {
    "height": "797px",
    "tier": "free"
  },
  "categories": [
    "roadmap"
  ],
  "type": "registry:block"
}