feat(landing): add landing page with Hero, HowItWorks and FeatureCards
This commit is contained in:
parent
767970b6e6
commit
4f514a4e99
4 changed files with 164 additions and 2 deletions
45
apps/web/src/components/landing/FeatureCards.tsx
Normal file
45
apps/web/src/components/landing/FeatureCards.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
const features = [
|
||||
{
|
||||
emoji: "📱",
|
||||
title: "Mobile-first",
|
||||
description: "Designed for your thumb. Play on the go, anytime.",
|
||||
},
|
||||
{
|
||||
emoji: "🌍",
|
||||
title: "5 languages",
|
||||
description:
|
||||
"English, Italian, German, French, Spanish — with more on the way.",
|
||||
},
|
||||
{
|
||||
emoji: "⚔️",
|
||||
title: "Multiplayer coming",
|
||||
description: "Challenge friends and see who has the bigger vocabulary.",
|
||||
},
|
||||
];
|
||||
|
||||
const FeatureCards = () => {
|
||||
return (
|
||||
<section className="py-16">
|
||||
<h2 className="text-center text-3xl font-black tracking-tight text-(--color-text) mb-12">
|
||||
Why lila
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{features.map(({ emoji, title, description }) => (
|
||||
<div
|
||||
key={title}
|
||||
className="flex flex-col gap-3 p-6 rounded-2xl border border-(--color-primary-light)"
|
||||
>
|
||||
<span className="text-3xl">{emoji}</span>
|
||||
<h3 className="text-lg font-bold text-(--color-text)">{title}</h3>
|
||||
<p className="text-sm text-(--color-text-muted) leading-relaxed">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeatureCards;
|
||||
64
apps/web/src/components/landing/Hero.tsx
Normal file
64
apps/web/src/components/landing/Hero.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { Link } from "@tanstack/react-router";
|
||||
import { useSession } from "../../lib/auth-client";
|
||||
|
||||
const Hero = () => {
|
||||
const { data: session } = useSession();
|
||||
|
||||
return (
|
||||
<section className="relative flex flex-col items-center text-center pt-20 pb-16">
|
||||
<div className="-rotate-1 mb-2">
|
||||
<span className="text-sm font-semibold tracking-widest uppercase text-(--color-accent)">
|
||||
Vocabulary trainer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-6xl font-black tracking-tight text-(--color-text) leading-tight">
|
||||
Meet{" "}
|
||||
<span className="inline-block rotate-1 px-3 py-1 bg-(--color-primary) text-white rounded-xl">
|
||||
lila
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p className="mt-6 text-xl font-medium text-(--color-text-muted) max-w-sm">
|
||||
Learn words.{" "}
|
||||
<span className="text-(--color-accent) font-bold">Beat friends.</span>
|
||||
</p>
|
||||
|
||||
<div className="mt-4 flex gap-2 flex-wrap justify-center">
|
||||
{["🇬🇧", "🇮🇹", "🇩🇪", "🇫🇷", "🇪🇸"].map((flag) => (
|
||||
<span key={flag} className="text-2xl">
|
||||
{flag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-10 flex gap-4">
|
||||
{session ? (
|
||||
<Link
|
||||
to="/play"
|
||||
className="px-8 py-3 rounded-full text-white font-bold text-sm bg-(--color-primary) hover:bg-(--color-primary-dark)"
|
||||
>
|
||||
Start playing →
|
||||
</Link>
|
||||
) : (
|
||||
<>
|
||||
<Link
|
||||
to="/login"
|
||||
className="px-8 py-3 rounded-full text-white font-bold text-sm bg-(--color-primary) hover:bg-(--color-primary-dark)"
|
||||
>
|
||||
Get started →
|
||||
</Link>
|
||||
<Link
|
||||
to="/login"
|
||||
className="px-8 py-3 rounded-full font-bold text-sm text-(--color-primary) border-2 border-(--color-primary) hover:bg-(--color-surface)"
|
||||
>
|
||||
Login
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
48
apps/web/src/components/landing/HowItWorks.tsx
Normal file
48
apps/web/src/components/landing/HowItWorks.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
const steps = [
|
||||
{
|
||||
number: "01",
|
||||
title: "See a word",
|
||||
description:
|
||||
"A word appears in your target language, ready to challenge you.",
|
||||
},
|
||||
{
|
||||
number: "02",
|
||||
title: "Pick the translation",
|
||||
description:
|
||||
"Choose from four options. Only one is correct — trust your gut.",
|
||||
},
|
||||
{
|
||||
number: "03",
|
||||
title: "Track your score",
|
||||
description: "See how you did and challenge a friend to beat it.",
|
||||
},
|
||||
];
|
||||
|
||||
const HowItWorks = () => {
|
||||
return (
|
||||
<section className="py-16">
|
||||
<h2 className="text-center text-3xl font-black tracking-tight text-(--color-text) mb-12">
|
||||
How it works
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{steps.map(({ number, title, description }) => (
|
||||
<div
|
||||
key={number}
|
||||
className="flex flex-col gap-3 p-6 rounded-2xl bg-(--color-surface) border border-(--color-primary-light)"
|
||||
>
|
||||
<span className="text-4xl font-black text-(--color-primary-light)">
|
||||
{number}
|
||||
</span>
|
||||
<h3 className="text-lg font-bold text-(--color-text)">{title}</h3>
|
||||
<p className="text-sm text-(--color-text-muted) leading-relaxed">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default HowItWorks;
|
||||
|
|
@ -1,11 +1,16 @@
|
|||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import Hero from "../components/landing/Hero";
|
||||
import HowItWorks from "../components/landing/HowItWorks";
|
||||
import FeatureCards from "../components/landing/FeatureCards";
|
||||
|
||||
export const Route = createFileRoute("/")({ component: Index });
|
||||
|
||||
function Index() {
|
||||
return (
|
||||
<div className="p-2 text-3xl text-amber-400">
|
||||
<h3>Welcome Home!</h3>
|
||||
<div className="flex flex-col">
|
||||
<Hero />
|
||||
<HowItWorks />
|
||||
<FeatureCards />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue