<!-- RUBY-BACKUP · part 329 -->
ht:1;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent;';
    btn.onclick = function(){
      if(!confirm('Clear all cached game data and reload fresh?')) return;
      try{
        // clear Cache API
        if('caches' in window){
          caches.keys().then(function(names){
            names.forEach(function(n){ caches.delete(n); });
          });
        }
        // clear storage
        try{ localStorage.clear(); }catch(e){}
        try{ sessionStorage.clear(); }catch(e){}
        // unregister service workers
        if('serviceWorker' in navigator){
          navigator.serviceWorker.getRegistrations().then(function(regs){
            regs.forEach(function(r){ r.unregister(); });
          });
        }
      }catch(e){}
      // hard reload with fresh timestamp
      setTimeout(function(){
        window.location.href = window.location.pathname + '?fresh=' + Date.now();
      }, 500);
    };
    document.body.appendChild(btn);
  }catch(e){}
})();
/* THE GROUND — floor, land, streets, grass, babysteps, all one. Never off, never missing. */
window._ground = window._ground || {};
function registerGroundPart(name, obj){
  try{
    window._ground[name] = obj;
    // the ground is always visible — never turn off
    if(obj) obj.visible = true;
  }catch(e){}
}
/* STREETS ON START — permanent, guaranteed */
/* signs load with streets */
setTimeout(function(){
  try{ if(typeof buildHighwaySigns==='function' && !window._highwaySigns) buildHighwaySigns(); }catch(e){}
}, 3000);
function ensureStreets(){
  try{
    var inScene = false;
    if(window._streets && typeof scene!=='undefined'){
      // check if actually in the scene
      scene.traverse(function(o){ if(o===window._streets) inScene = true; });
    }
    if(typeof buildStreets==='function' && !inScene){
      buildStreets(); // re-add if missing from scene, never null out
    }
  }catch(e){}
  // keep trying until they're truly in the scene
  var ok = false;
  try{
    if(window._streets && typeof scene!=='undefined'){
      scene.traverse(function(o){ if(o===window._streets) ok = true; });
    }
  }catch(e){}
  if(!ok){
    setTimeout(ensureStreets, 1000);
  }
}
setTimeout(ensureStreets, 1500); /* build once on start, signs ride along */
/* INFRASTRUCTURE — intersections, crossings, stations, ports */
function buildInfrastructure(){
  try{
    if(window._infra) return;
    var g = new THREE.Group();
    var concMat = new THREE.MeshStandardMaterial({color:0x4a4a4a, roughness:0.9});
    var yellowMat = new THREE.MeshStandardMaterial({color:0xffd700, emissive:0xffd700, emissiveIntensity:0.4});
    var redMat = new THREE.MeshStandardMaterial({color:0xcc0000, emissive:0x550000, emissiveIntensity:0.5});
    var glassMat = new THREE.MeshStandardMaterial({color:0x88ccff, roughness:0.2, metalness:0.8, transparent:true, opacity:0.7});

    // INTERSECTIONS — roundabouts where highways meet the plaza ring
    [[30,0],[-30,0],[0,30],[0,-30]].forEach(function(pt){
      var r = new THREE.Mesh(new THREE.CylinderGeometry(6, 6, 0.3, 16), concMat);
      r.position.set(pt[0], 10.1, pt[1]);
      r.name = 'intersection';
      g.add(r);
      var ring = new THREE.Mesh(new THREE.TorusGeometry(5, 0.2, 8, 24), yellowMat);
      ring.position.set(pt[0], 10.3, pt[1]);
      ring.rotation.x = Math.PI/2;
      ring.name = 'intersection-ring';
      g.add(ring);
    });

    // TRAIN CROSSINGS — tracks crossing highways with gates
    [[200,30],[400,-50],[-30,400]].forEach(function(pt, idx){
      // tracks (perpendicular to highway)
      var track = new THREE.Mesh(new THREE.BoxGeometry(30, 0.2, 3), new THREE.MeshStandardMaterial({color:0x2a2a2a}));
      track.position.set(pt[0], 10.2, pt[1]);
      track.rotation.y = Math.PI/4 * idx;
      track.name = 'train-track';
      g.add(track);
      // crossing gates
      [-8, 8].forEach(function(off){
        var post = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.2, 4, 8), redMat);
        post.position.set(pt[0]+off, 12, pt[1]+off);
        post.name = 'crossing-post';
        g.add(post);
        var arm = new THREE.Mesh(new THREE.BoxGeometry(6, 0.3, 0.3), new THREE.MeshStandardMaterial({color:0xffffff}));
        arm.position.set(pt[0]+off, 13.5, pt[1]+off);
        arm.name = 'crossing-arm';
        g.add(arm);
      });
      // warning sign
      var sign = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 0.2),
        new THREE.MeshStandardMaterial({color:0xffd700, emissive:0xffaa00, emissiveIntensity:0.6}));
      sign.position.set(pt[0]+12, 12, pt[1]);
      sign.name = 'crossing-sign';
      g.add(sign);
    });

    // BUS STATION — near the plaza
    (function(){
      var bx=50, bz=-60;
      // main terminal
      var term = new THREE.Mesh(new THREE.BoxGeometry(30, 8, 15), concMat);
      term.position.set(bx, 4, bz);
      term.name = 'bus-terminal';
      g.add(term);
      // glass front
      var front = new THREE.Mesh(new THREE.BoxGeometry(28, 5, 0.5), glassMat