@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
@@ -1,22 +1,52 @@
1
- /* Keybricks typography tokens — sizes/tracking verbatim from the .fig */
1
+ /* Keybricks typography tokens — the 14px scale (v2.0).
2
+ One ladder, 3–5 sizes do almost all the work: 12 captions · 14 body and controls · 16 section titles · 20 page titles.
3
+ Control text (--control-text) is defined per size tier in layout.css and points back into this ladder. */
2
4
  :root{
3
5
  --font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
4
- --font-mono:Menlo,ui-monospace,'SF Mono',Consolas,monospace;
5
- /* size / line-height / letter-spacing pairs */
6
- --text-2xs:10px;--leading-2xs:12.5px;--tracking-2xs:.117px; /* palette tile labels */
7
- --text-xs:11px;--leading-xs:16.5px;--tracking-xs:.064px; /* table cells, captions, step labels */
8
- --text-sm:12px;--leading-sm:18px;--tracking-sm:0; /* form labels, inputs, chips, meta */
9
- --text-base:13px;--leading-base:19.5px;--tracking-base:-.076px; /* default UI text, buttons, nav */
10
- --text-md:14px;--leading-md:21px;--tracking-md:-.15px; /* section headings, panel titles */
11
- --text-lg:15px;--leading-lg:22.5px;--tracking-lg:-.234px; /* page titles, wordmark */
12
- --text-xl:20px;--leading-xl:30px;--tracking-xl:-.449px; /* greeting heading */
6
+ --font-mono:Menlo,ui-monospace,'SF Mono',Consolas,monospace; /* code only: code blocks, logs, inline code and config-code chips — never IDs or amounts in the UI */
7
+ /* size / line-height / letter-spacing triples — always set all three together */
8
+ --text-2xs:11px;--leading-2xs:16px;--tracking-2xs:.064px; /* chart text only — nothing in the system is smaller; 12px in CJK */
9
+ --text-2xs-mono:11px;
10
+ --text-code:12px;--leading-code:18px; /* config-code chips (Table `code` columns): Latin, so not bumped in CJK; 11/16 in sm */
11
+ --text-glyph-min:11px; /* floor for text sized from geometry (switch inside text, avatar initials); 12px in CJK */ /* chart numerals (UI font, tabular figures; name kept for compatibility): Latin digits, so they stay 11px in CJK too */
12
+ --text-xs:12px;--leading-xs:16px;--tracking-xs:0; /* captions, helper text, badges, tags, meta; sm-tier control text — 13px in CJK */
13
+ --text-sm:12px;--leading-sm:16px;--tracking-sm:0; /* alias of --text-xs kept for compatibility — prefer --text-xs */
14
+ --text-base:14px;--leading-base:20px;--tracking-base:-.15px; /* body, md/lg controls, labels, table cells */
15
+ --text-md:16px;--leading-md:24px;--tracking-md:-.28px; /* section headings, panel / card / dialog titles */
16
+ --text-lg:20px;--leading-lg:28px;--tracking-lg:-.449px; /* page titles */
17
+ --text-xl:24px;--leading-xl:32px;--tracking-xl:-.54px; /* greeting heading, page hero */
13
18
  --text-num:24px;--leading-num:32px;--tracking-num:.07px; /* stat numbers (weight 300) */
14
- /* Extended display scale — extrapolated from the file's own size→tracking curve (≈ −.0225px per size px) */
15
- --text-2xl:24px;--leading-2xl:31px;--tracking-2xl:-.54px; /* modal/page hero headings */
16
- --text-3xl:30px;--leading-3xl:37px;--tracking-3xl:-.67px; /* marketing/report headings */
17
- --text-4xl:36px;--leading-4xl:43px;--tracking-4xl:-.81px; /* dashboard hero numbers */
18
- --text-display:48px;--leading-display:54px;--tracking-display:-1.08px; /* slides, covers */
19
+ /* Extended display scale — same size→tracking curve, continued */
20
+ --text-2xl:30px;--leading-2xl:38px;--tracking-2xl:-.67px; /* modal / report hero headings */
21
+ --text-3xl:38px;--leading-3xl:46px;--tracking-3xl:-.855px; /* marketing headings, site hero */
22
+ --text-4xl:48px;--leading-4xl:56px;--tracking-4xl:-1.08px; /* dashboard hero numbers */
23
+ --text-display:60px;--leading-display:68px;--tracking-display:-1.35px; /* slides, covers */
19
24
  --weight-light:300;--weight-regular:400;--weight-medium:500;--weight-semibold:600;
20
25
  }
26
+ /* Chinese (Simplified and Traditional), Japanese and Korean — one rule for all square scripts.
27
+ A square glyph carries far more strokes than a Latin letter, so the same numeric weight reads heavier:
28
+ PingFang 600 beside Inter 500 looks a full step bolder, and 600 everywhere flattens labels and headers
29
+ into one weight. CJK therefore uses 500 (PingFang / Hiragino / Apple SD Gothic Neo Medium) for both
30
+ --weight-medium and --weight-semibold, and Latin tracking is switched off. Microsoft YaHei, Meiryo,
31
+ Yu Gothic UI and Malgun Gothic ship no 500 face, so on Windows these render Regular — hierarchy there
32
+ comes from size, colour and the header fill.
33
+ Small sizes are one step larger than Latin: a 12px square glyph has about 11 device pixels for up to
34
+ 8 horizontal strokes, which a 1x display cannot resolve. 12 → 13 (leading 18) and 11 → 12, so nothing
35
+ CJK renders below 12px. 14px and up are unchanged. In sm regions (13px CJK text) the medium weight
36
+ drops back to 400, because bold strokes merge at that size.
37
+ Set lang on <html> or on the region; every Keybricks component re-reads --font-sans so a per-region
38
+ switch works too. */
39
+ [lang|="zh"]{--font-sans:'Inter','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Noto Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
40
+ [lang|="ja"]{--font-sans:'Inter','Hiragino Kaku Gothic ProN','Hiragino Sans','Yu Gothic UI','Meiryo','Noto Sans JP',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
41
+ [lang|="ko"]{--font-sans:'Inter','Apple SD Gothic Neo','Malgun Gothic','Noto Sans KR',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
42
+ :lang(zh),:lang(ja),:lang(ko){font-family:var(--font-sans)}
43
+ [lang|="zh"],[lang|="ja"],[lang|="ko"]{--weight-medium:500;--weight-semibold:500;
44
+ --text-glyph-min:12px;--text-2xs:12px;--text-xs:13px;--leading-xs:18px;--text-sm:13px;--leading-sm:18px;
45
+ --tracking-2xs:0;--tracking-xs:0;--tracking-sm:0;--tracking-base:0;--tracking-md:0;--tracking-lg:0;--tracking-xl:0;--tracking-num:0;--tracking-2xl:0;--tracking-3xl:0;--tracking-4xl:0;--tracking-display:0}
46
+ /* sm tier in CJK: 13px text at regular weight. The second rule re-derives the tier's control text on a
47
+ lang element inside an sm region (a tier token resolves where it is declared, not where it is read). */
48
+ :is([lang|="zh"],[lang|="ja"],[lang|="ko"])[data-size="sm"],:is([lang|="zh"],[lang|="ja"],[lang|="ko"]) [data-size="sm"]{--weight-medium:400}
49
+ [data-size="sm"] :is([lang|="zh"],[lang|="ja"],[lang|="ko"]){--control-text:var(--text-xs);--control-leading:var(--leading-xs);--weight-medium:400}
50
+ :is([lang|="zh"],[lang|="ja"],[lang|="ko"]) :is([data-size="md"],[data-size="lg"]){--weight-medium:500}
21
51
  body{font-family:var(--font-sans);color:var(--text-primary);-webkit-font-smoothing:antialiased}
22
52
  a{color:var(--link);text-decoration:none}a:hover{color:var(--link-hover)}
@@ -1,43 +0,0 @@
1
- <!-- @dsCard group="Brand" viewport="700x560" name="Brand Visuals" subtitle="Seven generative motifs — one 1200×400 canvas each, cropped to fill any box" -->
2
- <!DOCTYPE html>
3
- <html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css">
4
- <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
5
- <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
6
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
7
- <script src="../../_ds_bundle.js"></script>
8
- <script src="../_shared/view-source.js"></script>
9
- <style>body{margin:0;background:var(--bg-surface);padding:20px;font-family:var(--font-sans)}
10
- .lab{font-size:var(--text-2xs);letter-spacing:.7px;text-transform:uppercase;color:var(--text-muted);font-weight:var(--weight-semibold);margin:0 0 6px}
11
- .grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
12
- .name{font-size:var(--text-xs);color:var(--text-secondary);margin:5px 0 0}
13
- .name b{color:var(--text-heading);font-weight:var(--weight-medium)}
14
- .hero-t{font-size:26px;line-height:30px;font-weight:var(--weight-semibold);color:#fff;letter-spacing:-.4px;margin:0}
15
- .hero-e{font-size:var(--text-2xs);letter-spacing:.8px;text-transform:uppercase;color:#93c5fd;font-weight:var(--weight-semibold);margin:0 0 6px}
16
- a{color:var(--link)}a:hover{color:var(--link-hover)}</style></head>
17
- <body><div id="root"></div>
18
- <script type="text/babel">
19
- const { BrandVisual } = window.KeybricksDesignSystem_71231a;
20
- const M = [["orbit","Orbit","同心弧 · 主母题"],["entropy","Entropy","晶核与尘"],["focal","Focal","景深点阵"],["manifold","Manifold","参数曲面"],["tesseract","Tesseract","嵌套立方"],["meridian","Meridian","经线扭曲"],["ledger","Ledger","刻度与游标"]];
21
- function Demo(){
22
- return (<div>
23
- <p className="lab">Hero — full width, overlay content</p>
24
- <BrandVisual motif="orbit" height={150}>
25
- <div style={{padding:"26px 28px"}}>
26
- <p className="hero-e">Design System</p>
27
- <p className="hero-t">Keybricks</p>
28
- </div>
29
- </BrandVisual>
30
- <p className="lab" style={{marginTop:22}}>Motifs — uniform 1200×400 canvas, cropped to fill</p>
31
- <div className="grid">
32
- {M.map(([m,en,zh])=>(
33
- <div key={m}>
34
- <BrandVisual motif={m} height={104}/>
35
- <p className="name"><b>{en}</b> · {zh}</p>
36
- </div>
37
- ))}
38
- </div>
39
- </div>);
40
- }
41
- ReactDOM.createRoot(document.getElementById("root")).render(<Demo/>);
42
- if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"BrandVisual.jsx","path":"../brand/BrandVisual.jsx"},{"name":"brandMotifs.js","path":"../brand/brandMotifs.js"}]); }, 0);
43
- </script></body></html>
@@ -1,48 +0,0 @@
1
- <!-- @dsCard group="Components" viewport="700x460" name="Data Table" subtitle="Selectable comparison table · dense preview mode" -->
2
- <!DOCTYPE html>
3
- <html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css">
4
- <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
5
- <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
6
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
7
- <script src="../../_ds_bundle.js"></script>
8
- <script src="../_shared/view-source.js"></script>
9
- <style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:10px;letter-spacing:.5px;text-transform:uppercase;color:var(--text-muted);display:block;padding-bottom:8px}</style></head>
10
- <body><div id="root"></div>
11
- <script type="text/babel">
12
- const { DataTable, Select, Card } = window.KeybricksDesignSystem_71231a;
13
- function Sheet(){
14
- const [sel,setSel]=React.useState([0]);
15
- const toggle=(w,v)=>{ if(w==="all") setSel(v?[0,1,2]:[]); else setSel(v?[...sel,w]:sel.filter(i=>i!==w)); };
16
- return <div style={{display:"flex",flexDirection:"column",gap:20}}>
17
- <div><span className="lbl">Default — selectable, with row actions</span>
18
- <DataTable selectable selected={sel} onToggle={toggle} columns={[
19
- {key:"module",label:"Module"},
20
- {key:"code",label:"Code",mono:true},
21
- {key:"cur",label:"Current Value"},
22
- {key:"next",label:"New Value"},
23
- {key:"action",label:"Action",render:()=> <Select size="sm" options={["New","Overwrite","Skip"]}/>},
24
- ]} rows={[
25
- {module:"Financial Settings",code:"FIN_CURRENCY_DEFAULT",cur:"USD",next:"EUR"},
26
- {module:"Financial Settings",code:"FIN_DECIMAL_PLACES",cur:"2",next:"2"},
27
- {module:"User Management",code:"USER_SESSION_TIMEOUT",cur:"30",next:"60"},
28
- ]}/>
29
- </div>
30
- <div><span className="lbl">Dense — data-preview drawer style</span>
31
- <DataTable dense columns={[
32
- {key:"id",label:"ID",mono:true},{key:"entity",label:"Entity",mono:true},{key:"customer",label:"Customer",mono:true},{key:"batch",label:"Batch Code",mono:true},{key:"qty",label:"Qty",mono:true},
33
- ]} rows={[
34
- {id:"528563",entity:"HK",customer:"A",batch:"HYSTK-1",qty:"4100"},
35
- {id:"528564",entity:"SG",customer:"B",batch:"HYSTK-4",qty:"1610"},
36
- {id:"528565",entity:"HK",customer:"C",batch:"HYSTK-5",qty:"3200"},
37
- ]}/>
38
- </div>
39
- <div><span className="lbl">Empty state</span>
40
- <Card pad={false}><DataTable columns={[{key:"module",label:"Module"},{key:"code",label:"Code",mono:true},{key:"cur",label:"Current Value"}]} rows={[]}/>
41
- <div style={{padding:"28px 0",textAlign:"center",fontSize:13,color:"var(--text-muted)"}}>No rows to display</div>
42
- </Card>
43
- </div>
44
- </div>;
45
- }
46
- ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
47
- if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"DataTable.jsx","path":"../data/DataTable.jsx"},{"name":"Select.jsx","path":"../forms/Select.jsx"},{"name":"Card.jsx","path":"../display/Card.jsx"}]); }, 0);
48
- </script></body></html>
@@ -1 +0,0 @@
1
- window.__KB_SRC__=Object.assign(window.__KB_SRC__||{},{"brand/BrandVisual.jsx":"import React from \"react\";\nimport { buildMotif, motifList, motifLabels } from \"./brandMotifs.js\";\n\n/** Generative brand visual. One canvas (1200×400) per motif, cropped to fill any box —\n * use for page heroes, section headers and card headers. Always dark; never themed. */\nexport function BrandVisual({ motif = \"orbit\", width = \"100%\", height = 200, radius = \"var(--radius-lg)\", fit = \"slice\", children, style }) {\n const { viewBox, els } = buildMotif(motif, 1200, 400);\n return (\n <div style={{ position: \"relative\", width, height, borderRadius: radius, overflow: \"hidden\", background: \"#060a1e\", ...style }}>\n <svg viewBox={viewBox} preserveAspectRatio={fit === \"slice\" ? \"xMidYMid slice\" : \"xMidYMid meet\"} style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\", display: \"block\" }}>\n <defs>\n <linearGradient id=\"kbv-bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stopColor=\"#060a1e\" /><stop offset=\".5\" stopColor=\"#0b1638\" /><stop offset=\"1\" stopColor=\"#10265f\" /></linearGradient>\n <linearGradient id=\"kbv-bg-v\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stopColor=\"#060a1e\" /><stop offset=\".55\" stopColor=\"#0b1638\" /><stop offset=\"1\" stopColor=\"#10265f\" /></linearGradient>\n <linearGradient id=\"kbv-bg-d\" x1=\"1\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stopColor=\"#0a1231\" /><stop offset=\".55\" stopColor=\"#070c22\" /><stop offset=\"1\" stopColor=\"#050815\" /></linearGradient>\n <radialGradient id=\"kbv-core\" cx=\".5\" cy=\".5\" r=\".5\"><stop offset=\"0\" stopColor=\"#2b7fff\" stopOpacity=\".55\" /><stop offset=\"1\" stopColor=\"#2b7fff\" stopOpacity=\"0\" /></radialGradient>\n <radialGradient id=\"kbv-glow\" cx=\".5\" cy=\".5\" r=\".5\"><stop offset=\"0\" stopColor=\"#155dfc\" stopOpacity=\".5\" /><stop offset=\"1\" stopColor=\"#155dfc\" stopOpacity=\"0\" /></radialGradient>\n <filter id=\"kbv-b1\"><feGaussianBlur stdDeviation=\"1.5\" /></filter>\n <filter id=\"kbv-b2\"><feGaussianBlur stdDeviation=\"3\" /></filter>\n <filter id=\"kbv-b3\"><feGaussianBlur stdDeviation=\"9\" /></filter>\n </defs>\n {els.map(({ t, ...a }, i) => React.createElement(t, { key: i, ...a }))}\n </svg>\n {children ? <div style={{ position: \"relative\", height: \"100%\" }}>{children}</div> : null}\n </div>\n );\n}\n\nBrandVisual.motifs = motifList;\nBrandVisual.labels = motifLabels;\n","brand/BrandVisual.vue":"<script setup>\n// Generative brand visual. One canvas (1200×400) per motif, cropped to fill any box. Always dark; never themed.\nimport { computed } from 'vue'\nimport { buildMotif } from './brandMotifs.js'\n\nconst props = defineProps({\n motif: { type: String, default: 'orbit' },\n width: { type: [Number, String], default: '100%' },\n height: { type: [Number, String], default: 200 },\n radius: { type: [Number, String], default: 'var(--radius-lg)' },\n fit: { type: String, default: 'slice' },\n style: Object\n})\nconst art = computed(() => buildMotif(props.motif, 1200, 400))\nconst attrsOf = (e) => { const { t, ...a } = e; return a }\n</script>\n<template>\n <div :style=\"{ position:'relative', width: props.width, height: props.height, borderRadius: props.radius, overflow:'hidden', background:'#060a1e', ...props.style }\">\n <svg :viewBox=\"art.viewBox\" :preserveAspectRatio=\"props.fit === 'slice' ? 'xMidYMid slice' : 'xMidYMid meet'\" style=\"position:absolute;inset:0;width:100%;height:100%;display:block\">\n <defs>\n <linearGradient id=\"kbv-bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#060a1e\" /><stop offset=\".5\" stop-color=\"#0b1638\" /><stop offset=\"1\" stop-color=\"#10265f\" /></linearGradient>\n <linearGradient id=\"kbv-bg-v\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#060a1e\" /><stop offset=\".55\" stop-color=\"#0b1638\" /><stop offset=\"1\" stop-color=\"#10265f\" /></linearGradient>\n <linearGradient id=\"kbv-bg-d\" x1=\"1\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#0a1231\" /><stop offset=\".55\" stop-color=\"#070c22\" /><stop offset=\"1\" stop-color=\"#050815\" /></linearGradient>\n <radialGradient id=\"kbv-core\" cx=\".5\" cy=\".5\" r=\".5\"><stop offset=\"0\" stop-color=\"#2b7fff\" stop-opacity=\".55\" /><stop offset=\"1\" stop-color=\"#2b7fff\" stop-opacity=\"0\" /></radialGradient>\n <radialGradient id=\"kbv-glow\" cx=\".5\" cy=\".5\" r=\".5\"><stop offset=\"0\" stop-color=\"#155dfc\" stop-opacity=\".5\" /><stop offset=\"1\" stop-color=\"#155dfc\" stop-opacity=\"0\" /></radialGradient>\n <filter id=\"kbv-b1\"><feGaussianBlur stdDeviation=\"1.5\" /></filter>\n <filter id=\"kbv-b2\"><feGaussianBlur stdDeviation=\"3\" /></filter>\n <filter id=\"kbv-b3\"><feGaussianBlur stdDeviation=\"9\" /></filter>\n </defs>\n <component v-for=\"(e, i) in art.els\" :key=\"i\" :is=\"e.t\" v-bind=\"attrsOf(e)\" />\n </svg>\n <div v-if=\"$slots.default\" style=\"position:relative;height:100%\"><slot /></div>\n </div>\n</template>\n","brand/brandMotifs.js":"/* Keybricks brand motifs — generative geometry for BrandVisual.\n Every motif is authored against one canvas (1200×400) and expressed in fractions of W/H,\n so a single component renders at any size. Deterministic: seeded PRNG per motif. */\n\nconst seeded = (s) => { let a = s >>> 0; return () => { a = (a * 1664525 + 1013904223) >>> 0; return a / 4294967296; }; };\nconst lerp = (a, b, t) => a + (b - a) * t;\nconst clamp = (v, a, b) => Math.min(b, Math.max(a, v));\nconst n = (v) => Math.round(v * 10) / 10;\n\nexport const motifList = [\"orbit\", \"entropy\", \"focal\", \"manifold\", \"tesseract\", \"meridian\", \"ledger\"];\nexport const motifLabels = {\n orbit: \"Orbit — concentric arcs\",\n entropy: \"Entropy — crystal and dust\",\n focal: \"Focal — depth-of-field lattice\",\n manifold: \"Manifold — parametric surface\",\n tesseract: \"Tesseract — nested cubes\",\n meridian: \"Meridian — bent meridians\",\n ledger: \"Ledger — scale and cursor\",\n};\n\nconst LINE = \"#51a2ff\", BRIGHT = \"#93c5fd\", HI = \"#dbeafe\";\n\n/** Returns { viewBox, els } — els are plain SVG element descriptors: { t, ...attrs }. */\nexport function buildMotif(motif = \"orbit\", W = 1200, H = 400) {\n const rnd = seeded(motif.length * 7919 + 104729);\n const els = [];\n const push = (t, a) => els.push({ t, ...a });\n const line = (d, o, w = 1, stroke = LINE, filter) => push(\"path\", { d, fill: \"none\", stroke, \"stroke-opacity\": o, \"stroke-width\": w, ...(filter ? { filter } : null) });\n const dot = (x, y, r, fill, o) => push(\"circle\", { cx: n(x), cy: n(y), r: n(r), fill, \"fill-opacity\": o });\n const ring = (x, y, r, o, w = 1.5, stroke = HI) => push(\"circle\", { cx: n(x), cy: n(y), r: n(r), fill: \"none\", stroke, \"stroke-opacity\": o, \"stroke-width\": w });\n const marker = (x, y, s = 1) => { dot(x, y, 4.5 * s, HI, 1); ring(x, y, 12 * s, 0.55); ring(x, y, 25 * s, 0.22, 1.2, BRIGHT); };\n const grid = (cols, rows, o = 0.14) => {\n for (let i = 1; i < rows; i++) line(`M 0 ${n(H * i / rows)} L ${W} ${n(H * i / rows)}`, o, 1, BRIGHT);\n for (let i = 1; i < cols; i++) line(`M ${n(W * i / cols)} 0 L ${n(W * i / cols)} ${H}`, o, 1, BRIGHT);\n };\n\n if (motif === \"orbit\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg)\" });\n push(\"ellipse\", { cx: n(W * 0.72), cy: n(H * 0.2), rx: n(W * 0.36), ry: n(H * 0.78), fill: \"url(#kbv-core)\" });\n push(\"ellipse\", { cx: n(W * 0.12), cy: n(H * 0.92), rx: n(W * 0.28), ry: n(H * 0.5), fill: \"url(#kbv-glow)\", opacity: 0.55 });\n grid(4, 3);\n const cx = W * 0.84, cy = H * 1.06;\n const arc = (r, a1, a2) => {\n const p = (a) => [cx + r * Math.cos(a * Math.PI / 180), cy + r * Math.sin(a * Math.PI / 180)];\n const [x1, y1] = p(a1), [x2, y2] = p(a2);\n return `M ${n(x1)} ${n(y1)} A ${n(r)} ${n(r)} 0 0 1 ${n(x2)} ${n(y2)}`;\n };\n const wedge = (r, a1, a2) => `M ${n(cx)} ${n(cy)} L ${arc(r, a1, a2).slice(2)} Z`;\n push(\"path\", { d: wedge(H * 1.24, 194, 248), fill: LINE, opacity: 0.2 });\n push(\"path\", { d: wedge(H * 1.24, 248, 262), fill: BRIGHT, opacity: 0.16 });\n push(\"path\", { d: wedge(H * 0.86, 206, 252), fill: \"#155dfc\", opacity: 0.42 });\n [[1.62, 0.2], [1.28, 0.34], [0.98, 0.5], [0.7, 0.66], [0.44, 0.4]].forEach(([k, o], i) =>\n line(arc(H * k, 178, 272), o, i === 2 ? 1.5 : 1, i > 1 ? BRIGHT : LINE));\n marker(W * 0.34, H * 0.78);\n dot(W * 0.25, H * 0.28, 3, HI, 0.9);\n dot(W * 0.11, H * 0.6, 2.5, BRIGHT, 0.7);\n dot(W * 0.75, H * 0.28, 2.5, HI, 0.6);\n }\n\n if (motif === \"entropy\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg-d)\" });\n push(\"ellipse\", { cx: n(W * 0.74), cy: n(H * 0.35), rx: n(W * 0.4), ry: n(H * 0.82), fill: \"url(#kbv-core)\" });\n push(\"ellipse\", { cx: n(W * 0.18), cy: n(H * 0.95), rx: n(W * 0.3), ry: n(H * 0.5), fill: \"url(#kbv-glow)\", opacity: 0.45 });\n const NX = 11, NY = 6, NZ = 3, nuc = [8.2, 1.1, 2.05];\n const sx = W * 0.042, sy = H * 0.072, sz = H * 0.132, nx = W * 0.745, ny = H * 0.335;\n const iso = (x, y, z) => [nx + ((x - nuc[0]) - (y - nuc[1])) * sx, ny + ((x - nuc[0]) + (y - nuc[1])) * sy - (z - nuc[2]) * sz];\n const nodes = new Map();\n for (let x = 0; x < NX; x++) for (let y = 0; y < NY; y++) for (let z = 0; z < NZ; z++) {\n const dn = Math.hypot((x - nuc[0]) * 0.92, (y - nuc[1]) * 0.72, (z - nuc[2]) * 1.15);\n const order = clamp(1 - (dn - 1.5) / 5.4 + (rnd() - 0.5) * 0.24, 0, 1);\n if (order < 0.1 && rnd() < 0.66) continue;\n const c = iso(x, y, z), chaos = Math.pow(1 - order, 1.75);\n nodes.set(`${x},${y},${z}`, { px: c[0] + (rnd() - 0.5) * W * 0.17 * chaos, py: c[1] + (rnd() - 0.5) * H * 0.52 * chaos, order, depth: x + y - z * 1.2 });\n }\n for (const [k, p] of nodes) {\n const [x, y, z] = k.split(\",\").map(Number);\n [[x + 1, y, z], [x, y + 1, z], [x, y, z + 1]].forEach((q) => {\n const b = nodes.get(q.join(\",\"));\n if (!b) return;\n const o = Math.min(p.order, b.order);\n if (o < 0.28 && rnd() < 0.62) return;\n const near = clamp(1 - (p.depth + 5) / 16, 0, 1);\n const d = `M ${n(p.px)} ${n(p.py)} L ${n(b.px)} ${n(b.py)}`;\n if (o > 0.82) line(d, 0.34, 3.4, BRIGHT, \"url(#kbv-b2)\");\n line(d, lerp(0.05, 0.62, Math.pow(o, 1.2)) * lerp(0.55, 1.15, near), lerp(1, 1.5, o), o > 0.7 ? BRIGHT : LINE);\n });\n }\n for (const [, p] of nodes) {\n const near = clamp(1 - (p.depth + 5) / 16, 0, 1);\n dot(p.px, p.py, lerp(1.1, 3.2, near) * lerp(0.65, 1, p.order), p.order > 0.72 ? HI : BRIGHT, lerp(0.2, 0.95, p.order * 0.65 + near * 0.35));\n }\n for (let i = 0; i < 34; i++) {\n const x = rnd() * W * 0.42, y = rnd() * H, L = lerp(W * 0.004, W * 0.022, rnd());\n const a = Math.atan2(ny - y, nx - x) + (rnd() - 0.5) * 0.7;\n line(`M ${n(x)} ${n(y)} L ${n(x + Math.cos(a) * L)} ${n(y + Math.sin(a) * L)}`, lerp(0.07, 0.3, rnd()), 1, BRIGHT, rnd() < 0.45 ? \"url(#kbv-b1)\" : undefined);\n }\n for (let i = 0; i < 18; i++) dot(rnd() * W * 0.46, rnd() * H, lerp(0.6, 1.7, rnd()), BRIGHT, lerp(0.12, 0.42, rnd()));\n push(\"circle\", { cx: n(nx), cy: n(ny), r: n(H * 0.06), fill: LINE, \"fill-opacity\": 0.3, filter: \"url(#kbv-b3)\" });\n marker(nx, ny);\n }\n\n if (motif === \"focal\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg-v)\" });\n push(\"ellipse\", { cx: n(W * 0.5), cy: n(H * 0.3), rx: n(W * 0.42), ry: n(H * 0.5), fill: \"url(#kbv-glow)\" });\n const R = 11, C = 15, pts = [];\n for (let i = 0; i <= R; i++) {\n const t = i / R, y = lerp(H * 0.26, H * 1.02, Math.pow(t, 1.4)), half = lerp(W * 0.17, W * 0.6, Math.pow(t, 1.08));\n const row = [];\n for (let j = 0; j <= C; j++) row.push([W * 0.48 + lerp(-half, half, j / C) - W * 0.04 * (1 - t), y - H * 0.03 * Math.sin(j / C * Math.PI * 1.6)]);\n pts.push({ row, t });\n }\n pts.forEach(({ row, t }) => {\n line(row.map(([x, y], j) => `${j ? \"L\" : \"M\"} ${n(x)} ${n(y)}`).join(\" \"), lerp(0.08, 0.42, t), 1, t > 0.6 ? BRIGHT : LINE);\n });\n for (let j = 0; j <= C; j += 1) {\n line(pts.map(({ row }, i) => `${i ? \"L\" : \"M\"} ${n(row[j][0])} ${n(row[j][1])}`).join(\" \"), j % 3 === 0 ? 0.2 : 0.09, 1, LINE);\n }\n pts.forEach(({ row, t }) => row.forEach(([x, y]) => dot(x, y, lerp(1, 3, t), t > 0.55 ? HI : BRIGHT, lerp(0.22, 0.9, t))));\n marker(W * 0.82, H * 0.34, 0.9);\n }\n\n if (motif === \"manifold\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg-v)\" });\n push(\"ellipse\", { cx: n(W * 0.5), cy: n(H * 0.32), rx: n(W * 0.42), ry: n(H * 0.46), fill: \"url(#kbv-glow)\" });\n const V = 9, U = 16, span = W * 0.46;\n const f = (u, v) => {\n const t = v / V, x = lerp(W * 0.5 - span * (0.35 + 0.65 * t), W * 0.5 + span * (0.35 + 0.65 * t), u / U);\n const y = lerp(H * 0.27, H * 1.03, Math.pow(t, 1.5));\n const z = Math.sin(u / U * Math.PI * 2.2 + t * 3) * Math.cos(t * 2.4) * H * 0.077 * (0.4 + t);\n return [x, y - z, z];\n };\n for (let v = 0; v <= V; v++) {\n let d = \"\", peak = null, pz = -1e9;\n for (let u = 0; u <= U; u++) { const [x, y, z] = f(u, v); d += `${u ? \" L \" : \"M \"}${n(x)} ${n(y)}`; if (z > pz) { pz = z; peak = [x, y]; } }\n const t = v / V;\n line(d, lerp(0.15, 0.55, t), 1.2, t > 0.7 ? BRIGHT : LINE);\n if (v === 6) marker(peak[0], peak[1], 0.9);\n }\n for (let u = 0; u <= U; u += 2) {\n let d = \"\";\n for (let v = 0; v <= V; v++) { const [x, y] = f(u, v); d += `${v ? \" L \" : \"M \"}${n(x)} ${n(y)}`; }\n line(d, 0.14, 1.2);\n }\n }\n\n if (motif === \"tesseract\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg)\" });\n push(\"ellipse\", { cx: n(W * 0.5), cy: n(H * 0.46), rx: n(W * 0.4), ry: n(H * 0.56), fill: \"url(#kbv-core)\" });\n const cx = W * 0.5, cy = H * 0.5;\n const cube = (r, rt, o, c, w) => {\n const p = [];\n for (let i = 0; i < 4; i++) { const a = rt + i * Math.PI / 2; p.push([cx + r * Math.cos(a), cy + r * Math.sin(a) * 0.82]); }\n const up = p.map(([x, y]) => [x, y - r * 0.62]);\n for (let i = 0; i < 4; i++) {\n const j = (i + 1) % 4;\n line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(p[j][0])} ${n(p[j][1])}`, o, w, c);\n line(`M ${n(up[i][0])} ${n(up[i][1])} L ${n(up[j][0])} ${n(up[j][1])}`, o, w, c);\n line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(up[i][0])} ${n(up[i][1])}`, o * 0.8, w, c);\n }\n return { p, up };\n };\n const A = cube(H * 0.44, Math.PI / 4 + 0.2, 0.32, LINE, 1.2);\n const B = cube(H * 0.218, Math.PI / 4 + 0.55, 0.75, BRIGHT, 1.4);\n for (let i = 0; i < 4; i++) {\n line(`M ${n(A.p[i][0])} ${n(A.p[i][1])} L ${n(B.p[i][0])} ${n(B.p[i][1])}`, 0.22, 1.2);\n line(`M ${n(A.up[i][0])} ${n(A.up[i][1])} L ${n(B.up[i][0])} ${n(B.up[i][1])}`, 0.22, 1.2);\n }\n marker(B.up[1][0], B.up[1][1], 0.85);\n dot(W * 0.14, H * 0.79, 2.5, HI, 0.65);\n dot(W * 0.87, H * 0.2, 2.5, HI, 0.65);\n }\n\n if (motif === \"meridian\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg-v)\" });\n push(\"ellipse\", { cx: n(W * 0.5), cy: n(H * 0.5), rx: n(W * 0.34), ry: n(H * 0.62), fill: \"url(#kbv-core)\" });\n const cx = W * 0.5, cy = H * 0.5;\n for (let j = 0; j <= 12; j++) {\n const x0 = lerp(W * 0.06, W * 0.94, j / 12), k = (x0 - cx) / (W * 0.5);\n let d = \"\";\n for (let i = 0; i <= 24; i++) {\n const y = lerp(-H * 0.04, H * 1.04, i / 24);\n const bend = k * W * 0.055 * Math.exp(-Math.pow((y - cy) / (H * 0.42), 2));\n d += `${i ? \" L \" : \"M \"}${n(x0 + bend)} ${n(y)}`;\n }\n line(d, lerp(0.42, 0.16, Math.abs(k)), Math.abs(k) < 0.2 ? 1.4 : 1, Math.abs(k) < 0.35 ? BRIGHT : LINE);\n }\n line(`M 0 ${n(cy)} L ${W} ${n(cy)}`, 0.14, 1, BRIGHT);\n marker(cx, cy);\n dot(W * 0.2, H * 0.22, 2.5, BRIGHT, 0.6);\n dot(W * 0.84, H * 0.78, 2, BRIGHT, 0.5);\n }\n\n if (motif === \"ledger\") {\n push(\"rect\", { width: W, height: H, fill: \"url(#kbv-bg-d)\" });\n push(\"ellipse\", { cx: n(W * 0.5), cy: n(H * 1.04), rx: n(W * 0.46), ry: n(H * 0.66), fill: \"url(#kbv-glow)\" });\n grid(8, 4, 0.12);\n for (let i = 1; i < 40; i++) {\n const x = W * i / 40, major = i % 5 === 0;\n line(`M ${n(x)} ${n(H * 0.68)} L ${n(x)} ${n(H * 0.68 + (major ? H * 0.09 : H * 0.045))}`, major ? 0.5 : 0.24, 1, major ? BRIGHT : LINE);\n }\n const cur = W * 0.48;\n line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.6, 1.4, HI);\n line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.22, 4, BRIGHT, \"url(#kbv-b2)\");\n marker(cur, H * 0.42, 0.9);\n dot(W * 0.18, H * 0.22, 2.5, BRIGHT, 0.55);\n dot(W * 0.72, H * 0.72, 2, BRIGHT, 0.45);\n }\n\n return { viewBox: `0 0 ${W} ${H}`, els };\n}\n"});
@@ -1,17 +0,0 @@
1
- import * as React from "react";
2
- /** Generative brand visual — dark, geometric, always on-brand. Seven motifs, one 1200×400 canvas each, cropped to fill any box. */
3
- export type BrandMotif = "orbit" | "entropy" | "focal" | "manifold" | "tesseract" | "meridian" | "ledger";
4
- export interface BrandVisualProps {
5
- /** Which motif to draw. Banner-leaning: orbit, entropy, ledger. Centred: focal, manifold, tesseract, meridian. */
6
- motif?: BrandMotif;
7
- width?: number | string;
8
- height?: number | string;
9
- /** Corner radius; pass 0 for a full-bleed hero. */
10
- radius?: number | string;
11
- /** "slice" crops to fill (default); "meet" letterboxes the whole canvas. */
12
- fit?: "slice" | "meet";
13
- /** Overlay content — headings, eyebrows. Sits above the artwork. */
14
- children?: React.ReactNode;
15
- style?: React.CSSProperties;
16
- }
17
- export declare function BrandVisual(props: BrandVisualProps): JSX.Element;
@@ -1,29 +0,0 @@
1
- import React from "react";
2
- import { buildMotif, motifList, motifLabels } from "./brandMotifs.js";
3
-
4
- /** Generative brand visual. One canvas (1200×400) per motif, cropped to fill any box —
5
- * use for page heroes, section headers and card headers. Always dark; never themed. */
6
- export function BrandVisual({ motif = "orbit", width = "100%", height = 200, radius = "var(--radius-lg)", fit = "slice", children, style }) {
7
- const { viewBox, els } = buildMotif(motif, 1200, 400);
8
- return (
9
- <div style={{ position: "relative", width, height, borderRadius: radius, overflow: "hidden", background: "#060a1e", ...style }}>
10
- <svg viewBox={viewBox} preserveAspectRatio={fit === "slice" ? "xMidYMid slice" : "xMidYMid meet"} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", display: "block" }}>
11
- <defs>
12
- <linearGradient id="kbv-bg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stopColor="#060a1e" /><stop offset=".5" stopColor="#0b1638" /><stop offset="1" stopColor="#10265f" /></linearGradient>
13
- <linearGradient id="kbv-bg-v" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor="#060a1e" /><stop offset=".55" stopColor="#0b1638" /><stop offset="1" stopColor="#10265f" /></linearGradient>
14
- <linearGradient id="kbv-bg-d" x1="1" y1="0" x2="0" y2="1"><stop offset="0" stopColor="#0a1231" /><stop offset=".55" stopColor="#070c22" /><stop offset="1" stopColor="#050815" /></linearGradient>
15
- <radialGradient id="kbv-core" cx=".5" cy=".5" r=".5"><stop offset="0" stopColor="#2b7fff" stopOpacity=".55" /><stop offset="1" stopColor="#2b7fff" stopOpacity="0" /></radialGradient>
16
- <radialGradient id="kbv-glow" cx=".5" cy=".5" r=".5"><stop offset="0" stopColor="#155dfc" stopOpacity=".5" /><stop offset="1" stopColor="#155dfc" stopOpacity="0" /></radialGradient>
17
- <filter id="kbv-b1"><feGaussianBlur stdDeviation="1.5" /></filter>
18
- <filter id="kbv-b2"><feGaussianBlur stdDeviation="3" /></filter>
19
- <filter id="kbv-b3"><feGaussianBlur stdDeviation="9" /></filter>
20
- </defs>
21
- {els.map(({ t, ...a }, i) => React.createElement(t, { key: i, ...a }))}
22
- </svg>
23
- {children ? <div style={{ position: "relative", height: "100%" }}>{children}</div> : null}
24
- </div>
25
- );
26
- }
27
-
28
- BrandVisual.motifs = motifList;
29
- BrandVisual.labels = motifLabels;
@@ -1,34 +0,0 @@
1
- <script setup>
2
- // Generative brand visual. One canvas (1200×400) per motif, cropped to fill any box. Always dark; never themed.
3
- import { computed } from 'vue'
4
- import { buildMotif } from './brandMotifs.js'
5
-
6
- const props = defineProps({
7
- motif: { type: String, default: 'orbit' },
8
- width: { type: [Number, String], default: '100%' },
9
- height: { type: [Number, String], default: 200 },
10
- radius: { type: [Number, String], default: 'var(--radius-lg)' },
11
- fit: { type: String, default: 'slice' },
12
- style: Object
13
- })
14
- const art = computed(() => buildMotif(props.motif, 1200, 400))
15
- const attrsOf = (e) => { const { t, ...a } = e; return a }
16
- </script>
17
- <template>
18
- <div :style="{ position:'relative', width: props.width, height: props.height, borderRadius: props.radius, overflow:'hidden', background:'#060a1e', ...props.style }">
19
- <svg :viewBox="art.viewBox" :preserveAspectRatio="props.fit === 'slice' ? 'xMidYMid slice' : 'xMidYMid meet'" style="position:absolute;inset:0;width:100%;height:100%;display:block">
20
- <defs>
21
- <linearGradient id="kbv-bg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#060a1e" /><stop offset=".5" stop-color="#0b1638" /><stop offset="1" stop-color="#10265f" /></linearGradient>
22
- <linearGradient id="kbv-bg-v" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#060a1e" /><stop offset=".55" stop-color="#0b1638" /><stop offset="1" stop-color="#10265f" /></linearGradient>
23
- <linearGradient id="kbv-bg-d" x1="1" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#0a1231" /><stop offset=".55" stop-color="#070c22" /><stop offset="1" stop-color="#050815" /></linearGradient>
24
- <radialGradient id="kbv-core" cx=".5" cy=".5" r=".5"><stop offset="0" stop-color="#2b7fff" stop-opacity=".55" /><stop offset="1" stop-color="#2b7fff" stop-opacity="0" /></radialGradient>
25
- <radialGradient id="kbv-glow" cx=".5" cy=".5" r=".5"><stop offset="0" stop-color="#155dfc" stop-opacity=".5" /><stop offset="1" stop-color="#155dfc" stop-opacity="0" /></radialGradient>
26
- <filter id="kbv-b1"><feGaussianBlur stdDeviation="1.5" /></filter>
27
- <filter id="kbv-b2"><feGaussianBlur stdDeviation="3" /></filter>
28
- <filter id="kbv-b3"><feGaussianBlur stdDeviation="9" /></filter>
29
- </defs>
30
- <component v-for="(e, i) in art.els" :key="i" :is="e.t" v-bind="attrsOf(e)" />
31
- </svg>
32
- <div v-if="$slots.default" style="position:relative;height:100%"><slot /></div>
33
- </div>
34
- </template>
@@ -1,13 +0,0 @@
1
- <!-- @dsCard group="Directory Index" viewport="700x120" name="Brand dir" subtitle="Full card: Brand → Brand Visuals" -->
2
- <!DOCTYPE html>
3
- <html><head><meta charset="utf-8"><link rel="stylesheet" href="../../styles.css">
4
- <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
5
- <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
6
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
7
- <script src="../../_ds_bundle.js"></script>
8
- <style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans)}</style></head>
9
- <body><div id="root"></div>
10
- <script type="text/babel">
11
- const { BrandVisual } = window.KeybricksDesignSystem_71231a;
12
- ReactDOM.createRoot(document.getElementById("root")).render(<BrandVisual motif="orbit" height={88}/>);
13
- </script></body></html>
@@ -1,210 +0,0 @@
1
- /* Keybricks brand motifs — generative geometry for BrandVisual.
2
- Every motif is authored against one canvas (1200×400) and expressed in fractions of W/H,
3
- so a single component renders at any size. Deterministic: seeded PRNG per motif. */
4
-
5
- const seeded = (s) => { let a = s >>> 0; return () => { a = (a * 1664525 + 1013904223) >>> 0; return a / 4294967296; }; };
6
- const lerp = (a, b, t) => a + (b - a) * t;
7
- const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
8
- const n = (v) => Math.round(v * 10) / 10;
9
-
10
- export const motifList = ["orbit", "entropy", "focal", "manifold", "tesseract", "meridian", "ledger"];
11
- export const motifLabels = {
12
- orbit: "Orbit — concentric arcs",
13
- entropy: "Entropy — crystal and dust",
14
- focal: "Focal — depth-of-field lattice",
15
- manifold: "Manifold — parametric surface",
16
- tesseract: "Tesseract — nested cubes",
17
- meridian: "Meridian — bent meridians",
18
- ledger: "Ledger — scale and cursor",
19
- };
20
-
21
- const LINE = "#51a2ff", BRIGHT = "#93c5fd", HI = "#dbeafe";
22
-
23
- /** Returns { viewBox, els } — els are plain SVG element descriptors: { t, ...attrs }. */
24
- export function buildMotif(motif = "orbit", W = 1200, H = 400) {
25
- const rnd = seeded(motif.length * 7919 + 104729);
26
- const els = [];
27
- const push = (t, a) => els.push({ t, ...a });
28
- const line = (d, o, w = 1, stroke = LINE, filter) => push("path", { d, fill: "none", stroke, "stroke-opacity": o, "stroke-width": w, ...(filter ? { filter } : null) });
29
- const dot = (x, y, r, fill, o) => push("circle", { cx: n(x), cy: n(y), r: n(r), fill, "fill-opacity": o });
30
- const ring = (x, y, r, o, w = 1.5, stroke = HI) => push("circle", { cx: n(x), cy: n(y), r: n(r), fill: "none", stroke, "stroke-opacity": o, "stroke-width": w });
31
- const marker = (x, y, s = 1) => { dot(x, y, 4.5 * s, HI, 1); ring(x, y, 12 * s, 0.55); ring(x, y, 25 * s, 0.22, 1.2, BRIGHT); };
32
- const grid = (cols, rows, o = 0.14) => {
33
- for (let i = 1; i < rows; i++) line(`M 0 ${n(H * i / rows)} L ${W} ${n(H * i / rows)}`, o, 1, BRIGHT);
34
- for (let i = 1; i < cols; i++) line(`M ${n(W * i / cols)} 0 L ${n(W * i / cols)} ${H}`, o, 1, BRIGHT);
35
- };
36
-
37
- if (motif === "orbit") {
38
- push("rect", { width: W, height: H, fill: "url(#kbv-bg)" });
39
- push("ellipse", { cx: n(W * 0.72), cy: n(H * 0.2), rx: n(W * 0.36), ry: n(H * 0.78), fill: "url(#kbv-core)" });
40
- push("ellipse", { cx: n(W * 0.12), cy: n(H * 0.92), rx: n(W * 0.28), ry: n(H * 0.5), fill: "url(#kbv-glow)", opacity: 0.55 });
41
- grid(4, 3);
42
- const cx = W * 0.84, cy = H * 1.06;
43
- const arc = (r, a1, a2) => {
44
- const p = (a) => [cx + r * Math.cos(a * Math.PI / 180), cy + r * Math.sin(a * Math.PI / 180)];
45
- const [x1, y1] = p(a1), [x2, y2] = p(a2);
46
- return `M ${n(x1)} ${n(y1)} A ${n(r)} ${n(r)} 0 0 1 ${n(x2)} ${n(y2)}`;
47
- };
48
- const wedge = (r, a1, a2) => `M ${n(cx)} ${n(cy)} L ${arc(r, a1, a2).slice(2)} Z`;
49
- push("path", { d: wedge(H * 1.24, 194, 248), fill: LINE, opacity: 0.2 });
50
- push("path", { d: wedge(H * 1.24, 248, 262), fill: BRIGHT, opacity: 0.16 });
51
- push("path", { d: wedge(H * 0.86, 206, 252), fill: "#155dfc", opacity: 0.42 });
52
- [[1.62, 0.2], [1.28, 0.34], [0.98, 0.5], [0.7, 0.66], [0.44, 0.4]].forEach(([k, o], i) =>
53
- line(arc(H * k, 178, 272), o, i === 2 ? 1.5 : 1, i > 1 ? BRIGHT : LINE));
54
- marker(W * 0.34, H * 0.78);
55
- dot(W * 0.25, H * 0.28, 3, HI, 0.9);
56
- dot(W * 0.11, H * 0.6, 2.5, BRIGHT, 0.7);
57
- dot(W * 0.75, H * 0.28, 2.5, HI, 0.6);
58
- }
59
-
60
- if (motif === "entropy") {
61
- push("rect", { width: W, height: H, fill: "url(#kbv-bg-d)" });
62
- push("ellipse", { cx: n(W * 0.74), cy: n(H * 0.35), rx: n(W * 0.4), ry: n(H * 0.82), fill: "url(#kbv-core)" });
63
- push("ellipse", { cx: n(W * 0.18), cy: n(H * 0.95), rx: n(W * 0.3), ry: n(H * 0.5), fill: "url(#kbv-glow)", opacity: 0.45 });
64
- const NX = 11, NY = 6, NZ = 3, nuc = [8.2, 1.1, 2.05];
65
- const sx = W * 0.042, sy = H * 0.072, sz = H * 0.132, nx = W * 0.745, ny = H * 0.335;
66
- const iso = (x, y, z) => [nx + ((x - nuc[0]) - (y - nuc[1])) * sx, ny + ((x - nuc[0]) + (y - nuc[1])) * sy - (z - nuc[2]) * sz];
67
- const nodes = new Map();
68
- for (let x = 0; x < NX; x++) for (let y = 0; y < NY; y++) for (let z = 0; z < NZ; z++) {
69
- const dn = Math.hypot((x - nuc[0]) * 0.92, (y - nuc[1]) * 0.72, (z - nuc[2]) * 1.15);
70
- const order = clamp(1 - (dn - 1.5) / 5.4 + (rnd() - 0.5) * 0.24, 0, 1);
71
- if (order < 0.1 && rnd() < 0.66) continue;
72
- const c = iso(x, y, z), chaos = Math.pow(1 - order, 1.75);
73
- nodes.set(`${x},${y},${z}`, { px: c[0] + (rnd() - 0.5) * W * 0.17 * chaos, py: c[1] + (rnd() - 0.5) * H * 0.52 * chaos, order, depth: x + y - z * 1.2 });
74
- }
75
- for (const [k, p] of nodes) {
76
- const [x, y, z] = k.split(",").map(Number);
77
- [[x + 1, y, z], [x, y + 1, z], [x, y, z + 1]].forEach((q) => {
78
- const b = nodes.get(q.join(","));
79
- if (!b) return;
80
- const o = Math.min(p.order, b.order);
81
- if (o < 0.28 && rnd() < 0.62) return;
82
- const near = clamp(1 - (p.depth + 5) / 16, 0, 1);
83
- const d = `M ${n(p.px)} ${n(p.py)} L ${n(b.px)} ${n(b.py)}`;
84
- if (o > 0.82) line(d, 0.34, 3.4, BRIGHT, "url(#kbv-b2)");
85
- line(d, lerp(0.05, 0.62, Math.pow(o, 1.2)) * lerp(0.55, 1.15, near), lerp(1, 1.5, o), o > 0.7 ? BRIGHT : LINE);
86
- });
87
- }
88
- for (const [, p] of nodes) {
89
- const near = clamp(1 - (p.depth + 5) / 16, 0, 1);
90
- dot(p.px, p.py, lerp(1.1, 3.2, near) * lerp(0.65, 1, p.order), p.order > 0.72 ? HI : BRIGHT, lerp(0.2, 0.95, p.order * 0.65 + near * 0.35));
91
- }
92
- for (let i = 0; i < 34; i++) {
93
- const x = rnd() * W * 0.42, y = rnd() * H, L = lerp(W * 0.004, W * 0.022, rnd());
94
- const a = Math.atan2(ny - y, nx - x) + (rnd() - 0.5) * 0.7;
95
- line(`M ${n(x)} ${n(y)} L ${n(x + Math.cos(a) * L)} ${n(y + Math.sin(a) * L)}`, lerp(0.07, 0.3, rnd()), 1, BRIGHT, rnd() < 0.45 ? "url(#kbv-b1)" : undefined);
96
- }
97
- for (let i = 0; i < 18; i++) dot(rnd() * W * 0.46, rnd() * H, lerp(0.6, 1.7, rnd()), BRIGHT, lerp(0.12, 0.42, rnd()));
98
- push("circle", { cx: n(nx), cy: n(ny), r: n(H * 0.06), fill: LINE, "fill-opacity": 0.3, filter: "url(#kbv-b3)" });
99
- marker(nx, ny);
100
- }
101
-
102
- if (motif === "focal") {
103
- push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
104
- push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.3), rx: n(W * 0.42), ry: n(H * 0.5), fill: "url(#kbv-glow)" });
105
- const R = 11, C = 15, pts = [];
106
- for (let i = 0; i <= R; i++) {
107
- const t = i / R, y = lerp(H * 0.26, H * 1.02, Math.pow(t, 1.4)), half = lerp(W * 0.17, W * 0.6, Math.pow(t, 1.08));
108
- const row = [];
109
- for (let j = 0; j <= C; j++) row.push([W * 0.48 + lerp(-half, half, j / C) - W * 0.04 * (1 - t), y - H * 0.03 * Math.sin(j / C * Math.PI * 1.6)]);
110
- pts.push({ row, t });
111
- }
112
- pts.forEach(({ row, t }) => {
113
- line(row.map(([x, y], j) => `${j ? "L" : "M"} ${n(x)} ${n(y)}`).join(" "), lerp(0.08, 0.42, t), 1, t > 0.6 ? BRIGHT : LINE);
114
- });
115
- for (let j = 0; j <= C; j += 1) {
116
- line(pts.map(({ row }, i) => `${i ? "L" : "M"} ${n(row[j][0])} ${n(row[j][1])}`).join(" "), j % 3 === 0 ? 0.2 : 0.09, 1, LINE);
117
- }
118
- pts.forEach(({ row, t }) => row.forEach(([x, y]) => dot(x, y, lerp(1, 3, t), t > 0.55 ? HI : BRIGHT, lerp(0.22, 0.9, t))));
119
- marker(W * 0.82, H * 0.34, 0.9);
120
- }
121
-
122
- if (motif === "manifold") {
123
- push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
124
- push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.32), rx: n(W * 0.42), ry: n(H * 0.46), fill: "url(#kbv-glow)" });
125
- const V = 9, U = 16, span = W * 0.46;
126
- const f = (u, v) => {
127
- const t = v / V, x = lerp(W * 0.5 - span * (0.35 + 0.65 * t), W * 0.5 + span * (0.35 + 0.65 * t), u / U);
128
- const y = lerp(H * 0.27, H * 1.03, Math.pow(t, 1.5));
129
- const z = Math.sin(u / U * Math.PI * 2.2 + t * 3) * Math.cos(t * 2.4) * H * 0.077 * (0.4 + t);
130
- return [x, y - z, z];
131
- };
132
- for (let v = 0; v <= V; v++) {
133
- let d = "", peak = null, pz = -1e9;
134
- for (let u = 0; u <= U; u++) { const [x, y, z] = f(u, v); d += `${u ? " L " : "M "}${n(x)} ${n(y)}`; if (z > pz) { pz = z; peak = [x, y]; } }
135
- const t = v / V;
136
- line(d, lerp(0.15, 0.55, t), 1.2, t > 0.7 ? BRIGHT : LINE);
137
- if (v === 6) marker(peak[0], peak[1], 0.9);
138
- }
139
- for (let u = 0; u <= U; u += 2) {
140
- let d = "";
141
- for (let v = 0; v <= V; v++) { const [x, y] = f(u, v); d += `${v ? " L " : "M "}${n(x)} ${n(y)}`; }
142
- line(d, 0.14, 1.2);
143
- }
144
- }
145
-
146
- if (motif === "tesseract") {
147
- push("rect", { width: W, height: H, fill: "url(#kbv-bg)" });
148
- push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.46), rx: n(W * 0.4), ry: n(H * 0.56), fill: "url(#kbv-core)" });
149
- const cx = W * 0.5, cy = H * 0.5;
150
- const cube = (r, rt, o, c, w) => {
151
- const p = [];
152
- for (let i = 0; i < 4; i++) { const a = rt + i * Math.PI / 2; p.push([cx + r * Math.cos(a), cy + r * Math.sin(a) * 0.82]); }
153
- const up = p.map(([x, y]) => [x, y - r * 0.62]);
154
- for (let i = 0; i < 4; i++) {
155
- const j = (i + 1) % 4;
156
- line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(p[j][0])} ${n(p[j][1])}`, o, w, c);
157
- line(`M ${n(up[i][0])} ${n(up[i][1])} L ${n(up[j][0])} ${n(up[j][1])}`, o, w, c);
158
- line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(up[i][0])} ${n(up[i][1])}`, o * 0.8, w, c);
159
- }
160
- return { p, up };
161
- };
162
- const A = cube(H * 0.44, Math.PI / 4 + 0.2, 0.32, LINE, 1.2);
163
- const B = cube(H * 0.218, Math.PI / 4 + 0.55, 0.75, BRIGHT, 1.4);
164
- for (let i = 0; i < 4; i++) {
165
- line(`M ${n(A.p[i][0])} ${n(A.p[i][1])} L ${n(B.p[i][0])} ${n(B.p[i][1])}`, 0.22, 1.2);
166
- line(`M ${n(A.up[i][0])} ${n(A.up[i][1])} L ${n(B.up[i][0])} ${n(B.up[i][1])}`, 0.22, 1.2);
167
- }
168
- marker(B.up[1][0], B.up[1][1], 0.85);
169
- dot(W * 0.14, H * 0.79, 2.5, HI, 0.65);
170
- dot(W * 0.87, H * 0.2, 2.5, HI, 0.65);
171
- }
172
-
173
- if (motif === "meridian") {
174
- push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
175
- push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.5), rx: n(W * 0.34), ry: n(H * 0.62), fill: "url(#kbv-core)" });
176
- const cx = W * 0.5, cy = H * 0.5;
177
- for (let j = 0; j <= 12; j++) {
178
- const x0 = lerp(W * 0.06, W * 0.94, j / 12), k = (x0 - cx) / (W * 0.5);
179
- let d = "";
180
- for (let i = 0; i <= 24; i++) {
181
- const y = lerp(-H * 0.04, H * 1.04, i / 24);
182
- const bend = k * W * 0.055 * Math.exp(-Math.pow((y - cy) / (H * 0.42), 2));
183
- d += `${i ? " L " : "M "}${n(x0 + bend)} ${n(y)}`;
184
- }
185
- line(d, lerp(0.42, 0.16, Math.abs(k)), Math.abs(k) < 0.2 ? 1.4 : 1, Math.abs(k) < 0.35 ? BRIGHT : LINE);
186
- }
187
- line(`M 0 ${n(cy)} L ${W} ${n(cy)}`, 0.14, 1, BRIGHT);
188
- marker(cx, cy);
189
- dot(W * 0.2, H * 0.22, 2.5, BRIGHT, 0.6);
190
- dot(W * 0.84, H * 0.78, 2, BRIGHT, 0.5);
191
- }
192
-
193
- if (motif === "ledger") {
194
- push("rect", { width: W, height: H, fill: "url(#kbv-bg-d)" });
195
- push("ellipse", { cx: n(W * 0.5), cy: n(H * 1.04), rx: n(W * 0.46), ry: n(H * 0.66), fill: "url(#kbv-glow)" });
196
- grid(8, 4, 0.12);
197
- for (let i = 1; i < 40; i++) {
198
- const x = W * i / 40, major = i % 5 === 0;
199
- line(`M ${n(x)} ${n(H * 0.68)} L ${n(x)} ${n(H * 0.68 + (major ? H * 0.09 : H * 0.045))}`, major ? 0.5 : 0.24, 1, major ? BRIGHT : LINE);
200
- }
201
- const cur = W * 0.48;
202
- line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.6, 1.4, HI);
203
- line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.22, 4, BRIGHT, "url(#kbv-b2)");
204
- marker(cur, H * 0.42, 0.9);
205
- dot(W * 0.18, H * 0.22, 2.5, BRIGHT, 0.55);
206
- dot(W * 0.72, H * 0.72, 2, BRIGHT, 0.45);
207
- }
208
-
209
- return { viewBox: `0 0 ${W} ${H}`, els };
210
- }
@@ -1,13 +0,0 @@
1
- <!-- @dsCard group="Directory Index" viewport="700x70" name="Buttons dir" subtitle="Full card: Components → Button" -->
2
- <!DOCTYPE html>
3
- <html><head><meta charset="utf-8"><link rel="stylesheet" href="../../styles.css">
4
- <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
5
- <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
6
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
7
- <script src="../../_ds_bundle.js"></script>
8
- <style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans)}</style></head>
9
- <body><div id="root"></div>
10
- <script type="text/babel">
11
- const { Button } = window.KeybricksDesignSystem_71231a;
12
- ReactDOM.createRoot(document.getElementById("root")).render(<Button icon="send">Submit</Button>);
13
- </script></body></html>
@@ -1,47 +0,0 @@
1
- <script setup>
2
- import { computed } from 'vue'
3
- import { SERIES } from './chart-geometry.js'
4
- /**
5
- * Shared chart furniture for the Vue charts — one component, two shapes via `kind`
6
- * ("legend" | "tooltip"), so a single import covers both. The React side exposes these
7
- * as ChartLegend / ChartTooltip.
8
- */
9
- const props = defineProps({
10
- kind: { type: String, default: 'legend' },
11
- items: { type: Array, default: () => [] },
12
- hidden: { type: Array, default: () => [] },
13
- align: { type: String, default: 'left' },
14
- x: Number,
15
- y: Number,
16
- title: String,
17
- rows: { type: Array, default: () => [] },
18
- flip: Boolean,
19
- style: Object,
20
- })
21
- const emit = defineEmits(['toggle'])
22
- const tipStyle = computed(() => ({
23
- position: 'absolute', left: props.x + 'px', top: props.y + 'px',
24
- transform: props.flip ? 'translate(calc(-100% - 10px),-50%)' : 'translate(10px,-50%)',
25
- pointerEvents: 'none', zIndex: 5, background: 'var(--bg-surface)',
26
- border: '1px solid var(--border-card)', borderRadius: 'var(--radius-md)',
27
- boxShadow: 'var(--shadow-menu)', padding: '7px 10px', minWidth: '90px',
28
- lineHeight: 'normal', whiteSpace: 'nowrap',
29
- }))
30
- </script>
31
- <template>
32
- <div v-if="kind === 'tooltip'" :style="tipStyle">
33
- <div v-if="title != null" style="font-family:var(--font-sans);font-size:var(--text-2xs);color:var(--text-muted);padding-bottom:4px">{{ title }}</div>
34
- <div v-for="(r,i) in rows" :key="i" style="display:flex;align-items:center;gap:6px;padding:1px 0">
35
- <span v-if="r.color" :style="{width:'7px',height:'7px',borderRadius:'2px',background:r.color,flexShrink:0}"/>
36
- <span style="font-family:var(--font-sans);font-size:var(--text-xs);color:var(--text-secondary)">{{ r.label }}</span>
37
- <span style="font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-heading);margin-left:auto;padding-left:10px">{{ r.value }}</span>
38
- </div>
39
- </div>
40
- <div v-else :style="{display:'flex',flexWrap:'wrap',gap:'4px 14px',justifyContent:align==='right'?'flex-end':'flex-start',lineHeight:'normal',...style}">
41
- <span v-for="(it,i) in items" :key="it.label" role="button" tabindex="0" @click="emit('toggle', it.label)"
42
- :style="{display:'inline-flex',alignItems:'center',gap:'6px',cursor:'pointer',opacity:hidden.includes(it.label)?0.4:1,transition:'var(--t-hover)'}">
43
- <span :style="{width:'8px',height:'8px',borderRadius:'2px',background:it.color||SERIES[i%SERIES.length],flexShrink:0}"/>
44
- <span :style="{fontFamily:'var(--font-sans)',fontSize:'var(--text-xs)',color:'var(--text-secondary)',textDecoration:hidden.includes(it.label)?'line-through':'none'}">{{ it.label }}</span>
45
- </span>
46
- </div>
47
- </template>
@@ -1,7 +0,0 @@
1
- <!-- @dsCard group="Directory Index" viewport="700x240" name="charts/" subtitle="22 chart types · 3 size tiers · chart-geometry core + ChartKit furniture" -->
2
- <!DOCTYPE html>
3
- <html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css">
4
- <style>body{margin:0;background:var(--bg-surface);padding:18px;font-family:var(--font-sans)}.g{display:flex;flex-wrap:wrap;gap:8px}.p{border:1px solid var(--border-card);border-radius:var(--radius-md);padding:6px 10px;font-size:var(--text-xs);color:var(--text-body);font-family:var(--font-mono)}.h{font-size:var(--text-sm);line-height:19px;color:var(--text-secondary);padding-bottom:12px}</style></head>
5
- <body><div class="h">components/charts/ — the charting module. Every type has a live card under the <b>Charts</b> group; sizing tiers and color rules in <span style="font-family:var(--font-mono)">charts.prompt.md</span>. <b>WorldMap</b> additionally needs the pinned d3 + topojson tags on the page.</div>
6
- <div class="g"><span class="p">Sparkline</span><span class="p">LineChart</span><span class="p">BarChart</span><span class="p">BarList</span><span class="p">DonutChart</span><span class="p">ScatterChart</span><span class="p">HeatmapChart</span><span class="p">WaterfallChart</span><span class="p">BulletChart</span><span class="p">GaugeChart</span><span class="p">FunnelChart</span><span class="p">TreemapChart</span><span class="p">RadarChart</span><span class="p">Histogram</span><span class="p">BoxPlot</span><span class="p">ParetoChart</span><span class="p">CandlestickChart</span><span class="p">SankeyChart</span><span class="p">ChordChart</span><span class="p">SunburstChart</span><span class="p">WorldMap</span><span class="p">GanttChart</span><span class="p">ChartKit</span></div>
7
- </body></html>