@harmonia-core/ui 1.2.2 → 1.2.4
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/dist/capacity/index.d.ts +2 -0
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +77 -3
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/index.mjs +78 -5
- package/dist/capacity/index.mjs.map +1 -1
- package/dist/capacity/provider.d.ts +3 -0
- package/dist/capacity/provider.d.ts.map +1 -1
- package/dist/capacity/server.d.ts +18 -0
- package/dist/capacity/server.d.ts.map +1 -0
- package/dist/capacity/server.js +356 -0
- package/dist/capacity/server.js.map +1 -0
- package/dist/capacity/server.mjs +327 -0
- package/dist/capacity/server.mjs.map +1 -0
- package/dist/capacity/validation.d.ts +32 -0
- package/dist/capacity/validation.d.ts.map +1 -0
- package/dist/components/capacity-controls.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +260 -569
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +243 -552
- package/dist/components/index.mjs.map +1 -1
- package/package.json +16 -11
package/dist/components/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
var react = require('react');
|
|
4
|
-
var
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var ui = require('@harmonia-core/ui');
|
|
6
6
|
var tokens = require('@renge-ui/tokens');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
|
|
8
9
|
var __defProp = Object.defineProperty;
|
|
9
10
|
var __defProps = Object.defineProperties;
|
|
@@ -36,320 +37,6 @@ var __objRest = (source, exclude) => {
|
|
|
36
37
|
}
|
|
37
38
|
return target;
|
|
38
39
|
};
|
|
39
|
-
var FEEDBACK_FREQUENCIES = {
|
|
40
|
-
low: 396,
|
|
41
|
-
// Foundation/root elements
|
|
42
|
-
mid: 528,
|
|
43
|
-
// Primary interactive content
|
|
44
|
-
high: 741
|
|
45
|
-
// Dynamic/feedback elements
|
|
46
|
-
};
|
|
47
|
-
var DEFAULT_FIELD_CONFIG = {
|
|
48
|
-
smoothing: 0.15,
|
|
49
|
-
// Exponential smoothing factor
|
|
50
|
-
velocityThreshold: 0.05,
|
|
51
|
-
// Min velocity to register as trend
|
|
52
|
-
debounceMs: 100
|
|
53
|
-
// Debounce rapid changes
|
|
54
|
-
};
|
|
55
|
-
var DEFAULT_USER_CAPACITY = {
|
|
56
|
-
cognitive: 0.7,
|
|
57
|
-
temporal: 0.7,
|
|
58
|
-
emotional: 0.7
|
|
59
|
-
};
|
|
60
|
-
var DEFAULT_EMOTIONAL_STATE = {
|
|
61
|
-
valence: 0.3,
|
|
62
|
-
// > 0.15 (with emotional > 0.6) triggers expressive motion mode
|
|
63
|
-
arousal: 0.5
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// lib/capacity/feedback.ts
|
|
67
|
-
var HAPTIC_PATTERNS = {
|
|
68
|
-
/** Short tap — confirm/select */
|
|
69
|
-
tap: [8],
|
|
70
|
-
/** Two pulses — toggle/switch */
|
|
71
|
-
toggle: [8, 50, 8],
|
|
72
|
-
/** Gentle pulse — ambient/ambient confirmation */
|
|
73
|
-
pulse: [15, 30, 15],
|
|
74
|
-
/** Error/warning — three quick */
|
|
75
|
-
error: [50, 30, 50, 30, 50]
|
|
76
|
-
};
|
|
77
|
-
function triggerHaptic(pattern = "tap") {
|
|
78
|
-
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
|
|
79
|
-
navigator.vibrate(HAPTIC_PATTERNS[pattern]);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
var _audioCtx = null;
|
|
83
|
-
function getAudioContext() {
|
|
84
|
-
if (typeof window === "undefined") return null;
|
|
85
|
-
try {
|
|
86
|
-
if (!_audioCtx || _audioCtx.state === "closed") {
|
|
87
|
-
_audioCtx = new AudioContext();
|
|
88
|
-
}
|
|
89
|
-
if (_audioCtx.state === "suspended") {
|
|
90
|
-
_audioCtx.resume();
|
|
91
|
-
}
|
|
92
|
-
return _audioCtx;
|
|
93
|
-
} catch (e) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function playSonicFeedback(frequency, duration = 120, volume = 0.06) {
|
|
98
|
-
const ctx = getAudioContext();
|
|
99
|
-
if (!ctx) return;
|
|
100
|
-
const oscillator = ctx.createOscillator();
|
|
101
|
-
const gainNode = ctx.createGain();
|
|
102
|
-
oscillator.connect(gainNode);
|
|
103
|
-
gainNode.connect(ctx.destination);
|
|
104
|
-
oscillator.type = "sine";
|
|
105
|
-
oscillator.frequency.setValueAtTime(frequency, ctx.currentTime);
|
|
106
|
-
gainNode.gain.setValueAtTime(0, ctx.currentTime);
|
|
107
|
-
gainNode.gain.linearRampToValueAtTime(volume, ctx.currentTime + 0.015);
|
|
108
|
-
gainNode.gain.linearRampToValueAtTime(0, ctx.currentTime + duration / 1e3);
|
|
109
|
-
oscillator.start(ctx.currentTime);
|
|
110
|
-
oscillator.stop(ctx.currentTime + duration / 1e3 + 0.02);
|
|
111
|
-
}
|
|
112
|
-
function getFrequencyForPace(pace) {
|
|
113
|
-
if (pace === "activated") return FEEDBACK_FREQUENCIES.high;
|
|
114
|
-
if (pace === "calm") return FEEDBACK_FREQUENCIES.low;
|
|
115
|
-
return FEEDBACK_FREQUENCIES.mid;
|
|
116
|
-
}
|
|
117
|
-
function playPacedSonic(pace, duration) {
|
|
118
|
-
playSonicFeedback(getFrequencyForPace(pace), duration);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// lib/capacity/fields/field-manager.ts
|
|
122
|
-
function deriveEnergyField(capacity) {
|
|
123
|
-
const { cognitive, temporal, emotional } = capacity;
|
|
124
|
-
return Math.pow(cognitive * temporal * emotional, 1 / 3);
|
|
125
|
-
}
|
|
126
|
-
function deriveAttentionField(capacity) {
|
|
127
|
-
return 1 - capacity.temporal * 0.5;
|
|
128
|
-
}
|
|
129
|
-
function deriveEmotionalValenceField(state) {
|
|
130
|
-
return state.valence;
|
|
131
|
-
}
|
|
132
|
-
function createFieldValue(value, previousValue) {
|
|
133
|
-
var _a;
|
|
134
|
-
const now = Date.now();
|
|
135
|
-
const lastChange = (_a = previousValue == null ? void 0 : previousValue.lastChange) != null ? _a : now;
|
|
136
|
-
const timeDelta = (now - lastChange) / 1e3;
|
|
137
|
-
let trend = "stable";
|
|
138
|
-
let velocity;
|
|
139
|
-
if (typeof value === "number" && previousValue && typeof previousValue.value === "number") {
|
|
140
|
-
const valueDelta = value - previousValue.value;
|
|
141
|
-
velocity = timeDelta > 0 ? valueDelta / timeDelta : 0;
|
|
142
|
-
if (Math.abs(velocity) > DEFAULT_FIELD_CONFIG.velocityThreshold) {
|
|
143
|
-
trend = velocity > 0 ? "rising" : "falling";
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
value,
|
|
148
|
-
lastChange: now,
|
|
149
|
-
trend,
|
|
150
|
-
velocity
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
var FieldManagerClass = class {
|
|
154
|
-
constructor() {
|
|
155
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
156
|
-
this.config = DEFAULT_FIELD_CONFIG;
|
|
157
|
-
const initialCapacity = DEFAULT_USER_CAPACITY;
|
|
158
|
-
const initialState = DEFAULT_EMOTIONAL_STATE;
|
|
159
|
-
this.context = {
|
|
160
|
-
energy: createFieldValue(deriveEnergyField(initialCapacity)),
|
|
161
|
-
attention: createFieldValue(deriveAttentionField(initialCapacity)),
|
|
162
|
-
emotionalValence: createFieldValue(deriveEmotionalValenceField(initialState)),
|
|
163
|
-
userCapacity: initialCapacity,
|
|
164
|
-
emotionalState: initialState
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Get current ambient context (read-only)
|
|
169
|
-
*/
|
|
170
|
-
getContext() {
|
|
171
|
-
return this.context;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Update user capacity (Phase 1 slider system writes here)
|
|
175
|
-
*/
|
|
176
|
-
updateCapacity(capacity) {
|
|
177
|
-
const newCapacity = __spreadValues(__spreadValues({}, this.context.userCapacity), capacity);
|
|
178
|
-
this.context = __spreadProps(__spreadValues({}, this.context), {
|
|
179
|
-
userCapacity: newCapacity,
|
|
180
|
-
energy: createFieldValue(deriveEnergyField(newCapacity), this.context.energy),
|
|
181
|
-
attention: createFieldValue(deriveAttentionField(newCapacity), this.context.attention)
|
|
182
|
-
});
|
|
183
|
-
this.notifyListeners();
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Update emotional state (Phase 1 slider system writes here)
|
|
187
|
-
*/
|
|
188
|
-
updateEmotionalState(state) {
|
|
189
|
-
const newState = __spreadValues(__spreadValues({}, this.context.emotionalState), state);
|
|
190
|
-
this.context = __spreadProps(__spreadValues({}, this.context), {
|
|
191
|
-
emotionalState: newState,
|
|
192
|
-
emotionalValence: createFieldValue(deriveEmotionalValenceField(newState), this.context.emotionalValence)
|
|
193
|
-
});
|
|
194
|
-
this.notifyListeners();
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Subscribe to field changes
|
|
198
|
-
*/
|
|
199
|
-
subscribe(listener) {
|
|
200
|
-
this.listeners.add(listener);
|
|
201
|
-
return () => {
|
|
202
|
-
this.listeners.delete(listener);
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Notify all listeners of field changes
|
|
207
|
-
*/
|
|
208
|
-
notifyListeners() {
|
|
209
|
-
this.listeners.forEach((listener) => {
|
|
210
|
-
try {
|
|
211
|
-
listener(this.context);
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.error("[v0] Field listener error:", error);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Update field configuration
|
|
219
|
-
*/
|
|
220
|
-
updateConfig(config) {
|
|
221
|
-
this.config = __spreadValues(__spreadValues({}, this.config), config);
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Get current field configuration
|
|
225
|
-
*/
|
|
226
|
-
getConfig() {
|
|
227
|
-
return this.config;
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
new FieldManagerClass();
|
|
231
|
-
|
|
232
|
-
// lib/capacity/mode.ts
|
|
233
|
-
function deriveMode(field) {
|
|
234
|
-
var _a;
|
|
235
|
-
const lowCognitive = field.cognitive < 0.4;
|
|
236
|
-
const highCognitive = field.cognitive > 0.7;
|
|
237
|
-
const lowEmotional = field.emotional < 0.4;
|
|
238
|
-
const highEmotional = field.emotional > 0.6;
|
|
239
|
-
const lowTemporal = field.temporal < 0.4;
|
|
240
|
-
const highValence = field.valence > 0.15;
|
|
241
|
-
const negValence = field.valence < -0.15;
|
|
242
|
-
const density = lowCognitive ? "low" : highCognitive ? "high" : "medium";
|
|
243
|
-
const choiceLoad = lowTemporal ? "minimal" : "normal";
|
|
244
|
-
const guidance = lowCognitive ? "high" : lowTemporal ? "medium" : "low";
|
|
245
|
-
const veryLowEmotional = field.emotional < 0.15;
|
|
246
|
-
const motion2 = veryLowEmotional ? "off" : lowEmotional ? "soothing" : highEmotional && highValence ? "expressive" : "subtle";
|
|
247
|
-
const contrast = negValence ? "boosted" : "standard";
|
|
248
|
-
const focus = motion2 === "off" ? "default" : lowCognitive ? "guided" : !highCognitive ? "gentle" : "default";
|
|
249
|
-
const arousal = (_a = field.arousal) != null ? _a : 0.5;
|
|
250
|
-
const pace = arousal < 0.35 ? "calm" : arousal > 0.65 ? "activated" : "neutral";
|
|
251
|
-
return { density, guidance, motion: motion2, contrast, choiceLoad, focus, pace };
|
|
252
|
-
}
|
|
253
|
-
function deriveModeLabel(inputs) {
|
|
254
|
-
const { cognitive, temporal, emotional } = inputs;
|
|
255
|
-
if (cognitive > 0.6 && emotional > 0.6) {
|
|
256
|
-
return "Exploratory";
|
|
257
|
-
}
|
|
258
|
-
if (cognitive < 0.4 && temporal < 0.4) {
|
|
259
|
-
return "Minimal";
|
|
260
|
-
}
|
|
261
|
-
if (cognitive >= 0.55 && temporal >= 0.55) {
|
|
262
|
-
return "Focused";
|
|
263
|
-
}
|
|
264
|
-
return "Calm";
|
|
265
|
-
}
|
|
266
|
-
function getModeBadgeColor(label) {
|
|
267
|
-
switch (label) {
|
|
268
|
-
case "Calm":
|
|
269
|
-
return "oklch(0.65 0.15 220)";
|
|
270
|
-
// Soft blue
|
|
271
|
-
case "Focused":
|
|
272
|
-
return "oklch(0.68 0.16 45)";
|
|
273
|
-
// Primary rust
|
|
274
|
-
case "Exploratory":
|
|
275
|
-
return "oklch(0.65 0.2 135)";
|
|
276
|
-
// Toxic green
|
|
277
|
-
case "Minimal":
|
|
278
|
-
return "oklch(0.55 0.1 280)";
|
|
279
|
-
// Muted purple
|
|
280
|
-
default:
|
|
281
|
-
return "oklch(0.5 0 0)";
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
var CapacityContext = react.createContext(null);
|
|
285
|
-
function useCapacityContext() {
|
|
286
|
-
const context = react.useContext(CapacityContext);
|
|
287
|
-
if (!context) {
|
|
288
|
-
throw new Error("useCapacityContext must be used within CapacityProvider");
|
|
289
|
-
}
|
|
290
|
-
return context;
|
|
291
|
-
}
|
|
292
|
-
function useEnergyField() {
|
|
293
|
-
const { context } = useCapacityContext();
|
|
294
|
-
return context.energy;
|
|
295
|
-
}
|
|
296
|
-
function useAttentionField() {
|
|
297
|
-
const { context } = useCapacityContext();
|
|
298
|
-
return context.attention;
|
|
299
|
-
}
|
|
300
|
-
function useEmotionalValenceField() {
|
|
301
|
-
const { context } = useCapacityContext();
|
|
302
|
-
return context.emotionalValence;
|
|
303
|
-
}
|
|
304
|
-
function useDerivedMode() {
|
|
305
|
-
const { context } = useCapacityContext();
|
|
306
|
-
const field = {
|
|
307
|
-
cognitive: context.userCapacity.cognitive,
|
|
308
|
-
temporal: context.userCapacity.temporal,
|
|
309
|
-
emotional: context.userCapacity.emotional,
|
|
310
|
-
valence: context.emotionalState.valence,
|
|
311
|
-
arousal: context.emotionalState.arousal
|
|
312
|
-
};
|
|
313
|
-
const mode = deriveMode(field);
|
|
314
|
-
return { field, mode };
|
|
315
|
-
}
|
|
316
|
-
function useFeedback() {
|
|
317
|
-
const { hapticEnabled, sonicEnabled, setHapticEnabled, setSonicEnabled } = useCapacityContext();
|
|
318
|
-
const { mode } = useDerivedMode();
|
|
319
|
-
const fire = react.useCallback((pattern = "tap") => {
|
|
320
|
-
if (hapticEnabled) triggerHaptic(pattern);
|
|
321
|
-
if (sonicEnabled) playPacedSonic(mode.pace);
|
|
322
|
-
}, [hapticEnabled, sonicEnabled, mode.pace]);
|
|
323
|
-
return { hapticEnabled, sonicEnabled, setHapticEnabled, setSonicEnabled, fire };
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// lib/capacity/animation.ts
|
|
327
|
-
var ENTRANCE_PRESETS = {
|
|
328
|
-
/** Liquid organic morph -> gentle scale fade -> soft bloom -> none */
|
|
329
|
-
morph: { expressive: "morph-fade-in", subtle: "sacred-fade", soothing: "bloom", off: "" },
|
|
330
|
-
/** Spinning vortex -> gentle scale fade -> soft bloom -> none */
|
|
331
|
-
vortex: { expressive: "vortex-reveal", subtle: "sacred-fade", soothing: "bloom", off: "" },
|
|
332
|
-
/** Spiral in from corner -> soft bloom -> soft bloom -> none */
|
|
333
|
-
spiral: { expressive: "spiral-in", subtle: "bloom", soothing: "bloom", off: "" }
|
|
334
|
-
};
|
|
335
|
-
function entranceClass(motion2, preset, hasPlayed) {
|
|
336
|
-
return ENTRANCE_PRESETS[preset][motion2];
|
|
337
|
-
}
|
|
338
|
-
function hoverClass(motion2) {
|
|
339
|
-
if (motion2 === "expressive") return "hover-expand";
|
|
340
|
-
if (motion2 === "subtle" || motion2 === "soothing") return "hover-lift";
|
|
341
|
-
return "";
|
|
342
|
-
}
|
|
343
|
-
function ambientClass(motion2, type) {
|
|
344
|
-
if (motion2 === "expressive") return type;
|
|
345
|
-
if (motion2 === "soothing" && (type === "breathe" || type === "float")) return type;
|
|
346
|
-
return "";
|
|
347
|
-
}
|
|
348
|
-
function listItemClass(motion2) {
|
|
349
|
-
if (motion2 === "expressive") return "helix-rise";
|
|
350
|
-
if (motion2 === "subtle" || motion2 === "soothing") return "sacred-fade";
|
|
351
|
-
return "";
|
|
352
|
-
}
|
|
353
40
|
var SLIDER_STYLES = `
|
|
354
41
|
[data-renge-slider] {
|
|
355
42
|
-webkit-appearance: none;
|
|
@@ -995,14 +682,14 @@ var DEFAULT_CALM_STATE = {
|
|
|
995
682
|
function CapacityControls() {
|
|
996
683
|
var _a;
|
|
997
684
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
998
|
-
const { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode } = useCapacityContext();
|
|
999
|
-
const { hapticEnabled, sonicEnabled, setHapticEnabled, setSonicEnabled, fire: fireFeedback } = useFeedback();
|
|
1000
|
-
const { field, mode } = useDerivedMode();
|
|
1001
|
-
const energy = useEnergyField();
|
|
1002
|
-
const attention = useAttentionField();
|
|
1003
|
-
const valence = useEmotionalValenceField();
|
|
1004
|
-
const modeLabel = deriveModeLabel(field);
|
|
1005
|
-
const modeBadgeColor = getModeBadgeColor(modeLabel);
|
|
685
|
+
const { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode, conflicts } = ui.useCapacityContext();
|
|
686
|
+
const { hapticEnabled, sonicEnabled, setHapticEnabled, setSonicEnabled, fire: fireFeedback } = ui.useFeedback();
|
|
687
|
+
const { field, mode } = ui.useDerivedMode();
|
|
688
|
+
const energy = ui.useEnergyField();
|
|
689
|
+
const attention = ui.useAttentionField();
|
|
690
|
+
const valence = ui.useEmotionalValenceField();
|
|
691
|
+
const modeLabel = ui.deriveModeLabel(field);
|
|
692
|
+
const modeBadgeColor = ui.getModeBadgeColor(modeLabel);
|
|
1006
693
|
const handleReset = () => {
|
|
1007
694
|
updateCapacity({
|
|
1008
695
|
cognitive: DEFAULT_CALM_STATE.cognitive,
|
|
@@ -1018,262 +705,266 @@ function CapacityControls() {
|
|
|
1018
705
|
fireFeedback("tap");
|
|
1019
706
|
}, [fireFeedback]);
|
|
1020
707
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-4 right-4 z-50", children: [
|
|
1021
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
"Capacity"
|
|
1047
|
-
]
|
|
1048
|
-
}
|
|
1049
|
-
)
|
|
1050
|
-
]
|
|
1051
|
-
}
|
|
1052
|
-
) }),
|
|
1053
|
-
/* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1054
|
-
react$1.motion.div,
|
|
708
|
+
!isOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
709
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
710
|
+
Badge,
|
|
711
|
+
{
|
|
712
|
+
className: "shadow-lg",
|
|
713
|
+
style: { backgroundColor: modeBadgeColor, color: "white" },
|
|
714
|
+
children: modeLabel
|
|
715
|
+
}
|
|
716
|
+
),
|
|
717
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
718
|
+
Button,
|
|
719
|
+
{
|
|
720
|
+
onClick: () => setIsOpen(true),
|
|
721
|
+
variant: "outline",
|
|
722
|
+
size: "sm",
|
|
723
|
+
className: "shadow-lg bg-background",
|
|
724
|
+
children: [
|
|
725
|
+
/* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, { className: "w-4 h-4 mr-2" }),
|
|
726
|
+
"Capacity"
|
|
727
|
+
]
|
|
728
|
+
}
|
|
729
|
+
)
|
|
730
|
+
] }),
|
|
731
|
+
isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
732
|
+
"div",
|
|
1055
733
|
{
|
|
1056
|
-
initial: { opacity: 0 },
|
|
1057
|
-
animate: { opacity: 1 },
|
|
1058
|
-
exit: { opacity: 0 },
|
|
1059
734
|
className: "fixed inset-0 bg-black/20 backdrop-blur-sm md:hidden",
|
|
1060
735
|
onClick: () => setIsOpen(false),
|
|
1061
736
|
"aria-hidden": "true"
|
|
1062
737
|
}
|
|
1063
|
-
)
|
|
1064
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
exit: { opacity: 0, y: 20, scale: 0.95 },
|
|
1070
|
-
transition: { type: "spring", damping: 20, stiffness: 300 },
|
|
1071
|
-
className: "relative",
|
|
1072
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "w-80 shadow-xl max-h-[85vh] overflow-y-auto", children: [
|
|
1073
|
-
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "pb-3", children: [
|
|
1074
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
1075
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1076
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-sm font-semibold", children: "Capacity Controls" }),
|
|
1077
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1078
|
-
Button,
|
|
1079
|
-
{
|
|
1080
|
-
variant: "ghost",
|
|
1081
|
-
size: "icon",
|
|
1082
|
-
className: "h-8 w-8 shrink-0",
|
|
1083
|
-
onClick: (e) => {
|
|
1084
|
-
e.stopPropagation();
|
|
1085
|
-
setIsOpen(false);
|
|
1086
|
-
},
|
|
1087
|
-
"aria-label": "Close capacity controls",
|
|
1088
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { className: "w-4 h-4" })
|
|
1089
|
-
}
|
|
1090
|
-
)
|
|
1091
|
-
] }),
|
|
1092
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1093
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1094
|
-
Badge,
|
|
1095
|
-
{
|
|
1096
|
-
className: "text-xs",
|
|
1097
|
-
style: { backgroundColor: modeBadgeColor, color: "white" },
|
|
1098
|
-
children: modeLabel
|
|
1099
|
-
}
|
|
1100
|
-
),
|
|
1101
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1102
|
-
Button,
|
|
1103
|
-
{
|
|
1104
|
-
variant: isAutoMode ? "default" : "outline",
|
|
1105
|
-
size: "sm",
|
|
1106
|
-
className: "h-7 text-xs px-2",
|
|
1107
|
-
onClick: toggleAutoMode,
|
|
1108
|
-
"aria-label": isAutoMode ? "Switch to manual mode" : "Switch to auto mode",
|
|
1109
|
-
children: isAutoMode ? "Auto" : "Manual"
|
|
1110
|
-
}
|
|
1111
|
-
)
|
|
1112
|
-
] })
|
|
1113
|
-
] }),
|
|
1114
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: isAutoMode ? "Signals are driving values automatically. Move any slider to take manual control." : "Adjust your state to see the UI adapt in real-time." })
|
|
1115
|
-
] }),
|
|
1116
|
-
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-6", children: [
|
|
1117
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 flex flex-col gap-2", children: [
|
|
1118
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Quick Presets" }),
|
|
1119
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1120
|
-
Select,
|
|
1121
|
-
{
|
|
1122
|
-
defaultValue: "",
|
|
1123
|
-
onValueChange: (value) => {
|
|
1124
|
-
if (!value) return;
|
|
1125
|
-
const preset = CAPACITY_PRESETS[value];
|
|
1126
|
-
updateCapacity({
|
|
1127
|
-
cognitive: preset.cognitive,
|
|
1128
|
-
temporal: preset.temporal,
|
|
1129
|
-
emotional: preset.emotional
|
|
1130
|
-
});
|
|
1131
|
-
updateEmotionalState({ valence: preset.valence, arousal: preset.arousal });
|
|
1132
|
-
fireInteractionFeedback();
|
|
1133
|
-
},
|
|
1134
|
-
children: [
|
|
1135
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select a preset..." }),
|
|
1136
|
-
Object.entries(CAPACITY_PRESETS).map(([key, preset]) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: key, children: [
|
|
1137
|
-
preset.label,
|
|
1138
|
-
" \u2014 ",
|
|
1139
|
-
preset.description
|
|
1140
|
-
] }, key))
|
|
1141
|
-
]
|
|
1142
|
-
}
|
|
1143
|
-
)
|
|
1144
|
-
] }),
|
|
1145
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-t border-border pt-4", children: [
|
|
1146
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Or adjust individually:" }),
|
|
1147
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1148
|
-
Button,
|
|
1149
|
-
{
|
|
1150
|
-
variant: "ghost",
|
|
1151
|
-
size: "sm",
|
|
1152
|
-
onClick: handleReset,
|
|
1153
|
-
className: "h-7 text-xs text-muted-foreground hover:text-foreground",
|
|
1154
|
-
children: [
|
|
1155
|
-
/* @__PURE__ */ jsxRuntime.jsx(ResetIcon, { className: "w-3 h-3 mr-1" }),
|
|
1156
|
-
"Reset"
|
|
1157
|
-
]
|
|
1158
|
-
}
|
|
1159
|
-
)
|
|
1160
|
-
] }),
|
|
738
|
+
),
|
|
739
|
+
isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "w-80 shadow-xl max-h-[85vh] overflow-y-auto", children: [
|
|
740
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "pb-3", children: [
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
742
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
743
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-sm font-semibold", children: "Capacity Controls" }),
|
|
1161
744
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1162
|
-
|
|
745
|
+
Button,
|
|
1163
746
|
{
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
747
|
+
variant: "ghost",
|
|
748
|
+
size: "icon",
|
|
749
|
+
className: "h-8 w-8 shrink-0",
|
|
750
|
+
onClick: (e) => {
|
|
751
|
+
e.stopPropagation();
|
|
752
|
+
setIsOpen(false);
|
|
753
|
+
},
|
|
754
|
+
"aria-label": "Close capacity controls",
|
|
755
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { className: "w-4 h-4" })
|
|
1170
756
|
}
|
|
1171
|
-
)
|
|
757
|
+
)
|
|
758
|
+
] }),
|
|
759
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1172
760
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1173
|
-
|
|
761
|
+
Badge,
|
|
1174
762
|
{
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
onChange: (v) => updateCapacity({ temporal: v }),
|
|
1179
|
-
lowLabel: "Abbreviated",
|
|
1180
|
-
highLabel: "Full detail"
|
|
763
|
+
className: "text-xs",
|
|
764
|
+
style: { backgroundColor: modeBadgeColor, color: "white" },
|
|
765
|
+
children: modeLabel
|
|
1181
766
|
}
|
|
1182
767
|
),
|
|
1183
768
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1184
|
-
|
|
769
|
+
Button,
|
|
1185
770
|
{
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
771
|
+
variant: isAutoMode ? "default" : "outline",
|
|
772
|
+
size: "sm",
|
|
773
|
+
className: "h-7 text-xs px-2",
|
|
774
|
+
onClick: toggleAutoMode,
|
|
775
|
+
"aria-label": isAutoMode ? "Switch to manual mode" : "Switch to auto mode",
|
|
776
|
+
children: isAutoMode ? "Auto" : "Manual"
|
|
1192
777
|
}
|
|
1193
|
-
)
|
|
1194
|
-
|
|
1195
|
-
|
|
778
|
+
)
|
|
779
|
+
] })
|
|
780
|
+
] }),
|
|
781
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: isAutoMode ? "Signals are driving values automatically. Move any slider to take manual control." : "Adjust your state to see the UI adapt in real-time." })
|
|
782
|
+
] }),
|
|
783
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-6", children: [
|
|
784
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 flex flex-col gap-2", children: [
|
|
785
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Quick Presets" }),
|
|
786
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
787
|
+
Select,
|
|
788
|
+
{
|
|
789
|
+
defaultValue: "",
|
|
790
|
+
onValueChange: (value) => {
|
|
791
|
+
if (!value) return;
|
|
792
|
+
const preset = CAPACITY_PRESETS[value];
|
|
793
|
+
updateCapacity({
|
|
794
|
+
cognitive: preset.cognitive,
|
|
795
|
+
temporal: preset.temporal,
|
|
796
|
+
emotional: preset.emotional
|
|
797
|
+
});
|
|
798
|
+
updateEmotionalState({ valence: preset.valence, arousal: preset.arousal });
|
|
799
|
+
fireInteractionFeedback();
|
|
800
|
+
},
|
|
801
|
+
children: [
|
|
802
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select a preset..." }),
|
|
803
|
+
Object.entries(CAPACITY_PRESETS).map(([key, preset]) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: key, children: [
|
|
804
|
+
preset.label,
|
|
805
|
+
" \u2014 ",
|
|
806
|
+
preset.description
|
|
807
|
+
] }, key))
|
|
808
|
+
]
|
|
809
|
+
}
|
|
810
|
+
)
|
|
811
|
+
] }),
|
|
812
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-t border-border pt-4", children: [
|
|
813
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Or adjust individually:" }),
|
|
814
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
815
|
+
Button,
|
|
816
|
+
{
|
|
817
|
+
variant: "ghost",
|
|
818
|
+
size: "sm",
|
|
819
|
+
onClick: handleReset,
|
|
820
|
+
className: "h-7 text-xs text-muted-foreground hover:text-foreground",
|
|
821
|
+
children: [
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResetIcon, { className: "w-3 h-3 mr-1" }),
|
|
823
|
+
"Reset"
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
)
|
|
827
|
+
] }),
|
|
828
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
829
|
+
SliderControl,
|
|
830
|
+
{
|
|
831
|
+
label: "Cognitive Capacity",
|
|
832
|
+
description: "Controls: density, hierarchy, concurrency",
|
|
833
|
+
value: field.cognitive,
|
|
834
|
+
onChange: (v) => updateCapacity({ cognitive: v }),
|
|
835
|
+
lowLabel: "Fewer items",
|
|
836
|
+
highLabel: "More items"
|
|
837
|
+
}
|
|
838
|
+
),
|
|
839
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
840
|
+
SliderControl,
|
|
841
|
+
{
|
|
842
|
+
label: "Temporal Capacity",
|
|
843
|
+
description: "Controls: content length, shortcuts, defaults",
|
|
844
|
+
value: field.temporal,
|
|
845
|
+
onChange: (v) => updateCapacity({ temporal: v }),
|
|
846
|
+
lowLabel: "Abbreviated",
|
|
847
|
+
highLabel: "Full detail"
|
|
848
|
+
}
|
|
849
|
+
),
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
SliderControl,
|
|
852
|
+
{
|
|
853
|
+
label: "Emotional Capacity",
|
|
854
|
+
description: "Controls: motion restraint, friction",
|
|
855
|
+
value: field.emotional,
|
|
856
|
+
onChange: (v) => updateCapacity({ emotional: v }),
|
|
857
|
+
lowLabel: "Calm UI",
|
|
858
|
+
highLabel: "Expressive"
|
|
859
|
+
}
|
|
860
|
+
),
|
|
861
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2 border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
862
|
+
ValenceSliderControl,
|
|
863
|
+
{
|
|
864
|
+
label: "Emotional Valence",
|
|
865
|
+
description: "Controls: tone, expressiveness (not info volume)",
|
|
866
|
+
value: field.valence,
|
|
867
|
+
onChange: (v) => updateEmotionalState({ valence: v })
|
|
868
|
+
}
|
|
869
|
+
) }),
|
|
870
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
871
|
+
SliderControl,
|
|
872
|
+
{
|
|
873
|
+
label: "Arousal",
|
|
874
|
+
description: "Controls: animation pacing (calm \u2192 activated)",
|
|
875
|
+
value: (_a = field.arousal) != null ? _a : 0.5,
|
|
876
|
+
onChange: (v) => updateEmotionalState({ arousal: v }),
|
|
877
|
+
lowLabel: "Calm",
|
|
878
|
+
highLabel: "Activated"
|
|
879
|
+
}
|
|
880
|
+
),
|
|
881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-2 border-t border-border space-y-2", children: [
|
|
882
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
883
|
+
"Feedback ",
|
|
884
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-normal opacity-60", children: "(opt-in)" })
|
|
885
|
+
] }),
|
|
886
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
887
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
888
|
+
"button",
|
|
1196
889
|
{
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
890
|
+
onClick: () => setHapticEnabled((v) => !v),
|
|
891
|
+
className: `flex-1 py-1.5 px-2 rounded-md text-xs border transition-colors ${hapticEnabled ? "bg-primary/10 border-primary/50 text-primary" : "border-border text-muted-foreground hover:text-foreground"}`,
|
|
892
|
+
"aria-pressed": hapticEnabled,
|
|
893
|
+
children: "\u{1F4F3} Haptic"
|
|
1201
894
|
}
|
|
1202
|
-
)
|
|
895
|
+
),
|
|
1203
896
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1204
|
-
|
|
897
|
+
"button",
|
|
1205
898
|
{
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
lowLabel: "Calm",
|
|
1211
|
-
highLabel: "Activated"
|
|
899
|
+
onClick: () => setSonicEnabled((v) => !v),
|
|
900
|
+
className: `flex-1 py-1.5 px-2 rounded-md text-xs border transition-colors ${sonicEnabled ? "bg-primary/10 border-primary/50 text-primary" : "border-border text-muted-foreground hover:text-foreground"}`,
|
|
901
|
+
"aria-pressed": sonicEnabled,
|
|
902
|
+
children: "\u{1F514} Sonic"
|
|
1212
903
|
}
|
|
1213
|
-
)
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
)
|
|
1238
|
-
] }),
|
|
1239
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[10px] text-muted-foreground opacity-60", children: [
|
|
1240
|
-
"Pace: ",
|
|
1241
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.pace }),
|
|
1242
|
-
" \u2192 ",
|
|
1243
|
-
mode.pace === "calm" ? "+50% duration" : mode.pace === "activated" ? "\u221235% duration" : "standard"
|
|
1244
|
-
] })
|
|
1245
|
-
] }),
|
|
1246
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t border-border", children: [
|
|
1247
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Derived Fields" }),
|
|
1248
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2 text-center", children: [
|
|
1249
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Energy", value: energy.value, color: "text-chart-1" }),
|
|
1250
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Attention", value: attention.value, color: "text-chart-2" }),
|
|
1251
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Valence", value: valence.value, color: "text-chart-3", signed: true })
|
|
1252
|
-
] })
|
|
1253
|
-
] }),
|
|
1254
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t border-border", children: [
|
|
1255
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Interface Mode" }),
|
|
1256
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-1 text-xs", children: [
|
|
1257
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Density:" }),
|
|
1258
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.density }),
|
|
1259
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Guidance:" }),
|
|
1260
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.guidance }),
|
|
1261
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Motion:" }),
|
|
1262
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.motion }),
|
|
1263
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Contrast:" }),
|
|
1264
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.contrast }),
|
|
1265
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Choices:" }),
|
|
1266
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.choiceLoad }),
|
|
1267
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Focus:" }),
|
|
1268
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.focus }),
|
|
1269
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Pace:" }),
|
|
1270
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.pace })
|
|
1271
|
-
] })
|
|
904
|
+
)
|
|
905
|
+
] }),
|
|
906
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[10px] text-muted-foreground opacity-60", children: [
|
|
907
|
+
"Pace: ",
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.pace }),
|
|
909
|
+
" \u2192 ",
|
|
910
|
+
mode.pace === "calm" ? "+50% duration" : mode.pace === "activated" ? "\u221235% duration" : "standard"
|
|
911
|
+
] })
|
|
912
|
+
] }),
|
|
913
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t border-border", children: [
|
|
914
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Derived Fields" }),
|
|
915
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2 text-center", children: [
|
|
916
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Energy", value: energy.value, color: "text-chart-1" }),
|
|
917
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Attention", value: attention.value, color: "text-chart-2" }),
|
|
918
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldDisplay, { label: "Valence", value: valence.value, color: "text-chart-3", signed: true })
|
|
919
|
+
] })
|
|
920
|
+
] }),
|
|
921
|
+
conflicts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t border-border space-y-2", children: [
|
|
922
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
923
|
+
"Conflicts ",
|
|
924
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-normal opacity-60", children: [
|
|
925
|
+
"(",
|
|
926
|
+
conflicts.length,
|
|
927
|
+
")"
|
|
1272
928
|
] })
|
|
929
|
+
] }),
|
|
930
|
+
conflicts.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
931
|
+
"div",
|
|
932
|
+
{
|
|
933
|
+
className: `rounded-md p-2 text-xs space-y-1 ${c.severity === "warning" ? "bg-warning/10 border border-warning/30 text-warning-content" : "bg-muted/60 border border-border text-muted-foreground"}`,
|
|
934
|
+
children: [
|
|
935
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: c.label }),
|
|
936
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "opacity-80 leading-snug", children: c.message }),
|
|
937
|
+
c.suggestion && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "opacity-60 italic", children: c.suggestion }),
|
|
938
|
+
c.affectedTokens.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "opacity-50", children: [
|
|
939
|
+
"Affects: ",
|
|
940
|
+
c.affectedTokens.join(", ")
|
|
941
|
+
] })
|
|
942
|
+
]
|
|
943
|
+
},
|
|
944
|
+
c.id
|
|
945
|
+
))
|
|
946
|
+
] }),
|
|
947
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-4 border-t border-border", children: [
|
|
948
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Interface Mode" }),
|
|
949
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-1 text-xs", children: [
|
|
950
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Density:" }),
|
|
951
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.density }),
|
|
952
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Guidance:" }),
|
|
953
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.guidance }),
|
|
954
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Motion:" }),
|
|
955
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.motion }),
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Contrast:" }),
|
|
957
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.contrast }),
|
|
958
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Choices:" }),
|
|
959
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.choiceLoad }),
|
|
960
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Focus:" }),
|
|
961
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.focus }),
|
|
962
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Pace:" }),
|
|
963
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: mode.pace })
|
|
1273
964
|
] })
|
|
1274
965
|
] })
|
|
1275
|
-
}
|
|
1276
|
-
) })
|
|
966
|
+
] })
|
|
967
|
+
] }) })
|
|
1277
968
|
] });
|
|
1278
969
|
}
|
|
1279
970
|
function SliderControl({
|
|
@@ -1404,16 +1095,16 @@ var TONE = {
|
|
|
1404
1095
|
}
|
|
1405
1096
|
};
|
|
1406
1097
|
function CapacityDemoCard() {
|
|
1407
|
-
const { field, mode } = useDerivedMode();
|
|
1408
|
-
const { fire } = useFeedback();
|
|
1409
|
-
const modeLabel = deriveModeLabel(field);
|
|
1410
|
-
const modeBadgeColor = getModeBadgeColor(modeLabel);
|
|
1098
|
+
const { field, mode } = ui.useDerivedMode();
|
|
1099
|
+
const { fire } = ui.useFeedback();
|
|
1100
|
+
const modeLabel = ui.deriveModeLabel(field);
|
|
1101
|
+
const modeBadgeColor = ui.getModeBadgeColor(modeLabel);
|
|
1411
1102
|
const densityContent = DENSITY_CONTENT[mode.density];
|
|
1412
1103
|
const temporalContent = field.temporal > 0.4 ? TEMPORAL_CONTENT.full : TEMPORAL_CONTENT.abbreviated;
|
|
1413
1104
|
const toneKey = field.valence > 0.2 ? "positive" : field.valence < -0.2 ? "negative" : "neutral";
|
|
1414
1105
|
const tone = TONE[toneKey];
|
|
1415
|
-
const entrance = entranceClass(mode.motion, "morph");
|
|
1416
|
-
const hover = hoverClass(mode.motion);
|
|
1106
|
+
const entrance = ui.entranceClass(mode.motion, "morph", false);
|
|
1107
|
+
const hover = ui.hoverClass(mode.motion);
|
|
1417
1108
|
const visibleFeatures = temporalContent.features.slice(0, densityContent.featureCount);
|
|
1418
1109
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1419
1110
|
Card,
|
|
@@ -1436,14 +1127,14 @@ function CapacityDemoCard() {
|
|
|
1436
1127
|
),
|
|
1437
1128
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-xs ${tone.accent}`, children: tone.greeting })
|
|
1438
1129
|
] }),
|
|
1439
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: ambientClass(mode.motion, "float"), children: densityContent.title }),
|
|
1130
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: ui.ambientClass(mode.motion, "float"), children: densityContent.title }),
|
|
1440
1131
|
mode.density !== "low" && /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: temporalContent.description })
|
|
1441
1132
|
] }),
|
|
1442
1133
|
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4", children: [
|
|
1443
1134
|
visibleFeatures.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-2", children: visibleFeatures.map((feature, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1444
1135
|
"li",
|
|
1445
1136
|
{
|
|
1446
|
-
className: `flex items-start gap-2 text-sm text-muted-foreground ${listItemClass(mode.motion)}`,
|
|
1137
|
+
className: `flex items-start gap-2 text-sm text-muted-foreground ${ui.listItemClass(mode.motion)}`,
|
|
1447
1138
|
style: { animationDelay: `${idx * 0.15}s` },
|
|
1448
1139
|
children: [
|
|
1449
1140
|
/* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "w-4 h-4 text-primary shrink-0 mt-0.5" }),
|
|
@@ -1457,7 +1148,7 @@ function CapacityDemoCard() {
|
|
|
1457
1148
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1458
1149
|
"button",
|
|
1459
1150
|
{
|
|
1460
|
-
className: `${mode.choiceLoad === "normal" ? "flex-1" : "w-full"} py-2 px-4 rounded-md bg-primary text-primary-foreground font-medium text-sm transition-transform ${hover} ${ambientClass(mode.motion, "breathe")}`,
|
|
1151
|
+
className: `${mode.choiceLoad === "normal" ? "flex-1" : "w-full"} py-2 px-4 rounded-md bg-primary text-primary-foreground font-medium text-sm transition-transform ${hover} ${ui.ambientClass(mode.motion, "breathe")}`,
|
|
1461
1152
|
onClick: () => fire("tap"),
|
|
1462
1153
|
children: densityContent.cta
|
|
1463
1154
|
}
|
|
@@ -1529,9 +1220,9 @@ function AmbientFieldMonitor() {
|
|
|
1529
1220
|
] });
|
|
1530
1221
|
}
|
|
1531
1222
|
function InputsToModeFlow() {
|
|
1532
|
-
const { field, mode } = useDerivedMode();
|
|
1533
|
-
const label = deriveModeLabel(field);
|
|
1534
|
-
const badgeColor = getModeBadgeColor(label);
|
|
1223
|
+
const { field, mode } = ui.useDerivedMode();
|
|
1224
|
+
const label = ui.deriveModeLabel(field);
|
|
1225
|
+
const badgeColor = ui.getModeBadgeColor(label);
|
|
1535
1226
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "overflow-hidden border-border/50", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-3 divide-y lg:divide-y-0 lg:divide-x divide-border/50", children: [
|
|
1536
1227
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-4", children: [
|
|
1537
1228
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [
|