@stephen-netu/design-system 0.1.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 (204) hide show
  1. package/README.md +66 -0
  2. package/package.json +130 -0
  3. package/src/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte +221 -0
  4. package/src/b0-app-shell/clarification-overlay/index.ts +1 -0
  5. package/src/b0-app-shell/command-bar/CommandBar.svelte +565 -0
  6. package/src/b0-app-shell/index.ts +14 -0
  7. package/src/base.css +152 -0
  8. package/src/d0-data-viz/BarChart.svelte +236 -0
  9. package/src/d0-data-viz/CheckpointBar.svelte +574 -0
  10. package/src/d0-data-viz/CheckpointPill.svelte +297 -0
  11. package/src/d0-data-viz/MetricCard.svelte +159 -0
  12. package/src/d0-data-viz/SparkLine.svelte +66 -0
  13. package/src/d0-data-viz/StorageMap.svelte +182 -0
  14. package/src/d0-data-viz/Timeline.svelte +188 -0
  15. package/src/d0-data-viz/checkpoint-types.ts +162 -0
  16. package/src/d0-data-viz/d0-tokens.css +32 -0
  17. package/src/d0-data-viz/index.ts +58 -0
  18. package/src/d0-data-viz/storage-map-types.ts +142 -0
  19. package/src/d0-data-viz/theme-integration.ts +134 -0
  20. package/src/d0-data-viz/types.ts +53 -0
  21. package/src/demos/BspSizingInfographic.svelte +386 -0
  22. package/src/demos/BspZoneDemo.svelte +255 -0
  23. package/src/demos/ControlRoomDemo.svelte +570 -0
  24. package/src/demos/NodepadBlocksShowcase.svelte +189 -0
  25. package/src/demos/index.ts +7 -0
  26. package/src/editor/CodeEditor.svelte +188 -0
  27. package/src/editor/FindReplaceDialog.svelte +516 -0
  28. package/src/editor/MarkdownEditor.svelte +660 -0
  29. package/src/editor/index.ts +2 -0
  30. package/src/entity-graph-view/WorldView.svelte +171 -0
  31. package/src/entity-graph-view/index.ts +6 -0
  32. package/src/entity-graph-view/types.ts +364 -0
  33. package/src/epistemic/index.ts +2 -0
  34. package/src/epistemic/types.ts +134 -0
  35. package/src/epistemic/utils.ts +32 -0
  36. package/src/f0-forms/checkbox/Checkbox.svelte +158 -0
  37. package/src/f0-forms/field/FormField.svelte +91 -0
  38. package/src/f0-forms/index.ts +11 -0
  39. package/src/f0-forms/radio/RadioGroup.svelte +192 -0
  40. package/src/f0-forms/search/SearchBar.svelte +99 -0
  41. package/src/f0-forms/select/Select.svelte +198 -0
  42. package/src/f0-forms/textarea/TextArea.svelte +170 -0
  43. package/src/f0-forms/toggle/FormToggle.svelte +147 -0
  44. package/src/f0-forms/validation/validate.ts +47 -0
  45. package/src/fabric/ai/ChatPanel.svelte +648 -0
  46. package/src/fabric/ai/index.ts +11 -0
  47. package/src/fabric/data/index.ts +21 -0
  48. package/src/fabric/feedback/StatusBar.svelte +274 -0
  49. package/src/fabric/feedback/ToastContainer.svelte +122 -0
  50. package/src/fabric/feedback/index.ts +14 -0
  51. package/src/fabric/index.ts +37 -0
  52. package/src/fabric/input/CommandBar.svelte +79 -0
  53. package/src/fabric/input/KeyboardShortcuts.svelte +388 -0
  54. package/src/fabric/input/index.ts +12 -0
  55. package/src/fabric/layout/GlassBox.svelte +193 -0
  56. package/src/fabric/layout/KanbanBoard.svelte +158 -0
  57. package/src/fabric/layout/KanbanCard.svelte +226 -0
  58. package/src/fabric/layout/KanbanColumn.svelte +278 -0
  59. package/src/fabric/layout/index.ts +17 -0
  60. package/src/fabric/navigation/ActivityRail.svelte +271 -0
  61. package/src/fabric/navigation/index.ts +11 -0
  62. package/src/g0-geo/SovereignMap.svelte +149 -0
  63. package/src/g0-geo/index.ts +2 -0
  64. package/src/index.ts +68 -0
  65. package/src/l0-layout/block-writer/BlockConnectionLines.svelte +98 -0
  66. package/src/l0-layout/block-writer/BlockContent.svelte +213 -0
  67. package/src/l0-layout/block-writer/BlockHeader.svelte +230 -0
  68. package/src/l0-layout/block-writer/BlockItem.svelte +177 -0
  69. package/src/l0-layout/block-writer/BlockWriter.svelte +219 -0
  70. package/src/l0-layout/block-writer/block-writer-types.ts +63 -0
  71. package/src/l0-layout/block-writer/index.ts +24 -0
  72. package/src/l0-layout/block-writer/markdown.ts +110 -0
  73. package/src/l0-layout/chat-view/ChatViewLayout.svelte +61 -0
  74. package/src/l0-layout/epistemic/AllayDetailPanel.svelte +113 -0
  75. package/src/l0-layout/epistemic/AssayDetailPanel.svelte +164 -0
  76. package/src/l0-layout/epistemic/AvenueTrace.svelte +253 -0
  77. package/src/l0-layout/epistemic/KnowledgeDetailPanel.svelte +204 -0
  78. package/src/l0-layout/epistemic/ParadigmLens.svelte +170 -0
  79. package/src/l0-layout/epistemic/ProvenanceChain.svelte +164 -0
  80. package/src/l0-layout/epistemic/TrustView.svelte +195 -0
  81. package/src/l0-layout/epistemic/index.ts +7 -0
  82. package/src/l0-layout/grove/AccordCard.svelte +156 -0
  83. package/src/l0-layout/grove/GroveCard.svelte +197 -0
  84. package/src/l0-layout/grove/MemberBadge.svelte +96 -0
  85. package/src/l0-layout/grove/MemberList.svelte +59 -0
  86. package/src/l0-layout/grove/grove-types.ts +29 -0
  87. package/src/l0-layout/grove/index.ts +14 -0
  88. package/src/l0-layout/index.ts +45 -0
  89. package/src/l0-layout/kanban/KanbanBoard.svelte +71 -0
  90. package/src/l0-layout/kanban/KanbanCard.svelte +276 -0
  91. package/src/l0-layout/kanban/KanbanColumn.svelte +198 -0
  92. package/src/l0-layout/kanban/KanbanViewLayout.svelte +61 -0
  93. package/src/l0-layout/workspace/WorkspaceLayout.svelte +93 -0
  94. package/src/n0-node-graph/GraphEditor.svelte +342 -0
  95. package/src/n0-node-graph/GraphHistory.svelte +122 -0
  96. package/src/n0-node-graph/Node.svelte +269 -0
  97. package/src/n0-node-graph/NodeCanvas.svelte +187 -0
  98. package/src/n0-node-graph/NodeEdge.svelte +152 -0
  99. package/src/n0-node-graph/NodePalette.svelte +318 -0
  100. package/src/n0-node-graph/NodePort.svelte +128 -0
  101. package/src/n0-node-graph/index.ts +33 -0
  102. package/src/n0-node-graph/n0-tokens.css +29 -0
  103. package/src/n0-node-graph/node-port-types.ts +19 -0
  104. package/src/n0-node-graph/types.ts +96 -0
  105. package/src/n0-node-graph/validate.test.ts +722 -0
  106. package/src/n0-node-graph/validate.ts +371 -0
  107. package/src/n1-flow-canvas/FlowCanvas.svelte +202 -0
  108. package/src/n1-flow-canvas/graph-state.svelte.ts +95 -0
  109. package/src/n1-flow-canvas/index.ts +21 -0
  110. package/src/n1-flow-canvas/layout.ts +118 -0
  111. package/src/n1-flow-canvas/layout.worker.ts +128 -0
  112. package/src/n1-flow-canvas/types.ts +102 -0
  113. package/src/n1-flow-canvas/utils.ts +146 -0
  114. package/src/n2-manifold-disk/ManifoldDisk.svelte +314 -0
  115. package/src/n2-manifold-disk/index.ts +6 -0
  116. package/src/n2-manifold-disk/poincare.ts +184 -0
  117. package/src/n3-force-graph/ForceGraph.svelte +180 -0
  118. package/src/n3-force-graph/GraphTooltip.svelte +99 -0
  119. package/src/n3-force-graph/animated-edge.ts +107 -0
  120. package/src/n3-force-graph/health-node.ts +128 -0
  121. package/src/n3-force-graph/index.ts +31 -0
  122. package/src/n3-force-graph/types.ts +94 -0
  123. package/src/n4-adaptive-manifold/AdaptiveManifold.svelte +1165 -0
  124. package/src/n4-adaptive-manifold/DetailCard.svelte +212 -0
  125. package/src/n4-adaptive-manifold/SuggestionIndicator.svelte +91 -0
  126. package/src/n4-adaptive-manifold/classifier.ts +139 -0
  127. package/src/n4-adaptive-manifold/index.ts +45 -0
  128. package/src/n4-adaptive-manifold/n4-tokens.css +155 -0
  129. package/src/n4-adaptive-manifold/orchestrator.ts +301 -0
  130. package/src/n4-adaptive-manifold/phase-theme.ts +92 -0
  131. package/src/n4-adaptive-manifold/pinnacle-events.ts +135 -0
  132. package/src/n4-adaptive-manifold/providers/gravitational-provider.ts +191 -0
  133. package/src/n4-adaptive-manifold/providers/manifold-provider.ts +276 -0
  134. package/src/n4-adaptive-manifold/transition.ts +90 -0
  135. package/src/n4-adaptive-manifold/types.ts +313 -0
  136. package/src/p0-primitives/index.ts +6 -0
  137. package/src/p0-primitives/tokens/control-room.css +309 -0
  138. package/src/p0-primitives/tokens/index.ts +6 -0
  139. package/src/p0-primitives/tokens/tokens.css +140 -0
  140. package/src/p0-primitives/tokens/tokens.json +132 -0
  141. package/src/p0-primitives/types/index.ts +123 -0
  142. package/src/p0-primitives/types/plugin-types.ts +74 -0
  143. package/src/p0-primitives/utils/index.ts +39 -0
  144. package/src/platform/hud-protocol.ts +20 -0
  145. package/src/platform/index.ts +3 -0
  146. package/src/s0-state/create-store.ts +84 -0
  147. package/src/s0-state/derived.ts +41 -0
  148. package/src/s0-state/index.ts +6 -0
  149. package/src/showcase/Showcase.svelte +401 -0
  150. package/src/spatial/BspTilingCanvas.svelte +232 -0
  151. package/src/spatial/ForceCanvas.svelte +289 -0
  152. package/src/spatial/LodRenderer.svelte +334 -0
  153. package/src/spatial/SnapZoomCamera.svelte +185 -0
  154. package/src/spatial/ZoneTiler.svelte +311 -0
  155. package/src/spatial/camera-types.ts +45 -0
  156. package/src/spatial/content-proportional-bsp.ts +253 -0
  157. package/src/spatial/force-canvas-types.ts +102 -0
  158. package/src/spatial/index.ts +15 -0
  159. package/src/spatial/lod-types.ts +70 -0
  160. package/src/spatial/zone-tiler-types.ts +177 -0
  161. package/src/stores/vaultStore.svelte +14 -0
  162. package/src/t0-transport/connection.ts +34 -0
  163. package/src/t0-transport/error.ts +37 -0
  164. package/src/t0-transport/events.ts +50 -0
  165. package/src/t0-transport/index.ts +6 -0
  166. package/src/t0-transport/invoke.ts +30 -0
  167. package/src/tauri/index.ts +13 -0
  168. package/src/u0-primitives/allay-gauge/AllayGauge.svelte +90 -0
  169. package/src/u0-primitives/allay-gauge/index.ts +1 -0
  170. package/src/u0-primitives/animated-icon/AnimatedIcon.svelte +273 -0
  171. package/src/u0-primitives/animated-icon/README.md +53 -0
  172. package/src/u0-primitives/animated-icon/index.ts +31 -0
  173. package/src/u0-primitives/assay-badge/AssayBadge.svelte +121 -0
  174. package/src/u0-primitives/assay-badge/AssaySignalBar.svelte +83 -0
  175. package/src/u0-primitives/assay-badge/index.ts +2 -0
  176. package/src/u0-primitives/avatar/Avatar.svelte +177 -0
  177. package/src/u0-primitives/badge/Badge.svelte +149 -0
  178. package/src/u0-primitives/button/Button.svelte +304 -0
  179. package/src/u0-primitives/card/Card.svelte +182 -0
  180. package/src/u0-primitives/dropdown/Dropdown.svelte +305 -0
  181. package/src/u0-primitives/expert-badge/ExpertBadge.svelte +89 -0
  182. package/src/u0-primitives/expert-badge/index.ts +1 -0
  183. package/src/u0-primitives/index.ts +35 -0
  184. package/src/u0-primitives/input/Input.svelte +237 -0
  185. package/src/u0-primitives/modal/Modal.svelte +331 -0
  186. package/src/u0-primitives/modal/index.ts +1 -0
  187. package/src/u0-primitives/spinner/Spinner.svelte +129 -0
  188. package/src/u0-primitives/tabs/Tabs.svelte +225 -0
  189. package/src/u0-primitives/tabs/tabs-types.ts +11 -0
  190. package/src/u0-primitives/toggle/Toggle.svelte +161 -0
  191. package/src/u0-primitives/tooltip/Tooltip.svelte +234 -0
  192. package/src/v0-diagrams/DiagramPanel.svelte +68 -0
  193. package/src/v0-diagrams/MarkmapDiagram.svelte +56 -0
  194. package/src/v0-diagrams/MermaidDiagram.svelte +53 -0
  195. package/src/v0-diagrams/index.ts +4 -0
  196. package/src/v0-diagrams/types.ts +28 -0
  197. package/src/v0-diagrams/v0-tokens.css +6 -0
  198. package/src/vite-env.d.ts +7 -0
  199. package/src/x0-enchanted-blocks/ENCHANTED_BLOCKS_SPEC.md +457 -0
  200. package/src/x0-enchanted-blocks/components/EnchantedBlock.svelte +485 -0
  201. package/src/x0-enchanted-blocks/components/NodepadBlock.svelte +262 -0
  202. package/src/x0-enchanted-blocks/core/block-layout.ts +211 -0
  203. package/src/x0-enchanted-blocks/core/block-types.ts +227 -0
  204. package/src/x0-enchanted-blocks/index.ts +46 -0
package/src/base.css ADDED
@@ -0,0 +1,152 @@
1
+ /* @kos/design-system - Base Styles */
2
+ @import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:ital,wght@0,300..900;1,300..900&family=Outfit:wght@100..900&display=swap');
3
+ @import './p0-primitives/tokens/tokens.css';
4
+
5
+ /* --- Reset & Global --- */
6
+ *, *::before, *::after {
7
+ box-sizing: border-box;
8
+ margin: 0;
9
+ padding: 0;
10
+ }
11
+
12
+ html {
13
+ font-family: var(--font-sans);
14
+ font-size: 16px;
15
+ line-height: 1.5;
16
+ -webkit-font-smoothing: antialiased;
17
+ -moz-osx-font-smoothing: grayscale;
18
+ text-rendering: optimizeLegibility;
19
+ background-color: var(--color-bg-app);
20
+ color: var(--color-text-primary);
21
+ /* The design system defaults to dark mode */
22
+ color-scheme: dark;
23
+ }
24
+
25
+ [data-theme="light"], .theme-light {
26
+ color-scheme: light;
27
+ }
28
+
29
+ body {
30
+ width: 100vw;
31
+ height: 100vh;
32
+ overflow: hidden;
33
+ }
34
+
35
+ /* --- Scrollbars --- */
36
+ ::-webkit-scrollbar {
37
+ width: 8px;
38
+ height: 8px;
39
+ }
40
+
41
+ ::-webkit-scrollbar-track {
42
+ background: transparent;
43
+ }
44
+
45
+ ::-webkit-scrollbar-thumb {
46
+ background: rgba(184, 115, 51, 0.2); /* Brass tinted scrollbar */
47
+ border-radius: var(--radius-full);
48
+ border: 2px solid transparent;
49
+ background-clip: padding-box;
50
+ }
51
+
52
+ ::-webkit-scrollbar-thumb:hover {
53
+ background: var(--color-accent-subtle);
54
+ border: 1px solid transparent;
55
+ background-clip: padding-box;
56
+ }
57
+
58
+ /* --- Focus Management --- */
59
+ :focus-visible {
60
+ outline: 2px solid var(--color-accent);
61
+ outline-offset: 2px;
62
+ }
63
+
64
+ a {
65
+ color: var(--color-accent);
66
+ text-decoration: none;
67
+ transition: color var(--transition-fast);
68
+ }
69
+
70
+ a:hover {
71
+ color: var(--color-accent-hover);
72
+ }
73
+
74
+ /* --- Selection --- */
75
+ ::selection {
76
+ background-color: var(--color-accent-subtle);
77
+ color: var(--color-accent-hover);
78
+ }
79
+
80
+ /* --- Utility Classes --- */
81
+
82
+ /* Typography */
83
+ h1, .ds-text-h1 { font-family: var(--font-sans); font-size: var(--text-4xl); font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }
84
+ h2, .ds-text-h2 { font-family: var(--font-sans); font-size: var(--text-3xl); font-weight: 600; line-height: 1.2; letter-spacing: -0.01em; }
85
+ h3, .ds-text-h3 { font-family: var(--font-sans); font-size: var(--text-2xl); font-weight: 600; line-height: 1.3; }
86
+ h4, .ds-text-h4 { font-family: var(--font-sans); font-size: var(--text-xl); font-weight: 500; line-height: 1.4; }
87
+ h5, .ds-text-h5 { font-family: var(--font-sans); font-size: var(--text-lg); font-weight: 500; line-height: 1.4; }
88
+ h6, .ds-text-h6 { font-family: var(--font-sans); font-size: var(--text-base); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); }
89
+
90
+ p, .ds-text-body { font-size: var(--text-base); line-height: 1.6; color: var(--color-text-secondary); }
91
+ small, .ds-text-sm { font-size: var(--text-sm); }
92
+ .ds-text-xs { font-size: var(--text-xs); }
93
+ .ds-text-muted { color: var(--color-text-muted); }
94
+
95
+ code, pre {
96
+ font-family: var(--font-mono);
97
+ font-size: 0.9em;
98
+ background: var(--color-bg-panel-elevated);
99
+ padding: 0.2em 0.4em;
100
+ border-radius: var(--radius-sm);
101
+ color: var(--color-accent-hover);
102
+ }
103
+
104
+ /* Layout Primitives */
105
+ .ds-stack {
106
+ display: flex;
107
+ flex-direction: column;
108
+ }
109
+
110
+ .ds-stack-1 { gap: var(--space-1); }
111
+ .ds-stack-2 { gap: var(--space-2); }
112
+ .ds-stack-3 { gap: var(--space-3); }
113
+ .ds-stack-4 { gap: var(--space-4); }
114
+ .ds-stack-5 { gap: var(--space-5); }
115
+ .ds-stack-6 { gap: var(--space-6); }
116
+
117
+ .ds-flex { display: flex; }
118
+ .ds-flex-row { flex-direction: row; }
119
+ .ds-flex-col { flex-direction: column; }
120
+ .ds-items-center { align-items: center; }
121
+ .ds-justify-between { justify-content: space-between; }
122
+ .ds-justify-center { justify-content: center; }
123
+ .ds-flex-wrap { flex-wrap: wrap; }
124
+
125
+ .ds-grid {
126
+ display: grid;
127
+ }
128
+
129
+ .ds-canvas-grid {
130
+ background-image:
131
+ linear-gradient(var(--grid-line) 1px, transparent 1px),
132
+ linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
133
+ background-size: 40px 40px;
134
+ }
135
+
136
+ .ds-canvas-dots {
137
+ background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
138
+ background-size: 20px 20px;
139
+ }
140
+
141
+ /* Accessibility */
142
+ .sr-only {
143
+ position: absolute;
144
+ width: 1px;
145
+ height: 1px;
146
+ padding: 0;
147
+ margin: -1px;
148
+ overflow: hidden;
149
+ clip: rect(0, 0, 0, 0);
150
+ white-space: nowrap;
151
+ border-width: 0;
152
+ }
@@ -0,0 +1,236 @@
1
+ <script lang="ts">
2
+ import type { DataSeries } from './types';
3
+
4
+ interface BarChartProps {
5
+ series: DataSeries[];
6
+ width?: number;
7
+ height?: number;
8
+ orientation?: 'vertical' | 'horizontal';
9
+ showLabels?: boolean;
10
+ showGrid?: boolean;
11
+ }
12
+
13
+ let {
14
+ series,
15
+ width = 400,
16
+ height = 300,
17
+ orientation = 'vertical',
18
+ showLabels = true,
19
+ showGrid = true,
20
+ }: BarChartProps = $props();
21
+
22
+ const PADDING = { top: 16, right: 16, bottom: 32, left: 48 };
23
+ const GRID_LINES = 5;
24
+
25
+ let allPoints = $derived(series.flatMap((s) => s.data));
26
+
27
+ let maxValue = $derived(
28
+ allPoints.length > 0 ? Math.max(...allPoints.map((p) => p.value)) : 0
29
+ );
30
+
31
+ let chartWidth = $derived(width - PADDING.left - PADDING.right);
32
+ let chartHeight = $derived(height - PADDING.top - PADDING.bottom);
33
+
34
+ let gridValues = $derived(
35
+ Array.from({ length: GRID_LINES + 1 }, (_, i) =>
36
+ maxValue > 0 ? (maxValue / GRID_LINES) * i : 0
37
+ )
38
+ );
39
+
40
+ /** Flatten all points across series for bar layout. */
41
+ let flatBars = $derived.by(() => {
42
+ const bars: Array<{
43
+ label: string;
44
+ value: number;
45
+ color: string | undefined;
46
+ seriesIndex: number;
47
+ pointIndex: number;
48
+ }> = [];
49
+ for (let si = 0; si < series.length; si++) {
50
+ const s = series[si];
51
+ const seriesColor = s.color ?? undefined;
52
+ for (let pi = 0; pi < s.data.length; pi++) {
53
+ const pt = s.data[pi];
54
+ bars.push({
55
+ label: pt.label,
56
+ value: pt.value,
57
+ color: pt.color ?? seriesColor,
58
+ seriesIndex: si,
59
+ pointIndex: pi,
60
+ });
61
+ }
62
+ }
63
+ return bars;
64
+ });
65
+
66
+ let barGap = $derived(flatBars.length > 0
67
+ ? (orientation === 'vertical'
68
+ ? chartWidth / flatBars.length
69
+ : chartHeight / flatBars.length)
70
+ : 0
71
+ );
72
+
73
+ let barWidth = $derived(Math.max(barGap * 0.7, 2));
74
+
75
+ function barGeometry(index: number, value: number) {
76
+ const ratio = maxValue > 0 ? value / maxValue : 0;
77
+ if (orientation === 'vertical') {
78
+ const barH = chartHeight * ratio;
79
+ return {
80
+ x: PADDING.left + index * barGap + (barGap - barWidth) / 2,
81
+ y: PADDING.top + chartHeight - barH,
82
+ w: barWidth,
83
+ h: barH,
84
+ };
85
+ }
86
+ const barW = chartWidth * ratio;
87
+ return {
88
+ x: PADDING.left,
89
+ y: PADDING.top + index * barGap + (barGap - barWidth) / 2,
90
+ w: barW,
91
+ h: barWidth,
92
+ };
93
+ }
94
+ </script>
95
+
96
+ <svg
97
+ class="d0-bar-chart"
98
+ viewBox="0 0 {width} {height}"
99
+ xmlns="http://www.w3.org/2000/svg"
100
+ role="img"
101
+ aria-label="Bar chart"
102
+ >
103
+ <!-- Background -->
104
+ <rect
105
+ class="d0-chart-bg"
106
+ x={0}
107
+ y={0}
108
+ width={width}
109
+ height={height}
110
+ rx={6}
111
+ ry={6}
112
+ />
113
+
114
+ <!-- Grid lines -->
115
+ {#if showGrid}
116
+ {#each gridValues as gv, i}
117
+ {#if orientation === 'vertical'}
118
+ {@const gy = PADDING.top + chartHeight - (maxValue > 0 ? (gv / maxValue) * chartHeight : 0)}
119
+ <line
120
+ class="d0-grid-line"
121
+ x1={PADDING.left}
122
+ y1={gy}
123
+ x2={PADDING.left + chartWidth}
124
+ y2={gy}
125
+ />
126
+ {#if showLabels}
127
+ <text
128
+ class="d0-axis-label"
129
+ x={PADDING.left - 6}
130
+ y={gy + 4}
131
+ text-anchor="end"
132
+ >
133
+ {Math.round(gv)}
134
+ </text>
135
+ {/if}
136
+ {:else}
137
+ {@const gx = PADDING.left + (maxValue > 0 ? (gv / maxValue) * chartWidth : 0)}
138
+ <line
139
+ class="d0-grid-line"
140
+ x1={gx}
141
+ y1={PADDING.top}
142
+ x2={gx}
143
+ y2={PADDING.top + chartHeight}
144
+ />
145
+ {#if showLabels}
146
+ <text
147
+ class="d0-axis-label"
148
+ x={gx}
149
+ y={PADDING.top + chartHeight + 16}
150
+ text-anchor="middle"
151
+ >
152
+ {Math.round(gv)}
153
+ </text>
154
+ {/if}
155
+ {/if}
156
+ {/each}
157
+ {/if}
158
+
159
+ <!-- Bars -->
160
+ {#each flatBars as bar, idx (idx)}
161
+ {@const geo = barGeometry(idx, bar.value)}
162
+ <rect
163
+ class="d0-bar"
164
+ x={geo.x}
165
+ y={geo.y}
166
+ width={geo.w}
167
+ height={geo.h}
168
+ fill={bar.color ?? undefined}
169
+ rx={2}
170
+ ry={2}
171
+ >
172
+ <title>{bar.label}: {bar.value}</title>
173
+ </rect>
174
+
175
+ <!-- Bar labels -->
176
+ {#if showLabels}
177
+ {#if orientation === 'vertical'}
178
+ <text
179
+ class="d0-bar-label"
180
+ x={geo.x + geo.w / 2}
181
+ y={PADDING.top + chartHeight + 16}
182
+ text-anchor="middle"
183
+ >
184
+ {bar.label}
185
+ </text>
186
+ {:else}
187
+ <text
188
+ class="d0-bar-label"
189
+ x={PADDING.left - 6}
190
+ y={geo.y + geo.h / 2 + 4}
191
+ text-anchor="end"
192
+ >
193
+ {bar.label}
194
+ </text>
195
+ {/if}
196
+ {/if}
197
+ {/each}
198
+ </svg>
199
+
200
+ <style>
201
+ .d0-bar-chart {
202
+ display: block;
203
+ width: 100%;
204
+ height: auto;
205
+ }
206
+
207
+ .d0-chart-bg {
208
+ fill: var(--d0-chart-bg, #222);
209
+ }
210
+
211
+ .d0-grid-line {
212
+ stroke: var(--d0-chart-grid, rgba(184, 115, 51, 0.1));
213
+ stroke-width: 1;
214
+ }
215
+
216
+ .d0-axis-label {
217
+ fill: var(--d0-chart-text, #a09880);
218
+ font-family: var(--font-sans, system-ui, sans-serif);
219
+ font-size: 10px;
220
+ }
221
+
222
+ .d0-bar {
223
+ fill: var(--d0-chart-accent, #b87333);
224
+ transition: opacity 150ms ease;
225
+ }
226
+
227
+ .d0-bar:hover {
228
+ opacity: 0.8;
229
+ }
230
+
231
+ .d0-bar-label {
232
+ fill: var(--d0-chart-text, #a09880);
233
+ font-family: var(--font-sans, system-ui, sans-serif);
234
+ font-size: 10px;
235
+ }
236
+ </style>