Quantum Lattice #1874

Closed
opened 2026-02-16 17:33:02 -05:00 by yindo · 0 comments
Owner

Originally created by @Mjmames on GitHub (Sep 28, 2025).

<html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ethers/6.13.2/ethers.umd.min.js"></script> <style> /* Custom styles for the neon-noir quantum vibe */ body { font-family: 'Roboto', sans-serif; background-color: #000000; color: #e0e0e0; overflow-x: hidden; }
    h1, h2, h3, .font-orbitron {
        font-family: 'Orbitron', sans-serif;
    }

    #bg-canvas {
        position: fixed;
        top: 0;
        left: 0;
        z-index: -1;
        width: 100vw;
        height: 100vh;
    }

    .content-wrapper {
        position: relative;
        z-index: 1;
        background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.9) 70%, #000 100%);
    }

    .neon-text {
        text-shadow:
            0 0 5px rgba(129, 140, 248, 0.8),
            0 0 10px rgba(129, 140, 248, 0.8),
            0 0 20px rgba(129, 140, 248, 0.6),
            0 0 40px rgba(99, 102, 241, 0.5),
            0 0 80px rgba(99, 102, 241, 0.4);
    }

    .violet-text {
        color: #c4b5fd;
         text-shadow:
            0 0 5px rgba(196, 181, 253, 0.8),
            0 0 10px rgba(167, 139, 250, 0.6),
            0 0 20px rgba(139, 92, 246, 0.5);
    }

    .neon-button {
        border: 1px solid rgba(99, 102, 241, 0.8);
        box-shadow: 0 0 5px rgba(99, 102, 241, 0.6), 0 0 10px rgba(99, 102, 241, 0.4) inset;
        transition: all 0.3s ease;
    }
    .neon-button:hover {
        background-color: rgba(99, 102, 241, 0.2);
        box-shadow: 0 0 10px rgba(129, 140, 248, 0.8), 0 0 20px rgba(129, 140, 248, 0.6) inset;
        transform: translateY(-2px);
    }
    
    .glitch-card {
        background: rgba(17, 24, 39, 0.5);
        backdrop-filter: blur(10px);
        border: 1px solid rgba(129, 140, 248, 0.3);
        position: relative;
        overflow: hidden;
    }

    .glitch-card::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(0deg, transparent 50%, rgba(99, 102, 241, 0.1) 50%);
        background-size: 100% 4px;
        animation: glitch-scan 8s linear infinite;
        pointer-events: none;
    }

    .holographic-orb {
        animation: float 6s ease-in-out infinite;
    }
    
    #weave-canvas {
        cursor: crosshair;
        touch-action: none;
    }

    @keyframes float {
        0% { transform: translateY(0px); }
        50% { transform: translateY(-20px); }
        100% { transform: translateY(0px); }
    }

    @keyframes glitch-scan {
        0% { background-position: 0 0; }
        100% { background-position: 0 -200px; }
    }
</style>
</head>
<div class="content-wrapper min-h-screen">
    <header class="fixed top-0 left-0 right-0 z-20 bg-black/50 backdrop-blur-sm p-4">
        <div class="container mx-auto flex justify-between items-center">
            <h1 class="text-xl md:text-2xl font-bold neon-text">Quantum Lattice Hub</h1>
            <button id="connectWalletBtn" class="neon-button text-sm md:text-base font-bold py-2 px-4 rounded-lg text-indigo-300">
                Connect Wallet
            </button>
        </div>
    </header>

    <main class="container mx-auto px-4 pt-24 pb-12">
        <!-- Hero Section -->
        <section id="hero" class="text-center min-h-[70vh] flex flex-col justify-center items-center">
            <h2 class="text-4xl md:text-6xl font-bold neon-text leading-tight">Weave the Cosmos</h2>
            <h3 class="text-3xl md:text-5xl font-bold violet-text mt-2">Echo the Void</h3>
            <p class="max-w-3xl mx-auto mt-6 text-gray-300 text-lg">
                This is not a platform; it's a living Möbius strip of sound and shadow. A neon-noir symphony where music isn't consumed—it's <span class="font-bold text-indigo-300">entangled</span>.
            </p>
            <div class="mt-8">
                <a href="#game" class="neon-button text-lg font-bold py-3 px-8 rounded-lg text-indigo-300">
                    Enter the Weave
                </a>
            </div>
        </section>

        <!-- The Vibe Section -->
        <section id="vibe" class="my-24">
            <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 violet-text">Neon Shadows, Entangled Echoes</h2>
            <div class="grid md:grid-cols-3 gap-8">
                <div class="glitch-card p-6 rounded-xl">
                    <h3 class="text-2xl font-bold text-indigo-300 mb-3">Visuals</h3>
                    <p class="text-gray-400">Möbius strips uncoil into infinite loops. Backgrounds shift from obsidian black to fractured prisms, with holographic orbs floating like forbidden fruit. Your playtime, visualized as quantum fluctuations.</p>
                </div>
                <div class="glitch-card p-6 rounded-xl">
                    <h3 class="text-2xl font-bold text-indigo-300 mb-3">Lore</h3>
                    <p class="text-gray-400">You are a "Resonator." The Lattice is fracturing, and music is lost to the Void. Listeners mend it with vibes; creators forge new strands. Airdrops are "entanglements"—rewards linking players in a shared cosmic destiny.</p>
                </div>
                <div class="glitch-card p-6 rounded-xl">
                    <h3 class="text-2xl font-bold text-indigo-300 mb-3">Soundscape</h3>
                    <p class="text-gray-400">Ambient synth drones underscore your journey. AI remixes snippets in real-time, birthing "Void Echoes"—haunting, procedural beats that feel personal, like the universe whispering back just to you.</p>
                </div>
            </div>
        </section>

        <!-- The Game Section -->
        <section id="game" class="my-24">
            <h2 class="text-3xl md:text-4xl font-bold text-center mb-4 violet-text">Resonance Weave</h2>
            <p class="text-center text-lg max-w-3xl mx-auto mb-12 text-gray-300">A Proof-of-Play ritual. Light, addictive, and deeply quantum. Your music choices build a shared quantum web that ripples across the hub.</p>
            
            <div class="glitch-card p-4 md:p-8 rounded-xl max-w-4xl mx-auto">
                <div id="game-container" class="bg-black rounded-lg p-4 relative">
                    <canvas id="weave-canvas" class="w-full h-64 md:h-96 rounded-md"></canvas>
                    <div id="game-overlay" class="absolute inset-0 flex flex-col justify-center items-center bg-black/70 rounded-md">
                        <h3 id="game-status" class="text-2xl font-bold text-white mb-4">Ready to Weave?</h3>
                        <button id="startGameBtn" class="neon-button text-lg font-bold py-3 px-8 rounded-lg text-indigo-300">Spin Superposition</button>
                    </div>
                </div>
                 <div class="text-center mt-4">
                    <p class="text-gray-400">Trace the glowing waveform with your cursor or finger to strengthen the strand. Perfection earns LATTICE points.</p>
                </div>
            </div>
        </section>

         <!-- Tokens Section -->
        <section id="tokens" class="my-24">
            <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 violet-text">The Quantum Contracts</h2>
             <div class="grid md:grid-cols-2 gap-8 max-w-5xl mx-auto">
                <!-- $QLC Card -->
                <div class="glitch-card p-8 rounded-xl flex flex-col items-center text-center">
                    <div class="holographic-orb w-24 h-24 rounded-full bg-gradient-to-br from-indigo-500 to-blue-400 flex justify-center items-center shadow-2xl shadow-indigo-500/50 mb-4">
                       <span class="text-3xl font-orbitron font-bold text-white">$QLC</span>
                    </div>
                    <h3 class="text-3xl font-bold text-indigo-300">The Listener's Echo</h3>
                    <p class="text-lg my-3">0.0025 ETH</p>
                    <p class="text-gray-400 flex-grow">For Resonators who mend the Lattice. Use $QLC to unlock premium weaves and amplify your resonance across the Void.</p>
                    <button class="buy-token-btn mt-6 neon-button w-full font-bold py-3 px-6 rounded-lg text-indigo-300" data-token="QLC">
                        Acquire $QLC
                    </button>
                </div>
                <!-- $QUANTUM Card -->
                <div class="glitch-card p-8 rounded-xl flex flex-col items-center text-center">
                     <div class="holographic-orb w-24 h-24 rounded-full bg-gradient-to-br from-purple-500 to-violet-400 flex justify-center items-center shadow-2xl shadow-purple-500/50 mb-4">
                       <span class="text-3xl font-orbitron font-bold text-white">$QNTM</span>
                    </div>
                    <h3 class="text-3xl font-bold text-violet-300">The Creator's Spark</h3>
                    <p class="text-lg my-3">0.025 ETH</p>
                    <p class="text-gray-400 flex-grow">For Resonators who forge new realities. Use $QUANTUM to mint your woven strands into timeless tracks and monetize your cosmic art.</p>
                    <button class="buy-token-btn mt-6 neon-button w-full font-bold py-3 px-6 rounded-lg text-violet-300" data-token="QUANTUM">
                        Acquire $QUANTUM
                    </button>
                </div>
            </div>
        </section>

    </main>

    <footer class="text-center py-8 border-t border-indigo-900/50">
        <p class="text-gray-400">Quantum Lattice Hub - Entangling towards 2028</p>
        <p class="text-xs text-gray-600 mt-2">Receiver Wallet: <span id="receiverWallet">0xc00A9...5822</span></p>
         <div class="mt-4">
            <a href="#" class="text-indigo-400 hover:text-indigo-200 mx-2">Discord</a>
            <a href="#" class="text-indigo-400 hover:text-indigo-200 mx-2">X (Twitter)</a>
        </div>
    </footer>
</div>

<!-- Modal for notifications -->
<div id="notification-modal" class="hidden fixed inset-0 bg-black/60 z-50 flex justify-center items-center p-4">
    <div class="glitch-card max-w-sm w-full p-6 rounded-xl text-center">
        <h3 id="modal-title" class="text-2xl font-bold text-indigo-300 mb-3">Notification</h3>
        <p id="modal-message" class="text-gray-300 mb-6"></p>
        <button id="modal-close" class="neon-button font-bold py-2 px-6 rounded-lg text-indigo-300">Close</button>
    </div>
</div>


<script>
    // --- Service Worker for PWA ---
    if ('serviceWorker' in navigator) {
        const sw = `
            self.addEventListener('install', (e) => {
                e.waitUntil(
                    caches.open('qlh-cache').then((cache) => {
                        return cache.addAll(['/']);
                    })
                );
            });

            self.addEventListener('fetch', (e) => {
                e.respondWith(
                    caches.match(e.request).then((response) => {
                        return response || fetch(e.request);
                    })
                );
            });
        `;
        const blob = new Blob([sw], { type: 'application/javascript' });
        const swUrl = URL.createObjectURL(blob);
        navigator.serviceWorker.register(swUrl).then(function(registration) {
            console.log('Service Worker registration successful with scope: ', registration.scope);
        }).catch(function(err) {
            console.log('Service Worker registration failed: ', err);
        });
    }
    
    // --- Three.js Background Animation ---
    let scene, camera, renderer, particles;

    function initBackground() {
        const canvas = document.getElementById('bg-canvas');
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true });
        renderer.setSize(window.innerWidth, window.innerHeight);

        const particleCount = 5000;
        const geometry = new THREE.BufferGeometry();
        const positions = new Float32Array(particleCount * 3);

        for (let i = 0; i < particleCount * 3; i++) {
            positions[i] = (Math.random() - 0.5) * 10;
        }
        geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
        
        const material = new THREE.PointsMaterial({
            color: 0x6366f1,
            size: 0.015,
            transparent: true,
            blending: THREE.AdditiveBlending
        });

        particles = new THREE.Points(geometry, material);
        scene.add(particles);

        camera.position.z = 5;

        animate();
    }

    let clock = new THREE.Clock();

    function animate() {
        requestAnimationFrame(animate);
        const elapsedTime = clock.getElapsedTime();
        
        particles.rotation.y = elapsedTime * 0.1;
        particles.rotation.x = elapsedTime * 0.05;

        renderer.render(scene, camera);
    }

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    window.addEventListener('resize', onWindowResize, false);
    
    // --- Modal/Notification Logic ---
    const modal = document.getElementById('notification-modal');
    const modalTitle = document.getElementById('modal-title');
    const modalMessage = document.getElementById('modal-message');
    const modalClose = document.getElementById('modal-close');
    
    function showNotification(title, message) {
        modalTitle.textContent = title;
        modalMessage.textContent = message;
        modal.classList.remove('hidden');
    }
    
    modalClose.addEventListener('click', () => modal.classList.add('hidden'));

    // --- Web3 Wallet Connection ---
    const connectWalletBtn = document.getElementById('connectWalletBtn');
    let userAccount = null;

    const contracts = {
        QLC: '0xC83793B6bb4f00e61A519646dd124dCabD6D7155',
        QUANTUM: '0xfbf50123AD439fD64EB417CCA3483852Beb4C172'
    };
    const receiverWallet = '0xc00A961c98105e5e5ABCe9c8B26d021fC4Eb5822';
    document.getElementById('receiverWallet').textContent = `${receiverWallet.slice(0,6)}...${receiverWallet.slice(-4)}`;

    function handleAccountsChanged(accounts) {
        if (accounts.length === 0) {
            // MetaMask is locked or the user has disconnected all accounts.
            userAccount = null;
            connectWalletBtn.textContent = 'Connect Wallet';
            showNotification('Wallet Disconnected', 'Your wallet has been disconnected. Please connect again.');
        } else if (accounts[0] !== userAccount) {
            userAccount = accounts[0];
            connectWalletBtn.textContent = `${userAccount.slice(0, 6)}...${userAccount.slice(-4)}`;
            showNotification('Account Switched', `Switched to account: ${userAccount}`);
        }
    }
    
    function updateConnectionStatus(accounts) {
         if (accounts.length > 0) {
            userAccount = accounts[0];
            connectWalletBtn.textContent = `${userAccount.slice(0, 6)}...${userAccount.slice(-4)}`;
        } else {
            userAccount = null;
            connectWalletBtn.textContent = 'Connect Wallet';
        }
    }

    async function connectWallet() {
        if (typeof window.ethereum !== 'undefined') {
            try {
                const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
                updateConnectionStatus(accounts);
                showNotification('Wallet Connected', `Your wallet ${accounts[0]} has been successfully connected.`);
            } catch (error) {
                console.error('Connection error:', error);
                if (error.code === 4001) {
                    showNotification('Connection Failed', 'You rejected the wallet connection request.');
                } else {
                    showNotification('Connection Failed', 'An error occurred while connecting your wallet.');
                }
            }
        } else {
            showNotification('MetaMask Not Found', 'No Ethereum wallet detected. Redirecting to install MetaMask...');
            setTimeout(() => {
                window.open('https://metamask.io/download/', '_blank');
            }, 3000);
        }
    }

    function setupWalletListeners() {
        if (typeof window.ethereum !== 'undefined') {
            // Listen for account changes
            window.ethereum.on('accountsChanged', handleAccountsChanged);

            // Listen for network changes
            window.ethereum.on('chainChanged', (_chainId) => {
                showNotification('Network Changed', 'The network has been changed. Reloading the page for consistency.');
                setTimeout(() => window.location.reload(), 2000);
            });
            
            // Check for existing connection on page load without prompting user
            window.ethereum.request({ method: 'eth_accounts' })
                .then(updateConnectionStatus)
                .catch(err => {
                    console.error("Could not check for existing wallet connection:", err);
                });
        }
    }

    connectWalletBtn.addEventListener('click', connectWallet);
    
    document.querySelectorAll('.buy-token-btn').forEach(button => {
        button.addEventListener('click', async (e) => {
            if (!userAccount) {
                showNotification('Wallet Not Connected', 'Please connect your wallet first to acquire tokens.');
                return;
            }
            
            const token = e.target.getAttribute('data-token');
            const isQLC = token === 'QLC';
            const value = isQLC ? '0.0025' : '0.025';
            const contractAddress = contracts[token];
            
            showNotification('Transaction Initiated', `Acquiring $${token} for ${value} ETH. Please confirm in your wallet.`);
            
            // This is a simulation of the transaction.
            // In a real app, you would use ethers.js or web3.js to call the contract.
            console.log(`--- SIMULATING TRANSACTION ---`);
            console.log(`Token: $${token}`);
            console.log(`Value: ${value} ETH`);
            console.log(`From: ${userAccount}`);
            console.log(`To Contract: ${contractAddress}`);
            console.log(`Fee Receiver: ${receiverWallet}`);
            
            try {
                const provider = new ethers.providers.Web3Provider(window.ethereum);
                const signer = provider.getSigner();
                const tx = await signer.sendTransaction({
                   to: contractAddress,
                   value: ethers.utils.parseEther(value)
                });
                await tx.wait();
                showNotification('Transaction Successful', `You have acquired $${token}.`);
                
            } catch (error) {
                console.error("Transaction failed:", error);
                showNotification('Transaction Failed', 'There was an error processing your transaction.');
            }
        });
    });


    // --- Resonance Weave Game Logic ---
    const gameCanvas = document.getElementById('weave-canvas');
    const gameCtx = gameCanvas.getContext('2d');
    const startGameBtn = document.getElementById('startGameBtn');
    const gameOverlay = document.getElementById('game-overlay');
    const gameStatus = document.getElementById('game-status');

    let isDrawing = false;
    let path = [];
    let targetWave = [];
    let animationFrameId;

    function resizeCanvas() {
        const container = document.getElementById('game-container');
        gameCanvas.width = container.clientWidth;
        gameCanvas.height = container.clientHeight;
    }

    function generateTargetWave() {
        targetWave = [];
        const amplitude = gameCanvas.height / 4;
        const frequency = Math.random() * 2 + 2; // Randomize frequency
        const yOffset = gameCanvas.height / 2;
        for (let x = 0; x < gameCanvas.width; x++) {
            const y = Math.sin((x / gameCanvas.width) * frequency * Math.PI) * amplitude + yOffset;
            targetWave.push({ x, y });
        }
    }
    
    function draw() {
        gameCtx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);

        // Draw target wave
        gameCtx.beginPath();
        gameCtx.moveTo(targetWave[0].x, targetWave[0].y);
        for (let i = 1; i < targetWave.length; i++) {
            gameCtx.lineTo(targetWave[i].x, targetWave[i].y);
        }
        gameCtx.strokeStyle = 'rgba(99, 102, 241, 0.5)';
        gameCtx.lineWidth = 10;
        gameCtx.lineCap = 'round';
        gameCtx.shadowColor = 'rgba(129, 140, 248, 1)';
        gameCtx.shadowBlur = 15;
        gameCtx.stroke();
        gameCtx.shadowBlur = 0;


        // Draw user path
        if(path.length > 1) {
            gameCtx.beginPath();
            gameCtx.moveTo(path[0].x, path[0].y);
            for (let i = 1; i < path.length; i++) {
                gameCtx.lineTo(path[i].x, path[i].y);
            }
            gameCtx.strokeStyle = '#c4b5fd';
            gameCtx.lineWidth = 4;
            gameCtx.stroke();
        }
    }

    function calculateScore() {
        let totalDistance = 0;
        let pointCount = 0;

        path.forEach(point => {
            const targetPoint = targetWave[Math.floor(point.x)];
            if(targetPoint){
                const distance = Math.abs(point.y - targetPoint.y);
                totalDistance += distance;
                pointCount++;
            }
        });

        const avgDistance = totalDistance / pointCount;
        const maxDistance = gameCanvas.height / 4;
        const score = Math.max(0, 100 - (avgDistance / maxDistance) * 100);
        return score;
    }

    function endGame() {
        isDrawing = false;
        cancelAnimationFrame(animationFrameId);
        const score = calculateScore();
        
        gameOverlay.style.display = 'flex';
        if(score > 80) {
            gameStatus.innerHTML = `Resonance Peak! <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`;
            showNotification("Strand Woven", `Your weave was near perfect. +10 LATTICE points.`);
        } else if (score > 50) {
             gameStatus.innerHTML = `Strand Woven. <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`;
             showNotification("Strand Stabilized", `Your weave holds. +5 LATTICE points.`);
        } else {
             gameStatus.innerHTML = `Strand Frayed... <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`;
             showNotification("Void Echoes", `The strand frayed but revealed a mystery echo.`);
        }
        startGameBtn.textContent = 'Weave Again';
    }

    function getEventPosition(event) {
        const rect = gameCanvas.getBoundingClientRect();
        if (event.touches) {
            return { x: event.touches[0].clientX - rect.left, y: event.touches[0].clientY - rect.top };
        }
        return { x: event.clientX - rect.left, y: event.clientY - rect.top };
    }

    gameCanvas.addEventListener('mousedown', (e) => {
        if(!animationFrameId) return;
        isDrawing = true;
        path = [getEventPosition(e)];
    });
    
    gameCanvas.addEventListener('touchstart', (e) => {
        if(!animationFrameId) return;
        e.preventDefault();
        isDrawing = true;
        path = [getEventPosition(e)];
    });

    gameCanvas.addEventListener('mousemove', (e) => {
        if (isDrawing) {
            path.push(getEventPosition(e));
            draw();
        }
    });

    gameCanvas.addEventListener('touchmove', (e) => {
        if (isDrawing) {
            e.preventDefault();
            path.push(getEventPosition(e));
            draw();
        }
    });

    window.addEventListener('mouseup', () => { if(isDrawing) endGame(); });
    gameCanvas.addEventListener('touchend', () => { if(isDrawing) endGame(); });
    
    function gameLoop() {
        draw();
        animationFrameId = requestAnimationFrame(gameLoop);
    }

    startGameBtn.addEventListener('click', () => {
        if (!userAccount) {
             showNotification('Wallet Not Connected', 'Please connect your wallet to start weaving.');
             return;
        }
        resizeCanvas();
        path = [];
        generateTargetWave();
        gameOverlay.style.display = 'none';
        animationFrameId = requestAnimationFrame(gameLoop);
    });
    
    // --- Initial Load ---
    document.addEventListener('DOMContentLoaded', () => {
        initBackground();
        setupWalletListeners(); // Set up MetaMask event listeners and check connection
        resizeCanvas(); // Initial size for game canvas
        generateTargetWave();
        draw(); // Draw the initial target wave
    });
    
</script>
</html>
Originally created by @Mjmames on GitHub (Sep 28, 2025). <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Quantum Lattice Hub</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Roboto:wght@300;400&display=swap" rel="stylesheet"> <link rel="manifest" href="data:application/manifest+json,{ &quot;name&quot;: &quot;Quantum Lattice Hub&quot;, &quot;short_name&quot;: &quot;QLH&quot;, &quot;start_url&quot;: &quot;.&quot;, &quot;display&quot;: &quot;standalone&quot;, &quot;background_color&quot;: &quot;#000000&quot;, &quot;theme_color&quot;: &quot;#4f46e5&quot;, &quot;description&quot;: &quot;Weave the Cosmos, Echo the Void.&quot;, &quot;icons&quot;: [{ &quot;src&quot;: &quot;https://placehold.co/192x192/000000/818cf8?text=QLH&quot;, &quot;sizes&quot;: &quot;192x192&quot;, &quot;type&quot;: &quot;image/png&quot; }, { &quot;src&quot;: &quot;https://placehold.co/512x512/000000/818cf8?text=QLH&quot;, &quot;sizes&quot;: &quot;512x512&quot;, &quot;type&quot;: &quot;image/png&quot; }] }"> <script src="https://cdnjs.cloudflare.com/ajax/libs/ethers/6.13.2/ethers.umd.min.js"></script> <style> /* Custom styles for the neon-noir quantum vibe */ body { font-family: 'Roboto', sans-serif; background-color: #000000; color: #e0e0e0; overflow-x: hidden; } h1, h2, h3, .font-orbitron { font-family: 'Orbitron', sans-serif; } #bg-canvas { position: fixed; top: 0; left: 0; z-index: -1; width: 100vw; height: 100vh; } .content-wrapper { position: relative; z-index: 1; background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.9) 70%, #000 100%); } .neon-text { text-shadow: 0 0 5px rgba(129, 140, 248, 0.8), 0 0 10px rgba(129, 140, 248, 0.8), 0 0 20px rgba(129, 140, 248, 0.6), 0 0 40px rgba(99, 102, 241, 0.5), 0 0 80px rgba(99, 102, 241, 0.4); } .violet-text { color: #c4b5fd; text-shadow: 0 0 5px rgba(196, 181, 253, 0.8), 0 0 10px rgba(167, 139, 250, 0.6), 0 0 20px rgba(139, 92, 246, 0.5); } .neon-button { border: 1px solid rgba(99, 102, 241, 0.8); box-shadow: 0 0 5px rgba(99, 102, 241, 0.6), 0 0 10px rgba(99, 102, 241, 0.4) inset; transition: all 0.3s ease; } .neon-button:hover { background-color: rgba(99, 102, 241, 0.2); box-shadow: 0 0 10px rgba(129, 140, 248, 0.8), 0 0 20px rgba(129, 140, 248, 0.6) inset; transform: translateY(-2px); } .glitch-card { background: rgba(17, 24, 39, 0.5); backdrop-filter: blur(10px); border: 1px solid rgba(129, 140, 248, 0.3); position: relative; overflow: hidden; } .glitch-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(0deg, transparent 50%, rgba(99, 102, 241, 0.1) 50%); background-size: 100% 4px; animation: glitch-scan 8s linear infinite; pointer-events: none; } .holographic-orb { animation: float 6s ease-in-out infinite; } #weave-canvas { cursor: crosshair; touch-action: none; } @keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-20px); } 100% { transform: translateY(0px); } } @keyframes glitch-scan { 0% { background-position: 0 0; } 100% { background-position: 0 -200px; } } </style> </head> <body class="antialiased"> <canvas id="bg-canvas"></canvas> <div class="content-wrapper min-h-screen"> <header class="fixed top-0 left-0 right-0 z-20 bg-black/50 backdrop-blur-sm p-4"> <div class="container mx-auto flex justify-between items-center"> <h1 class="text-xl md:text-2xl font-bold neon-text">Quantum Lattice Hub</h1> <button id="connectWalletBtn" class="neon-button text-sm md:text-base font-bold py-2 px-4 rounded-lg text-indigo-300"> Connect Wallet </button> </div> </header> <main class="container mx-auto px-4 pt-24 pb-12"> <!-- Hero Section --> <section id="hero" class="text-center min-h-[70vh] flex flex-col justify-center items-center"> <h2 class="text-4xl md:text-6xl font-bold neon-text leading-tight">Weave the Cosmos</h2> <h3 class="text-3xl md:text-5xl font-bold violet-text mt-2">Echo the Void</h3> <p class="max-w-3xl mx-auto mt-6 text-gray-300 text-lg"> This is not a platform; it's a living Möbius strip of sound and shadow. A neon-noir symphony where music isn't consumed—it's <span class="font-bold text-indigo-300">entangled</span>. </p> <div class="mt-8"> <a href="#game" class="neon-button text-lg font-bold py-3 px-8 rounded-lg text-indigo-300"> Enter the Weave </a> </div> </section> <!-- The Vibe Section --> <section id="vibe" class="my-24"> <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 violet-text">Neon Shadows, Entangled Echoes</h2> <div class="grid md:grid-cols-3 gap-8"> <div class="glitch-card p-6 rounded-xl"> <h3 class="text-2xl font-bold text-indigo-300 mb-3">Visuals</h3> <p class="text-gray-400">Möbius strips uncoil into infinite loops. Backgrounds shift from obsidian black to fractured prisms, with holographic orbs floating like forbidden fruit. Your playtime, visualized as quantum fluctuations.</p> </div> <div class="glitch-card p-6 rounded-xl"> <h3 class="text-2xl font-bold text-indigo-300 mb-3">Lore</h3> <p class="text-gray-400">You are a "Resonator." The Lattice is fracturing, and music is lost to the Void. Listeners mend it with vibes; creators forge new strands. Airdrops are "entanglements"—rewards linking players in a shared cosmic destiny.</p> </div> <div class="glitch-card p-6 rounded-xl"> <h3 class="text-2xl font-bold text-indigo-300 mb-3">Soundscape</h3> <p class="text-gray-400">Ambient synth drones underscore your journey. AI remixes snippets in real-time, birthing "Void Echoes"—haunting, procedural beats that feel personal, like the universe whispering back just to you.</p> </div> </div> </section> <!-- The Game Section --> <section id="game" class="my-24"> <h2 class="text-3xl md:text-4xl font-bold text-center mb-4 violet-text">Resonance Weave</h2> <p class="text-center text-lg max-w-3xl mx-auto mb-12 text-gray-300">A Proof-of-Play ritual. Light, addictive, and deeply quantum. Your music choices build a shared quantum web that ripples across the hub.</p> <div class="glitch-card p-4 md:p-8 rounded-xl max-w-4xl mx-auto"> <div id="game-container" class="bg-black rounded-lg p-4 relative"> <canvas id="weave-canvas" class="w-full h-64 md:h-96 rounded-md"></canvas> <div id="game-overlay" class="absolute inset-0 flex flex-col justify-center items-center bg-black/70 rounded-md"> <h3 id="game-status" class="text-2xl font-bold text-white mb-4">Ready to Weave?</h3> <button id="startGameBtn" class="neon-button text-lg font-bold py-3 px-8 rounded-lg text-indigo-300">Spin Superposition</button> </div> </div> <div class="text-center mt-4"> <p class="text-gray-400">Trace the glowing waveform with your cursor or finger to strengthen the strand. Perfection earns LATTICE points.</p> </div> </div> </section> <!-- Tokens Section --> <section id="tokens" class="my-24"> <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 violet-text">The Quantum Contracts</h2> <div class="grid md:grid-cols-2 gap-8 max-w-5xl mx-auto"> <!-- $QLC Card --> <div class="glitch-card p-8 rounded-xl flex flex-col items-center text-center"> <div class="holographic-orb w-24 h-24 rounded-full bg-gradient-to-br from-indigo-500 to-blue-400 flex justify-center items-center shadow-2xl shadow-indigo-500/50 mb-4"> <span class="text-3xl font-orbitron font-bold text-white">$QLC</span> </div> <h3 class="text-3xl font-bold text-indigo-300">The Listener's Echo</h3> <p class="text-lg my-3">0.0025 ETH</p> <p class="text-gray-400 flex-grow">For Resonators who mend the Lattice. Use $QLC to unlock premium weaves and amplify your resonance across the Void.</p> <button class="buy-token-btn mt-6 neon-button w-full font-bold py-3 px-6 rounded-lg text-indigo-300" data-token="QLC"> Acquire $QLC </button> </div> <!-- $QUANTUM Card --> <div class="glitch-card p-8 rounded-xl flex flex-col items-center text-center"> <div class="holographic-orb w-24 h-24 rounded-full bg-gradient-to-br from-purple-500 to-violet-400 flex justify-center items-center shadow-2xl shadow-purple-500/50 mb-4"> <span class="text-3xl font-orbitron font-bold text-white">$QNTM</span> </div> <h3 class="text-3xl font-bold text-violet-300">The Creator's Spark</h3> <p class="text-lg my-3">0.025 ETH</p> <p class="text-gray-400 flex-grow">For Resonators who forge new realities. Use $QUANTUM to mint your woven strands into timeless tracks and monetize your cosmic art.</p> <button class="buy-token-btn mt-6 neon-button w-full font-bold py-3 px-6 rounded-lg text-violet-300" data-token="QUANTUM"> Acquire $QUANTUM </button> </div> </div> </section> </main> <footer class="text-center py-8 border-t border-indigo-900/50"> <p class="text-gray-400">Quantum Lattice Hub - Entangling towards 2028</p> <p class="text-xs text-gray-600 mt-2">Receiver Wallet: <span id="receiverWallet">0xc00A9...5822</span></p> <div class="mt-4"> <a href="#" class="text-indigo-400 hover:text-indigo-200 mx-2">Discord</a> <a href="#" class="text-indigo-400 hover:text-indigo-200 mx-2">X (Twitter)</a> </div> </footer> </div> <!-- Modal for notifications --> <div id="notification-modal" class="hidden fixed inset-0 bg-black/60 z-50 flex justify-center items-center p-4"> <div class="glitch-card max-w-sm w-full p-6 rounded-xl text-center"> <h3 id="modal-title" class="text-2xl font-bold text-indigo-300 mb-3">Notification</h3> <p id="modal-message" class="text-gray-300 mb-6"></p> <button id="modal-close" class="neon-button font-bold py-2 px-6 rounded-lg text-indigo-300">Close</button> </div> </div> <script> // --- Service Worker for PWA --- if ('serviceWorker' in navigator) { const sw = ` self.addEventListener('install', (e) => { e.waitUntil( caches.open('qlh-cache').then((cache) => { return cache.addAll(['/']); }) ); }); self.addEventListener('fetch', (e) => { e.respondWith( caches.match(e.request).then((response) => { return response || fetch(e.request); }) ); }); `; const blob = new Blob([sw], { type: 'application/javascript' }); const swUrl = URL.createObjectURL(blob); navigator.serviceWorker.register(swUrl).then(function(registration) { console.log('Service Worker registration successful with scope: ', registration.scope); }).catch(function(err) { console.log('Service Worker registration failed: ', err); }); } // --- Three.js Background Animation --- let scene, camera, renderer, particles; function initBackground() { const canvas = document.getElementById('bg-canvas'); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); const particleCount = 5000; const geometry = new THREE.BufferGeometry(); const positions = new Float32Array(particleCount * 3); for (let i = 0; i < particleCount * 3; i++) { positions[i] = (Math.random() - 0.5) * 10; } geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); const material = new THREE.PointsMaterial({ color: 0x6366f1, size: 0.015, transparent: true, blending: THREE.AdditiveBlending }); particles = new THREE.Points(geometry, material); scene.add(particles); camera.position.z = 5; animate(); } let clock = new THREE.Clock(); function animate() { requestAnimationFrame(animate); const elapsedTime = clock.getElapsedTime(); particles.rotation.y = elapsedTime * 0.1; particles.rotation.x = elapsedTime * 0.05; renderer.render(scene, camera); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } window.addEventListener('resize', onWindowResize, false); // --- Modal/Notification Logic --- const modal = document.getElementById('notification-modal'); const modalTitle = document.getElementById('modal-title'); const modalMessage = document.getElementById('modal-message'); const modalClose = document.getElementById('modal-close'); function showNotification(title, message) { modalTitle.textContent = title; modalMessage.textContent = message; modal.classList.remove('hidden'); } modalClose.addEventListener('click', () => modal.classList.add('hidden')); // --- Web3 Wallet Connection --- const connectWalletBtn = document.getElementById('connectWalletBtn'); let userAccount = null; const contracts = { QLC: '0xC83793B6bb4f00e61A519646dd124dCabD6D7155', QUANTUM: '0xfbf50123AD439fD64EB417CCA3483852Beb4C172' }; const receiverWallet = '0xc00A961c98105e5e5ABCe9c8B26d021fC4Eb5822'; document.getElementById('receiverWallet').textContent = `${receiverWallet.slice(0,6)}...${receiverWallet.slice(-4)}`; function handleAccountsChanged(accounts) { if (accounts.length === 0) { // MetaMask is locked or the user has disconnected all accounts. userAccount = null; connectWalletBtn.textContent = 'Connect Wallet'; showNotification('Wallet Disconnected', 'Your wallet has been disconnected. Please connect again.'); } else if (accounts[0] !== userAccount) { userAccount = accounts[0]; connectWalletBtn.textContent = `${userAccount.slice(0, 6)}...${userAccount.slice(-4)}`; showNotification('Account Switched', `Switched to account: ${userAccount}`); } } function updateConnectionStatus(accounts) { if (accounts.length > 0) { userAccount = accounts[0]; connectWalletBtn.textContent = `${userAccount.slice(0, 6)}...${userAccount.slice(-4)}`; } else { userAccount = null; connectWalletBtn.textContent = 'Connect Wallet'; } } async function connectWallet() { if (typeof window.ethereum !== 'undefined') { try { const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); updateConnectionStatus(accounts); showNotification('Wallet Connected', `Your wallet ${accounts[0]} has been successfully connected.`); } catch (error) { console.error('Connection error:', error); if (error.code === 4001) { showNotification('Connection Failed', 'You rejected the wallet connection request.'); } else { showNotification('Connection Failed', 'An error occurred while connecting your wallet.'); } } } else { showNotification('MetaMask Not Found', 'No Ethereum wallet detected. Redirecting to install MetaMask...'); setTimeout(() => { window.open('https://metamask.io/download/', '_blank'); }, 3000); } } function setupWalletListeners() { if (typeof window.ethereum !== 'undefined') { // Listen for account changes window.ethereum.on('accountsChanged', handleAccountsChanged); // Listen for network changes window.ethereum.on('chainChanged', (_chainId) => { showNotification('Network Changed', 'The network has been changed. Reloading the page for consistency.'); setTimeout(() => window.location.reload(), 2000); }); // Check for existing connection on page load without prompting user window.ethereum.request({ method: 'eth_accounts' }) .then(updateConnectionStatus) .catch(err => { console.error("Could not check for existing wallet connection:", err); }); } } connectWalletBtn.addEventListener('click', connectWallet); document.querySelectorAll('.buy-token-btn').forEach(button => { button.addEventListener('click', async (e) => { if (!userAccount) { showNotification('Wallet Not Connected', 'Please connect your wallet first to acquire tokens.'); return; } const token = e.target.getAttribute('data-token'); const isQLC = token === 'QLC'; const value = isQLC ? '0.0025' : '0.025'; const contractAddress = contracts[token]; showNotification('Transaction Initiated', `Acquiring $${token} for ${value} ETH. Please confirm in your wallet.`); // This is a simulation of the transaction. // In a real app, you would use ethers.js or web3.js to call the contract. console.log(`--- SIMULATING TRANSACTION ---`); console.log(`Token: $${token}`); console.log(`Value: ${value} ETH`); console.log(`From: ${userAccount}`); console.log(`To Contract: ${contractAddress}`); console.log(`Fee Receiver: ${receiverWallet}`); try { const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); const tx = await signer.sendTransaction({ to: contractAddress, value: ethers.utils.parseEther(value) }); await tx.wait(); showNotification('Transaction Successful', `You have acquired $${token}.`); } catch (error) { console.error("Transaction failed:", error); showNotification('Transaction Failed', 'There was an error processing your transaction.'); } }); }); // --- Resonance Weave Game Logic --- const gameCanvas = document.getElementById('weave-canvas'); const gameCtx = gameCanvas.getContext('2d'); const startGameBtn = document.getElementById('startGameBtn'); const gameOverlay = document.getElementById('game-overlay'); const gameStatus = document.getElementById('game-status'); let isDrawing = false; let path = []; let targetWave = []; let animationFrameId; function resizeCanvas() { const container = document.getElementById('game-container'); gameCanvas.width = container.clientWidth; gameCanvas.height = container.clientHeight; } function generateTargetWave() { targetWave = []; const amplitude = gameCanvas.height / 4; const frequency = Math.random() * 2 + 2; // Randomize frequency const yOffset = gameCanvas.height / 2; for (let x = 0; x < gameCanvas.width; x++) { const y = Math.sin((x / gameCanvas.width) * frequency * Math.PI) * amplitude + yOffset; targetWave.push({ x, y }); } } function draw() { gameCtx.clearRect(0, 0, gameCanvas.width, gameCanvas.height); // Draw target wave gameCtx.beginPath(); gameCtx.moveTo(targetWave[0].x, targetWave[0].y); for (let i = 1; i < targetWave.length; i++) { gameCtx.lineTo(targetWave[i].x, targetWave[i].y); } gameCtx.strokeStyle = 'rgba(99, 102, 241, 0.5)'; gameCtx.lineWidth = 10; gameCtx.lineCap = 'round'; gameCtx.shadowColor = 'rgba(129, 140, 248, 1)'; gameCtx.shadowBlur = 15; gameCtx.stroke(); gameCtx.shadowBlur = 0; // Draw user path if(path.length > 1) { gameCtx.beginPath(); gameCtx.moveTo(path[0].x, path[0].y); for (let i = 1; i < path.length; i++) { gameCtx.lineTo(path[i].x, path[i].y); } gameCtx.strokeStyle = '#c4b5fd'; gameCtx.lineWidth = 4; gameCtx.stroke(); } } function calculateScore() { let totalDistance = 0; let pointCount = 0; path.forEach(point => { const targetPoint = targetWave[Math.floor(point.x)]; if(targetPoint){ const distance = Math.abs(point.y - targetPoint.y); totalDistance += distance; pointCount++; } }); const avgDistance = totalDistance / pointCount; const maxDistance = gameCanvas.height / 4; const score = Math.max(0, 100 - (avgDistance / maxDistance) * 100); return score; } function endGame() { isDrawing = false; cancelAnimationFrame(animationFrameId); const score = calculateScore(); gameOverlay.style.display = 'flex'; if(score > 80) { gameStatus.innerHTML = `Resonance Peak! <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`; showNotification("Strand Woven", `Your weave was near perfect. +10 LATTICE points.`); } else if (score > 50) { gameStatus.innerHTML = `Strand Woven. <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`; showNotification("Strand Stabilized", `Your weave holds. +5 LATTICE points.`); } else { gameStatus.innerHTML = `Strand Frayed... <br/> <span class="text-xl text-gray-300">Score: ${score.toFixed(0)}</span>`; showNotification("Void Echoes", `The strand frayed but revealed a mystery echo.`); } startGameBtn.textContent = 'Weave Again'; } function getEventPosition(event) { const rect = gameCanvas.getBoundingClientRect(); if (event.touches) { return { x: event.touches[0].clientX - rect.left, y: event.touches[0].clientY - rect.top }; } return { x: event.clientX - rect.left, y: event.clientY - rect.top }; } gameCanvas.addEventListener('mousedown', (e) => { if(!animationFrameId) return; isDrawing = true; path = [getEventPosition(e)]; }); gameCanvas.addEventListener('touchstart', (e) => { if(!animationFrameId) return; e.preventDefault(); isDrawing = true; path = [getEventPosition(e)]; }); gameCanvas.addEventListener('mousemove', (e) => { if (isDrawing) { path.push(getEventPosition(e)); draw(); } }); gameCanvas.addEventListener('touchmove', (e) => { if (isDrawing) { e.preventDefault(); path.push(getEventPosition(e)); draw(); } }); window.addEventListener('mouseup', () => { if(isDrawing) endGame(); }); gameCanvas.addEventListener('touchend', () => { if(isDrawing) endGame(); }); function gameLoop() { draw(); animationFrameId = requestAnimationFrame(gameLoop); } startGameBtn.addEventListener('click', () => { if (!userAccount) { showNotification('Wallet Not Connected', 'Please connect your wallet to start weaving.'); return; } resizeCanvas(); path = []; generateTargetWave(); gameOverlay.style.display = 'none'; animationFrameId = requestAnimationFrame(gameLoop); }); // --- Initial Load --- document.addEventListener('DOMContentLoaded', () => { initBackground(); setupWalletListeners(); // Set up MetaMask event listeners and check connection resizeCanvas(); // Initial size for game canvas generateTargetWave(); draw(); // Draw the initial target wave }); </script> </body> </html>
yindo closed this issue 2026-02-16 17:33:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1874