<!-- SOLIDABILITY-WORLD · part 27 -->
 { width: 600, depth: 600, floors: 1, floorHeight: 8 },
      rooms,
      districts,
      lights: [],
      doors: [],
      stairs: null, // single-floor default; multi-floor added by hierarchy
      elevator: null,
      hallways: [],
      fullMap: true,
      generatedAt: archMap.generated_at,
      sourceRoot: archMap.root,
    };
  }

  // Detect hierarchy for multi-floor layout
  // Directories with high route counts → upper floors (API layer)
  // Returns modified layout with floor assignments
  function applyHierarchy(layout, archMap) {
    // Simple heuristic: sort districts by route count
    // Top 20% by routes → "API floor" (elevated)
    const districts = [...layout.districts]
      .sort((a, b) => b.routeCount - a.routeCount);
    const apiCount = Math.max(1, Math.floor(districts.length * 0.2));
    const apiDistricts = new Set(districts.slice(0, apiCount).map(d => d.name));

    if (apiDistricts.size > 0 && districts.length > 3) {
      layout.building.floors = 2;
      layout.rooms.forEach(room => {
        if (apiDistricts.has(room.district)) {
          room.floor = 1;
          room.position.y = layout.building.floorHeight;
        } else {
          room.floor = 0;
        }
      });
      // Add stairs connecting floors
      layout.stairs = { position: { x: 0, y: 0, z: -250 } };
      layout.elevator = { position: { x: 8, y: 0, z: -250 } };
    }

    return layout;
  }

  return {
    fileToBuilding,
    layoutDistricts,
    layoutFiles,
    mapToWorld,
    applyHierarchy,
  };
})();


===== FILE: public/solidability-world/js/sw-glass.js =====
// Solidability World — The Glass
// HTML overlay panel showing component purpose, dependencies, verification.
// Phase 1: inspection only. No repair options (reserved for Phase 2).

const SWGlass = (() => {
  let panel = null;
  let backStack = [];

  function init() {
    panel = document.getElementById('glass-panel');
    // 2026-10-09 fix: public.html has no #glass-panel — create it so FOCUS/arrival cards render.
    if (!panel) {
      panel = document.createElement('div'); panel.id = 'glass-panel';
      (document.getElementById('app') || document.body).appendChild(panel);
    }
  }

  function show(room, options) {
    if (!panel) init();

    // PUBLIC MODE: show human explanation only, no source, no diagnostics
    if (room.publicInfo) {
      showPublic(room);
      return;
    }

    const v = room.verification || { status: 'untested' };
    const opts = options || {};
    const isPaused = !!opts.paused;

    // Alarm status text — light reflects actual issues, verification shown separately
    const lightStatus = SWLayout.verificationToLight(v.status);
    const lightText = lightStatus === 'off' && v.status === 'untested'
      ? '● OFF — No issues detected'
      : lightStatus === 'off' ? '● OFF — No issues detected'
      : lightStatus === 'blinking' ? '● BLINKING — Running rough'
      : '● SOLID — Problem detected';
    const verificationText = v.status === 'verified' ? '✦ VERIFIED'
      : v.status === 'untested' ? 'UNTESTED / UNKNOWN'
      : v.status === 'rough' ? 'NEEDS ATTENTION'
      : v.status === 'defect' ? 'DEFECT CONFIRMED'
      : v.status.toUpperCase();

    // For file buildings (full map), show file-specific info
    const isFile = !!room.filePath;

    // Build dependency list
    const deps = isFile && room.dependencies
      ? room.dependencies.map(d => `<code>${escapeHtml(d)}</code>`).join(', ') || 'None detected'
      : inferDependencies(room);

    // Functions list for files
    const funcsHtml = isFile && room.functions ? `
      <div class="glass-section">
        <h3>Functions (${room.functions.length})</h3>
        <ul class="route-list">
          ${room.functions.slice(0, 10).map(f =>
            `<li><code>${escapeHtml(f.name)}()</code> <span class="line">L${f.line}</span></li>`
          ).join('')}
          ${room.functions.length > 10 ? `<li class="more">+ ${room.functions.length - 10} more</li>` : ''}
        </ul>
      </div>` : '';

    panel.innerHTML = `
      <div class="glass-header">
        <span class="glass-close-left" onclick="SWGlass.hide()">✕</span>
        <h2>${escapeHtml(room.label)}</h2>
      </div>
      ${isPaused ? `
      <div class="pause-banner">
        <span class="pause-badge">⏸️ PAUSED</span>
        <span class="pause-detail">${escapeHtml(opts.pauseInfo.mode)} at (${opts.pauseInfo.position.x.toFixed(0)}, ${opts.pauseInfo.position.z.toFixed(0)})</span>
      </div>
      <div class="pause-actions">
        <button class="int-btn primary" onclick="SWIntervene.resume()">▶️ Resume</button>
        <button class="int-btn" onclick="SWIntervene.redirect()">🧭 Redirect</button>
        <button class="int-btn" onclick="SWIntervene.manual()">🚶 Manual</button>
        <button class="int-btn danger" onclick="SWIntervene.end()">⏹️ End</button>
      </div>` : ''}
      <div class="glass-body">
        ${isFile ? `
        <div class