  // ----------------------------------------------------
    // --- JS 动态效果 (电路板背景) ---
    // ----------------------------------------------------
    const canvas = document.getElementById('circuit-board-canvas');
    const ctx = canvas.getContext('2d');
    
    // 配置参数
    const initialCircuitAlpha = 0.05; 
    const targetCircuitAlpha = 0.2; 
    const revealSpeed = 0.005; 
    const whiteGlowColor = 'rgba(255, 255, 255, 1)';
    const streamColor = 'rgba(255, 140, 0, 0.8)';
    const streamFadeSpeed = 0.01;
    const streamInitialLife = 200;
    const lineDensity = 40; 
    window.lines = []; 
    window.particles = []; 
    const particleCount = 50; 
    window.fiberParticles = [];
    const fiberSourceX = 50;
    const fiberSourceY = 50;
    const fiberCount = 30;
    const fiberMaxLife = 120;
    const fiberSpeed = 1.5;
    const fiberMaxLength = 50;
    
    // --- 流星/全屏数据流粒子 ---
    window.meteorParticles = [];
    const meteorCount = 12; 
    const meteorMaxLife = 150;
    const meteorMinSpeed = 4;
    const meteorMaxSpeed = 7;
    const meteorTrailLengthFactor = 15; 

    // 数据流粒子起始位置计算函数 (确保粒子从边界外开始，用于 Stream 和 Meteor)
    function getStreamStartPos() {
        const offScreenOffset = 100; 
        let startX, startY;
        // 50% 几率从左侧开始，50% 几率从顶部开始
        if (Math.random() < 0.5) { 
            // 从左侧开始 (向右下方移动)
            startX = -offScreenOffset - Math.random() * 100; 
            startY = Math.random() * (canvas.height + offScreenOffset) - offScreenOffset;
        } else {
            // 从顶部开始 (向右下方移动)
            startX = Math.random() * (canvas.width + offScreenOffset) - offScreenOffset;
            startY = -offScreenOffset - Math.random() * 100;
        }
        return { x: startX, y: startY };
    }
    
    // 调整 Canvas 尺寸
    function resizeCanvas() {
        canvas.width = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
        if(window.lines) initLines();
        if(window.particles) initParticles();
        if(window.streamParticles) initStreamParticles();
        if(window.fiberParticles) initFiberParticles();
        if(window.meteorParticles) initMeteorParticles();
    }
    
    // 初始化网格线
    function initLines() {
        lines.length = 0;
        const cols = Math.floor(canvas.width / lineDensity);
        const rows = Math.floor(canvas.height / lineDensity);
        for (let i = 0; i < cols; i++) {
            for (let j = 0; j < rows; j++) {
                const x = i * lineDensity + lineDensity / 2;
                const y = j * lineDensity + lineDensity / 2;
                if (Math.random() > 0.3) { 
                    lines.push({
                        x: x, 
                        y: y, 
                        direction: Math.floor(Math.random() * 5), 
                        currentAlpha: initialCircuitAlpha, 
                        glow: Math.random() > 0.97 ? { life: 150, speed: Math.random() * 0.5 + 0.2, angle: Math.random() * Math.PI * 2 } : null 
                    });
                }
            }
        }
    }
    
    // 初始化漂浮粒子
    function initParticles() {
        particles.length = 0;
        for (let i = 0; i < particleCount; i++) {
            particles.push({
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                radius: Math.random() * 2 + 1,
                speedX: (Math.random() - 0.5) * 0.4,
                speedY: (Math.random() - 0.5) * 0.4,
                alpha: Math.random() * 0.5 + 0.2 
            });
        }
    }

    // 初始化数据流粒子 (橙色)
    function initStreamParticles() {
        window.streamParticles = [];
        const streamCount = 50; 
        for (let i = 0; i < streamCount; i++) {
            const pos = getStreamStartPos(); 
            window.streamParticles.push({
                x: pos.x, 
                y: pos.y, 
                radius: Math.random() * 2 + 1,
                speedX: Math.random() * 2 + 0.5,
                speedY: Math.random() * 2 + 0.5,
                life: Math.random() * streamInitialLife
            });
        }
    }
    
    // 初始化流星粒子 (白色拖尾效果)
    function initMeteorParticles() {
        window.meteorParticles.length = 0;
        for (let i = 0; i < meteorCount; i++) {
            const pos = getStreamStartPos();
            
            // 随机方向和速度，保证向右下方移动
            const angle = Math.random() * (Math.PI / 4) + (Math.PI / 8); 
            const speed = Math.random() * (meteorMaxSpeed - meteorMinSpeed) + meteorMinSpeed;
            
            window.meteorParticles.push({
                x: pos.x,
                y: pos.y,
                speedX: Math.cos(angle) * speed,
                speedY: Math.sin(angle) * speed,
                life: Math.random() * meteorMaxLife,
                maxLife: meteorMaxLife,
            });
        }
    }
    
    // 初始化纤维光束粒子 (白色，来自左上角)
    function initFiberParticles() {
        window.fiberParticles = [];
        for (let i = 0; i < fiberCount; i++) {
            window.fiberParticles.push({
                x: fiberSourceX,
                y: fiberSourceY,
                angle: Math.random() * Math.PI / 2 + Math.PI / 4, 
                life: Math.random() * fiberMaxLife,
                maxLife: fiberMaxLife,
                length: Math.random() * fiberMaxLength + 10,
                speed: Math.random() * fiberSpeed + 0.5
            });
        }
    }

    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    
    initStreamParticles();
    initFiberParticles();
    initMeteorParticles(); 
    
    // 绘制循环
    function drawCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // 用于判断粒子是否移出屏幕
        const maxOut = Math.max(canvas.width, canvas.height) * 1.2;
        
        // 1. 绘制网格线和节点
        lines.forEach(line => {
            const x = line.x;
            const y = line.y;
            
            // 逐渐显示网格
            if (line.currentAlpha < targetCircuitAlpha) {
                line.currentAlpha += revealSpeed;
            } 
            if (line.currentAlpha > targetCircuitAlpha) {
                line.currentAlpha = targetCircuitAlpha;
            }
            const lineAlpha = line.currentAlpha;
            
            ctx.strokeStyle = `rgba(255, 255, 255, ${lineAlpha})`;
            ctx.lineWidth = 1;
            ctx.fillStyle = `rgba(255, 255, 255, ${lineAlpha})`;
            ctx.shadowBlur = 0;
            ctx.globalAlpha = 1;
            
            // 绘制节点
            ctx.beginPath();
            ctx.arc(x, y, 1, 0, Math.PI * 2);
            ctx.fill();
            
            // 绘制连线
            ctx.beginPath();
            ctx.moveTo(x, y);
            if (line.direction === 1) { 
                ctx.lineTo(x, y - lineDensity);
            } else if (line.direction === 2) { 
                ctx.lineTo(x + lineDensity, y);
            }
            ctx.stroke();
            
            // 绘制发光粒子
            if (line.glow) {
                const glow = line.glow;
                if (glow.life > 0) {
                    glow.x = (glow.x || x) + Math.cos(glow.angle) * glow.speed;
                    glow.y = (glow.y || y) + Math.sin(glow.angle) * glow.speed;
                    glow.life--;
                    ctx.save();
                    ctx.fillStyle = whiteGlowColor;
                    ctx.shadowBlur = 25;
                    ctx.shadowColor = whiteGlowColor;
                    ctx.globalAlpha = glow.life / 150;
                    ctx.beginPath();
                    ctx.arc(glow.x, glow.y, 3, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.restore();
                } else {
                    if (Math.random() > 0.995) { 
                        line.glow = { life: 150, speed: Math.random() * 0.5 + 0.2, angle: Math.random() * Math.PI * 2 };
                    } else {
                        line.glow = null;
                    }
                }
            }
        });

        // 2. 绘制数据流粒子 (Orange Dots)
        window.streamParticles.forEach(s => {
            s.x += s.speedX;
            s.y += s.speedY;
            s.life -= streamFadeSpeed * streamInitialLife; 

            // 粒子移出边界或生命周期结束，重新初始化
            if (s.x > canvas.width + maxOut || s.y > canvas.height + maxOut || s.life <= 0) {
                const pos = getStreamStartPos();
                s.x = pos.x;
                s.y = pos.y;
                s.life = streamInitialLife;
            }

            // 绘制粒子
            ctx.save();
            ctx.fillStyle = streamColor;
            ctx.shadowBlur = 15;
            ctx.shadowColor = streamColor;
            ctx.globalAlpha = (s.life / streamInitialLife) * 0.8; 
            ctx.beginPath();
            ctx.arc(s.x, s.y, s.radius, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();
        });
        
        // 2.5. 绘制流星粒子 (White Meteor/Shooting Star)
        window.meteorParticles.forEach(m => {
            
            // 粒子移动
            m.x += m.speedX;
            m.y += m.speedY;
            m.life--;
            
            // 重新初始化（移出边界或生命周期结束）
            if (m.x > canvas.width + maxOut || m.y > canvas.height + maxOut || m.life <= 0) {
                const pos = getStreamStartPos();
                // 重置起始点和生命周期
                m.x = pos.x;
                m.y = pos.y;
                m.life = m.maxLife; 
            }

            // 绘制拖尾效果 (Line/Streak)
            ctx.save();
            ctx.shadowBlur = 15;
            ctx.shadowColor = whiteGlowColor;
            
            // 透明度随生命值变化
            ctx.globalAlpha = (m.life / m.maxLife) * 0.9; 
            
            // 计算拖尾起点
            const startX = m.x - m.speedX * meteorTrailLengthFactor;
            const startY = m.y - m.speedY * meteorTrailLengthFactor;
            
            ctx.lineWidth = 1.5; 
            ctx.strokeStyle = whiteGlowColor;
            ctx.lineCap = 'round';
            
            // 绘制拖尾线
            ctx.beginPath();
            ctx.moveTo(startX, startY);
            ctx.lineTo(m.x, m.y);
            ctx.stroke();

            // 绘制粒子头部 (点)
            ctx.fillStyle = whiteGlowColor;
            ctx.beginPath();
            ctx.arc(m.x, m.y, 1.5, 0, Math.PI * 2);
            ctx.fill();
            
            ctx.restore();
        });
        
        // 3. 绘制纤维光束 (White, 来自左上角)
        window.fiberParticles.forEach(fp => {
            fp.life--;

            if (fp.life <= 0) {
                // 重新生成
                fp.x = fiberSourceX;
                fp.y = fiberSourceY;
                fp.angle = Math.random() * Math.PI / 2 + Math.PI / 4; 
                fp.life = fiberMaxLife;
                fp.maxLife = fiberMaxLife;
                fp.length = Math.random() * fiberMaxLength + 10;
                fp.speed = Math.random() * fiberSpeed + 0.5;
            }

            const currentLength = fp.length * (1 - fp.life / fp.maxLife);
            const endX = fp.x + Math.cos(fp.angle) * currentLength;
            const endY = fp.y + Math.sin(fp.angle) * currentLength;

            ctx.save();
            ctx.strokeStyle = whiteGlowColor;
            ctx.lineWidth = 1.5;
            ctx.shadowBlur = 10;
            ctx.shadowColor = whiteGlowColor;
            ctx.globalAlpha = fp.life / fp.maxLife;
            ctx.beginPath();
            ctx.moveTo(fp.x, fp.y);
            ctx.lineTo(endX, endY);
            ctx.stroke();
            ctx.restore();

            fp.x += Math.cos(fp.angle) * fp.speed;
            fp.y += Math.sin(fp.angle) * fp.speed;
        });

        // 4. 绘制漂浮粒子 (White Dots)
        particles.forEach(p => {
            p.x += p.speedX;
            p.y += p.speedY;

            // 边界循环
            if (p.x < 0 || p.x > canvas.width) p.speedX *= -1;
            if (p.y < 0 || p.y > canvas.height) p.speedY *= -1;
            
            ctx.fillStyle = `rgba(255, 255, 255, ${p.alpha})`;
            ctx.beginPath();
            ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
            ctx.fill();
        });

        requestAnimationFrame(drawCanvas);
    }
    drawCanvas();
    
    // ----------------------------------------------------
    // --- THREE.JS 3D CUBE LOGIC ---
    // ----------------------------------------------------

    function createLabelTexture(text, type) {
        const canvas = document.createElement('canvas');
        canvas.width = 512; 
        canvas.height = 512;
        const ctx = canvas.getContext('2d');
        
        // 渐变背景
        const grd = ctx.createLinearGradient(0,0,512,512);
        grd.addColorStop(0, '#FF8C00');
        grd.addColorStop(1, '#ff7b00');
        ctx.fillStyle = grd;
        ctx.fillRect(0,0,512,512);

        // Tech Border
        ctx.strokeStyle = 'rgba(255,255,255,0.8)';
        ctx.lineWidth = 15;
        ctx.strokeRect(20,20,472,472);

        // 绘制图标 (相对 256, 256 中心)
        ctx.save();
        
        // 图标位置调整：向上移动 50px，为文字留出空间
        ctx.translate(256, 256 - 50); 
        
        // 图标大小调整：缩小到 70%
        const iconScale = 0.7; 
        ctx.scale(iconScale, iconScale); 
        
        // 所有图标绘制代码保持原有坐标，由上面的 translate 和 scale 进行调整

        if (type === 'production') {
            ctx.fillStyle = 'rgba(255,255,255,0.9)';
            ctx.fillRect(-80, -80, 30, 40);
            ctx.fillRect(-30, -60, 30, 60);
            ctx.fillRect(20, -40, 30, 40);
        } else if (type === 'data') {
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth = 8;
            ctx.beginPath();
            ctx.arc(0, 0, 80, 0, Math.PI * 2);
            ctx.stroke();
            
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.arc(0, 0, 80, 0, Math.PI * 1.5);
            ctx.fillStyle = '#ffffff';
            ctx.fill();
            
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.arc(0, 0, 80, Math.PI * 1.5, Math.PI * 2);
            ctx.fillStyle = 'rgba(255,255,255,0.6)';
            ctx.fill();

        } else if (type === 'logistics') { 
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth = 8;
            ctx.setLineDash([15, 10]);
            ctx.beginPath();
            ctx.moveTo(-80, 20);
            ctx.quadraticCurveTo(-20, -60, 80, 20);
            ctx.stroke();
            ctx.setLineDash([]);
            ctx.fillStyle = '#ffffff';
            ctx.beginPath();
            ctx.arc(-80, 20, 10, 0, Math.PI*2);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(80, 20, 10, 0, Math.PI*2);
            ctx.fill();
        } else if (type === 'order') { 
            ctx.fillStyle = 'rgba(255,255,255,0.9)';
            ctx.fillRect(-60, -60, 120, 140);
            ctx.fillStyle = '#ff7b00';
            ctx.fillRect(-40, -40, 80, 10);
            ctx.fillRect(-40, -10, 80, 10);
            ctx.fillRect(-40, 20, 50, 10);
        } else if (type === 'customer') { 
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth = 6;
            ctx.beginPath();
            ctx.arc(0, 0, 50, 0, Math.PI*2);
            ctx.stroke();
            ctx.fillStyle = '#ffffff';
            ctx.beginPath();
            ctx.arc(-20, -15, 6, 0, Math.PI*2);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(20, -15, 6, 0, Math.PI*2);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(0, 5, 30, 0.2, Math.PI - 0.2);
            ctx.stroke();
        } else if (type === 'core') { 
            ctx.fillStyle = '#ffffff';
            ctx.beginPath();
            ctx.arc(0, 0, 25, 0, Math.PI*2);
            ctx.fill();
            ctx.strokeStyle = 'rgba(255,255,255,0.8)';
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(-50, -50);
            ctx.lineTo(50, 50);
            ctx.moveTo(-50, 50);
            ctx.lineTo(50, -50);
            ctx.stroke();
        }
        
        ctx.restore(); // 恢复 context, 取消 scale 和 translate

        // 文字位置调整：增加距离
        const textOffset = 150; 
        ctx.font = 'Bold 60px Arial';
        ctx.fillStyle = 'white';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(text, 256, 256 + textOffset); 

        const texture = new THREE.CanvasTexture(canvas);
        return texture;
    }


    const cubeContainer = document.getElementById('three-cube-container');
    if (cubeContainer) {
        // 再次加大容器尺寸，避免正方体显示不全
        const width = 1000; 
        const height = 600;
        const cubeSize = 2.4; // 放大正方体尺寸，从1.6调整到2.4 

        // 1. 场景与相机设置
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000); // 增加视野角度到55度
        camera.position.set(0, 2, 8); // 向后移动相机，增加距离
        camera.lookAt(0, 1, 0); // 向下看一点，解决粒子顶部显示不完整的问题

        // 2. 渲染器设置
        const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
        renderer.setSize(width, height);
        renderer.setPixelRatio(window.devicePixelRatio);
        
        cubeContainer.appendChild(renderer.domElement);
        
        // --- 修复: 重新添加环境光，确保材质可见 ---
        const ambientLight = new THREE.AmbientLight(0xffffff, 1.0); 
        scene.add(ambientLight);

        // 3. 立方体几何体与材质
        const materials = [
            // 材质改为 MeshLambertMaterial，确保在有光照时能正常显示贴图
            new THREE.MeshLambertMaterial({ map: createLabelTexture('订单接收', 'order') }),    
            new THREE.MeshLambertMaterial({ map: createLabelTexture('生产管理', 'production') }), 
            new THREE.MeshLambertMaterial({ map: createLabelTexture('物流仓储', 'logistics') }),  
            new THREE.MeshLambertMaterial({ map: createLabelTexture('客户收货', 'customer') }),  
            new THREE.MeshLambertMaterial({ map: createLabelTexture('平台核心', 'core') }),      
            new THREE.MeshLambertMaterial({ map: createLabelTexture('数据分析', 'data') }),      
        ];
        const geometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
        const cube = new THREE.Mesh(geometry, materials);
        // 调整正方体位置到指定区域
        cube.position.x = 0; // 水平居中
        cube.position.y = 2; // 垂直方向适当位置
        scene.add(cube);
        
        // --- 模拟阴影的圆形平面 (Fake Shadow Plane) ---
        // 使用圆形平面模拟柔和的底部阴影，并添加高斯模糊效果
        const shadowRadius =1.5; // 放大阴影半径，从1.0调整到1.5
        const shadowGeo = new THREE.CircleGeometry(shadowRadius, 64); // 增加分段数，使阴影更平滑
        const shadowMat = new THREE.ShaderMaterial({
            uniforms: {
                color: { value: new THREE.Color(0x000000) },
                opacity: { value: 0.3 }, // 调整阴影强度
                blur: { value: 0.3 }, // 调整模糊程度以适应较小的阴影
                resolution: { value: new THREE.Vector2(width, height) }
            },
            vertexShader: `
                varying vec2 vUv;
                void main() {
                    vUv = uv;
                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
            `,
            fragmentShader: `
                uniform vec3 color;
                uniform float opacity;
                uniform float blur;
                uniform vec2 resolution;
                varying vec2 vUv;
                
                float gaussian(float x, float sigma) {
                    return exp(-(x * x) / (2.0 * sigma * sigma)) / (sqrt(2.0 * 3.14159) * sigma);
                }
                
                void main() {
                    // 计算到中心的距离
                    vec2 center = vec2(0.5, 0.5);
                    float distanceToCenter = length(vUv - center);
                    
                    // 圆形裁剪
                    float circle = smoothstep(0.5, 0.5 - blur * 0.5, distanceToCenter);
                    
                    // 高斯模糊效果 - 调整参数以适应较小的阴影
                    float blurFactor = gaussian(distanceToCenter - 0.25, blur);
                    float alpha = opacity * blurFactor * circle;
                    
                    gl_FragColor = vec4(color, alpha);
                }
            `,
            transparent: true,
            side: THREE.DoubleSide,
            depthWrite: false // 禁用深度写入，避免阴影遮挡其他物体
        });
        const shadowPlane = new THREE.Mesh(shadowGeo, shadowMat);
        shadowPlane.rotation.x = -Math.PI / 2; // 平放
        shadowPlane.position.x = cube.position.x;
        shadowPlane.position.y = cube.position.y - cubeSize / 2 - 0.1; // 位于立方体底部下方
        shadowPlane.position.z = cube.position.z;
        scene.add(shadowPlane);
        // ------------------------------------------------

        
        // --- 4. 数据流环 (Data Flow Rings) ---
        const flowParticles = [];
        const packetCount = 10; // 每个环上的数据包数量

        function createDataFlowRing(radius, colorHex, attachedToCube, flowSpeed, yRotation = 0) {
            const color = new THREE.Color(colorHex);
            const ringGroup = new THREE.Group();
            ringGroup.rotation.x = Math.PI / 2; // XZ平面环
            ringGroup.rotation.y = yRotation; 

            // A. 虚线路径 (The Path)
            const lineGeo = new THREE.TorusGeometry(radius, 0.005, 16, 100);
            const edges = new THREE.EdgesGeometry(lineGeo); 
            
            const lineMat = new THREE.LineDashedMaterial({
                color: color,
                linewidth: 1.5,
                scale: 1,
                dashSize: 0.15, 
                gapSize: 0.15,  
                transparent: true,
                opacity: 0.5,
            });
            
            const line = new THREE.LineSegments(edges, lineMat);
            line.computeLineDistances(); 
            ringGroup.add(line);
            
            // B. 移动数据包 (Small Cubes) - 将粒子改为小正方体
            const packetData = [];
            const packetCubes = []; // 存储小正方体实例
            const cubeSize = 0.15; // 小正方体尺寸
            
            // 创建小正方体材质
            const packetMat = new THREE.MeshBasicMaterial({
                color: color,
                transparent: true,
                opacity: 1,
            });
            
            // 创建小正方体几何体，使用较小尺寸避免出界
            const particleCubeSize = 0.1; // 小正方体尺寸，从0.15调整到0.1
            const cubeGeo = new THREE.BoxGeometry(particleCubeSize, particleCubeSize, particleCubeSize);

            for (let i = 0; i < packetCount; i++) {
                const angle = (i / packetCount) * Math.PI * 2 + Math.random() * 0.5; 
                packetData.push({
                    angle: angle,
                    speed: flowSpeed * (Math.random() * 0.5 + 0.75), 
                    radius: radius,
                });
                
                // 初始位置计算
                const x = Math.cos(angle) * radius;
                const y = 0;
                const z = Math.sin(angle) * radius;
                
                // 创建小正方体
                const cube = new THREE.Mesh(cubeGeo, packetMat);
                cube.position.set(x, y, z);
                ringGroup.add(cube);
                packetCubes.push(cube);
            }
            
            if (attachedToCube) {
                cube.add(ringGroup);
            } else {
                scene.add(ringGroup);
            }
            
            flowParticles.push({
                group: ringGroup,
                lineMaterial: lineMat,
                packetCubes: packetCubes, // 存储小正方体数组
                packetData: packetData
            });
        }

        // 环 1 (白色数据流，与立方体一同旋转) - 半径 2.4
        createDataFlowRing(2.4, 0xFFFFFF, true, 0.5); 

        // 环 2 (蓝色数据流，与立方体一同旋转, 速度 -0.4) - 半径 3.0 (蓝色粒子加速已保留)
        createDataFlowRing(3.0, 0x3B82F6, true, -0.4, 0.5); 
        // ------------------------------------------------
        
        
        // 5. 添加鼠标交互控制
        let mouseX = 0;
        let isMouseDown = false;
        let mouseStartX = 0;
        let cubeStartRotationY = 0;
        
        // 获取背景图片元素
        const backgroundElement = document.querySelector('.baner-Imgbackground');
        
        // 鼠标按下事件
        if (backgroundElement) {
            backgroundElement.addEventListener('mousedown', (e) => {
                isMouseDown = true;
                mouseStartX = e.clientX;
                cubeStartRotationY = cube.rotation.y;
            });
            
            // 鼠标移动事件
            backgroundElement.addEventListener('mousemove', (e) => {
                mouseX = e.clientX;
                
                if (isMouseDown) {
                    // 计算鼠标移动距离
                    const deltaX = e.clientX - mouseStartX;
                    // 根据移动距离调整立方体旋转角度
                    cube.rotation.y = cubeStartRotationY + deltaX * 0.005;
                }
            });
            
            // 鼠标释放事件
            backgroundElement.addEventListener('mouseup', () => {
                isMouseDown = false;
            });
            
            // 鼠标离开背景图片事件
            backgroundElement.addEventListener('mouseleave', () => {
                isMouseDown = false;
            });
        }
        
        // 6. 动画循环
        let frameId;
        const animate = () => {
            // 立方体绕 Y 轴慢速自转（仅当鼠标未按下时）
            if (!isMouseDown) {
                cube.rotation.y += 0.004; 
            }
            
            // 更新阴影位置以跟随立方体
            shadowPlane.position.x = cube.position.x;
            shadowPlane.position.y = cube.position.y - cubeSize / 2 - 0.1;
            shadowPlane.position.z = cube.position.z;
            
            // 立方体绕 X 轴缓慢倾斜动画
            cube.rotation.x = Math.sin(Date.now() * 0.001) * 0.1 + 0.2; 
            
            // --- Data Flow Particle and Line Update (更新数据流粒子和虚线路径) ---
            flowParticles.forEach(flowGroup => {
                
                // 1. 虚线路径移动 (通过修改 dashOffset)
                flowGroup.lineMaterial.dashOffset -= 0.005; 
                
                // 2. 数据包移动 (Small Cubes Movement)
                const packetCubes = flowGroup.packetCubes;
                const packetData = flowGroup.packetData;
                
                for (let i = 0; i < packetData.length; i++) {
                    const p = packetData[i];
                    const cube = packetCubes[i];
                    
                    // 更新角度 (模拟数据流沿环运动)
                    p.angle += p.speed * 0.001; 
                    
                    // 计算新位置
                    const x = Math.cos(p.angle) * p.radius;
                    const z = Math.sin(p.angle) * p.radius;
                    
                    // 直接更新小正方体的位置
                    cube.position.x = x;
                    cube.position.z = z;
                    cube.position.y = 0; // 保持在同一平面
                }
            });
            // -----------------------------------------------------

            renderer.render(scene, camera);
            frameId = requestAnimationFrame(animate);
        };
        animate();

        // 6. 销毁逻辑（在页面卸载时清理动画帧）
        window.addEventListener('beforeunload', () => {
            cancelAnimationFrame(frameId);
            if(renderer.domElement.parentNode) {
                renderer.domElement.parentNode.removeChild(renderer.domElement);
            }
            renderer.dispose();
        });
    }

    // ----------------------------------------------------
    // --- 文本打字效果和列表交互 (保留) ---
    // ----------------------------------------------------
    
    function setupListInteractions() {
        const allItems = document.querySelectorAll('.feature-list li');

        allItems.forEach(item => {
            const dataIndex = item.getAttribute('data-index');
            
            const currentGroupElement = item.closest('.pain-points, .empowerment');
            if (!currentGroupElement) return;

            const isPainPoint = currentGroupElement.classList.contains('pain-points');
            
            const targetGroupClass = isPainPoint ? '.empowerment' : '.pain-points';

            const targetItem = document.querySelector(`${targetGroupClass} li[data-index='${dataIndex}']`);

            const toggleHighlight = (element, isEnter) => {
                if (element) {
                    element.classList.toggle('linked-hover', isEnter);
                    if (element.closest('.empowerment')) {
                        element.classList.toggle('hovered', isEnter);
                    }
                }
            };

            item.addEventListener('mouseenter', () => {
                toggleHighlight(item, true);
                toggleHighlight(targetItem, true);
            });

            item.addEventListener('mouseleave', () => {
                toggleHighlight(item, false);
                toggleHighlight(targetItem, false);
            });
        });
    }

    document.addEventListener('DOMContentLoaded', function() {
        setupListInteractions(); 
    });