{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "app-shell-2",
  "description": "A sidebar-free app shell with a sticky top bar (logo, search, avatar dropdown) above a tabbed content area featuring project cards, a task checklist, and an activity feed.",
  "dependencies": [
    "@remixicon/react",
    "@base-ui/react"
  ],
  "registryDependencies": [
    "avatar",
    "badge",
    "button",
    "card",
    "command",
    "dropdown-menu",
    "kbd",
    "progress",
    "separator",
    "tabs"
  ],
  "files": [
    {
      "path": "registry/blocks/app-shell/2/app-shell-block.tsx",
      "content": "\"use client\"\n\nimport React from \"react\"\nimport {\n  RiSearchLine,\n  RiAddLine,\n  RiMoreLine,\n  RiCheckboxCircleLine,\n  RiTimeLine,\n  RiArrowRightLine,\n  RiUser3Line,\n  RiGitMergeLine,\n  RiChat1Line,\n  RiCloseCircleLine,\n  RiGitPullRequestLine,\n  RiTaskLine,\n  RiDeleteBinLine,\n} from \"@remixicon/react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport { Card, CardContent, CardFooter, CardHeader } from \"@/components/ui/card\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ui/command\"\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\"\nimport {\n  Progress,\n  ProgressLabel,\n  ProgressValue,\n} from \"@/components/ui/progress\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\nconst members: Record<string, { name: string; avatar: string }> = {\n  KS: { name: \"Kenji Sato\", avatar: \"https://i.pravatar.cc/150?img=11\" },\n  LM: { name: \"Layla Mori\", avatar: \"https://i.pravatar.cc/150?img=23\" },\n  TP: { name: \"Tariq Patel\", avatar: \"https://i.pravatar.cc/150?img=14\" },\n  RM: { name: \"Roma Müller\", avatar: \"https://i.pravatar.cc/150?img=32\" },\n  SJ: { name: \"Sofia Jiménez\", avatar: \"https://i.pravatar.cc/150?img=44\" },\n  NW: { name: \"Noa Weiss\", avatar: \"https://i.pravatar.cc/150?img=5\" },\n  AL: { name: \"André Lefèvre\", avatar: \"https://i.pravatar.cc/150?img=68\" },\n  CB: { name: \"Chloe Byrne\", avatar: \"https://i.pravatar.cc/150?img=47\" },\n}\n\nconst projects = [\n  {\n    name: \"Website Redesign\",\n    description: \"Revamp the public-facing marketing site and docs hub.\",\n    status: \"In Progress\",\n    dueDate: \"Jun 30\",\n    progress: 68,\n    memberKeys: [\"KS\", \"LM\", \"TP\"],\n    image:\n      \"https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=80\",\n    imageAlt: \"Analytics dashboard on a laptop screen\",\n  },\n  {\n    name: \"Mobile App v2\",\n    description: \"Next major release with offline sync and push notifications.\",\n    status: \"Planning\",\n    dueDate: \"Jul 15\",\n    progress: 24,\n    memberKeys: [\"RM\", \"SJ\"],\n    image:\n      \"https://images.unsplash.com/photo-1667372393119-3d4c48d07fc9?w=800&q=80\",\n    imageAlt: \"Source code on a dark editor screen\",\n  },\n  {\n    name: \"API Gateway\",\n    description: \"Unified gateway layer across all internal microservices.\",\n    status: \"Review\",\n    dueDate: \"Jun 22\",\n    progress: 91,\n    memberKeys: [\"NW\", \"AL\", \"CB\"],\n    image:\n      \"https://images.unsplash.com/photo-1558494949-ef010cbdcc31?w=800&q=80\",\n    imageAlt: \"Server racks in a data center\",\n  },\n]\n\nconst tasks = [\n  {\n    title: \"Finalize design tokens\",\n    assigneeKey: \"KS\",\n    priority: \"High\",\n    done: false,\n  },\n  {\n    title: \"Write integration tests\",\n    assigneeKey: \"RM\",\n    priority: \"Medium\",\n    done: false,\n  },\n  {\n    title: \"Deploy staging environment\",\n    assigneeKey: \"LM\",\n    priority: \"High\",\n    done: true,\n  },\n  {\n    title: \"Update API documentation\",\n    assigneeKey: \"NW\",\n    priority: \"Low\",\n    done: false,\n  },\n  {\n    title: \"Accessibility audit\",\n    assigneeKey: \"TP\",\n    priority: \"Medium\",\n    done: true,\n  },\n]\n\nconst activity = [\n  {\n    actorKey: \"KS\",\n    action: \"merged\",\n    target: \"#241 Add dark mode support\",\n    time: \"2 Min Ago\",\n    icon: \"merge\",\n  },\n  {\n    actorKey: \"LM\",\n    action: \"commented on\",\n    target: \"Website Redesign milestone\",\n    time: \"18 Min Ago\",\n    icon: \"comment\",\n  },\n  {\n    actorKey: \"RM\",\n    action: \"closed issue\",\n    target: \"#198 Button focus ring\",\n    time: \"1 Hour Ago\",\n    icon: \"close\",\n  },\n  {\n    actorKey: \"TP\",\n    action: \"opened pull request\",\n    target: \"#242 Tabs refactor\",\n    time: \"3 Hours Ago\",\n    icon: \"pr\",\n  },\n  {\n    actorKey: \"NW\",\n    action: \"created task\",\n    target: \"Update API documentation\",\n    time: \"5 Hours Ago\",\n    icon: \"task\",\n  },\n]\n\nconst statusConfig: Record<\n  string,\n  { variant: \"default\" | \"secondary\" | \"outline\"; dot: string }\n> = {\n  \"In Progress\": { variant: \"default\", dot: \"bg-primary-foreground\" },\n  Planning: { variant: \"outline\", dot: \"bg-muted-foreground\" },\n  Review: { variant: \"secondary\", dot: \"bg-foreground\" },\n}\n\nconst priorityConfig: Record<\n  string,\n  { variant: \"default\" | \"secondary\" | \"outline\" | \"destructive\" }\n> = {\n  High: { variant: \"destructive\" },\n  Medium: { variant: \"secondary\" },\n  Low: { variant: \"outline\" },\n}\n\nconst activityIcon: Record<string, React.ReactNode> = {\n  merge: <RiGitMergeLine className=\"size-3.5\" aria-hidden=\"true\" />,\n  comment: <RiChat1Line className=\"size-3.5\" aria-hidden=\"true\" />,\n  close: <RiCloseCircleLine className=\"size-3.5\" aria-hidden=\"true\" />,\n  pr: <RiGitPullRequestLine className=\"size-3.5\" aria-hidden=\"true\" />,\n  task: <RiTaskLine className=\"size-3.5\" aria-hidden=\"true\" />,\n}\n\nconst navCommands = [\n  { label: \"View Projects\", icon: RiTaskLine },\n  { label: \"View Tasks\", icon: RiCheckboxCircleLine },\n  { label: \"View Activity\", icon: RiTimeLine },\n]\n\nconst actionCommands = [\n  { label: \"New Project\", icon: RiAddLine },\n  { label: \"View Profile\", icon: RiUser3Line },\n]\n\nexport default function AppShellBlock() {\n  const [commandOpen, setCommandOpen] = React.useState(false)\n  const [taskList, setTaskList] = React.useState(tasks)\n\n  function toggleTask(title: string) {\n    setTaskList((prev) =>\n      prev.map((t) => (t.title === title ? { ...t, done: !t.done } : t))\n    )\n  }\n\n  function removeTask(title: string) {\n    setTaskList((prev) => prev.filter((t) => t.title !== title))\n  }\n\n  React.useEffect(() => {\n    function onKeyDown(event: KeyboardEvent) {\n      if (event.key === \"k\" && (event.metaKey || event.ctrlKey)) {\n        event.preventDefault()\n        setCommandOpen((open) => !open)\n      }\n    }\n    document.addEventListener(\"keydown\", onKeyDown)\n    return () => document.removeEventListener(\"keydown\", onKeyDown)\n  }, [])\n\n  return (\n    <section className=\"flex min-h-svh w-full flex-col bg-background text-foreground\">\n      <header className=\"sticky top-0 z-10 flex h-14 shrink-0 items-center gap-4 border-b border-border bg-background/95 px-6 backdrop-blur-sm\">\n        <div className=\"flex shrink-0 items-center gap-2\">\n          <svg\n            viewBox=\"0 0 24 24\"\n            fill=\"currentColor\"\n            aria-hidden=\"true\"\n            className=\"size-5 shrink-0 text-foreground\"\n          >\n            <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" transform=\"rotate(-6 7 7)\" />\n            <rect\n              x=\"3\"\n              y=\"13\"\n              width=\"8\"\n              height=\"8\"\n              transform=\"rotate(5 7 17)\"\n            />\n            <rect\n              x=\"13\"\n              y=\"13\"\n              width=\"8\"\n              height=\"8\"\n              transform=\"rotate(-4 17 17)\"\n            />\n            <rect\n              x=\"13\"\n              y=\"3\"\n              width=\"8\"\n              height=\"8\"\n              transform=\"rotate(15 17 7)\"\n            />\n          </svg>\n          <span className=\"text-sm font-semibold tracking-tight\">Acme</span>\n        </div>\n\n        <Separator\n          orientation=\"vertical\"\n          className=\"-my-px shrink-0 self-stretch\"\n        />\n\n        <button\n          type=\"button\"\n          onClick={() => setCommandOpen(true)}\n          className=\"flex h-8 max-w-xs flex-1 items-center gap-2 border border-border bg-background px-2.5 text-xs text-muted-foreground transition-colors hover:bg-muted/50 focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:outline-none\"\n        >\n          <RiSearchLine className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n          <span className=\"flex-1 text-left\">Search projects, tasks…</span>\n          <KbdGroup className=\"hidden sm:inline-flex\">\n            <Kbd>Ctrl</Kbd>\n            <Kbd>K</Kbd>\n          </KbdGroup>\n        </button>\n\n        <div className=\"ml-auto flex items-center gap-2\">\n          <Button size=\"sm\" className=\"h-8 gap-1.5 text-xs\">\n            <RiAddLine className=\"size-3.5\" aria-hidden=\"true\" />\n            New Project\n          </Button>\n\n          <DropdownMenu>\n            <DropdownMenuTrigger\n              className=\"cursor-pointer outline-none\"\n              aria-label=\"User menu\"\n            >\n              <Avatar className=\"size-7 ring-1 ring-border ring-offset-1 ring-offset-background transition-opacity hover:opacity-80\">\n                <AvatarImage\n                  src={members.KS.avatar}\n                  alt={members.KS.name}\n                  className=\"grayscale\"\n                />\n                <AvatarFallback className=\"text-[10px]\">KS</AvatarFallback>\n              </Avatar>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\" className=\"w-44\">\n              <div className=\"flex items-center gap-2 px-2 py-1.5\">\n                <Avatar className=\"size-6\">\n                  <AvatarImage\n                    src={members.KS.avatar}\n                    alt={members.KS.name}\n                    className=\"grayscale\"\n                  />\n                  <AvatarFallback className=\"text-[9px]\">KS</AvatarFallback>\n                </Avatar>\n                <div className=\"flex flex-col\">\n                  <span className=\"text-xs font-medium\">Kenji Sato</span>\n                  <span className=\"text-[10px] text-muted-foreground\">\n                    k.sato@acme.io\n                  </span>\n                </div>\n              </div>\n              <DropdownMenuSeparator />\n              <DropdownMenuItem>\n                <RiUser3Line className=\"size-3.5\" aria-hidden=\"true\" />\n                Profile\n              </DropdownMenuItem>\n              <DropdownMenuSeparator />\n              <DropdownMenuItem className=\"text-destructive focus:text-destructive\">\n                Sign Out\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n      </header>\n\n      <main className=\"flex flex-1 flex-col gap-6 px-6 py-8\">\n        <div className=\"flex items-end justify-between\">\n          <div className=\"flex flex-col gap-0.5\">\n            <h1 className=\"text-2xl font-bold tracking-tight\">\n              Good morning, Kenji\n            </h1>\n            <p className=\"text-sm text-muted-foreground\">\n              3 open tasks, 2 projects due this week\n            </p>\n          </div>\n\n          <div className=\"hidden items-center gap-2 sm:flex\">\n            <div className=\"flex items-center gap-1.5 border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground\">\n              <RiCheckboxCircleLine\n                className=\"size-3.5 text-primary\"\n                aria-hidden=\"true\"\n              />\n              <span>\n                <span className=\"font-semibold text-foreground\">12</span>{\" \"}\n                Completed\n              </span>\n            </div>\n            <div className=\"flex items-center gap-1.5 border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground\">\n              <RiTimeLine className=\"size-3.5\" aria-hidden=\"true\" />\n              <span>\n                <span className=\"font-semibold text-foreground\">3</span>{\" \"}\n                Projects Active\n              </span>\n            </div>\n          </div>\n        </div>\n\n        <Tabs defaultValue=\"projects\">\n          <TabsList variant=\"line\">\n            <TabsTrigger value=\"projects\">Projects</TabsTrigger>\n            <TabsTrigger value=\"tasks\">Tasks</TabsTrigger>\n            <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n          </TabsList>\n\n          <TabsContent value=\"projects\">\n            <div className=\"mt-5 grid gap-4 sm:grid-cols-2 md:grid-cols-3\">\n              {projects.map((project) => (\n                <Card\n                  key={project.name}\n                  className=\"group flex flex-col overflow-hidden pt-0 transition-shadow hover:shadow-md\"\n                >\n                  <div className=\"aspect-[16/7] w-full overflow-hidden border-b border-border bg-muted\">\n                    <img\n                      src={project.image}\n                      alt={project.imageAlt}\n                      className=\"size-full object-cover grayscale transition-all duration-300 group-hover:grayscale-0\"\n                    />\n                  </div>\n\n                  <CardHeader className=\"gap-2 pt-4 pb-3\">\n                    <div className=\"flex items-start justify-between gap-2\">\n                      <span className=\"text-sm leading-tight font-semibold\">\n                        {project.name}\n                      </span>\n                      <Badge\n                        variant={statusConfig[project.status].variant}\n                        className=\"shrink-0 text-[10px]\"\n                      >\n                        {project.status}\n                      </Badge>\n                    </div>\n                    <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                      {project.description}\n                    </p>\n                  </CardHeader>\n\n                  <CardContent className=\"flex flex-col gap-3 pb-4\">\n                    <Progress value={project.progress} className=\"gap-1\">\n                      <div className=\"flex w-full items-center justify-between text-[10px] text-muted-foreground\">\n                        <ProgressLabel className=\"text-[10px]\">\n                          Progress\n                        </ProgressLabel>\n                        <ProgressValue className=\"ml-0 text-[10px] font-medium text-foreground\" />\n                      </div>\n                    </Progress>\n\n                    <div className=\"flex items-center justify-between\">\n                      <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n                        <RiTimeLine\n                          className=\"size-3.5 shrink-0\"\n                          aria-hidden=\"true\"\n                        />\n                        <span>Due {project.dueDate}</span>\n                      </div>\n                      <div className=\"flex -space-x-1.5\">\n                        {project.memberKeys.map((key) => (\n                          <Avatar\n                            key={key}\n                            className=\"size-5 ring-1 ring-background\"\n                            title={members[key].name}\n                          >\n                            <AvatarImage\n                              src={members[key].avatar}\n                              alt={members[key].name}\n                              className=\"grayscale\"\n                            />\n                            <AvatarFallback className=\"text-[8px]\">\n                              {key}\n                            </AvatarFallback>\n                          </Avatar>\n                        ))}\n                      </div>\n                    </div>\n                  </CardContent>\n\n                  <CardFooter className=\"border-t border-border pt-3\">\n                    <Button\n                      nativeButton={false}\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      className=\"ml-auto h-7 gap-1 text-xs\"\n                      render={<a href=\"#\" />}\n                    >\n                      View Project\n                      <RiArrowRightLine\n                        className=\"size-3.5\"\n                        aria-hidden=\"true\"\n                      />\n                    </Button>\n                  </CardFooter>\n                </Card>\n              ))}\n            </div>\n          </TabsContent>\n\n          <TabsContent value=\"tasks\">\n            <div className=\"mt-5 flex flex-col border border-border\">\n              {taskList.length === 0 && (\n                <div className=\"bg-card px-4 py-10 text-center text-xs text-muted-foreground\">\n                  All tasks cleared. Nice work.\n                </div>\n              )}\n              {taskList.map((task, idx) => {\n                const assignee = members[task.assigneeKey]\n                return (\n                  <div\n                    key={task.title}\n                    className={[\n                      \"group flex items-center gap-3 bg-card px-4 py-3 transition-colors hover:bg-muted/50\",\n                      idx !== taskList.length - 1\n                        ? \"border-b border-border\"\n                        : \"\",\n                    ].join(\" \")}\n                  >\n                    <button\n                      type=\"button\"\n                      onClick={() => toggleTask(task.title)}\n                      aria-pressed={task.done}\n                      aria-label={\n                        task.done\n                          ? `Mark \"${task.title}\" as incomplete`\n                          : `Mark \"${task.title}\" as complete`\n                      }\n                      className={\n                        task.done\n                          ? \"shrink-0 text-primary transition-colors focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:outline-none\"\n                          : \"shrink-0 text-muted-foreground/30 transition-colors hover:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:outline-none\"\n                      }\n                    >\n                      <RiCheckboxCircleLine\n                        className=\"size-4\"\n                        aria-hidden=\"true\"\n                      />\n                    </button>\n                    <span\n                      className={\n                        task.done\n                          ? \"flex-1 truncate text-xs text-muted-foreground line-through\"\n                          : \"flex-1 truncate text-xs text-foreground\"\n                      }\n                    >\n                      {task.title}\n                    </span>\n                    <Badge\n                      variant={priorityConfig[task.priority].variant}\n                      className=\"shrink-0 text-[10px]\"\n                    >\n                      {task.priority}\n                    </Badge>\n                    <div className=\"flex shrink-0 items-center gap-1.5\">\n                      <Avatar className=\"size-5\">\n                        <AvatarImage\n                          src={assignee.avatar}\n                          alt={assignee.name}\n                          className=\"grayscale\"\n                        />\n                        <AvatarFallback className=\"text-[8px]\">\n                          {task.assigneeKey}\n                        </AvatarFallback>\n                      </Avatar>\n                      <span className=\"hidden text-[10px] text-muted-foreground sm:inline\">\n                        {assignee.name.split(\" \")[0]}\n                      </span>\n                    </div>\n                    <DropdownMenu>\n                      <DropdownMenuTrigger\n                        render={\n                          <Button\n                            variant=\"ghost\"\n                            size=\"icon-sm\"\n                            aria-label={`More options for ${task.title}`}\n                            className=\"shrink-0 opacity-0 transition-opacity group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[popup-open]:opacity-100\"\n                          >\n                            <RiMoreLine\n                              className=\"size-3.5\"\n                              aria-hidden=\"true\"\n                            />\n                          </Button>\n                        }\n                      />\n                      <DropdownMenuContent align=\"end\" className=\"w-44\">\n                        <DropdownMenuItem\n                          onClick={() => toggleTask(task.title)}\n                        >\n                          <RiCheckboxCircleLine\n                            className=\"size-3.5\"\n                            aria-hidden=\"true\"\n                          />\n                          {task.done\n                            ? \"Mark as incomplete\"\n                            : \"Mark as complete\"}\n                        </DropdownMenuItem>\n                        <DropdownMenuSeparator />\n                        <DropdownMenuItem\n                          onClick={() => removeTask(task.title)}\n                          className=\"text-destructive focus:text-destructive\"\n                        >\n                          <RiDeleteBinLine\n                            className=\"size-3.5\"\n                            aria-hidden=\"true\"\n                          />\n                          Remove task\n                        </DropdownMenuItem>\n                      </DropdownMenuContent>\n                    </DropdownMenu>\n                  </div>\n                )\n              })}\n            </div>\n          </TabsContent>\n\n          <TabsContent value=\"activity\">\n            <div className=\"mt-5 flex flex-col border border-border\">\n              {activity.map((item, idx) => {\n                const actor = members[item.actorKey]\n                const initials = item.actorKey\n                return (\n                  <div\n                    key={`${item.actorKey}-${item.time}-${item.target}`}\n                    className={[\n                      \"flex items-start gap-3 bg-card px-4 py-3.5 transition-colors hover:bg-muted/50\",\n                      idx !== activity.length - 1\n                        ? \"border-b border-border\"\n                        : \"\",\n                    ].join(\" \")}\n                  >\n                    <div className=\"relative mt-0.5 shrink-0\">\n                      <Avatar className=\"size-7\">\n                        <AvatarImage\n                          src={actor.avatar}\n                          alt={actor.name}\n                          className=\"grayscale\"\n                        />\n                        <AvatarFallback className=\"text-[10px]\">\n                          {initials}\n                        </AvatarFallback>\n                      </Avatar>\n                      <span className=\"absolute -right-0.5 -bottom-0.5 flex size-4 items-center justify-center border border-border bg-muted text-muted-foreground\">\n                        {activityIcon[item.icon]}\n                      </span>\n                    </div>\n\n                    <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n                      <p className=\"text-xs leading-relaxed\">\n                        <span className=\"font-medium\">{actor.name}</span>{\" \"}\n                        <span className=\"text-muted-foreground\">\n                          {item.action}\n                        </span>{\" \"}\n                        <span className=\"font-medium\">{item.target}</span>\n                      </p>\n                      <p className=\"text-[10px] text-muted-foreground\">\n                        {item.time}\n                      </p>\n                    </div>\n                  </div>\n                )\n              })}\n            </div>\n          </TabsContent>\n        </Tabs>\n      </main>\n\n      <CommandDialog open={commandOpen} onOpenChange={setCommandOpen}>\n        <Command>\n          <CommandInput\n            aria-label=\"Type a command or search\"\n            placeholder=\"Type a command or search…\"\n          />\n          <CommandList>\n            <CommandEmpty>No results found.</CommandEmpty>\n            <CommandGroup heading=\"Navigation\">\n              {navCommands.map((command) => (\n                <CommandItem\n                  key={command.label}\n                  onSelect={() => setCommandOpen(false)}\n                >\n                  <command.icon />\n                  <span>{command.label}</span>\n                </CommandItem>\n              ))}\n            </CommandGroup>\n            <CommandGroup heading=\"Actions\">\n              {actionCommands.map((command) => (\n                <CommandItem\n                  key={command.label}\n                  onSelect={() => setCommandOpen(false)}\n                >\n                  <command.icon />\n                  <span>{command.label}</span>\n                </CommandItem>\n              ))}\n            </CommandGroup>\n          </CommandList>\n        </Command>\n      </CommandDialog>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "height": "90vh",
    "tier": "free"
  },
  "categories": [
    "app-shell"
  ],
  "type": "registry:block"
}