Lets-Vibe-CodeOnChain / index.html
arpit13's picture
Update index.html
57d24a3 verified
raw
history blame
23.5 kB
<!DOCTYPE html>
<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>