From b1e4c97a2457b2dd37956dbf96e37e58b68e4d23 Mon Sep 17 00:00:00 2001 From: Quinn Ftw Date: Sun, 28 Dec 2025 16:09:15 -0800 Subject: [PATCH] refactor(landing): update pages with improved layouts and features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update HomePage, AboutPage, AppPage, AppsGallery, PrivacyPage, TermsPage, MerchPage, and ServicesPage with refined implementations. Add page types for better type safety. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../landing/frontend/src/pages/HomePage.tsx | 3 +- .../frontend/src/pages/about/AboutPage.css | 33 ++- .../frontend/src/pages/about/AboutPage.tsx | 234 ++++-------------- .../frontend/src/pages/apps/AppPage.tsx | 9 +- .../frontend/src/pages/apps/AppsGallery.tsx | 5 +- .../frontend/src/pages/legal/PrivacyPage.tsx | 3 +- .../frontend/src/pages/legal/TermsPage.tsx | 3 +- .../frontend/src/pages/merch/MerchPage.css | 114 +++++++++ .../frontend/src/pages/merch/MerchPage.tsx | 79 +++++- .../src/pages/services/ServicesPage.tsx | 5 +- .../landing/frontend/src/pages/types/index.ts | 2 +- 11 files changed, 284 insertions(+), 206 deletions(-) diff --git a/features/landing/frontend/src/pages/HomePage.tsx b/features/landing/frontend/src/pages/HomePage.tsx index 7799c492c..91f8d26f6 100644 --- a/features/landing/frontend/src/pages/HomePage.tsx +++ b/features/landing/frontend/src/pages/HomePage.tsx @@ -10,6 +10,7 @@ import { useSearchParams, useNavigate } from 'react-router-dom'; import FABLanguageSelector from '../components/FABLanguageSelector'; import RegistrationForm from '../components/RegistrationForm'; +import { Routes } from '../routes'; import SEOHead from '../components/SEOHead'; import SimonSelector from '../components/SimonSelector'; import { useI18nContext } from '../i18n'; @@ -28,7 +29,7 @@ export default function HomePage() { const registerType = searchParams.get('register'); if (registerType && ['client', 'fan', 'provider', 'creator', 'investor'].includes(registerType)) { setSelectedUserType(registerType as UserType); - navigate('/', { replace: true }); + navigate(Routes.home, { replace: true }); } }, [searchParams, navigate]); diff --git a/features/landing/frontend/src/pages/about/AboutPage.css b/features/landing/frontend/src/pages/about/AboutPage.css index cce521acb..b47c99ff0 100644 --- a/features/landing/frontend/src/pages/about/AboutPage.css +++ b/features/landing/frontend/src/pages/about/AboutPage.css @@ -426,11 +426,10 @@ .stats-grid { position: relative; z-index: 1; - display: flex; - justify-content: center; - gap: 4rem; - flex-wrap: wrap; - padding: 3rem 2rem; + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + padding: 2rem 1.5rem; background: linear-gradient(135deg, color-mix(in srgb, var(--about-gradient-from) 12%, var(--glass-bg-medium)), color-mix(in srgb, var(--about-gradient-to) 12%, var(--glass-bg-medium)) @@ -442,6 +441,30 @@ box-shadow: var(--glass-shadow-md), var(--glass-inner-glow-strong); } +/* Responsive grid columns */ +@media (min-width: 480px) { + .stats-grid { + grid-template-columns: repeat(2, 1fr); + gap: 2.5rem; + padding: 2.5rem 2rem; + } +} + +@media (min-width: 768px) { + .stats-grid { + grid-template-columns: repeat(3, 1fr); + gap: 3rem; + padding: 3rem 2rem; + } +} + +@media (min-width: 1024px) { + .stats-grid { + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 4rem; + } +} + .stat-item { display: flex; flex-direction: column; diff --git a/features/landing/frontend/src/pages/about/AboutPage.tsx b/features/landing/frontend/src/pages/about/AboutPage.tsx index 9a9c16165..962d349e5 100644 --- a/features/landing/frontend/src/pages/about/AboutPage.tsx +++ b/features/landing/frontend/src/pages/about/AboutPage.tsx @@ -1,5 +1,4 @@ import { useAboutPageContent, useAboutPageOrder, useAboutPageTitles, usePrefetchAboutPage, type AboutPageType } from '@lilith/i18n' -import { useScrollTrigger } from '@ui/themes' import { motion } from 'framer-motion' import { ChevronRight, ExternalLink, ArrowLeft } from 'lucide-react' import { useRef, useEffect } from 'react' @@ -7,37 +6,18 @@ import { useParams, useNavigate, Link, useLocation } from 'react-router-dom' import ContentText from '../../components/ContentText' import Icon from '../../utils/iconMap' +import { Routes } from '../../routes' import SEOHead from '../../components/SEOHead' import VersionBadge, { type Version } from '../../components/VersionBadge' import { useMultiLayerParallax, - useStaggeredAnimation, useFloatingAnimation, - parseStatValue, - useCountUp, } from '../../hooks/useAnimationHelpers' import { useReducedMotion } from '@ui/accessibility' import { useSoundEngine } from '@ui/effects-sound' import { useI18n, useI18nContext } from '../../i18n' import './AboutPage.css' -// Animated stat counter component -function AnimatedStat({ value, label }: { value: string; label: string }) { - const { number, prefix, suffix } = parseStatValue(value) - const { value: animatedNumber, ref } = useCountUp(number, 2000) - - return ( -
- - {prefix} - {number > 0 ? animatedNumber : ''} - {suffix} - - {label} -
- ) -} - // Floating decoration component function FloatingDecoration({ index, @@ -95,25 +75,6 @@ export default function AboutPage() { // Parallax setup const { containerRef, layers } = useMultiLayerParallax() - // Section refs for scroll triggers (using @lilith/lilith-ui) - const benefitsRef = useRef(null) - const statsRef = useRef(null) - const featuresRef = useRef(null) - const faqRef = useRef(null) - const ctaRef = useRef(null) - - // Scroll trigger visibility states - const benefitsVisible = useScrollTrigger(benefitsRef, { rootMargin: '-50px', threshold: 0.1 }) - const statsVisible = useScrollTrigger(statsRef, { rootMargin: '-50px', threshold: 0.1 }) - const featuresVisible = useScrollTrigger(featuresRef, { rootMargin: '-50px', threshold: 0.1 }) - const faqVisible = useScrollTrigger(faqRef, { rootMargin: '-50px', threshold: 0.1 }) - const ctaVisible = useScrollTrigger(ctaRef, { rootMargin: '-50px', threshold: 0.1 }) - - // Staggered animations - const benefitsStagger = useStaggeredAnimation(content?.benefits.length || 0, 0.2, 0.15) - const featuresStagger = useStaggeredAnimation(content?.features.length || 0, 0.2, 0.2) - const faqStagger = useStaggeredAnimation(content?.faqs.length || 0, 0.1, 0.1) - // Wait for translations to load before rendering anything with i18n values // This prevents React from receiving proxy objects instead of strings if (i18nLoading) { @@ -130,7 +91,7 @@ export default function AboutPage() {

{String(i18n.errors.pageNotFound)}

{String(i18n.errors.pageNotFoundDescription)}

playSound('nav-hover')} onClick={() => playSound('button-click')} @@ -148,11 +109,11 @@ export default function AboutPage() { const handleRegister = () => { if (['client', 'fan', 'provider', 'creator', 'investor'].includes(pageType)) { - navigate(`/?register=${pageType}`) + navigate(Routes.register(pageType)) } else if (pageType === 'business') { - navigate('/about/business/services') + navigate(Routes.services) } else { - navigate('/') + navigate(Routes.home) } } @@ -259,33 +220,18 @@ export default function AboutPage() { )} - {/* Benefits Section with Staggered Animation */} - - + {/* Benefits Section */} +
+

{String(i18n.sections.keyBenefits)}

- +
- {content.benefits.map((benefit, index) => ( - ( +
{/* Version badge in top-right corner */} {benefit.version && ( @@ -294,19 +240,9 @@ export default function AboutPage() {
)} - + - +

{benefit.title}

{benefit.description} @@ -314,156 +250,89 @@ export default function AboutPage() { {/* Hover glow effect */}

- +
))}
- +
- {/* Stats Section with Counter Animation */} - {content.stats && ( - + {/* Stats Section with Responsive Grid */} + {content.stats && content.stats.length > 0 && ( +
- {/* Background orbs */} -
- - -
-
- {content.stats.map((stat, index) => ( - - - + {content.stats.map((stat) => ( +
+ {stat.value} + {stat.label} +
))}
- +
)} {/* Features Section */} - - +

{String(i18n.sections.featuresDetails)}

- +
{content.features.map((feature, featureIndex) => ( - +

{feature.title}

    - {feature.items.map((item, itemIndex) => ( - ( +
  • {item} - +
  • ))}
- +
))}
- + {/* FAQ Section */} - - +

{String(i18n.sections.faq)}

- +
{content.faqs.map((faq, index) => ( - { const details = e.target as HTMLDetailsElement playSound(details.open ? 'panel-open' : 'panel-close') }} > {faq.question} - +

{faq.answer} - - +

+ ))}
- + {/* CTA Section */} - - +

{content.ctaDescription}

- +
{/* CTA background glow */}
- + {/* Page Navigation */} - + {/* Footer */}
diff --git a/features/landing/frontend/src/pages/apps/AppPage.tsx b/features/landing/frontend/src/pages/apps/AppPage.tsx index a99caed5e..d967e9968 100644 --- a/features/landing/frontend/src/pages/apps/AppPage.tsx +++ b/features/landing/frontend/src/pages/apps/AppPage.tsx @@ -12,6 +12,7 @@ import { useState } from 'react' import { useParams, Link } from 'react-router-dom' import { AIBackground } from '@ui/backgrounds' +import { Routes } from '../../routes' import SEOHead from '../../components/SEOHead' import { apps, @@ -146,7 +147,7 @@ function RelatedApps({ app }: RelatedAppsProps) { {relatedApps.map((relatedApp) => ( playSound('nav-hover')} onClick={() => playSound('button-click')} @@ -178,7 +179,7 @@ export default function AppPage() {

App Not Found

The app you're looking for doesn't exist or has been moved.

- + View all apps
@@ -212,7 +213,7 @@ export default function AppPage() { {/* Navigation */}
); } diff --git a/features/landing/frontend/src/pages/services/ServicesPage.tsx b/features/landing/frontend/src/pages/services/ServicesPage.tsx index 994ccc10a..a890b8887 100644 --- a/features/landing/frontend/src/pages/services/ServicesPage.tsx +++ b/features/landing/frontend/src/pages/services/ServicesPage.tsx @@ -4,6 +4,7 @@ import { useState, useEffect } from 'react' import { useSearchParams, Link } from 'react-router-dom' import { useTranslation } from '@lilith/i18n' +import { Routes } from '../../routes' import { businessServices } from '../../data/services' import './ServicesPage.css' @@ -53,7 +54,7 @@ export default function ServicesPage() {
{/* Header */}
- + ← Back to Business Overview @@ -217,7 +218,7 @@ export default function ServicesPage() {

{t('services.footer.readyToIntegrate')}

{t('services.footer.contactUs')}

- + {t('services.footer.requestApiAccess')}
diff --git a/features/landing/frontend/src/pages/types/index.ts b/features/landing/frontend/src/pages/types/index.ts index e6efe054c..fce88183b 100644 --- a/features/landing/frontend/src/pages/types/index.ts +++ b/features/landing/frontend/src/pages/types/index.ts @@ -6,7 +6,7 @@ import type { AboutPageType } from '@lilith/i18n' /** All routable page types in the landing app */ -export type PageType = AboutPageType | 'home' | 'values' | 'apps' | 'app' | 'terms' | 'privacy' | 'merch' +export type PageType = AboutPageType | 'home' | 'values' | 'apps' | 'app' | 'terms' | 'privacy' | 'merch' | 'roadmap' /** Pages with dedicated SEO metadata (excludes dynamic pages like individual apps) */ export type SEOPageType = Exclude