diff --git a/app.js b/app.js index b396094..39ef973 100644 --- a/app.js +++ b/app.js @@ -826,6 +826,9 @@ window.addEventListener('status-update', (/** @type {CustomEvent} */ event) => { window.addEventListener('pr-notification', (/** @type {CustomEvent} */ event) => { console.log('[hermes] PR notification:', event.detail); + if (event.detail && event.detail.action === 'merged') { + triggerMergeFlash(); + } }); // === SOVEREIGNTY EASTER EGG === @@ -898,6 +901,62 @@ function triggerSovereigntyEasterEgg() { requestAnimationFrame(fadeBack); } +/** + * Triggers a visual flash effect for merge events: stars pulse bright, lines glow. + */ +function triggerMergeFlash() { + // Flash constellation lines bright blue-green + const originalLineColor = constellationLines.material.color.getHex(); + constellationLines.material.color.setHex(0x00ffff); + constellationLines.material.opacity = 1.0; + + // Stars burst bright blue-green + const originalStarColor = starMaterial.color.getHex(); + const originalStarOpacity = starMaterial.opacity; + starMaterial.color.setHex(0x00ffff); + starMaterial.opacity = 1.0; + + // Animate fade-out over 2.0s + const startTime = performance.now(); + const DURATION = 2000; // 2 seconds + + function fadeBack() { + const t = Math.min((performance.now() - startTime) / DURATION, 1); + const eased = t * t; // ease in: slow start, fast end + + // Interpolate star color back + const mergeR = 0.0, mergeG = 1.0, mergeB = 1.0; // Cyan + const origStarColor = new THREE.Color(originalStarColor); + starMaterial.color.setRGB( + mergeR + (origStarColor.r - mergeR) * eased, + mergeG + (origStarColor.g - mergeG) * eased, + mergeB + (origStarColor.b - mergeB) * eased + ); + starMaterial.opacity = 1.0 + (originalStarOpacity - 1.0) * eased; + + // Interpolate line color back + const origLineColor = new THREE.Color(originalLineColor); + constellationLines.material.color.setRGB( + mergeR + (origLineColor.r - mergeR) * eased, + mergeG + (origLineColor.g - mergeG) * eased, + mergeB + (origLineColor.b - mergeB) * eased + ); + constellationLines.material.opacity = 1.0 + (0.18 - 1.0) * eased; // Assuming original opacity is 0.18 for lines. + + if (t < 1) { + requestAnimationFrame(fadeBack); + } else { + // Restore originals exactly + starMaterial.color.setHex(originalStarColor); + starMaterial.opacity = originalStarOpacity; + constellationLines.material.color.setHex(originalLineColor); + constellationLines.material.opacity = 0.18; // Explicitly set to original + } + } + + requestAnimationFrame(fadeBack); +} + // Detect 'sovereignty' typed anywhere on the page (cheat-code style) document.addEventListener('keydown', (e) => { if (e.metaKey || e.ctrlKey || e.altKey) return;