Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Vibecode | Onchain Replit with Vibes</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=VT323&family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --bg-dark: #0a0e14; | |
| --neon-green: #00ff99; | |
| --neon-cyan: #66fff9; | |
| --neon-purple: #ab7cf9; | |
| } | |
| body { | |
| background-color: var(--bg-dark); | |
| color: white; | |
| font-family: 'IBM Plex Mono', monospace; | |
| overflow-x: hidden; | |
| } | |
| .pixel-font { | |
| font-family: 'Press Start 2P', cursive; | |
| } | |
| .terminal-font { | |
| font-family: 'VT323', monospace; | |
| } | |
| .neon-green { | |
| color: var(--neon-green); | |
| text-shadow: 0 0 5px var(--neon-green); | |
| } | |
| .neon-cyan { | |
| color: var(--neon-cyan); | |
| text-shadow: 0 0 5px var(--neon-cyan); | |
| } | |
| .neon-purple { | |
| color: var(--neon-purple); | |
| text-shadow: 0 0 5px var(--neon-purple); | |
| } | |
| .neon-glow { | |
| box-shadow: 0 0 10px var(--neon-green), 0 0 20px var(--neon-purple); | |
| } | |
| .scanlines { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .scanlines:before { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: linear-gradient( | |
| to bottom, | |
| transparent 0%, | |
| rgba(255, 255, 255, 0.05) 50%, | |
| transparent 100% | |
| ); | |
| background-size: 100% 4px; | |
| pointer-events: none; | |
| z-index: 10; | |
| } | |
| .glitch { | |
| position: relative; | |
| } | |
| .glitch::before, .glitch::after { | |
| content: attr(data-text); | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: var(--bg-dark); | |
| } | |
| .glitch::before { | |
| left: 2px; | |
| text-shadow: -2px 0 var(--neon-purple); | |
| clip: rect(44px, 450px, 56px, 0); | |
| animation: glitch-anim 5s infinite linear alternate-reverse; | |
| } | |
| .glitch::after { | |
| left: -2px; | |
| text-shadow: -2px 0 var(--neon-cyan); | |
| clip: rect(44px, 450px, 56px, 0); | |
| animation: glitch-anim2 5s infinite linear alternate-reverse; | |
| } | |
| @keyframes glitch-anim { | |
| 0% { clip: rect(31px, 9999px, 94px, 0); } | |
| 10% { clip: rect(112px, 9999px, 76px, 0); } | |
| 20% { clip: rect(85px, 9999px, 77px, 0); } | |
| 30% { clip: rect(27px, 9999px, 97px, 0); } | |
| 40% { clip: rect(64px, 9999px, 98px, 0); } | |
| 50% { clip: rect(61px, 9999px, 85px, 0); } | |
| 60% { clip: rect(99px, 9999px, 114px, 0); } | |
| 70% { clip: rect(34px, 9999px, 115px, 0); } | |
| 80% { clip: rect(98px, 9999px, 129px, 0); } | |
| 90% { clip: rect(43px, 9999px, 96px, 0); } | |
| 100% { clip: rect(82px, 9999px, 64px, 0); } | |
| } | |
| @keyframes glitch-anim2 { | |
| 0% { clip: rect(65px, 9999px, 119px, 0); } | |
| 10% { clip: rect(144px, 9999px, 41px, 0); } | |
| 20% { clip: rect(6px, 9999px, 187px, 0); } | |
| 30% { clip: rect(133px, 9999px, 50px, 0); } | |
| 40% { clip: rect(115px, 9999px, 23px, 0); } | |
| 50% { clip: rect(187px, 9999px, 169px, 0); } | |
| 60% { clip: rect(40px, 9999px, 128px, 0); } | |
| 70% { clip: rect(45px, 9999px, 7px, 0); } | |
| 80% { clip: rect(24px, 9999px, 162px, 0); } | |
| 90% { clip: rect(138px, 9999px, 180px, 0); } | |
| 100% { clip: rect(6px, 9999px, 103px, 0); } | |
| } | |
| .typing { | |
| border-right: 2px solid var(--neon-green); | |
| animation: blink 0.75s step-end infinite; | |
| } | |
| @keyframes blink { | |
| from, to { border-color: transparent; } | |
| 50% { border-color: var(--neon-green); } | |
| } | |
| .pixel-corners { | |
| position: relative; | |
| } | |
| .pixel-corners::before, .pixel-corners::after { | |
| content: ''; | |
| position: absolute; | |
| width: 10px; | |
| height: 10px; | |
| border: 2px solid var(--neon-green); | |
| } | |
| .pixel-corners::before { | |
| top: -5px; | |
| left: -5px; | |
| border-right: none; | |
| border-bottom: none; | |
| } | |
| .pixel-corners::after { | |
| bottom: -5px; | |
| right: -5px; | |
| border-left: none; | |
| border-top: none; | |
| } | |
| .loading-dots:after { | |
| content: '...'; | |
| animation: dots 1.5s steps(5, end) infinite; | |
| display: inline-block; | |
| width: 0; | |
| overflow: hidden; | |
| vertical-align: bottom; | |
| } | |
| @keyframes dots { | |
| 0%, 20% { width: 0; } | |
| 40% { width: 0.2em; } | |
| 60% { width: 0.4em; } | |
| 80% { width: 0.6em; } | |
| 100% { width: 0; } | |
| } | |
| /* Code syntax highlighting */ | |
| .code-snippet { | |
| background-color: rgba(0,0,0,0.4); | |
| padding: 12px; | |
| border-radius: 4px; | |
| border-left: 3px solid var(--neon-green); | |
| font-family: 'IBM Plex Mono', monospace; | |
| font-size: 0.9em; | |
| overflow-x: auto; | |
| margin: 10px 0; | |
| } | |
| .code-keyword { color: #ff79c6; } | |
| .code-string { color: #f1fa8c; } | |
| .code-comment { color: #6272a4; } | |
| .code-function { color: #50fa7b; } | |
| .code-variable { color: #8be9fd; } | |
| .code-number { color: #bd93f9; } | |
| </style> | |
| </head> | |
| <body class="scanlines min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="flex flex-col items-center mb-12"> | |
| <h1 class="glitch text-5xl md:text-6xl mb-4 pixel-font neon-green" data-text="VIBECODE">VIBECODE</h1> | |
| <p class="terminal-font text-xl neon-cyan mb-6">Onchain Replit with Vibes</p> | |
| <div class="flex space-x-4"> | |
| <button class="terminal-font px-6 py-2 bg-transparent border-2 border-neon-green neon-green hover:bg-green-900/20 transition-all"> | |
| DOCS | |
| </button> | |
| <button class="terminal-font px-6 py-2 bg-neon-green text-black hover:bg-green-300 transition-all"> | |
| LAUNCH APP | |
| </button> | |
| </div> | |
| </header> | |
| <!-- Main Terminal --> | |
| <div class="max-w-4xl mx-auto bg-black/70 border-2 border-neon-green rounded-lg overflow-hidden neon-glow"> | |
| <!-- Terminal Header --> | |
| <div class="bg-gray-900 px-4 py-2 flex items-center"> | |
| <div class="flex space-x-2 mr-4"> | |
| <div class="w-3 h-3 rounded-full bg-red-500"></div> | |
| <div class="w-3 h-3 rounded-full bg-yellow-500"></div> | |
| <div class="w-3 h-3 rounded-full bg-green-500"></div> | |
| </div> | |
| <div class="terminal-font text-sm neon-green flex-1 text-center"> | |
| vibecode-terminal ~/launch-onchain-app | |
| </div> | |
| </div> | |
| <!-- Terminal Content --> | |
| <div class="p-4 h-96 overflow-y-auto terminal-font text-green-200" id="terminal-content"> | |
| <div class="mb-4"> | |
| <span class="neon-purple">user@vibecode:~$</span> <span class="neon-green">welcome to Vibecode</span> | |
| </div> | |
| <div class="mb-4"> | |
| <span class="neon-purple">user@vibecode:~$</span> <span class="neon-green">type your onchain creation prompt below</span> | |
| </div> | |
| <div class="mb-4"> | |
| <span class="neon-purple">user@vibecode:~$</span> <span class="neon-cyan">examples:</span> | |
| </div> | |
| <div class="mb-2 ml-8 text-gray-400"> | |
| > "Launch $VIBE token with 1% burn and 10% LP on Base" | |
| </div> | |
| <div class="mb-2 ml-8 text-gray-400"> | |
| > "Deploy an NFT mint for 777 images, free mint, 10% royalty" | |
| </div> | |
| <div class="mb-2 ml-8 text-gray-400"> | |
| > "Create a DAO with 30 day vesting and 5% treasury fee" | |
| </div> | |
| <div class="mb-6"> | |
| <span class="neon-purple">user@vibecode:~$</span> <span class="typing"></span> | |
| </div> | |
| <!-- Chat messages will appear here --> | |
| <div id="chat-messages" class="space-y-4"></div> | |
| </div> | |
| <!-- Input Area --> | |
| <div class="border-t border-neon-green/50 p-4 bg-gray-900/50"> | |
| <div class="flex"> | |
| <span class="terminal-font text-lg neon-purple mr-2">></span> | |
| <input | |
| type="text" | |
| id="user-input" | |
| class="terminal-font flex-1 bg-transparent border-none outline-none text-green-200 caret-green-500" | |
| placeholder="Type your onchain creation prompt..." | |
| autofocus | |
| > | |
| <button id="send-btn" class="terminal-font px-4 py-1 bg-neon-green text-black hover:bg-green-300 transition-all"> | |
| SEND | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Features Grid --> | |
| <div class="mt-16 grid grid-cols-1 md:grid-cols-3 gap-8"> | |
| <!-- Feature 1 --> | |
| <div class="bg-gray-900/50 border border-neon-green/30 rounded-lg p-6 relative pixel-corners hover:neon-glow transition-all"> | |
| <div class="text-4xl neon-green mb-4">1</div> | |
| <h3 class="terminal-font text-xl neon-cyan mb-3">Chat Interface</h3> | |
| <p class="text-gray-300"> | |
| Natural language prompts to create tokens, NFTs, DAOs, and more. No coding required. | |
| </p> | |
| </div> | |
| <!-- Feature 2 --> | |
| <div class="bg-gray-900/50 border border-neon-green/30 rounded-lg p-6 relative pixel-corners hover:neon-glow transition-all"> | |
| <div class="text-4xl neon-green mb-4">2</div> | |
| <h3 class="terminal-font text-xl neon-cyan mb-3">Auto Contracts</h3> | |
| <p class="text-gray-300"> | |
| ERC20, ERC721, vesting, and LP contracts generated from your prompts. | |
| </p> | |
| </div> | |
| <!-- Feature 3 --> | |
| <div class="bg-gray-900/50 border border-neon-green/30 rounded-lg p-6 relative pixel-corners hover:neon-glow transition-all"> | |
| <div class="text-4xl neon-green mb-4">3</div> | |
| <h3 class="terminal-font text-xl neon-cyan mb-3">Deploy Anywhere</h3> | |
| <p class="text-gray-300"> | |
| Testnet for free, mainnet when ready. Base, Polygon, Zora, and Solana supported. | |
| </p> | |
| </div> | |
| </div> | |
| <!-- CTA Section --> | |
| <div class="mt-20 text-center"> | |
| <h2 class="terminal-font text-3xl neon-green mb-6">Ready to launch your onchain app?</h2> | |
| <button class="terminal-font px-8 py-3 bg-neon-green text-black text-lg hover:bg-green-300 transition-all"> | |
| START BUILDING NOW | |
| </button> | |
| </div> | |
| <!-- Footer --> | |
| <footer class="mt-20 pt-8 border-t border-neon-green/20 text-center text-gray-400 terminal-font"> | |
| <div class="mb-4"> | |
| <a href="#" class="mx-2 hover:text-neon-green transition-all">Twitter</a> | |
| <a href="#" class="mx-2 hover:text-neon-green transition-all">Discord</a> | |
| <a href="#" class="mx-2 hover:text-neon-green transition-all">GitHub</a> | |
| </div> | |
| <p>Vibecode © 2025 | Onchain Replit with Vibes</p> | |
| </footer> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const userInput = document.getElementById('user-input'); | |
| const sendBtn = document.getElementById('send-btn'); | |
| const chatMessages = document.getElementById('chat-messages'); | |
| const terminalContent = document.getElementById('terminal-content'); | |
| // Gemini API Key | |
| const GEMINI_API_KEY = "AIzaSyAX_-SVl0NpZ8Iv8mlkJ3olLbgxs_fTyGw"; | |
| const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"; | |
| // Typing animation for the terminal prompt | |
| const typingElement = document.querySelector('.typing'); | |
| const messages = [ | |
| "Launch $VIBE token with 1% burn...", | |
| "Create NFT collection...", | |
| "Deploy DAO with vesting...", | |
| "Build onchain app..." | |
| ]; | |
| let messageIndex = 0; | |
| let charIndex = 0; | |
| let isDeleting = false; | |
| function type() { | |
| const currentMessage = messages[messageIndex]; | |
| if (isDeleting) { | |
| typingElement.textContent = currentMessage.substring(0, charIndex - 1); | |
| charIndex--; | |
| } else { | |
| typingElement.textContent = currentMessage.substring(0, charIndex + 1); | |
| charIndex++; | |
| } | |
| if (!isDeleting && charIndex === currentMessage.length) { | |
| isDeleting = true; | |
| setTimeout(type, 2000); | |
| } else if (isDeleting && charIndex === 0) { | |
| isDeleting = false; | |
| messageIndex = (messageIndex + 1) % messages.length; | |
| setTimeout(type, 500); | |
| } else { | |
| const speed = isDeleting ? 50 : 100; | |
| setTimeout(type, speed); | |
| } | |
| } | |
| setTimeout(type, 1000); | |
| // Handle user input | |
| function sendMessage() { | |
| const message = userInput.value.trim(); | |
| if (message) { | |
| // Add user message | |
| addMessage(message, 'user'); | |
| // Add loading indicator | |
| const loadingId = addLoadingIndicator(); | |
| // Call Gemini API | |
| callGeminiAPI(message) | |
| .then(response => { | |
| // Remove loading indicator | |
| removeLoadingIndicator(loadingId); | |
| // Add AI response | |
| addMessage(formatResponse(response, message), 'ai'); | |
| // Scroll to bottom | |
| terminalContent.scrollTop = terminalContent.scrollHeight; | |
| }) | |
| .catch(error => { | |
| // Remove loading indicator | |
| removeLoadingIndicator(loadingId); | |
| // Add error message | |
| addMessage("Error processing your request. Please try again.", 'ai'); | |
| console.error("Gemini API Error:", error); | |
| }); | |
| // Clear input | |
| userInput.value = ''; | |
| } | |
| } | |
| function addMessage(text, sender) { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.className = `flex ${sender === 'user' ? 'justify-end' : 'justify-start'}`; | |
| const bubble = document.createElement('div'); | |
| bubble.className = `terminal-font max-w-3/4 rounded px-4 py-2 ${ | |
| sender === 'user' | |
| ? 'bg-neon-green/10 border border-neon-green/30 text-neon-green' | |
| : 'bg-gray-800/50 border border-neon-purple/30 text-gray-300' | |
| }`; | |
| // Format the response with code highlighting if it contains code | |
| if (sender === 'ai' && text.includes('```')) { | |
| const formattedText = formatCodeBlocks(text); | |
| bubble.innerHTML = formattedText; | |
| } else { | |
| bubble.textContent = text; | |
| } | |
| messageDiv.appendChild(bubble); | |
| chatMessages.appendChild(messageDiv); | |
| // Scroll to bottom | |
| terminalContent.scrollTop = terminalContent.scrollHeight; | |
| } | |
| function addLoadingIndicator() { | |
| const loadingId = 'loading-' + Date.now(); | |
| const loadingDiv = document.createElement('div'); | |
| loadingDiv.id = loadingId; | |
| loadingDiv.className = 'flex justify-start'; | |
| const loadingBubble = document.createElement('div'); | |
| loadingBubble.className = 'terminal-font rounded px-4 py-2 bg-gray-800/50 border border-neon-purple/30 text-gray-300'; | |
| const loadingText = document.createElement('span'); | |
| loadingText.className = 'loading-dots'; | |
| loadingText.textContent = 'Generating smart contract'; | |
| loadingBubble.appendChild(loadingText); | |
| loadingDiv.appendChild(loadingBubble); | |
| chatMessages.appendChild(loadingDiv); | |
| // Scroll to bottom | |
| terminalContent.scrollTop = terminalContent.scrollHeight; | |
| return loadingId; | |
| } | |
| function removeLoadingIndicator(loadingId) { | |
| const loadingElement = document.getElementById(loadingId); | |
| if (loadingElement) { | |
| loadingElement.remove(); | |
| } | |
| } | |
| async function callGeminiAPI(message) { | |
| // Construct prompt for blockchain context | |
| const blockchainPrompt = `You are Vibecode AI, an expert in blockchain development and smart contract creation. | |
| The user will give you a request related to creating tokens, NFTs, DAOs, or other blockchain applications. | |
| Please respond with: | |
| 1. An explanation of what you'll create based on their request | |
| 2. The appropriate smart contract code (Solidity) to implement their request | |
| 3. Clear deployment instructions | |
| Current user request: "${message}"`; | |
| try { | |
| const response = await fetch(`${GEMINI_API_URL}?key=${GEMINI_API_KEY}`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| contents: [{ | |
| parts: [{ | |
| text: blockchainPrompt | |
| }] | |
| }] | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| // Extract the text from the response | |
| if (data.candidates && | |
| data.candidates[0] && | |
| data.candidates[0].content && | |
| data.candidates[0].content.parts && | |
| data.candidates[0].content.parts[0]) { | |
| return data.candidates[0].content.parts[0].text; | |
| } else { | |
| throw new Error("Unexpected response format from Gemini API"); | |
| } | |
| } catch (error) { | |
| console.error("Error calling Gemini API:", error); | |
| throw error; | |
| } | |
| } | |
| function formatResponse(response, userRequest) { | |
| // You can customize the formatting of the AI response here | |
| return response; | |
| } | |
| function formatCodeBlocks(text) { | |
| // Split the text by code blocks | |
| const parts = text.split('```'); | |
| let result = ''; | |
| for (let i = 0; i < parts.length; i++) { | |
| if (i % 2 === 0) { | |
| // Regular text | |
| result += parts[i]; | |
| } else { | |
| // Code block | |
| const codeLines = parts[i].split('\n'); | |
| const language = codeLines[0] || ''; | |
| const code = codeLines.slice(1).join('\n'); | |
| // Basic syntax highlighting for Solidity | |
| let highlightedCode = code | |
| .replace(/\b(contract|function|address|uint|string|bytes|mapping|struct|enum|bool|public|private|internal|external|view|pure|returns|memory|storage|calldata)\b/g, '<span class="code-keyword">$1</span>') | |
| .replace(/(\/\/.*)/g, '<span class="code-comment">$1</span>') | |
| .replace(/"([^"]*)"/g, '<span class="code-string">"$1"</span>') | |
| .replace(/\b(\d+)\b/g, '<span class="code-number">$1</span>') | |
| .replace(/\b(constructor|require|assert|emit)\b/g, '<span class="code-function">$1</span>') | |
| .replace(/\b(msg|block|tx|address)\b/g, '<span class="code-variable">$1</span>'); | |
| result += `<div class="code-snippet">${highlightedCode}</div>`; | |
| } | |
| } | |
| return result; | |
| } | |
| // Event listeners | |
| sendBtn.addEventListener('click', sendMessage); | |
| userInput.addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| sendMessage(); | |
| } | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |