<!-- SAGA2 · part 69 -->
d) avatarGrp.userData.pulseT = 0;
    avatarGrp.userData.pulseT += 0.016;
    var pulse = 0.75+Math.sin(avatarGrp.userData.pulseT*2.5)*0.25;
    if(avatarGrp.userData.lineMats){
      avatarGrp.userData.lineMats[1].opacity = 0.7+pulse*0.3; // gold breathes
      avatarGrp.userData.lineMats[0].opacity = 0.65+pulse*0.25; // cyan follows
    }
    // mandala — the pure linework breathes
    // (halo removed)
    if(avatarGrp.userData.reticle){
      avatarGrp.userData.reticle.rotation.z = t*0.3;
      var rs = 1+Math.sin(t*2)*0.05;
      avatarGrp.userData.reticle.scale.set(rs, rs, 1);
    }

    if(avatarGrp.userData.antTip){
      avatarGrp.userData.antTip.material.color.setHex(Math.sin(t*5)>0?0x44ccff:0x226688);
    }
    // subtle breathing
    avatarGrp.position.y = -16 + Math.sin(t*1.5)*0.35;
  }

  var sp=40*dt, fx=-Math.sin(yaw), fz=-Math.cos(yaw), rx=Math.cos(yaw), rz=-Math.sin(yaw); // 6x slower
  if(keys['w']){camera.position.x+=fx*sp;camera.position.z+=fz*sp;}
  if(keys['s']){camera.position.x-=fx*sp;camera.position.z-=fz*sp;}
  if(keys['a']){camera.position.x-=rx*sp;camera.position.z-=rz*sp;}
  if(keys['d']){camera.position.x+=rx*sp;camera.position.z+=rz*sp;}
  if(keys[' '])camera.position.y+=sp;
  if(stickL.active){
    camera.position.x+=(fx*-stickL.dy+rx*stickL.dx)*sp;
    camera.position.z+=(fz*-stickL.dy+rz*stickL.dx)*sp;
  }
  camera.rotation.order='YXZ'; camera.rotation.y=yaw; camera.rotation.x=pitch; camera.rotation.z=0;
  // CONTINUOUS FIRE: CANNONS button toggles, lasers never stop while live
  if(weaponMode){
    if(!window._lastAuto) window._lastAuto = 0;
    if(t - window._lastAuto > 0.22){
      window._lastAuto = t;
      fireLaser();
    }
  }
  // laser fade
  for(var li=lasers.length-1; li>=0; li--){
    lasers[li].life -= dt;
    lasers[li].mesh.children.forEach(function(c){ c.material.opacity = Math.max(0, lasers[li].life*5); });
    if(lasers[li].life<=0){ scene.remove(lasers[li].mesh); lasers.splice(li,1); }
  }
  // sparkles drift + fade
  for(var si=sparkles.length-1; si>=0; si--){
    var spk=sparkles[si], u=spk.userData;
    u.life-=dt;
    spk.position.x+=u.vx*dt; spk.position.y+=u.vy*dt; spk.position.z+=u.vz*dt;
    spk.rotation.x+=dt*5; spk.rotation.y+=dt*7;
    spk.material.opacity=Math.max(0,u.life*2);
    if(u.life<=0){ scene.remove(spk); sparkles.splice(si,1); }
  }
  // scorch marks fade shortly
  for(var mi=scorchMarks.length-1; mi>=0; mi--){
    var sm=scorchMarks[mi];
    sm.life-=dt;
    if(sm.life<1.5) sm.m.material.opacity=Math.max(0, sm.life/1.5*0.85);
    if(sm.life<=0){ scene.remove(sm.m); scorchMarks.splice(mi,1); }
  }
  renderer.render(scene,camera);
}
// BLACKOUT — only avatars and h=10 remain
//buildSentinel();
//buildScout();
//buildHuman();
buildAvatar();
// BLACK WALL behind the winning face (King's order)
(function(){
  var wall = new THREE.Mesh(
    new THREE.PlaneGeometry(60, 40),
    new THREE.MeshBasicMaterial({color:0x080808})
  );
  wall.position.set(0, 14, 132);
  // face the soldiers/camera (toward -Z)
  wall.rotation.y = Math.PI;
  scene.add(wall);
})();

// MANNEQUIN HEAD — winner's face (index 0), clean 3D form (King's order)
(function(){ return; // BLACKOUT
  var mg = new THREE.Group();
  var mCyan = new THREE.LineBasicMaterial({color:0x66eeff, transparent:true, opacity:0.85});
  var mGold = new THREE.LineBasicMaterial({color:0xffcc44, transparent:true, opacity:0.85});
  function mline(pts, mat){
    mg.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts.map(function(p){
      return new THREE.Vector3(p[0],p[1],p[2]); })), mat));
  }
  function mellipse(cx,cy,cz,rx,ry,mat,rz){
    var pts=[];
    for(var i=0;i<=24;i++){ var a=(i/24)*Math.PI*2;
      pts.push(new THREE.Vector3(cx+Math.cos(a)*rx, cy+Math.sin(a)*ry, (rz||0)+cz*0.1));
      // Actually 3D: vary z with angle for form
      pts[pts.length-1].z = cz + Math.sin(a)*ry*0.3;
    }
    mline(pts, mat);
  }
  // CRANIUM — clean sphere meridians (8)
  for(var mi=0; mi<8; mi++){
    var ma = (mi/8)*Math.PI*2, mpts=[];
    for(var mh=0; mh<=12; mh++){
      var phi = (mh/12)*Math.PI; // 0 to PI
      var mr = 5.0*Math.sin(phi);
      mpts.push([Math.cos(ma)*mr, 5.0*Math.cos(phi)+2, Math.sin(ma)*mr*0.92]);
    }
    mline(mpts, mi%2?mGold:mCyan);
  }
  // CRANIUM — latitudinal (5)
  for(var la=0; la<5; la++){
    var ly = 6.5 - la*2.2, lr = 5.0*Math.sqrt(Math.max(0,1-Math.pow((ly-2)/5.0,2)));
    var lpts=[];
    for(var la2=0; la2<=24; la2++){ var ang=(la2/24)*Math.PI*2;
      lpts.push([Math.cos(ang)*lr, ly, Math.sin(ang)*lr*0.92]);
    }
    mline(lpts, la%2?mCyan:mGold);
  }
  // FACE — sculptural relief (King: indented eyes, protruding nose, lip work)
  var eDX = 1.9, eSZ = 1.15;
  // center line
  mline([[0,7,4.6],[0,3,5.0],[0,0,5.2],[0,-2.5,5.0]], mGold);
  // brows (on surface)
  mline([[-3.2,3.2,4.2],[-eDX,3.5,4.6],[-0.8,3.2,4.7]], mGold);
  mline([[0.8,3.2,4.7],[eDX,3.5,4.6],[3.2,3.2,4.2]], mGold);
  // EYE SOCKETS — indented (concave 