<!-- SOLID CITY · part 2815 -->
), leafCanopies,
    function (d, p) { d.position.set(p.x, p.y, p.z); d.rotation.set(0, p.ry, 0); d.scale.set(p.s, p.s * 0.74, p.s); },
    function (c) { greens(c, 0.19, 0.13); });

  /* ——— PINES ———
   * Reason: high conifers run 20–40 m in life with the
   * crown starting a third up; at world scale ours stack
   * two cones over a 3.6 m trunk to ~11–13 m of spire. */
  var pineTrunkGeo = new T.CylinderGeometry(0.16, 0.28, 3.6, 7); pineTrunkGeo.translate(0, 1.8, 0); bendGeo(pineTrunkGeo, 0.2, 3.6);
  var pineConeGeo = new T.ConeGeometry(2.0, 5.4, 8); pineConeGeo.translate(0, 2.7, 0); fbmDisplace(pineConeGeo, 0.8, 0.10, 8.4, 1);
  var pines = scatter(hiTier ? 120 : 65, function (x, z, h) { if (h < 40 || h > 330 || slope(x, z, h) > 0.75) return null; var ry = R() * 6.28, s = 0.9 + R() * 0.6; var st = seatSettle(x, z, h, 0.28 * s, 0.12, 0.6); return { x: x, z: z, y: h - st, ry: ry, s: s }; });
  counts.pines = pines.length; note('pines', pines);
  instanced('pine-trunks', pineTrunkGeo, trunkMat, pines,
    function (d, p) { d.position.set(p.x, p.y - 0.1, p.z); d.rotation.set(0, p.ry, 0); d.scale.setScalar(p.s); }, null);
  var pineMat = lambert(0xffffff, { flatShading: true });
  instanced('pine-cones-1', pineConeGeo, pineMat, pines,
    function (d, p) { var t1 = 3.1 / 3.6; d.position.set(p.x + Math.cos(p.ry) * 0.2 * t1 * t1 * p.s, p.y + 3.1 * p.s, p.z - Math.sin(p.ry) * 0.2 * t1 * t1 * p.s); d.rotation.set(0, p.ry, 0); d.scale.setScalar(p.s); },
    function (c) { greens(c, 0.10, 0.07); });
  instanced('pine-cones-2', pineConeGeo, pineMat, pines,
    function (d, p) { d.position.set(p.x + Math.cos(p.ry) * 0.2 * p.s, p.y + 6.6 * p.s, p.z - Math.sin(p.ry) * 0.2 * p.s); d.rotation.set(0, p.ry + 0.4, 0); d.scale.setScalar(p.s * 0.60); },
    function (c) { greens(c, 0.10, 0.07); });

  /* ——— THE MONKEY PODS: umbrella crowns on short giants ——— */
  var podTrunkGeo = new T.CylinderGeometry(1.05, 1.45, 5.2, 9); podTrunkGeo.translate(0, 2.6, 0); bendGeo(podTrunkGeo, 0.5, 5.2);
  var podCanGeo = new T.IcosahedronGeometry(1, 1); fbmDisplace(podCanGeo, 0.85, 0.17, 5.3, 1);
  var pods = scatterGiants(hiTier ? 14 : 8, 80, function (x, z, h) { if (h < 3 || h > 120 || slope(x, z, h) > 0.5) return null; var ry = R() * 6.28, cr = 10 + R() * 4.5; var st = seatSettle(x, z, h, 1.45, 0.15, 0.7); return { x: x, z: z, y: h - st, ry: ry, cr: cr }; });
  counts.pods = pods.length; note('pods', pods, 14);
  pods.forEach(function (p) { leafSpawns.push({ x: p.x, y: p.y + 7.2, z: p.z }); });
  instanced('pod-trunks', podTrunkGeo, lambert(0x5d4630), pods,
    function (d, p) { d.position.set(p.x, p.y - 0.15, p.z); d.rotation.set(0, p.ry, 0); d.scale.setScalar(1); }, null);
  instanced('pod-canopies', podCanGeo, lambert(0xffffff, { flatShading: true }), pods,
    function (d, p) { d.position.set(p.x, p.y + 7.6, p.z); d.rotation.set(0, p.ry, 0); d.scale.set(p.cr, p.cr * 0.30, p.cr); },
    function (c) { greens(c, 0.20, 0.10); });
  instanced('pod-crowns', podCanGeo, lambert(0xffffff, { flatShading: true }), pods,
    function (d, p) { d.position.set(p.x, p.y + 9.3, p.z); d.rotation.set(0, p.ry + 2, 0); d.scale.set(p.cr * 0.6, p.cr * 0.22, p.cr * 0.6); },
    function (c) { greens(c, 0.23, 0.10); });
  /* the umbrella's underside, filled: a ring of lobes
   * hangs in the hollow beneath the great disc, so the
   * crown reads as LEAVES all the way through, not a lid */
  var podLobes = [];
  pods.forEach(function (p) {
    for (var li = 0; li < 5; li++) {
      var la3 = (li / 5) * 6.283 + R() * 0.7, lr3 = p.cr * (0.52 + R() * 0.2);
      podLobes.push({ x: p.x + Math.cos(la3) * lr3, z: p.z + Math.sin(la3) * lr3, y: p.y + 7.6 - p.cr * 0.13, s: p.cr * (0.30 + R() * 0.1), ry: R() * 6.28 });
    }
  });
  instanced('pod-lobes', podCanGeo, lambert(0xffffff, { flatShading: true }), podLobes,
    function (d, p) { d.position.set(p.x, p.y, p.z); d.rotation.set(0, p.ry, 0); d.scale.set(p.s, p.s * 0.42, p.s); },
    function (c) { greens(c, 0.18, 0.10); });

  /* ——— THE BANYANS: pillars from the sky ——— */
  var banTrunkGeo = new T.CylinderGeometry(1.25, 1.7, 7.5, 10); banTrunkGeo.translate(0, 3.75, 0); bendGeo(banTrunkGeo, 0.6, 7.5);
  var banCanGeo = new T.IcosahedronGeometry(1, 1); fbmDisplace(banCanGeo, 0.85, 0.19, 4.7, 1);
  var banyans = scatterGiants(hiTier ? 8 : 5, 110, function (x, z, h) { if (h < 3 || h > 110 || slope(x, z, h) > 0.5) return null; var ry = R() * 6.28, cr = 10 + R() * 3.5, ch = 10.5 + R() * 2; var st = seatSettle(x, z, h, 1.7, 0.15, 0.7); return { x: x, z: z, y: h - st, ry: ry, cr: cr, ch: ch }; },
    [[-150, 700], [500, 500], [-700, -250], [1500, 900]]);
  counts.banyans = banyans.length; note('banyans', banyans, 8);
  banyans.forEach(function (p) { leafSpawns.push({ x: p.x, y: p.y + p.ch - 1.2, z: p.z }); });
  instanced('banyan-trunks', banTrunkGeo, lambert(0x54432e), banyans,
    function (d, p) { d.position.set(p.x, p.y - 0.15, p.z); d.rotation.set(0, p.ry, 0); d.scale.setScalar