@comitor/ui 0.1.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 (307) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +458 -0
  3. package/dist/chart/chart.d.ts +88 -0
  4. package/dist/chart/chart.js +199 -0
  5. package/dist/chart/chart.js.map +1 -0
  6. package/dist/chart/comitor-chart.d.ts +109 -0
  7. package/dist/chart/comitor-chart.js +189 -0
  8. package/dist/chart/comitor-chart.js.map +1 -0
  9. package/dist/chart/index.d.ts +4 -0
  10. package/dist/chart/index.js +3 -0
  11. package/dist/chart/index.js.map +1 -0
  12. package/dist/components/composite/avatar-group.d.ts +33 -0
  13. package/dist/components/composite/avatar-group.js +86 -0
  14. package/dist/components/composite/avatar-group.js.map +1 -0
  15. package/dist/components/composite/combobox.d.ts +70 -0
  16. package/dist/components/composite/combobox.js +291 -0
  17. package/dist/components/composite/combobox.js.map +1 -0
  18. package/dist/components/composite/command-palette.d.ts +56 -0
  19. package/dist/components/composite/command-palette.js +131 -0
  20. package/dist/components/composite/command-palette.js.map +1 -0
  21. package/dist/components/composite/confirm-dialog.d.ts +40 -0
  22. package/dist/components/composite/confirm-dialog.js +96 -0
  23. package/dist/components/composite/confirm-dialog.js.map +1 -0
  24. package/dist/components/composite/copy-button.d.ts +27 -0
  25. package/dist/components/composite/copy-button.js +80 -0
  26. package/dist/components/composite/copy-button.js.map +1 -0
  27. package/dist/components/composite/data-table.d.ts +136 -0
  28. package/dist/components/composite/data-table.js +300 -0
  29. package/dist/components/composite/data-table.js.map +1 -0
  30. package/dist/components/composite/date-picker.d.ts +77 -0
  31. package/dist/components/composite/date-picker.js +268 -0
  32. package/dist/components/composite/date-picker.js.map +1 -0
  33. package/dist/components/composite/empty-state.d.ts +38 -0
  34. package/dist/components/composite/empty-state.js +35 -0
  35. package/dist/components/composite/empty-state.js.map +1 -0
  36. package/dist/components/composite/filter-chips.d.ts +39 -0
  37. package/dist/components/composite/filter-chips.js +79 -0
  38. package/dist/components/composite/filter-chips.js.map +1 -0
  39. package/dist/components/composite/form-field.d.ts +58 -0
  40. package/dist/components/composite/form-field.js +81 -0
  41. package/dist/components/composite/form-field.js.map +1 -0
  42. package/dist/components/composite/form-section.d.ts +33 -0
  43. package/dist/components/composite/form-section.js +85 -0
  44. package/dist/components/composite/form-section.js.map +1 -0
  45. package/dist/components/composite/inline-edit.d.ts +38 -0
  46. package/dist/components/composite/inline-edit.js +165 -0
  47. package/dist/components/composite/inline-edit.js.map +1 -0
  48. package/dist/components/composite/keyboard-hint.d.ts +31 -0
  49. package/dist/components/composite/keyboard-hint.js +72 -0
  50. package/dist/components/composite/keyboard-hint.js.map +1 -0
  51. package/dist/components/composite/letter-avatar.d.ts +47 -0
  52. package/dist/components/composite/letter-avatar.js +66 -0
  53. package/dist/components/composite/letter-avatar.js.map +1 -0
  54. package/dist/components/composite/page-container.d.ts +25 -0
  55. package/dist/components/composite/page-container.js +23 -0
  56. package/dist/components/composite/page-container.js.map +1 -0
  57. package/dist/components/composite/page-header.d.ts +49 -0
  58. package/dist/components/composite/page-header.js +75 -0
  59. package/dist/components/composite/page-header.js.map +1 -0
  60. package/dist/components/composite/relative-time.d.ts +28 -0
  61. package/dist/components/composite/relative-time.js +44 -0
  62. package/dist/components/composite/relative-time.js.map +1 -0
  63. package/dist/components/composite/search-filter-bar.d.ts +38 -0
  64. package/dist/components/composite/search-filter-bar.js +135 -0
  65. package/dist/components/composite/search-filter-bar.js.map +1 -0
  66. package/dist/components/composite/stat-card.d.ts +48 -0
  67. package/dist/components/composite/stat-card.js +76 -0
  68. package/dist/components/composite/stat-card.js.map +1 -0
  69. package/dist/components/composite/status-config.d.ts +85 -0
  70. package/dist/components/composite/status-config.js +41 -0
  71. package/dist/components/composite/status-config.js.map +1 -0
  72. package/dist/components/composite/status-pill.d.ts +26 -0
  73. package/dist/components/composite/status-pill.js +59 -0
  74. package/dist/components/composite/status-pill.js.map +1 -0
  75. package/dist/components/composite/table-pagination.d.ts +31 -0
  76. package/dist/components/composite/table-pagination.js +103 -0
  77. package/dist/components/composite/table-pagination.js.map +1 -0
  78. package/dist/components/composite/text-utils.d.ts +38 -0
  79. package/dist/components/composite/text-utils.js +40 -0
  80. package/dist/components/composite/text-utils.js.map +1 -0
  81. package/dist/components/composite/toast.d.ts +56 -0
  82. package/dist/components/composite/toast.js +63 -0
  83. package/dist/components/composite/toast.js.map +1 -0
  84. package/dist/components/ui/accordion.d.ts +17 -0
  85. package/dist/components/ui/accordion.js +53 -0
  86. package/dist/components/ui/accordion.js.map +1 -0
  87. package/dist/components/ui/alert-dialog.d.ts +34 -0
  88. package/dist/components/ui/alert-dialog.js +103 -0
  89. package/dist/components/ui/alert-dialog.js.map +1 -0
  90. package/dist/components/ui/alert.d.ts +16 -0
  91. package/dist/components/ui/alert.js +50 -0
  92. package/dist/components/ui/alert.js.map +1 -0
  93. package/dist/components/ui/aspect-ratio.d.ts +7 -0
  94. package/dist/components/ui/aspect-ratio.js +10 -0
  95. package/dist/components/ui/aspect-ratio.js.map +1 -0
  96. package/dist/components/ui/avatar.d.ts +11 -0
  97. package/dist/components/ui/avatar.js +33 -0
  98. package/dist/components/ui/avatar.js.map +1 -0
  99. package/dist/components/ui/badge.d.ts +15 -0
  100. package/dist/components/ui/badge.js +37 -0
  101. package/dist/components/ui/badge.js.map +1 -0
  102. package/dist/components/ui/breadcrumb.d.ts +30 -0
  103. package/dist/components/ui/breadcrumb.js +89 -0
  104. package/dist/components/ui/breadcrumb.js.map +1 -0
  105. package/dist/components/ui/button-group.d.ts +21 -0
  106. package/dist/components/ui/button-group.js +62 -0
  107. package/dist/components/ui/button-group.js.map +1 -0
  108. package/dist/components/ui/button.d.ts +21 -0
  109. package/dist/components/ui/button.js +70 -0
  110. package/dist/components/ui/button.js.map +1 -0
  111. package/dist/components/ui/calendar.d.ts +26 -0
  112. package/dist/components/ui/calendar.js +148 -0
  113. package/dist/components/ui/calendar.js.map +1 -0
  114. package/dist/components/ui/card.d.ts +33 -0
  115. package/dist/components/ui/card.js +70 -0
  116. package/dist/components/ui/card.js.map +1 -0
  117. package/dist/components/ui/carousel.d.ts +46 -0
  118. package/dist/components/ui/carousel.js +173 -0
  119. package/dist/components/ui/carousel.js.map +1 -0
  120. package/dist/components/ui/checkbox.d.ts +17 -0
  121. package/dist/components/ui/checkbox.js +67 -0
  122. package/dist/components/ui/checkbox.js.map +1 -0
  123. package/dist/components/ui/collapsible.d.ts +17 -0
  124. package/dist/components/ui/collapsible.js +18 -0
  125. package/dist/components/ui/collapsible.js.map +1 -0
  126. package/dist/components/ui/command.d.ts +41 -0
  127. package/dist/components/ui/command.js +122 -0
  128. package/dist/components/ui/command.js.map +1 -0
  129. package/dist/components/ui/context-menu.d.ts +51 -0
  130. package/dist/components/ui/context-menu.js +166 -0
  131. package/dist/components/ui/context-menu.js.map +1 -0
  132. package/dist/components/ui/dialog.d.ts +48 -0
  133. package/dist/components/ui/dialog.js +131 -0
  134. package/dist/components/ui/dialog.js.map +1 -0
  135. package/dist/components/ui/drawer.d.ts +32 -0
  136. package/dist/components/ui/drawer.js +102 -0
  137. package/dist/components/ui/drawer.js.map +1 -0
  138. package/dist/components/ui/dropdown-menu.d.ts +52 -0
  139. package/dist/components/ui/dropdown-menu.js +167 -0
  140. package/dist/components/ui/dropdown-menu.js.map +1 -0
  141. package/dist/components/ui/empty.d.ts +22 -0
  142. package/dist/components/ui/empty.js +87 -0
  143. package/dist/components/ui/empty.js.map +1 -0
  144. package/dist/components/ui/field.d.ts +46 -0
  145. package/dist/components/ui/field.js +197 -0
  146. package/dist/components/ui/field.js.map +1 -0
  147. package/dist/components/ui/form.d.ts +50 -0
  148. package/dist/components/ui/form.js +100 -0
  149. package/dist/components/ui/form.js.map +1 -0
  150. package/dist/components/ui/hover-card.d.ts +17 -0
  151. package/dist/components/ui/hover-card.js +31 -0
  152. package/dist/components/ui/hover-card.js.map +1 -0
  153. package/dist/components/ui/input-group.d.ts +26 -0
  154. package/dist/components/ui/input-group.js +148 -0
  155. package/dist/components/ui/input-group.js.map +1 -0
  156. package/dist/components/ui/input-otp.d.ts +23 -0
  157. package/dist/components/ui/input-otp.js +54 -0
  158. package/dist/components/ui/input-otp.js.map +1 -0
  159. package/dist/components/ui/input.d.ts +21 -0
  160. package/dist/components/ui/input.js +62 -0
  161. package/dist/components/ui/input.js.map +1 -0
  162. package/dist/components/ui/item.d.ts +39 -0
  163. package/dist/components/ui/item.js +142 -0
  164. package/dist/components/ui/item.js.map +1 -0
  165. package/dist/components/ui/kbd.d.ts +8 -0
  166. package/dist/components/ui/kbd.js +25 -0
  167. package/dist/components/ui/kbd.js.map +1 -0
  168. package/dist/components/ui/label.d.ts +7 -0
  169. package/dist/components/ui/label.js +21 -0
  170. package/dist/components/ui/label.js.map +1 -0
  171. package/dist/components/ui/menubar.d.ts +51 -0
  172. package/dist/components/ui/menubar.js +196 -0
  173. package/dist/components/ui/menubar.js.map +1 -0
  174. package/dist/components/ui/navigation-menu.d.ts +39 -0
  175. package/dist/components/ui/navigation-menu.js +123 -0
  176. package/dist/components/ui/navigation-menu.js.map +1 -0
  177. package/dist/components/ui/pagination.d.ts +40 -0
  178. package/dist/components/ui/pagination.js +95 -0
  179. package/dist/components/ui/pagination.js.map +1 -0
  180. package/dist/components/ui/popover.d.ts +19 -0
  181. package/dist/components/ui/popover.js +35 -0
  182. package/dist/components/ui/popover.js.map +1 -0
  183. package/dist/components/ui/progress.d.ts +12 -0
  184. package/dist/components/ui/progress.js +27 -0
  185. package/dist/components/ui/progress.js.map +1 -0
  186. package/dist/components/ui/radio-group.d.ts +9 -0
  187. package/dist/components/ui/radio-group.js +34 -0
  188. package/dist/components/ui/radio-group.js.map +1 -0
  189. package/dist/components/ui/resizable.d.ts +19 -0
  190. package/dist/components/ui/resizable.js +38 -0
  191. package/dist/components/ui/resizable.js.map +1 -0
  192. package/dist/components/ui/scroll-area.d.ts +13 -0
  193. package/dist/components/ui/scroll-area.js +46 -0
  194. package/dist/components/ui/scroll-area.js.map +1 -0
  195. package/dist/components/ui/select.d.ts +33 -0
  196. package/dist/components/ui/select.js +133 -0
  197. package/dist/components/ui/select.js.map +1 -0
  198. package/dist/components/ui/separator.d.ts +7 -0
  199. package/dist/components/ui/separator.js +23 -0
  200. package/dist/components/ui/separator.js.map +1 -0
  201. package/dist/components/ui/sheet.d.ts +38 -0
  202. package/dist/components/ui/sheet.js +96 -0
  203. package/dist/components/ui/sheet.js.map +1 -0
  204. package/dist/components/ui/skeleton.d.ts +6 -0
  205. package/dist/components/ui/skeleton.js +9 -0
  206. package/dist/components/ui/skeleton.js.map +1 -0
  207. package/dist/components/ui/slider.d.ts +12 -0
  208. package/dist/components/ui/slider.js +54 -0
  209. package/dist/components/ui/slider.js.map +1 -0
  210. package/dist/components/ui/sonner.d.ts +9 -0
  211. package/dist/components/ui/sonner.js +25 -0
  212. package/dist/components/ui/sonner.js.map +1 -0
  213. package/dist/components/ui/spinner.d.ts +6 -0
  214. package/dist/components/ui/spinner.js +10 -0
  215. package/dist/components/ui/spinner.js.map +1 -0
  216. package/dist/components/ui/switch.d.ts +14 -0
  217. package/dist/components/ui/switch.js +65 -0
  218. package/dist/components/ui/switch.js.map +1 -0
  219. package/dist/components/ui/table.d.ts +30 -0
  220. package/dist/components/ui/table.js +87 -0
  221. package/dist/components/ui/table.js.map +1 -0
  222. package/dist/components/ui/tabs.d.ts +35 -0
  223. package/dist/components/ui/tabs.js +54 -0
  224. package/dist/components/ui/tabs.js.map +1 -0
  225. package/dist/components/ui/textarea.d.ts +6 -0
  226. package/dist/components/ui/textarea.js +19 -0
  227. package/dist/components/ui/textarea.js.map +1 -0
  228. package/dist/components/ui/toggle-group.d.ts +18 -0
  229. package/dist/components/ui/toggle-group.js +52 -0
  230. package/dist/components/ui/toggle-group.js.map +1 -0
  231. package/dist/components/ui/toggle.d.ts +15 -0
  232. package/dist/components/ui/toggle.js +33 -0
  233. package/dist/components/ui/toggle.js.map +1 -0
  234. package/dist/components/ui/tooltip.d.ts +21 -0
  235. package/dist/components/ui/tooltip.js +38 -0
  236. package/dist/components/ui/tooltip.js.map +1 -0
  237. package/dist/form.d.ts +5 -0
  238. package/dist/form.js +2 -0
  239. package/dist/form.js.map +1 -0
  240. package/dist/index.d.ts +111 -0
  241. package/dist/index.js +76 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/lib/cn.d.ts +16 -0
  244. package/dist/lib/cn.js +9 -0
  245. package/dist/lib/cn.js.map +1 -0
  246. package/dist/shell/app-header.d.ts +41 -0
  247. package/dist/shell/app-header.js +136 -0
  248. package/dist/shell/app-header.js.map +1 -0
  249. package/dist/shell/app-launcher.d.ts +33 -0
  250. package/dist/shell/app-launcher.js +189 -0
  251. package/dist/shell/app-launcher.js.map +1 -0
  252. package/dist/shell/app-shell.d.ts +44 -0
  253. package/dist/shell/app-shell.js +99 -0
  254. package/dist/shell/app-shell.js.map +1 -0
  255. package/dist/shell/comitor-lockup.d.ts +33 -0
  256. package/dist/shell/comitor-lockup.js +112 -0
  257. package/dist/shell/comitor-lockup.js.map +1 -0
  258. package/dist/shell/comitor-logo.d.ts +28 -0
  259. package/dist/shell/comitor-logo.js +92 -0
  260. package/dist/shell/comitor-logo.js.map +1 -0
  261. package/dist/shell/index.d.ts +24 -0
  262. package/dist/shell/index.js +23 -0
  263. package/dist/shell/index.js.map +1 -0
  264. package/dist/shell/mobile-menu.d.ts +26 -0
  265. package/dist/shell/mobile-menu.js +56 -0
  266. package/dist/shell/mobile-menu.js.map +1 -0
  267. package/dist/shell/notifications-button.d.ts +22 -0
  268. package/dist/shell/notifications-button.js +39 -0
  269. package/dist/shell/notifications-button.js.map +1 -0
  270. package/dist/shell/shell-context.d.ts +91 -0
  271. package/dist/shell/shell-context.js +233 -0
  272. package/dist/shell/shell-context.js.map +1 -0
  273. package/dist/shell/shell-link.d.ts +19 -0
  274. package/dist/shell/shell-link.js +18 -0
  275. package/dist/shell/shell-link.js.map +1 -0
  276. package/dist/shell/sidebar-group.d.ts +21 -0
  277. package/dist/shell/sidebar-group.js +43 -0
  278. package/dist/shell/sidebar-group.js.map +1 -0
  279. package/dist/shell/sidebar-menu-item.d.ts +27 -0
  280. package/dist/shell/sidebar-menu-item.js +152 -0
  281. package/dist/shell/sidebar-menu-item.js.map +1 -0
  282. package/dist/shell/sidebar.d.ts +26 -0
  283. package/dist/shell/sidebar.js +92 -0
  284. package/dist/shell/sidebar.js.map +1 -0
  285. package/dist/shell/theme-provider.d.ts +18 -0
  286. package/dist/shell/theme-provider.js +29 -0
  287. package/dist/shell/theme-provider.js.map +1 -0
  288. package/dist/shell/theme-toggle.d.ts +28 -0
  289. package/dist/shell/theme-toggle.js +67 -0
  290. package/dist/shell/theme-toggle.js.map +1 -0
  291. package/dist/shell/types.d.ts +168 -0
  292. package/dist/shell/types.js +38 -0
  293. package/dist/shell/types.js.map +1 -0
  294. package/dist/shell/user-menu.d.ts +42 -0
  295. package/dist/shell/user-menu.js +132 -0
  296. package/dist/shell/user-menu.js.map +1 -0
  297. package/dist/shell/utils.d.ts +62 -0
  298. package/dist/shell/utils.js +73 -0
  299. package/dist/shell/utils.js.map +1 -0
  300. package/dist/shell/workspace-switcher.d.ts +24 -0
  301. package/dist/shell/workspace-switcher.js +219 -0
  302. package/dist/shell/workspace-switcher.js.map +1 -0
  303. package/dist/tokens.d.ts +173 -0
  304. package/dist/tokens.js +161 -0
  305. package/dist/tokens.js.map +1 -0
  306. package/package.json +151 -0
  307. package/styles.css +357 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tokens.ts"],"sourcesContent":["/**\n * Design token dạng TS object — dành cho nơi KHÔNG có Tailwind: canvas, biểu đồ tuỳ biến,\n * email HTML, xuất PDF, (sau này) React Native.\n *\n * ⚠ Nguồn sự thật của giá trị là `styles.css` (CSS variable). File này chỉ MIRROR hằng số.\n * Sửa màu ở styles.css thì phải sửa kèm ở đây — và ngược lại.\n *\n * Trong môi trường có Tailwind, LUÔN dùng class token (`bg-primary`, `text-ash-500`),\n * đừng đọc hex từ đây rồi nhét vào style inline: làm vậy là mất dark mode.\n */\n\n/** Thang GOLD 7 bậc — trục màu chính của brand Comitor. */\nexport const gold = {\n 50: \"#FBF5DC\",\n 100: \"#F8E89D\",\n 200: \"#F5D060\",\n /** primary ở light mode */\n 300: \"#E8B824\",\n 400: \"#B88A00\",\n 500: \"#7A5800\",\n 600: \"#5C4006\"\n} as const;\n\n/** Trung tính brand (khác thang ash — đây là màu \"giấy/mực\" của brand book). */\nexport const brandNeutral = {\n ink: \"#0E1116\",\n inkSoft: \"#3A3F4A\",\n paper: \"#FBF7EE\",\n warm: \"#EDE8D8\"\n} as const;\n\n/**\n * Thang xám Comitor — namespace `ash`, KHÔNG phải `gray`.\n * Chỉ có 6 bậc; các bậc khuyết (200/400/600/800) cố ý không khai để không lẫn với\n * thang gray dựng sẵn của Tailwind (xem chú thích trong styles.css).\n */\nexport const ash = {\n 50: \"#F7F7F8\",\n 100: \"#EDEEF1\",\n 300: \"#C8CBD3\",\n 500: \"#7E8290\",\n 700: \"#3A3F4A\",\n 900: \"#16181D\"\n} as const;\n\n/**\n * Màu phụ. Bản `dark` được nâng sáng để đạt tương phản AA khi làm CHỮ trên nền #0E1116 —\n * bản `light` quá tối cho việc đó.\n */\nexport const accent = {\n light: {\n navy: \"#0F1E3D\",\n teal: \"#1F8A8B\",\n red: \"#D64545\",\n green: \"#2EA56A\",\n yellow: \"#F2C94C\"\n },\n dark: {\n navy: \"#0F1E3D\",\n teal: \"#2DD4BF\",\n red: \"#F87171\",\n green: \"#4ADE80\",\n yellow: \"#FACC15\"\n }\n} as const;\n\n/** Semantic token của shadcn — mirror khối `:root` / `.dark` trong styles.css. */\nexport const semantic = {\n light: {\n background: \"#FFFFFF\",\n foreground: \"#0E1116\",\n card: \"#FFFFFF\",\n cardForeground: \"#0E1116\",\n popover: \"#FFFFFF\",\n popoverForeground: \"#0E1116\",\n primary: \"#E8B824\",\n primaryForeground: \"#0E1116\",\n secondary: \"#EDE8D8\",\n secondaryForeground: \"#0E1116\",\n muted: \"#F7F7F8\",\n mutedForeground: \"#7E8290\",\n accent: \"#FBF5DC\",\n accentForeground: \"#0E1116\",\n destructive: \"#D64545\",\n destructiveForeground: \"#FFFFFF\",\n border: \"#EDEEF1\",\n input: \"#EDEEF1\",\n ring: \"#E8B824\",\n sidebar: \"#FAFAF9\",\n sidebarForeground: \"#0E1116\",\n sidebarBorder: \"#EDEEF1\",\n sidebarAccent: \"#FBF5DC\",\n sidebarAccentForeground: \"#0E1116\"\n },\n dark: {\n background: \"#0E1116\",\n foreground: \"#F7F7F8\",\n card: \"#16181D\",\n cardForeground: \"#F7F7F8\",\n popover: \"#16181D\",\n popoverForeground: \"#F7F7F8\",\n primary: \"#F5D060\",\n primaryForeground: \"#0E1116\",\n secondary: \"#1E2128\",\n secondaryForeground: \"#F7F7F8\",\n muted: \"#1E2128\",\n mutedForeground: \"#7E8290\",\n accent: \"#1E2128\",\n accentForeground: \"#F7F7F8\",\n destructive: \"#D64545\",\n destructiveForeground: \"#FFFFFF\",\n border: \"#1E2128\",\n input: \"#1E2128\",\n ring: \"#F5D060\",\n sidebar: \"#16181D\",\n sidebarForeground: \"#F7F7F8\",\n sidebarBorder: \"#1E2128\",\n sidebarAccent: \"#1E2128\",\n sidebarAccentForeground: \"#F7F7F8\"\n }\n} as const;\n\n/** Alias trạng thái — success/warning/info trỏ vào màu phụ, destructive giữ nguyên 2 chế độ. */\nexport const status = {\n light: {\n success: accent.light.green,\n successForeground: \"#FFFFFF\",\n warning: accent.light.yellow,\n warningForeground: \"#0E1116\",\n info: accent.light.teal,\n infoForeground: \"#FFFFFF\",\n destructive: \"#D64545\",\n destructiveForeground: \"#FFFFFF\"\n },\n dark: {\n success: accent.dark.green,\n successForeground: \"#0E1116\",\n warning: accent.dark.yellow,\n warningForeground: \"#0E1116\",\n info: accent.dark.teal,\n infoForeground: \"#0E1116\",\n destructive: \"#D64545\",\n destructiveForeground: \"#FFFFFF\"\n }\n} as const;\n\n/** Bảng màu biểu đồ (chart-1…chart-5). Thứ tự = thứ tự series mặc định. */\nexport const chart = {\n light: [gold[300], accent.light.teal, accent.light.navy, accent.light.green, accent.light.red],\n dark: [gold[200], accent.dark.teal, \"#7EA2E8\", accent.dark.green, accent.dark.red]\n} as const;\n\n/** Màu avatar chữ cái — chọn deterministic theo tên, lấy từ token nên luôn hợp tông brand. */\nexport const avatarPalette = [\n gold[400],\n gold[600],\n accent.light.teal,\n accent.light.navy,\n accent.light.green,\n accent.light.red,\n ash[500],\n brandNeutral.inkSoft\n] as const;\n\n/** Số đo khung ứng dụng — mirror --sidebar-width / --sidebar-width-icon / --header-height. */\nexport const layout = {\n /** px — --header-height 3.5rem */\n headerHeight: 56,\n /** px — --sidebar-width 16rem */\n sidebarWidth: 256,\n /** px — --sidebar-width-icon 3.5rem */\n sidebarCollapsedWidth: 56,\n /** px — --radius 0.375rem */\n radius: 6,\n breakpoints: { mobile: 768, tablet: 1024, desktop: 1280 },\n pageSizes: [20, 50, 100],\n /** px — kích thước tối thiểu của vùng chạm trên mobile (WCAG 2.5.5) */\n minTapTarget: 44\n} as const;\n\n/** Font stack — app phải tự nạp Inter (subsets latin + vietnamese) và gán --font-inter. */\nexport const typography = {\n fontSans: '\"Inter\", system-ui, sans-serif',\n fontMono: '\"Geist Mono\", ui-monospace, monospace'\n} as const;\n\nexport type ThemeMode = \"light\" | \"dark\";\n"],"mappings":"AAYO,MAAM,OAAO;AAAA,EAClB,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA;AAAA,EAEL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAGO,MAAM,eAAe;AAAA,EAC1B,KAAK;AAAA,EACL,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAOO,MAAM,MAAM;AAAA,EACjB,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAMO,MAAM,SAAS;AAAA,EACpB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAGO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,uBAAuB;AAAA,IACvB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,eAAe;AAAA,IACf,yBAAyB;AAAA,EAC3B;AAAA,EACA,MAAM;AAAA,IACJ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,uBAAuB;AAAA,IACvB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,eAAe;AAAA,IACf,yBAAyB;AAAA,EAC3B;AACF;AAGO,MAAM,SAAS;AAAA,EACpB,OAAO;AAAA,IACL,SAAS,OAAO,MAAM;AAAA,IACtB,mBAAmB;AAAA,IACnB,SAAS,OAAO,MAAM;AAAA,IACtB,mBAAmB;AAAA,IACnB,MAAM,OAAO,MAAM;AAAA,IACnB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,uBAAuB;AAAA,EACzB;AAAA,EACA,MAAM;AAAA,IACJ,SAAS,OAAO,KAAK;AAAA,IACrB,mBAAmB;AAAA,IACnB,SAAS,OAAO,KAAK;AAAA,IACrB,mBAAmB;AAAA,IACnB,MAAM,OAAO,KAAK;AAAA,IAClB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,uBAAuB;AAAA,EACzB;AACF;AAGO,MAAM,QAAQ;AAAA,EACnB,OAAO,CAAC,KAAK,GAAG,GAAG,OAAO,MAAM,MAAM,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM,GAAG;AAAA,EAC7F,MAAM,CAAC,KAAK,GAAG,GAAG,OAAO,KAAK,MAAM,WAAW,OAAO,KAAK,OAAO,OAAO,KAAK,GAAG;AACnF;AAGO,MAAM,gBAAgB;AAAA,EAC3B,KAAK,GAAG;AAAA,EACR,KAAK,GAAG;AAAA,EACR,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,IAAI,GAAG;AAAA,EACP,aAAa;AACf;AAGO,MAAM,SAAS;AAAA;AAAA,EAEpB,cAAc;AAAA;AAAA,EAEd,cAAc;AAAA;AAAA,EAEd,uBAAuB;AAAA;AAAA,EAEvB,QAAQ;AAAA,EACR,aAAa,EAAE,QAAQ,KAAK,QAAQ,MAAM,SAAS,KAAK;AAAA,EACxD,WAAW,CAAC,IAAI,IAAI,GAAG;AAAA;AAAA,EAEvB,cAAc;AAChB;AAGO,MAAM,aAAa;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
package/package.json ADDED
@@ -0,0 +1,151 @@
1
+ {
2
+ "name": "@comitor/ui",
3
+ "version": "0.1.0",
4
+ "description": "Comitor design system — Shadcn/UI tùy biến theo brand Comitor + component dùng chung cho hệ sinh thái SaaS (Tasks, Chat, CRM, HR…)",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/comitor-ai/comitor-ui.git"
13
+ },
14
+ "homepage": "https://github.com/comitor-ai/comitor-ui#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/comitor-ai/comitor-ui/issues"
17
+ },
18
+ "keywords": [
19
+ "comitor",
20
+ "design-system",
21
+ "react",
22
+ "shadcn",
23
+ "tailwindcss",
24
+ "ui"
25
+ ],
26
+ "sideEffects": [
27
+ "*.css",
28
+ "**/*.css"
29
+ ],
30
+ "files": [
31
+ "dist",
32
+ "styles.css",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js"
40
+ },
41
+ "./shell": {
42
+ "types": "./dist/shell/index.d.ts",
43
+ "import": "./dist/shell/index.js"
44
+ },
45
+ "./chart": {
46
+ "types": "./dist/chart/index.d.ts",
47
+ "import": "./dist/chart/index.js"
48
+ },
49
+ "./form": {
50
+ "types": "./dist/form.d.ts",
51
+ "import": "./dist/form.js"
52
+ },
53
+ "./tokens": {
54
+ "types": "./dist/tokens.d.ts",
55
+ "import": "./dist/tokens.js"
56
+ },
57
+ "./styles.css": "./styles.css",
58
+ "./package.json": "./package.json"
59
+ },
60
+ "scripts": {
61
+ "build": "tsup",
62
+ "typecheck": "tsc --noEmit",
63
+ "lint": "biome check .",
64
+ "lint:fix": "biome check --write .",
65
+ "verify:directives": "node scripts/verify-directives.mjs",
66
+ "check:exports": "publint --strict && attw --pack . --profile esm-only --exclude-entrypoints styles.css",
67
+ "prepublishOnly": "pnpm run typecheck && pnpm run build && pnpm run verify:directives"
68
+ },
69
+ "peerDependencies": {
70
+ "lucide-react": ">=0.540.0",
71
+ "next": ">=15",
72
+ "next-themes": ">=0.4",
73
+ "react": "^19.0.0",
74
+ "react-dom": "^19.0.0",
75
+ "react-hook-form": "^7.54.0",
76
+ "recharts": "^2.15.0",
77
+ "tailwindcss": "^4.1.0"
78
+ },
79
+ "peerDependenciesMeta": {
80
+ "next": {
81
+ "optional": true
82
+ },
83
+ "next-themes": {
84
+ "optional": true
85
+ },
86
+ "react-hook-form": {
87
+ "optional": true
88
+ },
89
+ "recharts": {
90
+ "optional": true
91
+ }
92
+ },
93
+ "dependencies": {
94
+ "@radix-ui/react-accordion": "1.2.12",
95
+ "@radix-ui/react-alert-dialog": "1.1.15",
96
+ "@radix-ui/react-aspect-ratio": "1.1.8",
97
+ "@radix-ui/react-avatar": "1.1.11",
98
+ "@radix-ui/react-checkbox": "1.3.3",
99
+ "@radix-ui/react-collapsible": "1.1.12",
100
+ "@radix-ui/react-context-menu": "2.2.16",
101
+ "@radix-ui/react-dialog": "1.1.15",
102
+ "@radix-ui/react-dropdown-menu": "2.1.16",
103
+ "@radix-ui/react-hover-card": "1.1.15",
104
+ "@radix-ui/react-label": "2.1.8",
105
+ "@radix-ui/react-menubar": "1.1.16",
106
+ "@radix-ui/react-navigation-menu": "1.2.14",
107
+ "@radix-ui/react-popover": "1.1.15",
108
+ "@radix-ui/react-progress": "1.1.8",
109
+ "@radix-ui/react-radio-group": "1.3.8",
110
+ "@radix-ui/react-scroll-area": "1.2.10",
111
+ "@radix-ui/react-select": "2.2.6",
112
+ "@radix-ui/react-separator": "1.1.8",
113
+ "@radix-ui/react-slider": "1.3.6",
114
+ "@radix-ui/react-slot": "1.2.4",
115
+ "@radix-ui/react-switch": "1.2.6",
116
+ "@radix-ui/react-tabs": "1.1.13",
117
+ "@radix-ui/react-toggle": "1.1.10",
118
+ "@radix-ui/react-toggle-group": "1.1.11",
119
+ "@radix-ui/react-tooltip": "1.2.8",
120
+ "class-variance-authority": "^0.7.1",
121
+ "clsx": "^2.1.1",
122
+ "cmdk": "1.1.1",
123
+ "date-fns": "4.1.0",
124
+ "embla-carousel-react": "8.6.0",
125
+ "input-otp": "1.4.2",
126
+ "react-day-picker": "9.13.2",
127
+ "react-resizable-panels": "^2.1.7",
128
+ "sonner": "^2.0.0",
129
+ "tailwind-merge": "^3.3.1",
130
+ "tw-animate-css": "1.3.3",
131
+ "vaul": "^1.1.2"
132
+ },
133
+ "devDependencies": {
134
+ "@arethetypeswrong/cli": "^0.18.4",
135
+ "@biomejs/biome": "^2.4.11",
136
+ "@types/node": "^22.0.0",
137
+ "@types/react": "^19.0.0",
138
+ "@types/react-dom": "^19.0.0",
139
+ "lucide-react": "^0.564.0",
140
+ "next": "^16.0.0",
141
+ "next-themes": "^0.4.6",
142
+ "publint": "^0.3.21",
143
+ "react": "^19.0.0",
144
+ "react-dom": "^19.0.0",
145
+ "react-hook-form": "^7.54.1",
146
+ "recharts": "^2.15.0",
147
+ "tailwindcss": "^4.2.0",
148
+ "tsup": "^8.3.5",
149
+ "typescript": "^5.7.0"
150
+ }
151
+ }
package/styles.css ADDED
@@ -0,0 +1,357 @@
1
+ /*
2
+ * @comitor/ui — NGUỒN TOKEN của hệ thống thiết kế Comitor (Tailwind v4, CSS-first).
3
+ *
4
+ * ⚠ CÁCH DÙNG (dễ sai nhất khi tới từ Tailwind 3):
5
+ * Đặt trong app/globals.css của app tiêu thụ, NGAY SAU @import "tailwindcss":
6
+ *
7
+ * @import "tailwindcss";
8
+ * @import "@comitor/ui/styles.css";
9
+ *
10
+ * KHÔNG import file này trong layout.tsx. File này chứa @theme / @custom-variant /
11
+ * @source — những at-rule chỉ có nghĩa khi ĐƯỢC TAILWIND BIÊN DỊCH. Import ở
12
+ * layout.tsx thì biến CSS vẫn có, nhưng không utility nào (bg-gold-300, dark:*) được
13
+ * sinh ra → giao diện vỡ.
14
+ *
15
+ * Thứ tự các khối bên dưới là bắt buộc, đừng đảo.
16
+ */
17
+
18
+ /* 1. Animation utility (animate-in / fade-in-0 / zoom-in-95 …) mà primitive shadcn dùng. */
19
+ @import "tw-animate-css";
20
+
21
+ /* 2. Cho Tailwind của app quét class nằm trong dist của package.
22
+ Tailwind v4 KHÔNG tự quét node_modules → thiếu dòng này là mất sạch style.
23
+ Đường dẫn resolve tương đối theo chính file CSS này (nằm ở gốc package). */
24
+ @source "./dist";
25
+
26
+ /* 3. Dark mode theo class — khớp next-themes attribute="class".
27
+ Lưu ý: (&:is(.dark *)) chỉ khớp CON CHÁU của .dark, không khớp chính phần tử .dark.
28
+ next-themes gắn class lên <html> nên thực tế luôn đúng; nếu tự dựng preview 2 theme
29
+ cạnh nhau thì phải bọc thêm một lớp: <div class="dark"><div>…</div></div>. */
30
+ @custom-variant dark (&:is(.dark *));
31
+
32
+ /* ────────────────────────────────────────────────────────────────────────────
33
+ 4. BIẾN — LIGHT
34
+ ──────────────────────────────────────────────────────────────────────────── */
35
+ :root {
36
+ /* ─ Brand: thang GOLD 7 bậc (trục chính của Comitor) ─ */
37
+ --gold-50: #fbf5dc;
38
+ --gold-100: #f8e89d;
39
+ --gold-200: #f5d060;
40
+ --gold-300: #e8b824; /* primary ở light */
41
+ --gold-400: #b88a00;
42
+ --gold-500: #7a5800;
43
+ --gold-600: #5c4006;
44
+
45
+ /* ─ Brand neutral ─ */
46
+ --ink: #0e1116;
47
+ --ink-soft: #3a3f4a;
48
+ --paper: #fbf7ee;
49
+ --warm: #ede8d8;
50
+
51
+ /* ─ Thang xám riêng của Comitor: namespace ASH (không phải gray) ─
52
+ Vì sao đổi tên: chỉ khai 6 bậc (50/100/300/500/700/900); nếu vẫn gọi là gray-*
53
+ thì gray-200/400/600/800 rơi về gray mặc định của Tailwind (ám xanh) và trộn
54
+ với gray Comitor (ám tím) → lệch tông. Đặt tên ash-* để hai thang không đụng nhau. */
55
+ --ash-50: #f7f7f8;
56
+ --ash-100: #edeef1;
57
+ --ash-300: #c8cbd3;
58
+ --ash-500: #7e8290;
59
+ --ash-700: #3a3f4a;
60
+ --ash-900: #16181d;
61
+
62
+ /* Alias tương thích ngược với comitor-ds — KHÔNG dùng cho code mới, sẽ bỏ ở 1.0. */
63
+ --gray-50: var(--ash-50);
64
+ --gray-100: var(--ash-100);
65
+ --gray-300: var(--ash-300);
66
+ --gray-500: var(--ash-500);
67
+ --gray-700: var(--ash-700);
68
+ --gray-900: var(--ash-900);
69
+
70
+ /* ─ Màu phụ ─ */
71
+ --navy: #0f1e3d;
72
+ --teal: #1f8a8b;
73
+ --red: #d64545;
74
+ --green: #2ea56a;
75
+ --yellow: #f2c94c;
76
+
77
+ /* ─ Semantic shadcn ─ */
78
+ --background: #ffffff;
79
+ --foreground: #0e1116;
80
+ --card: #ffffff;
81
+ --card-foreground: #0e1116;
82
+ --popover: #ffffff;
83
+ --popover-foreground: #0e1116;
84
+ --primary: #e8b824;
85
+ --primary-foreground: #0e1116;
86
+ --secondary: #ede8d8;
87
+ --secondary-foreground: #0e1116;
88
+ --muted: #f7f7f8;
89
+ --muted-foreground: #7e8290;
90
+ --accent: #fbf5dc;
91
+ --accent-foreground: #0e1116;
92
+ --destructive: #d64545;
93
+ --destructive-foreground: #ffffff;
94
+ --border: #edeef1;
95
+ --input: #edeef1;
96
+ --ring: #e8b824;
97
+
98
+ --sidebar: #fafaf9;
99
+ --sidebar-foreground: #0e1116;
100
+ --sidebar-border: #edeef1;
101
+ --sidebar-accent: #fbf5dc;
102
+ --sidebar-accent-foreground: #0e1116;
103
+
104
+ /* ─ Alias trạng thái (package bổ sung; comitor-ds chưa có) ─
105
+ Trỏ vào màu phụ để đổi tông trạng thái mà không đụng brand.
106
+ Vì trỏ bằng var(), khối .dark bên dưới đổi --green/--yellow/--teal là
107
+ --success/--warning/--info tự sáng theo, không cần khai lại. */
108
+ --success: var(--green);
109
+ --success-foreground: #ffffff;
110
+ --warning: var(--yellow);
111
+ --warning-foreground: #0e1116;
112
+ --info: var(--teal);
113
+ --info-foreground: #ffffff;
114
+
115
+ /* ─ Bảng màu biểu đồ (đổi độc lập với brand) ─ */
116
+ --chart-1: var(--gold-300);
117
+ --chart-2: var(--teal);
118
+ --chart-3: var(--navy);
119
+ --chart-4: var(--green);
120
+ --chart-5: var(--red);
121
+
122
+ /* ─ Accent theo từng app trong hệ sinh thái (Tasks/Chat/CRM/HR…) ─
123
+ App set lại 2 biến này ở <body> là đổi được ô app trong AppLauncher và
124
+ thanh active của sidebar, không cần build lại package. */
125
+ --app-accent: var(--primary);
126
+ --app-accent-foreground: var(--primary-foreground);
127
+
128
+ /* ─ Số đo khung ứng dụng (shell dùng ở cả CSS lẫn TS — xem tokens.ts) ─ */
129
+ --sidebar-width: 16rem; /* 256px */
130
+ --sidebar-width-icon: 3.5rem; /* 56px, sidebar thu gọn */
131
+ --header-height: 3.5rem; /* 56px */
132
+
133
+ /* ─ Thang ĐỔ BÓNG (elevation) ─
134
+ Giá trị THÔ nằm ở đây chứ không nằm trong @theme, vì bóng phải đổi theo light/dark:
135
+ @theme thường "đóng băng" giá trị lúc build, chỉ biến CSS thật mới được khối .dark
136
+ ghi đè lúc chạy. Section 6 map --elevation-* → --shadow-* trong @theme inline để sinh
137
+ utility shadow-surface / shadow-control / shadow-card / shadow-overlay.
138
+ App muốn chỉnh độ nổi thì ghi đè đúng 4 biến này (ví dụ ở <body>), không cần build lại.
139
+
140
+ Bốn bậc, thấp → cao:
141
+ surface — mặt phẳng nghỉ, viền mới là tín hiệu chính (Card mặc định)
142
+ control — control tương tác nhấc nhẹ khỏi nền (Button nền đặc)
143
+ card — thẻ/panel nổi (StatCard, Toast, Card elevated, tooltip biểu đồ)
144
+ overlay — lớp phủ lên nội dung (Dialog, Sheet, Popover, menu, Select, Tooltip) */
145
+ --elevation-surface: 0 1px 2px rgba(14, 17, 22, 0.04);
146
+ --elevation-control: 0 1px 2px rgba(14, 17, 22, 0.08);
147
+ --elevation-card: 0 1px 2px rgba(14, 17, 22, 0.04), 0 8px 24px rgba(14, 17, 22, 0.04);
148
+ --elevation-overlay: 0 8px 32px rgba(14, 17, 22, 0.16);
149
+
150
+ --radius: 0.375rem; /* 6px — chữ ký thị giác của Comitor */
151
+ }
152
+
153
+ /* ────────────────────────────────────────────────────────────────────────────
154
+ 5. BIẾN — DARK (chỉ override, không khai lại thứ không đổi)
155
+ ──────────────────────────────────────────────────────────────────────────── */
156
+ .dark {
157
+ --background: #0e1116;
158
+ --foreground: #f7f7f8;
159
+ --card: #16181d;
160
+ --card-foreground: #f7f7f8;
161
+ --popover: #16181d;
162
+ --popover-foreground: #f7f7f8;
163
+ --primary: #f5d060;
164
+ --primary-foreground: #0e1116;
165
+ --secondary: #1e2128;
166
+ --secondary-foreground: #f7f7f8;
167
+ --muted: #1e2128;
168
+ --muted-foreground: #7e8290;
169
+ --accent: #1e2128;
170
+ --accent-foreground: #f7f7f8;
171
+ --destructive: #d64545;
172
+ --destructive-foreground: #ffffff;
173
+ --border: #1e2128;
174
+ --input: #1e2128;
175
+ --ring: #f5d060;
176
+
177
+ --sidebar: #16181d;
178
+ --sidebar-foreground: #f7f7f8;
179
+ --sidebar-border: #1e2128;
180
+ --sidebar-accent: #1e2128;
181
+ --sidebar-accent-foreground: #f7f7f8;
182
+
183
+ /* Màu phụ bản dark — bản light quá tối để làm CHỮ trên nền #0E1116 (không đạt AA).
184
+ Các giá trị dưới đây đều ≥ 6:1 trên nền dark. Cần đo lại nếu đổi nền. */
185
+ --teal: #2dd4bf;
186
+ --red: #f87171;
187
+ --green: #4ade80;
188
+ --yellow: #facc15;
189
+
190
+ /* Foreground của trạng thái phải lật lại: nền sáng → chữ tối. */
191
+ --success-foreground: #0e1116;
192
+ --info-foreground: #0e1116;
193
+
194
+ /* Đổ bóng bản dark — bóng "mực" 4–16% trên nền #0E1116 gần như vô hình, lớp overlay
195
+ mất sạch tín hiệu độ cao (dialog/popover trông như dán phẳng vào nền). Trên nền tối,
196
+ bóng là chỗ VẮNG ÁNH SÁNG chứ không phải mực loang: dùng đen thuần với alpha cao hơn
197
+ hẳn. Giữ nguyên hình học (offset/blur) để ngôn ngữ độ cao không lệch giữa hai theme. */
198
+ --elevation-surface: 0 1px 2px rgba(0, 0, 0, 0.32);
199
+ --elevation-control: 0 1px 2px rgba(0, 0, 0, 0.4);
200
+ --elevation-card: 0 1px 2px rgba(0, 0, 0, 0.32), 0 8px 24px rgba(0, 0, 0, 0.4);
201
+ --elevation-overlay: 0 8px 32px rgba(0, 0, 0, 0.64);
202
+
203
+ /* navy nguyên bản chìm hẳn vào nền dark → chỉ nâng ở vai trò biểu đồ. */
204
+ --chart-3: #7ea2e8;
205
+ }
206
+
207
+ /* ────────────────────────────────────────────────────────────────────────────
208
+ 6. MAP BIẾN → NAMESPACE TAILWIND (sinh bg-*, text-*, border-*, rounded-*…)
209
+
210
+ @theme *inline* là chủ ý: `inline` nhúng thẳng var(--x) vào utility, nhờ đó
211
+ .dark { --primary: … } đổi được màu tại runtime. Dùng @theme thường sẽ "đóng băng"
212
+ giá trị lúc build → dark mode chết.
213
+ ──────────────────────────────────────────────────────────────────────────── */
214
+ @theme inline {
215
+ /* Font: app tự khai Inter (subsets latin + vietnamese) qua next/font và gán
216
+ --font-inter; package chỉ tiêu thụ biến. --font-inter-mono là TUỲ CHỌN (README §2).
217
+
218
+ Vì sao --font-inter-mono phải có fallback ngay trong var() còn --font-inter thì không:
219
+ app nào cũng gán --font-inter (README §2 bắt buộc), nhưng --font-inter-mono thì hiếm.
220
+ Mà var() không fallback + biến chưa khai = CẢ khai báo thành invalid at
221
+ computed-value time → class font-mono rơi về font kế thừa, KHÔNG rơi về "Geist Mono"
222
+ hay ui-monospace của danh sách này. */
223
+ --font-sans: var(--font-inter), "Inter", system-ui, sans-serif;
224
+ --font-mono: var(--font-inter-mono, "Geist Mono"), ui-monospace, monospace;
225
+
226
+ /* Semantic shadcn */
227
+ --color-background: var(--background);
228
+ --color-foreground: var(--foreground);
229
+ --color-card: var(--card);
230
+ --color-card-foreground: var(--card-foreground);
231
+ --color-popover: var(--popover);
232
+ --color-popover-foreground: var(--popover-foreground);
233
+ --color-primary: var(--primary);
234
+ --color-primary-foreground: var(--primary-foreground);
235
+ --color-secondary: var(--secondary);
236
+ --color-secondary-foreground: var(--secondary-foreground);
237
+ --color-muted: var(--muted);
238
+ --color-muted-foreground: var(--muted-foreground);
239
+ --color-accent: var(--accent);
240
+ --color-accent-foreground: var(--accent-foreground);
241
+ --color-destructive: var(--destructive);
242
+ --color-destructive-foreground: var(--destructive-foreground);
243
+ --color-border: var(--border);
244
+ --color-input: var(--input);
245
+ --color-ring: var(--ring);
246
+
247
+ /* Sidebar */
248
+ --color-sidebar: var(--sidebar);
249
+ --color-sidebar-foreground: var(--sidebar-foreground);
250
+ --color-sidebar-border: var(--sidebar-border);
251
+ --color-sidebar-accent: var(--sidebar-accent);
252
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
253
+
254
+ /* Gold scale */
255
+ --color-gold-50: var(--gold-50);
256
+ --color-gold-100: var(--gold-100);
257
+ --color-gold-200: var(--gold-200);
258
+ --color-gold-300: var(--gold-300);
259
+ --color-gold-400: var(--gold-400);
260
+ --color-gold-500: var(--gold-500);
261
+ --color-gold-600: var(--gold-600);
262
+
263
+ /* Brand neutral */
264
+ --color-ink: var(--ink);
265
+ --color-ink-soft: var(--ink-soft);
266
+ --color-paper: var(--paper);
267
+ --color-warm: var(--warm);
268
+
269
+ /* Thang xám Comitor (ash-*, KHÔNG phải gray-*) */
270
+ --color-ash-50: var(--ash-50);
271
+ --color-ash-100: var(--ash-100);
272
+ --color-ash-300: var(--ash-300);
273
+ --color-ash-500: var(--ash-500);
274
+ --color-ash-700: var(--ash-700);
275
+ --color-ash-900: var(--ash-900);
276
+
277
+ /* Màu phụ */
278
+ --color-navy: var(--navy);
279
+ --color-teal: var(--teal);
280
+ --color-red: var(--red);
281
+ --color-green: var(--green);
282
+ --color-yellow: var(--yellow);
283
+
284
+ /* Trạng thái */
285
+ --color-success: var(--success);
286
+ --color-success-foreground: var(--success-foreground);
287
+ --color-warning: var(--warning);
288
+ --color-warning-foreground: var(--warning-foreground);
289
+ --color-info: var(--info);
290
+ --color-info-foreground: var(--info-foreground);
291
+
292
+ /* Biểu đồ */
293
+ --color-chart-1: var(--chart-1);
294
+ --color-chart-2: var(--chart-2);
295
+ --color-chart-3: var(--chart-3);
296
+ --color-chart-4: var(--chart-4);
297
+ --color-chart-5: var(--chart-5);
298
+
299
+ /* Accent theo app */
300
+ --color-app-accent: var(--app-accent);
301
+ --color-app-accent-foreground: var(--app-accent-foreground);
302
+
303
+ /* Đổ bóng — sinh shadow-surface / shadow-control / shadow-card / shadow-overlay.
304
+ BẮT BUỘC là @theme *inline* và tên biến nguồn phải KHÁC (--elevation-*): khai
305
+ @theme inline { --shadow-card: var(--shadow-card) } là biến tự trỏ chính nó → hỏng.
306
+ Đánh đổi đã cân nhắc: giá trị là var() nên Tailwind không tách được phần màu, do đó
307
+ modifier `shadow-card/50` và đổi màu bóng bằng `shadow-<color>` mất tác dụng. Muốn
308
+ đổi tông/độ đậm thì ghi đè --elevation-* ở tầng app — đúng chỗ nên đổi. */
309
+ --shadow-surface: var(--elevation-surface);
310
+ --shadow-control: var(--elevation-control);
311
+ --shadow-card: var(--elevation-card);
312
+ --shadow-overlay: var(--elevation-overlay);
313
+
314
+ /* Bo góc */
315
+ --radius-sm: calc(var(--radius) - 2px);
316
+ --radius-md: var(--radius);
317
+ --radius-lg: calc(var(--radius) + 4px);
318
+ --radius-xl: 0.75rem;
319
+
320
+ /* Số đo khung: sinh w-sidebar / w-sidebar-icon / h-header cho tầng shell,
321
+ tránh magic number rải rác trong component. */
322
+ --spacing-sidebar: var(--sidebar-width);
323
+ --spacing-sidebar-icon: var(--sidebar-width-icon);
324
+ --spacing-header: var(--header-height);
325
+ }
326
+
327
+ /* ────────────────────────────────────────────────────────────────────────────
328
+ 7. BASE LAYER + utility riêng của Comitor
329
+ ──────────────────────────────────────────────────────────────────────────── */
330
+ @layer base {
331
+ * {
332
+ @apply border-border outline-ring/50;
333
+ }
334
+
335
+ body {
336
+ @apply bg-background text-foreground font-sans antialiased;
337
+ }
338
+
339
+ /* Chữ ký thị giác: focus dày 2px, cách viền 2px, màu ring. */
340
+ :focus-visible {
341
+ @apply outline-2 outline-offset-2 outline-ring;
342
+ }
343
+ }
344
+
345
+ /* Thanh cuộn mảnh — dùng cho sidebar, panel danh sách dài. */
346
+ @utility scrollbar-thin {
347
+ scrollbar-width: thin;
348
+ scrollbar-color: var(--ash-300) transparent;
349
+ }
350
+
351
+ @utility scrollbar-none {
352
+ scrollbar-width: none;
353
+ -ms-overflow-style: none;
354
+ &::-webkit-scrollbar {
355
+ display: none;
356
+ }
357
+ }