@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,170 @@
1
+ <script lang="ts">
2
+ import type { ParadigmDefinition } from '../../epistemic/types.js';
3
+
4
+ type ParadigmId = 'spatial' | 'temporal' | 'hierarchical' | 'graph' | 'trust';
5
+
6
+ interface Props {
7
+ activeParadigm?: ParadigmId;
8
+ onParadigmChange?: (id: ParadigmId) => void;
9
+ class?: string;
10
+ }
11
+
12
+ let { activeParadigm = 'spatial', onParadigmChange, class: className = '' }: Props = $props();
13
+
14
+ const PARADIGMS: ParadigmDefinition[] = [
15
+ {
16
+ id: 'spatial',
17
+ label: 'Spatial',
18
+ description: 'Knowledge arranged by position. Good for: spatial reasoning, clustering, free association.',
19
+ conceals: 'Temporal ordering, verification state, provenance chains.',
20
+ icon: '⊞',
21
+ },
22
+ {
23
+ id: 'temporal',
24
+ label: 'Temporal',
25
+ description: 'Knowledge ordered by creation tick. Good for: understanding sequence, causation, when knowledge arrived.',
26
+ conceals: 'Spatial relationships, clustering.',
27
+ icon: '⊟',
28
+ },
29
+ {
30
+ id: 'hierarchical',
31
+ label: 'Hierarchical',
32
+ description: 'Knowledge organized by source path and tags. Good for: file structure, categorical grouping.',
33
+ conceals: 'Cross-cutting relationships, temporal dynamics.',
34
+ icon: '⊠',
35
+ },
36
+ {
37
+ id: 'graph',
38
+ label: 'Graph',
39
+ description: 'Knowledge atoms as nodes, connections as edges. Good for: network structure, indirect connections.',
40
+ conceals: 'Spatial intuition, temporal sequence.',
41
+ icon: '⊡',
42
+ },
43
+ {
44
+ id: 'trust',
45
+ label: 'Trust',
46
+ description: 'Knowledge sorted by Allay stage. Good for: seeing what\'s trusted, contested, or unverified.',
47
+ conceals: 'Spatial, temporal, and structural organization.',
48
+ icon: '⊕',
49
+ },
50
+ ];
51
+
52
+ let hoveredParadigm: ParadigmDefinition | null = $state(null);
53
+
54
+ function select(id: ParadigmId) {
55
+ onParadigmChange?.(id);
56
+ }
57
+ </script>
58
+
59
+ <div class="ds-paradigm-lens {className}">
60
+ <div class="tab-bar" role="tablist">
61
+ {#each PARADIGMS as p}
62
+ <button
63
+ class="tab"
64
+ class:active={activeParadigm === p.id}
65
+ role="tab"
66
+ aria-selected={activeParadigm === p.id}
67
+ type="button"
68
+ onmouseenter={() => hoveredParadigm = p}
69
+ onmouseleave={() => hoveredParadigm = null}
70
+ onclick={() => select(p.id as ParadigmId)}
71
+ >
72
+ <span class="tab-icon">{p.icon}</span>
73
+ <span class="tab-label">{p.label}</span>
74
+ </button>
75
+ {/each}
76
+ </div>
77
+
78
+ {#if hoveredParadigm}
79
+ <div class="paradigm-tooltip">
80
+ <strong>{hoveredParadigm.label}</strong>
81
+ <p>{hoveredParadigm.description}</p>
82
+ <p class="conceals">Conceals: {hoveredParadigm.conceals}</p>
83
+ </div>
84
+ {:else}
85
+ {@const current = PARADIGMS.find(p => p.id === activeParadigm)}
86
+ {#if current}
87
+ <div class="paradigm-tooltip muted">
88
+ <strong>{current.label}</strong>
89
+ <p>{current.description}</p>
90
+ <p class="conceals">Conceals: {current.conceals}</p>
91
+ </div>
92
+ {/if}
93
+ {/if}
94
+ </div>
95
+
96
+ <style>
97
+ .ds-paradigm-lens {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: var(--space-2);
101
+ font-family: var(--font-sans);
102
+ }
103
+
104
+ .tab-bar {
105
+ display: flex;
106
+ gap: 2px;
107
+ border-bottom: 1px solid var(--border-default);
108
+ overflow-x: auto;
109
+ scrollbar-width: none;
110
+ }
111
+
112
+ .tab-bar::-webkit-scrollbar { display: none; }
113
+
114
+ .tab {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: var(--space-1);
118
+ padding: var(--space-2) var(--space-3);
119
+ background: none;
120
+ border: none;
121
+ border-bottom: 2px solid transparent;
122
+ margin-bottom: -1px;
123
+ font-family: var(--font-sans);
124
+ font-size: var(--text-xs);
125
+ font-weight: 500;
126
+ color: var(--color-text-tertiary);
127
+ cursor: pointer;
128
+ white-space: nowrap;
129
+ transition: color 150ms, border-color 150ms;
130
+ }
131
+
132
+ .tab:hover { color: var(--color-text-secondary); }
133
+
134
+ .tab.active {
135
+ color: var(--color-accent);
136
+ border-bottom-color: var(--color-accent);
137
+ }
138
+
139
+ .tab-icon { font-size: var(--text-sm); }
140
+ .tab-label { font-size: var(--text-xs); }
141
+
142
+ .paradigm-tooltip {
143
+ padding: var(--space-2) var(--space-3);
144
+ background: var(--color-bg-panel-elevated);
145
+ border-radius: var(--radius-md);
146
+ border: 1px solid var(--border-subtle);
147
+ font-size: var(--text-xs);
148
+ }
149
+
150
+ .paradigm-tooltip.muted { opacity: 0.7; }
151
+
152
+ .paradigm-tooltip strong {
153
+ color: var(--color-text-primary);
154
+ font-weight: 600;
155
+ display: block;
156
+ margin-bottom: var(--space-1);
157
+ }
158
+
159
+ .paradigm-tooltip p {
160
+ color: var(--color-text-secondary);
161
+ line-height: 1.5;
162
+ margin: 0;
163
+ }
164
+
165
+ .paradigm-tooltip .conceals {
166
+ color: var(--color-text-muted);
167
+ margin-top: var(--space-1);
168
+ font-style: italic;
169
+ }
170
+ </style>
@@ -0,0 +1,164 @@
1
+ <script lang="ts">
2
+ import type { ProvenanceChainNode } from '../../epistemic/types.js';
3
+ import { getProvenanceNodeLabel } from '../../epistemic/utils.js';
4
+ import ExpertBadge from '../../u0-primitives/expert-badge/ExpertBadge.svelte';
5
+
6
+ interface Props {
7
+ nodes: ProvenanceChainNode[];
8
+ onnodeclick?: (node: ProvenanceChainNode) => void;
9
+ class?: string;
10
+ }
11
+
12
+ let { nodes, onnodeclick, class: className = '' }: Props = $props();
13
+
14
+ function getNodeActionLabel(node: ProvenanceChainNode): string | null {
15
+ switch (node.type) {
16
+ case 'file_source': return 'Open source';
17
+ case 'web_source': return 'Open URL';
18
+ case 'sigchain_witness': return 'View on chain';
19
+ case 'assay_evaluation': return 'View clearance';
20
+ case 'accord_replication': return 'View source Realm';
21
+ case 'agent_research': return 'View avenue';
22
+ default: return null;
23
+ }
24
+ }
25
+ </script>
26
+
27
+ <div class="ds-provenance-chain {className}">
28
+ {#each nodes as node, i}
29
+ <div class="node">
30
+ <!-- Timeline track -->
31
+ <div class="track">
32
+ <div class="bullet"></div>
33
+ {#if i < nodes.length - 1}
34
+ <div class="line"></div>
35
+ {/if}
36
+ </div>
37
+
38
+ <!-- Node content -->
39
+ <div class="content">
40
+ <div class="node-header">
41
+ <ExpertBadge expert={node.expert} size="sm" showName={false} />
42
+ <span class="node-label">{getProvenanceNodeLabel(node)}</span>
43
+ <span class="node-tick">tick {node.timestamp}</span>
44
+ </div>
45
+ <div class="node-expert-name">{node.expert.name}</div>
46
+
47
+ {#if getNodeActionLabel(node)}
48
+ <button
49
+ class="node-action"
50
+ type="button"
51
+ onclick={() => onnodeclick?.(node)}
52
+ >
53
+ {getNodeActionLabel(node)}
54
+ </button>
55
+ {/if}
56
+ </div>
57
+ </div>
58
+ {/each}
59
+
60
+ {#if nodes.length === 0}
61
+ <div class="empty">No provenance data available</div>
62
+ {/if}
63
+ </div>
64
+
65
+ <style>
66
+ .ds-provenance-chain {
67
+ display: flex;
68
+ flex-direction: column;
69
+ font-family: var(--font-sans);
70
+ }
71
+
72
+ .node {
73
+ display: flex;
74
+ gap: var(--space-3);
75
+ min-height: 3rem;
76
+ }
77
+
78
+ .track {
79
+ display: flex;
80
+ flex-direction: column;
81
+ align-items: center;
82
+ flex-shrink: 0;
83
+ width: 16px;
84
+ }
85
+
86
+ .bullet {
87
+ width: 8px;
88
+ height: 8px;
89
+ border-radius: 50%;
90
+ background: var(--color-accent);
91
+ border: 2px solid var(--color-bg-panel);
92
+ outline: 1px solid var(--color-accent);
93
+ flex-shrink: 0;
94
+ margin-top: 4px;
95
+ }
96
+
97
+ .line {
98
+ width: 2px;
99
+ flex: 1;
100
+ background: var(--border-default);
101
+ min-height: 1.5rem;
102
+ margin-top: 4px;
103
+ }
104
+
105
+ .content {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 2px;
109
+ padding-bottom: var(--space-3);
110
+ flex: 1;
111
+ }
112
+
113
+ .node-header {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: var(--space-2);
117
+ flex-wrap: wrap;
118
+ }
119
+
120
+ .node-label {
121
+ font-size: var(--text-xs);
122
+ color: var(--color-text-primary);
123
+ flex: 1;
124
+ min-width: 0;
125
+ }
126
+
127
+ .node-tick {
128
+ font-size: var(--text-xs);
129
+ font-family: var(--font-mono);
130
+ color: var(--color-text-tertiary);
131
+ flex-shrink: 0;
132
+ }
133
+
134
+ .node-expert-name {
135
+ font-size: var(--text-xs);
136
+ color: var(--color-text-tertiary);
137
+ padding-left: 1px;
138
+ }
139
+
140
+ .node-action {
141
+ background: none;
142
+ border: none;
143
+ padding: 0;
144
+ font-family: var(--font-sans);
145
+ font-size: var(--text-xs);
146
+ color: var(--color-accent);
147
+ cursor: pointer;
148
+ text-decoration: underline;
149
+ text-underline-offset: 2px;
150
+ text-align: left;
151
+ }
152
+
153
+ .node-action:hover {
154
+ color: var(--color-accent-hover);
155
+ }
156
+
157
+ .empty {
158
+ font-size: var(--text-xs);
159
+ color: var(--color-text-muted);
160
+ font-style: italic;
161
+ padding: var(--space-4) 0;
162
+ text-align: center;
163
+ }
164
+ </style>
@@ -0,0 +1,195 @@
1
+ <script lang="ts">
2
+ import type { KnowledgeEpistemicDetail } 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
+
7
+ interface Props {
8
+ knowledge: KnowledgeEpistemicDetail[];
9
+ onitemclick?: (item: KnowledgeEpistemicDetail) => void;
10
+ class?: string;
11
+ }
12
+
13
+ let { knowledge, onitemclick, class: className = '' }: Props = $props();
14
+
15
+ type GateGroup = 'Cleared' | 'Pending' | 'Blocked';
16
+ let activeGroup: GateGroup = $state('Cleared');
17
+
18
+ const groups: GateGroup[] = ['Cleared', 'Pending', 'Blocked'];
19
+
20
+ const sorted = $derived(
21
+ [...knowledge].sort((a, b) => b.allay.stage - a.allay.stage)
22
+ );
23
+
24
+ const cleared = $derived(sorted.filter(k => k.assay?.gate === 'Cleared'));
25
+ const blocked = $derived(sorted.filter(k => k.assay?.gate === 'Blocked'));
26
+ const pending = $derived(sorted.filter(k => !k.assay || (k.assay.gate !== 'Cleared' && k.assay.gate !== 'Blocked')));
27
+
28
+ function getGroup(group: GateGroup): KnowledgeEpistemicDetail[] {
29
+ switch (group) {
30
+ case 'Cleared': return cleared;
31
+ case 'Blocked': return blocked;
32
+ case 'Pending': return pending;
33
+ }
34
+ }
35
+
36
+ function groupCount(group: GateGroup): number {
37
+ return getGroup(group).length;
38
+ }
39
+ </script>
40
+
41
+ <div class="ds-trust-view {className}">
42
+ <!-- Group tabs -->
43
+ <div class="group-tabs" role="tablist">
44
+ {#each groups as group}
45
+ <button
46
+ class="group-tab"
47
+ class:active={activeGroup === group}
48
+ class:cleared={group === 'Cleared'}
49
+ class:blocked={group === 'Blocked'}
50
+ class:pending={group === 'Pending'}
51
+ role="tab"
52
+ aria-selected={activeGroup === group}
53
+ type="button"
54
+ onclick={() => activeGroup = group}
55
+ >
56
+ {group}
57
+ <span class="count">{groupCount(group)}</span>
58
+ </button>
59
+ {/each}
60
+ </div>
61
+
62
+ <!-- Knowledge list -->
63
+ <div class="knowledge-list">
64
+ {#each getGroup(activeGroup) as item}
65
+ <button
66
+ class="knowledge-item"
67
+ type="button"
68
+ onclick={() => onitemclick?.(item)}
69
+ >
70
+ <div class="item-gauges">
71
+ <AllayGauge stage={item.allay.stage} confidence={item.allay.confidence} size="sm" />
72
+ <AssayBadge clearance={item.assay ?? null} size="sm" />
73
+ </div>
74
+ <div class="item-info">
75
+ <span class="item-title">{item.title}</span>
76
+ <span class="item-source">{item.source}</span>
77
+ </div>
78
+ {#if item.expert}<ExpertBadge expert={item.expert} size="sm" showName={false} />{/if}
79
+ </button>
80
+ {/each}
81
+
82
+ {#if getGroup(activeGroup).length === 0}
83
+ <div class="empty">No {activeGroup.toLowerCase()} knowledge atoms</div>
84
+ {/if}
85
+ </div>
86
+ </div>
87
+
88
+ <style>
89
+ .ds-trust-view {
90
+ display: flex;
91
+ flex-direction: column;
92
+ font-family: var(--font-sans);
93
+ }
94
+
95
+ .group-tabs {
96
+ display: flex;
97
+ border-bottom: 1px solid var(--border-default);
98
+ margin-bottom: var(--space-3);
99
+ }
100
+
101
+ .group-tab {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: var(--space-1);
105
+ padding: var(--space-2) var(--space-4);
106
+ background: none;
107
+ border: none;
108
+ border-bottom: 2px solid transparent;
109
+ margin-bottom: -1px;
110
+ font-family: var(--font-sans);
111
+ font-size: var(--text-xs);
112
+ font-weight: 500;
113
+ color: var(--color-text-tertiary);
114
+ cursor: pointer;
115
+ transition: color 150ms, border-color 150ms;
116
+ }
117
+
118
+ .group-tab.active.cleared { color: var(--epistemic-cleared); border-bottom-color: var(--epistemic-cleared); }
119
+ .group-tab.active.blocked { color: var(--epistemic-blocked); border-bottom-color: var(--epistemic-blocked); }
120
+ .group-tab.active.pending { color: var(--epistemic-pending); border-bottom-color: var(--epistemic-pending); }
121
+
122
+ .count {
123
+ background: var(--color-bg-panel-elevated);
124
+ border-radius: var(--radius-full);
125
+ padding: 0 var(--space-1);
126
+ font-size: 10px;
127
+ font-family: var(--font-mono);
128
+ color: var(--color-text-secondary);
129
+ }
130
+
131
+ .knowledge-list {
132
+ display: flex;
133
+ flex-direction: column;
134
+ gap: var(--space-1);
135
+ }
136
+
137
+ .knowledge-item {
138
+ display: flex;
139
+ align-items: center;
140
+ gap: var(--space-3);
141
+ padding: var(--space-2) var(--space-3);
142
+ background: var(--color-bg-panel-elevated);
143
+ border: 1px solid var(--border-subtle);
144
+ border-radius: var(--radius-md);
145
+ cursor: pointer;
146
+ text-align: left;
147
+ transition: background 150ms, border-color 150ms;
148
+ width: 100%;
149
+ }
150
+
151
+ .knowledge-item:hover {
152
+ background: var(--color-bg-panel);
153
+ border-color: var(--border-hover);
154
+ }
155
+
156
+ .item-gauges {
157
+ display: flex;
158
+ align-items: center;
159
+ gap: var(--space-2);
160
+ flex-shrink: 0;
161
+ }
162
+
163
+ .item-info {
164
+ display: flex;
165
+ flex-direction: column;
166
+ gap: 2px;
167
+ flex: 1;
168
+ min-width: 0;
169
+ }
170
+
171
+ .item-title {
172
+ font-size: var(--text-xs);
173
+ color: var(--color-text-primary);
174
+ white-space: nowrap;
175
+ overflow: hidden;
176
+ text-overflow: ellipsis;
177
+ }
178
+
179
+ .item-source {
180
+ font-size: var(--text-xs);
181
+ font-family: var(--font-mono);
182
+ color: var(--color-text-tertiary);
183
+ white-space: nowrap;
184
+ overflow: hidden;
185
+ text-overflow: ellipsis;
186
+ }
187
+
188
+ .empty {
189
+ font-size: var(--text-xs);
190
+ color: var(--color-text-muted);
191
+ font-style: italic;
192
+ padding: var(--space-4);
193
+ text-align: center;
194
+ }
195
+ </style>
@@ -0,0 +1,7 @@
1
+ export { default as AssayDetailPanel } from './AssayDetailPanel.svelte';
2
+ export { default as AllayDetailPanel } from './AllayDetailPanel.svelte';
3
+ export { default as ProvenanceChain } from './ProvenanceChain.svelte';
4
+ export { default as KnowledgeDetailPanel } from './KnowledgeDetailPanel.svelte';
5
+ export { default as AvenueTrace } from './AvenueTrace.svelte';
6
+ export { default as ParadigmLens } from './ParadigmLens.svelte';
7
+ export { default as TrustView } from './TrustView.svelte';
@@ -0,0 +1,156 @@
1
+ <script lang="ts">
2
+ import Card from '../../u0-primitives/card/Card.svelte';
3
+ import Badge from '../../u0-primitives/badge/Badge.svelte';
4
+
5
+ interface Props {
6
+ accordId: string;
7
+ domains: string[];
8
+ participantCount: number;
9
+ expiresAt: number;
10
+ groveId?: string;
11
+ class?: string;
12
+ }
13
+
14
+ let {
15
+ accordId,
16
+ domains,
17
+ participantCount,
18
+ expiresAt,
19
+ groveId,
20
+ class: className = ''
21
+ }: Props = $props();
22
+
23
+ let now = $state(Date.now());
24
+
25
+ $effect(() => {
26
+ const id = setInterval(() => { now = Date.now(); }, 60_000);
27
+ return () => clearInterval(id);
28
+ });
29
+
30
+ let timeRemaining = $derived.by(() => {
31
+ const diff = expiresAt - now;
32
+ if (diff <= 0) return 'Expired';
33
+ const days = Math.floor(diff / (1000 * 60 * 60 * 24));
34
+ const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
35
+ if (days > 0) return `${days}d ${hours}h`;
36
+ const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
37
+ return `${hours}h ${minutes}m`;
38
+ });
39
+
40
+ let isExpired = $derived(expiresAt <= now);
41
+ let isExpiringSoon = $derived(!isExpired && (expiresAt - now) < 1000 * 60 * 60 * 24);
42
+ </script>
43
+
44
+ <Card variant="elevated" class="ds-accord-card {className}">
45
+ <div class="ds-accord-inner">
46
+ <div class="ds-accord-header">
47
+ <h3 class="ds-accord-name" title={accordId}>{accordId}</h3>
48
+ {#if groveId}
49
+ <span class="ds-accord-grove" title="Linked grove: {groveId}">{groveId}</span>
50
+ {/if}
51
+ </div>
52
+
53
+ <div class="ds-accord-domains">
54
+ {#each domains as domain}
55
+ <Badge variant="outline" color="accent" size="sm">{domain}</Badge>
56
+ {/each}
57
+ </div>
58
+
59
+ <div class="ds-accord-footer">
60
+ <span class="ds-accord-stat">
61
+ <span class="ds-accord-stat-value">{participantCount}</span>
62
+ <span class="ds-accord-stat-label">{participantCount === 1 ? 'realm' : 'realms'}</span>
63
+ </span>
64
+
65
+ <span
66
+ class="ds-accord-expiry"
67
+ class:is-expired={isExpired}
68
+ class:is-expiring-soon={isExpiringSoon}
69
+ title="Expires: {new Date(expiresAt).toLocaleString()}"
70
+ >
71
+ {timeRemaining}
72
+ </span>
73
+ </div>
74
+ </div>
75
+ </Card>
76
+
77
+ <style>
78
+ .ds-accord-inner {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: var(--space-3);
82
+ padding: var(--space-4);
83
+ font-family: var(--font-sans);
84
+ }
85
+
86
+ .ds-accord-header {
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: space-between;
90
+ gap: var(--space-3);
91
+ }
92
+
93
+ .ds-accord-name {
94
+ margin: 0;
95
+ font-size: var(--text-sm);
96
+ font-weight: 600;
97
+ color: var(--color-text-primary);
98
+ overflow: hidden;
99
+ text-overflow: ellipsis;
100
+ white-space: nowrap;
101
+ min-width: 0;
102
+ }
103
+
104
+ .ds-accord-grove {
105
+ font-size: var(--text-xs);
106
+ color: var(--color-text-muted);
107
+ font-family: var(--font-mono);
108
+ flex-shrink: 0;
109
+ }
110
+
111
+ .ds-accord-domains {
112
+ display: flex;
113
+ flex-wrap: wrap;
114
+ gap: var(--space-2);
115
+ }
116
+
117
+ .ds-accord-footer {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: space-between;
121
+ padding-top: var(--space-2);
122
+ border-top: 1px solid var(--border-subtle);
123
+ }
124
+
125
+ .ds-accord-stat {
126
+ display: flex;
127
+ align-items: baseline;
128
+ gap: var(--space-1);
129
+ }
130
+
131
+ .ds-accord-stat-value {
132
+ font-size: var(--text-sm);
133
+ font-weight: 600;
134
+ color: var(--color-text-primary);
135
+ font-family: var(--font-mono);
136
+ }
137
+
138
+ .ds-accord-stat-label {
139
+ font-size: var(--text-xs);
140
+ color: var(--color-text-muted);
141
+ }
142
+
143
+ .ds-accord-expiry {
144
+ font-size: var(--text-xs);
145
+ font-family: var(--font-mono);
146
+ color: var(--color-text-secondary);
147
+ }
148
+
149
+ .ds-accord-expiry.is-expiring-soon {
150
+ color: var(--color-warning);
151
+ }
152
+
153
+ .ds-accord-expiry.is-expired {
154
+ color: var(--color-error);
155
+ }
156
+ </style>