<!-- SOLIDABILITY-WORLD · part 54 -->
k/tap to select
    setupSelection();
  }

  // Build from full architectural map (districts = directories, buildings = files)
  function buildFull(fullLayout) {
    layout = fullLayout;
    const scene = SWEngine.getScene();

    // Single ground plane for the full map (no floors — districts spread horizontally)
    const groundSize = 500;
    const groundGeo = new THREE.BoxGeometry(groundSize, 0.5, groundSize);
    const groundMat = new THREE.MeshStandardMaterial({ color: 0x2a2a35 });
    const ground = new THREE.Mesh(groundGeo, groundMat);
    ground.position.set(0, -0.25, 0);
    ground.receiveShadow = true;
    scene.add(ground);

    // District zones (colored ground pads + labels)
    const districtColors = [0x3a3a5a, 0x3a4a5a, 0x4a3a5a, 0x3a5a4a, 0x5a4a3a];
    layout.districts.forEach((district, idx) => {
      const color = districtColors[idx % districtColors.length];
      const padGeo = new THREE.PlaneGeometry(70, 70);
      const padMat = new THREE.MeshBasicMaterial({
        color, transparent: true, opacity: 0.15
      });
      const pad = new THREE.Mesh(padGeo, padMat);
      pad.rotation.x = -Math.PI / 2;
      pad.position.set(district.position.x, 0.05, district.position.z);
      scene.add(pad);

      // District label (only for significant districts)
      if (district.fileCount >= 5 || idx < 10) {
        addLabel(scene, district.name.toUpperCase(), district.position.x, 25,
                 district.position.z - 35, 0x8888aa, 2.5);
        addLabel(scene, `${district.fileCount} files`, district.position.x, 22,
                 district.position.z - 35, 0x666677, 1.5);
      }
    });

    // Buildings (files) — LOD: full detail for top complexity, simple for rest
    const sortedRooms = [...layout.rooms].sort((a, b) => b.complexity - a.complexity);
    sortedRooms.forEach((room, idx) => {
      buildFileBuilding(scene, room, idx < 30); // detailed for top 30
    });

    // Central landmark: server.js tower
    const serverRoom = layout.rooms.find(r => r.filePath === 'server.js');
    if (serverRoom) {
      addLabel(scene, '⭐ SERVER.JS — CORE', serverRoom.position.x,
               serverRoom.size.height + 8, serverRoom.position.z, 0xffd700, 3);
    }

    setupSelection();
  }

  // Build public world from sanitized map (no source, no auth)
  // Simple circular layout, human names only
  function buildPublic(publicLayout) {
    layout = publicLayout;
    const scene = SWEngine.getScene();

    // 2026-10-09: removed a leftover debug red cube + green 'RED CUBE AT ORIGIN' banner from the public page.

    // Ground
    const groundSize = 300;
    const groundGeo = new THREE.BoxGeometry(groundSize, 0.5, groundSize);
    const groundMat = new THREE.MeshStandardMaterial({ color: 0x2a2a35 });
    const ground = new THREE.Mesh(groundGeo, groundMat);
    ground.position.set(0, -0.25, 0);
    ground.receiveShadow = true;
    scene.add(ground);

    // Position buildings in a spiral (most connected at center)
    const rooms = [...publicLayout.rooms].sort(
      (a, b) => (b.publicInfo?.connections || 0) - (a.publicInfo?.connections || 0)
    );

    const angleStep = (Math.PI * 2) / Math.max(rooms.length, 1);
    rooms.forEach((room, idx) => {
      const ring = Math.floor(idx / 8);
      const radius = 18 + ring * 25;
      const angle = idx * angleStep + ring * 0.5;

      room.position = {
        x: Math.cos(angle) * radius,
        z: Math.sin(angle) * radius,
        y: 0,
      };

      // Size by connections (not complexity — public doesn't see complexity)
      const conns = room.publicInfo?.connections || 1;
      const height = 8 + Math.min(conns * 0.5, 20);
      const width = 10 + Math.min(conns * 0.3, 8);
      room.size = { width, height, depth: width };

      buildPublicBuilding(scene, room);
    });

    // Center landmark
    addLabel(scene, '✦ SOLIDABILITY WORLD', 0, 40, 0, 0x00ffcc, 3);
    addLabel(scene, 'Epistles.xyz — Public Preview', 0, 36, 0, 0x8888aa, 1.5);

    setupSelection();
  }

  function buildPublicBuilding(scene, room) {
    // Register SOLID collision (works without color/rendering)
    const bx = room.position.x, bz = room.position.z;
    const bw = room.size ? room.size.width : 12;
    const bd = room.size ? room.size.depth : 12;
    addCollider(bx, bz, bw, bd);

    const geo = new THREE.BoxGeometry(12, 12, 12);
    // FUTURISTIC TACTICAL FORTIFICATION texture (red/black)
    const _c = document.createElement('canvas');
    _c.width = 256; _c.height = 256;
    const _x = _c.getContext('2d');
    // Black base
    _x.fillStyle = '#0a0a0c'; _x.fillRect(0, 0, 256, 256);
    // Dark panel grid
    _x.strokeStyle = '#1a1a1e'; _x.lineWidth = 2;
    for (let i = 0; i <= 256; i += 32) {
      _x.beginPath(); _x.moveTo(i, 0); _x.lineTo(i, 256); _x.stroke();
      _x.beginPath(); _x.moveTo(0, i); _x.lineTo(256, i); _x.stroke();
    }
    // Red tactical accents — corner brackets
    _x.strokeStyle = '#FF0000'; _x.lineWi