<!-- PLAYASPACE · part 5 -->
e}
.marker .mnum{font-family:monospace;font-size:20px}
.marker .mname{font-size:13px;letter-spacing:1px;margin-top:4px}
.marker .mfn{font-family:monospace;font-size:11px;color:#00ff88;margin-top:6px;word-break:break-all}
</style></head><body>
<div class="topbar"><h1>PLAYASPACE</h1><div><a href="/playaspace">HOME</a><a href="/">SITE</a></div></div>
<div class="catbar">4 — SIGHT</div>
<table><tr><td class="tablelabel" id="tablelabel">TABLE 4</td></tr><tr><td><iframe class="frame" name="gameframe" src="/saga/?runcode=sight" title="game"></iframe></td></tr><tr><td><a class="code" id="boxlink" href="/saga/?runcode=tp%20114%203334" target="gameframe">VIEW BOX 4</a><a class="code" id="codelink" href="/saga/?runcode=sight" target="gameframe">sight</a><div class="desc">Branch 4 is the eyes — the all-seeing vantage, slowly sweeping the world. You're building.</div></td></tr></table><div class="markers" id="markers"></div>
<div class="webnav">
<a href="/playaspace/1">1</a><a href="/playaspace/2">2</a><a href="/playaspace/3">3</a><a href="/playaspace/4">4</a><br>
<a class="home" href="/playaspace">PLAYASPACE HOME</a><a class="home" href="/">SITE HOME</a>
</div>

<script>
/* every number is a branch: cycle the four, loop upon loop. Loop 2+ adds the free camera drift. */
(function(){
  var m = location.pathname.match(/\/playaspace\/(\d+)/);
  if(!m) return;
  var n = parseInt(m[1], 10);
  var b = ((n - 1) % 4) + 1;
  var loop = Math.floor((n - 1) / 4) + 1;
  var tl = document.getElementById('tablelabel');
  if(tl) tl.textContent = 'TABLE ' + n + (loop > 1 ? ' \u2014 LOOP ' + loop : '');
  var bl = document.getElementById('boxlink');
  if(bl){
    var bx = {1:[60,3334],2:[78,3334],3:[96,3334],4:[114,3334]}[b];
    bl.setAttribute('href', '/saga/?runcode=tp%20' + bx[0] + '%20' + bx[1]);
    bl.textContent = 'VIEW BOX ' + b;
  }
  if(n === b && loop === 1) return;
  var cat = document.querySelector('.catbar');
  if(cat){
    var parts = cat.textContent.split('\u2014');
    var name = parts.length > 1 ? parts[1].trim() : cat.textContent;
    cat.textContent = n + ' \u2014 ' + name + ' \u2014 LOOP ' + loop;
    document.title = 'Branch ' + n + ' \u2014 ' + name + ' \u2014 playaspace';
  }
  if(loop > 1){
    var f = document.querySelector('iframe[name=gameframe]');
    if(f){
      var src = f.getAttribute('src');
      if(src.indexOf('runcode=') > -1) src += ',freecam';
      else src += (src.indexOf('?') > -1 ? '&' : '?') + 'runcode=freecam';
      f.setAttribute('src', src);
    }
    var c = document.querySelector('a.code');
    if(c){
      var h = c.getAttribute('href');
      if(h && h.indexOf('runcode=') > -1) c.setAttribute('href', h + ',freecam');
    }
  }
})();
</script>

<script>
/* marker scroll: every box, its function — tap to find it in the frame */
(function(){
  var boxes = [
    {n:1, name:'UNFOLD', fn:'playa2', x:60, z:3334},
    {n:2, name:'STAND', fn:'newbody', x:78, z:3334},
    {n:3, name:'BUILD', fn:'bam box 10', x:96, z:3334},
    {n:4, name:'SIGHT', fn:'sight', x:114, z:3334}
  ];
  var hold = document.getElementById('markers');
  if(!hold) return;
  var frame = document.querySelector('iframe[name=gameframe]');
  boxes.forEach(function(bx){
    var a = document.createElement('a');
    a.className = 'marker';
    a.href = '/saga/?runcode=tp%20' + bx.x + '%20' + bx.z;
    a.target = 'gameframe';
    a.innerHTML = '<div class="mnum">' + bx.n + '</div><div class="mname">' + bx.name + '</div><div class="mfn">' + bx.fn + '</div>';
    hold.appendChild(a);
  });
})();
</script>
</body>
</html>

===== FILE: public/playaspace/index.html =====
<!DOCTYPE html><html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Playa 2.0's Space — playaspace</title><style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#000;color:#e8dcc0;font-family:Georgia,serif;min-height:100vh}
.topbar{background:#1a0505;border-bottom:2px solid #d8a920;padding:10px 14px;display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:10}
.topbar h1{color:#ffd700;font-size:18px;letter-spacing:3px}
.topbar a{color:#ff6a6a;text-decoration:none;font-size:13px;margin-left:12px}
.catbar{background:linear-gradient(180deg,#5a0a0a,#2a0505);color:#ffd700;padding:10px 14px;font-size:15px;letter-spacing:2px;border-top:1px solid #d8a920;border-bottom:1px solid #d8a920;margin-top:14px}
table{width:100%;border-collapse:collapse;margin:0}
td{border:1px solid #3a2a1a;padding:10px 12px;vertical-align:top}
.hero{width:100%;max-height:220px;object-fit:cover;display:block;opacity:.9}
.frame{width:100%;height:320px;border:1px solid #d8a920;background:#050505}
.code{display:inline-block;background:#1a1a1a;border:1px solid #ffd700;color:#ffd700;padding:10px 18px;font-family:monospace;font-size:17px;text-decoration:none;border-radius:6px;margin:6px 0}
.desc{color:#c8b890;font-size:14px;line-height:1.5}
.webnav{text-align:center;padding: