diff --git a/app.js b/app.js index 5a028f6..06ec5d6 100644 --- a/app.js +++ b/app.js @@ -187,6 +187,65 @@ function animate() { animate(); +// === CHANGELOG PANEL === +(function initChangelog() { + const panel = document.getElementById('changelog-panel'); + const toggleBtn = document.getElementById('changelog-toggle'); + const closeBtn = document.getElementById('changelog-close'); + const list = document.getElementById('changelog-list'); + + /** + * Renders changelog entries into the list element. + * @param {Array<{hash: string, date: string, author: string, message: string}>} entries + * @returns {void} + */ + function renderEntries(entries) { + list.innerHTML = ''; + for (const entry of entries) { + const li = document.createElement('li'); + li.className = 'changelog-entry'; + + const authorClass = 'changelog-author author-' + entry.author; + li.innerHTML = + '
' + + '' + entry.date + '' + + '' + entry.author + '' + + '
' + + '
' + entry.message + '
'; + + list.appendChild(li); + } + } + + fetch('changelog.json') + .then((/** @type {Response} */ res) => res.json()) + .then((/** @type {Array<{hash: string, date: string, author: string, message: string}>} */ entries) => { + renderEntries(entries); + }) + .catch(() => { + const li = document.createElement('li'); + li.className = 'changelog-entry'; + li.innerHTML = '
No changelog available.
'; + list.appendChild(li); + }); + + toggleBtn.addEventListener('click', () => { + const isVisible = panel.classList.toggle('visible'); + toggleBtn.style.backgroundColor = isVisible + ? 'var(--color-primary)' + : 'var(--color-secondary)'; + toggleBtn.style.color = isVisible + ? 'var(--color-bg)' + : 'var(--color-text)'; + }); + + closeBtn.addEventListener('click', () => { + panel.classList.remove('visible'); + toggleBtn.style.backgroundColor = 'var(--color-secondary)'; + toggleBtn.style.color = 'var(--color-text)'; + }); +}()); + // === DEBUG MODE === let debugMode = false; diff --git a/changelog.json b/changelog.json new file mode 100644 index 0000000..385b2e7 --- /dev/null +++ b/changelog.json @@ -0,0 +1,17 @@ +[ + {"hash":"440e31e","date":"2026-03-24","author":"claude","message":"Add photo mode with camera controls and depth of field"}, + {"hash":"2ebd153","date":"2026-03-24","author":"claude","message":"Add test harness for scene validation"}, + {"hash":"4f853aa","date":"2026-03-24","author":"claude","message":"World map overview mode — press Tab for bird's-eye view"}, + {"hash":"316ce63","date":"2026-03-24","author":"claude","message":"Add JSDoc types to all function parameters"}, + {"hash":"7eca0fb","date":"2026-03-24","author":"groq","message":"Debug mode — visualize collision boxes and light sources"}, + {"hash":"3934a7b","date":"2026-03-24","author":"claude","message":"Constellation system — connect nearby stars with faint lines"}, + {"hash":"554a4a0","date":"2026-03-24","author":"groq","message":"WebSocket stub for future live multiplayer"}, + {"hash":"8767f2c","date":"2026-03-24","author":"groq","message":"Manifest.json for PWA install"}, + {"hash":"4c4b776","date":"2026-03-24","author":"groq","message":"Meta tags for SEO and social sharing"}, + {"hash":"b40b7d9","date":"2026-03-24","author":"groq","message":"Ambient sound toggle for the Nexus"}, + {"hash":"db354e8","date":"2026-03-24","author":"claude","message":"NIP-07 visitor identity in the workshop"}, + {"hash":"a377da0","date":"2026-03-24","author":"claude","message":"Agent idle behaviors in 3D world"}, + {"hash":"d0edfe8","date":"2026-03-24","author":"claude","message":"Portal system — entry points to other worlds"}, + {"hash":"e293fbf","date":"2026-03-24","author":"manus","message":"Sovereign Memory Vault — 3D Knowledge Store"}, + {"hash":"6587869","date":"2026-03-24","author":"manus","message":"Three.js scene foundation"} +] diff --git a/index.html b/index.html index 26344f3..eb68ed9 100644 --- a/index.html +++ b/index.html @@ -33,9 +33,21 @@ + + +
+
+ NEXUS CHANGELOG + +
+ +
+
MAP VIEW [Tab] to exit diff --git a/style.css b/style.css index 1d78e52..6e273fc 100644 --- a/style.css +++ b/style.css @@ -106,3 +106,120 @@ canvas { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } } + +/* === CHANGELOG PANEL === */ +#changelog-panel { + display: none; + position: fixed; + bottom: 16px; + left: 16px; + width: 320px; + max-height: 400px; + background: rgba(0, 0, 8, 0.88); + border: 1px solid var(--color-secondary); + border-radius: 6px; + z-index: 20; + font-family: var(--font-body); + font-size: 11px; + overflow: hidden; + box-shadow: 0 0 20px rgba(68, 136, 255, 0.15); +} + +#changelog-panel.visible { + display: flex; + flex-direction: column; +} + +#changelog-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 12px; + border-bottom: 1px solid var(--color-secondary); + background: rgba(51, 68, 136, 0.3); +} + +#changelog-title { + color: var(--color-primary); + letter-spacing: 0.15em; + text-transform: uppercase; + font-size: 10px; +} + +#changelog-close { + background: none; + border: none; + color: var(--color-text-muted); + cursor: pointer; + font-family: var(--font-body); + font-size: 12px; + padding: 0 2px; + line-height: 1; +} + +#changelog-close:hover { + color: var(--color-text); +} + +#changelog-list { + list-style: none; + overflow-y: auto; + max-height: 340px; + padding: 8px 0; +} + +#changelog-list::-webkit-scrollbar { + width: 4px; +} + +#changelog-list::-webkit-scrollbar-track { + background: transparent; +} + +#changelog-list::-webkit-scrollbar-thumb { + background: var(--color-secondary); + border-radius: 2px; +} + +.changelog-entry { + padding: 6px 12px; + border-bottom: 1px solid rgba(51, 68, 136, 0.2); +} + +.changelog-entry:last-child { + border-bottom: none; +} + +.changelog-meta { + display: flex; + gap: 8px; + margin-bottom: 2px; +} + +.changelog-date { + color: var(--color-text-muted); + font-size: 10px; +} + +.changelog-author { + font-size: 10px; + padding: 0 4px; + border-radius: 2px; + background: rgba(68, 136, 255, 0.15); + color: var(--color-primary); +} + +.changelog-author.author-groq { + background: rgba(255, 136, 68, 0.15); + color: #ff8844; +} + +.changelog-author.author-manus { + background: rgba(136, 255, 68, 0.15); + color: #88ff44; +} + +.changelog-message { + color: var(--color-text); + line-height: 1.4; +}