<!-- RUBY-BACKUP · part 448 -->
ction getProgress(){
  try{
    return JSON.parse(localStorage.getItem('ruby-progress')||'{}');
  }catch(e){ return {}; }
}
/* what "all you could do" means */
var COMPLETION_KEYS = [
  'met_solid',      /* met Solid */
  'did_quest',      /* completed a quest */
  'filled_max',     /* Continuum to 25 */
  'saw_hokulea',    /* saw the mother ship */
  'visited_city',   /* built the city */
  'visited_dark',   /* saw the dark places */
  'helped_soul',    /* helped a funny soul */
  'asked_solid'     /* asked Solid a question */
];
function checkEnding(){
  var prog = getProgress();
  var done = COMPLETION_KEYS.filter(function(k){ return prog[k]; });
  if(done.length >= COMPLETION_KEYS.length){
    /* the game ends */
    showEnding();
  }
  return done.length;
}
function showEnding(){
  try{
    if(localStorage.getItem('ruby-ended')==='1') return; /* only once */
    localStorage.setItem('ruby-ended', '1');
  }catch(e){}
  var div = document.createElement('div');
  div.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;background:radial-gradient(ellipse at center, rgba(20,10,40,0.95) 0%, rgba(5,2,15,0.98) 100%);display:flex;flex-direction:column;justify-content:center;align-items:center;color:#ffeebb;font-family:Georgia,serif;text-align:center;padding:40px;';
  div.innerHTML = '<div style="font-size:42px;color:#ffd700;margin-bottom:30px;">✦</div>'
    + '<div style="font-size:28px;font-style:italic;margin-bottom:20px;line-height:1.6;">'
    + 'You did all you could do.'
    + '</div>'
    + '<div style="font-size:18px;opacity:0.85;line-height:1.8;max-width:600px;">'
    + 'You met Solid. You helped the souls.<br>'
    + 'You walked the ancestral streets.<br>'
    + 'You saw Hokulea in orbit.<br>'
    + 'The ancestors were gracious.<br><br>'
    + 'The last King built this for you.<br>'
    + 'And you — you did all you could do.<br><br>'
    + '<span style="color:#ffd700;">This is felt by all.</span>'
    + '</div>'
    + '<div style="margin-top:40px;font-size:14px;opacity:0.6;">The game ends. But the map remains.<br>You can always return.</div>'
    + '<button onclick="this.parentElement.remove()" style="margin-top:30px;padding:12px 30px;background:transparent;border:2px solid #ffd700;color:#ffd700;border-radius:8px;font-size:16px;cursor:pointer;">Return to the Map</button>';
  document.body.appendChild(div);
  codeStatus('the ending — you did all you could do');
}
/* hook progress tracking into existing actions */
var _origMeetSolid = meetSolid;
meetSolid = function(){ trackProgress('met_solid'); _origMeetSolid(); };
var _origCompleteQuest = completeQuest;
completeQuest = function(){ trackProgress('did_quest'); _origCompleteQuest(); };
var _origFillMax = fillContinuumMax;
fillContinuumMax = function(){ trackProgress('filled_max'); _origFillMax(); };
var _origHokulea = summonHokulea;
summonHokulea = function(){ trackProgress('saw_hokulea'); _origHokulea(); };
var _origCity = buildAncestralCity;
buildAncestralCity = function(){ trackProgress('visited_city'); _origCity(); };
var _origDark = buildDarkPlaces;
buildDarkPlaces = function(){ trackProgress('visited_dark'); _origDark(); };
var _origAsk = solidAnswer;
solidAnswer = function(q){ trackProgress('asked_solid'); _origAsk(q); };
function progress(){
  var prog = getProgress();
  var done = COMPLETION_KEYS.filter(function(k){ return prog[k]; });
  codeStatus('progress: '+done.length+'/'+COMPLETION_KEYS.length+' — '+done.join(', '));
}

/* THE EXPANDED WORLD — racing, court, work, influence, updates */
/* SPACE RACING — to Mars, Europa, and beyond */
var RACE_DESTINATIONS = [
  {name: 'Mars', distance: 100, color: 0xff4400},
  {name: 'Europa', distance: 150, color: 0xaaccff},
  {name: 'Titan', distance: 200, color: 0xffcc66},
  {name: 'Enceladus', distance: 180, color: 0xffffff},
  {name: 'Ganymede', distance: 220, color: 0x88aa66}
];
var RACE_ACTIVE = null;
function startRace(destName){
  var dest = RACE_DESTINATIONS.find(function(d){ return d.name.toLowerCase()===destName.toLowerCase(); });
  if(!dest){
    codeStatus('destinations: '+RACE_DESTINATIONS.map(function(d){ return d.name; }).join(', '));
    return;
  }
  codeStatus('racing to '+dest.name+' — distance '+dest.distance+'. Go!');
  RACE_ACTIVE = {dest: dest, progress: 0, start: Date.now()};
  var raceTimer = setInterval(function(){
    if(!RACE_ACTIVE) { clearInterval(raceTimer); return; }
    RACE_ACTIVE.progress += 2 + Math.random()*3;
    if(RACE_ACTIVE.progress >= dest.distance){
      var time = ((Date.now()-RACE_ACTIVE.start)/1000).toFixed(1);
      codeStatus('arrived at '+dest.name+' in '+time+'s! You win.');
      earnPay(100, 'space race to '+dest.name);
      unlockAchievement('Raced to '+dest.name);
      clearInterval(raceTimer);
      RACE_ACTIVE = null;
    }else{
      codeStatus('racing to '+dest.name+' — '+Math.floor(RACE_ACTIVE.progress/dest.distance*100)+'%');
    }
  }, 500);
}
/* COURT — logical arguments and ac