<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>KJS - Charity & Elite Badminton</title>

    

    <script src="https://cdn.tailwindcss.com"></script>

    

    <style>

        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=IBM+Plex+Mono:ital,wght@0,400;0,700;0,900;1,400&display=swap');


        * { 

            font-family: 'Inter', sans-serif; 

            cursor: none; 

        }

        .font-mono-kjs { font-family: 'IBM Plex Mono', monospace; }


        :root {

            --orange: #FF8C00;

            --dark: #050505;

        }


        body::-webkit-scrollbar { display: none; }

        body { 

            -ms-overflow-style: none; 

            scrollbar-width: none; 

            background-color: var(--dark);

            color: #fff;

            overscroll-behavior: none;

            overflow: hidden; 

        }


        /* NOISE OVERLAY */

        .noise-bg {

            position: fixed;

            inset: 0;

            z-index: 9998;

            opacity: 0.04;

            pointer-events: none;

            background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");

        }


        /* CUSTOM CURSOR */

        #custom-cursor {

            position: fixed;

            top: 0; left: 0;

            width: 15px; height: 15px;

            background: #FF8C00;

            border-radius: 50%;

            pointer-events: none;

            z-index: 9999;

            mix-blend-mode: normal;

            transform: translate(-50%, -50%);

            transition: width 0.3s cubic-bezier(0.16, 1, 0.3, 1), height 0.3s cubic-bezier(0.16, 1, 0.3, 1), background 0.3s ease;

            will-change: transform, width, height;

        }

        body.hovering #custom-cursor {

            width: 60px;

            height: 60px;

            background: white;

            mix-blend-mode: difference;

            opacity: 1;

        }


        /* PRELOADER */

        #preloader {

            position: fixed;

            inset: 0;

            background: var(--dark);

            z-index: 10000;

            display: flex;

            justify-content: center;

            align-items: center;

            flex-direction: column;

            transition: transform 1.2s cubic-bezier(0.7, 0, 0.3, 1);

        }

        #preloader.hide {

            transform: translateY(-100%);

        }

        

        /* SMOOTH SCROLL WRAPPERS */

        #smooth-wrapper {

            position: fixed;

            top: 0; left: 0;

            width: 100vw; height: 100vh;

            overflow: hidden;

            pointer-events: none;

            z-index: 0;

        }

        #smooth-content {

            width: 100%;

            will-change: transform;

            pointer-events: auto;

        }


        /* Animasi Load */

        .reveal-up {

            opacity: 0;

            transform: translateY(40px);

            transition: all 1.2s cubic-bezier(0.16, 1, 0.3, 1);

        }

        .reveal-up.active {

            opacity: 1;

            transform: translateY(0);

        }


        .magnetic { display: inline-block; }


        /* FLOATING IMAGE REVEAL (EVENTS) */

        #hover-preview {

            position: fixed;

            top: 0; left: 0;

            width: 320px; height: 220px;

            background-size: cover;

            background-position: center;

            pointer-events: none;

            z-index: 9000;

            opacity: 0;

            transform: scale(0.8) rotate(0deg);

            border-radius: 12px;

            transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);

            will-change: transform, opacity;

            box-shadow: 0 30px 60px rgba(0,0,0,0.5);

        }

        #hover-preview.show {

            opacity: 1;

            transform: scale(1) rotate(4deg);

        }

    </style>

</head>

<body>


    <div id="preloader">

        <img src="KJS.png" alt="Logo KJS" class="h-16 md:h-24 w-auto mb-8 drop-shadow-2xl">

        <div class="font-mono-kjs text-sm tracking-[0.4em] text-[#FF8C00] mb-4">LOADING KJS EXPERIENCE</div>

        <div id="loader-counter" class="font-mono-kjs font-black text-8xl md:text-9xl text-white">0%</div>

    </div>


    <div class="noise-bg"></div>

    <div id="custom-cursor"></div>

    <div id="hover-preview"></div>


    <nav class="fixed top-0 left-0 right-0 z-[100] flex items-center justify-between p-6 text-white mix-blend-difference">

        <div class="hover-target magnetic cursor-pointer" onclick="scrollToId('hero')">

            <img src="KJS.png" alt="Logo KJS" class="h-8 md:h-10 w-auto inline-block pointer-events-none">

        </div>

        <div class="hidden md:flex bg-white/10 backdrop-blur-md border border-white/20 rounded-full px-2 py-2 items-center gap-2">

            <button onclick="scrollToId('vision')" class="hover-target text-[#FF8C00] px-5 py-2 rounded-full text-sm font-bold font-mono-kjs hover:bg-white/10 transition">Vision</button>

            <button onclick="scrollToId('squad')" class="hover-target text-white px-5 py-2 rounded-full text-sm font-medium transition hover:bg-white/20">Squad</button>

            <button onclick="scrollToId('events')" class="hover-target text-white px-5 py-2 rounded-full text-sm font-medium transition hover:bg-white/20">Events</button>

        </div>

        <button class="hover-target magnetic bg-white text-black font-mono-kjs font-bold text-sm px-6 py-2.5 rounded-full hover:bg-[#FF8C00] hover:text-white transition-colors">

            <span class="inline-block">JOIN US</span>

        </button>

    </nav>


    <div id="smooth-wrapper">

        <div id="smooth-content">


            <section id="hero" class="relative w-full h-screen overflow-hidden bg-black flex items-center justify-center pt-20">

                <div class="absolute inset-0 bg-center bg-cover bg-no-repeat opacity-40 scale-105 transition-transform duration-[3s]" id="hero-img-1"

                     style="background-image: url('https://images.unsplash.com/photo-1611095567219-8157778b1973?q=80&w=1920&auto=format&fit=crop');">

                </div>

                <div id="reveal-layer" class="absolute inset-0 bg-center bg-cover bg-no-repeat z-30 pointer-events-none"

                     style="background-image: url('test.webp'); mask-size: 100% 100%; -webkit-mask-size: 100% 100%;">

                </div>

                

                <canvas id="mask-canvas" class="absolute inset-0 pointer-events-none z-20" style="display: none;"></canvas>


                <div class="relative z-40 text-center pointer-events-none w-full px-4 flex justify-center items-center">

                    <img src="FULL.png" alt="Kencana Jingga Society" class="w-[70vw] md:w-[35vw] drop-shadow-[0_20px_50px_rgba(0,0,0,0.5)] reveal-up delay-100">

                </div>

            </section>


            <div class="w-full bg-[#FF8C00] text-black py-5 overflow-hidden relative z-50 border-y border-[#FF8C00]/50">

                <div class="flex whitespace-nowrap font-mono-kjs font-black text-5xl uppercase" id="marquee">

                    <span class="px-8">PLAY FOR FREE</span>

                    <span class="px-8">GIVE FOR A CAUSE</span>

                    <span class="px-8">MALANG CITY</span>

                    <span class="px-8">KJS COLLECTIVE</span>

                    <span class="px-8">PLAY FOR FREE</span>

                    <span class="px-8">GIVE FOR A CAUSE</span>

                    <span class="px-8">MALANG CITY</span>

                    <span class="px-8">KJS COLLECTIVE</span>

                </div>

            </div>


            <section id="vision" class="relative w-full min-h-screen bg-[#050505] flex items-center py-32 px-6 md:px-20 overflow-hidden">

                <div class="absolute inset-0 opacity-10" style="background-image: radial-gradient(circle at right, #FF8C00 0%, transparent 50%);" data-speed="0.2"></div>

                

                <div class="max-w-6xl mx-auto z-10 w-full">

                    <div class="text-[#FF8C00] font-mono-kjs font-bold tracking-[0.2em] mb-8 reveal-up">OUR VISION</div>

                    <h2 class="text-white font-medium text-4xl md:text-5xl lg:text-6xl leading-tight reveal-up delay-100">

                        Every match means more than the final score. Through <span class="text-[#FF8C00] font-mono-kjs italic">free-to-enter</span> tournaments, we bring people together and use the power of sport to <span class="text-white font-mono-kjs italic underline decoration-[#FF8C00]">support those who need it most.</span>

                    </h2>

                    <p class="mt-8 text-white/50 text-xl max-w-3xl reveal-up delay-150">

                        Zero entry fees. 100% voluntary donations. You play your heart out on the court, and if you choose to, you donate to the charities we partner with. That's the KJS way.

                    </p>

                    

                    <div class="mt-16 grid grid-cols-1 md:grid-cols-3 gap-12 reveal-up delay-200 border-t border-white/10 pt-12">

                        <div>

                            <div class="text-7xl font-mono-kjs font-black text-[#FF8C00]">20</div>

                            <div class="text-sm text-white/50 tracking-widest mt-2 uppercase font-bold">Members</div>

                        </div>

                        <div>

                            <div class="text-7xl font-mono-kjs font-black text-[#FF8C00]">10</div>

                            <div class="text-sm text-white/50 tracking-widest mt-2 uppercase font-bold">Matches Played</div>

                        </div>

                        <div>

                            <div class="text-7xl font-mono-kjs font-black text-[#FF8C00]">1</div>

                            <div class="text-sm text-white/50 tracking-widest mt-2 uppercase font-bold">Tour Held</div>

                        </div>

                    </div>

                </div>

            </section>


            <section id="squad" class="relative w-full min-h-screen bg-[#0a0a0a] px-6 md:px-20 py-32 border-t border-white/5">

                <div class="text-center mb-24 reveal-up">

                    <h2 class="font-mono-kjs font-black text-6xl text-white mb-4">THE CREW.</h2>

                    <p class="text-xl text-white/50">The minds behind the movement.</p>

                </div>


                <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">

                    <a href="https://www.instagram.com/rifqyprdya/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up" style="transform-style: preserve-3d;" data-speed="0.1">

                        <img src="rifqy.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors">RIFQY</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Head of KJS</p>

                        </div>

                    </a>


                    <a href="https://www.instagram.com/farrrelarya/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up delay-100" style="transform-style: preserve-3d;" data-speed="0.3">

                        <img src="ayel.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-3xl lg:text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors leading-tight">FARREL ICY APPLE</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Vice Head</p>

                        </div>

                    </a>


                    <a href="https://www.instagram.com/fatyaazhraa/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up delay-200" style="transform-style: preserve-3d;" data-speed="0.15">

                        <img src="aya.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors">AYA</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Secretary</p>

                        </div>

                    </a>


                    <a href="https://www.instagram.com/salsabilasalda/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up delay-300" style="transform-style: preserve-3d;" data-speed="0.25">

                        <img src="salsa.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors">SALSA</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Head of Event</p>

                        </div>

                    </a>


                    <a href="https://www.instagram.com/naysillartha/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up delay-400" style="transform-style: preserve-3d;" data-speed="0.1">

                        <img src="nai.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors">NAI</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Head of Creative</p>

                        </div>

                    </a>


                    <a href="https://www.instagram.com/afilardho/" target="_blank" class="block hover-target js-tilt w-full h-[500px] bg-[#111] rounded-2xl overflow-hidden relative cursor-pointer group reveal-up delay-500" style="transform-style: preserve-3d;" data-speed="0.2">

                        <img src="aldo.webp" class="absolute inset-0 w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 group-hover:scale-110 transition-all duration-700">

                        <div class="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent"></div>

                        <div class="absolute bottom-8 left-8 z-20 pointer-events-none" style="transform: translateZ(50px);">

                            <h3 class="font-mono-kjs font-black text-4xl text-white mb-1 group-hover:text-[#FF8C00] transition-colors">ALDO</h3>

                            <p class="text-[#FF8C00] font-bold tracking-widest uppercase text-sm">Head of PR</p>

                        </div>

                    </a>

                </div>

            </section>


            <section id="events" class="relative w-full min-h-screen bg-[#050505] py-32 px-6 md:px-20 border-t border-white/5">

                <div class="border-b border-white/20 pb-8 mb-16 reveal-up">

                    <h2 class="font-mono-kjs font-black text-6xl text-[#FF8C00]">TOURNAMENTS</h2>

                </div>


                <div class="flex flex-col w-full">

                    <div class="event-row hover-target group border-b border-white/10 py-12 flex flex-col md:flex-row justify-between md:items-center cursor-pointer transition-colors hover:bg-white/5 px-6 reveal-up" 

                         data-img="batam.webp">

                        <div class="text-4xl md:text-6xl font-mono-kjs font-bold text-white/40 group-hover:text-white group-hover:translate-x-4 transition-all duration-500">KJS GOES TO BATAM</div>

                        <div class="text-[#FF8C00] font-mono-kjs mt-4 md:mt-0 tracking-widest text-xl group-hover:-translate-x-4 transition-transform duration-500">JULY 2026</div>

                    </div>

                    

                    <div class="event-row hover-target group border-b border-white/10 py-12 flex flex-col md:flex-row justify-between md:items-center cursor-pointer transition-colors hover:bg-white/5 px-6 reveal-up" 

                         data-img="agustus.webp">

                        <div class="text-4xl md:text-6xl font-mono-kjs font-bold text-white/40 group-hover:text-white group-hover:translate-x-4 transition-all duration-500">KJS AGUSTUSAN</div>

                        <div class="text-[#FF8C00] font-mono-kjs mt-4 md:mt-0 tracking-widest text-xl group-hover:-translate-x-4 transition-transform duration-500">AUGUST 2026</div>

                    </div>


                    <div class="event-row hover-target group border-b border-white/10 py-12 flex flex-col md:flex-row justify-between md:items-center cursor-pointer transition-colors hover:bg-white/5 px-6 reveal-up" 

                         data-img="malang.webp">

                        <div class="flex items-center gap-4">

                            <div class="text-4xl md:text-6xl font-mono-kjs font-bold text-white/20 group-hover:text-white/80 group-hover:translate-x-4 transition-all duration-500">KJS BADMINTON VOL. 1</div>

                            <span class="border border-white/20 text-white/40 text-xs px-3 py-1 rounded-full group-hover:translate-x-4 transition-transform duration-500">COMPLETED</span>

                        </div>

                        <div class="text-white/30 font-mono-kjs mt-4 md:mt-0 tracking-widest text-xl group-hover:-translate-x-4 transition-transform duration-500">22 MAY 2026</div>

                    </div>

                </div>

            </section>


            <footer class="bg-[#050505] py-24 px-6 md:px-20 border-t border-white/10 flex flex-col items-center justify-center">

                <img src="KJS.png" alt="KJS Footer Logo" class="hover-target w-[50vw] md:w-[20vw] opacity-20 hover:opacity-100 transition-opacity duration-700 mb-6 cursor-pointer" onclick="scrollToId('hero')">

                <p class="text-white/40 mt-2 text-sm tracking-[0.3em] font-mono-kjs uppercase text-center">MALANG BADMINTON CLUB</p>

            </footer>


        </div>

    </div>


    <script>

        // 1. PRELOADER

        const preloader = document.getElementById('preloader');

        const counter = document.getElementById('loader-counter');

        const heroImg1 = document.getElementById('hero-img-1');

        let count = 0;

        

        document.body.style.overflow = 'hidden';


        let loaderInterval = setInterval(() => {

            count += Math.floor(Math.random() * 12) + 1;

            if(count >= 100) {

                count = 100;

                clearInterval(loaderInterval);

                setTimeout(() => {

                    preloader.classList.add('hide');

                    document.body.style.overflow = 'auto'; 

                    heroImg1.style.transform = 'scale(1)'; 

                    document.querySelectorAll('.reveal-up').forEach((el, index) => {

                        setTimeout(() => el.classList.add('active'), 100 * index);

                    });

                }, 500);

            }

            counter.innerText = count + '%';

        }, 60);


        // 2. CUSTOM CURSOR & MAGNETIC BTN

        const cursor = document.getElementById('custom-cursor');

        let cursorX = window.innerWidth / 2, cursorY = window.innerHeight / 2;

        let smoothCursorX = cursorX, smoothCursorY = cursorY;


        window.addEventListener('mousemove', (e) => {

            cursorX = e.clientX;

            cursorY = e.clientY;

        });


        document.querySelectorAll('.hover-target, button, a').forEach(el => {

            el.addEventListener('mouseenter', () => document.body.classList.add('hovering'));

            el.addEventListener('mouseleave', () => document.body.classList.remove('hovering'));

        });


        document.querySelectorAll('.magnetic').forEach(btn => {

            const child = btn.querySelector('span') || btn.querySelector('img');

            if(child) {

                btn.addEventListener('mousemove', (e) => {

                    const rect = btn.getBoundingClientRect();

                    const x = e.clientX - rect.left - rect.width / 2;

                    const y = e.clientY - rect.top - rect.height / 2;

                    child.style.transform = `translate(${x * 0.4}px, ${y * 0.4}px)`;

                });

                btn.addEventListener('mouseleave', () => {

                    child.style.transform = `translate(0px, 0px)`;

                    child.style.transition = `transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)`;

                    setTimeout(() => child.style.transition = '', 300);

                });

            }

        });


        // 3. LERP SCROLL

        const body = document.body;

        const smoothContent = document.getElementById('smooth-content');

        const marquee = document.getElementById('marquee');

        const parallaxEls = document.querySelectorAll('[data-speed]');

        

        let currentScroll = 0;

        let targetScroll = 0;

        let ease = 0.08;


        function setBodyHeight() {

            body.style.height = `${smoothContent.getBoundingClientRect().height}px`;

        }

        window.addEventListener('resize', setBodyHeight);

        setInterval(setBodyHeight, 1000); 


        window.addEventListener('scroll', () => {

            targetScroll = window.scrollY;

        });


        function scrollToId(id) {

            const section = document.getElementById(id);

            if(section) {

                window.scrollTo({

                    top: section.offsetTop,

                    behavior: 'smooth'

                });

            }

        }


        // 4. FLOATING EVENT IMAGES

        const hoverPreview = document.getElementById('hover-preview');

        let previewTargetX = 0, previewTargetY = 0;

        let previewCurrentX = 0, previewCurrentY = 0;

        let isPreviewVisible = false;


        document.querySelectorAll('.event-row').forEach(row => {

            row.addEventListener('mouseenter', (e) => {

                hoverPreview.style.backgroundImage = `url('${row.dataset.img}')`;

                hoverPreview.classList.add('show');

                isPreviewVisible = true;

                

                previewCurrentX = e.clientX + 20;

                previewCurrentY = e.clientY - 100;

                hoverPreview.style.transform = `translate(${previewCurrentX}px, ${previewCurrentY}px) scale(1) rotate(4deg)`;

            });

            

            row.addEventListener('mousemove', (e) => {

                previewTargetX = e.clientX + 20;

                previewTargetY = e.clientY - 100;

            });


            row.addEventListener('mouseleave', () => {

                hoverPreview.classList.remove('show');

                isPreviewVisible = false;

            });

        });


        // 5. SPOTLIGHT HERO

        const heroSection = document.getElementById('hero');

        const canvas = document.getElementById('mask-canvas');

        const ctx = canvas.getContext('2d', { willReadFrequently: true });

        const revealLayer = document.getElementById('reveal-layer');

        const SPOTLIGHT_R = 250;

        

        let maskMouseX = -999, maskMouseY = -999;

        let smoothMaskX = -999, smoothMaskY = -999;


        function resizeCanvas() {

            canvas.width = heroSection.offsetWidth;

            canvas.height = heroSection.offsetHeight;

        }

        window.addEventListener('resize', resizeCanvas);

        resizeCanvas();


        heroSection.addEventListener('mousemove', (e) => {

            const rect = heroSection.getBoundingClientRect();

            maskMouseX = e.clientX - rect.left;

            maskMouseY = e.clientY - rect.top;

        });

        heroSection.addEventListener('mouseleave', () => {

            maskMouseX = -999; maskMouseY = -999;

        });


        // 6. RENDER LOOP

        function render() {

            currentScroll += (targetScroll - currentScroll) * ease;

            smoothContent.style.transform = `translate3d(0, -${currentScroll}px, 0)`;


            parallaxEls.forEach(el => {

                let speed = parseFloat(el.getAttribute('data-speed'));

                let yPos = (targetScroll - currentScroll) * speed;

                el.style.transform = `translate3d(0, ${yPos}px, 0)`;

            });


            marquee.style.transform = `translate3d(-${(currentScroll * 0.4) % 1000}px, 0, 0)`;


            document.querySelectorAll('.reveal-up:not(.active)').forEach(el => {

                const rect = el.getBoundingClientRect();

                if(rect.top < window.innerHeight * 0.85) {

                    el.classList.add('active');

                }

            });


            smoothCursorX += (cursorX - smoothCursorX) * 0.2;

            smoothCursorY += (cursorY - smoothCursorY) * 0.2;

            cursor.style.left = `${smoothCursorX}px`;

            cursor.style.top = `${smoothCursorY}px`;


            if(isPreviewVisible) {

                previewCurrentX += (previewTargetX - previewCurrentX) * 0.1;

                previewCurrentY += (previewTargetY - previewCurrentY) * 0.1;

                hoverPreview.style.transform = `translate(${previewCurrentX}px, ${previewCurrentY}px) scale(1) rotate(4deg)`;

            }


            smoothMaskX += (maskMouseX - smoothMaskX) * 0.15;

            smoothMaskY += (maskMouseY - smoothMaskY) * 0.15;

            

            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (Math.abs(smoothMaskX - maskMouseX) > 0.1 || maskMouseX !== -999) {

                const gradient = ctx.createRadialGradient(smoothMaskX, smoothMaskY, 0, smoothMaskX, smoothMaskY, SPOTLIGHT_R);

                gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');

                gradient.addColorStop(0.3, 'rgba(255, 255, 255, 0.9)');

                gradient.addColorStop(0.6, 'rgba(255, 255, 255, 0.5)');

                gradient.addColorStop(0.8, 'rgba(255, 255, 255, 0.1)');

                gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');


                ctx.fillStyle = gradient;

                ctx.beginPath();

                ctx.arc(smoothMaskX, smoothMaskY, SPOTLIGHT_R, 0, Math.PI * 2);

                ctx.fill();


                const dataUrl = canvas.toDataURL();

                revealLayer.style.maskImage = `url(${dataUrl})`;

                revealLayer.style.webkitMaskImage = `url(${dataUrl})`;

            }


            requestAnimationFrame(render);

        }

        render();


        // 7. 3D TILT

        document.querySelectorAll('.js-tilt').forEach(card => {

            card.addEventListener('mousemove', (e) => {

                const rect = card.getBoundingClientRect();

                const x = e.clientX - rect.left - rect.width / 2;

                const y = e.clientY - rect.top - rect.height / 2;

                const rotateX = (y / (rect.height / 2)) * -12; 

                const rotateY = (x / (rect.width / 2)) * 12;

                

                card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.02, 1.02, 1.02)`;

                card.style.zIndex = "50";

            });

            card.addEventListener('mouseleave', () => {

                card.style.transition = 'transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)';

                card.style.transform = `perspective(1000px) rotateX(0) rotateY(0) scale3d(1, 1, 1)`;

                card.style.zIndex = "10";

                setTimeout(() => card.style.transition = '', 500);

            });

        });

    </script>

</body>

</html>