<!-- SAGA2 · part 24 -->
rm + forearm as one tapered form
    // ARM SURFACE — dense wrap
    for(var as2=0; as2<20; as2++){
      var apts=[], ay2 = 8-as2*1.0;
      for(var ai=0;ai<=16;ai++){ var aan=ai/16*Math.PI*2;
        apts.push(new THREE.Vector3(ax+Math.cos(aan)*2.4, ay2, 6.5+Math.sin(aan)*2.0));
      }
      draw(apts, as2%5===0?lnGold:lnCyan);
    }
    // RULED MECHANICAL — straight precision lines on arms
    for(var rl=0; rl<8; rl++){
      var pts=[];
      for(var ri=0; ri<=10; ri++){
        pts.push(new THREE.Vector3(ax-2.5+rl*0.7, 8-ri*1.9, 6.5));
      }
      draw(pts, lnDim);
    }
    for(var ar=0; ar<12; ar++){
      var ay = 8-ar*1.8;
      var aw = 2.8-ar*0.06;
      var pts=[];
      for(var i=0;i<=16;i++){ var an=i/16*Math.PI*2;
        pts.push(new THREE.Vector3(ax+Math.cos(an)*aw, ay, 4+Math.sin(an)*aw));
      }
      draw(pts, ar%4===0?lnGold:lnCyan);
    }
    // cannon: line-art barrel
    var bx = ax;
    for(var br=0; br<8; br++){
      var by = -10, bz = 7+br*1.8, bw = 1.6-br*0.05;
      var pts=[];
      for(var i=0;i<=12;i++){ var an=i/12*Math.PI*2;
        pts.push(new THREE.Vector3(bx+Math.cos(an)*bw, by+Math.sin(an)*bw, bz));
      }
      draw(pts, sd<0?lnGold:lnCyan);
    }
    // muzzle ring
    var mpts=[];
    for(var i=0;i<=16;i++){ var an=i/16*Math.PI*2;
      mpts.push(new THREE.Vector3(bx+Math.cos(an)*1.4, -10+Math.sin(an)*1.4, 21.5)); }
    draw(mpts, sd<0?lnGold:lnCyan);
    // hand — finger lines below cannon
    for(var fn=0; fn<4; fn++){
      var fpts=[];
      for(var fi=0; fi<=6; fi++){
        fpts.push(new THREE.Vector3(bx-1.2+fn*0.8, -13-fi*0.5, 4+Math.sin(fi)*0.3));
      }
      draw(fpts, lnDim);
    }
    // store tip for laser origin
    if(sd<0){ avatarCannonL = {userData:{tipPos:new THREE.Vector3(bx,-10,21.5)}}; }
    else { avatarCannonR = {userData:{tipPos:new THREE.Vector3(bx,-10,21.5)}}; }
  });

  // ===== LEGS — contour lines =====
  [-1,1].forEach(function(sd){
    var lx = sd*5;
    // LEG FILIGREE — decorative bands
    for(var lf=0; lf<4; lf++){
      var pts=[], ly=-4-lf*5;
      for(var i=0;i<=20;i++){ var an=i/20*Math.PI*2;
        var wob = Math.sin(an*8+lf)*0.2;
        pts.push(new THREE.Vector3(lx+Math.cos(an)*(3.8+wob), ly, Math.sin(an)*(3.8+wob)*0.8));
      }
      draw(pts, lf%2?lnGold:lnCyan);
    }
    for(var lr=0; lr<14; lr++){
      var ly = -2-lr*1.8;
      var lw = 3.6-lr*0.08;
      var pts=[];
      for(var i=0;i<=16;i++){ var an=i/16*Math.PI*2;
        pts.push(new THREE.Vector3(lx+Math.cos(an)*lw, ly, Math.sin(an)*lw*0.8));
      }
      draw(pts, lr%5===0?lnGold:lnCyan);
    }
  });

  // (halo removed at King order)

  // lights
  var eyeL = new THREE.PointLight(0x66eeff, 1.5, 50);
  eyeL.position.set(0, 21, 10);
  avatarGrp.add(eyeL);
  avatarGrp.userData.lights = [eyeL];
  // PRESENCE — soft radial glow behind (he exists in space)
  var glowTex = (function(){
    var c = document.createElement('canvas'); c.width=c.height=128;
    var ctx = c.getContext('2d');
    var g = ctx.createRadialGradient(64,64,0,64,64,64);
    g.addColorStop(0,'rgba(80,180,220,0.35)');
    g.addColorStop(0.5,'rgba(60,140,200,0.12)');
    g.addColorStop(1,'rgba(0,0,0,0)');
    ctx.fillStyle=g; ctx.fillRect(0,0,128,128);
    return new THREE.CanvasTexture(c);
  })();
  var presence = new THREE.Mesh(new THREE.PlaneGeometry(60, 60),
    new THREE.MeshBasicMaterial({map:glowTex, transparent:true, blending:THREE.AdditiveBlending, depthWrite:false}));
  presence.position.set(0, 5, -15);
  avatarGrp.add(presence);

  camera.add(avatarGrp);
  avatarGrp.scale.set(0.55, 0.55, 0.55);
  avatarGrp.position.set(0, -14, -27);
  avatarGrp.rotation.x = 0.05;
  scene.add(camera);
}

===== FILE: public/saga2/avatar.html =====
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Human Avatar</title>
<style>
  body { margin:0; overflow:hidden; background:#000; }
  canvas { display:block; }
</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
// HUMAN AVATAR — clean build, no shortcuts (v1)
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0a0a);
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 8, 35);
camera.lookAt(0, 8, 0);
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);

// LIGHTS (proper three-point)
var hemi = new THREE.HemisphereLight(0xffffff, 0x444444, 0.5);
scene.add(hemi);
var key = new THREE.DirectionalLight(0xffffff, 1.0);
key.position.set(10, 20, 15);
key.castShadow = true;
key.shadow.mapSize.width = 2048;
key.shadow.mapSize.height = 2048;
scene.add(key);
var fill = new THREE.DirectionalLight(0x8888ff, 0.4);
fill.position.set(