<!-- NEW1 — TEST 1 · THE LIVING DISTRICT · part 10 -->
dMove { right: 14px; bottom: 24px; flex-direction: column; }
  .padCluster button {
    width: 64px; height: 64px; border-radius: 50%; border: 1px solid rgba(246,217,123,.55);
    background: rgba(10,12,10,.55); color: #f6d97b; font-size: 24px; line-height: 1;
    touch-action: none; -webkit-user-select: none; user-select: none; cursor: pointer;
  }
  .padCluster button.on { background: rgba(216,169,68,.75); color: #241a02; }
  #app canvas { touch-action: none; }
</style>
</head>
<body>
<div id="app"></div>

<div class="masthead">
  <div class="kicker">A test at /new1 · made known to all</div>
  <h1>THE BLOCK CITY</h1>
  <div class="sub">the whole district on the game map floor — and now every citizen has a house, a job, and a schedule</div>
  <div class="crew">The Citywright · The Nervesmith · The Stagehand — lives directed by Solid, at the King's word</div>
</div>
<div class="census" id="census">laying the floor…</div>
<button id="enterBtn" type="button">ENTER THE CITY</button>
<div id="pad">
  <div class="padCluster padTurn">
    <button type="button" data-k="left" aria-label="turn left">◀</button>
    <button type="button" data-k="right" aria-label="turn right">▶</button>
  </div>
  <div class="padCluster padMove">
    <button type="button" data-k="fwd" aria-label="walk forward">▲</button>
    <button type="button" data-k="back" aria-label="walk back">▼</button>
  </div>
</div>

<!-- the citizens factory is a classic script: it registers window.makeFigure / makeBike / poses / gait -->
<script src="citizens.js?v=2"></script>

<script type="module">
import * as THREE from './lib/three.module.js';
import { makeStage } from './stage.js?v=2';
import { buildCity } from './city-layout.js?v=2';
import { makeLife } from './life.js?v=1';
import { makeKing } from './enter.js?v=1';

/* ---------- diagnostics (the gate reads these; the King sees the census) ---------- */
const diag = window.__NEW1 = { frames: 0, errors: [], citizens: 0, complexes: 0, stoplights: 0, moved: 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: floor, stand layer, fenced camera ----------
 * The stage brings its own scene (sky, fog, lights, floor, stand
 * layer already placed). The page builds inside that scene. */
const stage = makeStage(THREE, renderer, { size: 1200 });
const scene = stage.scene;
const camera = stage.getCamera();

/* the sky's levers: the stage's own sun and hemisphere, found once */
let sunLight = null, hemiLight = null;
scene.traverse((o) => {
  if (o.isDirectionalLight) sunLight = o;
  if (o.isHemisphereLight) hemiLight = o;
});

/* ---------- the city: the list, stood up ---------- */
const city = buildCity(THREE);
scene.add(city.group);
diag.complexes = city.meta.complexes.length;
diag.stoplights = city.meta.stoplights;

/* ---------- the people: lives, directed ----------
 * Each citizen: a house in the suburbs, a job in the city, their own
 * schedule — sleeping at night, working by day, errands and leisure
 * in between, all routed along the streets and over the bridges. */
const pieces = { makeFigure: window.makeFigure, makeBike: window.makeBike, poses: window.poses, gait: window.gait };
const life = makeLife(THREE, city.meta, pieces);
life.group.position.y = stage.groundY(0, 0); // every foot answers to the stand layer
scene.add(life.group);
diag.citizens = life.citizens.length;

if (window.logBuild) window.logBuild('new1 lives: ' + diag.citizens + ' citizens given houses, jobs, schedules; Day 1 opens 06:00, a day runs 12 minutes');

/* ---------- the way in: the King's own figure ----------
 * He stands on the same stand layer, is stopped by the same city
 * (collision measured from the standing geometry), and crosses the
 * river only at bridges. The citizens' lives go on around him. */
const king = makeKing(THREE, pieces, city.meta);
const kingHolder = new THREE.Group();
kingHolder.position.y = stage.groundY(0, 0);
kingHolder.add(king.group);
scene.add(kingHolder);
const colliderCount = king.buildColliders(city.group);
king.spawn(-41, 123, Math.PI); // the street south of the Long Park, facing the city
king.hide();
if (window.logBuild) window.logBuild('new1 entry: the King may enter; ' + colliderCount + ' solids measured for collision');

/* ---------- the sky follows the citizens' clock ---------- */
const SKY_KEYS = [ // hour -> [background, sun intensity, sun color, hemi intensity]
  [0.0, 0x0a0e14, 0.06, 0x8fa3c7, 0.22],
  [5.0, 0x0a0e14, 0.06, 0x8fa3c7, 0.22],
  [6.5, 0x4a3049, 0.55, 0xffb37a, 0.45]