@konitif/theme 0.284.2

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 (48) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +56 -0
  3. package/package.json +56 -0
  4. package/reference/README.md +10 -0
  5. package/reference/catalog.json +129 -0
  6. package/reference/diagrams.json +60 -0
  7. package/src/ambient/SpatialAmbientCanvas.svelte +148 -0
  8. package/src/ambient/SpatialAmbientParticles.svelte +89 -0
  9. package/src/ambient/SpatialAmbientRuntime.svelte +306 -0
  10. package/src/ambient/SpatialProjectionGrid.svelte +252 -0
  11. package/src/ambient/shaders/noise.glsl +1 -0
  12. package/src/ambient/shaders/particleField.glsl +1 -0
  13. package/src/ambient/shaders/spatialAmbient.frag.glsl +1 -0
  14. package/src/ambient/shaders/spatialAmbient.vert.glsl +1 -0
  15. package/src/ambient/shaders/volumetricFog.glsl +1 -0
  16. package/src/ambient/spatialAmbientStore.ts +3 -0
  17. package/src/ambient/spatialAmbientTypes.ts +11 -0
  18. package/src/ambient/spatialProjectionGridModel.ts +276 -0
  19. package/src/ambient/spatialProjectionGridPresets.ts +152 -0
  20. package/src/ambient/spatialProjectionGridTypes.ts +72 -0
  21. package/src/ambient/themeToAmbientUniforms.ts +3 -0
  22. package/src/components/KonitifBadge.svelte +2 -0
  23. package/src/components/KonitifButton.svelte +2 -0
  24. package/src/components/KonitifCard.svelte +2 -0
  25. package/src/components/KonitifGlassSurface.svelte +3 -0
  26. package/src/components/KonitifIconFrame.svelte +2 -0
  27. package/src/components/KonitifPanel.svelte +2 -0
  28. package/src/depth/SpatialDepthLayer.svelte +49 -0
  29. package/src/depth/SpatialDepthStack.svelte +25 -0
  30. package/src/depth/spatialDepthTokens.css +82 -0
  31. package/src/depth/spatialDepthTypes.ts +79 -0
  32. package/src/focus/FocusPlaneProvider.svelte +43 -0
  33. package/src/focus/PerceptualSurface.svelte +146 -0
  34. package/src/focus/focusDepthMap.ts +33 -0
  35. package/src/focus/perceptualFocusStore.ts +98 -0
  36. package/src/focus/perceptualFocusTypes.ts +38 -0
  37. package/src/focus/usePerceptualFocus.ts +18 -0
  38. package/src/index.ts +22 -0
  39. package/src/konitifRuntimePhaseTokens.ts +15 -0
  40. package/src/konitifTheme.ts +2 -0
  41. package/src/konitifThemeAdapter.ts +13 -0
  42. package/src/konitifTokens.css +201 -0
  43. package/src/konitifWorkbenchThemeRuntime.ts +35 -0
  44. package/src/runtime/RuntimePhaseTintProvider.svelte +28 -0
  45. package/src/runtime/runtimePhaseIconMap.ts +1 -0
  46. package/src/runtime/runtimePhaseVisualMap.ts +37 -0
  47. package/src/runtime/runtimeSpatialReactivity.ts +307 -0
  48. package/src/runtime/runtimeSpatialStateStore.ts +53 -0
@@ -0,0 +1,201 @@
1
+ :root,
2
+ [data-theme='konitif-dark'] {
3
+ color-scheme: dark;
4
+
5
+ --color-background-canvas: #02050a;
6
+ --color-background-surface: rgba(8, 17, 31, 0.86);
7
+ --color-background-elevated: rgba(10, 22, 40, 0.92);
8
+ --color-background-accent: rgba(14, 34, 58, 0.92);
9
+ --color-background-muted: rgba(6, 13, 24, 0.86);
10
+ --color-background-empty-panel: rgba(5, 12, 22, 0.8);
11
+ --color-background-empty-panel-stripe: rgba(34, 211, 238, 0.045);
12
+ --color-background-hover: rgba(20, 44, 70, 0.9);
13
+ --color-background-pressed: rgba(25, 58, 88, 0.92);
14
+ --color-background-selected: rgba(17, 45, 74, 0.9);
15
+ --color-background-danger: rgba(56, 18, 27, 0.82);
16
+ --color-background-danger-hover: rgba(74, 24, 35, 0.9);
17
+ --color-background-overlay: rgba(2, 5, 10, 0.72);
18
+ --color-background-glow: rgba(34, 211, 238, 0.13);
19
+
20
+ --color-border-subtle: rgba(148, 178, 255, 0.18);
21
+ --color-border-strong: rgba(148, 178, 255, 0.34);
22
+ --color-border-focus: #22d3ee;
23
+ --color-border-danger: rgba(239, 68, 68, 0.58);
24
+ --color-border-edge-split: rgba(96, 165, 250, 0.56);
25
+ --color-border-edge-split-hover: rgba(34, 211, 238, 0.78);
26
+
27
+ --color-text-primary: #f4f8ff;
28
+ --color-text-secondary: #9db3cc;
29
+ --color-text-muted: #60758c;
30
+ --color-text-danger: #ff9aa8;
31
+
32
+ --color-status-success: #4ade80;
33
+ --color-status-warning: #f59e0b;
34
+ --color-status-danger: #ef4444;
35
+
36
+ --color-action-primary: #22d3ee;
37
+ --color-action-primary-hover: #67e8f9;
38
+ --color-action-secondary: rgba(10, 22, 40, 0.8);
39
+ --color-action-secondary-hover: rgba(16, 36, 62, 0.92);
40
+ --color-action-danger: rgba(127, 29, 44, 0.58);
41
+ --color-action-danger-hover: rgba(159, 35, 52, 0.68);
42
+
43
+ --shadow-surface: 0 24px 80px rgba(0, 0, 0, 0.28);
44
+ --shadow-focus: 0 0 0 1px var(--color-border-focus), 0 0 28px rgba(34, 211, 238, 0.18);
45
+ }
46
+
47
+ :root[data-theme='konitif-light'],
48
+ [data-theme='konitif-light'] {
49
+ color-scheme: light;
50
+
51
+ --color-background-canvas: #f6f8fc;
52
+ --color-background-surface: rgba(255, 255, 255, 0.68);
53
+ --color-background-elevated: rgba(255, 255, 255, 0.84);
54
+ --color-background-accent: rgba(231, 237, 244, 0.86);
55
+ --color-background-muted: rgba(238, 242, 247, 0.88);
56
+ --color-background-empty-panel: rgba(239, 245, 252, 0.86);
57
+ --color-background-empty-panel-stripe: rgba(56, 189, 248, 0.06);
58
+ --color-background-hover: rgba(230, 239, 250, 0.94);
59
+ --color-background-pressed: rgba(216, 229, 245, 0.96);
60
+ --color-background-selected: rgba(220, 237, 255, 0.96);
61
+ --color-background-danger: rgba(255, 239, 242, 0.9);
62
+ --color-background-danger-hover: rgba(255, 225, 231, 0.96);
63
+ --color-background-overlay: rgba(28, 36, 50, 0.32);
64
+ --color-background-glow: rgba(56, 189, 248, 0.15);
65
+
66
+ --color-border-subtle: rgba(110, 140, 180, 0.18);
67
+ --color-border-strong: rgba(90, 125, 170, 0.28);
68
+ --color-border-focus: #2f8fd6;
69
+ --color-border-danger: rgba(239, 68, 68, 0.48);
70
+ --color-border-edge-split: rgba(99, 102, 241, 0.42);
71
+ --color-border-edge-split-hover: rgba(56, 189, 248, 0.65);
72
+
73
+ --color-text-primary: #1b3048;
74
+ --color-text-secondary: #4d6480;
75
+ --color-text-muted: #7b8fa8;
76
+ --color-text-danger: #b4233b;
77
+
78
+ --color-status-success: #34a875;
79
+ --color-status-warning: #d89125;
80
+ --color-status-danger: #d9534f;
81
+
82
+ --color-action-primary: #2f8fd6;
83
+ --color-action-primary-hover: #257bc0;
84
+ --color-action-secondary: rgba(255, 255, 255, 0.72);
85
+ --color-action-secondary-hover: rgba(236, 244, 255, 0.92);
86
+ --color-action-danger: rgba(255, 226, 231, 0.82);
87
+ --color-action-danger-hover: rgba(255, 210, 219, 0.9);
88
+
89
+ --shadow-surface: 0 22px 70px rgba(50, 68, 98, 0.16);
90
+ --shadow-focus: 0 0 0 1px var(--color-border-focus), 0 0 24px rgba(56, 189, 248, 0.18);
91
+ }
92
+
93
+ :root,
94
+ [data-theme='konitif-dark'],
95
+ [data-workbench-color-mode='dark'] {
96
+ --k-bg-root: var(--color-background-canvas, #02050a);
97
+ --k-bg-space: #06121f;
98
+ --k-bg-space-deep: #02060d;
99
+ --k-bg-surface: color-mix(in srgb, var(--color-background-surface, #08111f) 78%, transparent);
100
+ --k-bg-surface-strong: color-mix(in srgb, var(--color-background-elevated, #0a1628) 90%, transparent);
101
+ --k-text-primary: var(--color-text-primary, #f4f8ff);
102
+ --k-text-secondary: var(--color-text-secondary, #9db3cc);
103
+ --k-text-muted: var(--color-text-muted, #60758c);
104
+ --k-accent-primary: var(--color-action-primary, #22d3ee);
105
+ --k-accent-secondary: #60a5fa;
106
+ --k-accent-success: var(--color-status-success, #4ade80);
107
+ --k-accent-warning: var(--color-status-warning, #f59e0b);
108
+ --k-accent-error: var(--color-status-danger, #ef4444);
109
+ --k-accent-hydration: #a855f7;
110
+ --k-entity-application: #69ecc1;
111
+ --k-entity-application-rgb: 105, 236, 193;
112
+ --k-entity-repository: #b084ff;
113
+ --k-entity-repository-rgb: 176, 132, 255;
114
+ --k-border-soft: color-mix(in srgb, var(--color-border-subtle, #94b2ff) 64%, transparent);
115
+ --k-border-strong: color-mix(in srgb, var(--color-border-strong, #94b2ff) 74%, transparent);
116
+ --k-glow-primary: rgba(34, 211, 238, 0.32);
117
+ --k-glow-success: rgba(74, 222, 128, 0.28);
118
+ --k-glow-error: rgba(239, 68, 68, 0.32);
119
+ --k-frustum-fog: rgba(20, 80, 120, 0.18);
120
+ --k-frustum-light: rgba(34, 211, 238, 0.22);
121
+ --k-frustum-light-core: rgba(150, 245, 255, 0.36);
122
+ --k-frustum-shadow: rgba(0, 0, 0, 0.22);
123
+ --k-particle-color: rgba(170, 220, 255, 0.72);
124
+ --k-particle-glow: rgba(34, 211, 238, 0.22);
125
+ --k-space-grid-major: rgba(45, 230, 210, 0.74);
126
+ --k-space-grid-minor: rgba(45, 230, 210, 0.32);
127
+ --k-space-grid-tertiary: rgba(45, 230, 210, 0.16);
128
+ --k-space-grid-node: rgba(158, 255, 239, 0.9);
129
+ --k-space-grid-origin: rgba(236, 255, 255, 0.96);
130
+ --k-space-grid-horizon: rgba(36, 220, 160, 0.22);
131
+ --k-space-grid-fog: rgba(20, 180, 150, 0.12);
132
+ --k-space-grid-axis: rgba(103, 255, 232, 0.86);
133
+ --k-space-grid-opacity: 0.92;
134
+ --k-space-grid-blur: 0px;
135
+ --k-runtime-tint: var(--k-accent-primary);
136
+ --k-runtime-tint-rgb: 34, 211, 238;
137
+ --k-runtime-intensity: 0.5;
138
+ }
139
+
140
+ :root[data-theme='light'],
141
+ [data-theme='konitif-light'],
142
+ [data-workbench-color-mode='light'] {
143
+ --k-bg-root: #eef2f7;
144
+ --k-bg-space: #e7edf4;
145
+ --k-bg-space-deep: #dbe6f0;
146
+ --k-bg-surface: rgba(255, 255, 255, 0.68);
147
+ --k-bg-surface-strong: rgba(255, 255, 255, 0.84);
148
+ --k-text-primary: #1b3048;
149
+ --k-text-secondary: #4d6480;
150
+ --k-text-muted: #7b8fa8;
151
+ --k-accent-primary: #2f8fd6;
152
+ --k-accent-secondary: #6b7fe8;
153
+ --k-accent-success: #34a875;
154
+ --k-accent-warning: #d89125;
155
+ --k-accent-error: #d9534f;
156
+ --k-accent-hydration: #9275d8;
157
+ --k-entity-application: #0f9f86;
158
+ --k-entity-application-rgb: 15, 159, 134;
159
+ --k-entity-repository: #8b5cf6;
160
+ --k-entity-repository-rgb: 139, 92, 246;
161
+ --k-border-soft: rgba(110, 140, 180, 0.18);
162
+ --k-border-strong: rgba(90, 125, 170, 0.28);
163
+ --k-glow-primary: rgba(47, 143, 214, 0.2);
164
+ --k-glow-success: rgba(52, 168, 117, 0.18);
165
+ --k-glow-error: rgba(217, 83, 79, 0.18);
166
+ --k-frustum-light: rgba(255, 238, 205, 0.38);
167
+ --k-frustum-light-core: rgba(255, 246, 230, 0.72);
168
+ --k-frustum-fog: rgba(190, 220, 255, 0.14);
169
+ --k-frustum-shadow: rgba(110, 135, 165, 0.12);
170
+ --k-particle-color: rgba(90, 130, 175, 0.34);
171
+ --k-particle-glow: rgba(255, 228, 185, 0.26);
172
+ --k-space-grid-major: rgba(105, 145, 190, 0.22);
173
+ --k-space-grid-minor: rgba(105, 145, 190, 0.075);
174
+ --k-space-grid-tertiary: rgba(105, 145, 190, 0.04);
175
+ --k-space-grid-node: rgba(90, 145, 195, 0.34);
176
+ --k-space-grid-origin: rgba(75, 135, 190, 0.48);
177
+ --k-space-grid-axis: rgba(80, 140, 190, 0.2);
178
+ --k-space-grid-horizon: rgba(160, 190, 220, 0.1);
179
+ --k-space-grid-fog: rgba(200, 220, 240, 0.18);
180
+ --k-space-grid-opacity: 0.76;
181
+ --k-space-grid-blur: 0px;
182
+ }
183
+
184
+ .konitif-theme-root {
185
+ min-height: 100dvh;
186
+ background: var(--k-bg-root);
187
+ color: var(--k-text-primary);
188
+ transition:
189
+ background-color 700ms ease,
190
+ color 700ms ease;
191
+ }
192
+
193
+ .konitif-glass-panel {
194
+ border: 1px solid var(--k-border-soft);
195
+ background: var(--k-bg-surface);
196
+ color: var(--k-text-primary);
197
+ backdrop-filter: blur(18px) saturate(1.22);
198
+ box-shadow:
199
+ 0 24px 80px rgba(0, 0, 0, 0.2),
200
+ inset 0 1px 0 rgba(255, 255, 255, 0.06);
201
+ }
@@ -0,0 +1,35 @@
1
+ import type { ComponentType, SvelteComponent } from 'svelte';
2
+ import SpatialAmbientRuntime from './ambient/SpatialAmbientRuntime.svelte';
3
+ import FocusPlaneProvider from './focus/FocusPlaneProvider.svelte';
4
+ import PerceptualSurface from './focus/PerceptualSurface.svelte';
5
+ import { applyKonitifTheme } from './konitifThemeAdapter';
6
+ import type { KonitifThemeMode } from './konitifTheme';
7
+
8
+ export type KonitifWorkbenchThemeColorMode = 'dark' | 'light';
9
+ export type KonitifWorkbenchThemeComponent = ComponentType<SvelteComponent>;
10
+
11
+ export interface KonitifWorkbenchThemeRuntime {
12
+ themeFamily: string;
13
+ AmbientRuntime: KonitifWorkbenchThemeComponent;
14
+ FocusPlaneProvider: KonitifWorkbenchThemeComponent;
15
+ SurfaceFrame: KonitifWorkbenchThemeComponent;
16
+ applyTheme: (themeId: string, colorMode: KonitifWorkbenchThemeColorMode) => void;
17
+ resolveThemeModeId: (colorMode: KonitifWorkbenchThemeColorMode) => string;
18
+ }
19
+
20
+ export const konitifWorkbenchThemeRuntime: KonitifWorkbenchThemeRuntime = {
21
+ themeFamily: 'konitif',
22
+ AmbientRuntime: SpatialAmbientRuntime,
23
+ FocusPlaneProvider,
24
+ SurfaceFrame: PerceptualSurface,
25
+ applyTheme: (themeId) => applyKonitifTheme(resolveKonitifThemeMode(themeId)),
26
+ resolveThemeModeId: resolveKonitifWorkbenchThemeModeId
27
+ };
28
+
29
+ export function resolveKonitifWorkbenchThemeModeId(colorMode: KonitifWorkbenchThemeColorMode): KonitifThemeMode {
30
+ return colorMode === 'light' ? 'konitif-light' : 'konitif-dark';
31
+ }
32
+
33
+ function resolveKonitifThemeMode(themeId: string): KonitifThemeMode {
34
+ return themeId === 'konitif-light' ? 'konitif-light' : 'konitif-dark';
35
+ }
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import { normalizeKonitifRuntimePhase, type RuntimePhase } from '../konitifRuntimePhaseTokens';
3
+ import { resolveRuntimePhaseVisual } from './runtimePhaseVisualMap';
4
+
5
+ export let phase: RuntimePhase = 'LAUNCH_GATE';
6
+
7
+ $: visual = resolveRuntimePhaseVisual(normalizeKonitifRuntimePhase(phase));
8
+ </script>
9
+
10
+ <div
11
+ class="phase-tint"
12
+ style={`--phase-tint:${visual.tint}; --phase-tint-rgb:${visual.tintRgb}; --phase-intensity:${visual.intensity}`}
13
+ >
14
+ <slot />
15
+ </div>
16
+
17
+ <style>
18
+ .phase-tint {
19
+ --phase-tint: var(--k-accent-primary);
20
+ --phase-tint-rgb: 34, 211, 238;
21
+ --phase-intensity: 0.5;
22
+ }
23
+
24
+ .phase-tint :global(.phase-aware) {
25
+ border-color: var(--k-border-soft);
26
+ box-shadow: 0 0 calc(24px * var(--phase-intensity)) rgba(var(--phase-tint-rgb), 0.18);
27
+ }
28
+ </style>
@@ -0,0 +1 @@
1
+ export const runtimePhaseIconMap={BOOT:'power',LAUNCH_GATE:'door-open',CONTEXT_RESOLVED:'folder-search',PREFLIGHT:'clipboard-check',PLANNED:'table',INITIALIZING:'settings',HYDRATING:'droplet',RUNNING:'play',SUSPENDING:'pause',SUSPENDED:'square',RESUMING:'fast-forward',TEARING_DOWN:'trash',RECOVERING:'refresh-cw',SAFE_MODE:'shield'} as const;
@@ -0,0 +1,37 @@
1
+ import type { RuntimePhase } from '../konitifRuntimePhaseTokens';
2
+ import { createRuntimeSpatialState } from './runtimeSpatialReactivity';
3
+
4
+ export type RuntimePhaseVisual = {
5
+ tint: string;
6
+ tintRgb: string;
7
+ intensity: number;
8
+ };
9
+
10
+ export const runtimePhaseVisualMap = {
11
+ BOOT: { tint: 'var(--k-accent-secondary)', tintRgb: '96, 165, 250', intensity: 0.35 },
12
+ LAUNCH_GATE: { tint: 'var(--k-accent-primary)', tintRgb: '34, 211, 238', intensity: 0.42 },
13
+ CONTEXT_RESOLVED: { tint: 'var(--k-accent-primary)', tintRgb: '34, 211, 238', intensity: 0.4 },
14
+ PREFLIGHT: { tint: 'var(--k-accent-success)', tintRgb: '74, 222, 128', intensity: 0.48 },
15
+ PLANNED: { tint: 'var(--k-accent-success)', tintRgb: '74, 222, 128', intensity: 0.44 },
16
+ INITIALIZING: { tint: 'var(--k-accent-secondary)', tintRgb: '96, 165, 250', intensity: 0.58 },
17
+ HYDRATING: { tint: 'var(--k-accent-hydration)', tintRgb: '168, 85, 247', intensity: 0.5 },
18
+ RUNNING: { tint: 'var(--k-accent-primary)', tintRgb: '34, 211, 238', intensity: 0.62 },
19
+ SUSPENDING: { tint: 'var(--k-accent-warning)', tintRgb: '245, 158, 11', intensity: 0.36 },
20
+ SUSPENDED: { tint: 'var(--k-accent-warning)', tintRgb: '245, 158, 11', intensity: 0.26 },
21
+ RESUMING: { tint: 'var(--k-accent-primary)', tintRgb: '34, 211, 238', intensity: 0.5 },
22
+ TEARDOWN: { tint: 'var(--k-accent-warning)', tintRgb: '245, 158, 11', intensity: 0.32 },
23
+ TEARING_DOWN: { tint: 'var(--k-accent-warning)', tintRgb: '245, 158, 11', intensity: 0.32 },
24
+ RECOVERY: { tint: 'var(--k-accent-error)', tintRgb: '239, 68, 68', intensity: 0.6 },
25
+ RECOVERING: { tint: 'var(--k-accent-error)', tintRgb: '239, 68, 68', intensity: 0.6 },
26
+ SAFE_MODE: { tint: 'var(--k-accent-error)', tintRgb: '239, 68, 68', intensity: 0.28 }
27
+ } satisfies Record<RuntimePhase, RuntimePhaseVisual>;
28
+
29
+ export function resolveRuntimePhaseVisual(phase: RuntimePhase | string | null | undefined): RuntimePhaseVisual {
30
+ const spatialState = createRuntimeSpatialState(phase);
31
+
32
+ return {
33
+ tint: spatialState.tint,
34
+ tintRgb: spatialState.tintRgb,
35
+ intensity: spatialState.lightIntensity
36
+ };
37
+ }
@@ -0,0 +1,307 @@
1
+ import { normalizeKonitifRuntimePhase, type RuntimePhase } from '../konitifRuntimePhaseTokens';
2
+ import type { AmbientQuality } from '../ambient/spatialAmbientTypes';
3
+
4
+ export type RuntimeSpatialState = {
5
+ phase: RuntimePhase;
6
+ tint: string;
7
+ tintRgb: string;
8
+ fogDensity: number;
9
+ particleDensity: number;
10
+ particleSpeed: number;
11
+ lightIntensity: number;
12
+ motionIntensity: number;
13
+ tiltStrength: number;
14
+ focusFalloff: number;
15
+ instability: number;
16
+ };
17
+
18
+ export type RuntimeSpatialStateOptions = {
19
+ quality?: AmbientQuality;
20
+ reducedMotion?: boolean;
21
+ hidden?: boolean;
22
+ };
23
+
24
+ const baseSpatialState = {
25
+ BOOT: {
26
+ tint: 'var(--k-accent-secondary)',
27
+ tintRgb: '96, 165, 250',
28
+ fogDensity: 0.18,
29
+ particleDensity: 0.24,
30
+ particleSpeed: 0.18,
31
+ lightIntensity: 0.28,
32
+ motionIntensity: 0.16,
33
+ tiltStrength: 0.08,
34
+ focusFalloff: 0.52,
35
+ instability: 0.06
36
+ },
37
+ LAUNCH_GATE: {
38
+ tint: 'var(--k-accent-primary)',
39
+ tintRgb: '34, 211, 238',
40
+ fogDensity: 0.24,
41
+ particleDensity: 0.34,
42
+ particleSpeed: 0.22,
43
+ lightIntensity: 0.38,
44
+ motionIntensity: 0.2,
45
+ tiltStrength: 0.1,
46
+ focusFalloff: 0.56,
47
+ instability: 0.04
48
+ },
49
+ CONTEXT_RESOLVED: {
50
+ tint: 'var(--k-accent-primary)',
51
+ tintRgb: '34, 211, 238',
52
+ fogDensity: 0.24,
53
+ particleDensity: 0.36,
54
+ particleSpeed: 0.24,
55
+ lightIntensity: 0.4,
56
+ motionIntensity: 0.22,
57
+ tiltStrength: 0.1,
58
+ focusFalloff: 0.56,
59
+ instability: 0.04
60
+ },
61
+ PREFLIGHT: {
62
+ tint: 'var(--k-accent-success)',
63
+ tintRgb: '74, 222, 128',
64
+ fogDensity: 0.28,
65
+ particleDensity: 0.42,
66
+ particleSpeed: 0.28,
67
+ lightIntensity: 0.44,
68
+ motionIntensity: 0.28,
69
+ tiltStrength: 0.12,
70
+ focusFalloff: 0.62,
71
+ instability: 0.05
72
+ },
73
+ PLANNED: {
74
+ tint: 'var(--k-accent-success)',
75
+ tintRgb: '74, 222, 128',
76
+ fogDensity: 0.22,
77
+ particleDensity: 0.36,
78
+ particleSpeed: 0.24,
79
+ lightIntensity: 0.46,
80
+ motionIntensity: 0.22,
81
+ tiltStrength: 0.1,
82
+ focusFalloff: 0.66,
83
+ instability: 0.03
84
+ },
85
+ INITIALIZING: {
86
+ tint: 'var(--k-accent-secondary)',
87
+ tintRgb: '96, 165, 250',
88
+ fogDensity: 0.34,
89
+ particleDensity: 0.62,
90
+ particleSpeed: 0.54,
91
+ lightIntensity: 0.58,
92
+ motionIntensity: 0.56,
93
+ tiltStrength: 0.16,
94
+ focusFalloff: 0.6,
95
+ instability: 0.16
96
+ },
97
+ HYDRATING: {
98
+ tint: 'var(--k-accent-hydration)',
99
+ tintRgb: '168, 85, 247',
100
+ fogDensity: 0.42,
101
+ particleDensity: 0.54,
102
+ particleSpeed: 0.36,
103
+ lightIntensity: 0.52,
104
+ motionIntensity: 0.34,
105
+ tiltStrength: 0.18,
106
+ focusFalloff: 0.7,
107
+ instability: 0.12
108
+ },
109
+ RUNNING: {
110
+ tint: 'var(--k-accent-primary)',
111
+ tintRgb: '34, 211, 238',
112
+ fogDensity: 0.3,
113
+ particleDensity: 0.46,
114
+ particleSpeed: 0.3,
115
+ lightIntensity: 0.62,
116
+ motionIntensity: 0.32,
117
+ tiltStrength: 0.14,
118
+ focusFalloff: 0.68,
119
+ instability: 0.04
120
+ },
121
+ SUSPENDING: {
122
+ tint: 'var(--k-accent-warning)',
123
+ tintRgb: '245, 158, 11',
124
+ fogDensity: 0.34,
125
+ particleDensity: 0.3,
126
+ particleSpeed: 0.14,
127
+ lightIntensity: 0.32,
128
+ motionIntensity: 0.12,
129
+ tiltStrength: 0.08,
130
+ focusFalloff: 0.48,
131
+ instability: 0.08
132
+ },
133
+ SUSPENDED: {
134
+ tint: 'var(--k-accent-warning)',
135
+ tintRgb: '245, 158, 11',
136
+ fogDensity: 0.38,
137
+ particleDensity: 0.12,
138
+ particleSpeed: 0.04,
139
+ lightIntensity: 0.2,
140
+ motionIntensity: 0.04,
141
+ tiltStrength: 0.03,
142
+ focusFalloff: 0.38,
143
+ instability: 0.02
144
+ },
145
+ RESUMING: {
146
+ tint: 'var(--k-accent-primary)',
147
+ tintRgb: '34, 211, 238',
148
+ fogDensity: 0.32,
149
+ particleDensity: 0.48,
150
+ particleSpeed: 0.42,
151
+ lightIntensity: 0.5,
152
+ motionIntensity: 0.44,
153
+ tiltStrength: 0.14,
154
+ focusFalloff: 0.58,
155
+ instability: 0.1
156
+ },
157
+ TEARDOWN: {
158
+ tint: 'var(--k-accent-warning)',
159
+ tintRgb: '245, 158, 11',
160
+ fogDensity: 0.32,
161
+ particleDensity: 0.26,
162
+ particleSpeed: 0.16,
163
+ lightIntensity: 0.28,
164
+ motionIntensity: 0.12,
165
+ tiltStrength: 0.08,
166
+ focusFalloff: 0.46,
167
+ instability: 0.1
168
+ },
169
+ TEARING_DOWN: {
170
+ tint: 'var(--k-accent-warning)',
171
+ tintRgb: '245, 158, 11',
172
+ fogDensity: 0.32,
173
+ particleDensity: 0.26,
174
+ particleSpeed: 0.16,
175
+ lightIntensity: 0.28,
176
+ motionIntensity: 0.12,
177
+ tiltStrength: 0.08,
178
+ focusFalloff: 0.46,
179
+ instability: 0.1
180
+ },
181
+ RECOVERY: {
182
+ tint: 'var(--k-accent-error)',
183
+ tintRgb: '239, 68, 68',
184
+ fogDensity: 0.44,
185
+ particleDensity: 0.46,
186
+ particleSpeed: 0.38,
187
+ lightIntensity: 0.52,
188
+ motionIntensity: 0.36,
189
+ tiltStrength: 0.2,
190
+ focusFalloff: 0.5,
191
+ instability: 0.34
192
+ },
193
+ RECOVERING: {
194
+ tint: 'var(--k-accent-error)',
195
+ tintRgb: '239, 68, 68',
196
+ fogDensity: 0.44,
197
+ particleDensity: 0.46,
198
+ particleSpeed: 0.38,
199
+ lightIntensity: 0.52,
200
+ motionIntensity: 0.36,
201
+ tiltStrength: 0.2,
202
+ focusFalloff: 0.5,
203
+ instability: 0.34
204
+ },
205
+ SAFE_MODE: {
206
+ tint: 'var(--k-accent-error)',
207
+ tintRgb: '239, 68, 68',
208
+ fogDensity: 0.12,
209
+ particleDensity: 0.08,
210
+ particleSpeed: 0.02,
211
+ lightIntensity: 0.18,
212
+ motionIntensity: 0.02,
213
+ tiltStrength: 0.02,
214
+ focusFalloff: 0.34,
215
+ instability: 0.04
216
+ }
217
+ } satisfies Record<RuntimePhase, Omit<RuntimeSpatialState, 'phase'>>;
218
+
219
+ const qualityDensityFactor: Record<AmbientQuality, number> = {
220
+ off: 0,
221
+ low: 0.46,
222
+ medium: 1,
223
+ high: 1.34
224
+ };
225
+
226
+ function clamp01(value: number): number {
227
+ return Math.min(1, Math.max(0, Number.isFinite(value) ? value : 0));
228
+ }
229
+
230
+ function lerp(from: number, to: number, progress: number): number {
231
+ return from + (to - from) * progress;
232
+ }
233
+
234
+ function smoothStep(progress: number): number {
235
+ const clamped = clamp01(progress);
236
+ return clamped * clamped * (3 - 2 * clamped);
237
+ }
238
+
239
+ function parseTintRgb(value: string): [number, number, number] {
240
+ const channels = value.split(',').map((channel) => Number.parseFloat(channel.trim()));
241
+ return [
242
+ Number.isFinite(channels[0]) ? channels[0] : 34,
243
+ Number.isFinite(channels[1]) ? channels[1] : 211,
244
+ Number.isFinite(channels[2]) ? channels[2] : 238
245
+ ];
246
+ }
247
+
248
+ function formatTintRgb(channels: [number, number, number]): string {
249
+ return channels.map((channel) => String(Math.round(Math.min(255, Math.max(0, channel))))).join(', ');
250
+ }
251
+
252
+ export function createRuntimeSpatialState(
253
+ phase: RuntimePhase | string | null | undefined,
254
+ options: RuntimeSpatialStateOptions = {}
255
+ ): RuntimeSpatialState {
256
+ const resolvedPhase = normalizeKonitifRuntimePhase(phase);
257
+ const quality = options.quality ?? 'medium';
258
+ const base = baseSpatialState[resolvedPhase] ?? baseSpatialState.LAUNCH_GATE;
259
+ const densityFactor = qualityDensityFactor[quality];
260
+ const motionFactor = options.reducedMotion || options.hidden ? 0.08 : quality === 'low' ? 0.58 : quality === 'high' ? 1.12 : 1;
261
+
262
+ return {
263
+ phase: resolvedPhase,
264
+ tint: base.tint,
265
+ tintRgb: base.tintRgb,
266
+ fogDensity: clamp01(base.fogDensity * (quality === 'off' ? 0.18 : quality === 'low' ? 0.7 : quality === 'high' ? 1.12 : 1)),
267
+ particleDensity: clamp01(base.particleDensity * densityFactor),
268
+ particleSpeed: clamp01(base.particleSpeed * motionFactor),
269
+ lightIntensity: clamp01(base.lightIntensity * (quality === 'off' ? 0.3 : quality === 'low' ? 0.78 : quality === 'high' ? 1.08 : 1)),
270
+ motionIntensity: clamp01(base.motionIntensity * motionFactor),
271
+ tiltStrength: clamp01(base.tiltStrength * motionFactor),
272
+ focusFalloff: clamp01(base.focusFalloff),
273
+ instability: clamp01(base.instability * (options.reducedMotion ? 0.3 : 1))
274
+ };
275
+ }
276
+
277
+ export function interpolateRuntimeSpatialState(
278
+ from: RuntimeSpatialState,
279
+ to: RuntimeSpatialState,
280
+ progress: number
281
+ ): RuntimeSpatialState {
282
+ const easedProgress = smoothStep(progress);
283
+ const fromRgb = parseTintRgb(from.tintRgb);
284
+ const toRgb = parseTintRgb(to.tintRgb);
285
+
286
+ return {
287
+ phase: easedProgress >= 0.5 ? to.phase : from.phase,
288
+ tint: easedProgress >= 0.5 ? to.tint : from.tint,
289
+ tintRgb: formatTintRgb([
290
+ lerp(fromRgb[0], toRgb[0], easedProgress),
291
+ lerp(fromRgb[1], toRgb[1], easedProgress),
292
+ lerp(fromRgb[2], toRgb[2], easedProgress)
293
+ ]),
294
+ fogDensity: clamp01(lerp(from.fogDensity, to.fogDensity, easedProgress)),
295
+ particleDensity: clamp01(lerp(from.particleDensity, to.particleDensity, easedProgress)),
296
+ particleSpeed: clamp01(lerp(from.particleSpeed, to.particleSpeed, easedProgress)),
297
+ lightIntensity: clamp01(lerp(from.lightIntensity, to.lightIntensity, easedProgress)),
298
+ motionIntensity: clamp01(lerp(from.motionIntensity, to.motionIntensity, easedProgress)),
299
+ tiltStrength: clamp01(lerp(from.tiltStrength, to.tiltStrength, easedProgress)),
300
+ focusFalloff: clamp01(lerp(from.focusFalloff, to.focusFalloff, easedProgress)),
301
+ instability: clamp01(lerp(from.instability, to.instability, easedProgress))
302
+ };
303
+ }
304
+
305
+ export function shouldRunSpatialAnimation(quality: AmbientQuality, reducedMotion = false, hidden = false): boolean {
306
+ return quality !== 'off' && !reducedMotion && !hidden;
307
+ }
@@ -0,0 +1,53 @@
1
+ import { get, writable } from 'svelte/store';
2
+ import type { RuntimePhase } from '../konitifRuntimePhaseTokens';
3
+ import type { AmbientQuality } from '../ambient/spatialAmbientTypes';
4
+ import {
5
+ createRuntimeSpatialState,
6
+ type RuntimeSpatialState,
7
+ type RuntimeSpatialStateOptions
8
+ } from './runtimeSpatialReactivity';
9
+
10
+ export type RuntimeSpatialStateStore = {
11
+ subscribe: (run: (state: RuntimeSpatialState) => void) => () => void;
12
+ updatePhase: (phase: RuntimePhase | string, options?: RuntimeSpatialStateOptions) => RuntimeSpatialState;
13
+ updateOptions: (options: RuntimeSpatialStateOptions) => RuntimeSpatialState;
14
+ getState: () => RuntimeSpatialState;
15
+ };
16
+
17
+ export function createRuntimeSpatialStateStore(
18
+ phase: RuntimePhase | string = 'LAUNCH_GATE',
19
+ options: RuntimeSpatialStateOptions = {}
20
+ ): RuntimeSpatialStateStore {
21
+ let currentPhase: RuntimePhase | string = phase;
22
+ let currentOptions: RuntimeSpatialStateOptions = options;
23
+ const state = writable(createRuntimeSpatialState(currentPhase, currentOptions));
24
+
25
+ function setNext(nextPhase: RuntimePhase | string, nextOptions: RuntimeSpatialStateOptions): RuntimeSpatialState {
26
+ currentPhase = nextPhase;
27
+ currentOptions = nextOptions;
28
+ const nextState = createRuntimeSpatialState(currentPhase, currentOptions);
29
+ state.set(nextState);
30
+ return nextState;
31
+ }
32
+
33
+ return {
34
+ subscribe: state.subscribe,
35
+ updatePhase(nextPhase, nextOptions = currentOptions) {
36
+ return setNext(nextPhase, { ...currentOptions, ...nextOptions });
37
+ },
38
+ updateOptions(nextOptions) {
39
+ return setNext(currentPhase, { ...currentOptions, ...nextOptions });
40
+ },
41
+ getState() {
42
+ return get(state);
43
+ }
44
+ };
45
+ }
46
+
47
+ export function createRuntimeSpatialStateFromQuality(
48
+ phase: RuntimePhase | string,
49
+ quality: AmbientQuality,
50
+ reducedMotion = false
51
+ ): RuntimeSpatialState {
52
+ return createRuntimeSpatialState(phase, { quality, reducedMotion });
53
+ }