@vib3code/sdk 2.0.1 → 2.0.3-canary.6f35b4c

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 (96) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +243 -0
  3. package/DOCS/CLI_ONBOARDING.md +1 -1
  4. package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +117 -0
  5. package/DOCS/EPIC_SCROLL_EVENTS.md +773 -0
  6. package/DOCS/HANDOFF_LANDING_PAGE.md +154 -0
  7. package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +493 -0
  8. package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +937 -0
  9. package/DOCS/PRODUCT_STRATEGY.md +63 -0
  10. package/DOCS/README.md +103 -0
  11. package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +97 -0
  12. package/DOCS/ROADMAP.md +111 -0
  13. package/DOCS/SCROLL_TIMELINE_v3.md +269 -0
  14. package/DOCS/SITE_REFACTOR_PLAN.md +100 -0
  15. package/DOCS/STATUS.md +24 -0
  16. package/DOCS/SYSTEM_INVENTORY.md +33 -30
  17. package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +85 -0
  18. package/DOCS/VISUAL_ANALYSIS_FACETAD.md +133 -0
  19. package/DOCS/VISUAL_ANALYSIS_SIMONE.md +95 -0
  20. package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +86 -0
  21. package/DOCS/{BLUEPRINT_EXECUTION_PLAN_2026-01-07.md → archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md} +1 -1
  22. package/DOCS/{DEV_TRACK_ANALYSIS.md → archive/DEV_TRACK_ANALYSIS.md} +3 -0
  23. package/DOCS/{SYSTEM_AUDIT_2026-01-30.md → archive/SYSTEM_AUDIT_2026-01-30.md} +3 -0
  24. package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +1 -1
  25. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +231 -0
  26. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +127 -0
  27. package/DOCS/dev-tracks/README.md +10 -0
  28. package/README.md +26 -13
  29. package/cpp/CMakeLists.txt +236 -0
  30. package/cpp/bindings/embind.cpp +269 -0
  31. package/cpp/build.sh +129 -0
  32. package/cpp/geometry/Crystal.cpp +103 -0
  33. package/cpp/geometry/Fractal.cpp +136 -0
  34. package/cpp/geometry/GeometryGenerator.cpp +262 -0
  35. package/cpp/geometry/KleinBottle.cpp +71 -0
  36. package/cpp/geometry/Sphere.cpp +134 -0
  37. package/cpp/geometry/Tesseract.cpp +94 -0
  38. package/cpp/geometry/Tetrahedron.cpp +83 -0
  39. package/cpp/geometry/Torus.cpp +65 -0
  40. package/cpp/geometry/WarpFunctions.cpp +238 -0
  41. package/cpp/geometry/Wave.cpp +85 -0
  42. package/cpp/include/vib3_ffi.h +238 -0
  43. package/cpp/math/Mat4x4.cpp +409 -0
  44. package/cpp/math/Mat4x4.hpp +209 -0
  45. package/cpp/math/Projection.cpp +142 -0
  46. package/cpp/math/Projection.hpp +148 -0
  47. package/cpp/math/Rotor4D.cpp +322 -0
  48. package/cpp/math/Rotor4D.hpp +204 -0
  49. package/cpp/math/Vec4.cpp +303 -0
  50. package/cpp/math/Vec4.hpp +225 -0
  51. package/cpp/src/vib3_ffi.cpp +607 -0
  52. package/cpp/tests/Geometry_test.cpp +213 -0
  53. package/cpp/tests/Mat4x4_test.cpp +494 -0
  54. package/cpp/tests/Projection_test.cpp +298 -0
  55. package/cpp/tests/Rotor4D_test.cpp +423 -0
  56. package/cpp/tests/Vec4_test.cpp +489 -0
  57. package/package.json +31 -27
  58. package/src/agent/mcp/MCPServer.js +722 -0
  59. package/src/agent/mcp/stdio-server.js +264 -0
  60. package/src/agent/mcp/tools.js +367 -0
  61. package/src/cli/index.js +0 -0
  62. package/src/core/CanvasManager.js +97 -204
  63. package/src/core/ErrorReporter.js +1 -1
  64. package/src/core/Parameters.js +1 -1
  65. package/src/core/VIB3Engine.js +38 -1
  66. package/src/core/VitalitySystem.js +53 -0
  67. package/src/core/renderers/HolographicRendererAdapter.js +2 -2
  68. package/src/creative/AestheticMapper.js +628 -0
  69. package/src/creative/ChoreographyPlayer.js +481 -0
  70. package/src/export/TradingCardManager.js +3 -4
  71. package/src/faceted/FacetedSystem.js +237 -388
  72. package/src/holograms/HolographicVisualizer.js +29 -12
  73. package/src/holograms/RealHolographicSystem.js +68 -12
  74. package/src/polychora/PolychoraSystem.js +77 -0
  75. package/src/quantum/QuantumEngine.js +103 -66
  76. package/src/quantum/QuantumVisualizer.js +7 -2
  77. package/src/render/UnifiedRenderBridge.js +3 -0
  78. package/src/shaders/faceted/faceted.frag.glsl +220 -80
  79. package/src/shaders/faceted/faceted.frag.wgsl +138 -97
  80. package/src/shaders/holographic/holographic.frag.glsl +28 -9
  81. package/src/shaders/holographic/holographic.frag.wgsl +107 -38
  82. package/src/shaders/quantum/quantum.frag.glsl +1 -0
  83. package/src/shaders/quantum/quantum.frag.wgsl +1 -1
  84. package/src/viewer/index.js +1 -1
  85. package/tools/headless-renderer.js +258 -0
  86. package/tools/shader-sync-verify.js +8 -4
  87. package/tools/site-analysis/all-reports.json +32 -0
  88. package/tools/site-analysis/combined-analysis.md +50 -0
  89. package/tools/site-analyzer.mjs +779 -0
  90. package/tools/visual-catalog/capture.js +276 -0
  91. package/tools/visual-catalog/composite.js +138 -0
  92. /package/DOCS/{DEV_TRACK_PLAN_2026-01-07.md → archive/DEV_TRACK_PLAN_2026-01-07.md} +0 -0
  93. /package/DOCS/{SESSION_014_PLAN.md → archive/SESSION_014_PLAN.md} +0 -0
  94. /package/DOCS/{SESSION_LOG_2026-01-07.md → archive/SESSION_LOG_2026-01-07.md} +0 -0
  95. /package/DOCS/{STRATEGIC_BLUEPRINT_2026-01-07.md → archive/STRATEGIC_BLUEPRINT_2026-01-07.md} +0 -0
  96. /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
@@ -0,0 +1,481 @@
1
+ /**
2
+ * ChoreographyPlayer.js - VIB3+ Multi-Scene Choreography Playback Runtime
3
+ *
4
+ * Plays back choreography specifications created by the `create_choreography`
5
+ * MCP tool. Orchestrates system switching, geometry changes, per-scene
6
+ * ParameterTimeline playback, color presets, post-processing, and scene
7
+ * transitions across the full choreography duration.
8
+ *
9
+ * @module creative/ChoreographyPlayer
10
+ * @version 1.0.0
11
+ */
12
+
13
+ import { ParameterTimeline } from './ParameterTimeline.js';
14
+ import { TransitionAnimator } from './TransitionAnimator.js';
15
+
16
+ /**
17
+ * @typedef {Object} ChoreographyScene
18
+ * @property {number} index - Scene index
19
+ * @property {number} time_start - Start time (ms)
20
+ * @property {number} time_end - End time (ms)
21
+ * @property {string} system - Visualization system name
22
+ * @property {number} geometry - Geometry index (0-23)
23
+ * @property {Object} transition_in - Entry transition config
24
+ * @property {Object} tracks - Per-scene parameter timeline tracks
25
+ * @property {string|null} color_preset - Color preset name
26
+ * @property {string[]} post_processing - Active effect names
27
+ * @property {Object|null} audio - Audio reactivity config
28
+ */
29
+
30
+ /**
31
+ * @typedef {Object} ChoreographySpec
32
+ * @property {string} id - Choreography ID
33
+ * @property {string} name - Choreography name
34
+ * @property {number} duration_ms - Total duration
35
+ * @property {number|null} bpm - BPM for beat sync
36
+ * @property {number} scene_count - Number of scenes
37
+ * @property {ChoreographyScene[]} scenes - Scene array
38
+ */
39
+
40
+ /**
41
+ * Plays multi-scene VIB3+ choreographies.
42
+ *
43
+ * Manages the lifecycle of scenes: at each scene boundary, it switches
44
+ * the visualization system, sets geometry, loads per-scene timelines,
45
+ * applies color presets and post-processing, and handles transitions
46
+ * between scenes.
47
+ *
48
+ * @example
49
+ * const player = new ChoreographyPlayer(engine);
50
+ * player.load(choreographySpec);
51
+ * player.play();
52
+ *
53
+ * // Seek to 50%
54
+ * player.seekToPercent(0.5);
55
+ *
56
+ * // Pause / resume
57
+ * player.pause();
58
+ * player.play();
59
+ */
60
+ export class ChoreographyPlayer {
61
+ /**
62
+ * @param {Object} engine - VIB3Engine instance (or any object with
63
+ * setParameter, getParameter, switchSystem, getCurrentSystem methods)
64
+ * @param {Object} [options]
65
+ * @param {Function} [options.onSceneChange] - Callback(sceneIndex, scene) on scene transitions
66
+ * @param {Function} [options.onComplete] - Callback when choreography finishes (once mode)
67
+ * @param {Function} [options.onTick] - Callback(currentTime, totalDuration) each frame
68
+ */
69
+ constructor(engine, options = {}) {
70
+ if (!engine) {
71
+ throw new Error('ChoreographyPlayer requires a VIB3Engine instance');
72
+ }
73
+
74
+ /** @type {Object} */
75
+ this.engine = engine;
76
+
77
+ /** @type {ChoreographySpec|null} */
78
+ this.spec = null;
79
+
80
+ /** @type {boolean} */
81
+ this.playing = false;
82
+
83
+ /** @type {number} Current playback position in ms */
84
+ this.currentTime = 0;
85
+
86
+ /** @type {number} Playback speed multiplier */
87
+ this.playbackSpeed = 1.0;
88
+
89
+ /** @type {'once'|'loop'} */
90
+ this.loopMode = 'once';
91
+
92
+ /** @type {number} Index of currently active scene (-1 if none) */
93
+ this.activeSceneIndex = -1;
94
+
95
+ /** @type {ParameterTimeline|null} Current scene's timeline */
96
+ this._sceneTimeline = null;
97
+
98
+ /** @type {TransitionAnimator} Shared transition animator */
99
+ this._transitionAnimator = new TransitionAnimator(
100
+ (name, value) => this.engine.setParameter(name, value),
101
+ (name) => this.engine.getParameter?.(name) ?? 0
102
+ );
103
+
104
+ /** @type {number|null} requestAnimationFrame ID */
105
+ this._frameId = null;
106
+
107
+ /** @type {number} Last frame timestamp */
108
+ this._lastFrameTime = 0;
109
+
110
+ // Callbacks
111
+ this._onSceneChange = options.onSceneChange || null;
112
+ this._onComplete = options.onComplete || null;
113
+ this._onTick = options.onTick || null;
114
+ }
115
+
116
+ // ─────────────────────────────────────────────────────────────────────────
117
+ // Public API
118
+ // ─────────────────────────────────────────────────────────────────────────
119
+
120
+ /**
121
+ * Load a choreography specification.
122
+ *
123
+ * @param {ChoreographySpec} spec - Choreography data (from create_choreography MCP tool
124
+ * or parsed from choreography_json)
125
+ * @returns {boolean} true if loaded successfully
126
+ */
127
+ load(spec) {
128
+ if (!spec || !Array.isArray(spec.scenes) || spec.scenes.length === 0) {
129
+ console.warn('ChoreographyPlayer: Invalid spec — needs scenes array');
130
+ return false;
131
+ }
132
+
133
+ this.stop();
134
+
135
+ this.spec = {
136
+ id: spec.id || `choreo_${Date.now()}`,
137
+ name: spec.name || 'Untitled',
138
+ duration_ms: spec.duration_ms || this._inferDuration(spec.scenes),
139
+ bpm: spec.bpm || null,
140
+ scene_count: spec.scenes.length,
141
+ scenes: spec.scenes.map((s, i) => ({
142
+ index: s.index ?? i,
143
+ time_start: s.time_start ?? 0,
144
+ time_end: s.time_end ?? spec.duration_ms,
145
+ system: s.system || 'quantum',
146
+ geometry: s.geometry ?? 0,
147
+ transition_in: s.transition_in || { type: 'cut', duration: 0 },
148
+ tracks: s.tracks || {},
149
+ color_preset: s.color_preset || null,
150
+ post_processing: s.post_processing || [],
151
+ audio: s.audio || null
152
+ }))
153
+ };
154
+
155
+ // Sort scenes by start time
156
+ this.spec.scenes.sort((a, b) => a.time_start - b.time_start);
157
+
158
+ this.currentTime = 0;
159
+ this.activeSceneIndex = -1;
160
+
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Start or resume playback.
166
+ */
167
+ play() {
168
+ if (!this.spec) {
169
+ console.warn('ChoreographyPlayer: No choreography loaded');
170
+ return;
171
+ }
172
+
173
+ if (this.playing) return;
174
+
175
+ this.playing = true;
176
+ this._lastFrameTime = performance.now();
177
+
178
+ // Enter the current scene if not already in one
179
+ this._evaluateScene(this.currentTime);
180
+
181
+ this._tick();
182
+ }
183
+
184
+ /**
185
+ * Pause playback (maintains position).
186
+ */
187
+ pause() {
188
+ this.playing = false;
189
+ if (this._frameId !== null) {
190
+ cancelAnimationFrame(this._frameId);
191
+ this._frameId = null;
192
+ }
193
+ if (this._sceneTimeline) {
194
+ this._sceneTimeline.pause();
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Stop playback and reset to beginning.
200
+ */
201
+ stop() {
202
+ this.pause();
203
+ this.currentTime = 0;
204
+ this.activeSceneIndex = -1;
205
+ if (this._sceneTimeline) {
206
+ this._sceneTimeline.stop();
207
+ this._sceneTimeline = null;
208
+ }
209
+ this._transitionAnimator.cancelAll();
210
+ }
211
+
212
+ /**
213
+ * Seek to an absolute time position.
214
+ * @param {number} timeMs - Time in milliseconds
215
+ */
216
+ seek(timeMs) {
217
+ if (!this.spec) return;
218
+ this.currentTime = Math.max(0, Math.min(timeMs, this.spec.duration_ms));
219
+ this._evaluateScene(this.currentTime);
220
+ }
221
+
222
+ /**
223
+ * Seek to a percentage of the total duration.
224
+ * @param {number} percent - 0.0 to 1.0
225
+ */
226
+ seekToPercent(percent) {
227
+ if (!this.spec) return;
228
+ this.seek(Math.max(0, Math.min(1, percent)) * this.spec.duration_ms);
229
+ }
230
+
231
+ /**
232
+ * Get current playback state.
233
+ * @returns {Object} State summary
234
+ */
235
+ getState() {
236
+ const scene = this.spec?.scenes[this.activeSceneIndex] ?? null;
237
+ return {
238
+ playing: this.playing,
239
+ currentTime: this.currentTime,
240
+ duration: this.spec?.duration_ms ?? 0,
241
+ progress: this.spec ? this.currentTime / this.spec.duration_ms : 0,
242
+ activeScene: scene ? {
243
+ index: scene.index,
244
+ system: scene.system,
245
+ geometry: scene.geometry,
246
+ time_start: scene.time_start,
247
+ time_end: scene.time_end,
248
+ scene_progress: scene.time_end > scene.time_start
249
+ ? (this.currentTime - scene.time_start) / (scene.time_end - scene.time_start)
250
+ : 0
251
+ } : null,
252
+ sceneCount: this.spec?.scene_count ?? 0,
253
+ playbackSpeed: this.playbackSpeed
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Clean up resources.
259
+ */
260
+ destroy() {
261
+ this.stop();
262
+ this._transitionAnimator.destroy?.() || this._transitionAnimator.cancelAll();
263
+ this.spec = null;
264
+ }
265
+
266
+ // ─────────────────────────────────────────────────────────────────────────
267
+ // Internal
268
+ // ─────────────────────────────────────────────────────────────────────────
269
+
270
+ /**
271
+ * Main animation loop.
272
+ */
273
+ _tick() {
274
+ if (!this.playing) return;
275
+
276
+ const now = performance.now();
277
+ const delta = (now - this._lastFrameTime) * this.playbackSpeed;
278
+ this._lastFrameTime = now;
279
+
280
+ this.currentTime += delta;
281
+
282
+ // Handle end-of-choreography
283
+ if (this.currentTime >= this.spec.duration_ms) {
284
+ if (this.loopMode === 'loop') {
285
+ this.currentTime = this.currentTime % this.spec.duration_ms;
286
+ this.activeSceneIndex = -1; // Force re-evaluation
287
+ } else {
288
+ this.currentTime = this.spec.duration_ms;
289
+ this.playing = false;
290
+ if (this._onComplete) this._onComplete();
291
+ return;
292
+ }
293
+ }
294
+
295
+ // Evaluate which scene we should be in
296
+ this._evaluateScene(this.currentTime);
297
+
298
+ // Update scene timeline position (relative to scene start)
299
+ if (this._sceneTimeline && this._sceneTimeline.playing) {
300
+ const scene = this.spec.scenes[this.activeSceneIndex];
301
+ const sceneLocalTime = this.currentTime - scene.time_start;
302
+ this._sceneTimeline.seek(sceneLocalTime);
303
+ }
304
+
305
+ // Tick callback
306
+ if (this._onTick) {
307
+ this._onTick(this.currentTime, this.spec.duration_ms);
308
+ }
309
+
310
+ this._frameId = requestAnimationFrame(() => this._tick());
311
+ }
312
+
313
+ /**
314
+ * Determine which scene should be active at the given time,
315
+ * and transition if needed.
316
+ */
317
+ _evaluateScene(timeMs) {
318
+ if (!this.spec) return;
319
+
320
+ // Find the scene that contains this time
321
+ let targetIndex = -1;
322
+ for (let i = 0; i < this.spec.scenes.length; i++) {
323
+ const scene = this.spec.scenes[i];
324
+ if (timeMs >= scene.time_start && timeMs < scene.time_end) {
325
+ targetIndex = i;
326
+ break;
327
+ }
328
+ }
329
+
330
+ // If no scene found and we're at the very end, use the last scene
331
+ if (targetIndex === -1 && timeMs >= this.spec.duration_ms && this.spec.scenes.length > 0) {
332
+ targetIndex = this.spec.scenes.length - 1;
333
+ }
334
+
335
+ // Scene change needed?
336
+ if (targetIndex !== this.activeSceneIndex && targetIndex >= 0) {
337
+ this._enterScene(targetIndex);
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Enter a new scene — switch system, geometry, load timeline, apply presets.
343
+ */
344
+ async _enterScene(sceneIndex) {
345
+ const scene = this.spec.scenes[sceneIndex];
346
+ const previousIndex = this.activeSceneIndex;
347
+ this.activeSceneIndex = sceneIndex;
348
+
349
+ // Stop previous scene timeline
350
+ if (this._sceneTimeline) {
351
+ this._sceneTimeline.stop();
352
+ this._sceneTimeline = null;
353
+ }
354
+
355
+ // 1. Handle scene transition (crossfade, etc.)
356
+ const transition = scene.transition_in;
357
+ if (transition && transition.type !== 'cut' && transition.duration > 0 && previousIndex >= 0) {
358
+ // For non-cut transitions, we do a smooth crossfade via intensity
359
+ this._transitionAnimator.transition(
360
+ { intensity: 0 },
361
+ transition.duration / 2,
362
+ 'easeIn',
363
+ () => {
364
+ // Midpoint: switch system/geometry while faded out
365
+ this._applyCoreSceneState(scene);
366
+ this._transitionAnimator.transition(
367
+ { intensity: scene.tracks?.intensity?.[0]?.value ?? 0.5 },
368
+ transition.duration / 2,
369
+ 'easeOut'
370
+ );
371
+ }
372
+ );
373
+ } else {
374
+ // Cut: immediately apply
375
+ await this._applyCoreSceneState(scene);
376
+ }
377
+
378
+ // 2. Build and start per-scene ParameterTimeline
379
+ if (scene.tracks && Object.keys(scene.tracks).length > 0) {
380
+ const sceneDuration = scene.time_end - scene.time_start;
381
+ this._sceneTimeline = new ParameterTimeline(
382
+ (name, value) => this.engine.setParameter(name, value)
383
+ );
384
+ this._sceneTimeline.setDuration(sceneDuration);
385
+ this._sceneTimeline.setLoopMode('once');
386
+
387
+ if (this.spec.bpm) {
388
+ this._sceneTimeline.bpm = this.spec.bpm;
389
+ }
390
+
391
+ for (const [param, keyframes] of Object.entries(scene.tracks)) {
392
+ this._sceneTimeline.addTrack(param);
393
+ if (Array.isArray(keyframes)) {
394
+ for (const kf of keyframes) {
395
+ this._sceneTimeline.addKeyframe(
396
+ param,
397
+ kf.time ?? 0,
398
+ kf.value ?? 0,
399
+ kf.easing || 'easeInOut'
400
+ );
401
+ }
402
+ }
403
+ }
404
+
405
+ // Seek to the correct position within the scene
406
+ const sceneLocalTime = this.currentTime - scene.time_start;
407
+ this._sceneTimeline.seek(Math.max(0, sceneLocalTime));
408
+ if (this.playing) {
409
+ this._sceneTimeline.play();
410
+ }
411
+ }
412
+
413
+ // 3. Notify callback
414
+ if (this._onSceneChange) {
415
+ this._onSceneChange(sceneIndex, scene);
416
+ }
417
+ }
418
+
419
+ /**
420
+ * Apply the core state of a scene: system, geometry, color preset.
421
+ */
422
+ async _applyCoreSceneState(scene) {
423
+ // Switch system if different
424
+ const currentSystem = this.engine.getCurrentSystem?.() || this.engine.currentSystemName;
425
+ if (scene.system && scene.system !== currentSystem) {
426
+ if (this.engine.switchSystem) {
427
+ await this.engine.switchSystem(scene.system);
428
+ }
429
+ }
430
+
431
+ // Set geometry
432
+ if (scene.geometry !== undefined) {
433
+ this.engine.setParameter('geometry', scene.geometry);
434
+ }
435
+
436
+ // Apply color preset (simplified — maps preset name to hue/sat/intensity)
437
+ if (scene.color_preset) {
438
+ const colors = ChoreographyPlayer.COLOR_PRESET_MAP[scene.color_preset];
439
+ if (colors) {
440
+ this.engine.setParameter('hue', colors.hue);
441
+ this.engine.setParameter('saturation', colors.saturation);
442
+ this.engine.setParameter('intensity', colors.intensity);
443
+ }
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Infer total duration from scene end times.
449
+ */
450
+ _inferDuration(scenes) {
451
+ return Math.max(...scenes.map(s => s.time_end || 0), 10000);
452
+ }
453
+
454
+ /**
455
+ * Color preset lookup (matches MCPServer.applyColorPreset).
456
+ */
457
+ static COLOR_PRESET_MAP = {
458
+ Ocean: { hue: 200, saturation: 0.8, intensity: 0.6 },
459
+ Lava: { hue: 15, saturation: 0.9, intensity: 0.8 },
460
+ Neon: { hue: 300, saturation: 1.0, intensity: 0.9 },
461
+ Monochrome: { hue: 0, saturation: 0.0, intensity: 0.6 },
462
+ Sunset: { hue: 30, saturation: 0.85, intensity: 0.7 },
463
+ Aurora: { hue: 140, saturation: 0.7, intensity: 0.6 },
464
+ Cyberpunk: { hue: 280, saturation: 0.9, intensity: 0.8 },
465
+ Forest: { hue: 120, saturation: 0.6, intensity: 0.5 },
466
+ Desert: { hue: 40, saturation: 0.5, intensity: 0.7 },
467
+ Galaxy: { hue: 260, saturation: 0.8, intensity: 0.4 },
468
+ Ice: { hue: 190, saturation: 0.5, intensity: 0.8 },
469
+ Fire: { hue: 10, saturation: 1.0, intensity: 0.9 },
470
+ Toxic: { hue: 100, saturation: 0.9, intensity: 0.7 },
471
+ Royal: { hue: 270, saturation: 0.7, intensity: 0.5 },
472
+ Pastel: { hue: 330, saturation: 0.3, intensity: 0.8 },
473
+ Retro: { hue: 50, saturation: 0.7, intensity: 0.6 },
474
+ Midnight: { hue: 240, saturation: 0.6, intensity: 0.3 },
475
+ Tropical: { hue: 160, saturation: 0.8, intensity: 0.7 },
476
+ Ethereal: { hue: 220, saturation: 0.4, intensity: 0.7 },
477
+ Volcanic: { hue: 5, saturation: 0.95, intensity: 0.6 },
478
+ Holographic: { hue: 180, saturation: 0.6, intensity: 0.8 },
479
+ Vaporwave: { hue: 310, saturation: 0.7, intensity: 0.7 }
480
+ };
481
+ }
@@ -57,10 +57,9 @@ export class TradingCardManager {
57
57
 
58
58
  // Dynamic import based on system - USE EXACT GENERATORS THAT MATCH ENGINE VISUALS
59
59
  const generatorMap = {
60
- 'faceted': () => import('./FacetedCardGeneratorExact.js'),
61
- 'quantum': () => import('./QuantumCardGeneratorExact.js'),
62
- 'holographic': () => import('./HolographicCardGeneratorMultiLayer.js'),
63
- 'polychora': () => import('./PolychoraCardGenerator.js')
60
+ 'faceted': () => import('./FacetedCardGenerator.js'),
61
+ 'quantum': () => import('./QuantumCardGenerator.js'),
62
+ 'holographic': () => import('./HolographicCardGenerator.js')
64
63
  };
65
64
 
66
65
  const importFunction = generatorMap[system];