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 { 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 });
|
export const Route = createFileRoute("/")({ component: Index });
|
||||||
|
|
||||||
function Index() {
|
function Index() {
|
||||||
return (
|
return (
|
||||||
<div className="p-2 text-3xl text-amber-400">
|
<div className="flex flex-col">
|
||||||
<h3>Welcome Home!</h3>
|
<Hero />
|
||||||
|
<HowItWorks />
|
||||||
|
<FeatureCards />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue