<!-- SOLIDABILITY-WORLD · part 25 -->


    // 2026-10-09 fix: the public world layout has no `building` (open ground) —
    // reading layout.building.width threw every frame and froze movement.
    if (layout && layout.building) {
      const b = layout.building;
      // Outer building walls — solid
      if (newX < -b.width / 2 + r || newX > b.width / 2 - r) return;
      if (newZ < -b.depth / 2 + r || newZ > b.depth / 2 - r) return;

      // Room walls — solid except door gap on hallway side
      const playerFloor = Math.round(player.position.y / b.floorHeight);
      for (const room of layout.rooms) {
        if (room.floor !== playerFloor) continue;
        if (collidesWithRoom(newX, newZ, r, room)) return;
      }
    }

    player.position.x = newX;
    player.position.z = newZ;
  }

  function collidesWithRoom(x, z, r, room) {
    const hw = room.size.width / 2;
    const hd = room.size.depth / 2;
    const cx = room.position.x;
    const cz = room.position.z;
    const wt = 0.3 + r; // wall thickness + player radius
    const doorHalf = 2; // 4-unit door gap on hallway side (front wall, -z)

    // Front wall (faces hallway) — solid except door gap
    if (Math.abs(z - (cz - hd)) < wt && x > cx - hw && x < cx + hw) {
      if (Math.abs(x - cx) > doorHalf) return true;
    }
    // Back wall — solid
    if (Math.abs(z - (cz + hd)) < wt && x > cx - hw && x < cx + hw) return true;
    // Left wall — solid
    if (Math.abs(x - (cx - hw)) < wt && z > cz - hd && z < cz + hd) return true;
    // Right wall — solid
    if (Math.abs(x - (cx + hw)) < wt && z > cz - hd && z < cz + hd) return true;

    return false;
  }

  // Stairs: walking on stairs changes Y; off stairs, snap to nearest floor
  function updateStairs() {
    const layout = SWWorld.getLayout();
    if (!layout || !layout.stairs) return;
    const fh = layout.building.floorHeight;
    const sx = layout.stairs.position.x;
    const sz = layout.stairs.position.z;
    const px = player.position.x;
    const pz = player.position.z;

    // Stair zone: x within 1.5 of stair center, z from sz+1 (bottom) to sz-8 (top)
    if (Math.abs(px - sx) < 1.5 && pz < sz + 1 && pz > sz - 8) {
      const progress = Math.max(0, Math.min(1, (sz - pz) / 8));
      const targetY = progress * fh;
      player.position.y += (targetY - player.position.y) * 0.3;
    } else {
      // Off stairs: settle to nearest floor
      const floor = Math.max(0, Math.round(player.position.y / fh));
      const targetY = floor * fh;
      player.position.y += (targetY - player.position.y) * 0.2;
    }
  }

  let lastTime = performance.now();
  let loopTestDone = false;
  function animate() {
    requestAnimationFrame(animate);
    // 2026-10-09: removed a leftover debug blue cube + 'BLUE CUBE ADDED IN RENDER LOOP' banner.
    const now = performance.now();
    const dt = Math.min((now - lastTime) / 1000, 0.1);
    lastTime = now;
    updatePlayer(dt);
    SWWorld.update(dt);
    if (typeof SWHyper !== 'undefined') SWHyper.update(dt);
    scene.updateMatrixWorld(true);
    renderer.render(scene, camera);
  }

  function getScene() { return scene; }
  function getPlayer() { return player; }
  function getCamera() { return camera; }

  return { init, getScene, getPlayer, getCamera };
})();


===== FILE: public/solidability-world/js/sw-geometry.js =====
// Solidability Universal Core — Geometry Engine
// Deterministic calculation: code architecture → 3D spatial geometry.
// NOT Epistles-specific. Works for any architectural map.
//
// Principles:
// - Size from structural complexity (dependencies, branching, functions, routes)
// - Shape from relationships (not raw size)
// - Position from hierarchy (not random)
// - Explainable: every dimension has a formula

const SWGeometry = (() => {

  // Calculate building dimensions from file analysis
  // LOGARITHMIC SCALING (per GPT-6 review 2026-10-08):
  // Linear scaling capped at complexity 80-105, hiding differences.
  // Logarithmic preserves distinction across the full range.
  // High-complexity files get internal floors, not just taller boxes.
  //
  // Returns {width, depth, height, floors, explanation, scalingNote}
  function fileToBuilding(file) {
    const complexity = file.complexity || 0;
    const deps = (file.dependencies || []).length;
    const funcs = (file.functions || []).length;
    const routes = (file.routes || []).length;
    const branching = Math.max(0, complexity - deps * 2 - funcs - routes * 3);

    // Logarithmic scaling: distinguishes 100 from 5,981
    // log10(1) = 0 → 4m base. log10(5981) ≈ 3.78 → ~15m
    const logC = Math.log10(Math.max(1, complexity));
    const width = Math.max(4, Math.min(18, 4 + logC * 3.2));
    const depth = width;

    // Height: base + logarithmic, capped for navigability
    const height = Math.max(3, Math.min(30, 3 + logC * 7));

    // Internal floors for high complexity (not just taller — structured)
    // Every ~1.0 log unit = one additional floor
    const floors = M