index.html

12.72 KB
11/12/2025 12:26
HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Holiday Season 2025 | Magic Awaits</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=Cinzel:wght@400;700&family=Lato:wght@300;400&family=Pinyon+Script&display=swap" rel="stylesheet">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>

    <style>
        :root {
            --bg-dark: #0a1f1c; /* Deep Forest */
            --bg-accent: #0f2e29;
            --gold: #d4af37;
            --gold-light: #f3e5ab;
            --white: #f0f0f0;
            --glass: rgba(255, 255, 255, 0.05);
            --glass-border: rgba(255, 255, 255, 0.1);
        }

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

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

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

        /* --- Typography --- */
        h1, h2, h3 {
            font-family: 'Cinzel', serif;
            color: var(--gold);
        }

        .script-font {
            font-family: 'Pinyon Script', cursive;
            color: var(--gold-light);
            font-size: 2.5rem;
        }

        /* --- Navigation --- */
        nav {
            position: fixed;
            top: 0;
            width: 100%;
            padding: 20px 50px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 100;
            backdrop-filter: blur(10px);
            border-bottom: 1px solid var(--glass-border);
        }

        .logo {
            font-size: 1.5rem;
            font-weight: 700;
            letter-spacing: 2px;
        }

        .nav-links button {
            background: transparent;
            border: 1px solid var(--gold);
            color: var(--gold);
            padding: 10px 25px;
            border-radius: 30px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-family: 'Cinzel', serif;
        }

        .nav-links button:hover {
            background: var(--gold);
            color: var(--bg-dark);
            box-shadow: 0 0 15px var(--gold);
        }

        /* --- Hero Section --- */
        header {
            height: 100vh;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            text-align: center;
            position: relative;
            z-index: 10;
        }

        .hero-content {
            opacity: 0;
            transform: translateY(30px);
        }

        h1 {
            font-size: 5rem;
            margin-bottom: 20px;
            line-height: 1.1;
            text-shadow: 0 4px 20px rgba(0,0,0,0.5);
        }

        .sub-headline {
            font-size: 1.2rem;
            letter-spacing: 3px;
            text-transform: uppercase;
            margin-bottom: 40px;
        }

        /* --- Countdown Timer --- */
        .countdown-container {
            display: flex;
            gap: 30px;
            margin-top: 50px;
        }

        .time-box {
            background: var(--glass);
            border: 1px solid var(--glass-border);
            padding: 20px;
            min-width: 100px;
            border-radius: 10px;
            backdrop-filter: blur(5px);
        }

        .time-box span {
            display: block;
            font-size: 2.5rem;
            font-weight: 700;
            color: var(--gold);
            font-family: 'Cinzel', serif;
        }

        .time-box label {
            font-size: 0.8rem;
            text-transform: uppercase;
            letter-spacing: 1px;
        }

        /* --- Content Sections --- */
        section {
            padding: 100px 10%;
            position: relative;
            z-index: 10;
        }

        .glass-card {
            background: var(--glass);
            border: 1px solid var(--glass-border);
            border-radius: 20px;
            padding: 50px;
            backdrop-filter: blur(10px);
            margin-bottom: 50px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            transform: translateY(50px);
            opacity: 0;
        }

        .grid-2 {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 50px;
            align-items: center;
        }

        .glow-text {
            color: var(--white);
            font-size: 3rem;
            margin-bottom: 20px;
        }

        /* --- Footer --- */
        footer {
            text-align: center;
            padding: 50px;
            border-top: 1px solid var(--glass-border);
            position: relative;
            z-index: 10;
            background: rgba(10, 31, 28, 0.95);
        }

        /* --- Responsive --- */
        @media (max-width: 768px) {
            h1 { font-size: 3rem; }
            .grid-2 { grid-template-columns: 1fr; }
            .countdown-container { gap: 10px; }
            .time-box { min-width: 70px; padding: 10px; }
            .time-box span { font-size: 1.5rem; }
            nav { padding: 20px; }
        }
    </style>
</head>
<body>

    <canvas id="snow-canvas"></canvas>

    <nav>
        <div class="logo">NOEL 2025</div>
        <div class="nav-links">
            <button onclick="toggleSnowStorm()">Make it Storm</button>
        </div>
    </nav>

    <header>
        <div class="hero-content">
            <p class="script-font">Wishing you a...</p>
            <h1>Merry<br>Christmas</h1>
            <p class="sub-headline">And a Prosperous New Year</p>

            <div class="countdown-container">
                <div class="time-box"><span id="days">00</span><label>Days</label></div>
                <div class="time-box"><span id="hours">00</span><label>Hours</label></div>
                <div class="time-box"><span id="minutes">00</span><label>Mins</label></div>
                <div class="time-box"><span id="seconds">00</span><label>Secs</label></div>
            </div>
        </div>
    </header>

    <section>
        <div class="glass-card trigger-anim">
            <div class="grid-2">
                <div>
                    <p class="script-font">Reflect & Rejoice</p>
                    <h2 class="glow-text">The Season of Giving</h2>
                    <p>Embrace the warmth of the holidays. Whether you are celebrating with family, friends, or taking a moment of solitude, let the spirit of the season fill your heart with peace and gold-tinted memories.</p>
                </div>
                <div style="text-align: center;">
                    <svg width="200" height="200" viewBox="0 0 100 100" fill="none" stroke="#d4af37" stroke-width="2">
                        <path d="M50 10 L60 40 L90 40 L65 60 L75 90 L50 70 L25 90 L35 60 L10 40 L40 40 Z" />
                    </svg>
                </div>
            </div>
        </div>

        <div class="glass-card trigger-anim">
            <div class="grid-2">
                <div style="order: 2;">
                    <p class="script-font">New Beginnings</p>
                    <h2 class="glow-text">Hello, 2026</h2>
                    <p>As the clock ticks down, we prepare to turn the page. New goals, new dreams, and a fresh start await. Let's make the upcoming year the most brilliant one yet.</p>
                </div>
                <div style="order: 1; text-align: center;">
                    <div style="width: 150px; height: 150px; border: 2px dashed #d4af37; border-radius: 50%; margin: 0 auto; display: flex; align-items: center; justify-content: center;">
                        <span style="font-size: 2rem; color: #f3e5ab;">2026</span>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <footer>
        <p>&copy; 2025 Winter Collection. Designed with Holiday Cheer.</p>
    </footer>

    <script>
        // --- 1. GSAP Animations ---
        gsap.registerPlugin(ScrollTrigger);

        // Hero Animation
        gsap.to(".hero-content", {
            opacity: 1,
            y: 0,
            duration: 1.5,
            ease: "power3.out",
            delay: 0.2
        });

        // Scroll Trigger Animations for Cards
        gsap.utils.toArray('.trigger-anim').forEach(element => {
            gsap.to(element, {
                scrollTrigger: {
                    trigger: element,
                    start: "top 80%",
                    toggleActions: "play none none reverse"
                },
                opacity: 1,
                y: 0,
                duration: 1,
                ease: "power2.out"
            });
        });

        // --- 2. Countdown Timer ---
        const newYear = new Date('January 1, 2026 00:00:00').getTime();

        function updateTimer() {
            const now = new Date().getTime();
            const gap = newYear - now;

            const d = Math.floor(gap / (1000 * 60 * 60 * 24));
            const h = Math.floor((gap % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            const m = Math.floor((gap % (1000 * 60 * 60)) / (1000 * 60));
            const s = Math.floor((gap % (1000 * 60)) / 1000);

            document.getElementById('days').innerText = d < 10 ? '0' + d : d;
            document.getElementById('hours').innerText = h < 10 ? '0' + h : h;
            document.getElementById('minutes').innerText = m < 10 ? '0' + m : m;
            document.getElementById('seconds').innerText = s < 10 ? '0' + s : s;
        }
        setInterval(updateTimer, 1000);

        // --- 3. High Performance Canvas Snow ---
        const canvas = document.getElementById('snow-canvas');
        const ctx = canvas.getContext('2d');
        let width = window.innerWidth;
        let height = window.innerHeight;
        canvas.width = width;
        canvas.height = height;

        const flakes = [];
        let maxFlakes = 100; // Default gentle snow
        let stormMode = false;

        class Flake {
            constructor() {
                this.reset();
            }

            reset() {
                this.x = Math.random() * width;
                this.y = Math.random() * height - height; // Start above screen
                this.speed = Math.random() * 2 + 1;
                this.size = Math.random() * 3 + 1;
                this.drift = Math.random() * 1 - 0.5;
            }

            update() {
                this.y += this.speed;
                this.x += this.drift;

                if (this.y > height) {
                    this.reset();
                    this.y = -10; // Reset to top
                }

                // Storm mode speed multiplier
                if(stormMode) {
                    this.y += 3;
                }
            }

            draw() {
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fillStyle = "rgba(255, 255, 255, 0.7)";
                ctx.fill();
            }
        }

        function initSnow() {
            for (let i = 0; i < 300; i++) {
                flakes.push(new Flake());
            }
        }

        function animateSnow() {
            ctx.clearRect(0, 0, width, height);

            // Only draw up to maxFlakes
            const activeFlakes = stormMode ? 300 : 100;

            for (let i = 0; i < activeFlakes; i++) {
                flakes[i].update();
                flakes[i].draw();
            }
            requestAnimationFrame(animateSnow);
        }

        window.addEventListener('resize', () => {
            width = window.innerWidth;
            height = window.innerHeight;
            canvas.width = width;
            canvas.height = height;
        });

        // Toggle Storm Button
        function toggleSnowStorm() {
            stormMode = !stormMode;
            const btn = document.querySelector('.nav-links button');
            if(stormMode) {
                btn.innerText = "Calm the Storm";
                btn.style.background = "#fff";
                btn.style.color = "#0a1f1c";
            } else {
                btn.innerText = "Make it Storm";
                btn.style.background = "transparent";
                btn.style.color = "#d4af37";
            }
        }

        initSnow();
        animateSnow();
    </script>
</body>
</html>