diff --git a/apps/web/package.json b/apps/web/package.json
index f051e98..bc96979 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@afterlife/shared": "*",
+ "framer-motion": "^12.34.3",
"next": "^15",
"next-intl": "^4.8.3",
"react": "^19",
diff --git a/apps/web/src/app/[locale]/layout.tsx b/apps/web/src/app/[locale]/layout.tsx
index bedbd09..202f004 100644
--- a/apps/web/src/app/[locale]/layout.tsx
+++ b/apps/web/src/app/[locale]/layout.tsx
@@ -3,6 +3,8 @@ import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import { notFound } from "next/navigation";
import { routing } from "@/i18n/routing";
+import { Navbar } from "@/components/layout/Navbar";
+import { Footer } from "@/components/layout/Footer";
import "./globals.css";
export const metadata: Metadata = {
@@ -25,9 +27,11 @@ export default async function LocaleLayout({
return (
-
+
- {children}
+
+ {children}
+
diff --git a/apps/web/src/components/layout/Footer.tsx b/apps/web/src/components/layout/Footer.tsx
new file mode 100644
index 0000000..fbaa56d
--- /dev/null
+++ b/apps/web/src/components/layout/Footer.tsx
@@ -0,0 +1,13 @@
+import { useTranslations } from "next-intl";
+
+export function Footer() {
+ const t = useTranslations("footer");
+
+ return (
+
+ );
+}
diff --git a/apps/web/src/components/layout/LanguageSwitcher.tsx b/apps/web/src/components/layout/LanguageSwitcher.tsx
new file mode 100644
index 0000000..e9e1821
--- /dev/null
+++ b/apps/web/src/components/layout/LanguageSwitcher.tsx
@@ -0,0 +1,36 @@
+"use client";
+
+import { useLocale, useTranslations } from "next-intl";
+import { useRouter, usePathname } from "next/navigation";
+
+export function LanguageSwitcher() {
+ const locale = useLocale();
+ const router = useRouter();
+ const pathname = usePathname();
+ const t = useTranslations("footer");
+
+ function switchLocale(newLocale: string) {
+ const segments = pathname.split("/");
+ segments[1] = newLocale;
+ router.push(segments.join("/"));
+ }
+
+ return (
+
+ {t("language")}:
+
+ |
+
+
+ );
+}
diff --git a/apps/web/src/components/layout/Navbar.tsx b/apps/web/src/components/layout/Navbar.tsx
new file mode 100644
index 0000000..b813b0e
--- /dev/null
+++ b/apps/web/src/components/layout/Navbar.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import Link from "next/link";
+import { useLocale, useTranslations } from "next-intl";
+import { LanguageSwitcher } from "./LanguageSwitcher";
+
+export function Navbar() {
+ const t = useTranslations("nav");
+ const locale = useLocale();
+
+ const links = [
+ { href: `/${locale}`, label: t("home") },
+ { href: `/${locale}/catalog`, label: t("catalog") },
+ { href: `/${locale}/about`, label: t("about") },
+ { href: `/${locale}/donate`, label: t("donate") },
+ ];
+
+ return (
+
+ );
+}
diff --git a/package-lock.json b/package-lock.json
index 7aa7e71..9a172f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -37,6 +37,7 @@
"version": "0.1.0",
"dependencies": {
"@afterlife/shared": "*",
+ "framer-motion": "^12.34.3",
"next": "^15",
"next-intl": "^4.8.3",
"react": "^19",