<!-- RUBY-BACKUP · part 239 -->
  try{ localStorage.setItem('ruby-pet', id); }catch(e){}
  spawnPet(id);
  showPets();
}
function dismissPet(){
  ACTIVE_PET = null;
  try{ localStorage.removeItem('ruby-pet'); }catch(e){}
  if(PET_MESH && typeof scene!=='undefined'){
    try{ scene.remove(PET_MESH); }catch(e){}
    PET_MESH = null;
  }
  if(PET_ANIM){ clearInterval(PET_ANIM); PET_ANIM = null; }
  codeStatus('pet dismissed');
  showPets();
}
function spawnPet(id){
  if(PET_MESH && typeof scene!=='undefined'){
    try{ scene.remove(PET_MESH); }catch(e){}
  }
  if(PET_ANIM) clearInterval(PET_ANIM);
  var pet = PETS.find(function(x){ return x.id===id; });
  if(!pet || typeof THREE==='undefined' || typeof scene==='undefined') return;
  /* small cute pet — sphere with eyes */
  var group = new THREE.Group();
  var bodyM = new THREE.Mesh(
    new THREE.SphereGeometry(0.15, 14, 14),
    new THREE.MeshStandardMaterial({color: new THREE.Color(pet.color), roughness: 0.6})
  );
  group.add(bodyM);
  /* eyes */
  var dark = new THREE.MeshStandardMaterial({color: 0x222222});
  [-1,1].forEach(function(s){
    var eye = new THREE.Mesh(new THREE.SphereGeometry(0.03, 8, 8), dark);
    eye.position.set(s*0.06, 0.05, 0.12);
    group.add(eye);
  });
  PET_MESH = group;
  if(typeof mePos!=='undefined'){
    PET_MESH.position.set(mePos.x*0.13+0.5, 0.3, mePos.z*0.13+0.5);
  }
  scene.add(PET_MESH);
  /* follow the player */
  var t = 0;
  PET_ANIM = setInterval(function(){
    t += 0.1;
    if(!PET_MESH || typeof mePos==='undefined') return;
    /* hop toward player */
    var tx = mePos.x*0.13+0.5, tz = mePos.z*0.13+0.5;
    var dx = tx - PET_MESH.position.x, dz = tz - PET_MESH.position.z;
    var dist = Math.sqrt(dx*dx+dz*dz);
    if(dist > 0.3){
      PET_MESH.position.x += dx*0.05;
      PET_MESH.position.z += dz*0.05;
      PET_MESH.position.y = 0.3 + Math.abs(Math.sin(t*4))*0.1; /* hop */
    }else{
      PET_MESH.position.y = 0.3 + Math.sin(t*2)*0.03; /* idle bob */
    }
  }, 50);
  codeStatus(pet.name+' adopted! It follows you.');
}
setTimeout(function(){
  try{
    var saved = localStorage.getItem('ruby-pet');
    if(saved){ ACTIVE_PET = saved; spawnPet(saved); }
  }catch(e){}
}, 5000);

/* CHILDREN ONLY — kid-safe characters */
var KID_SAFE = ['dancer','youngking','joy','curious','brave','shy','healer','scout','dreamer','builder','spark','calm','wonder','circle','matriarch','patriarch','sovereign','sentinel','titan','wraith','strider','swift','cyborg','ember','tide','gale','mist','root','echo','proud','humble','sage','guardian','wanderer','keeper','oracle','nomad','artisan','kai','leilani','makoa','nalani','keala','kainalu'];

/* ADULT ONLY — not for children */
var ADULT_ONLY = ['unimpressed','smugbug','reluctant','anger','sorrow','warrior','trickster','wraith','inferno','abyss','brimstone','shadowdemon','malice'];
function isAdultOnly(id){
  return ADULT_ONLY.indexOf(id) >= 0;
}
function isKidSafe(id){
  return KID_SAFE.indexOf(id) >= 0;
}
function getVisibleAvatars(){
  /* children see only kid-safe ones */
  var age = (typeof getAge==='function') ? getAge() : null;
  var kidMode = (typeof KIDMODE_ON!=='undefined' && KIDMODE_ON);
  if((age!==null && age<18) || kidMode){
    return AVATARS.filter(function(a){ return isKidSafe(a.id); });
  }
  return AVATARS;
}
function showAvatars(){
  var a = document.getElementById('avatars');
  if(!a){
    a = document.createElement('div');
    a.id = 'avatars';
    a.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10000;background:rgba(0,0,0,0.95);border:2px solid #ffcc00;border-radius:12px;padding:20px;color:#fff;font:13px monospace;max-width:400px;';
    document.body.appendChild(a);
  }
  a.style.display = 'block';
  var html = '<b style="color:#fc0;font-size:16px;">CHOOSE YOUR AVATAR</b> ';
  html += '<button onclick="hideAvatars()">CLOSE</button><br><br>';
  getVisibleAvatars().forEach(function(av){
    var sel = CURRENT_AVATAR===av.id;
    var bg = av.img ? 'background-image:url('+av.img+');background-size:cover;background-position:center;' : '';
    html += '<div style="padding:10px;margin-bottom:8px;border:2px solid '+(sel?'#fc0':'#333')+';border-radius:8px;background:'+(sel?'#221100':'#111')+';'+bg+'min-height:120px;position:relative;">';
    html += '<div style="background:rgba(0,0,0,0.7);padding:8px;border-radius:6px;position:relative;z-index:1">';
    html += '<div style="width:40px;height:40px;border-radius:50%;background:'+av.color+';display:inline-block;vertical-align:middle;margin-right:10px"></div>';
    html += '<b style="color:#fc0">'+av.name+'</b>';
    if(isAdultOnly(av.id)) html += ' <span style="background:#f00;color:#fff;font-size:10px;padding:2px 4px;border-radius:3px">18+</span>';
    html += '<br>';
    html += '<i style="color:#aaa">'+av.desc+'</i><br>';
    if(!sel) html += '<button onclick="selectAvatar(\''+av.id+'\')" style="margin-top:5px">SELECT</button>';
    else html += '<span style="color:#fc0">ACTIVE</