@assistkick/create 1.6.0 → 1.8.0

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 (214) hide show
  1. package/package.json +2 -2
  2. package/templates/assistkick-product-system/.env.example +1 -0
  3. package/templates/assistkick-product-system/local.db +0 -0
  4. package/templates/assistkick-product-system/package.json +4 -2
  5. package/templates/assistkick-product-system/packages/backend/package.json +2 -0
  6. package/templates/assistkick-product-system/packages/backend/src/routes/agents.ts +165 -0
  7. package/templates/assistkick-product-system/packages/backend/src/routes/files.test.ts +358 -0
  8. package/templates/assistkick-product-system/packages/backend/src/routes/files.ts +356 -0
  9. package/templates/assistkick-product-system/packages/backend/src/routes/git.ts +96 -1
  10. package/templates/assistkick-product-system/packages/backend/src/routes/graph.ts +1 -0
  11. package/templates/assistkick-product-system/packages/backend/src/routes/kanban.ts +43 -4
  12. package/templates/assistkick-product-system/packages/backend/src/routes/pipeline.ts +200 -84
  13. package/templates/assistkick-product-system/packages/backend/src/routes/projects.ts +6 -3
  14. package/templates/assistkick-product-system/packages/backend/src/routes/terminal.ts +53 -17
  15. package/templates/assistkick-product-system/packages/backend/src/routes/video.ts +218 -0
  16. package/templates/assistkick-product-system/packages/backend/src/routes/workflow_groups.ts +119 -0
  17. package/templates/assistkick-product-system/packages/backend/src/routes/workflows.ts +154 -0
  18. package/templates/assistkick-product-system/packages/backend/src/server.ts +81 -9
  19. package/templates/assistkick-product-system/packages/backend/src/services/agent_service.test.ts +489 -0
  20. package/templates/assistkick-product-system/packages/backend/src/services/agent_service.ts +416 -0
  21. package/templates/assistkick-product-system/packages/backend/src/services/bundle_service.test.ts +189 -0
  22. package/templates/assistkick-product-system/packages/backend/src/services/bundle_service.ts +182 -0
  23. package/templates/assistkick-product-system/packages/backend/src/services/init.ts +28 -78
  24. package/templates/assistkick-product-system/packages/backend/src/services/project_service.test.ts +16 -0
  25. package/templates/assistkick-product-system/packages/backend/src/services/project_service.ts +73 -2
  26. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.test.ts +4 -4
  27. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.ts +87 -11
  28. package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.test.ts +210 -69
  29. package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.ts +210 -215
  30. package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.test.ts +162 -0
  31. package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.ts +148 -0
  32. package/templates/assistkick-product-system/packages/backend/src/services/terminal_ws_handler.ts +11 -5
  33. package/templates/assistkick-product-system/packages/backend/src/services/tts_service.test.ts +64 -0
  34. package/templates/assistkick-product-system/packages/backend/src/services/tts_service.ts +134 -0
  35. package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.test.ts +256 -0
  36. package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.ts +258 -0
  37. package/templates/assistkick-product-system/packages/backend/src/services/workflow_group_service.ts +106 -0
  38. package/templates/assistkick-product-system/packages/backend/src/services/workflow_service.test.ts +275 -0
  39. package/templates/assistkick-product-system/packages/backend/src/services/workflow_service.ts +222 -0
  40. package/templates/assistkick-product-system/packages/frontend/index.html +3 -0
  41. package/templates/assistkick-product-system/packages/frontend/package-lock.json +800 -11
  42. package/templates/assistkick-product-system/packages/frontend/package.json +11 -1
  43. package/templates/assistkick-product-system/packages/frontend/src/App.tsx +24 -7
  44. package/templates/assistkick-product-system/packages/frontend/src/api/client.ts +456 -16
  45. package/templates/assistkick-product-system/packages/frontend/src/api/client_files.test.ts +172 -0
  46. package/templates/assistkick-product-system/packages/frontend/src/api/client_video.test.ts +238 -0
  47. package/templates/assistkick-product-system/packages/frontend/src/components/AgentsView.tsx +307 -0
  48. package/templates/assistkick-product-system/packages/frontend/src/components/CoherenceView.tsx +82 -66
  49. package/templates/assistkick-product-system/packages/frontend/src/components/CompositionPlaceholder.tsx +97 -0
  50. package/templates/assistkick-product-system/packages/frontend/src/components/DesignSystemView.tsx +383 -0
  51. package/templates/assistkick-product-system/packages/frontend/src/components/EditorTabBar.tsx +57 -0
  52. package/templates/assistkick-product-system/packages/frontend/src/components/FileTree.tsx +313 -0
  53. package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeContextMenu.tsx +61 -0
  54. package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeInlineInput.tsx +73 -0
  55. package/templates/assistkick-product-system/packages/frontend/src/components/FilesView.tsx +404 -0
  56. package/templates/assistkick-product-system/packages/frontend/src/components/GitRepoModal.tsx +193 -64
  57. package/templates/assistkick-product-system/packages/frontend/src/components/GraphLegend.tsx +71 -73
  58. package/templates/assistkick-product-system/packages/frontend/src/components/GraphSettings.tsx +8 -8
  59. package/templates/assistkick-product-system/packages/frontend/src/components/GraphView.tsx +1 -1
  60. package/templates/assistkick-product-system/packages/frontend/src/components/InviteUserDialog.tsx +15 -11
  61. package/templates/assistkick-product-system/packages/frontend/src/components/KanbanView.tsx +226 -291
  62. package/templates/assistkick-product-system/packages/frontend/src/components/LoginPage.tsx +14 -14
  63. package/templates/assistkick-product-system/packages/frontend/src/components/ProjectSelector.tsx +54 -33
  64. package/templates/assistkick-product-system/packages/frontend/src/components/QaIssueSheet.tsx +40 -66
  65. package/templates/assistkick-product-system/packages/frontend/src/components/SidePanel.tsx +55 -115
  66. package/templates/assistkick-product-system/packages/frontend/src/components/TerminalView.tsx +121 -52
  67. package/templates/assistkick-product-system/packages/frontend/src/components/Toolbar.tsx +155 -77
  68. package/templates/assistkick-product-system/packages/frontend/src/components/UsersView.tsx +52 -52
  69. package/templates/assistkick-product-system/packages/frontend/src/components/VideoGallery.tsx +313 -0
  70. package/templates/assistkick-product-system/packages/frontend/src/components/VideographyView.tsx +250 -0
  71. package/templates/assistkick-product-system/packages/frontend/src/components/WorkflowsView.tsx +474 -0
  72. package/templates/assistkick-product-system/packages/frontend/src/components/ds/AccentBorderList.tsx +53 -0
  73. package/templates/assistkick-product-system/packages/frontend/src/components/ds/Button.tsx +87 -0
  74. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ButtonGroup.tsx +29 -0
  75. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ButtonShowcase.tsx +221 -0
  76. package/templates/assistkick-product-system/packages/frontend/src/components/ds/CardGlass.tsx +141 -0
  77. package/templates/assistkick-product-system/packages/frontend/src/components/ds/CompletionRing.tsx +30 -0
  78. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ContentCard.tsx +34 -0
  79. package/templates/assistkick-product-system/packages/frontend/src/components/ds/IconButton.tsx +74 -0
  80. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KanbanCard.tsx +270 -0
  81. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KanbanCardShowcase.tsx +37 -0
  82. package/templates/assistkick-product-system/packages/frontend/src/components/ds/Kbd.tsx +11 -0
  83. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KindBadge.tsx +21 -0
  84. package/templates/assistkick-product-system/packages/frontend/src/components/ds/NavBarSidekick.tsx +207 -0
  85. package/templates/assistkick-product-system/packages/frontend/src/components/ds/SidePanelShowcase.tsx +370 -0
  86. package/templates/assistkick-product-system/packages/frontend/src/components/ds/SideSheet.tsx +64 -0
  87. package/templates/assistkick-product-system/packages/frontend/src/components/ds/StatusDot.tsx +18 -0
  88. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/CheckCardPositionNode.tsx +36 -0
  89. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/CheckCycleCountNode.tsx +60 -0
  90. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/EndNode.tsx +42 -0
  91. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/GroupNode.tsx +189 -0
  92. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/NodePalette.tsx +123 -0
  93. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/RunAgentNode.tsx +51 -0
  94. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/SetCardMetadataNode.tsx +53 -0
  95. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/StartNode.tsx +18 -0
  96. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/TransitionCardNode.tsx +59 -0
  97. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowCanvas.tsx +335 -0
  98. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowMonitorModal.tsx +634 -0
  99. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/autoLayout.ts +103 -0
  100. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/edgeColors.ts +35 -0
  101. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/monitor_nodes.tsx +208 -0
  102. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.test.ts +119 -0
  103. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.ts +107 -0
  104. package/templates/assistkick-product-system/packages/frontend/src/constants/graph.ts +13 -11
  105. package/templates/assistkick-product-system/packages/frontend/src/hooks/useAutoSave.ts +75 -0
  106. package/templates/assistkick-product-system/packages/frontend/src/hooks/useGraph.ts +6 -21
  107. package/templates/assistkick-product-system/packages/frontend/src/hooks/useProjects.ts +15 -80
  108. package/templates/assistkick-product-system/packages/frontend/src/hooks/useToast.tsx +16 -3
  109. package/templates/assistkick-product-system/packages/frontend/src/pages/accept_invitation_page.tsx +30 -27
  110. package/templates/assistkick-product-system/packages/frontend/src/pages/forgot_password_page.tsx +18 -15
  111. package/templates/assistkick-product-system/packages/frontend/src/pages/register_page.tsx +21 -18
  112. package/templates/assistkick-product-system/packages/frontend/src/pages/reset_password_page.tsx +28 -25
  113. package/templates/assistkick-product-system/packages/frontend/src/routes/AgentsRoute.tsx +6 -0
  114. package/templates/assistkick-product-system/packages/frontend/src/routes/CoherenceRoute.tsx +19 -0
  115. package/templates/assistkick-product-system/packages/frontend/src/routes/DashboardLayout.tsx +54 -0
  116. package/templates/assistkick-product-system/packages/frontend/src/routes/DesignSystemRoute.tsx +6 -0
  117. package/templates/assistkick-product-system/packages/frontend/src/routes/FilesRoute.tsx +13 -0
  118. package/templates/assistkick-product-system/packages/frontend/src/routes/GraphRoute.tsx +93 -0
  119. package/templates/assistkick-product-system/packages/frontend/src/routes/KanbanRoute.tsx +30 -0
  120. package/templates/assistkick-product-system/packages/frontend/src/routes/TerminalRoute.tsx +9 -0
  121. package/templates/assistkick-product-system/packages/frontend/src/routes/UsersRoute.tsx +6 -0
  122. package/templates/assistkick-product-system/packages/frontend/src/routes/VideographyRoute.tsx +13 -0
  123. package/templates/assistkick-product-system/packages/frontend/src/routes/WorkflowsRoute.tsx +6 -0
  124. package/templates/assistkick-product-system/packages/frontend/src/stores/useGitModalStore.ts +14 -0
  125. package/templates/assistkick-product-system/packages/frontend/src/stores/useGraphStore.ts +36 -0
  126. package/templates/assistkick-product-system/packages/frontend/src/stores/useGraphUIStore.ts +25 -0
  127. package/templates/assistkick-product-system/packages/frontend/src/stores/useProjectStore.ts +90 -0
  128. package/templates/assistkick-product-system/packages/frontend/src/stores/useQaSheetStore.ts +27 -0
  129. package/templates/assistkick-product-system/packages/frontend/src/stores/useSidePanelStore.ts +76 -0
  130. package/templates/assistkick-product-system/packages/frontend/src/styles/index.css +336 -3632
  131. package/templates/assistkick-product-system/packages/frontend/src/utils/auto_save_service.test.ts +167 -0
  132. package/templates/assistkick-product-system/packages/frontend/src/utils/auto_save_service.ts +101 -0
  133. package/templates/assistkick-product-system/packages/frontend/src/utils/composition_matcher.test.ts +42 -0
  134. package/templates/assistkick-product-system/packages/frontend/src/utils/composition_matcher.ts +17 -0
  135. package/templates/assistkick-product-system/packages/frontend/src/utils/file_utils.test.ts +145 -0
  136. package/templates/assistkick-product-system/packages/frontend/src/utils/file_utils.ts +42 -0
  137. package/templates/assistkick-product-system/packages/frontend/src/utils/task_status.test.ts +4 -10
  138. package/templates/assistkick-product-system/packages/frontend/src/utils/task_status.ts +19 -1
  139. package/templates/assistkick-product-system/packages/frontend/vite.config.ts +7 -1
  140. package/templates/assistkick-product-system/packages/shared/db/local.db +0 -0
  141. package/templates/assistkick-product-system/packages/shared/db/migrations/0004_tidy_matthew_murdock.sql +9 -0
  142. package/templates/assistkick-product-system/packages/shared/db/migrations/0005_mysterious_falcon.sql +692 -0
  143. package/templates/assistkick-product-system/packages/shared/db/migrations/0006_next_venom.sql +9 -0
  144. package/templates/assistkick-product-system/packages/shared/db/migrations/0007_deep_barracuda.sql +39 -0
  145. package/templates/assistkick-product-system/packages/shared/db/migrations/0008_puzzling_hannibal_king.sql +1 -0
  146. package/templates/assistkick-product-system/packages/shared/db/migrations/0009_amused_beast.sql +8 -0
  147. package/templates/assistkick-product-system/packages/shared/db/migrations/0010_spotty_moira_mactaggert.sql +9 -0
  148. package/templates/assistkick-product-system/packages/shared/db/migrations/0011_goofy_snowbird.sql +3 -0
  149. package/templates/assistkick-product-system/packages/shared/db/migrations/0011_supreme_doctor_octopus.sql +3 -0
  150. package/templates/assistkick-product-system/packages/shared/db/migrations/0013_reflective_prowler.sql +15 -0
  151. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0004_snapshot.json +921 -0
  152. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0005_snapshot.json +1042 -0
  153. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0006_snapshot.json +1101 -0
  154. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0007_snapshot.json +1336 -0
  155. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0008_snapshot.json +1275 -0
  156. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0009_snapshot.json +1327 -0
  157. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0010_snapshot.json +1393 -0
  158. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0011_snapshot.json +1436 -0
  159. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0013_snapshot.json +1538 -0
  160. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/_journal.json +70 -0
  161. package/templates/assistkick-product-system/packages/shared/db/schema.ts +113 -0
  162. package/templates/assistkick-product-system/packages/shared/lib/claude-service.ts +32 -7
  163. package/templates/assistkick-product-system/packages/shared/lib/constants.ts +9 -0
  164. package/templates/assistkick-product-system/packages/shared/lib/git_workflow.ts +12 -4
  165. package/templates/assistkick-product-system/packages/shared/lib/graph.ts +16 -5
  166. package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.test.ts +1753 -0
  167. package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.ts +1281 -0
  168. package/templates/assistkick-product-system/packages/shared/lib/workflow_orchestrator.ts +211 -0
  169. package/templates/assistkick-product-system/packages/shared/tools/add_node.test.ts +43 -0
  170. package/templates/assistkick-product-system/packages/shared/tools/add_node.ts +13 -2
  171. package/templates/assistkick-product-system/packages/shared/tools/get_kanban.ts +1 -1
  172. package/templates/assistkick-product-system/packages/shared/tools/migrate_epics.test.ts +226 -0
  173. package/templates/assistkick-product-system/packages/shared/tools/migrate_epics.ts +251 -0
  174. package/templates/assistkick-product-system/packages/shared/tools/update_node.ts +2 -2
  175. package/templates/assistkick-product-system/packages/shared/utils/hello_workflow.test.ts +10 -0
  176. package/templates/assistkick-product-system/packages/shared/utils/hello_workflow.ts +6 -0
  177. package/templates/assistkick-product-system/packages/video/Root.tsx +85 -0
  178. package/templates/assistkick-product-system/packages/video/components/email_scene.tsx +231 -0
  179. package/templates/assistkick-product-system/packages/video/components/outro_scene.tsx +153 -0
  180. package/templates/assistkick-product-system/packages/video/components/part_divider.tsx +90 -0
  181. package/templates/assistkick-product-system/packages/video/components/scene.tsx +226 -0
  182. package/templates/assistkick-product-system/packages/video/components/theme.ts +22 -0
  183. package/templates/assistkick-product-system/packages/video/components/title_scene.tsx +169 -0
  184. package/templates/assistkick-product-system/packages/video/components/video_split_layout.tsx +84 -0
  185. package/templates/assistkick-product-system/packages/video/compositions/.gitkeep +0 -0
  186. package/templates/assistkick-product-system/packages/video/index.ts +4 -0
  187. package/templates/assistkick-product-system/packages/video/package.json +28 -0
  188. package/templates/assistkick-product-system/packages/video/remotion.config.ts +11 -0
  189. package/templates/assistkick-product-system/packages/video/scripts/process_script.test.ts +326 -0
  190. package/templates/assistkick-product-system/packages/video/scripts/process_script.ts +630 -0
  191. package/templates/assistkick-product-system/packages/video/style.css +1 -0
  192. package/templates/assistkick-product-system/packages/video/tsconfig.json +18 -0
  193. package/templates/assistkick-product-system/tests/graph_legend.test.ts +2 -1
  194. package/templates/assistkick-product-system/tests/video_render_service.test.ts +179 -0
  195. package/templates/assistkick-product-system/tests/web_terminal.test.ts +219 -455
  196. package/templates/assistkick-product-system/tests/workflow_integration.test.ts +341 -0
  197. package/templates/skills/assistkick-bootstrap/SKILL.md +3 -3
  198. package/templates/skills/assistkick-code-reviewer/SKILL.md +2 -2
  199. package/templates/skills/assistkick-debugger/SKILL.md +2 -2
  200. package/templates/skills/assistkick-developer/SKILL.md +6 -3
  201. package/templates/skills/assistkick-developer/references/react_development_guidelines.md +225 -0
  202. package/templates/skills/assistkick-interview/SKILL.md +2 -2
  203. package/templates/skills/product-system/graph.json +1890 -0
  204. package/templates/skills/product-system/kanban.json +304 -0
  205. package/templates/skills/product-system/nodes/comp_001.md +56 -0
  206. package/templates/skills/product-system/nodes/comp_002.md +57 -0
  207. package/templates/skills/product-system/nodes/data_001.md +51 -0
  208. package/templates/skills/product-system/nodes/data_002.md +40 -0
  209. package/templates/skills/product-system/nodes/data_004.md +38 -0
  210. package/templates/skills/product-system/nodes/dec_001.md +34 -0
  211. package/templates/skills/product-system/nodes/dec_016.md +32 -0
  212. package/templates/skills/product-system/nodes/feat_008.md +30 -0
  213. package/templates/skills/video-composition-agent/SKILL.md +232 -0
  214. package/templates/skills/video-script-writer/SKILL.md +136 -0
@@ -0,0 +1,221 @@
1
+ import { Play, Copy, Settings, Plus, Trash2, AlertTriangle, Check, ArrowRight, Download, ExternalLink } from 'lucide-react';
2
+ import { Button } from './Button';
3
+ import { IconButton } from './IconButton';
4
+ import { ButtonGroup } from './ButtonGroup';
5
+
6
+ /* ── Component ── */
7
+
8
+ export const ButtonShowcase = () => {
9
+ return (
10
+ <div>
11
+ {/* ─── Primary ─── */}
12
+ <h4 className="mb-3 text-[11px] font-bold uppercase tracking-widest text-content-muted">
13
+ Primary
14
+ </h4>
15
+ <p className="mb-4 text-[12px] text-content-muted">
16
+ Accent fill with glow. Use for the main call-to-action per view.
17
+ </p>
18
+ <div className="flex flex-wrap items-center gap-3">
19
+ <Button variant="primary" icon={<Plus size={14} strokeWidth={2} />}>
20
+ Create Feature
21
+ </Button>
22
+ <Button variant="primary">
23
+ Save Changes
24
+ </Button>
25
+ <Button variant="primary" disabled>
26
+ Disabled
27
+ </Button>
28
+ </div>
29
+
30
+ {/* ─── Secondary / Outline ─── */}
31
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
32
+ Secondary (Outline)
33
+ </h4>
34
+ <p className="mb-4 text-[12px] text-content-muted">
35
+ Transparent with accent border. Fills on hover. Use alongside primary or for secondary actions.
36
+ </p>
37
+ <div className="flex flex-wrap items-center gap-3">
38
+ <Button variant="secondary" icon={<ArrowRight size={14} strokeWidth={2} />}>
39
+ Continue
40
+ </Button>
41
+ <Button variant="secondary">
42
+ Sign In
43
+ </Button>
44
+ <Button variant="secondary" disabled>
45
+ Disabled
46
+ </Button>
47
+ </div>
48
+
49
+ {/* ─── Ghost ─── */}
50
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
51
+ Ghost
52
+ </h4>
53
+ <p className="mb-4 text-[12px] text-content-muted">
54
+ Transparent with subtle border. Use for toolbar actions, settings, and low-emphasis controls.
55
+ </p>
56
+ <div className="flex flex-wrap items-center gap-3">
57
+ <Button variant="ghost" icon={<Settings size={14} strokeWidth={2} />}>
58
+ Settings
59
+ </Button>
60
+ <Button variant="ghost" icon={<Download size={14} strokeWidth={2} />}>
61
+ Export
62
+ </Button>
63
+ <Button variant="ghost">
64
+ Cancel
65
+ </Button>
66
+ </div>
67
+
68
+ {/* ─── Danger ─── */}
69
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
70
+ Danger
71
+ </h4>
72
+ <p className="mb-4 text-[12px] text-content-muted">
73
+ Dashed error border. Fills on hover. Use for destructive or irreversible actions.
74
+ </p>
75
+ <div className="flex flex-wrap items-center gap-3">
76
+ <Button variant="danger" icon={<Trash2 size={14} strokeWidth={2} />}>
77
+ Delete
78
+ </Button>
79
+ <Button variant="danger" icon={<AlertTriangle size={14} strokeWidth={2} />}>
80
+ Unblock
81
+ </Button>
82
+ </div>
83
+
84
+ {/* ─── Icon Buttons ─── */}
85
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
86
+ Icon Buttons
87
+ </h4>
88
+ <p className="mb-4 text-[12px] text-content-muted">
89
+ Square icon-only buttons for compact controls. Available in multiple sizes and variants.
90
+ </p>
91
+ <div className="flex flex-wrap items-center gap-3">
92
+ <div className="flex flex-col items-center gap-1.5">
93
+ <IconButton label="Settings" size="lg">
94
+ <Settings size={18} strokeWidth={2} />
95
+ </IconButton>
96
+ <span className="text-[10px] text-content-muted">lg</span>
97
+ </div>
98
+ <div className="flex flex-col items-center gap-1.5">
99
+ <IconButton label="Settings" size="md">
100
+ <Settings size={14} strokeWidth={2} />
101
+ </IconButton>
102
+ <span className="text-[10px] text-content-muted">md</span>
103
+ </div>
104
+ <div className="flex flex-col items-center gap-1.5">
105
+ <IconButton label="Copy" size="sm">
106
+ <Copy size={12} strokeWidth={2} />
107
+ </IconButton>
108
+ <span className="text-[10px] text-content-muted">sm</span>
109
+ </div>
110
+
111
+ <div className="mx-2 h-8 w-px bg-edge" />
112
+
113
+ <div className="flex flex-col items-center gap-1.5">
114
+ <IconButton label="Add" variant="accent">
115
+ <Plus size={14} strokeWidth={2} />
116
+ </IconButton>
117
+ <span className="text-[10px] text-content-muted">accent</span>
118
+ </div>
119
+ <div className="flex flex-col items-center gap-1.5">
120
+ <IconButton label="Play" variant="accent" shape="circle">
121
+ <Play size={12} strokeWidth={2} fill="currentColor" />
122
+ </IconButton>
123
+ <span className="text-[10px] text-content-muted">circle</span>
124
+ </div>
125
+ <div className="flex flex-col items-center gap-1.5">
126
+ <IconButton label="Delete" variant="danger">
127
+ <Trash2 size={14} strokeWidth={2} />
128
+ </IconButton>
129
+ <span className="text-[10px] text-content-muted">danger</span>
130
+ </div>
131
+ </div>
132
+
133
+ {/* ─── Sizes ─── */}
134
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
135
+ Sizes
136
+ </h4>
137
+ <p className="mb-4 text-[12px] text-content-muted">
138
+ Three sizes for different contexts. Small for inline/card controls, medium for standard actions, large for hero CTAs.
139
+ </p>
140
+ <div className="flex flex-wrap items-center gap-3">
141
+ <div className="flex flex-col items-center gap-1.5">
142
+ <Button variant="primary" size="sm" icon={<Check size={12} strokeWidth={2} />}>
143
+ Small
144
+ </Button>
145
+ <span className="text-[10px] text-content-muted">sm · 28px</span>
146
+ </div>
147
+ <div className="flex flex-col items-center gap-1.5">
148
+ <Button variant="primary" size="md" icon={<Check size={14} strokeWidth={2} />}>
149
+ Medium
150
+ </Button>
151
+ <span className="text-[10px] text-content-muted">md · 36px</span>
152
+ </div>
153
+ <div className="flex flex-col items-center gap-1.5">
154
+ <Button variant="primary" size="lg" icon={<Check size={16} strokeWidth={2} />}>
155
+ Large
156
+ </Button>
157
+ <span className="text-[10px] text-content-muted">lg · 44px</span>
158
+ </div>
159
+ </div>
160
+
161
+ {/* ─── Button Group ─── */}
162
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
163
+ Button Group
164
+ </h4>
165
+ <p className="mb-4 text-[12px] text-content-muted">
166
+ Related actions grouped with merged borders.
167
+ </p>
168
+ <div className="flex flex-wrap items-center gap-3">
169
+ <ButtonGroup>
170
+ <button>Board</button>
171
+ <button className="bg-accent/10 font-semibold text-accent">List</button>
172
+ <button>Timeline</button>
173
+ </ButtonGroup>
174
+
175
+ <div className="mx-2 h-8 w-px bg-edge" />
176
+
177
+ <ButtonGroup>
178
+ <button className="flex items-center gap-1.5">
179
+ <Copy size={12} strokeWidth={2} />
180
+ Copy
181
+ </button>
182
+ <button className="flex items-center gap-1.5">
183
+ <Download size={12} strokeWidth={2} />
184
+ Export
185
+ </button>
186
+ <button className="flex items-center gap-1.5">
187
+ <ExternalLink size={12} strokeWidth={2} />
188
+ Share
189
+ </button>
190
+ </ButtonGroup>
191
+ </div>
192
+
193
+ {/* ─── States ─── */}
194
+ <h4 className="mb-3 mt-8 text-[11px] font-bold uppercase tracking-widest text-content-muted">
195
+ Interactive States
196
+ </h4>
197
+ <p className="mb-4 text-[12px] text-content-muted">
198
+ All buttons follow the same state pattern: default, hover (brighter/fill), active (pressed), disabled (50% opacity).
199
+ </p>
200
+ <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
201
+ {([
202
+ { state: 'Default', extraClass: '' },
203
+ { state: 'Hover', extraClass: 'brightness-110' },
204
+ { state: 'Active', extraClass: 'brightness-90' },
205
+ { state: 'Disabled', extraClass: '', disabled: true },
206
+ ] as const).map(({ state, extraClass, ...rest }) => (
207
+ <div key={state} className="rounded-xl border border-edge px-4 py-3 text-center">
208
+ <Button
209
+ variant="primary"
210
+ className={extraClass}
211
+ disabled={'disabled' in rest}
212
+ >
213
+ Action
214
+ </Button>
215
+ <div className="mt-2 text-[10px] text-content-muted">{state}</div>
216
+ </div>
217
+ ))}
218
+ </div>
219
+ </div>
220
+ );
221
+ };
@@ -0,0 +1,141 @@
1
+ import {
2
+ Play, AlertTriangle, Lock, CircleDot, Copy,
3
+ } from 'lucide-react';
4
+ import { KindBadge } from './KindBadge';
5
+
6
+ /* ── Types ── */
7
+
8
+ export interface DemoCard {
9
+ id: string;
10
+ name: string;
11
+ pct: number;
12
+ kind: 'new' | 'improvement' | 'bugfix';
13
+ rejections: number;
14
+ pipeline: 'idle' | 'active' | 'completed' | 'failed' | 'interrupted' | 'blocked';
15
+ blocked: boolean;
16
+ issues: number;
17
+ stage: 'in_progress' | 'in_review' | 'qa';
18
+ }
19
+
20
+ interface Props {
21
+ card: DemoCard;
22
+ }
23
+
24
+ /* ── Pipeline helpers ── */
25
+
26
+ const pipelineStyle = (status: DemoCard['pipeline']): string => {
27
+ switch (status) {
28
+ case 'active': return 'bg-accent/10 text-accent animate-pulse';
29
+ case 'completed': return 'bg-emerald-500/10 text-emerald-400';
30
+ case 'failed': return 'bg-error/10 text-error';
31
+ case 'blocked': return 'bg-error/10 text-error';
32
+ case 'interrupted': return 'bg-amber-500/10 text-amber-400';
33
+ default: return '';
34
+ }
35
+ };
36
+
37
+ const pipelineLabel = (status: DemoCard['pipeline'], rejections: number): string => {
38
+ if (rejections >= 1 && status !== 'idle') return `Retry ${rejections + 1}`;
39
+ switch (status) {
40
+ case 'active': return 'Running...';
41
+ case 'completed': return 'Completed';
42
+ case 'failed': return 'Failed';
43
+ case 'blocked': return 'Blocked';
44
+ case 'interrupted': return 'Interrupted';
45
+ default: return '';
46
+ }
47
+ };
48
+
49
+ /* ── Component ── */
50
+
51
+ export const CardGlass = ({ card }: Props) => {
52
+ const hasPipeline = card.pipeline !== 'idle';
53
+ const hasStatusRow = card.rejections > 0 || hasPipeline;
54
+ const stripColor = card.blocked
55
+ ? 'from-error/60 to-error/20'
56
+ : card.rejections >= 3
57
+ ? 'from-error/40 to-amber-500/20'
58
+ : card.pipeline === 'active'
59
+ ? 'from-accent/60 to-accent/20'
60
+ : card.pipeline === 'completed'
61
+ ? 'from-emerald-400/60 to-emerald-400/20'
62
+ : 'from-edge to-transparent';
63
+
64
+ return (
65
+ <div className="group relative overflow-hidden rounded-2xl bg-surface border border-edge shadow-lg shadow-black/10 backdrop-blur-sm transition-all duration-200 hover:border-content/15 hover:shadow-xl hover:shadow-black/15">
66
+ <div className={`absolute left-0 top-0 h-full w-1 bg-gradient-to-b ${stripColor}`} />
67
+ <div className="p-5 pl-6">
68
+ {/* Header */}
69
+ <div className="flex items-center gap-2.5">
70
+ <span className="font-mono text-[12px] text-content-secondary">{card.id}</span>
71
+ <KindBadge kind={card.kind} />
72
+ <button className="flex h-6 w-6 items-center justify-center rounded-md bg-white/[0.08] text-content-secondary transition-colors hover:bg-white/15 hover:text-content cursor-pointer">
73
+ <Copy size={12} strokeWidth={2} />
74
+ </button>
75
+ <div className="flex-1" />
76
+ {card.blocked ? (
77
+ <span className="flex items-center gap-1.5 rounded-full bg-error/15 px-2.5 py-1 text-[11px] font-bold text-error backdrop-blur">
78
+ <Lock size={11} strokeWidth={2.5} /> Blocked
79
+ </span>
80
+ ) : card.pipeline === 'idle' ? (
81
+ <button className="flex h-7 w-7 items-center justify-center rounded-full bg-accent/10 text-accent backdrop-blur transition-all hover:bg-accent hover:text-surface hover:shadow-[0_0_12px_-2px_var(--accent)] cursor-pointer">
82
+ <Play size={12} strokeWidth={2.5} fill="currentColor" />
83
+ </button>
84
+ ) : null}
85
+ </div>
86
+
87
+ {/* Name */}
88
+ <div className="mt-3 text-[15px] font-semibold leading-snug text-content">{card.name}</div>
89
+
90
+ {/* Spec disc */}
91
+ <div className="mt-3.5 flex items-center gap-2.5">
92
+ <svg width="24" height="24" viewBox="0 0 24 24" className="shrink-0 -rotate-90">
93
+ <circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" strokeWidth="2.5" className="text-white/5" />
94
+ <circle
95
+ cx="12" cy="12" r="10" fill="none" strokeWidth="2.5"
96
+ stroke="url(#specGrad)" strokeLinecap="round"
97
+ strokeDasharray={`${(card.pct / 100) * 2 * Math.PI * 10} ${2 * Math.PI * 10}`}
98
+ />
99
+ <defs>
100
+ <linearGradient id="specGrad" x1="0" y1="0" x2="1" y2="1">
101
+ <stop offset="0%" stopColor="var(--completeness-fill)" />
102
+ <stop offset="100%" stopColor="var(--accent)" stopOpacity="0.6" />
103
+ </linearGradient>
104
+ </defs>
105
+ </svg>
106
+ <span className="font-mono text-[12px] text-content-secondary">{card.pct}%</span>
107
+ </div>
108
+
109
+ {/* Status pills */}
110
+ {hasStatusRow && (
111
+ <div className="mt-3.5">
112
+ <div className="flex gap-1.5">
113
+ {card.rejections > 0 && (
114
+ <span className="flex-1 rounded-full bg-amber-400/15 py-1 text-center text-[11px] font-semibold text-amber-400 backdrop-blur">
115
+ {card.rejections}x rejected
116
+ </span>
117
+ )}
118
+ {hasPipeline && (
119
+ <span className={`flex-1 inline-flex items-center justify-center gap-1.5 rounded-full py-1 text-[11px] font-semibold backdrop-blur ${pipelineStyle(card.pipeline)}`}>
120
+ {card.pipeline === 'active' && <CircleDot size={12} strokeWidth={2.5} />}
121
+ {card.pipeline === 'failed' && <AlertTriangle size={12} strokeWidth={2.5} />}
122
+ {pipelineLabel(card.pipeline, card.rejections)}
123
+ </span>
124
+ )}
125
+ </div>
126
+ </div>
127
+ )}
128
+
129
+ {/* Issues */}
130
+ <button className={[
131
+ 'mt-3.5 w-full rounded-full border py-2 text-center text-[12px] font-mono backdrop-blur transition-all cursor-pointer',
132
+ card.issues > 0
133
+ ? 'border-white/10 text-content-secondary hover:border-accent/30 hover:text-accent'
134
+ : 'border-white/5 text-content-muted/50 hover:border-white/10 hover:text-content-muted',
135
+ ].join(' ')}>
136
+ {card.issues > 0 ? `${card.issues} issue${card.issues !== 1 ? 's' : ''} reported` : 'No issues'}
137
+ </button>
138
+ </div>
139
+ </div>
140
+ );
141
+ };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+
3
+ export interface CompletionRingProps {
4
+ /** Completion percentage as 0–1 fraction */
5
+ pct: number;
6
+ /** Outer diameter in px */
7
+ size?: number;
8
+ }
9
+
10
+ export function CompletionRing({ pct, size = 40 }: CompletionRingProps) {
11
+ const r = (size - 6) / 2;
12
+ const circumference = 2 * Math.PI * r;
13
+ const offset = circumference * (1 - pct);
14
+ return (
15
+ <svg width={size} height={size} className="shrink-0">
16
+ <circle cx={size / 2} cy={size / 2} r={r} fill="none"
17
+ stroke="var(--completeness-bg)" strokeWidth={3} />
18
+ <circle cx={size / 2} cy={size / 2} r={r} fill="none"
19
+ stroke="var(--completeness-fill)" strokeWidth={3}
20
+ strokeDasharray={circumference} strokeDashoffset={offset}
21
+ strokeLinecap="round"
22
+ transform={`rotate(-90 ${size / 2} ${size / 2})`}
23
+ className="transition-all duration-500" />
24
+ <text x={size / 2} y={size / 2} textAnchor="middle" dominantBaseline="central"
25
+ className="fill-content text-[10px] font-bold">
26
+ {Math.round(pct * 100)}%
27
+ </text>
28
+ </svg>
29
+ );
30
+ }
@@ -0,0 +1,34 @@
1
+ import React, { useState } from 'react';
2
+ import { ChevronDown, ChevronRight } from 'lucide-react';
3
+
4
+ export interface ContentCardProps {
5
+ icon: React.ReactNode;
6
+ label: string;
7
+ badge?: React.ReactNode;
8
+ defaultOpen?: boolean;
9
+ children: React.ReactNode;
10
+ }
11
+
12
+ export function ContentCard({ icon, label, badge, defaultOpen = false, children }: ContentCardProps) {
13
+ const [open, setOpen] = useState(defaultOpen);
14
+ return (
15
+ <div className="rounded-xl border border-edge bg-surface-alt overflow-hidden">
16
+ <button
17
+ onClick={() => setOpen(v => !v)}
18
+ className="flex w-full items-center gap-2 px-3 py-2.5 text-left hover:bg-surface-raised/50 transition-colors"
19
+ >
20
+ <span className="text-content-muted shrink-0">{icon}</span>
21
+ <span className="text-[12px] font-medium text-content flex-1">{label}</span>
22
+ {badge}
23
+ {open
24
+ ? <ChevronDown size={13} className="text-content-muted" />
25
+ : <ChevronRight size={13} className="text-content-muted" />}
26
+ </button>
27
+ {open && (
28
+ <div className="border-t border-edge px-3 py-3">
29
+ {children}
30
+ </div>
31
+ )}
32
+ </div>
33
+ );
34
+ }
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+
3
+ /* ── Types ── */
4
+
5
+ type IconButtonVariant = 'ghost' | 'accent' | 'danger';
6
+ type IconButtonSize = 'sm' | 'md' | 'lg';
7
+ type IconButtonShape = 'square' | 'circle';
8
+
9
+ interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
10
+ variant?: IconButtonVariant;
11
+ size?: IconButtonSize;
12
+ shape?: IconButtonShape;
13
+ /** Accessible label — required since there is no visible text */
14
+ label: string;
15
+ children: React.ReactNode;
16
+ }
17
+
18
+ /* ── Style maps ── */
19
+
20
+ const variantClasses: Record<IconButtonVariant, string> = {
21
+ ghost: [
22
+ 'border border-edge bg-transparent text-content-muted',
23
+ 'hover:border-content/20 hover:text-content',
24
+ ].join(' '),
25
+ accent: [
26
+ 'border border-accent/30 bg-transparent text-accent',
27
+ 'hover:bg-accent hover:text-surface',
28
+ ].join(' '),
29
+ danger: [
30
+ 'border border-dashed border-error bg-transparent text-error',
31
+ 'hover:bg-error hover:text-white',
32
+ ].join(' '),
33
+ };
34
+
35
+ const sizeClasses: Record<IconButtonSize, { box: string; radius: Record<IconButtonShape, string> }> = {
36
+ sm: { box: 'h-6 w-6', radius: { square: 'rounded-md', circle: 'rounded-full' } },
37
+ md: { box: 'h-8 w-8', radius: { square: 'rounded-lg', circle: 'rounded-full' } },
38
+ lg: { box: 'h-10 w-10', radius: { square: 'rounded-lg', circle: 'rounded-full' } },
39
+ };
40
+
41
+ /* ── Component ── */
42
+
43
+ export const IconButton = ({
44
+ variant = 'ghost',
45
+ size = 'md',
46
+ shape = 'square',
47
+ label,
48
+ disabled,
49
+ className = '',
50
+ children,
51
+ ...rest
52
+ }: Props) => {
53
+ const base = 'flex items-center justify-center outline-none cursor-pointer transition-all duration-150';
54
+ const disabledClass = disabled ? 'opacity-50 cursor-not-allowed' : '';
55
+ const sizeConfig = sizeClasses[size];
56
+
57
+ return (
58
+ <button
59
+ aria-label={label}
60
+ disabled={disabled}
61
+ className={[
62
+ base,
63
+ variantClasses[variant],
64
+ sizeConfig.box,
65
+ sizeConfig.radius[shape],
66
+ disabledClass,
67
+ className,
68
+ ].join(' ')}
69
+ {...rest}
70
+ >
71
+ {children}
72
+ </button>
73
+ );
74
+ };