@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.
- package/DEPLOY.md +204 -0
- package/DESIGN.md +269 -0
- package/INTEGRATION.md +417 -0
- package/SKILL.md +32 -0
- package/_adherence.oxlintrc.json +1469 -0
- package/_scripts/build-index.mjs +80 -0
- package/_scripts/build-tokens.mjs +135 -0
- package/assets/icons/icon-index.js +1 -0
- package/assets/icons/icon-index.json +1 -0
- package/assets/icons/unicons-index.js +1 -0
- package/assets/icons/unicons-index.json +1 -0
- package/assets/keybricks-logo.png +0 -0
- package/components/_cards/accordion.card.html +32 -0
- package/components/_cards/action-chip.card.html +22 -0
- package/components/_cards/activity.card.html +34 -0
- package/components/_cards/alert.card.html +32 -0
- package/components/_cards/app-chrome.card.html +36 -0
- package/components/_cards/banner.card.html +21 -0
- package/components/_cards/brand-visual.card.html +43 -0
- package/components/_cards/breadcrumb.card.html +23 -0
- package/components/_cards/button-1-base.card.html +39 -0
- package/components/_cards/button-2-states.card.html +56 -0
- package/components/_cards/button-3-sizes-icons.card.html +32 -0
- package/components/_cards/button-4-group.card.html +47 -0
- package/components/_cards/canvas-zoom-controls.card.html +19 -0
- package/components/_cards/cards-indicators.card.html +59 -0
- package/components/_cards/charts-1-sparkline.card.html +55 -0
- package/components/_cards/charts-10-gauge.card.html +31 -0
- package/components/_cards/charts-11-funnel.card.html +28 -0
- package/components/_cards/charts-12-treemap.card.html +23 -0
- package/components/_cards/charts-14-radar.card.html +31 -0
- package/components/_cards/charts-15-distribution.card.html +32 -0
- package/components/_cards/charts-16-pareto.card.html +25 -0
- package/components/_cards/charts-17-candlestick.card.html +34 -0
- package/components/_cards/charts-18-sankey.card.html +29 -0
- package/components/_cards/charts-19-chord.card.html +31 -0
- package/components/_cards/charts-2-line.card.html +46 -0
- package/components/_cards/charts-20-sunburst.card.html +38 -0
- package/components/_cards/charts-21-worldmap.card.html +33 -0
- package/components/_cards/charts-22-gantt.card.html +37 -0
- package/components/_cards/charts-23-bar3d.card.html +26 -0
- package/components/_cards/charts-24-pie3d.card.html +32 -0
- package/components/_cards/charts-25-surface3d.card.html +24 -0
- package/components/_cards/charts-26-scatter3d.card.html +24 -0
- package/components/_cards/charts-27-ribbon3d.card.html +23 -0
- package/components/_cards/charts-3-bar.card.html +71 -0
- package/components/_cards/charts-4-barlist.card.html +30 -0
- package/components/_cards/charts-5-donut.card.html +35 -0
- package/components/_cards/charts-6-scatter.card.html +26 -0
- package/components/_cards/charts-7-heatmap.card.html +28 -0
- package/components/_cards/charts-8-waterfall.card.html +25 -0
- package/components/_cards/charts-9-bullet.card.html +31 -0
- package/components/_cards/charts-99-fullpage.card.html +194 -0
- package/components/_cards/checkbox.card.html +34 -0
- package/components/_cards/codeblock.card.html +19 -0
- package/components/_cards/combobox.card.html +25 -0
- package/components/_cards/context-menu.card.html +21 -0
- package/components/_cards/datatable.card.html +48 -0
- package/components/_cards/date-picker.card.html +31 -0
- package/components/_cards/diffvalue.card.html +21 -0
- package/components/_cards/divider.card.html +24 -0
- package/components/_cards/drawer.card.html +30 -0
- package/components/_cards/dropdown-menu.card.html +38 -0
- package/components/_cards/dropzone.card.html +22 -0
- package/components/_cards/empty-state.card.html +29 -0
- package/components/_cards/filter-bar.card.html +34 -0
- package/components/_cards/icon-button.card.html +27 -0
- package/components/_cards/icons-1-core.card.html +49 -0
- package/components/_cards/icons-2-feather.card.html +39 -0
- package/components/_cards/icons-3-unicons.card.html +44 -0
- package/components/_cards/input.card.html +25 -0
- package/components/_cards/kbd.card.html +20 -0
- package/components/_cards/keyvalue.card.html +23 -0
- package/components/_cards/listrow.card.html +30 -0
- package/components/_cards/loading.card.html +33 -0
- package/components/_cards/log-viewer.card.html +23 -0
- package/components/_cards/modal.card.html +35 -0
- package/components/_cards/multi-select.card.html +26 -0
- package/components/_cards/number-stepper.card.html +24 -0
- package/components/_cards/pagination.card.html +25 -0
- package/components/_cards/people.card.html +46 -0
- package/components/_cards/pipeline-node.card.html +76 -0
- package/components/_cards/pipeline-palette.card.html +54 -0
- package/components/_cards/search.card.html +23 -0
- package/components/_cards/select.card.html +23 -0
- package/components/_cards/slider.card.html +25 -0
- package/components/_cards/smart-table.card.html +37 -0
- package/components/_cards/spreadsheet.card.html +31 -0
- package/components/_cards/stepper.card.html +25 -0
- package/components/_cards/tabs.card.html +25 -0
- package/components/_cards/tag.card.html +26 -0
- package/components/_cards/textarea.card.html +27 -0
- package/components/_cards/timeline.card.html +32 -0
- package/components/_cards/toast.card.html +33 -0
- package/components/_cards/toggles.card.html +68 -0
- package/components/_cards/tooltip.card.html +22 -0
- package/components/_cards/tree.card.html +150 -0
- package/components/_shared/frame-theme.js +16 -0
- package/components/_shared/src-brand.js +1 -0
- package/components/_shared/src-buttons.js +1 -0
- package/components/_shared/src-charts.js +1 -0
- package/components/_shared/src-data.js +1 -0
- package/components/_shared/src-display.js +1 -0
- package/components/_shared/src-feedback.js +1 -0
- package/components/_shared/src-forms.js +1 -0
- package/components/_shared/src-icons.js +1 -0
- package/components/_shared/src-navigation.js +1 -0
- package/components/_shared/src-pipeline.js +1 -0
- package/components/_shared/src-tabs.js +1 -0
- package/components/_shared/svg-download.js +19 -0
- package/components/_shared/view-source.js +185 -0
- package/components/_vue/index.mjs +114 -0
- package/components/brand/BrandVisual.d.ts +17 -0
- package/components/brand/BrandVisual.jsx +29 -0
- package/components/brand/BrandVisual.vue +34 -0
- package/components/brand/_dir.card.html +13 -0
- package/components/brand/brandMotifs.js +210 -0
- package/components/buttons/ActionChip.d.ts +10 -0
- package/components/buttons/ActionChip.jsx +20 -0
- package/components/buttons/ActionChip.vue +18 -0
- package/components/buttons/Button.d.ts +40 -0
- package/components/buttons/Button.jsx +101 -0
- package/components/buttons/Button.vue +87 -0
- package/components/buttons/IconButton.d.ts +26 -0
- package/components/buttons/IconButton.jsx +28 -0
- package/components/buttons/IconButton.vue +21 -0
- package/components/buttons/_dir.card.html +13 -0
- package/components/buttons/buttons.prompt.md +19 -0
- package/components/charts/Bar3D.d.ts +15 -0
- package/components/charts/Bar3D.jsx +93 -0
- package/components/charts/Bar3D.vue +79 -0
- package/components/charts/BarChart.d.ts +23 -0
- package/components/charts/BarChart.jsx +135 -0
- package/components/charts/BarChart.vue +139 -0
- package/components/charts/BarList.d.ts +13 -0
- package/components/charts/BarList.jsx +31 -0
- package/components/charts/BarList.vue +25 -0
- package/components/charts/BoxPlot.d.ts +18 -0
- package/components/charts/BoxPlot.jsx +62 -0
- package/components/charts/BoxPlot.vue +58 -0
- package/components/charts/BulletChart.d.ts +12 -0
- package/components/charts/BulletChart.jsx +41 -0
- package/components/charts/BulletChart.vue +33 -0
- package/components/charts/CandlestickChart.d.ts +15 -0
- package/components/charts/CandlestickChart.jsx +63 -0
- package/components/charts/CandlestickChart.vue +62 -0
- package/components/charts/ChartKit.d.ts +8 -0
- package/components/charts/ChartKit.jsx +76 -0
- package/components/charts/ChartKit.vue +47 -0
- package/components/charts/ChordChart.d.ts +13 -0
- package/components/charts/ChordChart.jsx +55 -0
- package/components/charts/ChordChart.vue +54 -0
- package/components/charts/DonutChart.d.ts +15 -0
- package/components/charts/DonutChart.jsx +73 -0
- package/components/charts/DonutChart.vue +61 -0
- package/components/charts/FunnelChart.d.ts +11 -0
- package/components/charts/FunnelChart.jsx +37 -0
- package/components/charts/FunnelChart.vue +29 -0
- package/components/charts/GanttChart.d.ts +20 -0
- package/components/charts/GanttChart.jsx +80 -0
- package/components/charts/GanttChart.vue +60 -0
- package/components/charts/GaugeChart.d.ts +13 -0
- package/components/charts/GaugeChart.jsx +33 -0
- package/components/charts/GaugeChart.vue +29 -0
- package/components/charts/HeatmapChart.d.ts +13 -0
- package/components/charts/HeatmapChart.jsx +62 -0
- package/components/charts/HeatmapChart.vue +38 -0
- package/components/charts/Histogram.d.ts +16 -0
- package/components/charts/Histogram.jsx +56 -0
- package/components/charts/Histogram.vue +53 -0
- package/components/charts/LineChart.d.ts +17 -0
- package/components/charts/LineChart.jsx +84 -0
- package/components/charts/LineChart.vue +86 -0
- package/components/charts/ParetoChart.d.ts +13 -0
- package/components/charts/ParetoChart.jsx +54 -0
- package/components/charts/ParetoChart.vue +55 -0
- package/components/charts/Pie3D.d.ts +17 -0
- package/components/charts/Pie3D.jsx +145 -0
- package/components/charts/Pie3D.vue +115 -0
- package/components/charts/RadarChart.d.ts +14 -0
- package/components/charts/RadarChart.jsx +79 -0
- package/components/charts/RadarChart.vue +73 -0
- package/components/charts/Ribbon3D.d.ts +13 -0
- package/components/charts/Ribbon3D.jsx +89 -0
- package/components/charts/Ribbon3D.vue +79 -0
- package/components/charts/SankeyChart.d.ts +15 -0
- package/components/charts/SankeyChart.jsx +59 -0
- package/components/charts/SankeyChart.vue +53 -0
- package/components/charts/Scatter3D.d.ts +12 -0
- package/components/charts/Scatter3D.jsx +69 -0
- package/components/charts/Scatter3D.vue +59 -0
- package/components/charts/ScatterChart.d.ts +12 -0
- package/components/charts/ScatterChart.jsx +53 -0
- package/components/charts/ScatterChart.vue +57 -0
- package/components/charts/Sparkline.d.ts +19 -0
- package/components/charts/Sparkline.jsx +63 -0
- package/components/charts/Sparkline.vue +54 -0
- package/components/charts/SunburstChart.d.ts +12 -0
- package/components/charts/SunburstChart.jsx +61 -0
- package/components/charts/SunburstChart.vue +60 -0
- package/components/charts/Surface3D.d.ts +13 -0
- package/components/charts/Surface3D.jsx +70 -0
- package/components/charts/Surface3D.vue +63 -0
- package/components/charts/TreemapChart.d.ts +11 -0
- package/components/charts/TreemapChart.jsx +35 -0
- package/components/charts/TreemapChart.vue +27 -0
- package/components/charts/WaterfallChart.d.ts +11 -0
- package/components/charts/WaterfallChart.jsx +59 -0
- package/components/charts/WaterfallChart.vue +46 -0
- package/components/charts/WorldMap.d.ts +21 -0
- package/components/charts/WorldMap.jsx +107 -0
- package/components/charts/WorldMap.vue +73 -0
- package/components/charts/_dir.card.html +7 -0
- package/components/charts/chart-3d.js +84 -0
- package/components/charts/chart-geometry.js +223 -0
- package/components/charts/charts.prompt.md +24 -0
- package/components/data/CodeBlock.d.ts +9 -0
- package/components/data/CodeBlock.jsx +19 -0
- package/components/data/CodeBlock.vue +22 -0
- package/components/data/DataTable.d.ts +28 -0
- package/components/data/DataTable.jsx +32 -0
- package/components/data/DataTable.vue +25 -0
- package/components/data/DiffValue.d.ts +11 -0
- package/components/data/DiffValue.jsx +15 -0
- package/components/data/DiffValue.vue +13 -0
- package/components/data/FilterBar.d.ts +16 -0
- package/components/data/FilterBar.jsx +22 -0
- package/components/data/FilterBar.vue +23 -0
- package/components/data/KeyValue.d.ts +16 -0
- package/components/data/KeyValue.jsx +25 -0
- package/components/data/KeyValue.vue +26 -0
- package/components/data/ListRow.d.ts +14 -0
- package/components/data/ListRow.jsx +25 -0
- package/components/data/ListRow.vue +25 -0
- package/components/data/Pagination.d.ts +12 -0
- package/components/data/Pagination.jsx +27 -0
- package/components/data/Pagination.vue +24 -0
- package/components/data/SmartTable.d.ts +30 -0
- package/components/data/SmartTable.jsx +73 -0
- package/components/data/SmartTable.vue +74 -0
- package/components/data/Spreadsheet.d.ts +33 -0
- package/components/data/Spreadsheet.jsx +110 -0
- package/components/data/Spreadsheet.vue +95 -0
- package/components/data/_dir.card.html +13 -0
- package/components/data/data.prompt.md +33 -0
- package/components/display/Avatar.d.ts +21 -0
- package/components/display/Avatar.jsx +31 -0
- package/components/display/Avatar.vue +34 -0
- package/components/display/Badge.d.ts +27 -0
- package/components/display/Badge.jsx +40 -0
- package/components/display/Badge.vue +47 -0
- package/components/display/Card.d.ts +27 -0
- package/components/display/Card.jsx +27 -0
- package/components/display/Card.vue +28 -0
- package/components/display/Divider.d.ts +8 -0
- package/components/display/Divider.jsx +14 -0
- package/components/display/Divider.vue +13 -0
- package/components/display/Kbd.d.ts +7 -0
- package/components/display/Kbd.jsx +12 -0
- package/components/display/Kbd.vue +9 -0
- package/components/display/ProgressBar.d.ts +42 -0
- package/components/display/ProgressBar.jsx +70 -0
- package/components/display/ProgressBar.vue +69 -0
- package/components/display/Tag.d.ts +9 -0
- package/components/display/Tag.jsx +15 -0
- package/components/display/Tag.vue +15 -0
- package/components/display/_dir.card.html +13 -0
- package/components/display/display.prompt.md +30 -0
- package/components/feedback/Accordion.d.ts +13 -0
- package/components/feedback/Accordion.jsx +21 -0
- package/components/feedback/Accordion.vue +22 -0
- package/components/feedback/ActivityItem.d.ts +25 -0
- package/components/feedback/ActivityItem.jsx +39 -0
- package/components/feedback/ActivityItem.vue +46 -0
- package/components/feedback/Alert.d.ts +36 -0
- package/components/feedback/Alert.jsx +48 -0
- package/components/feedback/Alert.vue +59 -0
- package/components/feedback/Banner.d.ts +15 -0
- package/components/feedback/Banner.jsx +25 -0
- package/components/feedback/Banner.vue +25 -0
- package/components/feedback/ContextMenu.d.ts +8 -0
- package/components/feedback/ContextMenu.jsx +18 -0
- package/components/feedback/ContextMenu.vue +19 -0
- package/components/feedback/Drawer.d.ts +18 -0
- package/components/feedback/Drawer.jsx +26 -0
- package/components/feedback/Drawer.vue +24 -0
- package/components/feedback/Menu.d.ts +10 -0
- package/components/feedback/Menu.jsx +24 -0
- package/components/feedback/Menu.vue +21 -0
- package/components/feedback/Modal.d.ts +38 -0
- package/components/feedback/Modal.jsx +69 -0
- package/components/feedback/Modal.vue +65 -0
- package/components/feedback/Stepper.d.ts +9 -0
- package/components/feedback/Stepper.jsx +24 -0
- package/components/feedback/Stepper.vue +18 -0
- package/components/feedback/Timeline.d.ts +15 -0
- package/components/feedback/Timeline.jsx +27 -0
- package/components/feedback/Timeline.vue +21 -0
- package/components/feedback/_dir.card.html +13 -0
- package/components/feedback/feedback.prompt.md +35 -0
- package/components/forms/Checkbox.d.ts +13 -0
- package/components/forms/Checkbox.jsx +17 -0
- package/components/forms/Checkbox.vue +18 -0
- package/components/forms/Combobox.d.ts +13 -0
- package/components/forms/Combobox.jsx +34 -0
- package/components/forms/Combobox.vue +35 -0
- package/components/forms/DatePicker.d.ts +12 -0
- package/components/forms/DatePicker.jsx +48 -0
- package/components/forms/DatePicker.vue +46 -0
- package/components/forms/Dropzone.d.ts +20 -0
- package/components/forms/Dropzone.jsx +36 -0
- package/components/forms/Dropzone.vue +28 -0
- package/components/forms/Field.d.ts +13 -0
- package/components/forms/Field.jsx +13 -0
- package/components/forms/Field.vue +12 -0
- package/components/forms/Input.d.ts +18 -0
- package/components/forms/Input.jsx +35 -0
- package/components/forms/Input.vue +38 -0
- package/components/forms/MultiSelect.d.ts +14 -0
- package/components/forms/MultiSelect.jsx +33 -0
- package/components/forms/MultiSelect.vue +36 -0
- package/components/forms/NumberStepper.d.ts +13 -0
- package/components/forms/NumberStepper.jsx +15 -0
- package/components/forms/NumberStepper.vue +17 -0
- package/components/forms/Radio.vue +16 -0
- package/components/forms/RadioGroup.vue +11 -0
- package/components/forms/SearchInput.d.ts +12 -0
- package/components/forms/SearchInput.jsx +17 -0
- package/components/forms/SearchInput.vue +14 -0
- package/components/forms/Select.d.ts +14 -0
- package/components/forms/Select.jsx +17 -0
- package/components/forms/Select.vue +16 -0
- package/components/forms/Slider.d.ts +15 -0
- package/components/forms/Slider.jsx +21 -0
- package/components/forms/Slider.vue +23 -0
- package/components/forms/Switch.d.ts +31 -0
- package/components/forms/Switch.jsx +40 -0
- package/components/forms/Switch.vue +16 -0
- package/components/forms/_dir.card.html +13 -0
- package/components/forms/forms.prompt.md +23 -0
- package/components/icons/Icon.d.ts +19 -0
- package/components/icons/Icon.jsx +93 -0
- package/components/icons/Icon.prompt.md +8 -0
- package/components/icons/Icon.vue +12 -0
- package/components/icons/Unicon.d.ts +12 -0
- package/components/icons/Unicon.jsx +16 -0
- package/components/icons/Unicon.vue +15 -0
- package/components/icons/_dir.card.html +13 -0
- package/components/icons/feather-paths.js +2 -0
- package/components/icons/icon-paths.js +73 -0
- package/components/index.d.ts +87 -0
- package/components/index.js +110 -0
- package/components/navigation/Breadcrumb.d.ts +24 -0
- package/components/navigation/Breadcrumb.jsx +120 -0
- package/components/navigation/Breadcrumb.vue +94 -0
- package/components/navigation/DocTree.d.ts +18 -0
- package/components/navigation/DocTree.jsx +37 -0
- package/components/navigation/DocTree.vue +25 -0
- package/components/navigation/Sidebar.d.ts +29 -0
- package/components/navigation/Sidebar.jsx +75 -0
- package/components/navigation/Sidebar.vue +54 -0
- package/components/navigation/TopBar.d.ts +27 -0
- package/components/navigation/TopBar.jsx +44 -0
- package/components/navigation/TopBar.vue +51 -0
- package/components/navigation/Tree.d.ts +83 -0
- package/components/navigation/Tree.jsx +347 -0
- package/components/navigation/Tree.vue +258 -0
- package/components/navigation/_dir.card.html +13 -0
- package/components/navigation/navigation.prompt.md +22 -0
- package/components/pipeline/ConfigPanel.d.ts +18 -0
- package/components/pipeline/ConfigPanel.jsx +30 -0
- package/components/pipeline/ConfigPanel.vue +32 -0
- package/components/pipeline/DataPreview.d.ts +14 -0
- package/components/pipeline/DataPreview.jsx +24 -0
- package/components/pipeline/DataPreview.vue +21 -0
- package/components/pipeline/NodeCard.d.ts +47 -0
- package/components/pipeline/NodeCard.jsx +97 -0
- package/components/pipeline/NodeCard.vue +75 -0
- package/components/pipeline/PaletteItem.vue +15 -0
- package/components/pipeline/PaletteListItem.vue +15 -0
- package/components/pipeline/PalettePanel.d.ts +20 -0
- package/components/pipeline/PalettePanel.jsx +74 -0
- package/components/pipeline/PalettePanel.vue +45 -0
- package/components/pipeline/PipelineCanvas.d.ts +25 -0
- package/components/pipeline/PipelineCanvas.jsx +94 -0
- package/components/pipeline/PipelineCanvas.vue +73 -0
- package/components/pipeline/ZoomControls.d.ts +9 -0
- package/components/pipeline/ZoomControls.jsx +15 -0
- package/components/pipeline/ZoomControls.vue +15 -0
- package/components/pipeline/_dir.card.html +13 -0
- package/components/pipeline/pipeline.prompt.md +22 -0
- package/components/tabs/SegmentedControl.d.ts +11 -0
- package/components/tabs/SegmentedControl.jsx +21 -0
- package/components/tabs/SegmentedControl.vue +15 -0
- package/components/tabs/Tabs.d.ts +13 -0
- package/components/tabs/Tabs.jsx +52 -0
- package/components/tabs/Tabs.vue +39 -0
- package/components/tabs/ViewToggle.d.ts +8 -0
- package/components/tabs/ViewToggle.jsx +12 -0
- package/components/tabs/ViewToggle.vue +12 -0
- package/components/tabs/_dir.card.html +13 -0
- package/components/tabs/tabs.prompt.md +14 -0
- package/package.json +76 -0
- package/readme.md +150 -0
- package/styles.css +10 -0
- package/tokens/alpha.css +27 -0
- package/tokens/charts.css +55 -0
- package/tokens/colors-extended.css +40 -0
- package/tokens/colors.css +39 -0
- package/tokens/dark.css +96 -0
- package/tokens/fonts.css +4 -0
- package/tokens/interaction.css +48 -0
- package/tokens/layout.css +30 -0
- package/tokens/motion.css +22 -0
- package/tokens/tokens.d.ts +680 -0
- package/tokens/tokens.js +1018 -0
- package/tokens/tokens.json +2928 -0
- package/tokens/typography.css +22 -0
|
@@ -0,0 +1 @@
|
|
|
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"});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
window.__KB_SRC__=Object.assign(window.__KB_SRC__||{},{"buttons/ActionChip.jsx":"import React from \"react\";\n\nconst chipTones = {\n success: { background: \"var(--success-bg)\", color: \"var(--success-text)\" },\n warning: { background: \"var(--warning-bg)\", color: \"var(--warning-text)\" },\n neutral: { background: \"var(--bg-hover)\", color: \"var(--text-body)\" },\n info: { background: \"var(--info-bg)\", color: \"var(--action-primary)\" },\n danger: { background: \"var(--danger-bg)\", color: \"var(--danger-text)\" },\n};\n\n/** Tinted bulk-action chip (\"Mark as New\", \"Mark as Overwrite\", \"Skip Selected\"). */\nexport function ActionChip({ tone = \"neutral\", children, onClick, style }) {\n const [hover, setHover] = React.useState(false);\n return (\n <button type=\"button\" onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}\n style={{ height: 30, padding: \"0 12px\", borderRadius: \"var(--radius-md)\", border: \"none\", cursor: \"pointer\", fontFamily: \"var(--font-sans)\", fontWeight: \"var(--weight-medium)\", fontSize: \"var(--text-sm)\", lineHeight: \"var(--leading-sm)\", display: \"inline-flex\", alignItems: \"center\", filter: hover ? \"brightness(1.06) saturate(1.05)\" : \"none\", transition: \"var(--t-hover),filter var(--dur-fast) var(--ease-out)\", ...chipTones[tone], ...style }}>\n {children}\n </button>\n );\n}\n","buttons/ActionChip.vue":"<script setup>\nimport { ref, computed } from 'vue'\nconst chipTones = {\n success: { background: 'var(--success-bg)', color: 'var(--success-text)' },\n warning: { background: 'var(--warning-bg)', color: 'var(--warning-text)' },\n neutral: { background: 'var(--bg-hover)', color: 'var(--text-body)' },\n info: { background: 'var(--info-bg)', color: 'var(--action-primary)' },\n danger: { background: 'var(--danger-bg)', color: 'var(--danger-text)' },\n}\n// Tinted bulk-action chip (\"Mark as New\", \"Mark as Overwrite\", \"Skip Selected\").\nconst props = defineProps({ tone: { type: String, default: 'neutral' }, style: Object })\ndefineEmits(['click'])\nconst hover = ref(false)\nconst s = computed(() => ({ height: 30, padding: '0 12px', borderRadius: 'var(--radius-md)', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--text-sm)', lineHeight: 'var(--leading-sm)', display: 'inline-flex', alignItems: 'center', filter: hover.value ? 'brightness(1.06) saturate(1.05)' : 'none', transition: 'var(--t-hover),filter var(--dur-fast) var(--ease-out)', ...chipTones[props.tone], ...props.style }))\n</script>\n<template>\n <button type=\"button\" @click=\"$emit('click')\" @mouseenter=\"hover = true\" @mouseleave=\"hover = false\" :style=\"s\"><slot /></button>\n</template>\n","buttons/Button.jsx":"import React from \"react\";\nimport { Icon } from \"../icons/Icon.jsx\";\n\nconst btnBase = { display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\", gap: 6, fontFamily: \"var(--font-sans)\", fontWeight: \"var(--weight-regular)\", fontSize: \"var(--text-base)\", lineHeight: \"var(--leading-base)\", letterSpacing: \"var(--tracking-base)\", border: \"1px solid transparent\", cursor: \"pointer\", whiteSpace: \"nowrap\", boxSizing: \"border-box\", background: \"transparent\", transition: \"var(--t-hover)\" };\n\nconst variants = {\n primary: { background: \"var(--action-primary)\", color: \"var(--on-accent)\" },\n dark: { background: \"var(--action-dark)\", color: \"var(--action-dark-fg)\" },\n outline: { background: \"var(--bg-surface)\", color: \"var(--text-body)\", borderColor: \"var(--border-control)\" },\n ghost: { color: \"var(--text-body)\" },\n \"primary-soft\": { background: \"var(--soft-bg)\", color: \"var(--action-primary)\", borderColor: \"var(--soft-border)\" },\n danger: { background: \"var(--danger)\", color: \"var(--on-accent)\" },\n \"danger-soft\": { background: \"var(--danger-bg)\", color: \"var(--danger-text)\" },\n text: { color: \"var(--text-secondary)\", padding: \"0\", height: \"auto\" },\n};\nconst hovers = {\n primary: \"var(--action-primary-hover)\", dark: \"var(--action-dark-hover)\",\n outline: \"var(--bg-hover)\", ghost: \"var(--bg-hover)\", \"primary-soft\": \"var(--soft-hover)\",\n danger: \"var(--danger-text)\", \"danger-soft\": \"var(--danger-bg)\",\n};\n/** Press (mouse-down) fills — one step past hover. */\nconst presses = {\n primary: \"var(--action-primary-active)\", dark: \"var(--action-dark-active)\",\n outline: \"var(--bg-press)\", ghost: \"var(--bg-press)\", \"primary-soft\": \"var(--soft-active)\",\n danger: \"var(--danger-active)\", \"danger-soft\": \"var(--danger-soft-active)\",\n};\n/** Variants that change text color (+ underline) on hover instead of a background wash. */\nconst colorHoverVariants = { text: \"var(--text-heading)\" };\nconst sizes = {\n sm: { height: 30, padding: \"6px 12px\", fontSize: \"var(--text-sm)\", lineHeight: \"var(--leading-sm)\", letterSpacing: 0, borderRadius: \"var(--radius-md)\" },\n md: { height: 32, padding: \"6px 12px\", borderRadius: \"var(--radius-md)\" },\n lg: { height: 35.5, padding: \"8px 16px\", fontWeight: \"var(--weight-medium)\", borderRadius: \"var(--radius-lg)\" },\n};\nconst iconOnlyPad = { sm: 0, md: 0, lg: 0 };\nconst iconOnlyBox = { sm: 30, md: 32, lg: 36 };\n\nfunction Spinner({ size, color }) {\n return <span style={{ display: \"inline-block\", width: size, height: size, borderRadius: \"var(--radius-full)\", border: \"2px solid currentColor\", borderTopColor: \"transparent\", opacity: .9, color, animation: \"kb-spin .7s linear infinite\", flexShrink: 0 }} />;\n}\n\n/** Keybricks button. variant: primary | dark | outline | ghost | primary-soft | danger | danger-soft | text; size: sm | md | lg. Interaction states: hover (one step darker) · press (two steps, set via mouse-down) · keyboard focus ring · loading · disabled. */\nexport function Button({ variant = \"primary\", size = \"md\", icon, iconSize, iconPosition = \"left\", medium, disabled, loading, fullWidth, iconOnly, label, pressed, focused, children, style, onClick, ...rest }) {\n const [hover, setHover] = React.useState(false);\n const [press, setPress] = React.useState(false);\n const [focus, setFocus] = React.useState(false);\n const busy = disabled || loading;\n const isPressed = press || pressed;\n const isFocused = focus || focused;\n const s = {\n ...btnBase, ...sizes[size], ...variants[variant],\n ...(medium ? { fontWeight: \"var(--weight-medium)\" } : null),\n ...(fullWidth ? { width: \"100%\" } : null),\n ...(iconOnly ? { width: iconOnlyBox[size], padding: iconOnlyPad[size], gap: 0 } : null),\n ...(busy ? { opacity: .55, cursor: \"default\" } : null),\n ...style,\n };\n if (!busy) {\n if (colorHoverVariants[variant]) {\n if (hover || isPressed) { s.color = colorHoverVariants[variant]; s.textDecoration = \"underline\"; }\n if (isPressed) s.opacity = .7;\n } else if (isPressed) {\n s.background = presses[variant];\n } else if (hover) {\n s.background = hovers[variant];\n }\n if (isFocused) s.boxShadow = \"var(--ring-focus)\";\n }\n const iSize = iconSize || (size === \"sm\" ? 12 : 14);\n const leading = loading ? <Spinner size={iSize} color={s.color} /> : (icon && iconPosition === \"left\" ? <Icon name={icon} size={iSize} /> : null);\n const trailing = !loading && icon && iconPosition === \"right\" ? <Icon name={icon} size={iSize} /> : null;\n return (\n <button type=\"button\" data-press=\"own\" style={s} disabled={busy} aria-label={iconOnly ? label : undefined} onClick={onClick}\n onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}\n onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}\n onKeyDown={(e) => { if (e.key === \" \" || e.key === \"Enter\") setPress(true); }} onKeyUp={() => setPress(false)}\n onFocus={(e) => { try { setFocus(e.target.matches(\":focus-visible\")); } catch (err) { setFocus(true); } }} onBlur={() => setFocus(false)} {...rest}>\n {leading}\n {iconOnly ? null : children}\n {trailing}\n </button>\n );\n}\n\n/** Attached row of Buttons sharing one outline (segmented action group). Children should be <Button variant=\"outline\"> or similar. */\nexport function ButtonGroup({ children, style }) {\n const items = React.Children.toArray(children);\n return (\n <div style={{ display: \"inline-flex\", ...style }}>\n {items.map((child, i) => React.cloneElement(child, {\n key: i,\n style: {\n ...(child.props.style || {}),\n borderRadius: 0,\n ...(i === 0 ? { borderTopLeftRadius: \"var(--radius-md)\", borderBottomLeftRadius: \"var(--radius-md)\" } : null),\n ...(i === items.length - 1 ? { borderTopRightRadius: \"var(--radius-md)\", borderBottomRightRadius: \"var(--radius-md)\" } : null),\n marginLeft: i === 0 ? 0 : -1,\n },\n }))}\n </div>\n );\n}\n","buttons/Button.vue":"<script setup>\nimport { computed, ref } from 'vue'\nimport Icon from '../icons/Icon.vue'\n\nconst btnBase = { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6, fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-regular)', fontSize: 'var(--text-base)', lineHeight: 'var(--leading-base)', letterSpacing: 'var(--tracking-base)', border: '1px solid transparent', cursor: 'pointer', whiteSpace: 'nowrap', boxSizing: 'border-box', background: 'transparent', transition: 'var(--t-hover)' }\nconst variants = {\n primary: { background: 'var(--action-primary)', color: 'var(--on-accent)' },\n dark: { background: 'var(--action-dark)', color: 'var(--action-dark-fg)' },\n outline: { background: 'var(--bg-surface)', color: 'var(--text-body)', borderColor: 'var(--border-control)' },\n ghost: { color: 'var(--text-body)' },\n 'primary-soft': { background: 'var(--soft-bg)', color: 'var(--action-primary)', borderColor: 'var(--soft-border)' },\n danger: { background: 'var(--danger)', color: 'var(--on-accent)' },\n 'danger-soft': { background: 'var(--danger-bg)', color: 'var(--danger-text)' },\n text: { color: 'var(--text-secondary)', padding: '0', height: 'auto' },\n}\nconst hovers = { primary: 'var(--action-primary-hover)', dark: 'var(--action-dark-hover)', outline: 'var(--bg-hover)', ghost: 'var(--bg-hover)', 'primary-soft': 'var(--soft-hover)', danger: 'var(--danger-text)', 'danger-soft': 'var(--danger-bg)' }\nconst presses = { primary: 'var(--action-primary-active)', dark: 'var(--action-dark-active)', outline: 'var(--bg-press)', ghost: 'var(--bg-press)', 'primary-soft': 'var(--soft-active)', danger: 'var(--danger-active)', 'danger-soft': 'var(--danger-soft-active)' }\nconst colorHoverVariants = { text: 'var(--text-heading)' }\nconst sizes = {\n sm: { height: 30, padding: '6px 12px', fontSize: 'var(--text-sm)', lineHeight: 'var(--leading-sm)', letterSpacing: 0, borderRadius: 'var(--radius-md)' },\n md: { height: 32, padding: '6px 12px', borderRadius: 'var(--radius-md)' },\n lg: { height: 35.5, padding: '8px 16px', fontWeight: 'var(--weight-medium)', borderRadius: 'var(--radius-lg)' },\n}\nconst iconOnlyPad = { sm: 0, md: 0, lg: 0 }\nconst iconOnlyBox = { sm: 30, md: 32, lg: 36 }\n\n// Button — variant: primary | dark | outline | ghost | primary-soft | danger | danger-soft | text; size: sm | md | lg.\nconst props = defineProps({\n variant: { type: String, default: 'primary' }, size: { type: String, default: 'md' },\n icon: String, iconSize: Number, iconPosition: { type: String, default: 'left' },\n medium: Boolean, disabled: Boolean, loading: Boolean, fullWidth: Boolean, iconOnly: Boolean,\n label: String, pressed: Boolean, focused: Boolean, style: Object,\n})\ndefineEmits(['click'])\nconst hover = ref(false), press = ref(false), focus = ref(false)\nconst busy = computed(() => props.disabled || props.loading)\nconst isPressed = computed(() => press.value || props.pressed)\nconst isFocused = computed(() => focus.value || props.focused)\nconst s = computed(() => {\n const base = { ...btnBase, ...sizes[props.size], ...variants[props.variant],\n ...(props.medium ? { fontWeight: 'var(--weight-medium)' } : null),\n ...(props.fullWidth ? { width: '100%' } : null),\n ...(props.iconOnly ? { width: iconOnlyBox[props.size], padding: iconOnlyPad[props.size], gap: 0 } : null),\n ...(busy.value ? { opacity: .55, cursor: 'default' } : null), ...props.style }\n if (!busy.value) {\n if (colorHoverVariants[props.variant]) {\n if (hover.value || isPressed.value) { base.color = colorHoverVariants[props.variant]; base.textDecoration = 'underline' }\n if (isPressed.value) base.opacity = .7\n } else if (isPressed.value) base.background = presses[props.variant]\n else if (hover.value) base.background = hovers[props.variant]\n if (isFocused.value) base.boxShadow = 'var(--ring-focus)'\n }\n return base\n})\nconst iSize = computed(() => props.iconSize || (props.size === 'sm' ? 12 : 14))\n</script>\n<template>\n <button type=\"button\" data-press=\"own\" :style=\"s\" :disabled=\"busy\" :aria-label=\"iconOnly ? label : undefined\"\n @click=\"$emit('click')\" @mouseenter=\"hover = true\" @mouseleave=\"hover = false; press = false\"\n @mousedown=\"press = true\" @mouseup=\"press = false\" @keydown.enter=\"press = true\" @keydown.space=\"press = true\" @keyup=\"press = false\"\n @focus=\"focus = $event.target.matches(':focus-visible')\" @blur=\"focus = false\">\n <span v-if=\"loading\" :style=\"{ display: 'inline-block', width: iSize, height: iSize, borderRadius: 'var(--radius-full)', border: '2px solid currentColor', borderTopColor: 'transparent', opacity: .9, animation: 'kb-spin .7s linear infinite', flexShrink: 0 }\" />\n <Icon v-else-if=\"icon && iconPosition === 'left'\" :name=\"icon\" :size=\"iSize\" />\n <slot v-if=\"!iconOnly\" />\n <Icon v-if=\"!loading && icon && iconPosition === 'right'\" :name=\"icon\" :size=\"iSize\" />\n </button>\n</template>\n\n<!-- ButtonGroup — attached row of Buttons sharing one outline (segmented action group). -->\n<!--\n<script setup name=\"ButtonGroup\">\nimport { useSlots, computed } from 'vue'\nconst props = defineProps({ style: Object })\nconst slots = useSlots()\nconst items = computed(() => slots.default ? slots.default() : [])\n</script>\n<template>\n <div :style=\"{ display: 'inline-flex', ...style }\">\n <template v-for=\"(child, i) in items\" :key=\"i\">\n <component :is=\"child\" :style=\"{ borderRadius: 0,\n ...(i === 0 ? { borderTopLeftRadius: 'var(--radius-md)', borderBottomLeftRadius: 'var(--radius-md)' } : null),\n ...(i === items.length - 1 ? { borderTopRightRadius: 'var(--radius-md)', borderBottomRightRadius: 'var(--radius-md)' } : null),\n marginLeft: i === 0 ? 0 : -1 }\" />\n </template>\n </div>\n</template>\n-->\n","buttons/IconButton.jsx":"import React from \"react\";\nimport { Icon } from \"../icons/Icon.jsx\";\n\nconst ibSizes = { xs: { box: 22, icon: 14, radius: \"var(--radius-md)\" }, sm: { box: 26, icon: 14, radius: \"var(--radius-sm)\" }, md: { box: 28, icon: 16, radius: \"var(--radius-md)\" }, lg: { box: 34, icon: 18, radius: \"var(--radius-md)\" } };\n\n/** Square ghost icon button (toolbar/back/bell/view toggles). size: xs 22 | sm 26 | md 28 | lg 34. danger tints red; loading shows a spinner and disables interaction. States: hover · press · keyboard focus ring · active (persistent toggle-on) · disabled. */\nexport function IconButton({ icon, size = \"md\", active, muted, danger, disabled, loading, label, pressed, focused, style, onClick, ...rest }) {\n const [hover, setHover] = React.useState(false);\n const [press, setPress] = React.useState(false);\n const [focus, setFocus] = React.useState(false);\n const t = ibSizes[size];\n const busy = disabled || loading;\n const isPressed = (press || pressed) && !busy;\n const color = danger ? \"var(--danger)\" : muted ? \"var(--text-muted)\" : \"var(--text-body)\";\n const bg = isPressed ? (danger ? \"var(--danger-soft-active)\" : \"var(--bg-press)\")\n : active ? \"var(--bg-active)\"\n : hover && !busy ? (danger ? \"var(--danger-bg)\" : \"var(--bg-hover)\") : \"transparent\";\n return (\n <button type=\"button\" data-press=\"own\" aria-label={label} disabled={busy} onClick={onClick}\n onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}\n onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}\n onKeyDown={(e) => { if (e.key === \" \" || e.key === \"Enter\") setPress(true); }} onKeyUp={() => setPress(false)}\n onFocus={(e) => { try { setFocus(e.target.matches(\":focus-visible\")); } catch (err) { setFocus(true); } }} onBlur={() => setFocus(false)}\n style={{ width: t.box, height: t.box, borderRadius: t.radius, border: \"none\", cursor: busy ? \"default\" : \"pointer\", display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\", background: bg, color, opacity: busy ? .5 : 1, boxShadow: (focus || focused) && !busy ? \"var(--ring-focus)\" : \"none\", transition: \"var(--t-hover)\", padding: 0, flexShrink: 0, ...style }} {...rest}>\n {loading ? <span style={{ display: \"inline-block\", width: t.icon, height: t.icon, borderRadius: \"var(--radius-full)\", border: \"2px solid currentColor\", borderTopColor: \"transparent\", animation: \"kb-spin .7s linear infinite\" }} /> : <Icon name={icon} size={t.icon} />}\n </button>\n );\n}\n","buttons/IconButton.vue":"<script setup>\nimport { ref, computed } from 'vue'\nimport Icon from '../icons/Icon.vue'\nconst ibSizes = { xs: { box: 22, icon: 14, radius: 'var(--radius-md)' }, sm: { box: 26, icon: 14, radius: 'var(--radius-sm)' }, md: { box: 28, icon: 16, radius: 'var(--radius-md)' }, lg: { box: 34, icon: 18, radius: 'var(--radius-md)' } }\n// Square ghost icon button (toolbar/back/bell/view toggles). size: xs 22 | sm 26 | md 28 | lg 34.\nconst props = defineProps({ icon: String, size: { type: String, default: 'md' }, active: Boolean, muted: Boolean, danger: Boolean, disabled: Boolean, loading: Boolean, label: String, pressed: Boolean, focused: Boolean, style: Object })\ndefineEmits(['click'])\nconst hover = ref(false), press = ref(false), focus = ref(false)\nconst t = computed(() => ibSizes[props.size])\nconst busy = computed(() => props.disabled || props.loading)\nconst isPressed = computed(() => (press.value || props.pressed) && !busy.value)\nconst color = computed(() => props.danger ? 'var(--danger)' : props.muted ? 'var(--text-muted)' : 'var(--text-body)')\nconst bg = computed(() => isPressed.value ? (props.danger ? 'var(--danger-soft-active)' : 'var(--bg-press)') : props.active ? 'var(--bg-active)' : (hover.value && !busy.value ? (props.danger ? 'var(--danger-bg)' : 'var(--bg-hover)') : 'transparent'))\nconst s = computed(() => ({ width: t.value.box, height: t.value.box, borderRadius: t.value.radius, border: 'none', cursor: busy.value ? 'default' : 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: bg.value, color: color.value, opacity: busy.value ? .5 : 1, boxShadow: (focus.value || props.focused) && !busy.value ? 'var(--ring-focus)' : 'none', transition: 'var(--t-hover)', padding: 0, flexShrink: 0, ...props.style }))\n</script>\n<template>\n <button type=\"button\" data-press=\"own\" :aria-label=\"label\" :disabled=\"busy\" @click=\"$emit('click')\" @mouseenter=\"hover = true\" @mouseleave=\"hover = false; press = false\" @mousedown=\"press = true\" @mouseup=\"press = false\" @keydown.enter=\"press = true\" @keydown.space=\"press = true\" @keyup=\"press = false\" @focus=\"focus = $event.target.matches(':focus-visible')\" @blur=\"focus = false\" :style=\"s\">\n <span v-if=\"loading\" :style=\"{ display: 'inline-block', width: t.icon, height: t.icon, borderRadius: 'var(--radius-full)', border: '2px solid currentColor', borderTopColor: 'transparent', animation: 'kb-spin .7s linear infinite' }\" />\n <Icon v-else :name=\"icon\" :size=\"t.icon\" />\n </button>\n</template>\n"});
|