Index: frontend/src/pages/Dashboard.jsx
===================================================================
--- frontend/src/pages/Dashboard.jsx	(revision 793ce2c999fddd728a9a4f772ab13cc20b8c9914)
+++ frontend/src/pages/Dashboard.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
@@ -1,2 +1,61 @@
-// hello world
-import React from "react";
+import React, { useMemo } from "react";
+import { Link, useNavigate } from "react-router-dom";
+
+const Dashboard = () => {
+  const navigate = useNavigate();
+
+  const user = useMemo(() => {
+    try {
+      const raw = localStorage.getItem("authUser");
+      return raw ? JSON.parse(raw) : null;
+    } catch {
+      return null;
+    }
+  }, []);
+
+  const onLogout = () => {
+    localStorage.removeItem("authToken");
+    localStorage.removeItem("authUser");
+    navigate("/", { replace: true });
+  };
+
+  return (
+    <div className="min-h-screen p-6">
+      <div className="max-w-3xl mx-auto">
+        <div className="flex items-center justify-between gap-3">
+          <h1 className="text-2xl font-bold">Dashboard</h1>
+          <div className="flex items-center gap-2">
+            <Link className="btn btn-ghost" to="/">
+              Landing
+            </Link>
+            <button className="btn btn-outline" onClick={onLogout}>
+              Logout
+            </button>
+          </div>
+        </div>
+
+        <div className="mt-6 card bg-base-200 border border-base-300">
+          <div className="card-body">
+            <h2 className="card-title">Account</h2>
+            <div className="text-sm leading-7">
+              <div>
+                <span className="opacity-70">Username:</span>{" "}
+                <span className="font-medium">{user?.username ?? "—"}</span>
+              </div>
+              <div>
+                <span className="opacity-70">Email:</span>{" "}
+                <span className="font-medium">{user?.email ?? "—"}</span>
+              </div>
+              <div>
+                <span className="opacity-70">User ID:</span>{" "}
+                <span className="font-medium">{user?.userId ?? "—"}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default Dashboard;
Index: frontend/src/pages/LandingPage/components/Hero.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Hero.jsx	(revision 793ce2c999fddd728a9a4f772ab13cc20b8c9914)
+++ frontend/src/pages/LandingPage/components/Hero.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
@@ -1,5 +1,20 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
 
 const Hero = () => {
+  const [isAuthed, setIsAuthed] = useState(() =>
+    Boolean(localStorage.getItem("authToken")),
+  );
+
+  useEffect(() => {
+    const onStorage = (e) => {
+      if (e.key === "authToken") {
+        setIsAuthed(Boolean(e.newValue));
+      }
+    };
+    window.addEventListener("storage", onStorage);
+    return () => window.removeEventListener("storage", onStorage);
+  }, []);
+
   return (
     <div
@@ -21,5 +36,10 @@
             consistently, and see your progress in one place.
           </p>
-          <button className="btn btn-primary">Get started</button>
+          <Link
+            className="btn btn-primary"
+            to={isAuthed ? "/dashboard" : "/register"}
+          >
+            {isAuthed ? "Go to dashboard" : "Get started"}
+          </Link>
         </div>
       </div>
Index: frontend/src/pages/LandingPage/components/NavbarLanding.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/NavbarLanding.jsx	(revision 793ce2c999fddd728a9a4f772ab13cc20b8c9914)
+++ frontend/src/pages/LandingPage/components/NavbarLanding.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
@@ -1,17 +1,54 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
+import { Link, useNavigate } from "react-router-dom";
 import logo from "../../../assets/logo.png";
 
 const NavbarLanding = () => {
+  const navigate = useNavigate();
+  const [isAuthed, setIsAuthed] = useState(() =>
+    Boolean(localStorage.getItem("authToken")),
+  );
+
+  useEffect(() => {
+    const onStorage = (e) => {
+      if (e.key === "authToken") {
+        setIsAuthed(Boolean(e.newValue));
+      }
+    };
+    window.addEventListener("storage", onStorage);
+    return () => window.removeEventListener("storage", onStorage);
+  }, []);
+
+  const onLogout = () => {
+    localStorage.removeItem("authToken");
+    localStorage.removeItem("authUser");
+    setIsAuthed(false);
+    navigate("/", { replace: true });
+  };
+
   return (
     <div className="navbar bg-neutral shadow-sm">
       <div className="navbar-start">
-        <a className="btn btn-ghost" aria-label="Trekr home">
+        <Link className="btn btn-ghost" aria-label="Trekr home" to="/">
           <img src={logo} alt="Trekr" className="h-12 w-auto rounded-2xl" />
-        </a>
+        </Link>
       </div>
       <div className="navbar-end">
-        <button className="btn bg-black text-green-200 border-black hover:bg-black/90 hover:border-black px-8 mr-6">
-          Start Tracking
-        </button>
+        {isAuthed ? (
+          <div className="flex items-center gap-2 mr-6">
+            <Link className="btn btn-primary" to="/dashboard">
+              Dashboard
+            </Link>
+            <button className="btn btn-outline" onClick={onLogout}>
+              Logout
+            </button>
+          </div>
+        ) : (
+          <Link
+            className="btn bg-black text-green-200 border-black hover:bg-black/90 hover:border-black px-8 mr-6"
+            to="/login"
+          >
+            Start Tracking
+          </Link>
+        )}
       </div>
     </div>
Index: frontend/src/pages/Login/Login.jsx
===================================================================
--- frontend/src/pages/Login/Login.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
+++ frontend/src/pages/Login/Login.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
@@ -0,0 +1,99 @@
+import React, { useEffect, useState } from "react";
+import { Link, useNavigate } from "react-router-dom";
+
+import api from "../../api/axios";
+
+const Login = () => {
+  const navigate = useNavigate();
+  const [usernameOrEmail, setUsernameOrEmail] = useState("");
+  const [password, setPassword] = useState("");
+  const [error, setError] = useState("");
+  const [isSubmitting, setIsSubmitting] = useState(false);
+
+  useEffect(() => {
+    const token = localStorage.getItem("authToken");
+    if (token) navigate("/dashboard", { replace: true });
+  }, [navigate]);
+
+  const onSubmit = async (e) => {
+    e.preventDefault();
+    setError("");
+    setIsSubmitting(true);
+    try {
+      const res = await api.post("/auth/login", {
+        usernameOrEmail,
+        password,
+      });
+      localStorage.setItem("authToken", res.data.token);
+      localStorage.setItem(
+        "authUser",
+        JSON.stringify({
+          userId: res.data.userId,
+          username: res.data.username,
+          email: res.data.email,
+        }),
+      );
+      navigate("/dashboard");
+    } catch (err) {
+      const message =
+        err?.response?.data?.message ||
+        err?.response?.data?.errors?.usernameOrEmail ||
+        "Login failed";
+      setError(message);
+    } finally {
+      setIsSubmitting(false);
+    }
+  };
+
+  return (
+    <div className="min-h-screen flex items-center justify-center p-4">
+      <form
+        onSubmit={onSubmit}
+        className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4"
+      >
+        <legend className="fieldset-legend">Login</legend>
+
+        <label className="label">Username or Email</label>
+        <input
+          type="text"
+          className="input"
+          placeholder="Username or Email"
+          value={usernameOrEmail}
+          onChange={(e) => setUsernameOrEmail(e.target.value)}
+          autoComplete="username"
+          required
+        />
+
+        <label className="label">Password</label>
+        <input
+          type="password"
+          className="input"
+          placeholder="Password"
+          value={password}
+          onChange={(e) => setPassword(e.target.value)}
+          autoComplete="current-password"
+          required
+        />
+
+        {error ? <p className="text-error mt-2 text-sm">{error}</p> : null}
+
+        <button
+          className="btn btn-neutral mt-4"
+          type="submit"
+          disabled={isSubmitting}
+        >
+          {isSubmitting ? "Logging in..." : "Login"}
+        </button>
+
+        <p className="mt-3 text-sm">
+          Don&apos;t have an account?{" "}
+          <Link className="link link-primary" to="/register">
+            Register
+          </Link>
+        </p>
+      </form>
+    </div>
+  );
+};
+
+export default Login;
Index: frontend/src/pages/Register/Register.jsx
===================================================================
--- frontend/src/pages/Register/Register.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
+++ frontend/src/pages/Register/Register.jsx	(revision 86158850756b7b97df263e784aecbbae73d37b17)
@@ -0,0 +1,112 @@
+import React, { useEffect, useState } from "react";
+import { Link, useNavigate } from "react-router-dom";
+
+import api from "../../api/axios";
+
+const Register = () => {
+  const navigate = useNavigate();
+  const [email, setEmail] = useState("");
+  const [username, setUsername] = useState("");
+  const [password, setPassword] = useState("");
+  const [error, setError] = useState("");
+  const [isSubmitting, setIsSubmitting] = useState(false);
+
+  useEffect(() => {
+    const token = localStorage.getItem("authToken");
+    if (token) navigate("/dashboard", { replace: true });
+  }, [navigate]);
+
+  const onSubmit = async (e) => {
+    e.preventDefault();
+    setError("");
+    setIsSubmitting(true);
+    try {
+      const res = await api.post("/auth/register", {
+        email,
+        username,
+        password,
+      });
+      localStorage.setItem("authToken", res.data.token);
+      localStorage.setItem(
+        "authUser",
+        JSON.stringify({
+          userId: res.data.userId,
+          username: res.data.username,
+          email: res.data.email,
+        }),
+      );
+      navigate("/dashboard");
+    } catch (err) {
+      const message =
+        err?.response?.data?.message ||
+        Object.values(err?.response?.data?.errors ?? {})[0] ||
+        "Registration failed";
+      setError(message);
+    } finally {
+      setIsSubmitting(false);
+    }
+  };
+
+  return (
+    <div className="min-h-screen flex items-center justify-center p-4">
+      <form
+        onSubmit={onSubmit}
+        className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4"
+      >
+        <legend className="fieldset-legend">Register</legend>
+
+        <label className="label">Email</label>
+        <input
+          type="email"
+          className="input"
+          placeholder="Email"
+          value={email}
+          onChange={(e) => setEmail(e.target.value)}
+          autoComplete="email"
+          required
+        />
+
+        <label className="label">Username</label>
+        <input
+          type="text"
+          className="input"
+          placeholder="Username"
+          value={username}
+          onChange={(e) => setUsername(e.target.value)}
+          autoComplete="username"
+          required
+        />
+
+        <label className="label">Password</label>
+        <input
+          type="password"
+          className="input"
+          placeholder="Password"
+          value={password}
+          onChange={(e) => setPassword(e.target.value)}
+          autoComplete="new-password"
+          required
+        />
+
+        {error ? <p className="text-error mt-2 text-sm">{error}</p> : null}
+
+        <button
+          className="btn btn-neutral mt-4"
+          type="submit"
+          disabled={isSubmitting}
+        >
+          {isSubmitting ? "Creating account..." : "Register"}
+        </button>
+
+        <p className="mt-3 text-sm">
+          Already have an account?{" "}
+          <Link className="link link-primary" to="/login">
+            Login
+          </Link>
+        </p>
+      </form>
+    </div>
+  );
+};
+
+export default Register;
