diff --git a/frontend/src/components/layout/L1RouteGuard.tsx b/frontend/src/components/layout/L1RouteGuard.tsx
new file mode 100644
index 00000000..b613dc26
--- /dev/null
+++ b/frontend/src/components/layout/L1RouteGuard.tsx
@@ -0,0 +1,10 @@
+import { Navigate } from 'react-router-dom'
+import { usePermissions } from '@/hooks/usePermissions'
+
+export function L1RouteGuard({ children }: { children: React.ReactNode }) {
+ const { canUseL1Surface } = usePermissions()
+ if (!canUseL1Surface) {
+ return
+ }
+ return <>{children}>
+}
diff --git a/frontend/src/pages/l1/L1Dashboard.tsx b/frontend/src/pages/l1/L1Dashboard.tsx
new file mode 100644
index 00000000..e7de2fbe
--- /dev/null
+++ b/frontend/src/pages/l1/L1Dashboard.tsx
@@ -0,0 +1,13 @@
+import { PageMeta } from '@/components/common/PageMeta'
+
+export default function L1Dashboard() {
+ return (
+
+
+
+
L1 Workspace
+
Loading…
+
+
+ )
+}
diff --git a/frontend/src/pages/l1/L1DraftsPage.tsx b/frontend/src/pages/l1/L1DraftsPage.tsx
new file mode 100644
index 00000000..7fd02a22
--- /dev/null
+++ b/frontend/src/pages/l1/L1DraftsPage.tsx
@@ -0,0 +1,13 @@
+import { PageMeta } from '@/components/common/PageMeta'
+
+export default function L1DraftsPage() {
+ return (
+
+ )
+}
diff --git a/frontend/src/pages/l1/L1TicketsPage.tsx b/frontend/src/pages/l1/L1TicketsPage.tsx
new file mode 100644
index 00000000..b4c1b01f
--- /dev/null
+++ b/frontend/src/pages/l1/L1TicketsPage.tsx
@@ -0,0 +1,13 @@
+import { PageMeta } from '@/components/common/PageMeta'
+
+export default function L1TicketsPage() {
+ return (
+
+
+
+
L1 Tickets
+
Loading…
+
+
+ )
+}
diff --git a/frontend/src/pages/l1/L1WalkPage.tsx b/frontend/src/pages/l1/L1WalkPage.tsx
new file mode 100644
index 00000000..24007ec7
--- /dev/null
+++ b/frontend/src/pages/l1/L1WalkPage.tsx
@@ -0,0 +1,13 @@
+import { PageMeta } from '@/components/common/PageMeta'
+
+export default function L1WalkPage() {
+ return (
+
+ )
+}
diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx
index cadd0032..c57664f4 100644
--- a/frontend/src/router.tsx
+++ b/frontend/src/router.tsx
@@ -7,6 +7,7 @@ import { RouteError } from '@/components/common/RouteError'
import { ErrorBoundary } from '@/components/common/ErrorBoundary'
import { PageLoader } from '@/components/common/PageLoader'
import { lazyWithRetry } from '@/lib/lazyWithRetry'
+import { L1RouteGuard } from '@/components/layout/L1RouteGuard'
const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV7(createBrowserRouter)
import {
@@ -95,6 +96,12 @@ const AdminSurveyInvitesPage = lazyWithRetry(() => import('@/pages/admin/SurveyI
const AdminSurveyResponsesPage = lazyWithRetry(() => import('@/pages/admin/SurveyResponsesPage'))
const AdminGalleryManagementPage = lazyWithRetry(() => import('@/pages/admin/GalleryManagementPage'))
+// L1 workspace pages
+const L1Dashboard = lazyWithRetry(() => import('@/pages/l1/L1Dashboard'))
+const L1WalkPage = lazyWithRetry(() => import('@/pages/l1/L1WalkPage'))
+const L1DraftsPage = lazyWithRetry(() => import('@/pages/l1/L1DraftsPage'))
+const L1TicketsPage = lazyWithRetry(() => import('@/pages/l1/L1TicketsPage'))
+
// Account pages
const AccountLayout = lazyWithRetry(() => import('@/components/account/AccountLayout'))
const ProfileSettingsPage = lazyWithRetry(() => import('@/pages/account/ProfileSettingsPage'))
@@ -284,6 +291,11 @@ export const router = sentryCreateBrowserRouter([
{ path: 'welcome/step-1', element: page(WelcomeStep1) },
{ path: 'welcome/step-2', element: page(WelcomeStep2) },
{ path: 'welcome/step-3', element: page(WelcomeStep3) },
+ // L1 workspace routes — gated by canUseL1Surface
+ { path: 'l1', element: {page(L1Dashboard)} },
+ { path: 'l1/walk/:sessionId', element: {page(L1WalkPage)} },
+ { path: 'l1/drafts', element: {page(L1DraftsPage)} },
+ { path: 'l1/tickets', element: {page(L1TicketsPage)} },
// Admin routes
{
path: 'admin',