| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>A.I. Engineer Portfolio | Cinematic Experience</title> |
| | |
| | |
| | <script src="https://cdn.tailwindcss.com"></script> |
| | <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> |
| | <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> |
| | <script src="https://unpkg.com/lucide@latest"></script> |
| |
|
| | |
| | <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=JetBrains+Mono:wght@100;300;400;700&family=Space+Grotesk:wght@300;500;700&display=swap" rel="stylesheet"> |
| |
|
| | |
| | <script> |
| | tailwind.config = { |
| | theme: { |
| | extend: { |
| | colors: { |
| | void: '#050505', |
| | obsidian: '#0a0a0a', |
| | charcoal: '#1c1c1c', |
| | platinum: '#e5e5e5', |
| | accent: '#ff3333', |
| | }, |
| | fontFamily: { |
| | mono: ['"JetBrains Mono"', 'monospace'], |
| | sans: ['"Space Grotesk"', 'sans-serif'], |
| | }, |
| | backgroundImage: { |
| | 'grid-pattern': "linear-gradient(to right, #1f1f1f 1px, transparent 1px), linear-gradient(to bottom, #1f1f1f 1px, transparent 1px)", |
| | } |
| | } |
| | } |
| | } |
| | </script> |
| |
|
| | <style> |
| | |
| | body { |
| | background-color: #050505; |
| | color: #e5e5e5; |
| | overflow-x: hidden; |
| | cursor: none; |
| | } |
| | |
| | ::selection { |
| | background: #333; |
| | color: #fff; |
| | } |
| | |
| | |
| | ::-webkit-scrollbar { |
| | width: 8px; |
| | } |
| | ::-webkit-scrollbar-track { |
| | background: #0a0a0a; |
| | } |
| | ::-webkit-scrollbar-thumb { |
| | background: #333; |
| | border-radius: 4px; |
| | } |
| | ::-webkit-scrollbar-thumb:hover { |
| | background: #555; |
| | } |
| | |
| | |
| | #cursor { |
| | position: fixed; |
| | top: 0; |
| | left: 0; |
| | width: 20px; |
| | height: 20px; |
| | border: 1px solid rgba(255, 255, 255, 0.5); |
| | border-radius: 50%; |
| | pointer-events: none; |
| | z-index: 9999; |
| | transform: translate(-50%, -50%); |
| | transition: width 0.3s, height 0.3s, background-color 0.3s; |
| | mix-blend-mode: difference; |
| | } |
| | #cursor.hovered { |
| | width: 50px; |
| | height: 50px; |
| | background-color: rgba(255, 255, 255, 0.1); |
| | border-color: transparent; |
| | } |
| | |
| | |
| | .glass-panel { |
| | background: rgba(10, 10, 10, 0.6); |
| | backdrop-filter: blur(12px); |
| | -webkit-backdrop-filter: blur(12px); |
| | border: 1px solid rgba(255, 255, 255, 0.05); |
| | } |
| | |
| | .text-outline { |
| | -webkit-text-stroke: 1px rgba(255, 255, 255, 0.2); |
| | color: transparent; |
| | transition: all 0.5s ease; |
| | } |
| | .text-outline:hover { |
| | color: #fff; |
| | -webkit-text-stroke: 1px #fff; |
| | } |
| | |
| | |
| | .noise-overlay { |
| | position: fixed; |
| | top: 0; |
| | left: 0; |
| | width: 100%; |
| | height: 100%; |
| | pointer-events: none; |
| | z-index: 50; |
| | opacity: 0.05; |
| | 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"); |
| | } |
| | |
| | |
| | #loader { |
| | position: fixed; |
| | top: 0; |
| | left: 0; |
| | width: 100%; |
| | height: 100%; |
| | background: #000; |
| | z-index: 10000; |
| | display: flex; |
| | justify-content: center; |
| | align-items: center; |
| | flex-direction: column; |
| | } |
| | .loader-bar { |
| | width: 0%; |
| | height: 2px; |
| | background: #fff; |
| | margin-top: 20px; |
| | transition: width 0.1s; |
| | } |
| | |
| | |
| | #canvas-container { |
| | position: fixed; |
| | top: 0; |
| | left: 0; |
| | width: 100%; |
| | height: 100%; |
| | z-index: -1; |
| | opacity: 0; |
| | transition: opacity 1.5s ease; |
| | } |
| | </style> |
| | </head> |
| | <body class="font-sans antialiased"> |
| |
|
| | |
| | <div id="loader"> |
| | <div class="font-mono text-xs tracking-[0.5em] text-gray-400">INITIALIZING SYSTEM</div> |
| | <div class="loader-bar" id="loader-bar"></div> |
| | </div> |
| |
|
| | |
| | <div class="noise-overlay"></div> |
| |
|
| | |
| | <div id="cursor"></div> |
| |
|
| | |
| | <div id="canvas-container"></div> |
| |
|
| | |
| | <nav class="fixed top-0 left-0 w-full p-6 flex justify-between items-center z-40 mix-blend-difference"> |
| | <div class="font-mono text-sm font-bold tracking-widest hover-trigger">AI.ENGINEER</div> |
| | <div class="hidden md:flex gap-8 font-mono text-xs tracking-wider"> |
| | <a href="#work" class="hover:text-white transition-colors hover-trigger">WORK</a> |
| | <a href="#research" class="hover:text-white transition-colors hover-trigger">RESEARCH</a> |
| | <a href="#about" class="hover:text-white transition-colors hover-trigger">ABOUT</a> |
| | </div> |
| | <button class="border border-white/20 px-4 py-2 rounded-full font-mono text-xs hover:bg-white hover:text-black transition-all hover-trigger"> |
| | CONTACT |
| | </button> |
| | </nav> |
| |
|
| | |
| | <main class="relative z-10"> |
| |
|
| | |
| | <section class="h-screen w-full flex flex-col justify-center items-center relative px-4"> |
| | <div class="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-[#050505] pointer-events-none"></div> |
| | |
| | <div class="text-center z-10"> |
| | <p class="font-mono text-xs md:text-sm text-gray-400 mb-4 tracking-[0.3em] hero-anim opacity-0 translate-y-10"> |
| | ARTIFICIAL INTELLIGENCE & RESEARCH |
| | </p> |
| | <h1 class="text-5xl md:text-8xl lg:text-9xl font-bold tracking-tighter leading-none mb-6 hero-anim opacity-0 translate-y-10"> |
| | <span class="block bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-600">PRECISION</span> |
| | <span class="block text-outline">ENGINEERING</span> |
| | </h1> |
| | <p class="max-w-xl mx-auto font-light text-gray-400 text-sm md:text-base leading-relaxed hero-anim opacity-0 translate-y-10"> |
| | Architecting the future through neural networks and high-performance algorithms. |
| | </p> |
| | </div> |
| |
|
| | <div class="absolute bottom-10 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 hero-anim opacity-0"> |
| | <span class="font-mono text-[10px] tracking-widest text-gray-500">SCROLL TO EXPLORE</span> |
| | <div class="w-[1px] h-12 bg-gradient-to-b from-white to-transparent"></div> |
| | </div> |
| | </section> |
| |
|
| | |
| | <section id="kpi-section" class="py-32 px-6 md:px-20 relative"> |
| | <div class="absolute top-0 left-0 w-full h-[1px] bg-white/10"></div> |
| | |
| | <div class="flex flex-col md:flex-row justify-between items-end mb-20 border-b border-white/10 pb-8"> |
| | <h2 class="text-4xl md:text-6xl font-bold">SYSTEM METRICS</h2> |
| | <div class="font-mono text-xs text-gray-500 mt-4 md:mt-0"> |
| | REAL-TIME DATA STREAM |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> |
| | |
| | <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> |
| | <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> |
| | <i data-lucide="cpu" class="w-6 h-6"></i> |
| | </div> |
| | <div class="font-mono text-xs text-gray-500 mb-2">MODEL ACCURACY</div> |
| | <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="99.8">0</div> |
| | <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> |
| | <div class="absolute top-0 left-0 h-full w-1/2 bg-white group-hover:w-full transition-all duration-1000 ease-out"></div> |
| | </div> |
| | <p class="text-sm text-gray-400">Optimized for edge deployment and low-latency inference.</p> |
| | </div> |
| |
|
| | |
| | <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> |
| | <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> |
| | <i data-lucide="database" class="w-6 h-6"></i> |
| | </div> |
| | <div class="font-mono text-xs text-gray-500 mb-2">DATA PROCESSED</div> |
| | <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="850">0</div> |
| | <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> |
| | <div class="absolute top-0 left-0 h-full w-0 group-hover:w-full transition-all duration-1000 ease-out delay-200"></div> |
| | </div> |
| | <p class="text-sm text-gray-400">Petabytes of structured and unstructured data analyzed.</p> |
| | </div> |
| |
|
| | |
| | <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> |
| | <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> |
| | <i data-lucide="zap" class="w-6 h-6"></i> |
| | </div> |
| | <div class="font-mono text-xs text-gray-500 mb-2">INFERENCE TIME</div> |
| | <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="12">0</div> |
| | <div class="text-xs text-gray-500 font-mono mb-4">ms</div> |
| | <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> |
| | <div class="absolute top-0 left-0 h-full w-1/3 bg-white group-hover:w-full transition-all duration-1000 ease-out delay-400"></div> |
| | </div> |
| | <p class="text-sm text-gray-400">Achieving sub-15ms response times on consumer hardware.</p> |
| | </div> |
| | </div> |
| | </section> |
| |
|
| | |
| | <section id="work" class="py-32 relative overflow-hidden"> |
| | <div class="container mx-auto px-6"> |
| | <div class="flex flex-col md:flex-row justify-between items-start mb-16"> |
| | <h2 class="text-4xl md:text-6xl font-bold">PROJECTS</h2> |
| | <div class="font-mono text-xs text-gray-500 mt-4 md:mt-0">ARCHIVE: 2023 - 2024</div> |
| | </div> |
| |
|
| | |
| | <div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center"> |
| | |
| | |
| | <div class="order-2 md:order-1 space-y-8"> |
| | <div class="project-trigger group cursor-pointer"> |
| | <div class="flex items-center gap-4 mb-2"> |
| | <span class="font-mono text-xs text-accent">01</span> |
| | <span class="font-mono text-xs text-gray-500">NEURAL INTERFACE</span> |
| | </div> |
| | <h3 class="text-3xl md:text-5xl font-bold group-hover:text-white transition-colors">Brain-Computer Interface</h3> |
| | <p class="text-gray-400 mt-4 leading-relaxed"> |
| | Decoding motor cortex signals in real-time to control robotic prosthetics with millimeter precision. |
| | </p> |
| | </div> |
| |
|
| | <div class="w-full h-[1px] bg-white/10"></div> |
| |
|
| | <div class="project-trigger group cursor-pointer"> |
| | <div class="flex items-center gap-4 mb-2"> |
| | <span class="font-mono text-xs text-accent">02</span> |
| | <span class="font-mono text-xs text-gray-500">GENERATIVE MODEL</span> |
| | </div> |
| | <h3 class="text-3xl md:text-5xl font-bold group-hover:text-white transition-colors">Synthetic Data Fabric</h3> |
| | <p class="text-gray-400 mt-4 leading-relaxed"> |
| | Creating infinite, privacy-compliant datasets for training LLMs and Computer Vision models. |
| | </p> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="order-1 md:order-2 relative h-[600px] w-full border border-white/10 bg-charcoal overflow-hidden group hover-trigger"> |
| | |
| | <div class="absolute inset-0 bg-grid-pattern opacity-20"></div> |
| | <div class="absolute inset-0 flex items-center justify-center"> |
| | <div class="w-64 h-64 border border-white/20 rounded-full animate-[spin_10s_linear_infinite]"></div> |
| | <div class="absolute w-48 h-48 border border-white/10 rotate-45"></div> |
| | <div class="absolute w-32 h-32 bg-white/5 blur-xl rounded-full"></div> |
| | </div> |
| | <div class="absolute bottom-0 left-0 p-8 bg-gradient-to-t from-black to-transparent w-full"> |
| | <span class="font-mono text-xs">FIG 1.1: ARCHITECTURE</span> |
| | </div> |
| | </div> |
| |
|
| | </div> |
| | </div> |
| | </section> |
| |
|
| | |
| | <section id="research" class="py-32 bg-[#0a0a0a] relative"> |
| | <div class="container mx-auto px-6"> |
| | <h2 class="text-4xl md:text-6xl font-bold mb-20 text-center">RESEARCH PAPERS</h2> |
| | |
| | <div class="max-w-4xl mx-auto space-y-4"> |
| | |
| | <div class="research-item group border-b border-white/10 pb-4 cursor-pointer hover:bg-white/5 transition-colors"> |
| | <div class="flex justify-between items-center py-6"> |
| | <h3 class="text-2xl font-bold">Attention Is All You Need (Redux)</h3> |
| | <i data-lucide="chevron-down" class="w-6 h-6 transform transition-transform duration-300"></i> |
| | </div> |
| | <div class="max-h-0 overflow-hidden transition-all duration-500 ease-in-out"> |
| | <div class="pb-8 grid grid-cols-1 md:grid-cols-3 gap-6"> |
| | <div class="md:col-span-2 text-gray-400 text-sm leading-relaxed"> |
| | <p class="mb-4">An exploration into self-attention mechanisms in transformer architectures, optimized for sparse computation.</p> |
| | <ul class="list-disc list-inside text-gray-500 font-mono text-xs space-y-1"> |
| | <li>ArXiv: 2023.10.24</li> |
| | <li>Latex Source Available</li> |
| | <li>Code: GitHub.com/AI-Eng/Transformer</li> |
| | </ul> |
| | </div> |
| | <div class="bg-white/5 p-4 border border-white/10"> |
| | <div class="text-xs font-mono text-gray-500 mb-2">CITATION SCORE</div> |
| | <div class="text-3xl font-bold">142</div> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="research-item group border-b border-white/10 pb-4 cursor-pointer hover:bg-white/5 transition-colors"> |
| | <div class="flex justify-between items-center py-6"> |
| | <h3 class="text-2xl font-bold">Quantum-Classical Hybrid Heuristics</h3> |
| | <i data-lucide="chevron-down" class="w-6 h-6 transform transition-transform duration-300"></i> |
| | </div> |
| | <div class="max-h-0 overflow-hidden transition-all duration-500 ease-in-out"> |
| | <div class="pb-8 grid grid-cols-1 md:grid-cols-3 gap-6"> |
| | <div class="md:col-span-2 text-gray-400 text-sm leading-relaxed"> |
| | <p class="mb-4">Leveraging variational quantum eigensolvers (VQE) to optimize reinforcement learning policies.</p> |
| | </div> |
| | <div class="bg-white/5 p-4 border border-white/10"> |
| | <div class="text-xs font-mono text-gray-500 mb-2">CITATION SCORE</div> |
| | <div class="text-3xl font-bold">89</div> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | </section> |
| |
|
| | |
| | <footer class="py-20 border-t border-white/10 bg-void relative overflow-hidden"> |
| | <div class="container mx-auto px-6 flex flex-col md:flex-row justify-between items-center relative z-10"> |
| | <div class="mb-8 md:mb-0 text-center md:text-left"> |
| | <h2 class="text-2xl font-bold">READY TO COLLABORATE?</h2> |
| | <p class="text-gray-500 font-mono text-sm mt-2">Open for select research partnerships.</p> |
| | </div> |
| | <div class="flex gap-6"> |
| | <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="github" class="w-6 h-6"></i></a> |
| | <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="twitter" class="w-6 h-6"></i></a> |
| | <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="linkedin" class="w-6 h-6"></i></a> |
| | </div> |
| | </div> |
| | <div class="absolute bottom-4 right-6 font-mono text-[10px] text-gray-700"> |
| | Built with anycoder |
| | </div> |
| | </footer> |
| |
|
| | </main> |
| |
|
| | <script> |
| | |
| | lucide.createIcons(); |
| | |
| | |
| | const loader = document.getElementById('loader'); |
| | const loaderBar = document.getElementById('loader-bar'); |
| | const canvasContainer = document.getElementById('canvas-container'); |
| | |
| | let progress = 0; |
| | const interval = setInterval(() => { |
| | progress += Math.random() * 10; |
| | if (progress >= 100) { |
| | progress = 100; |
| | clearInterval(interval); |
| | |
| | gsap.to(loaderBar, { width: '100%', duration: 0.2, onComplete: () => { |
| | gsap.to(loader, { |
| | yPercent: -100, |
| | duration: 1, |
| | ease: "power4.inOut", |
| | onComplete: () => { |
| | canvasContainer.style.opacity = 1; |
| | initAnimations(); |
| | } |
| | }); |
| | }}); |
| | } |
| | loaderBar.style.width = `${progress}%`; |
| | }, 100); |
| | |
| | |
| | |
| | const scene = new THREE.Scene(); |
| | |
| | scene.fog = new THREE.FogExp2(0x050505, 0.002); |
| | |
| | const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); |
| | camera.position.z = 100; |
| | |
| | const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); |
| | renderer.setSize(window.innerWidth, window.innerHeight); |
| | renderer.setPixelRatio(window.devicePixelRatio); |
| | canvasContainer.appendChild(renderer.domElement); |
| | |
| | |
| | const geometry = new THREE.BufferGeometry(); |
| | const count = 3000; |
| | const positions = new Float32Array(count * 3); |
| | const colors = new Float32Array(count * 3); |
| | const sizes = new Float32Array(count); |
| | |
| | const color1 = new THREE.Color(0xffffff); |
| | const color2 = new THREE.Color(0x333333); |
| | |
| | for(let i = 0; i < count; i++) { |
| | |
| | const angle = Math.random() * Math.PI * 2; |
| | const radius = 20 + Math.random() * 80; |
| | const z = (Math.random() - 0.5) * 400; |
| | |
| | positions[i * 3] = Math.cos(angle) * radius; |
| | positions[i * 3 + 1] = Math.sin(angle) * radius; |
| | positions[i * 3 + 2] = z; |
| | |
| | |
| | const mixedColor = Math.random() > 0.5 ? color1 : color2; |
| | colors[i * 3] = mixedColor.r; |
| | colors[i * 3 + 1] = mixedColor.g; |
| | colors[i * 3 + 2] = mixedColor.b; |
| | |
| | sizes[i] = Math.random() * 2; |
| | } |
| | |
| | geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); |
| | geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); |
| | geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1)); |
| | |
| | |
| | const material = new THREE.PointsMaterial({ |
| | size: 0.5, |
| | vertexColors: true, |
| | transparent: true, |
| | opacity: 0.8, |
| | blending: THREE.AdditiveBlending |
| | }); |
| | |
| | const particles = new THREE.Points(geometry, material); |
| | scene.add(particles); |
| | |
| | |
| | const gridHelper = new THREE.GridHelper(200, 50, 0x333333, 0x111111); |
| | gridHelper.position.y = -50; |
| | scene.add(gridHelper); |
| | |
| | |
| | let mouseX = 0; |
| | let mouseY = 0; |
| | let targetX = 0; |
| | let targetY = 0; |
| | |
| | document.addEventListener('mousemove', (event) => { |
| | mouseX = event.clientX - window.innerWidth / 2; |
| | mouseY = event.clientY - window.innerHeight / 2; |
| | }); |
| | |
| | const clock = new THREE.Clock(); |
| | |
| | function animate() { |
| | requestAnimationFrame(animate); |
| | const elapsedTime = clock.getElapsedTime(); |
| | |
| | targetX = mouseX * 0.001; |
| | targetY = mouseY * 0.001; |
| | |
| | |
| | particles.rotation.y += 0.002; |
| | particles.rotation.x += (targetY - particles.rotation.x) * 0.05; |
| | particles.rotation.y += (targetX - particles.rotation.y) * 0.05; |
| | |
| | |
| | const positions = particles.geometry.attributes.position.array; |
| | for(let i = 0; i < count; i++) { |
| | |
| | positions[i * 3 + 2] += 0.5; |
| | |
| | |
| | if(positions[i * 3 + 2] > 150) { |
| | positions[i * 3 + 2] = -250; |
| | } |
| | } |
| | particles.geometry.attributes.position.needsUpdate = true; |
| | |
| | |
| | gridHelper.rotation.y = -mouseX * 0.0002; |
| | |
| | renderer.render(scene, camera); |
| | } |
| | |
| | animate(); |
| | |
| | |
| | window.addEventListener('resize', () => { |
| | camera.aspect = window.innerWidth / window.innerHeight; |
| | camera.updateProjectionMatrix(); |
| | renderer.setSize(window.innerWidth, window.innerHeight); |
| | }); |
| | |
| | |
| | gsap.registerPlugin(ScrollTrigger); |
| | |
| | function initAnimations() { |
| | |
| | const heroTl = gsap.timeline(); |
| | heroTl.to('.hero-anim', { |
| | y: 0, |
| | opacity: 1, |
| | duration: 1, |
| | stagger: 0.2, |
| | ease: "power3.out" |
| | }); |
| | |
| | |
| | gsap.utils.toArray('.counter').forEach(counter => { |
| | const target = parseFloat(counter.getAttribute('data-target')); |
| | gsap.to(counter, { |
| | innerText: target, |
| | duration: 2, |
| | snap: { innerText: 0.1 }, |
| | scrollTrigger: { |
| | trigger: counter, |
| | start: "top 85%", |
| | toggleActions: "play none none reverse" |
| | } |
| | }); |
| | }); |
| | |
| | |
| | gsap.from('.kpi-card', { |
| | y: 50, |
| | opacity: 0, |
| | duration: 1, |
| | stagger: 0.2, |
| | scrollTrigger: { |
| | trigger: '#kpi-section', |
| | start: "top 70%" |
| | } |
| | }); |
| | |
| | |
| | gsap.from('.project-trigger', { |
| | x: -50, |
| | opacity: 0, |
| | duration: 1, |
| | stagger: 0.2, |
| | scrollTrigger: { |
| | trigger: '#work', |
| | start: "top 70%" |
| | } |
| | }); |
| | |
| | |
| | const researchItems = document.querySelectorAll('.research-item'); |
| | researchItems.forEach(item => { |
| | const header = item.querySelector('div.flex'); |
| | const content = item.querySelector('.max-h-0'); |
| | const icon = item.querySelector('i'); |
| | |
| | header.addEventListener('click', () => { |
| | const isOpen = content.style.maxHeight; |
| | |
| | |
| | researchItems.forEach(otherItem => { |
| | otherItem.querySelector('.max-h-0').style.maxHeight = null; |
| | otherItem.querySelector('i').style.transform = 'rotate(0deg)'; |
| | }); |
| | |
| | |
| | if (!isOpen) { |
| | content.style.maxHeight = content.scrollHeight + "px"; |
| | icon.style.transform = 'rotate(180deg)'; |
| | } |
| | }); |
| | }); |
| | } |
| | |
| | |
| | const cursor = document.getElementById('cursor'); |
| | const triggers = document.querySelectorAll('.hover-trigger'); |
| | |
| | document.addEventListener('mousemove', (e) => { |
| | cursor.style.left = e.clientX + 'px'; |
| | cursor.style.top = e.clientY + 'px'; |
| | }); |
| | |
| | triggers.forEach(trigger => { |
| | trigger.addEventListener('mouseenter', () => { |
| | cursor.classList.add('hovered'); |
| | }); |
| | trigger.addEventListener('mouseleave', () => { |
| | cursor.classList.remove('hovered'); |
| | }); |
| | }); |
| | |
| | </script> |
| | </body> |
| | </html> |