{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "employee-org-chart-tree",
  "title": "Employee Org Chart Tree",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/EmployeeOrgChartTree.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch, type HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport EmployeeProfileDrawer from './EmployeeProfileDrawer.vue'\nimport OrgChartNodeCard from './OrgChartNodeCard.vue'\nimport OrgChartToolbar from './OrgChartToolbar.vue'\nimport { DEFAULT_ORG_DATA } from './org-chart-data'\nimport type { EmployeeNode } from './org-chart-types'\nimport { getDeptBadgeClasses } from './org-chart-types'\n\nexport type { EmployeeNode }\n\ninterface Props {\n  title?: string\n  subtitle?: string\n  orgData?: EmployeeNode\n  initialSelectedId?: string\n  initialDepartment?: string\n  initialSearch?: string\n  initialExpandedIds?: string[]\n  initialDrawerOpen?: boolean\n  class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  title: 'Company Organizational Chart',\n  subtitle: '148 Employees across 5 Departments',\n  orgData: () => DEFAULT_ORG_DATA,\n  initialSelectedId: 'emp-ceo',\n  initialDepartment: 'All',\n  initialSearch: '',\n  initialExpandedIds: () => ['emp-ceo', 'emp-eng-vp', 'emp-prod-vp', 'emp-ops-vp'],\n  initialDrawerOpen: true,\n})\n\nconst canvasRef = ref<HTMLDivElement | null>(null)\nonMounted(() => {\n  const el = canvasRef.value\n  if (el) el.scrollLeft = Math.max(0, (el.scrollWidth - el.clientWidth) / 2)\n})\n\nfunction flatten(node: EmployeeNode): EmployeeNode[] {\n  const result: EmployeeNode[] = [node]\n  if (node.children) {\n    for (const child of node.children) {\n      result.push(...flatten(child))\n    }\n  }\n  return result\n}\n\nconst allEmployees = computed(() => flatten(props.orgData))\n\nconst selectedEmployeeId = ref<string>(props.initialSelectedId)\nconst selectedDepartment = ref<string>(props.initialDepartment)\nconst searchQuery = ref<string>(props.initialSearch)\nconst isDrawerOpen = ref<boolean>(props.initialDrawerOpen)\nconst zoomLevel = ref<number>(100)\nconst emailCopied = ref<boolean>(false)\nconst expandedIds = ref<Set<string>>(new Set(props.initialExpandedIds))\n\nconst departmentCounts = computed(() => [\n  { label: 'All', value: 'All', count: allEmployees.value.length },\n  {\n    label: 'Executive',\n    value: 'Executive',\n    count: allEmployees.value.filter((e) => e.department === 'Executive').length,\n  },\n  {\n    label: 'Engineering',\n    value: 'Engineering',\n    count: allEmployees.value.filter((e) => e.department === 'Engineering').length,\n  },\n  { label: 'Design', value: 'Design', count: allEmployees.value.filter((e) => e.department === 'Design').length },\n  { label: 'Product', value: 'Product', count: allEmployees.value.filter((e) => e.department === 'Product').length },\n  {\n    label: 'Operations',\n    value: 'Operations',\n    count: allEmployees.value.filter((e) => e.department === 'Operations').length,\n  },\n])\n\nconst selectedEmployee = computed(() => {\n  return allEmployees.value.find((e) => e.id === selectedEmployeeId.value) || props.orgData\n})\n\nconst matchingEmployeeIds = computed(() => {\n  const q = searchQuery.value.trim().toLowerCase()\n  if (!q) return new Set<string>()\n\n  const matches = new Set<string>()\n  for (const emp of allEmployees.value) {\n    if (\n      emp.name.toLowerCase().includes(q) ||\n      emp.role.toLowerCase().includes(q) ||\n      emp.department.toLowerCase().includes(q) ||\n      emp.location.toLowerCase().includes(q) ||\n      emp.skills.some((s) => s.toLowerCase().includes(q))\n    ) {\n      matches.add(emp.id)\n    }\n  }\n  return matches\n})\n\nwatch(\n  () => searchQuery.value,\n  (q) => {\n    if (q.trim()) {\n      const allParentIds = allEmployees.value.filter((e) => e.children && e.children.length > 0).map((e) => e.id)\n      expandedIds.value = new Set(allParentIds)\n    }\n  },\n)\n\nfunction isExpanded(id: string): boolean {\n  return expandedIds.value.has(id)\n}\n\nfunction toggleExpand(id: string) {\n  const updated = new Set(expandedIds.value)\n  if (updated.has(id)) {\n    updated.delete(id)\n  } else {\n    updated.add(id)\n  }\n  expandedIds.value = updated\n}\n\nfunction expandAll() {\n  const allParentIds = allEmployees.value.filter((e) => e.children && e.children.length > 0).map((e) => e.id)\n  expandedIds.value = new Set(allParentIds)\n}\n\nfunction collapseAll() {\n  expandedIds.value = new Set()\n}\n\nfunction selectEmployee(emp: EmployeeNode) {\n  selectedEmployeeId.value = emp.id\n  isDrawerOpen.value = true\n}\n\nfunction selectSelectedManager() {\n  const manager = allEmployees.value.find((e) => e.id === selectedEmployee.value?.managerId)\n  if (manager) selectEmployee(manager)\n}\n\nfunction copyEmail(email: string) {\n  navigator.clipboard.writeText(email)\n  emailCopied.value = true\n  setTimeout(() => {\n    emailCopied.value = false\n  }, 2000)\n}\n\nfunction adjustZoom(delta: number) {\n  zoomLevel.value = Math.min(130, Math.max(70, zoomLevel.value + delta))\n}\n\nfunction resetZoom() {\n  zoomLevel.value = 100\n}\n\nfunction isNodeDimmed(node: EmployeeNode): boolean {\n  if (selectedDepartment.value !== 'All') {\n    if (selectedDepartment.value === 'Executive' && node.department !== 'Executive') return true\n    if (\n      selectedDepartment.value === 'Engineering' &&\n      node.department !== 'Engineering' &&\n      node.department !== 'Executive'\n    )\n      return true\n    if (selectedDepartment.value === 'Design' && node.department !== 'Design' && node.department !== 'Executive')\n      return true\n    if (selectedDepartment.value === 'Product' && node.department !== 'Product' && node.department !== 'Executive')\n      return true\n    if (\n      selectedDepartment.value === 'Operations' &&\n      node.department !== 'Operations' &&\n      node.department !== 'Executive'\n    )\n      return true\n  }\n\n  if (searchQuery.value.trim().length > 0) {\n    const isDirectMatch = matchingEmployeeIds.value.has(node.id)\n    const hasMatchingDescendant = flatten(node).some((n) => matchingEmployeeIds.value.has(n.id))\n    return !isDirectMatch && !hasMatchingDescendant\n  }\n\n  return false\n}\n\nfunction isNodeHighlighted(node: EmployeeNode): boolean {\n  if (searchQuery.value.trim().length > 0) {\n    return matchingEmployeeIds.value.has(node.id)\n  }\n  return false\n}\n</script>\n\n<template>\n  <div\n    data-slot=\"employee-org-chart-tree\"\n    :class=\"cn('bg-background border-border flex flex-col rounded-xl border shadow-xs', props.class)\"\n  >\n    <!-- Header & Toolbar Controls -->\n    <OrgChartToolbar\n      :title=\"props.title\"\n      :subtitle=\"props.subtitle\"\n      :search-query=\"searchQuery\"\n      :is-drawer-open=\"isDrawerOpen\"\n      :department-counts=\"departmentCounts\"\n      :selected-department=\"selectedDepartment\"\n      :matching-count=\"matchingEmployeeIds.size\"\n      :zoom-level=\"zoomLevel\"\n      @update:search-query=\"searchQuery = $event\"\n      @update:is-drawer-open=\"isDrawerOpen = $event\"\n      @update:selected-department=\"selectedDepartment = $event\"\n      @expand-all=\"expandAll\"\n      @collapse-all=\"collapseAll\"\n      @adjust-zoom=\"adjustZoom\"\n      @reset-zoom=\"resetZoom\"\n    />\n\n    <!-- Main Content: Canvas & Quick Info Drawer -->\n    <div class=\"relative flex flex-1 flex-col lg:flex-row\">\n      <!-- Tree Hierarchy Node Canvas -->\n      <div ref=\"canvasRef\" class=\"bg-muted/10 relative flex-1 overflow-x-auto overflow-y-visible p-6 md:p-10\">\n        <div\n          class=\"flex min-w-max flex-col items-center transition-transform duration-200\"\n          :style=\"{ transform: `scale(${zoomLevel / 100})`, transformOrigin: 'top center' }\"\n        >\n          <!-- LEVEL 0: CEO Node -->\n          <div class=\"flex flex-col items-center\">\n            <OrgChartNodeCard\n              :node=\"orgData\"\n              :is-selected=\"selectedEmployeeId === orgData.id\"\n              :is-highlighted=\"isNodeHighlighted(orgData)\"\n              :is-dimmed=\"isNodeDimmed(orgData)\"\n              :is-expanded=\"isExpanded(orgData.id)\"\n              reports-label=\"Direct reports: 3 VPs\"\n              :headcount-label=\"`${orgData.teamHeadcount} total org`\"\n              expand-label=\"Expand Executive Team\"\n              collapse-label=\"Collapse Executive Team\"\n              @select=\"selectEmployee\"\n              @toggle-expand=\"toggleExpand\"\n            />\n\n            <!-- Connector stem down from CEO -->\n            <div v-if=\"isExpanded(orgData.id) && orgData.children?.length\" class=\"bg-border h-8 w-px\" />\n\n            <!-- LEVEL 1: VPs and Directors -->\n            <div\n              v-if=\"isExpanded(orgData.id) && orgData.children?.length\"\n              class=\"relative flex items-start gap-10 pt-0\"\n            >\n              <!-- Horizontal branching rail connecting Level 1 nodes -->\n              <div\n                v-if=\"orgData.children.length > 1\"\n                class=\"bg-border absolute top-0 right-[16.666%] left-[16.666%] h-px\"\n              />\n\n              <!-- Iterate Level 1 VPs -->\n              <div v-for=\"vp in orgData.children\" :key=\"vp.id\" class=\"flex flex-col items-center\">\n                <!-- Top stem connecting rail to VP card -->\n                <div class=\"bg-border h-8 w-px\" />\n\n                <!-- VP Node Card -->\n                <OrgChartNodeCard\n                  :node=\"vp\"\n                  :is-selected=\"selectedEmployeeId === vp.id\"\n                  :is-highlighted=\"isNodeHighlighted(vp)\"\n                  :is-dimmed=\"isNodeDimmed(vp)\"\n                  :is-expanded=\"isExpanded(vp.id)\"\n                  :reports-label=\"`Direct reports: ${vp.reportsCount} teams`\"\n                  :headcount-label=\"`${vp.teamHeadcount} staff`\"\n                  :expand-label=\"`Expand (${vp.children?.length || 0} Leads)`\"\n                  collapse-label=\"Collapse Branch\"\n                  @select=\"selectEmployee\"\n                  @toggle-expand=\"toggleExpand\"\n                />\n\n                <!-- Connector down from VP -->\n                <div v-if=\"isExpanded(vp.id) && vp.children?.length\" class=\"bg-border h-8 w-px\" />\n\n                <!-- LEVEL 2: Staff Leads & Managers -->\n                <div v-if=\"isExpanded(vp.id) && vp.children?.length\" class=\"relative flex items-start gap-6 pt-0\">\n                  <!-- Horizontal rail for Level 2 nodes -->\n                  <div\n                    v-if=\"vp.children.length === 3\"\n                    class=\"bg-border absolute top-0 right-[16.666%] left-[16.666%] h-px\"\n                  />\n                  <div\n                    v-else-if=\"vp.children.length === 2\"\n                    class=\"bg-border absolute top-0 right-[25%] left-[25%] h-px\"\n                  />\n\n                  <!-- Iterate Level 2 Leads -->\n                  <div v-for=\"lead in vp.children\" :key=\"lead.id\" class=\"flex flex-col items-center\">\n                    <div class=\"bg-border h-8 w-px\" />\n\n                    <!-- Lead Node Card -->\n                    <OrgChartNodeCard\n                      :node=\"lead\"\n                      :is-selected=\"selectedEmployeeId === lead.id\"\n                      :is-highlighted=\"isNodeHighlighted(lead)\"\n                      :is-dimmed=\"isNodeDimmed(lead)\"\n                      :is-expanded=\"isExpanded(lead.id)\"\n                      :reports-label=\"`${lead.reportsCount} reports`\"\n                      :headcount-label=\"`${lead.teamHeadcount} members`\"\n                      :expand-label=\"`Team (${lead.children?.length || 0})`\"\n                      collapse-label=\"Collapse\"\n                      @select=\"selectEmployee\"\n                      @toggle-expand=\"toggleExpand\"\n                    />\n\n                    <!-- Connector down from Lead -->\n                    <div v-if=\"isExpanded(lead.id) && lead.children?.length\" class=\"bg-border h-8 w-px\" />\n\n                    <!-- LEVEL 3: Team ICs / Senior Contributors -->\n                    <div\n                      v-if=\"isExpanded(lead.id) && lead.children?.length\"\n                      class=\"relative flex items-start gap-4 pt-0\"\n                    >\n                      <div\n                        v-if=\"lead.children.length === 2\"\n                        class=\"bg-border absolute top-0 right-[25%] left-[25%] h-px\"\n                      />\n\n                      <!-- Iterate Level 3 ICs -->\n                      <div v-for=\"ic in lead.children\" :key=\"ic.id\" class=\"flex flex-col items-center\">\n                        <div class=\"bg-border h-8 w-px\" />\n\n                        <!-- IC Card -->\n                        <OrgChartNodeCard\n                          :node=\"ic\"\n                          :is-selected=\"selectedEmployeeId === ic.id\"\n                          :is-highlighted=\"isNodeHighlighted(ic)\"\n                          :is-dimmed=\"isNodeDimmed(ic)\"\n                          :reports-label=\"`${ic.reportsCount} direct`\"\n                          :headcount-label=\"`${ic.teamHeadcount} member`\"\n                          @select=\"selectEmployee\"\n                        />\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Quick Info Side Profile Drawer -->\n      <EmployeeProfileDrawer\n        v-if=\"isDrawerOpen\"\n        :employee=\"selectedEmployee\"\n        :email-copied=\"emailCopied\"\n        :copy-email=\"copyEmail\"\n        :get-dept-badge-classes=\"getDeptBadgeClasses\"\n        @close=\"isDrawerOpen = false\"\n        @select-employee=\"selectEmployee\"\n        @view-manager=\"selectSelectedManager\"\n      />\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/EmployeeOrgChartTree.vue"
    },
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/EmployeeProfileDrawer.vue",
      "content": "<script setup lang=\"ts\">\nimport { ArrowRight, Briefcase, Calendar, Check, Copy, Mail, MapPin, User, Users, X } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Separator } from '@/components/ui/separator'\nimport type { EmployeeNode } from './org-chart-types'\n\ninterface Props {\n  employee: EmployeeNode\n  emailCopied: boolean\n  copyEmail: (email: string) => void\n  getDeptBadgeClasses: (dept: string) => string\n}\n\ndefineProps<Props>()\n\ndefineEmits<{\n  close: []\n  'select-employee': [employee: EmployeeNode]\n  'view-manager': []\n}>()\n</script>\n\n<template>\n  <div class=\"border-border bg-card flex w-full shrink-0 flex-col border-t lg:w-96 lg:border-t-0 lg:border-l\">\n    <!-- Drawer Header -->\n    <div class=\"border-border flex items-center justify-between border-b p-4\">\n      <div class=\"flex items-center gap-2\">\n        <User class=\"text-primary size-4\" />\n        <h3 class=\"text-foreground text-sm font-semibold\">Employee Profile</h3>\n      </div>\n      <Button variant=\"ghost\" size=\"icon\" class=\"size-7\" aria-label=\"Close profile drawer\" @click=\"$emit('close')\">\n        <X class=\"size-4\" />\n      </Button>\n    </div>\n\n    <!-- Drawer Body -->\n    <div class=\"max-h-[700px] flex-1 space-y-5 overflow-y-auto p-5\">\n      <!-- Profile Identity Header -->\n      <div class=\"flex items-start gap-3.5\">\n        <div class=\"relative\">\n          <Avatar class=\"border-border ring-background size-14 border ring-2\">\n            <AvatarImage :src=\"employee.avatar\" :alt=\"employee.name\" />\n            <AvatarFallback>{{ employee.initials }}</AvatarFallback>\n          </Avatar>\n          <span class=\"ring-background bg-success absolute right-0 bottom-0 size-3 rounded-full ring-2\" />\n        </div>\n        <div class=\"min-w-0 flex-1\">\n          <h4 class=\"text-foreground text-base font-semibold tracking-tight\">{{ employee.name }}</h4>\n          <p class=\"text-muted-foreground text-xs\">{{ employee.role }}</p>\n          <div class=\"mt-2 flex flex-wrap items-center gap-1.5\">\n            <Badge variant=\"outline\" :class=\"cn('text-xs font-medium', getDeptBadgeClasses(employee.department))\">\n              {{ employee.department }}\n            </Badge>\n            <Badge variant=\"secondary\" class=\"text-xs font-normal\"> Active · Full-time </Badge>\n          </div>\n        </div>\n      </div>\n\n      <!-- Quick Action Buttons -->\n      <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n        <Button as-child variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\">\n          <a :href=\"`mailto:${employee.email}`\">\n            <Mail class=\"size-3.5\" />\n            <span>Send Email</span>\n          </a>\n        </Button>\n        <Button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" @click=\"copyEmail(employee.email)\">\n          <Check v-if=\"emailCopied\" class=\"text-success size-3.5\" />\n          <Copy v-else class=\"size-3.5\" />\n          <span>{{ emailCopied ? 'Copied!' : 'Copy Email' }}</span>\n        </Button>\n      </div>\n\n      <Separator />\n\n      <!-- Bio / Leadership Scope -->\n      <div class=\"space-y-1.5\">\n        <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">About & Focus</h5>\n        <p class=\"text-muted-foreground text-xs leading-relaxed\">\n          {{ employee.bio }}\n        </p>\n      </div>\n\n      <!-- Key Details Grid -->\n      <div class=\"space-y-1.5\">\n        <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Overview Details</h5>\n        <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n          <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n              <Users class=\"size-3\" />\n              <span>Team Scope</span>\n            </div>\n            <p class=\"text-foreground mt-1 text-xs font-semibold\">{{ employee.teamHeadcount }} Members</p>\n          </div>\n\n          <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n              <MapPin class=\"size-3\" />\n              <span>Location</span>\n            </div>\n            <p class=\"text-foreground mt-1 truncate text-xs font-semibold\">\n              {{ employee.location }}\n            </p>\n          </div>\n\n          <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n              <Calendar class=\"size-3\" />\n              <span>Tenure</span>\n            </div>\n            <p class=\"text-foreground mt-1 text-xs font-semibold\">\n              {{ employee.tenure }}\n            </p>\n          </div>\n\n          <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n              <Briefcase class=\"size-3\" />\n              <span>Phone</span>\n            </div>\n            <p class=\"text-foreground mt-1 truncate text-xs font-semibold\">\n              {{ employee.phone }}\n            </p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Reporting Manager Context (if applicable) -->\n      <div v-if=\"employee.managerName\" class=\"space-y-1.5\">\n        <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Reports To</h5>\n        <div class=\"border-border/80 bg-muted/20 flex items-center justify-between rounded-lg border p-2.5\">\n          <div class=\"min-w-0\">\n            <p class=\"text-foreground text-xs font-medium\">{{ employee.managerName }}</p>\n            <p class=\"text-muted-foreground text-xs\">{{ employee.managerRole }}</p>\n          </div>\n          <Button variant=\"ghost\" size=\"sm\" class=\"h-7 gap-1 text-xs\" @click=\"$emit('view-manager')\">\n            <span>View</span>\n            <ArrowRight class=\"size-3\" />\n          </Button>\n        </div>\n      </div>\n\n      <!-- Direct Reports Roster (if has children) -->\n      <div v-if=\"employee.children?.length\" class=\"space-y-2\">\n        <div class=\"flex items-center justify-between\">\n          <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">\n            Direct Reports ({{ employee.children.length }})\n          </h5>\n          <span class=\"text-muted-foreground text-xs font-medium\">{{ employee.reportsCount }} reporting teams</span>\n        </div>\n\n        <div class=\"space-y-1.5\">\n          <div\n            v-for=\"sub in employee.children\"\n            :key=\"sub.id\"\n            class=\"border-border/60 bg-muted/20 hover:bg-muted/40 flex cursor-pointer items-center justify-between rounded-lg border p-2 transition-colors\"\n            @click=\"$emit('select-employee', sub)\"\n          >\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <Avatar class=\"border-border size-7 border\">\n                <AvatarImage :src=\"sub.avatar\" :alt=\"sub.name\" />\n                <AvatarFallback>{{ sub.initials }}</AvatarFallback>\n              </Avatar>\n              <div class=\"min-w-0\">\n                <p class=\"text-foreground truncate text-xs font-medium\">{{ sub.name }}</p>\n                <p class=\"text-muted-foreground truncate text-xs\">{{ sub.role }}</p>\n              </div>\n            </div>\n            <Badge variant=\"outline\" :class=\"cn('shrink-0 px-1.5 py-0 text-xs', getDeptBadgeClasses(sub.department))\">\n              {{ sub.teamHeadcount }} staff\n            </Badge>\n          </div>\n        </div>\n      </div>\n\n      <!-- Skills & Competencies -->\n      <div class=\"space-y-1.5\">\n        <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Core Competencies</h5>\n        <div class=\"flex flex-wrap gap-1.5\">\n          <Badge v-for=\"skill in employee.skills\" :key=\"skill\" variant=\"secondary\" class=\"text-xs font-normal\">\n            {{ skill }}\n          </Badge>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/EmployeeProfileDrawer.vue"
    },
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/OrgChartToolbar.vue",
      "content": "<script setup lang=\"ts\">\nimport { Building2, Minus, Plus, RotateCcw, Search, User, X, ZoomIn, ZoomOut } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\n\nexport interface DepartmentCount {\n  label: string\n  value: string\n  count: number\n}\n\ninterface Props {\n  title: string\n  subtitle: string\n  searchQuery: string\n  isDrawerOpen: boolean\n  departmentCounts: DepartmentCount[]\n  selectedDepartment: string\n  matchingCount: number\n  zoomLevel: number\n}\n\ndefineProps<Props>()\n\nconst emit = defineEmits<{\n  'update:searchQuery': [value: string]\n  'update:isDrawerOpen': [value: boolean]\n  'update:selectedDepartment': [value: string]\n  expandAll: []\n  collapseAll: []\n  adjustZoom: [delta: number]\n  resetZoom: []\n}>()\n</script>\n\n<template>\n  <div>\n    <!-- Header Section -->\n    <div class=\"border-border flex flex-col gap-4 border-b p-5 md:flex-row md:items-center md:justify-between\">\n      <div>\n        <div class=\"flex items-center gap-2\">\n          <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n            <Building2 class=\"size-4\" />\n          </div>\n          <h2 class=\"text-foreground text-lg font-semibold tracking-tight\">{{ title }}</h2>\n        </div>\n        <p class=\"text-muted-foreground mt-1 text-xs\">\n          {{ subtitle }}\n        </p>\n      </div>\n\n      <!-- Header Action Controls -->\n      <div class=\"flex flex-wrap items-center gap-2\">\n        <!-- Search input -->\n        <div class=\"relative max-w-xs min-w-[220px]\">\n          <Search class=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n          <Input\n            :model-value=\"searchQuery\"\n            placeholder=\"Search employee, title, skill...\"\n            class=\"h-8 pr-7 pl-8 text-xs\"\n            @update:model-value=\"emit('update:searchQuery', String($event))\"\n          />\n          <button\n            v-if=\"searchQuery\"\n            type=\"button\"\n            class=\"text-muted-foreground hover:text-foreground absolute top-1/2 right-2 -translate-y-1/2\"\n            aria-label=\"Clear search\"\n            @click=\"emit('update:searchQuery', '')\"\n          >\n            <X class=\"size-3.5\" />\n          </button>\n        </div>\n\n        <Separator orientation=\"vertical\" class=\"hidden h-6 md:block\" />\n\n        <!-- Expand / Collapse All -->\n        <Button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" @click=\"emit('expandAll')\">\n          <Plus class=\"size-3.5\" />\n          <span>Expand All</span>\n        </Button>\n\n        <Button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" @click=\"emit('collapseAll')\">\n          <Minus class=\"size-3.5\" />\n          <span>Collapse All</span>\n        </Button>\n\n        <!-- Profile Drawer Toggle Button -->\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          :class=\"cn('h-8 gap-1.5 text-xs', isDrawerOpen && 'bg-accent text-accent-foreground')\"\n          @click=\"emit('update:isDrawerOpen', !isDrawerOpen)\"\n        >\n          <User class=\"size-3.5\" />\n          <span>{{ isDrawerOpen ? 'Hide Profile' : 'View Profile' }}</span>\n        </Button>\n      </div>\n    </div>\n\n    <!-- Filter & Toolbar Bar -->\n    <div class=\"border-border bg-muted/20 flex flex-wrap items-center justify-between gap-3 border-b px-5 py-3\">\n      <!-- Department Filter Pills -->\n      <div class=\"flex flex-wrap items-center gap-1.5\">\n        <span class=\"text-muted-foreground mr-1 text-xs font-medium\">Department:</span>\n        <button\n          v-for=\"dept in departmentCounts\"\n          :key=\"dept.value\"\n          type=\"button\"\n          :class=\"\n            cn(\n              'focus-visible:ring-ring inline-flex h-7 items-center gap-1.5 rounded-full px-2.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              selectedDepartment === dept.value\n                ? 'bg-primary text-primary-foreground shadow-xs'\n                : 'bg-background hover:bg-muted text-muted-foreground border-border border',\n            )\n          \"\n          @click=\"emit('update:selectedDepartment', dept.value)\"\n        >\n          <span>{{ dept.label }}</span>\n          <span\n            :class=\"\n              cn(\n                'py-0.2 rounded-full px-1.5 text-xs',\n                selectedDepartment === dept.value\n                  ? 'bg-primary-foreground/20 text-primary-foreground'\n                  : 'bg-muted text-muted-foreground',\n              )\n            \"\n          >\n            {{ dept.count }}\n          </span>\n        </button>\n      </div>\n\n      <!-- Zoom and Search Banner -->\n      <div class=\"flex items-center gap-2\">\n        <div v-if=\"searchQuery.trim()\" class=\"text-success text-xs\">\n          Found {{ matchingCount }} matching member{{ matchingCount === 1 ? '' : 's' }}\n        </div>\n\n        <div class=\"bg-background border-border flex items-center rounded-lg border p-0.5 shadow-2xs\">\n          <Button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"size-6 text-xs\"\n            :disabled=\"zoomLevel <= 70\"\n            aria-label=\"Zoom out\"\n            @click=\"emit('adjustZoom', -10)\"\n          >\n            <ZoomOut class=\"size-3\" />\n          </Button>\n          <span class=\"text-muted-foreground w-10 text-center text-xs font-medium\">{{ zoomLevel }}%</span>\n          <Button\n            variant=\"ghost\"\n            size=\"icon\"\n            class=\"size-6 text-xs\"\n            :disabled=\"zoomLevel >= 130\"\n            aria-label=\"Zoom in\"\n            @click=\"emit('adjustZoom', 10)\"\n          >\n            <ZoomIn class=\"size-3\" />\n          </Button>\n          <Separator orientation=\"vertical\" class=\"mx-0.5 h-3.5\" />\n          <Button variant=\"ghost\" size=\"icon\" class=\"size-6 text-xs\" aria-label=\"Reset zoom\" @click=\"emit('resetZoom')\">\n            <RotateCcw class=\"size-3\" />\n          </Button>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/OrgChartToolbar.vue"
    },
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/OrgChartNodeCard.vue",
      "content": "<script setup lang=\"ts\">\nimport { ChevronDown, ChevronRight, Mail, MapPin, Users } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport type { EmployeeNode } from './org-chart-types'\nimport { getDeptBadgeClasses, getDeptTopStripClasses } from './org-chart-types'\n\ninterface Props {\n  node: EmployeeNode\n  isSelected: boolean\n  isHighlighted: boolean\n  isDimmed: boolean\n  isExpanded?: boolean\n  reportsLabel?: string\n  headcountLabel?: string\n  expandLabel?: string\n  collapseLabel?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n  isExpanded: false,\n  reportsLabel: '',\n  headcountLabel: '',\n  expandLabel: '',\n  collapseLabel: '',\n})\n\nconst emit = defineEmits<{\n  select: [node: EmployeeNode]\n  toggleExpand: [id: string]\n}>()\n</script>\n\n<template>\n  <div\n    :class=\"\n      cn(\n        'bg-card border-border hover:border-primary/50 relative w-72 cursor-pointer rounded-xl border text-left shadow-xs transition-colors duration-200 hover:shadow-md',\n        isSelected && 'ring-primary border-primary bg-primary/[0.02] ring-2',\n        isHighlighted && 'border-success bg-success/10/20 ring-success dark:bg-success/10 ring-2',\n        isDimmed && 'opacity-35 grayscale-[25%]',\n      )\n    \"\n    tabindex=\"0\"\n    role=\"button\"\n    :aria-label=\"`Select ${node.name}`\"\n    @click=\"emit('select', node)\"\n    @keydown.enter=\"emit('select', node)\"\n    @keydown.space.prevent=\"emit('select', node)\"\n  >\n    <!-- Top department accent strip -->\n    <div :class=\"cn('h-1 w-full rounded-t-xl', getDeptTopStripClasses(node.department))\" />\n\n    <div class=\"space-y-3 p-4\">\n      <!-- Identity row -->\n      <div class=\"flex items-start justify-between gap-2.5\">\n        <div class=\"flex min-w-0 items-center gap-2.5\">\n          <div class=\"relative\">\n            <Avatar class=\"border-border ring-background size-10 border ring-1\">\n              <AvatarImage :src=\"node.avatar\" :alt=\"node.name\" />\n              <AvatarFallback>{{ node.initials }}</AvatarFallback>\n            </Avatar>\n            <span class=\"ring-background bg-success absolute right-0 bottom-0 size-2.5 rounded-full ring-2\" />\n          </div>\n          <div class=\"min-w-0\">\n            <h4 class=\"text-foreground truncate text-sm font-semibold\">{{ node.name }}</h4>\n            <p class=\"text-muted-foreground truncate text-xs\">{{ node.role }}</p>\n          </div>\n        </div>\n        <Badge variant=\"outline\" :class=\"cn('shrink-0 text-xs font-normal', getDeptBadgeClasses(node.department))\">\n          {{ node.department }}\n        </Badge>\n      </div>\n\n      <!-- Contact & Location info -->\n      <div class=\"text-muted-foreground space-y-1 text-xs\">\n        <div class=\"flex items-center gap-1.5\">\n          <MapPin class=\"size-3.5 shrink-0\" />\n          <span class=\"truncate\">{{ node.location }}</span>\n        </div>\n        <div class=\"flex items-center gap-1.5\">\n          <Mail class=\"size-3.5 shrink-0\" />\n          <span class=\"truncate\">{{ node.email }}</span>\n        </div>\n      </div>\n\n      <!-- Team Reports Count Pill -->\n      <div class=\"bg-muted/60 flex items-center justify-between rounded-lg px-2.5 py-1.5 text-xs\">\n        <div class=\"text-foreground flex items-center gap-1.5 font-medium\">\n          <Users class=\"text-muted-foreground size-3.5\" />\n          <span>{{ reportsLabel || `Direct reports: ${node.reportsCount}` }}</span>\n        </div>\n        <span class=\"text-muted-foreground text-xs\">{{ headcountLabel || `${node.teamHeadcount} staff` }}</span>\n      </div>\n\n      <!-- Expand/Collapse Button (if has children) -->\n      <Button\n        v-if=\"node.children && node.children.length > 0\"\n        variant=\"ghost\"\n        size=\"sm\"\n        class=\"text-muted-foreground hover:text-foreground h-7 w-full justify-between text-xs font-medium\"\n        @click.stop=\"emit('toggleExpand', node.id)\"\n      >\n        <span class=\"flex items-center gap-1.5\">\n          <ChevronDown v-if=\"isExpanded\" class=\"size-3.5\" />\n          <ChevronRight v-else class=\"size-3.5\" />\n          <span>{{\n            isExpanded ? collapseLabel || 'Collapse Branch' : expandLabel || `Expand (${node.children.length})`\n          }}</span>\n        </span>\n        <span class=\"bg-muted rounded px-1.5 py-0.5 text-xs\">{{ node.children.length }}</span>\n      </Button>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/OrgChartNodeCard.vue"
    },
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/org-chart-types.ts",
      "content": "export interface EmployeeNode {\n  id: string\n  name: string\n  role: string\n  department: 'Executive' | 'Engineering' | 'Design' | 'Product' | 'Operations'\n  email: string\n  phone: string\n  location: string\n  avatar: string\n  initials: string\n  reportsCount: number\n  teamHeadcount: number\n  managerId?: string\n  managerName?: string\n  managerRole?: string\n  startDate: string\n  tenure: string\n  bio: string\n  skills: string[]\n  status: 'active' | 'on-leave'\n  children?: EmployeeNode[]\n}\n\nexport function getDeptBadgeClasses(dept: string): string {\n  switch (dept) {\n    case 'Executive':\n      return 'border-chart-1/30 bg-chart-1/10 text-chart-1'\n    case 'Engineering':\n      return 'border-chart-2/30 bg-chart-2/10 text-chart-2'\n    case 'Design':\n      return 'border-chart-3/30 bg-chart-3/10 text-chart-3'\n    case 'Product':\n      return 'border-chart-4/30 bg-chart-4/10 text-chart-4'\n    case 'Operations':\n      return 'border-chart-5/30 bg-chart-5/10 text-chart-5'\n    default:\n      return 'border-border bg-muted text-muted-foreground'\n  }\n}\n\nexport function getDeptTopStripClasses(dept: string): string {\n  switch (dept) {\n    case 'Executive':\n      return 'bg-chart-1'\n    case 'Engineering':\n      return 'bg-chart-2'\n    case 'Design':\n      return 'bg-chart-3'\n    case 'Product':\n      return 'bg-chart-4'\n    case 'Operations':\n      return 'bg-chart-5'\n    default:\n      return 'bg-muted-foreground'\n  }\n}\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/org-chart-types.ts"
    },
    {
      "path": "packages/registry-vue/blocks/employee-org-chart-tree/org-chart-data.ts",
      "content": "import type { EmployeeNode } from './org-chart-types'\n\nexport const DEFAULT_ORG_DATA: EmployeeNode = {\n  id: 'emp-ceo',\n  name: 'Sarah Jenkins',\n  role: 'Chief Executive Officer',\n  department: 'Executive',\n  email: 'sarah.jenkins@acme.corp',\n  phone: '+1 (415) 890-1200',\n  location: 'San Francisco, CA (HQ)',\n  avatar: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=160&auto=format&fit=crop&q=80',\n  initials: 'SJ',\n  reportsCount: 3,\n  teamHeadcount: 148,\n  startDate: 'January 2019',\n  tenure: '5 yrs 8 mos',\n  bio: 'Directs company-wide vision, long-range enterprise roadmap, capital allocation, and executive leadership across 5 global divisions.',\n  skills: ['Executive Leadership', 'Corporate Strategy', 'Enterprise SaaS', 'M&A', 'Culture'],\n  status: 'active',\n  children: [\n    {\n      id: 'emp-eng-vp',\n      name: 'Marcus Vance',\n      role: 'VP of Engineering',\n      department: 'Engineering',\n      email: 'marcus.vance@acme.corp',\n      phone: '+1 (212) 745-9921',\n      location: 'New York, NY',\n      avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n      initials: 'MV',\n      reportsCount: 3,\n      teamHeadcount: 64,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'March 2020',\n      tenure: '4 yrs 6 mos',\n      bio: 'Leads 64 engineers across platform architecture, frontend infrastructure, and Site Reliability Engineering with 99.99% uptime SLA.',\n      skills: ['Distributed Systems', 'Cloud Architecture', 'Tech Strategy', 'Kubernetes', 'Scalability'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-eng-lead-1',\n          name: 'Alex Rivera',\n          role: 'Principal Architect',\n          department: 'Engineering',\n          email: 'alex.rivera@acme.corp',\n          phone: '+1 (512) 634-1109',\n          location: 'Austin, TX',\n          avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=160&auto=format&fit=crop&q=80',\n          initials: 'AR',\n          reportsCount: 2,\n          teamHeadcount: 18,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'September 2020',\n          tenure: '4 yrs',\n          bio: 'Designs core distributed event pipelines, data mesh architecture, and multi-tenant database infrastructure.',\n          skills: ['Go', 'Kafka', 'PostgreSQL', 'System Architecture', 'Event Streaming'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-1',\n              name: 'Kai Zhang',\n              role: 'Senior Backend Engineer',\n              department: 'Engineering',\n              email: 'kai.zhang@acme.corp',\n              phone: '+1 (512) 634-1188',\n              location: 'Austin, TX',\n              avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n              initials: 'KZ',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-1',\n              managerName: 'Alex Rivera',\n              managerRole: 'Principal Architect',\n              startDate: 'January 2022',\n              tenure: '2 yrs 8 mos',\n              bio: 'Builds low-latency gRPC services, consensus layers, and distributed caching protocols.',\n              skills: ['Rust', 'gRPC', 'Raft', 'Redis', 'High Throughput'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-2',\n              name: 'Hannah Schmidt',\n              role: 'Staff Database Architect',\n              department: 'Engineering',\n              email: 'hannah.schmidt@acme.corp',\n              phone: '+1 (512) 634-1192',\n              location: 'Remote, US',\n              avatar: 'https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=160&auto=format&fit=crop&q=80',\n              initials: 'HS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-1',\n              managerName: 'Alex Rivera',\n              managerRole: 'Principal Architect',\n              startDate: 'May 2021',\n              tenure: '3 yrs 4 mos',\n              bio: 'Specializes in multi-master replication, query optimization, and automated sharding migrations.',\n              skills: ['PostgreSQL', 'CockroachDB', 'Data Warehousing', 'Query Tuning'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-eng-lead-2',\n          name: 'Sofia Rossi',\n          role: 'Staff Frontend Lead',\n          department: 'Engineering',\n          email: 'sofia.rossi@acme.corp',\n          phone: '+49 30 2219 4481',\n          location: 'Berlin, Germany',\n          avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n          initials: 'SR',\n          reportsCount: 2,\n          teamHeadcount: 24,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'November 2020',\n          tenure: '3 yrs 10 mos',\n          bio: 'Leads the unified component design system, micro-frontend architecture, and web accessibility standards.',\n          skills: ['Vue 3', 'React', 'Design Systems', 'Web Performance', 'WCAG AA'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-3',\n              name: 'Leo Garcia',\n              role: 'Senior UI Engineer',\n              department: 'Engineering',\n              email: 'leo.garcia@acme.corp',\n              phone: '+49 30 2219 4490',\n              location: 'Berlin, Germany',\n              avatar: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=160&auto=format&fit=crop&q=80',\n              initials: 'LG',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-2',\n              managerName: 'Sofia Rossi',\n              managerRole: 'Staff Frontend Lead',\n              startDate: 'February 2022',\n              tenure: '2 yrs 7 mos',\n              bio: 'Focuses on complex interactive data visualization canvases, charts, and keyboard shortcuts engine.',\n              skills: ['TypeScript', 'Tailwind CSS', 'D3.js', 'Canvas API'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-4',\n              name: 'Nina Patel',\n              role: 'Frontend Platform Engineer',\n              department: 'Engineering',\n              email: 'nina.patel@acme.corp',\n              phone: '+44 20 8123 9940',\n              location: 'London, UK',\n              avatar: 'https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=160&auto=format&fit=crop&q=80',\n              initials: 'NP',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-2',\n              managerName: 'Sofia Rossi',\n              managerRole: 'Staff Frontend Lead',\n              startDate: 'October 2022',\n              tenure: '1 yr 11 mos',\n              bio: 'Manages automated bundle size budgets, CI build plugins, and island rendering hydration pipelines.',\n              skills: ['Vite', 'Turborepo', 'Playwright', 'ESBuild'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-eng-lead-3',\n          name: 'Tariq Mansour',\n          role: 'DevOps & SRE Lead',\n          department: 'Engineering',\n          email: 'tariq.mansour@acme.corp',\n          phone: '+1 (415) 555-8910',\n          location: 'San Francisco, CA',\n          avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=160&auto=format&fit=crop&q=80',\n          initials: 'TM',\n          reportsCount: 2,\n          teamHeadcount: 22,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'January 2021',\n          tenure: '3 yrs 8 mos',\n          bio: 'Directs cloud infrastructure resilience, multi-region Kubernetes clusters, and automated zero-downtime rollouts.',\n          skills: ['AWS', 'Terraform', 'Kubernetes', 'CI/CD', 'Observability'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-5',\n              name: 'Kiran Rao',\n              role: 'Senior SRE Engineer',\n              department: 'Engineering',\n              email: 'kiran.rao@acme.corp',\n              phone: '+1 (415) 555-8933',\n              location: 'San Francisco, CA',\n              avatar: 'https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?w=160&auto=format&fit=crop&q=80',\n              initials: 'KR',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-3',\n              managerName: 'Tariq Mansour',\n              managerRole: 'DevOps & SRE Lead',\n              startDate: 'August 2022',\n              tenure: '2 yrs 1 mo',\n              bio: 'Maintains Prometheus/Grafana telemetry stacks, SLO/SLI tracking dashboards, and disaster drills.',\n              skills: ['Prometheus', 'Grafana', 'OpenTelemetry', 'Chaos Engineering'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-6',\n              name: 'Elena Dubois',\n              role: 'Cloud Security Specialist',\n              department: 'Engineering',\n              email: 'elena.dubois@acme.corp',\n              phone: '+33 1 42 68 55 00',\n              location: 'Paris, France',\n              avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n              initials: 'ED',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-3',\n              managerName: 'Tariq Mansour',\n              managerRole: 'DevOps & SRE Lead',\n              startDate: 'March 2023',\n              tenure: '1 yr 6 mos',\n              bio: 'Owns zero-trust cloud network topology, HashiCorp Vault key rotation, and automated CVE vulnerability audits.',\n              skills: ['Vault', 'OIDC', 'IAM Hardening', 'SOC 2 Type II'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 'emp-prod-vp',\n      name: 'Elena Rostova',\n      role: 'VP of Product & Design',\n      department: 'Product',\n      email: 'elena.rostova@acme.corp',\n      phone: '+44 20 7946 0912',\n      location: 'London, UK',\n      avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=160&auto=format&fit=crop&q=80',\n      initials: 'ER',\n      reportsCount: 2,\n      teamHeadcount: 40,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'June 2020',\n      tenure: '4 yrs 3 mos',\n      bio: 'Guides end-to-end product vision, quarterly roadmap discovery cycles, and customer experience excellence across enterprise tools.',\n      skills: ['Product Strategy', 'Design Leadership', 'User Research', 'PLG', 'Enterprise UX'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-prod-lead-1',\n          name: 'Maya Patel',\n          role: 'Head of Product Design',\n          department: 'Design',\n          email: 'maya.patel@acme.corp',\n          phone: '+44 20 7946 0988',\n          location: 'London, UK',\n          avatar: 'https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?w=160&auto=format&fit=crop&q=80',\n          initials: 'MP',\n          reportsCount: 2,\n          teamHeadcount: 18,\n          managerId: 'emp-prod-vp',\n          managerName: 'Elena Rostova',\n          managerRole: 'VP of Product & Design',\n          startDate: 'February 2021',\n          tenure: '3 yrs 7 mos',\n          bio: 'Leads our 18-member UI/UX and design research studio, creating intuitive interfaces for data-intensive enterprise users.',\n          skills: ['Figma', 'UX Research', 'Design Systems', 'Design Operations'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-des-ic-1',\n              name: 'Aria Thorne',\n              role: 'Lead UX Researcher',\n              department: 'Design',\n              email: 'aria.thorne@acme.corp',\n              phone: '+1 (415) 321-7789',\n              location: 'San Francisco, CA',\n              avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n              initials: 'AT',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-1',\n              managerName: 'Maya Patel',\n              managerRole: 'Head of Product Design',\n              startDate: 'July 2022',\n              tenure: '2 yrs 2 mos',\n              bio: 'Conducts qualitative enterprise customer interview loops, card sorting, and workflow pain-point mapping.',\n              skills: ['Qualitative Analysis', 'Usability Testing', 'Personas', 'Journey Mapping'],\n              status: 'active',\n            },\n            {\n              id: 'emp-des-ic-2',\n              name: 'Lucas Silva',\n              role: 'Senior Interaction Designer',\n              department: 'Design',\n              email: 'lucas.silva@acme.corp',\n              phone: '+351 21 098 7654',\n              location: 'Lisbon, Portugal',\n              avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=160&auto=format&fit=crop&q=80',\n              initials: 'LS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-1',\n              managerName: 'Maya Patel',\n              managerRole: 'Head of Product Design',\n              startDate: 'November 2022',\n              tenure: '1 yr 10 mos',\n              bio: 'Architects micro-interactions, spring animation specs, and tactile feedback patterns across web and desktop.',\n              skills: ['Framer', 'Prototyping', 'Micro-interactions', 'Token Systems'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-prod-lead-2',\n          name: 'Liam Tanaka',\n          role: 'Principal Product Manager',\n          department: 'Product',\n          email: 'liam.tanaka@acme.corp',\n          phone: '+81 3 5555 0142',\n          location: 'Tokyo, Japan',\n          avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n          initials: 'LT',\n          reportsCount: 2,\n          teamHeadcount: 22,\n          managerId: 'emp-prod-vp',\n          managerName: 'Elena Rostova',\n          managerRole: 'VP of Product & Design',\n          startDate: 'August 2021',\n          tenure: '3 yrs 1 mo',\n          bio: 'Spearheads core enterprise workflow automation, AI copilots, and monetization experiments across global markets.',\n          skills: ['Product Roadmapping', 'AI Integration', 'Data Analytics', 'Enterprise Growth'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-prod-ic-1',\n              name: 'Devon Vance',\n              role: 'Senior Technical PM',\n              department: 'Product',\n              email: 'devon.vance@acme.corp',\n              phone: '+1 (212) 745-3390',\n              location: 'New York, NY',\n              avatar: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=160&auto=format&fit=crop&q=80',\n              initials: 'DV',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-2',\n              managerName: 'Liam Tanaka',\n              managerRole: 'Principal Product Manager',\n              startDate: 'April 2023',\n              tenure: '1 yr 5 mos',\n              bio: 'Defines developer API contracts, webhook architectures, and 3rd party integration partner specifications.',\n              skills: ['API Specs', 'OpenAPI', 'Webhooks', 'Partner Integrations'],\n              status: 'active',\n            },\n            {\n              id: 'emp-prod-ic-2',\n              name: 'Sarah Lin',\n              role: 'Product Analytics Lead',\n              department: 'Product',\n              email: 'sarah.lin@acme.corp',\n              phone: '+81 3 5555 0199',\n              location: 'Tokyo, Japan',\n              avatar: 'https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=160&auto=format&fit=crop&q=80',\n              initials: 'SL',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-2',\n              managerName: 'Liam Tanaka',\n              managerRole: 'Principal Product Manager',\n              startDate: 'January 2023',\n              tenure: '1 yr 8 mos',\n              bio: 'Models customer retention cohorts, feature usage drop-off rates, and self-service conversion funnels.',\n              skills: ['SQL', 'Mixpanel', 'Cohort Retention', 'A/B Testing'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 'emp-ops-vp',\n      name: 'David Chen',\n      role: 'VP of Operations & Finance',\n      department: 'Operations',\n      email: 'david.chen@acme.corp',\n      phone: '+65 6789 0123',\n      location: 'Singapore',\n      avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=160&auto=format&fit=crop&q=80',\n      initials: 'DC',\n      reportsCount: 2,\n      teamHeadcount: 44,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'August 2021',\n      tenure: '3 yrs 1 mo',\n      bio: 'Manages worldwide financial planning, global entity setup, real estate facilities, and international compliance operations.',\n      skills: ['Financial Modeling', 'Corporate Finance', 'Global Compliance', 'Treasury', 'Operations'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-ops-lead-1',\n          name: 'Chloe Dupont',\n          role: 'Director of Finance',\n          department: 'Operations',\n          email: 'chloe.dupont@acme.corp',\n          phone: '+33 1 42 68 90 12',\n          location: 'Paris, France',\n          avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=160&auto=format&fit=crop&q=80',\n          initials: 'CD',\n          reportsCount: 2,\n          teamHeadcount: 20,\n          managerId: 'emp-ops-vp',\n          managerName: 'David Chen',\n          managerRole: 'VP of Operations & Finance',\n          startDate: 'March 2022',\n          tenure: '2 yrs 6 mos',\n          bio: 'Leads FP&A, annual budgeting models, GAAP audits, and international cross-border tax compliance.',\n          skills: ['FP&A', 'GAAP Audits', 'Treasury Management', 'Tax Modeling'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-ops-ic-1',\n              name: 'Arthur Leclerc',\n              role: 'Senior Financial Analyst',\n              department: 'Operations',\n              email: 'arthur.leclerc@acme.corp',\n              phone: '+33 1 42 68 90 33',\n              location: 'Paris, France',\n              avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=160&auto=format&fit=crop&q=80',\n              initials: 'AL',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-1',\n              managerName: 'Chloe Dupont',\n              managerRole: 'Director of Finance',\n              startDate: 'November 2022',\n              tenure: '1 yr 10 mos',\n              bio: 'Analyzes recurring SaaS revenue trends, customer lifetime values, and department OPEX burn rates.',\n              skills: ['Financial Forecasting', 'Excel Modeling', 'ARR Accounting'],\n              status: 'active',\n            },\n            {\n              id: 'emp-ops-ic-2',\n              name: 'Zoe Martinez',\n              role: 'Global Payroll & Benefits Lead',\n              department: 'Operations',\n              email: 'zoe.martinez@acme.corp',\n              phone: '+34 91 555 0177',\n              location: 'Madrid, Spain',\n              avatar: 'https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=160&auto=format&fit=crop&q=80',\n              initials: 'ZM',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-1',\n              managerName: 'Chloe Dupont',\n              managerRole: 'Director of Finance',\n              startDate: 'June 2023',\n              tenure: '1 yr 3 mos',\n              bio: 'Oversees payroll runs across 12 countries, international equity plans, and local pension schemes.',\n              skills: ['Global Payroll', 'Equity Schemes', 'Statutory Benefits'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-ops-lead-2',\n          name: 'James Wilson',\n          role: 'Director of Global Operations',\n          department: 'Operations',\n          email: 'james.wilson@acme.corp',\n          phone: '+1 (212) 745-8812',\n          location: 'New York, NY',\n          avatar: 'https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?w=160&auto=format&fit=crop&q=80',\n          initials: 'JW',\n          reportsCount: 2,\n          teamHeadcount: 24,\n          managerId: 'emp-ops-vp',\n          managerName: 'David Chen',\n          managerRole: 'VP of Operations & Finance',\n          startDate: 'May 2022',\n          tenure: '2 yrs 4 mos',\n          bio: 'Oversees global facilities, vendor procurement relationships, workplace experience, and corporate IT hardware fleets.',\n          skills: ['Vendor Negotiations', 'Facilities Management', 'Asset Tracking', 'Workplace Ops'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-ops-ic-3',\n              name: 'Rachel Green',\n              role: 'Workplace Experience Manager',\n              department: 'Operations',\n              email: 'rachel.green@acme.corp',\n              phone: '+1 (212) 745-8833',\n              location: 'New York, NY',\n              avatar: 'https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?w=160&auto=format&fit=crop&q=80',\n              initials: 'RG',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-2',\n              managerName: 'James Wilson',\n              managerRole: 'Director of Global Operations',\n              startDate: 'January 2023',\n              tenure: '1 yr 8 mos',\n              bio: 'Coordinates global office events, collaborative space design, catering vendors, and team onsites.',\n              skills: ['Event Planning', 'Space Management', 'Culture Initiatives'],\n              status: 'active',\n            },\n            {\n              id: 'emp-ops-ic-4',\n              name: 'Vikram Seth',\n              role: 'IT Systems & Security Lead',\n              department: 'Operations',\n              email: 'vikram.seth@acme.corp',\n              phone: '+65 6789 0188',\n              location: 'Singapore',\n              avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n              initials: 'VS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-2',\n              managerName: 'James Wilson',\n              managerRole: 'Director of Global Operations',\n              startDate: 'October 2022',\n              tenure: '1 yr 11 mos',\n              bio: 'Manages enterprise MDM configurations, Okta SSO provisioning, and hardware lifecycle deployment.',\n              skills: ['Okta SSO', 'Jamf MDM', 'Endpoint Security', 'Hardware Logistics'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n  ],\n}\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/org-chart-data.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/avatar.json",
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/separator.json"
  ],
  "description": "Interactive organizational hierarchy tree with manager reporting lines, team counts, multi-level expandable branches, department filter pills, employee search, and an employee profile quick info drawer.",
  "categories": [
    "hr",
    "app"
  ]
}