<!-- SOLIDIVISM-STAGING · part 3 -->
 group.add(legR);

    // THIGH PLATES: armor
    const thighGeo = new THREE.BoxGeometry(0.4, 0.5, 0.35);
    const thighL = new THREE.Mesh(thighGeo, armorMat);
    thighL.position.set(-0.32, 0.9, 0.1);
    group.add(thighL);
    const thighR = new THREE.Mesh(thighGeo, armorMat);
    thighR.position.set(0.32, 0.9, 0.1);
    group.add(thighR);

    // HELMET: sphere (armor)
    const helmGeo = new THREE.SphereGeometry(0.5, 16, 12);
    const helmet = new THREE.Mesh(helmGeo, armorMat);
    helmet.position.y = 2.85;
    group.add(helmet);
    avatarParts.helmet = helmet;

    // VISOR: glowing slit — the "face" (highest payoff detail)
    const visorGeo = new THREE.BoxGeometry(0.65, 0.14, 0.2);
    const visor = new THREE.Mesh(visorGeo, glowMat);
    visor.position.set(0, 2.88, 0.38);
    group.add(visor);
    avatarParts.visor = visor;

    // HELMET FIN: rear silhouette signature (third-person camera sees back)
    const finGeo = new THREE.BoxGeometry(0.08, 0.5, 0.4);
    const fin = new THREE.Mesh(finGeo, armorMat);
    fin.position.set(0, 3.15, -0.35);
    fin.rotation.x = -0.3;
    group.add(fin);

    // BACKPACK: box with glowing exhaust (rear view design)
    const packGeo = new THREE.BoxGeometry(0.7, 0.9, 0.35);
    const pack = new THREE.Mesh(packGeo, suitMat);
    pack.position.set(0, 1.8, -0.5);
    group.add(pack);

    const exhaustGeo = new THREE.CylinderGeometry(0.08, 0.12, 0.15, 8);
    const exhaust = new THREE.Mesh(exhaustGeo, glowMat);
    exhaust.position.set(0, 1.35, -0.5);
    group.add(exhaust);
    avatarParts.exhaust = exhaust;

    group.position.set(0, 0, 58); // Behind FORGE building (back face at z=53)
    group.rotation.y = Math.PI; // Face -z (building's back, toward center)
    scene.add(group);
    player = group;
  }

  // ── IDLE ANIMATION: alive, not mannequin ──
  function updateAvatar(dt) {
    if (!player) return;
    avatarTime += dt;
    // Body faces camera direction (back to camera, standard third-person)
    // camYaw defines camera orbit; player faces opposite (away from camera)
    const targetRotY = Math.atan2(Math.sin(camYaw), Math.cos(camYaw)) + Math.PI;
    // Smooth turn
    let diff = targetRotY - player.rotation.y;
    while (diff > Math.PI) diff -= Math.PI * 2;
    while (diff < -Math.PI) diff += Math.PI * 2;
    player.rotation.y += diff * 0.15;
    const t = avatarTime;
    // Breathing bob
    player.position.y = Math.sin(t * 2) * 0.03;
    // Head scan (slow yaw)
    if (avatarParts.helmet) {
      avatarParts.helmet.rotation.y = Math.sin(t * 0.4) * 0.25;
    }
    // Visor pulse (glow as life)
    if (avatarParts.visor) {
      const m = avatarParts.visor.material;
      m.emissiveIntensity = 2.2 + Math.sin(t * 3) * 0.6;
    }
    // Emblem pulse (synced, offset)
    if (avatarParts.emblem) {
      const m = avatarParts.emblem.material;
      m.emissiveIntensity = 2.0 + Math.sin(t * 3 + 1) * 0.5;
    }
    // Subtle arm sway
    if (avatarParts.armL) avatarParts.armL.rotation.x = Math.sin(t * 2) * 0.05;
    if (avatarParts.armR) avatarParts.armR.rotation.x = Math.sin(t * 2 + Math.PI) * 0.05;
  }

  // ── DOOR TEXTURE: Visible entrance on front face ──
  function createDoorTexture(label) {
    const c = document.createElement('canvas');
    c.width = 256; c.height = 256;
    const x = c.getContext('2d');

    // Same black armor base
    x.fillStyle = '#0a0a0c';
    x.fillRect(0, 0, 256, 256);

    // Panel grid (subtle)
    x.strokeStyle = '#1e1e24';
    x.lineWidth = 2;
    for (let i = 0; i <= 256; i += 32) {
      x.beginPath(); x.moveTo(i, 0); x.lineTo(i, 256); x.stroke();
      x.beginPath(); x.moveTo(0, i); x.lineTo(256, i); x.stroke();
    }

    // THE DOOR: large central rectangle with glowing frame
    const dw = 100, dh = 180;
    const dx = (256 - dw) / 2, dy = 256 - dh - 10;

    // Door frame (bright red glow)
    x.fillStyle = '#FF0000';
    x.fillRect(dx - 6, dy - 6, dw + 12, dh + 12);

    // Door itself (dark with red edge light)
    x.fillStyle = '#1a0505';
    x.fillRect(dx, dy, dw, dh);

    // Door split line (double doors)
    x.strokeStyle = '#FF0000';
    x.lineWidth = 3;
    x.beginPath(); x.moveTo(128, dy); x.lineTo(128, dy + dh); x.stroke();

    // Door horizontal panels
    x.strokeStyle = '#660000';
    x.lineWidth = 2;
    for (let py = dy + 40; py < dy + dh; py += 40) {
      x.beginPath(); x.moveTo(dx, py); x.lineTo(dx + dw, py); x.stroke();
    }

    // "ENTRANCE" label above door
    x.fillStyle = '#FF0000';
    x.font = 'bold 16px monospace';
    x.textAlign = 'center';
    x.fillText('▼ ENTRANCE ▼', 128, dy - 16);

    // Building label at top
    if (label) {
      x.fillStyle = '#FFFFFF';
      x.font = 'bold 20px monospace';
      x.fillText(label.substring(0, 12).toUpperCase(), 128, 30);
    }

    // Red corner brackets
    x.strokeStyle = '#FF0000';
    x.lineWidth = 6;
    const B = 8, L = 36;
    x.beginPath(); x.moveTo(B, B+L); x.lineTo(B, B); x.lineTo(B+L, B); x.