);
}
diff --git a/v2/operator-app/src/routes/briefs/theme.tsx b/v2/operator-app/src/routes/briefs/theme.tsx
new file mode 100644
index 0000000..4fa510e
--- /dev/null
+++ b/v2/operator-app/src/routes/briefs/theme.tsx
@@ -0,0 +1,73 @@
+// Dedicated brief theme & branding tool. The same ThemeEditor that lives on
+// the brief edit page, but with a live preview pane to its right and proper
+// page chrome (title, breadcrumb, back-to-brief link) so it feels like a
+// real edit tool.
+//
+// Path: /briefs/:id/theme — linked from the brief detail page header,
+// brief edit page, and brief list rows.
+
+import { useState } from 'react';
+import { Link, useParams } from 'react-router-dom';
+import { useBrief, type BriefTheme } from '../../api/briefs';
+import { ThemeEditor, DEFAULT_THEME } from '../../components/ThemeEditor';
+import { ThemePreview } from '../../components/ThemePreview';
+
+export default function BriefThemeRoute() {
+ const { id } = useParams();
+ const { data, isLoading, error } = useBrief(id);
+ const [livePreview, setLivePreview] = useState(
+ data?.brief.theme ?? DEFAULT_THEME,
+ );
+
+ if (isLoading) return
+ Pick the look the per-report dashboard renders for {brief.client_name}.
+ Reports rebuilt after a change pick up the new theme.
+
+
+
+ Back to brief
+
+
+
+
+
+
+
+
+
Live preview
+
+
+ This pane updates live as you tweak the controls — it's a slice of what the per-report
+ dashboard will render. Changes only persist once you click Save theme;
+ existing finished reports keep their old theme until rebuilt.
+