<!-- SOLID CITY · part 3631 -->
r: 0x2e2a26 });

  // ---------- three terraces ----------
  // A upper (gathering hale), B mid (huts), C lower (huts + lookout)
  var TER = [
    { x: 0, z: -85, y: 0,   r: 58 },
    { x: 0, z: 0,   y: -18, r: 60 },
    { x: 0, z: 85,  y: -36, r: 58 }
  ];
  TER.forEach(function (t) {
    var disc = new T.Mesh(new T.CylinderGeometry(t.r, t.r + 6, 46, 40), terraceMat);
    disc.position.set(t.x, t.y - 23, t.z); root.add(disc);
    var top = new T.Mesh(new T.CylinderGeometry(t.r, t.r, 1.5, 40), new T.MeshLambertMaterial({ color: 0x3a332c }));
    top.position.set(t.x, t.y + 0.4, t.z); root.add(top);
  });

  // ---------- warm window glow material ----------
  var winMat = new T.MeshBasicMaterial({ color: C.warm });

  // ---------- huts (hale-style gabled) ----------
  function hut(x, z, ty, ry, s) {
    s = s || 1;
    var g = new T.Group();
    var w = 9 * s, d = 7 * s, h = 3.6 * s;
    var walls = new T.Mesh(new T.BoxGeometry(w, h, d), woodMat); walls.position.y = h / 2; g.add(walls);
    // pitched roof: two slabs
    var rl = Math.sqrt((w / 2 + 1) * (w / 2 + 1) + 4 * s * s);
    var 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), h + 1.0 * s, 0);
      slab.rotation.z = sd * ang; g.add(slab);
    });
    // warm windows (front) + door glow
    var win = new T.Mesh(new T.PlaneGeometry(1.6 * s, 1.2 * s), winMat);
    win.position.set(-w / 4, h * 0.55, d / 2 + 0.06); g.add(win);
    var win2 = win.clone(); win2.position.x = w / 4; g.add(win2);
    var door = new T.Mesh(new T.PlaneGeometry(1.8 * s, 2.6 * s), new T.MeshBasicMaterial({ color: 0xffb050 }));
    door.position.set(0, 1.3 * s, d / 2 + 0.06); g.add(door);
    g.position.set(x, ty, z); g.rotation.y = ry;
    root.add(g);
    foot.push([x, z, w + 1, d + 1, ty, ty + h + 2.4 * s, ry]);
  }
  // Terrace B huts (5)
  hut(-28, -12, -18, 0.3, 1); hut(8, -22, -18, -0.2, 1.1); hut(34, 4, -18, 0.5, 0.95);
  hut(-8, 26, -18, 3.3, 1.05); hut(-38, 18, -18, 2.8, 0.9);
  // Terrace C huts (5)
  hut(-30, 72, -36, 0.4, 1); hut(6, 66, -36, -0.3, 1.1); hut(36, 92, -36, 0.6, 0.95);
  hut(-12, 108, -36, 3.1, 1); hut(28, 112, -36, 2.9, 0.9);

  // ---------- gathering hale (open-sided, Terrace A) ----------
  (function () {
    var ty = 0, cx = 0, cz = -85;
    var g = new T.Group();
    var W = 20, D = 14, PH = 5.5;
    // corner + mid posts
    [[-W/2,-D/2],[W/2,-D/2],[-W/2,D/2],[W/2,D/2],[0,-D/2],[0,D/2],[-W/2,0],[W/2,0]].forEach(function (p) {
      var post = new T.Mesh(new T.CylinderGeometry(0.45, 0.55, PH, 8), woodDarkMat);
      post.position.set(p[0], PH / 2, p[1]); g.add(post);
    });
    // big pitched thatch roof
    var rl = Math.sqrt((W / 2 + 2) * (W / 2 + 2) + 16);
    var ang = Math.atan2(4, W / 2 + 2);
    [-1, 1].forEach(function (sd) {
      var slab = new T.Mesh(new T.BoxGeometry(rl, 0.7, D + 3), thatchMat);
      slab.position.set(sd * (W / 4 + 0.8), PH + 2, 0); slab.rotation.z = sd * ang; g.add(slab);
    });
    // low stone curb walls (open above)
    [[0, -D/2, W, 0.6], [0, D/2, W, 0.6]].forEach(function (w) {
      var curb = new T.Mesh(new T.BoxGeometry(w[2], 1.1, w[3] + 0.6), basaltMat);
      curb.position.set(w[0], 0.55, w[1]); g.add(curb);
    });
    // fire pit
    var pit = new T.Mesh(new T.CylinderGeometry(2.6, 3, 1.2, 12), basaltMat);
    pit.position.y = 0.6; g.add(pit);
    var flame = new T.Mesh(new T.ConeGeometry(1.6, 4.2, 10),
      new T.MeshBasicMaterial({ color: C.fire, transparent: true, opacity: 0.9 }));
    flame.position.y = 3.4; flame.name = 'flame'; g.add(flame);
    var fireLight = new T.PointLight(0xff9a40, 2.2, 70); fireLight.position.y = 5; g.add(fireLight);
    g.userData.fireLight = fireLight; g.userData.flame = flame;
    // log benches around the fire
    for (var b = 0; b < 6; b++) {
      var ba = (b / 6) * Math.PI * 2 + 0.26;
      var bench = new T.Mesh(new T.CylinderGeometry(0.5, 0.5, 4.4, 8), woodDarkMat);
      bench.rotation.z = Math.PI / 2; bench.rotation.y = -ba;
      bench.position.set(Math.cos(ba) * 6.4, 0.9, Math.sin(ba) * 6.4); g.add(bench);
    }
    g.position.set(cx, ty, cz);
    root.add(g);
    root.userData.hale = g;
    haleRef.g = g;
    foot.push([cx - W/2, cz - D/2, 1.2, D, ty, ty + PH, 0]); foot.push([cx + W/2, cz - D/2, 1.2, D, ty, ty + PH, 0]);
    foot.push([cx, cz, 5.4, 5.4, ty, ty + 2, 0]);  // fire pit
  })();

  // ---------- lookout (Terrace C, northwest edge — faces the city) ----------
  (function () {
    // city is at ~(0,0); village at (2000,2000) → city dir ≈ (-0.707,-0.707); local NW edge
    var lx = -38, lz = 108, ty = -36;
    var deck = new T.Mesh(new T.BoxGeometry(16, 1.2, 10), woodMat);
    deck.position.set(lx, ty + 2.6, lz); root.add(deck);
    // posts + railing on the view side
    for (var i = -2; i <= 2; i++) {
      var pr = new T.Mesh(new T.CylinderGeometry(0.22, 0.22, 2