diff --git a/apps/web/src/components/InitiativeList.tsx b/apps/web/src/components/InitiativeList.tsx
index f70c71e..3360678 100644
--- a/apps/web/src/components/InitiativeList.tsx
+++ b/apps/web/src/components/InitiativeList.tsx
@@ -1,4 +1,5 @@
import { AlertCircle, Plus } from "lucide-react";
+import { motion } from "motion/react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Skeleton } from "@/components/Skeleton";
@@ -83,12 +84,22 @@ export function InitiativeList({
// Populated state
return (
- {initiatives.map((initiative) => (
- (
+ onViewInitiative(initiative.id)}
- />
+ initial={{ opacity: 0, y: 12 }}
+ animate={{ opacity: 1, y: 0 }}
+ transition={{
+ duration: 0.3,
+ delay: Math.min(i * 0.05, 0.3),
+ ease: [0, 0, 0.2, 1],
+ }}
+ >
+ onViewInitiative(initiative.id)}
+ />
+
))}
);
diff --git a/apps/web/src/routes/agents.tsx b/apps/web/src/routes/agents.tsx
index 399fe7a..cbe1468 100644
--- a/apps/web/src/routes/agents.tsx
+++ b/apps/web/src/routes/agents.tsx
@@ -1,5 +1,6 @@
import { useState } from "react";
import { createFileRoute, useNavigate, useSearch } from "@tanstack/react-router";
+import { motion } from "motion/react";
import { AlertCircle, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
@@ -182,7 +183,12 @@ function AgentsPage() {
];
return (
-
+
{/* Header + Filters */}
@@ -195,7 +201,12 @@ function AgentsPage() {
Refresh
-
+
{filterOptions.map((opt) => (
))}
-
+
{/* Two-panel layout */}
-
+
{/* Left: Agent List */}
{filtered.length === 0 ? (
@@ -227,60 +243,70 @@ function AgentsPage() {
) : (
- filtered.map((agent) => (
- (
+ setSelectedAgentId(agent.id)}
+ initial={{ opacity: 0, y: 12 }}
+ animate={{ opacity: 1, y: 0 }}
+ transition={{
+ duration: 0.3,
+ delay: Math.min(i * 0.05, 0.3),
+ ease: [0, 0, 0.2, 1],
+ }}
>
-
-
-
-
- {agent.name}
-
-
-
-
- {agent.provider}
-
-
- {modeLabel(agent.mode)}
-
- {/* Action dropdown */}
-
e.stopPropagation()}>
-
+
setSelectedAgentId(agent.id)}
+ >
+
+
+
+
+ {agent.name}
+
+
+
+
+ {agent.provider}
+
+
+ {modeLabel(agent.mode)}
+
+ {/* Action dropdown */}
+
e.stopPropagation()}>
+
+
-
-
-
- {formatRelativeTime(String(agent.updatedAt))}
-
- {agent.status === "waiting_for_input" && (
-
{
- e.stopPropagation();
- handleGoToInbox();
- }}
- >
- Answer questions →
+
+
+ {formatRelativeTime(String(agent.updatedAt))}
- )}
-
-
+ {agent.status === "waiting_for_input" && (
+ {
+ e.stopPropagation();
+ handleGoToInbox();
+ }}
+ >
+ Answer questions →
+
+ )}
+
+
+
))
)}
@@ -302,7 +328,7 @@ function AgentsPage() {
)}
-
-
+
+
);
}
diff --git a/apps/web/src/routes/inbox.tsx b/apps/web/src/routes/inbox.tsx
index 80b5532..d7cc2cb 100644
--- a/apps/web/src/routes/inbox.tsx
+++ b/apps/web/src/routes/inbox.tsx
@@ -1,5 +1,6 @@
import { useState } from "react";
import { createFileRoute } from "@tanstack/react-router";
+import { motion } from "motion/react";
import { AlertCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
@@ -176,10 +177,20 @@ function InboxPage() {
}));
return (
-
+
{/* Left: Inbox List -- hidden on mobile when agent selected */}
-
+
-
+
{/* Right: Detail Panel */}
{selectedAgent && (
@@ -251,6 +262,6 @@ function InboxPage() {
)}
-
+
);
}
diff --git a/apps/web/src/routes/initiatives/$id.tsx b/apps/web/src/routes/initiatives/$id.tsx
index 9d68368..e8944ae 100644
--- a/apps/web/src/routes/initiatives/$id.tsx
+++ b/apps/web/src/routes/initiatives/$id.tsx
@@ -1,4 +1,5 @@
import { createFileRoute, useNavigate } from "@tanstack/react-router";
+import { motion } from "motion/react";
import { AlertCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/Skeleton";
@@ -99,7 +100,12 @@ function InitiativeDetailPage() {
const phases = phasesQuery.data ?? [];
return (
-
+
{/* Header */}
{/* Tab bar */}
-
+
{TABS.map((tab) => (
+
{/* Tab content */}
- {activeTab === "content" &&
}
- {activeTab === "plan" && (
-
- )}
- {activeTab === "execution" && (
-
- )}
- {activeTab === "review" &&
}
-
+
+ {activeTab === "content" && }
+ {activeTab === "plan" && (
+
+ )}
+ {activeTab === "execution" && (
+
+ )}
+ {activeTab === "review" && }
+
+
);
}
diff --git a/apps/web/src/routes/initiatives/index.tsx b/apps/web/src/routes/initiatives/index.tsx
index 52388fb..41c7066 100644
--- a/apps/web/src/routes/initiatives/index.tsx
+++ b/apps/web/src/routes/initiatives/index.tsx
@@ -1,5 +1,6 @@
import { useState } from "react";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
+import { motion } from "motion/react";
import { Plus } from "lucide-react";
import { Button } from "@/components/ui/button";
import { InitiativeList } from "@/components/InitiativeList";
@@ -31,7 +32,12 @@ function DashboardPage() {
]);
return (
-
+
{/* Page header */}
Initiatives
@@ -57,19 +63,25 @@ function DashboardPage() {
{/* Initiative list */}
- setCreateDialogOpen(true)}
- onViewInitiative={(id) =>
- navigate({ to: "/initiatives/$id", params: { id } })
- }
- />
+
+ setCreateDialogOpen(true)}
+ onViewInitiative={(id) =>
+ navigate({ to: "/initiatives/$id", params: { id } })
+ }
+ />
+
{/* Create initiative dialog */}
-
+
);
}