@keyfunc/keybricks-ds 1.0.4 → 2.1.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 (357) hide show
  1. package/DEPLOY.md +4 -4
  2. package/DESIGN.md +154 -53
  3. package/INTEGRATION.md +174 -35
  4. package/SKILL.md +6 -4
  5. package/_adherence.oxlintrc.json +164 -68
  6. package/_scripts/build-index.mjs +9 -0
  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 +8 -3
  12. package/components/_cards/activity.card.html +2 -2
  13. package/components/_cards/alert.card.html +2 -2
  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 +2 -2
  17. package/components/_cards/button-1-base.card.html +2 -2
  18. package/components/_cards/button-2-states.card.html +14 -14
  19. package/components/_cards/button-3-sizes-icons.card.html +1 -1
  20. package/components/_cards/button-4-group.card.html +5 -5
  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 +2 -2
  24. package/components/_cards/charts-10-gauge.card.html +4 -4
  25. package/components/_cards/charts-11-funnel.card.html +2 -2
  26. package/components/_cards/charts-12-treemap.card.html +2 -2
  27. package/components/_cards/charts-14-radar.card.html +1 -1
  28. package/components/_cards/charts-15-distribution.card.html +1 -1
  29. package/components/_cards/charts-16-pareto.card.html +2 -2
  30. package/components/_cards/charts-17-candlestick.card.html +2 -2
  31. package/components/_cards/charts-18-sankey.card.html +2 -2
  32. package/components/_cards/charts-19-chord.card.html +2 -2
  33. package/components/_cards/charts-2-line.card.html +2 -2
  34. package/components/_cards/charts-20-sunburst.card.html +2 -2
  35. package/components/_cards/charts-21-worldmap.card.html +2 -2
  36. package/components/_cards/charts-22-gantt.card.html +2 -2
  37. package/components/_cards/charts-23-bar3d.card.html +2 -2
  38. package/components/_cards/charts-24-pie3d.card.html +2 -2
  39. package/components/_cards/charts-25-surface3d.card.html +2 -2
  40. package/components/_cards/charts-26-scatter3d.card.html +2 -2
  41. package/components/_cards/charts-27-ribbon3d.card.html +2 -2
  42. package/components/_cards/charts-3-bar.card.html +2 -2
  43. package/components/_cards/charts-4-barlist.card.html +2 -2
  44. package/components/_cards/charts-5-donut.card.html +3 -3
  45. package/components/_cards/charts-6-scatter.card.html +2 -2
  46. package/components/_cards/charts-7-heatmap.card.html +2 -2
  47. package/components/_cards/charts-8-waterfall.card.html +2 -2
  48. package/components/_cards/charts-9-bullet.card.html +2 -2
  49. package/components/_cards/charts-99-fullpage.card.html +5 -5
  50. package/components/_cards/checkbox.card.html +4 -4
  51. package/components/_cards/codeblock.card.html +1 -1
  52. package/components/_cards/combobox.card.html +3 -2
  53. package/components/_cards/context-menu.card.html +3 -2
  54. package/components/_cards/date-picker.card.html +5 -2
  55. package/components/_cards/diffvalue.card.html +2 -2
  56. package/components/_cards/divider.card.html +3 -3
  57. package/components/_cards/drawer.card.html +2 -2
  58. package/components/_cards/dropdown-menu.card.html +6 -6
  59. package/components/_cards/dropzone.card.html +1 -1
  60. package/components/_cards/empty-state.card.html +5 -5
  61. package/components/_cards/filter-bar.card.html +5 -5
  62. package/components/_cards/icon-button.card.html +2 -2
  63. package/components/_cards/icons-1-core.card.html +2 -2
  64. package/components/_cards/icons-2-feather.card.html +3 -3
  65. package/components/_cards/icons-3-unicons.card.html +3 -3
  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 +2 -2
  71. package/components/_cards/log-viewer.card.html +2 -2
  72. package/components/_cards/modal.card.html +9 -9
  73. package/components/_cards/multi-select.card.html +3 -2
  74. package/components/_cards/number-stepper.card.html +3 -2
  75. package/components/_cards/pagination.card.html +3 -2
  76. package/components/_cards/people.card.html +3 -3
  77. package/components/_cards/pipeline-node.card.html +2 -2
  78. package/components/_cards/pipeline-palette.card.html +4 -4
  79. package/components/_cards/radio.card.html +2 -2
  80. package/components/_cards/search.card.html +5 -2
  81. package/components/_cards/segmented-control.card.html +2 -2
  82. package/components/_cards/select.card.html +4 -4
  83. package/components/_cards/slider.card.html +1 -1
  84. package/components/_cards/smart-table.card.html +1 -1
  85. package/components/_cards/spreadsheet.card.html +2 -2
  86. package/components/_cards/stepper.card.html +2 -2
  87. package/components/_cards/table.card.html +103 -0
  88. package/components/_cards/tabs.card.html +3 -2
  89. package/components/_cards/tag.card.html +5 -2
  90. package/components/_cards/textarea.card.html +2 -2
  91. package/components/_cards/timeline.card.html +1 -1
  92. package/components/_cards/toast.card.html +4 -4
  93. package/components/_cards/toggles.card.html +3 -3
  94. package/components/_cards/tooltip.card.html +5 -5
  95. package/components/_cards/tree.card.html +2 -2
  96. package/components/_shared/src-buttons.js +1 -1
  97. package/components/_shared/src-charts.js +1 -1
  98. package/components/_shared/src-data.js +1 -1
  99. package/components/_shared/src-display.js +1 -1
  100. package/components/_shared/src-feedback.js +1 -1
  101. package/components/_shared/src-forms.js +1 -1
  102. package/components/_shared/src-navigation.js +1 -1
  103. package/components/_shared/src-pipeline.js +1 -1
  104. package/components/_shared/src-tabs.js +1 -1
  105. package/components/_vue/index.mjs +9 -5
  106. package/components/buttons/ActionChip.d.ts +3 -1
  107. package/components/buttons/ActionChip.jsx +4 -4
  108. package/components/buttons/ActionChip.vue +4 -4
  109. package/components/buttons/Button.d.ts +5 -2
  110. package/components/buttons/Button.jsx +15 -18
  111. package/components/buttons/Button.vue +17 -18
  112. package/components/buttons/ButtonGroup.vue +1 -1
  113. package/components/buttons/IconButton.d.ts +2 -1
  114. package/components/buttons/IconButton.jsx +9 -7
  115. package/components/buttons/IconButton.vue +10 -8
  116. package/components/buttons/buttons.prompt.md +6 -5
  117. package/components/charts/Bar3D.jsx +2 -2
  118. package/components/charts/Bar3D.vue +2 -2
  119. package/components/charts/BarChart.jsx +4 -4
  120. package/components/charts/BarChart.vue +4 -4
  121. package/components/charts/BarList.jsx +1 -1
  122. package/components/charts/BarList.vue +1 -1
  123. package/components/charts/BoxPlot.jsx +1 -1
  124. package/components/charts/BoxPlot.vue +2 -2
  125. package/components/charts/BulletChart.jsx +1 -1
  126. package/components/charts/BulletChart.vue +1 -1
  127. package/components/charts/CandlestickChart.jsx +2 -2
  128. package/components/charts/CandlestickChart.vue +3 -3
  129. package/components/charts/ChartKit.jsx +5 -5
  130. package/components/charts/ChartLegend.vue +16 -0
  131. package/components/charts/ChartTooltip.vue +16 -0
  132. package/components/charts/ChordChart.jsx +2 -2
  133. package/components/charts/ChordChart.vue +2 -2
  134. package/components/charts/GanttChart.jsx +2 -2
  135. package/components/charts/GanttChart.vue +2 -2
  136. package/components/charts/GaugeChart.jsx +2 -2
  137. package/components/charts/GaugeChart.vue +2 -2
  138. package/components/charts/HeatmapChart.jsx +2 -2
  139. package/components/charts/HeatmapChart.vue +2 -2
  140. package/components/charts/Histogram.jsx +2 -2
  141. package/components/charts/Histogram.vue +3 -3
  142. package/components/charts/LineChart.jsx +1 -1
  143. package/components/charts/LineChart.vue +3 -3
  144. package/components/charts/ParetoChart.jsx +3 -3
  145. package/components/charts/ParetoChart.vue +4 -4
  146. package/components/charts/PlotGrid.vue +18 -0
  147. package/components/charts/RadarChart.jsx +1 -1
  148. package/components/charts/RadarChart.vue +1 -1
  149. package/components/charts/Ribbon3D.jsx +2 -2
  150. package/components/charts/Ribbon3D.vue +2 -2
  151. package/components/charts/SankeyChart.jsx +2 -2
  152. package/components/charts/SankeyChart.vue +2 -2
  153. package/components/charts/Scatter3D.jsx +1 -1
  154. package/components/charts/Scatter3D.vue +1 -1
  155. package/components/charts/ScatterChart.jsx +3 -3
  156. package/components/charts/ScatterChart.vue +4 -4
  157. package/components/charts/Sparkline.jsx +1 -1
  158. package/components/charts/Sparkline.vue +1 -1
  159. package/components/charts/SunburstChart.jsx +1 -1
  160. package/components/charts/SunburstChart.vue +1 -1
  161. package/components/charts/Surface3D.jsx +2 -2
  162. package/components/charts/Surface3D.vue +2 -2
  163. package/components/charts/TreemapChart.jsx +2 -2
  164. package/components/charts/TreemapChart.vue +2 -2
  165. package/components/charts/WaterfallChart.jsx +2 -2
  166. package/components/charts/WaterfallChart.vue +3 -3
  167. package/components/charts/WorldMap.jsx +2 -2
  168. package/components/charts/WorldMap.vue +2 -2
  169. package/components/charts/XLabels.vue +11 -0
  170. package/components/data/CodeBlock.jsx +1 -1
  171. package/components/data/CodeBlock.vue +1 -1
  172. package/components/data/DiffValue.jsx +1 -1
  173. package/components/data/DiffValue.vue +1 -1
  174. package/components/data/FilterBar.d.ts +2 -0
  175. package/components/data/FilterBar.jsx +10 -9
  176. package/components/data/FilterBar.vue +9 -8
  177. package/components/data/KeyValue.jsx +3 -3
  178. package/components/data/KeyValue.vue +3 -3
  179. package/components/data/ListRow.jsx +2 -2
  180. package/components/data/ListRow.vue +2 -2
  181. package/components/data/Pagination.d.ts +5 -1
  182. package/components/data/Pagination.jsx +16 -12
  183. package/components/data/Pagination.vue +14 -9
  184. package/components/data/SmartTable.d.ts +4 -1
  185. package/components/data/SmartTable.jsx +16 -14
  186. package/components/data/SmartTable.vue +25 -22
  187. package/components/data/Spreadsheet.d.ts +2 -0
  188. package/components/data/Spreadsheet.jsx +12 -11
  189. package/components/data/Spreadsheet.vue +14 -13
  190. package/components/data/Table.d.ts +47 -0
  191. package/components/data/Table.jsx +85 -0
  192. package/components/data/Table.vue +63 -0
  193. package/components/data/data.prompt.md +3 -3
  194. package/components/display/Avatar.vue +3 -2
  195. package/components/display/AvatarGroup.vue +3 -2
  196. package/components/display/Badge.vue +1 -1
  197. package/components/display/Divider.vue +3 -3
  198. package/components/display/Donut.vue +3 -2
  199. package/components/display/IconTile.vue +2 -1
  200. package/components/display/Kbd.vue +1 -1
  201. package/components/display/ProgressBar.jsx +1 -1
  202. package/components/display/ProgressBar.vue +1 -1
  203. package/components/display/StatCard.vue +1 -1
  204. package/components/display/Tag.d.ts +3 -1
  205. package/components/display/Tag.jsx +4 -4
  206. package/components/display/Tag.vue +4 -4
  207. package/components/feedback/Accordion.jsx +2 -2
  208. package/components/feedback/Accordion.vue +2 -2
  209. package/components/feedback/ActivityItem.d.ts +3 -1
  210. package/components/feedback/ActivityItem.jsx +5 -5
  211. package/components/feedback/ActivityItem.vue +5 -4
  212. package/components/feedback/Alert.jsx +4 -4
  213. package/components/feedback/Alert.vue +3 -3
  214. package/components/feedback/Banner.jsx +5 -5
  215. package/components/feedback/Banner.vue +5 -5
  216. package/components/feedback/ContextMenu.d.ts +3 -1
  217. package/components/feedback/ContextMenu.jsx +5 -5
  218. package/components/feedback/ContextMenu.vue +5 -5
  219. package/components/feedback/DotActivity.vue +3 -3
  220. package/components/feedback/Drawer.d.ts +2 -0
  221. package/components/feedback/Drawer.jsx +6 -6
  222. package/components/feedback/Drawer.vue +22 -15
  223. package/components/feedback/EmptyState.vue +2 -2
  224. package/components/feedback/LogViewer.vue +1 -1
  225. package/components/feedback/Modal.d.ts +2 -0
  226. package/components/feedback/Modal.jsx +12 -11
  227. package/components/feedback/Modal.vue +10 -8
  228. package/components/feedback/Skeleton.vue +2 -1
  229. package/components/feedback/Spinner.vue +2 -1
  230. package/components/feedback/Stepper.vue +1 -1
  231. package/components/feedback/Timeline.jsx +1 -1
  232. package/components/feedback/Timeline.vue +1 -1
  233. package/components/feedback/Toast.vue +4 -4
  234. package/components/feedback/ToastStack.vue +11 -0
  235. package/components/feedback/Tooltip.vue +19 -0
  236. package/components/feedback/feedback.prompt.md +4 -4
  237. package/components/forms/Checkbox.d.ts +3 -2
  238. package/components/forms/Checkbox.jsx +7 -7
  239. package/components/forms/Checkbox.vue +8 -8
  240. package/components/forms/Combobox.d.ts +2 -0
  241. package/components/forms/Combobox.jsx +12 -10
  242. package/components/forms/Combobox.vue +11 -10
  243. package/components/forms/DatePicker.d.ts +4 -0
  244. package/components/forms/DatePicker.jsx +16 -12
  245. package/components/forms/DatePicker.vue +15 -11
  246. package/components/forms/Dropzone.jsx +2 -2
  247. package/components/forms/Dropzone.vue +5 -5
  248. package/components/forms/Field.d.ts +5 -1
  249. package/components/forms/Field.jsx +4 -4
  250. package/components/forms/Field.vue +4 -4
  251. package/components/forms/Input.d.ts +5 -1
  252. package/components/forms/Input.jsx +7 -7
  253. package/components/forms/Input.vue +3 -3
  254. package/components/forms/MultiSelect.d.ts +2 -0
  255. package/components/forms/MultiSelect.jsx +13 -11
  256. package/components/forms/MultiSelect.vue +12 -11
  257. package/components/forms/NumberStepper.d.ts +3 -1
  258. package/components/forms/NumberStepper.jsx +7 -7
  259. package/components/forms/NumberStepper.vue +8 -7
  260. package/components/forms/Radio.d.ts +5 -3
  261. package/components/forms/Radio.jsx +13 -15
  262. package/components/forms/Radio.vue +9 -10
  263. package/components/forms/RadioGroup.vue +5 -5
  264. package/components/forms/SearchInput.d.ts +3 -1
  265. package/components/forms/SearchInput.jsx +6 -6
  266. package/components/forms/SearchInput.vue +7 -6
  267. package/components/forms/Select.d.ts +3 -2
  268. package/components/forms/Select.jsx +6 -7
  269. package/components/forms/Select.vue +6 -6
  270. package/components/forms/Slider.jsx +3 -3
  271. package/components/forms/Slider.vue +3 -3
  272. package/components/forms/Switch.d.ts +2 -2
  273. package/components/forms/Switch.jsx +20 -22
  274. package/components/forms/Switch.vue +15 -14
  275. package/components/forms/Textarea.vue +4 -4
  276. package/components/forms/forms.prompt.md +1 -1
  277. package/components/forms/input-base.js +2 -1
  278. package/components/index.d.ts +1 -2
  279. package/components/index.js +3 -4
  280. package/components/navigation/Breadcrumb.jsx +3 -3
  281. package/components/navigation/Breadcrumb.vue +4 -4
  282. package/components/navigation/DocTree.jsx +3 -3
  283. package/components/navigation/DocTree.vue +3 -3
  284. package/components/navigation/PageHeading.vue +1 -1
  285. package/components/navigation/PageToolbar.vue +7 -6
  286. package/components/navigation/Sidebar.jsx +1 -1
  287. package/components/navigation/Sidebar.vue +3 -3
  288. package/components/navigation/ThemeToggle.vue +2 -1
  289. package/components/navigation/TopBar.d.ts +3 -1
  290. package/components/navigation/TopBar.jsx +6 -6
  291. package/components/navigation/Tree.jsx +5 -5
  292. package/components/navigation/Tree.vue +5 -5
  293. package/components/pipeline/ConfigPanel.d.ts +2 -0
  294. package/components/pipeline/ConfigPanel.jsx +9 -9
  295. package/components/pipeline/ConfigPanel.vue +9 -9
  296. package/components/pipeline/DataPreview.d.ts +3 -1
  297. package/components/pipeline/DataPreview.jsx +7 -7
  298. package/components/pipeline/DataPreview.vue +7 -7
  299. package/components/pipeline/NodeCard.jsx +3 -3
  300. package/components/pipeline/NodeCard.vue +3 -3
  301. package/components/pipeline/PaletteItem.vue +2 -2
  302. package/components/pipeline/PaletteListItem.vue +1 -1
  303. package/components/pipeline/PalettePanel.jsx +2 -2
  304. package/components/pipeline/PalettePanel.vue +1 -1
  305. package/components/pipeline/Port.vue +15 -0
  306. package/components/pipeline/PortLabel.vue +15 -0
  307. package/components/pipeline/ZoomControls.vue +1 -1
  308. package/components/pipeline/port-skin.js +13 -0
  309. package/components/px.js +4 -0
  310. package/components/tabs/PanelTabs.vue +5 -4
  311. package/components/tabs/PillTabs.vue +5 -4
  312. package/components/tabs/SegmentedControl.d.ts +2 -2
  313. package/components/tabs/SegmentedControl.jsx +7 -7
  314. package/components/tabs/SegmentedControl.vue +7 -7
  315. package/components/tabs/Tabs.d.ts +5 -3
  316. package/components/tabs/Tabs.jsx +15 -15
  317. package/components/tabs/Tabs.vue +5 -5
  318. package/components/tabs/ViewToggle.d.ts +3 -1
  319. package/components/tabs/ViewToggle.jsx +5 -5
  320. package/components/tabs/ViewToggle.vue +5 -5
  321. package/components/tabs/tabs.prompt.md +1 -1
  322. package/keybricks.css +4 -0
  323. package/package.json +6 -3
  324. package/readme.md +90 -122
  325. package/readme.zh-CN.md +120 -0
  326. package/tokens/charts.css +20 -17
  327. package/tokens/colors.css +2 -2
  328. package/tokens/dark.css +2 -2
  329. package/tokens/hover.css +32 -0
  330. package/tokens/interaction.css +3 -1
  331. package/tokens/layout.css +29 -7
  332. package/tokens/tokens.d.ts +36 -0
  333. package/tokens/tokens.js +143 -89
  334. package/tokens/tokens.json +240 -106
  335. package/tokens/typography.css +27 -14
  336. package/components/_cards/brand-visual.card.html +0 -43
  337. package/components/_cards/datatable.card.html +0 -48
  338. package/components/_shared/src-brand.js +0 -1
  339. package/components/brand/BrandVisual.d.ts +0 -17
  340. package/components/brand/BrandVisual.jsx +0 -29
  341. package/components/brand/BrandVisual.vue +0 -34
  342. package/components/brand/_dir.card.html +0 -13
  343. package/components/brand/brandMotifs.js +0 -210
  344. package/components/buttons/_dir.card.html +0 -13
  345. package/components/charts/ChartKit.vue +0 -47
  346. package/components/charts/_dir.card.html +0 -7
  347. package/components/data/DataTable.d.ts +0 -28
  348. package/components/data/DataTable.jsx +0 -32
  349. package/components/data/DataTable.vue +0 -25
  350. package/components/data/_dir.card.html +0 -13
  351. package/components/display/_dir.card.html +0 -13
  352. package/components/feedback/_dir.card.html +0 -13
  353. package/components/forms/_dir.card.html +0 -13
  354. package/components/icons/_dir.card.html +0 -13
  355. package/components/navigation/_dir.card.html +0 -13
  356. package/components/pipeline/_dir.card.html +0 -13
  357. package/components/tabs/_dir.card.html +0 -13
@@ -1,22 +1,35 @@
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
6
  --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 */
7
+ /* size / line-height / letter-spacing triples — always set all three together */
8
+ --text-2xs:11px;--leading-2xs:16px;--tracking-2xs:.064px; /* chart tick labels only — nothing in the system is smaller */
9
+ --text-xs:12px;--leading-xs:16px;--tracking-xs:0; /* captions, helper text, badges, tags, meta; sm-tier control text */
10
+ --text-sm:12px;--leading-sm:16px;--tracking-sm:0; /* alias of --text-xs kept for compatibility — prefer --text-xs */
11
+ --text-base:14px;--leading-base:20px;--tracking-base:-.15px; /* body, md/lg controls, labels, table cells */
12
+ --text-md:16px;--leading-md:24px;--tracking-md:-.28px; /* section headings, panel / card / dialog titles */
13
+ --text-lg:20px;--leading-lg:28px;--tracking-lg:-.449px; /* page titles */
14
+ --text-xl:24px;--leading-xl:32px;--tracking-xl:-.54px; /* greeting heading, page hero */
13
15
  --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 */
16
+ /* Extended display scale — same size→tracking curve, continued */
17
+ --text-2xl:30px;--leading-2xl:38px;--tracking-2xl:-.67px; /* modal / report hero headings */
18
+ --text-3xl:38px;--leading-3xl:46px;--tracking-3xl:-.855px; /* marketing headings, site hero */
19
+ --text-4xl:48px;--leading-4xl:56px;--tracking-4xl:-1.08px; /* dashboard hero numbers */
20
+ --text-display:60px;--leading-display:68px;--tracking-display:-1.35px; /* slides, covers */
19
21
  --weight-light:300;--weight-regular:400;--weight-medium:500;--weight-semibold:600;
20
22
  }
23
+ /* Chinese, Japanese and Korean. Han, kana and Hangul have no capitals and no italics, so emphasis is
24
+ weight — and Microsoft YaHei, Meiryo, Yu Gothic UI and Malgun Gothic ship no 500 face, which turns
25
+ weight 500 into Regular on Windows. In these languages the medium weight is therefore 600 (a real
26
+ Semibold/Bold in every system CJK font) and Latin tracking is switched off. Set lang on <html> or on
27
+ the region; every Keybricks component re-reads --font-sans so a per-region switch works too. */
28
+ [lang|="zh"]{--font-sans:'Inter','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Noto Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
29
+ [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}
30
+ [lang|="ko"]{--font-sans:'Inter','Apple SD Gothic Neo','Malgun Gothic','Noto Sans KR',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
31
+ :lang(zh),:lang(ja),:lang(ko){font-family:var(--font-sans)}
32
+ [lang|="zh"],[lang|="ja"],[lang|="ko"]{--weight-medium:600;
33
+ --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}
21
34
  body{font-family:var(--font-sans);color:var(--text-primary);-webkit-font-smoothing:antialiased}
22
35
  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>
@@ -1,28 +0,0 @@
1
- import * as React from "react";
2
- /**
3
- * Hairline data table — #fafafa header, #f5f5f5 row separators.
4
- * @startingPoint section="Data" subtitle="Comparison / preview tables with mono cells" viewport="700x300"
5
- */
6
- export interface DataTableColumn {
7
- key: string;
8
- label: string;
9
- width?: number | string;
10
- /** Menlo 11px cell (config codes, values) */
11
- mono?: boolean;
12
- align?: "left" | "right" | "center";
13
- render?: (value: any, row: any, index: number) => React.ReactNode;
14
- }
15
- export interface DataTableProps {
16
- columns?: DataTableColumn[];
17
- rows?: Record<string, any>[];
18
- /** 29px rows + lowercase 11px headers (data-preview drawer) */
19
- dense?: boolean;
20
- /** Leading checkbox column */
21
- selectable?: boolean;
22
- selected?: number[];
23
- /** onToggle("all"|rowIndex, checked) */
24
- onToggle?: (which: number | "all", checked: boolean) => void;
25
- headerBorder?: boolean;
26
- style?: React.CSSProperties;
27
- }
28
- export declare function DataTable(props: DataTableProps): JSX.Element;