<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Happy Birthday, My Love!</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Great+Vibes&family=Playfair+Display:ital,wght@0,600;1,400&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet"> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { min-height: 100vh; display: flex; justify-content: center; align-items: center; background: radial-gradient(circle at center, #2e0814 0%, #140207 70%, #080103 100%); font-family: 'Poppins', sans-serif; overflow-x: hidden; padding: 20px; } /* Floating petals */ .petals-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } .petal { position: absolute; background: linear-gradient(135deg, #ff4b72, #a80024); border-radius: 150% 0 150% 0; opacity: 0.7; filter: drop-shadow(0 2px 5px rgba(0,0,0,0.3)); animation: fall linear infinite; } @keyframes fall { 0% { transform: translate(0, -10%) rotate(0deg) scale(0.8); opacity: 0; } 10% { opacity: 0.8; } 90% { opacity: 0.8; } 100% { transform: translate(120px, 110vh) rotate(360deg) scale(1.1); opacity: 0; } } /* Container */ .scene { position: relative; width: 100%; max-width: 480px; perspective: 1200px; z-index: 1; display: flex; flex-direction: column; align-items: center; } .instruction { color: #f7d794; font-size: 0.95rem; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 25px; text-align: center; transition: opacity 0.5s ease; animation: pulse 2s infinite ease-in-out; } @keyframes pulse { 0%, 100% { opacity: 0.6; transform: scale(0.98); } 50% { opacity: 1; transform: scale(1.02); } } /* Envelope styling */ .envelope-wrapper { position: relative; width: 100%; height: 320px; background: #7a0f24; border-radius: 12px; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.6), 0 0 40px rgba(255, 75, 114, 0.15); cursor: pointer; transition: transform 0.6s ease; } .envelope-wrapper::before { content: ''; position: absolute; inset: 6px; border: 1px dashed rgba(247, 215, 148, 0.4); border-radius: 8px; pointer-events: none; z-index: 2; } /* Envelope Top Flap */ .flap { position: absolute; top: 0; left: 0; width: 100%; height: 100%; clip-path: polygon(0 0, 50% 55%, 100% 0); background: linear-gradient(180deg, #9e1834 0%, #7a0f24 100%); transform-origin: top; transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1), z-index 0.2s 0.3s; z-index: 5; } /* Envelope Pockets (Bottom & Sides) */ .pocket { position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; clip-path: polygon(0 100%, 50% 45%, 100% 100%); background: #640a1c; z-index: 4; } .pocket-left { position: absolute; inset: 0; clip-path: polygon(0 0, 0 100%, 50% 50%); background: #700c20; z-index: 3; } .pocket-right { position: absolute; inset: 0; clip-path: polygon(100% 0, 100% 100%, 50% 50%); background: #700c20; z-index: 3; } /* Wax Seal */ .wax-seal { position: absolute; top: 55%; left: 50%; transform: translate(-50%, -50%); width: 62px; height: 62px; background: radial-gradient(circle at 30% 30%, #e74c3c, #8b0000); border-radius: 50%; display: flex; justify-content: center; align-items: center; box-shadow: 0 4px 15px rgba(0,0,0,0.5), inset 0 2px 4px rgba(255,255,255,0.3); z-index: 6; transition: opacity 0.4s ease, transform 0.4s ease; } .wax-seal::after { content: '❤'; color: #ffd700; font-size: 24px; text-shadow: 0 1px 2px rgba(0,0,0,0.6); } /* Letter / Birthday Card */ .card { position: absolute; top: 10px; left: 5%; width: 90%; background: #fffdf9; border-radius: 12px; padding: 24px 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); transition: transform 0.9s cubic-bezier(0.34, 1.2, 0.64, 1), opacity 0.6s ease; z-index: 2; opacity: 0; max-height: 85vh; overflow-y: auto; scrollbar-width: none; } .card::-webkit-scrollbar { display: none; } /* Opened State */ .scene.open .flap { transform: rotateX(180deg); z-index: 1; } .scene.open .wax-seal { opacity: 0; transform: translate(-50%, -50%) scale(0.5); pointer-events: none; } .scene.open .card { transform: translateY(-160px); opacity: 1; z-index: 10; box-shadow: 0 30px 60px rgba(0,0,0,0.4); } .scene.open .instruction { opacity: 0; } /* Card Content */ .card-header { text-align: center; margin-bottom: 15px; } .card-header h1 { font-family: 'Great Vibes', cursive; color: #9e1834; font-size: 2.5rem; line-height: 1.1; font-weight: normal; } .card-header p { font-family: 'Playfair Display', serif; font-style: italic; color: #b38728; font-size: 0.9rem; letter-spacing: 1px; } /* Quotes */ .quote-box { text-align: center; font-family: 'Playfair Display', serif; font-style: italic; color: #4a2c2c; font-size: 0.95rem; margin: 12px 0; line-height: 1.4; position: relative; padding: 0 15px; } .quote-box::before, .quote-box::after { content: '“'; color: #d4af37; font-size: 1.4rem; line-height: 0; vertical-align: -5px; } .quote-box::after { content: '”'; } /* Photo Gallery Collage */ .photo-grid { display: flex; flex-direction: column; gap: 12px; margin: 18px 0; } .photo-frame { background: #ffffff; padding: 8px 8px 16px 8px; border-radius: 6px; box-shadow: 0 4px 12px rgba(0,0,0,0.12); border: 1px solid #f0e6d6; transition: transform 0.3s ease; } .photo-frame:hover { transform: scale(1.02); } .photo-frame img { width: 100%; height: 220px; object-fit: cover; border-radius: 4px; display: block; } .photo-frame.tilt-left { transform: rotate(-2deg); } .photo-frame.tilt-right { transform: rotate(2deg); } .photo-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } .photo-row .photo-frame img { height: 150px; } .card-footer { text-align: center; margin-top: 15px; padding-top: 15px; border-top: 1px dashed #e8d7c3; } .card-footer p { font-family: 'Great Vibes', cursive; font-size: 1.8rem; color: #9e1834; } .close-btn { display: block; margin: 15px auto 0; background: transparent; border: 1px solid #d4af37; color: #b38728; padding: 5px 16px; border-radius: 20px; font-size: 0.75rem; cursor: pointer; text-transform: uppercase; letter-spacing: 1px; transition: all 0.3s; } .close-btn:hover { background: #b38728; color: #fff; } </style> </head> <body> <div class="petals-container" id="petals"></div> <div class="scene" id="scene"> <div class="instruction">✨ Tap the wax seal to open ✨</div> <div class="envelope-wrapper" id="envelope"> <div class="flap"></div> <div class="wax-seal"></div> <div class="pocket-left"></div> <div class="pocket-right"></div> <div class="pocket"></div> <!-- Birthday Card Inside --> <div class="card" id="card"> <div class="card-header"> <h1>Happy Birthday, My Love</h1> <p>You make every single day magical</p> </div> <div class="quote-box"> Every day with you is a beautiful adventure. </div> <div class="photo-grid"> <!-- Main Photo --> <div class="photo-frame tilt-left"> <img src="photo1.jpg" alt="Special memory 1"> </div> <div class="quote-box"> You are my heart's greatest joy. </div> <!-- Dual Photo Row --> <div class="photo-row"> <div class="photo-frame tilt-right"> <img src="photo2.jpg" alt="Special memory 2"> </div> <div class="photo-frame tilt-left"> <img src="photo3.jpg" alt="Special memory 3"> </div> </div> </div> <div class="quote-box"> To the love of my life, wishing you the happiest birthday! </div> <div class="card-footer"> <p>Forever & Always Yours</p> <button class="close-btn" id="closeBtn">Close Envelope</button> </div> </div> </div> </div> <script> const scene = document.getElementById('scene'); const envelope = document.getElementById('envelope'); const closeBtn = document.getElementById('closeBtn'); const petalsContainer = document.getElementById('petals'); // Toggle open state envelope.addEventListener('click', (e) => { if (!scene.classList.contains('open')) { scene.classList.add('open'); } }); closeBtn.addEventListener('click', (e) => { e.stopPropagation(); scene.classList.remove('open'); }); // Create floating petals for (let i = 0; i < 25; i++) { const petal = document.createElement('div'); petal.classList.add('petal'); petal.style.left = Math.random() * 100 + 'vw'; petal.style.width = Math.random() * 12 + 10 + 'px'; petal.style.height = Math.random() * 15 + 12 + 'px'; petal.style.animationDuration = Math.random() * 5 + 6 + 's'; petal.style.animationDelay = Math.random() * 5 + 's'; petalsContainer.appendChild(petal); } </script> </body> </html>