index.html

21.24 KB
28/01/2026 03:59
HTML
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Happy Valentine's Day | A Digital Love Letter</title>
  <!-- Import Google Fonts -->
  <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=Dancing+Script:wght@600;700&family=Nunito:wght@300;400;700&display=swap" rel="stylesheet">
  <!-- Font Awesome for Icons -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

  <style>
    /* --- CSS Variables & Reset --- */
    :root {
      --primary: #e91e63;
      --primary-dark: #c2185b;
      --secondary: #ff80ab;
      --bg-color: #fce4ec;
      --text-color: #4a4a4a;
      --white: #ffffff;
      --glass: rgba(255, 255, 255, 0.7);
      --shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
      --transition: all 0.3s ease-in-out;
    }

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    html {
      scroll-behavior: smooth;
    }

    body {
      font-family: 'Nunito', sans-serif;
      background-color: var(--bg-color);
      color: var(--text-color);
      overflow-x: hidden;
      line-height: 1.6;
    }

    h1,
    h2,
    h3 {
      font-family: 'Dancing Script', cursive;
      color: var(--primary);
    }

    /* --- Canvas Background --- */
    #heart-canvas {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
      pointer-events: none;
    }

    /* --- Navigation --- */
    nav {
      position: fixed;
      top: 0;
      width: 100%;
      padding: 1.5rem 2rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
      z-index: 1000;
      background: rgba(252, 228, 236, 0.8);
      backdrop-filter: blur(10px);
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
    }

    .logo {
      font-size: 1.8rem;
      font-weight: 700;
      color: var(--primary);
    }

    .nav-links button {
      background: transparent;
      border: 2px solid var(--primary);
      padding: 0.5rem 1.2rem;
      border-radius: 50px;
      cursor: pointer;
      font-family: 'Nunito', sans-serif;
      font-weight: 600;
      color: var(--primary);
      transition: var(--transition);
    }

    .nav-links button:hover {
      background: var(--primary);
      color: var(--white);
    }

    /* --- Hero Section --- */
    .hero {
      height: 100vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      text-align: center;
      padding: 2rem;
      position: relative;
    }

    .hero h1 {
      font-size: 5rem;
      margin-bottom: 1rem;
      opacity: 0;
      animation: fadeUp 1s ease forwards 0.5s;
    }

    .hero p {
      font-size: 1.5rem;
      max-width: 600px;
      margin-bottom: 2.5rem;
      opacity: 0;
      animation: fadeUp 1s ease forwards 1s;
    }

    .pulse-heart {
      font-size: 4rem;
      color: var(--primary);
      cursor: pointer;
      animation: heartbeat 1.5s infinite;
      margin-bottom: 1rem;
      opacity: 0;
      animation: heartbeat 1.5s infinite, fadeUp 1s ease forwards 1.5s;
    }

    .scroll-down {
      position: absolute;
      bottom: 2rem;
      font-size: 2rem;
      color: var(--primary);
      animation: bounce 2s infinite;
    }

    /* --- Memories Timeline Section --- */
    .section-title {
      text-align: center;
      font-size: 3.5rem;
      margin: 4rem 0 3rem;
      position: relative;
      display: inline-block;
      left: 50%;
      transform: translateX(-50%);
    }

    .section-title::after {
      content: '';
      display: block;
      width: 60%;
      height: 3px;
      background: var(--secondary);
      margin: 0.5rem auto 0;
      border-radius: 2px;
    }

    .timeline {
      max-width: 800px;
      margin: 0 auto;
      padding: 2rem;
      position: relative;
    }

    .timeline::before {
      content: '';
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      width: 2px;
      height: 100%;
      background: var(--secondary);
    }

    .timeline-item {
      display: flex;
      justify-content: flex-end;
      padding-right: 3rem;
      position: relative;
      margin-bottom: 2rem;
      width: 50%;
      opacity: 0;
      /* Hidden initially for JS Observer */
      transform: translateY(30px);
      transition: var(--transition);
    }

    .timeline-item:nth-child(even) {
      align-self: flex-end;
      justify-content: flex-start;
      padding-right: 0;
      padding-left: 3rem;
      left: 50%;
    }

    .timeline-dot {
      position: absolute;
      right: -8px;
      top: 0;
      width: 16px;
      height: 16px;
      background: var(--primary);
      border-radius: 50%;
      border: 3px solid var(--white);
      z-index: 2;
    }

    .timeline-item:nth-child(even) .timeline-dot {
      right: auto;
      left: -8px;
    }

    .timeline-content {
      background: var(--white);
      padding: 1.5rem;
      border-radius: 15px;
      box-shadow: var(--shadow);
      width: 100%;
      position: relative;
    }

    .timeline-content h3 {
      font-family: 'Nunito', sans-serif;
      font-weight: 700;
      color: var(--primary-dark);
      margin-bottom: 0.5rem;
    }

    .timeline-content span {
      font-size: 0.85rem;
      color: #888;
      font-style: italic;
    }

    /* --- Reasons (Flip Cards) --- */
    .reasons-section {
      padding: 4rem 2rem;
      background: rgba(255, 255, 255, 0.4);
    }

    .cards-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 2rem;
      max-width: 1200px;
      margin: 0 auto;
    }

    .flip-card {
      background-color: transparent;
      height: 300px;
      perspective: 1000px;
      /* Enable 3D effect */
      opacity: 0;
      transform: translateY(30px);
      transition: var(--transition);
    }

    .flip-card-inner {
      position: relative;
      width: 100%;
      height: 100%;
      text-align: center;
      transition: transform 0.8s;
      transform-style: preserve-3d;
      border-radius: 20px;
      box-shadow: var(--shadow);
      cursor: pointer;
    }

    .flip-card:hover .flip-card-inner {
      transform: rotateY(180deg);
    }

    .flip-card-front,
    .flip-card-back {
      position: absolute;
      width: 100%;
      height: 100%;
      -webkit-backface-visibility: hidden;
      /* Safari */
      backface-visibility: hidden;
      border-radius: 20px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      padding: 2rem;
    }

    .flip-card-front {
      background: var(--white);
      border: 2px solid var(--secondary);
    }

    .flip-card-front i {
      font-size: 3rem;
      color: var(--primary);
      margin-bottom: 1rem;
    }

    .flip-card-back {
      background: var(--primary);
      color: var(--white);
      transform: rotateY(180deg);
    }

    /* --- Gallery Section --- */
    .gallery {
      padding: 4rem 2rem;
      max-width: 1000px;
      margin: 0 auto;
    }

    .photo-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 1rem;
    }

    .photo-item {
      border-radius: 15px;
      overflow: hidden;
      height: 250px;
      box-shadow: var(--shadow);
      opacity: 0;
      transform: scale(0.9);
      transition: var(--transition);
    }

    .photo-item img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.5s ease;
    }

    .photo-item:hover img {
      transform: scale(1.1);
    }

    /* --- Interactive Surprise Section --- */
    .surprise-section {
      min-height: 50vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      text-align: center;
      padding: 2rem;
    }

    .open-gift-btn {
      background: var(--primary);
      color: var(--white);
      border: none;
      padding: 1rem 3rem;
      font-size: 1.2rem;
      border-radius: 50px;
      cursor: pointer;
      box-shadow: 0 4px 15px rgba(233, 30, 99, 0.4);
      transition: var(--transition);
      font-family: 'Nunito', sans-serif;
      font-weight: 700;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .open-gift-btn:hover {
      transform: translateY(-3px) scale(1.05);
      box-shadow: 0 6px 20px rgba(233, 30, 99, 0.6);
    }

    /* --- Modal --- */
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
      backdrop-filter: blur(5px);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 2000;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.3s ease;
    }

    .modal-overlay.active {
      opacity: 1;
      pointer-events: auto;
    }

    .modal-content {
      background: var(--white);
      padding: 3rem;
      border-radius: 20px;
      max-width: 500px;
      width: 90%;
      text-align: center;
      position: relative;
      transform: scale(0.7);
      transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
      box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    }

    .modal-overlay.active .modal-content {
      transform: scale(1);
    }

    .close-modal {
      position: absolute;
      top: 15px;
      right: 20px;
      font-size: 1.5rem;
      cursor: pointer;
      color: #aaa;
      transition: color 0.3s;
    }

    .close-modal:hover {
      color: var(--primary);
    }

    /* --- Footer --- */
    footer {
      text-align: center;
      padding: 2rem;
      background: var(--primary);
      color: var(--white);
      font-size: 0.9rem;
    }

    /* --- Keyframes --- */
    @keyframes fadeUp {
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }

    @keyframes bounce {

      0%,
      20%,
      50%,
      80%,
      100% {
        transform: translateY(0);
      }

      40% {
        transform: translateY(-10px);
      }

      60% {
        transform: translateY(-5px);
      }
    }

    @keyframes heartbeat {
      0% {
        transform: scale(1);
      }

      14% {
        transform: scale(1.1);
      }

      28% {
        transform: scale(1);
      }

      42% {
        transform: scale(1.1);
      }

      70% {
        transform: scale(1);
      }
    }

    /* --- Utility Class for Observer --- */
    .visible {
      opacity: 1 !important;
      transform: translateY(0) scale(1) !important;
    }

    /* Mobile Responsive */
    @media (max-width: 768px) {
      .hero h1 {
        font-size: 3.5rem;
      }

      .timeline::before {
        left: 20px;
      }

      .timeline-item {
        width: 100%;
        padding-left: 45px;
        padding-right: 0;
      }

      .timeline-item:nth-child(even) {
        left: 0;
        padding-left: 45px;
      }

      .timeline-dot {
        left: 12px;
        right: auto;
      }

      .timeline-item:nth-child(even) .timeline-dot {
        left: 12px;
      }
    }
  </style>
</head>

<body>

  <!-- Background Canvas -->
  <canvas id="heart-canvas"></canvas>

  <!-- Navigation -->
  <nav>
    <div class="logo"><i class="fas fa-heart"></i> Love</div>
    <div class="nav-links">
      <button onclick="scrollToSection('surprise')">Open Gift</button>
    </div>
  </nav>

  <!-- Hero Section -->
  <section class="hero">
    <div class="pulse-heart"><i class="fas fa-heart"></i></div>
    <h1>Happy Valentine's Day</h1>
    <p>Every love story is beautiful, but ours is my favorite. This is a tiny digital corner to celebrate us.</p>
    <div class="scroll-down" onclick="scrollToSection('timeline')">
      <i class="fas fa-chevron-down"></i>
    </div>
  </section>

  <!-- Timeline / Journey -->
  <section id="timeline" class="timeline-section">
    <h2 class="section-title">Our Journey</h2>
    <div class="timeline">
      <div class="timeline-item">
        <div class="timeline-dot"></div>
        <div class="timeline-content">
          <h3>First Met</h3>
          <span>The Beginning</span>
          <p>I remember the day we met. The world seemed a little brighter, and your smile caught me off guard.</p>
        </div>
      </div>
      <div class="timeline-item">
        <div class="timeline-dot"></div>
        <div class="timeline-content">
          <h3>First Date</h3>
          <span>Butterflies</span>
          <p>Coffee turned into hours of conversation. I knew right then that I wanted to know everything about you.</p>
        </div>
      </div>
      <div class="timeline-item">
        <div class="timeline-dot"></div>
        <div class="timeline-content">
          <h3>Falling in Love</h3>
          <span>The Magic</span>
          <p>It wasn't a single moment, but a collection of small moments that made me realize I was in love.</p>
        </div>
      </div>
      <div class="timeline-item">
        <div class="timeline-dot"></div>
        <div class="timeline-content">
          <h3>Today & Forever</h3>
          <span>Still Falling</span>
          <p>Every day with you is a gift. Here's to creating a million more memories together.</p>
        </div>
      </div>
    </div>
  </section>

  <!-- Reasons Flip Cards -->
  <section class="reasons-section">
    <h2 class="section-title">Why I Love You</h2>
    <div class="cards-grid">
      <div class="flip-card">
        <div class="flip-card-inner">
          <div class="flip-card-front">
            <i class="fas fa-smile-beam"></i>
            <h3>Your Smile</h3>
          </div>
          <div class="flip-card-back">
            <h3>Your Smile</h3>
            <p>It lights up the darkest rooms and makes my worst days instantly better.</p>
          </div>
        </div>
      </div>
      <div class="flip-card">
        <div class="flip-card-inner">
          <div class="flip-card-front">
            <i class="fas fa-brain"></i>
            <h3>Your Mind</h3>
          </div>
          <div class="flip-card-back">
            <h3>Your Mind</h3>
            <p>I love how you think, your creativity, and the way you solve problems.</p>
          </div>
        </div>
      </div>
      <div class="flip-card">
        <div class="flip-card-inner">
          <div class="flip-card-front">
            <i class="fas fa-mug-hot"></i>
            <h3>Kindness</h3>
          </div>
          <div class="flip-card-back">
            <h3>Your Kindness</h3>
            <p>The way you care for others, even strangers, shows the beautiful soul you have.</p>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- Photo Gallery (Placeholders) -->
  <section class="gallery">
    <h2 class="section-title">Memories</h2>
    <div class="photo-grid">
      <div class="photo-item">
        <img src="../images/pexels-pixabay-326612.jpg" alt="Memory 1">
      </div>
      <div class="photo-item">
        <img src="../images/pexels-fmaderebner-340566.jpg" alt="Memory 2">

      </div>
      <div class="photo-item">
        <img src="../images/pexels-asadphoto-1024984.jpg" alt="Memory 3">
      </div>
      <div class="photo-item">
        <img src="../images/pexels-nurseryart-348520.jpg" alt="Memory 4">
      </div>
    </div>
  </section>

  <!-- Surprise CTA -->
  <section id="surprise" class="surprise-section">
    <h2>I have one more thing to say...</h2>
    <br>
    <button class="open-gift-btn" onclick="openModal()">
      <i class="fas fa-gift"></i> Click Here
    </button>
  </section>

  <!-- Footer -->
  <footer>
    <p>Made with <i class="fas fa-heart"></i> just for you. Happy Valentine's Day.</p>
  </footer>

  <!-- Modal -->
  <div class="modal-overlay" id="modal">
    <div class="modal-content">
      <span class="close-modal" onclick="closeModal()">&times;</span>
      <i class="fas fa-heart" style="font-size: 3rem; color: var(--primary); margin-bottom: 1rem;"></i>
      <h2 style="font-family: 'Dancing Script'; margin-bottom: 1rem;">I Love You!</h2>
      <p>Thank you for being you, for being my rock, and for making life so incredibly beautiful. Today and every day, you are my valentine.</p>
      <button onclick="closeModal()"
              style="margin-top: 1.5rem; background: var(--secondary); border: none; padding: 0.5rem 1.5rem; border-radius: 20px; color: white; cursor: pointer;">Close</button>
    </div>
  </div>

  <script>
    // --- 1. Canvas Falling Hearts Animation ---
    const canvas = document.getElementById('heart-canvas');
    const ctx = canvas.getContext('2d');

    let width, height;
    let hearts = [];

    function resize() {
      width = canvas.width = window.innerWidth;
      height = canvas.height = window.innerHeight;
    }

    window.addEventListener('resize', resize);
    resize();

    class Heart {
      constructor() {
        this.x = Math.random() * width;
        this.y = Math.random() * height - height; // Start above screen
        this.size = Math.random() * 10 + 5;
        this.speedY = Math.random() * 1 + 0.5;
        this.speedX = Math.random() * 1 - 0.5;
        this.opacity = Math.random() * 0.5 + 0.1;
        this.color = `rgba(233, 30, 99, ${this.opacity})`; // Primary pink
      }

      update() {
        this.y += this.speedY;
        this.x += Math.sin(this.y * 0.01) * 0.5; // Gentle sway

        if (this.y > height) {
          this.y = -20;
          this.x = Math.random() * width;
        }
      }

      draw() {
        ctx.fillStyle = this.color;
        ctx.beginPath();
        // Draw heart shape
        let topCurveHeight = this.size * 0.3;
        ctx.moveTo(this.x, this.y + topCurveHeight);
        // Top left curve
        ctx.bezierCurveTo(
          this.x, this.y,
          this.x - this.size / 2, this.y,
          this.x - this.size / 2, this.y + topCurveHeight
        );
        // Bottom left curve
        ctx.bezierCurveTo(
          this.x - this.size / 2, this.y + (this.size + topCurveHeight) / 2,
          this.x, this.y + (this.size + topCurveHeight) / 2,
          this.x, this.y + this.size
        );
        // Bottom right curve
        ctx.bezierCurveTo(
          this.x, this.y + (this.size + topCurveHeight) / 2,
          this.x + this.size / 2, this.y + (this.size + topCurveHeight) / 2,
          this.x + this.size / 2, this.y + topCurveHeight
        );
        // Top right curve
        ctx.bezierCurveTo(
          this.x + this.size / 2, this.y,
          this.x, this.y,
          this.x, this.y + topCurveHeight
        );
        ctx.fill();
      }
    }

    function initHearts() {
      hearts = [];
      for (let i = 0; i < 50; i++) {
        hearts.push(new Heart());
      }
    }

    function animateHearts() {
      ctx.clearRect(0, 0, width, height);
      hearts.forEach(heart => {
        heart.update();
        heart.draw();
      });
      requestAnimationFrame(animateHearts);
    }

    initHearts();
    animateHearts();


    // --- 2. Scroll Animations (Intersection Observer) ---
    const observerOptions = {
      threshold: 0.2,
      rootMargin: "0px 0px -50px 0px"
    };

    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('visible');
          // Optional: Stop observing once visible
          // observer.unobserve(entry.target);
        }
      });
    }, observerOptions);

    document.querySelectorAll('.timeline-item, .flip-card, .photo-item').forEach(el => {
      observer.observe(el);
    });


    // --- 3. Interaction Functions ---
    function scrollToSection(id) {
      document.getElementById(id).scrollIntoView({behavior: 'smooth'});
    }

    function openModal() {
      document.getElementById('modal').classList.add('active');
      launchConfetti();
    }

    function closeModal() {
      document.getElementById('modal').classList.remove('active');
    }

    // Close modal if clicking outside content
    document.getElementById('modal').addEventListener('click', function(e) {
      if (e.target === this) {
        closeModal();
      }
    });


    // --- 4. Simple Confetti Effect (JS) ---
    function launchConfetti() {
      const colors = ['#e91e63', '#ff80ab', '#ffc107', '#ffffff'];

      for (let i = 0; i < 100; i++) {
        createConfettiPiece(colors);
      }
    }

    function createConfettiPiece(colors) {
      const confetti = document.createElement('div');
      const bg = colors[Math.floor(Math.random() * colors.length)];

      confetti.style.position = 'fixed';
      confetti.style.width = '10px';
      confetti.style.height = '10px';
      confetti.style.backgroundColor = bg;
      confetti.style.top = '50%';
      confetti.style.left = '50%';
      confetti.style.zIndex = '2001';
      confetti.style.pointerEvents = 'none';

      document.body.appendChild(confetti);

      // Random destination
      const x = (Math.random() - 0.5) * window.innerWidth * 0.8;
      const y = (Math.random() - 0.5) * window.innerHeight * 0.8;
      const rotation = Math.random() * 360;

      const animation = confetti.animate([
        {transform: `translate(0, 0) rotate(0deg)`, opacity: 1},
        {transform: `translate(${x}px, ${y}px) rotate(${rotation}deg)`, opacity: 0}
      ], {
        duration: 1000 + Math.random() * 1000,
        easing: 'cubic-bezier(0.25, 1, 0.5, 1)'
      });

      animation.onfinish = () => confetti.remove();
    }

  </script>
</body>

</html>