jensvde's picture
rubberdaken
ea61761 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RubberDuck - Debugging Assistant</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<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.net.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
},
secondary: {
50: '#fefce8',
100: '#fef9c3',
200: '#fef08a',
300: '#fde047',
400: '#facc15',
500: '#eab308',
600: '#ca8a04',
700: '#a16207',
800: '#854d0e',
900: '#713f12',
}
}
}
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
}
.typing-cursor {
animation: blink 1s infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.duck-animation {
transition: all 0.3s ease;
}
.duck-animation:hover {
transform: rotate(-5deg) scale(1.05);
}
.message-bubble {
animation: fadeInUp 0.5s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body class="bg-gradient-to-br from-primary-50 to-secondary-50 min-h-screen">
<div id="vanta-bg" class="fixed inset-0 z-0"></div>
<!-- Header -->
<header class="relative z-10 bg-white/80 backdrop-blur-sm border-b border-primary-200">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="bg-primary-500 p-2 rounded-full duck-animation">
<i data-feather="help-circle" class="text-white w-6 h-6"></i>
</div>
<h1 class="text-2xl font-bold text-primary-800">RubberDuck 🦆</h1>
</div>
<nav class="hidden md:flex space-x-6">
<a href="#features" class="text-primary-700 hover:text-primary-500 font-medium transition-colors">Features</a>
<a href="#how-it-works" class="text-primary-700 hover:text-primary-500 font-medium transition-colors">How It Works</a>
<a href="#try-it" class="text-primary-700 hover:text-primary-500 font-medium transition-colors">Try It</a>
</nav>
<button class="bg-primary-500 text-white px-4 py-2 rounded-lg hover:bg-primary-600 transition-colors font-medium">
Get Started
</button>
</div>
</div>
</header>
<!-- Hero Section -->
<section class="relative z-10 py-20 px-4">
<div class="container mx-auto max-w-4xl text-center">
<div class="bg-white/60 backdrop-blur-sm rounded-2xl p-8 shadow-lg border border-primary-100">
<div class="flex justify-center mb-6">
<div class="bg-gradient-to-r from-primary-400 to-secondary-400 p-4 rounded-full duck-animation">
<i data-feather="message-circle" class="text-white w-12 h-12"></i>
</div>
</div>
<h1 class="text-5xl md:text-6xl font-bold text-primary-900 mb-4">
Talk to Your Rubber Duck
</h1>
<p class="text-xl text-primary-700 mb-8 max-w-2xl mx-auto">
The ultimate debugging companion that helps you solve problems by explaining them out loud.
Because sometimes, the solution is in the explanation.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<button class="bg-primary-500 text-white px-8 py-3 rounded-lg hover:bg-primary-600 transition-colors font-medium text-lg">
Start Debugging
</button>
<button class="border-2 border-primary-500 text-primary-600 px-8 py-3 rounded-lg hover:bg-primary-50 transition-colors font-medium text-lg">
Learn More
</button>
</div>
</div>
</div>
</section>
<!-- Features Section -->
<section id="features" class="relative z-10 py-16 px-4 bg-white/60 backdrop-blur-sm">
<div class="container mx-auto max-w-6xl">
<h2 class="text-4xl font-bold text-center text-primary-900 mb-12">Why RubberDuck Works</h2>
<div class="grid md:grid-cols-3 gap-8">
<div class="bg-white p-6 rounded-xl shadow-lg border border-primary-100 message-bubble">
<div class="bg-primary-100 w-12 h-12 rounded-lg flex items-center justify-center mb-4">
<i data-feather="lightbulb" class="text-primary-600 w-6 h-6"></i>
</div>
<h3 class="text-xl font-semibold text-primary-800 mb-2">Clarity Through Explanation</h3>
<p class="text-primary-600">Explaining your problem forces you to organize your thoughts and often reveals the solution.</p>
</div>
<div class="bg-white p-6 rounded-xl shadow-lg border border-primary-100 message-bubble">
<div class="bg-secondary-100 w-12 h-12 rounded-lg flex items-center justify-center mb-4">
<i data-feather="clock" class="text-secondary-600 w-6 h-6"></i>
</div>
<h3 class="text-xl font-semibold text-primary-800 mb-2">Save Time</h3>
<p class="text-primary-600">Avoid hours of frustration by catching logical errors early in the explanation process.</p>
</div>
<div class="bg-white p-6 rounded-xl shadow-lg border border-primary-100 message-bubble">
<div class="bg-primary-100 w-12 h-12 rounded-lg flex items-center justify-center mb-4">
<i data-feather="users" class="text-primary-600 w-6 h-6"></i>
</div>
<h3 class="text-xl font-semibold text-primary-800 mb-2">Always Available</h3>
<p class="text-primary-600">Your rubber duck never sleeps, never judges, and is always ready to listen.</p>
</div>
</div>
</div>
</section>
<!-- Interactive Debugging Section -->
<section id="try-it" class="relative z-10 py-16 px-4">
<div class="container mx-auto max-w-4xl">
<div class="bg-white rounded-2xl shadow-xl border border-primary-200 overflow-hidden">
<div class="bg-primary-500 text-white p-6">
<h2 class="text-2xl font-bold">Debugging Session</h2>
<p class="opacity-90">Explain your problem to the rubber duck below</p>
</div>
<div class="p-6">
<div class="flex items-start space-x-4 mb-6">
<div class="bg-secondary-100 p-3 rounded-full">
<i data-feather="user" class="text-secondary-600 w-5 h-5"></i>
</div>
<div class="bg-primary-100 rounded-lg p-4 flex-1">
<p class="text-primary-800" id="user-message">I'm having trouble with my function that should filter an array, but it's returning unexpected results...</p>
</div>
</div>
<div class="flex items-start space-x-4">
<div class="bg-primary-500 p-3 rounded-full duck-animation">
<i data-feather="help-circle" class="text-white w-5 h-5"></i>
</div>
<div class="bg-secondary-100 rounded-lg p-4 flex-1">
<p class="text-primary-800" id="duck-response">
<span id="typing-text"></span><span class="typing-cursor">|</span>
</p>
</div>
</div>
<div class="mt-6">
<textarea
class="w-full border border-primary-200 rounded-lg p-4 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
rows="4"
placeholder="Type your problem here..."></textarea>
<button class="bg-primary-500 text-white px-6 py-2 rounded-lg hover:bg-primary-600 transition-colors font-medium mt-3">
Explain to Duck
</button>
</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="relative z-10 bg-primary-900 text-white py-8 px-4">
<div class="container mx-auto text-center">
<p class="text-primary-200">Made with ❤️ for developers everywhere</p>
<p class="text-primary-300 text-sm mt-2">RubberDuck 🦆 - Your debugging companion since 2024</p>
</div>
</footer>
<script>
// Initialize Vanta.js background
VANTA.NET({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x0ea5e9,
backgroundColor: 0xfefce8,
points: 10.00,
maxDistance: 25.00
});
// Typing animation for duck response
const messages = [
"Interesting! Can you walk me through what you expect the function to do?",
"Have you checked if your filter condition is working as intended?",
"Sometimes stepping through the logic line by line helps. Want to try that?",
"I notice you mentioned unexpected results. What exactly are you seeing vs expecting?",
"Let's break this down. What's the simplest case that should work but doesn't?"
];
let currentMessage = 0;
let charIndex = 0;
const typingText = document.getElementById('typing-text');
const typingCursor = document.querySelector('.typing-cursor');
function typeWriter() {
if (charIndex < messages[currentMessage].length) {
typingText.textContent += messages[currentMessage].charAt(charIndex);
charIndex++;
setTimeout(typeWriter, 50);
} else {
setTimeout(() => {
typingText.textContent = '';
charIndex = 0;
currentMessage = (currentMessage + 1) % messages.length;
setTimeout(typeWriter, 1000);
}, 3000);
}
}
// Start typing animation after page load
document.addEventListener('DOMContentLoaded', function() {
setTimeout(typeWriter, 1000);
// Initialize feather icons
feather.replace();
// Add hover effects to interactive elements
document.querySelectorAll('button').forEach(button => {
button.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.transition = 'transform 0.2s ease';
});
button.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
});
</script>
</body>
</html>