# Fabled App Overhaul — Design Spec **Date:** 2026-03-11 **Project:** `/home/bvandeusen/Nextcloud/Projects/fabled_app` ## Goal Reposition the Flutter Android app from a general-purpose mirror of the web app into a focused mobile companion: the Daily Briefing is the primary experience, Quick Capture is the secondary utility, and Notes/Tasks/Projects are a browsable library — secondary to both. --- ## Navigation & Shell Three-tab shell replacing the current four-tab (Notes · Tasks · Projects · Chat) structure. | Tab | Icon | Screen | Route | |-----|------|--------|-------| | Briefing | `Icons.wb_sunny_outlined` / `Icons.wb_sunny` | `BriefingScreen` | `/briefing` | | Library | `Icons.library_books_outlined` / `Icons.library_books` | `LibraryScreen` | `/library` | | Chat | `Icons.chat_bubble_outline` / `Icons.chat_bubble` | `ConversationsListScreen` (inline) | `/conversations` | The `_QuickCaptureBar` remains pinned above the shell on all three tabs. The settings icon stays in the capture bar row. **Briefing is the initial route** — the app opens directly to the briefing tab on every launch. **Wide layout (≥ 600dp):** `NavigationRail` on the left (as today), same 3 destinations. ### Dead Code Removed **Screens deleted:** - `lib/screens/notes/notes_list_screen.dart` - `lib/screens/tasks/tasks_list_screen.dart` - `lib/screens/projects/project_list_screen.dart` - `lib/screens/chat/conversations_list_screen.dart` - `lib/screens/quick_capture/quick_capture_screen.dart` **Screens kept:** - `lib/screens/notes/note_detail_screen.dart` - `lib/screens/notes/note_edit_screen.dart` - `lib/screens/tasks/task_edit_screen.dart` - `lib/screens/chat/chat_screen.dart` - All auth, settings, setup, splash screens --- ## Theme Custom `ColorScheme` matching the main web app's "Illuminated Transcript" palette, in `lib/core/theme.dart`. System light/dark preference respected. ### Dark theme | Token | Value | |-------|-------| | `background` | `#111113` | | `surface` | `#18181c` | | `primary` | `#6366f1` | | `onSurface` | `#e8e8f0` | | `onSurfaceVariant` (muted) | `#8888a8` | ### Light theme | Token | Value | |-------|-------| | `background` | `#f4f4f8` | | `surface` | `#ffffff` | | `primary` | `#4f46e5` | | `onSurface` | `#18181c` | | `onSurfaceVariant` (muted) | `#6b6b88` | ### Typography - Add `google_fonts` to `pubspec.yaml` - `headlineMedium`, `titleLarge`, `titleMedium` → `GoogleFonts.fraunces()` - Body styles → system default (unchanged) ### Buttons & Cards - Primary action buttons: `BoxDecoration` with `LinearGradient(135°, #6366f1, #4f46e5)`; applied to send buttons in capture bar and briefing reply bar - Cards: `borderRadius: 14`, subtle elevation shadow, no explicit border --- ## BriefingScreen **File:** `lib/screens/briefing/briefing_screen.dart` The app's primary screen. Opens on launch. ### Layout ``` AppBar: title: "Briefing" (Fraunces) subtitle: today's date ("Wednesday, March 11") actions: [↻ refresh button] Body (scrollable column): ┌─ DigestCard ──────────────────────┐ │ ☀ Good morning — Mar 11 │ │ [first assistant message, │ │ truncated to 5 lines] │ │ [Show more ↓] │ └───────────────────────────────────┘ ─── Conversation ─── [scrollable message list] [streaming bubble while generating] Bottom pinned: [ Reply to your briefing… ] [➤] ``` ### Digest Card - Extracted widget: `lib/widgets/briefing_digest_card.dart` - Shows the content of the first `assistant` message from today's conversation - Truncated to 5 lines by default; `[Show more]` expands with `AnimatedSize` - If no briefing exists yet: "No briefing yet today" placeholder + "Generate now" button ### Conversation - Message bubbles reuse the same widget used in `ChatScreen`; extracted to `lib/widgets/chat_message_bubble.dart` (shared between both screens) - User messages: right-aligned, primary colour container - Assistant messages: left-aligned, surface container with left accent border (indigo, 2dp) - Streaming: a streaming bubble appears at the bottom of the list while SSE is active ### Reply Bar - Always visible (pinned to bottom, above system nav bar) - Send button: indigo gradient, disabled when input is empty or streaming - Submitting a reply uses the existing SSE chat endpoint with today's briefing `conversation_id` ### Overflow Menu (`···`) - "View past briefings" → pushes `BriefingHistoryScreen` (simple date list, read-only — no reply bar) ### Refresh Button - Calls `POST /api/briefing/trigger` with `{"slot": "compilation"}` - Shows `CircularProgressIndicator` in the AppBar while in-flight - Reloads conversation on completion ### New Files - `lib/screens/briefing/briefing_screen.dart` - `lib/screens/briefing/briefing_history_screen.dart` - `lib/widgets/briefing_digest_card.dart` - `lib/widgets/chat_message_bubble.dart` (extracted from ChatScreen) - `lib/data/api/briefing_api.dart` — `getToday()`, `getMessages(id)`, `triggerSlot(slot)` - `lib/data/models/briefing_conversation.dart` — `id`, `briefingDate`, `title`, `messages` - `lib/providers/briefing_provider.dart` — `briefingTodayProvider` (AsyncNotifier) --- ## LibraryScreen **File:** `lib/screens/library/library_screen.dart` Unified browsing screen for notes, tasks, and projects. ### Layout ``` AppBar: title: "Library" actions: [🔍 search icon → expands inline search bar] Filter pills (scrollable horizontal row): [All] [Notes] [Tasks] [Projects] Content: Unified list sorted by updated_at desc Each item: LibraryItemCard FAB: [+] → bottom sheet: "New note" | "New task" ``` ### Filter Pills | Pill | Content | Extra controls | |------|---------|----------------| | All | Notes + tasks interleaved | — | | Notes | Notes only | — | | Tasks | Tasks only | Secondary status row: Todo · In Progress · Done · All | | Projects | Project cards | — | ### Item Cards (`lib/widgets/library_item_card.dart`) - **Note:** title (Fraunces medium), 1-line body snippet, tag chips, relative timestamp - **Task:** status checkbox (tappable → cycles `todo → in_progress → done` via `PATCH /api/tasks/:id/status`), title, due date, priority dot (high = red, medium = amber) - **Project:** left colour strip matching project colour, title, active task count, milestone progress bar ### Search - Tapping 🔍 slides an `AnimatedContainer` search bar into the AppBar - Searches title + body across notes and tasks via `GET /api/notes?q=` (respects active filter pill) - Dismisses with Escape / back gesture ### FAB - Bottom sheet with two large tap targets: "New note" → `NoteEditScreen`, "New task" → `TaskEditScreen` ### New Files - `lib/screens/library/library_screen.dart` - `lib/widgets/library_item_card.dart` --- ## Quick Capture Queue The `_QuickCaptureBar` in `app.dart` is updated to support multiple in-flight captures queued sequentially. ### Behaviour - Input **never disables** while the worker is active (only disables on offline — existing behaviour) - Submitting appends text to the work queue; the worker drains it one item at a time - Each completion fires a snackbar (`"Note created: …"`) - Queue depth > 0: prefix icon shows a badge `⋯ N` - Worker active: a 2dp `LinearProgressIndicator` in indigo animates below the capture bar ### Implementation - New `lib/providers/capture_work_queue_provider.dart` — `CaptureWorkQueueNotifier` (in-memory `List` + async drain loop) - Separate from the existing `captureQueueProvider` (which handles offline persistence); the two queues are distinct: - **Work queue:** in-memory, drains sequentially while online - **Offline queue:** persisted to SharedPreferences, drained on reconnect - Network errors during work queue drain fall through to offline queue (existing logic) --- ## Files Created / Modified Summary **New:** - `lib/core/theme.dart` - `lib/screens/briefing/briefing_screen.dart` - `lib/screens/briefing/briefing_history_screen.dart` - `lib/screens/library/library_screen.dart` - `lib/widgets/briefing_digest_card.dart` - `lib/widgets/chat_message_bubble.dart` - `lib/widgets/library_item_card.dart` - `lib/data/api/briefing_api.dart` - `lib/data/models/briefing_conversation.dart` - `lib/providers/briefing_provider.dart` - `lib/providers/capture_work_queue_provider.dart` **Modified:** - `lib/app.dart` — new 3-tab shell, new routes, updated `_QuickCaptureBar` - `lib/main.dart` — import `theme.dart` - `lib/screens/chat/chat_screen.dart` — extract bubble widget - `pubspec.yaml` — add `google_fonts` **Deleted:** - `lib/screens/notes/notes_list_screen.dart` - `lib/screens/tasks/tasks_list_screen.dart` - `lib/screens/projects/project_list_screen.dart` - `lib/screens/chat/conversations_list_screen.dart` - `lib/screens/quick_capture/quick_capture_screen.dart` --- ## Out of Scope - iOS support — Android only, as today - Workspace view — web-only feature - Graph view — web-only feature - Note editing from Library (tap → NoteDetailScreen → edit button, as today) - Push notification handling in-app — handled by the OS notification tray