Skip to content

Commit 07ca99f

Browse files
Merge pull request #60 from traboda/develop
Landing page content fixes
2 parents 681b6df + 8dd965a commit 07ca99f

8 files changed

Lines changed: 347 additions & 111 deletions

File tree

app/page.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import MissionBrief from '../src/components/landing/MissionBrief';
77
import CrewEligibility from '../src/components/landing/CrewEligibility';
88
import CrewRewards from '../src/components/landing/CrewRewards';
99
import MissionCredentials from '../src/components/landing/MissionCredentials';
10-
import PastSponsorsMarquee from '../src/components/landing/PastSponsorsMarquee';
10+
import PastSponsorsTable from '../src/components/landing/PastSponsorsTable';
1111
import CurrentSpeakers from '../src/components/landing/CurrentSpeakers';
1212
import OperationTimeline from '../src/components/landing/OperationTimeline';
1313
import CurrentSponsors from '../src/components/landing/CurrentSponsors';
@@ -51,10 +51,6 @@ export default async function LandingPage() {
5151
<CurrentSponsors />
5252
</section>
5353

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

5955
{/* Mission Timeline Section */}
6056
<OperationTimeline />
@@ -141,6 +137,9 @@ export default async function LandingPage() {
141137
</div>
142138
</section>
143139

140+
{/* Past Sponsors */}
141+
<PastSponsorsTable />
142+
144143
{/* Footer */}
145144
<Footer />
146145
</div>

public/inctf/assets/images/current_speakers/speaker2.jpeg renamed to public/inctf/assets/images/current_speakers/Abhishek_JM.jpeg

File renamed without changes.

public/inctf/assets/images/current_speakers/speaker1.jpeg renamed to public/inctf/assets/images/current_speakers/Sreepriya_C.jpeg

File renamed without changes.

src/components/landing/CurrentSpeakers.tsx

Lines changed: 171 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,50 @@
11
'use client';
22
import React, { useRef } from 'react';
3-
import { motion, useInView } from 'framer-motion';
4-
import { ChevronLeft, ChevronRight } from 'lucide-react';
3+
import { motion, AnimatePresence } from 'framer-motion';
4+
import { ChevronLeft, ChevronRight, X } from 'lucide-react';
5+
import gsap from 'gsap';
6+
import { useGSAP } from '@gsap/react';
7+
import { ScrollTrigger } from 'gsap/ScrollTrigger';
8+
9+
if (typeof window !== 'undefined') {
10+
gsap.registerPlugin(ScrollTrigger);
11+
}
512

613
interface Speaker {
714
name: string;
815
title: string;
916
company: string;
1017
image: string;
18+
bio?: string;
1119
}
1220

1321
const speakers: Speaker[] = [
1422
{
15-
name: 'Speaker Name',
16-
title: 'Their Info',
17-
company: 'EXPERT SPEAKER',
18-
image: '/inctf/assets/images/current_speakers/speaker1.jpeg',
23+
name: 'Sreepriya C',
24+
title: '101 to Product Security Incident Response (PSIRT)',
25+
company: 'Siemens',
26+
image: '/inctf/assets/images/current_speakers/Sreepriya_C.jpeg',
27+
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.`
1928
},
2029
{
21-
name: 'Speaker Name',
22-
title: 'Their Info',
23-
company: 'EXPERT SPEAKER',
24-
image: '/inctf/assets/images/current_speakers/speaker2.jpeg',
30+
name: 'Abhishek JM',
31+
title: 'Lead Security Engineer at CRED',
32+
company: 'Cred',
33+
image: '/inctf/assets/images/current_speakers/Abhishek_JM.jpeg',
34+
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.`
2535
},
2636
];
2737

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

3241
return (
33-
<motion.div
34-
ref={ref}
35-
className="flex-shrink-0 w-[85vw] sm:w-72 md:w-80 snap-center group"
36-
initial={{ opacity: 0, y: 30 }}
37-
animate={isInView ? { opacity: 1, y: 0 } : {}}
38-
transition={{ duration: 0.5, delay: index * 0.1, ease: 'easeOut' }}
42+
<div
43+
className={`speaker-card flex-shrink-0 w-[85vw] sm:w-72 md:w-80 snap-center group opacity-0 ${isClickable ? 'cursor-pointer' : 'cursor-default'}`}
44+
onClick={isClickable ? onClick : undefined}
3945
>
40-
<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">
46+
<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)]' : ''
47+
}`}>
4148

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

7488
{/* Bottom Corner Accents */}
7589
<div className="absolute bottom-0 left-0 w-4 h-4 border-b-2 border-l-2 border-sky-400/50 z-10" />
7690
<div className="absolute bottom-0 right-0 w-4 h-4 border-b-2 border-r-2 border-sky-400/50 z-10" />
7791
</div>
78-
</motion.div>
92+
</div>
7993
);
8094
};
8195

8296
const CurrentSpeakers: React.FC = () => {
97+
const containerRef = useRef<HTMLDivElement>(null);
8398
const scrollRef = useRef<HTMLDivElement>(null);
84-
const titleRef = useRef<HTMLDivElement>(null);
85-
const isTitleInView = useInView(titleRef, { once: true });
99+
const [selectedSpeaker, setSelectedSpeaker] = React.useState<Speaker | null>(null);
100+
101+
useGSAP(() => {
102+
if (!containerRef.current) return;
103+
104+
const tl = gsap.timeline({
105+
scrollTrigger: {
106+
trigger: containerRef.current,
107+
start: 'top 85%',
108+
toggleActions: 'play none none none'
109+
}
110+
});
111+
112+
// Animate Title
113+
tl.fromTo('.speakers-header',
114+
{ opacity: 0, y: 30 },
115+
{ opacity: 1, y: 0, duration: 0.8, ease: 'power3.out' }
116+
);
117+
118+
// Stagger Cards
119+
tl.fromTo('.speaker-card',
120+
{
121+
opacity: 0,
122+
y: 40,
123+
scale: 0.95
124+
},
125+
{
126+
opacity: 1,
127+
y: 0,
128+
scale: 1,
129+
duration: 0.8,
130+
stagger: 0.1,
131+
ease: 'power3.out'
132+
},
133+
'-=0.6'
134+
);
135+
}, { scope: containerRef });
136+
137+
React.useEffect(() => {
138+
const header = document.querySelector('header');
139+
if (selectedSpeaker) {
140+
document.body.style.overflow = 'hidden';
141+
if (window.innerWidth <= 768 && header) {
142+
header.style.display = 'none';
143+
}
144+
} else {
145+
document.body.style.overflow = 'unset';
146+
if (header) header.style.display = 'flex';
147+
}
148+
return () => {
149+
document.body.style.overflow = 'unset';
150+
if (header) header.style.display = 'flex';
151+
};
152+
}, [selectedSpeaker]);
86153

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

97164
return (
98-
<section className="relative z-10 w-full py-16 md:py-24 overflow-hidden">
165+
<section className="relative z-10 w-full py-16 md:py-24 overflow-hidden" ref={containerRef}>
99166
{/* Section Header */}
100-
<div ref={titleRef} className="px-6 md:px-16 mb-10 md:mb-16">
101-
<motion.div
102-
initial={{ opacity: 0, y: 20 }}
103-
animate={isTitleInView ? { opacity: 1, y: 0 } : {}}
104-
transition={{ duration: 0.5 }}
105-
className="flex flex-row items-end justify-between gap-2"
106-
>
167+
<div className="speakers-header px-6 md:px-16 mb-10 md:mb-16 opacity-0">
168+
<div className="flex flex-row items-end justify-between gap-2">
107169
<div>
108170
<p className="font-mono text-sky-400 text-xs tracking-[0.3em] uppercase mb-3">
109171
[ Expert Speakers ]
@@ -128,7 +190,7 @@ const CurrentSpeakers: React.FC = () => {
128190
<ChevronRight size={20} />
129191
</button>
130192
</div>
131-
</motion.div>
193+
</div>
132194

133195
<div className="mt-6 h-[1px] w-full bg-gradient-to-r from-sky-400/60 via-sky-400/20 to-transparent" />
134196
</div>
@@ -139,9 +201,85 @@ const CurrentSpeakers: React.FC = () => {
139201
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none', WebkitOverflowScrolling: 'touch' }}
140202
>
141203
{speakers.map((speaker, index) => (
142-
<SpeakerCard key={`${speaker.name}-${index}`} speaker={speaker} index={index} />
204+
<SpeakerCard
205+
key={`${speaker.name}-${index}`}
206+
speaker={speaker}
207+
index={index}
208+
onClick={() => setSelectedSpeaker(speaker)}
209+
/>
143210
))}
144211
</div>
212+
213+
{/* Speaker Bio Modal */}
214+
<AnimatePresence>
215+
{selectedSpeaker && (
216+
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 sm:p-6 md:p-10 text-left">
217+
{/* Backdrop */}
218+
<motion.div
219+
initial={{ opacity: 0 }}
220+
animate={{ opacity: 1 }}
221+
exit={{ opacity: 0 }}
222+
onClick={() => setSelectedSpeaker(null)}
223+
className="absolute inset-0 bg-black/90 backdrop-blur-xl"
224+
/>
225+
226+
{/* Modal Content */}
227+
<motion.div
228+
initial={{ opacity: 0, scale: 0.95, y: 20 }}
229+
animate={{ opacity: 1, scale: 1, y: 0 }}
230+
exit={{ opacity: 0, scale: 0.95, y: 20 }}
231+
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]"
232+
>
233+
{/* Tactical Accents */}
234+
<div className="absolute top-0 left-0 w-8 h-8 border-t-2 border-l-2 border-sky-400 m-4 z-10" />
235+
<div className="absolute bottom-0 right-0 w-8 h-8 border-b-2 border-r-2 border-sky-400 m-4 z-10" />
236+
237+
<button
238+
onClick={() => setSelectedSpeaker(null)}
239+
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"
240+
>
241+
<X size={24} />
242+
</button>
243+
244+
{/* Left Side: Photo & Quick Info */}
245+
<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">
246+
<div className="relative w-32 h-32 md:w-48 md:h-48 mb-6">
247+
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-sky-400 via-purple-500 to-pink-500 p-[3px]">
248+
<div className="w-full h-full rounded-full bg-slate-900 p-[2px]">
249+
<img
250+
src={selectedSpeaker.image}
251+
alt={selectedSpeaker.name}
252+
className="w-full h-full rounded-full object-cover grayscale hover:grayscale-0 transition-all duration-500"
253+
/>
254+
</div>
255+
</div>
256+
</div>
257+
<h4 className="text-white font-heading font-bold text-xl md:text-2xl text-center mb-1 uppercase">
258+
{selectedSpeaker.name}
259+
</h4>
260+
<p className="text-sky-400 font-mono text-sm uppercase tracking-widest text-center mb-4">
261+
{selectedSpeaker.company}
262+
</p>
263+
<div className="h-px w-24 bg-sky-400/30" />
264+
</div>
265+
266+
{/* Right Side: Bio & Mission Intel */}
267+
<div className="w-full md:w-2/3 p-8 md:p-12 overflow-y-auto">
268+
<div className="mb-8">
269+
<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">
270+
{selectedSpeaker.title}
271+
</h5>
272+
<div className="prose prose-invert max-w-none">
273+
<p className="text-white/80 font-mono text-sm leading-relaxed whitespace-pre-line mb-4">
274+
{selectedSpeaker.bio}
275+
</p>
276+
</div>
277+
</div>
278+
</div>
279+
</motion.div>
280+
</div>
281+
)}
282+
</AnimatePresence>
145283
</section>
146284
);
147285
};

src/components/landing/CurrentSponsors.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const CurrentSponsors = () => {
66
return (
77
<section className="py-8 bg-transparent relative z-20">
88
<div className="container mx-auto px-4 flex justify-center">
9-
<motion.div
9+
<motion.div
1010
initial={{ opacity: 0, y: 30 }}
1111
whileInView={{ opacity: 1, y: 0 }}
1212
viewport={{ once: true }}
@@ -15,7 +15,7 @@ const CurrentSponsors = () => {
1515
>
1616
{/* Tactical Card Container - Enhanced Blue Visibility */}
1717
<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)]">
18-
18+
1919
{/* Static Red Corner Brackets - Enhanced Vibrancy & Glow */}
2020
<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)]" />
2121
<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)]" />
@@ -34,7 +34,7 @@ const CurrentSponsors = () => {
3434
</h3>
3535
<div className="h-[1px] w-12 md:w-20 bg-gradient-to-l from-transparent to-sky-400 opacity-50"></div>
3636
</div>
37-
37+
3838
{/* Powered By Section */}
3939
<div className="flex flex-col items-center gap-6 w-full">
4040
<div className="text-white/60 font-mono text-xs uppercase tracking-[0.25em] mb-1">
@@ -80,6 +80,31 @@ const CurrentSponsors = () => {
8080
</a>
8181
</div>
8282

83+
84+
<div className="flex items-center gap-4 w-full opacity-20">
85+
<div className="h-px flex-grow bg-gradient-to-r from-transparent to-sky-digital" />
86+
<div className="w-2 h-2 rotate-45 border border-sky-digital" />
87+
<div className="h-px flex-grow bg-gradient-to-l from-transparent to-sky-digital" />
88+
</div>
89+
90+
{/* Organizing Partner Section */}
91+
<div className="flex flex-col items-center gap-6 w-full">
92+
<div className="text-white/60 font-mono text-xs uppercase tracking-[0.25em] mb-1">
93+
Organizing Partner
94+
</div>
95+
<a
96+
href="https://traboda.com/"
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
className="transition-all duration-500 hover:scale-105 filter drop-shadow-[0_0_15px_rgba(255,255,255,0.1)]"
100+
>
101+
<img
102+
src="/inctf/assets/images/conference/logos/traboda_light.png"
103+
alt="Traboda CyberLabs Logo"
104+
className="h-10 md:h-16 w-auto object-contain brightness-0 invert opacity-90 hover:opacity-100 transition-opacity"
105+
/>
106+
</a>
107+
</div>
83108
</div>
84109

85110
{/* Background Data Matrix (Very Subtle) */}

0 commit comments

Comments
 (0)