<!-- NEW1 — TEST 1 · THE LIVING DISTRICT · part 4 -->
 + (rng() * 2 - 1) * pitch.hd;
  }

  /* ---------------- per-frame nerves ---------------- */
  function update(dt /*, t */) {
    dt = Math.min(dt, 0.05);
    for (const c of crowd) {
      if (c.kind === 'walk') {
        c.s += c.speed * dt;
        c.phase += dt * c.speed * 3.4;
        const p = c.path.at(c.s);
        c.rig.root.position.set(p.x, 0, p.z);
        faceToward(c.rig.root, p.dx, p.dz);
        poseGait(c.rig, c.phase, 0.55, 0.06, 0.7);
      } else if (c.kind === 'run') {
        c.a += c.angSpeed * dt;
        c.phase += dt * 9.2;
        const p = c.path.at(c.a);
        c.rig.root.position.set(p.x, 0, p.z);
        faceToward(c.rig.root, p.dx, p.dz);
        poseGait(c.rig, c.phase, 0.95, 0.22, 1.25);
      } else if (c.kind === 'bike') {
        c.s += c.speed * dt;
        c.phase += dt * (c.speed / 0.34) * 0.55; // pedal cadence from wheel speed
        const p = c.path.at(c.s);
        c.holder.position.set(p.x, 0, p.z);
        faceToward(c.holder, p.dx, p.dz);
        c.holder.rotation.z = Math.sin(c.phase * 0.5) * 0.015;
        const spin = (c.speed / 0.34) * dt;
        c.bike.wF.rotation.x += spin;
        c.bike.wB.rotation.x += spin;
        posePedal(c.rig, c.phase);
      } else if (c.kind === 'foot') {
        const dx = c.tx - c.x, dz = c.tz - c.z;
        const dist = Math.hypot(dx, dz);
        let moving = 0;
        if (dist > 0.25) {
          const step = Math.min(dist, c.speed * dt);
          c.x += (dx / dist) * step; c.z += (dz / dist) * step;
          c.phase += dt * c.speed * 3.1;
          moving = 1;
          faceToward(c.rig.root, dx / dist, dz / dist);
        } else if ((c.wait -= dt) <= 0) {
          newTarget(c); c.wait = 0.6 + rng() * 2.2;
        }
        c.rig.root.position.set(c.x, 0, c.z);
        if (moving) poseGait(c.rig, c.phase, 0.7, 0.13, 0.95);
        else { // idle: breathe, shift weight, watch the game
          poseIdle(c.rig, c.phase * 0.25, 1); // phase ticks 4x/s; /4 = seconds
          c.phase += dt * 4;
        }
      }
    }

    /* the ball: rests at the holder's feet, then a kicked pass arcs over */
    if (game.flying) {
      const f = game.flying;
      f.k += dt / f.dur;
      if (f.k >= 1) {
        game.holder = f.to; game.flying = null; game.rest = 0.9 + rng() * 1.6;
        ball.position.set(f.to.x, 0.16, f.to.z);
      } else {
        const x = f.x0 + (f.x1 - f.x0) * f.k;
        const z = f.z0 + (f.z1 - f.z0) * f.k;
        const y = 0.16 + Math.sin(f.k * Math.PI) * f.h;
        ball.position.set(x, y, z);
        ball.rotation.x += dt * 7;
      }
    } else {
      const h = game.holder;
      ball.position.set(h.x + Math.sin(h.rig.root.rotation.y) * 0.35, 0.16,
                        h.z + Math.cos(h.rig.root.rotation.y) * 0.35);
      if ((game.rest -= dt) <= 0) {
        let to = h;
        while (to === h) to = footies[Math.floor(rng() * footies.length)];
        const d = Math.hypot(to.x - h.x, to.z - h.z);
        game.flying = {
          x0: ball.position.x, z0: ball.position.z, x1: to.x, z1: to.z,
          k: 0, dur: Math.max(0.45, d * 0.09), h: 0.5 + d * 0.08, to,
        };
        newTarget(to); // receiver shuffles to meet it
      }
    }
  }

  return { group, update };
}

/* Export both ways: page module script and bundler-style.
 * makeCitizens is the crowd whole; makeFigure, makeBike, poses and
 * gait are the same craft in pieces, for the life director to drive. */
const EXPORTS = { makeCitizens, makeFigure, makeBike, poses, gait };
if (typeof module !== 'undefined' && module.exports) module.exports = EXPORTS;
if (typeof window !== 'undefined') Object.assign(window, EXPORTS);


===== FILE: public/new1/city-layout.js =====
/* city-layout.js — THE CITYWRIGHT's piece for the King's /new1 test.
 *
 * A massive flat city district, generated from a data list
 * (list-into-standing: the COMPLEXES array drives everything;
 * no building is hand-placed). Vanilla JS, no external assets,
 * no textures — THREE is passed in by the page.
 *
 * Everything sits on y=0 flat. Roads, sidewalks, parking stalls,
 * stop lights, a river with bridges, a park with a lake.
 *
 * export: buildCity(THREE) -> { group, meta }
 *   meta.complexes: [{ name, kind, center:{x,z} }, ...]
 *   meta.houses:    [{ x, z, suburb, door:{x,z} }, ...] — every suburb
 *                   house's address (for the life director: a home each)
 *   meta.streets:   { xs:[...], zs:[...] } — street center lines,
 *                   the lattice a router walks
 *   meta.riverBand: { zMin, zMax } — the river channel's span; it may
 *                   only be crossed at meta.bridges' street columns
 *   (the doorway / activity layer will read meta later)
 */

'use strict';

/* ---------- deterministic seed (fixed: the city is the same city
 * on every visit — a place, not a dice roll) ---------- */
function mulberry32(seed) {
  let a = seed >>> 0;
  return function () {
    a |= 0; 