@handled-ai/design-system 0.8.0 → 0.9.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 (336) hide show
  1. package/README.md +14 -4
  2. package/dist/charts/bar-chart-component.d.ts +24 -0
  3. package/dist/charts/bar-chart-component.js +123 -0
  4. package/dist/charts/bar-chart-component.js.map +1 -0
  5. package/dist/charts/chart-tooltip.d.ts +26 -0
  6. package/dist/charts/chart-tooltip.js +69 -0
  7. package/dist/charts/chart-tooltip.js.map +1 -0
  8. package/dist/charts/chart.d.ts +64 -0
  9. package/dist/charts/chart.js +285 -0
  10. package/dist/charts/chart.js.map +1 -0
  11. package/dist/charts/donut-chart.d.ts +21 -0
  12. package/dist/charts/donut-chart.js +96 -0
  13. package/dist/charts/donut-chart.js.map +1 -0
  14. package/dist/charts/index.d.ts +11 -0
  15. package/dist/charts/index.js +10 -0
  16. package/dist/charts/index.js.map +1 -0
  17. package/dist/charts/pipeline-overview.d.ts +76 -0
  18. package/dist/charts/pipeline-overview.js +372 -0
  19. package/dist/charts/pipeline-overview.js.map +1 -0
  20. package/dist/charts/sankey-chart.d.ts +52 -0
  21. package/dist/charts/sankey-chart.js +219 -0
  22. package/dist/charts/sankey-chart.js.map +1 -0
  23. package/dist/charts/top-line-metrics.d.ts +26 -0
  24. package/dist/charts/top-line-metrics.js +224 -0
  25. package/dist/charts/top-line-metrics.js.map +1 -0
  26. package/dist/charts/trend-area-chart.d.ts +21 -0
  27. package/dist/charts/trend-area-chart.js +150 -0
  28. package/dist/charts/trend-area-chart.js.map +1 -0
  29. package/dist/charts/volume-analysis-chart.d.ts +19 -0
  30. package/dist/charts/volume-analysis-chart.js +121 -0
  31. package/dist/charts/volume-analysis-chart.js.map +1 -0
  32. package/dist/components/activity-detail.d.ts +38 -0
  33. package/dist/components/activity-detail.js +163 -0
  34. package/dist/components/activity-detail.js.map +1 -0
  35. package/dist/components/activity-log.d.ts +21 -0
  36. package/dist/components/activity-log.js +61 -0
  37. package/dist/components/activity-log.js.map +1 -0
  38. package/dist/components/agent-popover.d.ts +71 -0
  39. package/dist/components/agent-popover.js +282 -0
  40. package/dist/components/agent-popover.js.map +1 -0
  41. package/dist/components/agent-widget.d.ts +24 -0
  42. package/dist/components/agent-widget.js +117 -0
  43. package/dist/components/agent-widget.js.map +1 -0
  44. package/dist/components/avatar.d.ts +13 -0
  45. package/dist/components/avatar.js +140 -0
  46. package/dist/components/avatar.js.map +1 -0
  47. package/dist/components/badge.d.ts +12 -0
  48. package/dist/components/badge.js +75 -0
  49. package/dist/components/badge.js.map +1 -0
  50. package/dist/components/button.d.ts +13 -0
  51. package/dist/components/button.js +83 -0
  52. package/dist/components/button.js.map +1 -0
  53. package/dist/components/card.d.ts +11 -0
  54. package/dist/components/card.js +119 -0
  55. package/dist/components/card.js.map +1 -0
  56. package/dist/components/contact-list.d.ts +34 -0
  57. package/dist/components/contact-list.js +84 -0
  58. package/dist/components/contact-list.js.map +1 -0
  59. package/dist/components/dashboard-cards.d.ts +10 -0
  60. package/dist/components/dashboard-cards.js +164 -0
  61. package/dist/components/dashboard-cards.js.map +1 -0
  62. package/dist/components/data-table-display.d.ts +19 -0
  63. package/dist/components/data-table-display.js +109 -0
  64. package/dist/components/data-table-display.js.map +1 -0
  65. package/dist/components/data-table-filter.d.ts +18 -0
  66. package/dist/components/data-table-filter.js +107 -0
  67. package/dist/components/data-table-filter.js.map +1 -0
  68. package/dist/components/data-table-quick-views.d.ts +13 -0
  69. package/dist/components/data-table-quick-views.js +90 -0
  70. package/dist/components/data-table-quick-views.js.map +1 -0
  71. package/dist/components/data-table-toolbar.d.ts +18 -0
  72. package/dist/components/data-table-toolbar.js +45 -0
  73. package/dist/components/data-table-toolbar.js.map +1 -0
  74. package/dist/components/data-table.d.ts +39 -0
  75. package/dist/components/data-table.js +821 -0
  76. package/dist/components/data-table.js.map +1 -0
  77. package/dist/components/detail-view.d.ts +44 -0
  78. package/dist/components/detail-view.js +165 -0
  79. package/dist/components/detail-view.js.map +1 -0
  80. package/dist/components/dialog.d.ts +19 -0
  81. package/dist/components/dialog.js +188 -0
  82. package/dist/components/dialog.js.map +1 -0
  83. package/dist/components/dropdown-menu.d.ts +27 -0
  84. package/dist/components/dropdown-menu.js +279 -0
  85. package/dist/components/dropdown-menu.js.map +1 -0
  86. package/dist/components/entity-panel.d.ts +69 -0
  87. package/dist/components/entity-panel.js +584 -0
  88. package/dist/components/entity-panel.js.map +1 -0
  89. package/dist/components/inbox-row.d.ts +27 -0
  90. package/dist/components/inbox-row.js +139 -0
  91. package/dist/components/inbox-row.js.map +1 -0
  92. package/dist/components/inbox-toolbar.d.ts +21 -0
  93. package/dist/components/inbox-toolbar.js +203 -0
  94. package/dist/components/inbox-toolbar.js.map +1 -0
  95. package/dist/components/input.d.ts +5 -0
  96. package/dist/components/input.js +50 -0
  97. package/dist/components/input.js.map +1 -0
  98. package/dist/components/insights-filter-bar.d.ts +21 -0
  99. package/dist/components/insights-filter-bar.js +99 -0
  100. package/dist/components/insights-filter-bar.js.map +1 -0
  101. package/dist/components/item-list-display.d.ts +22 -0
  102. package/dist/components/item-list-display.js +240 -0
  103. package/dist/components/item-list-display.js.map +1 -0
  104. package/dist/components/item-list-filter.d.ts +16 -0
  105. package/dist/components/item-list-filter.js +87 -0
  106. package/dist/components/item-list-filter.js.map +1 -0
  107. package/dist/components/item-list-toolbar.d.ts +25 -0
  108. package/dist/components/item-list-toolbar.js +79 -0
  109. package/dist/components/item-list-toolbar.js.map +1 -0
  110. package/dist/components/item-list.d.ts +20 -0
  111. package/dist/components/item-list.js +702 -0
  112. package/dist/components/item-list.js.map +1 -0
  113. package/dist/components/label.d.ts +6 -0
  114. package/dist/components/label.js +55 -0
  115. package/dist/components/label.js.map +1 -0
  116. package/dist/components/message.d.ts +23 -0
  117. package/dist/components/message.js +117 -0
  118. package/dist/components/message.js.map +1 -0
  119. package/dist/components/metric-card.d.ts +25 -0
  120. package/dist/components/metric-card.js +107 -0
  121. package/dist/components/metric-card.js.map +1 -0
  122. package/dist/components/performance-metrics-table.d.ts +38 -0
  123. package/dist/components/performance-metrics-table.js +342 -0
  124. package/dist/components/performance-metrics-table.js.map +1 -0
  125. package/dist/components/preview-list.d.ts +14 -0
  126. package/dist/components/preview-list.js +83 -0
  127. package/dist/components/preview-list.js.map +1 -0
  128. package/dist/components/progress.d.ts +6 -0
  129. package/dist/components/progress.js +69 -0
  130. package/dist/components/progress.js.map +1 -0
  131. package/dist/components/quick-action-chat-area.d.ts +24 -0
  132. package/dist/components/quick-action-chat-area.js +178 -0
  133. package/dist/components/quick-action-chat-area.js.map +1 -0
  134. package/dist/components/quick-action-modal.d.ts +30 -0
  135. package/dist/components/quick-action-modal.js +288 -0
  136. package/dist/components/quick-action-modal.js.map +1 -0
  137. package/dist/components/quick-action-sidebar-nav.d.ts +51 -0
  138. package/dist/components/quick-action-sidebar-nav.js +528 -0
  139. package/dist/components/quick-action-sidebar-nav.js.map +1 -0
  140. package/dist/components/recommended-actions-section.d.ts +23 -0
  141. package/dist/components/recommended-actions-section.js +215 -0
  142. package/dist/components/recommended-actions-section.js.map +1 -0
  143. package/dist/components/report-card.d.ts +26 -0
  144. package/dist/components/report-card.js +69 -0
  145. package/dist/components/report-card.js.map +1 -0
  146. package/dist/components/score-analysis-modal.d.ts +26 -0
  147. package/dist/components/score-analysis-modal.js +141 -0
  148. package/dist/components/score-analysis-modal.js.map +1 -0
  149. package/dist/components/score-breakdown.d.ts +17 -0
  150. package/dist/components/score-breakdown.js +162 -0
  151. package/dist/components/score-breakdown.js.map +1 -0
  152. package/dist/components/score-feedback.d.ts +40 -0
  153. package/dist/components/score-feedback.js +209 -0
  154. package/dist/components/score-feedback.js.map +1 -0
  155. package/dist/components/score-ring.d.ts +14 -0
  156. package/dist/components/score-ring.js +79 -0
  157. package/dist/components/score-ring.js.map +1 -0
  158. package/dist/components/scroll-area.d.ts +7 -0
  159. package/dist/components/scroll-area.js +101 -0
  160. package/dist/components/scroll-area.js.map +1 -0
  161. package/dist/components/select.d.ts +17 -0
  162. package/dist/components/select.js +228 -0
  163. package/dist/components/select.js.map +1 -0
  164. package/dist/components/separator.d.ts +6 -0
  165. package/dist/components/separator.js +61 -0
  166. package/dist/components/separator.js.map +1 -0
  167. package/dist/components/sheet.d.ts +16 -0
  168. package/dist/components/sheet.js +168 -0
  169. package/dist/components/sheet.js.map +1 -0
  170. package/dist/components/sidebar.d.ts +73 -0
  171. package/dist/components/sidebar.js +723 -0
  172. package/dist/components/sidebar.js.map +1 -0
  173. package/dist/components/signal-feedback-inline.d.ts +51 -0
  174. package/dist/components/signal-feedback-inline.js +548 -0
  175. package/dist/components/signal-feedback-inline.js.map +1 -0
  176. package/dist/components/simple-data-table.d.ts +15 -0
  177. package/dist/components/simple-data-table.js +91 -0
  178. package/dist/components/simple-data-table.js.map +1 -0
  179. package/dist/components/skeleton.d.ts +5 -0
  180. package/dist/components/skeleton.js +44 -0
  181. package/dist/components/skeleton.js.map +1 -0
  182. package/dist/components/status-badge.d.ts +10 -0
  183. package/dist/components/status-badge.js +82 -0
  184. package/dist/components/status-badge.js.map +1 -0
  185. package/dist/components/styled-bar-list.d.ts +20 -0
  186. package/dist/components/styled-bar-list.js +59 -0
  187. package/dist/components/styled-bar-list.js.map +1 -0
  188. package/dist/components/suggested-actions.d.ts +110 -0
  189. package/dist/components/suggested-actions.js +1538 -0
  190. package/dist/components/suggested-actions.js.map +1 -0
  191. package/dist/components/table.d.ts +12 -0
  192. package/dist/components/table.js +147 -0
  193. package/dist/components/table.js.map +1 -0
  194. package/dist/components/tabs.d.ts +14 -0
  195. package/dist/components/tabs.js +129 -0
  196. package/dist/components/tabs.js.map +1 -0
  197. package/dist/components/textarea.d.ts +5 -0
  198. package/dist/components/textarea.js +47 -0
  199. package/dist/components/textarea.js.map +1 -0
  200. package/dist/components/timeline-activity.d.ts +34 -0
  201. package/dist/components/timeline-activity.js +181 -0
  202. package/dist/components/timeline-activity.js.map +1 -0
  203. package/dist/components/tooltip.d.ts +9 -0
  204. package/dist/components/tooltip.js +93 -0
  205. package/dist/components/tooltip.js.map +1 -0
  206. package/dist/components/view-mode-toggle.d.ts +16 -0
  207. package/dist/components/view-mode-toggle.js +24 -0
  208. package/dist/components/view-mode-toggle.js.map +1 -0
  209. package/dist/hooks/use-mobile.d.ts +3 -0
  210. package/dist/hooks/use-mobile.js +21 -0
  211. package/dist/hooks/use-mobile.js.map +1 -0
  212. package/dist/index.d.ts +68 -1878
  213. package/dist/index.js +69 -10918
  214. package/dist/index.js.map +1 -1
  215. package/dist/lib/icons.d.ts +18 -0
  216. package/dist/lib/icons.js +21 -0
  217. package/dist/lib/icons.js.map +1 -0
  218. package/dist/lib/utils.d.ts +5 -0
  219. package/dist/lib/utils.js +9 -0
  220. package/dist/lib/utils.js.map +1 -0
  221. package/dist/prototype/index.d.ts +20 -0
  222. package/dist/prototype/index.js +8 -0
  223. package/dist/prototype/index.js.map +1 -0
  224. package/dist/prototype/prototype-accounts-view.d.ts +22 -0
  225. package/dist/prototype/prototype-accounts-view.js +70 -0
  226. package/dist/prototype/prototype-accounts-view.js.map +1 -0
  227. package/dist/prototype/prototype-admin-view.d.ts +21 -0
  228. package/dist/prototype/prototype-admin-view.js +53 -0
  229. package/dist/prototype/prototype-admin-view.js.map +1 -0
  230. package/dist/prototype/prototype-config.d.ts +226 -0
  231. package/dist/prototype/prototype-config.js +1 -0
  232. package/dist/prototype/prototype-config.js.map +1 -0
  233. package/dist/prototype/prototype-inbox-view.d.ts +48 -0
  234. package/dist/prototype/prototype-inbox-view.js +701 -0
  235. package/dist/prototype/prototype-inbox-view.js.map +1 -0
  236. package/dist/prototype/prototype-insights-view.d.ts +23 -0
  237. package/dist/prototype/prototype-insights-view.js +335 -0
  238. package/dist/prototype/prototype-insights-view.js.map +1 -0
  239. package/dist/prototype/prototype-shell.d.ts +40 -0
  240. package/dist/prototype/prototype-shell.js +190 -0
  241. package/dist/prototype/prototype-shell.js.map +1 -0
  242. package/dist/prototype/prototype-work-queue-view.d.ts +8 -0
  243. package/dist/prototype/prototype-work-queue-view.js +17 -0
  244. package/dist/prototype/prototype-work-queue-view.js.map +1 -0
  245. package/dist/three/agent-orb.d.ts +39 -0
  246. package/dist/three/agent-orb.js +500 -0
  247. package/dist/three/agent-orb.js.map +1 -0
  248. package/dist/three/index.d.ts +2 -0
  249. package/dist/three/index.js +2 -0
  250. package/dist/three/index.js.map +1 -0
  251. package/package.json +98 -17
  252. package/src/charts/bar-chart-component.tsx +150 -0
  253. package/src/charts/chart-tooltip.tsx +86 -0
  254. package/src/charts/chart.tsx +371 -0
  255. package/src/charts/donut-chart.tsx +112 -0
  256. package/src/charts/index.ts +13 -0
  257. package/src/charts/pipeline-overview.tsx +476 -0
  258. package/src/charts/sankey-chart.tsx +290 -0
  259. package/src/charts/top-line-metrics.tsx +261 -0
  260. package/src/charts/trend-area-chart.tsx +150 -0
  261. package/src/charts/volume-analysis-chart.tsx +124 -0
  262. package/src/components/activity-detail.tsx +233 -0
  263. package/src/components/activity-log.tsx +89 -0
  264. package/src/components/agent-popover.tsx +373 -0
  265. package/src/components/agent-widget.tsx +163 -0
  266. package/src/components/avatar.tsx +109 -0
  267. package/src/components/badge.tsx +48 -0
  268. package/src/components/button.tsx +59 -0
  269. package/src/components/card.tsx +92 -0
  270. package/src/components/contact-list.tsx +121 -0
  271. package/src/components/dashboard-cards.tsx +170 -0
  272. package/src/components/data-table-display.tsx +139 -0
  273. package/src/components/data-table-filter.tsx +138 -0
  274. package/src/components/data-table-quick-views.tsx +103 -0
  275. package/src/components/data-table-toolbar.tsx +56 -0
  276. package/src/components/data-table.tsx +915 -0
  277. package/src/components/detail-view.tsx +237 -0
  278. package/src/components/dialog.tsx +158 -0
  279. package/src/components/dropdown-menu.tsx +257 -0
  280. package/src/components/entity-panel.tsx +767 -0
  281. package/src/components/inbox-row.tsx +132 -0
  282. package/src/components/inbox-toolbar.tsx +213 -0
  283. package/src/components/input.tsx +21 -0
  284. package/src/components/insights-filter-bar.tsx +132 -0
  285. package/src/components/item-list-display.tsx +278 -0
  286. package/src/components/item-list-filter.tsx +118 -0
  287. package/src/components/item-list-toolbar.tsx +97 -0
  288. package/src/components/item-list.tsx +843 -0
  289. package/src/components/label.tsx +24 -0
  290. package/src/components/message.tsx +83 -0
  291. package/src/components/metric-card.tsx +178 -0
  292. package/src/components/performance-metrics-table.tsx +442 -0
  293. package/src/components/preview-list.tsx +62 -0
  294. package/src/components/progress.tsx +31 -0
  295. package/src/components/quick-action-chat-area.tsx +156 -0
  296. package/src/components/quick-action-modal.tsx +331 -0
  297. package/src/components/quick-action-sidebar-nav.tsx +592 -0
  298. package/src/components/recommended-actions-section.tsx +258 -0
  299. package/src/components/report-card.tsx +106 -0
  300. package/src/components/score-analysis-modal.tsx +172 -0
  301. package/src/components/score-breakdown.tsx +179 -0
  302. package/src/components/score-feedback.tsx +288 -0
  303. package/src/components/score-ring.tsx +87 -0
  304. package/src/components/scroll-area.tsx +58 -0
  305. package/src/components/select.tsx +190 -0
  306. package/src/components/separator.tsx +28 -0
  307. package/src/components/sheet.tsx +143 -0
  308. package/src/components/sidebar.tsx +726 -0
  309. package/src/components/signal-feedback-inline.tsx +591 -0
  310. package/src/components/simple-data-table.tsx +124 -0
  311. package/src/components/skeleton.tsx +15 -0
  312. package/src/components/status-badge.tsx +63 -0
  313. package/src/components/styled-bar-list.tsx +70 -0
  314. package/src/components/suggested-actions.tsx +1985 -0
  315. package/src/components/table.tsx +116 -0
  316. package/src/components/tabs.tsx +91 -0
  317. package/src/components/textarea.tsx +18 -0
  318. package/src/components/timeline-activity.tsx +234 -0
  319. package/src/components/tooltip.tsx +57 -0
  320. package/src/components/view-mode-toggle.tsx +39 -0
  321. package/src/hooks/use-mobile.ts +21 -0
  322. package/src/index.ts +77 -0
  323. package/src/lib/icons.ts +18 -0
  324. package/src/lib/utils.ts +6 -0
  325. package/src/prototype/index.ts +11 -0
  326. package/src/prototype/prototype-accounts-view.tsx +112 -0
  327. package/src/prototype/prototype-admin-view.tsx +67 -0
  328. package/src/prototype/prototype-config.ts +243 -0
  329. package/src/prototype/prototype-inbox-view.tsx +810 -0
  330. package/src/prototype/prototype-insights-view.tsx +379 -0
  331. package/src/prototype/prototype-shell.tsx +219 -0
  332. package/src/prototype/prototype-work-queue-view.tsx +30 -0
  333. package/src/styles/globals.css +299 -0
  334. package/src/three/agent-orb.tsx +557 -0
  335. package/src/three/index.ts +5 -0
  336. package/src/types/r3f.d.ts +8 -0
@@ -0,0 +1,767 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Sheet, SheetContent, SheetHeader, SheetTitle } from "./sheet"
5
+ import { Badge } from "./badge"
6
+ import { Button } from "./button"
7
+ import { Input } from "./input"
8
+ import {
9
+ Plus,
10
+ ExternalLink,
11
+ Mail,
12
+ FileText,
13
+ MessageCircle,
14
+ Briefcase,
15
+ Building2,
16
+ Users,
17
+ X,
18
+ ChevronDown,
19
+ ChevronUp,
20
+ Link as LinkIcon,
21
+ Maximize2,
22
+ Minimize2,
23
+ CalendarDays,
24
+ } from "lucide-react"
25
+ import { TimelineActivity, type TimelineEvent } from "./timeline-activity"
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // EntityPanel – supports both Sheet (side panel) and fullscreen modes
29
+ // ---------------------------------------------------------------------------
30
+
31
+ export function EntityPanel({
32
+ isOpen,
33
+ onClose,
34
+ children,
35
+ }: {
36
+ isOpen: boolean
37
+ onClose: (open: boolean) => void
38
+ children?: React.ReactNode
39
+ }) {
40
+ const [isFullscreen, setIsFullscreen] = React.useState(false)
41
+
42
+ React.useEffect(() => {
43
+ if (!isOpen) setIsFullscreen(false)
44
+ }, [isOpen])
45
+
46
+ const handleClose = React.useCallback(() => {
47
+ setIsFullscreen(false)
48
+ onClose(false)
49
+ }, [onClose])
50
+
51
+ const panelContent = (
52
+ <EntityPanelContext.Provider value={{ isFullscreen, setIsFullscreen, onClose: handleClose }}>
53
+ {children}
54
+ </EntityPanelContext.Provider>
55
+ )
56
+
57
+ if (isFullscreen && isOpen) {
58
+ return (
59
+ <div className="fixed inset-0 z-50 flex flex-col overflow-hidden bg-background">
60
+ <div className="flex-1 overflow-y-auto px-6 py-6">{panelContent}</div>
61
+ </div>
62
+ )
63
+ }
64
+
65
+ return (
66
+ <Sheet open={isOpen} onOpenChange={onClose}>
67
+ <SheetContent
68
+ side="right"
69
+ className="w-full sm:w-[500px] sm:max-w-[600px] overflow-hidden p-0 bg-background border-l border-border flex flex-col"
70
+ showCloseButton={false}
71
+ >
72
+ <SheetHeader className="sr-only p-0">
73
+ <SheetTitle>Entity panel</SheetTitle>
74
+ </SheetHeader>
75
+ <div className="flex-1 overflow-y-auto px-6 py-6">{panelContent}</div>
76
+ </SheetContent>
77
+ </Sheet>
78
+ )
79
+ }
80
+
81
+ const EntityPanelContext = React.createContext<{
82
+ isFullscreen: boolean
83
+ setIsFullscreen: (v: boolean) => void
84
+ onClose: () => void
85
+ }>({
86
+ isFullscreen: false,
87
+ setIsFullscreen: () => {},
88
+ onClose: () => {},
89
+ })
90
+
91
+ function useEntityPanel() {
92
+ return React.useContext(EntityPanelContext)
93
+ }
94
+
95
+ // ---------------------------------------------------------------------------
96
+ // EntityPanelHeader – MeetingDetail-inspired header bar
97
+ // ---------------------------------------------------------------------------
98
+
99
+ export function EntityPanelHeader({
100
+ icon,
101
+ title,
102
+ badgeLabel,
103
+ subtitle: _subtitle,
104
+ headerAction,
105
+ }: {
106
+ icon?: React.ReactNode
107
+ title: string
108
+ badgeLabel?: string
109
+ subtitle?: string
110
+ headerAction?: React.ReactNode
111
+ }) {
112
+ const { isFullscreen, setIsFullscreen, onClose } = useEntityPanel()
113
+
114
+ return (
115
+ <div className="flex items-center justify-between mb-6">
116
+ <div className="flex items-center gap-2 min-w-0">
117
+ {icon ?? <CalendarDays className="w-5 h-5 text-muted-foreground shrink-0" />}
118
+ <h2 className="text-lg font-semibold text-foreground truncate">{title}</h2>
119
+ {badgeLabel && (
120
+ <Badge
121
+ variant="outline"
122
+ className="text-blue-600 border-blue-300 dark:border-blue-700 dark:text-blue-400 shadow-none px-2 py-0.5 text-[11px] font-medium shrink-0"
123
+ >
124
+ {badgeLabel}
125
+ </Badge>
126
+ )}
127
+ </div>
128
+ <div className="flex items-center gap-1 shrink-0 ml-4 text-muted-foreground">
129
+ {headerAction}
130
+ <button
131
+ type="button"
132
+ className="p-1.5 rounded-md hover:bg-secondary transition-colors"
133
+ title="Copy Link"
134
+ >
135
+ <LinkIcon className="w-4 h-4" />
136
+ </button>
137
+ <button
138
+ type="button"
139
+ onClick={() => setIsFullscreen(!isFullscreen)}
140
+ className="p-1.5 rounded-md hover:bg-secondary transition-colors"
141
+ title={isFullscreen ? "Exit fullscreen" : "Fullscreen"}
142
+ >
143
+ {isFullscreen ? (
144
+ <Minimize2 className="w-4 h-4" />
145
+ ) : (
146
+ <Maximize2 className="w-4 h-4" />
147
+ )}
148
+ </button>
149
+ <button
150
+ type="button"
151
+ onClick={onClose}
152
+ className="p-1.5 rounded-md hover:bg-secondary transition-colors"
153
+ title="Close"
154
+ >
155
+ <X className="w-4 h-4" />
156
+ </button>
157
+ </div>
158
+ </div>
159
+ )
160
+ }
161
+
162
+ // ---------------------------------------------------------------------------
163
+ // EntityPanelTabs – Overview/Details tab bar
164
+ // ---------------------------------------------------------------------------
165
+
166
+ export function EntityPanelTabs({
167
+ tabs,
168
+ activeTab,
169
+ onTabChange,
170
+ }: {
171
+ tabs: { id: string; label: string }[]
172
+ activeTab: string
173
+ onTabChange: (id: string) => void
174
+ }) {
175
+ return (
176
+ <div className="flex items-center gap-6 border-b border-border mb-6">
177
+ {tabs.map((tab) => (
178
+ <button
179
+ key={tab.id}
180
+ type="button"
181
+ onClick={() => onTabChange(tab.id)}
182
+ className={`pb-3 text-sm font-medium border-b-2 transition-colors ${
183
+ activeTab === tab.id
184
+ ? "border-primary text-foreground"
185
+ : "border-transparent text-muted-foreground hover:text-foreground"
186
+ }`}
187
+ >
188
+ {tab.label}
189
+ </button>
190
+ ))}
191
+ </div>
192
+ )
193
+ }
194
+
195
+ // ---------------------------------------------------------------------------
196
+ // EntityMetadataGrid – key/value metadata rows with icons
197
+ // ---------------------------------------------------------------------------
198
+
199
+ export interface EntityMetadataField {
200
+ icon: React.ComponentType<{ className?: string }>
201
+ label: string
202
+ value: React.ReactNode
203
+ }
204
+
205
+ export function EntityMetadataGrid({ fields }: { fields: EntityMetadataField[] }) {
206
+ return (
207
+ <div className="grid grid-cols-1 md:grid-cols-[160px_1fr] gap-y-4 gap-x-6 mb-8 text-sm">
208
+ {fields.map((field, idx) => (
209
+ <React.Fragment key={idx}>
210
+ <div className="flex items-center gap-2 text-muted-foreground font-medium">
211
+ <field.icon className="w-4 h-4" />
212
+ <span>{field.label}</span>
213
+ </div>
214
+ <div className="text-foreground">{field.value}</div>
215
+ </React.Fragment>
216
+ ))}
217
+ </div>
218
+ )
219
+ }
220
+
221
+ // ---------------------------------------------------------------------------
222
+ // EntitySection – clean section with title (MeetingDetail-style)
223
+ // ---------------------------------------------------------------------------
224
+
225
+ export function EntitySection({
226
+ title,
227
+ children,
228
+ action,
229
+ }: {
230
+ title: string
231
+ children: React.ReactNode
232
+ action?: React.ReactNode
233
+ }) {
234
+ return (
235
+ <section className="mb-8">
236
+ <div className="flex items-center justify-between mb-3">
237
+ <h3 className="text-sm font-semibold text-foreground">{title}</h3>
238
+ {action}
239
+ </div>
240
+ {children}
241
+ </section>
242
+ )
243
+ }
244
+
245
+ // ---------------------------------------------------------------------------
246
+ // EntityActivityItem – clean activity row (MeetingDetail-style)
247
+ // ---------------------------------------------------------------------------
248
+
249
+ export function EntityActivityItem({
250
+ icon,
251
+ title,
252
+ description,
253
+ date,
254
+ }: {
255
+ icon?: React.ReactNode
256
+ title: React.ReactNode
257
+ description?: React.ReactNode
258
+ date?: string
259
+ }) {
260
+ return (
261
+ <div className="flex gap-3 text-[13px]">
262
+ <div className="mt-0.5 text-muted-foreground shrink-0">
263
+ {icon ?? <CalendarDays className="w-4 h-4" />}
264
+ </div>
265
+ <div>
266
+ <p className="text-foreground leading-relaxed">{title}</p>
267
+ {description && <p className="text-[11px] text-muted-foreground/70 mt-0.5">{description}</p>}
268
+ {date && <p className="text-[11px] text-muted-foreground/70 mt-0.5">{date}</p>}
269
+ </div>
270
+ </div>
271
+ )
272
+ }
273
+
274
+ // ---------------------------------------------------------------------------
275
+ // SystemActivity – standalone section for bottom of entity panel
276
+ // ---------------------------------------------------------------------------
277
+
278
+ export function SystemActivity() {
279
+ return (
280
+ <EntitySection title="System Activity">
281
+ <div className="space-y-4">
282
+ <EntityActivityItem
283
+ title={<><span className="font-medium">System</span> enriched the lead</>}
284
+ date="Today at 10:15 AM"
285
+ />
286
+ <EntityActivityItem
287
+ icon={<Mail className="w-4 h-4" />}
288
+ title={<><span className="font-medium">Jackie Lee</span> submitted website form</>}
289
+ date="Yesterday at 3:22 PM"
290
+ />
291
+ </div>
292
+ </EntitySection>
293
+ )
294
+ }
295
+
296
+ // ---------------------------------------------------------------------------
297
+ // PotentialContacts – unchanged from original
298
+ // ---------------------------------------------------------------------------
299
+
300
+ export interface EntityPanelBrandIcons {
301
+ linkedin?: string
302
+ gmail?: string
303
+ slack?: string
304
+ gdoc?: string
305
+ }
306
+
307
+ function EntityPanelBrandIcon({
308
+ src,
309
+ alt,
310
+ className,
311
+ fallback,
312
+ }: {
313
+ src?: string
314
+ alt: string
315
+ className: string
316
+ fallback: React.ReactNode
317
+ }) {
318
+ if (!src) {
319
+ return <>{fallback}</>
320
+ }
321
+
322
+ return <img src={src} alt={alt} className={className} />
323
+ }
324
+
325
+ export function PotentialContacts({
326
+ icons,
327
+ }: {
328
+ icons?: Pick<EntityPanelBrandIcons, "linkedin" | "gmail">
329
+ }) {
330
+ return (
331
+ <div className="space-y-3 mb-8">
332
+ <div className="flex items-center justify-between">
333
+ <h3 className="text-sm font-semibold text-foreground">Potential Contacts</h3>
334
+ <span className="text-xs text-muted-foreground">3 identified</span>
335
+ </div>
336
+ <div className="space-y-0 pt-1">
337
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
338
+ <div className="flex items-center gap-2.5 min-w-0">
339
+ <Badge variant="outline" className="bg-indigo-50 text-indigo-700 border-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-300 dark:border-indigo-800 shadow-none px-2 py-0 text-[11px] font-medium shrink-0">Primary</Badge>
340
+ <span className="font-medium text-sm text-foreground truncate">Jackie Lee</span>
341
+ <span className="text-muted-foreground text-sm shrink-0">&middot;</span>
342
+ <span className="text-muted-foreground text-sm truncate">VP Finance</span>
343
+ </div>
344
+ <div className="flex items-center gap-1 shrink-0">
345
+ <button className="h-7 w-7 flex items-center justify-center hover:bg-muted rounded-md transition-colors">
346
+ <EntityPanelBrandIcon
347
+ src={icons?.linkedin}
348
+ alt="LinkedIn"
349
+ className="w-3.5 h-3.5 object-contain"
350
+ fallback={<LinkIcon className="w-3.5 h-3.5 text-muted-foreground" />}
351
+ />
352
+ </button>
353
+ <button className="h-7 w-7 flex items-center justify-center hover:bg-muted rounded-md transition-colors">
354
+ <EntityPanelBrandIcon
355
+ src={icons?.gmail}
356
+ alt="Gmail"
357
+ className="w-3.5 h-3.5 object-contain"
358
+ fallback={<Mail className="w-3.5 h-3.5 text-muted-foreground" />}
359
+ />
360
+ </button>
361
+ <Button size="sm" className="bg-foreground text-background hover:bg-foreground/90 h-6 text-[11px] font-medium shadow-none ml-1">
362
+ <Plus className="w-3 h-3 mr-1" /> Add to SF
363
+ </Button>
364
+ </div>
365
+ </div>
366
+
367
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
368
+ <div className="flex items-center gap-2.5 min-w-0">
369
+ <Badge variant="outline" className="bg-green-50 text-green-700 border-green-200 dark:bg-green-900/30 dark:text-green-300 dark:border-green-800 shadow-none px-2 py-0 text-[11px] font-medium shrink-0">78%</Badge>
370
+ <span className="font-medium text-sm text-foreground truncate">Marcus Webb</span>
371
+ <span className="text-muted-foreground text-sm shrink-0">&middot;</span>
372
+ <span className="text-muted-foreground text-sm truncate">CEO</span>
373
+ </div>
374
+ <div className="flex items-center gap-1 shrink-0">
375
+ <button className="h-7 w-7 flex items-center justify-center hover:bg-muted rounded-md transition-colors">
376
+ <EntityPanelBrandIcon
377
+ src={icons?.linkedin}
378
+ alt="LinkedIn"
379
+ className="w-3.5 h-3.5 object-contain"
380
+ fallback={<LinkIcon className="w-3.5 h-3.5 text-muted-foreground" />}
381
+ />
382
+ </button>
383
+ <Button size="sm" className="bg-foreground text-background hover:bg-foreground/90 h-6 text-[11px] font-medium shadow-none ml-1">
384
+ <Plus className="w-3 h-3 mr-1" /> Add to SF
385
+ </Button>
386
+ </div>
387
+ </div>
388
+
389
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 last:border-0 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
390
+ <div className="flex items-center gap-2.5 min-w-0">
391
+ <Badge variant="outline" className="bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-800 shadow-none px-2 py-0 text-[11px] font-medium shrink-0">65%</Badge>
392
+ <span className="font-medium text-sm text-foreground truncate">Priya Shah</span>
393
+ <span className="text-muted-foreground text-sm shrink-0">&middot;</span>
394
+ <span className="text-muted-foreground text-sm truncate">Head of Ops</span>
395
+ </div>
396
+ <div className="flex items-center gap-1 shrink-0">
397
+ <button className="h-7 w-7 flex items-center justify-center hover:bg-muted rounded-md transition-colors">
398
+ <EntityPanelBrandIcon
399
+ src={icons?.linkedin}
400
+ alt="LinkedIn"
401
+ className="w-3.5 h-3.5 object-contain"
402
+ fallback={<LinkIcon className="w-3.5 h-3.5 text-muted-foreground" />}
403
+ />
404
+ </button>
405
+ <button className="h-7 w-7 flex items-center justify-center hover:bg-muted rounded-md transition-colors">
406
+ <EntityPanelBrandIcon
407
+ src={icons?.gmail}
408
+ alt="Gmail"
409
+ className="w-3.5 h-3.5 object-contain"
410
+ fallback={<Mail className="w-3.5 h-3.5 text-muted-foreground" />}
411
+ />
412
+ </button>
413
+ <Button size="sm" className="bg-foreground text-background hover:bg-foreground/90 h-6 text-[11px] font-medium shadow-none ml-1">
414
+ <Plus className="w-3 h-3 mr-1" /> Add to SF
415
+ </Button>
416
+ </div>
417
+ </div>
418
+ </div>
419
+ </div>
420
+ )
421
+ }
422
+
423
+ // ---------------------------------------------------------------------------
424
+ // RecentActivity
425
+ // ---------------------------------------------------------------------------
426
+
427
+ export type ActivityItem = TimelineEvent
428
+
429
+ export function RecentActivity({
430
+ title = "Recent Activity",
431
+ count = "10 total events",
432
+ filters = [],
433
+ items = [],
434
+ }: {
435
+ title?: string
436
+ count?: string
437
+ filters?: string[]
438
+ items?: TimelineEvent[]
439
+ }) {
440
+ return (
441
+ <div id="entity-recent-activity" className="space-y-4 mb-8 scroll-m-20">
442
+ <div className="flex items-center justify-between">
443
+ <h3 className="text-sm font-semibold text-foreground">{title}</h3>
444
+ {count && <span className="text-xs text-muted-foreground">{count}</span>}
445
+ </div>
446
+
447
+ {filters.length > 0 && (
448
+ <div className="flex flex-wrap items-center gap-1.5">
449
+ {filters.map((filter) => (
450
+ <Button
451
+ key={filter}
452
+ variant="outline"
453
+ size="sm"
454
+ className="h-7 text-xs rounded-md shadow-none font-medium border-border text-muted-foreground hover:text-foreground"
455
+ >
456
+ {filter}
457
+ </Button>
458
+ ))}
459
+ </div>
460
+ )}
461
+
462
+ <div className="relative">
463
+ <Input
464
+ placeholder="Search activity..."
465
+ className="h-9 text-sm bg-background border-border shadow-none"
466
+ />
467
+ </div>
468
+
469
+ <div>
470
+ <TimelineActivity events={items} />
471
+ </div>
472
+ </div>
473
+ )
474
+ }
475
+
476
+ // ---------------------------------------------------------------------------
477
+ // ConnectedApps
478
+ // ---------------------------------------------------------------------------
479
+
480
+ export function ConnectedApps({
481
+ icons,
482
+ }: {
483
+ icons?: Pick<EntityPanelBrandIcons, "slack" | "gdoc">
484
+ }) {
485
+ return (
486
+ <div className="space-y-3 mb-8">
487
+ <div className="flex items-center justify-between">
488
+ <h3 className="text-sm font-semibold text-foreground">Connected Apps</h3>
489
+ <span className="text-xs text-muted-foreground">3 connected</span>
490
+ </div>
491
+
492
+ <div className="space-y-0 pt-1">
493
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
494
+ <div className="flex items-center gap-3 min-w-0">
495
+ <div className="w-8 h-8 rounded-md border border-border/60 bg-muted/30 flex items-center justify-center shrink-0">
496
+ <EntityPanelBrandIcon
497
+ src={icons?.slack}
498
+ alt="Slack"
499
+ className="w-4 h-4 object-contain"
500
+ fallback={<MessageCircle className="w-4 h-4 text-muted-foreground" />}
501
+ />
502
+ </div>
503
+ <div className="min-w-0">
504
+ <p className="font-medium text-sm text-foreground leading-snug truncate">#lunchclub-acmeco</p>
505
+ <p className="text-xs text-muted-foreground/60">Slack Channel</p>
506
+ </div>
507
+ </div>
508
+ <div className="flex items-center gap-1.5 shrink-0">
509
+ <ExternalLink className="w-3 h-3 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" />
510
+ <span className="text-xs text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer hover:text-foreground">Open</span>
511
+ </div>
512
+ </div>
513
+
514
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
515
+ <div className="flex items-center gap-3 min-w-0">
516
+ <div className="w-8 h-8 rounded-md border border-border/60 bg-muted/30 flex items-center justify-center shrink-0">
517
+ <EntityPanelBrandIcon
518
+ src={icons?.gdoc}
519
+ alt="Google Docs"
520
+ className="w-4 h-4 object-contain"
521
+ fallback={<FileText className="w-4 h-4 text-muted-foreground" />}
522
+ />
523
+ </div>
524
+ <div className="min-w-0">
525
+ <p className="font-medium text-sm text-foreground leading-snug truncate">Account Strategy Document</p>
526
+ <p className="text-xs text-muted-foreground/60">Google Document</p>
527
+ </div>
528
+ </div>
529
+ <div className="flex items-center gap-1.5 shrink-0">
530
+ <ExternalLink className="w-3 h-3 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" />
531
+ <span className="text-xs text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer hover:text-foreground">Open</span>
532
+ </div>
533
+ </div>
534
+
535
+ <div className="flex items-center justify-between gap-3 group py-2.5 border-b border-border/30 last:border-0 hover:bg-muted/20 -mx-2 px-2 rounded-sm transition-colors">
536
+ <div className="flex items-center gap-3 min-w-0">
537
+ <div className="w-8 h-8 rounded-md border border-border/60 bg-muted/30 flex items-center justify-center shrink-0">
538
+ <FileText className="w-4 h-4 text-foreground" />
539
+ </div>
540
+ <div className="min-w-0">
541
+ <p className="font-medium text-sm text-foreground leading-snug truncate">Customer Success Playbook</p>
542
+ <p className="text-xs text-muted-foreground/60">Notion Page</p>
543
+ </div>
544
+ </div>
545
+ <div className="flex items-center gap-1.5 shrink-0">
546
+ <ExternalLink className="w-3 h-3 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" />
547
+ <span className="text-xs text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer hover:text-foreground">Open</span>
548
+ </div>
549
+ </div>
550
+ </div>
551
+ </div>
552
+ )
553
+ }
554
+
555
+ // ---------------------------------------------------------------------------
556
+ // EntityDetails – updated with MeetingDetail-inspired metadata grid + tabs
557
+ // ---------------------------------------------------------------------------
558
+
559
+ export function EntityDetails({ onClose: _onClose }: { onClose?: () => void }) {
560
+ const [activeTab, setActiveTab] = React.useState<"overview" | "details">("overview")
561
+ const [showMore, setShowMore] = React.useState(false)
562
+
563
+ const leadFields: EntityMetadataField[] = [
564
+ { icon: Users, label: "Lead Name", value: <span className="font-medium">Jackie Lee</span> },
565
+ { icon: Briefcase, label: "Title", value: <span className="font-medium">VP Finance</span> },
566
+ { icon: Building2, label: "Company", value: <span className="font-medium">CloudKitchen</span> },
567
+ { icon: Mail, label: "Lead Source", value: <span className="font-medium">Inbound — Website form</span> },
568
+ {
569
+ icon: ({ className }) => (
570
+ <div className={className}>
571
+ <div className="w-3 h-3 rounded-full border-[2px] border-amber-500" />
572
+ </div>
573
+ ),
574
+ label: "Lead Status",
575
+ value: (
576
+ <Badge variant="outline" className="text-amber-700 border-amber-200 bg-amber-50 dark:bg-amber-950 dark:text-amber-300 dark:border-amber-800 shadow-none font-medium px-2 py-0 text-[11px]">
577
+ New — Not Contacted
578
+ </Badge>
579
+ ),
580
+ },
581
+ { icon: Users, label: "Lead Owner", value: <span className="font-medium">Sarah Johnson (SDR)</span> },
582
+ {
583
+ icon: Building2,
584
+ label: "Industry",
585
+ value: (
586
+ <Badge variant="outline" className="text-blue-700 border-blue-200 bg-blue-50 dark:bg-blue-950 dark:text-blue-300 dark:border-blue-800 shadow-none font-medium px-2 py-0 text-[11px]">
587
+ Food Tech / Logistics
588
+ </Badge>
589
+ ),
590
+ },
591
+ { icon: Users, label: "Company Size", value: <span className="font-medium">200-500 employees</span> },
592
+ ]
593
+
594
+ const visibleFields = showMore ? leadFields : leadFields.slice(0, 6)
595
+
596
+ return (
597
+ <div className="space-y-0">
598
+ {/* Header */}
599
+ <EntityPanelHeader
600
+ icon={
601
+ <div className="w-10 h-10 rounded-lg bg-muted flex items-center justify-center text-sm font-medium text-muted-foreground shrink-0">
602
+ CK
603
+ </div>
604
+ }
605
+ title="CloudKitchen"
606
+ badgeLabel="Lead"
607
+ subtitle="Last enriched: Today at 10:15 AM"
608
+ />
609
+
610
+ {/* Tabs */}
611
+ <EntityPanelTabs
612
+ tabs={[
613
+ { id: "overview", label: "Overview" },
614
+ { id: "details", label: "Details" },
615
+ ]}
616
+ activeTab={activeTab}
617
+ onTabChange={(id) => setActiveTab(id as "overview" | "details")}
618
+ />
619
+
620
+ {activeTab === "overview" ? (
621
+ <div className="space-y-0">
622
+ {/* Metadata Grid */}
623
+ <EntityMetadataGrid fields={visibleFields} />
624
+
625
+ {leadFields.length > 6 && (
626
+ <button
627
+ onClick={() => setShowMore(!showMore)}
628
+ className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors mb-8"
629
+ >
630
+ {showMore ? "See less" : "See more"}
631
+ {showMore ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
632
+ </button>
633
+ )}
634
+
635
+ {/* Enrichment as sections */}
636
+ <EntitySection title="Company Signals">
637
+ <ul className="space-y-2">
638
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
639
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
640
+ <span>
641
+ Recent funding: $45M Series B, 3 months ago
642
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">1</span>
643
+ </span>
644
+ </li>
645
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
646
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
647
+ <span>
648
+ Hiring: 3 finance/treasury roles in last 30 days
649
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">2</span>
650
+ </span>
651
+ </li>
652
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
653
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
654
+ <span>
655
+ Market expansion: 8 &rarr; 15 US markets planned
656
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">3</span>
657
+ </span>
658
+ </li>
659
+ </ul>
660
+ </EntitySection>
661
+
662
+ <EntitySection title="Contact Signals (Jackie Lee)">
663
+ <ul className="space-y-2">
664
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
665
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
666
+ <span>
667
+ Started role: 12 days ago
668
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">4</span>
669
+ </span>
670
+ </li>
671
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
672
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
673
+ <span>
674
+ Previous: Deel — operations/finance
675
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">4</span>
676
+ </span>
677
+ </li>
678
+ <li className="flex items-start gap-2 text-sm text-muted-foreground">
679
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
680
+ <span>
681
+ LinkedIn connections to existing customers: 2 detected
682
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">4</span>
683
+ </span>
684
+ </li>
685
+ </ul>
686
+ </EntitySection>
687
+
688
+ <SourcesToggle />
689
+ </div>
690
+ ) : (
691
+ <div className="space-y-0">
692
+ <EntitySection title="Estimated Tech Stack">
693
+ <div className="space-y-2">
694
+ <div className="flex items-start gap-2 text-sm">
695
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
696
+ <span className="text-muted-foreground min-w-[100px] shrink-0">Banking:</span>
697
+ <span className="text-muted-foreground/50 italic">Unknown</span>
698
+ </div>
699
+ <div className="flex items-start gap-2 text-sm">
700
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
701
+ <span className="text-muted-foreground min-w-[100px] shrink-0">Corporate Cards:</span>
702
+ <span className="text-foreground font-medium">
703
+ Brex <span className="text-muted-foreground font-normal">(from job posting requirements)</span>
704
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">2</span>
705
+ </span>
706
+ </div>
707
+ <div className="flex items-start gap-2 text-sm">
708
+ <span className="text-muted-foreground/50 mt-1 shrink-0">&bull;</span>
709
+ <span className="text-muted-foreground min-w-[100px] shrink-0">Payroll:</span>
710
+ <span className="text-foreground font-medium">
711
+ Gusto <span className="text-muted-foreground font-normal">(from LinkedIn integrations)</span>
712
+ <span className="inline-flex items-center justify-center w-4 h-4 ml-1.5 align-text-top text-[9px] font-medium text-muted-foreground bg-muted/30 border border-border/50 rounded-full">5</span>
713
+ </span>
714
+ </div>
715
+ </div>
716
+ </EntitySection>
717
+ </div>
718
+ )}
719
+ </div>
720
+ )
721
+ }
722
+
723
+ // ---------------------------------------------------------------------------
724
+ // SourcesToggle – collapsible sources list
725
+ // ---------------------------------------------------------------------------
726
+
727
+ function SourcesToggle() {
728
+ const [expanded, setExpanded] = React.useState(false)
729
+
730
+ const sources = [
731
+ { name: "Crunchbase", type: "Funding data", lastPull: "2h ago" },
732
+ { name: "LinkedIn", type: "People & company", lastPull: "12h ago" },
733
+ { name: "LinkedIn Jobs", type: "Hiring signals", lastPull: "1d ago" },
734
+ { name: "PR Newswire", type: "News & press", lastPull: "6h ago" },
735
+ { name: "Clearbit", type: "Tech stack & firmographics", lastPull: "2h ago" },
736
+ ]
737
+
738
+ return (
739
+ <div className="mb-8">
740
+ <button
741
+ onClick={() => setExpanded(!expanded)}
742
+ className="flex items-center gap-1.5 text-xs font-semibold text-muted-foreground hover:text-foreground transition-colors"
743
+ >
744
+ Sources
745
+ <ChevronDown className={`w-3.5 h-3.5 transition-transform duration-200 ${expanded ? "rotate-180" : ""}`} />
746
+ </button>
747
+
748
+ {expanded && (
749
+ <div className="pt-3 space-y-2 animate-in fade-in slide-in-from-top-1 duration-200">
750
+ {sources.map((src, idx) => (
751
+ <div key={idx} className="flex items-center justify-between text-xs text-muted-foreground py-1">
752
+ <div className="flex items-center gap-2">
753
+ <span className="inline-flex items-center justify-center w-4 h-4 text-[9px] font-medium text-muted-foreground/50 border border-border rounded-full">
754
+ {idx + 1}
755
+ </span>
756
+ <span className="font-medium text-foreground">{src.name}</span>
757
+ <span className="text-muted-foreground/60">&middot;</span>
758
+ <span>{src.type}</span>
759
+ </div>
760
+ <span className="text-muted-foreground/50">{src.lastPull}</span>
761
+ </div>
762
+ ))}
763
+ </div>
764
+ )}
765
+ </div>
766
+ )
767
+ }