@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,164 @@
1
+ <script lang="ts">
2
+ import type { AssayClearanceView } from '../../epistemic/types.js';
3
+ import AssayBadge from '../../u0-primitives/assay-badge/AssayBadge.svelte';
4
+ import AssaySignalBar from '../../u0-primitives/assay-badge/AssaySignalBar.svelte';
5
+
6
+ interface Props {
7
+ clearance: AssayClearanceView;
8
+ onViewWitness?: () => void;
9
+ onViewHash?: () => void;
10
+ class?: string;
11
+ }
12
+
13
+ let { clearance, onViewWitness, onViewHash, class: className = '' }: Props = $props();
14
+
15
+ const hardGates = $derived(clearance.signals.filter(s => s.isHardGate));
16
+ const weightedSignals = $derived(clearance.signals.filter(s => !s.isHardGate));
17
+ const weightedSumPct = $derived((clearance.weightedSum * 100).toFixed(0));
18
+ </script>
19
+
20
+ <div class="ds-assay-detail {className}">
21
+ <!-- Header -->
22
+ <div class="header">
23
+ <div class="header-row">
24
+ <span class="label">Checkpoint:</span>
25
+ <span class="value">{clearance.checkpoint}</span>
26
+ <span class="label">Tick:</span>
27
+ <span class="value mono">{clearance.computedAt}</span>
28
+ </div>
29
+ <div class="header-row">
30
+ <span class="label">Gate:</span>
31
+ <AssayBadge {clearance} size="md" />
32
+ <span class="label">Weighted:</span>
33
+ <span class="value mono">{weightedSumPct}%</span>
34
+ </div>
35
+ </div>
36
+
37
+ <!-- Hard Gates section -->
38
+ {#if hardGates.length > 0}
39
+ <div class="section">
40
+ <div class="section-title">Hard Gates</div>
41
+ {#each hardGates as signal}
42
+ <AssaySignalBar {signal} />
43
+ {/each}
44
+ </div>
45
+ {/if}
46
+
47
+ <!-- Weighted Signals section -->
48
+ {#if weightedSignals.length > 0}
49
+ <div class="section">
50
+ <div class="section-title">Weighted Signals</div>
51
+ {#each weightedSignals as signal}
52
+ <AssaySignalBar {signal} />
53
+ {/each}
54
+ </div>
55
+ {/if}
56
+
57
+ {#if clearance.isDegraded}
58
+ <div class="degraded-notice">
59
+ Degraded — some soft signals were unavailable at evaluation time
60
+ </div>
61
+ {/if}
62
+
63
+ <!-- Footer -->
64
+ <div class="footer">
65
+ <button class="link-btn" type="button" onclick={onViewWitness}>
66
+ View sigchain witness
67
+ </button>
68
+ <button class="link-btn" type="button" onclick={onViewHash}>
69
+ View clearance hash
70
+ </button>
71
+ </div>
72
+ </div>
73
+
74
+ <style>
75
+ .ds-assay-detail {
76
+ display: flex;
77
+ flex-direction: column;
78
+ gap: var(--space-3);
79
+ padding: var(--space-4);
80
+ background: var(--color-bg-panel);
81
+ border-radius: var(--radius-lg);
82
+ border: 1px solid var(--border-default);
83
+ min-width: 320px;
84
+ font-family: var(--font-sans);
85
+ }
86
+
87
+ .header {
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: var(--space-2);
91
+ padding-bottom: var(--space-3);
92
+ border-bottom: 1px solid var(--border-subtle);
93
+ }
94
+
95
+ .header-row {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: var(--space-2);
99
+ }
100
+
101
+ .label {
102
+ font-size: var(--text-xs);
103
+ color: var(--color-text-tertiary);
104
+ min-width: 6rem;
105
+ }
106
+
107
+ .value {
108
+ font-size: var(--text-xs);
109
+ color: var(--color-text-secondary);
110
+ }
111
+
112
+ .mono {
113
+ font-family: var(--font-mono);
114
+ }
115
+
116
+ .section {
117
+ display: flex;
118
+ flex-direction: column;
119
+ gap: var(--space-1);
120
+ }
121
+
122
+ .section-title {
123
+ font-size: var(--text-xs);
124
+ font-weight: 600;
125
+ color: var(--color-text-tertiary);
126
+ text-transform: uppercase;
127
+ letter-spacing: 0.08em;
128
+ padding: var(--space-1) 0;
129
+ border-bottom: 1px solid var(--border-subtle);
130
+ margin-bottom: var(--space-1);
131
+ }
132
+
133
+ .degraded-notice {
134
+ font-size: var(--text-xs);
135
+ color: var(--epistemic-degraded);
136
+ font-style: italic;
137
+ padding: var(--space-2);
138
+ background: rgba(107, 114, 128, 0.08);
139
+ border-radius: var(--radius-sm);
140
+ }
141
+
142
+ .footer {
143
+ display: flex;
144
+ gap: var(--space-3);
145
+ padding-top: var(--space-2);
146
+ border-top: 1px solid var(--border-subtle);
147
+ }
148
+
149
+ .link-btn {
150
+ background: none;
151
+ border: none;
152
+ padding: 0;
153
+ font-family: var(--font-sans);
154
+ font-size: var(--text-xs);
155
+ color: var(--color-accent);
156
+ cursor: pointer;
157
+ text-decoration: underline;
158
+ text-underline-offset: 2px;
159
+ }
160
+
161
+ .link-btn:hover {
162
+ color: var(--color-accent-hover);
163
+ }
164
+ </style>
@@ -0,0 +1,253 @@
1
+ <script lang="ts">
2
+ import type { AvenueTraceView, AvenueStepView } from '../../epistemic/types.js';
3
+
4
+ interface Props {
5
+ trace: AvenueTraceView;
6
+ expanded?: boolean;
7
+ class?: string;
8
+ }
9
+
10
+ let { trace, expanded = false, class: className = '' }: Props = $props();
11
+
12
+ let isExpanded: boolean = $state(false);
13
+
14
+ $effect(() => {
15
+ isExpanded = expanded;
16
+ });
17
+
18
+ const sourceCount = $derived(
19
+ trace.steps.filter((s: AvenueStepView) => s.step_type === 'retrieve').length
20
+ );
21
+
22
+ const confidencePct = $derived(`${Math.round(trace.confidence * 100)}%`);
23
+
24
+ function stepIcon(stepType: AvenueStepView['step_type']): string {
25
+ switch (stepType) {
26
+ case 'query': return '⊕';
27
+ case 'retrieve': return '⊙';
28
+ case 'filter': return '⊘';
29
+ case 'synthesize': return '⊛';
30
+ case 'contradict': return '⊗';
31
+ case 'verify': return '⊚';
32
+ default: return '○';
33
+ }
34
+ }
35
+
36
+ function stepLabel(stepType: AvenueStepView['step_type']): string {
37
+ switch (stepType) {
38
+ case 'query': return 'Query';
39
+ case 'retrieve': return 'Retrieve';
40
+ case 'filter': return 'Filter';
41
+ case 'synthesize': return 'Synthesize';
42
+ case 'contradict': return 'Contradiction';
43
+ case 'verify': return 'Verify';
44
+ default: return stepType;
45
+ }
46
+ }
47
+ </script>
48
+
49
+ <div class="ds-avenue-trace {className}" class:expanded={isExpanded}>
50
+
51
+ {#if !isExpanded}
52
+ <!-- Collapsed summary bar -->
53
+ <div class="collapsed-bar">
54
+ <span class="summary">
55
+ {trace.steps.length} step{trace.steps.length !== 1 ? 's' : ''}
56
+ · {sourceCount} source{sourceCount !== 1 ? 's' : ''}
57
+ · {confidencePct} confidence
58
+ </span>
59
+ {#if trace.isPartial}
60
+ <span class="partial-tag">(partial)</span>
61
+ {/if}
62
+ <button class="expand-btn" type="button" onclick={() => isExpanded = true}>
63
+ Expand →
64
+ </button>
65
+ </div>
66
+
67
+ {:else}
68
+ <!-- Expanded step timeline -->
69
+ <div class="expanded-header">
70
+ <span class="header-title">Agent Avenue</span>
71
+ {#if trace.isPartial}
72
+ <span class="partial-tag">partial — agent did not log all steps</span>
73
+ {/if}
74
+ <button class="collapse-btn" type="button" onclick={() => isExpanded = false}>
75
+ ← Collapse
76
+ </button>
77
+ </div>
78
+
79
+ <div class="steps">
80
+ {#each trace.steps as step, i}
81
+ <div class="step">
82
+ <!-- Step connector -->
83
+ <div class="step-track">
84
+ <div class="step-icon">{stepIcon(step.step_type)}</div>
85
+ {#if i < trace.steps.length - 1}
86
+ <div class="step-line"></div>
87
+ {/if}
88
+ </div>
89
+
90
+ <!-- Step content -->
91
+ <div class="step-body">
92
+ <div class="step-header">
93
+ <span class="step-type">{stepLabel(step.step_type)}</span>
94
+ </div>
95
+ <div class="step-summary">{step.summary}</div>
96
+ </div>
97
+ </div>
98
+ {/each}
99
+
100
+ {#if trace.steps.length === 0}
101
+ <div class="empty-steps">
102
+ {trace.isPartial ? 'No step data available — agent session predates structured logging.' : 'No steps recorded.'}
103
+ </div>
104
+ {/if}
105
+ </div>
106
+
107
+ <div class="expanded-footer">
108
+ <span class="footer-confidence">Aggregate confidence: {confidencePct}</span>
109
+ </div>
110
+ {/if}
111
+
112
+ </div>
113
+
114
+ <style>
115
+ .ds-avenue-trace {
116
+ font-family: var(--font-sans);
117
+ border: 1px solid var(--border-subtle);
118
+ border-radius: var(--radius-md);
119
+ background: var(--color-bg-panel-elevated);
120
+ overflow: hidden;
121
+ }
122
+
123
+ /* Collapsed */
124
+ .collapsed-bar {
125
+ display: flex;
126
+ align-items: center;
127
+ gap: var(--space-2);
128
+ padding: var(--space-2) var(--space-3);
129
+ }
130
+
131
+ .summary {
132
+ font-size: var(--text-xs);
133
+ color: var(--color-text-secondary);
134
+ flex: 1;
135
+ }
136
+
137
+ .partial-tag {
138
+ font-size: var(--text-xs);
139
+ color: var(--color-text-muted);
140
+ font-style: italic;
141
+ }
142
+
143
+ .expand-btn, .collapse-btn {
144
+ background: none;
145
+ border: none;
146
+ font-family: var(--font-sans);
147
+ font-size: var(--text-xs);
148
+ color: var(--color-accent);
149
+ cursor: pointer;
150
+ padding: 0;
151
+ flex-shrink: 0;
152
+ }
153
+
154
+ .expand-btn:hover, .collapse-btn:hover {
155
+ color: var(--color-accent-hover);
156
+ }
157
+
158
+ /* Expanded */
159
+ .expanded-header {
160
+ display: flex;
161
+ align-items: center;
162
+ gap: var(--space-2);
163
+ padding: var(--space-3) var(--space-4);
164
+ border-bottom: 1px solid var(--border-subtle);
165
+ }
166
+
167
+ .header-title {
168
+ font-size: var(--text-xs);
169
+ font-weight: 600;
170
+ color: var(--color-text-primary);
171
+ flex: 1;
172
+ }
173
+
174
+ .steps {
175
+ padding: var(--space-3) var(--space-4);
176
+ display: flex;
177
+ flex-direction: column;
178
+ }
179
+
180
+ .step {
181
+ display: flex;
182
+ gap: var(--space-3);
183
+ min-height: 2.5rem;
184
+ }
185
+
186
+ .step-track {
187
+ display: flex;
188
+ flex-direction: column;
189
+ align-items: center;
190
+ flex-shrink: 0;
191
+ width: 1.5rem;
192
+ }
193
+
194
+ .step-icon {
195
+ font-size: var(--text-sm);
196
+ color: var(--color-accent);
197
+ line-height: 1.4;
198
+ }
199
+
200
+ .step-line {
201
+ width: 1px;
202
+ flex: 1;
203
+ background: var(--border-default);
204
+ min-height: 1rem;
205
+ margin: 2px 0;
206
+ }
207
+
208
+ .step-body {
209
+ display: flex;
210
+ flex-direction: column;
211
+ gap: 2px;
212
+ padding-bottom: var(--space-3);
213
+ flex: 1;
214
+ }
215
+
216
+ .step-header {
217
+ display: flex;
218
+ align-items: baseline;
219
+ gap: var(--space-2);
220
+ }
221
+
222
+ .step-type {
223
+ font-size: var(--text-xs);
224
+ font-weight: 600;
225
+ color: var(--color-text-primary);
226
+ text-transform: uppercase;
227
+ letter-spacing: 0.04em;
228
+ }
229
+
230
+ .step-summary {
231
+ font-size: var(--text-xs);
232
+ color: var(--color-text-secondary);
233
+ }
234
+
235
+ .empty-steps {
236
+ font-size: var(--text-xs);
237
+ color: var(--color-text-muted);
238
+ font-style: italic;
239
+ padding: var(--space-4) 0;
240
+ text-align: center;
241
+ }
242
+
243
+ .expanded-footer {
244
+ padding: var(--space-2) var(--space-4);
245
+ border-top: 1px solid var(--border-subtle);
246
+ }
247
+
248
+ .footer-confidence {
249
+ font-size: var(--text-xs);
250
+ color: var(--color-text-tertiary);
251
+ font-family: var(--font-mono);
252
+ }
253
+ </style>
@@ -0,0 +1,204 @@
1
+ <script lang="ts">
2
+ import type { KnowledgeEpistemicDetail, ProvenanceChainNode } from '../../epistemic/types.js';
3
+ import AssayBadge from '../../u0-primitives/assay-badge/AssayBadge.svelte';
4
+ import AllayGauge from '../../u0-primitives/allay-gauge/AllayGauge.svelte';
5
+ import ExpertBadge from '../../u0-primitives/expert-badge/ExpertBadge.svelte';
6
+ import AssayDetailPanel from './AssayDetailPanel.svelte';
7
+ import AllayDetailPanel from './AllayDetailPanel.svelte';
8
+ import ProvenanceChain from './ProvenanceChain.svelte';
9
+ import AvenueTrace from './AvenueTrace.svelte';
10
+
11
+ interface Props {
12
+ detail: KnowledgeEpistemicDetail;
13
+ onnodeclick?: (node: ProvenanceChainNode) => void;
14
+ class?: string;
15
+ }
16
+
17
+ let { detail, onnodeclick, class: className = '' }: Props = $props();
18
+
19
+ type Tab = 'overview' | 'allay' | 'assay' | 'provenance' | 'trace';
20
+ let activeTab: Tab = $state('overview');
21
+
22
+ const tabs: { id: Tab; label: string }[] = [
23
+ { id: 'overview', label: 'Overview' },
24
+ { id: 'allay', label: 'Allay' },
25
+ { id: 'assay', label: 'ASSAY' },
26
+ { id: 'provenance', label: 'Provenance' },
27
+ { id: 'trace', label: 'Ψ-Trace' },
28
+ ];
29
+
30
+ const hashPreview = $derived(
31
+ detail.contentHash.length > 12 ? detail.contentHash.slice(0, 12) + '…' : detail.contentHash
32
+ );
33
+
34
+
35
+ </script>
36
+
37
+ <div class="ds-knowledge-detail {className}">
38
+ <!-- Tab bar -->
39
+ <div class="tab-bar" role="tablist">
40
+ {#each tabs as tab}
41
+ <button
42
+ class="tab"
43
+ class:active={activeTab === tab.id}
44
+ role="tab"
45
+ aria-selected={activeTab === tab.id}
46
+ onclick={() => activeTab = tab.id}
47
+ type="button"
48
+ >
49
+ {tab.label}
50
+ </button>
51
+ {/each}
52
+ </div>
53
+
54
+ <!-- Tab content -->
55
+ <div class="tab-content">
56
+
57
+ {#if activeTab === 'overview'}
58
+ <div class="overview">
59
+ <div class="field-row">
60
+ <span class="field-label">Title</span>
61
+ <span class="field-value">{detail.title}</span>
62
+ </div>
63
+ <div class="field-row">
64
+ <span class="field-label">Source</span>
65
+ <span class="field-value mono">{detail.source}</span>
66
+ </div>
67
+ <div class="field-row">
68
+ <span class="field-label">Expert</span>
69
+ {#if detail.expert && typeof detail.expert === 'object'}
70
+ <ExpertBadge expert={detail.expert} size="md" />
71
+ {:else}
72
+ <span class="field-value">{detail.expert ?? '—'}</span>
73
+ {/if}
74
+ </div>
75
+ <div class="field-row">
76
+ <span class="field-label">Content hash</span>
77
+ <span class="field-value mono" title={detail.contentHash}>{hashPreview}</span>
78
+ </div>
79
+ <div class="field-row">
80
+ <span class="field-label">Convergence</span>
81
+ <span class="field-value">{detail.convergence} independent witness(es)</span>
82
+ </div>
83
+ <div class="field-row">
84
+ <span class="field-label">Allay</span>
85
+ <AllayGauge stage={detail.allay.stage} confidence={detail.allay.confidence} size="sm" showLabel />
86
+ </div>
87
+ <div class="field-row">
88
+ <span class="field-label">ASSAY</span>
89
+ {#if detail.assay}<AssayBadge clearance={detail.assay} size="md" />{/if}
90
+ </div>
91
+ </div>
92
+
93
+ {:else if activeTab === 'allay'}
94
+ <AllayDetailPanel allay={detail.allay} />
95
+
96
+ {:else if activeTab === 'assay'}
97
+ {#if detail.assay}
98
+ <AssayDetailPanel clearance={detail.assay} />
99
+ {:else}
100
+ <div class="empty">ASSAY not yet evaluated for this atom.</div>
101
+ {/if}
102
+
103
+ {:else if activeTab === 'provenance'}
104
+ <ProvenanceChain nodes={detail.provenance ?? []} {onnodeclick} />
105
+
106
+ {:else if activeTab === 'trace'}
107
+ {#if detail.avenue}
108
+ <AvenueTrace trace={detail.avenue} expanded={true} />
109
+ {:else}
110
+ <div class="empty">No avenue trace available</div>
111
+ {/if}
112
+ {/if}
113
+
114
+ </div>
115
+ </div>
116
+
117
+ <style>
118
+ .ds-knowledge-detail {
119
+ display: flex;
120
+ flex-direction: column;
121
+ background: var(--color-bg-panel);
122
+ border-radius: var(--radius-lg);
123
+ border: 1px solid var(--border-default);
124
+ min-width: 360px;
125
+ max-width: 600px;
126
+ font-family: var(--font-sans);
127
+ overflow: hidden;
128
+ }
129
+
130
+ .tab-bar {
131
+ display: flex;
132
+ border-bottom: 1px solid var(--border-default);
133
+ background: var(--color-bg-panel-elevated);
134
+ overflow-x: auto;
135
+ scrollbar-width: none;
136
+ }
137
+
138
+ .tab-bar::-webkit-scrollbar { display: none; }
139
+
140
+ .tab {
141
+ padding: var(--space-2) var(--space-4);
142
+ background: none;
143
+ border: none;
144
+ border-bottom: 2px solid transparent;
145
+ font-family: var(--font-sans);
146
+ font-size: var(--text-xs);
147
+ font-weight: 500;
148
+ color: var(--color-text-tertiary);
149
+ cursor: pointer;
150
+ white-space: nowrap;
151
+ transition: color 150ms, border-color 150ms;
152
+ }
153
+
154
+ .tab:hover { color: var(--color-text-secondary); }
155
+
156
+ .tab.active {
157
+ color: var(--color-accent);
158
+ border-bottom-color: var(--color-accent);
159
+ }
160
+
161
+ .tab-content {
162
+ padding: var(--space-4);
163
+ overflow-y: auto;
164
+ max-height: 60vh;
165
+ }
166
+
167
+ .overview {
168
+ display: flex;
169
+ flex-direction: column;
170
+ gap: var(--space-3);
171
+ }
172
+
173
+ .field-row {
174
+ display: grid;
175
+ grid-template-columns: 7rem 1fr;
176
+ align-items: center;
177
+ gap: var(--space-2);
178
+ padding: var(--space-1) 0;
179
+ border-bottom: 1px solid var(--border-subtle);
180
+ }
181
+
182
+ .field-label {
183
+ font-size: var(--text-xs);
184
+ color: var(--color-text-tertiary);
185
+ }
186
+
187
+ .field-value {
188
+ font-size: var(--text-xs);
189
+ color: var(--color-text-primary);
190
+ }
191
+
192
+ .mono {
193
+ font-family: var(--font-mono);
194
+ word-break: break-all;
195
+ }
196
+
197
+ .empty {
198
+ font-size: var(--text-xs);
199
+ color: var(--color-text-muted);
200
+ font-style: italic;
201
+ padding: var(--space-4) 0;
202
+ text-align: center;
203
+ }
204
+ </style>