undefined / index.html
srab1980's picture
Got it—here’s a tight, production-oriented “master prompt + plan” for your icon-generation subsystem, built around **Gemini (to write the per-word prompts)** and **ComfyUI (to render the images)**. I’ve split it into discrete tasks so each can be delivered independently.
b004c97 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IconForge Studio</title>
<link rel="icon" type="image/x-icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎨</text></svg>">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card-hover {
transition: all 0.3s ease;
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.animate-pulse-slow {
animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: .5; }
}
</style>
</head>
<body class="min-h-screen text-gray-900">
<!-- Hero Section with Vanta.js Background -->
<div id="vanta-bg" class="relative h-screen flex items-center justify-center overflow-hidden">
<div class="absolute inset-0 bg-black opacity-70 z-0"></div>
<div class="relative z-10 text-center px-4 max-w-4xl">
<h1 class="text-5xl md:text-7xl font-bold text-white mb-6 animate-fade-in">
<span class="block">IconForge</span>
<span class="block text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-pink-600">Studio</span>
</h1>
<p class="text-xl md:text-2xl text-gray-200 mb-10 max-w-2xl mx-auto">
AI-powered icon generation for language learning applications. Create stunning, culturally-aware icons with precision.
</p>
<div class="flex flex-col sm:flex-row justify-center gap-4">
<button onclick="scrollToGenerator()" class="px-8 py-4 bg-gradient-to-r from-purple-600 to-indigo-600 text-white font-semibold rounded-full shadow-lg hover:from-purple-700 hover:to-indigo-700 transform hover:scale-105 transition-all duration-300">
Generate Icons
</button>
<button onclick="scrollToFeatures()" class="px-8 py-4 bg-white bg-opacity-20 backdrop-blur-lg text-white font-semibold rounded-full shadow-lg hover:bg-opacity-30 transition-all duration-300">
Learn More
</button>
</div>
</div>
</div>
<!-- Features Section -->
<section id="features" class="py-20 bg-white">
<div class="container mx-auto px-4">
<h2 class="text-4xl font-bold text-center mb-16 text-gray-800">Powerful Icon Generation</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-10">
<!-- Feature 1 -->
<div class="bg-gradient-to-br from-gray-50 to-gray-100 p-8 rounded-2xl shadow-lg card-hover">
<div class="w-16 h-16 rounded-full bg-purple-100 flex items-center justify-center mb-6">
<i data-feather="cpu" class="text-purple-600 w-8 h-8"></i>
</div>
<h3 class="text-2xl font-bold mb-3 text-gray-800">AI-Powered Design</h3>
<p class="text-gray-600">
Leverage advanced AI models to generate high-quality, contextually appropriate icons for language learning.
</p>
</div>
<!-- Feature 2 -->
<div class="bg-gradient-to-br from-gray-50 to-gray-100 p-8 rounded-2xl shadow-lg card-hover">
<div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mb-6">
<i data-feather="globe" class="text-indigo-600 w-8 h-8"></i>
</div>
<h3 class="text-2xl font-bold mb-3 text-gray-800">Multilingual Support</h3>
<p class="text-gray-600">
Generate icons for words in multiple languages with cultural sensitivity and semantic accuracy.
</p>
</div>
<!-- Feature 3 -->
<div class="bg-gradient-to-br from-gray-50 to-gray-100 p-8 rounded-2xl shadow-lg card-hover">
<div class="w-16 h-16 rounded-full bg-pink-100 flex items-center justify-center mb-6">
<i data-feather="sliders" class="text-pink-600 w-8 h-8"></i>
</div>
<h3 class="text-2xl font-bold mb-3 text-gray-800">Customizable Styles</h3>
<p class="text-gray-600">
Fine-tune icon appearance with style tags, difficulty levels, and visual parameters.
</p>
</div>
</div>
</div>
</section>
<!-- Generator Section -->
<section id="generator" class="py-20 bg-gradient-to-br from-gray-50 to-gray-100">
<div class="container mx-auto px-4">
<h2 class="text-4xl font-bold text-center mb-4 text-gray-800">Icon Generator</h2>
<p class="text-xl text-center text-gray-600 mb-12 max-w-2xl mx-auto">
Create custom icons by specifying word details and style preferences
</p>
<div class="max-w-4xl mx-auto bg-white rounded-2xl shadow-xl overflow-hidden">
<div class="md:flex">
<div class="md:w-1/2 p-8">
<form id="iconForm" class="space-y-6">
<div>
<label class="block text-gray-700 font-medium mb-2">Turkish Word</label>
<input type="text" id="word_tr" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="Enter Turkish word" required>
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Arabic Translation</label>
<input type="text" id="word_ar" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="Enter Arabic translation" required>
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Category</label>
<select id="category" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent">
<option value="Clothing">Clothing</option>
<option value="Food">Food</option>
<option value="Transportation">Transportation</option>
<option value="Nature">Nature</option>
<option value="Technology">Technology</option>
</select>
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">CEFR Level</label>
<select id="cefr_level" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent">
<option value="A1">A1 - Beginner</option>
<option value="A2">A2 - Elementary</option>
<option value="B1">B1 - Intermediate</option>
<option value="B2">B2 - Upper Intermediate</option>
<option value="C1">C1 - Advanced</option>
<option value="C2">C2 - Proficiency</option>
</select>
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Difficulty (1-5)</label>
<input type="range" id="difficulty" min="1" max="5" value="3" class="w-full">
<div class="flex justify-between text-sm text-gray-600 mt-1">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Style Tags (comma separated)</label>
<input type="text" id="style_tags" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="e.g., friendly, kids, polished">
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Turkish Example Sentence</label>
<input type="text" id="usage_tr" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="e.g., Ceketimi dolaba astım.">
</div>
<div>
<label class="block text-gray-700 font-medium mb-2">Arabic Example Sentence</label>
<input type="text" id="usage_ar" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="e.g., علّقتُ معطفي في الخزانة.">
</div>
<button type="submit" class="w-full py-4 bg-gradient-to-r from-purple-600 to-indigo-600 text-white font-semibold rounded-lg shadow-md hover:from-purple-700 hover:to-indigo-700 transform hover:scale-[1.02] transition-all duration-300">
Generate Icon
</button>
</form>
</div>
<div class="md:w-1/2 bg-gradient-to-br from-purple-500 to-indigo-600 p-8 flex flex-col items-center justify-center">
<div class="text-center mb-8">
<h3 class="text-2xl font-bold text-white mb-2">Preview</h3>
<p class="text-purple-100">Your generated icon will appear here</p>
</div>
<div class="bg-white bg-opacity-20 backdrop-blur-lg rounded-2xl p-6 w-64 h-64 flex items-center justify-center">
<div id="icon-preview" class="w-48 h-48 bg-gray-200 rounded-xl flex items-center justify-center">
<i data-feather="image" class="text-gray-400 w-12 h-12"></i>
</div>
</div>
<div class="mt-8 text-center">
<p class="text-purple-100 text-sm">1024×1024px | PNG Format</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- How It Works -->
<section class="py-20 bg-white">
<div class="container mx-auto px-4">
<h2 class="text-4xl font-bold text-center mb-16 text-gray-800">How It Works</h2>
<div class="flex flex-col md:flex-row items-center justify-between gap-12">
<div class="md:w-1/2">
<div class="relative">
<div class="absolute -left-8 top-0 w-16 h-16 rounded-full bg-purple-100 flex items-center justify-center">
<span class="text-purple-600 font-bold text-xl">1</span>
</div>
<div class="pl-12">
<h3 class="text-2xl font-bold text-gray-800 mb-3">Input Word Details</h3>
<p class="text-gray-600">
Enter the word in Turkish and Arabic, select category, CEFR level, difficulty, and style preferences.
</p>
</div>
</div>
<div class="relative mt-12">
<div class="absolute -left-8 top-0 w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center">
<span class="text-indigo-600 font-bold text-xl">2</span>
</div>
<div class="pl-12">
<h3 class="text-2xl font-bold text-gray-800 mb-3">AI Prompt Generation</h3>
<p class="text-gray-600">
Our system creates a precise prompt for the AI image generator based on your inputs and linguistic requirements.
</p>
</div>
</div>
<div class="relative mt-12">
<div class="absolute -left-8 top-0 w-16 h-16 rounded-full bg-pink-100 flex items-center justify-center">
<span class="text-pink-600 font-bold text-xl">3</span>
</div>
<div class="pl-12">
<h3 class="text-2xl font-bold text-gray-800 mb-3">Icon Rendering</h3>
<p class="text-gray-600">
The AI generates a high-quality, skeuomorphic 3D icon that meets all specified criteria.
</p>
</div>
</div>
</div>
<div class="md:w-2/5">
<div class="bg-gradient-to-br from-gray-50 to-gray-100 rounded-2xl p-8 shadow-lg">
<div class="flex justify-center mb-6">
<div class="w-32 h-32 rounded-full bg-gradient-to-br from-purple-400 to-indigo-500 flex items-center justify-center">
<i data-feather="zap" class="text-white w-16 h-16"></i>
</div>
</div>
<h3 class="text-2xl font-bold text-center text-gray-800 mb-4">AI Pipeline</h3>
<p class="text-gray-600 text-center">
Powered by Gemini for prompt engineering and ComfyUI for image generation
</p>
</div>
</div>
</div>
</div>
</section>
<!-- API Status Section -->
<section class="py-20 bg-gradient-to-br from-gray-50 to-white">
<div class="container mx-auto px-4">
<h2 class="text-4xl font-bold text-center mb-16 text-gray-800">System Status</h2>
<div class="max-w-4xl mx-auto grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Gemini API</h3>
<div id="gemini-status" class="w-3 h-3 rounded-full bg-yellow-400 animate-pulse"></div>
</div>
<p class="text-sm text-gray-600">Prompt Engineering</p>
</div>
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">ComfyUI</h3>
<div id="comfyui-status" class="w-3 h-3 rounded-full bg-yellow-400 animate-pulse"></div>
</div>
<p class="text-sm text-gray-600">Image Generation</p>
</div>
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Job Queue</h3>
<div id="queue-status" class="w-3 h-3 rounded-full bg-green-400"></div>
</div>
<p class="text-sm text-gray-600">Processing: <span id="queue-count">0</span> jobs</p>
</div>
</div>
<div class="mt-8 text-center">
<button onclick="checkSystemHealth()" class="px-6 py-3 bg-purple-600 text-white font-medium rounded-lg hover:bg-purple-700 transition-colors">
Check Health
</button>
</div>
</div>
</section>
<!-- Footer -->
<footer class="bg-gray-900 text-white py-12">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-6 md:mb-0">
<h2 class="text-2xl font-bold flex items-center">
<span class="mr-2">🎨</span> IconForge Studio
</h2>
<p class="text-gray-400 mt-2">AI-powered icon generation for language learning</p>
<div class="flex items-center mt-2 text-sm text-gray-500">
<i data-feather="cpu" class="w-4 h-4 mr-1"></i>
<span>Powered by Gemini + ComfyUI</span>
</div>
</div>
<div class="flex space-x-6">
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="github" class="w-6 h-6"></i>
</a>
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="twitter" class="w-6 h-6"></i>
</a>
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="linkedin" class="w-6 h-6"></i>
</a>
</div>
</div>
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
<p>&copy; 2023 IconForge Studio. All rights reserved.</p>
<p class="text-xs mt-2">v1.0.0 | Production Ready</p>
</div>
</div>
</footer>
<script>
// Initialize Vanta.js
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x6a11cb,
color2: 0x2575fc,
backgroundColor: 0x0
});
// Initialize Feather Icons
feather.replace();
// Check system health on load
window.addEventListener('load', checkSystemHealth);
// System health check
function checkSystemHealth() {
// Check Gemini API
fetch('/api/health/gemini')
.then(r => r.json())
.then(data => {
const status = document.getElementById('gemini-status');
status.className = `w-3 h-3 rounded-full ${data.status === 'healthy' ? 'bg-green-400' : 'bg-red-400'}`;
})
.catch(() => {
document.getElementById('gemini-status').className = 'w-3 h-3 rounded-full bg-red-400';
});
// Check ComfyUI
fetch('/api/health/comfyui')
.then(r => r.json())
.then(data => {
const status = document.getElementById('comfyui-status');
status.className = `w-3 h-3 rounded-full ${data.status === 'healthy' ? 'bg-green-400' : 'bg-red-400'}`;
})
.catch(() => {
document.getElementById('comfyui-status').className = 'w-3 h-3 rounded-full bg-red-400';
});
// Check queue status
fetch('/api/queue/status')
.then(r => r.json())
.then(data => {
document.getElementById('queue-count').textContent = data.pending || 0;
const status = document.getElementById('queue-status');
status.className = `w-3 h-3 rounded-full ${data.pending > 0 ? 'bg-yellow-400 animate-pulse' : 'bg-green-400'}`;
})
.catch(() => {
document.getElementById('queue-status').className = 'w-3 h-3 rounded-full bg-red-400';
});
}
// Form submission handler
document.getElementById('iconForm').addEventListener('submit', function(e) {
e.preventDefault();
// Get form values
const word_tr = document.getElementById('word_tr').value;
const word_ar = document.getElementById('word_ar').value;
const category = document.getElementById('category').value;
const cefr_level = document.getElementById('cefr_level').value;
const difficulty = document.getElementById('difficulty').value;
const style_tags = document.getElementById('style_tags').value.split(',').map(tag => tag.trim()).filter(tag => tag);
const usage_tr = document.getElementById('usage_tr').value;
const usage_ar = document.getElementById('usage_ar').value;
// Build request body
const body = {
word_tr,
word_ar,
category,
cefr_level,
difficulty: parseInt(difficulty),
usage_tr,
usage_ar,
style_tags
};
const preview = document.getElementById('icon-preview');
preview.innerHTML = '<div class="animate-pulse-slow text-gray-500">Generating...</div>';
// Call backend
fetch('/api/generate-icon', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then(r => r.json())
.then(data => {
if (data.url) {
preview.innerHTML = `<img src="${data.url}" class="w-full h-full object-contain rounded-xl" alt="Generated icon">`;
} else if (data.job_id) {
// Job queued - show loading state
preview.innerHTML = `
<div class="text-center">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-600 mx-auto mb-4"></div>
<p class="text-gray-600 text-sm">Job queued: ${data.job_id}</p>
<p class="text-gray-500 text-xs mt-2">Generating icon...</p>
</div>
`;
// Poll for completion
pollJobStatus(data.job_id);
} else {
throw new Error(data.error || 'Unknown error');
}
})
.catch(err => {
preview.innerHTML = `<div class="text-red-500 text-sm text-center">${err.message}</div>`;
});
// Poll job status
function pollJobStatus(jobId) {
const pollInterval = setInterval(() => {
fetch(`/api/job-status/${jobId}`)
.then(r => r.json())
.then(data => {
if (data.status === 'completed' && data.url) {
clearInterval(pollInterval);
preview.innerHTML = `<img src="${data.url}" class="w-full h-full object-contain rounded-xl" alt="Generated icon">`;
} else if (data.status === 'failed') {
clearInterval(pollInterval);
preview.innerHTML = `<div class="text-red-500 text-sm text-center">Generation failed: ${data.error}</div>`;
}
})
.catch(err => {
clearInterval(pollInterval);
preview.innerHTML = `<div class="text-red-500 text-sm text-center">Error checking status: ${err.message}</div>`;
});
}, 2000);
// Stop polling after 2 minutes
setTimeout(() => clearInterval(pollInterval), 120000);
}
});
// Scroll functions
function scrollToGenerator() {
document.getElementById('generator').scrollIntoView({ behavior: 'smooth' });
}
function scrollToFeatures() {
document.getElementById('features').scrollIntoView({ behavior: 'smooth' });
}
// Add keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Ctrl/Cmd + Enter to submit form
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
const form = document.getElementById('iconForm');
if (form) form.dispatchEvent(new Event('submit'));
}
// Escape to clear form
if (e.key === 'Escape') {
document.getElementById('iconForm').reset();
document.getElementById('icon-preview').innerHTML = '<i data-feather="image" class="text-gray-400 w-12 h-12"></i>';
feather.replace();
}
});
// Add difficulty value display
const difficultySlider = document.getElementById('difficulty');
const difficultyValue = document.createElement('div');
difficultyValue.className = 'text-center text-sm font-medium text-purple-600 mt-2';
difficultySlider.parentNode.appendChild(difficultyValue);
difficultySlider.addEventListener('input', function() {
difficultyValue.textContent = `Difficulty: ${this.value}`;
});
difficultyValue.textContent = `Difficulty: ${difficultySlider.value}`;
</script>
</body>
</html>