@dxos/ui-theme 0.0.0 → 0.8.4-main.05e74ebcff

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 (260) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/index.mjs +1370 -0
  4. package/dist/lib/browser/index.mjs.map +7 -0
  5. package/dist/lib/browser/meta.json +1 -0
  6. package/dist/lib/node-esm/index.mjs +1372 -0
  7. package/dist/lib/node-esm/index.mjs.map +7 -0
  8. package/dist/lib/node-esm/meta.json +1 -0
  9. package/dist/plugin/node-cjs/main.css +1573 -0
  10. package/dist/plugin/node-cjs/main.css.map +7 -0
  11. package/dist/plugin/node-cjs/meta.json +1 -0
  12. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs +137 -0
  13. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs.map +7 -0
  14. package/dist/plugin/node-esm/main.css +1573 -0
  15. package/dist/plugin/node-esm/main.css.map +7 -0
  16. package/dist/plugin/node-esm/meta.json +1 -0
  17. package/dist/plugin/node-esm/plugins/ThemePlugin.mjs +105 -0
  18. package/dist/plugin/node-esm/plugins/ThemePlugin.mjs.map +7 -0
  19. package/dist/types/src/Theme.stories.d.ts +27 -0
  20. package/dist/types/src/Theme.stories.d.ts.map +1 -0
  21. package/dist/types/src/defs.d.ts +21 -0
  22. package/dist/types/src/defs.d.ts.map +1 -0
  23. package/dist/types/src/fragments/density.d.ts +4 -0
  24. package/dist/types/src/fragments/density.d.ts.map +1 -0
  25. package/dist/types/src/fragments/disabled.d.ts +3 -0
  26. package/dist/types/src/fragments/disabled.d.ts.map +1 -0
  27. package/dist/types/src/fragments/hover.d.ts +9 -0
  28. package/dist/types/src/fragments/hover.d.ts.map +1 -0
  29. package/dist/types/src/fragments/index.d.ts +5 -0
  30. package/dist/types/src/fragments/index.d.ts.map +1 -0
  31. package/dist/types/src/fragments/text.d.ts +2 -0
  32. package/dist/types/src/fragments/text.d.ts.map +1 -0
  33. package/dist/types/src/index.d.ts +5 -0
  34. package/dist/types/src/index.d.ts.map +1 -0
  35. package/dist/types/src/plugins/ThemePlugin.d.ts +16 -0
  36. package/dist/types/src/plugins/ThemePlugin.d.ts.map +1 -0
  37. package/dist/types/src/plugins/dark-mode.d.ts +1 -0
  38. package/dist/types/src/plugins/dark-mode.d.ts.map +1 -0
  39. package/dist/types/src/theme/components/avatar.d.ts +21 -0
  40. package/dist/types/src/theme/components/avatar.d.ts.map +1 -0
  41. package/dist/types/src/theme/components/breadcrumb.d.ts +9 -0
  42. package/dist/types/src/theme/components/breadcrumb.d.ts.map +1 -0
  43. package/dist/types/src/theme/components/button.d.ts +15 -0
  44. package/dist/types/src/theme/components/button.d.ts.map +1 -0
  45. package/dist/types/src/theme/components/card.d.ts +12 -0
  46. package/dist/types/src/theme/components/card.d.ts.map +1 -0
  47. package/dist/types/src/theme/components/dialog.d.ts +17 -0
  48. package/dist/types/src/theme/components/dialog.d.ts.map +1 -0
  49. package/dist/types/src/theme/components/focus.d.ts +6 -0
  50. package/dist/types/src/theme/components/focus.d.ts.map +1 -0
  51. package/dist/types/src/theme/components/icon-button.d.ts +9 -0
  52. package/dist/types/src/theme/components/icon-button.d.ts.map +1 -0
  53. package/dist/types/src/theme/components/icon.d.ts +10 -0
  54. package/dist/types/src/theme/components/icon.d.ts.map +1 -0
  55. package/dist/types/src/theme/components/index.d.ts +27 -0
  56. package/dist/types/src/theme/components/index.d.ts.map +1 -0
  57. package/dist/types/src/theme/components/input.d.ts +115 -0
  58. package/dist/types/src/theme/components/input.d.ts.map +1 -0
  59. package/dist/types/src/theme/components/link.d.ts +7 -0
  60. package/dist/types/src/theme/components/link.d.ts.map +1 -0
  61. package/dist/types/src/theme/components/list.d.ts +14 -0
  62. package/dist/types/src/theme/components/list.d.ts.map +1 -0
  63. package/dist/types/src/theme/components/main.d.ts +28 -0
  64. package/dist/types/src/theme/components/main.d.ts.map +1 -0
  65. package/dist/types/src/theme/components/menu.d.ts +13 -0
  66. package/dist/types/src/theme/components/menu.d.ts.map +1 -0
  67. package/dist/types/src/theme/components/message.d.ts +12 -0
  68. package/dist/types/src/theme/components/message.d.ts.map +1 -0
  69. package/dist/types/src/theme/components/popover.d.ts +11 -0
  70. package/dist/types/src/theme/components/popover.d.ts.map +1 -0
  71. package/dist/types/src/theme/components/scroll-area.d.ts +32 -0
  72. package/dist/types/src/theme/components/scroll-area.d.ts.map +1 -0
  73. package/dist/types/src/theme/components/select.d.ts +13 -0
  74. package/dist/types/src/theme/components/select.d.ts.map +1 -0
  75. package/dist/types/src/theme/components/separator.d.ts +8 -0
  76. package/dist/types/src/theme/components/separator.d.ts.map +1 -0
  77. package/dist/types/src/theme/components/skeleton.d.ts +7 -0
  78. package/dist/types/src/theme/components/skeleton.d.ts.map +1 -0
  79. package/dist/types/src/theme/components/splitter.d.ts +4 -0
  80. package/dist/types/src/theme/components/splitter.d.ts.map +1 -0
  81. package/dist/types/src/theme/components/status.d.ts +9 -0
  82. package/dist/types/src/theme/components/status.d.ts.map +1 -0
  83. package/dist/types/src/theme/components/tag.d.ts +7 -0
  84. package/dist/types/src/theme/components/tag.d.ts.map +1 -0
  85. package/dist/types/src/theme/components/toast.d.ts +12 -0
  86. package/dist/types/src/theme/components/toast.d.ts.map +1 -0
  87. package/dist/types/src/theme/components/toolbar.d.ts +11 -0
  88. package/dist/types/src/theme/components/toolbar.d.ts.map +1 -0
  89. package/dist/types/src/theme/components/tooltip.d.ts +8 -0
  90. package/dist/types/src/theme/components/tooltip.d.ts.map +1 -0
  91. package/dist/types/src/theme/components/treegrid.d.ts +10 -0
  92. package/dist/types/src/theme/components/treegrid.d.ts.map +1 -0
  93. package/dist/types/src/theme/index.d.ts +4 -0
  94. package/dist/types/src/theme/index.d.ts.map +1 -0
  95. package/dist/types/src/theme/primitives/column.d.ts +29 -0
  96. package/dist/types/src/theme/primitives/column.d.ts.map +1 -0
  97. package/dist/types/src/theme/primitives/index.d.ts +3 -0
  98. package/dist/types/src/theme/primitives/index.d.ts.map +1 -0
  99. package/dist/types/src/theme/primitives/panel.d.ts +13 -0
  100. package/dist/types/src/theme/primitives/panel.d.ts.map +1 -0
  101. package/dist/types/src/theme/theme.d.ts +5 -0
  102. package/dist/types/src/theme/theme.d.ts.map +1 -0
  103. package/dist/types/src/util/elevation.d.ts +9 -0
  104. package/dist/types/src/util/elevation.d.ts.map +1 -0
  105. package/dist/types/src/util/hash-styles.d.ts +18 -0
  106. package/dist/types/src/util/hash-styles.d.ts.map +1 -0
  107. package/dist/types/src/util/index.d.ts +6 -0
  108. package/dist/types/src/util/index.d.ts.map +1 -0
  109. package/dist/types/src/util/mx.d.ts +58 -0
  110. package/dist/types/src/util/mx.d.ts.map +1 -0
  111. package/dist/types/src/util/size.d.ts +27 -0
  112. package/dist/types/src/util/size.d.ts.map +1 -0
  113. package/dist/types/src/util/valence.d.ts +4 -0
  114. package/dist/types/src/util/valence.d.ts.map +1 -0
  115. package/dist/types/tsconfig.tsbuildinfo +1 -0
  116. package/package.json +32 -39
  117. package/src/Theme.stories.tsx +224 -0
  118. package/src/css/DESIGN_SYSTEM.md +159 -0
  119. package/src/css/base/base.css +43 -0
  120. package/src/{styles/layers → css/base}/typography.css +21 -3
  121. package/src/{styles/layers → css/components}/button.css +23 -14
  122. package/src/{styles/layers → css/components}/checkbox.css +12 -8
  123. package/src/css/components/dialog.css +78 -0
  124. package/src/{styles/layers/focus-ring.css → css/components/focus.css} +60 -41
  125. package/src/css/components/icon.css +9 -0
  126. package/src/css/components/link.css +12 -0
  127. package/src/css/components/panel.css +117 -0
  128. package/src/css/components/scrollbar.css +24 -0
  129. package/src/css/components/selected.css +76 -0
  130. package/src/css/components/selected.md +101 -0
  131. package/src/css/components/surface.css +34 -0
  132. package/src/css/components/tag.css +132 -0
  133. package/src/css/components/text.css +124 -0
  134. package/src/css/integrations/codemirror.css +34 -0
  135. package/src/css/integrations/tldraw.css +14 -0
  136. package/src/css/layout/main.css +205 -0
  137. package/src/{styles/layers → css/layout}/native.css +6 -4
  138. package/src/css/layout/positioning.css +19 -0
  139. package/src/{styles/layers → css/layout}/size.css +130 -102
  140. package/src/css/theme/animation.css +260 -0
  141. package/src/css/theme/border.css +23 -0
  142. package/src/css/theme/palette.css +36 -0
  143. package/src/css/theme/semantic.css +112 -0
  144. package/src/css/theme/spacing.css +147 -0
  145. package/src/css/theme/styles.css +145 -0
  146. package/src/css/theme/text.css +37 -0
  147. package/src/css/utilities.css +118 -0
  148. package/src/defs.ts +48 -0
  149. package/src/fragments/AUDIT.md +55 -0
  150. package/src/fragments/density.ts +16 -0
  151. package/src/fragments/hover.ts +16 -0
  152. package/src/fragments/index.ts +10 -0
  153. package/src/fragments/text.ts +6 -0
  154. package/src/index.ts +3 -14
  155. package/src/main.css +121 -0
  156. package/src/plugins/ThemePlugin.ts +125 -0
  157. package/src/plugins/dark-mode.ts +22 -0
  158. package/src/plugins/main.css +45 -0
  159. package/src/{styles → theme}/components/avatar.ts +12 -13
  160. package/src/theme/components/button.ts +48 -0
  161. package/src/theme/components/card.ts +102 -0
  162. package/src/theme/components/dialog.ts +61 -0
  163. package/src/theme/components/focus.ts +33 -0
  164. package/src/{styles → theme}/components/icon-button.ts +6 -5
  165. package/src/theme/components/icon.ts +28 -0
  166. package/src/{styles → theme}/components/index.ts +4 -1
  167. package/src/theme/components/input.ts +171 -0
  168. package/src/{styles → theme}/components/link.ts +3 -4
  169. package/src/{styles → theme}/components/list.ts +5 -5
  170. package/src/{styles → theme}/components/main.ts +9 -11
  171. package/src/{styles → theme}/components/menu.ts +11 -21
  172. package/src/{styles → theme}/components/message.ts +11 -7
  173. package/src/{styles → theme}/components/popover.ts +13 -12
  174. package/src/theme/components/scroll-area.ts +115 -0
  175. package/src/{styles → theme}/components/select.ts +8 -16
  176. package/src/{styles → theme}/components/separator.ts +3 -3
  177. package/src/theme/components/skeleton.ts +23 -0
  178. package/src/theme/components/splitter.ts +20 -0
  179. package/src/{styles → theme}/components/status.ts +7 -7
  180. package/src/{styles → theme}/components/tag.ts +1 -1
  181. package/src/{styles → theme}/components/toast.ts +6 -8
  182. package/src/theme/components/toolbar.ts +35 -0
  183. package/src/{styles → theme}/components/tooltip.ts +4 -6
  184. package/src/{styles → theme}/components/treegrid.ts +9 -9
  185. package/src/{styles → theme}/index.ts +2 -2
  186. package/src/theme/primitives/column.ts +71 -0
  187. package/src/theme/primitives/index.ts +6 -0
  188. package/src/theme/primitives/panel.ts +43 -0
  189. package/src/{styles → theme}/theme.ts +27 -9
  190. package/src/typings.d.ts +3 -1
  191. package/src/{styles/fragments → util}/elevation.ts +6 -8
  192. package/src/util/hash-styles.ts +118 -98
  193. package/src/util/index.ts +3 -0
  194. package/src/util/mx.ts +165 -43
  195. package/src/util/size.ts +103 -0
  196. package/src/util/valence.ts +33 -0
  197. package/src/Tokens.stories.tsx +0 -88
  198. package/src/config/index.ts +0 -6
  199. package/src/config/tailwind.ts +0 -250
  200. package/src/config/tokens/alias-colors.ts +0 -39
  201. package/src/config/tokens/index.ts +0 -92
  202. package/src/config/tokens/lengths.ts +0 -97
  203. package/src/config/tokens/physical-colors.ts +0 -125
  204. package/src/config/tokens/semantic-colors.ts +0 -27
  205. package/src/config/tokens/sememes-calls.ts +0 -17
  206. package/src/config/tokens/sememes-codemirror.ts +0 -50
  207. package/src/config/tokens/sememes-hue.ts +0 -54
  208. package/src/config/tokens/sememes-sheet.ts +0 -62
  209. package/src/config/tokens/sememes-system.ts +0 -302
  210. package/src/config/tokens/sizes.ts +0 -7
  211. package/src/config/tokens/types.ts +0 -9
  212. package/src/docs/theme.drawio.svg +0 -635
  213. package/src/plugins/esbuild-plugin.ts +0 -65
  214. package/src/plugins/plugin.ts +0 -130
  215. package/src/plugins/resolveContent.ts +0 -51
  216. package/src/styles/components/README.md +0 -6
  217. package/src/styles/components/anchored-overflow.ts +0 -20
  218. package/src/styles/components/button.ts +0 -48
  219. package/src/styles/components/dialog.ts +0 -36
  220. package/src/styles/components/icon.ts +0 -19
  221. package/src/styles/components/input.ts +0 -177
  222. package/src/styles/components/scroll-area.ts +0 -43
  223. package/src/styles/components/toolbar.ts +0 -29
  224. package/src/styles/fragments/density.ts +0 -17
  225. package/src/styles/fragments/dimension.ts +0 -8
  226. package/src/styles/fragments/focus.ts +0 -16
  227. package/src/styles/fragments/group.ts +0 -12
  228. package/src/styles/fragments/hover.ts +0 -25
  229. package/src/styles/fragments/index.ts +0 -20
  230. package/src/styles/fragments/layout.ts +0 -7
  231. package/src/styles/fragments/motion.ts +0 -6
  232. package/src/styles/fragments/ornament.ts +0 -10
  233. package/src/styles/fragments/selected.ts +0 -45
  234. package/src/styles/fragments/shimmer.ts +0 -9
  235. package/src/styles/fragments/size.ts +0 -117
  236. package/src/styles/fragments/surface.ts +0 -29
  237. package/src/styles/fragments/text.ts +0 -12
  238. package/src/styles/fragments/valence.ts +0 -46
  239. package/src/styles/layers/README.md +0 -15
  240. package/src/styles/layers/anchored-overflow.css +0 -9
  241. package/src/styles/layers/animation.css +0 -17
  242. package/src/styles/layers/attention.css +0 -8
  243. package/src/styles/layers/base.css +0 -25
  244. package/src/styles/layers/can-scroll.css +0 -26
  245. package/src/styles/layers/dialog.css +0 -42
  246. package/src/styles/layers/drag-preview.css +0 -18
  247. package/src/styles/layers/hues.css +0 -110
  248. package/src/styles/layers/index.css +0 -26
  249. package/src/styles/layers/main.css +0 -160
  250. package/src/styles/layers/positioning.css +0 -23
  251. package/src/styles/layers/surfaces.css +0 -31
  252. package/src/styles/layers/tag.css +0 -132
  253. package/src/styles/layers/tldraw.css +0 -91
  254. package/src/styles/layers/tokens.css +0 -45
  255. package/src/tailwind.ts +0 -5
  256. package/src/theme.css +0 -9
  257. package/src/types.ts +0 -7
  258. package/src/util/withLogical.ts +0 -114
  259. /package/src/{styles/fragments → fragments}/disabled.ts +0 -0
  260. /package/src/{styles → theme}/components/breadcrumb.ts +0 -0
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@dxos/ui-theme",
3
- "version": "0.0.0",
3
+ "version": "0.8.4-main.05e74ebcff",
4
4
  "description": "A set of design system tokens to use with DXOS UI.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
13
  "sideEffects": [
10
14
  "*.css"
@@ -16,24 +20,11 @@
16
20
  "types": "./dist/types/src/index.d.ts",
17
21
  "default": "./dist/lib/browser/index.mjs"
18
22
  },
19
- "./esbuild-plugin": {
20
- "source": "./src/plugins/esbuild-plugin.ts",
21
- "types": "./dist/types/src/plugins/esbuild-plugin.d.ts",
22
- "import": "./dist/plugin/node-esm/plugins/esbuild-plugin.mjs",
23
- "require": "./dist/plugin/node-cjs/plugins/esbuild-plugin.cjs"
24
- },
25
23
  "./plugin": {
26
- "source": "./src/plugins/plugin.ts",
27
- "types": "./dist/types/src/plugins/plugin.d.ts",
28
- "import": "./dist/plugin/node-esm/plugins/plugin.mjs",
29
- "require": "./dist/plugin/node-cjs/plugins/plugin.cjs"
30
- }
31
- },
32
- "typesVersions": {
33
- "*": {
34
- "plugin": [
35
- "dist/types/src/plugins/plugin.d.ts"
36
- ]
24
+ "source": "./src/plugins/ThemePlugin.ts",
25
+ "types": "./dist/types/src/plugins/ThemePlugin.d.ts",
26
+ "import": "./dist/plugin/node-esm/plugins/ThemePlugin.mjs",
27
+ "require": "./dist/plugin/node-cjs/plugins/ThemePlugin.cjs"
37
28
  }
38
29
  },
39
30
  "files": [
@@ -41,40 +32,42 @@
41
32
  "src"
42
33
  ],
43
34
  "dependencies": {
44
- "@ch-ui/tailwind-tokens": "2.8.1",
45
- "@ch-ui/tokens": "3.0.1",
46
- "@fontsource-variable/inter": "5.0.16",
35
+ "@fontsource-variable/inter": "5.2.8",
47
36
  "@fontsource-variable/jetbrains-mono": "5.0.21",
48
37
  "@fontsource/poiret-one": "^5.0.20",
49
- "@tailwindcss/container-queries": "^0.1.1",
50
- "@tailwindcss/forms": "^0.5.3",
51
- "autoprefixer": "^10.4.12",
52
- "esbuild-style-plugin": "^1.6.1",
53
- "glob": "^7.2.3",
38
+ "@radix-ui/react-slot": "1.1.2",
39
+ "@tailwindcss/forms": "^0.5.9",
40
+ "@tailwindcss/postcss": "^4.2.0",
41
+ "autoprefixer": "^10.5.0",
42
+ "esbuild-style-plugin": "^1.6.3",
54
43
  "globby": "14.1.0",
55
44
  "lodash.merge": "^4.6.2",
56
- "postcss": "^8.4.41",
45
+ "postcss": "^8.5.12",
57
46
  "postcss-import": "^16.1.0",
58
- "tailwind-merge": "^2.2.1",
59
- "tailwind-scrollbar": "^3.1.0",
60
- "tailwindcss": "~3.4.1",
61
- "tailwindcss-logical": "^3.0.0",
62
- "tailwindcss-radix": "^2.8.0",
63
- "@dxos/node-std": "0.8.3",
64
- "@dxos/util": "0.8.3"
47
+ "postcss-nesting": "^13.0.1",
48
+ "tailwind-merge": "^3.5.0",
49
+ "tailwind-scrollbar": "^4.0.0",
50
+ "tailwindcss": "^4.2.0",
51
+ "tailwindcss-radix": "^4.0.2",
52
+ "@dxos/log": "0.8.4-main.05e74ebcff",
53
+ "@dxos/node-std": "0.8.4-main.05e74ebcff",
54
+ "@dxos/util": "0.8.4-main.05e74ebcff"
65
55
  },
66
56
  "devDependencies": {
67
- "@ch-ui/colors": "1.2.1",
68
57
  "@types/lodash.merge": "^4.6.6",
69
58
  "@types/postcss-import": "^14.0.3",
70
- "esbuild": "0.25.10",
71
- "vite": "7.1.9",
72
- "@dxos/ui-types": "0.0.0"
59
+ "esbuild": "0.28.0",
60
+ "vite": "^8.0.13",
61
+ "@dxos/ui-types": "0.8.4-main.05e74ebcff"
62
+ },
63
+ "peerDependencies": {
64
+ "react": "~19.2.3"
73
65
  },
74
66
  "publishConfig": {
75
67
  "access": "public"
76
68
  },
77
69
  "scripts": {
70
+ "audit-classes": "npx tsx bin/audit-classes.mts",
78
71
  "tailwind-check": "tailwindcss -i ./dist/plugin/node-esm/theme.css --config ./src/tailwind.ts --content \"./src/**/*.{js,ts,jsx,tsx,vue}\" --check"
79
72
  }
80
73
  }
@@ -0,0 +1,224 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { hueShades, hues } from './defs';
9
+ import { mx } from './util';
10
+
11
+ // prettier-ignore
12
+ const neutralShades: [number, string][] = [
13
+ [50, 'bg-neutral-50'],
14
+ [75, 'bg-neutral-75'],
15
+ [100, 'bg-neutral-100'],
16
+ [200, 'bg-neutral-200'],
17
+ [250, 'bg-neutral-250'],
18
+ [300, 'bg-neutral-300'],
19
+ [400, 'bg-neutral-400'],
20
+ [500, 'bg-neutral-500'],
21
+ [600, 'bg-neutral-600'],
22
+ [700, 'bg-neutral-700'],
23
+ [750, 'bg-neutral-750'],
24
+ [800, 'bg-neutral-800'],
25
+ [900, 'bg-neutral-900'],
26
+ [925, 'bg-neutral-925'],
27
+ [950, 'bg-neutral-950'],
28
+ ];
29
+
30
+ const ColorSwatch = ({ hue }: { hue: string }) => {
31
+ return (
32
+ <div
33
+ style={{
34
+ borderColor: `var(--color-${hue}-border)`,
35
+ }}
36
+ className={mx('shrink-0 aspect-square w-36 grid grid-rows-3 border-2 overflow-hidden rounded-md')}
37
+ >
38
+ <div
39
+ style={{
40
+ backgroundColor: `var(--color-base-surface)`,
41
+ color: `var(--color-${hue}-text)`,
42
+ }}
43
+ className='p-2 text-sm'
44
+ >
45
+ {hue}
46
+ </div>
47
+ <div
48
+ style={{
49
+ backgroundColor: `var(--color-${hue}-fill)`,
50
+ color: `var(--color-${hue}-text)`,
51
+ }}
52
+ className='px-1 text-sm flex items-center'
53
+ >
54
+ <svg className='h-6 w-6'>
55
+ <use href='/icons.svg#ph--aperture--regular' />
56
+ </svg>
57
+ </div>
58
+ <div
59
+ style={{
60
+ backgroundColor: `var(--color-${hue}-surface)`,
61
+ color: `var(--color-${hue}-foreground)`,
62
+ }}
63
+ className='p-2 text-sm'
64
+ >
65
+ {hue}
66
+ </div>
67
+ </div>
68
+ );
69
+ };
70
+
71
+ const HueSwatch = ({ hue, shades }: { hue: string; shades: readonly number[] }) => (
72
+ <div className='flex gap-1'>
73
+ {shades.map((shade) => (
74
+ <div
75
+ key={shade}
76
+ className='shrink-0 aspect-square w-24 flex flex-col rounded-sm'
77
+ style={{ backgroundColor: `var(--color-${hue}-${shade})` }}
78
+ >
79
+ <span
80
+ className='flex flex-col h-full justify-between text-sm p-2'
81
+ style={{ color: shade <= 500 ? 'black' : 'white' }}
82
+ >
83
+ <span className='text-xs'>{shade}</span>
84
+ {shade === 500 && <span className='text-xs'>{hue}</span>}
85
+ </span>
86
+ </div>
87
+ ))}
88
+ </div>
89
+ );
90
+
91
+ const meta = {
92
+ title: 'ui/ui-theme/Theme',
93
+ parameters: {
94
+ layout: 'fullscreen',
95
+ },
96
+ } satisfies Meta;
97
+
98
+ export default meta;
99
+
100
+ export const Styles = {
101
+ render: () => {
102
+ return (
103
+ <div className='p-4'>
104
+ <div className='flex flex-wrap gap-2'>
105
+ {['neutral', ...hues].map((hue) => (
106
+ <ColorSwatch key={hue} hue={hue} />
107
+ ))}
108
+ </div>
109
+ </div>
110
+ );
111
+ },
112
+ };
113
+
114
+ export const Colors = {
115
+ render: () => {
116
+ return (
117
+ <div className='p-4'>
118
+ <div className='flex flex-col gap-1'>
119
+ {['neutral', ...hues].map((hue) => (
120
+ <HueSwatch key={hue} hue={hue} shades={hueShades} />
121
+ ))}
122
+ </div>
123
+ </div>
124
+ );
125
+ },
126
+ };
127
+
128
+ export const Neutral = {
129
+ render: () => {
130
+ return (
131
+ <div className='p-4'>
132
+ <div className='flex flex-col items-center'>
133
+ {neutralShades.map(([value, className]) => (
134
+ <div
135
+ key={value}
136
+ className={mx(
137
+ 'h-12 w-48 p-2 text-right text-sm',
138
+ className,
139
+ value <= 500 ? 'text-neutral-950' : 'text-neutral-50',
140
+ )}
141
+ >
142
+ {value}
143
+ </div>
144
+ ))}
145
+ </div>
146
+ </div>
147
+ );
148
+ },
149
+ };
150
+
151
+ export const Surfaces = {
152
+ render: () => {
153
+ return (
154
+ <div className='absolute inset-0 h-full p-4 bg-white dark:bg-black'>
155
+ <div className='flex flex-wrap gap-2'>
156
+ {[
157
+ { className: 'bg-scrim-surface', label: 'scrim' },
158
+ { className: 'bg-base-surface', label: 'base' },
159
+ { className: 'bg-deck-surface', label: 'deck' },
160
+ { className: 'bg-group-surface', label: 'group' },
161
+ { className: 'bg-sidebar-surface', label: 'sidebar' },
162
+ { className: 'bg-header-surface', label: 'header' },
163
+ { className: 'bg-card-surface', label: 'card' },
164
+ { className: 'bg-modal-surface', label: 'modal' },
165
+ { className: 'bg-input-surface', label: 'input' },
166
+ { className: 'bg-current-surface', label: 'current' },
167
+ { className: 'bg-hover-surface', label: 'hover' },
168
+ { className: 'bg-inverse-surface text-inverse-foreground', label: 'inverse' },
169
+ ].map(({ className, label }) => (
170
+ <div key={className} className={mx('shrink-0 p-2 aspect-square w-48 rounded-md', className)}>
171
+ {label}
172
+ </div>
173
+ ))}
174
+ </div>
175
+ </div>
176
+ );
177
+ },
178
+ };
179
+
180
+ export const Tags = {
181
+ render: () => {
182
+ return (
183
+ <div className='p-4'>
184
+ <div className='flex flex-col gap-1'>
185
+ {['neutral', ...hues].map((hue) => (
186
+ <div key={hue} className='grid grid-cols-[8rem_8rem]'>
187
+ <div>
188
+ <span className='dx-tag' data-hue={hue}>
189
+ {hue}
190
+ </span>
191
+ </div>
192
+ <div>
193
+ <span className='dx-text text-sm' data-hue={hue}>
194
+ {hue}
195
+ </span>
196
+ </div>
197
+ </div>
198
+ ))}
199
+ </div>
200
+ </div>
201
+ );
202
+ },
203
+ };
204
+
205
+ export const Animation = {
206
+ render: () => {
207
+ return (
208
+ <div className='absolute inset-0 grid place-items-center'>
209
+ <div className='dx-density-coarse border border-separator rounded-md'>
210
+ <div
211
+ className={mx(
212
+ 'flex items-center font-mono text-2xl text-test-experimental',
213
+ 'p-form-padding w-card-min-width grid grid-cols-[min-content_1fr_min-content]',
214
+ )}
215
+ >
216
+ <span className='animate-blink text-error-text'>*</span>
217
+ <span className='text-center'>experimental</span>
218
+ <span className='animate-blink text-error-text'>*</span>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ );
223
+ },
224
+ };
@@ -0,0 +1,159 @@
1
+ # Design System: Color Tokens
2
+
3
+ This document describes how color tokens are organized in `ui-theme`, the naming rules they follow, and the rationalization of overlapping state tokens (`current` / `active` / `highlight` / `selected` / `hover`) and text-on-surface tokens (`surface-text` → `foreground`).
4
+
5
+ ## Token tiers
6
+
7
+ Three layers, each consuming the one below:
8
+
9
+ | Tier | File | Purpose | Example |
10
+ | ----------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
11
+ | 1. Scale | [`theme/palette.css`](./theme/palette.css) | Raw color values. Extends Tailwind's neutral/blue scales with intermediate stops and aliases the `primary-*` ramp to `blue-*`. | `--color-neutral-150`, `--color-primary-500` |
12
+ | 2. Hue role | [`theme/styles.css`](./theme/styles.css) | Per-hue role tokens generated mechanically for every Tailwind hue plus `neutral`. Five roles each: `fill`, `surface`, `foreground`, `text`, `border`. Light/dark resolved via `light-dark()`. | `--color-red-surface`, `--color-neutral-border` |
13
+ | 3. Semantic | [`theme/semantic.css`](./theme/semantic.css) | Named UI surfaces and states. May reference hue-role tokens (e.g. `error-surface` → `rose-surface`) or compose directly from the scale. | `--color-card-surface`, `--color-current-surface`, `--color-error-text` |
14
+
15
+ A consumer should reach for the highest tier that fits. Use `bg-card-surface`, not `bg-neutral-75`. Use `text-error-text`, not `text-rose-700`.
16
+
17
+ ## Naming convention
18
+
19
+ Token names follow `--color-{name}-{part}[-{state}]`:
20
+
21
+ - **`name`** identifies the role or surface (`card`, `current`, `accent`, `error`, `red`).
22
+ - **`part`** is one of a fixed vocabulary:
23
+ - `surface` — the background fill of a thing.
24
+ - `foreground` — the text/icon color that sits on the surface (paired with `surface`).
25
+ - `border` — border color on the surface.
26
+ - `fill` — solid attention-grabbing fill (badges, dots, indicators); more saturated than `surface`.
27
+ - `text` — text color used standalone, on the base canvas (no enclosing surface).
28
+ - **`state`** is optional, appended last: `hover`, `active` (pressed). State always follows the part it modifies.
29
+
30
+ ### Pattern rules
31
+
32
+ - Suffix order is fixed: `{name}-{part}-{state}`. The part comes first, then the state.
33
+ - Pair rule: every `{name}-surface` that hosts text has a matching `{name}-foreground`. Don't invent new ink-suffix names — keep the vocabulary closed.
34
+ - A state token implies a base — `current-surface-hover` only makes sense if `current-surface` exists.
35
+ - The `-text` part (standalone) is reserved for text on the base canvas, with no enclosing surface (e.g. `accent-text` for a hyperlink in body copy). Text on any named surface uses `{name}-foreground`.
36
+
37
+ ## Surfaces
38
+
39
+ Layered fills, ordered from recessive to prominent:
40
+
41
+ ```
42
+ base-surface n-50 / n-950 the page canvas
43
+ deck-surface n-50 / n-950 deck panes
44
+ toolbar-surface n-75 / n-925 toolbars
45
+ card-surface n-75 / n-925 cards
46
+ group-surface n-100 / n-900 grouped containers
47
+ modal-surface n-100 / n-900 modals / dialogs
48
+ sidebar-surface n-100 / n-900 sidebars
49
+ header-surface n-100 / n-900 headers
50
+ input-surface n-200 / n-800 form controls
51
+ ```
52
+
53
+ Each surface that hosts text declares a matching `*-foreground` (defaulting to `n-950 / n-50`).
54
+
55
+ ## State tokens (rationalized)
56
+
57
+ The system has three orthogonal states. Pick by what the ARIA / markup is saying.
58
+
59
+ | State | Token | When | Value |
60
+ | -------------------------- | ------------------------ | ---------------------------------------------------------------- | ----------------- |
61
+ | Active item, one-of-N | `current-surface` | `aria-current=true` (nav cursor, current row, current path) | `n-100` / `n-900` |
62
+ | Hovering on current item | `current-surface-hover` | pointer-over on a `current` element | `n-200` / `n-800` |
63
+ | Text on a current surface | `current-foreground` | text/icon color paired with `current-surface` | `n-950` / `n-50` |
64
+ | Selected / checked | `selected-surface` | `aria-selected=true` (multi-select, listbox option, checked row) | `n-150` / `n-850` |
65
+ | Hovering on selected | `selected-surface-hover` | pointer-over on a `selected` element | `n-250` / `n-750` |
66
+ | Text on a selected surface | `selected-foreground` | text/icon color paired with `selected-surface` | `n-950` / `n-50` |
67
+ | Transient pointer-over | `hover-surface` | `:hover`, Radix `data-highlighted` (keyboard cursor in menus) | `n-250` / `n-750` |
68
+ | Text on a transient hover | `hover-foreground` | text/icon color paired with `hover-surface` | `n-950` / `n-50` |
69
+
70
+ **Why these three.** `current` describes one-of-N navigation/selection state ("you are here"); `selected` describes a checked item in a set (multi-select-able); `hover` is transient pointer feedback. Driving the distinction off ARIA keeps markup and tokens in sync.
71
+
72
+ ### Visual hierarchy
73
+
74
+ ```
75
+ card-surface n-75 / n-925 resting
76
+ current-surface n-100 / n-900 "I am the active one"
77
+ current-surface-hover n-200 / n-800 hovering the active one
78
+ hover-surface n-250 / n-750 transient pointer-over anywhere else
79
+ ```
80
+
81
+ ## Consolidation: tokens that go away
82
+
83
+ These are merged into the rationalized state vocabulary:
84
+
85
+ | Removed | Replaced by | Notes |
86
+ | ------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
87
+ | `active-surface` | `current-surface` | Same concept ("the active one"). Same value already. |
88
+ | `active-text` | `current-foreground` | Renamed and reclassified — it was always foreground (text on the surface), not `text`. |
89
+ | `highlight-surface` | `current-surface` | `selected.css` used it for `aria-current=true`. |
90
+ | `highlight-surface-hover` | `current-surface-hover` | |
91
+ | `highlight-surface-text` | `current-foreground` | Rename to the new `-foreground` suffix. |
92
+ | `*-surface-text` (all) | `*-foreground` | Repository-wide rename for every hue, semantic, and named-surface token (e.g. `base-surface-text` → `base-foreground`, `red-surface-text` → `red-foreground`, `error-surface-text` → `error-foreground`). |
93
+
94
+ ### Visual change to expect
95
+
96
+ The 9 `bg-active-surface` call sites become one shade subtler (from `n-200/800` to `n-100/900`). This aligns them with the existing `selected.css` treatment of `aria-current=true` and produces the coherent layering shown above.
97
+
98
+ ### Out-of-scope drift to fix separately
99
+
100
+ Two sites use `bg-hover-surface` as a _resting_ fill (not a hover state):
101
+
102
+ - [packages/plugins/plugin-navtree/src/experimental/Tree.tsx:196](../../../../plugins/plugin-navtree/src/experimental/Tree.tsx)
103
+ - [packages/plugins/plugin-script/src/components/TestPanel/TestPanel.tsx:171](../../../../plugins/plugin-script/src/components/TestPanel/TestPanel.tsx)
104
+
105
+ These should probably move to `card-surface` or `current-surface` depending on intent. Tracked as a follow-up; not part of this rationalization.
106
+
107
+ ## Accent (primary)
108
+
109
+ `accent-*` is the project's primary brand color (blue). The token name is `accent`, not `primary`, to avoid colliding with the raw scale `--color-primary-*` (which is aliased to `blue-*` for Tailwind utility convenience).
110
+
111
+ | Token | Purpose |
112
+ | ---------------------- | --------------------------------------------------- |
113
+ | `accent-surface` | Fill for primary buttons / call-to-action surfaces. |
114
+ | `accent-surface-hover` | Hover state. |
115
+ | `accent-foreground` | Text/icon color on accent surfaces. |
116
+ | `accent-text` | Standalone accent-colored text (links, emphasis). |
117
+ | `accent-text-hover` | Hover state for accent text. |
118
+
119
+ This is the canonical illustration of the `foreground` vs `text` distinction: `accent-foreground` is the ink on an accent button; `accent-text` is the accent-colored body link.
120
+
121
+ Note: `accent-focus-indicator` is removed — focus rings are now global tokens (see [Focus rings](#focus-rings)).
122
+
123
+ ## Focus rings
124
+
125
+ Focus indicators are a global UI affordance, not a per-surface property. Every focusable element should pick from the same small set of ring colors so focus stays visually consistent and accessible.
126
+
127
+ | Token | Value | Used by |
128
+ | ------------------- | ----------------- | -------------------------------------------------------- |
129
+ | `focus-ring` | `blue-600` | Default focus ring (buttons, inputs, grid cells, links). |
130
+ | `focus-ring-subtle` | `n-400` / `n-600` | Subdued ring for low-emphasis focusable elements. |
131
+
132
+ Tokens removed in this rationalization:
133
+
134
+ | Removed | Replaced by | Notes |
135
+ | ------------------------- | ------------------- | -------------------------------------------------------------- |
136
+ | `accent-focus-indicator` | `focus-ring` | Was `blue-600`. Same value. |
137
+ | `grid-focus-indicator` | `focus-ring` | Was `primary-600` (= `blue-600`). Identical to accent variant. |
138
+ | `neutral-focus-indicator` | `focus-ring-subtle` | Was `n-400` / `n-600`. Same value. |
139
+
140
+ ## Semantic aliases
141
+
142
+ Status colors point at hue-role tokens:
143
+
144
+ | Token | Aliases |
145
+ | ----------- | ----------- |
146
+ | `info-*` | `cyan-*` |
147
+ | `success-*` | `emerald-*` |
148
+ | `warning-*` | `amber-*` |
149
+ | `error-*` | `rose-*` |
150
+
151
+ Each provides `fill`, `surface`, `foreground`, `text`, `border`.
152
+
153
+ ## Adding a new token
154
+
155
+ 1. Does an existing semantic token already cover it? If yes, use it.
156
+ 2. Does it represent a new named surface, state, or status? Add it to `semantic.css` referencing scale or hue-role tokens — never raw hex.
157
+ 3. Follow the suffix order: `{name}-{part}[-{state}]`.
158
+ 4. If the new token will be used through a Tailwind utility that the source-scan can't see (e.g. CSS file, dynamic class), add it to `@source inline(...)` in [`main.css`](./main.css).
159
+ 5. If it ships state variants (`-hover`, `-active`), declare them adjacent to the base in the same block.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Base utilities.
3
+ */
4
+
5
+ @layer dx-base {
6
+ :root {
7
+ color-scheme: light;
8
+ touch-action: pan-x pan-y;
9
+ font-synthesis: none;
10
+ font-variation-settings:
11
+ 'wght' 400,
12
+ 'slnt' 0;
13
+ scroll-padding-block-start: var(--spacing-14);
14
+ scroll-padding-block-end: var(--spacing-2);
15
+ @apply font-body;
16
+ }
17
+
18
+ .dark {
19
+ color-scheme: dark;
20
+ }
21
+
22
+ button {
23
+ @apply cursor-pointer;
24
+ -webkit-tap-highlight-color: transparent;
25
+ }
26
+ }
27
+
28
+ @layer dx-tokens {
29
+ :root {
30
+ --dx-tag-padding-block: var(--spacing-tag-padding-block);
31
+ }
32
+
33
+ html,
34
+ html.dark,
35
+ html .dark,
36
+ .sb-show-main {
37
+ background-color: var(--color-base-surface);
38
+ color: var(--color-base-foreground);
39
+ --surface-bg: var(--color-base-surface);
40
+ --foreground: var(--color-base-foreground);
41
+ --description-text: var(--color-description);
42
+ }
43
+ }