feat: update layout, styling, story sections, footer, and add Header and ScrollProgress components

This commit is contained in:
R-Bharathraj
2026-07-16 17:35:14 +05:30
parent 09bbd9a23d
commit fbf6ee89b9
10 changed files with 807 additions and 220 deletions

View File

@@ -32,30 +32,52 @@
:root { :root {
--font-sora: 'Sora', sans-serif; --font-sora: 'Sora', sans-serif;
--font-inter: 'Inter', sans-serif; --font-inter: 'Inter', sans-serif;
/* Section gutters (ported from the loyaly website).
--sec-gutter = left/right side margin; --sec-gap = vertical gap between
stacked sections; --hdr-gutter = header side padding. */
--sec-gutter: 20px;
--sec-gap: 20px;
--hdr-gutter: 48px;
} }
/* Custom Scrollbar */ /* Phones — full-bleed sections, tighter header padding */
@media (max-width: 600px) {
:root {
--sec-gutter: 12px;
--sec-gap: 12px;
--hdr-gutter: 20px;
}
}
/* Custom Scrollbar — neobrutalist, on-theme (no track border) */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 8px; width: 14px;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background: #090909; background: #FBF3DD;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: #333333; background: linear-gradient(180deg, #FFC72C 0%, #FF2E88 60%, #8B3DFF 100%);
border-radius: 4px; border: 2px solid #0a0a0a;
border-radius: 10px;
background-clip: padding-box;
} }
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
background: #FFC72C; background: linear-gradient(180deg, #FFD95A 0%, #FF2E88 55%, #8B3DFF 100%);
background-clip: padding-box;
} }
/* Base Body Styles */ /* Base Body Styles */
html, body { html, body {
background-color: #090909; background-color: #FBF3DD;
color: #FFFFFF; color: #FFFFFF;
font-family: var(--font-inter), sans-serif; font-family: var(--font-inter), sans-serif;
overflow-x: hidden; overflow-x: hidden;
scroll-behavior: smooth; scroll-behavior: smooth;
color-scheme: light;
scrollbar-width: auto;
scrollbar-color: #FF2E88 #FBF3DD;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {

View File

@@ -50,7 +50,7 @@ export default function RootLayout({
className={`${sora.variable} ${inter.variable} h-full antialiased`} className={`${sora.variable} ${inter.variable} h-full antialiased`}
suppressHydrationWarning suppressHydrationWarning
> >
<body className="min-h-full flex flex-col bg-dark text-white selection:bg-primary selection:text-dark"> <body className="min-h-full flex flex-col bg-[#FBF3DD] text-white selection:bg-primary selection:text-dark">
<Providers> <Providers>
{children} {children}
</Providers> </Providers>

View File

@@ -1,4 +1,6 @@
import SideNav, { NavSection } from "@/components/layout/SideNav"; import Header from "@/components/layout/Header";
import Footer from "@/components/layout/Footer";
import ScrollProgress from "@/components/layout/ScrollProgress";
import { import {
Intro, Intro,
TheWhy, TheWhy,
@@ -21,30 +23,11 @@ import {
ThePromise, ThePromise,
} from "@/components/story/SectionsB"; } from "@/components/story/SectionsB";
const sections: NavSection[] = [
{ id: "intro", label: "Intro" },
{ id: "the-why", label: "The Why" },
{ id: "the-problem", label: "The Problem" },
{ id: "the-shift", label: "The Shift" },
{ id: "lyts", label: "Meet LYTs" },
{ id: "one-day", label: "One Day" },
{ id: "feelings", label: "Feelings" },
{ id: "difference", label: "Difference" },
{ id: "the-loop", label: "The Loop" },
{ id: "for-you", label: "For You" },
{ id: "for-business", label: "For Business" },
{ id: "why-now", label: "Why Now" },
{ id: "how-it-works", label: "How It Works" },
{ id: "old-vs-new", label: "Old vs New" },
{ id: "the-vision", label: "The Vision" },
{ id: "our-belief", label: "Our Belief" },
{ id: "the-promise", label: "The Promise" },
];
export default function Home() { export default function Home() {
return ( return (
<main className="relative w-full"> <main className="relative w-full">
<SideNav sections={sections} /> <ScrollProgress />
<Header />
<Intro /> <Intro />
<TheWhy /> <TheWhy />
<TheProblem /> <TheProblem />
@@ -62,6 +45,7 @@ export default function Home() {
<TheVision /> <TheVision />
<OurBelief /> <OurBelief />
<ThePromise /> <ThePromise />
<Footer />
</main> </main>
); );
} }

View File

@@ -35,7 +35,7 @@ export default function Providers({ children }: { children: React.ReactNode }) {
}, []); }, []);
return ( return (
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false}> <ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false} enableColorScheme={false}>
<UserProvider> <UserProvider>
{children} {children}
</UserProvider> </UserProvider>

View File

@@ -1,152 +1,246 @@
"use client"; 'use client';
import { useState } from "react"; import { useState, useEffect } from 'react';
import { Send, Instagram, Twitter, MessageSquare, Heart } from "lucide-react"; import Link from 'next/link';
import Link from "next/link"; import Image from 'next/image';
const INK = '#0a0a0a';
const NAV = [
{
title: 'Earn',
color: '#C8FF37', // lime
links: [
{ label: 'Walk to Earn', href: '#for-you' },
{ label: 'Play & Win', href: '#for-you' },
{ label: 'Refer Friends', href: '#for-you' },
],
},
{
title: 'Platform',
color: '#FF2E88', // pink
links: [
{ label: 'For You', href: '#for-you' },
{ label: 'For Business', href: '#for-business' },
{ label: 'How It Works', href: '#how-it-works' },
],
},
{
title: 'Company',
color: '#8B3DFF', // purple
links: [
{ label: 'The Vision', href: '#the-vision' },
{ label: 'The Why', href: '#the-why' },
{ label: 'Contact Us', href: '#for-business' },
],
},
];
const SOCIALS = [
{
label: 'Instagram', href: 'https://instagram.com/lytsup', bg: '#FF2E88',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>,
},
{
label: 'X / Twitter', href: 'https://twitter.com/lytsup', bg: '#8B3DFF',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M13.98 10.62 20.54 3h-1.55l-5.7 6.62L8.74 3H3.5l6.88 10.01L3.5 21h1.55l6.01-6.99L15.87 21h5.24l-7.13-10.38zm-2.13 2.47-.7-1-5.54-7.93H8l4.47 6.4.7 1 5.82 8.32h-2.39l-4.74-6.79z"/></svg>,
},
{
label: 'YouTube', href: 'https://www.youtube.com/@lytsup', bg: '#FF6B35',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M21.8 8s-.2-1.38-.8-1.99c-.76-.8-1.61-.8-2-.85C16.2 5 12 5 12 5s-4.2 0-7 .17c-.39.05-1.24.05-2 .85C2.4 6.62 2.2 8 2.2 8S2 9.62 2 11.24v1.52c0 1.62.2 3.24.2 3.24s.2 1.38.8 1.99c.76.8 1.76.77 2.2.85C6.8 19 12 19.03 12 19.03s4.2-.01 7-.22c.39-.05 1.24-.05 2-.85.6-.61.8-1.99.8-1.99S22 14.38 22 12.76v-1.52C22 9.62 21.8 8 21.8 8zm-11.87 6.59V8.79l5.4 2.82-5.4 2.98z"/></svg>,
},
];
export default function Footer() { export default function Footer() {
const [email, setEmail] = useState(""); const [showScroll, setShowScroll] = useState(false);
const [subscribed, setSubscribed] = useState(false);
const handleSubscribe = (e: React.FormEvent) => { useEffect(() => {
e.preventDefault(); const onScroll = () => setShowScroll(window.scrollY > 400);
if (email) { window.addEventListener('scroll', onScroll, { passive: true });
setSubscribed(true); return () => window.removeEventListener('scroll', onScroll);
setEmail(""); }, []);
setTimeout(() => setSubscribed(false), 5000);
}
};
return ( return (
<footer className="relative bg-[#060606] border-t border-white/5 pt-16 pb-8 overflow-hidden"> <>
{/* Ambient background light glows */} <footer className="lu-footer bg-night font-sora" style={{
<div className="absolute top-0 left-1/4 -translate-y-1/2 w-80 h-80 rounded-full bg-accent-purple/10 blur-[80px] pointer-events-none" /> color: '#fff',
<div className="absolute top-0 right-1/4 -translate-y-1/2 w-80 h-80 rounded-full bg-accent-pink/10 blur-[80px] pointer-events-none" /> position: 'relative',
overflow: 'hidden',
margin: '0 var(--sec-gutter) var(--sec-gap)',
border: `4px solid ${INK}`,
borderRadius: 28,
boxShadow: `0 12px 0 0 rgba(0,0,0,0.35)`,
}}>
{/* ── BIG CTA STICKER CARD ── */}
<div className="lu-cta-wrap" style={{ padding: '56px 48px 40px' }}>
<div className="lu-cta bg-cream" style={{
position: 'relative',
color: INK,
border: `4px solid ${INK}`,
borderRadius: 24,
boxShadow: `8px 8px 0 0 ${INK}`,
padding: '44px 48px',
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
flexWrap: 'wrap', gap: 28,
overflow: 'hidden',
}}>
{/* corner sticker */}
<span style={{
position: 'absolute', top: -18, right: 34, transform: 'rotate(8deg)',
background: '#FF2E88', color: '#fff', border: `3px solid ${INK}`,
borderRadius: 12, padding: '6px 14px', fontSize: 12, fontWeight: 900,
textTransform: 'uppercase', letterSpacing: '0.05em', boxShadow: `3px 3px 0 0 ${INK}`,
}}>join the loop</span>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> <div style={{ maxWidth: 620 }}>
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16"> <span style={{ display: 'inline-block', background: '#8B3DFF', color: '#fff', border: `3px solid ${INK}`, borderRadius: 10, padding: '5px 12px', fontSize: 11, fontWeight: 900, textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 18, boxShadow: `3px 3px 0 0 ${INK}` }}>
{/* Brand Info */} Earn. Spend. Live More.
<div className="space-y-4 col-span-1 md:col-span-1">
<Link href="/" className="inline-block">
<span className="text-2xl font-extrabold tracking-wider font-sora text-white">
Lyts<span className="text-primary text-glow-yellow">Up</span>
</span> </span>
<h2 className="lu-cta-heading" style={{ fontSize: 'clamp(32px, 4.6vw, 60px)', fontWeight: 800, letterSpacing: '-0.03em', lineHeight: 0.98, margin: 0 }}>
Turn everyday moments<br />
<span style={{ position: 'relative', display: 'inline-block' }}>
into <span style={{ color: '#FF2E88' }}>real value.</span>
</span>
</h2>
</div>
<Link href="#for-business" className="lu-cta-btn" style={{
display: 'inline-flex', alignItems: 'center', gap: 10,
padding: '18px 36px', background: '#FFC72C', color: INK,
fontSize: 17, fontWeight: 900, textTransform: 'uppercase', letterSpacing: '0.03em',
border: `4px solid ${INK}`, borderRadius: 16, textDecoration: 'none',
boxShadow: `5px 5px 0 0 ${INK}`, whiteSpace: 'nowrap',
transition: 'transform 0.12s ease, box-shadow 0.12s ease',
}}>
Get Started
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</Link> </Link>
<p className="text-white/60 text-sm leading-relaxed max-w-xs">
The premier social currency app for Gen Z. Earn rewards for walking, playing, and living your best life.
</p>
<p className="text-primary font-semibold text-xs tracking-wider uppercase">
Earn. Spend. Live More.
</p>
</div>
{/* Site Navigation */}
<div className="space-y-4">
<h4 className="text-white font-bold text-sm tracking-wider uppercase font-sora">Navigate</h4>
<ul className="space-y-2.5">
<li>
<a href="#earn" className="text-white/60 hover:text-primary transition-colors text-sm">Earn Points</a>
</li>
<li>
<a href="#spend" className="text-white/60 hover:text-primary transition-colors text-sm">Redeem Rewards</a>
</li>
<li>
<a href="#play" className="text-white/60 hover:text-primary transition-colors text-sm">Mini-Game</a>
</li>
<li>
<a href="#leaderboard" className="text-white/60 hover:text-primary transition-colors text-sm">Leaderboard</a>
</li>
</ul>
</div>
{/* Corporate Links */}
<div className="space-y-4">
<h4 className="text-white font-bold text-sm tracking-wider uppercase font-sora">Partnerships</h4>
<ul className="space-y-2.5">
<li>
<Link href="#" className="text-white/60 hover:text-primary transition-colors text-sm">Become a Partner</Link>
</li>
<li>
<Link href="#" className="text-white/60 hover:text-primary transition-colors text-sm">Brands Portal</Link>
</li>
<li>
<Link href="#" className="text-white/60 hover:text-primary transition-colors text-sm">API Integration</Link>
</li>
<li>
<Link href="#" className="text-white/60 hover:text-primary transition-colors text-sm">Support Hub</Link>
</li>
</ul>
</div>
{/* Newsletter subscription */}
<div className="space-y-4">
<h4 className="text-white font-bold text-sm tracking-wider uppercase font-sora">Get Secret Drops</h4>
<p className="text-white/60 text-xs">
Subscribe to get notified about ultra-rare brand voucher drops.
</p>
<form onSubmit={handleSubscribe} className="relative flex">
<input
type="email"
placeholder="your.email@gmail.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-white focus:outline-none focus:border-primary/50 transition-colors pr-10"
/>
<button
type="submit"
className="absolute right-1 top-1 bottom-1 bg-primary text-dark font-bold px-3.5 rounded-lg hover:bg-primary/95 transition-colors flex items-center justify-center cursor-pointer"
aria-label="Subscribe"
>
<Send className="w-4 h-4" />
</button>
</form>
{subscribed && (
<p className="text-accent-lime text-xs font-semibold animate-pulse">
You're in! Check your inbox for secret codes.
</p>
)}
</div> </div>
</div> </div>
<hr className="border-white/5 mb-8" /> {/* ── COLUMNS ── */}
<div className="lu-columns" style={{
{/* Socials & Copyright */} display: 'grid',
<div className="flex flex-col sm:flex-row justify-between items-center space-y-4 sm:space-y-0"> gridTemplateColumns: '1.6fr 1fr 1fr 1fr',
<div className="flex items-center space-x-2 text-xs text-white/40"> gap: 40, padding: '24px 48px 44px',
<span>© {new Date().getFullYear()} LytsUp.com. All rights reserved.</span> alignItems: 'start',
<span className="hidden sm:inline"></span> }}>
<span className="flex items-center"> {/* Brand */}
Made with <Heart className="w-3.5 h-3.5 text-accent-pink fill-current mx-1" /> for Gen Z <div className="lu-brand" style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
</span> <Link href="#intro" aria-label="LytsUp home" style={{
display: 'inline-flex', marginBottom: 20, textDecoration: 'none',
background: '#fff', border: `3px solid ${INK}`, borderRadius: 14,
padding: '10px 14px', boxShadow: `4px 4px 0 0 ${INK}`,
}}>
<Image src="/images/lytsup_app.png" alt="LytsUp" width={2048} height={554} style={{ height: 30, width: 'auto', display: 'block' }} />
</Link>
<p style={{ fontSize: 14.5, lineHeight: 1.7, color: 'rgba(255,255,255,0.6)', margin: '0 0 24px', maxWidth: 300 }}>
Social currency for real life. Earn LYTs for the things you already do then spend them on stuff you actually want.
</p>
<div style={{ display: 'flex', gap: 12 }}>
{SOCIALS.map(({ label, href, icon, bg }) => (
<a key={label} href={href} target="_blank" rel="noopener noreferrer" aria-label={label}
className="lu-social"
style={{
width: 42, height: 42, borderRadius: 12,
display: 'flex', alignItems: 'center', justifyContent: 'center',
background: bg, color: '#fff', border: `3px solid ${INK}`,
boxShadow: `3px 3px 0 0 ${INK}`,
transition: 'transform 0.12s ease, box-shadow 0.12s ease',
}}
>{icon}</a>
))}
</div>
</div> </div>
{/* Social Icons */} {/* Nav columns */}
<div className="flex space-x-4"> {NAV.map(col => (
<a <nav key={col.title} className="lu-nav" aria-label={col.title}>
href="#" <h4 style={{ display: 'inline-block', margin: '0 0 18px', fontSize: 12, fontWeight: 900, letterSpacing: '0.08em', textTransform: 'uppercase', color: INK, background: col.color, border: `2px solid ${INK}`, borderRadius: 8, padding: '4px 10px', boxShadow: `2px 2px 0 0 ${INK}` }}>
className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-white/60 hover:bg-accent-pink hover:text-white transition-all scale-95 hover:scale-100" {col.title}
aria-label="Instagram" </h4>
> <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 12 }}>
<Instagram className="w-4 h-4" /> {col.links.map(({ label, href }) => (
</a> <li key={label}>
<a <Link href={href} className="lu-link" style={{ textDecoration: 'none', fontSize: 15, color: 'rgba(255,255,255,0.65)', fontWeight: 600, transition: 'color 0.15s, transform 0.15s', display: 'inline-block' }}
href="#" onMouseEnter={e => { const el = e.currentTarget as HTMLElement; el.style.color = col.color; el.style.transform = 'translateX(4px)'; }}
className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-white/60 hover:bg-accent-purple hover:text-white transition-all scale-95 hover:scale-100" onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.color = 'rgba(255,255,255,0.65)'; el.style.transform = 'translateX(0)'; }}
aria-label="Twitter" >{label}</Link>
> </li>
<Twitter className="w-4 h-4" /> ))}
</a> </ul>
<a </nav>
href="#" ))}
className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-white/60 hover:bg-primary hover:text-dark transition-all scale-95 hover:scale-100" </div>
aria-label="Discord"
> {/* ── BOTTOM BAR ── */}
<MessageSquare className="w-4 h-4" /> <div className="lu-bottom" style={{
</a> display: 'flex', alignItems: 'center', justifyContent: 'space-between',
flexWrap: 'wrap', gap: 14,
padding: '18px 48px 30px',
borderTop: `2px dashed rgba(255,255,255,0.2)`,
fontSize: 13, color: 'rgba(255,255,255,0.5)',
}}>
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontWeight: 600 }}>
© {new Date().getFullYear()} LytsUp. Made with
<span style={{ color: '#FF2E88' }}></span> for Gen Z.
</span>
<div style={{ display: 'flex', gap: 20 }}>
{[['Terms', '#'], ['Privacy', '#'], ['Cookies', '#']].map(([l, h]) => (
<Link key={l} href={h} style={{ textDecoration: 'none', color: 'inherit', fontWeight: 600, transition: 'color 0.15s' }}
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.color = '#FFC72C')}
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.color = 'rgba(255,255,255,0.5)')}
>{l}</Link>
))}
</div> </div>
</div> </div>
</div>
</footer> <style>{`
.lu-cta-btn:hover, .lu-social:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 0 ${INK} !important; }
.lu-cta-btn:active { transform: translate(1px, 1px); box-shadow: 2px 2px 0 0 ${INK} !important; }
@media (max-width: 900px) {
.lu-footer { margin: 0 12px 12px; border-radius: 22px; }
.lu-cta-wrap { padding: 32px 20px 24px !important; }
.lu-cta { padding: 32px 26px !important; align-items: flex-start !important; }
.lu-cta-btn { width: 100%; justify-content: center; }
.lu-columns { grid-template-columns: 1fr 1fr !important; gap: 32px 24px !important; padding: 16px 24px 36px !important; }
.lu-brand { grid-column: 1 / -1; }
.lu-bottom { padding: 18px 24px 26px !important; flex-direction: column !important; align-items: flex-start !important; }
}
@media (max-width: 520px) {
.lu-columns { grid-template-columns: 1fr !important; }
.lu-cta-heading { font-size: clamp(26px, 8vw, 40px) !important; }
}
`}</style>
</footer>
{/* Scroll-to-top — neobrutalist */}
<style>{`
@keyframes luBounce { 0%,100% { transform: translateY(0);} 40% { transform: translateY(-4px);} 60% { transform: translateY(-2px);} }
.lu-stt:hover { transform: translate(-2px,-2px) !important; box-shadow: 6px 6px 0 0 ${INK} !important; }
.lu-stt:active { transform: translate(1px,1px) !important; box-shadow: 1px 1px 0 0 ${INK} !important; }
.lu-stt-arrow { animation: luBounce 1.5s ease-in-out infinite; }
`}</style>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
aria-label="Scroll to top"
className="lu-stt"
style={{
position: 'fixed', bottom: 28, right: 28, zIndex: 9999,
width: 60, height: 60, borderRadius: 16,
background: '#FFC72C', color: INK, border: `3px solid ${INK}`,
cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
boxShadow: `4px 4px 0 0 ${INK}`,
opacity: showScroll ? 1 : 0,
transform: showScroll ? 'translateY(0)' : 'translateY(16px)',
pointerEvents: showScroll ? 'auto' : 'none',
transition: 'opacity 0.25s ease, transform 0.15s ease, box-shadow 0.15s ease',
}}
>
<span className="lu-stt-arrow" style={{ display: 'flex' }}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
</span>
</button>
</>
); );
} }

View File

@@ -0,0 +1,383 @@
'use client';
import { useState, useEffect, useRef } from 'react';
import Link from 'next/link';
import Image from 'next/image';
const INK = '#0a0a0a';
const NAV_LINKS = [
{ label: 'Earn', href: '#for-you', color: '#C8FF37' }, // lime
{ label: 'Spend', href: '#difference', color: '#FF2E88' }, // pink
{ label: 'Live', href: '#the-vision', color: '#8B3DFF' }, // purple
];
const MOBILE_QUERY = '(max-width: 1023px)';
export default function Header() {
const [mobileOpen, setMobileOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
const [hidden, setHidden] = useState(false);
const mobileMenuRef = useRef<HTMLDivElement>(null);
const lastScrollYRef = useRef(0);
// Hide on scroll-down, reveal on scroll-up; deepen the shadow once scrolled.
useEffect(() => {
lastScrollYRef.current = window.scrollY;
const onScroll = () => {
const y = window.scrollY;
setScrolled(y > 40);
const lastY = lastScrollYRef.current;
if (y <= 80) setHidden(false);
else if (y > lastY + 4) setHidden(true);
else if (y < lastY - 4) setHidden(false);
lastScrollYRef.current = y;
};
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
useEffect(() => {
if (mobileOpen) setHidden(false);
}, [mobileOpen]);
useEffect(() => {
if (!mobileOpen) return;
const handler = (e: MouseEvent) => {
if (mobileMenuRef.current && !mobileMenuRef.current.contains(e.target as Node)) {
setMobileOpen(false);
}
};
document.addEventListener('mousedown', handler);
return () => document.removeEventListener('mousedown', handler);
}, [mobileOpen]);
useEffect(() => {
document.body.style.overflow = mobileOpen ? 'hidden' : '';
return () => { document.body.style.overflow = ''; };
}, [mobileOpen]);
const [isMobileViewport, setIsMobileViewport] = useState(false);
useEffect(() => {
const mql = window.matchMedia(MOBILE_QUERY);
setIsMobileViewport(mql.matches);
const update = () => setIsMobileViewport(mql.matches);
mql.addEventListener('change', update);
return () => mql.removeEventListener('change', update);
}, []);
return (
<div suppressHydrationWarning>
{/* Mobile menu overlay */}
{mobileOpen && (
<div
onClick={() => setMobileOpen(false)}
aria-hidden="true"
style={{ position: 'fixed', inset: 0, zIndex: 99999998, background: 'rgba(10,4,20,0.6)' }}
/>
)}
{/* Mobile slide-in panel — night dot-grid, neobrutalist links */}
<div
ref={mobileMenuRef}
role="dialog"
aria-label="Navigation menu"
aria-modal="true"
className="bg-night"
style={{
position: 'fixed',
top: 0,
left: 0,
height: '100%',
width: 'min(330px, 86vw)',
zIndex: 999999999,
color: '#fff',
transform: mobileOpen ? 'translateX(0)' : 'translateX(-100%)',
transition: 'transform 0.32s cubic-bezier(0.34,1.3,0.64,1)',
overflowY: 'auto',
padding: '22px 24px 40px',
display: 'flex',
flexDirection: 'column',
gap: '28px',
// Border + shadow only while open, so nothing bleeds onto the screen's
// left edge when the panel is parked off-screen.
borderRight: mobileOpen ? `4px solid ${INK}` : 'none',
boxShadow: mobileOpen ? `8px 0 0 0 rgba(0,0,0,0.35)` : 'none',
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ display: 'inline-flex', background: '#fff', border: `3px solid ${INK}`, borderRadius: 14, padding: '8px 12px', boxShadow: `4px 4px 0 0 ${INK}` }}>
<Image src="/images/lytsup_app.png" alt="LytsUp" width={2048} height={554} priority style={{ height: 24, width: 'auto', display: 'block' }} />
</span>
<button
onClick={() => setMobileOpen(false)}
aria-label="Close menu"
style={{ background: '#FF2E88', color: '#fff', border: `3px solid ${INK}`, borderRadius: 12, width: 40, height: 40, fontSize: 20, fontWeight: 900, cursor: 'pointer', lineHeight: 1, boxShadow: `3px 3px 0 0 ${INK}` }}
>
</button>
</div>
<nav>
<ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '12px' }}>
{NAV_LINKS.map(({ label, href, color }) => (
<li key={href}>
<Link
href={href}
onClick={() => setMobileOpen(false)}
className="font-sora"
style={{
display: 'block',
padding: '14px 18px',
color: INK,
background: color,
textDecoration: 'none',
fontSize: '18px',
fontWeight: 800,
textTransform: 'uppercase',
letterSpacing: '0.02em',
border: `3px solid ${INK}`,
borderRadius: 14,
boxShadow: `4px 4px 0 0 ${INK}`,
}}
>
{label}
</Link>
</li>
))}
</ul>
</nav>
<div>
<p className="font-sora" style={{ margin: '0 0 12px', fontWeight: 800, textTransform: 'uppercase', fontSize: '11px', letterSpacing: '0.12em', color: '#FFC72C' }}>
Follow us
</p>
<div style={{ display: 'flex', gap: '12px' }}>
{SOCIALS.map(({ href, label, icon }) => (
<a
key={label}
href={href}
target="_blank"
rel="noopener noreferrer"
aria-label={label}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 40, height: 40, borderRadius: 12, background: '#fff', color: INK, border: `3px solid ${INK}`, boxShadow: `3px 3px 0 0 ${INK}` }}
>
{icon}
</a>
))}
</div>
</div>
<Link
href="#for-business"
onClick={() => setMobileOpen(false)}
className="font-sora"
style={{
display: 'block',
marginTop: 'auto',
padding: '16px 24px',
background: '#FFC72C',
color: INK,
border: `3px solid ${INK}`,
borderRadius: 14,
fontWeight: 900,
fontSize: 16,
textTransform: 'uppercase',
textDecoration: 'none',
textAlign: 'center',
boxShadow: `5px 5px 0 0 ${INK}`,
}}
>
Get Started
</Link>
</div>
{/* ——— Funky neobrutalist floating bar ——— */}
<header
style={{
position: 'fixed',
top: isMobileViewport ? '14px' : '18px',
left: 0,
right: 0,
width: isMobileViewport ? 'auto' : '70%',
maxWidth: 'calc(100% - 2 * var(--hdr-gutter))',
marginLeft: isMobileViewport ? 'var(--hdr-gutter)' : 'auto',
marginRight: isMobileViewport ? 'var(--hdr-gutter)' : 'auto',
zIndex: 99999999,
background: '#FFFDF5',
border: `3px solid ${INK}`,
borderRadius: '20px',
boxShadow: scrolled ? `8px 8px 0 0 ${INK}` : `5px 6px 0 0 ${INK}`,
transform: hidden ? 'translateY(-160%)' : 'translateY(0)',
transition: 'transform 0.35s cubic-bezier(0.4,0,0.2,1), box-shadow 0.25s ease',
}}
>
<div className="header-inner" style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '0 22px',
height: '72px',
width: '100%',
boxSizing: 'border-box',
gap: 16,
}}>
{/* Logo */}
<div style={{ display: 'flex', alignItems: 'center' }}>
<Link href="#intro" aria-label="LytsUp home" style={{ display: 'inline-flex', alignItems: 'center', textDecoration: 'none' }}>
<Image
src="/images/lytsup_app.png"
alt="LytsUp"
width={2048}
height={554}
priority
className="header-logo-img"
style={{ height: 34, width: 'auto', objectFit: 'contain', display: 'block' }}
/>
</Link>
</div>
{/* Desktop nav — boxy neobrutalist sticker tabs */}
<nav aria-label="Main navigation" className="desktop-nav">
<ul className="header-nav-row" style={{
display: 'flex',
listStyle: 'none',
margin: 0,
padding: 0,
alignItems: 'center',
gap: 12,
}}>
{NAV_LINKS.map(({ label, href, color }, i) => {
const tilt = i % 2 === 0 ? -2 : 2;
return (
<li key={href}>
<Link
href={href}
className="header-nav-tab font-sora"
style={{
display: 'inline-flex',
alignItems: 'center',
gap: 8,
padding: '8px 16px',
color: INK,
textDecoration: 'none',
fontWeight: 800,
fontSize: '13px',
letterSpacing: '0.05em',
textTransform: 'uppercase',
borderRadius: '12px',
background: '#fff',
border: `2.5px solid ${INK}`,
boxShadow: `3px 3px 0 0 ${INK}`,
transition: 'transform 0.15s, background 0.15s, box-shadow 0.15s',
whiteSpace: 'nowrap',
transform: `rotate(${tilt}deg)`,
['--hov' as string]: color,
['--tilt' as string]: `${tilt}deg`,
}}
>
<span
style={{ width: 8, height: 8, borderRadius: 3, background: color, border: `1.5px solid ${INK}`, flexShrink: 0 }}
/>
{label}
</Link>
</li>
);
})}
</ul>
</nav>
{/* Right actions */}
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<Link
href="#for-business"
className="header-cta desktop-nav font-sora"
style={{
display: 'inline-flex',
alignItems: 'center',
padding: '11px 26px',
background: '#FFC72C',
color: INK,
border: `3px solid ${INK}`,
borderRadius: '50px',
fontWeight: 900,
textDecoration: 'none',
fontSize: '14px',
textTransform: 'uppercase',
letterSpacing: '0.03em',
whiteSpace: 'nowrap',
boxShadow: `3px 3px 0 0 ${INK}`,
transition: 'transform 0.12s ease, box-shadow 0.12s ease, background 0.15s',
}}
>
Get Started
</Link>
{/* Hamburger — mobile only */}
<button
className="menu-trigger"
onClick={() => setMobileOpen(true)}
aria-label="Open navigation menu"
aria-expanded={mobileOpen}
style={{ background: '#8B3DFF', border: `3px solid ${INK}`, borderRadius: 12, cursor: 'pointer', padding: 0, width: 44, height: 44, display: 'none', alignItems: 'center', justifyContent: 'center', boxShadow: `3px 3px 0 0 ${INK}` }}
>
<span style={{ display: 'flex', flexDirection: 'column', gap: '4px', width: '20px' }}>
<span style={{ display: 'block', height: '3px', background: '#fff', borderRadius: '2px' }} />
<span style={{ display: 'block', height: '3px', background: '#fff', borderRadius: '2px' }} />
<span style={{ display: 'block', height: '3px', background: '#fff', borderRadius: '2px' }} />
</span>
</button>
</div>
</div>
</header>
<style>{`
@media (max-width: 1023px) {
.desktop-nav { display: none !important; }
.menu-trigger { display: flex !important; }
.header-inner { height: 60px !important; }
.header-logo-img { height: 28px !important; }
}
@media (min-width: 1024px) and (max-width: 1200px) {
.header-nav-tab { padding: 7px 12px !important; font-size: 11px !important; letter-spacing: 0.03em !important; }
.header-cta { padding: 9px 18px !important; font-size: 12px !important; }
.header-logo-img { height: 30px !important; }
}
.header-nav-tab:hover {
background: var(--hov) !important;
transform: translateY(-3px) rotate(var(--tilt));
box-shadow: 5px 5px 0 0 ${INK} !important;
}
.header-nav-tab:active {
transform: translateY(1px) rotate(var(--tilt));
box-shadow: 1px 1px 0 0 ${INK} !important;
}
.header-cta:hover {
background: #FFD95A !important;
transform: translate(-2px, -2px);
box-shadow: 5px 5px 0 0 ${INK} !important;
}
.header-cta:active {
transform: translate(1px, 1px);
box-shadow: 1px 1px 0 0 ${INK} !important;
}
`}</style>
</div>
);
}
/* ——— Inline SVG social icons ——— */
const SOCIALS = [
{
label: 'Instagram', href: 'https://instagram.com/lytsup',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2.16c3.2 0 3.58.01 4.85.07 3.25.15 4.77 1.69 4.92 4.92.06 1.27.07 1.65.07 4.85 0 3.2-.01 3.58-.07 4.85-.15 3.23-1.66 4.77-4.92 4.92-1.27.06-1.64.07-4.85.07-3.2 0-3.58-.01-4.85-.07-3.26-.15-4.77-1.7-4.92-4.92-.06-1.27-.07-1.64-.07-4.85 0-3.2.01-3.58.07-4.85.15-3.23 1.66-4.77 4.92-4.92C8.42 2.17 8.8 2.16 12 2.16zm0-2.16C8.74 0 8.33.01 7.05.07 2.7.27.27 2.69.07 7.05.01 8.33 0 8.74 0 12s.01 3.67.07 4.95c.2 4.36 2.62 6.78 6.98 6.98C8.33 23.99 8.74 24 12 24s3.67-.01 4.95-.07c4.35-.2 6.78-2.62 6.98-6.98.06-1.28.07-1.69.07-4.95s-.01-3.67-.07-4.95c-.2-4.35-2.62-6.78-6.98-6.98C15.67.01 15.26 0 12 0zm0 5.84a6.16 6.16 0 100 12.32 6.16 6.16 0 000-12.32zM12 16a4 4 0 110-8 4 4 0 010 8zm6.41-11.85a1.44 1.44 0 100 2.88 1.44 1.44 0 000-2.88z"/></svg>,
},
{
label: 'X / Twitter', href: 'https://twitter.com/lytsup',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M13.98 10.62 20.54 3h-1.55l-5.7 6.62L8.74 3H3.5l6.88 10.01L3.5 21h1.55l6.01-6.99L15.87 21h5.24l-7.13-10.38zm-2.13 2.47-.7-1-5.54-7.93H8l4.47 6.4.7 1 5.82 8.32h-2.39l-4.74-6.79z"/></svg>,
},
{
label: 'YouTube', href: 'https://www.youtube.com/@lytsup',
icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M21.8 8s-.2-1.38-.8-1.99c-.76-.8-1.61-.8-2-.85C16.2 5 12 5 12 5s-4.2 0-7 .17c-.39.05-1.24.05-2 .85C2.4 6.62 2.2 8 2.2 8S2 9.62 2 11.24v1.52c0 1.62.2 3.24.2 3.24s.2 1.38.8 1.99c.76.8 1.76.77 2.2.85C6.8 19 12 19.03 12 19.03s4.2-.01 7-.22c.39-.05 1.24-.05 2-.85.6-.61.8-1.99.8-1.99S22 14.38 22 12.76v-1.52C22 9.62 21.8 8 21.8 8zm-11.87 6.59V8.79l5.4 2.82-5.4 2.98z"/></svg>,
},
];

View File

@@ -0,0 +1,38 @@
"use client";
import { useEffect, useRef } from "react";
/* Site-wide reading-progress bar — sits at the very top edge and fills with the
brand gradient as you scroll. Driven by a rAF lerp so it glides smoothly and
works with Lenis smooth-scroll (reads native window.scrollY). */
export default function ScrollProgress() {
const barRef = useRef<HTMLDivElement>(null);
const target = useRef(0);
const current = useRef(0);
useEffect(() => {
let raf = 0;
const tick = () => {
// Read scroll position every frame so it tracks regardless of how the
// smooth-scroll library emits events.
const max = document.documentElement.scrollHeight - window.innerHeight;
target.current = max > 0 ? Math.min(1, Math.max(0, window.scrollY / max)) : 0;
current.current += (target.current - current.current) * 0.12;
if (barRef.current) {
barRef.current.style.transform = `scaleX(${current.current.toFixed(4)})`;
}
raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
return () => cancelAnimationFrame(raf);
}, []);
return (
<div
aria-hidden
ref={barRef}
className="fixed left-0 top-0 z-[100000000] h-1.5 w-full origin-left bg-gradient-to-r from-[#FFC72C] via-[#FF2E88] to-[#8B3DFF]"
style={{ transform: "scaleX(0)" }}
/>
);
}

View File

@@ -1,45 +1,109 @@
import { Section, Pill, Card, Chip, Heading, Logo, Group, Reveal } from "./ui"; import { Section, Pill, Card, Chip, Heading, Group, Reveal } from "./ui";
import { C } from "./palette"; import { C } from "./palette";
/* 01 — INTRO / HERO */ /* 01 — INTRO / HERO */
export function Intro() { export function Intro() {
return ( return (
<Section id="intro" variant="deep"> <Section id="intro" variant="deep">
{/* giant watermark */} {/* animated ambient glows — soft washes, heavily blurred so no hard edge shows */}
<span className="pointer-events-none absolute right-0 top-1/2 -z-0 -translate-y-1/2 select-none font-sora text-[28vw] font-extrabold leading-none text-white/5"> <span aria-hidden className="animate-pulse-glow pointer-events-none absolute -left-40 -top-16 -z-0 h-[30rem] w-[30rem] rounded-full bg-[#FF2E88]/15 blur-[150px]" />
<span aria-hidden className="animate-float pointer-events-none absolute -bottom-16 left-1/4 -z-0 h-[28rem] w-[28rem] rounded-full bg-[#8B3DFF]/20 blur-[150px]" />
<span aria-hidden className="animate-float pointer-events-none absolute -right-16 top-1/3 -z-0 h-[26rem] w-[26rem] rounded-full bg-[#C8FF37]/10 blur-[140px]" style={{ animationDelay: "1.5s" }} />
{/* giant drifting watermark */}
<span className="animate-float pointer-events-none absolute right-0 top-1/2 -z-0 -translate-y-1/2 select-none font-sora text-[28vw] font-extrabold leading-none text-white/[0.06]">
LYTS LYTS
</span> </span>
<div className="relative z-10">
<Card bg="#fff" className="mb-8 w-fit px-6 py-4" rounded="rounded-2xl"> <div className="relative z-10 pt-24 sm:pt-28 lg:pt-32">
<Logo /> {/* eyebrow badge */}
</Card> <Reveal>
<div className="mt-8 space-y-1 font-bold text-[#FFD21E] sm:text-lg"> <span className="nb inline-flex items-center gap-2.5 rounded-full bg-[#C8FF37] px-5 py-2.5 font-sora text-sm font-extrabold uppercase tracking-wide text-[#0a0a0a]">
<p>we built this for you.</p> <span className="relative flex h-2.5 w-2.5">
<p> <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-[#FF2E88] opacity-75" />
social currency is value earned for <em className="italic">participating</em> in life. <span className="relative inline-flex h-2.5 w-2.5 rounded-full bg-[#FF2E88]" />
</p>
<p>a LYTIAN believes every meaningful interaction has value.</p>
</div>
<h1 className="mt-8 font-sora text-6xl font-extrabold leading-[0.9] tracking-tight text-white sm:text-7xl lg:text-8xl">
social
<br />
currency
<br />
for real life.
</h1>
<div className="mt-8">
<Chip bg="#0a0a0a" text="#fff">
<span className="text-[#C8FF37]">&quot;earn. spend. live more.&quot;</span>
<span className="ml-2 font-semibold text-white/80">
a quiet belief that everyday moments matter.
</span> </span>
</Chip> social currency, reimagined
</div> </span>
</Reveal>
{/* eyebrow copy */}
<Reveal delay={0.08}>
<div className="mt-6 space-y-1 font-bold text-[#FFD21E] sm:text-lg">
<p>we built this for you.</p>
<p>
social currency is value earned for <em className="italic">participating</em> in life.
</p>
<p>a LYTIAN believes every meaningful interaction has value.</p>
</div>
</Reveal>
{/* headline — line-by-line reveal, shimmering last line */}
<h1 className="mt-8 font-sora text-6xl font-extrabold leading-[0.88] tracking-tight text-white sm:text-7xl lg:text-8xl">
<Reveal delay={0.14}><span className="block">social</span></Reveal>
<Reveal delay={0.22}><span className="block">currency</span></Reveal>
<Reveal delay={0.3}>
<span className="block">
for{" "}
<span className="animate-shimmer bg-gradient-to-r from-[#FFC72C] via-[#FF2E88] to-[#8B3DFF] bg-[length:200%_auto] bg-clip-text text-transparent">
real life.
</span>
</span>
</Reveal>
</h1>
{/* CTA buttons */}
<Reveal delay={0.38}>
<div className="mt-9 flex flex-col items-start gap-4 sm:flex-row sm:items-center">
<a
href="#for-business"
className="nb nb-hover inline-flex items-center gap-2 rounded-full bg-[#FFC72C] px-8 py-4 font-sora text-base font-extrabold uppercase tracking-wide text-[#0a0a0a] sm:text-lg"
>
Get Started
<span aria-hidden></span>
</a>
<a
href="#how-it-works"
className="nb nb-hover inline-flex items-center gap-2 rounded-full bg-white px-8 py-4 font-sora text-base font-extrabold uppercase tracking-wide text-[#0a0a0a] sm:text-lg"
>
How it works
</a>
</div>
</Reveal>
{/* tagline chip */}
<Reveal delay={0.46}>
<div className="mt-8">
<Chip bg="#0a0a0a" text="#fff">
<span className="text-[#C8FF37]">&quot;earn. spend. live more.&quot;</span>
<span className="ml-2 font-semibold text-white/80">
a quiet belief that everyday moments matter.
</span>
</Chip>
</div>
</Reveal>
</div> </div>
<div className="absolute right-8 top-24 hidden h-40 w-40 rotate-6 items-center justify-center rounded-full bg-[#FFD21E] text-center font-sora text-lg font-extrabold text-[#0a0a0a] nb lg:flex">
<div> {/* floating reward stickers (desktop) */}
<div className="text-xs font-bold text-[#FF2E88]">psst</div> <div aria-hidden className="pointer-events-none absolute inset-0 -z-0 hidden lg:block">
make everyday count. <span className="animate-float nb-sm absolute right-[16%] top-[20%] -rotate-6 rounded-xl bg-[#FF2E88] px-4 py-2 font-sora text-lg font-extrabold text-white">
+50 LYTs
</span>
<span className="animate-float nb-sm absolute right-[30%] top-[52%] rotate-6 rounded-xl bg-white px-4 py-2 font-sora text-lg font-extrabold text-[#0a0a0a]" style={{ animationDelay: "0.8s" }}>
🔥 7-day streak
</span>
<span className="animate-float nb-sm absolute bottom-[16%] right-[20%] -rotate-3 rounded-xl bg-[#C8FF37] px-4 py-2 font-sora text-lg font-extrabold text-[#0a0a0a]" style={{ animationDelay: "1.6s" }}>
🎁 rewards unlocked
</span>
</div>
{/* rotating "make everyday count" badge — pinned to the right, vertically centered */}
<div className="absolute right-8 top-1/2 hidden -translate-y-1/2 lg:block">
<div className="animate-float nb flex h-40 w-40 rotate-6 items-center justify-center rounded-full bg-[#FFD21E] text-center font-sora text-lg font-extrabold text-[#0a0a0a]">
<div>
<div className="text-xs font-bold uppercase tracking-widest text-[#FF2E88]">psst</div>
make everyday count.
</div>
</div> </div>
</div> </div>
</Section> </Section>
@@ -78,7 +142,7 @@ export function TheWhy() {
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<Card bg="#fff" className="-rotate-1 p-5"> <Card bg="#fff" className="-rotate-1 p-5">
<div className="font-sora font-extrabold">🎬 DISCOVER ON TIKTOK</div> <div className="font-sora font-extrabold">🎬 DISCOVER ON SOCIAL MEDIA</div>
<div className="text-sm font-semibold text-black/70">brand relationships start before purchase</div> <div className="text-sm font-semibold text-black/70">brand relationships start before purchase</div>
</Card> </Card>
<Card bg={C.pink} text="#fff" className="rotate-1 p-5"> <Card bg={C.pink} text="#fff" className="rotate-1 p-5">

View File

@@ -231,22 +231,20 @@ export function OurBelief() {
return ( return (
<Section id="our-belief" variant="night"> <Section id="our-belief" variant="night">
<div className="mx-auto flex flex-col items-center text-center"> <div className="mx-auto flex flex-col items-center text-center">
<span className="nb flex h-20 w-20 items-center justify-center rounded-full bg-[#0a0a0a] font-sora text-sm font-extrabold text-[#FFD21E] ring-2 ring-[#FF2E88]"> <Pill bg="#0a0a0a" text={C.yellow}>🌱 our belief</Pill>
🌱 our belief
</span>
</div> </div>
<div className="mt-12 space-y-6"> <div className="mt-14 space-y-8">
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-start gap-4">
<span className="flex h-8 w-8 items-center justify-center rounded bg-[#0a0a0a] font-extrabold text-white ring-2 ring-white/20">1</span> <span className="nb-sm flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-[#0a0a0a] font-sora text-2xl font-extrabold text-white">1</span>
<h3 className="font-sora text-4xl font-extrabold leading-tight sm:text-5xl"> <h3 className="font-sora text-4xl font-extrabold leading-[1.05] tracking-tight sm:text-6xl">
<span className="strike-pink">traditional loyalty</span> begins when you SPEND. <span className="strike-pink">traditional loyalty</span> begins when you <span className="text-[#FFD21E]">SPEND.</span>
</h3> </h3>
</div> </div>
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-start gap-4">
<span className="flex h-8 w-8 items-center justify-center rounded bg-[#C8FF37] font-extrabold text-[#0a0a0a]">2</span> <span className="nb-sm flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-[#C8FF37] font-sora text-2xl font-extrabold text-[#0a0a0a]">2</span>
<div className="nb-lg w-full rounded-2xl bg-gradient-to-r from-[#FF2E88] to-[#A020F0] p-6"> <div className="nb-lg w-full rounded-3xl bg-gradient-to-r from-[#FF2E88] to-[#A020F0] p-7 sm:p-9">
<h3 className="font-sora text-4xl font-extrabold leading-tight text-white sm:text-5xl"> <h3 className="font-sora text-4xl font-extrabold leading-[1.05] tracking-tight text-white sm:text-6xl">
<span className="nb-sm bg-[#C8FF37] px-2 text-[#0a0a0a]">LYTs</span> begins when you ENGAGE. <span className="nb-sm inline-block rounded-lg bg-[#C8FF37] px-3 py-0.5 text-[#0a0a0a]">LYTs</span> begins when you ENGAGE.
</h3> </h3>
</div> </div>
</div> </div>

View File

@@ -7,20 +7,23 @@ import { C } from "./palette";
export { C }; export { C };
const viewport = { once: true, amount: 0.25 } as const; const viewport = { once: true, amount: 0.2 } as const;
/* Shared smooth easing — a soft, premium ease-out curve reused across reveals. */
const smoothEase = [0.22, 1, 0.36, 1] as const;
/* stagger container variants */ /* stagger container variants */
export const stagger: Variants = { export const stagger: Variants = {
hidden: {}, hidden: {},
show: { transition: { staggerChildren: 0.09, delayChildren: 0.05 } }, show: { transition: { staggerChildren: 0.11, delayChildren: 0.06 } },
}; };
export const riseItem: Variants = { export const riseItem: Variants = {
hidden: { opacity: 0, y: 30, scale: 0.96 }, hidden: { opacity: 0, y: 34, scale: 0.96 },
show: { show: {
opacity: 1, opacity: 1,
y: 0, y: 0,
scale: 1, scale: 1,
transition: { type: "spring", stiffness: 130, damping: 16 }, transition: { duration: 0.7, ease: smoothEase },
}, },
}; };
@@ -44,7 +47,7 @@ export function Section({ id, children, variant = "deep", className = "" }: Sect
return ( return (
<section <section
id={id} id={id}
className={`relative flex min-h-screen w-full flex-col justify-center overflow-hidden px-6 py-20 sm:px-10 lg:px-20 ${bg} ${className}`} className={`relative m-5 flex min-h-[calc(100vh-40px)] flex-col justify-center overflow-hidden rounded-[20px] px-6 py-20 sm:px-10 lg:px-20 ${bg} ${className}`}
> >
<div className="mx-auto w-full max-w-6xl">{children}</div> <div className="mx-auto w-full max-w-6xl">{children}</div>
</section> </section>
@@ -69,7 +72,7 @@ export function Reveal({
initial={{ opacity: 0, y }} initial={{ opacity: 0, y }}
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
viewport={viewport} viewport={viewport}
transition={{ type: "spring", stiffness: 120, damping: 18, delay }} transition={{ duration: 0.7, ease: smoothEase, delay }}
> >
{children} {children}
</motion.div> </motion.div>
@@ -109,12 +112,13 @@ export function Pill({
}) { }) {
return ( return (
<motion.span <motion.span
className="nb-sm inline-flex items-center gap-2 rounded-full px-4 py-1.5 text-xs font-extrabold uppercase tracking-wide sm:text-sm" className="nb inline-flex items-center gap-2.5 rounded-full px-6 py-3 text-lg font-extrabold uppercase tracking-wide sm:px-8 sm:py-4 sm:text-2xl"
style={{ background: bg, color: text }} style={{ background: bg, color: text }}
initial={{ opacity: 0, scale: 0.8, y: 12 }} initial={{ opacity: 0, scale: 0.8, y: 12 }}
whileInView={{ opacity: 1, scale: 1, y: 0 }} whileInView={{ opacity: 1, scale: 1, y: 0 }}
viewport={viewport} viewport={viewport}
transition={{ type: "spring", stiffness: 320, damping: 15 }} transition={{ type: "spring", stiffness: 320, damping: 15 }}
whileHover={{ rotate: -2, scale: 1.04 }}
> >
{children} {children}
</motion.span> </motion.span>
@@ -146,7 +150,7 @@ export function Card({
initial: { opacity: 0, y: 30, scale: 0.96 }, initial: { opacity: 0, y: 30, scale: 0.96 },
whileInView: { opacity: 1, y: 0, scale: 1 }, whileInView: { opacity: 1, y: 0, scale: 1 },
viewport, viewport,
transition: { type: "spring" as const, stiffness: 130, damping: 16, delay }, transition: { duration: 0.7, ease: smoothEase, delay },
}; };
return ( return (
<motion.div <motion.div
@@ -206,7 +210,7 @@ export function Heading({
initial={{ opacity: 0, y: 28 }} initial={{ opacity: 0, y: 28 }}
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
viewport={viewport} viewport={viewport}
transition={{ type: "spring", stiffness: 120, damping: 18 }} transition={{ duration: 0.75, ease: smoothEase }}
> >
{children} {children}
</motion.h2> </motion.h2>