diff --git a/job-tracker-ui/src/App.tsx b/job-tracker-ui/src/App.tsx
index 228c397..15e49cc 100644
--- a/job-tracker-ui/src/App.tsx
+++ b/job-tracker-ui/src/App.tsx
@@ -28,6 +28,7 @@ import JobTable from "./components/JobTable";
import type { JobTableColumns } from "./components/JobTable";
import { I18nProvider, useI18n } from "./i18n/I18nProvider";
import LoginPage from "./pages/LoginPage";
+import LandingPage from "./pages/LandingPage";
import ForgotPasswordPage from "./pages/ForgotPasswordPage";
import ResetPasswordPage from "./pages/ResetPasswordPage";
import RouteErrorPage from "./pages/RouteErrorPage";
@@ -344,6 +345,7 @@ export default function App() {
});
const router = useMemo(() => createBrowserRouter([
+ { path: "/", element: , errorElement: },
{ path: "/login", element: , errorElement: },
{ path: "/forgot-password", element: , errorElement: },
{ path: "/reset-password", element: , errorElement: },
diff --git a/job-tracker-ui/src/pages/LandingPage.tsx b/job-tracker-ui/src/pages/LandingPage.tsx
new file mode 100644
index 0000000..64050f9
--- /dev/null
+++ b/job-tracker-ui/src/pages/LandingPage.tsx
@@ -0,0 +1,174 @@
+import React, { useEffect, useState } from "react";
+
+import { Box, Button, Container, Stack, Typography } from "@mui/material";
+import { alpha } from "@mui/material/styles";
+import { useNavigate } from "react-router-dom";
+
+import DashboardIcon from "@mui/icons-material/SpaceDashboardOutlined";
+import AlarmIcon from "@mui/icons-material/NotificationsActiveOutlined";
+import MatchIcon from "@mui/icons-material/FactCheckOutlined";
+import MailIcon from "@mui/icons-material/MarkEmailReadOutlined";
+import AttachIcon from "@mui/icons-material/DescriptionOutlined";
+import InsightsIcon from "@mui/icons-material/InsightsOutlined";
+
+import { api } from "../api";
+
+const BRAND_DARK = "#0b1020";
+const BRAND_PANEL = "#111a33";
+
+const FEATURES: { icon: React.ReactNode; title: string; body: string }[] = [
+ { icon: , title: "Centralized pipeline", body: "Track every application across Applied, Waiting, Interview, Offer, Rejected and Ghosted — drag to update." },
+ { icon: , title: "Smart follow-ups", body: "Reminders surface what needs attention next, with a grounded draft ready to review and send." },
+ { icon: , title: "Honest CV match", body: "A deterministic keyword-coverage score with matched vs missing skills — not an opaque black box." },
+ { icon: , title: "Email correspondence", body: "Link Gmail threads to a job; new replies appear automatically without re-importing." },
+ { icon: , title: "Attachments & docs", body: "Keep resumes, cover letters and portfolios versioned per application, right where you need them." },
+ { icon: , title: "Dashboard & insights", body: "Response rates, funnel, time-in-stage and skill demand across your whole search." },
+];
+
+const STEPS: { n: number; title: string; body: string }[] = [
+ { n: 1, title: "Import", body: "Paste a job URL or use the bookmarklet — we parse the role into structured fields." },
+ { n: 2, title: "Match", body: "See how your CV covers the role: matched keywords and the gaps to close." },
+ { n: 3, title: "Tailor", body: "AI drafts a tailored CV and cover letter — you review every word before it goes out." },
+ { n: 4, title: "Track", body: "Move it through the pipeline; documents, notes and history stay attached." },
+ { n: 5, title: "Follow up", body: "Linked email threads and reminders keep momentum with grounded replies." },
+ { n: 6, title: "Analyze", body: "See what's working — response rate, funnel and time-in-stage — and focus your effort." },
+];
+
+export default function LandingPage() {
+ const navigate = useNavigate();
+ const [checking, setChecking] = useState(true);
+
+ // If the visitor already has a session, send them straight into the app.
+ useEffect(() => {
+ let active = true;
+ api
+ .get("/auth/me")
+ .then(() => { if (active) navigate("/jobs", { replace: true }); })
+ .catch(() => { if (active) setChecking(false); });
+ return () => { active = false; };
+ }, [navigate]);
+
+ if (checking) {
+ return (
+
+ Loading…
+
+ );
+ }
+
+ const gradientText = {
+ background: "linear-gradient(90deg,#6366f1,#22d3ee)",
+ WebkitBackgroundClip: "text",
+ WebkitTextFillColor: "transparent",
+ } as const;
+
+ return (
+
+ {/* Top bar */}
+
+
+
+
+ ✓
+ JobTrack
+
+
+
+
+
+
+ {/* Hero */}
+
+
+
+
+ AI-ASSISTED JOB SEARCH WORKSPACE
+
+
+ Run your job search without losing the thread.
+
+
+ Import a role, tailor your CV, track every application, and keep recruiter correspondence tied to the
+ right job — all in one focused workspace. Assistive, never autonomous: you approve every draft.
+
+
+
+
+
+
+ React · TypeScript · ASP.NET Core · EF Core · FastAPI AI · Gmail
+
+
+
+
+
+ {/* Features */}
+
+
+ WHAT IT DOES
+ One workspace for the whole search
+
+ Everything from a single import to the final offer — no more spreadsheets and scattered inboxes.
+
+
+
+ {FEATURES.map((f) => (
+
+ {f.icon}
+ {f.title}
+ {f.body}
+
+ ))}
+
+
+
+ {/* How it works */}
+
+
+
+ HOW IT WORKS
+ From a link to an offer
+
+
+ {STEPS.map((s) => (
+
+ {s.n}
+ {s.title}
+ {s.body}
+
+ ))}
+
+
+
+
+ {/* CTA */}
+
+
+
+ Ready to organize your search?
+ Sign in to start tracking applications, tailoring CVs, and following up with intent.
+
+
+
+
+
+ {/* Footer */}
+
+
+
+ © {new Date().getFullYear()} JobTrack — a focused workspace for the modern job search.
+
+
+
+
+
+ );
+}