<!-- SOLID CITY · part 2547 -->
.17, wh - 0.15, 6, px, (wh - 0.15) / 2, d / 2 + depth - 0.25, C.woodDark);
    });
    // lanai roof: a shallower slope continuing the front roof line
    var sl = Math.hypot(depth + 0.7, 0.85);
    box(solid, w + 1.2, 0.14, sl, 0, wh + 0.35, d / 2 + depth / 2, C.shingle2, 0, Math.atan2(0.85, depth + 0.7), 0);
    // railing on the front edge with a center entry gap (2.2 wide)
    var railW = (w / 2 - 1.1);
    box(solid, railW, 0.1, 0.12, -(1.1 + railW / 2), 1.0, d / 2 + depth - 0.2, C.lanaiWood);
    box(solid, railW, 0.1, 0.12, (1.1 + railW / 2), 1.0, d / 2 + depth - 0.2, C.lanaiWood);
    box(solid, railW, 0.08, 0.1, -(1.1 + railW / 2), 0.5, d / 2 + depth - 0.2, C.lanaiWood);
    box(solid, railW, 0.08, 0.1, (1.1 + railW / 2), 0.5, d / 2 + depth - 0.2, C.lanaiWood);
    footprint(-(1.1 + railW / 2), d / 2 + depth - 0.2, railW, 0.4, 0, 1.1);
    footprint((1.1 + railW / 2), d / 2 + depth - 0.2, railW, 0.4, 0, 1.1);
    if (enclosed) {  // Dickey enclosed lanai: glass panels between posts
      box(glassB, w - 1, 1.9, 0.06, 0, 1.55, d / 2 + depth - 0.22, C.glass);
    }
    return lz;
  }
  function stepsDown(n, zFront) {   // stone steps from pad front (y=0) down toward the path
    for (var i = 0; i < n; i++) {
      var sy = -0.28 * (i + 1), sz = zFront + 0.55 + i * 0.62;
      box(solid, 2.4, 0.26, 0.66, 0, sy - 0.13, sz, C.stone);
      stand(0, sz, 2.4, 0.7, sy);
    }
  }

  var STYLE_COUNT = { waa: 0, noa: 0, plantation: 0, dickey: 0, mission: 0 };
  function buildHome(style, x, z, ry, scale, interior) {
    scale = scale || 1;
    var w, d, wh, wallColor, roofColor;
    if (style === 'waa') { w = 10.5; d = 7.5; wh = 2.3; wallColor = C.woodWall; roofColor = 0x8a6a3a; }
    else if (style === 'noa') { w = 9; d = 7; wh = 2.5; wallColor = C.woodWall; roofColor = 0x8a6a3a; }
    else if (style === 'plantation') { w = 10; d = 7.5; wh = 2.9; wallColor = R() < 0.5 ? C.white : 0xd8cfb8; roofColor = C.shingle2; }
    else if (style === 'dickey') { w = 12; d = 9; wh = 3.1; wallColor = 0xe2dbc8; roofColor = 0x6a5138; }
    else { w = 9.5; d = 7.5; wh = 3.0; wallColor = 0xded5c2; roofColor = C.shingle; }  // mission
    w *= scale; d *= scale;
    var lanaiDepth = style === 'plantation' ? 2.6 : style === 'dickey' ? 3.2 : style === 'mission' ? 1.8 : 3.0;
    var padY = lotHeight(x, z, Math.max(w, d) * 0.62);
    setHome(x, z, padY, ry);
    // --- foundation: stone platform from the slope up to floor level (lava-rock building stone) ---
    var gMin = Math.min(groundAt(x - w / 2, z - d / 2), groundAt(x + w / 2, z + d / 2), groundAt(x - w / 2, z + d / 2), groundAt(x + w / 2, z - d / 2));
    var baseDepth = Math.min(7, Math.max(1.6, padY - gMin + 0.7));
    var padW = w + 2.4, padD = d + lanaiDepth + 2.2;
    var padCz = (lanaiDepth - 0.6) / 2;   // pad center shifts toward the lanai side
    box(solid, padW, baseDepth, padD, 0, -baseDepth / 2, padCz, C.stone);
    box(solid, padW + 0.5, 0.3, padD + 0.5, 0, -0.15, padCz, C.stoneDark);   // platform cap edge
    footprint(0, padCz, padW, padD, -baseDepth, 0.15);
    if (style === 'plantation' || style === 'dickey') {   // post-and-pier hint: stone piers proud at corners
      [[-w / 2, -d / 2], [w / 2, -d / 2], [-w / 2, d / 2], [w / 2, d / 2]].forEach(function (p) {
        box(solid, 0.9, 1.1, 0.9, p[0], -0.55, p[1], C.stoneDark);
      });
    }
    // --- floor (warm wood inside) ---
    box(solid, w, 0.18, d, 0, 0.02, 0, C.lanaiWood);
    box(solid, w + 0.6, 0.14, lanaiDepth, 0, 0.0, d / 2 + lanaiDepth / 2, C.lanaiWood);   // lanai deck
    stand(0, padCz, padW, padD, 0.12);   // the whole stone platform is walkable
    // --- walls + door + windows ---
    wallSegs(w, d, wh, wallColor, 0.85, true);
    // --- roof ---
    if (style === 'waa') {
      var rise = d * 0.85;    // A-frame steepness from the King's Hilo photos
      gableRoof(w, d, wh, rise, roofColor, 1.15);
      gableEnds(w, d, wh, rise, wallColor);
      // post-and-beam: corner posts stand proud (lashed-frame look)
      [[-w / 2, -d / 2], [w / 2, -d / 2], [-w / 2, d / 2], [w / 2, d / 2]].forEach(function (p) {
        cyl(solid, 0.2, 0.24, wh + rise * 0.4, 6, p[0], (wh + rise * 0.4) / 2, p[1], C.woodDark);
      });
    } else if (style === 'noa') {
      gableRoof(w, d, wh, d * 0.62, roofColor, 1.0);
      gableEnds(w, d, wh, d * 0.62, wallColor);
    } else if (style === 'dickey') {
      dickeyRoof(w, d, wh, roofColor);
    } else if (style === 'mission') {
      gableRoof(w, d, wh, d * 0.55, roofColor, 0.7);
      gableEnds(w, d, wh, d * 0.55, wallColor);
    } else {   // plantation: honest gable, generous eaves
      gableRoof(w, d, wh, d * 0.42, roofColor, 1.1);
      gableEnds(w, d, wh, d * 0.42, wallColor);
    }
    // --- lanai (not for waa — its door opens to a small stone stoop instead) ---
    if (style !== 'waa') lanaiBuild(w, d, wh, lanaiDepth, style === 'dickey');
    else { box(solid, 3.4, 0.16, 1.6, 0, 0.02, d / 2 + 0.8, C.stone); }
    s