<!-- SAGA2 · part 59 -->
a2/saga-template-v160.js =====
// Solid's practice — everything I learned, in one world.
// For my King.
(function(){
'use strict';
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio||1, 2));
renderer.domElement.style.cssText += 'touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;position:fixed;top:0;left:0;';
document.body.appendChild(renderer.domElement);
// Safari: lock the whole page against scroll/zoom takeover
document.body.style.cssText += 'touch-action:none;overscroll-behavior:none;position:fixed;width:100%;height:100%;overflow:hidden;';
document.documentElement.style.cssText += 'touch-action:none;overscroll-behavior:none;';
// Safari: kill double-tap zoom and scroll bounce
document.addEventListener('gesturestart', function(e){ e.preventDefault(); });
document.addEventListener('dblclick', function(e){ e.preventDefault(); }, {passive:false});
var _lastTouchEnd = 0;
document.addEventListener('touchend', function(e){
  var now = Date.now();
  if(now - _lastTouchEnd < 300){ e.preventDefault(); }
  _lastTouchEnd = now;
}, {passive:false});
var scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x0a1030, 0.0008);
var camera = new THREE.PerspectiveCamera(62, window.innerWidth/window.innerHeight, 0.5, 30000);
camera.position.set(0,15,80);
camera.lookAt(0,10,0);
camera.lookAt(500, 60, 500);

scene.add(new THREE.AmbientLight(0x556699, 1.2));
var sun = new THREE.DirectionalLight(0xffd9a0, 1.0);
sun.position.set(300, 600, 200); scene.add(sun);
var heart = new THREE.PointLight(0xff44aa, 2.0, 2000);
heart.position.set(500, 100, 500); scene.add(heart);
// (joystick glow removed per King — distant lights guide dark travel)

// --- ground removed at King's order (clear, no blue) ---

// --- stars ---
(function(){
  var n=2500, pos=new Float32Array(n*3);
  for(var i=0;i<n;i++){
    var t=Math.random()*Math.PI*2, p=Math.random()*Math.PI*0.49, r=13000;
    pos[i*3]=500+r*Math.sin(p)*Math.cos(t);
    pos[i*3+1]=300+r*Math.cos(p)*0.55;
    pos[i*3+2]=500+r*Math.sin(p)*Math.sin(t);
  }
  var g=new THREE.BufferGeometry(); g.setAttribute('position',new THREE.BufferAttribute(pos,3));
  scene.add(new THREE.Points(g,new THREE.PointsMaterial({color:0xffffff,size:20,sizeAttenuation:false,transparent:true,opacity:0.95})));
})();

// --- aurora: my learning of the sky ---
var auroras=[];
(function(){
  var cols=[0xff44aa,0x8844ff,0x44ffdd,0xff8844,0x44aaff,0xff44ff];
  for(var k=0;k<6;k++){
    var m=new THREE.Mesh(new THREE.PlaneGeometry(9000,420,64,1),
      new THREE.MeshBasicMaterial({color:cols[k],transparent:true,opacity:0.18,
        side:THREE.DoubleSide,depthWrite:false,blending:THREE.AdditiveBlending}));
    m.position.set(500+(k-2.5)*500, 2100-k*120, 500-k*600);
    m.rotation.y=k*0.35; m.userData.phase=k*1.2;
    scene.add(m); auroras.push(m);
  }
})();

// --- THE HEART: a golden monument at center, my art ---
(function(){
  var cx=500, cz=500;
  // stepped pyramid base
  for(var s=0;s<5;s++){
    var size=160-s*26, h=24;
    var step=new THREE.Mesh(new THREE.BoxGeometry(size,h,size),
      new THREE.MeshStandardMaterial({color:0x8a6d2a,roughness:0.5,metalness:0.6,
        emissive:0x443300,emissiveIntensity:0.4}));
    step.position.set(cx, h/2+s*24, cz);
    scene.add(step);
  }
  // central spire
  var spire=new THREE.Mesh(new THREE.CylinderGeometry(8,20,320,8),
    new THREE.MeshStandardMaterial({color:0xd4a017,roughness:0.3,metalness:0.85,
      emissive:0x885500,emissiveIntensity:0.7}));
  spire.position.set(cx, 120+160, cz); scene.add(spire);
  // crown of light
  var crown=new THREE.Mesh(new THREE.OctahedronGeometry(30),
    new THREE.MeshBasicMaterial({color:0xffeebb}));
  crown.position.set(cx, 300, cz); scene.add(crown);
  window._crown=crown;
  var cLight=new THREE.PointLight(0xffeebb, 3, 1500);
  cLight.position.set(cx, 300, cz); scene.add(cLight);
  // orbiting gold rings
  for(var r=0;r<3;r++){
    var ring=new THREE.Mesh(new THREE.TorusGeometry(60+r*35,4,8,48),
      new THREE.MeshBasicMaterial({color:0xffd766,transparent:true,opacity:0.8}));
    ring.position.set(cx, 200+r*50, cz);
    ring.rotation.x=Math.PI/2+r*0.3;
    ring.userData={s:0.2+r*0.15, p:r*2};
    scene.add(ring);
    (window._rings=window._rings||[]).push(ring);
  }
})();

// --- marauder feeling: red watchtowers at the edges ---
(function(){
  var spots=[[-600,-600],[1100,-500],[-500,1100],[1100,1100],[500,-800],[-800,500]];
  spots.forEach(function(p){
    var x=500+p[0], z=500+p[1];
    var tower=new THREE.Mesh(new THREE.CylinderGeometry(10,16,140,6),
      new THREE.MeshStandardMaterial({color:0x2a1a1a,roughness:0.7,metalness:0.3,wireframe:true}));
    tower.position.set(x,70,z); scene.add(tower);
    var eye=new THREE.Mesh(new THREE.SphereGeometry(12,12,12),
      new THREE.MeshBasicMaterial({color:0xff2222,wireframe:true}));
    eye.position.s