diff --git a/.replit b/.replit index f2319f5..61c4468 100644 --- a/.replit +++ b/.replit @@ -13,7 +13,7 @@ localPort = 5000 externalPort = 80 [[ports]] -localPort = 44245 +localPort = 45659 externalPort = 3000 [agent] @@ -35,10 +35,10 @@ args = "Flask Server" name = "Flask Server" author = "agent" +[workflows.workflow.metadata] +outputType = "webview" + [[workflows.workflow.tasks]] task = "shell.exec" args = "python app.py" waitForPort = 5000 - -[workflows.workflow.metadata] -outputType = "webview" diff --git a/static/css/styles.css b/static/css/styles.css index 8428e06..186f21b 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -31,6 +31,29 @@ body { font-family: var(--font-body); line-height: 1.6; overflow-x: hidden; + position: relative; +} + +body::after { + content: ''; + position: fixed; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: + radial-gradient(circle at 30% 20%, rgba(59, 130, 246, 0.03) 0%, transparent 40%), + radial-gradient(circle at 70% 60%, rgba(139, 92, 246, 0.03) 0%, transparent 40%), + radial-gradient(circle at 50% 80%, rgba(59, 130, 246, 0.02) 0%, transparent 50%); + pointer-events: none; + z-index: 0; + animation: float-background 20s ease-in-out infinite; +} + +@keyframes float-background { + 0%, 100% { transform: translate(0, 0) rotate(0deg); } + 33% { transform: translate(2%, -2%) rotate(1deg); } + 66% { transform: translate(-2%, 2%) rotate(-1deg); } } nav { @@ -41,6 +64,12 @@ nav { z-index: 1000; width: calc(100% - 40px); max-width: 1200px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +nav.scrolled { + top: 10px; + backdrop-filter: blur(20px); } .nav-container { @@ -1192,4 +1221,406 @@ span.emoji:hover::after { .competition-year { margin-top: 25px !important; font-weight: 100 !important; +} + +html { + scroll-behavior: auto; +} + +body { + overflow-x: hidden; + position: relative; +} + +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 50%, rgba(59, 130, 246, 0.05) 0%, transparent 50%), + radial-gradient(circle at 80% 80%, rgba(139, 92, 246, 0.05) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +@keyframes float { + 0%, 100% { transform: translateY(0px); } + 50% { transform: translateY(-20px); } +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +@keyframes shimmer { + 0% { background-position: -200% center; } + 100% { background-position: 200% center; } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(40px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes scaleIn { + from { + opacity: 0; + transform: scale(0.9); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.nav-container { + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.nav-container::before { + content: ''; + position: absolute; + inset: -1px; + border-radius: 16px; + padding: 1px; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.3), rgba(139, 92, 246, 0.3)); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + opacity: 0; + transition: opacity 0.4s ease; +} + +.nav-container:hover::before { + opacity: 1; +} + +.stats-card { + position: relative; + overflow: hidden; +} + +.stats-card::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 45deg, + transparent, + rgba(59, 130, 246, 0.1), + transparent + ); + transform: rotate(45deg); + transition: all 0.6s ease; + opacity: 0; +} + +.stats-card:hover::before { + opacity: 1; + animation: shimmer 2s infinite; +} + +.card, +.card-sponsors, +.member-card { + position: relative; + overflow: hidden; +} + +.card::after, +.card-sponsors::after, +.member-card::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: radial-gradient(circle, rgba(59, 130, 246, 0.15) 0%, transparent 70%); + transform: translate(-50%, -50%); + transition: width 0.6s ease, height 0.6s ease; +} + +.card:hover::after, +.card-sponsors:hover::after, +.member-card:hover::after { + width: 300%; + height: 300%; +} + +.hero-image-section { + position: relative; + overflow: hidden; +} + +.hero-image-section::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), transparent); + z-index: 3; + opacity: 0; + transition: opacity 0.6s ease; +} + +.hero-image-section:hover::before { + opacity: 1; +} + +.stats-button, +.bottom-center-button, +#sponsors-more-button { + position: relative; + overflow: hidden; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.stats-button::before, +.bottom-center-button::before, +#sponsors-more-button::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 70%); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: width 0.4s ease, height 0.4s ease; +} + +.stats-button:hover::before, +.bottom-center-button:hover::before, +#sponsors-more-button:hover::before { + width: 300px; + height: 300px; +} + +.stats-card-header { + background: linear-gradient(135deg, #3b82f6, #8b5cf6); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + background-size: 200% 200%; + animation: gradient-shift 3s ease infinite; +} + +@keyframes gradient-shift { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.heading { + position: relative; + display: inline-block; + width: 100%; +} + +.heading::after { + content: ''; + position: absolute; + bottom: -8px; + left: 50%; + transform: translateX(-50%); + width: 0; + height: 3px; + background: linear-gradient(90deg, transparent, #3b82f6, transparent); + transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1); +} + +.heading:hover::after { + width: 80%; +} + +.robo-card { + cursor: pointer; +} + +.robo-card::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(139, 92, 246, 0.2)); + opacity: 0; + z-index: 1; + transition: opacity 0.4s ease; +} + +.robo-card:hover::before { + opacity: 1; +} + +.competition-card { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.sponsors-card { + position: relative; +} + +.sponsors-card::after { + content: ''; + position: absolute; + inset: -5px; + background: linear-gradient(45deg, #3b82f6, #8b5cf6); + border-radius: 8px; + opacity: 0; + z-index: -1; + filter: blur(20px); + transition: opacity 0.4s ease; +} + +.sponsors-card:hover::after { + opacity: 0.3; +} + +.overlay-container .overlay { + transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); +} + +hr { + position: relative; + overflow: hidden; +} + +hr::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.5), transparent); + animation: shimmer 3s infinite; +} + +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + + html { + scroll-behavior: auto; + } +} + +.member-image { + box-shadow: 0 0 20px rgba(59, 130, 246, 0.3); +} + +.home-but { + position: relative; + overflow: hidden; +} + +.home-but::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(59, 130, 246, 0.3); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: width 0.3s ease, height 0.3s ease; +} + +.home-but:hover::before { + width: 150%; + height: 150%; +} + +.scroll-indicator { + position: fixed; + top: 0; + left: 0; + height: 4px; + background: linear-gradient(90deg, #3b82f6, #8b5cf6); + z-index: 9999; + transform-origin: left; + border-radius: 0 4px 4px 0; +} + +* { + cursor: default; +} + +a, button, .stats-card, .card, .member-card { + cursor: pointer !important; +} + +body { + cursor: none; +} + +.custom-cursor { + width: 20px; + height: 20px; + border: 2px solid #3b82f6; + border-radius: 50%; + position: fixed; + pointer-events: none; + z-index: 10000; + transition: all 0.15s ease; + transform: translate(-50%, -50%); + mix-blend-mode: difference; +} + +.custom-cursor-follower { + width: 40px; + height: 40px; + border: 1px solid rgba(59, 130, 246, 0.3); + border-radius: 50%; + position: fixed; + pointer-events: none; + z-index: 9999; + transition: all 0.3s ease; + transform: translate(-50%, -50%); +} + +.custom-cursor.hover { + width: 50px; + height: 50px; + background: rgba(59, 130, 246, 0.1); +} + +@media (max-width: 850px) { + .custom-cursor, + .custom-cursor-follower { + display: none; + } + + body { + cursor: default; + } +} + +.sub-header, +.hero-title { + background: linear-gradient(135deg, #ffffff, #a0a0a0); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.border-triangle { + display: none; } \ No newline at end of file diff --git a/static/js/scripts.js b/static/js/scripts.js index b1be832..9dd877a 100644 --- a/static/js/scripts.js +++ b/static/js/scripts.js @@ -1,4 +1,62 @@ +let lenis; + document.addEventListener('DOMContentLoaded', function() { + gsap.registerPlugin(ScrollTrigger); + + lenis = new Lenis({ + duration: 1.2, + easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), + smoothWheel: true, + smoothTouch: false, + touchMultiplier: 2, + infinite: false + }); + + function raf(time) { + lenis.raf(time); + requestAnimationFrame(raf); + } + requestAnimationFrame(raf); + + lenis.on('scroll', ScrollTrigger.update); + + gsap.ticker.lagSmoothing(0); + + ScrollTrigger.scrollerProxy(document.body, { + scrollTop(value) { + if (arguments.length) { + lenis.scrollTo(value, { immediate: true }); + } + return lenis.scroll || 0; + }, + getBoundingClientRect() { + return { + top: 0, + left: 0, + width: window.innerWidth, + height: window.innerHeight + }; + }, + pinType: document.body.style.transform ? "transform" : "fixed" + }); + + ScrollTrigger.defaults({ scroller: document.body }); + + ScrollTrigger.addEventListener('refresh', () => lenis.update()); + ScrollTrigger.refresh(); + + let lastScrollTop = 0; + const nav = document.querySelector('nav'); + + lenis.on('scroll', ({ scroll }) => { + if (scroll > 100) { + nav?.classList.add('scrolled'); + } else { + nav?.classList.remove('scrolled'); + } + lastScrollTop = scroll; + }); + const currentPath = window.location.pathname; const navLinks = document.querySelectorAll('.nav-item-center, .nav-item-left'); @@ -30,4 +88,293 @@ document.addEventListener('DOMContentLoaded', function() { this.classList.add('active'); }); }); + + initParallaxEffects(); + initScrollAnimations(); + initMagneticButtons(); + initFloatingElements(); + initPageLoadAnimation(); + initCustomCursor(); + initScrollIndicator(); }); + +function initParallaxEffects() { + const heroImage = document.querySelector('.hero-team-image'); + if (heroImage) { + gsap.to(heroImage, { + yPercent: 30, + ease: "none", + scrollTrigger: { + trigger: heroImage.parentElement, + start: "top top", + end: "bottom top", + scrub: 1 + } + }); + } + + const baseImage = document.querySelector('.overlay-container .base'); + if (baseImage) { + gsap.to(baseImage, { + yPercent: 20, + ease: "none", + scrollTrigger: { + trigger: '.bg', + start: "top top", + end: "bottom top", + scrub: 1.5 + } + }); + } + + const meetTeamImage = document.querySelector('#meet-our-team'); + if (meetTeamImage) { + gsap.to(meetTeamImage, { + yPercent: 15, + ease: "none", + scrollTrigger: { + trigger: '.meet-our-team-container', + start: "top bottom", + end: "bottom top", + scrub: 1 + } + }); + } + + const sponsorCards = document.querySelectorAll('.sponsors-card'); + sponsorCards.forEach((card, index) => { + gsap.to(card, { + y: -30 * (index % 2 === 0 ? 1 : -1), + ease: "none", + scrollTrigger: { + trigger: card, + start: "top bottom", + end: "bottom top", + scrub: 1 + } + }); + }); +} + +function initScrollAnimations() { + const fadeUpElements = document.querySelectorAll('.home-info, .stats-container, .sub-header, .sub-content, .sponsors-container, .hero-image-section, .card, .member-card, .robo-card, .competition-card'); + + fadeUpElements.forEach((element, index) => { + gsap.fromTo(element, + { + opacity: 0, + y: 60 + }, + { + opacity: 1, + y: 0, + duration: 1, + ease: "power3.out", + scrollTrigger: { + trigger: element, + start: "top 85%", + end: "top 60%", + toggleActions: "play none none reverse" + } + } + ); + }); + + const statsCards = document.querySelectorAll('.stats-card'); + statsCards.forEach((card, index) => { + gsap.fromTo(card, + { + opacity: 0, + scale: 0.8, + y: 40 + }, + { + opacity: 1, + scale: 1, + y: 0, + duration: 0.8, + delay: index * 0.1, + ease: "back.out(1.7)", + scrollTrigger: { + trigger: card, + start: "top 85%", + toggleActions: "play none none reverse" + } + } + ); + }); + + const headings = document.querySelectorAll('.heading'); + headings.forEach(heading => { + gsap.fromTo(heading, + { + opacity: 0, + scale: 0.9, + y: 30 + }, + { + opacity: 1, + scale: 1, + y: 0, + duration: 0.8, + ease: "power2.out", + scrollTrigger: { + trigger: heading, + start: "top 90%", + toggleActions: "play none none reverse" + } + } + ); + }); + + const footerText = document.querySelector('.footer-text'); + if (footerText) { + gsap.fromTo(footerText, + { + opacity: 0, + y: 40 + }, + { + opacity: 1, + y: 0, + duration: 1.2, + delay: 0.5, + ease: "power3.out" + } + ); + } +} + +function initMagneticButtons() { + const buttons = document.querySelectorAll('.stats-button, .bottom-center-button, #sponsors-more-button, .home-but'); + + buttons.forEach(button => { + button.addEventListener('mouseenter', function(e) { + gsap.to(button, { + scale: 1.05, + duration: 0.3, + ease: "power2.out" + }); + }); + + button.addEventListener('mouseleave', function(e) { + gsap.to(button, { + scale: 1, + x: 0, + y: 0, + duration: 0.3, + ease: "elastic.out(1, 0.5)" + }); + }); + + button.addEventListener('mousemove', function(e) { + const rect = button.getBoundingClientRect(); + const x = e.clientX - rect.left - rect.width / 2; + const y = e.clientY - rect.top - rect.height / 2; + + gsap.to(button, { + x: x * 0.3, + y: y * 0.3, + duration: 0.3, + ease: "power2.out" + }); + }); + }); +} + +function initFloatingElements() { + const memberCards = document.querySelectorAll('.member-card'); + memberCards.forEach((card, index) => { + gsap.to(card, { + y: -10, + duration: 2 + (index % 3) * 0.5, + repeat: -1, + yoyo: true, + ease: "sine.inOut", + delay: index * 0.2 + }); + }); + + const cards = document.querySelectorAll('.card, .card-sponsors'); + cards.forEach((card, index) => { + gsap.to(card, { + y: -8, + duration: 2.5 + (index % 2) * 0.5, + repeat: -1, + yoyo: true, + ease: "sine.inOut", + delay: index * 0.15 + }); + }); +} + +function initPageLoadAnimation() { + gsap.fromTo('body', + { opacity: 0 }, + { opacity: 1, duration: 0.6, ease: "power2.out" } + ); + + const nav = document.querySelector('nav'); + if (nav) { + gsap.fromTo(nav, + { y: -100, opacity: 0 }, + { y: 0, opacity: 1, duration: 0.8, delay: 0.2, ease: "power3.out" } + ); + } + + const bg = document.querySelector('.bg'); + if (bg) { + gsap.fromTo(bg, + { scale: 1.1, opacity: 0 }, + { scale: 1, opacity: 1, duration: 1.5, ease: "power2.out" } + ); + } +} + +function initCustomCursor() { + if (window.innerWidth <= 850) return; + + const cursor = document.createElement('div'); + cursor.className = 'custom-cursor'; + document.body.appendChild(cursor); + + const follower = document.createElement('div'); + follower.className = 'custom-cursor-follower'; + document.body.appendChild(follower); + + let mouseX = 0, mouseY = 0; + let followerX = 0, followerY = 0; + + document.addEventListener('mousemove', (e) => { + mouseX = e.clientX; + mouseY = e.clientY; + cursor.style.left = mouseX + 'px'; + cursor.style.top = mouseY + 'px'; + }); + + function animateFollower() { + followerX += (mouseX - followerX) * 0.1; + followerY += (mouseY - followerY) * 0.1; + follower.style.left = followerX + 'px'; + follower.style.top = followerY + 'px'; + requestAnimationFrame(animateFollower); + } + animateFollower(); + + const hoverElements = document.querySelectorAll('a, button, .stats-card, .card, .member-card, .robo-card, .sponsors-card'); + hoverElements.forEach(el => { + el.addEventListener('mouseenter', () => cursor.classList.add('hover')); + el.addEventListener('mouseleave', () => cursor.classList.remove('hover')); + }); +} + +function initScrollIndicator() { + const indicator = document.createElement('div'); + indicator.className = 'scroll-indicator'; + document.body.appendChild(indicator); + + lenis.on('scroll', ({ scroll, limit }) => { + const progress = (scroll / limit) * 100; + indicator.style.width = progress + '%'; + }); +} diff --git a/templates/base.html b/templates/base.html index 449ef3e..619a6c9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -7,7 +7,10 @@