diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/metrics-page.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/metrics-page.tsx
index 7b2153abf..4f5922048 100644
--- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/metrics-page.tsx
+++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/metrics-page.tsx
@@ -46,6 +46,8 @@ import { LayoutGroup, motion, useReducedMotion, type Transition } from "motion/r
import { ErrorBoundary } from "next/dist/client/components/error-boundary";
import { type ElementType, type ReactNode, Suspense, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
import { AnalyticsEventLimitBanner } from "../analytics/shared";
+import { DailyBriefOverviewCard } from "../_daily-brief/components";
+import { TODAYS_DAILY_BRIEF } from "../_daily-brief/mock-data";
import { PageLayout } from "../page-layout";
import { useAdminApp, useProjectId } from "../use-admin-app";
import { UserPageMetricCard } from "../users/[userId]/user-page-metric-card";
@@ -1899,6 +1901,8 @@ function MetricsContent({
/>
+
+
void,
+ compact?: boolean,
+}) {
+ return (
+
+
+
+
+
+
+ {suggestion.title}
+
+
+
+ {suggestion.summary}
+
+
+ {suggestion.impact}
+
+
+
onApply(suggestion.id)}
+ className={cn(
+ "shrink-0 transition-all duration-150 hover:transition-none",
+ completed && "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
+ )}
+ >
+
+ {completed ? : null}
+ {completed ? "Completed" : suggestion.actionLabel}
+
+
+
+
+ );
+}
+
+export function DailyBriefOverviewCard({
+ brief,
+ projectId,
+}: {
+ brief: DailyBrief,
+ projectId: string,
+}) {
+ const previewBullets: DailyBriefBullet[] = brief.sections.flatMap((section) => section.blocks.flatMap((block) => block.type === "bullets" ? block.bullets : [])).slice(0, 3);
+ const suggestionCount = brief.sections.flatMap((section) => section.blocks.filter((block) => block.type === "suggestion")).length;
+ const coreMetrics = brief.sections.flatMap((section) => section.blocks.flatMap((block) => block.type === "metrics" ? block.metrics : [])).slice(0, 2);
+
+ return (
+
+ }
+ contentClassName="space-y-4"
+ >
+
+
+
+
+ {brief.dateLabel}
+ /
+ {brief.readTime}
+
+
+ {brief.title}
+
+
+
+ {previewBullets.map((bullet) => (
+ -
+
+
+ {bullet.label}:{" "}
+ {bullet.text}
+
+
+ ))}
+
+
+
+
+ Read full brief
+
+
+
+
+
+
+
+
+
+ Briefing signals
+
+
+
+ {coreMetrics.map((metric) => (
+
+
{metric.value}
+
{metric.label} / {metric.delta}
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/_daily-brief/mock-data.ts b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/_daily-brief/mock-data.ts
new file mode 100644
index 000000000..39b954ff7
--- /dev/null
+++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/_daily-brief/mock-data.ts
@@ -0,0 +1,368 @@
+export type DailyBriefSuggestion = {
+ id: string,
+ title: string,
+ summary: string,
+ impact: string,
+ actionLabel: string,
+};
+
+export type DailyBriefBullet = {
+ label: string,
+ text: string,
+};
+
+export type DailyBriefMetric = {
+ label: string,
+ value: string,
+ delta: string,
+ tone: "good" | "watch" | "neutral",
+};
+
+export type DailyBriefImportantUser = {
+ name: string,
+ email: string,
+ company: string,
+ signal: string,
+};
+
+export type DailyBriefVisual = {
+ title: string,
+ caption: string,
+ kind: "chart" | "screenshot" | "map",
+};
+
+export type DailyBriefBlock =
+ | { type: "bullets", bullets: DailyBriefBullet[] }
+ | { type: "metrics", metrics: DailyBriefMetric[] }
+ | { type: "users", users: DailyBriefImportantUser[] }
+ | { type: "visual", visual: DailyBriefVisual }
+ | { type: "suggestion", suggestion: DailyBriefSuggestion };
+
+export type DailyBriefSection = {
+ heading: string,
+ intro?: string,
+ blocks: DailyBriefBlock[],
+};
+
+export type DailyBrief = {
+ id: string,
+ dateLabel: string,
+ dayLabel: string,
+ title: string,
+ summary: string,
+ readTime: string,
+ tags: string[],
+ sections: DailyBriefSection[],
+};
+
+export const DAILY_BRIEFS: DailyBrief[] = [
+ {
+ id: "2026-07-08",
+ dateLabel: "July 8, 2026",
+ dayLabel: "Today",
+ title: "Search traffic is working better than social",
+ summary: "Short notes on growth, new users, revenue, and suggested next steps.",
+ readTime: "5 min read",
+ tags: ["Growth", "Users", "Revenue"],
+ sections: [
+ {
+ heading: "Executive summary",
+ intro: "Quick read. The main changes are below.",
+ blocks: [
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Search is stronger",
+ text: "Fewer visits than direct traffic. More sign-ups and first payments.",
+ },
+ {
+ label: "Team invites matter",
+ text: "Users who invited teammates finished setup faster.",
+ },
+ {
+ label: "No urgent issue",
+ text: "Email and payment health look normal today.",
+ },
+ ],
+ },
+ ],
+ },
+ {
+ heading: "Core metric growth",
+ blocks: [
+ {
+ type: "metrics",
+ metrics: [
+ { label: "Qualified sign-ups", value: "128", delta: "+18% vs last week", tone: "good" },
+ { label: "Activated projects", value: "42", delta: "+11% vs last week", tone: "good" },
+ { label: "First purchase revenue", value: "$675", delta: "+6% vs prior period", tone: "good" },
+ { label: "Avg. setup time", value: "14m", delta: "-9% faster", tone: "good" },
+ ],
+ },
+ {
+ type: "visual",
+ visual: {
+ kind: "chart",
+ title: "Setup by source",
+ caption: "Mock chart: search users reach setup steps sooner than paid social users.",
+ },
+ },
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Best search terms",
+ text: "\"auth pricing calculator\" and \"B2B user management SDK\" convert 38% above average.",
+ },
+ {
+ label: "Social is weaker",
+ text: "Paid social brings visits, but fewer users finish setup.",
+ },
+ ],
+ },
+ {
+ type: "suggestion",
+ suggestion: {
+ id: "increase-search-budget-auth-pricing",
+ title: "Move budget to search",
+ summary: "Increase budget for \"auth pricing calculator\" and \"B2B user management SDK\".",
+ impact: "+12-18% expected good-fit sign-ups",
+ actionLabel: "Apply suggestion",
+ },
+ },
+ ],
+ },
+ {
+ heading: "Important recent sign-ups",
+ blocks: [
+ {
+ type: "users",
+ users: [
+ {
+ name: "Maya Patel",
+ email: "maya@northstar.dev",
+ company: "Northstar Labs",
+ signal: "Created a project. Invited 3 teammates. Viewed payments.",
+ },
+ {
+ name: "Ethan Brooks",
+ email: "ethan@arcforge.ai",
+ company: "ArcForge AI",
+ signal: "Came from Google. Read RBAC docs twice. Signed up.",
+ },
+ {
+ name: "Sofia Nguyen",
+ email: "sofia@cloudlane.co",
+ company: "Cloudlane",
+ signal: "Set up email templates. Sent a test email in 11 minutes.",
+ },
+ ],
+ },
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Follow up",
+ text: "Prioritize accounts that invite teammates and view payments.",
+ },
+ {
+ label: "Main drop-off",
+ text: "Users still get stuck before adding a production domain.",
+ },
+ ],
+ },
+ {
+ type: "suggestion",
+ suggestion: {
+ id: "launch-domain-setup-nudge",
+ title: "Add domain setup nudge",
+ summary: "Prompt new admins if no domain is added after 20 minutes.",
+ impact: "+7% expected project activation",
+ actionLabel: "Apply suggestion",
+ },
+ },
+ ],
+ },
+ {
+ heading: "Extra context",
+ blocks: [
+ {
+ type: "visual",
+ visual: {
+ kind: "screenshot",
+ title: "Landing page test",
+ caption: "Mock image: add a short setup proof section near pricing.",
+ },
+ },
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Revenue",
+ text: "First purchases mostly come from accounts with multiple active users.",
+ },
+ {
+ label: "Today",
+ text: "Focus on search. Fix the domain setup drop-off.",
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: "2026-07-07",
+ dateLabel: "July 7, 2026",
+ dayLabel: "Yesterday",
+ title: "Team invites helped users finish setup",
+ summary: "Projects with early teammate invites were more active.",
+ readTime: "4 min read",
+ tags: ["Activation", "Teams"],
+ sections: [
+ {
+ heading: "Brief",
+ blocks: [
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Invites helped",
+ text: "Teams looked at roles, permissions, and email templates sooner.",
+ },
+ {
+ label: "Make it early",
+ text: "Ask for teammate invites earlier in setup.",
+ },
+ ],
+ },
+ ],
+ },
+ {
+ heading: "Recommended follow-up",
+ blocks: [
+ {
+ type: "suggestion",
+ suggestion: {
+ id: "promote-team-invite-onboarding",
+ title: "Move team invite up",
+ summary: "Show team invites earlier for new projects.",
+ impact: "+9% expected week-one retention",
+ actionLabel: "Apply suggestion",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: "2026-07-06",
+ dateLabel: "July 6, 2026",
+ dayLabel: "Monday",
+ title: "Email delivery is fine. Template setup needs help.",
+ summary: "Delivery is stable. Some users edit templates but never send a test.",
+ readTime: "3 min read",
+ tags: ["Emails", "Retention"],
+ sections: [
+ {
+ heading: "Brief",
+ blocks: [
+ {
+ type: "metrics",
+ metrics: [
+ { label: "Delivered emails", value: "1.8k", delta: "+4%", tone: "good" },
+ { label: "Bounce rate", value: "1.2%", delta: "flat", tone: "neutral" },
+ { label: "Template stalls", value: "14", delta: "+22%", tone: "watch" },
+ ],
+ },
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "Delivery is fine",
+ text: "No bounce spike today.",
+ },
+ {
+ label: "Template setup stalls",
+ text: "Some users edit templates but never send a test.",
+ },
+ ],
+ },
+ ],
+ },
+ {
+ heading: "Recommended follow-up",
+ blocks: [
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "UX nudge",
+ text: "Show test-send after two template edits.",
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: "2026-07-03",
+ dateLabel: "July 3, 2026",
+ dayLabel: "Friday",
+ title: "Pricing visitors want proof faster",
+ summary: "Pricing visitors often check docs before signing up.",
+ readTime: "4 min read",
+ tags: ["Pricing", "Website"],
+ sections: [
+ {
+ heading: "Brief",
+ blocks: [
+ {
+ type: "visual",
+ visual: {
+ kind: "map",
+ title: "Pricing to docs",
+ caption: "Mock journey: users check setup effort before signing up.",
+ },
+ },
+ {
+ type: "bullets",
+ bullets: [
+ {
+ label: "High intent",
+ text: "Pricing visitors open setup docs more often.",
+ },
+ {
+ label: "Missing proof",
+ text: "Add setup proof near pricing.",
+ },
+ ],
+ },
+ ],
+ },
+ {
+ heading: "Recommended follow-up",
+ blocks: [
+ {
+ type: "suggestion",
+ suggestion: {
+ id: "add-pricing-implementation-proof",
+ title: "Add setup proof",
+ summary: "Add a short setup block to the pricing page.",
+ impact: "+5% expected pricing-to-sign-up conversion",
+ actionLabel: "Apply suggestion",
+ },
+ },
+ ],
+ },
+ ],
+ },
+];
+
+export const TODAYS_DAILY_BRIEF = DAILY_BRIEFS[0];
+
+export function getAllDailyBriefSuggestions(): DailyBriefSuggestion[] {
+ return DAILY_BRIEFS.flatMap((brief) => brief.sections.flatMap((section) => section.blocks.flatMap((block) => block.type === "suggestion" ? [block.suggestion] : [])));
+}
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/daily-brief/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/daily-brief/page-client.tsx
new file mode 100644
index 000000000..ca5b71f86
--- /dev/null
+++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/daily-brief/page-client.tsx
@@ -0,0 +1,386 @@
+"use client";
+
+import { DesignBadge, DesignButton, DesignCard, DesignDialog, DesignDialogClose } from "@/components/design-components";
+import { Checkbox } from "@/components/ui";
+import { cn } from "@/lib/utils";
+import { CheckCircleIcon, GearIcon, ImageIcon, LightningIcon, SparkleIcon, UserCircleIcon } from "@phosphor-icons/react";
+import { useMemo, useState } from "react";
+import { SuggestionActionCard } from "../_daily-brief/components";
+import { DAILY_BRIEFS, getAllDailyBriefSuggestions, type DailyBrief, type DailyBriefBlock, type DailyBriefImportantUser, type DailyBriefMetric, type DailyBriefVisual } from "../_daily-brief/mock-data";
+import { PageLayout } from "../page-layout";
+
+const WEEKDAYS = [
+ { id: "mon", label: "Mo" },
+ { id: "tue", label: "Tu" },
+ { id: "wed", label: "We" },
+ { id: "thu", label: "Th" },
+ { id: "fri", label: "Fr" },
+ { id: "sat", label: "Sa" },
+ { id: "sun", label: "Su" },
+] as const;
+
+type WeekdayId = typeof WEEKDAYS[number]["id"];
+
+function MetricsBlock({ metrics }: { metrics: DailyBriefMetric[] }) {
+ return (
+
+ {metrics.map((metric) => (
+
+
{metric.label}
+
{metric.value}
+
+ {metric.delta}
+
+
+ ))}
+
+ );
+}
+
+function UsersBlock({ users }: { users: DailyBriefImportantUser[] }) {
+ return (
+
+ {users.map((user) => (
+
+
+
+
+
+
+
{user.name}
+
{user.company} / {user.email}
+
+
+
+ {user.signal}
+
+
+ ))}
+
+ );
+}
+
+function VisualBlock({ visual }: { visual: DailyBriefVisual }) {
+ return (
+
+
+
+
+ {[42, 58, 36, 74, 91].map((height) => (
+
+ ))}
+
+
+
+ {visual.kind === "chart" ? "Mock chart" : visual.kind === "map" ? "Mock journey map" : "Mock image"}
+
+
+
+
{visual.title}
+
{visual.caption}
+
+
+
+ );
+}
+
+function DailyBriefBlockRenderer({
+ block,
+ completedSuggestionIds,
+ onApplySuggestion,
+}: {
+ block: DailyBriefBlock,
+ completedSuggestionIds: Set
,
+ onApplySuggestion: (suggestionId: string) => void,
+}) {
+ switch (block.type) {
+ case "bullets": {
+ return (
+
+ {block.bullets.map((bullet) => (
+ -
+
+
{bullet.label}
+ {bullet.text}
+
+ ))}
+
+ );
+ }
+ case "metrics": {
+ return ;
+ }
+ case "users": {
+ return ;
+ }
+ case "visual": {
+ return ;
+ }
+ case "suggestion": {
+ return (
+
+ );
+ }
+ }
+}
+
+function BriefTreeSection({
+ section,
+ sectionIndex,
+ completedSuggestionIds,
+ onApplySuggestion,
+}: {
+ section: DailyBrief["sections"][number],
+ sectionIndex: number,
+ completedSuggestionIds: Set,
+ onApplySuggestion: (suggestionId: string) => void,
+}) {
+ return (
+
+
+
+
+
+
+ Section {sectionIndex + 1}
+
+
+ {section.heading}
+
+
+ {section.intro != null && (
+
+ {section.intro}
+
+ )}
+
+
+ {section.blocks.map((block, index) => (
+
+ ))}
+
+
+
+ );
+}
+
+function BriefTree({
+ brief,
+ completedSuggestionIds,
+ onApplySuggestion,
+}: {
+ brief: DailyBrief,
+ completedSuggestionIds: Set,
+ onApplySuggestion: (suggestionId: string) => void,
+}) {
+ return (
+
+
+
+ {brief.sections.map((section, sectionIndex) => (
+
+ ))}
+
+ );
+}
+
+export default function PageClient() {
+ const allSuggestions = useMemo(() => getAllDailyBriefSuggestions(), []);
+ const [completedSuggestionIds, setCompletedSuggestionIds] = useState>(() => new Set());
+ const [enabledBriefDays, setEnabledBriefDays] = useState>(() => new Set(["mon", "tue", "wed", "thu", "fri"]));
+ const completedCount = allSuggestions.filter((suggestion) => completedSuggestionIds.has(suggestion.id)).length;
+ const allSuggestionsCompleted = allSuggestions.length > 0 && completedCount === allSuggestions.length;
+ const enabledDayLabel = WEEKDAYS.filter((day) => enabledBriefDays.has(day.id)).map((day) => day.label).join(", ");
+
+ const applySuggestion = (suggestionId: string) => {
+ setCompletedSuggestionIds((previous) => {
+ const next = new Set(previous);
+ next.add(suggestionId);
+ return next;
+ });
+ };
+
+ const applyAllSuggestions = () => {
+ setCompletedSuggestionIds(new Set(allSuggestions.map((suggestion) => suggestion.id)));
+ };
+
+ const toggleBriefDay = (dayId: WeekdayId, enabled: boolean) => {
+ setEnabledBriefDays((previous) => {
+ const next = new Set(previous);
+ if (enabled) {
+ next.add(dayId);
+ } else {
+ next.delete(dayId);
+ }
+ return next;
+ });
+ };
+
+ return (
+
+
+
+
+ {allSuggestionsCompleted ? : null}
+ {allSuggestionsCompleted ? "All suggestions completed" : "Apply all suggestions"}
+
+
+
+
+
+ }
+ icon={GearIcon}
+ title="Daily Brief schedule"
+ description="Choose which days should create a new brief. This is mock UI for now."
+ size="md"
+ footer={
+
+ Done
+
+ }
+ >
+
+
+ Current schedule: {enabledDayLabel || "No days selected"}
+
+
+ {WEEKDAYS.map((day) => (
+
+ ))}
+
+
+
+
+ }
+ fillWidth
+ wrapHeaderInCard
+ >
+