@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
@@ -0,0 +1,255 @@
1
+ <script lang="ts">
2
+ // BSP Zone Demo — Working ZoneTiler with NodepadBlock content
3
+ // Demonstrates: h/j/k/l navigation, Ctrl+Shift+H/V splitting, draggable dividers
4
+
5
+ import ZoneTiler from '../spatial/ZoneTiler.svelte';
6
+ import NodepadBlock from '../x0-enchanted-blocks/components/NodepadBlock.svelte';
7
+ import { createDefaultBsp, splitZone, type BspNode, type ZoneLeaf, type ZoneRect, type SplitDirection } from '../spatial';
8
+ import type { EnchantedBlockData, BlockType } from '../x0-enchanted-blocks';
9
+
10
+ // Generate content for zones — 16+ varied contents
11
+ function generateContent(id: number): EnchantedBlockData {
12
+ const types: BlockType[] = ['task', 'idea', 'question', 'claim', 'reference', 'definition'];
13
+ const short = ['Short task.', 'Quick note.', 'Todo item.', 'Done.', 'Idea spark.', 'Reference link.'];
14
+ const medium = [
15
+ 'Medium complexity note that demonstrates how cards flow within a zone.',
16
+ 'Research on spatial canvas patterns and BSP tiling.',
17
+ 'Key insight: ZoneTiler creates clean divisions.',
18
+ 'Amethyst window manager approach to tiling.',
19
+ 'Nodepad natural flow concept adaptation.',
20
+ 'How do we measure content with Pretext?',
21
+ ];
22
+ const long = [
23
+ 'How do we integrate BSP tiling?\n\nKey points:\n- Binary space partitioning\n- Draggable dividers\n- Keyboard navigation\n- Content-adaptive zones',
24
+ 'BSP creates superior spatial organization.\n\nBenefits:\n- Clean divisions\n- Predictable layout\n- Keyboard navigation\n- Draggable dividers',
25
+ 'Research on content-proportional layouts.\n\nFindings:\n- Cards should size to content\n- Layout should adapt\n- No forced rectangles\n- Tight packing',
26
+ 'ZoneTiler implementation notes.\n\nFeatures:\n- h/j/k/l navigation\n- Ctrl+Shift+H/V splitting\n- Draggable dividers\n- Focus management',
27
+ ];
28
+
29
+ const pool = id % 3 === 0 ? long : id % 3 === 1 ? medium : short;
30
+ const content = pool[id % pool.length];
31
+
32
+ return {
33
+ id: `block-${String(id).padStart(3, '0')}`,
34
+ type: types[id % types.length],
35
+ content: content + (id > 15 ? ` [extra ${id - 15}]` : ''),
36
+ annotation: id % 4 === 0 ? 'Research' : undefined,
37
+ createdAt: Date.now(),
38
+ modifiedAt: Date.now(),
39
+ };
40
+ }
41
+
42
+ // Initialize with 16 zones in BSP tree
43
+ function initTree(): BspNode {
44
+ let t: BspNode = createDefaultBsp('zone-001', 'main');
45
+ // First level: split into 2 columns
46
+ t = splitZone(t, 'zone-001', 'horizontal',
47
+ { kind: 'leaf', id: 'zone-002', label: 'zone-002', privacyState: 'ouvert' }, 0.5);
48
+ // Second level: 4 zones
49
+ t = splitZone(t, 'zone-001', 'vertical',
50
+ { kind: 'leaf', id: 'zone-003', label: 'zone-003', privacyState: 'ouvert' }, 0.5);
51
+ t = splitZone(t, 'zone-002', 'vertical',
52
+ { kind: 'leaf', id: 'zone-004', label: 'zone-004', privacyState: 'ouvert' }, 0.5);
53
+ // Third level: 8 zones
54
+ t = splitZone(t, 'zone-003', 'horizontal',
55
+ { kind: 'leaf', id: 'zone-005', label: 'zone-005', privacyState: 'ouvert' }, 0.5);
56
+ t = splitZone(t, 'zone-004', 'horizontal',
57
+ { kind: 'leaf', id: 'zone-006', label: 'zone-006', privacyState: 'ouvert' }, 0.5);
58
+ t = splitZone(t, 'zone-005', 'vertical',
59
+ { kind: 'leaf', id: 'zone-007', label: 'zone-007', privacyState: 'ouvert' }, 0.5);
60
+ t = splitZone(t, 'zone-006', 'vertical',
61
+ { kind: 'leaf', id: 'zone-008', label: 'zone-008', privacyState: 'ouvert' }, 0.5);
62
+ // Fourth level: 16 zones
63
+ t = splitZone(t, 'zone-007', 'horizontal',
64
+ { kind: 'leaf', id: 'zone-009', label: 'zone-009', privacyState: 'ouvert' }, 0.5);
65
+ t = splitZone(t, 'zone-008', 'horizontal',
66
+ { kind: 'leaf', id: 'zone-010', label: 'zone-010', privacyState: 'ouvert' }, 0.5);
67
+ t = splitZone(t, 'zone-009', 'vertical',
68
+ { kind: 'leaf', id: 'zone-011', label: 'zone-011', privacyState: 'ouvert' }, 0.5);
69
+ t = splitZone(t, 'zone-010', 'vertical',
70
+ { kind: 'leaf', id: 'zone-012', label: 'zone-012', privacyState: 'ouvert' }, 0.5);
71
+ t = splitZone(t, 'zone-011', 'horizontal',
72
+ { kind: 'leaf', id: 'zone-013', label: 'zone-013', privacyState: 'ouvert' }, 0.5);
73
+ t = splitZone(t, 'zone-012', 'horizontal',
74
+ { kind: 'leaf', id: 'zone-014', label: 'zone-014', privacyState: 'ouvert' }, 0.5);
75
+ t = splitZone(t, 'zone-013', 'vertical',
76
+ { kind: 'leaf', id: 'zone-015', label: 'zone-015', privacyState: 'ouvert' }, 0.5);
77
+ t = splitZone(t, 'zone-014', 'vertical',
78
+ { kind: 'leaf', id: 'zone-016', label: 'zone-016', privacyState: 'ouvert' }, 0.5);
79
+ return t;
80
+ }
81
+ let tree = $state<BspNode>(initTree());
82
+
83
+ let containerWidth = $state(800);
84
+ let containerHeight = $state(600);
85
+ let focusedZoneId = $state('zone-001');
86
+ let nextZoneId = $state(17);
87
+
88
+ // Map zone IDs to content — 16 zones with varied content
89
+ function initContents(): Map<string, EnchantedBlockData> {
90
+ const m = new Map<string, EnchantedBlockData>();
91
+ for (let i = 1; i <= 16; i++) {
92
+ m.set(`zone-${String(i).padStart(3, '0')}`, generateContent(i - 1));
93
+ }
94
+ return m;
95
+ }
96
+ let zoneContents = $state<Map<string, EnchantedBlockData>>(initContents());
97
+
98
+ function handleSplitRequest(zoneId: string, direction: SplitDirection) {
99
+ const newZoneId = `zone-${String(nextZoneId).padStart(3, '0')}`;
100
+ nextZoneId++;
101
+
102
+ const newLeaf: ZoneLeaf = {
103
+ kind: 'leaf',
104
+ id: newZoneId,
105
+ label: newZoneId,
106
+ privacyState: 'ouvert',
107
+ };
108
+
109
+ tree = splitZone(tree, zoneId, direction, newLeaf, 0.5);
110
+
111
+ // Add content for new zone
112
+ zoneContents = new Map(zoneContents);
113
+ zoneContents.set(newZoneId, generateContent(nextZoneId));
114
+
115
+ // Focus new zone
116
+ focusedZoneId = newZoneId;
117
+ }
118
+
119
+ function handleContentChange(zoneId: string, content: string) {
120
+ const block = zoneContents.get(zoneId);
121
+ if (block) {
122
+ zoneContents = new Map(zoneContents);
123
+ zoneContents.set(zoneId, { ...block, content, modifiedAt: Date.now() });
124
+ }
125
+ }
126
+
127
+ function handleTypeChange(zoneId: string, type: BlockType) {
128
+ const block = zoneContents.get(zoneId);
129
+ if (block) {
130
+ zoneContents = new Map(zoneContents);
131
+ zoneContents.set(zoneId, { ...block, type } as EnchantedBlockData);
132
+ }
133
+ }
134
+
135
+ function getBlockForZone(zoneId: string): EnchantedBlockData | undefined {
136
+ return zoneContents.get(zoneId);
137
+ }
138
+ </script>
139
+
140
+ <div class="demo">
141
+ <header>
142
+ <h2>BSP ZoneTiler — 16 Zones</h2>
143
+ <div class="instructions">
144
+ <span><kbd>h</kbd><kbd>j</kbd><kbd>k</kbd><kbd>l</kbd> navigate</span>
145
+ <span><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>H</kbd>/<kbd>V</kbd> split</span>
146
+ <span>Drag dividers to resize</span>
147
+ </div>
148
+ </header>
149
+
150
+ <div class="canvas" bind:clientWidth={containerWidth} bind:clientHeight={containerHeight}>
151
+ <ZoneTiler
152
+ {tree}
153
+ width={containerWidth}
154
+ height={containerHeight}
155
+ {focusedZoneId}
156
+ onFocusChange={(id) => focusedZoneId = id}
157
+ onSplitRequest={handleSplitRequest}
158
+ >
159
+ {#snippet zoneContent(zone: ZoneRect)}
160
+ {@const block = getBlockForZone(zone.id)}
161
+ <div class="zone" class:focused={zone.id === focusedZoneId}>
162
+ {#if block}
163
+ <NodepadBlock
164
+ {block}
165
+ maxWidth={zone.width - 16}
166
+ onChange={(c) => handleContentChange(zone.id, c)}
167
+ onTypeChange={(t) => handleTypeChange(zone.id, t)}
168
+ />
169
+ {:else}
170
+ <div class="empty">{zone.id}</div>
171
+ {/if}
172
+ </div>
173
+ {/snippet}
174
+ </ZoneTiler>
175
+ </div>
176
+ </div>
177
+
178
+ <style>
179
+ .demo {
180
+ padding: 16px;
181
+ height: 100vh;
182
+ box-sizing: border-box;
183
+ display: flex;
184
+ flex-direction: column;
185
+ }
186
+
187
+ header {
188
+ flex-shrink: 0;
189
+ margin-bottom: 12px;
190
+ display: flex;
191
+ justify-content: space-between;
192
+ align-items: center;
193
+ }
194
+
195
+ h2 {
196
+ color: var(--color-text-primary, #e8e4dc);
197
+ margin: 0;
198
+ font-size: 18px;
199
+ }
200
+
201
+ .instructions {
202
+ display: flex;
203
+ gap: 16px;
204
+ font-size: 12px;
205
+ color: var(--color-text-muted, #706858);
206
+ }
207
+
208
+ .instructions span {
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 4px;
212
+ }
213
+
214
+ kbd {
215
+ background: var(--color-bg-elevated, #333);
216
+ border: 1px solid var(--color-border, #444);
217
+ border-radius: 3px;
218
+ padding: 2px 6px;
219
+ font-family: monospace;
220
+ font-size: 11px;
221
+ color: var(--color-text-secondary, #a89b8c);
222
+ }
223
+
224
+ .canvas {
225
+ flex: 1;
226
+ background: var(--color-bg-panel, #222);
227
+ border-radius: 8px;
228
+ position: relative;
229
+ overflow: hidden;
230
+ }
231
+
232
+ .zone {
233
+ width: 100%;
234
+ height: 100%;
235
+ padding: 8px;
236
+ box-sizing: border-box;
237
+ background: var(--color-bg-elevated, #252422);
238
+ overflow: auto;
239
+ transition: box-shadow 0.15s ease;
240
+ }
241
+
242
+ .zone.focused {
243
+ box-shadow: inset 0 0 0 2px var(--color-accent, #b87333);
244
+ }
245
+
246
+ .empty {
247
+ color: var(--color-text-muted, #706858);
248
+ font-size: 12px;
249
+ padding: 20px;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ height: 100%;
254
+ }
255
+ </style>