@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.
- package/README.md +66 -0
- package/package.json +130 -0
- package/src/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte +221 -0
- package/src/b0-app-shell/clarification-overlay/index.ts +1 -0
- package/src/b0-app-shell/command-bar/CommandBar.svelte +565 -0
- package/src/b0-app-shell/index.ts +14 -0
- package/src/base.css +152 -0
- package/src/d0-data-viz/BarChart.svelte +236 -0
- package/src/d0-data-viz/CheckpointBar.svelte +574 -0
- package/src/d0-data-viz/CheckpointPill.svelte +297 -0
- package/src/d0-data-viz/MetricCard.svelte +159 -0
- package/src/d0-data-viz/SparkLine.svelte +66 -0
- package/src/d0-data-viz/StorageMap.svelte +182 -0
- package/src/d0-data-viz/Timeline.svelte +188 -0
- package/src/d0-data-viz/checkpoint-types.ts +162 -0
- package/src/d0-data-viz/d0-tokens.css +32 -0
- package/src/d0-data-viz/index.ts +58 -0
- package/src/d0-data-viz/storage-map-types.ts +142 -0
- package/src/d0-data-viz/theme-integration.ts +134 -0
- package/src/d0-data-viz/types.ts +53 -0
- package/src/demos/BspSizingInfographic.svelte +386 -0
- package/src/demos/BspZoneDemo.svelte +255 -0
- package/src/demos/ControlRoomDemo.svelte +570 -0
- package/src/demos/NodepadBlocksShowcase.svelte +189 -0
- package/src/demos/index.ts +7 -0
- package/src/editor/CodeEditor.svelte +188 -0
- package/src/editor/FindReplaceDialog.svelte +516 -0
- package/src/editor/MarkdownEditor.svelte +660 -0
- package/src/editor/index.ts +2 -0
- package/src/entity-graph-view/WorldView.svelte +171 -0
- package/src/entity-graph-view/index.ts +6 -0
- package/src/entity-graph-view/types.ts +364 -0
- package/src/epistemic/index.ts +2 -0
- package/src/epistemic/types.ts +134 -0
- package/src/epistemic/utils.ts +32 -0
- package/src/f0-forms/checkbox/Checkbox.svelte +158 -0
- package/src/f0-forms/field/FormField.svelte +91 -0
- package/src/f0-forms/index.ts +11 -0
- package/src/f0-forms/radio/RadioGroup.svelte +192 -0
- package/src/f0-forms/search/SearchBar.svelte +99 -0
- package/src/f0-forms/select/Select.svelte +198 -0
- package/src/f0-forms/textarea/TextArea.svelte +170 -0
- package/src/f0-forms/toggle/FormToggle.svelte +147 -0
- package/src/f0-forms/validation/validate.ts +47 -0
- package/src/fabric/ai/ChatPanel.svelte +648 -0
- package/src/fabric/ai/index.ts +11 -0
- package/src/fabric/data/index.ts +21 -0
- package/src/fabric/feedback/StatusBar.svelte +274 -0
- package/src/fabric/feedback/ToastContainer.svelte +122 -0
- package/src/fabric/feedback/index.ts +14 -0
- package/src/fabric/index.ts +37 -0
- package/src/fabric/input/CommandBar.svelte +79 -0
- package/src/fabric/input/KeyboardShortcuts.svelte +388 -0
- package/src/fabric/input/index.ts +12 -0
- package/src/fabric/layout/GlassBox.svelte +193 -0
- package/src/fabric/layout/KanbanBoard.svelte +158 -0
- package/src/fabric/layout/KanbanCard.svelte +226 -0
- package/src/fabric/layout/KanbanColumn.svelte +278 -0
- package/src/fabric/layout/index.ts +17 -0
- package/src/fabric/navigation/ActivityRail.svelte +271 -0
- package/src/fabric/navigation/index.ts +11 -0
- package/src/g0-geo/SovereignMap.svelte +149 -0
- package/src/g0-geo/index.ts +2 -0
- package/src/index.ts +68 -0
- package/src/l0-layout/block-writer/BlockConnectionLines.svelte +98 -0
- package/src/l0-layout/block-writer/BlockContent.svelte +213 -0
- package/src/l0-layout/block-writer/BlockHeader.svelte +230 -0
- package/src/l0-layout/block-writer/BlockItem.svelte +177 -0
- package/src/l0-layout/block-writer/BlockWriter.svelte +219 -0
- package/src/l0-layout/block-writer/block-writer-types.ts +63 -0
- package/src/l0-layout/block-writer/index.ts +24 -0
- package/src/l0-layout/block-writer/markdown.ts +110 -0
- package/src/l0-layout/chat-view/ChatViewLayout.svelte +61 -0
- package/src/l0-layout/epistemic/AllayDetailPanel.svelte +113 -0
- package/src/l0-layout/epistemic/AssayDetailPanel.svelte +164 -0
- package/src/l0-layout/epistemic/AvenueTrace.svelte +253 -0
- package/src/l0-layout/epistemic/KnowledgeDetailPanel.svelte +204 -0
- package/src/l0-layout/epistemic/ParadigmLens.svelte +170 -0
- package/src/l0-layout/epistemic/ProvenanceChain.svelte +164 -0
- package/src/l0-layout/epistemic/TrustView.svelte +195 -0
- package/src/l0-layout/epistemic/index.ts +7 -0
- package/src/l0-layout/grove/AccordCard.svelte +156 -0
- package/src/l0-layout/grove/GroveCard.svelte +197 -0
- package/src/l0-layout/grove/MemberBadge.svelte +96 -0
- package/src/l0-layout/grove/MemberList.svelte +59 -0
- package/src/l0-layout/grove/grove-types.ts +29 -0
- package/src/l0-layout/grove/index.ts +14 -0
- package/src/l0-layout/index.ts +45 -0
- package/src/l0-layout/kanban/KanbanBoard.svelte +71 -0
- package/src/l0-layout/kanban/KanbanCard.svelte +276 -0
- package/src/l0-layout/kanban/KanbanColumn.svelte +198 -0
- package/src/l0-layout/kanban/KanbanViewLayout.svelte +61 -0
- package/src/l0-layout/workspace/WorkspaceLayout.svelte +93 -0
- package/src/n0-node-graph/GraphEditor.svelte +342 -0
- package/src/n0-node-graph/GraphHistory.svelte +122 -0
- package/src/n0-node-graph/Node.svelte +269 -0
- package/src/n0-node-graph/NodeCanvas.svelte +187 -0
- package/src/n0-node-graph/NodeEdge.svelte +152 -0
- package/src/n0-node-graph/NodePalette.svelte +318 -0
- package/src/n0-node-graph/NodePort.svelte +128 -0
- package/src/n0-node-graph/index.ts +33 -0
- package/src/n0-node-graph/n0-tokens.css +29 -0
- package/src/n0-node-graph/node-port-types.ts +19 -0
- package/src/n0-node-graph/types.ts +96 -0
- package/src/n0-node-graph/validate.test.ts +722 -0
- package/src/n0-node-graph/validate.ts +371 -0
- package/src/n1-flow-canvas/FlowCanvas.svelte +202 -0
- package/src/n1-flow-canvas/graph-state.svelte.ts +95 -0
- package/src/n1-flow-canvas/index.ts +21 -0
- package/src/n1-flow-canvas/layout.ts +118 -0
- package/src/n1-flow-canvas/layout.worker.ts +128 -0
- package/src/n1-flow-canvas/types.ts +102 -0
- package/src/n1-flow-canvas/utils.ts +146 -0
- package/src/n2-manifold-disk/ManifoldDisk.svelte +314 -0
- package/src/n2-manifold-disk/index.ts +6 -0
- package/src/n2-manifold-disk/poincare.ts +184 -0
- package/src/n3-force-graph/ForceGraph.svelte +180 -0
- package/src/n3-force-graph/GraphTooltip.svelte +99 -0
- package/src/n3-force-graph/animated-edge.ts +107 -0
- package/src/n3-force-graph/health-node.ts +128 -0
- package/src/n3-force-graph/index.ts +31 -0
- package/src/n3-force-graph/types.ts +94 -0
- package/src/n4-adaptive-manifold/AdaptiveManifold.svelte +1165 -0
- package/src/n4-adaptive-manifold/DetailCard.svelte +212 -0
- package/src/n4-adaptive-manifold/SuggestionIndicator.svelte +91 -0
- package/src/n4-adaptive-manifold/classifier.ts +139 -0
- package/src/n4-adaptive-manifold/index.ts +45 -0
- package/src/n4-adaptive-manifold/n4-tokens.css +155 -0
- package/src/n4-adaptive-manifold/orchestrator.ts +301 -0
- package/src/n4-adaptive-manifold/phase-theme.ts +92 -0
- package/src/n4-adaptive-manifold/pinnacle-events.ts +135 -0
- package/src/n4-adaptive-manifold/providers/gravitational-provider.ts +191 -0
- package/src/n4-adaptive-manifold/providers/manifold-provider.ts +276 -0
- package/src/n4-adaptive-manifold/transition.ts +90 -0
- package/src/n4-adaptive-manifold/types.ts +313 -0
- package/src/p0-primitives/index.ts +6 -0
- package/src/p0-primitives/tokens/control-room.css +309 -0
- package/src/p0-primitives/tokens/index.ts +6 -0
- package/src/p0-primitives/tokens/tokens.css +140 -0
- package/src/p0-primitives/tokens/tokens.json +132 -0
- package/src/p0-primitives/types/index.ts +123 -0
- package/src/p0-primitives/types/plugin-types.ts +74 -0
- package/src/p0-primitives/utils/index.ts +39 -0
- package/src/platform/hud-protocol.ts +20 -0
- package/src/platform/index.ts +3 -0
- package/src/s0-state/create-store.ts +84 -0
- package/src/s0-state/derived.ts +41 -0
- package/src/s0-state/index.ts +6 -0
- package/src/showcase/Showcase.svelte +401 -0
- package/src/spatial/BspTilingCanvas.svelte +232 -0
- package/src/spatial/ForceCanvas.svelte +289 -0
- package/src/spatial/LodRenderer.svelte +334 -0
- package/src/spatial/SnapZoomCamera.svelte +185 -0
- package/src/spatial/ZoneTiler.svelte +311 -0
- package/src/spatial/camera-types.ts +45 -0
- package/src/spatial/content-proportional-bsp.ts +253 -0
- package/src/spatial/force-canvas-types.ts +102 -0
- package/src/spatial/index.ts +15 -0
- package/src/spatial/lod-types.ts +70 -0
- package/src/spatial/zone-tiler-types.ts +177 -0
- package/src/stores/vaultStore.svelte +14 -0
- package/src/t0-transport/connection.ts +34 -0
- package/src/t0-transport/error.ts +37 -0
- package/src/t0-transport/events.ts +50 -0
- package/src/t0-transport/index.ts +6 -0
- package/src/t0-transport/invoke.ts +30 -0
- package/src/tauri/index.ts +13 -0
- package/src/u0-primitives/allay-gauge/AllayGauge.svelte +90 -0
- package/src/u0-primitives/allay-gauge/index.ts +1 -0
- package/src/u0-primitives/animated-icon/AnimatedIcon.svelte +273 -0
- package/src/u0-primitives/animated-icon/README.md +53 -0
- package/src/u0-primitives/animated-icon/index.ts +31 -0
- package/src/u0-primitives/assay-badge/AssayBadge.svelte +121 -0
- package/src/u0-primitives/assay-badge/AssaySignalBar.svelte +83 -0
- package/src/u0-primitives/assay-badge/index.ts +2 -0
- package/src/u0-primitives/avatar/Avatar.svelte +177 -0
- package/src/u0-primitives/badge/Badge.svelte +149 -0
- package/src/u0-primitives/button/Button.svelte +304 -0
- package/src/u0-primitives/card/Card.svelte +182 -0
- package/src/u0-primitives/dropdown/Dropdown.svelte +305 -0
- package/src/u0-primitives/expert-badge/ExpertBadge.svelte +89 -0
- package/src/u0-primitives/expert-badge/index.ts +1 -0
- package/src/u0-primitives/index.ts +35 -0
- package/src/u0-primitives/input/Input.svelte +237 -0
- package/src/u0-primitives/modal/Modal.svelte +331 -0
- package/src/u0-primitives/modal/index.ts +1 -0
- package/src/u0-primitives/spinner/Spinner.svelte +129 -0
- package/src/u0-primitives/tabs/Tabs.svelte +225 -0
- package/src/u0-primitives/tabs/tabs-types.ts +11 -0
- package/src/u0-primitives/toggle/Toggle.svelte +161 -0
- package/src/u0-primitives/tooltip/Tooltip.svelte +234 -0
- package/src/v0-diagrams/DiagramPanel.svelte +68 -0
- package/src/v0-diagrams/MarkmapDiagram.svelte +56 -0
- package/src/v0-diagrams/MermaidDiagram.svelte +53 -0
- package/src/v0-diagrams/index.ts +4 -0
- package/src/v0-diagrams/types.ts +28 -0
- package/src/v0-diagrams/v0-tokens.css +6 -0
- package/src/vite-env.d.ts +7 -0
- package/src/x0-enchanted-blocks/ENCHANTED_BLOCKS_SPEC.md +457 -0
- package/src/x0-enchanted-blocks/components/EnchantedBlock.svelte +485 -0
- package/src/x0-enchanted-blocks/components/NodepadBlock.svelte +262 -0
- package/src/x0-enchanted-blocks/core/block-layout.ts +211 -0
- package/src/x0-enchanted-blocks/core/block-types.ts +227 -0
- package/src/x0-enchanted-blocks/index.ts +46 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
// N4 Adaptive Manifold — Core Types
|
|
2
|
+
// Pure TypeScript — no Svelte, no DOM dependencies
|
|
3
|
+
// S-02: deterministic ordering, no HashMap/Set iteration
|
|
4
|
+
|
|
5
|
+
import type { NodeLayout, LayoutResult } from '../n1-flow-canvas/types.js';
|
|
6
|
+
|
|
7
|
+
// === Topology Kinds ===
|
|
8
|
+
|
|
9
|
+
/** The active layout algorithm. Gravitational is the only registered provider. */
|
|
10
|
+
export type LayoutAlgorithm = 'gravitational' | 'manifold';
|
|
11
|
+
|
|
12
|
+
// === Node Status ===
|
|
13
|
+
|
|
14
|
+
/** Visual treatment for nodes — maps to --n4-node-* design tokens. */
|
|
15
|
+
export type NodeStatus =
|
|
16
|
+
| 'active' // Brass glow, full opacity
|
|
17
|
+
| 'idle' // Muted, reduced opacity
|
|
18
|
+
| 'blocked' // Warning accent, dashed border
|
|
19
|
+
| 'completed' // Faded, can be auto-hidden
|
|
20
|
+
| 'critical'; // Error accent, pulse animation
|
|
21
|
+
|
|
22
|
+
// === Manifold Data Primitives ===
|
|
23
|
+
|
|
24
|
+
/** A node in the adaptive manifold. Domain-agnostic — the canvas never inspects metadata. */
|
|
25
|
+
export interface ManifoldNode {
|
|
26
|
+
/** Stable ID across snapshots. Same entity = same ID across domains. */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Domain-defined type: 'task', 'agent', 'signal', 'capability', 'intent', etc. */
|
|
29
|
+
kind: string;
|
|
30
|
+
/** Display name. */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Visual treatment — maps to design tokens. */
|
|
33
|
+
status: NodeStatus;
|
|
34
|
+
/** 0–1, influences node size and gravity. */
|
|
35
|
+
weight: number;
|
|
36
|
+
/** User has fixed this node's position. */
|
|
37
|
+
pinned: boolean;
|
|
38
|
+
/** Domain-specific, opaque to canvas. Exposed in click handlers. */
|
|
39
|
+
metadata: Record<string, unknown>;
|
|
40
|
+
/** Optional spatial hints — domain adapters can suggest, canvas can ignore. */
|
|
41
|
+
hint?: { x?: number; y?: number; cluster?: string; rotation_axis?: string | null };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** An edge in the adaptive manifold. */
|
|
45
|
+
export interface ManifoldEdge {
|
|
46
|
+
id: string;
|
|
47
|
+
/** Source node ID. */
|
|
48
|
+
source: string;
|
|
49
|
+
/** Target node ID. */
|
|
50
|
+
target: string;
|
|
51
|
+
/** Domain-defined relationship: 'depends_on', 'delegates_to', 'emits', etc. */
|
|
52
|
+
relation: string;
|
|
53
|
+
/** Whether the edge has direction (arrow). */
|
|
54
|
+
directed: boolean;
|
|
55
|
+
/** 0–1, influences edge visual weight and spring tension. */
|
|
56
|
+
strength: number;
|
|
57
|
+
/** If true, edge fades after animation (for signal pulses). */
|
|
58
|
+
transient: boolean;
|
|
59
|
+
/** Domain-specific, opaque to canvas. */
|
|
60
|
+
metadata: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Immutable snapshot of manifold data — the input to all layout providers. */
|
|
64
|
+
export interface ManifoldSnapshot {
|
|
65
|
+
/** SOVEREIGN deterministic sequence — not wall clock. S-02 compliant. */
|
|
66
|
+
readonly sequence: number;
|
|
67
|
+
readonly nodes: ReadonlyArray<ManifoldNode>;
|
|
68
|
+
readonly edges: ReadonlyArray<ManifoldEdge>;
|
|
69
|
+
/** 'initial' = full graph, 'incremental' = delta (new nodes/edges only). */
|
|
70
|
+
readonly epoch: 'initial' | 'incremental';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// === Node Style Registry ===
|
|
74
|
+
|
|
75
|
+
/** Maps node `kind` strings to visual treatment. Registered by consuming apps, not the canvas. */
|
|
76
|
+
export interface NodeStyleEntry {
|
|
77
|
+
/** Icon identifier (e.g. lucide icon name). */
|
|
78
|
+
icon: string;
|
|
79
|
+
/** Node shape for rendering. */
|
|
80
|
+
shape: 'rounded-rect' | 'hexagon' | 'diamond' | 'pill' | 'rect' | 'circle';
|
|
81
|
+
/** CSS custom property name for accent color (e.g. '--n4-kind-task'). */
|
|
82
|
+
accentVar: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type NodeStyleRegistry = Record<string, NodeStyleEntry>;
|
|
86
|
+
|
|
87
|
+
// ManifoldDomain (tab-per-domain adapter pattern) was removed per
|
|
88
|
+
// pinnacle-garden-observer-001 ADR. All entity types coexist on one composite canvas.
|
|
89
|
+
// Old per-domain adapters in consuming apps (tasksAdapter, agentsAdapter, etc.) are dead code.
|
|
90
|
+
|
|
91
|
+
// === Layout Preferences ===
|
|
92
|
+
|
|
93
|
+
/** User/adaptive preferences that influence topology selection and rendering. */
|
|
94
|
+
export interface LayoutPreferences {
|
|
95
|
+
/** Lock to a specific algorithm, bypassing the classifier. null = auto. */
|
|
96
|
+
lockedAlgorithm: LayoutAlgorithm | null;
|
|
97
|
+
/** Animate transitions between layouts. Default true. */
|
|
98
|
+
animate: boolean;
|
|
99
|
+
/** Morph transition duration in ms. Default 600. */
|
|
100
|
+
morphDurationMs: number;
|
|
101
|
+
/** Easing curve identifier. Default 'easeInOutCubic'. */
|
|
102
|
+
easing: EasingCurve;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type EasingCurve =
|
|
106
|
+
| 'linear'
|
|
107
|
+
| 'easeInOutCubic'
|
|
108
|
+
| 'easeOutExpo'
|
|
109
|
+
| 'spring';
|
|
110
|
+
|
|
111
|
+
/** Default layout preferences — auto-classify, animate, 600ms easeInOutCubic. */
|
|
112
|
+
export const DEFAULT_LAYOUT_PREFERENCES: LayoutPreferences = {
|
|
113
|
+
lockedAlgorithm: null,
|
|
114
|
+
animate: true,
|
|
115
|
+
morphDurationMs: 600,
|
|
116
|
+
easing: 'easeInOutCubic',
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// === Algorithm Provider Interface ===
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Each layout algorithm has an AlgorithmProvider that computes node positions.
|
|
123
|
+
* Providers are stateless — all context comes from arguments.
|
|
124
|
+
* Implementations must be deterministic given the same snapshot + dimensions.
|
|
125
|
+
*/
|
|
126
|
+
export interface AlgorithmProvider {
|
|
127
|
+
/** The layout algorithm this provider implements. */
|
|
128
|
+
readonly algorithm: LayoutAlgorithm;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Compute a layout for the given snapshot within the given canvas bounds.
|
|
132
|
+
* Returns a LayoutResult with positions and BFS order.
|
|
133
|
+
* May be async (e.g. ELK runs a web worker).
|
|
134
|
+
*/
|
|
135
|
+
layout(
|
|
136
|
+
snapshot: ManifoldSnapshot,
|
|
137
|
+
canvasWidth: number,
|
|
138
|
+
canvasHeight: number,
|
|
139
|
+
): Promise<LayoutResult>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// === Classifier ===
|
|
143
|
+
|
|
144
|
+
/** Topology metrics computed once per classification. */
|
|
145
|
+
export interface TopologyMetrics {
|
|
146
|
+
nodeCount: number;
|
|
147
|
+
edgeCount: number;
|
|
148
|
+
edgeDensity: number;
|
|
149
|
+
maxDepth: number;
|
|
150
|
+
rootCount: number;
|
|
151
|
+
cycleCount: number;
|
|
152
|
+
componentCount: number;
|
|
153
|
+
maxClusterSize: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Result of topology classification — recommended algorithm with reasoning. */
|
|
157
|
+
export interface ClassificationResult {
|
|
158
|
+
/** Recommended layout algorithm. */
|
|
159
|
+
recommended: LayoutAlgorithm;
|
|
160
|
+
/** Confidence 0–1 of the recommendation. */
|
|
161
|
+
confidence: number;
|
|
162
|
+
/** Human-readable reason. */
|
|
163
|
+
reason: string;
|
|
164
|
+
/** All algorithms ranked by fitness, descending. */
|
|
165
|
+
ranked: Array<{ algorithm: LayoutAlgorithm; fitness: number }>;
|
|
166
|
+
/** Computed topology metrics. */
|
|
167
|
+
metrics: TopologyMetrics;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// === Transition / Animation ===
|
|
171
|
+
|
|
172
|
+
/** Named animation moment types from the ADR. */
|
|
173
|
+
export type AnimationMomentKind =
|
|
174
|
+
| 'settle' // Initial layout or incremental update
|
|
175
|
+
| 'morph' // Layout algorithm switch
|
|
176
|
+
| 'pulse' // Transient edge signal
|
|
177
|
+
| 'arrive' // New node added
|
|
178
|
+
| 'depart' // Node removed
|
|
179
|
+
| 'focus'; // User clicked a node
|
|
180
|
+
|
|
181
|
+
/** A single frame in a layout transition animation. */
|
|
182
|
+
export interface AnimationFrame {
|
|
183
|
+
/** Interpolated positions at this frame. */
|
|
184
|
+
positions: Map<string, NodeLayout>;
|
|
185
|
+
/** Progress 0→1 through the transition. */
|
|
186
|
+
progress: number;
|
|
187
|
+
/** Elapsed ms since transition start. */
|
|
188
|
+
elapsedMs: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Easing function: takes t (0→1), returns eased t (0→1). */
|
|
192
|
+
export type EasingFn = (t: number) => number;
|
|
193
|
+
|
|
194
|
+
// === Suggestion ===
|
|
195
|
+
|
|
196
|
+
/** A layout suggestion to show the user when the classifier disagrees with current view. */
|
|
197
|
+
export interface LayoutSuggestion {
|
|
198
|
+
/** Suggested algorithm to switch to. */
|
|
199
|
+
algorithm: LayoutAlgorithm;
|
|
200
|
+
/** Confidence 0–1 of the suggestion. */
|
|
201
|
+
confidence: number;
|
|
202
|
+
/** Human-readable reason. */
|
|
203
|
+
reason: string;
|
|
204
|
+
/** Whether the user has dismissed this suggestion. */
|
|
205
|
+
dismissed: boolean;
|
|
206
|
+
/** Whether the user has pinned their current layout. */
|
|
207
|
+
pinned: boolean;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// === Resolved Theme Colors ===
|
|
211
|
+
|
|
212
|
+
/** Colors resolved from --n4-* CSS tokens at mount time via getComputedStyle. */
|
|
213
|
+
export interface ResolvedThemeColors {
|
|
214
|
+
canvasBg: string;
|
|
215
|
+
nodeActive: string;
|
|
216
|
+
nodeIdle: string;
|
|
217
|
+
nodeBlocked: string;
|
|
218
|
+
nodeCompleted: string;
|
|
219
|
+
nodeCritical: string;
|
|
220
|
+
nodeBg: string;
|
|
221
|
+
nodeBorder: string;
|
|
222
|
+
nodeText: string;
|
|
223
|
+
edgeColor: string;
|
|
224
|
+
edgeActive: string;
|
|
225
|
+
pulseColor: string;
|
|
226
|
+
pulseCritical: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// === Garden Observer Types ===
|
|
230
|
+
|
|
231
|
+
/** Inferred phase in the perceive-think-act-sync loop */
|
|
232
|
+
export type LoopPhase = 'perceive' | 'think' | 'act' | 'sync' | 'idle';
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Canonical event shape consumed by the Pinnacle canvas.
|
|
236
|
+
*
|
|
237
|
+
* Note: the ADR also specified `entry: SigchainEntry`, but that type lives in
|
|
238
|
+
* SOVEREIGN — the design-system cannot take that dependency. `sequence` provides
|
|
239
|
+
* the same S-04 auditability anchor. Consumers needing the raw sigchain entry
|
|
240
|
+
* should carry it separately alongside the PinnacleEvent.
|
|
241
|
+
*/
|
|
242
|
+
export interface PinnacleEvent {
|
|
243
|
+
/** Which agent this event concerns */
|
|
244
|
+
agentId: string;
|
|
245
|
+
/** Task/capability being interacted with, if any */
|
|
246
|
+
targetId: string | null;
|
|
247
|
+
/** Inferred loop phase */
|
|
248
|
+
loopPhase: LoopPhase;
|
|
249
|
+
/** Sigchain sequence number (deterministic ordering, not wall clock) */
|
|
250
|
+
sequence: number;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Visual parameters for a single FLOW phase */
|
|
254
|
+
export interface PhaseVisualParams {
|
|
255
|
+
/** Canvas background tint */
|
|
256
|
+
background: string;
|
|
257
|
+
/** 0-1 multiplier on indicator layer brightness */
|
|
258
|
+
brightness: number;
|
|
259
|
+
/** 0-1 multiplier on indicator opacity */
|
|
260
|
+
indicatorIntensity: number;
|
|
261
|
+
/** Seconds per ambient pulse cycle */
|
|
262
|
+
ambientPulseSpeed: number;
|
|
263
|
+
/** 0-1 desaturation factor (0 = full desaturation for freeze) */
|
|
264
|
+
saturation: number;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** Maps FLOW phases to visual parameters — the theming contract */
|
|
268
|
+
export interface PhaseTheme {
|
|
269
|
+
seed: PhaseVisualParams;
|
|
270
|
+
sprout: PhaseVisualParams;
|
|
271
|
+
go: PhaseVisualParams;
|
|
272
|
+
consult: PhaseVisualParams;
|
|
273
|
+
weed: PhaseVisualParams;
|
|
274
|
+
freeze: PhaseVisualParams;
|
|
275
|
+
compost: PhaseVisualParams;
|
|
276
|
+
prune: PhaseVisualParams;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Configuration for the gravitational force simulation */
|
|
280
|
+
export interface GravitationalConfig {
|
|
281
|
+
/** 0-1: how strongly role pulls toward zone */
|
|
282
|
+
roleGravityStrength: number;
|
|
283
|
+
/** 0-1: how strongly current work pulls agent toward target */
|
|
284
|
+
interactionPullStrength: number;
|
|
285
|
+
/** Velocity decay per tick (0-1, higher = more damping) */
|
|
286
|
+
damping: number;
|
|
287
|
+
/** Minimum node separation in pixels */
|
|
288
|
+
collisionRadius: number;
|
|
289
|
+
/** Subtle random motion amplitude when idle */
|
|
290
|
+
ambientDrift: number;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export const DEFAULT_GRAVITATIONAL_CONFIG: GravitationalConfig = {
|
|
294
|
+
roleGravityStrength: 0.3,
|
|
295
|
+
interactionPullStrength: 0.6,
|
|
296
|
+
damping: 0.85,
|
|
297
|
+
collisionRadius: 45,
|
|
298
|
+
ambientDrift: 0.5,
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/** Per-node indicator state for the compositing layer */
|
|
302
|
+
export interface NodeIndicatorState {
|
|
303
|
+
/** Current loop phase (drives animation) */
|
|
304
|
+
loopPhase: LoopPhase;
|
|
305
|
+
/** Milliseconds in current phase (for pulse timing) */
|
|
306
|
+
phaseElapsedMs: number;
|
|
307
|
+
/** Target node ID if perceive/act trace is active */
|
|
308
|
+
traceTargetId: string | null;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// === Re-export n1 types for convenience ===
|
|
312
|
+
|
|
313
|
+
export type { NodeLayout, LayoutResult } from '../n1-flow-canvas/types.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// P0 Primitives — Shared types, utilities, and design tokens
|
|
2
|
+
// This is the foundation layer that all other domains depend on
|
|
3
|
+
// CSS tokens are imported via base.css or '@kos/design-system/tokens.css'
|
|
4
|
+
|
|
5
|
+
export * from './types/index';
|
|
6
|
+
export * from './utils/index';
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/* @kos/design-system — Control Room Theme
|
|
2
|
+
"Industrial-grade functionalism" aesthetic.
|
|
3
|
+
Brutalist architecture × Command & Control telemetry.
|
|
4
|
+
|
|
5
|
+
Principles:
|
|
6
|
+
- Monolithic blocks, no rounded corners
|
|
7
|
+
- Strict 8px grid alignment
|
|
8
|
+
- High contrast: phosphor on charcoal
|
|
9
|
+
- Binary status language (SYSTEM_BUSY, not "Loading...")
|
|
10
|
+
- Monospace everything, all-caps chrome
|
|
11
|
+
- No fades — snap/blink transitions only */
|
|
12
|
+
|
|
13
|
+
:root[data-theme="control-room"] {
|
|
14
|
+
/* --- Backgrounds — Matte military finishes --- */
|
|
15
|
+
--color-bg-app: #0a0a0a; /* Deep matte — main terminal bg */
|
|
16
|
+
--color-bg-canvas: #111111; /* Slightly elevated — workspace surface */
|
|
17
|
+
--color-bg-panel: #141414; /* Panel containers */
|
|
18
|
+
--color-bg-panel-elevated: #1a1a1a; /* Elevated dialogs, modals */
|
|
19
|
+
--color-bg-inset: #080808; /* Inset wells, input fields */
|
|
20
|
+
|
|
21
|
+
/* Card backgrounds — high contrast for data density */
|
|
22
|
+
--color-card-bg: #0f0f0f;
|
|
23
|
+
--color-card-bg-alt: #151515;
|
|
24
|
+
--color-card-border: #2a2a2a;
|
|
25
|
+
|
|
26
|
+
/* --- Text — Phosphor on glass aesthetic --- */
|
|
27
|
+
--color-text-primary: #e8e8e8; /* Bright phosphor white */
|
|
28
|
+
--color-text-secondary: #888888; /* Dimmed readouts */
|
|
29
|
+
--color-text-tertiary: #555555; /* Inactive metadata */
|
|
30
|
+
--color-text-muted: #333333; /* Ghost text */
|
|
31
|
+
--color-text-inverse: #0a0a0a; /* For light backgrounds */
|
|
32
|
+
|
|
33
|
+
/* Card text (when cards have different bg) */
|
|
34
|
+
--color-card-text-primary: #e8e8e8;
|
|
35
|
+
--color-card-text-secondary: #888888;
|
|
36
|
+
--color-card-text-tertiary: #555555;
|
|
37
|
+
|
|
38
|
+
/* --- Accent — Warning/Status only --- */
|
|
39
|
+
--color-accent: #00ff41; /* Terminal green — primary action */
|
|
40
|
+
--color-accent-hover: #33ff66; /* Brighter on hover */
|
|
41
|
+
--color-accent-active: #00cc33; /* Depressed state */
|
|
42
|
+
--color-accent-glow: rgba(0, 255, 65, 0.3);
|
|
43
|
+
|
|
44
|
+
/* Status colors — binary state language */
|
|
45
|
+
--color-status-active: #00ff41; /* SYSTEM_READY */
|
|
46
|
+
--color-status-busy: #ffd700; /* SYSTEM_BUSY */
|
|
47
|
+
--color-status-alert: #ff3131; /* SYSTEM_FAULT */
|
|
48
|
+
--color-status-warn: #ff8c00; /* DEGRADED */
|
|
49
|
+
--color-status-info: #00bfff; /* INFO (rare use) */
|
|
50
|
+
|
|
51
|
+
/* --- Semantic (presence) --- */
|
|
52
|
+
--color-online: #00ff41;
|
|
53
|
+
--color-offline: #333333;
|
|
54
|
+
--color-away: #ffd700;
|
|
55
|
+
--color-busy: #ff3131;
|
|
56
|
+
|
|
57
|
+
/* --- Epistemic (ASSAY) — harsh binary states --- */
|
|
58
|
+
--epistemic-cleared: #00ff41;
|
|
59
|
+
--epistemic-cleared-glow: rgba(0, 255, 65, 0.2);
|
|
60
|
+
--epistemic-blocked: #ff3131;
|
|
61
|
+
--epistemic-blocked-glow: rgba(255, 49, 49, 0.2);
|
|
62
|
+
--epistemic-pending: #ffd700;
|
|
63
|
+
--epistemic-pending-glow: rgba(255, 215, 0, 0.2);
|
|
64
|
+
--epistemic-degraded: #555555;
|
|
65
|
+
--epistemic-degraded-glow: rgba(85, 85, 85, 0.15);
|
|
66
|
+
|
|
67
|
+
/* --- Allay stages — grayscale with terminal highlight --- */
|
|
68
|
+
--epistemic-stage-0: #1a1a1a; /* Propose — dark */
|
|
69
|
+
--epistemic-stage-1: #333333; /* Parse — dim */
|
|
70
|
+
--epistemic-stage-2: #666666; /* Authorize — mid */
|
|
71
|
+
--epistemic-stage-3: #999999; /* Execute — bright */
|
|
72
|
+
--epistemic-stage-4: #00ff41; /* Trace — active */
|
|
73
|
+
--epistemic-stage-5: #ffd700; /* Replicate — complete */
|
|
74
|
+
|
|
75
|
+
/* --- Expert identity — monochrome with single accent --- */
|
|
76
|
+
--expert-atelier: #00ff41; /* Knowledge — terminal green */
|
|
77
|
+
--expert-agora: #ffd700; /* Communication — hazard yellow */
|
|
78
|
+
--expert-ryu: #ff8c00; /* Task — amber */
|
|
79
|
+
--expert-sovereign: #00bfff; /* Kernel — ice blue */
|
|
80
|
+
--expert-agent: #888888; /* Agent — neutral */
|
|
81
|
+
|
|
82
|
+
/* --- Borders — Heavy, architectural --- */
|
|
83
|
+
--border-width-thin: 1px;
|
|
84
|
+
--border-width-default: 2px;
|
|
85
|
+
--border-width-thick: 2px; /* For active states, indicators */
|
|
86
|
+
--border-width-heavy: 3px; /* For structural emphasis */
|
|
87
|
+
--border-subtle: 1px solid #1a1a1a;
|
|
88
|
+
--border-default: 2px solid #2a2a2a;
|
|
89
|
+
--border-heavy: 3px solid #333333;
|
|
90
|
+
--border-focus: 2px solid #00ff41; /* Terminal green focus */
|
|
91
|
+
--border-alert: 2px solid #ff3131;
|
|
92
|
+
--border-warning: 2px solid #ffd700;
|
|
93
|
+
--divider-color: #1a1a1a;
|
|
94
|
+
|
|
95
|
+
/* --- Grid patterns — subtle telemetry lines --- */
|
|
96
|
+
--grid-line: rgba(0, 255, 65, 0.04); /* Faint phosphor grid */
|
|
97
|
+
--grid-dot: rgba(0, 255, 65, 0.08);
|
|
98
|
+
--grid-major: rgba(0, 255, 65, 0.12); /* Major divisions */
|
|
99
|
+
|
|
100
|
+
/* --- Typography — Monospace only --- */
|
|
101
|
+
--font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'Fira Code', ui-monospace, monospace;
|
|
102
|
+
--font-data: 'OCR-A', 'JetBrains Mono', monospace; /* For serial numbers, IDs */
|
|
103
|
+
--font-sans: var(--font-mono); /* Override — everything mono */
|
|
104
|
+
--font-serif: var(--font-mono); /* Override — everything mono */
|
|
105
|
+
--font-display: var(--font-mono); /* Override — everything mono */
|
|
106
|
+
|
|
107
|
+
/* Type scale — tight, compact */
|
|
108
|
+
--text-2xs: 0.5rem; /* 8px — micro indicators, arrows */
|
|
109
|
+
--text-xs: 0.625rem; /* 10px — metadata only */
|
|
110
|
+
--text-sm: 0.75rem; /* 12px — timestamps, coordinates */
|
|
111
|
+
--text-base: 0.875rem; /* 14px — body/data */
|
|
112
|
+
--text-lg: 1rem; /* 16px — section headers */
|
|
113
|
+
--text-xl: 1.125rem; /* 18px — panel titles */
|
|
114
|
+
--text-2xl: 1.25rem; /* 20px — major headers */
|
|
115
|
+
--text-3xl: 1.5rem; /* 24px — system labels */
|
|
116
|
+
|
|
117
|
+
/* --- Spacing — Strict 8px grid --- */
|
|
118
|
+
--space-1: 0.5rem; /* 8px */
|
|
119
|
+
--space-2: 1rem; /* 16px */
|
|
120
|
+
--space-3: 1.5rem; /* 24px */
|
|
121
|
+
--space-4: 2rem; /* 32px */
|
|
122
|
+
--space-6: 3rem; /* 48px */
|
|
123
|
+
--space-8: 4rem; /* 64px */
|
|
124
|
+
|
|
125
|
+
/* --- Border radius — ZERO --- */
|
|
126
|
+
--radius-none: 0;
|
|
127
|
+
--radius-xs: 0;
|
|
128
|
+
--radius-sm: 0;
|
|
129
|
+
--radius-md: 0;
|
|
130
|
+
--radius-lg: 0;
|
|
131
|
+
--radius-xl: 0;
|
|
132
|
+
--radius-full: 0;
|
|
133
|
+
|
|
134
|
+
/* Clipped corners (alternative to radius) */
|
|
135
|
+
--clip-corner-sm: polygon(
|
|
136
|
+
0 4px, 4px 0,
|
|
137
|
+
calc(100% - 4px) 0, 100% 4px,
|
|
138
|
+
100% calc(100% - 4px), calc(100% - 4px) 100%,
|
|
139
|
+
4px 100%, 0 calc(100% - 4px)
|
|
140
|
+
);
|
|
141
|
+
--clip-corner-md: polygon(
|
|
142
|
+
0 8px, 8px 0,
|
|
143
|
+
calc(100% - 8px) 0, 100% 8px,
|
|
144
|
+
100% calc(100% - 8px), calc(100% - 8px) 100%,
|
|
145
|
+
8px 100%, 0 calc(100% - 8px)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
/* --- Shadows — None. Use borders for depth. --- */
|
|
149
|
+
--shadow-none: none;
|
|
150
|
+
--shadow-sm: none;
|
|
151
|
+
--shadow-md: none;
|
|
152
|
+
/* --- Shadow/Glow — Minimal, functional --- */
|
|
153
|
+
--shadow-active: 0 0 8px var(--color-accent-glow);
|
|
154
|
+
--shadow-warning: 0 0 8px rgba(255, 215, 0, 0.4);
|
|
155
|
+
|
|
156
|
+
/* --- Overlay colors for scanlines, glass effects --- */
|
|
157
|
+
--color-overlay-scanline: rgba(0, 0, 0, 0.1);
|
|
158
|
+
--color-overlay-glass: rgba(10, 10, 10, 0.85);
|
|
159
|
+
|
|
160
|
+
/* --- Transitions — Snap/blink only --- */
|
|
161
|
+
--transition-instant: 0ms;
|
|
162
|
+
--transition-fast: 50ms step-end;
|
|
163
|
+
--transition-normal: 100ms step-end;
|
|
164
|
+
--transition-slow: 150ms step-end;
|
|
165
|
+
|
|
166
|
+
/* --- Animation speeds --- */
|
|
167
|
+
--animation-speed-flicker: 0.15s;
|
|
168
|
+
--animation-speed-pulse: 1s;
|
|
169
|
+
--animation-speed-blink: 0.5s;
|
|
170
|
+
|
|
171
|
+
/* --- Opacity variants for status colors --- */
|
|
172
|
+
--color-status-active-10: rgba(0, 255, 65, 0.1);
|
|
173
|
+
--color-status-active-30: rgba(0, 255, 65, 0.3);
|
|
174
|
+
--color-status-busy-10: rgba(255, 215, 0, 0.1);
|
|
175
|
+
--color-status-busy-30: rgba(255, 215, 0, 0.3);
|
|
176
|
+
--color-status-alert-10: rgba(255, 49, 49, 0.1);
|
|
177
|
+
--color-status-alert-30: rgba(255, 49, 49, 0.3);
|
|
178
|
+
--color-status-warn-10: rgba(255, 140, 0, 0.1);
|
|
179
|
+
--color-status-warn-30: rgba(255, 140, 0, 0.3);
|
|
180
|
+
|
|
181
|
+
/* --- Hazard pattern sizing tokens --- */
|
|
182
|
+
--hazard-stripe-width: 20px;
|
|
183
|
+
--hazard-stripe-band: 10px;
|
|
184
|
+
--hazard-alt-stripe-width: 16px;
|
|
185
|
+
--hazard-alt-stripe-band: 8px;
|
|
186
|
+
|
|
187
|
+
/* --- Component sizing tokens --- */
|
|
188
|
+
--size-hazard-divider-height: 4px;
|
|
189
|
+
--size-grid-gap-subtle: 1px;
|
|
190
|
+
--size-status-bar-height: 2px;
|
|
191
|
+
--size-border-left-heavy: 3px;
|
|
192
|
+
--size-network-link-width: 2px;
|
|
193
|
+
--size-network-link-height: 24px;
|
|
194
|
+
|
|
195
|
+
/* CRT flicker animation - applied via class */
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Apply flicker to overlay elements */
|
|
199
|
+
[data-theme="control-room"] .crt-flicker::before {
|
|
200
|
+
animation: flicker var(--animation-speed-flicker) infinite;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* --- Hazard Pattern Utility ---
|
|
204
|
+
* Uses theme tokens for full self-containment
|
|
205
|
+
*/
|
|
206
|
+
[data-theme="control-room"] .hazard-stripes {
|
|
207
|
+
background: repeating-linear-gradient(
|
|
208
|
+
45deg,
|
|
209
|
+
var(--color-bg-app),
|
|
210
|
+
var(--color-bg-app) var(--hazard-stripe-band),
|
|
211
|
+
var(--color-status-busy) var(--hazard-stripe-band),
|
|
212
|
+
var(--color-status-busy) var(--hazard-stripe-width)
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
[data-theme="control-room"] .hazard-stripes-alt {
|
|
217
|
+
background: repeating-linear-gradient(
|
|
218
|
+
-45deg,
|
|
219
|
+
var(--color-bg-canvas),
|
|
220
|
+
var(--color-bg-canvas) var(--hazard-alt-stripe-band),
|
|
221
|
+
var(--color-status-warn) var(--hazard-alt-stripe-band),
|
|
222
|
+
var(--color-status-warn) var(--hazard-alt-stripe-width)
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* --- CRT Scanline Overlay --- */
|
|
227
|
+
[data-theme="control-room"] .crt-overlay::before {
|
|
228
|
+
content: '';
|
|
229
|
+
position: absolute;
|
|
230
|
+
inset: 0;
|
|
231
|
+
background: repeating-linear-gradient(
|
|
232
|
+
0deg,
|
|
233
|
+
var(--color-overlay-scanline),
|
|
234
|
+
var(--color-overlay-scanline) 1px,
|
|
235
|
+
transparent 1px,
|
|
236
|
+
transparent 2px
|
|
237
|
+
);
|
|
238
|
+
pointer-events: none;
|
|
239
|
+
z-index: 1000;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* --- Phosphor Glow Effect --- */
|
|
243
|
+
[data-theme="control-room"] .phosphor-glow {
|
|
244
|
+
text-shadow: 0 0 4px var(--color-accent-glow);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* --- All Caps Chrome --- */
|
|
248
|
+
[data-theme="control-room"] .chrome-label,
|
|
249
|
+
[data-theme="control-room"] .panel-header,
|
|
250
|
+
[data-theme="control-room"] .section-title,
|
|
251
|
+
[data-theme="control-room"] button,
|
|
252
|
+
[data-theme="control-room"] .btn {
|
|
253
|
+
text-transform: uppercase;
|
|
254
|
+
letter-spacing: 0.05em;
|
|
255
|
+
font-weight: 500;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* --- Status Badge Patterns --- */
|
|
259
|
+
[data-theme="control-room"] .badge {
|
|
260
|
+
display: inline-flex;
|
|
261
|
+
align-items: center;
|
|
262
|
+
padding: 0.25rem 0.5rem;
|
|
263
|
+
border: 1px solid currentColor;
|
|
264
|
+
font-family: var(--font-mono);
|
|
265
|
+
font-size: var(--text-xs);
|
|
266
|
+
text-transform: uppercase;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
[data-theme="control-room"] .badge::before {
|
|
270
|
+
content: '';
|
|
271
|
+
width: 6px;
|
|
272
|
+
height: 6px;
|
|
273
|
+
margin-right: 0.375rem;
|
|
274
|
+
background: currentColor;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
[data-theme="control-room"] .badge--active {
|
|
278
|
+
color: var(--color-status-active);
|
|
279
|
+
border-color: var(--color-status-active);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
[data-theme="control-room"] .badge--busy {
|
|
283
|
+
color: var(--color-status-busy);
|
|
284
|
+
border-color: var(--color-status-busy);
|
|
285
|
+
animation: pulse var(--animation-speed-pulse) step-end infinite;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
[data-theme="control-room"] .badge--alert {
|
|
289
|
+
color: var(--color-status-alert);
|
|
290
|
+
border-color: var(--color-status-alert);
|
|
291
|
+
animation: blink var(--animation-speed-blink) step-end infinite;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@keyframes pulse {
|
|
295
|
+
0%, 100% { opacity: 1; }
|
|
296
|
+
50% { opacity: 0.5; }
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@keyframes blink {
|
|
300
|
+
0%, 100% { opacity: 1; }
|
|
301
|
+
50% { opacity: 0; }
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@keyframes flicker {
|
|
305
|
+
0%, 100% { opacity: 1; }
|
|
306
|
+
92% { opacity: 1; }
|
|
307
|
+
93% { opacity: 0.8; }
|
|
308
|
+
94% { opacity: 1; }
|
|
309
|
+
}
|