<!-- RUBY-BACKUP · part 340 -->
dth:200px;height:200px;pointer-events:none;';
    // center label
    var cl = document.createElement('div');
    cl.textContent = node.label;
    cl.style.cssText = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:40px;background:#d8a920;border-radius:50%;width:70px;height:70px;display:flex;align-items:center;justify-content:center;';
    webEl.appendChild(cl);
    // directional nodes — 8 directions
    var dirs = {
      up:[75,-50], up_right:[140,0], right:[155,75], down_right:[140,150],
      down:[75,165], down_left:[10,150], left:[-5,75], up_left:[10,0]
    };
    var dirKeys = ['up','up_right','right','down_right','down','down_left','left','up_left'];
    window._webNodes = {};
    dirKeys.forEach(function(d){
      var target = node[d];
      if(!target || !WEB[target]) return;
      var pos = dirs[d];
      var el = document.createElement('div');
      el.textContent = WEB[target].label;
      el.id = 'webnode-'+d;
      el.style.cssText = 'position:absolute;left:'+pos[0]+'px;top:'+pos[1]+'px;font-size:24px;background:#222;border:2px solid #d8a920;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;transition:opacity 0.3s, transform 0.3s;opacity:0.6;';
      webEl.appendChild(el);
      window._webNodes[d] = el;
    });
    document.body.appendChild(webEl);
    if(typeof codeStatus==='function') codeStatus('web: '+current);
  }
  function hideWeb(){
    webVisible = false;
    var w = document.getElementById('dirweb');
    if(w) w.remove();
    webEl = null;
  }
  var lastDir = null;
  function navigate(dir){
    var node = WEB[current];
    var target = node[dir];
    if(!target || !WEB[target]) return;
    // smooth fade: fade out the old direction, highlight the new
    if(window._webNodes){
      if(lastDir && window._webNodes[lastDir]){
        window._webNodes[lastDir].style.opacity = '0.3';
        window._webNodes[lastDir].style.transform = 'scale(0.9)';
      }
      if(window._webNodes[dir]){
        window._webNodes[dir].style.opacity = '1';
        window._webNodes[dir].style.transform = 'scale(1.2)';
        window._webNodes[dir].style.borderColor = '#fff';
      }
    }
    lastDir = dir;
    // run the function if it exists
    var fnKey = 'fn_'+dir;
    if(typeof node[fnKey]==='function'){
      try{ node[fnKey](); }catch(e){}
    }
    // move to the target node after a smooth beat
    setTimeout(function(){
      current = target;
      lastDir = null;
      showWeb();
    }, 350);
  }
  // long-press to open the web, swipe to navigate
  function findCanvas(){
    var canvas = document.querySelector('canvas');
    if(!canvas){ setTimeout(findCanvas, 500); return; }
    var longPressTimer = null;
    canvas.addEventListener('touchstart', function(e){
      if(e.touches.length===1){
        touchStartX = e.touches[0].clientX;
        touchStartY = e.touches[0].clientY;
        longPressTimer = setTimeout(function(){
          if(!webVisible){ current = 'center'; showWeb(); }
        }, 800);
      }
    }, {passive:true});
    canvas.addEventListener('touchmove', function(e){
      if(longPressTimer){ clearTimeout(longPressTimer); longPressTimer = null; }
    }, {passive:true});
    canvas.addEventListener('touchend', function(e){
      if(longPressTimer){ clearTimeout(longPressTimer); longPressTimer = null; }
      if(!webVisible) return;
      if(e.changedTouches.length!==1) return;
      var dx = e.changedTouches[0].clientX - touchStartX;
      var dy = e.changedTouches[0].clientY - touchStartY;
      if(Math.abs(dx)<30 && Math.abs(dy)<30){
        hideWeb(); // tap to close
        return;
      }
      var dir;
      var angle = Math.atan2(dy, dx) * 180 / Math.PI;
      // 8 directions: divide 360 into 8 slices of 45 degrees
      if(angle >= -22.5 && angle < 22.5) dir = 'right';
      else if(angle >= 22.5 && angle < 67.5) dir = 'down_right';
      else if(angle >= 67.5 && angle < 112.5) dir = 'down';
      else if(angle >= 112.5 && angle < 157.5) dir = 'down_left';
      else if(angle >= 157.5 || angle < -157.5) dir = 'left';
      else if(angle >= -157.5 && angle < -112.5) dir = 'up_left';
      else if(angle >= -112.5 && angle < -67.5) dir = 'up';
      else if(angle >= -67.5 && angle < -22.5) dir = 'up_right';
      navigate(dir);
    }, {passive:true});
  }
  findCanvas();
  window._dirWeb = { show: showWeb, hide: hideWeb, go: function(n){ current=n; showWeb(); } };
})();
/* SECRET DIRECTIONAL CODES — escalating */
(function(){
  var SECRETS = [
    {
      name: 'sky',
      seq: ['up','right','up','right','right','down','down','left','down','left','left','up'],
      reward: function(){
        if(typeof handleCheatCode==='function'){ try{ handleCheatCode('fly'); }catch(e){} }
        if(typeof codeStatus==='function') setTimeout(function(){ codeStatus('the sky is yours, my King'); }, 800);
      }
    },
    {
      name: 'golden',
      seq: ['up','up','down','do