From 76029427a4b8aeddfc51c0513f726c3d78e1fae8 Mon Sep 17 00:00:00 2001 From: Uwais Ishaq <66651633+Uwais12@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:01:48 +0000 Subject: [PATCH] Redesign landing page: centered hero with inline gradient highlight, 3D course cards, light mode - Hero: full-width centered "Master complex engineering." with animated gradient highlighter on "complex", inline stats row - Courses: 3D perspective-tilted cards with colored book spines and staggered offsets - Process: giant faded chapter number, connected timeline with gradient line - Features: dark interactive card with syntax-highlighted code preview - New tailwind keyframes: gradientBorder, glowPulse, timelinePulse Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/landing-page/page.js | 1711 ++++++++++++++++++++-------------- tailwind.config.mjs | 15 + 2 files changed, 1043 insertions(+), 683 deletions(-) diff --git a/src/app/landing-page/page.js b/src/app/landing-page/page.js index f789089..22e055b 100644 --- a/src/app/landing-page/page.js +++ b/src/app/landing-page/page.js @@ -6,91 +6,137 @@ import { Trophy, Clock, Target, - Users, Star, ArrowRight, - CheckCircle, - Sparkles, GraduationCap, Mail, - ChevronDown, BarChart3, Layers, Github, Twitter, Linkedin, Check, + Zap, + ArrowUpRight, + Play, + MoveRight, + Sparkles, + ChevronDown, } from "lucide-react"; import { useState, useEffect, useRef } from "react"; -import { motion, useInView, AnimatePresence } from "framer-motion"; -import Navbar from "../components/Navbar"; +import { motion, AnimatePresence } from "framer-motion"; import Link from "next/link"; // --------------------------------------------------------------------------- -// Animation helpers +// Ticker — infinite horizontal scroll (purely decorative, safe to animate) // --------------------------------------------------------------------------- -function useSectionInView(threshold = 0.15) { - const ref = useRef(null); - const isInView = useInView(ref, { once: true, amount: threshold }); - return { ref, isInView }; +function Ticker({ items }) { + return ( +
+ + {[...items, ...items].map((item, i) => ( + + + {item} + + ))} + +
+ ); } -const fadeUp = { - hidden: { opacity: 0, y: 32 }, - visible: (i = 0) => ({ - opacity: 1, - y: 0, - transition: { duration: 0.6, delay: i * 0.1, ease: [0.25, 0.46, 0.45, 0.94] }, - }), -}; - -const fadeIn = { - hidden: { opacity: 0 }, - visible: (i = 0) => ({ - opacity: 1, - transition: { duration: 0.5, delay: i * 0.1 }, - }), -}; - -const scaleIn = { - hidden: { opacity: 0, scale: 0.92 }, - visible: (i = 0) => ({ - opacity: 1, - scale: 1, - transition: { duration: 0.5, delay: i * 0.12, ease: [0.25, 0.46, 0.45, 0.94] }, - }), -}; - // --------------------------------------------------------------------------- -// Section wrapper with scroll-reveal +// Section Label // --------------------------------------------------------------------------- -function Section({ children, className = "", id }) { - const { ref, isInView } = useSectionInView(0.1); +function SectionLabel({ number, text }) { return ( - - {children} - +
+ + {number} + + + {text} + +
+
); } // --------------------------------------------------------------------------- -// Reusable badge component +// Navbar // --------------------------------------------------------------------------- -function Badge({ children }) { +function LandingNavbar() { + const [hasScrolled, setHasScrolled] = useState(false); + + useEffect(() => { + const handleScroll = () => setHasScrolled(window.scrollY > 20); + window.addEventListener("scroll", handleScroll, { passive: true }); + return () => window.removeEventListener("scroll", handleScroll); + }, []); + return ( - - {children} - + ); } @@ -106,8 +152,8 @@ export default function LandingPage() { const [reviews, setReviews] = useState([]); const [reviewsLoading, setReviewsLoading] = useState(true); const [reviewsError, setReviewsError] = useState(null); + const coursesRef = useRef(null); - // Fetch reviews useEffect(() => { const fetchReviews = async () => { try { @@ -129,7 +175,6 @@ export default function LandingPage() { fetchReviews(); }, []); - // Newsletter submit const handleNewsletterSubmit = async (e) => { e.preventDefault(); if (!email) { @@ -146,10 +191,16 @@ export default function LandingPage() { }); const data = await response.json(); if (response.ok) { - setStatus({ type: "success", message: data.message || "You're on the list!" }); + setStatus({ + type: "success", + message: data.message || "You're on the list!", + }); setEmail(""); } else { - setStatus({ type: "error", message: data.error || "Something went wrong." }); + setStatus({ + type: "error", + message: data.error || "Something went wrong.", + }); } } catch { setStatus({ type: "error", message: "Network error. Please try again." }); @@ -163,518 +214,808 @@ export default function LandingPage() { const savingsLabel = selectedInterval === "year" ? "Save £10/yr" : null; return ( -
- {/* Navbar */} - +
+ + + {/* Background texture */} +
+ + {/* Gradient blobs — fixed background */} +
+
+
+
+
{/* =================================================================== - HERO + HERO — "The Statement" + Full-width centered, single massive sentence with inline highlights =================================================================== */} -
- {/* Background gradient orbs */} -