<!-- RUBY-BACKUP · part 121 -->
.y = 0;
        camDir.normalize();
      } else {
        camDir.set(0, 0, -1);
      }
      var right = new THREE.Vector3();
      right.crossVectors(camDir, new THREE.Vector3(0, 1, 0)).normalize();
      var step = 0.3 * dir;
      PAD_SELECTED.position.x += right.x * step;
      PAD_SELECTED.position.z += right.z * step;
      /* anchored objects stay put */
      if(typeof ANCHORED_OBJECTS!=='undefined' && ANCHORED_OBJECTS[PAD_SELECTED.uuid]){
        var a = ANCHORED_OBJECTS[PAD_SELECTED.uuid];
        a.x = PAD_SELECTED.position.x;
        a.z = PAD_SELECTED.position.z;
      }
    }catch(e){}
  }
  var leftBtn = document.createElement('button');
  leftBtn.innerHTML = '&#9664; Left';
  leftBtn.style.cssText = 'padding:12px;background:#2a2214;color:#ffd700;border:1px solid #8a6a1c;border-radius:8px;font-size:14px;font-weight:bold;';
  var rightBtn = document.createElement('button');
  rightBtn.innerHTML = 'Right &#9654;';
  rightBtn.style.cssText = 'padding:12px;background:#2a2214;color:#ffd700;border:1px solid #8a6a1c;border-radius:8px;font-size:14px;font-weight:bold;';
  /* hold to keep moving */
  var _lrTimer = null;
  function startLR(dir){
    movePadSelectedLR(dir);
    _lrTimer = setInterval(function(){ movePadSelectedLR(dir); }, 120);
  }
  function stopLR(){ if(_lrTimer){ clearInterval(_lrTimer); _lrTimer = null; } }
  leftBtn.addEventListener('touchstart', function(e){ e.preventDefault(); startLR(-1); }, {passive:false});
  leftBtn.addEventListener('touchend', stopLR);
  leftBtn.addEventListener('mousedown', function(){ startLR(-1); });
  leftBtn.addEventListener('mouseup', stopLR);
  rightBtn.addEventListener('touchstart', function(e){ e.preventDefault(); startLR(1); }, {passive:false});
  rightBtn.addEventListener('touchend', stopLR);
  rightBtn.addEventListener('mousedown', function(){ startLR(1); });
  rightBtn.addEventListener('mouseup', stopLR);
  lrGrid.appendChild(leftBtn);
  lrGrid.appendChild(rightBtn);
  distBtns.forEach(function(b){
    var btn = document.createElement('button');
    btn.textContent = b.t;
    btn.style.cssText = 'padding:10px;background:#2a2214;color:#ffd700;border:1px solid #8a6a1c;border-radius:8px;font-size:13px;';
    btn.onclick = b.fn;
    distGrid.appendChild(btn);
  });
  _padEl.appendChild(distGrid);
  _padEl.appendChild(lrGrid);
  /* close button */
  var closeBtn = document.createElement('button');
  closeBtn.textContent = 'Done — leave her here';
  closeBtn.style.cssText = 'width:100%;padding:12px;margin-top:8px;background:#d8a920;color:#111;border:none;border-radius:8px;font-weight:bold;font-size:14px;';
  closeBtn.onclick = function(){ hideHandPad(); };
  _padEl.appendChild(closeBtn);
  document.body.appendChild(_padEl);
  /* measure current dims */
  try{
    var box = new THREE.Box3().setFromObject(obj);
    var sz = box.getSize(new THREE.Vector3());
    _padBaseDims = {height: sz.y, width: sz.x, length: sz.z};
  }catch(e){ _padBaseDims = {height:1, width:1, length:1}; }
}
var _padSliders = {};
var _padBaseDims = {height:1, width:1, length:1};
function applyPadDims(){
  if(!PAD_SELECTED) return;
  try{
    var h = parseFloat(_padSliders.height.value);
    var w = parseFloat(_padSliders.width.value);
    var l = parseFloat(_padSliders.length.value);
    /* scale relative to base */
    var box = new THREE.Box3().setFromObject(PAD_SELECTED);
    var cs = box.getSize(new THREE.Vector3());
    var cur = PAD_SELECTED.scale;
    if(cs.x > 0.001 && cs.y > 0.001 && cs.z > 0.001){
      var tw = _padBaseDims.width * w;
      var th = _padBaseDims.height * h;
      var tl = _padBaseDims.length * l;
      PAD_SELECTED.scale.set(
        cur.x * (tw / cs.x),
        cur.y * (th / cs.y),
        cur.z * (tl / cs.z)
      );
    }
  }catch(e){}
}
function showPadPartPicker(){
  if(!PAD_SELECTED) return;
  /* list the parts */
  var parts = [];
  try{
    PAD_SELECTED.traverse(function(o){
      if(o.isMesh && o.name) parts.push(o.name);
    });
  }catch(e){}
  if(parts.length === 0){ codeStatus('no named parts'); return; }
  /* simple picker — cycle through */
  var idx = 0;
  codeStatus('part: ' + parts[0] + ' — tap Pick again for next');
  /* store for cycling */
  _padEl._parts = parts;
  _padEl._partIdx = 0;
  /* change button to cycle */
  var btns = _padEl.querySelectorAll('button');
  for(var i=0; i<btns.length; i++){
    if(btns[i].textContent === 'Pick a Part'){
      btns[i].onclick = function(){
        _padEl._partIdx = (_padEl._partIdx + 1) % _padEl._parts.length;
        codeStatus('part: ' + _padEl._parts[_padEl._partIdx]);
      };
      break;
    }
  }
}
function hideHandPad(){
  if(_padEl){
    try{ document.body.removeChild(_padEl); }catch(e){}
    _padEl = null;
  }
  PAD_FOLLOW = false;
  window._crownLockTarget = null;
  /* object stays where it is — as he left it */
  codeStatus('she rests where you left her');
}
/* follow logic — runs each frame */
function updatePadFollow(){
  if(!PAD_FOLLOW || !PAD