| <!DOCTYPE html> |
| <html lang="de"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Alles Gute zum Geburtstag!</title> |
| |
| <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;600&family=Poppins:wght@300;400;700&display=swap" rel="stylesheet"> |
| |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| |
| <style> |
| :root { |
| --primary-color: #ff6b6b; |
| --secondary-color: #4ecdc4; |
| --accent-color: #ffe66d; |
| --dark-bg: #2c3e50; |
| --light-bg: #f7f9fc; |
| --text-color: #333; |
| --card-bg: rgba(255, 255, 255, 0.9); |
| --font-heading: 'Fredoka', sans-serif; |
| --font-body: 'Poppins', sans-serif; |
| } |
| |
| * { |
| margin: 0; |
| padding: 0; |
| box-sizing: border-box; |
| } |
| |
| body { |
| font-family: var(--font-body); |
| background-color: var(--light-bg); |
| color: var(--text-color); |
| overflow-x: hidden; |
| min-height: 100vh; |
| display: flex; |
| flex-direction: column; |
| } |
| |
| |
| #confetti-canvas { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| pointer-events: none; |
| z-index: 1; |
| } |
| |
| |
| header { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| padding: 1.5rem 5%; |
| background: rgba(255, 255, 255, 0.8); |
| backdrop-filter: blur(10px); |
| position: fixed; |
| width: 100%; |
| top: 0; |
| z-index: 100; |
| box-shadow: 0 2px 10px rgba(0,0,0,0.05); |
| } |
| |
| .logo { |
| font-family: var(--font-heading); |
| font-size: 1.5rem; |
| font-weight: 600; |
| color: var(--primary-color); |
| text-decoration: none; |
| display: flex; |
| align-items: center; |
| gap: 0.5rem; |
| } |
| |
| .logo span { |
| color: var(--secondary-color); |
| } |
| |
| .anycoder-link { |
| font-size: 0.8rem; |
| color: #888; |
| text-decoration: none; |
| transition: color 0.3s; |
| } |
| |
| .anycoder-link:hover { |
| color: var(--primary-color); |
| } |
| |
| |
| main { |
| flex: 1; |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| justify-content: center; |
| padding: 6rem 1rem 2rem; |
| z-index: 2; |
| text-align: center; |
| } |
| |
| |
| .hero { |
| margin-bottom: 4rem; |
| animation: fadeInDown 1s ease-out; |
| } |
| |
| .hero h1 { |
| font-family: var(--font-heading); |
| font-size: 4rem; |
| margin-bottom: 1rem; |
| background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| line-height: 1.2; |
| } |
| |
| .hero p { |
| font-size: 1.2rem; |
| color: #666; |
| max-width: 600px; |
| margin: 0 auto; |
| margin-bottom: 2rem; |
| } |
| |
| .scroll-down { |
| animation: bounce 2s infinite; |
| color: var(--primary-color); |
| font-size: 2rem; |
| cursor: pointer; |
| } |
| |
| |
| .cake-section { |
| background: var(--card-bg); |
| padding: 3rem; |
| border-radius: 20px; |
| box-shadow: 0 10px 30px rgba(0,0,0,0.1); |
| margin-bottom: 4rem; |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| max-width: 500px; |
| width: 100%; |
| transform: translateY(0); |
| transition: transform 0.3s; |
| } |
| |
| .cake-section:hover { |
| transform: translateY(-5px); |
| } |
| |
| .cake-container { |
| display: flex; |
| justify-content: center; |
| align-items: flex-end; |
| height: 200px; |
| position: relative; |
| margin-bottom: 2rem; |
| } |
| |
| |
| .plate { |
| width: 300px; |
| height: 15px; |
| background: #ddd; |
| border-radius: 10px; |
| position: absolute; |
| bottom: 0; |
| } |
| |
| .layer { |
| position: absolute; |
| bottom: 15px; |
| border-radius: 10px 10px 0 0; |
| } |
| |
| .layer-bottom { |
| width: 280px; |
| height: 80px; |
| background: var(--primary-color); |
| left: 10px; |
| } |
| |
| .layer-middle { |
| width: 240px; |
| height: 60px; |
| background: var(--secondary-color); |
| left: 30px; |
| } |
| |
| .layer-top { |
| width: 200px; |
| height: 40px; |
| background: var(--accent-color); |
| left: 50px; |
| } |
| |
| .candle { |
| position: absolute; |
| bottom: 95px; |
| width: 8px; |
| height: 40px; |
| background: repeating-linear-gradient( |
| to bottom, |
| #fff, |
| #fff 5px, |
| var(--secondary-color) 5px, |
| var(--secondary-color) 10px |
| ); |
| border-radius: 4px 4px 0 0; |
| cursor: pointer; |
| transition: transform 0.2s; |
| z-index: 5; |
| } |
| |
| .candle:hover { |
| transform: scale(1.1); |
| } |
| |
| .flame { |
| position: absolute; |
| top: -25px; |
| left: 50%; |
| transform: translateX(-50%); |
| width: 12px; |
| height: 25px; |
| background: radial-gradient(ellipse at bottom, #ffd700 0%, #ff8c00 100%); |
| border-radius: 50% 50% 20% 20%; |
| animation: flicker 1s infinite alternate; |
| box-shadow: 0 0 10px #ff8c00; |
| } |
| |
| .instruction { |
| font-size: 1rem; |
| color: #777; |
| font-weight: 500; |
| } |
| |
| .instruction i { |
| color: var(--primary-color); |
| animation: pulse 1.5s infinite; |
| } |
| |
| |
| .gift-section { |
| position: relative; |
| width: 100%; |
| max-width: 600px; |
| perspective: 1000px; |
| } |
| |
| .gift-box { |
| width: 200px; |
| height: 200px; |
| background: var(--primary-color); |
| margin: 0 auto 2rem; |
| position: relative; |
| cursor: pointer; |
| border-radius: 10px; |
| box-shadow: 0 15px 35px rgba(255, 107, 107, 0.3); |
| transition: transform 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .gift-box.opened { |
| transform: rotateY(180deg) scale(0.9); |
| opacity: 0; |
| pointer-events: none; |
| } |
| |
| .gift-lid { |
| position: absolute; |
| top: -30px; |
| left: -20px; |
| width: 240px; |
| height: 40px; |
| background: #ff4757; |
| border-radius: 5px; |
| z-index: 2; |
| transition: transform 0.6s; |
| } |
| |
| .gift-box.opened .gift-lid { |
| transform: rotateX(-180deg) translateY(-10px); |
| } |
| |
| .gift-ribbon-v { |
| position: absolute; |
| width: 40px; |
| height: 100%; |
| background: var(--secondary-color); |
| } |
| |
| .gift-ribbon-h { |
| position: absolute; |
| width: 100%; |
| height: 40px; |
| background: var(--secondary-color); |
| top: 0; |
| } |
| |
| .gift-handle { |
| position: absolute; |
| width: 100px; |
| height: 20px; |
| border: 5px solid var(--secondary-color); |
| border-bottom: none; |
| border-radius: 10px 10px 0 0; |
| top: 20px; |
| left: 50%; |
| transform: translateX(-50%); |
| z-index: 1; |
| } |
| |
| .message-card { |
| background: white; |
| padding: 2rem; |
| border-radius: 15px; |
| box-shadow: 0 10px 25px rgba(0,0,0,0.1); |
| text-align: left; |
| transform: rotateY(-90deg); |
| transition: transform 0.6s; |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| z-index: 10; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| align-items: center; |
| } |
| |
| .gift-box.opened ~ .message-card { |
| transform: rotateY(0deg); |
| } |
| |
| .message-card h3 { |
| color: var(--primary-color); |
| margin-bottom: 1rem; |
| } |
| |
| .message-card p { |
| font-size: 1rem; |
| line-height: 1.6; |
| color: #555; |
| } |
| |
| |
| .toast { |
| position: fixed; |
| bottom: 30px; |
| left: 50%; |
| transform: translateX(-50%) translateY(100px); |
| background: #333; |
| color: #fff; |
| padding: 12px 24px; |
| border-radius: 30px; |
| box-shadow: 0 5px 15px rgba(0,0,0,0.2); |
| opacity: 0; |
| transition: all 0.4s ease; |
| z-index: 200; |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| |
| .toast.show { |
| transform: translateX(-50%) translateY(0); |
| opacity: 1; |
| } |
| |
| |
| footer { |
| padding: 2rem; |
| text-align: center; |
| color: #888; |
| font-size: 0.9rem; |
| background: white; |
| width: 100%; |
| z-index: 2; |
| } |
| |
| |
| @keyframes float { |
| 0%, 100% { transform: translateY(0); } |
| 50% { transform: translateY(-20px); } |
| } |
| |
| @keyframes flicker { |
| 0% { transform: translateX(-50%) scale(1); opacity: 1; } |
| 100% { transform: translateX(-50%) scale(0.9); opacity: 0.8; } |
| } |
| |
| @keyframes pulse { |
| 0%, 100% { transform: scale(1); } |
| 50% { transform: scale(1.2); } |
| } |
| |
| @keyframes bounce { |
| 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } |
| 40% { transform: translateY(-10px); } |
| 60% { transform: translateY(-5px); } |
| } |
| |
| @keyframes fadeInDown { |
| from { opacity: 0; transform: translateY(-30px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| |
| |
| @media (max-width: 768px) { |
| .hero h1 { |
| font-size: 2.5rem; |
| } |
| .cake-container { |
| height: 150px; |
| } |
| .layer-bottom { width: 220px; height: 60px; } |
| .layer-middle { width: 180px; height: 45px; } |
| .layer-top { width: 140px; height: 30px; } |
| .candle { bottom: 75px; height: 30px; } |
| .plate { width: 220px; } |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <canvas id="confetti-canvas"></canvas> |
|
|
| <header> |
| <a href="#" class="logo"><i class="fa-solid fa-cake-candles"></i> Happy <span>Birthday</span></a> |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a> |
| </header> |
|
|
| <main> |
| <section class="hero"> |
| <h1 id="typing-text"></h1> |
| <p>Hier ist ein kleines Stück Glück für dich!</p> |
| <div class="scroll-down" onclick="scrollToContent()"> |
| <i class="fa-solid fa-chevron-down"></i> |
| </div> |
| </section> |
|
|
| <section class="cake-section"> |
| <div class="cake-container"> |
| <div class="plate"></div> |
| <div class="layer layer-bottom"></div> |
| <div class="layer layer-middle"></div> |
| <div class="layer layer-top"></div> |
| |
| |
| <div class="candle" style="left: 80px;" onclick="blowCandle(this, event)"><div class="flame"></div></div> |
| <div class="candle" style="left: 120px;" onclick="blowCandle(this, event)"><div class="flame"></div></div> |
| <div class="candle" style="left: 160px;" onclick="blowCandle(this, event)"><div class="flame"></div></div> |
| </div> |
| <p class="instruction"><i class="fa-regular fa-hand-pointer"></i> Klicke auf die Kerzen, um sie auszublähen!</p> |
| </section> |
|
|
| <section class="gift-section"> |
| <div class="gift-box" id="giftBox" onclick="openGift()"> |
| <div class="gift-lid"></div> |
| <div class="gift-ribbon-v"></div> |
| <div class="gift-ribbon-h"></div> |
| <div class="gift-handle"></div> |
| <div class="message-card"> |
| <h3>Alles Gute zum Geburtstag!</h3> |
| <p>Mögest du ein tolles Jahr haben voller Erfolg, Freude und süßen Überraschungen. Genieß den Tag!</p> |
| <button onclick="resetGift()" style="margin-top: 1rem; padding: 8px 16px; background: var(--secondary-color); border: none; border-radius: 20px; cursor: pointer; color: white;">Neu öffnen</button> |
| </div> |
| </div> |
| </section> |
| </main> |
|
|
| <div id="toast" class="toast"> |
| <i class="fa-regular fa-face-smile"></i> <span id="toast-message">Message</span> |
| </div> |
|
|
| <footer> |
| <p>© 2023 Happy Birthday Website. Made with <i class="fa-solid fa-heart" style="color: var(--primary-color);"></i> by you.</p> |
| </footer> |
|
|
| <script> |
| |
| const message = "Herzlichen Glückwunsch!"; |
| const typingElement = document.getElementById('typing-text'); |
| let charIndex = 0; |
| |
| function typeWriter() { |
| if (charIndex < message.length) { |
| typingElement.innerHTML += message.charAt(charIndex); |
| charIndex++; |
| setTimeout(typeWriter, 150); |
| } else { |
| |
| typingElement.style.animation = "float 3s ease-in-out infinite"; |
| } |
| } |
| |
| |
| window.onload = () => { |
| setTimeout(typeWriter, 500); |
| startConfetti(); |
| }; |
| |
| function scrollToContent() { |
| document.querySelector('.cake-section').scrollIntoView({ behavior: 'smooth' }); |
| } |
| |
| |
| function blowCandle(element, event) { |
| event.stopPropagation(); |
| const flame = element.querySelector('.flame'); |
| |
| if (flame.style.opacity === '0') return; |
| |
| |
| flame.style.transition = "all 0.5s ease-out"; |
| flame.style.transform = "translateX(-50%) scale(0.5) translateY(-10px)"; |
| flame.style.opacity = "0"; |
| |
| |
| createConfettiBurst(event.clientX, event.clientY); |
| |
| |
| const allCandles = document.querySelectorAll('.candle'); |
| const allBlown = Array.from(allCandles).every(c => c.querySelector('.flame').style.opacity === '0'); |
| |
| if (allBlown) { |
| showToast("Alle Kerzen sind aus! Das ist ein Geburtstag!"); |
| |
| for(let i=0; i<5; i++) { |
| setTimeout(() => { |
| createConfettiBurst(window.innerWidth/2, window.innerHeight/2); |
| }, i * 300); |
| } |
| } |
| } |
| |
| |
| function openGift() { |
| const gift = document.getElementById('giftBox'); |
| if (!gift.classList.contains('opened')) { |
| gift.classList.add('opened'); |
| showToast("Glückwunsch! Eine Nachricht für dich!"); |
| createConfettiBurst(window.innerWidth/2, window.innerHeight/2); |
| } |
| } |
| |
| function resetGift() { |
| const gift = document.getElementById('giftBox'); |
| gift.classList.remove('opened'); |
| } |
| |
| |
| function showToast(message) { |
| const toast = document.getElementById('toast'); |
| const toastMsg = document.getElementById('toast-message'); |
| toastMsg.textContent = message; |
| toast.classList.add('show'); |
| setTimeout(() => { |
| toast.classList.remove('show'); |
| }, 3000); |
| } |
| |
| |
| const canvas = document.getElementById('confetti-canvas'); |
| const ctx = canvas.getContext('2d'); |
| let particles = []; |
| |
| function resizeCanvas() { |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| } |
| window.addEventListener('resize', resizeCanvas); |
| resizeCanvas(); |
| |
| class Particle { |
| constructor(x, y, isBurst = false) { |
| this.x = x || Math.random() * canvas.width; |
| this.y = y || Math.random() * canvas.height - canvas.height; |
| this.size = Math.random() * 8 + 4; |
| this.speedY = Math.random() * 3 + 1; |
| this.speedX = (Math.random() - 0.5) * 2; |
| this.color = `hsl(${Math.random() * 360}, 70%, 50%)`; |
| this.rotation = Math.random() * 360; |
| this.rotationSpeed = (Math.random() - 0.5) * 5; |
| this.isBurst = isBurst; |
| |
| if (isBurst) { |
| this.vx = (Math.random() - 0.5) * 15; |
| this.vy = (Math.random() - 0.5) * 15; |
| } |
| } |
| |
| update() { |
| if (this.isBurst) { |
| this.x += this.vx; |
| this.y += this.vy; |
| this.vy += 0.2; |
| this.vx *= 0.95; |
| } else { |
| this.y += this.speedY; |
| this.x += Math.sin(this.y / 50) * 0.5; |
| } |
| |
| this.rotation += this.rotationSpeed; |
| |
| if (this.y > canvas.height) { |
| this.y = -20; |
| this.x = Math.random() * canvas.width; |
| } |
| } |
| |
| draw() { |
| ctx.save(); |
| ctx.translate(this.x, this.y); |
| ctx.rotate((this.rotation * Math.PI) / 180); |
| ctx.fillStyle = this.color; |
| ctx.fillRect(-this.size / 2, -this.size / 2, this.size, this.size); |
| ctx.restore(); |
| } |
| } |
| |
| function initParticles(count) { |
| for (let i = 0; i < count; i++) { |
| particles.push(new Particle()); |
| } |
| } |
| |
| function createConfettiBurst(x, y) { |
| for (let i = 0; i < 30; i++) { |
| particles.push(new Particle(x, y, true)); |
| } |
| } |
| |
| function startConfetti() { |
| initParticles(100); |
| animate(); |
| } |
| |
| function animate() { |
| ctx.clearRect(0, 0, canvas.width, canvas.height); |
| particles.forEach((p, index) => { |
| p.update(); |
| p.draw(); |
| |
| if (p.isBurst && (p.x < 0 || p.x > canvas.width || p.y > canvas.height)) { |
| |
| |
| } |
| }); |
| requestAnimationFrame(animate); |
| } |
| </script> |
| </body> |
| </html> |