@ecoma-io/loom 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 (259) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +180 -0
  3. package/dist/a11y.d.ts +2 -0
  4. package/dist/a11y.d.ts.map +1 -0
  5. package/dist/a11y.js +2 -0
  6. package/dist/blocks/AppHeader/AppHeader.js +7 -0
  7. package/dist/blocks/AppHeader/AppHeader.js.map +1 -0
  8. package/dist/blocks/AppHeader/AppHeader.vue.d.ts +83 -0
  9. package/dist/blocks/AppHeader/AppHeader.vue.d.ts.map +1 -0
  10. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js +96 -0
  11. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  12. package/dist/blocks/DashboardGrid/DashboardGrid.js +7 -0
  13. package/dist/blocks/DashboardGrid/DashboardGrid.js.map +1 -0
  14. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts +42 -0
  15. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts.map +1 -0
  16. package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js +45 -0
  17. package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/blocks/EmptyState/EmptyState.js +7 -0
  19. package/dist/blocks/EmptyState/EmptyState.js.map +1 -0
  20. package/dist/blocks/EmptyState/EmptyState.vue.d.ts +50 -0
  21. package/dist/blocks/EmptyState/EmptyState.vue.d.ts.map +1 -0
  22. package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +71 -0
  23. package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  24. package/dist/blocks/PageHeader/PageHeader.js +7 -0
  25. package/dist/blocks/PageHeader/PageHeader.js.map +1 -0
  26. package/dist/blocks/PageHeader/PageHeader.vue.d.ts +54 -0
  27. package/dist/blocks/PageHeader/PageHeader.vue.d.ts.map +1 -0
  28. package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js +68 -0
  29. package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/blocks/RowActions/RowActions.js +7 -0
  31. package/dist/blocks/RowActions/RowActions.js.map +1 -0
  32. package/dist/blocks/RowActions/RowActions.vue.d.ts +14 -0
  33. package/dist/blocks/RowActions/RowActions.vue.d.ts.map +1 -0
  34. package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js +47 -0
  35. package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
  36. package/dist/blocks/SidebarNav/SidebarNav.js +7 -0
  37. package/dist/blocks/SidebarNav/SidebarNav.js.map +1 -0
  38. package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts +40 -0
  39. package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts.map +1 -0
  40. package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js +125 -0
  41. package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -0
  42. package/dist/blocks/TitleBar/TitleBar.js +7 -0
  43. package/dist/blocks/TitleBar/TitleBar.js.map +1 -0
  44. package/dist/blocks/TitleBar/TitleBar.vue.d.ts +49 -0
  45. package/dist/blocks/TitleBar/TitleBar.vue.d.ts.map +1 -0
  46. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js +66 -0
  47. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  48. package/dist/blocks/ToastStack/ToastStack.js +7 -0
  49. package/dist/blocks/ToastStack/ToastStack.js.map +1 -0
  50. package/dist/blocks/ToastStack/ToastStack.vue.d.ts +24 -0
  51. package/dist/blocks/ToastStack/ToastStack.vue.d.ts.map +1 -0
  52. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js +38 -0
  53. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  54. package/dist/icons/BrandMark.d.ts +18 -0
  55. package/dist/icons/BrandMark.d.ts.map +1 -0
  56. package/dist/icons/BrandMark.js +47 -0
  57. package/dist/icons/BrandMark.js.map +1 -0
  58. package/dist/index.d.ts +75 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +46 -0
  61. package/dist/lib/a11y-scope.d.ts +19 -0
  62. package/dist/lib/a11y-scope.d.ts.map +1 -0
  63. package/dist/lib/a11y-scope.js +28 -0
  64. package/dist/lib/a11y-scope.js.map +1 -0
  65. package/dist/lib/attrs.d.ts +18 -0
  66. package/dist/lib/attrs.d.ts.map +1 -0
  67. package/dist/lib/attrs.js +28 -0
  68. package/dist/lib/attrs.js.map +1 -0
  69. package/dist/lib/cn.d.ts +9 -0
  70. package/dist/lib/cn.d.ts.map +1 -0
  71. package/dist/lib/cn.js +16 -0
  72. package/dist/lib/cn.js.map +1 -0
  73. package/dist/lib/icon-defaults.d.ts +22 -0
  74. package/dist/lib/icon-defaults.d.ts.map +1 -0
  75. package/dist/lib/icon-defaults.js +32 -0
  76. package/dist/lib/icon-defaults.js.map +1 -0
  77. package/dist/lib/motion.d.ts +14 -0
  78. package/dist/lib/motion.d.ts.map +1 -0
  79. package/dist/lib/motion.js +20 -0
  80. package/dist/lib/motion.js.map +1 -0
  81. package/dist/lib/props.d.ts +31 -0
  82. package/dist/lib/props.d.ts.map +1 -0
  83. package/dist/lib/props.js +37 -0
  84. package/dist/lib/props.js.map +1 -0
  85. package/dist/primitives/Avatar/Avatar.js +7 -0
  86. package/dist/primitives/Avatar/Avatar.js.map +1 -0
  87. package/dist/primitives/Avatar/Avatar.vue.d.ts +27 -0
  88. package/dist/primitives/Avatar/Avatar.vue.d.ts.map +1 -0
  89. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +33 -0
  90. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/primitives/Badge/Badge.js +7 -0
  92. package/dist/primitives/Badge/Badge.js.map +1 -0
  93. package/dist/primitives/Badge/Badge.vue.d.ts +27 -0
  94. package/dist/primitives/Badge/Badge.vue.d.ts.map +1 -0
  95. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js +30 -0
  96. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  97. package/dist/primitives/Button/Button.js +7 -0
  98. package/dist/primitives/Button/Button.js.map +1 -0
  99. package/dist/primitives/Button/Button.vue.d.ts +70 -0
  100. package/dist/primitives/Button/Button.vue.d.ts.map +1 -0
  101. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js +122 -0
  102. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -0
  103. package/dist/primitives/Checkbox/Checkbox.js +7 -0
  104. package/dist/primitives/Checkbox/Checkbox.js.map +1 -0
  105. package/dist/primitives/Checkbox/Checkbox.vue.d.ts +34 -0
  106. package/dist/primitives/Checkbox/Checkbox.vue.d.ts.map +1 -0
  107. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +94 -0
  108. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  109. package/dist/primitives/Dialog/Dialog.js +7 -0
  110. package/dist/primitives/Dialog/Dialog.js.map +1 -0
  111. package/dist/primitives/Dialog/Dialog.vue.d.ts +58 -0
  112. package/dist/primitives/Dialog/Dialog.vue.d.ts.map +1 -0
  113. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +88 -0
  114. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  115. package/dist/primitives/DropdownMenu/DropdownMenu.js +7 -0
  116. package/dist/primitives/DropdownMenu/DropdownMenu.js.map +1 -0
  117. package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts +55 -0
  118. package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts.map +1 -0
  119. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +82 -0
  120. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  121. package/dist/primitives/Field/Field.js +7 -0
  122. package/dist/primitives/Field/Field.js.map +1 -0
  123. package/dist/primitives/Field/Field.vue.d.ts +53 -0
  124. package/dist/primitives/Field/Field.vue.d.ts.map +1 -0
  125. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js +84 -0
  126. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js.map +1 -0
  127. package/dist/primitives/InlineError/InlineError.js +7 -0
  128. package/dist/primitives/InlineError/InlineError.js.map +1 -0
  129. package/dist/primitives/InlineError/InlineError.vue.d.ts +32 -0
  130. package/dist/primitives/InlineError/InlineError.vue.d.ts.map +1 -0
  131. package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js +44 -0
  132. package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js.map +1 -0
  133. package/dist/primitives/Menubar/Menubar.js +7 -0
  134. package/dist/primitives/Menubar/Menubar.js.map +1 -0
  135. package/dist/primitives/Menubar/Menubar.vue.d.ts +41 -0
  136. package/dist/primitives/Menubar/Menubar.vue.d.ts.map +1 -0
  137. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js +184 -0
  138. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  139. package/dist/primitives/NumberField/NumberField.js +7 -0
  140. package/dist/primitives/NumberField/NumberField.js.map +1 -0
  141. package/dist/primitives/NumberField/NumberField.vue.d.ts +47 -0
  142. package/dist/primitives/NumberField/NumberField.vue.d.ts.map +1 -0
  143. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +204 -0
  144. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  145. package/dist/primitives/Popover/Popover.js +7 -0
  146. package/dist/primitives/Popover/Popover.js.map +1 -0
  147. package/dist/primitives/Popover/Popover.vue.d.ts +61 -0
  148. package/dist/primitives/Popover/Popover.vue.d.ts.map +1 -0
  149. package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js +59 -0
  150. package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  151. package/dist/primitives/Progress/Progress.js +7 -0
  152. package/dist/primitives/Progress/Progress.js.map +1 -0
  153. package/dist/primitives/Progress/Progress.vue.d.ts +30 -0
  154. package/dist/primitives/Progress/Progress.vue.d.ts.map +1 -0
  155. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js +67 -0
  156. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  157. package/dist/primitives/RadioGroup/RadioGroup.js +7 -0
  158. package/dist/primitives/RadioGroup/RadioGroup.js.map +1 -0
  159. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts +39 -0
  160. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts.map +1 -0
  161. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js +63 -0
  162. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  163. package/dist/primitives/SegmentedControl/SegmentedControl.js +7 -0
  164. package/dist/primitives/SegmentedControl/SegmentedControl.js.map +1 -0
  165. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts +40 -0
  166. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts.map +1 -0
  167. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +89 -0
  168. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -0
  169. package/dist/primitives/Select/Select.js +7 -0
  170. package/dist/primitives/Select/Select.js.map +1 -0
  171. package/dist/primitives/Select/Select.vue.d.ts +56 -0
  172. package/dist/primitives/Select/Select.vue.d.ts.map +1 -0
  173. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js +122 -0
  174. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -0
  175. package/dist/primitives/Separator/Separator.js +7 -0
  176. package/dist/primitives/Separator/Separator.js.map +1 -0
  177. package/dist/primitives/Separator/Separator.vue.d.ts +19 -0
  178. package/dist/primitives/Separator/Separator.vue.d.ts.map +1 -0
  179. package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js +31 -0
  180. package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/primitives/Skeleton/Skeleton.js +7 -0
  182. package/dist/primitives/Skeleton/Skeleton.js.map +1 -0
  183. package/dist/primitives/Skeleton/Skeleton.vue.d.ts +16 -0
  184. package/dist/primitives/Skeleton/Skeleton.vue.d.ts.map +1 -0
  185. package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +37 -0
  186. package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/primitives/Slider/Slider.js +7 -0
  188. package/dist/primitives/Slider/Slider.js.map +1 -0
  189. package/dist/primitives/Slider/Slider.vue.d.ts +58 -0
  190. package/dist/primitives/Slider/Slider.vue.d.ts.map +1 -0
  191. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js +137 -0
  192. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  193. package/dist/primitives/Spinner/Spinner.js +7 -0
  194. package/dist/primitives/Spinner/Spinner.js.map +1 -0
  195. package/dist/primitives/Spinner/Spinner.vue.d.ts +21 -0
  196. package/dist/primitives/Spinner/Spinner.vue.d.ts.map +1 -0
  197. package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js +63 -0
  198. package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  199. package/dist/primitives/Surface/Surface.js +7 -0
  200. package/dist/primitives/Surface/Surface.js.map +1 -0
  201. package/dist/primitives/Surface/Surface.vue.d.ts +42 -0
  202. package/dist/primitives/Surface/Surface.vue.d.ts.map +1 -0
  203. package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js +48 -0
  204. package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js.map +1 -0
  205. package/dist/primitives/Switch/Switch.js +7 -0
  206. package/dist/primitives/Switch/Switch.js.map +1 -0
  207. package/dist/primitives/Switch/Switch.vue.d.ts +24 -0
  208. package/dist/primitives/Switch/Switch.vue.d.ts.map +1 -0
  209. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js +44 -0
  210. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/primitives/Tabs/Tabs.js +7 -0
  212. package/dist/primitives/Tabs/Tabs.js.map +1 -0
  213. package/dist/primitives/Tabs/Tabs.vue.d.ts +33 -0
  214. package/dist/primitives/Tabs/Tabs.vue.d.ts.map +1 -0
  215. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js +54 -0
  216. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  217. package/dist/primitives/TextField/TextField.js +7 -0
  218. package/dist/primitives/TextField/TextField.js.map +1 -0
  219. package/dist/primitives/TextField/TextField.vue.d.ts +58 -0
  220. package/dist/primitives/TextField/TextField.vue.d.ts.map +1 -0
  221. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js +71 -0
  222. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  223. package/dist/primitives/Textarea/Textarea.js +7 -0
  224. package/dist/primitives/Textarea/Textarea.js.map +1 -0
  225. package/dist/primitives/Textarea/Textarea.vue.d.ts +48 -0
  226. package/dist/primitives/Textarea/Textarea.vue.d.ts.map +1 -0
  227. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +54 -0
  228. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  229. package/dist/primitives/Toast/Toast.js +7 -0
  230. package/dist/primitives/Toast/Toast.js.map +1 -0
  231. package/dist/primitives/Toast/Toast.vue.d.ts +46 -0
  232. package/dist/primitives/Toast/Toast.vue.d.ts.map +1 -0
  233. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js +52 -0
  234. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -0
  235. package/dist/primitives/Toast/ToastItem.js +7 -0
  236. package/dist/primitives/Toast/ToastItem.js.map +1 -0
  237. package/dist/primitives/Toast/ToastItem.vue.d.ts +38 -0
  238. package/dist/primitives/Toast/ToastItem.vue.d.ts.map +1 -0
  239. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js +114 -0
  240. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  241. package/dist/primitives/Tooltip/Tooltip.js +7 -0
  242. package/dist/primitives/Tooltip/Tooltip.js.map +1 -0
  243. package/dist/primitives/Tooltip/Tooltip.vue.d.ts +52 -0
  244. package/dist/primitives/Tooltip/Tooltip.vue.d.ts.map +1 -0
  245. package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js +56 -0
  246. package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  247. package/dist/primitives/WindowControls/WindowControls.js +7 -0
  248. package/dist/primitives/WindowControls/WindowControls.js.map +1 -0
  249. package/dist/primitives/WindowControls/WindowControls.vue.d.ts +41 -0
  250. package/dist/primitives/WindowControls/WindowControls.vue.d.ts.map +1 -0
  251. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js +111 -0
  252. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -0
  253. package/dist/styles/fonts/Geist-Variable.woff2 +0 -0
  254. package/dist/styles/fonts/GeistMono-Variable.woff2 +0 -0
  255. package/dist/styles/fonts/OFL.txt +92 -0
  256. package/dist/styles/fonts.css +30 -0
  257. package/dist/styles/global.css +181 -0
  258. package/dist/styles/theme.css +212 -0
  259. package/package.json +123 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Loom — design tokens.
3
+ * =====================
4
+ * The single source of truth for the visual language. Everything a consumer
5
+ * can theme lives here and nowhere else: no colour, duration, easing, radius
6
+ * or shadow is written literally in a component.
7
+ *
8
+ * Positioning it encodes. Ecoma is a platform where an organization digitizes
9
+ * its own operations and AI agents are a first-class workforce, so the form
10
+ * language is dual-force:
11
+ *
12
+ * - Human (warp) — the threads strung and held under tension: what people
13
+ * author and decide. Doubles as the default action colour, because a
14
+ * person drives the interface.
15
+ * - Agent (weft) — the thread carried across them: work an agent is running
16
+ * or has produced.
17
+ * - The seam — a warp→weft gradient — appears ONLY where the two forces
18
+ * meet: handoffs, co-authored assets, brand moments. Never under body
19
+ * text, never on anything smaller than 20px, never in an interaction
20
+ * state.
21
+ *
22
+ * Two threads, one cloth: the forces are one piece of work, not two systems.
23
+ *
24
+ * Light-first. This is a daytime operations tool, so the paper-light theme is
25
+ * the single default and there is no runtime light/dark switch. A symmetric
26
+ * dark theme is a reserved seam that returns with the first surface that
27
+ * needs it.
28
+ *
29
+ * `static` rather than plain `@theme`: Tailwind emits only the variables its
30
+ * generated utilities reference, and several tokens here are read by an
31
+ * inline `style` binding or a `@keyframes` block instead — neither of which
32
+ * the scanner sees. `static` emits all of them, which is what makes
33
+ * `var(--duration-fast)` resolve inside a component's style attribute.
34
+ */
35
+ @theme static {
36
+ /* ---- Neutrals: technical paper, cooled slightly toward the warp ------- */
37
+ --color-background: hsl(213 25% 96%);
38
+ --color-foreground: hsl(213 29% 15%);
39
+
40
+ --color-card: hsl(0 0% 100%);
41
+ --color-card-foreground: hsl(213 29% 15%);
42
+
43
+ /* Workspace chrome (sidebars, rails) — the sunken layer of the elevation
44
+ * rhythm: sunken < background < card, so work surfaces read as lifted and
45
+ * navigation recedes. */
46
+ --color-sunken: hsl(213 22% 93%);
47
+
48
+ --color-popover: hsl(0 0% 100%);
49
+ --color-popover-foreground: hsl(213 29% 15%);
50
+
51
+ --color-muted: hsl(213 18% 91%);
52
+ --color-muted-foreground: hsl(213 14% 41%);
53
+
54
+ /* Two border weights: the default hairline recedes; strong is for the few
55
+ * blocks that must assert their edge — an active panel, a keyboard target
56
+ * zone. */
57
+ --color-border: hsl(213 16% 87%);
58
+ --color-border-strong: hsl(213 14% 78%);
59
+ --color-input: hsl(213 15% 82%);
60
+
61
+ /* Neutral hover/press fill. This is a neutral, not the brand: a hover state
62
+ * is not an action colour. */
63
+ --color-subtle: hsl(213 20% 94%);
64
+ --color-subtle-foreground: hsl(213 29% 18%);
65
+
66
+ /* ---- Force 1 · Human — warp: default action, structure, decisions ----- */
67
+ --color-primary: hsl(211 37% 32%);
68
+ --color-primary-foreground: hsl(0 0% 100%);
69
+ --color-primary-muted: hsl(211 35% 92%); /* warp wash: selected/active fills */
70
+
71
+ /* ---- Force 2 · Agent — weft: automated work running or produced ------- */
72
+ --color-agent: hsl(18 56% 39%);
73
+ --color-agent-foreground: hsl(0 0% 100%);
74
+ --color-agent-muted: hsl(18 50% 93%); /* weft wash: agent-driven surfaces */
75
+
76
+ --color-secondary: hsl(213 18% 91%);
77
+ --color-secondary-foreground: hsl(213 29% 18%);
78
+
79
+ /* Focus ring is the Human warp: keyboard focus is a person acting. */
80
+ --color-ring: hsl(211 37% 32%);
81
+
82
+ /* ---- Functional — hues kept distinct from both forces ----------------- */
83
+ --color-destructive: hsl(356 65% 41%);
84
+ --color-destructive-foreground: hsl(0 0% 100%);
85
+ --color-success: hsl(152 45% 30%);
86
+ --color-success-foreground: hsl(0 0% 100%);
87
+ --color-warning: hsl(38 92% 28%);
88
+ --color-warning-foreground: hsl(0 0% 100%);
89
+ --color-info: hsl(202 65% 35%);
90
+ --color-info-foreground: hsl(0 0% 100%);
91
+
92
+ /* ---- The seam: the two forces meeting. Interpolated in OKLCH so the
93
+ * midpoint never turns muddy. Reach for it through the `bg-seam` utility
94
+ * below, at handoff points and brand moments only. ---------------------- */
95
+ --seam: linear-gradient(90deg in oklch, hsl(211 37% 32%), hsl(18 56% 39%));
96
+
97
+ /* ---- Shape: small, even fillets — milled, never blobby.
98
+ * Nesting law: inner radius = outer radius − padding, floor 2px. Pick the
99
+ * step that honours it rather than an arbitrary value. ------------------ */
100
+ --radius-md: 0.5rem; /* 8px — the control radius */
101
+ --radius-sm: calc(var(--radius-md) - 4px);
102
+ --radius-lg: calc(var(--radius-md) + 4px);
103
+ --radius-xl: calc(var(--radius-md) + 8px);
104
+
105
+ /* ---- Motion. Motion is meaning, not decoration ------------------------ */
106
+ --ease-out: cubic-bezier(0.2, 0, 0, 1); /* emphasized decelerate — the default */
107
+ --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
108
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
109
+ --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1); /* restrained overshoot */
110
+
111
+ --duration-instant: 80ms;
112
+ --duration-fast: 140ms;
113
+ --duration-normal: 200ms; /* the feedback ceiling — snappy, never sluggish */
114
+ --duration-slow: 320ms;
115
+ --duration-slower: 480ms;
116
+
117
+ /* Tailwind's own defaults for a bare `transition-*`, so a component that
118
+ * declares no duration still speaks the Loom vocabulary. */
119
+ --default-transition-duration: var(--duration-normal);
120
+ --default-transition-timing-function: var(--ease-out);
121
+
122
+ /* ---- Elevation: hairline-first. Cool, soft, and reserved for true
123
+ * overlays — a shadow is depth, never a glow. -------------------------- */
124
+ --shadow-sm: 0 1px 2px 0 hsl(213 30% 12% / 0.07);
125
+ --shadow-md: 0 4px 12px -2px hsl(213 30% 12% / 0.1), 0 2px 6px -2px hsl(213 30% 12% / 0.07);
126
+ --shadow-lg: 0 12px 32px -6px hsl(213 30% 12% / 0.14), 0 4px 10px -4px hsl(213 30% 12% / 0.08);
127
+
128
+ /* Focus halo — a warp haze AROUND the crisp ring outline, added on top of
129
+ * it and never replacing it, so the outline still shows under
130
+ * forced-colors. */
131
+ --shadow-halo: 0 0 0 4px hsl(211 37% 32% / 0.15);
132
+
133
+ /* ---- Type ------------------------------------------------------------ */
134
+ --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
135
+ --font-mono: "Geist Mono", ui-monospace, "SF Mono", "JetBrains Mono", monospace;
136
+
137
+ /* The named scale, as utilities: text-display … text-micro. A view composes
138
+ * the scale instead of hand-picking a size, weight and tracking per
139
+ * heading; weight and tracking ride along. Override with font-* or
140
+ * tracking-* only for a deliberate divergence. */
141
+ --text-display: 2.25rem;
142
+ --text-display--line-height: 1.1;
143
+ --text-display--font-weight: 600;
144
+ --text-display--letter-spacing: -0.02em;
145
+
146
+ --text-heading: 1.5rem;
147
+ --text-heading--line-height: 1.2;
148
+ --text-heading--font-weight: 600;
149
+ --text-heading--letter-spacing: -0.01em;
150
+
151
+ --text-title: 1.125rem;
152
+ --text-title--line-height: 1.3;
153
+ --text-title--font-weight: 500;
154
+
155
+ --text-body: 0.875rem;
156
+ --text-body--line-height: 1.55;
157
+ --text-body--font-weight: 400;
158
+
159
+ --text-small: 0.75rem;
160
+ --text-small--line-height: 1.5;
161
+ --text-small--font-weight: 400;
162
+
163
+ --text-micro: 0.6875rem;
164
+ --text-micro--line-height: 1.4;
165
+ --text-micro--font-weight: 400;
166
+
167
+ /* ---- Wide and ultra-wide breakpoints. Tailwind's own scale stops at
168
+ * 1536px, short of the desktop reality these products run on; `@theme`
169
+ * merges, so sm…2xl stay intact. Width only — there is deliberately no
170
+ * height vocabulary. Snap a window's minimum width to one of these names,
171
+ * never to an arbitrary pixel count. ----------------------------------- */
172
+ --breakpoint-3xl: 1920px; /* FHD desktop, maximized on one monitor */
173
+ --breakpoint-4xl: 2560px; /* QHD */
174
+ --breakpoint-5xl: 3440px; /* 21:9 ultra-wide */
175
+
176
+ /* ---- The animation vocabulary. Keyframes live in global.css; these are
177
+ * the named utilities that play them. ---------------------------------- */
178
+ --animate-fade: fade var(--duration-normal) var(--ease-out) both;
179
+ --animate-fade-rise: fade-rise var(--duration-normal) var(--ease-out) both;
180
+ --animate-scale-in: scale-in var(--duration-fast) var(--ease-spring) both;
181
+ --animate-shimmer: shimmer 1.6s linear infinite;
182
+ /* Agent at work — the weft's shuttle beat. */
183
+ --animate-conduct: conduct 1.8s var(--ease-in-out) infinite;
184
+ /* A live seam: the warp↔weft boundary drifts while the collaboration runs,
185
+ * and goes static once the work settles. */
186
+ --animate-seam-flow: seam-flow 3.2s linear infinite;
187
+ --animate-progress-indeterminate: progress-indeterminate 1.3s var(--ease-in-out) infinite;
188
+ --animate-toast-in: toast-in var(--duration-normal) var(--ease-spring) both;
189
+ }
190
+
191
+ /* Tailwind has no `--duration-*` theme namespace — `duration-*` takes a bare
192
+ * millisecond count or an arbitrary value, so the named steps above would be
193
+ * reachable from an inline style but not from a class. These four close that
194
+ * gap, and they are why a component never writes `duration-[140ms]`. */
195
+ @utility duration-instant {
196
+ transition-duration: var(--duration-instant);
197
+ }
198
+ @utility duration-fast {
199
+ transition-duration: var(--duration-fast);
200
+ }
201
+ @utility duration-slow {
202
+ transition-duration: var(--duration-slow);
203
+ }
204
+ @utility duration-slower {
205
+ transition-duration: var(--duration-slower);
206
+ }
207
+
208
+ /* The seam, as a background. A gradient is not a colour, so it has no colour
209
+ * namespace to live in; this is the only sanctioned way to paint one. */
210
+ @utility bg-seam {
211
+ background-image: var(--seam);
212
+ }
package/package.json ADDED
@@ -0,0 +1,123 @@
1
+ {
2
+ "name": "@ecoma-io/loom",
3
+ "version": "0.1.0",
4
+ "description": "Design system & components for the Ecoma ecosystem.",
5
+ "keywords": [
6
+ "design-system",
7
+ "component-library",
8
+ "ui-components",
9
+ "ui-kit",
10
+ "design-tokens",
11
+ "vue",
12
+ "vue3",
13
+ "tailwindcss",
14
+ "accessibility",
15
+ "a11y",
16
+ "wcag",
17
+ "theming",
18
+ "dark-mode",
19
+ "ecoma"
20
+ ],
21
+ "homepage": "https://github.com/ecoma-io/loom#readme",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/ecoma-io/loom.git"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/ecoma-io/loom/issues"
28
+ },
29
+ "license": "Apache-2.0",
30
+ "author": {
31
+ "name": "Mai Ngọc Hóa (John Martin)",
32
+ "email": "john.itvn@gmail.com"
33
+ },
34
+ "type": "module",
35
+ "sideEffects": [
36
+ "**/*.css"
37
+ ],
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/index.d.ts",
44
+ "default": "./dist/index.js"
45
+ },
46
+ "./a11y": {
47
+ "types": "./dist/a11y.d.ts",
48
+ "default": "./dist/a11y.js"
49
+ },
50
+ "./styles/global.css": "./dist/styles/global.css",
51
+ "./styles/theme.css": "./dist/styles/theme.css",
52
+ "./styles/fonts.css": "./dist/styles/fonts.css",
53
+ "./package.json": "./package.json"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "packageManager": "pnpm@11.20.0",
59
+ "engines": {
60
+ "node": ">=24",
61
+ "pnpm": ">=11"
62
+ },
63
+ "scripts": {
64
+ "prepare": "lefthook install",
65
+ "format": "prettier --write .",
66
+ "format:check": "prettier --check .",
67
+ "lint": "eslint . --max-warnings 0 && node tools/check-component-artifacts.ts",
68
+ "typecheck": "vue-tsc --noEmit",
69
+ "test": "vitest run",
70
+ "test:watch": "vitest",
71
+ "e2e": "playwright test",
72
+ "build": "vite build && vue-tsc -p tsconfig.build.json",
73
+ "docs:dev": "vitepress dev docs",
74
+ "docs:build": "vitepress build docs",
75
+ "docs:stage": "node tools/stage-docs.ts",
76
+ "docs:preview": "vitepress preview docs"
77
+ },
78
+ "devDependencies": {
79
+ "@axe-core/playwright": "^4.12.1",
80
+ "@commitlint/cli": "^21.2.1",
81
+ "@commitlint/config-conventional": "^21.2.0",
82
+ "@eslint/js": "^10.0.1",
83
+ "@playwright/test": "^1.62.1",
84
+ "@tailwindcss/vite": "^4.3.3",
85
+ "@types/node": "^26.1.2",
86
+ "@vitejs/plugin-vue": "^6.0.8",
87
+ "@vitest/coverage-v8": "^4.1.10",
88
+ "@vitest/eslint-plugin": "^1.6.26",
89
+ "@vue/test-utils": "^2.4.11",
90
+ "eslint": "^10.8.0",
91
+ "eslint-config-prettier": "^10.1.8",
92
+ "eslint-plugin-playwright": "^2.11.0",
93
+ "eslint-plugin-vue": "^10.10.0",
94
+ "eslint-plugin-vuejs-accessibility": "^2.5.0",
95
+ "fast-check": "^4.9.0",
96
+ "globals": "^17.9.0",
97
+ "gsap": "^3.15.0",
98
+ "jsdom": "^30.0.1",
99
+ "lefthook": "^2.1.10",
100
+ "prettier": "^3.9.6",
101
+ "tailwindcss": "^4.3.3",
102
+ "typescript": "^5.9.3",
103
+ "typescript-eslint": "^8.66.0",
104
+ "vite": "^8.2.0",
105
+ "vitepress": "^1.6.4",
106
+ "vitest": "^4.1.10",
107
+ "vue": "^3.5.40",
108
+ "vue-docgen-api": "^4.79.2",
109
+ "vue-eslint-parser": "^10.4.1",
110
+ "vue-tsc": "^3.3.9",
111
+ "wrangler": "^4.118.0"
112
+ },
113
+ "dependencies": {
114
+ "@lucide/vue": "^1.28.0",
115
+ "class-variance-authority": "^0.7.1",
116
+ "clsx": "^2.1.1",
117
+ "reka-ui": "^2.10.1",
118
+ "tailwind-merge": "^3.6.0"
119
+ },
120
+ "peerDependencies": {
121
+ "vue": "^3.5.0"
122
+ }
123
+ }