@keyfunc/keybricks-ds 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/DEPLOY.md +204 -0
  2. package/DESIGN.md +269 -0
  3. package/INTEGRATION.md +417 -0
  4. package/SKILL.md +32 -0
  5. package/_adherence.oxlintrc.json +1469 -0
  6. package/_scripts/build-index.mjs +80 -0
  7. package/_scripts/build-tokens.mjs +135 -0
  8. package/assets/icons/icon-index.js +1 -0
  9. package/assets/icons/icon-index.json +1 -0
  10. package/assets/icons/unicons-index.js +1 -0
  11. package/assets/icons/unicons-index.json +1 -0
  12. package/assets/keybricks-logo.png +0 -0
  13. package/components/_cards/accordion.card.html +32 -0
  14. package/components/_cards/action-chip.card.html +22 -0
  15. package/components/_cards/activity.card.html +34 -0
  16. package/components/_cards/alert.card.html +32 -0
  17. package/components/_cards/app-chrome.card.html +36 -0
  18. package/components/_cards/banner.card.html +21 -0
  19. package/components/_cards/brand-visual.card.html +43 -0
  20. package/components/_cards/breadcrumb.card.html +23 -0
  21. package/components/_cards/button-1-base.card.html +39 -0
  22. package/components/_cards/button-2-states.card.html +56 -0
  23. package/components/_cards/button-3-sizes-icons.card.html +32 -0
  24. package/components/_cards/button-4-group.card.html +47 -0
  25. package/components/_cards/canvas-zoom-controls.card.html +19 -0
  26. package/components/_cards/cards-indicators.card.html +59 -0
  27. package/components/_cards/charts-1-sparkline.card.html +55 -0
  28. package/components/_cards/charts-10-gauge.card.html +31 -0
  29. package/components/_cards/charts-11-funnel.card.html +28 -0
  30. package/components/_cards/charts-12-treemap.card.html +23 -0
  31. package/components/_cards/charts-14-radar.card.html +31 -0
  32. package/components/_cards/charts-15-distribution.card.html +32 -0
  33. package/components/_cards/charts-16-pareto.card.html +25 -0
  34. package/components/_cards/charts-17-candlestick.card.html +34 -0
  35. package/components/_cards/charts-18-sankey.card.html +29 -0
  36. package/components/_cards/charts-19-chord.card.html +31 -0
  37. package/components/_cards/charts-2-line.card.html +46 -0
  38. package/components/_cards/charts-20-sunburst.card.html +38 -0
  39. package/components/_cards/charts-21-worldmap.card.html +33 -0
  40. package/components/_cards/charts-22-gantt.card.html +37 -0
  41. package/components/_cards/charts-23-bar3d.card.html +26 -0
  42. package/components/_cards/charts-24-pie3d.card.html +32 -0
  43. package/components/_cards/charts-25-surface3d.card.html +24 -0
  44. package/components/_cards/charts-26-scatter3d.card.html +24 -0
  45. package/components/_cards/charts-27-ribbon3d.card.html +23 -0
  46. package/components/_cards/charts-3-bar.card.html +71 -0
  47. package/components/_cards/charts-4-barlist.card.html +30 -0
  48. package/components/_cards/charts-5-donut.card.html +35 -0
  49. package/components/_cards/charts-6-scatter.card.html +26 -0
  50. package/components/_cards/charts-7-heatmap.card.html +28 -0
  51. package/components/_cards/charts-8-waterfall.card.html +25 -0
  52. package/components/_cards/charts-9-bullet.card.html +31 -0
  53. package/components/_cards/charts-99-fullpage.card.html +194 -0
  54. package/components/_cards/checkbox.card.html +34 -0
  55. package/components/_cards/codeblock.card.html +19 -0
  56. package/components/_cards/combobox.card.html +25 -0
  57. package/components/_cards/context-menu.card.html +21 -0
  58. package/components/_cards/datatable.card.html +48 -0
  59. package/components/_cards/date-picker.card.html +31 -0
  60. package/components/_cards/diffvalue.card.html +21 -0
  61. package/components/_cards/divider.card.html +24 -0
  62. package/components/_cards/drawer.card.html +30 -0
  63. package/components/_cards/dropdown-menu.card.html +38 -0
  64. package/components/_cards/dropzone.card.html +22 -0
  65. package/components/_cards/empty-state.card.html +29 -0
  66. package/components/_cards/filter-bar.card.html +34 -0
  67. package/components/_cards/icon-button.card.html +27 -0
  68. package/components/_cards/icons-1-core.card.html +49 -0
  69. package/components/_cards/icons-2-feather.card.html +39 -0
  70. package/components/_cards/icons-3-unicons.card.html +44 -0
  71. package/components/_cards/input.card.html +25 -0
  72. package/components/_cards/kbd.card.html +20 -0
  73. package/components/_cards/keyvalue.card.html +23 -0
  74. package/components/_cards/listrow.card.html +30 -0
  75. package/components/_cards/loading.card.html +33 -0
  76. package/components/_cards/log-viewer.card.html +23 -0
  77. package/components/_cards/modal.card.html +35 -0
  78. package/components/_cards/multi-select.card.html +26 -0
  79. package/components/_cards/number-stepper.card.html +24 -0
  80. package/components/_cards/pagination.card.html +25 -0
  81. package/components/_cards/people.card.html +46 -0
  82. package/components/_cards/pipeline-node.card.html +76 -0
  83. package/components/_cards/pipeline-palette.card.html +54 -0
  84. package/components/_cards/search.card.html +23 -0
  85. package/components/_cards/select.card.html +23 -0
  86. package/components/_cards/slider.card.html +25 -0
  87. package/components/_cards/smart-table.card.html +37 -0
  88. package/components/_cards/spreadsheet.card.html +31 -0
  89. package/components/_cards/stepper.card.html +25 -0
  90. package/components/_cards/tabs.card.html +25 -0
  91. package/components/_cards/tag.card.html +26 -0
  92. package/components/_cards/textarea.card.html +27 -0
  93. package/components/_cards/timeline.card.html +32 -0
  94. package/components/_cards/toast.card.html +33 -0
  95. package/components/_cards/toggles.card.html +68 -0
  96. package/components/_cards/tooltip.card.html +22 -0
  97. package/components/_cards/tree.card.html +150 -0
  98. package/components/_shared/frame-theme.js +16 -0
  99. package/components/_shared/src-brand.js +1 -0
  100. package/components/_shared/src-buttons.js +1 -0
  101. package/components/_shared/src-charts.js +1 -0
  102. package/components/_shared/src-data.js +1 -0
  103. package/components/_shared/src-display.js +1 -0
  104. package/components/_shared/src-feedback.js +1 -0
  105. package/components/_shared/src-forms.js +1 -0
  106. package/components/_shared/src-icons.js +1 -0
  107. package/components/_shared/src-navigation.js +1 -0
  108. package/components/_shared/src-pipeline.js +1 -0
  109. package/components/_shared/src-tabs.js +1 -0
  110. package/components/_shared/svg-download.js +19 -0
  111. package/components/_shared/view-source.js +185 -0
  112. package/components/_vue/index.mjs +114 -0
  113. package/components/brand/BrandVisual.d.ts +17 -0
  114. package/components/brand/BrandVisual.jsx +29 -0
  115. package/components/brand/BrandVisual.vue +34 -0
  116. package/components/brand/_dir.card.html +13 -0
  117. package/components/brand/brandMotifs.js +210 -0
  118. package/components/buttons/ActionChip.d.ts +10 -0
  119. package/components/buttons/ActionChip.jsx +20 -0
  120. package/components/buttons/ActionChip.vue +18 -0
  121. package/components/buttons/Button.d.ts +40 -0
  122. package/components/buttons/Button.jsx +101 -0
  123. package/components/buttons/Button.vue +87 -0
  124. package/components/buttons/IconButton.d.ts +26 -0
  125. package/components/buttons/IconButton.jsx +28 -0
  126. package/components/buttons/IconButton.vue +21 -0
  127. package/components/buttons/_dir.card.html +13 -0
  128. package/components/buttons/buttons.prompt.md +19 -0
  129. package/components/charts/Bar3D.d.ts +15 -0
  130. package/components/charts/Bar3D.jsx +93 -0
  131. package/components/charts/Bar3D.vue +79 -0
  132. package/components/charts/BarChart.d.ts +23 -0
  133. package/components/charts/BarChart.jsx +135 -0
  134. package/components/charts/BarChart.vue +139 -0
  135. package/components/charts/BarList.d.ts +13 -0
  136. package/components/charts/BarList.jsx +31 -0
  137. package/components/charts/BarList.vue +25 -0
  138. package/components/charts/BoxPlot.d.ts +18 -0
  139. package/components/charts/BoxPlot.jsx +62 -0
  140. package/components/charts/BoxPlot.vue +58 -0
  141. package/components/charts/BulletChart.d.ts +12 -0
  142. package/components/charts/BulletChart.jsx +41 -0
  143. package/components/charts/BulletChart.vue +33 -0
  144. package/components/charts/CandlestickChart.d.ts +15 -0
  145. package/components/charts/CandlestickChart.jsx +63 -0
  146. package/components/charts/CandlestickChart.vue +62 -0
  147. package/components/charts/ChartKit.d.ts +8 -0
  148. package/components/charts/ChartKit.jsx +76 -0
  149. package/components/charts/ChartKit.vue +47 -0
  150. package/components/charts/ChordChart.d.ts +13 -0
  151. package/components/charts/ChordChart.jsx +55 -0
  152. package/components/charts/ChordChart.vue +54 -0
  153. package/components/charts/DonutChart.d.ts +15 -0
  154. package/components/charts/DonutChart.jsx +73 -0
  155. package/components/charts/DonutChart.vue +61 -0
  156. package/components/charts/FunnelChart.d.ts +11 -0
  157. package/components/charts/FunnelChart.jsx +37 -0
  158. package/components/charts/FunnelChart.vue +29 -0
  159. package/components/charts/GanttChart.d.ts +20 -0
  160. package/components/charts/GanttChart.jsx +80 -0
  161. package/components/charts/GanttChart.vue +60 -0
  162. package/components/charts/GaugeChart.d.ts +13 -0
  163. package/components/charts/GaugeChart.jsx +33 -0
  164. package/components/charts/GaugeChart.vue +29 -0
  165. package/components/charts/HeatmapChart.d.ts +13 -0
  166. package/components/charts/HeatmapChart.jsx +62 -0
  167. package/components/charts/HeatmapChart.vue +38 -0
  168. package/components/charts/Histogram.d.ts +16 -0
  169. package/components/charts/Histogram.jsx +56 -0
  170. package/components/charts/Histogram.vue +53 -0
  171. package/components/charts/LineChart.d.ts +17 -0
  172. package/components/charts/LineChart.jsx +84 -0
  173. package/components/charts/LineChart.vue +86 -0
  174. package/components/charts/ParetoChart.d.ts +13 -0
  175. package/components/charts/ParetoChart.jsx +54 -0
  176. package/components/charts/ParetoChart.vue +55 -0
  177. package/components/charts/Pie3D.d.ts +17 -0
  178. package/components/charts/Pie3D.jsx +145 -0
  179. package/components/charts/Pie3D.vue +115 -0
  180. package/components/charts/RadarChart.d.ts +14 -0
  181. package/components/charts/RadarChart.jsx +79 -0
  182. package/components/charts/RadarChart.vue +73 -0
  183. package/components/charts/Ribbon3D.d.ts +13 -0
  184. package/components/charts/Ribbon3D.jsx +89 -0
  185. package/components/charts/Ribbon3D.vue +79 -0
  186. package/components/charts/SankeyChart.d.ts +15 -0
  187. package/components/charts/SankeyChart.jsx +59 -0
  188. package/components/charts/SankeyChart.vue +53 -0
  189. package/components/charts/Scatter3D.d.ts +12 -0
  190. package/components/charts/Scatter3D.jsx +69 -0
  191. package/components/charts/Scatter3D.vue +59 -0
  192. package/components/charts/ScatterChart.d.ts +12 -0
  193. package/components/charts/ScatterChart.jsx +53 -0
  194. package/components/charts/ScatterChart.vue +57 -0
  195. package/components/charts/Sparkline.d.ts +19 -0
  196. package/components/charts/Sparkline.jsx +63 -0
  197. package/components/charts/Sparkline.vue +54 -0
  198. package/components/charts/SunburstChart.d.ts +12 -0
  199. package/components/charts/SunburstChart.jsx +61 -0
  200. package/components/charts/SunburstChart.vue +60 -0
  201. package/components/charts/Surface3D.d.ts +13 -0
  202. package/components/charts/Surface3D.jsx +70 -0
  203. package/components/charts/Surface3D.vue +63 -0
  204. package/components/charts/TreemapChart.d.ts +11 -0
  205. package/components/charts/TreemapChart.jsx +35 -0
  206. package/components/charts/TreemapChart.vue +27 -0
  207. package/components/charts/WaterfallChart.d.ts +11 -0
  208. package/components/charts/WaterfallChart.jsx +59 -0
  209. package/components/charts/WaterfallChart.vue +46 -0
  210. package/components/charts/WorldMap.d.ts +21 -0
  211. package/components/charts/WorldMap.jsx +107 -0
  212. package/components/charts/WorldMap.vue +73 -0
  213. package/components/charts/_dir.card.html +7 -0
  214. package/components/charts/chart-3d.js +84 -0
  215. package/components/charts/chart-geometry.js +223 -0
  216. package/components/charts/charts.prompt.md +24 -0
  217. package/components/data/CodeBlock.d.ts +9 -0
  218. package/components/data/CodeBlock.jsx +19 -0
  219. package/components/data/CodeBlock.vue +22 -0
  220. package/components/data/DataTable.d.ts +28 -0
  221. package/components/data/DataTable.jsx +32 -0
  222. package/components/data/DataTable.vue +25 -0
  223. package/components/data/DiffValue.d.ts +11 -0
  224. package/components/data/DiffValue.jsx +15 -0
  225. package/components/data/DiffValue.vue +13 -0
  226. package/components/data/FilterBar.d.ts +16 -0
  227. package/components/data/FilterBar.jsx +22 -0
  228. package/components/data/FilterBar.vue +23 -0
  229. package/components/data/KeyValue.d.ts +16 -0
  230. package/components/data/KeyValue.jsx +25 -0
  231. package/components/data/KeyValue.vue +26 -0
  232. package/components/data/ListRow.d.ts +14 -0
  233. package/components/data/ListRow.jsx +25 -0
  234. package/components/data/ListRow.vue +25 -0
  235. package/components/data/Pagination.d.ts +12 -0
  236. package/components/data/Pagination.jsx +27 -0
  237. package/components/data/Pagination.vue +24 -0
  238. package/components/data/SmartTable.d.ts +30 -0
  239. package/components/data/SmartTable.jsx +73 -0
  240. package/components/data/SmartTable.vue +74 -0
  241. package/components/data/Spreadsheet.d.ts +33 -0
  242. package/components/data/Spreadsheet.jsx +110 -0
  243. package/components/data/Spreadsheet.vue +95 -0
  244. package/components/data/_dir.card.html +13 -0
  245. package/components/data/data.prompt.md +33 -0
  246. package/components/display/Avatar.d.ts +21 -0
  247. package/components/display/Avatar.jsx +31 -0
  248. package/components/display/Avatar.vue +34 -0
  249. package/components/display/Badge.d.ts +27 -0
  250. package/components/display/Badge.jsx +40 -0
  251. package/components/display/Badge.vue +47 -0
  252. package/components/display/Card.d.ts +27 -0
  253. package/components/display/Card.jsx +27 -0
  254. package/components/display/Card.vue +28 -0
  255. package/components/display/Divider.d.ts +8 -0
  256. package/components/display/Divider.jsx +14 -0
  257. package/components/display/Divider.vue +13 -0
  258. package/components/display/Kbd.d.ts +7 -0
  259. package/components/display/Kbd.jsx +12 -0
  260. package/components/display/Kbd.vue +9 -0
  261. package/components/display/ProgressBar.d.ts +42 -0
  262. package/components/display/ProgressBar.jsx +70 -0
  263. package/components/display/ProgressBar.vue +69 -0
  264. package/components/display/Tag.d.ts +9 -0
  265. package/components/display/Tag.jsx +15 -0
  266. package/components/display/Tag.vue +15 -0
  267. package/components/display/_dir.card.html +13 -0
  268. package/components/display/display.prompt.md +30 -0
  269. package/components/feedback/Accordion.d.ts +13 -0
  270. package/components/feedback/Accordion.jsx +21 -0
  271. package/components/feedback/Accordion.vue +22 -0
  272. package/components/feedback/ActivityItem.d.ts +25 -0
  273. package/components/feedback/ActivityItem.jsx +39 -0
  274. package/components/feedback/ActivityItem.vue +46 -0
  275. package/components/feedback/Alert.d.ts +36 -0
  276. package/components/feedback/Alert.jsx +48 -0
  277. package/components/feedback/Alert.vue +59 -0
  278. package/components/feedback/Banner.d.ts +15 -0
  279. package/components/feedback/Banner.jsx +25 -0
  280. package/components/feedback/Banner.vue +25 -0
  281. package/components/feedback/ContextMenu.d.ts +8 -0
  282. package/components/feedback/ContextMenu.jsx +18 -0
  283. package/components/feedback/ContextMenu.vue +19 -0
  284. package/components/feedback/Drawer.d.ts +18 -0
  285. package/components/feedback/Drawer.jsx +26 -0
  286. package/components/feedback/Drawer.vue +24 -0
  287. package/components/feedback/Menu.d.ts +10 -0
  288. package/components/feedback/Menu.jsx +24 -0
  289. package/components/feedback/Menu.vue +21 -0
  290. package/components/feedback/Modal.d.ts +38 -0
  291. package/components/feedback/Modal.jsx +69 -0
  292. package/components/feedback/Modal.vue +65 -0
  293. package/components/feedback/Stepper.d.ts +9 -0
  294. package/components/feedback/Stepper.jsx +24 -0
  295. package/components/feedback/Stepper.vue +18 -0
  296. package/components/feedback/Timeline.d.ts +15 -0
  297. package/components/feedback/Timeline.jsx +27 -0
  298. package/components/feedback/Timeline.vue +21 -0
  299. package/components/feedback/_dir.card.html +13 -0
  300. package/components/feedback/feedback.prompt.md +35 -0
  301. package/components/forms/Checkbox.d.ts +13 -0
  302. package/components/forms/Checkbox.jsx +17 -0
  303. package/components/forms/Checkbox.vue +18 -0
  304. package/components/forms/Combobox.d.ts +13 -0
  305. package/components/forms/Combobox.jsx +34 -0
  306. package/components/forms/Combobox.vue +35 -0
  307. package/components/forms/DatePicker.d.ts +12 -0
  308. package/components/forms/DatePicker.jsx +48 -0
  309. package/components/forms/DatePicker.vue +46 -0
  310. package/components/forms/Dropzone.d.ts +20 -0
  311. package/components/forms/Dropzone.jsx +36 -0
  312. package/components/forms/Dropzone.vue +28 -0
  313. package/components/forms/Field.d.ts +13 -0
  314. package/components/forms/Field.jsx +13 -0
  315. package/components/forms/Field.vue +12 -0
  316. package/components/forms/Input.d.ts +18 -0
  317. package/components/forms/Input.jsx +35 -0
  318. package/components/forms/Input.vue +38 -0
  319. package/components/forms/MultiSelect.d.ts +14 -0
  320. package/components/forms/MultiSelect.jsx +33 -0
  321. package/components/forms/MultiSelect.vue +36 -0
  322. package/components/forms/NumberStepper.d.ts +13 -0
  323. package/components/forms/NumberStepper.jsx +15 -0
  324. package/components/forms/NumberStepper.vue +17 -0
  325. package/components/forms/Radio.vue +16 -0
  326. package/components/forms/RadioGroup.vue +11 -0
  327. package/components/forms/SearchInput.d.ts +12 -0
  328. package/components/forms/SearchInput.jsx +17 -0
  329. package/components/forms/SearchInput.vue +14 -0
  330. package/components/forms/Select.d.ts +14 -0
  331. package/components/forms/Select.jsx +17 -0
  332. package/components/forms/Select.vue +16 -0
  333. package/components/forms/Slider.d.ts +15 -0
  334. package/components/forms/Slider.jsx +21 -0
  335. package/components/forms/Slider.vue +23 -0
  336. package/components/forms/Switch.d.ts +31 -0
  337. package/components/forms/Switch.jsx +40 -0
  338. package/components/forms/Switch.vue +16 -0
  339. package/components/forms/_dir.card.html +13 -0
  340. package/components/forms/forms.prompt.md +23 -0
  341. package/components/icons/Icon.d.ts +19 -0
  342. package/components/icons/Icon.jsx +93 -0
  343. package/components/icons/Icon.prompt.md +8 -0
  344. package/components/icons/Icon.vue +12 -0
  345. package/components/icons/Unicon.d.ts +12 -0
  346. package/components/icons/Unicon.jsx +16 -0
  347. package/components/icons/Unicon.vue +15 -0
  348. package/components/icons/_dir.card.html +13 -0
  349. package/components/icons/feather-paths.js +2 -0
  350. package/components/icons/icon-paths.js +73 -0
  351. package/components/index.d.ts +87 -0
  352. package/components/index.js +110 -0
  353. package/components/navigation/Breadcrumb.d.ts +24 -0
  354. package/components/navigation/Breadcrumb.jsx +120 -0
  355. package/components/navigation/Breadcrumb.vue +94 -0
  356. package/components/navigation/DocTree.d.ts +18 -0
  357. package/components/navigation/DocTree.jsx +37 -0
  358. package/components/navigation/DocTree.vue +25 -0
  359. package/components/navigation/Sidebar.d.ts +29 -0
  360. package/components/navigation/Sidebar.jsx +75 -0
  361. package/components/navigation/Sidebar.vue +54 -0
  362. package/components/navigation/TopBar.d.ts +27 -0
  363. package/components/navigation/TopBar.jsx +44 -0
  364. package/components/navigation/TopBar.vue +51 -0
  365. package/components/navigation/Tree.d.ts +83 -0
  366. package/components/navigation/Tree.jsx +347 -0
  367. package/components/navigation/Tree.vue +258 -0
  368. package/components/navigation/_dir.card.html +13 -0
  369. package/components/navigation/navigation.prompt.md +22 -0
  370. package/components/pipeline/ConfigPanel.d.ts +18 -0
  371. package/components/pipeline/ConfigPanel.jsx +30 -0
  372. package/components/pipeline/ConfigPanel.vue +32 -0
  373. package/components/pipeline/DataPreview.d.ts +14 -0
  374. package/components/pipeline/DataPreview.jsx +24 -0
  375. package/components/pipeline/DataPreview.vue +21 -0
  376. package/components/pipeline/NodeCard.d.ts +47 -0
  377. package/components/pipeline/NodeCard.jsx +97 -0
  378. package/components/pipeline/NodeCard.vue +75 -0
  379. package/components/pipeline/PaletteItem.vue +15 -0
  380. package/components/pipeline/PaletteListItem.vue +15 -0
  381. package/components/pipeline/PalettePanel.d.ts +20 -0
  382. package/components/pipeline/PalettePanel.jsx +74 -0
  383. package/components/pipeline/PalettePanel.vue +45 -0
  384. package/components/pipeline/PipelineCanvas.d.ts +25 -0
  385. package/components/pipeline/PipelineCanvas.jsx +94 -0
  386. package/components/pipeline/PipelineCanvas.vue +73 -0
  387. package/components/pipeline/ZoomControls.d.ts +9 -0
  388. package/components/pipeline/ZoomControls.jsx +15 -0
  389. package/components/pipeline/ZoomControls.vue +15 -0
  390. package/components/pipeline/_dir.card.html +13 -0
  391. package/components/pipeline/pipeline.prompt.md +22 -0
  392. package/components/tabs/SegmentedControl.d.ts +11 -0
  393. package/components/tabs/SegmentedControl.jsx +21 -0
  394. package/components/tabs/SegmentedControl.vue +15 -0
  395. package/components/tabs/Tabs.d.ts +13 -0
  396. package/components/tabs/Tabs.jsx +52 -0
  397. package/components/tabs/Tabs.vue +39 -0
  398. package/components/tabs/ViewToggle.d.ts +8 -0
  399. package/components/tabs/ViewToggle.jsx +12 -0
  400. package/components/tabs/ViewToggle.vue +12 -0
  401. package/components/tabs/_dir.card.html +13 -0
  402. package/components/tabs/tabs.prompt.md +14 -0
  403. package/package.json +76 -0
  404. package/readme.md +150 -0
  405. package/styles.css +10 -0
  406. package/tokens/alpha.css +27 -0
  407. package/tokens/charts.css +55 -0
  408. package/tokens/colors-extended.css +40 -0
  409. package/tokens/colors.css +39 -0
  410. package/tokens/dark.css +96 -0
  411. package/tokens/fonts.css +4 -0
  412. package/tokens/interaction.css +48 -0
  413. package/tokens/layout.css +30 -0
  414. package/tokens/motion.css +22 -0
  415. package/tokens/tokens.d.ts +680 -0
  416. package/tokens/tokens.js +1018 -0
  417. package/tokens/tokens.json +2928 -0
  418. package/tokens/typography.css +22 -0
@@ -0,0 +1,32 @@
1
+ <!-- @dsCard group="Charts" viewport="700x760" name="3D Pie & Donut" subtitle="Extruded and stepped-stairs slices — drag spins in place, hover lifts a slice" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { Pie3D } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="row sec">
16
+ <div><span className="lbl">Stairs pie — each slice extrudes by its value</span>
17
+ <Pie3D size={270} stairs segments={[{label:"Licences",value:42},{label:"Services",value:26},{label:"Support",value:18},{label:"Other",value:9}]}/></div>
18
+ <div><span className="lbl">Stairs donut</span>
19
+ <Pie3D size={270} stairs innerRatio={0.5} segments={[{label:"EMEA",value:35},{label:"AMER",value:25},{label:"APAC",value:22},{label:"LATAM",value:12}]}/></div>
20
+ </div>
21
+ <div className="row sec">
22
+ <div><span className="lbl">Flat extrusion — one thickness</span>
23
+ <Pie3D size={250} segments={[{label:"Passed",value:42},{label:"Warned",value:26},{label:"Failed",value:18},{label:"Skipped",value:14}]}/></div>
24
+ <div><span className="lbl">Flat donut</span>
25
+ <Pie3D size={250} innerRatio={0.5} segments={[{label:"Used",value:68},{label:"Free",value:32}]}/></div>
26
+ </div>
27
+ <div className="note"><strong>Spin, don't orbit.</strong> Dragging rotates the pie in place — the tilt is fixed, because free orbit only distorts an extruded ellipse further. Hover lifts a slice along its own angle and pins value + share. <code>stairs</code> gives every slice its own height (35%–100% of <code>thickness×2.1</code> by value), so magnitude reads twice: angle and elevation — pure deck furniture, and labeled as such.</div>
28
+ </div>;
29
+ }
30
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
31
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Pie3D.jsx","path":"../charts/Pie3D.jsx"}]); }, 0);
32
+ </script></body></html>
@@ -0,0 +1,24 @@
1
+ <!-- @dsCard group="Charts" viewport="700x400" name="3D Surface" subtitle="z = f(x,y) heat-shaded grid — drag to orbit, hover reads a cell" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { Surface3D } = window.KeybricksDesignSystem_71231a;
13
+ const SURF=[...Array(14)].map((_,r)=>[...Array(14)].map((__,c)=>Math.sin(r/2.1)*Math.cos(c/2.1)*40+50));
14
+ function Sheet(){
15
+ return <div>
16
+ <div className="sec"><span className="lbl">Risk surface over two parameters</span>
17
+ <Surface3D width={420} height={280} values={SURF} xLabel="Rate step" yLabel="Tenor" valueFormat={(v)=>Math.round(v)+""}/>
18
+ </div>
19
+ <div className="note"><strong>The shape is the message.</strong> Cells shade on the sequential heat ramp by height with one upper-left light, so peaks and valleys read in both themes without a legend; hovering a cell reports its grid position and value. <code>zScale</code> controls vertical exaggeration, <code>wire={"{false}"}</code> drops the mesh lines for a smoother skin.</div>
20
+ </div>;
21
+ }
22
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
23
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Surface3D.jsx","path":"../charts/Surface3D.jsx"}]); }, 0);
24
+ </script></body></html>
@@ -0,0 +1,24 @@
1
+ <!-- @dsCard group="Charts" viewport="700x420" name="3D Scatter" subtitle="Points in an orientation cube — drag to orbit, hover pins x·y·z" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { Scatter3D } = window.KeybricksDesignSystem_71231a;
13
+ const PTS=[...Array(90)].map((_,i)=>{const g=i%3;return{x:Math.round(Math.random()*100+g*40),y:Math.round(Math.random()*100+g*25),z:Math.round(Math.random()*100),series:["Alpha","Beta","Gamma"][g],label:["Alpha","Beta","Gamma"][g]+"-"+(Math.floor(i/3)+1)}});
14
+ function Sheet(){
15
+ return <div>
16
+ <div className="sec"><span className="lbl">Three clusters in x·y·z</span>
17
+ <Scatter3D width={420} height={300} points={PTS}/>
18
+ </div>
19
+ <div className="note"><strong>Depth is drawn, not implied.</strong> Nearer points render larger and more opaque; the cube edges keep orientation while orbiting. Hover pins the point's label and all three coordinates — with 3 clusters and ~100 points this stays legible, beyond that project to 2D <code>ScatterChart</code> with color as the third dimension.</div>
20
+ </div>;
21
+ }
22
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
23
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Scatter3D.jsx","path":"../charts/Scatter3D.jsx"}]); }, 0);
24
+ </script></body></html>
@@ -0,0 +1,23 @@
1
+ <!-- @dsCard group="Charts" viewport="700x430" name="3D Ribbon" subtitle="Series as extruded depth bands — the classic 3D area · drag to orbit" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { Ribbon3D } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="sec"><span className="lbl">Three series over eight periods</span>
16
+ <Ribbon3D width={440} height={290} xLabels={["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug"]} series={[{name:"Licences",values:[44,30,38,20,15,12,18,22]},{name:"Services",values:[30,34,28,36,30,26,22,18]},{name:"Support",values:[16,20,26,30,34,40,44,38]}]}/>
17
+ </div>
18
+ <div className="note"><strong>Each series owns a depth row,</strong> so bands never stack or occlude the way a 3D stacked area would. Hover (band or legend) isolates one ribbon and reports its peak and latest value. Rows paint far-to-near; drag to orbit with pitch clamped. For any real trend comparison the 2D stacked <code>LineChart</code> is still the default.</div>
19
+ </div>;
20
+ }
21
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
22
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Ribbon3D.jsx","path":"../charts/Ribbon3D.jsx"}]); }, 0);
23
+ </script></body></html>
@@ -0,0 +1,71 @@
1
+ <!-- @dsCard group="Charts" viewport="700x1560" name="Bar Chart" subtitle="Vertical &amp; horizontal — grouped · stacked · 100% stacked · diverging · combo line" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { BarChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="sec"><span className="lbl">md — grouped, margin line on its own right axis (combo)</span>
16
+ <BarChart width={650} height={240} categories={["Q1","Q2","Q3","Q4"]}
17
+ series={[{name:"Revenue",values:[4200,5100,4800,6100]},{name:"Cost",values:[2900,3300,3200,3900]}]}
18
+ overlay={{name:"Margin",values:[31,35,33,36]}}/>
19
+ </div>
20
+ <div className="row sec">
21
+ <div><span className="lbl">Stacked — parts of a whole</span>
22
+ <BarChart width={300} height={200} mode="stacked" categories={["Jan","Feb","Mar","Apr","May"]}
23
+ series={[{name:"Licences",values:[210,240,260,300,320]},{name:"Services",values:[120,130,110,160,170]},{name:"Support",values:[80,90,95,100,110]}]}/>
24
+ </div>
25
+ <div><span className="lbl">Diverging — variance vs. plan</span>
26
+ <BarChart width={300} height={200} mode="diverging" legend={false} categories={["DE","FR","UK","JP","SG","US"]}
27
+ series={[{name:"Δ vs plan",values:[120,-80,45,-150,60,220]}]}/>
28
+ </div>
29
+ </div>
30
+ <div className="sec"><span className="lbl">Horizontal — long category names read left-to-right</span>
31
+ <div className="row">
32
+ <div>
33
+ <div style={{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-secondary)",paddingBottom:6}}>stacked</div>
34
+ <BarChart width={330} height={210} orientation="horizontal" mode="stacked" legend={false}
35
+ categories={["Architecture","Installation","Computer & Math","Production","Business ops"]}
36
+ series={[{name:"Remote",values:[81,74,65,60,49]},{name:"On-site",values:[19,26,35,40,51]}]}/>
37
+ </div>
38
+ <div>
39
+ <div style={{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-secondary)",paddingBottom:6}}>100% stacked · <code>showValues</code></div>
40
+ <BarChart width={330} height={210} orientation="horizontal" mode="stacked100" showValues legend={false}
41
+ categories={["FY24 Q1","FY24 Q2","FY24 Q3","FY24 Q4","FY25 Q1"]}
42
+ series={[{name:"Research",values:[21,14,15,33,12]},{name:"Design",values:[19,11,10,32,10]},{name:"Engineering",values:[18,10,13,30,7]}]}/>
43
+ </div>
44
+ </div>
45
+ <div className="row" style={{paddingTop:22}}>
46
+ <div>
47
+ <div style={{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-secondary)",paddingBottom:6}}>grouped · paired measures</div>
48
+ <BarChart width={330} height={210} orientation="horizontal" showValues
49
+ categories={["Product 1","Product 2","Product 3","Product 4","Product 5"]}
50
+ series={[{name:"Profit",values:[4.8,3.0,2.8,2.3,2.1]},{name:"Discount",values:[2.6,1.5,1.3,1.6,1.2]}]}
51
+ yFormat={(v)=>v.toFixed(1)+"M"}/>
52
+ </div>
53
+ <div>
54
+ <div style={{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-secondary)",paddingBottom:6}}>diverging · ranked variance</div>
55
+ <BarChart width={330} height={210} orientation="horizontal" mode="diverging" legend={false}
56
+ categories={["US","Germany","Singapore","UK","France","Japan"]}
57
+ series={[{name:"Δ vs plan",values:[220,120,60,45,-80,-150]}]}/>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ <div className="sec"><span className="lbl">sm — a tile of bars: axes off</span>
62
+ <div className="tile"><div className="k">Journals by entity</div>
63
+ <BarChart width={230} height={80} axes={false} legend={false} categories={["DE","FR","UK","JP","SG"]} series={[{name:"n",values:[34,28,41,18,22]}]}/>
64
+ </div>
65
+ </div>
66
+ <div className="note"><strong>One meaning per color.</strong> Grouped/stacked walk <code>--series-1…10</code>; diverging mode is reserved for signed variance and always <code>--chart-pos</code>/<code>--chart-neg</code> — never mix it with categorical color. The combo overlay line is <code>--chart-total</code> so it reads as a different <em>kind</em> of measure, with its own axis format (<code>overlayFormat</code>). Inside a stack only the <em>outer end</em> of the whole bar is rounded — and only on that end’s two corners, since a full <code>rx</code> would round the segment’s inner corners too and open a visible notch at the color join. <strong>Go horizontal when the categories are words</strong>, not dates: labels stay readable without rotation, and ranked rows scan top-to-bottom. <code>mode="stacked100"</code> normalizes each category to 100% for share-of-total comparisons.</div>
67
+ </div>;
68
+ }
69
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
70
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"BarChart.jsx","path":"../charts/BarChart.jsx"}]); }, 0);
71
+ </script></body></html>
@@ -0,0 +1,30 @@
1
+ <!-- @dsCard group="Charts" viewport="700x330" name="Bar List" subtitle="Horizontal labeled bars — top-N rankings, budget consumption" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { BarList } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="row sec">
16
+ <div><span className="lbl">md — ranking with deltas</span>
17
+ <BarList width={320} rows={[{label:"Consolidation",value:840,delta:12.4},{label:"FX Revaluation",value:610,delta:-3.1},{label:"Intercompany",value:430,delta:5.9},{label:"Allocations",value:280,delta:0.4}]}/>
18
+ </div>
19
+ <div><span className="lbl">sm — budget consumption in a tile, shared max</span>
20
+ <div className="tile" style={{width:280}}><div className="k">Cloud budget · Q3</div>
21
+ <div style={{paddingTop:10}}><BarList width={246} max={100} barHeight={6} valueFormat={(v)=>v+"%"} rows={[{label:"Compute",value:82,color:"var(--series-1)"},{label:"Storage",value:64,color:"var(--series-2)"},{label:"Egress",value:31,color:"var(--series-7)"}]}/></div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div className="note"><strong>The readable alternative to a 10-slice donut.</strong> Rows sort by value unless the order itself is the message; the track shows headroom against <code>max</code>, so budget rows read as consumption at a glance. Deltas are signed and always <code>--chart-pos</code>/<code>--chart-neg</code>.</div>
26
+ </div>;
27
+ }
28
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
29
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"BarList.jsx","path":"../charts/BarList.jsx"}]); }, 0);
30
+ </script></body></html>
@@ -0,0 +1,35 @@
1
+ <!-- @dsCard group="Charts" viewport="700x340" name="Donut & Pie" subtitle="Composition with a KPI center — hover lifts a segment" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { DonutChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="row sec">
16
+ <div><span className="lbl">md — hover a segment or its legend row</span>
17
+ <DonutChart size={190} segments={[{label:"Licences",value:4200},{label:"Services",value:2100},{label:"Support",value:1200},{label:"Other",value:400}]} centerLabel="Total ARR" valueFormat={(v)=>"$"+(v/1000).toFixed(1)+"K"}/>
18
+ </div>
19
+ <div><span className="lbl">sm — a tile donut: legend off</span>
20
+ <div className="tile" style={{width:180}}><div className="k">Storage used</div>
21
+ <div style={{display:"flex",justifyContent:"center",paddingTop:6}}>
22
+ <DonutChart size={120} thickness={14} legend={false} segments={[{label:"Used",value:68},{label:"Free",value:32,color:"var(--chart-track)"}]} centerValue="68%" centerLabel="of 2 TB"/>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <div><span className="lbl">Pie — only when the center adds nothing</span>
27
+ <DonutChart size={150} pie legend={false} segments={[{label:"Passed",value:82},{label:"Warned",value:12,color:"var(--series-8)"},{label:"Failed",value:6,color:"var(--chart-neg)"}]}/>
28
+ </div>
29
+ </div>
30
+ <div className="note"><strong>Cap at ~6 segments.</strong> Beyond that the legend outgrows the ring — switch to Bar List or Treemap. The center is a KPI slot: total by default, any value via <code>centerValue</code>; hover temporarily swaps it for the segment under the cursor.</div>
31
+ </div>;
32
+ }
33
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
34
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"DonutChart.jsx","path":"../charts/DonutChart.jsx"}]); }, 0);
35
+ </script></body></html>
@@ -0,0 +1,26 @@
1
+ <!-- @dsCard group="Charts" viewport="700x400" name="Scatter & Bubble" subtitle="x/y correlation, bubble = third dimension — nearest-point tooltip" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { ScatterChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="sec"><span className="lbl">md — cost vs. headcount, bubble = entity size</span>
16
+ <ScatterChart width={650} height={260} xLabel="Headcount" yLabel="Cost ($K)" points={[
17
+ {x:12,y:340,r:8,label:"Germany",series:"EMEA"},{x:8,y:210,r:5,label:"France",series:"EMEA"},{x:6,y:180,r:4,label:"Spain",series:"EMEA"},
18
+ {x:22,y:520,r:14,label:"US",series:"AMER"},{x:15,y:390,r:9,label:"Canada",series:"AMER"},
19
+ {x:9,y:260,r:6,label:"Japan",series:"APAC"},{x:5,y:120,r:3,label:"Singapore",series:"APAC"},{x:11,y:280,r:7,label:"Australia",series:"APAC"}]}/>
20
+ </div>
21
+ <div className="note"><strong>Bubble area carries the third dimension,</strong> capped at 14px radius so an outlier can't swallow the plot. Hover snaps to the nearest point within 24px rather than requiring a direct hit. Series share the categorical palette; both axes always show zero-free nice ticks (<code>extent</code> without zero-clamping).</div>
22
+ </div>;
23
+ }
24
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
25
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"ScatterChart.jsx","path":"../charts/ScatterChart.jsx"}]); }, 0);
26
+ </script></body></html>
@@ -0,0 +1,28 @@
1
+ <!-- @dsCard group="Charts" viewport="700x460" name="Heatmap" subtitle="Matrix density — sequential blue ramp · diverging red/green variance" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { HeatmapChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="sec"><span className="lbl">Sequential — activity by entity × month</span>
16
+ <HeatmapChart width={650} showValues xLabels={["Jan","Feb","Mar","Apr","May","Jun"]} yLabels={["Germany","France","UK","Japan"]}
17
+ values={[[12,18,22,30,34,40],[8,9,14,18,22,26],[20,24,22,28,32,30],[5,7,6,9,12,14]]}/>
18
+ </div>
19
+ <div className="sec"><span className="lbl">Diverging — variance vs. plan (red under, green over)</span>
20
+ <HeatmapChart width={650} scale="diverging" showValues xLabels={["Q1","Q2","Q3","Q4"]} yLabels={["EMEA","APAC","AMER"]}
21
+ values={[[12,-8,22,30],[-14,9,-4,18],[20,-24,2,28]]}/>
22
+ </div>
23
+ <div className="note"><strong>Pick the scale by the question.</strong> Sequential (<code>--chart-heat-1…5</code>) answers “where is there more”; diverging answers “which side of zero” and is reserved for signed values — the same rule as diverging bars. Cell numbers switch to <code>--chart-heat-ink</code> on saturated steps so they hold contrast in both themes.</div>
24
+ </div>;
25
+ }
26
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
27
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"HeatmapChart.jsx","path":"../charts/HeatmapChart.jsx"}]); }, 0);
28
+ </script></body></html>
@@ -0,0 +1,25 @@
1
+ <!-- @dsCard group="Charts" viewport="700x400" name="Waterfall" subtitle="Finance bridge — signed deltas, re-baselining totals, running-sum connectors" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { WaterfallChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="sec"><span className="lbl">md — revenue to net income</span>
16
+ <WaterfallChart width={650} height={270} valueFormat={(v)=>"$"+Math.abs(v/1000).toFixed(1)+"M"} steps={[
17
+ {label:"Revenue",value:6100},{label:"COGS",value:-2400},{label:"Gross\nprofit",total:true},
18
+ {label:"Opex",value:-1800},{label:"FX",value:-140},{label:"One-offs",value:220},{label:"Net\nincome",total:true}]}/>
19
+ </div>
20
+ <div className="note"><strong>The waterfall is the finance chart.</strong> Deltas are signed (<code>--chart-pos</code>/<code>--chart-neg</code>), <code>total</code> rows are <code>--chart-total</code> and re-baseline from zero, and the dashed connector carries the running sum across bars — never fake a bridge with a stacked bar and invisible spacers.</div>
21
+ </div>;
22
+ }
23
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
24
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"WaterfallChart.jsx","path":"../charts/WaterfallChart.jsx"}]); }, 0);
25
+ </script></body></html>
@@ -0,0 +1,31 @@
1
+ <!-- @dsCard group="Charts" viewport="700x330" name="Bullet" subtitle="Actual vs. target rows with a target tick — misses in red" -->
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:18px;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:10px}.row{display:flex;flex-wrap:wrap;gap:24px 36px;align-items:flex-start}.sec{padding-bottom:26px}.tile{border:1px solid var(--border-card);border-radius:var(--radius-lg);padding:14px 16px;background:var(--bg-surface)}.tile .k{font-size:var(--text-xs);color:var(--text-secondary)}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:11px;color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
10
+ <body><div id="root"></div>
11
+ <script type="text/babel">
12
+ const { BulletChart } = window.KeybricksDesignSystem_71231a;
13
+ function Sheet(){
14
+ return <div>
15
+ <div className="row sec">
16
+ <div><span className="lbl">md — tone="auto" colors misses</span>
17
+ <BulletChart width={320} tone="auto" valueFormat={(v)=>v.toLocaleString("en-US")} rows={[
18
+ {label:"Revenue ($K)",value:6100,target:5800},{label:"New logos",value:34,target:45},{label:"NRR (%)",value:112,target:105,max:140},{label:"On-time close (%)",value:87,target:95,max:100}]}/>
19
+ </div>
20
+ <div><span className="lbl">With qualitative ranges</span>
21
+ <BulletChart width={300} rows={[
22
+ {label:"Data quality",value:96,target:98,max:100,ranges:[70,90]},
23
+ {label:"Forecast accuracy",value:88,target:95,max:100,ranges:[60,85]}]}/>
24
+ </div>
25
+ </div>
26
+ <div className="note"><strong>Bullets beat gauges past two KPIs.</strong> A column of bullets compares on one scale-per-row; the 2px target tick is <code>--chart-total</code>, the optional <code>ranges</code> tint poor/ok zones on the track. Default bar is <code>--series-1</code>; <code>tone="auto"</code> switches to hit/miss coloring.</div>
27
+ </div>;
28
+ }
29
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
30
+ if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"BulletChart.jsx","path":"../charts/BulletChart.jsx"}]); }, 0);
31
+ </script></body></html>
@@ -0,0 +1,194 @@
1
+ <!-- @dsCard group="Charts" viewport="1512x2170" name="Full-Page Analytics" subtitle="Reference layout only — every chart type composed into one screen" -->
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/d3@7.9.0/dist/d3.min.js" integrity="sha384-CjloA8y00+1SDAUkjs099PVfnY2KmDC2BZnws9kh8D/lX1s46w6EPhpXdqMfjK6i" crossorigin="anonymous"></script>
5
+ <script src="https://unpkg.com/topojson-client@3.1.0/dist/topojson-client.min.js" integrity="sha384-Ukv1p/xTma6P4/2bY5KzWBw+ydSpXmhCMtyciIQVDJ1RmOxtCYNMF1uXT9T63H67" crossorigin="anonymous"></script>
6
+ <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
7
+ <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
8
+ <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
9
+ <script src="../../_ds_bundle.js"></script>
10
+ <style>body{margin:0;background:var(--bg-app);font-family:var(--font-sans);box-sizing:border-box}
11
+ .card{border:1px solid var(--border-card);border-radius:var(--radius-lg);background:var(--bg-surface);padding:16px 18px;display:flex;flex-direction:column;min-width:0;box-sizing:border-box}
12
+ .ch{display:flex;align-items:baseline;gap:8px;padding-bottom:10px}
13
+ .ch b{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--text-heading)}
14
+ .ch span{font-size:var(--text-xs);color:var(--text-muted)}
15
+ /* Every chart sits in an equal-padding box and is centred in it, so a narrow chart
16
+ never drifts to one edge of its tile. */
17
+ .plot{flex:1;display:flex;align-items:center;justify-content:center;min-width:0;overflow:hidden}
18
+ .grid{display:grid;gap:14px}</style></head>
19
+ <body><div id="root"></div>
20
+ <script type="text/babel">
21
+ const K = window.KeybricksDesignSystem_71231a;
22
+ const { SegmentedControl, Button, Tag, Sparkline, LineChart, BarChart, BarList, DonutChart, ScatterChart, HeatmapChart,
23
+ WaterfallChart, BulletChart, GaugeChart, FunnelChart, TreemapChart, RadarChart, Histogram, BoxPlot, ParetoChart,
24
+ CandlestickChart, SankeyChart, ChordChart, SunburstChart, WorldMap, GanttChart } = K;
25
+ const M=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
26
+ const SETS={
27
+ "This year":{l:M,a:[820,932,901,934,1290,1330,1320,1450,1420,1510,1560,1610],p:[700,810,860,880,1010,1100,1150,1260,1300,1340,1390,1420]},
28
+ "H2":{l:M.slice(6),a:[1320,1450,1420,1510,1560,1610],p:[1150,1260,1300,1340,1390,1420]},
29
+ "QTD":{l:M.slice(9),a:[1510,1560,1610],p:[1340,1390,1420]}};
30
+ const CANDLES=[["Mar 2",128,132,126,131,3.2],["Mar 3",131,134,130,133,2.8],["Mar 4",133,133,127,128,4.1],["Mar 5",128,130,124,125,5.0],["Mar 6",125,131,125,130,3.6],["Mar 9",130,136,129,135,4.4],["Mar 10",135,138,134,137,3.1],["Mar 11",137,137,131,132,3.9],["Mar 12",132,140,132,139,5.5],["Mar 13",139,142,138,141,2.7]].map(([t,o,h,l,c,v])=>({t,o,h,l,c,v}));
31
+ const LAT=[...Array(220)].map((_,i)=>Math.round(38+Math.random()*24+Math.random()*24+(i%45===0?52:0)));
32
+ function Kpi({k,v,d,vals,labels}){
33
+ return <div className="card" style={{padding:"13px 15px"}}>
34
+ <div style={{fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>{k}</div>
35
+ <div style={{display:"flex",alignItems:"flex-end",gap:10,paddingTop:3}}>
36
+ <span style={{fontWeight:"var(--weight-light)",fontSize:25,lineHeight:1.1,color:"var(--text-heading)"}}>{v}</span>
37
+ <span style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-2xs)",paddingBottom:3,color:d>=0?"var(--chart-pos)":"var(--chart-neg)"}}>{(d>=0?"+":"")+d}%</span>
38
+ <span style={{marginLeft:"auto"}}><Sparkline values={vals} labels={labels} tone="auto" mode="area" curve="smooth" width={78} height={26}/></span>
39
+ </div>
40
+ </div>;
41
+ }
42
+ function Panel({title,meta,tag,children,style}){
43
+ return <div className="card" style={style}>
44
+ <div className="ch"><b>{title}</b>{meta?<span>{meta}</span>:null}{tag?<span style={{marginLeft:"auto"}}><Tag>{tag}</Tag></span>:null}</div>
45
+ <div className="plot">{children}</div>
46
+ </div>;
47
+ }
48
+ function Sheet(){
49
+ const [range,setRange]=React.useState("This year");
50
+ const d=SETS[range];
51
+ return <div style={{padding:"20px 28px 28px",width:1512,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:14}}>
52
+ <div style={{display:"flex",alignItems:"center",gap:12}}>
53
+ <div>
54
+ <div style={{fontSize:"var(--text-2xl)",fontWeight:"var(--weight-semibold)",letterSpacing:"var(--tracking-2xl)",color:"var(--text-heading)"}}>Revenue Analytics</div>
55
+ <div style={{fontSize:"var(--text-sm)",color:"var(--text-secondary)",paddingTop:3}}>Consolidated · all entities · USD</div>
56
+ </div>
57
+ <span style={{marginLeft:"auto"}}><SegmentedControl options={Object.keys(SETS)} value={range} onChange={setRange}/></span>
58
+ <Button icon="download">Export</Button>
59
+ </div>
60
+
61
+ <div className="grid" style={{gridTemplateColumns:"repeat(4,1fr)"}}>
62
+ <Kpi k="Recognized revenue" v="$14.9M" d={9.4} vals={d.a} labels={d.l}/>
63
+ <Kpi k="vs. prior year" v="+$1.9M" d={14.6} vals={d.a.map((v,i)=>v-d.p[i])} labels={d.l}/>
64
+ <Kpi k="Forecast accuracy" v="96.2%" d={1.1} vals={[93,94,95,94,96,96]} labels={d.l}/>
65
+ <Kpi k="Open adjustments" v="12" d={-25} vals={[24,20,18,16,14,12]} labels={d.l}/>
66
+ </div>
67
+
68
+ <div className="grid" style={{gridTemplateColumns:"1.62fr 1fr"}}>
69
+ <Panel title="Actual vs. prior year" meta="monthly, recognized" tag="Live">
70
+ <LineChart width={854} height={250} area curve="smooth" xLabels={d.l} target={1250} targetLabel="Plan $1.25M"
71
+ series={[{name:"Actual",values:d.a},{name:"Prior year",values:d.p}]}/>
72
+ </Panel>
73
+ <Panel title="Revenue to net income" meta="bridge">
74
+ <WaterfallChart width={504} height={250} valueFormat={(v)=>"$"+Math.abs(v/1000).toFixed(1)+"M"} steps={[
75
+ {label:"Rev",value:6100},{label:"COGS",value:-2400},{label:"Gross",total:true},{label:"Opex",value:-1800},{label:"FX",value:-140},{label:"Net",total:true}]}/>
76
+ </Panel>
77
+ </div>
78
+
79
+ <div className="grid" style={{gridTemplateColumns:"1.15fr 1fr 0.9fr 0.62fr"}}>
80
+ <Panel title="Quarterly mix" meta="revenue vs. cost · margin %">
81
+ <BarChart width={392} height={210} categories={["Q1","Q2","Q3","Q4"]}
82
+ series={[{name:"Revenue",values:[4200,5100,4800,6100]},{name:"Cost",values:[2900,3300,3200,3900]}]}
83
+ overlay={{name:"Margin",values:[31,35,33,36]}}/>
84
+ </Panel>
85
+ <Panel title="Composition over time" meta="stacked area">
86
+ <LineChart width={334} height={210} stacked xLabels={M.slice(0,8)}
87
+ series={[{name:"EMEA",values:[320,332,301,334,390,330,320,360]},{name:"APAC",values:[220,182,191,234,290,330,310,340]},{name:"AMER",values:[150,232,201,154,190,330,410,420]}]}/>
88
+ </Panel>
89
+ <Panel title="Cost base" meta="treemap">
90
+ <TreemapChart width={296} height={210} valueFormat={(v)=>"$"+v+"K"} items={[
91
+ {label:"Payroll",value:4200},{label:"Cloud",value:2600},{label:"Facilities",value:1300},{label:"Software",value:900},{label:"Travel",value:700},{label:"Other",value:400}]}/>
92
+ </Panel>
93
+ <Panel title="Pipeline health">
94
+ <GaugeChart size={168} value={78} label="weighted coverage"/>
95
+ </Panel>
96
+ </div>
97
+
98
+ <div className="grid" style={{gridTemplateColumns:"0.78fr 1fr 1fr 1fr"}}>
99
+ <Panel title="Product mix" meta="donut">
100
+ <DonutChart size={148} thickness={17} legend={false} segments={[{label:"Licences",value:8600},{label:"Services",value:4100},{label:"Support",value:2200}]} centerLabel="Total" valueFormat={(v)=>"$"+(v/1000).toFixed(1)+"M"}/>
101
+ </Panel>
102
+ <Panel title="Remote vs. on-site" meta="100% stacked, horizontal">
103
+ <BarChart width={330} height={196} orientation="horizontal" mode="stacked100" legend={false}
104
+ categories={["Architecture","Engineering","Business ops","Support"]}
105
+ series={[{name:"Remote",values:[81,65,49,35]},{name:"On-site",values:[19,35,51,65]}]}/>
106
+ </Panel>
107
+ <Panel title="Profit vs. discount" meta="grouped, horizontal">
108
+ <BarChart width={330} height={196} orientation="horizontal" legend={false} showValues
109
+ categories={["Product 1","Product 2","Product 3","Product 4"]}
110
+ series={[{name:"Profit",values:[4.8,3.0,2.8,2.3]},{name:"Discount",values:[2.6,1.5,1.3,1.6]}]} yFormat={(v)=>v.toFixed(1)+"M"}/>
111
+ </Panel>
112
+ <Panel title="Variance vs. plan" meta="diverging, horizontal">
113
+ <BarChart width={330} height={196} orientation="horizontal" mode="diverging" legend={false}
114
+ categories={["US","Germany","UK","France","Japan"]} series={[{name:"Δ vs plan",values:[220,120,45,-80,-150]}]}/>
115
+ </Panel>
116
+ </div>
117
+
118
+ <div className="grid" style={{gridTemplateColumns:"1.28fr 1fr 1fr"}}>
119
+ <Panel title="Global revenue" meta="choropleth · click a country">
120
+ <WorldMap width={470} height={250} unit="$K" valueFormat={(v)=>"$"+v+"K"} values={{
121
+ "United States":6400,Canada:2100,Brazil:1400,Mexico:800,"United Kingdom":4200,Germany:5200,France:3100,Spain:1100,Italy:1500,
122
+ Netherlands:1700,Poland:700,China:5900,Japan:2600,India:2200,"South Korea":1300,Singapore:900,Australia:950,"South Africa":420}}/>
123
+ </Panel>
124
+ <Panel title="Budget flow" meta="sankey">
125
+ <SankeyChart width={366} height={250} labelWidth={78} valueFormat={(v)=>"$"+v+"M"}
126
+ nodes={[{id:"b",label:"Budget"},{id:"mk",label:"Marketing"},{id:"op",label:"Ops"},{id:"rd",label:"R&D"},{id:"ads",label:"Ads"},{id:"sal",label:"Salaries"},{id:"sw",label:"Software"}]}
127
+ links={[{source:"b",target:"mk",value:40},{source:"b",target:"op",value:35},{source:"b",target:"rd",value:25},
128
+ {source:"mk",target:"ads",value:28},{source:"mk",target:"sal",value:12},{source:"op",target:"sal",value:20},{source:"op",target:"sw",value:15},{source:"rd",target:"sw",value:25}]}/>
129
+ </Panel>
130
+ <Panel title="Intercompany netting" meta="chord">
131
+ <ChordChart size={250} thickness={11} valueFormat={(v)=>"$"+v+"M"} labels={["EMEA","APAC","AMER","LATAM"]}
132
+ matrix={[[0,12,8,3],[9,0,14,2],[6,11,0,7],[2,3,5,0]]}/>
133
+ </Panel>
134
+ </div>
135
+
136
+ <div className="grid" style={{gridTemplateColumns:"1fr 1fr 1fr 1fr"}}>
137
+ <Panel title="Activity density" meta="heatmap">
138
+ <HeatmapChart width={314} cellHeight={22} showValues xLabels={["Jan","Feb","Mar","Apr","May","Jun"]} yLabels={["Germany","France","UK","Japan"]}
139
+ values={[[12,18,22,30,34,40],[8,9,14,18,22,26],[20,24,22,28,32,30],[5,7,6,9,12,14]]}/>
140
+ </Panel>
141
+ <Panel title="Cost vs. headcount" meta="scatter">
142
+ <ScatterChart width={314} height={200} legend={false} xLabel="HC" yLabel="$K" points={[
143
+ {x:12,y:340,r:8,label:"Germany"},{x:8,y:210,r:5,label:"France"},{x:22,y:520,r:14,label:"US"},{x:15,y:390,r:9,label:"Canada"},{x:9,y:260,r:6,label:"Japan"},{x:5,y:120,r:3,label:"Singapore"}]}/>
144
+ </Panel>
145
+ <Panel title="Break causes" meta="pareto">
146
+ <ParetoChart width={314} height={200} items={[{label:"FX",value:340},{label:"JE",value:210},{label:"Map",value:120},{label:"Round",value:70},{label:"Other",value:45}]}/>
147
+ </Panel>
148
+ <Panel title="Cost hierarchy" meta="sunburst">
149
+ <SunburstChart size={200} valueFormat={(v)=>"$"+(v/1000).toFixed(1)+"M"} data={{label:"Cost",children:[
150
+ {label:"People",children:[{label:"Eng",value:4200},{label:"Sales",value:2600},{label:"G&A",value:1200}]},
151
+ {label:"Cloud",children:[{label:"Compute",value:1800},{label:"Storage",value:900}]},{label:"Other",value:430}]}}/>
152
+ </Panel>
153
+ </div>
154
+
155
+ <div className="grid" style={{gridTemplateColumns:"1fr 1fr 1fr 1fr"}}>
156
+ <Panel title="Posting latency" meta="histogram">
157
+ <Histogram width={314} height={196} bins={10} showMean values={LAT} valueFormat={(v)=>Math.round(v)+"ms"} countFormat={(v)=>v+""}/>
158
+ </Panel>
159
+ <Panel title="Latency by entity" meta="box plot">
160
+ <BoxPlot width={314} height={196} valueFormat={(v)=>Math.round(v)+"ms"} groups={[
161
+ {label:"DE",values:[42,48,51,55,58,61,64,69,120]},{label:"FR",values:[38,40,44,47,49,52,56,59]},
162
+ {label:"US",values:[48,52,55,57,60,63,68,82,140]},{label:"JP",values:[35,37,39,41,43,45,48,51]}]}/>
163
+ </Panel>
164
+ <Panel title="KBX price" meta="candlestick">
165
+ <CandlestickChart width={314} height={196} ma={5} candles={CANDLES} valueFormat={(v)=>"$"+v.toFixed(0)}/>
166
+ </Panel>
167
+ <Panel title="Model fitness" meta="radar">
168
+ <RadarChart size={196} legend={false} levels={3} axes={[{label:"Fit"},{label:"Recall"},{label:"Speed"},{label:"Size"},{label:"Cost"}]} series={[{name:"v8",values:[74,88,62,55,70]}]}/>
169
+ </Panel>
170
+ </div>
171
+
172
+ <div className="grid" style={{gridTemplateColumns:"1.3fr 1fr 0.86fr 0.86fr"}}>
173
+ <Panel title="Close calendar" meta="gantt">
174
+ <GanttChart width={418} rowHeight={22} today="2026-03-11" tasks={[
175
+ {label:"Extract",start:"2026-03-02",end:"2026-03-05",progress:1,lane:0},
176
+ {label:"Validate",start:"2026-03-05",end:"2026-03-10",progress:0.8,lane:1},
177
+ {label:"FX revaluation",start:"2026-03-09",end:"2026-03-12",progress:0.35,lane:2},
178
+ {label:"Sign-off",start:"2026-03-17",milestone:true,lane:5}]}/>
179
+ </Panel>
180
+ <Panel title="KPIs vs. target" meta="bullet">
181
+ <BulletChart width={318} tone="auto" valueFormat={(v)=>v.toLocaleString("en-US")} rows={[
182
+ {label:"Revenue ($K)",value:6100,target:5800},{label:"New logos",value:34,target:45},{label:"On-time close (%)",value:87,target:95,max:100}]}/>
183
+ </Panel>
184
+ <Panel title="Close pipeline" meta="funnel">
185
+ <FunnelChart width={262} bandHeight={26} gap={10} stages={[{label:"Extracted",value:48200},{label:"Validated",value:41900},{label:"Loaded",value:38800}]}/>
186
+ </Panel>
187
+ <Panel title="Top drivers" meta="bar list">
188
+ <BarList width={262} rows={[{label:"AMER",value:6400,delta:11.2},{label:"EMEA",value:5200,delta:6.8},{label:"APAC",value:3300,delta:14.1}]} valueFormat={(v)=>"$"+(v/1000).toFixed(1)+"M"}/>
189
+ </Panel>
190
+ </div>
191
+ </div>;
192
+ }
193
+ ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
194
+ </script></body></html>