diff --git a/src/components/common/MobileBottomNav.tsx b/src/components/common/MobileBottomNav.tsx
new file mode 100644
index 00000000..8aae9751
--- /dev/null
+++ b/src/components/common/MobileBottomNav.tsx
@@ -0,0 +1,127 @@
+import { LayoutGrid, BarChart2, Bookmark, Bell } from 'lucide-react';
+import { NavLink, useLocation } from 'react-router';
+import { cn } from '@/lib/utils';
+import { useNotifications } from '@/hooks/useNotifications';
+import { useProfileStore } from '@/hooks/useProfileStore';
+
+interface Tab {
+ label: string;
+ href: string;
+ /** Additional paths that should also highlight this tab as active. */
+ matchPaths?: string[];
+ icon: React.ReactNode;
+ activeIcon?: React.ReactNode;
+}
+
+const tabs: Tab[] = [
+ {
+ label: 'Marketplace',
+ href: '/',
+ matchPaths: ['/creators'],
+ icon: ,
+ },
+ {
+ label: 'Portfolio',
+ href: '/profile',
+ icon: ,
+ },
+ {
+ label: 'Watchlist',
+ href: '/following',
+ icon: ,
+ },
+ {
+ label: 'Notifications',
+ href: '/notifications',
+ icon: ,
+ },
+];
+
+/**
+ * Fixed bottom navigation bar for mobile viewports (< 768px).
+ *
+ * Renders four primary navigation tabs (Marketplace, Portfolio, Watchlist,
+ * Notifications) with active route highlighting and an unread-count badge on
+ * the Notifications tab. Hidden on md+ viewports via Tailwind's `md:hidden`.
+ */
+export function MobileBottomNav() {
+ const { pathname } = useLocation();
+ const profile = useProfileStore(state => state.profile);
+ const userId = profile?.id ?? '';
+
+ const { unreadCount } = useNotifications(userId);
+
+ function isTabActive(tab: Tab): boolean {
+ if (tab.href === '/') {
+ // Only exact match for root to avoid matching everything
+ return pathname === '/' || (tab.matchPaths?.includes(pathname) ?? false);
+ }
+ return (
+ pathname === tab.href ||
+ pathname.startsWith(tab.href + '/') ||
+ (tab.matchPaths?.some(p => pathname === p || pathname.startsWith(p + '/')) ?? false)
+ );
+ }
+
+ return (
+
+ );
+}
+
+export default MobileBottomNav;
diff --git a/src/components/common/RootLayout.tsx b/src/components/common/RootLayout.tsx
new file mode 100644
index 00000000..7fa9d6a1
--- /dev/null
+++ b/src/components/common/RootLayout.tsx
@@ -0,0 +1,19 @@
+import { Outlet } from 'react-router';
+import MobileBottomNav from '@/components/common/MobileBottomNav';
+
+/**
+ * Root layout shared by all routes.
+ *
+ * Renders the matched child route via and mounts the
+ * MobileBottomNav globally so it is always available on mobile viewports
+ * without each page having to include it individually.
+ */
+export default function RootLayout() {
+ return (
+ <>
+
+ {/* Fixed bottom navigation bar — visible only on viewports < 768px (md:hidden) */}
+
+ >
+ );
+}
diff --git a/src/components/home/Header.tsx b/src/components/home/Header.tsx
index 086a25f4..9a3b76ad 100644
--- a/src/components/home/Header.tsx
+++ b/src/components/home/Header.tsx
@@ -50,7 +50,9 @@ export default function Header() {
- {/* Nav */}
+ {/* Nav — hidden on mobile (< 768px) because MobileBottomNav handles
+ primary navigation on small viewports. `md:flex` keeps it
+ visible on tablet and desktop. */}