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
21 changes: 13 additions & 8 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -47,21 +48,25 @@ export default async function LandingPage() {

<section className="relative z-50 overflow-x-hidden pt-12 md:pt-10 flex flex-col justify-center -mt-4 md:-mt-8">
<LandingHeader />
<CurrentSponsors />
</section>

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

{/* Past Speakers Section */}
<PastSpeakers />
{/* Mission Timeline Section */}
<OperationTimeline />

{/* Current Speakers Section */}
<CurrentSpeakers />

{/* Bento Grid Section */}
<section className="py-16 relative z-30" id="mission-grid">
<div className="container mx-auto px-4">
<BentoGridContainer>

{/* 1. Mission Brief (Desktop: 2/3 wide, Row 1 Left | Mobile Rank 1) */}
<div className="md:col-span-2 flex w-full bento-card-wrapper opacity-0">
<BentoCard title="Mission Brief">
Expand All @@ -72,7 +77,7 @@ export default async function LandingPage() {
</div>
<div className="mt-auto text-center">
<Link href="/mission-brief">
<button className="px-6 py-2 border border-alert-crimson text-alert-crimson font-mono uppercase tracking-wider text-sm hover:bg-alert-crimson/10 transition shadow-[0_0_12px_rgba(244,63,94,0.25)] hover:shadow-[0_0_20px_rgba(244,63,94,0.5)]">
<button className="px-6 py-2 border border-alert-crimson text-alert-crimson hover:bg-alert-crimson hover:text-white hover:-translate-y-1 font-mono uppercase tracking-wider text-sm transition shadow-[0_0_12px_rgba(244,63,94,0.25)] hover:shadow-[0_0_20px_rgba(244,63,94,0.5)]">
[ Know More ]
</button>
</Link>
Expand All @@ -93,7 +98,7 @@ export default async function LandingPage() {
</ul>
<div className="mt-auto text-center">
<Link href="/eligibility">
<button className="px-6 py-2 border border-alert-crimson text-alert-crimson font-mono uppercase tracking-wider text-sm hover:bg-alert-crimson/10 transition shadow-[0_0_12px_rgba(244,63,94,0.25)] hover:shadow-[0_0_20px_rgba(244,63,94,0.5)]">
<button className="px-6 py-2 border border-alert-crimson text-alert-crimson hover:bg-alert-crimson hover:text-white hover:-translate-y-1 font-mono uppercase tracking-wider text-sm transition shadow-[0_0_12px_rgba(244,63,94,0.25)] hover:shadow-[0_0_20px_rgba(244,63,94,0.5)]">
[ Know More ]
</button>
</Link>
Expand Down Expand Up @@ -121,10 +126,10 @@ export default async function LandingPage() {
Receive mission updates, briefings, timelines, and official communications.
</p>
<div className="flex flex-col md:flex-row gap-4 justify-center mt-auto">
<BentoHoverButton href="/mission-control" className="w-full md:w-auto px-3 sm:px-6 py-2.5 sm:py-3 bg-gradient-to-br from-red-900 to-red-800 border border-white/40 text-white font-mono font-bold tracking-wider rounded text-xs sm:text-sm hover:brightness-110 shadow-[0_0_12px_rgba(244,63,94,0.3)] hover:shadow-[0_0_22px_rgba(244,63,94,0.6)] transition-all duration-300">
<BentoHoverButton href="/mission-control" className="w-full md:w-auto px-6 sm:px-16 py-4 sm:py-5 bg-gradient-to-br from-red-900 to-red-800 border border-white/40 text-white font-mono font-bold tracking-wider rounded text-[10px] sm:text-sm hover:brightness-110 shadow-[0_0_12px_rgba(244,63,94,0.3)] hover:shadow-[0_0_22px_rgba(244,63,94,0.6)] transition-all duration-300 whitespace-nowrap flex items-center justify-center">
[ Enter Mission Control ]
</BentoHoverButton>
<BentoHoverButton href="/mission-brief" className="w-full md:w-auto px-3 sm:px-6 py-2.5 sm:py-3 bg-gradient-to-br from-red-900 to-red-800 border border-white/40 text-white font-mono font-bold tracking-wider rounded text-xs sm:text-sm hover:brightness-110 shadow-[0_0_12px_rgba(244,63,94,0.3)] hover:shadow-[0_0_22px_rgba(244,63,94,0.6)] transition-all duration-300">
<BentoHoverButton href="/mission-brief" className="w-full md:w-auto px-6 sm:px-16 py-4 sm:py-5 bg-gradient-to-br from-red-900 to-red-800 border border-white/40 text-white font-mono font-bold tracking-wider rounded text-[10px] sm:text-sm hover:brightness-110 shadow-[0_0_12px_rgba(244,63,94,0.3)] hover:shadow-[0_0_22px_rgba(244,63,94,0.6)] transition-all duration-300 whitespace-nowrap flex items-center justify-center">
[ View Mission Brief ]
</BentoHoverButton>
</div>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
149 changes: 149 additions & 0 deletions src/components/landing/CurrentSpeakers.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>(null);
const isInView = useInView(ref, { once: true });

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="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="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" />

{/* Circular Photo */}
<div className="flex justify-center mb-5 md:mb-6 flex-shrink-0">
<div className="relative w-32 h-32 md:w-44 md:h-44">
{/* Outer gradient ring */}
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-sky-400 via-purple-500 to-pink-500 p-[3px] group-hover:p-[4px] transition-all duration-300">
<div className="w-full h-full rounded-full bg-slate-900 p-[2px]">
<img
src={speaker.image}
alt={speaker.name}
className="w-full h-full rounded-full object-cover grayscale group-hover:grayscale-0 transition-all duration-500"
/>
</div>
</div>
</div>
</div>

{/* Info */}
<div className="flex-grow flex flex-col justify-center w-full">
<h3 className="font-heading font-bold text-white text-lg md:text-xl leading-tight mb-2 md:mb-3 uppercase">
{speaker.name}
</h3>
<p className="font-mono text-white/80 text-[11px] md:text-xs mb-2 md:mb-3 uppercase tracking-wider leading-relaxed line-clamp-3 min-h-[2.5rem]">
{speaker.title}
</p>
<p className="font-mono text-sky-400 text-xs md:text-sm font-semibold tracking-wide mt-auto">
{speaker.company}
</p>
</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>
);
};

const CurrentSpeakers: React.FC = () => {
const scrollRef = useRef<HTMLDivElement>(null);
const titleRef = useRef<HTMLDivElement>(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 className="relative z-10 w-full py-16 md:py-24 overflow-hidden">
{/* 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>
<p className="font-mono text-sky-400 text-xs tracking-[0.3em] uppercase mb-3">
[ Expert Speakers ]
</p>
<h2 className="font-heading text-white text-3xl md:text-4xl lg:text-5xl font-bold uppercase tracking-wider">
Current <span className="text-sky-400">Speakers</span>
</h2>
</div>
<div className="flex items-center gap-3 flex-shrink-0 mb-1">
<button
onClick={() => scroll('left')}
className="group flex items-center justify-center p-2 border border-sky-400/30 text-sky-400 hover:bg-sky-400/10 hover:border-sky-400 transition-all duration-200 rounded-sm"
aria-label="Scroll left"
>
<ChevronLeft size={20} />
</button>
<button
onClick={() => scroll('right')}
className="group flex items-center justify-center p-2 border border-sky-400/30 text-sky-400 hover:bg-sky-400/10 hover:border-sky-400 transition-all duration-200 rounded-sm"
aria-label="Scroll right"
>
<ChevronRight size={20} />
</button>
</div>
</motion.div>

<div className="mt-6 h-[1px] w-full bg-gradient-to-r from-sky-400/60 via-sky-400/20 to-transparent" />
</div>

<div
ref={scrollRef}
className="flex gap-6 md:gap-8 px-8 md:px-16 overflow-x-auto snap-x snap-mandatory scrollbar-hide pb-8 pt-4 md:justify-center scroll-smooth"
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none', WebkitOverflowScrolling: 'touch' }}
>
{speakers.map((speaker, index) => (
<SpeakerCard key={`${speaker.name}-${index}`} speaker={speaker} index={index} />
))}
</div>
</section>
);
};

export default CurrentSpeakers;
Loading
Loading