<!-- HONEYCOMB-STAGING · part 2 -->
N = {
      room: 'FORUM',
      route: '/forum',
      source: 'server.js: forum routes',
      behavior: 'Main discussion boards. Categories, threads, posts.',
      verified: true
    };
    if (typeof observe === 'function') observe('room.built', { room: 'FORUM', inspection: true });
  }
  // ── ROOM 1: LOGIN — The Entrance with Inspection ──
  function buildLoginRoom() {
    const HEX = 15;
    const cx = 0, cz = 0;
    const floorMat = new THREE.MeshStandardMaterial({ color: 0x0a0a0a, roughness: 0.7, metalness: 0.2 });
    const floor = new THREE.Mesh(new THREE.CylinderGeometry(HEX, HEX, 1, 6), floorMat);
    floor.rotation.y = Math.PI / 6;
    floor.position.set(cx, 0.5, cz);
    floor.receiveShadow = true;
    scene.add(floor);
    const wallMat = new THREE.MeshStandardMaterial({ color: 0xFF0000, emissive: 0xFF0000, emissiveIntensity: 0.8, roughness: 0.4, metalness: 0.1 });
    const wallH = 4, wallT = 1;
    for (let i = 0; i < 6; i++) {
      if (i === 4 || i === 1) continue; // South entrance + north doorway to FORUM
      const a1 = (Math.PI / 180) * (60 * i + 30);
      const a2 = (Math.PI / 180) * (60 * (i + 1) + 30);
      const x1 = cx + Math.cos(a1) * HEX, z1 = cz + Math.sin(a1) * HEX;
      const x2 = cx + Math.cos(a2) * HEX, z2 = cz + Math.sin(a2) * HEX;
      const len = Math.sqrt((x2-x1)*(x2-x1) + (z2-z1)*(z2-z1));
      const wall = new THREE.Mesh(new THREE.BoxGeometry(len, wallH, wallT), wallMat);
      wall.position.set((x1+x2)/2, wallH/2, (z1+z2)/2);
      wall.rotation.y = -Math.atan2(z2-z1, x2-x1);
      wall.castShadow = true;
      scene.add(wall);
      if (typeof addCollider === 'function') addCollider(wall);
    }
    const canvas = document.createElement('canvas');
    canvas.width = 512; canvas.height = 128;
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = '#FF3333'; ctx.font = 'bold 72px monospace'; ctx.textAlign = 'center';
    ctx.fillText('LOGIN', 256, 88);
    const label = new THREE.Mesh(new THREE.PlaneGeometry(16, 4), new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(canvas), transparent: true }));
    label.position.set(cx, 10, cz);
    scene.add(label);
    const ring = new THREE.Mesh(new THREE.TorusGeometry(3, 0.3, 8, 32), new THREE.MeshStandardMaterial({ color: 0xFF0000, emissive: 0xFF0000, emissiveIntensity: 2 }));
    ring.rotation.x = Math.PI / 2;
    ring.position.set(cx, 1.2, cz);
    scene.add(ring);
    // Inspection data for LOGIN room
    window.LOGIN_INSPECTION = {
      room: 'LOGIN',
      route: '/login',
      source: 'server.js:1334',
      handler: 'app.get(\'/login\')',
      renders: 'views.loginForm(null, null)',
      behavior: 'Redirects to / if authenticated. Supports ?next= parameter.',
      verified: true
    };
    if (typeof observe === 'function') observe('room.built', { room: 'LOGIN', inspection: true });
  }
    animate();
    
    // Handle resize
    window.addEventListener('resize', onResize);
  }

  // ── GROUND: Futuristic motherboard floor (seamless 4-side loop) ──
  function createMotherboardTexture() {
    const S = 512;
    const c = document.createElement('canvas');
    c.width = S; c.height = S;
    const x = c.getContext('2d');
    
    // PCB base: deep black-green
    x.fillStyle = '#0a0f0a';
    x.fillRect(0, 0, S, S);
    
    // Subtle PCB texture noise
    x.fillStyle = '#0d130d';
    for (let i = 0; i < 200; i++) {
      const px = Math.floor(Math.random() * S);
      const py = Math.floor(Math.random() * S);
      x.fillRect(px, py, 2, 2);
    }
    
    // Circuit traces: red copper lines (keep away from edges for seamless loop)
    const M = 24; // margin — nothing crosses the edge
    x.strokeStyle = '#CC0000';
    x.lineWidth = 3;
    
    // Horizontal traces
    const hLines = [80, 150, 230, 320, 410, 470];
    hLines.forEach(y => {
      x.beginPath();
      x.moveTo(M, y);
      // Zigzag like real motherboard traces
      let cx = M;
      while (cx < S - M - 40) {
        const seg = 40 + Math.random() * 60;
        x.lineTo(cx + seg, y);
        if (Math.random() > 0.5 && cx + seg < S - M - 40) {
          const dy = (Math.random() > 0.5 ? 1 : -1) * 30;
          x.lineTo(cx + seg, y + dy);
          x.lineTo(cx + seg + 30, y + dy);
          x.lineTo(cx + seg + 30, y);
          cx += seg + 30;
        } else {
          cx += seg;
        }
      }
      x.lineTo(S - M, y);
      x.stroke();
    });
    
    // Vertical traces
    const vLines = [70, 140, 250, 340, 430];
    vLines.forEach(px => {
      x.beginPath();
      x.moveTo(px, M);
      let cy = M;
      while (cy < S - M - 40) {
        const seg = 40 + Math.random() * 60;
        x.lineTo(px, cy + seg);
        cy += seg;
      }
      x.lineTo(px, S - M);
      x.stroke();
    });
    
    // Vias: connection points (red dots with dark centers)
    x.fillStyle = '#FF0000';
    for (let i = 0; i < 40; i++) {
      const px = M + Math.random() * (S - 2 * M);
      const py = M + M