<!-- SAGA3 · part 57 -->
de==='walk' && moving){
      animPhase.walk += 0.15;
      if(playerBody.userData.legL) playerBody.userData.legL.rotation.x = Math.sin(animPhase.walk) * animAmp.walk;
      if(playerBody.userData.legR) playerBody.userData.legR.rotation.x = -Math.sin(animPhase.walk) * animAmp.walk;
      if(playerBody.userData.armL) playerBody.userData.armL.rotation.x = -Math.sin(animPhase.walk) * animAmp.walk * 0.8;
      if(playerBody.userData.armR) playerBody.userData.armR.rotation.x = Math.sin(animPhase.walk) * animAmp.walk * 0.8;
      playerBody.rotation.x = 0;
    } else if(moveMode==='swim'){
      animPhase.swim += 0.1;
      if(playerBody.userData.armL) playerBody.userData.armL.rotation.x = Math.sin(animPhase.swim) * animAmp.swim;
      if(playerBody.userData.armR) playerBody.userData.armR.rotation.x = -Math.sin(animPhase.swim) * animAmp.swim;
      playerBody.rotation.x = -Math.PI/2 + 0.3;
    } else if(moveMode==='fly'){
      /* Fly: tilt only, limbs ease to neutral */
      if(playerBody.userData.legL) playerBody.userData.legL.rotation.x *= 0.9;
      if(playerBody.userData.legR) playerBody.userData.legR.rotation.x *= 0.9;
    }
  }
  /* 1. AUTO-SWIM check */
  if(typeof waterAt !== 'undefined'){
    var wtr = waterAt(kingPos.x, kingPos.z);
    if(wtr && kingPos.y <= wtr.surfaceY + 0.3 && moveMode !== 'swim' && moveMode !== 'fly'){
      moveMode = 'swim';
    } else if(!wtr && moveMode === 'swim'){
      moveMode = 'walk';
    }
  }
  updateCamera();
  renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', function(){
  camera.aspect=window.innerWidth/window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
document.getElementById('boot').style.display='none';
say('Coders100 — all codes organized. Type or tap \u2630.');

})();


/* Wire click sound to all UI buttons */
document.addEventListener('touchstart', function(e){
  var t = e.target;
  if(t && (t.tagName === 'BUTTON' || t.closest('button'))){
    sfx('click');
  }
}, {passive:true});


/* PLAYA 2.0 BUTTON — top-right, opens Playa 2.0 */
(function(){
  if(document.getElementById('playa2-btn')) return;
  var b = document.createElement('button');
  b.id = 'playa2-btn';
  b.innerHTML = '◆';
  b.title = 'Open Playa 2.0';
  b.style.cssText = 'position:fixed;top:12px;right:12px;z-index:9999;' +
    'width:44px;height:44px;border-radius:50%;' +
    'background:#1a1a2e;color:#ffd700;font-size:20px;' +
    'border:2px solid #ffd700;cursor:pointer;' +
    'display:flex;align-items:center;justify-content:center;';
  b.addEventListener('touchstart', function(e){
    e.stopPropagation();
    sfx('click');
    window.location.href = '/ruby';
  }, {passive:true});
  b.addEventListener('click', function(e){
    e.stopPropagation();
    sfx('click');
    window.location.href = '/ruby';
  });
  document.body.appendChild(b);
})();


/* IN-GAME CHAT — talk while building */
(function(){
  if(document.getElementById('game-chat')) return;

  // Chat toggle button (bottom-left)
  var chatBtn = document.createElement('button');
  chatBtn.id = 'game-chat-btn';
  chatBtn.innerHTML = '💬';
  chatBtn.style.cssText = 'position:fixed;top:70px;left:12px;z-index:9999;' +
    'width:44px;height:44px;border-radius:50%;' +
    'background:#1a1a2e;color:#ffd700;font-size:20px;' +
    'border:2px solid #ffd700;cursor:pointer;';
  document.body.appendChild(chatBtn);

  // Chat panel (hidden by default)
  var panel = document.createElement('div');
  panel.id = 'game-chat';
  panel.style.cssText = 'position:fixed;top:120px;left:12px;z-index:9998;' +
    'width:280px;height:300px;background:rgba(10,10,26,0.95);' +
    'border:2px solid #ffd700;border-radius:12px;display:none;' +
    'flex-direction:column;overflow:hidden;';
  panel.innerHTML =
    '<div id="game-chat-msgs" style="flex:1;overflow-y:auto;padding:8px;color:#ffd700;font-size:13px;"></div>' +
    '<div style="display:flex;border-top:1px solid #ffd700;">' +
    '<input id="game-chat-input" placeholder="Talk..." ' +
    'style="flex:1;background:transparent;border:none;color:#ffd700;padding:10px;font-size:14px;outline:none;">' +
    '<button id="game-chat-send" style="background:#ffd700;color:#1a1a2e;border:none;padding:10px 14px;cursor:pointer;">➤</button>' +
    '</div>';
  document.body.appendChild(panel);

  var open = false;
  function toggleChat(){
    open = !open;
    panel.style.display = open ? 'flex' : 'none';
    if(typeof sfx === 'function') sfx('click');
  }
  chatBtn.addEventListener('click', function(e){ e.stopPropagation(); toggleChat(); });
  chatBtn.addEventListener('touchstart', function(e){ e.stopPropagation(); toggleChat(); }, {passive:true});

  var msgs = panel.querySelector('#game-chat-msgs');
  var input = panel.querySelector('#game-chat-input');

  function addMsg(who, text){
    var d = document.createElement('div');
    d.style.cssText = 'margin:4px 0;padding:4px 8px;border-radius:8px;' +
     