<!-- SOLID CITY · part 3690 -->
ribute(verts,3));
    geo.computeVertexNormals();const mesh=new T.Mesh(geo,mat);mesh.receiveShadow=true;g.add(mesh);
  }
  g.userData.triangles=triangles;
}
function landscaping(T,groundAt,safe,g,ward,amount) {
  const trunk=material(T,0x73543e),leaf=material(T,0x6c9470),seat=material(T,0x9a8367);
  const [cx,cz]=ward.anchor;
  for(let i=0;i<amount;i++) {
    const a=i*2.39996,r=12+7*Math.sqrt(i+1),x=cx+r*Math.cos(a),z=cz+r*Math.sin(a);
    if(!diskSafe(safe,x,z,3.2))continue;
    const y=groundAt(x,z);
    cylinder(T,g,trunk,x,y+1.05,z,.13,.18,2.1);
    const crown=new T.Mesh(new T.IcosahedronGeometry(1.3,0),leaf);
    crown.position.set(x,y+2.55,z);g.add(crown);
  }
  for(const [dx,dz] of [[10,7],[-12,-8]]) {
    const x=cx+dx,z=cz+dz;if(!diskSafe(safe,x,z,2.5))continue;
    const y=groundAt(x,z);cube(T,g,seat,x,y+.55,z,2.0,.16,.55);
    for(const px of [-.65,.65])cube(T,g,trunk,x+px,y+.28,z,.14,.52,.38);
  }
}
function createWard(args,id) {
  const ward=WARDS.find(w=>w.id===id);if(!ward)throw Error(`WARD ${id} not defined`);
  const {THREE,groundAt,safe}=ctx(args,ward),g=new THREE.Group();
  g.name=`WARD ${id} — ${ward.name}`;
  g.userData={ward:id,band:ward.band,bounds:{minX:ward.minX,maxX:ward.maxX,minZ:ward.minZ,maxZ:ward.maxZ},
    grossEnvelopeM2:(ward.maxX-ward.minX)*(ward.maxZ-ward.minZ),netUsableM2:'not yet measured',
    previewOnly:true,signPlaced:false};
  if(id===2)pathSlabs(THREE,groundAt,safe,g,ROADS[id]);
  else pathRibbon(THREE,groundAt,safe,g,ROADS[id],id===5?1.5:3);
  if(id>=4)landscaping(THREE,groundAt,safe,g,ward,id===4?8:id===5?12:7);
  addSign(args,ward,g,safe);
  return g;
}
export function createWard2(args){return createWard(args,2)}
export function createWard3(args){return createWard(args,3)}
export function createWard4(args){return createWard(args,4)}
export function createWard5(args){return createWard(args,5)}
export function createWard6(args){return createWard(args,6)}
export function createWard7(args){return createWard(args,7)}
// Approximate net area, measured against the supplied actual exclusion mask.
// Reports error-scale ~ cellSize times boundary perimeter, not an exact survey.
export function measureWardAreas(isAllowed,cellSize=2) {
  if(typeof isAllowed!=='function'||!(cellSize>0))throw Error('verified isAllowed and positive cellSize required');
  const result=WARDS.map(w=>{
    let count=0;
    const nx=Math.ceil((w.maxX-w.minX)/cellSize),nz=Math.ceil((w.maxZ-w.minZ)/cellSize);
    const dx=(w.maxX-w.minX)/nx,dz=(w.maxZ-w.minZ)/nz;
    for(let ix=0;ix<nx;ix++)for(let iz=0;iz<nz;iz++) {
      const x=w.minX+(ix+.5)*dx,z=w.minZ+(iz+.5)*dz;
      if(isAllowed(x,z)===true)count++;
    }
    return {ward:w.id,band:w.band,bounds:[w.minX,w.maxX,w.minZ,w.maxZ],
      grossEnvelopeM2:(w.maxX-w.minX)*(w.maxZ-w.minZ),
      estimatedUsableM2:Math.round(count*dx*dz),sampleCellM2:dx*dz};
  });
  return {wards:result,estimatedTotalM2:result.reduce((s,r)=>s+r.estimatedUsableM2,0),
    note:'Grid estimate; verify mask coverage and compare against the independently reported 181350 m².'};
}

/* ================================================================
   SOLID'S INTEGRATION — the verified mask and the raising of the wards.
   The mask is the survey of 2026-10-13, measured against the true
   groundAt of this world: the shelf band (0.5-11.5 m) less the
   First City podium, the South Lot, and the Long Road corridor.
   ================================================================ */
const SOLID_EXCLUSIONS = [
  { x0: -1512, x1: -1088, z0: -1380, z1: -620 },  // the First City podium — the hood, claimed and kept
  { x0: -1445, x1: -1155, z0: -625,  z1: -443 },  // the South Lot and its rides
  { x0: -1160, x1: -656,  z0: -507,  z1: -489 }   // the Long Road corridor
];
export function isAllowedSolidCity(groundAt) {
  return function (x, z) {
    const g = groundAt(x, z);
    if (!(g >= 0.5 && g <= 11.5)) return false;
    for (const r of SOLID_EXCLUSIONS) if (x >= r.x0 && x <= r.x1 && z >= r.z0 && z <= r.z1) return false;
    return true;
  };
}
export function buildAllWards(THREE, groundAt) {
  const args = { THREE, groundAt, isAllowed: isAllowedSolidCity(groundAt) };
  const root = new THREE.Group(); root.name = 'THE WARDS OF THE NATION';
  const wards = [];
  for (const make of [createWard2, createWard3, createWard4, createWard5, createWard6, createWard7]) {
    const w = make(args); root.add(w); wards.push(w);
  }
  root.userData.wards = wards;
  return { root, wards };
}


===== FILE: public/city/warship-iii/index.html =====
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1, user-scalable=no">
  <meta name="color-scheme" content="light dark">
  <link rel="icon" href="data:,">
  <title>Warship III — The Warden of Meridian Gate</title>
  <style>
    :root{
      color-scheme:light dark;
      --bg:#e8eef1;--panel:#f7fafb;-