diff --git a/app/src/app/(tabs)/_layout.tsx b/app/src/app/(tabs)/_layout.tsx
deleted file mode 100644
index 07d99ea..0000000
--- a/app/src/app/(tabs)/_layout.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Link, Tabs } from "expo-router";
-import { Text } from "react-native";
-import { C } from "../../lib/theme";
-
-function icon(glyph: string) {
- return ({ focused }: { focused: boolean }) => (
- {glyph}
- );
-}
-
-export default function TabsLayout() {
- return (
- (
-
- ⚙️
-
- ),
- }}
- >
-
-
-
-
-
-
- );
-}
diff --git a/app/src/app/(tabs)/index.tsx b/app/src/app/(tabs)/index.tsx
deleted file mode 100644
index 3249c37..0000000
--- a/app/src/app/(tabs)/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import TaskListScreen from "../../components/TaskListScreen";
-
-export default function Inbox() {
- return ;
-}
diff --git a/app/src/app/(tabs)/next.tsx b/app/src/app/(tabs)/next.tsx
deleted file mode 100644
index 2b333b7..0000000
--- a/app/src/app/(tabs)/next.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import TaskListScreen from "../../components/TaskListScreen";
-
-export default function Next() {
- return ;
-}
diff --git a/app/src/app/(tabs)/someday.tsx b/app/src/app/(tabs)/someday.tsx
deleted file mode 100644
index a35ace5..0000000
--- a/app/src/app/(tabs)/someday.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import TaskListScreen from "../../components/TaskListScreen";
-
-export default function Someday() {
- return ;
-}
diff --git a/app/src/app/(tabs)/waiting.tsx b/app/src/app/(tabs)/waiting.tsx
deleted file mode 100644
index fb720c6..0000000
--- a/app/src/app/(tabs)/waiting.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import TaskListScreen from "../../components/TaskListScreen";
-
-export default function Waiting() {
- return ;
-}
diff --git a/app/src/app/_layout.tsx b/app/src/app/_layout.tsx
index 0a56e52..57cac87 100644
--- a/app/src/app/_layout.tsx
+++ b/app/src/app/_layout.tsx
@@ -1,4 +1,4 @@
-import { Stack } from "expo-router";
+import { Link, Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { C } from "../lib/theme";
@@ -14,7 +14,19 @@ export default function RootLayout() {
contentStyle: { backgroundColor: C.bg },
}}
>
-
+ (
+
+ ⚙️
+
+ ),
+ }}
+ />
+
+
diff --git a/app/src/app/index.tsx b/app/src/app/index.tsx
new file mode 100644
index 0000000..a1092a4
--- /dev/null
+++ b/app/src/app/index.tsx
@@ -0,0 +1,157 @@
+import { useFocusEffect, useRouter } from "expo-router";
+import { useCallback, useState } from "react";
+import { Pressable, StyleSheet, Text, TextInput, View } from "react-native";
+import { api } from "../lib/api";
+import { C } from "../lib/theme";
+import type { Project, Task } from "../lib/types";
+
+const Q = {
+ next: { title: "Next up", color: "#3DBF77", bg: "#15301F", border: "#1E4D33" },
+ waiting: { title: "Waiting for", color: "#E0A93E", bg: "#33270F", border: "#544019" },
+ someday: { title: "Someday", color: "#9D8FE8", bg: "#221E38", border: "#38315C" },
+ projects: { title: "Projects", color: "#5B9DE8", bg: "#152538", border: "#1F3D5C" },
+};
+
+function Quadrant({
+ kind,
+ count,
+ preview,
+ onPress,
+}: {
+ kind: keyof typeof Q;
+ count: number;
+ preview: string[];
+ onPress: () => void;
+}) {
+ const q = Q[kind];
+ return (
+
+
+ {q.title}
+ {count}
+
+ {preview.map((p, i) => (
+
+ {p}
+
+ ))}
+
+ );
+}
+
+export default function Home() {
+ const router = useRouter();
+ const [tasks, setTasks] = useState([]);
+ const [projects, setProjects] = useState([]);
+ const [draft, setDraft] = useState("");
+ const [error, setError] = useState(null);
+
+ const load = useCallback(async () => {
+ try {
+ const [ts, ps] = await Promise.all([api.tasks.list(), api.projects.list()]);
+ setTasks(ts);
+ setProjects(ps.filter((p) => p.status === "active"));
+ setError(null);
+ } catch (e) {
+ setError(e instanceof Error ? e.message : String(e));
+ }
+ }, []);
+
+ useFocusEffect(
+ useCallback(() => {
+ load();
+ }, [load]),
+ );
+
+ const capture = async () => {
+ const title = draft.trim();
+ if (!title) return;
+ setDraft("");
+ try {
+ await api.tasks.create({ title });
+ } finally {
+ load();
+ }
+ };
+
+ const byStatus = (st: string) => tasks.filter((t) => t.status === st);
+ const inboxCount = byStatus("inbox").length;
+ const titles = (st: string) => byStatus(st).slice(0, 3).map((t) => t.title);
+
+ return (
+
+
+ router.push("/list/inbox")}>
+ 📥 Inbox
+ {inboxCount}
+
+ {error && {error}}
+
+
+ router.push("/list/next")} />
+ router.push("/list/waiting")} />
+
+
+ router.push("/list/someday")} />
+ p.name)}
+ onPress={() => router.push("/projects")}
+ />
+
+
+
+ );
+}
+
+const s = StyleSheet.create({
+ screen: { flex: 1, backgroundColor: C.bg, padding: 12 },
+ capture: {
+ padding: 14,
+ borderRadius: 12,
+ backgroundColor: C.surface,
+ color: C.text,
+ fontSize: 16,
+ borderWidth: 1,
+ borderColor: C.border,
+ },
+ inboxPill: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ marginTop: 10,
+ paddingVertical: 12,
+ paddingHorizontal: 16,
+ borderRadius: 12,
+ backgroundColor: C.surface,
+ borderWidth: 1,
+ borderColor: C.border,
+ },
+ inboxText: { color: C.text, fontSize: 16, fontWeight: "600" },
+ grid: { flex: 1, marginTop: 10, gap: 10 },
+ gridRow: { flex: 1, flexDirection: "row", gap: 10 },
+ quad: {
+ flex: 1,
+ borderRadius: 16,
+ borderWidth: 1,
+ padding: 14,
+ },
+ quadHead: { flexDirection: "row", justifyContent: "space-between", marginBottom: 8 },
+ quadTitle: { fontSize: 17, fontWeight: "700" },
+ quadCount: { fontSize: 17, fontWeight: "700" },
+ quadItem: { color: C.muted, fontSize: 13, marginBottom: 4 },
+ error: { color: C.danger, marginTop: 8 },
+});
diff --git a/app/src/app/list/[status].tsx b/app/src/app/list/[status].tsx
new file mode 100644
index 0000000..602b996
--- /dev/null
+++ b/app/src/app/list/[status].tsx
@@ -0,0 +1,32 @@
+import { Stack, useLocalSearchParams } from "expo-router";
+import TaskListScreen from "../../components/TaskListScreen";
+import type { TaskStatus } from "../../lib/types";
+
+const TITLES: Record = {
+ inbox: "Inbox",
+ next: "Next up",
+ waiting: "Waiting for",
+ scheduled: "Scheduled",
+ someday: "Someday",
+ done: "Done",
+};
+
+const HINTS: Record = {
+ inbox: "Inbox zero. Capture from the home screen.",
+ next: "No next actions. Clarify your inbox.",
+ waiting: "Not waiting on anyone.",
+ scheduled: "Nothing scheduled.",
+ someday: "No someday/maybe items.",
+ done: "Nothing done yet.",
+};
+
+export default function ListByStatus() {
+ const { status } = useLocalSearchParams<{ status: string }>();
+ const st = (status in TITLES ? status : "inbox") as TaskStatus;
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/app/src/app/(tabs)/projects.tsx b/app/src/app/projects.tsx
similarity index 95%
rename from app/src/app/(tabs)/projects.tsx
rename to app/src/app/projects.tsx
index caf7d9d..95c0874 100644
--- a/app/src/app/(tabs)/projects.tsx
+++ b/app/src/app/projects.tsx
@@ -1,9 +1,9 @@
import { useFocusEffect, useRouter } from "expo-router";
import { useCallback, useState } from "react";
import { FlatList, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
-import { api } from "../../lib/api";
-import { C } from "../../lib/theme";
-import type { Project } from "../../lib/types";
+import { api } from "../lib/api";
+import { C } from "../lib/theme";
+import type { Project } from "../lib/types";
export default function Projects() {
const router = useRouter();