<!-- SOLID CITY · part 2950 -->
c(b.x,b.y,3,0,6.28);ctx.fill()});
    var mvangle=Math.atan2(state.player.vy,state.player.vx||100)*.25;ship(state.wing.x,state.wing.y,mvangle,colors.teal,.72);ship(state.player.x,state.player.y,mvangle,colors.gold,1.05);
    state.particles.forEach(function(p){ctx.globalAlpha=Math.max(0,p.life);ctx.fillStyle=p.c;ctx.fillRect(p.x,p.y,2,2)});ctx.globalAlpha=1;
    var wp=owners.weapon==='human'?input.weapon:aiWeapon();ctx.strokeStyle=owners.weapon==='human'?colors.gold:colors.teal;ctx.globalAlpha=.45;ctx.setLineDash([4,6]);ctx.beginPath();ctx.moveTo(state.player.x,state.player.y);ctx.lineTo(state.player.x+wp.x*110,state.player.y+wp.y*110);ctx.stroke();ctx.setLineDash([]);ctx.globalAlpha=1;
  }
  function loop(t){var dt=Math.min(.033,(t-last)/1000||.016);last=t;update(dt);draw();if(state.running)raf=requestAnimationFrame(loop)}
  reset();draw();
})();
</script>
</body>
</html>


===== FILE: public/city/ring-city-place.js =====
/* Solid City — places THE RING CITY OF THE ANCESTORS
 * (public/city/ring-city.js) on the Ancestral Roads terrace,
 * and its SKY TWIN above it.
 * "Build the city on these rings — fill this terrace." — the
 * King, 2026-10-14; and then: "Build another in the sky above
 * it — glass floor to see it from below."
 * The placer waits for the terrace itself, takes its height
 * from the terrace's own law (CityAncestorRoads.topY), lays
 * the ground city in the bands between the roads, and raises
 * the twin 140 metres above it on a glass floor with a gold-
 * ringed keel. Standing hooks (CityRingCity.standY) serve
 * both cities and were added to updateWalk and standingAt in
 * the same breath, as the Law of the Two Lists commands. */
(function () {
'use strict';
if (!window.SC || !SC.api) return;
var A = SC.api, S = A.S;
var POS = { x: 0, z: -1600 };
var SKY_LIFT = 140;
var M = { state: 'idle', wait: 4.2, cities: [] };
function addFootprint(b) {
  /* the factory's frame runs local X along the tangent
   * (-sin a, cos a) and local Z along the radius (cos a, sin a) */
  var tx = -Math.sin(b.a), tz = Math.cos(b.a), rx = Math.cos(b.a), rz = Math.sin(b.a);
  var nx = Math.max(1, Math.ceil(b.w / 2.5)), nz = Math.max(1, Math.ceil(b.d / 2.5));
  var cw = b.w / nx, cd = b.d / nz;
  for (var i = 0; i < nx; i++) for (var j = 0; j < nz; j++) {
    var ox = -b.w / 2 + cw * (i + 0.5), oz = -b.d / 2 + cd * (j + 0.5);
    var cx = b.x + tx * ox + rx * oz, cz = b.z + tz * ox + rz * oz;
    var hx = cw / 2 * Math.abs(tx) + cd / 2 * Math.abs(rx), hz = cw / 2 * Math.abs(tz) + cd / 2 * Math.abs(rz);
    A.solids.push({ x0: cx - hx, x1: cx + hx, z0: cz - hz, z1: cz + hz, y0: b.y0, y1: b.y1, ringCity: true });
  }
}
function hyperStop(id, name, short, x, z, standX, standZ, alias, text) {
  var H = window.CityHyper; if (!H || !H.pois) return;
  if (H.pois.some(function (p) { return p.id === id; })) return;
  H.pois.push({ id: id, name: name, short: short, x: x, z: z, stand: { x: standX, z: standZ }, alias: alias, text: text });
  if (H.regrid) H.regrid();
}
function hyperStops() {
  hyperStop('ring-city', 'THE RING CITY OF THE ANCESTORS', 'RING CITY', POS.x, POS.z, POS.x, POS.z + 470,
    'ring city ancestors terrace rings houses hotels mansions market',
    'The city the Ancestral Roads were drawn for, raised by the King\'s word on October 14, 2026: houses, pavilions, gardens and markets in the bands between the five brick rings — the First Hearth at the flame, then the Voyagers, the Chiefs, the Unifiers, the Builders, and the Family Ring at the rim. No road was covered and no ancestor moved.');
  M.cities.forEach(function (ct) {
    if (!ct.port) return;
    var a = 4.45, inw = 24;
    var sx = ct.port.x - Math.cos(a) * inw, sz = ct.port.z - Math.sin(a) * inw;
    if (ct.sky) {
      hyperStop('sky-ring-city', 'THE SKY RING CITY', 'SKY RINGS', POS.x, POS.z, POS.x, POS.z + 300,
        'sky ring city glass floor above ancestors terrace twin',
        'The twin of the Ring City, floating 140 metres above the Ancestral Roads on a floor of glass: stand on it and the whole terrace city turns below your feet; from the ground, its keel reads in gold rings against the sky.');
      hyperStop('sky-ring-port', 'SKY RING PORT', 'PORT', ct.port.x, ct.port.z, sx, sz,
        'sky ring port shuttle landing glass city',
        'The sky port of the Sky Ring City, where the shuttles of the living sky come and go above the ancestors.');
    } else {
      hyperStop('ring-city-port', 'RING CITY PORT', 'PORT', ct.port.x, ct.port.z, sx, sz,
        'ring city port sky shuttle landing ancestors',
        'The sky port of the Ring City: a stone disc with a gold ring on the Family Ring, where the shuttles of the living sky come and go above the ancestors\' terrace.');
    }
  });
}
async function build() {
  if (M.state !== 'idle') return;
  M.state = 'building';
  try {
    var mod = await import('/city/ring-city.js?v=20261014e');
    var topY = window.CityAncestorRoads.topY();
    [{ y: topY, sky: 