@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,388 @@
1
+ <script lang="ts">
2
+ /**
3
+ * KeyboardShortcuts - Fabric Component
4
+ *
5
+ * Keyboard shortcut display and binding visualization.
6
+ * Decoupled from shell stores - uses props/callbacks for all state.
7
+ *
8
+ * @package @kos/design-system/fabric/input
9
+ * @adr 2026-04-12-leap-substrate-refactor-001
10
+ */
11
+ import { X, Command, CornerDownLeft } from '@lucide/svelte';
12
+
13
+ export interface ShortcutBinding {
14
+ key: string;
15
+ modifiers?: ('ctrl' | 'alt' | 'shift' | 'meta')[];
16
+ description: string;
17
+ scope?: string;
18
+ }
19
+
20
+ export interface ShortcutGroup {
21
+ name: string;
22
+ shortcuts: ShortcutBinding[];
23
+ }
24
+
25
+ interface Props {
26
+ groups: ShortcutGroup[];
27
+ isOpen: boolean;
28
+ onClose: () => void;
29
+ onShortcutClick?: (shortcut: ShortcutBinding) => void;
30
+ searchable?: boolean;
31
+ title?: string;
32
+ }
33
+
34
+ const props: Props = $props();
35
+
36
+ let searchQuery = $state('');
37
+ let searchInput: HTMLInputElement | null = $state(null);
38
+
39
+ // Focus search when opened
40
+ $effect(() => {
41
+ if (props.isOpen && props.searchable && searchInput) {
42
+ searchInput.focus();
43
+ }
44
+ });
45
+
46
+ const filteredGroups = $derived(() => {
47
+ if (!props.searchable || !searchQuery.trim()) return props.groups;
48
+
49
+ const query = searchQuery.toLowerCase();
50
+ return props.groups
51
+ .map(group => ({
52
+ ...group,
53
+ shortcuts: group.shortcuts.filter(s =>
54
+ s.description.toLowerCase().includes(query) ||
55
+ s.key.toLowerCase().includes(query) ||
56
+ formatBinding(s).toLowerCase().includes(query)
57
+ )
58
+ }))
59
+ .filter(group => group.shortcuts.length > 0);
60
+ });
61
+
62
+ function formatBinding(shortcut: ShortcutBinding): string {
63
+ const mods = (shortcut.modifiers || []).map(m => {
64
+ switch (m) {
65
+ case 'ctrl': return 'Ctrl';
66
+ case 'alt': return 'Alt';
67
+ case 'shift': return 'Shift';
68
+ case 'meta': return '⌘';
69
+ default: return m;
70
+ }
71
+ });
72
+ return [...mods, shortcut.key.toUpperCase()].join(' + ');
73
+ }
74
+
75
+ function getPlatformSymbol(modifier: string): string {
76
+ if (modifier === 'meta') return '⌘';
77
+ return modifier.charAt(0).toUpperCase() + modifier.slice(1);
78
+ }
79
+
80
+ function handleKeydown(e: KeyboardEvent) {
81
+ // Close on Escape
82
+ if (e.key === 'Escape' && props.isOpen) {
83
+ props.onClose();
84
+ }
85
+ }
86
+ </script>
87
+
88
+ <svelte:window onkeydown={handleKeydown} />
89
+
90
+ {#if props.isOpen}
91
+ <div class="shortcuts-overlay" role="dialog" aria-modal="true" aria-label={props.title || 'Keyboard shortcuts'}>
92
+ <div class="shortcuts-panel">
93
+ <header class="panel-header">
94
+ <h2 class="panel-title">{props.title || 'Keyboard shortcuts'}</h2>
95
+ <button class="close-btn" onclick={props.onClose} aria-label="Close">
96
+ <X size={18} />
97
+ </button>
98
+ </header>
99
+
100
+ {#if props.searchable}
101
+ <div class="search-box">
102
+ <Command size={14} />
103
+ <input
104
+ bind:this={searchInput}
105
+ type="text"
106
+ placeholder="Search shortcuts..."
107
+ bind:value={searchQuery}
108
+ aria-label="Search shortcuts"
109
+ />
110
+ {#if searchQuery}
111
+ <button class="clear-btn" onclick={() => searchQuery = ''} aria-label="Clear search">
112
+ <X size={12} />
113
+ </button>
114
+ {/if}
115
+ </div>
116
+ {/if}
117
+
118
+ <div class="shortcuts-content">
119
+ {#each filteredGroups() as group}
120
+ <section class="shortcut-group">
121
+ <h3 class="group-title">{group.name}</h3>
122
+ <ul class="shortcut-list" role="list">
123
+ {#each group.shortcuts as shortcut}
124
+ <li class="shortcut-item" role="listitem">
125
+ <button
126
+ class="shortcut-btn"
127
+ onclick={() => props.onShortcutClick?.(shortcut)}
128
+ title={shortcut.scope ? `Scope: ${shortcut.scope}` : undefined}
129
+ >
130
+ <span class="shortcut-keys">
131
+ {#each (shortcut.modifiers || []) as mod}
132
+ <kbd class="key mod">{getPlatformSymbol(mod)}</kbd>
133
+ {/each}
134
+ <kbd class="key">{shortcut.key.toUpperCase()}</kbd>
135
+ </span>
136
+ <span class="shortcut-desc">{shortcut.description}</span>
137
+ {#if shortcut.scope}
138
+ <span class="shortcut-scope">{shortcut.scope}</span>
139
+ {/if}
140
+ </button>
141
+ </li>
142
+ {/each}
143
+ </ul>
144
+ </section>
145
+ {/each}
146
+
147
+ {#if filteredGroups().length === 0}
148
+ <div class="no-results">
149
+ <CornerDownLeft size={24} />
150
+ <p>No shortcuts found matching "{searchQuery}"</p>
151
+ </div>
152
+ {/if}
153
+ </div>
154
+
155
+ <footer class="panel-footer">
156
+ <span class="hint">Press <kbd>Esc</kbd> to close</span>
157
+ </footer>
158
+ </div>
159
+ </div>
160
+ {/if}
161
+
162
+ <style>
163
+ .shortcuts-overlay {
164
+ position: fixed;
165
+ inset: 0;
166
+ background: rgba(0, 0, 0, 0.8);
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: center;
170
+ z-index: 10000;
171
+ backdrop-filter: blur(4px);
172
+ }
173
+
174
+ .shortcuts-panel {
175
+ width: min(560px, 90vw);
176
+ max-height: 80vh;
177
+ background: var(--color-bg-panel, #222222);
178
+ border: 1px solid var(--border-default, #333333);
179
+ border-radius: var(--radius-xl, 0.75rem);
180
+ display: flex;
181
+ flex-direction: column;
182
+ overflow: hidden;
183
+ }
184
+
185
+ .panel-header {
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: space-between;
189
+ padding: 16px 20px;
190
+ border-bottom: 1px solid var(--border-subtle, rgba(255,255,255,0.06));
191
+ }
192
+
193
+ .panel-title {
194
+ font-size: 16px;
195
+ font-weight: 600;
196
+ color: var(--color-text-primary, #f2efe9);
197
+ margin: 0;
198
+ }
199
+
200
+ .close-btn {
201
+ background: none;
202
+ border: none;
203
+ color: var(--color-text-tertiary, #706858);
204
+ cursor: pointer;
205
+ padding: 4px;
206
+ border-radius: var(--radius-sm, 0.25rem);
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ transition: color 0.15s, background 0.15s;
211
+ }
212
+
213
+ .close-btn:hover {
214
+ color: var(--color-text-primary, #f2efe9);
215
+ background: rgba(255, 255, 255, 0.05);
216
+ }
217
+
218
+ .search-box {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 8px;
222
+ padding: 12px 20px;
223
+ border-bottom: 1px solid var(--border-subtle, rgba(255,255,255,0.06));
224
+ color: var(--color-text-tertiary, #706858);
225
+ }
226
+
227
+ .search-box input {
228
+ flex: 1;
229
+ background: none;
230
+ border: none;
231
+ color: var(--color-text-primary, #f2efe9);
232
+ font-size: 14px;
233
+ outline: none;
234
+ }
235
+
236
+ .search-box input::placeholder {
237
+ color: var(--color-text-tertiary, #706858);
238
+ }
239
+
240
+ .clear-btn {
241
+ background: none;
242
+ border: none;
243
+ color: var(--color-text-tertiary, #706858);
244
+ cursor: pointer;
245
+ padding: 2px;
246
+ border-radius: var(--radius-sm, 0.25rem);
247
+ display: flex;
248
+ align-items: center;
249
+ justify-content: center;
250
+ }
251
+
252
+ .clear-btn:hover {
253
+ color: var(--color-text-secondary, #a09880);
254
+ }
255
+
256
+ .shortcuts-content {
257
+ flex: 1;
258
+ overflow-y: auto;
259
+ padding: 16px 20px;
260
+ }
261
+
262
+ .shortcut-group {
263
+ margin-bottom: 24px;
264
+ }
265
+
266
+ .group-title {
267
+ font-size: 11px;
268
+ font-weight: 600;
269
+ text-transform: uppercase;
270
+ letter-spacing: 0.5px;
271
+ color: var(--color-text-tertiary, #706858);
272
+ margin: 0 0 12px 0;
273
+ }
274
+
275
+ .shortcut-list {
276
+ list-style: none;
277
+ margin: 0;
278
+ padding: 0;
279
+ display: flex;
280
+ flex-direction: column;
281
+ gap: 4px;
282
+ }
283
+
284
+ .shortcut-item {
285
+ margin: 0;
286
+ }
287
+
288
+ .shortcut-btn {
289
+ width: 100%;
290
+ display: flex;
291
+ align-items: center;
292
+ gap: 16px;
293
+ padding: 10px 12px;
294
+ background: none;
295
+ border: 1px solid transparent;
296
+ border-radius: var(--radius-md, 0.375rem);
297
+ cursor: pointer;
298
+ text-align: left;
299
+ transition: background 0.15s, border-color 0.15s;
300
+ }
301
+
302
+ .shortcut-btn:hover {
303
+ background: var(--color-bg-canvas, #1a1a1a);
304
+ border-color: var(--border-subtle, rgba(255,255,255,0.06));
305
+ }
306
+
307
+ .shortcut-keys {
308
+ display: flex;
309
+ align-items: center;
310
+ gap: 4px;
311
+ min-width: 100px;
312
+ }
313
+
314
+ .key {
315
+ display: inline-flex;
316
+ align-items: center;
317
+ justify-content: center;
318
+ min-width: 24px;
319
+ height: 24px;
320
+ padding: 0 6px;
321
+ background: var(--color-bg-canvas, #1a1a1a);
322
+ border: 1px solid var(--border-default, #333333);
323
+ border-radius: var(--radius-sm, 0.25rem);
324
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
325
+ font-size: 11px;
326
+ font-weight: 500;
327
+ color: var(--color-text-secondary, #a09880);
328
+ }
329
+
330
+ .key.mod {
331
+ min-width: 28px;
332
+ }
333
+
334
+ .shortcut-desc {
335
+ flex: 1;
336
+ font-size: 13px;
337
+ color: var(--color-text-primary, #f2efe9);
338
+ }
339
+
340
+ .shortcut-scope {
341
+ font-size: 10px;
342
+ padding: 2px 6px;
343
+ background: var(--color-bg-canvas, #1a1a1a);
344
+ border-radius: var(--radius-sm, 0.25rem);
345
+ color: var(--color-text-tertiary, #706858);
346
+ }
347
+
348
+ .no-results {
349
+ display: flex;
350
+ flex-direction: column;
351
+ align-items: center;
352
+ justify-content: center;
353
+ gap: 12px;
354
+ padding: 40px;
355
+ color: var(--color-text-tertiary, #706858);
356
+ }
357
+
358
+ .no-results p {
359
+ font-size: 13px;
360
+ margin: 0;
361
+ }
362
+
363
+ .panel-footer {
364
+ padding: 12px 20px;
365
+ border-top: 1px solid var(--border-subtle, rgba(255,255,255,0.06));
366
+ background: var(--color-bg-canvas, #1a1a1a);
367
+ }
368
+
369
+ .hint {
370
+ font-size: 12px;
371
+ color: var(--color-text-tertiary, #706858);
372
+ }
373
+
374
+ .hint kbd {
375
+ display: inline-flex;
376
+ align-items: center;
377
+ justify-content: center;
378
+ min-width: 20px;
379
+ height: 20px;
380
+ padding: 0 4px;
381
+ margin: 0 2px;
382
+ background: var(--color-bg-panel, #222222);
383
+ border: 1px solid var(--border-default, #333333);
384
+ border-radius: var(--radius-sm, 0.25rem);
385
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
386
+ font-size: 10px;
387
+ }
388
+ </style>
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Fabric Input Components
3
+ *
4
+ * Input patterns and command interfaces.
5
+ *
6
+ * @package @kos/design-system/fabric/input
7
+ * @adr 2026-04-12-leap-substrate-refactor-001
8
+ */
9
+
10
+ export { default as CommandBar } from './CommandBar.svelte';
11
+ export { default as KeyboardShortcuts } from './KeyboardShortcuts.svelte';
12
+ export type { ShortcutBinding, ShortcutGroup } from './KeyboardShortcuts.svelte';
@@ -0,0 +1,193 @@
1
+ <script lang="ts">
2
+ /**
3
+ * GlassBox - Fabric Component
4
+ *
5
+ * A modal overlay for agent handoff scenarios.
6
+ * Decoupled from shell stores - uses props/callbacks for all state.
7
+ *
8
+ * @package @kos/design-system/fabric/layout
9
+ * @adr 2026-04-12-leap-substrate-refactor-001
10
+ */
11
+ import type { Snippet } from 'svelte';
12
+
13
+ interface Props {
14
+ active: boolean;
15
+ reason: string | null;
16
+ taskId?: string | null;
17
+ description?: string;
18
+ ondone?: () => void;
19
+ onabandon?: () => void;
20
+ children?: Snippet;
21
+ }
22
+
23
+ const props : Props = $props();
24
+
25
+ function reasonLabel(r: string | null): string {
26
+ switch (r) {
27
+ case 'Captcha': return 'A CAPTCHA is blocking the agent.';
28
+ case 'AuthWall': return 'A login wall is blocking the agent.';
29
+ case 'PaymentRequired': return 'Payment is required to continue.';
30
+ case 'ConsentGate': return 'A consent or age gate is blocking the agent.';
31
+ case 'InteractiveForm': return props.description || 'An interactive form requires your input.';
32
+ default: return 'The agent needs your help to continue.';
33
+ }
34
+ }
35
+ </script>
36
+
37
+ {#if props.active}
38
+ <div class="glass-box-overlay" role="dialog" aria-modal="true" aria-label="Agent handoff required">
39
+ <div class="glass-box-panel">
40
+ <div class="glass-box-header">
41
+ <span class="glass-box-icon">⬡</span>
42
+ <span class="glass-box-title">Agent needs you</span>
43
+ {#if props.taskId}
44
+ <span class="glass-box-task-id">{props.taskId}</span>
45
+ {/if}
46
+ </div>
47
+
48
+ <p class="glass-box-reason">{reasonLabel(props.reason)}</p>
49
+
50
+ {#if props.description && props.reason !== 'InteractiveForm'}
51
+ <p class="glass-box-description">{props.description}</p>
52
+ {/if}
53
+
54
+ <div class="glass-box-viewport">
55
+ <!-- Browser interaction rendered here by parent -->
56
+ {@render props.children?.()}
57
+ </div>
58
+
59
+ <div class="glass-box-actions">
60
+ <button
61
+ class="glass-box-abandon"
62
+ onclick={() => props.onabandon?.()}
63
+ >
64
+ Abandon research
65
+ </button>
66
+ <button
67
+ class="glass-box-done"
68
+ onclick={() => props.ondone?.()}
69
+ >
70
+ Done — continue →
71
+ </button>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ {/if}
76
+
77
+ <style>
78
+ .glass-box-overlay {
79
+ position: fixed;
80
+ inset: 0;
81
+ background: rgba(0, 0, 0, 0.72);
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ z-index: 9000;
86
+ backdrop-filter: blur(4px);
87
+ }
88
+
89
+ .glass-box-panel {
90
+ width: min(720px, 90vw);
91
+ max-height: 80vh;
92
+ background: var(--color-bg-panel, #222222);
93
+ border: 1px solid var(--color-accent, #b87333);
94
+ border-radius: var(--radius-xl, 0.75rem);
95
+ display: flex;
96
+ flex-direction: column;
97
+ overflow: hidden;
98
+ box-shadow: 0 0 40px rgba(184, 115, 51, 0.2);
99
+ }
100
+
101
+ .glass-box-header {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 10px;
105
+ padding: 14px 18px;
106
+ border-bottom: 1px solid var(--border-default, #333333);
107
+ background: var(--color-bg-panel-elevated, #2a2a2a);
108
+ }
109
+
110
+ .glass-box-icon {
111
+ color: var(--color-accent, #b87333);
112
+ font-size: 16px;
113
+ }
114
+
115
+ .glass-box-title {
116
+ font-size: 14px;
117
+ font-weight: 600;
118
+ color: var(--color-text-primary, #f2efe9);
119
+ flex: 1;
120
+ }
121
+
122
+ .glass-box-task-id {
123
+ font-family: var(--font-mono, 'JetBrains Mono', monospace);
124
+ font-size: 11px;
125
+ color: var(--color-text-secondary, #a09880);
126
+ background: var(--color-bg-canvas, #1a1a1a);
127
+ padding: 2px 8px;
128
+ border-radius: var(--radius-sm, 0.25rem);
129
+ }
130
+
131
+ .glass-box-reason {
132
+ margin: 14px 18px 6px;
133
+ font-size: 13px;
134
+ color: var(--color-text-primary, #f2efe9);
135
+ line-height: 1.5;
136
+ }
137
+
138
+ .glass-box-description {
139
+ margin: 0 18px 14px;
140
+ font-size: 12px;
141
+ color: var(--color-text-secondary, #a09880);
142
+ }
143
+
144
+ .glass-box-viewport {
145
+ flex: 1;
146
+ overflow: auto;
147
+ margin: 0 18px;
148
+ background: var(--color-bg-canvas, #1a1a1a);
149
+ border: 1px solid var(--border-default, #333333);
150
+ border-radius: var(--radius-md, 0.375rem);
151
+ min-height: 200px;
152
+ }
153
+
154
+ .glass-box-actions {
155
+ display: flex;
156
+ justify-content: space-between;
157
+ padding: 14px 18px;
158
+ border-top: 1px solid var(--border-default, #333333);
159
+ gap: 10px;
160
+ }
161
+
162
+ .glass-box-abandon {
163
+ padding: 8px 16px;
164
+ background: transparent;
165
+ border: 1px solid var(--border-default, #444);
166
+ border-radius: var(--radius-md, 0.375rem);
167
+ color: var(--color-text-secondary, #a09880);
168
+ font-size: 13px;
169
+ cursor: pointer;
170
+ transition: border-color 0.15s, color 0.15s;
171
+ }
172
+
173
+ .glass-box-abandon:hover {
174
+ border-color: var(--color-error, #c0392b);
175
+ color: var(--color-error, #c0392b);
176
+ }
177
+
178
+ .glass-box-done {
179
+ padding: 8px 20px;
180
+ background: var(--color-accent, #b87333);
181
+ border: none;
182
+ border-radius: var(--radius-md, 0.375rem);
183
+ color: white;
184
+ font-size: 13px;
185
+ font-weight: 500;
186
+ cursor: pointer;
187
+ transition: background 0.15s;
188
+ }
189
+
190
+ .glass-box-done:hover {
191
+ background: var(--color-accent-active, #8a5626);
192
+ }
193
+ </style>