<!-- SAGA · part 66 -->
margin:10px 0 6px 0;border-bottom:1px solid #d8a920;padding-bottom:6px;';
  osEl.appendChild(header);
  for(var i=g[1]; i<g[2]; i++){
    (function(b){
      var cell = document.createElement('div');
      cell.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:2px;width:72px;flex-shrink:0;';
      var btn = document.createElement('button');
  btn.title = b[1];
  btn.innerHTML = '<img src="/coders100/buttons/'+b[0]+'.webp" style="width:100%;height:100%;border-radius:50%;object-fit:cover;" draggable="false">';
  btn.style.cssText = 'width:48px;height:48px;min-width:48px;min-height:48px;border-radius:50%;padding:0;margin:0;border:2px solid #d8a920;background:#141006;cursor:pointer;flex-shrink:0;overflow:hidden;';
      btn.onclick = (function(fn){ return function(){ fn(); }; })(b[2]);
      cell.appendChild(btn);
      var lbl = document.createElement('div');
      lbl.textContent = b[1];
      lbl.style.cssText = 'color:#d8a920;font-size:13px;font-family:Georgia,\'Times New Roman\',serif;text-align:center;line-height:1.2;max-width:72px;letter-spacing:0.5px;';
      cell.appendChild(lbl);
      osEl.appendChild(cell);
    })(BTNS[i]);
  }
});
/* REAL TOGGLES — switches with on/off state */











/* ===== DUAL JOYSTICKS — left: body, right: camera ===== */
function makeJoystick(pos, onMove){
  var base = document.createElement('div');
  base.style.cssText = 'position:fixed;'+pos+';width:100px;height:100px;border-radius:50%;border:2px solid #8a6a1c;background:rgba(20,14,6,0.4);z-index:998;touch-action:none;';
  var knob = document.createElement('div');
  knob.style.cssText = 'position:absolute;left:50%;top:50%;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;background:radial-gradient(circle at 30% 30%, #ffd700, #8a6a1c);box-shadow:0 0 8px rgba(255,215,0,0.5);';
  base.appendChild(knob);
  document.body.appendChild(base);
  var touchId = null, cx = 0, cy = 0;
  function setKnob(dx, dy){
    var max = 28;
    var len = Math.sqrt(dx*dx + dy*dy);
    if(len > max){ dx = dx/len*max; dy = dy/len*max; }
    knob.style.transform = 'translate('+dx+'px,'+dy+'px)';
    onMove(dx/max, dy/max);
  }
  base.addEventListener('touchstart', function(e){
    e.stopPropagation(); e.preventDefault();
    var t = e.changedTouches[0];
    touchId = t.identifier;
    var r = base.getBoundingClientRect();
    cx = r.left + r.width/2; cy = r.top + r.height/2;
  }, {passive:false});
  base.addEventListener('touchmove', function(e){
    e.stopPropagation(); e.preventDefault();
    for(var i=0; i<e.changedTouches.length; i++){
      var t = e.changedTouches[i];
      if(t.identifier === touchId){
        setKnob(t.clientX - cx, t.clientY - cy);
      }
    }
  }, {passive:false});
  base.addEventListener('touchend', function(e){
    e.stopPropagation();
    for(var i=0; i<e.changedTouches.length; i++){
      if(e.changedTouches[i].identifier === touchId){
        touchId = null;
        knob.style.transform = 'translate(0,0)';
        onMove(0, 0);
      }
    }
  }, {passive:true});
  return base;
}

/* LEFT joystick — moves the body */
var lastDX = 0, lastDZ = 0, walkPhase = 0;
makeJoystick('left:8%;bottom:100px;', function(dx, dy){
  var sp = 0.5;
  if(moveMode === 'fly'){
    sp = 2.0; /* Fly faster */
    /* FLIGHT: 3D movement — dx left/right, dy up/down */
    var fwdX = -Math.cos(camYaw), fwdZ = -Math.sin(camYaw);
    var rightX = Math.sin(camYaw), rightZ = -Math.cos(camYaw);
    var mx = rightX * dx * sp;
    var mz = rightZ * dx * sp;
    var my = -dy * sp; /* Push up = fly up, push down = descend */
    lastDX = mx;
    lastDZ = mz;
    kingPos.x += mx;
    kingPos.z += mz;
    kingPos.y = Math.max(0.5, kingPos.y + my);
    /* Tilt body when flying */
    if(typeof playerBody !== 'undefined' && playerBody){
      playerBody.rotation.x = -dy * 0.3;
    }
  } else if(moveMode === 'swim'){
    /* SWIM: water movement — fluid, buoyant, dive/surface */
    var spSwim = 0.3; /* Slower in water */
    var fwdX = -Math.cos(camYaw), fwdZ = -Math.sin(camYaw);
    var rightX = Math.sin(camYaw), rightZ = -Math.cos(camYaw);
    var mx = rightX * dx * spSwim + fwdX * (-dy) * spSwim;
    var mz = rightZ * dx * spSwim + fwdZ * (-dy) * spSwim;
    lastDX = mx;
    lastDZ = mz;
    kingPos.x += mx;
    kingPos.z += mz;
    /* Buoyancy: float at water level, push up/down to dive/surface */
    /* Water level assumed at y=0.5 */
    var targetY = 0.5 + (-dy * 0.3);
    kingPos.y += (targetY - kingPos.y) * 0.1;
    /* Swim animation: arms stroke */
    if(typeof playerBody !== 'undefined' && playerBody){
      walkPhase += 0.1;
      if(playerBody.userData.armL){
        playerBody.userData.armL.rotation.x = Math.sin(walkPhase) * 0.8;
        playerBody.userData.armR.rotation.x = -Math.sin(walkPhase) * 0.8;
      }
      /* Body horizontal in water */
      playerBody.rotation.x = -Math.PI/2 + 0.3;
    }
  } else {
    /* WALK: ground movement — dx left/right, dy forward/back — 