diff --git a/app/mobile/profile/page.tsx b/app/mobile/profile/page.tsx
new file mode 100644
index 0000000..f7cf71a
--- /dev/null
+++ b/app/mobile/profile/page.tsx
@@ -0,0 +1,30 @@
+// /mobile/profile (PROF-01) — gated by requireAuth(), server-rendered shell
+// hosts the four client sections.
+
+import { redirect } from 'next/navigation';
+import { requireAuth } from '@/lib/auth-utils';
+import { ProfileTimezoneSection } from '@/components/mobile/profile/ProfileTimezoneSection';
+import { ProfileThemeSection } from '@/components/mobile/profile/ProfileThemeSection';
+import { ProfileNotificationMatrix } from '@/components/mobile/profile/ProfileNotificationMatrix';
+import { ProfileChannelsSection } from '@/components/mobile/profile/ProfileChannelsSectionPlaceholder';
+
+export default async function MobileProfilePage() {
+ const { session, error } = await requireAuth();
+ // CRITICAL: requireAuth() returns NextResponse on miss — that shape is for
+ // API routes only. A Page route MUST call redirect() instead. Returning
+ // `error` from here would render a JSON 401 body as the page, which is wrong.
+ if (error || !session) {
+ redirect('/auth/sign-in');
+ }
+ return (
+ Profile & Preferences
+
Account
- {user.name} -
- )} - {user.email && ( -- {user.email} -
- )} -+ {user.name} +
+ )} + {user.email && ( ++ {user.email} +
+ )} +