Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import MissionBrief from '../src/components/landing/MissionBrief';
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 PastSponsorsTable from '../src/components/landing/PastSponsorsTable';
import CurrentSpeakers from '../src/components/landing/CurrentSpeakers';
import OperationTimeline from '../src/components/landing/OperationTimeline';
import CurrentSponsors from '../src/components/landing/CurrentSponsors';
Expand Down Expand Up @@ -51,10 +51,6 @@ export default async function LandingPage() {
<CurrentSponsors />
</section>

{/* Past Sponsors Marquee */}
<section className="relative z-10 w-full overflow-hidden bg-obsidian border-t border-sky-digital/20">
<PastSponsorsMarquee />
</section>

{/* Mission Timeline Section */}
<OperationTimeline />
Expand Down Expand Up @@ -141,6 +137,9 @@ export default async function LandingPage() {
</div>
</section>

{/* Past Sponsors */}
<PastSponsorsTable />

{/* Footer */}
<Footer />
</div>
Expand Down
204 changes: 171 additions & 33 deletions src/components/landing/CurrentSpeakers.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,50 @@
'use client';
import React, { useRef } from 'react';
import { motion, useInView } from 'framer-motion';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { ChevronLeft, ChevronRight, X } from 'lucide-react';
import gsap from 'gsap';
import { useGSAP } from '@gsap/react';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

if (typeof window !== 'undefined') {
gsap.registerPlugin(ScrollTrigger);
}

interface Speaker {
name: string;
title: string;
company: string;
image: string;
bio?: string;
}

const speakers: Speaker[] = [
{
name: 'Speaker Name',
title: 'Their Info',
company: 'EXPERT SPEAKER',
image: '/inctf/assets/images/current_speakers/speaker1.jpeg',
name: 'Sreepriya C',
title: '101 to Product Security Incident Response (PSIRT)',
company: 'Siemens',
image: '/inctf/assets/images/current_speakers/Sreepriya_C.jpeg',
bio: `Sreepriya Chalakkal is a Product Security Incident Response Team (PSIRT) engineer at Siemens, where she works on vulnerability handling and securing large-scale industrial and enterprise systems. Her expertise spans telecommunication security, protocol analysis, and real-world network infrastructures.\n\nPrior to this, she worked as a security researcher at ERNW GmbH, focusing on mobile and telecom security, including technologies like VoLTE and core network protocols.\n\nShe is a former core member and mentor of team bi0s and a strong advocate for diversity in cybersecurity. She founded Team Shakti and is a key organizer of ShaktiCon, contributing to building a more inclusive global security community.`
},
{
name: 'Speaker Name',
title: 'Their Info',
company: 'EXPERT SPEAKER',
image: '/inctf/assets/images/current_speakers/speaker2.jpeg',
name: 'Abhishek JM',
title: 'Lead Security Engineer at CRED',
company: 'Cred',
image: '/inctf/assets/images/current_speakers/Abhishek_JM.jpeg',
bio: `Abhishek JM is a Lead Security Engineer at CRED, specializing in mobile security and application security for large-scale fintech systems. He is also a trainer at 7ASecurity, where he has delivered hands-on training at global conferences including OWASP AppSec New Zealand, 44Con, and ThreatCon.\n\nWith extensive experience in offensive security, Abhishek leads security research projects such as Adhrit and EVABS, focusing on advanced mobile and application security testing. His work has been presented at premier venues like Black Hat (Asia, US, Europe) and OWASP Seasides, with his tool Adhrit gaining industry recognition.\n\nHe is an active contributor to the security community, regularly speaking at conferences and meetups, and has also served as a trainer for international security programs, helping mentor the next generation of cybersecurity professionals.`
},
];

const SpeakerCard: React.FC<{ speaker: Speaker; index: number }> = ({ speaker, index }) => {
const ref = useRef<HTMLDivElement>(null);
const isInView = useInView(ref, { once: true });
const SpeakerCard: React.FC<{ speaker: Speaker; index: number; onClick: () => void }> = ({ speaker, index, onClick }) => {
const isClickable = !!speaker.bio;

return (
<motion.div
ref={ref}
className="flex-shrink-0 w-[85vw] sm:w-72 md:w-80 snap-center group"
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: index * 0.1, ease: 'easeOut' }}
<div
className={`speaker-card flex-shrink-0 w-[85vw] sm:w-72 md:w-80 snap-center group opacity-0 ${isClickable ? 'cursor-pointer' : 'cursor-default'}`}
onClick={isClickable ? onClick : undefined}
>
<div className="relative h-full min-h-[380px] md:min-h-[440px] rounded-lg overflow-hidden border border-sky-400/20 bg-slate-900/60 backdrop-blur-sm transition-all duration-300 group-hover:border-sky-400/80 group-hover:shadow-[0_0_25px_rgba(56,189,248,0.2)] p-5 md:p-8 flex flex-col items-center text-center">
<div className={`relative h-full min-h-[380px] md:min-h-[440px] rounded-lg overflow-hidden border border-sky-400/20 bg-slate-900/40 backdrop-blur-sm transition-all duration-300 p-5 md:p-8 flex flex-col items-center text-center ${isClickable ? 'group-hover:border-sky-400/80 group-hover:shadow-[0_0_25px_rgba(56,189,248,0.15)]' : ''
}`}>

<div className="absolute top-0 left-0 w-4 h-4 border-t-2 border-l-2 border-sky-400 z-10" />
<div className="absolute top-0 right-0 w-4 h-4 border-t-2 border-r-2 border-sky-400 z-10" />
Expand Down Expand Up @@ -69,20 +76,80 @@ const SpeakerCard: React.FC<{ speaker: Speaker; index: number }> = ({ speaker, i
<p className="font-mono text-sky-400 text-xs md:text-sm font-semibold tracking-wide mt-auto">
{speaker.company}
</p>
{isClickable && (
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<span className="font-mono text-[9px] text-sky-400 border border-sky-400/30 px-3 py-1 rounded-full uppercase tracking-widest">
View Intel
</span>
</div>
)}
</div>

{/* Bottom Corner Accents */}
<div className="absolute bottom-0 left-0 w-4 h-4 border-b-2 border-l-2 border-sky-400/50 z-10" />
<div className="absolute bottom-0 right-0 w-4 h-4 border-b-2 border-r-2 border-sky-400/50 z-10" />
</div>
</motion.div>
</div>
);
};

const CurrentSpeakers: React.FC = () => {
const containerRef = useRef<HTMLDivElement>(null);
const scrollRef = useRef<HTMLDivElement>(null);
const titleRef = useRef<HTMLDivElement>(null);
const isTitleInView = useInView(titleRef, { once: true });
const [selectedSpeaker, setSelectedSpeaker] = React.useState<Speaker | null>(null);

useGSAP(() => {
if (!containerRef.current) return;

const tl = gsap.timeline({
scrollTrigger: {
trigger: containerRef.current,
start: 'top 85%',
toggleActions: 'play none none none'
}
});

// Animate Title
tl.fromTo('.speakers-header',
{ opacity: 0, y: 30 },
{ opacity: 1, y: 0, duration: 0.8, ease: 'power3.out' }
);

// Stagger Cards
tl.fromTo('.speaker-card',
{
opacity: 0,
y: 40,
scale: 0.95
},
{
opacity: 1,
y: 0,
scale: 1,
duration: 0.8,
stagger: 0.1,
ease: 'power3.out'
},
'-=0.6'
);
}, { scope: containerRef });

React.useEffect(() => {
const header = document.querySelector('header');
if (selectedSpeaker) {
document.body.style.overflow = 'hidden';
if (window.innerWidth <= 768 && header) {
header.style.display = 'none';
}
} else {
document.body.style.overflow = 'unset';
if (header) header.style.display = 'flex';
}
return () => {
document.body.style.overflow = 'unset';
if (header) header.style.display = 'flex';
};
}, [selectedSpeaker]);

const scroll = (direction: 'left' | 'right') => {
if (scrollRef.current) {
Expand All @@ -95,15 +162,10 @@ const CurrentSpeakers: React.FC = () => {
};

return (
<section className="relative z-10 w-full py-16 md:py-24 overflow-hidden">
<section className="relative z-10 w-full py-16 md:py-24 overflow-hidden" ref={containerRef}>
{/* Section Header */}
<div ref={titleRef} className="px-6 md:px-16 mb-10 md:mb-16">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isTitleInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5 }}
className="flex flex-row items-end justify-between gap-2"
>
<div className="speakers-header px-6 md:px-16 mb-10 md:mb-16 opacity-0">
<div className="flex flex-row items-end justify-between gap-2">
<div>
<p className="font-mono text-sky-400 text-xs tracking-[0.3em] uppercase mb-3">
[ Expert Speakers ]
Expand All @@ -128,7 +190,7 @@ const CurrentSpeakers: React.FC = () => {
<ChevronRight size={20} />
</button>
</div>
</motion.div>
</div>

<div className="mt-6 h-[1px] w-full bg-gradient-to-r from-sky-400/60 via-sky-400/20 to-transparent" />
</div>
Expand All @@ -139,9 +201,85 @@ const CurrentSpeakers: React.FC = () => {
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none', WebkitOverflowScrolling: 'touch' }}
>
{speakers.map((speaker, index) => (
<SpeakerCard key={`${speaker.name}-${index}`} speaker={speaker} index={index} />
<SpeakerCard
key={`${speaker.name}-${index}`}
speaker={speaker}
index={index}
onClick={() => setSelectedSpeaker(speaker)}
/>
))}
</div>

{/* Speaker Bio Modal */}
<AnimatePresence>
{selectedSpeaker && (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 sm:p-6 md:p-10 text-left">
{/* Backdrop */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={() => setSelectedSpeaker(null)}
className="absolute inset-0 bg-black/90 backdrop-blur-xl"
/>

{/* Modal Content */}
<motion.div
initial={{ opacity: 0, scale: 0.95, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 20 }}
className="relative w-full max-w-4xl bg-slate-900 border border-sky-400/30 rounded-lg overflow-y-auto md:overflow-hidden shadow-[0_0_80px_rgba(0,0,0,0.8),0_0_30px_rgba(56,189,248,0.1)] flex flex-col md:flex-row max-h-[90vh] md:max-h-[85vh]"
>
{/* Tactical Accents */}
<div className="absolute top-0 left-0 w-8 h-8 border-t-2 border-l-2 border-sky-400 m-4 z-10" />
<div className="absolute bottom-0 right-0 w-8 h-8 border-b-2 border-r-2 border-sky-400 m-4 z-10" />

<button
onClick={() => setSelectedSpeaker(null)}
className="absolute top-6 right-6 z-20 p-2 text-sky-400 hover:text-white hover:bg-sky-400/20 transition-all rounded-md"
>
<X size={24} />
</button>

{/* Left Side: Photo & Quick Info */}
<div className="w-full md:w-1/3 bg-slate-950 p-8 flex flex-col items-center justify-center border-b md:border-b-0 md:border-r border-sky-400/20">
<div className="relative w-32 h-32 md:w-48 md:h-48 mb-6">
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-sky-400 via-purple-500 to-pink-500 p-[3px]">
<div className="w-full h-full rounded-full bg-slate-900 p-[2px]">
<img
src={selectedSpeaker.image}
alt={selectedSpeaker.name}
className="w-full h-full rounded-full object-cover grayscale hover:grayscale-0 transition-all duration-500"
/>
</div>
</div>
</div>
<h4 className="text-white font-heading font-bold text-xl md:text-2xl text-center mb-1 uppercase">
{selectedSpeaker.name}
</h4>
<p className="text-sky-400 font-mono text-sm uppercase tracking-widest text-center mb-4">
{selectedSpeaker.company}
</p>
<div className="h-px w-24 bg-sky-400/30" />
</div>

{/* Right Side: Bio & Mission Intel */}
<div className="w-full md:w-2/3 p-8 md:p-12 overflow-y-auto">
<div className="mb-8">
<h5 className="text-white font-heading text-lg md:text-xl font-semibold mb-6 uppercase tracking-wider border-b border-sky-400/10 pb-4">
{selectedSpeaker.title}
</h5>
<div className="prose prose-invert max-w-none">
<p className="text-white/80 font-mono text-sm leading-relaxed whitespace-pre-line mb-4">
{selectedSpeaker.bio}
</p>
</div>
</div>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
</section>
);
};
Expand Down
31 changes: 28 additions & 3 deletions src/components/landing/CurrentSponsors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const CurrentSponsors = () => {
return (
<section className="py-8 bg-transparent relative z-20">
<div className="container mx-auto px-4 flex justify-center">
<motion.div
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
Expand All @@ -15,7 +15,7 @@ const CurrentSponsors = () => {
>
{/* Tactical Card Container - Enhanced Blue Visibility */}
<div className="relative overflow-hidden bg-slate-950/40 backdrop-blur-xl border border-sky-400/50 rounded-2xl p-8 md:p-12 shadow-[0_0_50px_rgba(0,0,0,0.5),0_0_20px_rgba(56,189,248,0.1)]">

{/* Static Red Corner Brackets - Enhanced Vibrancy & Glow */}
<div className="absolute top-0 left-0 w-8 h-8 border-t-2 border-l-2 border-red-600 shadow-[0_0_10px_rgba(220,38,38,0.4)]" />
<div className="absolute top-0 right-0 w-8 h-8 border-t-2 border-r-2 border-red-600 shadow-[0_0_10px_rgba(220,38,38,0.4)]" />
Expand All @@ -34,7 +34,7 @@ const CurrentSponsors = () => {
</h3>
<div className="h-[1px] w-12 md:w-20 bg-gradient-to-l from-transparent to-sky-400 opacity-50"></div>
</div>

{/* Powered By Section */}
<div className="flex flex-col items-center gap-6 w-full">
<div className="text-white/60 font-mono text-xs uppercase tracking-[0.25em] mb-1">
Expand Down Expand Up @@ -80,6 +80,31 @@ const CurrentSponsors = () => {
</a>
</div>


<div className="flex items-center gap-4 w-full opacity-20">
<div className="h-px flex-grow bg-gradient-to-r from-transparent to-sky-digital" />
<div className="w-2 h-2 rotate-45 border border-sky-digital" />
<div className="h-px flex-grow bg-gradient-to-l from-transparent to-sky-digital" />
</div>

{/* Organizing Partner Section */}
<div className="flex flex-col items-center gap-6 w-full">
<div className="text-white/60 font-mono text-xs uppercase tracking-[0.25em] mb-1">
Organizing Partner
</div>
<a
href="https://traboda.com/"
target="_blank"
rel="noopener noreferrer"
className="transition-all duration-500 hover:scale-105 filter drop-shadow-[0_0_15px_rgba(255,255,255,0.1)]"
>
<img
src="/inctf/assets/images/conference/logos/traboda_light.png"
alt="Traboda CyberLabs Logo"
className="h-10 md:h-16 w-auto object-contain brightness-0 invert opacity-90 hover:opacity-100 transition-opacity"
/>
</a>
</div>
</div>

{/* Background Data Matrix (Very Subtle) */}
Expand Down
Loading
Loading