<!-- RUBY-BACKUP · part 168 -->
nt.getElementById('controldesk');
  if(!d) return;
  var codes = DESK_CATS[DESK_CAT] || [];
  var perPage = 25;
  var pages = Math.ceil(codes.length/perPage);
  var start = DESK_PAGE*perPage;
  var pageCodes = codes.slice(start, start+perPage);
  var html = '<b style="color:#0ff">CONTROL DESK — '+DESK_CAT+'</b> ';
  html += '<button onclick="hideDesk()">EXIT</button><br><br>';
  /* categories */
  html += 'CAT: ';
  for(var cat in DESK_CATS){
    html += '<button onclick="deskCat(\''+cat+'\')"'+(cat===DESK_CAT?' style="background:#0ff"':'')+'>'+cat+'</button> ';
  }
  html += '<br><br>';
  /* codes */
  pageCodes.forEach(function(code){
    var inPad = DESK_PAD.indexOf(code)>=0;
    html += '<div style="padding:3px;border-bottom:1px solid #033">';
    html += '<span style="color:#0ff">'+code+'</span> ';
    html += '<button onclick="deskInfo(\''+code+'\')">INFO</button> ';
    html += '<button onclick="deskAdd(\''+code+'\')"'+(inPad?' disabled':'')+'>'+(inPad?'IN PAD':'+ PAD')+'</button>';
    html += '</div>';
  });
  /* pagination */
  html += '<br>';
  if(DESK_PAGE>0) html += '<button onclick="deskPage(-1)">PREV</button> ';
  html += 'Page '+(DESK_PAGE+1)+'/'+Math.max(1,pages)+' ';
  if(DESK_PAGE<pages-1) html += '<button onclick="deskPage(1)">NEXT</button>';
  html += '<br><br><b>Chart Pad ('+DESK_PAD.length+'):</b> '+DESK_PAD.join(', ');
  d.innerHTML = html;
}
function deskCat(cat){ DESK_CAT=cat; DESK_PAGE=0; renderDesk(); }
function deskPage(d){ DESK_PAGE+=d; renderDesk(); }
function deskInfo(code){ codeStatus(code+' — use the code directly, or add to pad'); }

/* TUTORIAL — simple steps for new users */
var TUT_STEP = 0;
function tutorial(){
  var steps = [
    'Step 1: Type "soliditronium" — the dome rises.',
    'Step 2: Type "enter" — you go inside, crown camera.',
    'Step 3: The desk opens. Pick a category (Building, Moving...).',
    'Step 4: Tap + PAD on codes you like. They gather.',
    'Step 5: Tap EXIT — you carry the Continuum.',
    'Step 6: Type "continuum" anywhere — your pad opens.',
    'Done! You know the Soliditronium. Now play.'
  ];
  codeStatus(steps[TUT_STEP % steps.length] + ' (tutorial '+(TUT_STEP%steps.length+1)+'/'+steps.length+')');
  TUT_STEP++;
}
/* KID FUN — the ancestors' gifts */
function kidPlay(){
  /* random colorful creation at spawn */
  var sp = getSpawnPoint();
  var colors = ['#ff0000','#ff8800','#ffff00','#00ff00','#0088ff','#ff00ff'];
  var col = colors[Math.floor(Math.random()*colors.length)];
  if(typeof placeStone==='function'){
    for(var i=0; i<5; i++){
      placeStone(sp.x+Math.floor(Math.random()*5)-2, sp.z+Math.floor(Math.random()*5)-2, 2, 'b', true, true, i, true);
    }
  }
  codeStatus('the ancestors surprise you with '+col+' joy!');
}
function kidRainbow(){
  if(typeof mePos==='undefined') return;
  var px = Math.round(mePos.x), pz = Math.round(mePos.z);
  var colors = ['#ff0000','#ff8800','#ffff00','#00ff00','#0088ff','#8800ff'];
  if(typeof placeStone==='function'){
    for(var i=0; i<12; i++){
      var ang = Math.PI * i/11;
      var x = px + Math.round(Math.cos(ang)*8);
      var z = pz + Math.round(Math.sin(ang)*4);
      var y = Math.round(Math.sin(ang)*6);
      placeStone(x, z, 2, 'b', true, true, y, true);
    }
  }
  codeStatus('a rainbow arcs across your sky!');
}
function kidTreasure(){
  if(typeof mePos==='undefined') return;
  var px = Math.round(mePos.x), pz = Math.round(mePos.z);
  var tx = px + Math.floor(Math.random()*10)-5;
  var tz = pz + Math.floor(Math.random()*10)-5;
  if(typeof placeStone==='function'){
    placeStone(tx, tz, 3, 'b', true, true, 0, true);
  }
  codeStatus('treasure hidden nearby... find the gold!');
}
/* CONTINUUM LIMIT — max 25, the Law */
function deskAdd(code){
  if(DESK_PAD.indexOf(code)>=0) return;
  if(DESK_PAD.length >= 25){
    codeStatus('Continuum full (25) — remove one first: padremove <code>');
    return;
  }
  DESK_PAD.push(code);
  try{ if(typeof continuumGathered==='function') continuumGathered(); }catch(e){}
  try{ localStorage.setItem('ruby-chartpad', JSON.stringify(DESK_PAD)); }catch(e){}
  codeStatus(code+' added to Continuum ('+DESK_PAD.length+'/25)');
  if(typeof renderDesk==='function') renderDesk();
}
function padRemove(code){
  var i = DESK_PAD.indexOf(code);
  if(i>=0){
    DESK_PAD.splice(i,1);
    try{ localStorage.setItem('ruby-chartpad', JSON.stringify(DESK_PAD)); }catch(e){}
    codeStatus(code+' released ('+DESK_PAD.length+'/25)');
  }else{
    codeStatus(code+' not in your Continuum');
  }
}

function hideDesk(){
  var d = document.getElementById('controldesk');
  if(d) d.style.display='none';
  /* exiting — grant the Continuum */
  codeStatus('you carry the Continuum — use "continuum" to open your chart pad');
}
function loadPad(){
  try{ DESK_PAD = JSON.parse(localStorage.getItem('ruby-chartpad')||'[]'); }catch(e){ DESK_PAD=[]; }
}
setTimeout(loadPad, 2000);

/* CONTINUUM — portable chart pad, context-aware code suggestions */

/* CO