diff --git a/app.js b/app.js index b673584e..de36a583 100644 --- a/app.js +++ b/app.js @@ -560,6 +560,9 @@ function createPortalMesh(cfg) { const ringEmit = new THREE.Color(cfg.ringEmissive); const pCol = new THREE.Color(cfg.particleColor); + const isOnline = !cfg.status || cfg.status === 'online'; + const emissiveStrength = isOnline ? 1.5 : 0.3; + const portalGroup = new THREE.Group(); portalGroup.position.set(...cfg.position); portalGroup.rotation.y = cfg.rotationY; @@ -570,7 +573,7 @@ function createPortalMesh(cfg) { const torusMat = new THREE.MeshStandardMaterial({ color: ringCol, emissive: ringEmit, - emissiveIntensity: 1.5, + emissiveIntensity: emissiveStrength, roughness: 0.2, metalness: 0.8, }); @@ -1039,23 +1042,38 @@ function activatePortal(entry) { overlay.style.display = 'flex'; overlay.classList.remove('fade-out'); + const portalStatus = entry.config.status || 'online'; + const statusColors = { online: '#4af0c0', offline: '#ff4466', maintenance: '#ffd700' }; + const statusColor = statusColors[portalStatus] || entry.config.ringColor; + status.style.color = statusColor; + + if (portalStatus === 'offline') { + status.textContent = '● OFFLINE — destination unreachable'; + return; + } + if (portalStatus === 'maintenance') { + status.textContent = '● MAINTENANCE — portal temporarily closed'; + return; + } + const url = entry.config.destination?.url; if (url) { + status.textContent = '● ONLINE'; let countdown = 3; - status.textContent = `Opening portal in ${countdown}s…`; + status.textContent = `● ONLINE — Opening portal in ${countdown}s…`; const iv = setInterval(() => { countdown--; if (countdown <= 0) { clearInterval(iv); - status.textContent = 'Entering…'; + status.textContent = '● ONLINE — Entering…'; window.location.href = url; } else { - status.textContent = `Opening portal in ${countdown}s…`; + status.textContent = `● ONLINE — Opening portal in ${countdown}s…`; } }, 1000); btn.dataset.intervalId = iv; } else { - status.textContent = 'Portal active — destination not yet linked'; + status.textContent = '● ONLINE — destination not yet linked'; } btn.onclick = () => { diff --git a/portals.json b/portals.json index 7c7eb013..5ae60538 100644 --- a/portals.json +++ b/portals.json @@ -4,6 +4,7 @@ "id": "morrowind", "label": "◈ MORROWIND", "description": "The Elder Scrolls III — Vvardenfell awaits", + "status": "online", "position": [15, 0, -10], "rotationY": -0.5, "ringColor": "#ff6600", @@ -22,6 +23,7 @@ "id": "bannerlord", "label": "⚔ BANNERLORD", "description": "Mount & Blade II — The Calradic Empire calls", + "status": "online", "position": [-15, 0, -10], "rotationY": 0.5, "ringColor": "#cc7700", @@ -40,6 +42,7 @@ "id": "workshop", "label": "⚙ WORKSHOP", "description": "The Forge — Build, create, iterate without limits", + "status": "online", "position": [0, 0, 18], "rotationY": 3.14159, "ringColor": "#00ccaa",