@keyfunc/keybricks-ds 1.0.4 → 2.3.1

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 (381) hide show
  1. package/DEPLOY.md +14 -5
  2. package/DESIGN.md +245 -59
  3. package/INTEGRATION.md +243 -49
  4. package/SKILL.md +13 -11
  5. package/_adherence.oxlintrc.json +183 -70
  6. package/_scripts/build-index.mjs +24 -4
  7. package/_scripts/build-tokens.mjs +5 -2
  8. package/assets/icons/icon-index.js +1 -1
  9. package/assets/icons/icon-index.json +1 -1
  10. package/components/_cards/accordion.card.html +2 -2
  11. package/components/_cards/action-chip.card.html +11 -9
  12. package/components/_cards/activity.card.html +3 -3
  13. package/components/_cards/alert.card.html +3 -3
  14. package/components/_cards/app-chrome.card.html +4 -4
  15. package/components/_cards/banner.card.html +1 -1
  16. package/components/_cards/breadcrumb.card.html +5 -5
  17. package/components/_cards/button-1-base.card.html +23 -26
  18. package/components/_cards/button-2-states.card.html +27 -25
  19. package/components/_cards/button-3-sizes-icons.card.html +20 -19
  20. package/components/_cards/button-4-group.card.html +14 -31
  21. package/components/_cards/canvas-zoom-controls.card.html +1 -1
  22. package/components/_cards/cards-indicators.card.html +2 -2
  23. package/components/_cards/charts-1-sparkline.card.html +5 -5
  24. package/components/_cards/charts-10-gauge.card.html +5 -5
  25. package/components/_cards/charts-11-funnel.card.html +3 -3
  26. package/components/_cards/charts-12-treemap.card.html +3 -3
  27. package/components/_cards/charts-14-radar.card.html +3 -3
  28. package/components/_cards/charts-15-distribution.card.html +2 -2
  29. package/components/_cards/charts-16-pareto.card.html +3 -3
  30. package/components/_cards/charts-17-candlestick.card.html +3 -3
  31. package/components/_cards/charts-18-sankey.card.html +3 -3
  32. package/components/_cards/charts-19-chord.card.html +3 -3
  33. package/components/_cards/charts-2-line.card.html +4 -4
  34. package/components/_cards/charts-20-sunburst.card.html +3 -3
  35. package/components/_cards/charts-21-worldmap.card.html +4 -4
  36. package/components/_cards/charts-22-gantt.card.html +3 -3
  37. package/components/_cards/charts-23-bar3d.card.html +3 -3
  38. package/components/_cards/charts-24-pie3d.card.html +3 -3
  39. package/components/_cards/charts-25-surface3d.card.html +3 -3
  40. package/components/_cards/charts-26-scatter3d.card.html +3 -3
  41. package/components/_cards/charts-27-ribbon3d.card.html +3 -3
  42. package/components/_cards/charts-3-bar.card.html +7 -7
  43. package/components/_cards/charts-4-barlist.card.html +3 -3
  44. package/components/_cards/charts-5-donut.card.html +4 -4
  45. package/components/_cards/charts-6-scatter.card.html +3 -3
  46. package/components/_cards/charts-7-heatmap.card.html +3 -3
  47. package/components/_cards/charts-8-waterfall.card.html +3 -3
  48. package/components/_cards/charts-9-bullet.card.html +3 -3
  49. package/components/_cards/charts-99-fullpage.card.html +5 -5
  50. package/components/_cards/checkbox.card.html +9 -6
  51. package/components/_cards/codeblock.card.html +2 -2
  52. package/components/_cards/combobox.card.html +6 -3
  53. package/components/_cards/context-menu.card.html +6 -3
  54. package/components/_cards/date-picker.card.html +10 -4
  55. package/components/_cards/diffvalue.card.html +3 -3
  56. package/components/_cards/divider.card.html +4 -4
  57. package/components/_cards/drawer.card.html +4 -4
  58. package/components/_cards/dropdown-menu.card.html +7 -7
  59. package/components/_cards/dropzone.card.html +5 -3
  60. package/components/_cards/empty-state.card.html +6 -6
  61. package/components/_cards/filter-bar.card.html +5 -5
  62. package/components/_cards/icon-button.card.html +14 -14
  63. package/components/_cards/icons-1-core.card.html +4 -4
  64. package/components/_cards/icons-2-feather.card.html +4 -4
  65. package/components/_cards/icons-3-unicons.card.html +4 -4
  66. package/components/_cards/input.card.html +5 -2
  67. package/components/_cards/kbd.card.html +2 -2
  68. package/components/_cards/keyvalue.card.html +2 -2
  69. package/components/_cards/listrow.card.html +2 -2
  70. package/components/_cards/loading.card.html +3 -3
  71. package/components/_cards/log-viewer.card.html +3 -3
  72. package/components/_cards/modal.card.html +9 -9
  73. package/components/_cards/multi-select.card.html +6 -3
  74. package/components/_cards/number-stepper.card.html +9 -5
  75. package/components/_cards/pagination.card.html +6 -3
  76. package/components/_cards/people.card.html +4 -4
  77. package/components/_cards/pipeline-node.card.html +8 -8
  78. package/components/_cards/pipeline-palette.card.html +5 -5
  79. package/components/_cards/radio.card.html +12 -7
  80. package/components/_cards/search.card.html +6 -3
  81. package/components/_cards/segmented-control.card.html +11 -10
  82. package/components/_cards/select.card.html +8 -4
  83. package/components/_cards/slider.card.html +2 -2
  84. package/components/_cards/smart-table.card.html +3 -3
  85. package/components/_cards/spreadsheet.card.html +3 -3
  86. package/components/_cards/stepper.card.html +3 -3
  87. package/components/_cards/table.card.html +165 -0
  88. package/components/_cards/tabs.card.html +6 -3
  89. package/components/_cards/tag.card.html +6 -3
  90. package/components/_cards/textarea.card.html +2 -2
  91. package/components/_cards/timeline.card.html +3 -3
  92. package/components/_cards/toast.card.html +10 -8
  93. package/components/_cards/toggles.card.html +15 -10
  94. package/components/_cards/tooltip.card.html +7 -7
  95. package/components/_cards/tree.card.html +3 -3
  96. package/components/_shared/card-kit.css +25 -0
  97. package/components/_shared/card-kit.js +50 -0
  98. package/components/_shared/src-buttons.js +1 -1
  99. package/components/_shared/src-charts.js +1 -1
  100. package/components/_shared/src-data.js +1 -1
  101. package/components/_shared/src-display.js +1 -1
  102. package/components/_shared/src-feedback.js +1 -1
  103. package/components/_shared/src-forms.js +1 -1
  104. package/components/_shared/src-icons.js +1 -1
  105. package/components/_shared/src-navigation.js +1 -1
  106. package/components/_shared/src-pipeline.js +1 -1
  107. package/components/_shared/src-tabs.js +1 -1
  108. package/components/_shared/view-source.js +3 -3
  109. package/components/_vue/index.mjs +16 -5
  110. package/components/buttons/ActionChip.d.ts +3 -1
  111. package/components/buttons/ActionChip.jsx +4 -4
  112. package/components/buttons/ActionChip.vue +4 -4
  113. package/components/buttons/Button.d.ts +5 -2
  114. package/components/buttons/Button.jsx +15 -18
  115. package/components/buttons/Button.vue +17 -18
  116. package/components/buttons/ButtonGroup.vue +1 -1
  117. package/components/buttons/IconButton.d.ts +2 -1
  118. package/components/buttons/IconButton.jsx +13 -9
  119. package/components/buttons/IconButton.vue +12 -9
  120. package/components/buttons/buttons.prompt.md +6 -5
  121. package/components/charts/Bar3D.jsx +2 -2
  122. package/components/charts/Bar3D.vue +3 -3
  123. package/components/charts/BarChart.jsx +4 -4
  124. package/components/charts/BarChart.vue +6 -6
  125. package/components/charts/BarList.jsx +4 -4
  126. package/components/charts/BarList.vue +4 -4
  127. package/components/charts/BoxPlot.jsx +1 -1
  128. package/components/charts/BoxPlot.vue +3 -3
  129. package/components/charts/BulletChart.jsx +6 -6
  130. package/components/charts/BulletChart.vue +6 -6
  131. package/components/charts/CandlestickChart.jsx +2 -2
  132. package/components/charts/CandlestickChart.vue +5 -5
  133. package/components/charts/ChartKit.jsx +8 -7
  134. package/components/charts/ChartLegend.vue +16 -0
  135. package/components/charts/ChartTooltip.vue +16 -0
  136. package/components/charts/ChordChart.jsx +2 -2
  137. package/components/charts/ChordChart.vue +3 -3
  138. package/components/charts/DonutChart.jsx +1 -1
  139. package/components/charts/DonutChart.vue +2 -2
  140. package/components/charts/FunnelChart.jsx +3 -3
  141. package/components/charts/FunnelChart.vue +4 -4
  142. package/components/charts/GanttChart.jsx +2 -2
  143. package/components/charts/GanttChart.vue +3 -3
  144. package/components/charts/GaugeChart.jsx +2 -2
  145. package/components/charts/GaugeChart.vue +2 -2
  146. package/components/charts/HeatmapChart.jsx +2 -2
  147. package/components/charts/HeatmapChart.vue +2 -2
  148. package/components/charts/Histogram.jsx +2 -2
  149. package/components/charts/Histogram.vue +4 -4
  150. package/components/charts/LineChart.jsx +1 -1
  151. package/components/charts/LineChart.vue +4 -4
  152. package/components/charts/ParetoChart.jsx +3 -3
  153. package/components/charts/ParetoChart.vue +5 -5
  154. package/components/charts/Pie3D.jsx +1 -1
  155. package/components/charts/Pie3D.vue +2 -2
  156. package/components/charts/PlotGrid.vue +18 -0
  157. package/components/charts/RadarChart.jsx +1 -1
  158. package/components/charts/RadarChart.vue +2 -2
  159. package/components/charts/Ribbon3D.jsx +2 -2
  160. package/components/charts/Ribbon3D.vue +3 -3
  161. package/components/charts/SankeyChart.jsx +2 -2
  162. package/components/charts/SankeyChart.vue +3 -3
  163. package/components/charts/Scatter3D.jsx +1 -1
  164. package/components/charts/Scatter3D.vue +2 -2
  165. package/components/charts/ScatterChart.jsx +3 -3
  166. package/components/charts/ScatterChart.vue +5 -5
  167. package/components/charts/Sparkline.jsx +1 -1
  168. package/components/charts/Sparkline.vue +1 -1
  169. package/components/charts/SunburstChart.jsx +1 -1
  170. package/components/charts/SunburstChart.vue +2 -2
  171. package/components/charts/Surface3D.jsx +2 -2
  172. package/components/charts/Surface3D.vue +3 -3
  173. package/components/charts/TreemapChart.jsx +2 -2
  174. package/components/charts/TreemapChart.vue +3 -3
  175. package/components/charts/WaterfallChart.jsx +2 -2
  176. package/components/charts/WaterfallChart.vue +6 -5
  177. package/components/charts/WorldMap.jsx +4 -4
  178. package/components/charts/WorldMap.vue +5 -5
  179. package/components/charts/XLabels.vue +11 -0
  180. package/components/data/CodeBlock.jsx +1 -1
  181. package/components/data/CodeBlock.vue +1 -1
  182. package/components/data/DiffValue.d.ts +1 -0
  183. package/components/data/DiffValue.jsx +1 -1
  184. package/components/data/DiffValue.vue +1 -1
  185. package/components/data/FilterBar.d.ts +2 -0
  186. package/components/data/FilterBar.jsx +10 -9
  187. package/components/data/FilterBar.vue +9 -8
  188. package/components/data/KeyValue.d.ts +1 -1
  189. package/components/data/KeyValue.jsx +4 -4
  190. package/components/data/KeyValue.vue +4 -4
  191. package/components/data/ListRow.jsx +2 -2
  192. package/components/data/ListRow.vue +2 -2
  193. package/components/data/Pagination.d.ts +5 -1
  194. package/components/data/Pagination.jsx +16 -12
  195. package/components/data/Pagination.vue +14 -9
  196. package/components/data/SmartTable.d.ts +4 -1
  197. package/components/data/SmartTable.jsx +16 -14
  198. package/components/data/SmartTable.vue +26 -23
  199. package/components/data/Spreadsheet.d.ts +2 -0
  200. package/components/data/Spreadsheet.jsx +16 -15
  201. package/components/data/Spreadsheet.vue +19 -18
  202. package/components/data/Table.d.ts +101 -0
  203. package/components/data/Table.jsx +223 -0
  204. package/components/data/Table.vue +153 -0
  205. package/components/data/data.prompt.md +3 -3
  206. package/components/display/Avatar.jsx +2 -2
  207. package/components/display/Avatar.vue +3 -2
  208. package/components/display/AvatarGroup.vue +3 -2
  209. package/components/display/Badge.d.ts +4 -1
  210. package/components/display/Badge.jsx +10 -5
  211. package/components/display/Badge.vue +1 -1
  212. package/components/display/Divider.vue +3 -3
  213. package/components/display/Donut.vue +3 -2
  214. package/components/display/IconTile.vue +10 -4
  215. package/components/display/Kbd.d.ts +1 -1
  216. package/components/display/Kbd.jsx +1 -1
  217. package/components/display/Kbd.vue +2 -2
  218. package/components/display/ProgressBar.jsx +1 -1
  219. package/components/display/ProgressBar.vue +1 -1
  220. package/components/display/StatCard.vue +1 -1
  221. package/components/display/Tag.d.ts +3 -1
  222. package/components/display/Tag.jsx +4 -4
  223. package/components/display/Tag.vue +4 -4
  224. package/components/feedback/Accordion.jsx +2 -2
  225. package/components/feedback/Accordion.vue +2 -2
  226. package/components/feedback/ActivityItem.d.ts +3 -1
  227. package/components/feedback/ActivityItem.jsx +6 -6
  228. package/components/feedback/ActivityItem.vue +5 -4
  229. package/components/feedback/Alert.jsx +4 -4
  230. package/components/feedback/Alert.vue +3 -3
  231. package/components/feedback/Banner.jsx +5 -5
  232. package/components/feedback/Banner.vue +5 -5
  233. package/components/feedback/ContextMenu.d.ts +3 -1
  234. package/components/feedback/ContextMenu.jsx +5 -5
  235. package/components/feedback/ContextMenu.vue +5 -5
  236. package/components/feedback/DotActivity.vue +3 -3
  237. package/components/feedback/Drawer.d.ts +2 -0
  238. package/components/feedback/Drawer.jsx +6 -6
  239. package/components/feedback/Drawer.vue +22 -15
  240. package/components/feedback/EmptyState.vue +2 -2
  241. package/components/feedback/LogViewer.vue +1 -1
  242. package/components/feedback/Modal.d.ts +2 -0
  243. package/components/feedback/Modal.jsx +12 -11
  244. package/components/feedback/Modal.vue +10 -8
  245. package/components/feedback/Skeleton.vue +2 -1
  246. package/components/feedback/Spinner.vue +2 -1
  247. package/components/feedback/Stepper.vue +1 -1
  248. package/components/feedback/Timeline.jsx +1 -1
  249. package/components/feedback/Timeline.vue +3 -3
  250. package/components/feedback/Toast.vue +4 -4
  251. package/components/feedback/ToastStack.vue +11 -0
  252. package/components/feedback/Tooltip.vue +19 -0
  253. package/components/feedback/feedback.prompt.md +4 -4
  254. package/components/forms/Checkbox.d.ts +3 -2
  255. package/components/forms/Checkbox.jsx +7 -7
  256. package/components/forms/Checkbox.vue +8 -8
  257. package/components/forms/Combobox.d.ts +2 -0
  258. package/components/forms/Combobox.jsx +12 -10
  259. package/components/forms/Combobox.vue +11 -10
  260. package/components/forms/DatePicker.d.ts +4 -0
  261. package/components/forms/DatePicker.jsx +16 -12
  262. package/components/forms/DatePicker.vue +15 -11
  263. package/components/forms/Dropzone.jsx +2 -2
  264. package/components/forms/Dropzone.vue +5 -5
  265. package/components/forms/Field.d.ts +5 -1
  266. package/components/forms/Field.jsx +4 -4
  267. package/components/forms/Field.vue +4 -4
  268. package/components/forms/Input.d.ts +5 -1
  269. package/components/forms/Input.jsx +8 -8
  270. package/components/forms/Input.vue +3 -3
  271. package/components/forms/MultiSelect.d.ts +2 -0
  272. package/components/forms/MultiSelect.jsx +13 -11
  273. package/components/forms/MultiSelect.vue +12 -11
  274. package/components/forms/NumberStepper.d.ts +3 -1
  275. package/components/forms/NumberStepper.jsx +7 -7
  276. package/components/forms/NumberStepper.vue +8 -7
  277. package/components/forms/Radio.d.ts +5 -3
  278. package/components/forms/Radio.jsx +13 -15
  279. package/components/forms/Radio.vue +9 -10
  280. package/components/forms/RadioGroup.vue +5 -5
  281. package/components/forms/SearchInput.d.ts +3 -1
  282. package/components/forms/SearchInput.jsx +6 -6
  283. package/components/forms/SearchInput.vue +7 -6
  284. package/components/forms/Select.d.ts +3 -2
  285. package/components/forms/Select.jsx +6 -7
  286. package/components/forms/Select.vue +6 -6
  287. package/components/forms/Slider.jsx +3 -3
  288. package/components/forms/Slider.vue +3 -3
  289. package/components/forms/Switch.d.ts +2 -2
  290. package/components/forms/Switch.jsx +20 -22
  291. package/components/forms/Switch.vue +22 -18
  292. package/components/forms/Textarea.vue +5 -5
  293. package/components/forms/forms.prompt.md +1 -1
  294. package/components/forms/input-base.js +2 -1
  295. package/components/icons/Icon.jsx +17 -1
  296. package/components/icons/Icon.prompt.md +2 -0
  297. package/components/icons/Icon.vue +1 -1
  298. package/components/icons/icon-paths.js +15 -0
  299. package/components/index.d.ts +1 -2
  300. package/components/index.js +4 -5
  301. package/components/navigation/Breadcrumb.jsx +6 -10
  302. package/components/navigation/Breadcrumb.vue +6 -12
  303. package/components/navigation/DocTree.jsx +3 -3
  304. package/components/navigation/DocTree.vue +3 -3
  305. package/components/navigation/PageHeading.vue +1 -1
  306. package/components/navigation/PageToolbar.vue +7 -6
  307. package/components/navigation/Sidebar.jsx +4 -23
  308. package/components/navigation/Sidebar.vue +5 -10
  309. package/components/navigation/ThemeToggle.vue +2 -1
  310. package/components/navigation/TopBar.d.ts +3 -1
  311. package/components/navigation/TopBar.jsx +6 -6
  312. package/components/navigation/Tree.jsx +5 -5
  313. package/components/navigation/Tree.vue +13 -8
  314. package/components/navigation/nav-model.js +23 -0
  315. package/components/navigation/theme-store.js +9 -0
  316. package/components/pipeline/ConfigPanel.d.ts +2 -0
  317. package/components/pipeline/ConfigPanel.jsx +9 -9
  318. package/components/pipeline/ConfigPanel.vue +9 -9
  319. package/components/pipeline/DataPreview.d.ts +3 -1
  320. package/components/pipeline/DataPreview.jsx +7 -7
  321. package/components/pipeline/DataPreview.vue +7 -7
  322. package/components/pipeline/NodeCard.jsx +3 -3
  323. package/components/pipeline/NodeCard.vue +3 -3
  324. package/components/pipeline/PaletteItem.vue +2 -2
  325. package/components/pipeline/PaletteListItem.vue +1 -1
  326. package/components/pipeline/PalettePanel.jsx +2 -2
  327. package/components/pipeline/PalettePanel.vue +1 -1
  328. package/components/pipeline/Port.vue +15 -0
  329. package/components/pipeline/PortLabel.vue +15 -0
  330. package/components/pipeline/ZoomControls.vue +1 -1
  331. package/components/pipeline/port-skin.js +13 -0
  332. package/components/px.js +4 -0
  333. package/components/tabs/PanelTabs.vue +5 -4
  334. package/components/tabs/PillTabs.vue +5 -4
  335. package/components/tabs/SegmentedControl.d.ts +2 -2
  336. package/components/tabs/SegmentedControl.jsx +7 -7
  337. package/components/tabs/SegmentedControl.vue +7 -7
  338. package/components/tabs/Tabs.d.ts +5 -3
  339. package/components/tabs/Tabs.jsx +15 -15
  340. package/components/tabs/Tabs.vue +5 -5
  341. package/components/tabs/ViewToggle.d.ts +3 -1
  342. package/components/tabs/ViewToggle.jsx +5 -5
  343. package/components/tabs/ViewToggle.vue +5 -5
  344. package/components/tabs/tabs.prompt.md +1 -1
  345. package/keybricks.css +4 -0
  346. package/package.json +6 -3
  347. package/readme.md +91 -122
  348. package/readme.zh-CN.md +121 -0
  349. package/tokens/alpha.css +3 -1
  350. package/tokens/charts.css +20 -17
  351. package/tokens/colors.css +3 -3
  352. package/tokens/dark.css +3 -3
  353. package/tokens/hover.css +32 -0
  354. package/tokens/interaction.css +3 -1
  355. package/tokens/layout.css +31 -7
  356. package/tokens/tokens.d.ts +58 -0
  357. package/tokens/tokens.js +179 -92
  358. package/tokens/tokens.json +327 -114
  359. package/tokens/typography.css +45 -15
  360. package/components/_cards/brand-visual.card.html +0 -43
  361. package/components/_cards/datatable.card.html +0 -48
  362. package/components/_shared/src-brand.js +0 -1
  363. package/components/brand/BrandVisual.d.ts +0 -17
  364. package/components/brand/BrandVisual.jsx +0 -29
  365. package/components/brand/BrandVisual.vue +0 -34
  366. package/components/brand/_dir.card.html +0 -13
  367. package/components/brand/brandMotifs.js +0 -210
  368. package/components/buttons/_dir.card.html +0 -13
  369. package/components/charts/ChartKit.vue +0 -47
  370. package/components/charts/_dir.card.html +0 -7
  371. package/components/data/DataTable.d.ts +0 -28
  372. package/components/data/DataTable.jsx +0 -32
  373. package/components/data/DataTable.vue +0 -25
  374. package/components/data/_dir.card.html +0 -13
  375. package/components/display/_dir.card.html +0 -13
  376. package/components/feedback/_dir.card.html +0 -13
  377. package/components/forms/_dir.card.html +0 -13
  378. package/components/icons/_dir.card.html +0 -13
  379. package/components/navigation/_dir.card.html +0 -13
  380. package/components/pipeline/_dir.card.html +0 -13
  381. package/components/tabs/_dir.card.html +0 -13
package/DEPLOY.md CHANGED
@@ -55,11 +55,11 @@ deploys the documentation site. Watch it under *Build → Pipelines*.
55
55
  **5. Cut the first release.**
56
56
 
57
57
  ```bash
58
- git tag v1.0.4 && git push --tags
58
+ git tag v2.3.1 && git push --tags
59
59
  ```
60
60
 
61
61
  That tag runs `generated:check` → `version:check` → `npm publish`. Confirm under *Deploy →
62
- Package Registry*: `@keyfunc/keybricks-ds` 1.0.4.
62
+ Package Registry*: `@keyfunc/keybricks-ds` 2.3.1.
63
63
 
64
64
  **6. Hand developers two things:** the Pages URL, and the `.npmrc` snippet in §4 below.
65
65
 
@@ -90,13 +90,13 @@ and `npm pack` both produce it via the `prepack` hook; CI does it explicitly. Re
90
90
  is a normal committed file.
91
91
 
92
92
  Published (`files` in `package.json`): `components/`, `tokens/`, `assets/`, `_scripts/`,
93
- `styles.css`, the four `.md` guides, `_adherence.oxlintrc.json`.
93
+ `styles.css`, `keybricks.css` (the `styles.css` export: tokens + `tokens/hover.css`), the four `.md` guides plus `readme.zh-CN.md`, `_adherence.oxlintrc.json`.
94
94
 
95
95
  > Installing from a **git tag** skips `prepack`, so `@keyfunc/keybricks-ds/vue` is absent in
96
96
  > that mode — Vue apps on a git dependency should deep-import
97
97
  > `@keyfunc/keybricks-ds/components/<group>/<Name>.vue`, which is the recommended path anyway.
98
98
 
99
- Not published: `guidelines/`, `ui_kits/`, `templates/`, `index.html`, `gallery.html`,
99
+ Not published: `guidelines/`, `index.html`, `gallery.html`,
100
100
  `_ds_bundle.js`. Those are the documentation site — they go to Pages, not into every
101
101
  `node_modules`.
102
102
 
@@ -156,7 +156,7 @@ GitLab injects `CI_JOB_TOKEN` — use that instead and no secret is stored anywh
156
156
  **Install — straight from git** (no registry, no publish; works today)
157
157
 
158
158
  ```json
159
- "@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v1.0.4"
159
+ "@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.3.1"
160
160
  ```
161
161
 
162
162
  Because the package has no build step, a git dependency needs no `prepare` script — npm
@@ -202,3 +202,12 @@ consuming app to fail CI on the two rules that break theming:
202
202
 
203
203
  Both are the same rule stated twice: components read the semantic layer, and only the
204
204
  semantic layer. That is what makes dark mode cost nothing.
205
+
206
+ ## Runtime checks
207
+
208
+ `_tests/` holds browser pages that exercise the real components: `react-runtime.html` (the compiled
209
+ bundle), `table-selection.html` (Table loaded from source: checkbox spacing at every width, code chips, two-line rows, sorting), `vue-runtime.html` (the `.vue` files, loaded with vue3-sfc-loader), `cards-interaction*.html`
210
+ (clicks through the documentation demos) and `icon-rules.html` (the Keybricks glyphs against the drawing rules). Serve the repo root (`npx serve .`), open a page and read the
211
+ console — every line starts with PASS or FAIL. Run them after changing a component in either framework.
212
+ `measure-cards.html` is a tool, not a test: it measures each documentation page at its card width so the
213
+ `viewport` sizes in the cards, `site-nav.js` and `gallery.html` can be kept in step.
package/DESIGN.md CHANGED
@@ -33,7 +33,8 @@ One action hue. Color carries meaning; the interface itself is near-monochrome.
33
33
  | `--bg-app` | `#fafafa` | Page canvas behind panels |
34
34
  | `--bg-surface` | `#ffffff` | Cards, menus, table cells |
35
35
  | `--bg-raised` | `#ffffff` | Modals, drawers, popovers |
36
- | `--bg-inset` | `#fafafa` | Wells, table headers, code blocks |
36
+ | `--bg-inset` | `#fafafa` | Wells, code blocks |
37
+ | `--bg-table-header` | `#f5f5f5` | Table header row — one step below `--bg-app`, so it still reads when the table sits on a grey page |
37
38
  | `--bg-hover` | `#f5f5f5` | Row / item hover |
38
39
  | `--bg-active` | `#f5f5f5` | Selected nav pill, toggled control |
39
40
  | `--bg-press` | `#e5e5e5` | Press wash |
@@ -46,9 +47,9 @@ order (`app` → `surface` → `raised`) and depth reads correctly in both theme
46
47
  | Token | Light | Use |
47
48
  | --- | --- | --- |
48
49
  | `--text-primary` | `#0a0a0a` | Maximum emphasis |
49
- | `--text-heading` | `#171717` | Headings, table headers |
50
+ | `--text-heading` | `#171717` | Headings |
50
51
  | `--text-body` | `#525252` | Default body text |
51
- | `--text-secondary` | `#737373` | Meta, labels, captions |
52
+ | `--text-secondary` | `#737373` | Meta, labels, captions, table headers |
52
53
  | `--text-muted` | `#a1a1a1` | Placeholder, disabled glyph |
53
54
  | `--on-accent` | `#ffffff` | Text on any saturated fill — **both themes** |
54
55
 
@@ -57,7 +58,7 @@ order (`app` → `surface` → `raised`) and depth reads correctly in both theme
57
58
  | --- | --- | --- |
58
59
  | `--border-card` | `rgba(229,229,229,.6)` | Card hairline |
59
60
  | `--border-control` | `#e5e5e5` | Input / button edge |
60
- | `--border-subtle` | `#f5f5f5` | List and table dividers |
61
+ | `--border-subtle` | `#f5f5f5` | List and table dividers — including the table header rule; a header is set apart by its `--bg-table-header` tint, never by a heavier line |
61
62
  | `--focus-border` | `#2b7fff` | Keyboard focus outline |
62
63
 
63
64
  ### Action
@@ -83,7 +84,7 @@ Never put `--success` (the solid) behind text — use the `-bg` / `-text` pair.
83
84
  Series walk `--series-1…10` in order; signed values are ALWAYS `--chart-pos` / `--chart-neg`
84
85
  (diverging bars, waterfall bridges, deltas, auto sparklines); totals and combo overlay lines are
85
86
  `--chart-total`; guides are dashed `--chart-guide`. Lines are straight or monotone-cubic — never
86
- a spline that overshoots a real value. Numbers are `--font-mono`, compact-formatted. Every chart
87
+ a spline that overshoots a real value. Numbers are `--font-sans` with tabular figures, compact-formatted. Every chart
87
88
  answers a hover at every size: a tile-tier chart drops its axes and legend, never its tooltip.
88
89
  Geography is data, not a drawing — country outlines come from Natural Earth via d3-geo.
89
90
  3D charts are presentation, not analysis: plain SVG painter’s-algorithm rendering, one upper-left
@@ -98,46 +99,228 @@ feedback colors mean **severity**. Do not mix the two vocabularies.
98
99
 
99
100
  ## Typography
100
101
 
101
- `--font-sans` is Inter. `--font-mono` is Menlo. There is no third family.
102
+ `--font-sans` is Inter. `--font-mono` is Menlo, and it is for code only: code blocks, logs, inline code in the docs, and config codes (`FIN_CURRENCY_DEFAULT`), which render as a code chip — Menlo at `--text-code` (12px; 11px in sm; Latin, so not bumped in CJK) on `--bg-inset` with a hairline border (`code: true` on a Table column). Everything else in the interface — IDs, amounts, chart numbers, keyboard keys — is `--font-sans`; numbers that must line up add `font-variant-numeric: tabular-nums`. There is no third family. Under
103
+ `lang="zh" | "ja" | "ko"` the sans stack continues into the system CJK face (PingFang SC /
104
+ Hiragino / Apple SD Gothic Neo on macOS, Microsoft YaHei / Yu Gothic UI / Malgun Gothic on
105
+ Windows, Noto Sans CJK elsewhere); Latin glyphs stay Inter.
102
106
 
103
- | Token | Size / line-height | Use |
104
- | --- | --- | --- |
105
- | `--text-2xs` | 10 / 12.5 | Tile labels |
106
- | `--text-xs` | 11 / 16.5 | Table cells, captions, step labels |
107
- | `--text-sm` | 12 / 18 | Form labels, inputs, chips, meta |
108
- | `--text-base` | **13 / 19.5** | **Default UI text, buttons, nav** |
109
- | `--text-md` | 14 / 21 | Section headings, panel titles |
110
- | `--text-lg` | 15 / 22.5 | Page titles |
111
- | `--text-xl` | 20 / 30 | Greeting heading |
112
- | `--text-2xl` | 24 / 31 | Modal / page hero |
113
-
114
- Weights: `--weight-regular` 400, `--weight-medium` 500, `--weight-semibold` 600.
115
- **500 is the emphasis weight** — headings and active nav items are 500, not bold.
107
+ **The 14px scale** — four sizes do almost all the work: 12 captions · 14 body and controls ·
108
+ 16 section titles · 20 page titles.
116
109
 
117
- Every size has a matching `--leading-*` and `--tracking-*`. Set all three together; the
118
- tracking values are negative at larger sizes and are not optional.
119
-
120
- This is a **dense, 13px-default interface**. If your text looks like a marketing site, it is
121
- too large.
110
+ | Token | Size / line-height / tracking | Use |
111
+ | --- | --- | --- |
112
+ | `--text-2xs` | 11 / 16 / +.064 | Chart tick labels only — nothing in the system is smaller |
113
+ | `--text-xs` | 12 / 16 / 0 | Captions, helper text, badges, tags, meta; control text at the `sm` tier |
114
+ | `--text-base` | **14 / 20 / −.15** | **Body, buttons, inputs, labels, table cells, nav** |
115
+ | `--text-md` | 16 / 24 / −.28 | Section headings, panel / card / dialog titles |
116
+ | `--text-lg` | 20 / 28 / −.45 | Page titles |
117
+ | `--text-xl` | 24 / 32 / −.54 | Greeting heading, page hero |
118
+ | `--text-num` | 24 / 32 / +.07 | Stat numbers, weight 300 |
119
+ | `--text-2xl` · `--text-3xl` · `--text-4xl` · `--text-display` | 30 · 38 · 48 · 60 | Report hero, marketing headings, dashboard hero numbers, slides |
120
+
121
+ `--text-sm` is an alias of `--text-xs` (12px) kept for compatibility — write `--text-xs`.
122
+
123
+ Weights: `--weight-light` 300, `--weight-regular` 400, `--weight-medium` 500,
124
+ `--weight-semibold` 600. **500 is the emphasis weight** — headings and active nav items are
125
+ 500, not bold. Table headers and section labels are 600.
126
+
127
+ Every size has a matching `--leading-*` and `--tracking-*`. Set all three together — or, inside
128
+ a control, read `--control-text` / `--control-leading` / `--control-tracking` and the size tier
129
+ hands you the right triple (see *Size tiers* below).
130
+
131
+ This is a **dense, 14px-default interface**. If your text looks like a marketing site, it is
132
+ too large; if a line of UI text is 11px, it is too small.
133
+
134
+ ### One size per line
135
+
136
+ Text that shares a line shares a size. Inside a control bar every label, button, input, select
137
+ and menu row is the tier's control text; a `Badge` or `Tag` is its own small object and the one
138
+ exception. In content, a secondary annotation (a timestamp beside a name, a count beside a label)
139
+ may be `--text-xs`. Never put a 14px label and a 12px control on the same baseline.
140
+
141
+ ### Table headers
142
+
143
+ A header cell is the **same size as its data cells**, weight 600, `--text-secondary`, sentence
144
+ case, no letter-spacing. The header is set apart by `--bg-table-header`, never by caps or a
145
+ heavier rule. Amount and ID columns (`mono: true`) keep the row's size, font and colour and add
146
+ only tabular figures; config-code columns (`code: true`) use the code chip — codes and amounts are never a point smaller than the words beside them.
147
+
148
+ ### Sortable headers
149
+
150
+ Mark a column `sortable: true` and its header gets a sort button: a muted sm `IconButton` at the
151
+ **right end of the header cell** — the same edge as a two-line row's `⋯`, so the two line up. The label
152
+ keeps its alignment (left, or right for number columns, where it sits 4px before the button).
153
+
154
+ - **Unsorted** — the button appears only while the header is hovered (or holds keyboard focus), icon
155
+ `arrow-up`. It keeps its space while hidden, so the label never shifts.
156
+ - **Click** cycles ascending (`arrow-up`) → descending (`arrow-down`) → unsorted. The tooltip names the
157
+ next step: *Sort ascending* · *Sort descending* · *Clear sorting*.
158
+ - **Sorted** — the button stays without hover and the label turns `--text-heading`; the header carries
159
+ `aria-sort`.
160
+ - **One column at a time.** Clicking another column's button starts it at ascending and clears the first.
161
+ - A long label truncates; the button never shrinks. With `resizable` the button sits inside the cell
162
+ padding, left of the divider, so the two never overlap.
163
+ - Action columns (row ⋯, checkboxes) are never `sortable`, so they show no button.
164
+
165
+ API: `sort` / `onSortChange` control it (`{ key, direction: "asc" | "desc" }` or `null`; Vue
166
+ `v-model:sort`, `@sort-change`); `defaultSort` seeds it uncontrolled. The table reorders rows itself —
167
+ numbers (commas allowed) numerically, text by locale with numeric collation, empty values last — unless
168
+ the column passes `compare(a, b, rowA, rowB)` or the table sets `manualSort` (rows arrive sorted from
169
+ the server). Selection indices and `onRowMore` always refer to the original `rows` order.
170
+
171
+ ### Two-line name rows
172
+
173
+ The name column of a document list (folders, models, sheets) is a **two-line title cell**:
174
+ `columns: [{ key: "name", label: "Name", width: 300, twoLine: true }, …]`. Left to right:
175
+
176
+ 1. an `IconTile kind="row"` tinted by the row's `hue` (`source` · `join` · `transform` · `merge` ·
177
+ `output`; `neutral` is the grey tile for folders and containers);
178
+ 2. two lines of text — the **title** in the tier's control text, `--text-heading`, regular weight, and the
179
+ **description** in `--text-xs`, `--text-secondary`. Each is one line and truncates with an ellipsis. Give the column a `width`; in a tight table it
180
+ shrinks to `minWidth` (default 180px) before the other columns give way;
181
+ 3. an sm `⋯` `IconButton` on the right (`onRowMore(row, index, event)`; Vue `@row-more`; `more: false` hides it).
182
+
183
+ An optional 14px **mark** sits right after the title: `mark: "favorite"` is a filled star in `--warning`;
184
+ `{ icon, color, label }` draws any 14px outline icon. Fields default to the row keys `icon`, `hue`,
185
+ `description`, `mark`; pass `twoLine: { icon, hue, description, mark }` with field names or
186
+ `(row, index) => value` accessors to read them from elsewhere.
187
+
188
+ The header stays the tier's bar height; only body rows grow. Every other cell stays vertically centred
189
+ and unchanged. All measures are `--title-cell-*` tier tokens:
190
+
191
+ | | sm | md | lg |
192
+ | --- | --- | --- | --- |
193
+ | Icon tile (`--title-cell-tile`, `-tile-r`) | 28 · r8 | **32 · r8** | 40 · r10 |
194
+ | Icon in the tile (`--title-cell-icon`) | 14 | 16 | 20 |
195
+ | Tile → text (`--title-cell-tile-gap`) | 8 | 12 | 12 |
196
+ | Title | 12 / 16 (13 / 18 CJK) | 14 / 20 | 14 / 20 |
197
+ | Description | 12 / 16 (13 / 18 CJK) | 12 / 16 (13 / 18 CJK) | 12 / 16 (13 / 18 CJK) |
198
+ | Title → description (`--title-cell-gap`) | 2 | 2 | 4 |
199
+ | Row padding top and bottom (`--title-cell-py`) | 8 | 10 | 14 |
200
+ | **Row height** (Latin / CJK) | **50 / 54** | **58 / 60** | **68 / 70** |
201
+ | Header | 36 | 40 | 48 |
202
+ | `⋯` button | sm 28 | sm 28 | sm 28 |
203
+
204
+ **Opening a row.** Pass `onRowOpen(row, index, event)` (Vue `@row-open`) and the icon tile and the title open
205
+ the row: both get the hand cursor, and the title is a keyboard target (Enter / Space). The ⋯ button and the
206
+ expand arrow never open the row. Without the callback nothing in the cell looks clickable.
207
+
208
+ **Tree rows.** Set `tree` on the table and nest rows through `children` — or set `hasChildren: true` on a
209
+ row whose children you load when it opens. The two-line column then indents **24px per level** and reserves a
210
+ **20px arrow slot + 4px** before the tile, so a child's arrow sits exactly under its parent's tile and leaf
211
+ rows line up with folders. The arrow is a muted `chevron-right` (tier icon size) that turns down when
212
+ open, with the `--overlay-hover` wash on hover; rows carry `aria-level` and `aria-expanded`. Expansion
213
+ is `expandedKeys` / `onExpandChange(row, expanded, keys)` (Vue `v-model:expandedKeys`, `@expand-change`),
214
+ or `defaultExpandedKeys` uncontrolled; `rowKey` names the key field (default `id`). Sorting reorders
215
+ siblings only — children stay under their parent. Every index the table reports (selection, `onRowMore`,
216
+ `onRowOpen`) is the row's depth-first position over all rows, expanded or not, so it never moves when the
217
+ user sorts or expands; for a flat table that is simply its position in `rows`.
218
+
219
+ **Labels.** The table draws six words itself — the sort tooltips, ⋯, and the arrow's expand / collapse.
220
+ `labels: { sortAsc, sortDesc, sortClear, more, expand, collapse }` translates them; missing keys fall
221
+ back to English. Pass them in the product's language — a Chinese table with English tooltips is a bug.
222
+
223
+ In sm the title and description are the same size, so the description is told apart by colour alone —
224
+ use sm two-line rows only where the list is dense and short labels are expected.
225
+
226
+ ### Chinese, Japanese and Korean
227
+
228
+ Han, kana and Hangul have no capitals and no italics, so emphasis is weight. Under
229
+ `:lang(zh|ja|ko)` the tokens change for you: `--weight-medium` and `--weight-semibold` both become
230
+ **500** — square glyphs carry more strokes, so PingFang 600 next to Inter 500 reads a full step bolder —
231
+ and every `--tracking-*` is **0**. (Microsoft YaHei, Meiryo, Yu Gothic UI and Malgun Gothic ship no 500
232
+ face, so on Windows these render Regular; size, colour and the header fill keep the hierarchy.) Below 14px CJK is one step larger than
233
+ Latin — `--text-xs` 13px (leading 18) and `--text-2xs` 12px — so no square glyph renders under
234
+ 12px; chart numerals read `--text-2xs-mono` and stay 11px. Text sized from geometry (switch inside text, avatar initials) is floored at `--text-glyph-min`: 11px, 12px in CJK. Inside an sm region `--weight-medium`
235
+ is 400 for CJK, because bold strokes merge at 13px. Simplified and Traditional Chinese, Japanese
236
+ and Korean get the same rule. CJK text is never smaller than the Latin
237
+ text beside it, never letter-spaced and never transformed; a CJK table header or section label
238
+ is emphasised by weight alone. Set `lang` on `<html>`, or on the region when one panel switches
239
+ language — every component re-reads `--font-sans`, so a per-region switch works.
122
240
 
123
241
  ---
124
242
 
125
243
  ## Spacing, radii, sizing
126
244
 
127
245
  **Radii** — pick by element, not by taste:
128
- `--radius-sm` 4px (checkbox, stepper) · `--radius-md` 8px (buttons, inputs, nav, chips) ·
129
- `--radius-lg` 10px (cards, search, dropzone) · `--radius-tile` 14px · `--radius-node` 16px ·
130
- `--radius-full` (pills, avatars).
131
-
132
- **Control heights** — fixed, never improvised:
133
- `--h-button` 32px · `--h-button-sm` 30px · `--h-input` 36px · `--h-nav-item` 35.5px ·
134
- `--h-tree-item` 30px.
246
+ `--radius-sm` 4px (checkbox) · `--radius-md` 8px (buttons, inputs, selects, search, steppers,
247
+ segmented controls, nav, chips) · `--radius-lg` 10px (cards, menus, dropzone) ·
248
+ `--radius-tile` 14px · `--radius-node` 16px · `--radius-full` (pills, avatars). Radii do not
249
+ change with the size tier.
250
+
251
+ ### Size tiers — one per region
252
+
253
+ Every control reads its height, text, icon size and padding from one set of tier tokens in
254
+ `tokens/layout.css`. A **region** — the app root, a toolbar, a filter bar, a form, a table, a
255
+ dialog, a drawer — declares `data-size="sm" | "md" | "lg"` and everything inside inherits it,
256
+ so two controls that share a row can never disagree. `md` is the default on `:root`.
257
+ **Change the region, not the control.**
258
+
259
+ | Token | sm | md | lg | Used by |
260
+ | --- | --- | --- | --- | --- |
261
+ | `--control-h` | 28 | **32** | 40 | buttons, inputs, selects, search, steppers, segmented controls, chips, pagination items, menu rows |
262
+ | `--control-text` | 12 (13 CJK) | **14** | 14 | text in controls and their labels, table cells |
263
+ | `--control-icon` | 14 | 16 | 16 | icon inside a control |
264
+ | `--control-px` | 8 | 12 | 16 | horizontal padding of a text control or button |
265
+ | `--control-gap` | 8 | 8 | 8 | inside one group: label → its control, button → button |
266
+ | `--group-gap` | 12 | 16 | 24 | between groups in one bar: field → next field |
267
+ | `--bar-h` | 36 | 40 | 48 | toolbar, filter bar, tab bar, table row, list row |
268
+ | `--bar-card-h` | 44 | 48 | 56 | a bar inside a bordered card (table toolbar, pagination) |
269
+ | `--edge-pad` | 12 | 16 | 16 | card edge → first control or cell |
270
+ | `--cell-px` | 8 | 12 | 16 | horizontal padding of a table cell |
271
+ | `--check-size` | 14 | 16 | 16 | checkbox and radio box |
272
+ | `--tag-h` | 20 | 24 | 28 | `Tag` |
273
+ | `--switch-w` × `--switch-h` | 28 × 16 | 36 × 20 | 44 × 24 | `Switch` track |
274
+
275
+ Where each tier belongs:
276
+
277
+ - **sm** — dense data grids (`SmartTable`, `Spreadsheet` and `DataPreview` set it themselves),
278
+ controls inside pipeline nodes, a toolbar that must fit a 32px row.
279
+ - **md** — everything else: app toolbars, filter bars, tables, long forms, settings pages.
280
+ - **lg** — dialogs (`Modal` sets it), short forms, wizards, onboarding, a page with one task.
281
+
282
+ Rules:
283
+
284
+ - **One tier per row.** Never a 28px icon button beside a 32px input.
285
+ - **Nothing interactive is smaller than 24px.** The former `xs` sizes and `dense` props map to `sm`.
286
+ - A per-control `size` prop only stamps `data-size` on that control. Use it for a control that
287
+ stands alone in its band — never to "fix" one control inside a bar.
288
+ - Text inside a control is `--control-text`, not `--text-xs` because it looks tidier.
289
+ - `--h-button` and `--h-input` are aliases of `--control-h`; `--h-button-sm` is 28px. Prefer the
290
+ tier tokens in new code.
291
+
292
+ ### Button emphasis — pick the variant, never the size
293
+
294
+ The tier says how dense a region is; the **variant** says how important an action is. Never
295
+ shrink a button to make it feel lighter: a 28px button beside 32px controls and 14px text reads
296
+ as a mistake on a calm page, and the tier rule above forbids it anyway. Reach for a quieter
297
+ variant instead.
298
+
299
+ | Variant | At rest | Where it lives |
300
+ | --- | --- | --- |
301
+ | `primary` | blue fill | The one main action of the view — page toolbar, dialog footer, wizard footer. Never two in sight. |
302
+ | `outline` | hairline box | Secondary actions that must read as buttons at a glance: beside a primary, in forms, in toolbars. |
303
+ | `ghost` | no box, grey wash on hover | Actions in card and section headers, table toolbars, panel chrome — anything that should stay quiet until needed. Same height and padding as `outline`, so it lines up with the controls beside it. Icon-only → `IconButton`, same rules. |
304
+ | `text` | bare label, underline on hover | Links that happen to be buttons: *View all* at a list end or header right, *Clear filters* in an empty state, *Learn more* inside a sentence. Never beside a boxed button, never as a toolbar action. |
305
+ | `primary-soft` · `dark` · `danger` · `danger-soft` | tint · near-black · red | Tinted secondary emphasis · brand / AI actions · destructive confirms and their softer in-row form. |
306
+
307
+ **Card and section headers** (title left, actions right) hold either controls at the region's
308
+ tier — `ghost` for secondary actions such as *Export* or *Filter*, and `primary` only when the
309
+ card *is* the page's main object, which makes it the page's one primary — or a single `text` link
310
+ such as *View all*. Not both in one header. The header row is the region's `--bar-h`; a 16px
311
+ section title and 32px ghost buttons share it comfortably.
312
+
313
+ **Chrome** (fixed, not tiered): `--sidebar-w` 240 · `--rail-w` 64 · `--topbar-h` 56 ·
314
+ `--panel-w` 400 · `--drawer-h` 250 · `--h-nav-item` 36 · `--h-subnav-item` 32 ·
315
+ `--h-tree-item` 32.
135
316
 
136
317
  **Page rhythm**: `--page-pad-y` 24px · `--page-pad-x` 32px · `--section-gap` 24px ·
137
- `--card-pad` 21px (`--card-pad-sm` 17px for dense cards).
318
+ `--card-pad` 21px (`--card-pad-sm` 17px for dense cards). Gaps inside a bar come from the tier:
319
+ 8px inside a group, 12 / 16 / 24px between groups, `--edge-pad` from a card edge to its first
320
+ control.
138
321
 
139
- The 35.5px and 21px are real. They come from the source design file. **Do not round them to
140
- 36 or 24 to fit a mental 4px grid.**
322
+ The 21px and 17px are real. They come from the source design file. **Do not round them to 24 or
323
+ 16 to fit a mental 4px grid.**
141
324
 
142
325
  **Shadows** — four, and only four: `--shadow-node` (canvas cards), `--shadow-menu` (dropdowns,
143
326
  popovers), `--shadow-modal` (modals), `--shadow-selected` (selected node). Cards in content
@@ -163,9 +346,18 @@ Nothing bounces. Nothing slides more than a few pixels. Keyframes available:
163
346
 
164
347
  ## Interaction states — you get these for free
165
348
 
166
- `tokens/interaction.css` applies press and keyboard focus globally. Do not re-implement them.
167
-
168
- - **Hover** — one step darker (`--bg-hover`, `--action-primary-hover`, `--soft-hover`)
349
+ `tokens/interaction.css` applies press and keyboard focus globally; `tokens/hover.css` carries the hover hooks. Do not re-implement them.
350
+
351
+ - **Hover** — every pointer target answers it, one step at a time:
352
+ filled and boxed buttons, menu rows, list rows, nav and tree items, segments → one surface step
353
+ (`--bg-hover`, `--action-primary-hover`, `--soft-hover`); a borderless `IconButton` → the alpha
354
+ overlay `--overlay-hover` (press `--overlay-press`), because it sits on white rows, grey table headers
355
+ and grey bars alike and a solid `--bg-hover` disappears on `--bg-table-header`; field boxes (inputs, selects, date,
356
+ combobox, multi-select, search, stepper) → border `--border-control` to `--border-strong`;
357
+ text-only controls (inactive tabs, legend items, clear ×, copy) → ink to `--text-heading`;
358
+ table body rows → `--bg-inset`; checkbox and radio rings → `--text-muted`; switch tracks →
359
+ one step toward the ink colour; inline action links → underline. Selected, open, focused and
360
+ error states never change on hover.
169
361
  - **Press** — a second step, applied automatically on `:active`
170
362
  - **Focus** — 2px `--focus-border` outline on `:focus-visible` only (never on mouse click)
171
363
  - **Disabled** — 55% opacity, default cursor
@@ -194,47 +386,41 @@ An indicator appears **only where a drop is legal**, and its shape names the ope
194
386
 
195
387
  ---
196
388
 
197
- ## Brand expression
198
-
199
- `BrandVisual` is the only place saturated dark artwork is allowed, and it is decoration —
200
- never a data surface.
201
-
202
- - **Seven motifs, one canvas.** Every motif is authored at 1200×400 and cropped to fill its
203
- box. Do not author a new one-off SVG for a hero; pick a motif.
204
- - **It never follows the theme.** The artwork is always the dark brand palette in both light
205
- and dark mode — it is imagery, not a surface.
206
- - **Text on it uses `--on-accent`-weight foregrounds** (`#fff` / `#93c5fd` for eyebrows) and
207
- sits in the calm region of the composition, never on top of the bright focal marker.
208
- - **Do not read data into it.** The arcs, lattices and ticks are not a chart; anything a user
209
- must read goes in a real chart component.
210
-
211
- ---
212
-
213
389
  ## Do not
214
390
 
215
391
  The list that prevents the most rework. These are absolute.
216
392
 
217
393
  - **Do not hard-code a hex, rgb, or named color.** Use a semantic token.
218
- - **Do not put a `BrandVisual` behind readable content without a scrim or a calm region** —
219
- and never restyle its palette to match a theme.
394
+ - **Do not write a unitless number for a length in a Vue `:style`.** Vue does not add `px`;
395
+ write `'30px'` or `px(size)` from `components/px.js`. (React adds `px` itself — except for
396
+ `lineHeight`, where a bare number is a multiplier.)
220
397
  - **Do not reference a palette step** (`--neutral-500`, `--blue-600`) in component code.
221
398
  - **Do not use any font other than Inter and Menlo.** No Roboto, no Arial, no system-ui stack.
222
399
  - **Do not use gradients.** The only exception in the entire system is the chart area fill.
223
400
  - **Do not add drop shadows to content cards.** Cards use a 1px `--border-card` hairline.
224
- - **Do not round the odd numbers.** 35.5px, 21px, 17px, 11px are from the source file.
401
+ - **Do not round the odd numbers.** `--card-pad` 21px and `--card-pad-sm` 17px are from the source
402
+ file; the 11px of `--text-2xs` is deliberate.
403
+ - **Do not use size as emphasis.** A quieter action gets a quieter variant (`ghost`, `text`), never a
404
+ smaller size.
405
+ - **Do not mix size tiers in one row.** The region declares `data-size`; the controls inherit. A
406
+ `size` prop on one control inside a bar is a bug, not a fix.
407
+ - **Do not shrink, letter-space or uppercase Chinese, Japanese or Korean text.** Under `lang`
408
+ the emphasis and heading weight is 500 (medium 400 at sm), tracking is 0, and sizes under 14px step up by one — that is the whole CJK rule.
225
409
  - **Do not put dark text on a saturated fill.** `--on-accent` (white) is the only option,
226
410
  in both themes — this is why the dark-mode primary button keeps white text.
227
411
  - **Do not scale or shift elements on press.** Press is a color step only.
228
412
  - **Do not show a drop indicator where the drop is impossible.** No half-row boxes on a
229
413
  container, no insert rules on a node that can't take children.
230
414
  - **Do not build a new primitive when one exists.** Check the component index in
231
- `INTEGRATION.md` first — there are 118.
232
- - **Do not use emoji as icons.** Use `<Icon name="..." />` (362 glyphs) or `<Unicon>` (1,206).
415
+ `INTEGRATION.md` first — there are 117.
416
+ - **Do not use emoji as icons.** Use `<Icon name="..." />` (330 glyphs) or `<Unicon>` (1,206).
233
417
  - **Do not invent new component variants.** If `Button` lacks the variant you want, that is a
234
418
  design-system request, not a local override.
235
419
  - **Do not stack two primary buttons.** One primary action per view; everything else is
236
420
  `outline`, `ghost`, or `text`.
237
- - **Do not use full-uppercase text** except in 9–10px section labels with letter-spacing.
421
+ - **Do not use full-uppercase text.** Table headers and section labels are sentence case, weight
422
+ 600, tracking 0 — the same size as the text they label. (This site's own card labels follow the
423
+ same rule: 12px, sentence case.)
238
424
  - **Do not animate anything longer than 360ms** or with a bounce/elastic easing.
239
425
 
240
426
  ---