<!-- NEW2 — TEST 2 · THE DISTRICT OF 800 · part 10 -->
dings: 0, uniqueFaces: 0, colliders: 0, calls: 0, triangles: 0 };
window.addEventListener('error', (e) => { diag.errors.push(String(e.message || e.error)); });
const censusEl = document.getElementById('census');

/* ---------- renderer ---------- */
const renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: 'high-performance' });
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('app').appendChild(renderer.domElement);

/* ---------- the stage at district scale ---------- */
const stage = makeStage(THREE, renderer, { size: 2600 });
const scene = stage.scene;
const camera = stage.getCamera();

/* a fixed day over the district — this test is about faces */
let sunLight = null, hemiLight = null;
scene.traverse((o) => {
  if (o.isDirectionalLight) sunLight = o;
  if (o.isHemisphereLight) hemiLight = o;
});
scene.background.setHex(0x87a6c8);
if (scene.fog) scene.fog.color.setHex(0x87a6c8);
if (sunLight) { sunLight.intensity = 1.55; sunLight.color.setHex(0xfff1cf); }
if (hemiLight) hemiLight.intensity = 0.95;

/* ---------- the district: the fashion, the list of 800 ---------- */
const district = buildDistrict(THREE);
scene.add(district.group);
diag.buildings = district.meta.count;
diag.uniqueFaces = district.meta.uniqueFaces;

/* ---------- the King's way in — collision from the list itself ---------- */
const pieces = { makeFigure: window.makeFigure, makeBike: window.makeBike, poses: window.poses, gait: window.gait };
const king = makeKing(THREE, pieces, district.meta);
const kingHolder = new THREE.Group();
kingHolder.position.y = stage.groundY(0, 0);
kingHolder.add(king.group);
scene.add(kingHolder);
diag.colliders = king.setCollidersFromList(district.meta.buildings);
const SPAWN = { x: district.meta.streets.xs[5], z: district.meta.streets.zs[8] };
king.spawn(SPAWN.x, SPAWN.z, Math.PI);
king.hide();
if (window.logBuild) window.logBuild('new2 test2: district of ' + diag.buildings + ' buildings, one fashion, faces unique ' + diag.uniqueFaces + ', colliders ' + diag.colliders);

/* ---------- entering and leaving (the same two worlds as Test 1) ---------- */
const enterBtn = document.getElementById('enterBtn');
let mode = 'sky';
let trans = null;
const _stubCam = { position: new THREE.Vector3(), look: new THREE.Vector3(), lookAt(v) { this.look.copy(v); } };
const _v1 = new THREE.Vector3(), _v2 = new THREE.Vector3();
function boomTarget() {
  _stubCam.position.set(king.x, 99, king.z);
  king.boom(_stubCam, 1000);
  return _stubCam;
}
enterBtn.addEventListener('click', () => {
  if (mode === 'sky') {
    king.spawn(SPAWN.x, SPAWN.z, Math.PI);
    trans = { k: 0, dur: 2.6, fromPos: camera.position.clone(), fromLook: new THREE.Vector3(0, 2, 0) };
    mode = 'diving';
    enterBtn.textContent = '···';
  } else if (mode === 'street') {
    const streetPos = camera.position.clone();
    const streetLook = new THREE.Vector3(king.x + Math.sin(king.yaw) * 5, 1.7, king.z + Math.cos(king.yaw) * 5);
    stage.update(0, clock.elapsedTime);
    trans = { k: 0, dur: 2.2, fromPos: streetPos, fromLook: streetLook, toPos: camera.position.clone(), toLook: new THREE.Vector3(0, 2, 0) };
    camera.position.copy(streetPos);
    mode = 'rising';
    enterBtn.textContent = '···';
  }
});
const smooth = (k) => k * k * (3 - 2 * k);

document.querySelectorAll('#pad button').forEach((btn) => {
  const key = btn.getAttribute('data-k');
  const on = (e) => { e.preventDefault(); king.input[key] = true; btn.classList.add('on'); };
  const off = (e) => { e.preventDefault(); king.input[key] = false; btn.classList.remove('on'); };
  btn.addEventListener('pointerdown', on);
  btn.addEventListener('pointerup', off);
  btn.addEventListener('pointercancel', off);
  btn.addEventListener('pointerleave', off);
});
let dragId = null, dragX = 0, dragY = 0;
renderer.domElement.addEventListener('pointerdown', (e) => { dragId = e.pointerId; dragX = e.clientX; dragY = e.clientY; });
renderer.domElement.addEventListener('pointermove', (e) => {
  if (dragId !== e.pointerId || mode !== 'street') return;
  king.look((dragX - e.clientX) * 0.0052);
  king.lift((dragY - e.clientY) * 0.02);
  dragX = e.clientX; dragY = e.clientY;
});
renderer.domElement.addEventListener('pointerup', () => { dragId = null; });
renderer.domElement.addEventListener('pointercancel', () => { dragId = null; });
const KEYMAP = { ArrowUp: 'fwd', KeyW: 'fwd', ArrowDown: 'back', KeyS: 'back', ArrowLeft: 'left', KeyA: 'left', ArrowRight: 'right', KeyD: 'right' };
window.addEventListener('keydown', (e) => { const k = KEYMAP[e.code]; if (k) { king.input[k] = true; e.preventDefault(); } });
window.addEventListener('keyup', (e) => { const k = KEYMAP[e.code]; if (k) { king.input[k] = false; e.preventDefault(); } });

const CROWNS = { lip: 'a parapet lip', cap: 'a flat cap', step: 'a stepped cap', spire: 'a spire' };
function neare