anycoder-6e7e8452 / index.html
CodingPenguin44's picture
Upload folder using huggingface_hub
f79f393 verified
<!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>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;600&family=Poppins:wght@300;400;700&display=swap" rel="stylesheet">
<!-- FontAwesome Icons -->
<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;
}
/* Canvas for Confetti */
#confetti-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
/* Header */
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 Content */
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 Section */
.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;
}
/* Interactive Cake Section */
.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;
}
/* CSS Only Cake */
.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; /* Adjust based on layer height */
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 Box Section */
.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); /* Initial hidden state */
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 Notification */
.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 */
footer {
padding: 2rem;
text-align: center;
color: #888;
font-size: 0.9rem;
background: white;
width: 100%;
z-index: 2;
}
/* Animations */
@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); }
}
/* Responsive */
@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>
<!-- Candles that can be blown out -->
<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>&copy; 2023 Happy Birthday Website. Made with <i class="fa-solid fa-heart" style="color: var(--primary-color);"></i> by you.</p>
</footer>
<script>
// --- Typing Effect ---
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 {
// Add sparkle effect after typing
typingElement.style.animation = "float 3s ease-in-out infinite";
}
}
// Start typing after a short delay
window.onload = () => {
setTimeout(typeWriter, 500);
startConfetti();
};
function scrollToContent() {
document.querySelector('.cake-section').scrollIntoView({ behavior: 'smooth' });
}
// --- Candle Blowing Logic ---
function blowCandle(element, event) {
event.stopPropagation(); // Prevent opening gift box if clicking candle
const flame = element.querySelector('.flame');
if (flame.style.opacity === '0') return; // Already gone
// Blow effect
flame.style.transition = "all 0.5s ease-out";
flame.style.transform = "translateX(-50%) scale(0.5) translateY(-10px)";
flame.style.opacity = "0";
// Trigger confetti burst
createConfettiBurst(event.clientX, event.clientY);
// Check if all candles are blown
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!");
// Trigger giant confetti
for(let i=0; i<5; i++) {
setTimeout(() => {
createConfettiBurst(window.innerWidth/2, window.innerHeight/2);
}, i * 300);
}
}
}
// --- Gift Box Logic ---
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');
}
// --- Toast Notification ---
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);
}
// --- Confetti System ---
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; // Gravity
this.vx *= 0.95; // Friction
} else {
this.y += this.speedY;
this.x += Math.sin(this.y / 50) * 0.5; // Sway effect
}
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();
// Remove burst particles that are off screen or slow
if (p.isBurst && (p.x < 0 || p.x > canvas.width || p.y > canvas.height)) {
// Optional: remove burst particles to save memory,
// but keeping them creates a nice pile effect
}
});
requestAnimationFrame(animate);
}
</script>
</body>
</html>