diff --git a/app/page.tsx b/app/page.tsx index 9cf903e..4761d44 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -8,7 +8,8 @@ import CrewEligibility from '../src/components/landing/CrewEligibility'; import CrewRewards from '../src/components/landing/CrewRewards'; import MissionCredentials from '../src/components/landing/MissionCredentials'; import PastSponsorsMarquee from '../src/components/landing/PastSponsorsMarquee'; -import PastSpeakers from '../src/components/landing/PastSpeakers'; +import CurrentSpeakers from '../src/components/landing/CurrentSpeakers'; +import OperationTimeline from '../src/components/landing/OperationTimeline'; import CurrentSponsors from '../src/components/landing/CurrentSponsors'; import Footer from '../src/components/shared/Footer'; import JoinMissionControl from '../src/components/landing/JoinMissionControl'; @@ -47,6 +48,7 @@ export default async function LandingPage() {
+
{/* Past Sponsors Marquee */} @@ -54,14 +56,17 @@ export default async function LandingPage() { - {/* Past Speakers Section */} - + {/* Mission Timeline Section */} + + + {/* Current Speakers Section */} + {/* Bento Grid Section */}
- + {/* 1. Mission Brief (Desktop: 2/3 wide, Row 1 Left | Mobile Rank 1) */}
@@ -72,7 +77,7 @@ export default async function LandingPage() {
- @@ -93,7 +98,7 @@ export default async function LandingPage() {
- @@ -121,10 +126,10 @@ export default async function LandingPage() { Receive mission updates, briefings, timelines, and official communications.

- + [ Enter Mission Control ] - + [ View Mission Brief ]
diff --git a/public/inctf/assets/images/current_speakers/speaker1.jpeg b/public/inctf/assets/images/current_speakers/speaker1.jpeg new file mode 100644 index 0000000..23362a4 Binary files /dev/null and b/public/inctf/assets/images/current_speakers/speaker1.jpeg differ diff --git a/public/inctf/assets/images/current_speakers/speaker2.jpeg b/public/inctf/assets/images/current_speakers/speaker2.jpeg new file mode 100644 index 0000000..aa7abe2 Binary files /dev/null and b/public/inctf/assets/images/current_speakers/speaker2.jpeg differ diff --git a/src/components/landing/CurrentSpeakers.tsx b/src/components/landing/CurrentSpeakers.tsx new file mode 100644 index 0000000..6fdcfc5 --- /dev/null +++ b/src/components/landing/CurrentSpeakers.tsx @@ -0,0 +1,149 @@ +'use client'; +import React, { useRef } from 'react'; +import { motion, useInView } from 'framer-motion'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; + +interface Speaker { + name: string; + title: string; + company: string; + image: string; +} + +const speakers: Speaker[] = [ + { + name: 'Speaker Name', + title: 'Their Info', + company: 'EXPERT SPEAKER', + image: '/inctf/assets/images/current_speakers/speaker1.jpeg', + }, + { + name: 'Speaker Name', + title: 'Their Info', + company: 'EXPERT SPEAKER', + image: '/inctf/assets/images/current_speakers/speaker2.jpeg', + }, +]; + +const SpeakerCard: React.FC<{ speaker: Speaker; index: number }> = ({ speaker, index }) => { + const ref = useRef(null); + const isInView = useInView(ref, { once: true }); + + return ( + +
+ +
+
+ + {/* Circular Photo */} +
+
+ {/* Outer gradient ring */} +
+
+ {speaker.name} +
+
+
+
+ + {/* Info */} +
+

+ {speaker.name} +

+

+ {speaker.title} +

+

+ {speaker.company} +

+
+ + {/* Bottom Corner Accents */} +
+
+
+ + ); +}; + +const CurrentSpeakers: React.FC = () => { + const scrollRef = useRef(null); + const titleRef = useRef(null); + const isTitleInView = useInView(titleRef, { once: true }); + + const scroll = (direction: 'left' | 'right') => { + if (scrollRef.current) { + const amount = 320; + scrollRef.current.scrollBy({ + left: direction === 'right' ? amount : -amount, + behavior: 'smooth', + }); + } + }; + + return ( +
+ {/* Section Header */} +
+ +
+

+ [ Expert Speakers ] +

+

+ Current Speakers +

+
+
+ + +
+
+ +
+
+ +
+ {speakers.map((speaker, index) => ( + + ))} +
+
+ ); +}; + +export default CurrentSpeakers; diff --git a/src/components/landing/CurrentSponsors.tsx b/src/components/landing/CurrentSponsors.tsx index b4ab438..71e7bc7 100644 --- a/src/components/landing/CurrentSponsors.tsx +++ b/src/components/landing/CurrentSponsors.tsx @@ -1,34 +1,93 @@ "use client"; import React from 'react'; - -const sponsors = [ - { name: 'NIQ', logo: '/inctf/assets/images/current_sponsors/NIQ-logo-bright-blue-web.png' }, - { name: 'Tata Consultancy Services', logo: '/inctf/assets/images/current_sponsors/Tata_Consultancy_Services_old_logo.svg.png' } -]; +import { motion } from 'framer-motion'; const CurrentSponsors = () => { return ( -
-
- Official Sponsors: -
-
- {sponsors.map((sponsor) => ( -
- {`${sponsor.name} +
+
+ + {/* Tactical Card Container - Enhanced Blue Visibility */} +
+ + {/* Static Red Corner Brackets - Enhanced Vibrancy & Glow */} +
+
+
+
+ + {/* Top Accent Strip - More Vibrant with Glow */} +
+ +
+ {/* Primary Section Label - Matching Past Sponsors Style */} +
+
+

+ Our Current Sponsors +

+
+
+ + {/* Powered By Section */} +
+
+ Powered By +
+ + Tata Consultancy Services Logo + +
+ + {/* Tactical Divider */} +
+
+
+
+
+ + {/* Co-Powered By Section */} +
+
+ Co-Powered By +
+ + NIQ Logo + +
+ +
+ + {/* Background Data Matrix (Very Subtle) */} +
- ))} +
-
+
); }; diff --git a/src/components/landing/Header.tsx b/src/components/landing/Header.tsx index bc90419..1f58fa9 100644 --- a/src/components/landing/Header.tsx +++ b/src/components/landing/Header.tsx @@ -257,6 +257,7 @@ const LandingHeader = () => { const seconds = Math.floor((diff % (1000 * 60)) / 1000); setTimeLeft({ days, hours, minutes, seconds }); + }, 1000); return () => clearInterval(interval); @@ -297,7 +298,7 @@ const LandingHeader = () => { initial={{ opacity: 0, x: -50 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.8 }} - className="w-full lg:w-1/2 flex flex-col items-start ml-4 mt-[-10px] sm:mt-[-20px] lg:mt-[-50px]" + className="w-full lg:w-3/5 flex flex-col items-start mt-12 lg:-mt-12 xl:-mt-16 ml-4 md:ml-0" > {/* Mission Alert Status */} { {/* Textbox and Buttons Container */} -
+
{/* Content Box with Border */} - -

+ +

- +

{/* 3-Stat Strip */} -
+
₹5L Prize Pool
|
Open to UG Students
@@ -333,9 +334,11 @@ const LandingHeader = () => {
Teams of 1-5
- {/* Countdown Timer */} -
+ {/* Countdown Timer (Commented Out) */} + {/* +
[ REGISTRATION CLOSES IN ]
+
{Object.entries(timeLeft).map(([label, value]) => (
@@ -361,7 +364,6 @@ const LandingHeader = () => { className="bg-red-950/40 hover:bg-red-600 text-alert-crimson hover:text-white font-mono text-sm sm:text-base font-bold tracking-wider px-9 py-3 sm:px-14 sm:py-3.5 rounded-md border-2 border-alert-crimson hover:border-red-600 shadow-[0_0_12px_rgba(244,63,94,0.3)] hover:shadow-[0_0_20px_rgba(244,63,94,0.6)] transition-all duration-300 flex items-center justify-center uppercase mt-1 register-btn opacity-70 hover:opacity-100" onClick={(event) => trackRegisterClick(event, { - ctaLocation: 'countdown', url: 'https://register.inctf.in', }) } @@ -370,65 +372,65 @@ const LandingHeader = () => {
+ */} {/* Value Prop Cards Grid - Replacing Description */} -
+
{[ - { icon: , title: "₹5 Lakh Prize Pool", desc: "Top teams win cash in final phase" }, - { icon: , title: "Internship Oppurtunities", desc: "Skills-first hiring exposure to tech firms" }, - { icon: , title: "Real-World Training", desc: "Hands-on scenarios built by practitioners" }, - { icon: , title: "Certified & Recognized", desc: "Spotlight for finalists & National Cert for all" } + { icon: , title: "₹5 Lakh Prize Pool" }, + { icon: , title: "Internship Oppurtunities" }, + { icon: , title: "Real-World Training" }, + { icon: , title: "Certified & Recognized" } ].map((prop, index) => ( -
+
{prop.icon}
-

+

{prop.title}

-

- {prop.desc} -

))}
- {/* Card Sponsors Footer */} -
-
Powered by TCS & Co-Powered by NIQ
-
- - TCS Logo - -
- - NIQ Logo - + {/* Card Sponsors Footer (Moved to page body) */} + {/* +
+
Powered by TCS & Co-Powered by NIQ
+
+ */} -
+
{
-
- - + {/* Relocated Sponsors Row */} +
{/* Rotating HUD Rings */}
@@ -495,10 +496,10 @@ const LandingHeader = () => { transition={{ duration: 1.2, delay: 0.5 }} className="relative z-10 floating md:static absolute inset-0 md:inset-auto flex justify-center items-center pointer-events-none md:pointer-events-auto mt-0" > - InCTF Satellite { />
+ {/* Scroll to Explore */}
gsap.to(window, { duration: 0.8, scrollTo: { y: "#mission-grid", offsetY: 240 }, ease: "power2.inOut" })} diff --git a/src/components/landing/JoinMissionControl.tsx b/src/components/landing/JoinMissionControl.tsx index 951e6e4..08df192 100644 --- a/src/components/landing/JoinMissionControl.tsx +++ b/src/components/landing/JoinMissionControl.tsx @@ -31,7 +31,7 @@ const JoinMissionControl = () => { whileHover={{ scale: 1.03, boxShadow: "0 0 40px rgba(244,63,94,0.6), 4px 4px 0 rgba(255,255,255,0.7)" }} whileTap={{ scale: 0.95 }} style={{ boxShadow: "4px 4px 0 rgba(255,255,255,0.5)" }} - className="px-8 py-4 bg-gradient-to-br from-red-900 to-red-800 border-2 border-white/60 text-white font-mono font-bold text-lg tracking-wide rounded" + className="px-16 py-6 bg-gradient-to-br from-red-900 to-red-800 border-2 border-white/60 text-white font-mono font-bold text-lg tracking-wide rounded" > [ Enter Mission Control ] @@ -42,7 +42,7 @@ const JoinMissionControl = () => { whileHover={{ scale: 1.03, boxShadow: "0 0 40px rgba(244,63,94,0.6), 4px 4px 0 rgba(255,255,255,0.7)" }} whileTap={{ scale: 0.95 }} style={{ boxShadow: "4px 4px 0 rgba(255,255,255,0.5)" }} - className="px-8 py-4 bg-gradient-to-br from-red-900 to-red-800 border-2 border-white/60 text-white font-mono font-bold text-lg tracking-wide rounded" + className="px-16 py-6 bg-gradient-to-br from-red-900 to-red-800 border-2 border-white/60 text-white font-mono font-bold text-lg tracking-wide rounded" > [ View Mission Brief ] diff --git a/src/components/landing/OperationTimeline.tsx b/src/components/landing/OperationTimeline.tsx new file mode 100644 index 0000000..8d258b4 --- /dev/null +++ b/src/components/landing/OperationTimeline.tsx @@ -0,0 +1,225 @@ +'use client'; +import React from 'react'; +import { motion } from 'framer-motion'; +import { Calendar, Target, Trophy, MousePointer2, ChevronRight, ChevronDown } from 'lucide-react'; + +const timelineEvents = [ + { + date: "APR 01 - APR 31", + title: "Masterclass", + description: "Talks + training + mock CTF", + icon: , + status: "ready", + coords: "01.04" + }, + { + date: "MAY 09 / 10", + title: "Qualifiers", + description: "Online jeopardy round", + icon: , + status: "locked", + coords: "09.05" + }, + { + date: "JULY", + title: "Finals", + description: "On-site competition", + icon: , + status: "final", + coords: "07.26" + } +]; + +const RedReticleOverlay = () => ( +
+ {/* Red Corners */} +
+
+
+
+
+); + +const OperationTimeline = () => { + return ( +
+ {/* HUD Scanlines */} +
+
+
+ + {/* Atmospheric Grid Overlay */} +
+ +
+
+ +

+ [ Operation Milestones ] +

+

+ Mission Timeline +

+
+
+
+ +
+ {/* Energy Conduit SVG Line */} +
+ + {/* Base Line */} + + + {/* Moving Pulse 1 */} + + + {/* Moving Pulse 2 (Secondary) */} + + + +
+ +
+ {/* Card Flow Arrows (Red) - Visible on desktop only */} +
+ + + + + +
+
+ + + + + +
+ + {timelineEvents.map((event, index) => ( + + {/* Node with Reticle */} +
+
+ {/* Interior Scanlines */} +
+ +
+ {event.icon} +
+ +
+ + +
+ + {/* Glassmorphic Tactical Card */} +
+ + {/* Hover Glow Effect */} +
+ + {/* Top Detail Rail */} +
+ SYSTEM_{event.status} +
+ +
+
+ + {event.date} +
+

+ {event.title} +

+

+ {event.description} +

+
+ + {/* Bottom Digital Artifacts */} +
+
+
+
+
+
+
+ + {/* Mobile Connector with Downward Chevrons - Enlarged with Gap */} + {index < timelineEvents.length - 1 && ( +
+
+ + + + +
+
+ )} +
+ ))} +
+
+
+ + +
+ ); +}; + +export default OperationTimeline; diff --git a/src/components/shared/TopBar/index.tsx b/src/components/shared/TopBar/index.tsx index 8bb2d8f..d8b1f1b 100644 --- a/src/components/shared/TopBar/index.tsx +++ b/src/components/shared/TopBar/index.tsx @@ -315,7 +315,6 @@ const TopBar = ({ UTMSource = null }) => { target="_blank" onClick={(event) => { trackRegisterClick(event, { - ctaLocation: 'top_bar', url: topbarConfig?.CTA?.link, }); }} @@ -357,7 +356,6 @@ const TopBar = ({ UTMSource = null }) => { className="px-3 py-1 border border-alert-crimson bg-alert-crimson/10 text-alert-crimson font-bold uppercase tracking-wider text-xs rounded-none hover:bg-alert-crimson hover:text-white transition-all duration-300" onClick={(event) => { trackRegisterClick(event, { - ctaLocation: 'top_bar_mobile', url: topbarConfig.CTA.link, }); }} diff --git a/src/utils/trackRegisterClick.ts b/src/utils/trackRegisterClick.ts index 6300bb4..9366869 100644 --- a/src/utils/trackRegisterClick.ts +++ b/src/utils/trackRegisterClick.ts @@ -1,8 +1,8 @@ import type { MouseEvent } from 'react'; type RegisterClickOptions = { - ctaLocation: string; url: string; + ctaLocation?: string; target?: '_blank' | '_self'; }; @@ -10,7 +10,7 @@ const NAVIGATION_FALLBACK_DELAY_MS = 500; export function trackRegisterClick( event: MouseEvent, - { ctaLocation, url, target = '_blank' }: RegisterClickOptions, + { url, ctaLocation = 'general', target = '_blank' }: RegisterClickOptions, ) { if (typeof window === 'undefined') { return; @@ -48,9 +48,9 @@ export function trackRegisterClick( }; window.gtag('event', 'register_cta_click', { - cta_location: ctaLocation, transport_type: 'beacon', event_callback: navigateOnce, + cta_location: ctaLocation, }); window.setTimeout(navigateOnce, NAVIGATION_FALLBACK_DELAY_MS);