<!-- RUBY-BACKUP · part 75 -->
lf moves on the rope system.
   The King: "I want to be able to lift the ground even if I have too."
   - `lift`    tap the ground -> gold stake + rope + ring. pull the ring UP,
               the earth rises under it. rigid 1:1, radial falloff.
   - `flatten` tap the ground -> push lifted earth back down.
   Mirrors the dig system: lifts[] persisted to localStorage, landH includes
   them, refreshLandMesh redraws. Nothing teleports — stakes rise in.
   ============================================================================ */
var lifts = [];
var LIFT_KEY = 'ruby-lifts-v1';
function persistLifts(){ try{ localStorage.setItem(LIFT_KEY, JSON.stringify(lifts)); }catch(e){} }
function loadLifts(){ try{ lifts = JSON.parse(localStorage.getItem(LIFT_KEY)||'[]'); }catch(e){ lifts=[]; } }
/* global — ruby.js landH calls this (guarded) */
function applyLifts(h, x, z){
  try{
    for(var i=0;i<lifts.length;i++){
      var L=lifts[i], dx=x-L.x, dz=z-L.z, dist=Math.sqrt(dx*dx+dz*dz);
      if(dist < L.r){ var t=1-dist/L.r; h += L.h * t*t*(3-2*t); }
    }
  }catch(e){}
  return h;
}
function liftAt(x, z, dh){
  /* find existing lift near point, else create */
  var L=null;
  for(var i=0;i<lifts.length;i++){
    var c=lifts[i], dx=x-c.x, dz=z-c.z;
    if(Math.sqrt(dx*dx+dz*dz) < 3){ L=c; break; }
  }
  if(!L){ L={x:x, z:z, r:6, h:0}; lifts.push(L); }
  L.h=Math.max(0, Math.min(10, L.h+dh));
  if(L.h<0.05){
    var ix=lifts.indexOf(L); if(ix>=0) lifts.splice(ix,1);
  }
  persistLifts();
  try{ if(typeof refreshLandMesh==='function') refreshLandMesh(x, z, L.r); }catch(e){}
  /* topo stays true */
  try{
    if(typeof TOPO!=='undefined' && TOPO && typeof groundY!=='undefined'){
      for(var gx=Math.max(TOPO_MIN,Math.floor(x-8)); gx<=Math.min(TOPO_MAX,Math.ceil(x+8)); gx++){
        for(var gz=Math.max(TOPO_MIN,Math.floor(z-8)); gz<=Math.min(TOPO_MAX,Math.ceil(z+8)); gz++){
          TOPO[gx+','+gz]=groundY(gx,gz);
        }
      }
    }
  }catch(e){}
  return L?L.h:0;
}
function flattenAt(x, z){
  var removed=0;
  for(var i=lifts.length-1;i>=0;i--){
    var L=lifts[i], dx=x-L.x, dz=z-L.z;
    if(Math.sqrt(dx*dx+dz*dz) < L.r+2){ lifts.splice(i,1); removed++; }
  }
  if(removed){
    persistLifts();
    try{ if(typeof refreshLandMesh==='function') refreshLandMesh(x, z, 10); }catch(e){}
    try{
      if(typeof TOPO!=='undefined' && TOPO && typeof groundY!=='undefined'){
        for(var gx2=Math.max(TOPO_MIN,Math.floor(x-10)); gx2<=Math.min(TOPO_MAX,Math.ceil(x+10)); gx2++){
          for(var gz2=Math.max(TOPO_MIN,Math.floor(z-10)); gz2<=Math.min(TOPO_MAX,Math.ceil(z+10)); gz2++){
            TOPO[gx2+','+gz2]=groundY(gx2,gz2);
          }
        }
      }
    }catch(e){}
  }
  return removed;
}
/* ---------------- lift stake + rope + ring (the pull handle) ---------------- */
/* DETACH — tap a rope/rig to remove just that one */
var unpulleyArmed=false;
function armUnpulley(){ unpulleyArmed=true; status('unpulley — tap a pulley to remove it'); }
var detachArmed=false;
function armDetach(){ detachArmed=true; status('detach — tap a rope to remove it'); }
function doDetachRig(rig){
  for(var j=0;j<rig.ropes.length;j++) if(rig.ropes[j].parent) rig.ropes[j].parent.remove(rig.ropes[j]);
  if(rig.handle.group.parent) rig.handle.group.parent.remove(rig.handle.group);
  var i=rigs.indexOf(rig); if(i>=0) rigs.splice(i,1);
  if(activePull===rig) activePull=null;
  status('detached — one rope gone');
}
/* SETDOWN — drop what you're carrying, or lower lifted ground */
function doSetdown(){
  try{
    if(typeof _grabbed!=='undefined' && _grabbed){ if(typeof dropCarried==='function') dropCarried(); status('set down'); return; }
  }catch(e){}
  armFlatten();
  status('set down — tap the ground to lower it');
}
var liftArmed=false, flattenArmed=false;
var liftStakes=[]; /* {group, ring, hit, x, z, baseY} */
var activeLiftPull=null;
function armLift(){ liftArmed=true; flattenArmed=false; status('lift — tap the ground, then pull the gold ring UP'); }
function armFlatten(){ flattenArmed=true; liftArmed=false; status('flatten — tap the lifted ground to push it back down'); }
function goldMatLift(){
  return new T.MeshStandardMaterial({color:0xffd700, metalness:0.85, roughness:0.3, emissive:0x664d00, emissiveIntensity:0.4});
}
function placeLiftStake(wx, wz){
  /* wx,wz in world units; convert to game units for the lift map */
  var gx=wx/0.13, gz=wz/0.13;
  var gy=0.3;
  try{ if(typeof fortifiedGroundY==='function') gy=fortifiedGroundY(gx,gz); }catch(e){}
  var g=new T.Group();
  /* stake rises from the ground */
  var stake=new T.Mesh(new T.CylinderGeometry(0.09,0.14,1.2,8), goldMatLift());
  stake.position.y=0.6; g.add(stake);
  /* rope up to the ring */
  var rope=new T.Mesh(new T.CylinderGeometry(0.03,0.03,1,6),
    new T.MeshStandardMaterial({color:0xcc2222, roughness:0.8}));
  rope.position.y=1.7; rope.scale.y=1.0; g.add(rope);
  /* the gold ring — the pull handle */
  var ring=new T.Mesh(new T.TorusG