@james_sww/metaform-asset-distribution 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +8 -6
  2. package/codebase/codebase.json +5 -4
  3. package/codebase/template/.metaform/template-overrides.json +24 -0
  4. package/codebase/template/index.html +1 -1
  5. package/codebase/template/src/layouts/role-workspace-shell.tsx +136 -48
  6. package/codebase/template/src/workspace/default-workspace.tsx +1 -1
  7. package/dist/application-source.d.ts +5 -3
  8. package/dist/application-source.js +43 -32
  9. package/dist/contracts.d.ts +6 -1
  10. package/dist/contracts.js +1 -1
  11. package/dist/export-source.js +3 -3
  12. package/dist/prepare.d.ts +1 -1
  13. package/dist/prepare.js +41 -25
  14. package/dist/source-map.d.ts +2 -1
  15. package/dist/source-map.js +10 -8
  16. package/package.json +2 -2
  17. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/catalog.json +1 -0
  18. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/common-semantic-region-scaffold.json +1 -0
  19. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-icons.json +1 -0
  20. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-types.json +1 -0
  21. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-common-semantic-region-contract.json +1 -0
  22. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-account.json +1 -0
  23. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-icons.json +1 -0
  24. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-routes.json +1 -0
  25. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-types.json +1 -0
  26. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json +1 -0
  27. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/quality-role-task-groups.json +1 -0
  28. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/quality-role-task-overview.json +1 -0
  29. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/role-workspace-shell.json +1 -0
  30. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-styles.json +1 -0
  31. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-theme-tokens.json +1 -0
  32. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-avatar.json +1 -0
  33. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-badge.json +1 -0
  34. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-button.json +1 -0
  35. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-collapsible.json +1 -0
  36. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-dropdown-menu.json +1 -0
  37. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-empty.json +1 -0
  38. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-sheet.json +1 -0
  39. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-skeleton.json +1 -0
  40. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-tooltip.json +1 -0
  41. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/registry.json +1 -0
  42. package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/release.json +1 -0
  43. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/catalog.json +1 -0
  44. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/common-semantic-region-scaffold.json +1 -0
  45. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-business-role-tasks-icons.json +1 -0
  46. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-business-role-tasks-types.json +1 -0
  47. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-common-semantic-region-contract.json +1 -0
  48. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-account.json +1 -0
  49. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-icons.json +1 -0
  50. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-routes.json +1 -0
  51. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-types.json +1 -0
  52. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/lib-utils.json +1 -0
  53. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/quality-role-task-groups.json +1 -0
  54. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/quality-role-task-overview.json +1 -0
  55. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/role-workspace-shell.json +1 -0
  56. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/styles-styles.json +1 -0
  57. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/styles-theme-tokens.json +1 -0
  58. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-avatar.json +1 -0
  59. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-badge.json +1 -0
  60. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-button.json +1 -0
  61. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-collapsible.json +1 -0
  62. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-dropdown-menu.json +1 -0
  63. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-empty.json +1 -0
  64. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-sheet.json +1 -0
  65. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-skeleton.json +1 -0
  66. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-tooltip.json +1 -0
  67. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/registry.json +1 -0
  68. package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/release.json +1 -0
  69. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/catalog.json +1 -0
  70. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/common-semantic-region-scaffold.json +1 -0
  71. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-business-role-tasks-icons.json +1 -0
  72. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-business-role-tasks-types.json +1 -0
  73. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-common-semantic-region-contract.json +1 -0
  74. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/lib-utils.json +1 -0
  75. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/quality-role-task-groups.json +1 -0
  76. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/quality-role-task-overview.json +1 -0
  77. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/styles-styles.json +1 -0
  78. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/styles-theme-tokens.json +1 -0
  79. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-badge.json +1 -0
  80. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-button.json +1 -0
  81. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-collapsible.json +1 -0
  82. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-empty.json +1 -0
  83. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/registry.json +1 -0
  84. package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/release.json +1 -0
  85. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/catalog.json +1 -0
  86. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/common-semantic-region-scaffold.json +1 -0
  87. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-business-role-tasks-icons.json +1 -0
  88. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-business-role-tasks-types.json +1 -0
  89. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-common-semantic-region-contract.json +1 -0
  90. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/lib-utils.json +1 -0
  91. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/quality-role-task-groups.json +1 -0
  92. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/quality-role-task-overview.json +1 -0
  93. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/styles-styles.json +1 -0
  94. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/styles-theme-tokens.json +1 -0
  95. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-badge.json +1 -0
  96. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-button.json +1 -0
  97. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-collapsible.json +1 -0
  98. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-empty.json +1 -0
  99. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/registry.json +1 -0
  100. package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/release.json +1 -0
  101. package/registry/release.json +1 -1
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8"],"description":"quality.role-task-groups","files":[{"content":"import \"../../../styles/styles.css\";\nimport { useId } from \"react\";\n\nimport { Badge } from \"../../ui/badge\";\nimport { Button } from \"../../ui/button\";\nimport { Empty, EmptyTitle } from \"../../ui/empty\";\n\nimport { RoleTaskIcon } from \"./icons\";\nimport type { RoleTask, RoleTaskGroupsProps } from \"./types\";\n\nexport type { RoleTaskGroupsProps } from \"./types\";\n\ntype PendingTone = 'primary' | 'accent' | 'neutral';\n\nfunction resolvePendingTone(task: RoleTask): PendingTone {\n if (task.pendingActionTone) return task.pendingActionTone;\n if (task.pendingItemCount !== null && task.pendingItemCount > 1) return 'primary';\n if (task.pendingItemCount === 1) return 'accent';\n return 'neutral';\n}\n\nconst pendingButtonClass: Record<PendingTone, string> = {\n primary:\n 'bg-link font-semibold text-action-foreground hover:bg-link-hover hover:text-action-foreground',\n accent:\n 'border-link bg-transparent font-semibold text-link shadow-none hover:bg-muted hover:text-link',\n neutral:\n 'border-border bg-muted/40 font-semibold text-muted-foreground shadow-none hover:bg-muted hover:text-muted-foreground',\n};\n\nexport function RoleTaskGroups({ groups, commands }: RoleTaskGroupsProps) {\n const prefix = useId();\n if (groups.length === 0)\n return (\n <Empty>\n <EmptyTitle className=\"text-sm\">暂无岗位任务</EmptyTitle>\n </Empty>\n );\n return (\n <div className=\"space-y-7\">\n {groups.map((group, index) => (\n <section key={group.id} aria-labelledby={`${prefix}-${index}`}>\n <div className=\"mb-2.5 flex flex-wrap items-baseline gap-x-5 gap-y-1\">\n <h2\n id={`${prefix}-${index}`}\n className=\"text-lg leading-7 font-semibold text-foreground\"\n >\n {group.title}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n <span className=\"tabular-nums\">{group.tasks.length}</span> 项任务 ·{' '}\n {group.description}\n </p>\n </div>\n {group.tasks.length === 0 ? (\n <Empty>\n <EmptyTitle className=\"text-sm\">此分组暂无岗位任务</EmptyTitle>\n </Empty>\n ) : (\n <div className=\"grid grid-cols-1 gap-2.5 md:grid-cols-2\">\n {group.tasks.map((task) => {\n const pendingTone = resolvePendingTone(task);\n return (\n <article\n key={task.id}\n aria-label={task.title}\n className=\"flex min-w-0 flex-col rounded-xl border border-border bg-card px-5 py-4 shadow-2xs\"\n >\n <div className=\"flex items-start gap-5\">\n {task.icon ? (\n <span\n aria-hidden=\"true\"\n className={`flex size-11 shrink-0 items-center justify-center rounded-lg [&_svg]:size-5 ${task.iconTone === 'support' ? 'bg-brand-support-soft text-brand-support-strong' : task.iconTone === 'warning' ? 'bg-warning-soft text-warning-foreground' : 'bg-link/10 text-link'}`}\n >\n {task.icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <Badge\n variant=\"secondary\"\n className=\"h-6 rounded-md bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\"\n >\n {task.typeLabel}\n </Badge>\n <p className=\"text-sm text-muted-foreground\">\n 关联事项{' '}\n <span\n className={`ml-1.5 text-lg leading-7 font-semibold tabular-nums ${task.relatedItemCount !== null && task.relatedItemCount > 0 ? 'text-foreground' : 'text-muted-foreground'}`}\n >\n {task.relatedItemCount ?? '—'}\n </span>\n </p>\n </div>\n <h3 className=\"mt-2 text-base leading-6 font-semibold text-foreground\">\n {task.title}\n </h3>\n <p className=\"mt-1 break-words text-sm leading-5 text-muted-foreground\">\n {task.description}\n </p>\n </div>\n </div>\n <div className=\"mt-auto flex flex-wrap items-center justify-between gap-2 pt-3\">\n <Button\n type=\"button\"\n variant={pendingTone === 'primary' ? 'default' : 'outline'}\n className={pendingButtonClass[pendingTone]}\n disabled={task.viewPendingDisabled}\n onClick={() => commands.onViewPendingItems(task, group)}\n aria-label={`${task.title}:查看待办事项(${task.pendingItemCount ?? '—'})`}\n >\n <span>\n 查看待办事项{' '}\n <span className=\"tabular-nums\">({task.pendingItemCount ?? '—'})</span>\n </span>\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost-neutral\"\n className=\"h-9 gap-1.5 px-0 text-sm font-medium hover:bg-transparent has-[>svg]:px-0\"\n disabled={task.openTaskDisabled}\n onClick={() => commands.onOpenTask(task, group)}\n aria-label={`${task.title}:打开任务界面`}\n >\n 打开任务界面 <RoleTaskIcon name=\"arrowUpRight\" />\n </Button>\n </div>\n </article>\n );\n })}\n </div>\n )}\n </section>\n ))}\n </div>\n );\n}\n","path":"src/components/business/role-tasks/role-task-groups.tsx","target":"~/src/components/business/role-tasks/role-task-groups.tsx","type":"registry:file"}],"meta":{"assetId":"quality.role-task-groups","contractRef":"business/quality/src/role-tasks/role-task-groups.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"quality-role-task-groups","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-icons.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-types.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-styles.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-badge.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-button.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-empty.json"],"title":"quality.role-task-groups","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8"],"description":"quality.role-task-overview","files":[{"content":"import \"../../../styles/styles.css\";\nimport { useId } from \"react\";\n\nimport { Button } from \"../../ui/button\";\n\nimport { RoleTaskIcon } from \"./icons\";\nimport type { RoleTaskOverviewProps } from \"./types\";\n\nexport type { RoleTaskOverviewProps } from \"./types\";\n\nexport function RoleTaskOverview({ model, commands }: RoleTaskOverviewProps) {\n const titleId = useId();\n return (\n <section aria-labelledby={titleId} className=\"space-y-5\">\n <div className=\"rounded-2xl border border-border bg-card px-5 py-4 shadow-2xs\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between lg:gap-8\">\n <div className=\"flex min-w-0 items-center gap-4\">\n {model.icon ? (\n <span\n aria-hidden=\"true\"\n className=\"flex size-12 shrink-0 items-center justify-center rounded-lg bg-link/10 text-link [&_svg]:size-6\"\n >\n {model.icon}\n </span>\n ) : null}\n <div className=\"min-w-0\">\n <h2 id={titleId} className=\"text-[22px] leading-8 font-semibold text-foreground\">\n {model.stageName}\n </h2>\n <p className=\"mt-0.5 text-sm leading-5 text-muted-foreground\">\n {model.stageDescription}\n </p>\n </div>\n </div>\n <dl className=\"flex shrink-0 flex-wrap items-center gap-y-2 text-sm [&>div]:mr-4 [&>div]:border-r [&>div]:border-border [&>div]:pr-4 [&>div:last-of-type]:mr-0 [&>div:last-of-type]:border-r-0 [&>div:last-of-type]:pr-0\">\n <div className=\"flex items-center gap-2\">\n <dt className=\"text-muted-foreground\">当前角色</dt>\n <dd className=\"font-semibold text-foreground\">{model.roleLabel}</dd>\n </div>\n <div className=\"flex items-center gap-2\">\n <dt className=\"text-muted-foreground\">岗位任务</dt>\n <dd className=\"font-semibold tabular-nums text-foreground\">\n {model.taskCount ?? '—'} 项\n </dd>\n </div>\n <div className=\"flex items-center gap-2\">\n <dt className=\"text-muted-foreground\">关联事项</dt>\n <dd className=\"font-semibold tabular-nums text-foreground\">\n {model.relatedItemCount ?? '—'} 项\n </dd>\n </div>\n {model.scopeLabel ? (\n <div className=\"text-muted-foreground\">\n <dt className=\"sr-only\">统计范围</dt>\n <dd>{model.scopeLabel}</dd>\n </div>\n ) : null}\n </dl>\n </div>\n </div>\n <div className=\"flex min-h-12 flex-wrap items-center justify-between gap-3 rounded-xl border border-link/20 bg-link/10 px-4 py-2\">\n <p className=\"flex min-w-0 items-center gap-3 text-sm text-foreground\">\n <span\n aria-hidden=\"true\"\n className=\"flex size-8 shrink-0 items-center justify-center rounded-full bg-card text-link\"\n >\n <RoleTaskIcon name=\"target\" className=\"size-4\" />\n </span>\n <span>\n <span className=\"font-semibold\">岗位目标:</span>\n <span className=\"text-muted-foreground\">{model.goal}</span>\n </span>\n </p>\n <div className=\"flex flex-wrap items-center\">\n {commands?.onViewValue ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 gap-1 rounded-none px-3 text-sm font-medium text-link hover:bg-transparent hover:text-link-hover\"\n disabled={commands.onViewValue.disabled}\n onClick={commands.onViewValue.onSelect}\n >\n 查看业务价值关联 <RoleTaskIcon name=\"arrowUpRight\" />\n </Button>\n ) : null}\n {commands?.onViewValue && commands?.onViewWorkItems ? (\n <span aria-hidden=\"true\" className=\"h-4 w-px bg-border\" />\n ) : null}\n {commands?.onViewWorkItems ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 gap-1 rounded-none px-3 text-sm font-medium text-link hover:bg-transparent hover:text-link-hover\"\n disabled={commands.onViewWorkItems.disabled}\n onClick={commands.onViewWorkItems.onSelect}\n >\n <span>\n 我的处理事项\n {model.workItemCount !== undefined ? (\n <span className=\"tabular-nums\"> ({model.workItemCount ?? '—'})</span>\n ) : null}\n </span>\n <RoleTaskIcon name=\"arrowRight\" />\n </Button>\n ) : null}\n </div>\n </div>\n </section>\n );\n}\n","path":"src/components/business/role-tasks/role-task-overview.tsx","target":"~/src/components/business/role-tasks/role-task-overview.tsx","type":"registry:file"}],"meta":{"assetId":"quality.role-task-overview","contractRef":"business/quality/src/role-tasks/role-task-overview.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"quality-role-task-overview","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-icons.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-types.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-styles.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-button.json"],"title":"quality.role-task-overview","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","lucide-react@0.468.0"],"description":"role-workspace-shell","files":[{"content":"import \"../styles/styles.css\";\nimport { type ReactNode, useId, useRef, useState } from \"react\";\n\nimport { ChevronLeft, ChevronRight, Layers3 } from \"lucide-react\";\n\nimport { Button } from \"../components/ui/button\";\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"../components/ui/sheet\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip\";\nimport { cn } from \"../lib/utils\";\n\nimport { WorkspaceAccount } from \"./role-workspace-account\";\nimport {\n WorkspaceBrandMark,\n WorkspaceRouteIcon,\n WorkspaceUtilityIcon,\n} from \"./role-workspace-icons\";\nimport { DEFAULT_WORKSPACE_ROUTES, isWorkspaceRouteId } from \"./role-workspace-routes\";\nimport type {\n RoleWorkspaceShellProps,\n WorkspaceSlot,\n WorkspaceSlotContext,\n WorkspaceTheme,\n} from \"./role-workspace-types\";\n\nexport type {\n RoleWorkspaceShellProps,\n WorkspaceTheme,\n WorkspaceSession,\n WorkspaceSlotContext,\n} from \"./role-workspace-types\";\n\nfunction renderSlot(slot: WorkspaceSlot | undefined, context: WorkspaceSlotContext) {\n return typeof slot === 'function' ? slot(context) : slot;\n}\nfunction hasNode(node: ReactNode) {\n return node !== null && node !== undefined && node !== false && node !== '';\n}\n\nfunction NavigationItem({\n theme,\n activeThemeId,\n onSelect,\n collapsed,\n}: {\n theme: WorkspaceTheme;\n activeThemeId: string;\n onSelect(id: string): void;\n collapsed: boolean;\n}) {\n const active = theme.id === activeThemeId;\n const button = (\n <Button\n type=\"button\"\n variant=\"ghost-neutral\"\n data-route-id={theme.id}\n className={cn(\n // 基础样式\n 'group relative h-auto w-full justify-start gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200',\n \n // 激活状态\n active && [\n 'bg-gradient-to-r from-[var(--theme-accent-soft)] via-[var(--theme-accent-soft)]/50 to-transparent',\n 'shadow-sm',\n 'border-l-2 border-[var(--theme-accent)]',\n 'font-semibold text-[var(--theme-accent)]',\n 'hover:from-[var(--theme-accent-soft)] hover:via-[var(--theme-accent-soft)]/60',\n ],\n \n // 非激活状态\n !active && [\n 'text-foreground/80',\n 'hover:bg-accent/50 hover:text-foreground',\n 'hover:translate-x-0.5 hover:shadow-sm',\n ],\n \n // 计划中状态\n theme.availability === 'planned' && [\n 'cursor-not-allowed opacity-50',\n 'hover:translate-x-0 hover:bg-transparent',\n ],\n \n // 折叠状态\n collapsed && 'justify-center px-2 border-l-0',\n )}\n aria-label={collapsed ? theme.label : undefined}\n aria-current={active ? 'page' : undefined}\n disabled={theme.availability === 'planned'}\n onClick={() => onSelect(theme.id)}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'relative flex size-5 shrink-0 items-center justify-center transition-transform duration-200',\n active ? 'scale-110 text-[var(--theme-accent)]' : 'text-muted-foreground group-hover:scale-105 group-hover:text-foreground',\n )}\n >\n {theme.icon ?? <Layers3 className=\"size-4\" />}\n {/* 激活状态的微妙发光效果 */}\n {active && (\n <span className=\"absolute inset-0 animate-pulse rounded-full bg-[var(--theme-accent-soft)] blur-sm\" />\n )}\n </span>\n {!collapsed ? <span className=\"flex-1 truncate text-left\">{theme.label}</span> : null}\n {!collapsed && theme.count !== undefined && theme.count > 0 ? (\n <span\n className={cn(\n 'flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-[11px] font-semibold shadow-sm transition-all duration-200',\n active\n ? 'bg-primary text-primary-foreground ring-1 ring-primary/20'\n : 'bg-muted text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary'\n )}\n >\n {theme.count > 99 ? '99+' : theme.count}\n </span>\n ) : null}\n {!collapsed && theme.availability === 'planned' ? (\n <span className=\"ml-auto text-[10px] font-medium uppercase tracking-wide text-muted-foreground/60\">\n 即将推出\n </span>\n ) : null}\n </Button>\n );\n return collapsed ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className=\"block\"\n tabIndex={theme.availability === 'planned' ? 0 : undefined}\n aria-label={theme.availability === 'planned' ? `${theme.label}(待开放)` : undefined}\n >\n {button}\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"right\" sideOffset={12}>\n {theme.label}\n {theme.availability === 'planned' ? '(待开放)' : ''}\n </TooltipContent>\n </Tooltip>\n ) : (\n button\n );\n}\n\nfunction ThemeNavigation({\n themes,\n pendingItemCount,\n activeThemeId,\n onSelect,\n collapsed = false,\n}: {\n themes: readonly WorkspaceTheme[];\n pendingItemCount?: number;\n activeThemeId: string;\n onSelect(id: string): void;\n collapsed?: boolean;\n}) {\n const count = pendingItemCount ?? themes.find((theme) => theme.id === 'inbox')?.count;\n const extensions = themes.filter((theme) => !isWorkspaceRouteId(theme.id));\n return (\n <TooltipProvider delayDuration={200}>\n <nav aria-label=\"角色工作主题\" className=\"space-y-1 px-3\">\n {/* 核心视图组 */}\n <div className=\"space-y-1\">\n {!collapsed && (\n <p className=\"mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70\">\n 核心视图\n </p>\n )}\n {DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'value').map((route) => (\n <NavigationItem\n key={route.id}\n theme={{\n ...route,\n availability: 'implemented',\n icon: <WorkspaceRouteIcon id={route.id} />,\n }}\n activeThemeId={activeThemeId}\n onSelect={onSelect}\n collapsed={collapsed}\n />\n ))}\n </div>\n\n {/* 渐变分隔线 */}\n <div className=\"my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent\" />\n\n {/* 待办事项组 */}\n <div className=\"space-y-1\">\n {!collapsed && (\n <p className=\"mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70\">\n 工作台\n </p>\n )}\n {DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'inbox').map((route) => (\n <NavigationItem\n key={route.id}\n theme={{\n ...route,\n availability: 'implemented',\n icon: <WorkspaceRouteIcon id={route.id} />,\n count: route.id === 'inbox' ? count : undefined,\n }}\n activeThemeId={activeThemeId}\n onSelect={onSelect}\n collapsed={collapsed}\n />\n ))}\n </div>\n\n {/* 企业协作组 */}\n {DEFAULT_WORKSPACE_ROUTES.some((route) => route.group === 'enterprise') && (\n <>\n <div className=\"my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent\" />\n <div className=\"space-y-1\">\n {!collapsed && (\n <p className=\"mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70\">\n 协作空间\n </p>\n )}\n {DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'enterprise').map((route) => (\n <NavigationItem\n key={route.id}\n theme={{\n ...route,\n availability: 'implemented',\n icon: <WorkspaceRouteIcon id={route.id} />,\n }}\n activeThemeId={activeThemeId}\n onSelect={onSelect}\n collapsed={collapsed}\n />\n ))}\n </div>\n </>\n )}\n\n {/* 扩展功能 */}\n {extensions.length > 0 && (\n <>\n <div className=\"my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent\" />\n <div className=\"space-y-1\">\n {extensions.map((theme) => (\n <NavigationItem\n key={theme.id}\n theme={theme}\n activeThemeId={activeThemeId}\n onSelect={onSelect}\n collapsed={collapsed}\n />\n ))}\n </div>\n </>\n )}\n </nav>\n </TooltipProvider>\n );\n}\n\nconst NO_THEMES: readonly WorkspaceTheme[] = [];\n\nexport function RoleWorkspaceShell({ model, state, commands, slots }: RoleWorkspaceShellProps) {\n const [internalMenuOpen, setInternalMenuOpen] = useState(false);\n const [internalCollapsed, setInternalCollapsed] = useState(false);\n const [internalToolsOpen, setInternalToolsOpen] = useState(false);\n const menuOpen = state?.mobileMenuOpen ?? internalMenuOpen;\n const collapsed = state?.sidebarCollapsed ?? internalCollapsed;\n const toolsOpen = state?.toolsOpen ?? internalToolsOpen;\n const sidebarId = useId();\n const toolsId = useId();\n const contentId = useId();\n const contentRef = useRef<HTMLElement>(null);\n const themes = model.themes ?? NO_THEMES;\n const context = {\n sidebarCollapsed: collapsed,\n mobileMenuOpen: menuOpen,\n toolsOpen,\n activeThemeId: model.activeThemeId,\n session: model.session,\n };\n const region = (\n name: keyof RoleWorkspaceShellProps['slots'],\n surface: WorkspaceSlotContext['surface'] = 'content',\n ) => renderSlot(slots[name], { ...context, surface });\n const search = region('globalSearch', 'header');\n const globalActions = region('globalActions', 'header');\n const switcher = region('contextSwitcher', 'header');\n const mobileSwitcher = region('contextSwitcher', 'mobile-menu');\n const mobileSearch = region('globalSearch', 'mobile-menu');\n const mobileActions = region('globalActions', 'mobile-menu');\n const toolsPanel = region('toolsPanel', 'tools');\n const banner = region('banner');\n const breadcrumbs = region('breadcrumbs');\n const pageHeader = region('pageHeader');\n const footer = region('footer');\n const sidebarBefore = region('navigationBefore', 'sidebar');\n const sidebarAfter = region('navigationAfter', 'sidebar');\n const sidebarFooter =\n slots.sidebarFooter === undefined ? (\n !collapsed && model.workspaceGoal ? (\n <div className=\"border-t border-border pt-4\">\n <p className=\"text-xs text-muted-foreground\">我的目标</p>\n <p className=\"mt-1 text-sm text-foreground\">{model.workspaceGoal}</p>\n </div>\n ) : null\n ) : (\n region('sidebarFooter', 'sidebar')\n );\n\n function changeMenu(open: boolean) {\n if (state?.mobileMenuOpen === undefined) setInternalMenuOpen(open);\n commands.onMobileMenuOpenChange?.(open);\n }\n function changeCollapsed(value: boolean) {\n if (state?.sidebarCollapsed === undefined) setInternalCollapsed(value);\n commands.onSidebarCollapsedChange?.(value);\n }\n function changeTools(open: boolean) {\n if (state?.toolsOpen === undefined) setInternalToolsOpen(open);\n commands.onToolsOpenChange?.(open);\n }\n function selectTheme(id: string) {\n if (\n !isWorkspaceRouteId(id) &&\n !themes.some((theme) => theme.id === id && theme.availability === 'implemented')\n )\n return;\n commands.onSelectTheme(id);\n changeMenu(false);\n }\n\n return (\n <Sheet open={hasNode(toolsPanel) && toolsOpen} onOpenChange={changeTools}>\n <div className=\"flex h-dvh flex-col overflow-hidden bg-background text-sm text-foreground\">\n <a\n href={`#${contentId}`}\n onClick={(event) => {\n event.preventDefault();\n contentRef.current?.focus();\n }}\n className=\"sr-only z-50 rounded-md bg-card p-3 focus:not-sr-only focus:fixed focus:left-3 focus:top-3\"\n >\n 跳到工作内容\n </a>\n <header className=\"relative z-20 flex h-[60px] shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 shadow-xs md:px-[22px]\">\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <Sheet open={menuOpen} onOpenChange={changeMenu}>\n <SheetTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost-neutral\"\n size=\"icon\"\n title=\"打开主题菜单\"\n className=\"lg:hidden\"\n aria-label=\"打开主题菜单\"\n >\n <WorkspaceUtilityIcon name=\"menu\" />\n </Button>\n </SheetTrigger>\n <SheetContent\n side=\"left\"\n showCloseButton={false}\n className=\"gap-0 overflow-hidden p-0 motion-reduce:animate-none motion-reduce:transition-none\"\n >\n <div className=\"flex items-start justify-between gap-3 border-b border-border px-4 py-3\">\n <SheetHeader className=\"min-w-0 gap-1 p-0\">\n <SheetTitle className=\"truncate text-base\">{model.workspaceTitle}</SheetTitle>\n <SheetDescription>选择要进入的工作主题</SheetDescription>\n </SheetHeader>\n <div className=\"flex shrink-0 items-center gap-1\">\n {hasNode(mobileActions) ? mobileActions : null}\n <SheetClose asChild>\n <Button type=\"button\" variant=\"ghost-neutral\" aria-label=\"关闭主题菜单\">\n 关闭\n </Button>\n </SheetClose>\n </div>\n </div>\n {hasNode(mobileSwitcher) ? (\n <div className=\"border-b border-border px-4 py-3\">{mobileSwitcher}</div>\n ) : null}\n {hasNode(mobileSearch) ? (\n <div className=\"border-b border-border px-4 py-3\">{mobileSearch}</div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto py-3\">\n {region('navigationBefore', 'mobile-menu')}\n <ThemeNavigation\n themes={themes}\n pendingItemCount={model.pendingItemCount}\n activeThemeId={model.activeThemeId}\n onSelect={selectTheme}\n />\n {region('navigationAfter', 'mobile-menu')}\n {slots.sidebarFooter !== undefined ? (\n <div className=\"mt-auto px-4 pt-4\">\n {region('sidebarFooter', 'mobile-menu')}\n </div>\n ) : null}\n </div>\n </SheetContent>\n </Sheet>\n {slots.brand === undefined ? (\n <>\n <span\n aria-hidden=\"true\"\n className=\"hidden size-[30px] shrink-0 items-center justify-center rounded-lg bg-brand text-brand-foreground sm:flex\"\n >\n <WorkspaceBrandMark />\n </span>\n <span className=\"truncate text-base font-semibold tracking-tight\">\n {model.productName}\n </span>\n </>\n ) : (\n region('brand', 'header')\n )}\n {hasNode(switcher) ? (\n <div className=\"hidden shrink-0 lg:block\">{switcher}</div>\n ) : slots.contextSwitcher === undefined && model.contextLabel ? (\n <span className=\"hidden truncate border-l border-border pl-3.5 text-[11px] text-muted-foreground xl:block\">\n {model.contextLabel}\n </span>\n ) : null}\n </div>\n {hasNode(search) ? (\n <div className=\"hidden min-w-0 max-w-72 flex-1 lg:block\">{search}</div>\n ) : null}\n <div className=\"flex min-w-0 shrink-0 items-center gap-2 md:gap-3\">\n {slots.globalActions === undefined ? (\n slots.headerActions\n ) : hasNode(globalActions) ? (\n <div className=\"hidden items-center gap-2 lg:flex\">{globalActions}</div>\n ) : null}\n {hasNode(toolsPanel) ? (\n <SheetTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost-neutral\"\n size=\"icon\"\n title=\"打开工具面板\"\n aria-label=\"打开工具面板\"\n aria-controls={toolsId}\n aria-expanded={toolsOpen}\n >\n <WorkspaceUtilityIcon name=\"tools\" />\n </Button>\n </SheetTrigger>\n ) : null}\n {slots.account === undefined ? (\n <WorkspaceAccount\n model={model}\n commands={commands}\n menu={region('accountMenu', 'header')}\n />\n ) : (\n region('account', 'header')\n )}\n </div>\n </header>\n {hasNode(banner) ? (\n <div className=\"shrink-0 border-b border-border bg-card\">{banner}</div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 overflow-hidden\">\n <aside\n id={sidebarId}\n className={cn(\n 'relative z-10 hidden h-full shrink-0 overflow-visible border-r border-border bg-card transition-[width] duration-200 ease-out motion-reduce:transition-none md:flex md:flex-col',\n collapsed ? 'w-[72px]' : 'w-[264px]',\n )}\n >\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain py-4\">\n {hasNode(sidebarBefore) ? <div className=\"mb-3 px-3\">{sidebarBefore}</div> : null}\n <ThemeNavigation\n themes={themes}\n pendingItemCount={model.pendingItemCount}\n activeThemeId={model.activeThemeId}\n onSelect={selectTheme}\n collapsed={collapsed}\n />\n {hasNode(sidebarAfter) ? <div className=\"mt-3 px-3\">{sidebarAfter}</div> : null}\n {hasNode(sidebarFooter) ? (\n <div className={cn('mt-auto pt-5', collapsed ? 'px-2' : 'px-[23px]')}>\n {sidebarFooter}\n </div>\n ) : null}\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"absolute right-0 top-1/2 z-30 size-9 translate-x-1/2 -translate-y-1/2 rounded-full bg-card shadow-sm hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 active:-translate-y-1/2\"\n aria-controls={sidebarId}\n aria-expanded={!collapsed}\n aria-label={collapsed ? '展开主题导航' : '收起主题导航'}\n title={collapsed ? '展开侧边栏' : '收起侧边栏'}\n onClick={() => changeCollapsed(!collapsed)}\n >\n {collapsed ? <ChevronRight className=\"size-4\" /> : <ChevronLeft className=\"size-4\" />}\n </Button>\n </aside>\n <main\n id={contentId}\n ref={contentRef}\n tabIndex={-1}\n className=\"min-h-0 min-w-0 flex-1 overflow-y-auto overscroll-contain bg-background p-4 outline-none [scrollbar-gutter:stable] scroll-pt-4 md:p-7\"\n >\n {hasNode(breadcrumbs) ? <div className=\"mb-4\">{breadcrumbs}</div> : null}\n {hasNode(pageHeader) ? <div className=\"mb-5\">{pageHeader}</div> : null}\n {region('content')}\n </main>\n </div>\n {hasNode(footer) ? (\n <footer className=\"shrink-0 border-t border-border bg-card px-4 py-2\">{footer}</footer>\n ) : null}\n {hasNode(toolsPanel) ? (\n <SheetContent\n id={toolsId}\n side=\"right\"\n showCloseButton={false}\n className=\"overflow-y-auto motion-reduce:animate-none motion-reduce:transition-none\"\n >\n <SheetHeader className=\"pr-20\">\n <SheetTitle>{model.toolsTitle ?? '工具面板'}</SheetTitle>\n <SheetDescription>查看当前工作空间的辅助内容</SheetDescription>\n </SheetHeader>\n <SheetClose asChild>\n <Button\n type=\"button\"\n variant=\"ghost-neutral\"\n className=\"absolute right-3 top-3\"\n aria-label=\"关闭工具面板\"\n >\n 关闭\n </Button>\n </SheetClose>\n <div className=\"px-4 pb-4\">{toolsPanel}</div>\n </SheetContent>\n ) : null}\n {region('overlays')}\n {slots.assistant}\n </div>\n </Sheet>\n );\n}\n","path":"src/layouts/role-workspace-shell.tsx","target":"~/src/layouts/role-workspace-shell.tsx","type":"registry:file"}],"meta":{"assetId":"role-workspace-shell","contractRef":"platform/src/platform/role-workspace-shell.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"role-workspace-shell","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-account.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-icons.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-routes.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-types.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-styles.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-button.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-sheet.json","http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-tooltip.json"],"title":"role-workspace-shell","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["tw-animate-css@1.4.0"],"description":"styles.styles","files":[{"content":"@import 'tw-animate-css';\n@import './theme-tokens.css';\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-link: var(--link-foreground);\n --color-link-hover: var(--link-hover-foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n --color-brand: var(--brand-accent);\n --color-brand-foreground: var(--brand-accent-foreground);\n --color-brand-hover: var(--brand-accent-hover);\n --color-brand-active: var(--brand-accent-active);\n --color-brand-soft: var(--brand-accent-soft);\n --color-brand-support: var(--brand-support);\n --color-brand-support-strong: var(--brand-support-strong);\n --color-brand-support-soft: var(--brand-support-soft);\n --color-action: var(--action-primary);\n --color-action-hover: var(--action-primary-hover);\n --color-action-active: var(--action-primary-active);\n --color-action-foreground: var(--action-primary-foreground);\n --color-selection: var(--selection);\n --color-selection-foreground: var(--selection-foreground);\n --color-surface-muted: var(--surface-muted);\n --color-surface-muted-foreground: var(--surface-muted-foreground);\n --color-control-hover: var(--control-hover);\n --color-control-active: var(--control-active);\n --color-control-active-foreground: var(--control-active-foreground);\n --color-control-active-border: var(--control-active-border);\n --color-sidebar: var(--sidebar-background);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-data-blue: var(--data-blue);\n --color-data-cyan: var(--data-cyan);\n --color-data-violet: var(--data-violet);\n --color-data-green: var(--data-green);\n --color-data-amber: var(--data-amber);\n --color-data-red: var(--data-red);\n --color-data-business: var(--data-business);\n --color-data-equipment: var(--data-equipment);\n --color-data-process: var(--data-process);\n --color-data-metric: var(--data-metric);\n --color-data-strategy: var(--data-strategy);\n --color-data-business-soft: var(--data-business-soft);\n --color-data-equipment-soft: var(--data-equipment-soft);\n --color-data-process-soft: var(--data-process-soft);\n --color-data-metric-soft: var(--data-metric-soft);\n --color-data-strategy-soft: var(--data-strategy-soft);\n --color-success: var(--semantic-success);\n --color-success-soft: var(--semantic-success-soft);\n --color-success-foreground: var(--semantic-success-foreground);\n --color-warning: var(--semantic-warning);\n --color-warning-soft: var(--semantic-warning-soft);\n --color-warning-foreground: var(--semantic-warning-foreground);\n --color-danger: var(--semantic-danger);\n --color-danger-soft: var(--semantic-danger-soft);\n --color-danger-foreground: var(--semantic-danger-foreground);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n --color-border-soft: var(--border-soft);\n}\n\n/*\n * Match shadcn-admin: default border-color on all elements so width-only\n * utilities (border-b, border, etc.) resolve to --border instead of currentColor.\n */\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n\n [data-sonner-toaster] [data-sonner-toast] {\n background: var(--card) !important;\n border-color: var(--border) !important;\n }\n\n [data-sonner-toaster] [data-sonner-toast][data-type='info'],\n [data-sonner-toaster] [data-sonner-toast][data-type='info'] [data-title],\n [data-sonner-toaster] [data-sonner-toast][data-type='info'] [data-content],\n [data-sonner-toaster] [data-sonner-toast]:not([data-type]),\n [data-sonner-toaster] [data-sonner-toast]:not([data-type]) [data-title],\n [data-sonner-toaster] [data-sonner-toast]:not([data-type]) [data-content] {\n color: var(--brand-accent) !important;\n }\n\n [data-sonner-toaster] [data-sonner-toast][data-type='success'],\n [data-sonner-toaster] [data-sonner-toast][data-type='success'] [data-title],\n [data-sonner-toaster] [data-sonner-toast][data-type='success'] [data-content] {\n color: var(--semantic-success) !important;\n }\n\n [data-sonner-toaster] [data-sonner-toast][data-type='warning'],\n [data-sonner-toaster] [data-sonner-toast][data-type='warning'] [data-title],\n [data-sonner-toaster] [data-sonner-toast][data-type='warning'] [data-content] {\n color: var(--semantic-warning) !important;\n }\n\n [data-sonner-toaster] [data-sonner-toast][data-type='error'],\n [data-sonner-toaster] [data-sonner-toast][data-type='error'] [data-title],\n [data-sonner-toaster] [data-sonner-toast][data-type='error'] [data-content] {\n color: var(--semantic-danger) !important;\n }\n\n [data-sonner-toaster] [data-sonner-toast] [data-description] {\n color: var(--muted-foreground) !important;\n }\n}\n","path":"src/styles/styles.css","target":"~/src/styles/styles.css","type":"registry:file"}],"meta":{"assetId":"styles.styles","contractRef":"vendor/design-system/src/styles.css","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"styles-styles","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-theme-tokens.json"],"title":"styles.styles","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":[],"description":"styles.theme-tokens","files":[{"content":"/* Platform console's always-dark navigation, shared by light and dark modes. */\n[data-sidebar-theme='platform'] {\n --sidebar-background: #17263c;\n --sidebar-foreground: #aebed0;\n --sidebar-border: #2e4055;\n --sidebar-user-foreground: #fff;\n --sidebar-avatar-background: #e4d9c9;\n --sidebar-avatar-foreground: #7a6044;\n --foreground: #fff;\n --muted-foreground: #859bb2;\n --control-hover: #263950;\n --selection: #294c54;\n --selection-foreground: #58d5bd;\n --selection-border: #294c54;\n --ring: #58d5bd;\n}\n\n/*\n * Metaform theme source of truth.\n *\n * Palette tokens never change meaning. Theme role tokens are the only values\n * overridden by a preset, so application code never depends on a brand hex.\n */\n:root {\n --radius: 0.5rem;\n\n /* Fixed palette */\n --palette-ink: oklch(21.01% 0.0318 264.66deg);\n --palette-ink-hover: oklch(27.81% 0.0296 256.85deg);\n --palette-ink-active: oklch(12.96% 0.0274 261.69deg);\n --palette-cobalt: oklch(54.78% 0.1724 265.67deg);\n --palette-cobalt-hover: oklch(47.44% 0.1459 265.64deg);\n --palette-cobalt-active: oklch(39.72% 0.1074 262.56deg);\n --palette-cyan: oklch(71.5% 0.143 215.22deg);\n --palette-teal: oklch(49.5% 0.102 181.5deg);\n --palette-teal-hover: oklch(43.5% 0.092 181.5deg);\n --palette-teal-active: oklch(36% 0.075 181.5deg);\n --palette-steel: oklch(48% 0.065 245deg);\n --palette-steel-hover: oklch(41% 0.06 245deg);\n --palette-steel-active: oklch(33% 0.052 245deg);\n --palette-safety: oklch(66% 0.17 58deg);\n --palette-safety-hover: oklch(57% 0.15 58deg);\n --palette-safety-active: oklch(48% 0.13 58deg);\n --palette-ocean: oklch(49% 0.11 210deg);\n --palette-ocean-hover: oklch(42% 0.1 210deg);\n --palette-ocean-active: oklch(35% 0.082 210deg);\n --palette-white: oklch(98.5% 0.003 247.86deg);\n\n /* Theme roles: neutral is the default preset. */\n --theme-accent: var(--palette-ink);\n --theme-accent-hover: var(--palette-ink-hover);\n --theme-accent-active: var(--palette-ink-active);\n --theme-accent-soft: oklch(96.83% 0.0069 247.9deg);\n --theme-accent-border: oklch(86.9% 0.0198 252.89deg);\n --theme-accent-foreground: var(--palette-white);\n\n /* Auxiliary brand roles: every preset owns the complete family. */\n --theme-support: var(--palette-cobalt);\n --theme-support-strong: var(--palette-teal);\n --theme-support-soft: oklch(96.5% 0.012 230deg);\n --theme-display-gradient-start: var(--palette-cobalt-active);\n --theme-display-gradient-highlight: var(--palette-cyan);\n --theme-display-gradient-end: var(--palette-teal);\n\n /* Stable semantic colors never follow the selected brand theme. */\n --semantic-success: oklch(65.59% 0.1686 146.19deg);\n --semantic-success-soft: oklch(96.3% 0.032 146.19deg);\n --semantic-success-foreground: oklch(40.5% 0.115 146.19deg);\n --semantic-warning: oklch(79.98% 0.1706 72.75deg);\n --semantic-warning-soft: oklch(97.3% 0.035 72.75deg);\n --semantic-warning-foreground: oklch(43% 0.12 72.75deg);\n --semantic-danger: oklch(63.07% 0.201 25.03deg);\n --semantic-danger-soft: oklch(95.8% 0.025 25.03deg);\n --semantic-danger-foreground: oklch(44% 0.16 25.03deg);\n\n /* Surfaces and content */\n --surface-canvas: oklch(97.89% 0.0029 264.54deg);\n --surface-panel: oklch(99.5% 0.002 247.86deg);\n --surface-raised: oklch(100% 0.001 247.86deg);\n --surface-muted: oklch(96.7% 0.004 264.54deg);\n --surface-muted-foreground: var(--text-regular);\n --text-primary: var(--palette-ink);\n --text-regular: oklch(37.3% 0.034 259.73deg);\n --text-secondary: oklch(55.44% 0.0407 257.42deg);\n\n /* Navigation links stay blue independently of the selected brand theme. */\n --link-foreground: var(--palette-cobalt);\n --link-hover-foreground: var(--palette-cobalt-hover);\n --border-base: oklch(92.88% 0.0126 255.51deg);\n --border-soft: oklch(95.5% 0.008 255.51deg);\n --border-input: oklch(84.5% 0.016 255.51deg);\n --control-hover: var(--surface-muted);\n --control-active: var(--selection);\n --control-active-foreground: var(--selection-foreground);\n --control-active-border: var(--selection-border);\n\n /* shadcn focus ring: neutral gray, not brand accent */\n --ring-muted: oklch(70.4% 0.04 256.79deg);\n\n /* Application roles derived from the active theme preset. */\n --brand-accent: var(--theme-accent);\n --brand-accent-hover: var(--theme-accent-hover);\n --brand-accent-active: var(--theme-accent-active);\n --brand-accent-soft: var(--theme-accent-soft);\n --brand-accent-border: var(--theme-accent-border);\n --brand-accent-foreground: var(--theme-accent-foreground);\n --brand-support: var(--theme-support);\n --brand-support-strong: var(--theme-support-strong);\n --brand-support-soft: var(--theme-support-soft);\n --brand-gradient-start: var(--theme-display-gradient-start);\n --brand-gradient-highlight: var(--theme-display-gradient-highlight);\n --brand-gradient-end: var(--theme-display-gradient-end);\n --action-primary: var(--theme-accent);\n --action-primary-hover: var(--theme-accent-hover);\n --action-primary-active: var(--theme-accent-active);\n --action-primary-foreground: var(--theme-accent-foreground);\n --selection: var(--theme-accent-soft);\n --selection-foreground: var(--theme-accent);\n --selection-border: var(--theme-accent-border);\n --selection-strong: var(--theme-accent-active);\n --focus-ring: var(--theme-accent);\n --sidebar-background: var(--surface-panel);\n --sidebar-foreground: var(--text-primary);\n --sidebar-active: var(--selection);\n --sidebar-active-foreground: var(--selection-foreground);\n --sidebar-border: var(--border-base);\n\n /* Data visualization colors are fixed and independent from branding. */\n --data-blue: var(--palette-cobalt);\n --data-cyan: var(--palette-cyan);\n --data-violet: oklch(60.6% 0.196 286.48deg);\n --data-green: var(--semantic-success);\n --data-amber: var(--semantic-warning);\n --data-red: var(--semantic-danger);\n --data-business: var(--palette-teal);\n --data-equipment: var(--semantic-danger);\n --data-process: var(--semantic-warning);\n --data-metric: var(--data-violet);\n --data-strategy: var(--palette-cyan);\n --data-business-soft: color-mix(in oklch, var(--data-business) 10%, var(--surface-panel));\n --data-equipment-soft: color-mix(in oklch, var(--data-equipment) 10%, var(--surface-panel));\n --data-process-soft: color-mix(in oklch, var(--data-process) 10%, var(--surface-panel));\n --data-metric-soft: color-mix(in oklch, var(--data-metric) 10%, var(--surface-panel));\n --data-strategy-soft: color-mix(in oklch, var(--data-strategy) 10%, var(--surface-panel));\n\n /* Theme setting swatches */\n --theme-swatch-neutral: var(--palette-ink);\n --theme-swatch-cobalt: var(--palette-cobalt);\n --theme-swatch-teal: var(--palette-teal);\n --theme-swatch-steel: var(--palette-steel);\n --theme-swatch-safety: var(--palette-safety);\n --theme-swatch-ocean: var(--palette-ocean);\n\n /* shadcn roles */\n --background: var(--surface-canvas);\n --foreground: var(--text-primary);\n --card: var(--surface-panel);\n --card-foreground: var(--text-primary);\n --popover: var(--surface-raised);\n --popover-foreground: var(--text-primary);\n --primary: var(--action-primary);\n --primary-foreground: var(--action-primary-foreground);\n --secondary: var(--surface-muted);\n --secondary-foreground: var(--surface-muted-foreground);\n --muted: var(--surface-muted);\n --muted-foreground: var(--text-secondary);\n --accent: var(--selection);\n --accent-foreground: var(--selection-foreground);\n --destructive: var(--semantic-danger);\n --destructive-foreground: var(--palette-white);\n --border: var(--border-base);\n --input: var(--border-input);\n --ring: var(--brand-accent);\n\n /* Legacy aliases. New code should use role tokens above. */\n --el-color-primary: var(--theme-accent);\n --el-color-primary-hover: var(--theme-accent-hover);\n --el-color-primary-active: var(--theme-accent-active);\n --el-color-primary-light-9: var(--theme-accent-soft);\n --el-color-primary-light-7: var(--theme-accent-border);\n --el-color-action: var(--action-primary);\n --el-color-action-hover: var(--action-primary-hover);\n --el-color-action-active: var(--action-primary-active);\n --el-color-success: var(--semantic-success);\n --el-color-success-light-9: var(--semantic-success-soft);\n --el-color-warning: var(--semantic-warning);\n --el-color-warning-light-9: var(--semantic-warning-soft);\n --el-color-danger: var(--semantic-danger);\n --el-color-danger-light-9: var(--semantic-danger-soft);\n --el-bg-color: var(--surface-canvas);\n --el-text-color-primary: var(--text-primary);\n --el-text-color-regular: var(--text-regular);\n --el-text-color-secondary: var(--text-secondary);\n --el-border-color-base: var(--border-base);\n}\n\n:root[data-accent='cobalt'] {\n --theme-accent: var(--palette-cobalt);\n --theme-accent-hover: var(--palette-cobalt-hover);\n --theme-accent-active: var(--palette-cobalt-active);\n --theme-accent-soft: oklch(95.53% 0.0154 269.98deg);\n --theme-accent-border: oklch(86.49% 0.0463 269.14deg);\n --theme-accent-foreground: var(--palette-white);\n --theme-support: var(--palette-cyan);\n --theme-support-strong: var(--palette-teal);\n --theme-support-soft: oklch(95.5% 0.025 215.22deg);\n --theme-display-gradient-start: var(--palette-cobalt-active);\n --theme-display-gradient-highlight: oklch(70% 0.13 265.67deg);\n --theme-display-gradient-end: var(--palette-cobalt);\n}\n\n:root[data-accent='teal'] {\n --theme-accent: var(--palette-teal);\n --theme-accent-hover: var(--palette-teal-hover);\n --theme-accent-active: var(--palette-teal-active);\n --theme-accent-soft: oklch(96% 0.018 181.5deg);\n --theme-accent-border: oklch(84% 0.045 181.5deg);\n --theme-accent-foreground: var(--palette-white);\n --theme-support: var(--palette-cyan);\n --theme-support-strong: var(--palette-cobalt);\n --theme-support-soft: oklch(95.5% 0.025 205deg);\n --theme-display-gradient-start: var(--palette-teal-active);\n --theme-display-gradient-highlight: oklch(72% 0.1 181.5deg);\n --theme-display-gradient-end: var(--palette-teal);\n}\n\n:root[data-accent='steel'] {\n --theme-accent: var(--palette-steel);\n --theme-accent-hover: var(--palette-steel-hover);\n --theme-accent-active: var(--palette-steel-active);\n --theme-accent-soft: oklch(95.5% 0.012 245deg);\n --theme-accent-border: oklch(84% 0.035 245deg);\n --theme-accent-foreground: var(--palette-white);\n --theme-support: var(--palette-cobalt);\n --theme-support-strong: var(--palette-ocean);\n --theme-support-soft: oklch(95.5% 0.02 225deg);\n --theme-display-gradient-start: var(--palette-steel-active);\n --theme-display-gradient-highlight: oklch(75% 0.08 225deg);\n --theme-display-gradient-end: var(--palette-ocean);\n}\n\n:root[data-accent='safety'] {\n --theme-accent: var(--palette-safety);\n --theme-accent-hover: var(--palette-safety-hover);\n --theme-accent-active: var(--palette-safety-active);\n --theme-accent-soft: oklch(96.5% 0.025 75deg);\n --theme-accent-border: oklch(86% 0.08 70deg);\n --theme-accent-foreground: var(--palette-ink-active);\n --theme-support: var(--palette-ocean);\n --theme-support-strong: var(--palette-steel);\n --theme-support-soft: oklch(95.5% 0.02 210deg);\n --theme-display-gradient-start: var(--palette-safety-active);\n --theme-display-gradient-highlight: oklch(79% 0.11 75deg);\n --theme-display-gradient-end: var(--palette-ocean);\n}\n\n:root[data-accent='ocean'] {\n --theme-accent: var(--palette-ocean);\n --theme-accent-hover: var(--palette-ocean-hover);\n --theme-accent-active: var(--palette-ocean-active);\n --theme-accent-soft: oklch(95.5% 0.02 210deg);\n --theme-accent-border: oklch(84% 0.055 210deg);\n --theme-accent-foreground: var(--palette-white);\n --theme-support: var(--palette-cyan);\n --theme-support-strong: var(--palette-steel);\n --theme-support-soft: oklch(95.5% 0.025 215deg);\n --theme-display-gradient-start: var(--palette-ocean-active);\n --theme-display-gradient-highlight: oklch(78% 0.1 210deg);\n --theme-display-gradient-end: var(--palette-cyan);\n}\n\n:root.dark {\n color-scheme: dark;\n\n --link-foreground: oklch(72% 0.12 265.67deg);\n --link-hover-foreground: oklch(78% 0.105 265.67deg);\n --theme-accent: oklch(92.88% 0.0126 255.51deg);\n --theme-accent-hover: oklch(86% 0.015 255.51deg);\n --theme-accent-active: oklch(78% 0.018 255.51deg);\n --theme-accent-soft: oklch(25.5% 0.018 257.42deg);\n --theme-accent-border: oklch(36% 0.02 257.42deg);\n --theme-accent-foreground: oklch(16% 0.02 264.66deg);\n --theme-support: oklch(72% 0.12 215.22deg);\n --theme-support-strong: oklch(72% 0.1 181.5deg);\n --theme-support-soft: oklch(25.5% 0.025 215.22deg);\n --theme-display-gradient-start: oklch(69% 0.02 257.42deg);\n --theme-display-gradient-highlight: oklch(96% 0.008 255.51deg);\n --theme-display-gradient-end: oklch(82% 0.014 255.51deg);\n --surface-canvas: oklch(14.5% 0.014 264.66deg);\n --surface-panel: oklch(17.8% 0.016 264.66deg);\n --surface-raised: oklch(21% 0.018 264.66deg);\n --surface-muted: oklch(24.5% 0.017 264.66deg);\n --surface-muted-foreground: var(--text-regular);\n --text-primary: oklch(95.5% 0.008 255.51deg);\n --text-regular: oklch(82% 0.014 255.51deg);\n --text-secondary: oklch(69% 0.02 257.42deg);\n --border-base: oklch(31% 0.018 257.42deg);\n --border-soft: oklch(25.5% 0.015 257.42deg);\n --border-input: oklch(38% 0.02 257.42deg);\n --ring-muted: oklch(55.1% 0.027 264.36deg);\n --semantic-success: oklch(74% 0.145 146.19deg);\n --semantic-success-soft: oklch(24% 0.045 146.19deg);\n --semantic-success-foreground: oklch(82% 0.12 146.19deg);\n --semantic-warning: oklch(82% 0.15 72.75deg);\n --semantic-warning-soft: oklch(25% 0.045 72.75deg);\n --semantic-warning-foreground: oklch(86% 0.12 72.75deg);\n --semantic-danger: oklch(70.4% 0.191 22.22deg);\n --semantic-danger-soft: oklch(25% 0.045 22.22deg);\n --semantic-danger-foreground: oklch(82% 0.14 22.22deg);\n}\n\n:root.dark[data-accent='cobalt'] {\n --theme-accent: oklch(67.5% 0.145 265.67deg);\n --theme-accent-hover: oklch(73% 0.125 265.67deg);\n --theme-accent-active: oklch(62% 0.135 265.67deg);\n --theme-accent-soft: oklch(25.5% 0.04 265.67deg);\n --theme-accent-border: oklch(42% 0.075 265.67deg);\n --theme-accent-foreground: oklch(16% 0.02 264.66deg);\n --theme-support: oklch(76% 0.11 215.22deg);\n --theme-support-strong: oklch(72% 0.1 181.5deg);\n --theme-support-soft: oklch(25.5% 0.04 215.22deg);\n --theme-display-gradient-start: oklch(62% 0.135 265.67deg);\n --theme-display-gradient-highlight: oklch(82% 0.095 265.67deg);\n --theme-display-gradient-end: oklch(70% 0.13 265.67deg);\n}\n\n:root.dark[data-accent='teal'] {\n --theme-accent: oklch(72% 0.12 181.5deg);\n --theme-accent-hover: oklch(78% 0.105 181.5deg);\n --theme-accent-active: oklch(65% 0.11 181.5deg);\n --theme-accent-soft: oklch(25.5% 0.035 181.5deg);\n --theme-accent-border: oklch(42% 0.065 181.5deg);\n --theme-accent-foreground: oklch(16% 0.02 264.66deg);\n --theme-support: oklch(76% 0.11 215.22deg);\n --theme-support-strong: oklch(72% 0.12 265.67deg);\n --theme-support-soft: oklch(25.5% 0.035 215.22deg);\n --theme-display-gradient-start: oklch(65% 0.11 181.5deg);\n --theme-display-gradient-highlight: oklch(84% 0.08 181.5deg);\n --theme-display-gradient-end: oklch(72% 0.12 181.5deg);\n}\n\n:root.dark[data-accent='steel'],\n:root.dark[data-accent='safety'],\n:root.dark[data-accent='ocean'] {\n --theme-accent-foreground: oklch(16% 0.02 264.66deg);\n --theme-accent-soft: color-mix(in oklch, var(--theme-accent) 22%, transparent);\n --theme-accent-border: color-mix(in oklch, var(--theme-accent) 48%, var(--border-base));\n --theme-support-soft: color-mix(in oklch, var(--theme-support) 22%, transparent);\n}\n\n:root.dark[data-accent='steel'] {\n --theme-accent: oklch(70% 0.075 245deg);\n --theme-accent-hover: oklch(77% 0.065 245deg);\n --theme-accent-active: oklch(62% 0.07 245deg);\n --theme-support: oklch(73% 0.1 210deg);\n --theme-support-strong: oklch(70% 0.08 210deg);\n}\n\n:root.dark[data-accent='safety'] {\n --theme-accent: oklch(76% 0.15 65deg);\n --theme-accent-hover: oklch(82% 0.12 65deg);\n --theme-accent-active: oklch(68% 0.14 65deg);\n --theme-support: oklch(73% 0.1 210deg);\n --theme-support-strong: oklch(70% 0.075 245deg);\n}\n\n:root.dark[data-accent='ocean'] {\n --theme-accent: oklch(72% 0.11 210deg);\n --theme-accent-hover: oklch(79% 0.095 210deg);\n --theme-accent-active: oklch(64% 0.105 210deg);\n --theme-support: oklch(76% 0.11 215.22deg);\n --theme-support-strong: oklch(70% 0.075 245deg);\n}\n","path":"src/styles/theme-tokens.css","target":"~/src/styles/theme-tokens.css","type":"registry:file"}],"meta":{"assetId":"styles.theme-tokens","contractRef":"vendor/design-system/src/theme-tokens.css","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"styles-theme-tokens","registryDependencies":[],"title":"styles.theme-tokens","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","radix-ui@1.6.7"],"description":"ui.avatar","files":[{"content":"import * as React from \"react\";\n\nimport { Avatar as AvatarPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('aspect-square size-full', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n 'flex size-full items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary select-none',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n","path":"src/components/ui/avatar.tsx","target":"~/src/components/ui/avatar.tsx","type":"registry:file"}],"meta":{"assetId":"ui.avatar","contractRef":"vendor/design-system/src/components/ui/avatar.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-avatar","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.avatar","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","class-variance-authority@0.7.1","radix-ui@1.6.7"],"description":"ui.badge","files":[{"content":"import * as React from \"react\";\n\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst badgeVariants = cva(\n 'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3',\n {\n variants: {\n variant: {\n default: 'bg-action text-action-foreground [a&]:hover:bg-action-hover',\n secondary: 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',\n destructive:\n 'bg-destructive text-destructive-foreground focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',\n outline:\n 'border-border text-foreground [a&]:hover:bg-control-hover [a&]:hover:text-foreground',\n ghost: '[a&]:hover:bg-control-hover [a&]:hover:text-foreground',\n link: 'text-brand underline-offset-4 [a&]:hover:text-brand-hover [a&]:hover:underline',\n success: 'bg-success-soft text-success-foreground',\n warning: 'bg-warning-soft text-warning-foreground',\n danger: 'bg-danger-soft text-danger-foreground',\n neutral: 'bg-secondary text-secondary-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nfunction Badge({\n className,\n variant = 'default',\n asChild = false,\n ...props\n}: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : 'span';\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n","path":"src/components/ui/badge.tsx","target":"~/src/components/ui/badge.tsx","type":"registry:file"}],"meta":{"assetId":"ui.badge","contractRef":"vendor/design-system/src/components/ui/badge.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-badge","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.badge","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","class-variance-authority@0.7.1","radix-ui@1.6.7"],"description":"ui.button","files":[{"content":"import * as React from \"react\";\n\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform,opacity] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:cursor-not-allowed disabled:translate-y-0 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: 'bg-action text-action-foreground hover:bg-action-hover active:bg-action-active',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',\n outline:\n 'border border-border bg-transparent text-foreground shadow-xs hover:bg-muted/60 hover:text-foreground active:bg-muted/80',\n secondary:\n 'border border-border bg-transparent text-brand hover:border-border hover:bg-brand-soft hover:text-brand-hover active:border-border active:bg-brand-soft/80 active:text-brand-active',\n ghost:\n 'border border-transparent bg-transparent text-brand hover:border-transparent hover:bg-brand-soft hover:text-brand-hover active:border-transparent active:bg-brand-soft/80 active:text-brand-active',\n 'ghost-neutral':\n 'border border-transparent bg-transparent text-muted-foreground hover:border-transparent hover:bg-control-hover hover:text-foreground active:border-transparent active:bg-control-hover active:text-foreground',\n link: 'text-brand underline-offset-4 hover:text-brand-hover hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: 'h-8 gap-1.5 rounded-md px-3 text-xs has-[>svg]:px-2.5',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n icon: 'size-9',\n 'icon-xs': \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n 'icon-sm': 'size-8',\n 'icon-lg': 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nfunction Button({\n className,\n variant = 'default',\n size = 'default',\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot.Root : 'button';\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","path":"src/components/ui/button.tsx","target":"~/src/components/ui/button.tsx","type":"registry:file"}],"meta":{"assetId":"ui.button","contractRef":"vendor/design-system/src/components/ui/button.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-button","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.button","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["radix-ui@1.6.7"],"description":"ui.collapsible","files":[{"content":"import { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return <CollapsiblePrimitive.CollapsibleContent data-slot=\"collapsible-content\" {...props} />;\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","path":"src/components/ui/collapsible.tsx","target":"~/src/components/ui/collapsible.tsx","type":"registry:file"}],"meta":{"assetId":"ui.collapsible","contractRef":"vendor/design-system/src/components/ui/collapsible.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-collapsible","registryDependencies":[],"title":"ui.collapsible","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","lucide-react@0.468.0","radix-ui@1.6.7"],"description":"ui.dropdown-menu","files":[{"content":"import * as React from \"react\";\n\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-xs outline-hidden transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pr-2 pl-8 text-xs outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pr-2 pl-8 text-xs outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn('px-2 py-1.5 text-xs font-semibold data-[inset]:pl-8', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border/80', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-xs outline-hidden focus:bg-accent data-[inset]:pl-8 data-[state=open]:bg-accent',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","path":"src/components/ui/dropdown-menu.tsx","target":"~/src/components/ui/dropdown-menu.tsx","type":"registry:file"}],"meta":{"assetId":"ui.dropdown-menu","contractRef":"vendor/design-system/src/components/ui/dropdown-menu.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-dropdown-menu","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.dropdown-menu","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","class-variance-authority@0.7.1"],"description":"ui.empty","files":[{"content":"import type { ComponentProps } from \"react\";\n\nimport { type VariantProps, cva } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Empty({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"empty\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn('flex max-w-sm flex-col items-center gap-2 text-center', className)}\n {...props}\n />\n );\n}\n\nconst emptyMediaVariants = cva(\n 'mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n icon: \"flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6\",\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nfunction EmptyMedia({\n className,\n variant = 'default',\n ...props\n}: ComponentProps<'div'> & VariantProps<typeof emptyMediaVariants>) {\n return (\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(emptyMediaVariants({ variant, className }))}\n {...props}\n />\n );\n}\n\nfunction EmptyTitle({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn('text-lg font-medium tracking-tight', className)}\n {...props}\n />\n );\n}\n\nfunction EmptyDescription({ className, ...props }: ComponentProps<'p'>) {\n return (\n <div\n data-slot=\"empty-description\"\n className={cn(\n 'text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-brand',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyContent({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(\n 'flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia };\n","path":"src/components/ui/empty.tsx","target":"~/src/components/ui/empty.tsx","type":"registry:file"}],"meta":{"assetId":"ui.empty","contractRef":"vendor/design-system/src/components/ui/empty.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-empty","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.empty","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","lucide-react@0.468.0","radix-ui@1.6.7"],"description":"ui.sheet","files":[{"content":"import * as React from \"react\";\n\nimport { XIcon } from \"lucide-react\";\nimport { Dialog as SheetPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nfunction SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nfunction SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nfunction SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n 'fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction SheetContent({\n className,\n children,\n side = 'right',\n showCloseButton = true,\n overlayClassName,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: 'top' | 'right' | 'bottom' | 'left';\n showCloseButton?: boolean;\n overlayClassName?: string;\n}) {\n return (\n <SheetPortal>\n <SheetOverlay className={overlayClassName} />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n className={cn(\n 'fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500',\n side === 'right' &&\n 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',\n side === 'left' &&\n 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',\n side === 'top' &&\n 'inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',\n side === 'bottom' &&\n 'inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-control-active\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n );\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex flex-col gap-1.5 p-4', className)}\n {...props}\n />\n );\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn('mt-auto flex flex-col gap-2 p-4', className)}\n {...props}\n />\n );\n}\n\nfunction SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('font-semibold text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n};\n","path":"src/components/ui/sheet.tsx","target":"~/src/components/ui/sheet.tsx","type":"registry:file"}],"meta":{"assetId":"ui.sheet","contractRef":"vendor/design-system/src/components/ui/sheet.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-sheet","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.sheet","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8"],"description":"ui.skeleton","files":[{"content":"import type { ComponentProps } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport function Skeleton({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn('animate-pulse rounded-md bg-muted/60', className)}\n {...props}\n />\n );\n}\n","path":"src/components/ui/skeleton.tsx","target":"~/src/components/ui/skeleton.tsx","type":"registry:file"}],"meta":{"assetId":"ui.skeleton","contractRef":"vendor/design-system/src/components/ui/skeleton.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-skeleton","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.skeleton","type":"registry:block"}
@@ -0,0 +1 @@
1
+ {"$schema":"https://ui.shadcn.com/schema/registry-item.json","dependencies":["react@19.2.8","radix-ui@1.6.7"],"description":"ui.tooltip","files":[{"content":"import * as React from \"react\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","path":"src/components/ui/tooltip.tsx","target":"~/src/components/ui/tooltip.tsx","type":"registry:file"}],"meta":{"assetId":"ui.tooltip","contractRef":"vendor/design-system/src/components/ui/tooltip.tsx","maturity":"candidate","releaseDigest":"47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9","version":"0.1.0"},"name":"ui-tooltip","registryDependencies":["http://localhost:4318/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json"],"title":"ui.tooltip","type":"registry:block"}