<!-- SOLID CITY · part 2576 -->
) {
    // a pitched top face projects short onto the plan — on the steep benches
    // (a 120% grade pitches 50 degrees) neighbouring faces would leave
    // pinholes at every joint: one was measured open at (1207,-1663), the
    // steepest joint in the district. The registered plane is therefore
    // stretched along its pitch by 1/cos(rx) (capped), so joints overlap in
    // plan; both planes pass through the shared joint height, so the
    // overlap crowns by centimetres where a gap would have swallowed a wheel.
    var ext = Math.min(1.7, 1 / Math.max(0.55, Math.cos(rx || 0)));
    var m = M4(cx, cy, cz, ang, rx || 0, 0), hw = w / 2, hl = len / 2 * ext, out = [];
    var cs = [[-hw, -hl], [hw, -hl], [hw, hl], [-hw, hl]];
    for (var i = 0; i < 4; i++) { var v = new T.Vector3(cs[i][0], topOff, cs[i][1]).applyMatrix4(m); out.push(v.x, v.y, v.z); }
    standTris.push(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8]);
    standTris.push(out[0], out[1], out[2], out[6], out[7], out[8], out[9], out[10], out[11]);
  }
  function setHome(x, z, y, ry) {
    HOME = { x: x, z: z, y: y, ry: ry, cos: Math.cos(ry), sin: Math.sin(ry) };
    BASE = M4(x, y, z, ry, 0, 0);
  }
  function clearHome() { HOME = null; BASE = new T.Matrix4(); }

  /* ================= THE HOME FACTORY =================
   * Local frame: origin at pad top center, +z = front (door/lanai side), floor at y=0.
   * Styles (King's verified guide):
   *   waa        — Hale Wa'a: A-FRAME steep thatch-look roof, stone foundation, door centered in side wall
   *   noa        — Hale Noa: enclosed traditional, steep thatch gable, low wood walls
   *   plantation — gable roof, single-wall siding, front porch, post-and-pier foundation
   *   dickey     — DICKEY double-pitch hip roof, lava-rock piers/columns, board-and-batten, enclosed lanai
   *   mission    — high-pitched gable, clapboard, plain form
   */
  function gableEnds(w, d, wh, rise, color) {
    var g1 = prismGeo(d / 2, rise, 0.34), g2 = prismGeo(d / 2, rise, 0.34);
    put(solid, g1, -(w / 2 - 0.17), wh, 0, 0, 0, 0, color);
    put(solid, g2, (w / 2 - 0.17), wh, 0, 0, 0, 0, color);
  }
  function gableRoof(w, d, wh, rise, color, ov) {
    ov = ov == null ? 0.9 : ov;
    var hd = d / 2 + ov, sl = Math.hypot(hd, rise), th = Math.atan2(rise, hd);
    box(solid, w + 2 * ov, 0.18, sl, 0, wh + rise / 2 + 0.1, hd / 2, color, 0, th, 0);
    box(solid, w + 2 * ov, 0.18, sl, 0, wh + rise / 2 + 0.1, -hd / 2, color, 0, -th, 0);
    box(solid, w + 2 * ov + 0.3, 0.22, 0.5, 0, wh + rise + 0.14, 0, C.woodDark);   // ridge cap
  }
  function putS(batch, geo, x, y, z, ry, sx, sy, sz, color) {
    _e.set(0, ry || 0, 0, 'YXZ'); _q.setFromEuler(_e);
    var m = new T.Matrix4().compose(new T.Vector3(x, y, z), _q.clone(), new T.Vector3(sx, sy, sz));
    if (BASE) m.premultiply(BASE);
    batch.add(geo, m, color);
  }
  function dickeyRoof(w, d, wh, color) {
    var ovLo = 1.7;
    var lo = new T.CylinderGeometry(0.60, 1, 1.2, 4);
    putS(solid, lo, 0, wh + 0.6, 0, Math.PI / 4, (w / 2 + ovLo) / 0.7071, 1, (d / 2 + ovLo) / 0.7071, color);
    // upper steep pitch sits INSIDE the lower section's top square
    var hiBotW = 0.60 * (w / 2 + ovLo) - 0.45, hiBotD = 0.60 * (d / 2 + ovLo) - 0.45;
    var hi = new T.CylinderGeometry(0.16, 0.60, 2.6, 4);
    putS(solid, hi, 0, wh + 1.2 + 1.3, 0, Math.PI / 4, hiBotW / (0.60 * 0.7071), 1, hiBotD / (0.60 * 0.7071), color);
    box(solid, w * 0.3, 0.2, d * 0.26, 0, wh + 3.9, 0, C.woodDark);
  }
  function wallSegs(w, d, wh, wallColor, doorHalf, winGlow) {
    // front wall (z=+d/2) with centered door gap 1.7 wide
    var doorTop = Math.min(2.35, wh - 0.12), segW = (w / 2 - doorHalf);
    box(solid, segW, wh, 0.28, -(doorHalf + segW / 2), wh / 2, d / 2, wallColor);
    box(solid, segW, wh, 0.28, (doorHalf + segW / 2), wh / 2, d / 2, wallColor);
    footprint(-(doorHalf + segW / 2), d / 2, segW, 0.5, 0, wh);
    footprint((doorHalf + segW / 2), d / 2, segW, 0.5, 0, wh);
    if (wh - doorTop > 0.05) {
      box(solid, doorHalf * 2, wh - doorTop, 0.28, 0, doorTop + (wh - doorTop) / 2, d / 2, wallColor);  // lintel
      footprint(0, d / 2, doorHalf * 2, 0.5, doorTop, wh);   // blocks only above head height at floor level
    }
    // back wall + side walls
    box(solid, w, wh, 0.28, 0, wh / 2, -d / 2, wallColor);
    box(solid, 0.28, wh, d, -w / 2, wh / 2, 0, wallColor);
    box(solid, 0.28, wh, d, w / 2, wh / 2, 0, wallColor);
    footprint(0, -d / 2, w, 0.5, 0, wh);
    footprint(-w / 2, 0, 0.5, d, 0, wh);
    footprint(w / 2, 0, 0.5, d, 0, wh);
    if (winGlow) {   // warm window panes: sides + back (thin boxes read from both sides)
      box(glowB, 0.1, 1.1, 1.6, -w / 2, 1.7, -d / 5, C.warm);
      box(glowB, 0.1, 1.1, 1.6, w / 2, 1.7, d / 5, C.warm);
      box(glowB, 1.7, 1.1, 0.1, -w / 5, 1.7, -d / 2, C.warm);
      box(glowB, 1.7, 1.1, 0.1, w / 4, 1.7, -d / 2, C.warm);
      // dark-framed glass door row flanking th