<!-- SOLID CITY · part 3621 -->
); walls.position.y = h / 2; g.add(walls);
    var roof = new T.Mesh(new T.ConeGeometry(w * 0.85, 2.2 * s, 4), thatchMat);
    roof.position.y = h + 1.1 * s; roof.rotation.y = Math.PI / 4; g.add(roof);
    var win = new T.Mesh(new T.PlaneGeometry(1.1 * s, 0.9 * s), winMat);
    win.position.set(0, h * 0.55, d / 2 + 0.05); g.add(win);
    var door = new T.Mesh(new T.PlaneGeometry(1.2 * s, 1.9 * s), new T.MeshBasicMaterial({ color: 0xffb050 }));
    door.position.set(0, 0.95 * s, d / 2 + 0.05); g.add(door);
    g.position.set(x, ty, z); g.rotation.y = ry; root.add(g);
    foot.push([x, z, w + 0.8, d + 0.8, ty, ty + h + 2.2 * s, ry]);
  }
  function stiltHut(x, z, ty, ry) {                                       // hut raised on poles
    var s = 1, g = new T.Group(), lift = 3.2;
    var w = 8 * s, d = 6.5 * s, h = 3.4 * s;
    [[-w/2+0.6,-d/2+0.6],[w/2-0.6,-d/2+0.6],[-w/2+0.6,d/2-0.6],[w/2-0.6,d/2-0.6]].forEach(function (p) {
      var pole = new T.Mesh(new T.CylinderGeometry(0.35, 0.4, lift + 1, 6), woodDarkMat);
      pole.position.set(p[0], (lift + 1) / 2 - 0.5, p[1]); g.add(pole);
    });
    var walls = new T.Mesh(new T.BoxGeometry(w, h, d), woodMat); walls.position.y = lift + h / 2; g.add(walls);
    var rl = Math.sqrt((w / 2 + 1) * (w / 2 + 1) + 4 * s * s), ang = Math.atan2(2 * s, w / 2 + 1);
    [-1, 1].forEach(function (sd) {
      var slab = new T.Mesh(new T.BoxGeometry(rl, 0.5 * s, d + 1.5 * s), thatchMat);
      slab.position.set(sd * (w / 4 + 0.4 * s), lift + h + 1.0 * s, 0); slab.rotation.z = sd * ang; g.add(slab);
    });
    var win = new T.Mesh(new T.PlaneGeometry(1.5, 1.1), winMat);
    win.position.set(-w / 4, lift + h * 0.55, d / 2 + 0.06); g.add(win);
    var win2 = win.clone(); win2.position.x = w / 4; g.add(win2);
    var ladder = new T.Mesh(new T.BoxGeometry(1.2, lift + 1.5, 0.3), woodDarkMat);
    ladder.position.set(w / 2 + 0.8, (lift + 1.5) / 2 - 0.5, 0); ladder.rotation.z = 0.25; g.add(ladder);
    g.position.set(x, ty, z); g.rotation.y = ry; root.add(g);
    foot.push([x, z, w + 1.5, d + 1.5, ty, ty + lift + h + 2.2, ry]);
  }

  // ---------- 30+ new huts in clusters ----------
  // THE HIGH LEDGES (Terrace A west)
  familyHale(-40, -95, 0, 0.4); hut(-48, -70, 0, 1.2, 1); hut(-30, -112, 0, -0.5, 0.95);
  // Terrace A east
  hut(40, -95, 0, -0.4, 1); hut(48, -70, 0, -1.2, 1.05);
  // THE HERMIT'S NOOK (far west, off-terrace)
  hermitHut(-95, -20, -14, 0.8); hermitHut(-105, -5, -14, 2.1); hermitHut(-90, 10, -14, -0.6);
  // Terrace B northeast grove
  hut(30, -30, -18, 0.7, 1); hut(45, -25, -18, -0.9, 1.05); familyHale(20, -42, -18, 0.2);
  // THE STILT ROW (Terrace B southwest)
  stiltHut(-20, 40, -18, 0.3); stiltHut(-35, 45, -18, 1.1); stiltHut(-10, 52, -18, -0.7);
  // Terrace C east + west
  hut(20, 75, -36, 0.5, 1); hut(50, 100, -36, -0.8, 0.95);
  hut(-45, 95, -36, 1.4, 1); hut(-20, 125, -36, 2.6, 1.05);
  // THE EASTERN GROVE (off-terrace)
  hut(90, 20, -20, 0.9, 1); hermitHut(100, 40, -22, -1.8); hut(85, 55, -22, 0.2, 0.95);
  // THE SOUTHERN SLOPE
  hut(10, 140, -40, 0.1, 1); hut(-15, 145, -40, 1.5, 1.05); hermitHut(30, 150, -40, -0.9);
  // Northern ridge near the road's end
  hut(-15, -140, 5, 0.6, 1); hut(10, -145, 5, -0.4, 0.95);
  // Terrace A south + B center-west
  familyHale(-20, -60, 0, 1.8); hut(20, -60, 0, -1.8, 1);
  hut(-50, -35, -18, 2.2, 0.95); stiltHut(-45, -52, -18, 0.9);

  // ---------- 100+ more trees: the forest closes in ----------
  var placed2 = 0, guard2 = 0;
  while (placed2 < 60 && guard2++ < 700) {          // denser inner ring r=70..135
    var a2 = R() * Math.PI * 2, rr2 = 70 + R() * 65;
    var tx2 = Math.cos(a2) * rr2, tz2 = Math.sin(a2) * rr2;
    if (!clearOf(tx2, tz2)) continue;
    if (Math.abs(tx2) < 18 && tz2 < -100 && tz2 > -340) continue;   // bore corridor stays clear
    var h2 = 22 + R() * 14, ty2 = -18 - R() * 28;
    if (R() < 0.55) pineTree(tx2, tz2, ty2, h2); else ohiaTree(tx2, tz2, ty2, h2);
    placed2++;
  }
  [[-120, -60], [120, -40], [-110, 90], [110, 110]].forEach(function (gv) {   // 4 dense groves
    for (var gi = 0; gi < 11; gi++) {
      var gx = gv[0] + (R() - 0.5) * 46, gz = gv[1] + (R() - 0.5) * 46;
      if (!clearOf(gx, gz)) continue;
      if (Math.abs(gx) < 18 && gz < -100 && gz > -340) continue;
      var gh = 24 + R() * 13, gy2 = -18 - R() * 26;
      if (R() < 0.55) pineTree(gx, gz, gy2, gh); else ohiaTree(gx, gz, gy2, gh);
    }
  });
  // saplings among the ancients (20)
  for (var spi = 0; spi < 20; spi++) {
    var sa = R() * Math.PI * 2, sr = 75 + R() * 120;
    var sx = Math.cos(sa) * sr, sz = Math.sin(sa) * sr;
    if (!clearOf(sx, sz)) continue;
    var sh = 6 + R() * 5, sy = -18 - R() * 24;
    var sap = new T.Mesh(new T.ConeGeometry(1.6 + sh * 0.06, sh * 0.8, 7), leafMat);
    sap.position.set(sx, sy + sh * 0.4, sz); root.add(sap);
    var str = new T.Mesh(new T.CylinderGeometry(0.25, 0.35, sh * 0.35, 6), trunkMat);
    str.position.set(sx, sy + sh * 0.17, sz); roo