{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "project-roadmap",
  "title": "Project Roadmap",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/project-roadmap/ProjectRoadmap.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Plus, Search, Download, Filter } from 'lucide-vue-next'\nimport { Button } from '@/components/ui/button'\nimport { Input, InputGroup, InputGroupAddon } from '@/components/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n  Gantt,\n  GanttHeader,\n  GanttTree,\n  GanttTimeline,\n  GanttContextMenu,\n  type GanttTask,\n  type GanttScale,\n  type GanttTaskStatus,\n  type GanttTaskPriority,\n} from '@/components/ui/gantt'\nimport RoadmapMetrics from './RoadmapMetrics.vue'\nimport RoadmapTaskDetail from './RoadmapTaskDetail.vue'\nimport RoadmapAddTaskDialog from './RoadmapAddTaskDialog.vue'\n\ninterface Props {\n  initialTasks?: GanttTask[]\n  title?: string\n  description?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  title: 'Engineering Q3 Deliverables',\n  description: 'Track roadmap work breakdown, sprint milestones, and cross-team dependencies.',\n  initialTasks: () => [\n    {\n      id: 'task-1',\n      name: 'System Architecture & Database Schema',\n      startDate: '2026-08-01',\n      endDate: '2026-08-08',\n      progress: 100,\n      status: 'done',\n      priority: 'high',\n      assignee: { name: 'Sarah Connor', initials: 'SC' },\n    },\n    {\n      id: 'task-2',\n      name: 'Auth, RBAC & Multi-Tenant Session Engine',\n      startDate: '2026-08-06',\n      endDate: '2026-08-16',\n      progress: 85,\n      status: 'in-progress',\n      priority: 'urgent',\n      assignee: { name: 'Marcus Rivera', initials: 'MR' },\n    },\n    {\n      id: 'task-3',\n      name: 'Real-time WebSocket Notification Bus',\n      startDate: '2026-08-12',\n      endDate: '2026-08-22',\n      progress: 50,\n      status: 'in-progress',\n      priority: 'high',\n      assignee: { name: 'Priya Nair', initials: 'PN' },\n    },\n    {\n      id: 'task-4',\n      name: 'Alpha Core API Release Milestone',\n      startDate: '2026-08-23',\n      endDate: '2026-08-23',\n      isMilestone: true,\n      status: 'todo',\n      priority: 'urgent',\n    },\n    {\n      id: 'task-5',\n      name: 'Stripe Billing & Invoicing Integration',\n      startDate: '2026-08-24',\n      endDate: '2026-09-04',\n      progress: 15,\n      status: 'todo',\n      priority: 'medium',\n      assignee: { name: 'Sundar Krishnan', initials: 'SK' },\n    },\n    {\n      id: 'task-6',\n      name: 'End-to-End Playwright Automated Testing',\n      startDate: '2026-08-28',\n      endDate: '2026-09-08',\n      progress: 0,\n      status: 'todo',\n      priority: 'low',\n      assignee: { name: 'Diane Cho', initials: 'DC' },\n    },\n    {\n      id: 'task-7',\n      name: 'Production Cloudflare Pages Deployment',\n      startDate: '2026-09-10',\n      endDate: '2026-09-10',\n      isMilestone: true,\n      status: 'todo',\n    },\n  ],\n})\n\nconst tasks = ref<GanttTask[]>([...props.initialTasks])\nconst searchQuery = ref('')\nconst statusFilter = ref('all')\nconst assigneeFilter = ref('all')\nconst scale = ref<GanttScale>('day')\n\nconst selectedTask = ref<GanttTask | null>(null)\nconst sheetOpen = ref(false)\nconst addDialogOpen = ref(false)\n\nconst filteredTasks = computed(() => {\n  return tasks.value.filter((t) => {\n    const matchesSearch = !searchQuery.value || t.name.toLowerCase().includes(searchQuery.value.toLowerCase())\n    const matchesStatus = statusFilter.value === 'all' || t.status === statusFilter.value\n    const matchesAssignee = assigneeFilter.value === 'all' || t.assignee?.name === assigneeFilter.value\n    return matchesSearch && matchesStatus && matchesAssignee\n  })\n})\n\nfunction handleTaskClick(task: GanttTask) {\n  selectedTask.value = task\n  sheetOpen.value = true\n}\n\nfunction handleAddTask(newTask: GanttTask) {\n  tasks.value.push(newTask)\n}\n\nfunction handleStatusChange(task: GanttTask, status: GanttTaskStatus) {\n  const target = tasks.value.find((t) => t.id === task.id)\n  if (target) {\n    target.status = status\n    if (status === 'done') target.progress = 100\n  }\n}\n\nfunction handlePriorityChange(task: GanttTask, priority: GanttTaskPriority) {\n  const target = tasks.value.find((t) => t.id === task.id)\n  if (target) target.priority = priority\n}\n\nfunction handleDuplicate(task: GanttTask) {\n  const cloned: GanttTask = {\n    ...task,\n    id: `task-${Date.now()}`,\n    name: `${task.name} (Copy)`,\n  }\n  tasks.value.push(cloned)\n}\n\nfunction handleDelete(task: GanttTask) {\n  tasks.value = tasks.value.filter((t) => t.id !== task.id)\n}\n</script>\n\n<template>\n  <div data-uipkge data-slot=\"project-roadmap\" class=\"space-y-6\">\n    <!-- Section Top Header -->\n    <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n      <div>\n        <h2 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">{{ title }}</h2>\n        <p class=\"text-muted-foreground mt-0.5 text-sm\">{{ description }}</p>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <Button variant=\"outline\" size=\"sm\">\n          <Download class=\"mr-1 size-3.5\" />\n          Export\n        </Button>\n        <Button size=\"sm\" @click=\"addDialogOpen = true\">\n          <Plus class=\"mr-1 size-3.5\" />\n          Add Task\n        </Button>\n      </div>\n    </div>\n\n    <!-- Summary Metrics -->\n    <RoadmapMetrics :tasks=\"tasks\" />\n\n    <!-- Filters & Action Bar -->\n    <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n      <div class=\"flex max-w-lg flex-1 flex-wrap items-center gap-2\">\n        <InputGroup size=\"small\" class=\"w-56\">\n          <InputGroupAddon>\n            <Search class=\"size-3.5\" />\n          </InputGroupAddon>\n          <Input v-model=\"searchQuery\" placeholder=\"Filter tasks by name...\" />\n        </InputGroup>\n\n        <Select v-model=\"statusFilter\">\n          <SelectTrigger class=\"h-8 w-32 text-xs\">\n            <SelectValue placeholder=\"All Status\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All Status</SelectItem>\n            <SelectItem value=\"done\">Completed</SelectItem>\n            <SelectItem value=\"in-progress\">In Progress</SelectItem>\n            <SelectItem value=\"todo\">To Do</SelectItem>\n          </SelectContent>\n        </Select>\n\n        <Select v-model=\"assigneeFilter\">\n          <SelectTrigger class=\"h-8 w-36 text-xs\">\n            <SelectValue placeholder=\"All Assignees\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All Assignees</SelectItem>\n            <SelectItem value=\"Sarah Connor\">Sarah Connor</SelectItem>\n            <SelectItem value=\"Marcus Rivera\">Marcus Rivera</SelectItem>\n            <SelectItem value=\"Priya Nair\">Priya Nair</SelectItem>\n            <SelectItem value=\"Sundar Krishnan\">Sundar Krishnan</SelectItem>\n            <SelectItem value=\"Diane Cho\">Diane Cho</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n\n      <p class=\"text-muted-foreground font-mono text-xs\">\n        Showing <span class=\"text-foreground font-bold\">{{ filteredTasks.length }}</span> of\n        {{ tasks.length }} deliverables\n        <span class=\"text-muted-foreground/60 ml-2\">(Right-click task for quick actions)</span>\n      </p>\n    </div>\n\n    <!-- Main Interactive Gantt Workspace with Right-Click Context Actions -->\n    <Gantt :tasks=\"filteredTasks\" :scale=\"scale\" class=\"h-[480px]\">\n      <GanttHeader :title=\"title\" />\n      <div class=\"flex min-h-0 flex-1 overflow-hidden\">\n        <GanttTree @click=\"handleTaskClick\" />\n        <GanttTimeline @task-click=\"handleTaskClick\" />\n      </div>\n    </Gantt>\n\n    <!-- Task Detail Drawer -->\n    <RoadmapTaskDetail v-model:open=\"sheetOpen\" :task=\"selectedTask\" />\n\n    <!-- Add Task Modal Dialog -->\n    <RoadmapAddTaskDialog v-model:open=\"addDialogOpen\" @add-task=\"handleAddTask\" />\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/ProjectRoadmap.vue"
    },
    {
      "path": "packages/registry-vue/blocks/project-roadmap/RoadmapMetrics.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { CheckCircle2, Clock, AlertCircle, Milestone } from 'lucide-vue-next'\nimport { Card, CardContent } from '@/components/ui/card'\nimport type { GanttTask } from '@/components/ui/gantt'\n\nconst props = defineProps<{\n  tasks: GanttTask[]\n}>()\n\nconst total = computed(() => props.tasks.length)\nconst completed = computed(() => props.tasks.filter((t) => t.status === 'done').length)\nconst inProgress = computed(() => props.tasks.filter((t) => t.status === 'in-progress').length)\nconst milestones = computed(() => props.tasks.filter((t) => t.isMilestone).length)\nconst progress = computed(() => {\n  if (total.value === 0) return 0\n  const sum = props.tasks.reduce((acc, t) => acc + (t.progress ?? 0), 0)\n  return Math.round(sum / total.value)\n})\n</script>\n\n<template>\n  <div data-slot=\"roadmap-metrics\" class=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n    <Card class=\"bg-card/50 border-border/80 shadow-none\">\n      <CardContent class=\"flex items-center justify-between p-3.5\">\n        <div>\n          <p class=\"text-muted-foreground text-xs font-medium\">Overall Progress</p>\n          <p class=\"text-foreground mt-0.5 font-mono text-xl font-bold\">{{ progress }}%</p>\n        </div>\n        <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-full\">\n          <Clock class=\"size-4\" />\n        </div>\n      </CardContent>\n    </Card>\n\n    <Card class=\"bg-card/50 border-border/80 shadow-none\">\n      <CardContent class=\"flex items-center justify-between p-3.5\">\n        <div>\n          <p class=\"text-muted-foreground text-xs font-medium\">In Progress</p>\n          <p class=\"text-foreground mt-0.5 font-mono text-xl font-bold\">{{ inProgress }}</p>\n        </div>\n        <div class=\"flex size-8 items-center justify-center rounded-full bg-blue-500/10 text-blue-500\">\n          <AlertCircle class=\"size-4\" />\n        </div>\n      </CardContent>\n    </Card>\n\n    <Card class=\"bg-card/50 border-border/80 shadow-none\">\n      <CardContent class=\"flex items-center justify-between p-3.5\">\n        <div>\n          <p class=\"text-muted-foreground text-xs font-medium\">Completed</p>\n          <p class=\"text-foreground mt-0.5 font-mono text-xl font-bold\">{{ completed }}</p>\n        </div>\n        <div class=\"flex size-8 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-500\">\n          <CheckCircle2 class=\"size-4\" />\n        </div>\n      </CardContent>\n    </Card>\n\n    <Card class=\"bg-card/50 border-border/80 shadow-none\">\n      <CardContent class=\"flex items-center justify-between p-3.5\">\n        <div>\n          <p class=\"text-muted-foreground text-xs font-medium\">Milestones</p>\n          <p class=\"text-foreground mt-0.5 font-mono text-xl font-bold\">{{ milestones }}</p>\n        </div>\n        <div class=\"flex size-8 items-center justify-center rounded-full bg-amber-500/10 text-amber-500\">\n          <Milestone class=\"size-4\" />\n        </div>\n      </CardContent>\n    </Card>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/RoadmapMetrics.vue"
    },
    {
      "path": "packages/registry-vue/blocks/project-roadmap/RoadmapTaskDetail.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Calendar, User, CheckCircle2, Clock, X, Tag } from 'lucide-vue-next'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '@/components/ui/sheet'\nimport type { GanttTask } from '@/components/ui/gantt'\n\nconst props = defineProps<{\n  task: GanttTask | null\n  open: boolean\n}>()\n\nconst emits = defineEmits<{\n  (e: 'update:open', val: boolean): void\n}>()\n\nconst statusBadge = computed(() => {\n  if (!props.task?.status) return { label: 'Active', variant: 'secondary' as const }\n  switch (props.task.status) {\n    case 'done':\n      return { label: 'Completed', variant: 'outline' as const, class: 'text-emerald-600 border-emerald-500/30' }\n    case 'in-progress':\n      return { label: 'In Progress', variant: 'default' as const }\n    case 'blocked':\n      return { label: 'Blocked', variant: 'destructive' as const }\n    default:\n      return { label: 'To Do', variant: 'secondary' as const }\n  }\n})\n</script>\n\n<template>\n  <Sheet :open=\"open\" @update:open=\"$emit('update:open', $event)\">\n    <SheetContent v-if=\"task\" class=\"sm:max-w-md\">\n      <SheetHeader class=\"border-border space-y-2 border-b pb-4\">\n        <div class=\"flex items-center gap-2\">\n          <Badge :variant=\"statusBadge.variant\" :class=\"statusBadge.class\">\n            {{ statusBadge.label }}\n          </Badge>\n          <Badge v-if=\"task.isMilestone\" variant=\"outline\" class=\"border-amber-500/30 text-amber-500\">\n            Milestone\n          </Badge>\n        </div>\n        <SheetTitle class=\"text-foreground text-lg font-semibold\">\n          {{ task.name }}\n        </SheetTitle>\n        <SheetDescription class=\"text-muted-foreground text-xs\">\n          Task ID: <span class=\"font-mono\">{{ task.id }}</span>\n        </SheetDescription>\n      </SheetHeader>\n\n      <div class=\"space-y-5 py-5 text-sm\">\n        <!-- Date Schedule -->\n        <div class=\"space-y-1.5\">\n          <span class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Schedule</span>\n          <div class=\"text-foreground flex items-center gap-2 font-mono text-xs\">\n            <Calendar class=\"text-muted-foreground size-4\" />\n            <span>{{ task.startDate }}</span>\n            <span>&rarr;</span>\n            <span>{{ task.endDate }}</span>\n          </div>\n        </div>\n\n        <!-- Progress -->\n        <div v-if=\"task.progress != null\" class=\"space-y-1.5\">\n          <div class=\"flex items-center justify-between text-xs\">\n            <span class=\"text-muted-foreground font-medium tracking-wider uppercase\">Completion</span>\n            <span class=\"font-mono font-bold\">{{ task.progress }}%</span>\n          </div>\n          <div class=\"bg-muted h-2 w-full overflow-hidden rounded-full\">\n            <div\n              :style=\"{ width: `${task.progress}%` }\"\n              class=\"bg-primary h-full rounded-full transition-all duration-300\"\n            />\n          </div>\n        </div>\n\n        <!-- Assignee -->\n        <div v-if=\"task.assignee\" class=\"space-y-1.5\">\n          <span class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Owner</span>\n          <div class=\"flex items-center gap-2.5\">\n            <div\n              class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-full text-xs font-medium\"\n            >\n              {{ task.assignee.initials || task.assignee.name.charAt(0) }}\n            </div>\n            <span class=\"text-foreground text-sm font-medium\">{{ task.assignee.name }}</span>\n          </div>\n        </div>\n      </div>\n    </SheetContent>\n  </Sheet>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/RoadmapTaskDetail.vue"
    },
    {
      "path": "packages/registry-vue/blocks/project-roadmap/RoadmapAddTaskDialog.vue",
      "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Plus, Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport type { GanttTask } from '@/components/ui/gantt'\n\nconst props = defineProps<{\n  open: boolean\n}>()\n\nconst emits = defineEmits<{\n  (e: 'update:open', val: boolean): void\n  (e: 'add-task', task: GanttTask): void\n}>()\n\nconst name = ref('')\nconst startDate = ref('2026-08-20')\nconst endDate = ref('2026-08-28')\nconst status = ref<'todo' | 'in-progress' | 'done'>('todo')\nconst progress = ref(0)\nconst isMilestone = ref(false)\nconst assigneeName = ref('Marcus Rivera')\n\nfunction handleSubmit() {\n  if (!name.value.trim()) return\n\n  const newTask: GanttTask = {\n    id: `task-${Date.now()}`,\n    name: name.value.trim(),\n    startDate: startDate.value,\n    endDate: isMilestone.value ? startDate.value : endDate.value,\n    status: status.value,\n    progress: isMilestone.value ? 100 : Number(progress.value) || 0,\n    isMilestone: isMilestone.value,\n    assignee: {\n      name: assigneeName.value,\n      initials: assigneeName.value\n        .split(' ')\n        .map((p) => p[0])\n        .join(''),\n    },\n  }\n\n  emits('add-task', newTask)\n  emits('update:open', false)\n\n  // Reset form\n  name.value = ''\n  progress.value = 0\n  isMilestone.value = false\n}\n</script>\n\n<template>\n  <Dialog :open=\"open\" @update:open=\"$emit('update:open', $event)\">\n    <DialogContent class=\"sm:max-w-[480px]\">\n      <DialogHeader>\n        <DialogTitle>Add Roadmap Task</DialogTitle>\n        <DialogDescription>\n          Create a new scheduled deliverable or critical milestone in the project Gantt timeline.\n        </DialogDescription>\n      </DialogHeader>\n\n      <form @submit.prevent=\"handleSubmit\" class=\"space-y-4 py-2\">\n        <!-- Task Name -->\n        <div class=\"space-y-1.5\">\n          <Label for=\"task-name\">Task Name</Label>\n          <Input id=\"task-name\" v-model=\"name\" placeholder=\"e.g. Design Token Hierarchy & Specs\" required />\n        </div>\n\n        <!-- Date Range -->\n        <div class=\"grid grid-cols-2 gap-3\">\n          <div class=\"space-y-1.5\">\n            <Label for=\"start-date\">Start Date</Label>\n            <Input id=\"start-date\" v-model=\"startDate\" type=\"date\" required />\n          </div>\n          <div class=\"space-y-1.5\">\n            <Label for=\"end-date\">End Date</Label>\n            <Input id=\"end-date\" v-model=\"endDate\" type=\"date\" :disabled=\"isMilestone\" required />\n          </div>\n        </div>\n\n        <!-- Milestone toggle -->\n        <div class=\"border-border/80 bg-muted/20 flex items-center space-x-2 rounded-md border p-3\">\n          <Checkbox id=\"milestone-toggle\" v-model:checked=\"isMilestone\" />\n          <div class=\"grid gap-0.5 leading-none\">\n            <label for=\"milestone-toggle\" class=\"text-foreground cursor-pointer text-xs font-semibold select-none\">\n              Key Project Milestone\n            </label>\n            <p class=\"text-muted-foreground text-[11px]\">\n              Marks a zero-duration target deliverable (e.g. Beta Release, Audit sign-off)\n            </p>\n          </div>\n        </div>\n\n        <!-- Status & Assignee -->\n        <div class=\"grid grid-cols-2 gap-3\">\n          <div class=\"space-y-1.5\">\n            <Label>Initial Status</Label>\n            <Select v-model=\"status\">\n              <SelectTrigger>\n                <SelectValue placeholder=\"Status\" />\n              </SelectTrigger>\n              <SelectContent>\n                <SelectItem value=\"todo\">To Do</SelectItem>\n                <SelectItem value=\"in-progress\">In Progress</SelectItem>\n                <SelectItem value=\"done\">Completed</SelectItem>\n              </SelectContent>\n            </Select>\n          </div>\n\n          <div class=\"space-y-1.5\">\n            <Label>Assignee</Label>\n            <Select v-model=\"assigneeName\">\n              <SelectTrigger>\n                <SelectValue placeholder=\"Assignee\" />\n              </SelectTrigger>\n              <SelectContent>\n                <SelectItem value=\"Marcus Rivera\">Marcus Rivera</SelectItem>\n                <SelectItem value=\"Sarah Connor\">Sarah Connor</SelectItem>\n                <SelectItem value=\"Priya Nair\">Priya Nair</SelectItem>\n                <SelectItem value=\"Sundar Krishnan\">Sundar Krishnan</SelectItem>\n                <SelectItem value=\"Diane Cho\">Diane Cho</SelectItem>\n              </SelectContent>\n            </Select>\n          </div>\n        </div>\n\n        <DialogFooter class=\"pt-4\">\n          <Button variant=\"outline\" type=\"button\" @click=\"$emit('update:open', false)\"> Cancel </Button>\n          <Button type=\"submit\">\n            <Plus class=\"mr-1.5 size-3.5\" />\n            Create Task\n          </Button>\n        </DialogFooter>\n      </form>\n    </DialogContent>\n  </Dialog>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/RoadmapAddTaskDialog.vue"
    },
    {
      "path": "packages/registry-vue/blocks/project-roadmap/types.ts",
      "content": "import type { GanttTask } from '@/components/ui/gantt'\n\nexport interface RoadmapProject {\n  id: string\n  name: string\n  description?: string\n  tasks: GanttTask[]\n}\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/types.ts"
    },
    {
      "path": "packages/registry-vue/blocks/project-roadmap/index.ts",
      "content": "export { default as ProjectRoadmap } from './ProjectRoadmap.vue'\nexport { default as RoadmapMetrics } from './RoadmapMetrics.vue'\nexport { default as RoadmapTaskDetail } from './RoadmapTaskDetail.vue'\nexport { default as RoadmapAddTaskDialog } from './RoadmapAddTaskDialog.vue'\nexport * from './types'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/project-roadmap/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/gantt.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/select.json",
    "https://uipkge.dev/r/vue/dialog.json",
    "https://uipkge.dev/r/vue/sheet.json",
    "https://uipkge.dev/r/vue/checkbox.json",
    "https://uipkge.dev/r/vue/label.json"
  ],
  "description": "Full interactive project roadmap and deliverables surface: Gantt timeline with multi-scale zooming, work breakdown task tree, overall progress metrics, search and status/assignee filters, task detail slide-over Sheet, and Add Task modal dialog.",
  "categories": [
    "dashboard",
    "data"
  ]
}