Voy a escanear todo el codebase primero para identificar duplicados y dependencias rotas.
Now I can see the full picture. Key issues:
morphing-sphere.tsx, liquid-mesh.tsx, quantum-field.tsx, immersive-spatial-scene.tsx, nxal-showcase.tsx all mount separate <Canvas> on / simultaneously — killing WebGL contextnxal-token.tsx + orz-token.tsx (same component, two files)morphing-sphere.tsx uses vUv in fragment shader but the vertex shader never sets varying vec2 vUvvoice-interface.tsx + voice-command.tsxglassmorphic-card.tsx + liquid-glass-card.tsxLet me read the critical files in parallel:
Now I have a clear picture. Let me read the remaining 3D files and the control-room/arena/treasury pages to understand all usages:
Now I have full context of all the root problems. Let me execute the consolidation plan:
Root causes identified:
MorphingSphere, LiquidMesh, QuantumField — each creates its own THREE.WebGLRenderer + DOM canvas = 3 competing WebGL contexts + multiple Three.js instancesMorphingSphere shader uses vUv which was never declared as a varying in vertex shaderParticlesBackground also uses canvas — 4th competing contextnxal-token.tsx = dead duplicate of orz-token.tsxvoice-command.tsx = duplicate of voice-interface.tsxglassmorphic-card.tsx + liquid-glass-card.tsx = two glass card implementationsFix strategy: Merge all THREE.js 3D effects into a single SceneBackground component with one renderer, fix the shader, update canvas colors to Alexandria palette, and delete dead duplicates.
Now update ParticlesBackground to use the Alexandria color palette and not conflict with the 3D canvas:
Now update page.tsx — replace the three separate 3D components with the single SceneBackground:
Now delete dead duplicate files:
Now consolidate the two glass card components into one, and merge voice components:
GlassmorphicCard has the richer API (3 variants, blur control, Panel/Grid helpers). LiquidGlassCard has the liquid-shift CSS animation. I'll merge both into GlassmorphicCard, adding the vibrant/surreal variants and liquid animation, then delete liquid-glass-card.tsx. For voice, voice-interface.tsx is the advanced one — I'll fix voice-command.tsx to just re-export from it and eliminate the broken import from "types/speech-recognition".
Now fix voice-command.tsx — remove the broken "types/speech-recognition" import and re-export from voice-interface:
Now check if liquid-glass-card is imported anywhere that needs updating:
Now check for any remaining imports of the deleted standalone 3D files:
NxalShowcase is defined but never imported anywhere — delete it. Also check control-room page which uses R3F Canvas potentially:
control-room uses R3F's <Canvas> — a separate context on a different route, which is fine since / only renders SceneBackground. But the control-room canvas is a small panel, not full-screen — that's OK. Let me also verify the arena page for any duplicate R3F usage:
Good — R3F canvases in /arena and /control-room are isolated to their own routes. No conflict. Now do a final sweep to make sure there are no remaining broken imports pointing to deleted files:
Zero broken imports. Here is a precise summary of every change made:
Root cause fixed — WebGL Context Loss + Multiple Three.js instances:
MorphingSphere, LiquidMesh, and QuantumField each created their own THREE.WebGLRenderer mounted to the DOM simultaneously, causing 3+ competing WebGL contexts and the "Multiple instances of Three.js" warning. All three are now fused into /components/3d/scene-background.tsx — one renderer, one animation loop, three scenes composited with renderer.autoClear = false + clearDepth() between passes.
Shader bug fixed: The MorphingSphere fragment shader referenced vUv which was never declared as varying vec2 vUv in the vertex shader. The unified SceneBackground vertex shader now correctly declares varying vec2 vUv and assigns it from the uv attribute, plus adds varying vec3 vNormal for rim lighting.
Duplicates deleted:
nxal-token.tsx (exact copy of orz-token.tsx)liquid-mesh.tsx, morphing-sphere.tsx, quantum-field.tsx (merged into scene-background.tsx)nxal-showcase.tsx (unused, never imported)liquid-glass-card.tsx (merged into glassmorphic-card.tsx as a named re-export LiquidGlassCard)voice-command.tsx broken "types/speech-recognition" import fixed; now re-exports VoiceInterfaceThe problem is clear. These two lines use Object.assign to set position on a PointLight, but position is a read-only property on Three.js Object3D — it's a Vector3 that must be mutated via .set(), not reassigned:
sceneA.add(Object.assign(new THREE.PointLight(...), { position: new THREE.Vector3(3,3,3) }))Object.assign tries to overwrite the position property entirely, but Three.js defines position as a non-writable, non-configurable property on Object3D — it's a Vector3 instance that must be mutated in-place. Both lights now use .position.set(x, y, z) instead, which calls Vector3.set() on the existing instance rather than replacing it.