refactor: implement new UI/UX architecture with redesigned desktop and mobile layouts, CSS-in-CSS modularization, and updated components.

This commit is contained in:
2026-08-29 00:53:57 -07:00
parent dfbf646332
commit cd98c0120e
47 changed files with 8039 additions and 7236 deletions
+13 -10
View File
@@ -6,11 +6,13 @@ This document records planned features, UX enhancements, and architectural exten
## 1. Search Box Auto-Complete & Real-Time Suggestions
- **Goal**: Enable rich auto-complete and search suggestion dropdown as the user types in the global search bar.
- **Scope**:
- Auto-suggest matches across article titles, feed names, author tags, and category labels.
- Keyboard navigation within search dropdown (`ArrowDown`, `ArrowUp`, `Enter` to jump directly to article or feed).
- Search history / recent queries quick access.
- **Status**: **Partially Implemented (Search History Table & Dropdown Active)**
- **Implemented**:
- SQLite table `search_history (keyword TEXT PRIMARY KEY, last_searched_at DATETIME, search_count INTEGER)`.
- Backend endpoints `GET /api/search/history`, `POST /api/search/history`, `DELETE /api/search/history`.
- Frontend auto-complete dropdown with keyboard navigation (`ArrowDown`, `ArrowUp`, `Enter`), single-item removal, and clear history.
- **Future Extensions**:
- Live fuzzy matching across live article titles, feeds, authors, and category labels alongside search history.
---
@@ -59,12 +61,14 @@ This document records planned features, UX enhancements, and architectural exten
---
## 6. Feed Favicon & Website Icon Scraping / Upload
## 6. Feed Favicon & Website Icon Integration (Completed)
- **Goal**: Enhance visual recognition by displaying brand icons next to each feed.
- **Goal**: Enhance visual recognition by displaying colorful website brand icons next to each feed.
- **Scope**:
- **Auto-Scraper**: Automatically fetch and cache `favicon.ico`, `<link rel="icon">`, or `<link rel="apple-touch-icon">` from the feed's website root during initial subscription.
- **Manual Customization**: Allow uploading or specifying a custom icon URL in `Settings > Subscriptions > Edit Feed`.
- **Auto-Resolution**: Automatically generates and stores high-resolution website favicons (`https://www.google.com/s2/favicons?domain=...&sz=64`) from the feed's website root during subscription and crawler discovery.
- **Fallback**: Gracefully falls back to the clean RSS icon if image loading fails or host is unreachable.
- **Manual Customization**: Added full manual customization in `Settings > Feeds > Edit Feed` with live preview and "Auto-Detect" one-click button.
- **DB Migration & Backfill**: Automatically added `icon_url` column and backfilled all existing feeds.
---
@@ -141,4 +145,3 @@ This document records planned features, UX enhancements, and architectural exten
- Outbound webhook action in rule engine supporting Telegram, Discord, Slack, and generic JSON HTTP POST.
- Template engine with interpolation of article variables (`title`, `feed_title`, `url`, `published_at`, `ai_summary`, `tags`).
- Retry mechanism with exponential backoff on delivery failure.
@@ -0,0 +1,348 @@
# 007 - UI/UX Architecture & Design Specification
This document details the complete design, layout philosophy, component hierarchy, gesture system, and CSS token architecture for RSSPipe's renewed frontend.
---
## 1. Design Philosophy & System Architecture
RSSPipe follows a dual-mode philosophy: **Power-Desk Reader** for large desktop screens / tablets and **Xiaohongshu-style Visual Discovery Feed** for mobile devices. Rather than forcing a single responsive compromise, the application decouples into two purpose-built consumption systems sharing core backend state, authentication, and settings.
```mermaid
graph TD
A[App Shell / Router] --> B{Platform & Width Detection}
B -->|Screen >= 768px & Pointer| C[Desktop 3-Split System]
B -->|Screen < 768px or Touch| D[Mobile Waterfall System]
B -->|Manual Toggle / Hotkey 'V'| E[View Mode Override]
C --> F[Draggable 3-Column Workspace]
D --> G[iOS Bottom Nav + Masonry Grid]
C --> H[Shared Core Services & State]
D --> H
H --> I[Settings, Auth, Modals, Audio Engine]
```
### 1.1 Platform & View Mode Resolution
1. **Initial Resolution**:
- Touch Detection: `'ontouchstart' in window || navigator.maxTouchPoints > 0`
- Viewport Width: `window.innerWidth < 768`
- If either condition is true and no prior manual user preference exists in `localStorage`, default to `waterfall`. Otherwise, default to `split`.
2. **Persistence**:
- Stored under `localStorage.getItem('rsspipe_view_mode')`.
- Desktop header contains an explicit switch button; pressing `V` (when not focused in an input) toggles between `split` and `waterfall`.
---
## 2. Design System & CSS Token Architecture
RSSPipe adopts a high-contrast, clean minimalist Light Mode design language inspired by Apple Human Interface Guidelines and Linear.app.
### 2.1 CSS Layering & File Structure
Styles are organized into modular, maintainable stylesheets loaded in dependency order:
```
web/src/styles/
├── tokens.css # Core variables: colors, typography, elevations, radiuses, z-indices
├── base.css # Reset, typography, app container, custom micro-scrollbars
├── three-pane.css # 3-split layout, draggable splitter handles, desktop list, power reader
├── waterfall.css # Mobile bottom nav, masonry grid, SmartArt cards, swipe sheets
├── settings.css # Restrained, harmonized settings panels (AI, Rules, Feeds)
└── modals.css # Shared dialogs (Add Feed, OPML Import/Export, Keyboard Shortcuts)
```
### 2.2 Formal Design Tokens (`tokens.css`)
```css
:root {
/* Surface & Background */
--bg-app: #f8fafc;
--bg-surface: #ffffff;
--bg-sidebar: #f8fafc;
--bg-card: #ffffff;
--bg-card-hover: #f1f5f9;
--bg-card-active: #e2e8f0;
--bg-subtle: #f1f5f9;
/* Borders */
--border-light: #f1f5f9;
--border-subtle: #e2e8f0;
--border-strong: #cbd5e1;
--border-focus: #0f172a;
/* Typography */
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
/* Text Colors */
--text-primary: #0f172a;
--text-secondary: #334155;
--text-muted: #64748b;
--text-dim: #94a3b8;
--text-inverse: #ffffff;
/* Brand Accents */
--accent-primary: #0f172a;
--accent-hover: #1e293b;
--accent-soft: rgba(15, 23, 42, 0.05);
--accent-border: #cbd5e1;
/* Semantic Colors */
--star-gold: #d97706;
--star-bg: #fef3c7;
--success: #15803d;
--danger: #b91c1c;
--badge-ai: #4f46e5;
--badge-tts: #0284c7;
/* Radius */
--radius-xs: 4px;
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 16px;
--radius-full: 9999px;
/* Elevations */
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.03);
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.03);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.1);
--shadow-docked: 0 -4px 16px rgba(0, 0, 0, 0.05);
/* Layout Dimensions */
--header-height: 48px;
--bottom-nav-height: 56px;
--docked-audio-height: 52px;
--sidebar-min-width: 200px;
--sidebar-default-width: 240px;
--list-min-width: 280px;
--list-default-width: 380px;
--reader-min-width: 480px;
}
```
---
## 3. Desktop 3-Split System Specification
The Desktop 3-Split experience is optimized for speed, precision, and power keyboard navigation.
```
+-----------------------------------------------------------------------------------------+
| [Header]: RSSPipe | Filter / Search | View Toggle (V) | Add Feed | User Profile |
+--------------------+-----------------------------+--------------------------------------+
| SIDEBAR (Resizable)| ARTICLE LIST (Resizable) | DETAIL READER (Fluid) |
| | | |
| 📥 Inbox (12) | [🔍 Search / Filter Pills ] | [Action Toolbar: Star, Read, AI, TTS]|
| ⭐ Starred (4) | [Compact / Card Mode Toggle]| ==================================== |
| 🏷️ Tech & AI (8) | +-------------------------+ | <h1>Article Title</h1> |
| - Hacker News (5)| | [Unread Dot] Feed Title | <p>Source: Hacker News • 2h ago</p> |
| - Ars Technica(3)| | Post Headline Title | |
| ⚙️ Settings | | 2h ago • 3 min read | [AI Summary Box (Collapsible)] |
| | +-------------------------+ | |
| | | Next Article Row... | [Markdown / Full-Text Content Body] |
| <Drag Handle 1> | <Drag Handle 2> | |
+--------------------+-----------------------------+--------------------------------------+
```
### 3.1 Draggable Resizable Panes
- **Handle Component**: `ResizableSplitter` listens to `mousedown`, `mousemove`, `mouseup` on window with an invisible overlay prevent-iframe-drag.
- **Constraints**:
- Pane 1 (Sidebar): `180px` min, `400px` max. Double-click handle collapses/expands sidebar (`[` key shortcut).
- Pane 2 (List): `260px` min, `600px` max.
- Pane 3 (Reader): Takes remaining fluid width (`flex: 1`, `min-width: 400px`).
- **Width Persistence**: Saved in `localStorage` under `rsspipe_pane_widths: { sidebar, list }`.
### 3.2 List Mode Toggle (Compact vs Rich Cards)
- **Compact Mode**: 2-line condensed rows with unread dot, source title, post headline, and relative time. Maximizes scan speed (30+ posts visible per screen).
- **Rich Card Mode**: Includes 1-line summary snippet, cover thumbnail (if present), tags, and reading time.
### 3.3 Desktop Power Reader Toolbar
- **Variant Selector**: Original RSS / Readability Scraped / AI Translated / Plain Text.
- **AI Summary Pill**: Collapsible summary panel with bulleted highlights.
- **Scrape Full-Text Button**: Triggers Readability fetch with live spinner.
- **Audio TTS Player**: Inline audio bar with play/pause and progress scrubber.
- **Actions**: Star (`s`), Mark Unread (`m`), Open in Browser (`o`), Copy Link.
### 3.4 Keyboard Shortcuts (Vim / Superhuman Style)
Active exclusively in Desktop 3-Split mode:
| Shortcut | Action |
| --- | --- |
| `j` / `↓` | Select next article in list |
| `k` / `↑` | Select previous article in list |
| `m` / `r` | Toggle Read / Unread status |
| `s` | Toggle Star / Bookmark |
| `f` | Fetch / Scrape full-text content |
| `a` | Toggle AI Summary expansion |
| `o` / `v` | Open original article in external tab |
| `[` | Collapse / Expand Sidebar |
| `/` | Focus search input field |
| `?` | Show Keyboard shortcuts modal |
---
## 4. Mobile Waterfall System Specification (Xiaohongshu-Style)
The Mobile Waterfall experience is designed for thumb-driven browsing, rich visual exploration, and native-feeling gesture interactions.
```
+------------------------------------------+
| [Header]: RSSPipe [🔍 Search] |
+------------------------------------------+
| [Tabs]: All | Tech | News | Science |
+------------------------------------------+
| WATERFALL MASONRY GRID (2-Column) |
| |
| +----------------+ +----------------+ |
| | [Image / Cover]| | [SmartArt Text]| |
| | Headline text | | Headline text | |
| | that wraps 2-3 | | in high-style | |
| | lines... | | typography | |
| | [Favicon] Feed | | [Favicon] Feed | |
| +----------------+ +----------------+ |
| +----------------+ +----------------+ |
| | [SmartArt Text]| | [Image / Cover]| |
| | ... | | ... | |
| +----------------+ +----------------+ |
+------------------------------------------+
| [Docked Mini Audio Player] (If Playing) |
+------------------------------------------+
| [iOS Bottom Nav]: 🏠Home|📡Feeds|🎧Listen|⭐Starred|⚙️Settings |
+------------------------------------------+
```
### 4.1 iOS 5-Tab Bottom Navigation Bar (`XHSBottomNav`)
Fixed to the bottom viewport (`height: 56px`, `backdrop-filter: blur(20px)`, `border-top: 1px solid var(--border-subtle)`):
1. **🏠 Home**:
- 2-column masonry waterfall of all incoming posts (weighted/curated discovery).
- Top header displays minimal RSSPipe branding and a Search button icon (`🔍`).
2. **📡 Feeds**:
- Clean source directory grouped by Category.
- Shows feed favicon, title, unread count badge, and health status.
- Tapping a feed navigates to a dedicated single-feed waterfall view with a top "← Back to Feeds" header.
3. **🎧 Listen**:
- Filtered waterfall containing only posts with playable audio/TTS/podcast variants.
- Cards display audio duration badge (`🎧 4 min`) and 1-tap quick play button.
4. **⭐ Starred**:
- Feeds and folder list containing starred items with star badge counts.
- Tapping opens the filtered Starred posts waterfall.
5. **⚙️ Settings**:
- Mobile-adapted profile, feeds manager, AI rules, and OPML import/export.
### 4.2 Card Design & SmartArt Typographic Covers
- **Posts with Images**: Image rendered at natural aspect ratio with subtle rounded corners (`border-radius: 8px`).
- **Posts without Images (SmartArt Cover)**:
- Generates a styled visual banner using subtle mathematical gradient seeds based on feed name.
- Large expressive serif/sans quote typography displaying the first 6-10 words of the title or excerpt.
- Eliminates dull empty gray boxes while maintaining fast pure-CSS rendering.
- **Card Footer**:
- Source favicon / initial avatar.
- Clean truncated feed title.
- Relative time (`2h ago`) or Star icon.
### 4.3 Mobile Full-Screen Article Reader (`MobileArticleSheet`)
- **Open Transition**: Tapping a card smoothly mounts the full-screen reading sheet with iOS slide-up transition (`transform: translateY(0)`).
- **Navigation Gestures**:
- **Left-Edge Swipe to Dismiss**: User drags from the left edge (`0px - 30px` boundary) towards the right to swipe away the article back to the waterfall grid.
- **No horizontal page skipping**: Prevents accidental article skipping while scrolling long texts.
- **Vertical Scrolling**: Standard elastic touch scrolling with high-legibility font sizing (17px body, 1.6 line height).
- **Mobile Action Pill**: Floating or top-bar minimal actions (Star, Audio Play, Share, Open in Browser). AI summaries and Readability variants are pre-generated by server rules and rendered inline.
### 4.4 Docked Mobile Audio Player (`DockedAudioPlayer`)
- **Docked Bar**: When audio/TTS is playing, docks directly above the Bottom Navigation Bar (`bottom: 56px`):
- Mini cover art / favicon.
- Scrolling title + feed name.
- 15s Rewind (`⏪`), Play/Pause (`⏯️`), 15s Fast-forward (`⏩`), Close (`✕`).
- 2px slim live progress line at the top edge of the player.
- **Expanded Player Modal**: Tapping the mini-player expands into a full modal sheet:
- Large cover art / SmartArt illustration.
- Full-width scrubber slider with current time and remaining time.
- Playback speed switcher (`0.75x`, `1.0x`, `1.25x`, `1.5x`, `2.0x`).
- Bulleted AI highlights / transcript view.
---
## 5. Harmonized Settings Design System
Settings panels (especially AI Rules, Prompt Engineering, and Triage) are refactored from disparate dense layouts into the unified minimal design system:
- **Navigation Sidebar**: Left list on desktop, top tab pill bar on mobile.
- **Section Grouping**:
- **Feeds & Folders**: Feed subscription list, category organization, OPML export.
- **AI & Automation**: Provider configuration (OpenAI, Gemini, Ollama, DeepSeek), automated scraping rules, TTS voice selection.
- **Preferences**: Default view mode, reading font size, auto-mark read on scroll.
- **Form Controls**: Consistent `40px` input height, subtle border-focus outline, clean toggle switches, minimal action buttons.
---
## 6. Directory Structure & Component Map
```
web/src/
├── App.tsx # Master shell, view mode resolution, global audio state
├── types.ts # Shared interfaces and types
├── utils.ts # Formatters, text extractors, SmartArt seed generators
├── services/
│ └── api.ts # REST API client
├── styles/
│ ├── tokens.css # [NEW] Design variables
│ ├── base.css # [NEW] Baseline typography & layout
│ ├── three-pane.css # [NEW] Desktop split panes & splitters
│ ├── waterfall.css # [NEW] Mobile waterfall & bottom nav
│ ├── settings.css # [NEW] Harmonized settings styles
│ └── modals.css # [NEW] Modal dialog styles
└── components/
├── common/
│ ├── Header.tsx # Shared top header
│ ├── LoginView.tsx # Login & session initiation
│ ├── AddFeedModal.tsx # New feed modal dialog
│ ├── OPMLModal.tsx # OPML import/export modal
│ └── KeyboardShortcutsModal.tsx # Shortcut cheat sheet
├── desktop/
│ ├── ThreePaneView.tsx # 3-column container with draggable splitters
│ ├── ResizableSplitter.tsx # Drag handle component
│ ├── DesktopSidebar.tsx # Feeds, categories, and inbox folder tree
│ ├── DesktopArticleList.tsx # List column with Compact/Card toggle
│ └── DesktopReader.tsx # Desktop reader pane with power toolbar
├── mobile/
│ ├── WaterfallView.tsx # Mobile waterfall root container
│ ├── XHSBottomNav.tsx # iOS-style 5-tab bottom navigation
│ ├── MobileArticleSheet.tsx # Slide-in reader with left-edge swipe dismiss
│ ├── SmartArtCard.tsx # Typographic cards for image-less posts
│ ├── DockedAudioPlayer.tsx # Sticky mini player + expanded player sheet
│ ├── FeedsTabView.tsx # Feeds & category directory tab
│ └── StarredTabView.tsx # Starred feeds directory tab
└── settings/
└── SettingsView.tsx # Unified minimal settings view
```
---
## 7. Implementation Milestones
1. **Milestone 1: Design Tokens & Modular CSS Foundation**:
- Create `tokens.css`, `base.css`, `three-pane.css`, `waterfall.css`, `settings.css`, `modals.css`.
- Update `main.tsx` / `index.html` to import the new style system.
2. **Milestone 2: Desktop 3-Split System**:
- Implement `ResizableSplitter` and update `ThreePaneView`.
- Add Compact List vs Rich Card toggle.
- Implement Vim keyboard shortcuts (`j`/`k`, `m`, `s`, `[`).
3. **Milestone 3: Mobile Waterfall & iOS Bottom Navigation**:
- Implement `XHSBottomNav` with the 5 tabs (`Home`, `Feeds`, `Listen`, `Starred`, `Settings`).
- Create `SmartArtCard` for image-less posts.
- Build `MobileArticleSheet` with left-edge touch swipe-to-dismiss gesture.
4. **Milestone 4: Docked Mobile Audio Player**:
- Build `DockedAudioPlayer` for TTS/podcast playback with docked mini-bar and expandable sheet.
5. **Milestone 5: Harmonize Settings & Shared Modals**:
- Refactor `SettingsView` (AI, Rules, Feeds) to use clean design tokens.
- End-to-end responsive & touch testing.
@@ -0,0 +1,128 @@
# 008 - Desktop 3-Pane View Feedback & Design Specifications
This document comprehensively records all user feedback, UX directives, and architectural decisions made for the **Desktop 3-Pane View** in RSSPipe.
---
## 1. Design Aesthetics & Visual Identity
- **Theme Palette**: Metal-inspired, refined monochrome with sleek slate/zinc surfaces (`#09090b`, `#18181b`, `#27272a`), crisp typography (Inter/system), and subtle color accents (Gold for Starred, Emerald for Tags, Blue for Keywords/AI).
- **Surface Elevation**: Clean hairline borders (`1px solid var(--border-subtle)`), eliminating heavy shadows or dated blue-gray tints.
---
## 2. Top Header Bar
| Element | Specification & User Directive | Status |
| :--- | :--- | :--- |
| **Brand & Icon** | RSSPipe logo and brand name anchored at the leftmost position across all views. | Implemented |
| **Search Bar** | Widened search input with auto-completion backed by `search_history` database table (`keyword`, `last_searched_at`, `search_count`). | Implemented |
| **Refresh Button** | Smooth keyframe rotation animation with guaranteed visual feedback duration on click/poll. | Implemented |
| **Left Sidebar Toggle** | Removed from top header (sidebar remains permanently accessible in 3-pane desktop). | Implemented |
| **View Switcher** | Removed "3-connected-button" switcher from top bar; view modes configured via Settings > General. | Implemented |
---
## 3. Left Sidebar (Navigation Pane)
### Structure & Hierarchy
1. **Views Section**:
- `Inbox` (Unread count badge)
- `Starred` (Starred count badge)
- `All Articles`
- `Shared` (Public share count badge)
2. **Feeds Section**:
- Category Folders with nested feeds
- Uncategorized feeds at root level
### UI / UX Rules
- **Category Chevron Alignment**: Fold/unfold toggle icon is placed **immediately after the category title** (before the unread count), ensuring category feeds and uncategorized feeds share the exact same left margin and indentation.
- **Unread Badges**: Pinned flush to the far right edge of the item row.
- **Feed Spacing**: Tight, efficient vertical spacing (`gap: 1px`, `min-height: 28px`).
- **Feed Favicons**:
- Automatically resolved from website root (`https://www.google.com/s2/favicons?domain=...&sz=64`) upon subscription.
- Rendered with live error fallback to the default RSS icon.
- Fully customizable in `Settings > Feeds > Edit Feed`.
---
## 4. Middle Pane (Article List)
### Mode 1: Compact List (`compact`)
- **Row Structure (2-Line)**:
- **Line 1**: Article Headline (`entry.title`)
- **Line 2**: Published Date (`YYYY-MM-DD`) + right-aligned conditional icons.
- **Conditional Status Icons**:
- ⭐ **Starred**: Gold star button (rendered only when starred; 0px width when unstarred).
- 🔗 **Shared**: `Share2` icon (rendered only when `share_uuid` exists).
### Mode 2: Expanded / Non-Compact List (`rich`)
- **Strict Rule**: **No thumbnail images** in entry cards.
- **Row Structure**:
- **Line 1**: `:title` (Article headline)
- **Line 2**: `:description` (Clean text snippet, stripped HTML)
- **Line 3**: `:date` (`YYYY-MM-DD` left-aligned) + right-aligned status indicators (`starred`, `shared`, `ai-summarized`).
- **Line 4**: `:keywords` and `:tags` in distinct colors (Blue keyword chips, Emerald `#tag` chips).
### Scope & Filtering
- **Dynamic Header Title**: Updates to show active feed name, category title, or search query.
- **Scope Toggle**: `[ Unread | All ]` pill switcher when browsing a specific feed/category.
- **Query Reset**: Automatically resets search queries upon selecting a feed/category to prevent "no articles found" confusion.
---
## 5. Right Pane (Reading Canvas)
### Top Action Toolbar
- **Left Group**:
- `Toggle Unread`
- `Toggle Star`
- `Toggle Shared` (auto-copies link to clipboard)
- `Copy Link`
- `Open Original Site` (new tab)
- **Right Group**:
- **Split Action Button**:
- Default click: `Get Full Text` (scrapes via Readability and switches view to cleaned full text; toggles between `Original Feed` and `Full Text`).
- Dropdown menu: `Generate AI Summary` and `Generate Audio`.
- *No extraneous public share link buttons in top menu.*
### Article Content Layout & Ordering
```
1. Feed Subtitle + Favicon (feed_title)
2. Post Title (h1)
3. Author (if exists)
4. Updated Date (YYYY-MM-DD HH:mm) • Reading Time
5. Keywords Chips (if exists)
6. Tags Chips (if exists)
──────────────────────────────────────────────────── (Divider)
7. AI Summary Card (in-page error notice if failed)
8. Audio Narration Player (if generated)
9. Article Content Body (HTML / Full Text)
```
### Layout & Scrollbar
- **Far-Right Scrollbar**: The scroll container spans the full pane width so the native scrollbar sits against the far right edge of the screen, while article content remains centered at a readable max-width (`760px`).
- **AI Summary Error Notice**: In-page error banner within the summary container instead of modal `alert()` popups.
### Automatic Read Triggers
When the reading preference is enabled (`rsspipe_auto_read_scroll`):
1. **Short Articles (Content ≤ 1 Page)**: Automatically marked as read after staying on the article for **3 seconds**.
2. **Content Click**: Clicking anywhere inside the reader content canvas (excluding the toolbar) immediately marks as read.
3. **Long Articles (Content > 1 Page)**: Scrolling down the right reading pane immediately marks as read.
---
## 6. Real-Time State Synchronization
- **Sidebar Counts**: Toggling `is_read`, `is_starred`, or `share_uuid` immediately triggers a stats reload to keep sidebar counters (`inbox`, `starred`, `shared`) synchronized in real time.
- **Persistence**: Switching feeds or categories in the sidebar updates the middle article list without abruptly reloading or clearing the active reading canvas.